Created
May 16, 2024 20:25
-
-
Save cdgriffith/b922efc8cc6e64b543d535176f55fb76 to your computer and use it in GitHub Desktop.
Block Game, first time trying out py5 at PyCon 2024
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
""" | |
Simple block destroyer game by Chris Griffith | |
First time working with py5, this is pretty bad code, but was done in classroom | |
https://github.com/cdgriffith/ | |
Use S to start the game | |
Use A and D to move the blocker | |
Use P to pause the game | |
Use Q to quit the game | |
""" | |
import py5 | |
from random import randint | |
class Block: | |
def __init__(self, x, y, w, h, color): | |
self.location = py5.Py5Vector(x, y) | |
self.w = w | |
self.h = h | |
self.color = color | |
self.propulsion = py5.Py5Vector(0, 0) | |
self.dead = False | |
def collision(self, ball_location: py5.Py5Vector): | |
if self.dead: | |
return False | |
if ( | |
ball_location.x > self.location.x | |
and ball_location.x < self.location.x + self.w | |
and ball_location.y > self.location.y | |
and ball_location.y < self.location.y + self.h | |
): | |
return True | |
return False | |
def display(self): | |
if self.dead: | |
return | |
py5.fill(self.color) | |
py5.rect(self.location.x, self.location.y, self.w, self.h) | |
class Blocker: | |
def __init__(self): | |
self.location = py5.Py5Vector(py5.width / 2 - 20, py5.height - 60) | |
self.width = 100 | |
self.height = 20 | |
def collision(self, ball_location: py5.Py5Vector): | |
if ( | |
ball_location.x + 2 > self.location.x | |
and ball_location.x - 2 < self.location.x + self.width | |
and ball_location.y > self.location.y | |
and ball_location.y < self.location.y + self.height | |
): | |
return True | |
return False | |
def center(self): | |
return self.location.x + self.width / 2 | |
def display(self): | |
py5.fill(0, 255, 0) | |
py5.rect(self.location.x, self.location.y, self.width, self.height) | |
def setup(): | |
py5.size(800, 500, py5.P2D) | |
class Ball: | |
def __init__(self): | |
self.location = py5.Py5Vector(py5.width / 2, py5.height - 100) | |
self.propulsion = py5.Py5Vector(0, 5) | |
def display(self): | |
py5.fill(255, 0, 0) | |
py5.circle(self.location.x, self.location.y, 20) | |
def edge_hit(self): | |
global game_over | |
if self.location.x < 0 or self.location.x > py5.width: | |
self.propulsion.x = -self.propulsion.x | |
if self.location.y < 0: | |
self.propulsion.y = -self.propulsion.y | |
if self.location.y > py5.height: | |
game_over = True | |
py5.text_size(46) | |
py5.fill(0, 0, 0) | |
py5.text("YOU LOOSE!", py5.width / 2 - 150, py5.height - 200) | |
def key_event(key): | |
match key: | |
case "q" | "Q": | |
py5.exit_sketch() | |
case "a" | "A": | |
if not blocker or game_over: | |
return | |
if blocker.location.x > -80: | |
blocker.location.x -= 10 | |
case "d" | "D": | |
if not blocker or game_over: | |
return | |
if blocker.location.x < py5.width - 20: | |
blocker.location.x += 10 | |
case "s" | "S": | |
global started | |
started = True | |
case "p" | "P": | |
global paused, last_paused | |
if last_paused not in list(range(py5.frame_count - 10, py5.frame_count)): | |
last_paused = py5.frame_count | |
paused = not paused | |
blocks = [] | |
sc = randint(0, 255), randint(0, 255), randint(0, 255) | |
for row in range(9): | |
for col in range(9): | |
blocks.append( | |
Block( | |
row * 85 + 15, | |
col * 28, | |
75, | |
20, | |
py5.color(sc[0] + row * 10, sc[1] + col * 10, sc[2] + row * col * 10), | |
) | |
) | |
ball = None | |
blocker = None | |
dead_blocks = 0 | |
game_over = False | |
last_hit = 0 | |
started = False | |
paused = False | |
last_paused = 0 | |
def draw(): | |
global blocker, ball, dead_blocks, game_over, last_hit, started | |
if py5.is_key_pressed: | |
key_event(py5.key) | |
if not started: | |
py5.fill(0, 0, 0) | |
py5.text_size(46) | |
py5.text("Press 's' to start", py5.width / 2 - 200, py5.height - 200) | |
return | |
if paused: | |
py5.fill(0, 0, 0) | |
py5.text_size(46) | |
py5.text("Press 'p' to resume", py5.width / 2 - 200, py5.height - 200) | |
return | |
if game_over: | |
return | |
py5.background(255, 255, 255) | |
if not blocker: | |
blocker = Blocker() | |
if not ball: | |
ball = Ball() | |
ball.edge_hit() | |
ball.location += ball.propulsion | |
ball.display() | |
if blocker.collision(ball.location): | |
if last_hit not in list(range(py5.frame_count - 10, py5.frame_count)): | |
last_hit = py5.frame_count | |
ball.propulsion.y = -abs(ball.propulsion.y) | |
ball.propulsion.x = (ball.location.x - blocker.center()) / 10 | |
blocker.display() | |
for i, block in enumerate(blocks): | |
if block.collision(ball.location): | |
ball.propulsion.y = -ball.propulsion.y | |
if dead_blocks in (20, 40, 60): | |
ball.propulsion.x += -1 if ball.propulsion.x < 0 else 1 | |
ball.propulsion.y += -1 if ball.propulsion.y < 0 else 1 | |
block.dead = True | |
dead_blocks += 1 | |
block.display() | |
if dead_blocks >= len(blocks): | |
py5.fill(0, 0, 0) | |
py5.text_size(46) | |
py5.text("YOU WIN!", py5.width / 2 - 100, py5.height - 200) | |
ball.propulsion = py5.Py5Vector(0, 0) | |
game_over = True | |
if __name__ == "__main__": | |
py5.run_sketch() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment