Skip to content

Commit

Permalink
added dodgy square
Browse files Browse the repository at this point in the history
  • Loading branch information
Federico committed Jun 14, 2023
1 parent 49f5cdc commit 974f86a
Showing 1 changed file with 174 additions and 0 deletions.
174 changes: 174 additions & 0 deletions bonus_projects/dodgy_square/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
import pygame
from pygame.font import Font
from pygame.time import Clock
import random
import sys


class DodgySquare:
def __init__(self):
# Pygame
pygame.init()

# Screen
self.screen_width, self.screen_height = 600, 600
self.screen = pygame.display.set_mode((self.screen_width, self.screen_height))
pygame.display.set_caption("Dodgy Square")

# Colours
self.WHITE: tuple = (255, 255, 255)
self.BLACK: tuple = (0, 0, 0)
self.RED: tuple = (255, 99, 71)

# Font
self.font: Font = pygame.font.Font(None, 36)

# Player
self.player_size: int = 50
self.player_speed: int = self.player_size // 2
self.player_pos: list[int] = [self.screen_width // 2, self.screen_height - (2 * self.player_size)]

# Enemies
self.enemy_size: int = 50
self.enemy_pos: list[int] = [random.randint(0, self.screen_width - self.enemy_size), 0]
self.enemy_list = [self.enemy_pos]
self.enemy_speed: int = 3 # Low = slow, High = Fast
self.enemy_frequency: int = 30 # Low = Lots, High = Few

# Clock
self.clock: Clock = pygame.time.Clock()

# Game data
self.game_over: bool = False
self.score: int = 0
self.frame_count: int = 0
self.tick: float = 30

# Set up enemy speed and frequency
self.enemy_speed: int = 3
self.enemy_frequency: int = 30 # Number of frames between enemy creation

def create_enemy(self):
"""Creates a new enemy at a random position"""

enemy_pos = [random.randint(0, self.screen_width - self.enemy_size), 0]
self.enemy_list.append(enemy_pos)

# Function to update enemy positions
def update_enemy_positions(self):
"""Check whether it is time to create a new enemy and then does so"""

if self.frame_count % self.enemy_frequency == 0:
self.create_enemy()

# Give each enemy an id
for idx, enemy_pos in enumerate(self.enemy_list):
# Simulate gravity until off-screen
if 0 <= enemy_pos[1] < self.screen_height:
enemy_pos[1] += self.enemy_speed
else:
# When the enemy has passed
self.enemy_list.pop(idx)
self.score += 1
self.enemy_speed += 0.1

def detect_collision(self, player_pos: list[int], enemy_pos: list[int]) -> bool:
"""Collision detection logic for checking if squares are intercepting"""

px, py = player_pos
ex, ey = enemy_pos
if (px <= ex < (px + self.player_size)) or (ex <= px < (ex + self.enemy_size)):
if (py <= ey < (py + self.player_size)) or (ey <= py < (ey + self.enemy_size)):
return True
return False

# Game over text
def show_game_over(self):
"""Display game-over text"""

game_over_text = self.font.render("Game Over", True, self.WHITE)
self.screen.blit(game_over_text, (self.screen_width // 2 - 70, self.screen_height // 2 - 16))

# Replay the game
def replay_game(self):
"""Reset everything to its initial state"""

self.player_pos: list[int] = [self.screen_width // 2, self.screen_height - (2 * self.player_size)]
self.enemy_list = [self.enemy_pos]
self.enemy_speed: int = 3
self.score: int = 0
self.game_over: bool = False
self.frame_count: int = 0

def draw_character(self, color: tuple, position: list[int], size: int):
"""Draws a rectangle on the screen"""

pygame.draw.rect(self.screen, color, (position[0], position[1], size, size))

# Main game loop
def run(self):
"""Run the game"""

while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()

# Handle key events
if event.type == pygame.KEYDOWN:
match event.key:
case pygame.K_LEFT:
self.player_pos[0] -= self.player_speed
case pygame.K_RIGHT:
self.player_pos[0] += self.player_speed
case pygame.K_UP:
self.player_pos[1] -= self.player_speed
case pygame.K_DOWN:
self.player_pos[1] += self.player_speed
case pygame.K_r if self.game_over:
self.replay_game()

# Make sure the player stays on the screen
self.player_pos[0]: int = max(0, min(self.player_pos[0], self.screen_width - self.player_size))
self.player_pos[1]: int = max(0, min(self.player_pos[1], self.screen_height - self.player_size))

if not self.game_over:
self.update_enemy_positions()

# Check for collisions
for enemy_pos in self.enemy_list:
if self.detect_collision(self.player_pos, enemy_pos):
self.game_over = True
break

# Reset everything for the next frame
self.screen.fill(self.BLACK)

# Draw the player
self.draw_character(self.WHITE, self.player_pos, self.player_size)

# Draw the enemies
for enemy_pos in self.enemy_list:
self.draw_character(self.RED, enemy_pos, self.enemy_size)

# Display the score
score_text = self.font.render("Score: " + str(self.score), True, self.WHITE)
self.screen.blit(score_text, [10, 10])

# Increment the frame count
self.frame_count += 1
else:
self.show_game_over()

# Update the display
pygame.display.update()

# Frame rate
self.clock.tick(60)


# Run the game
if __name__ == '__main__':
game = DodgySquare()
game.run()

0 comments on commit 974f86a

Please sign in to comment.