From 3eb8af999160b06a5117afd317204dd912f29434 Mon Sep 17 00:00:00 2001 From: IM23a-bachmannj2 Date: Sun, 8 Dec 2024 11:04:04 +0100 Subject: [PATCH] gamegrid, falling, Tetrominos, collision and deleting rows --- game_manager.py | 34 +++++++++++++++++++++++++++++++++- main.py | 36 ++++++++++++++++++++++++++++++------ tetrominos.py | 20 +++++++++++++++++--- 3 files changed, 80 insertions(+), 10 deletions(-) diff --git a/game_manager.py b/game_manager.py index aeb29eb..2ebe3a8 100644 --- a/game_manager.py +++ b/game_manager.py @@ -18,4 +18,36 @@ class Grid(): self.cell_size - 2, self.cell_size - 2 ) - pygame.draw.rect(surface, color, cell_rect) \ No newline at end of file + pygame.draw.rect(surface, color, cell_rect) + + def add_tetromino(self, tetromino): + """Lock the tetromino into the grid.""" + for row_idx, row in enumerate(tetromino.shape): + for col_idx, cell in enumerate(row): + if cell: # Only lock non-empty cells + grid_x = tetromino.x + col_idx + grid_y = tetromino.y + row_idx + if 0 <= grid_y < self.rows and 0 <= grid_x < self.cols: + self.grid[grid_y][grid_x] = 1 + + def check_collision(self, shape, x, y): + """Check if the tetromino collides with the grid or boundaries.""" + for row_idx, row in enumerate(shape): + for col_idx, cell in enumerate(row): + if cell: # Only check cells that are part of the tetromino + grid_x = x + col_idx + grid_y = y + row_idx + + # Check bounds + if grid_x < 0 or grid_x >= self.cols or grid_y >= self.rows: + return True + + # Check if cell is already occupied + if grid_y >= 0 and self.grid[grid_y][grid_x] != 0: + return True + + def check_full_row(self): + """Check for and clear any full rows.""" + new_grid = [row for row in self.grid if not all(cell == 1 for cell in row)] + cleared_rows = len(self.grid) - len(new_grid) + self.grid = [[0] * self.cols for _ in range(cleared_rows)] + new_grid diff --git a/main.py b/main.py index 7d3b3f9..fb49e34 100644 --- a/main.py +++ b/main.py @@ -14,10 +14,12 @@ def main(): game_grid = Grid(rows, cols, cell_size) tetromino = Tetrominos(cols, cell_size) - # Timer for controlling the falling speed fall_timer = 0 fall_interval = 1000 // falling_speed # Falling interval in milliseconds + move_timer = 0 + move_interval = 100 + while True: screen.fill((0, 153, 255)) # Background color current_time = pygame.time.get_ticks() @@ -26,16 +28,38 @@ def main(): if event.type == pygame.QUIT: sys.exit() elif event.type == pygame.KEYDOWN: - if event.key == pygame.K_RIGHT: + if event.key == pygame.K_UP: + rotated_shape = [list(row) for row in zip(*tetromino.shape[::-1])] + if not game_grid.check_collision(rotated_shape, tetromino.x, tetromino.y): + tetromino.shape = rotated_shape # Apply rotation + + keys = pygame.key.get_pressed() + if keys[pygame.K_RIGHT]: + if current_time - move_timer > move_interval: # Ensure delay between movements + if not game_grid.check_collision(tetromino.shape, tetromino.x + 1, tetromino.y): tetromino.move(1, 0) # Move right - elif event.key == pygame.K_LEFT: + move_timer = current_time # Reset timer + elif keys[pygame.K_LEFT]: + if current_time - move_timer > move_interval: # Ensure delay between movements + if not game_grid.check_collision(tetromino.shape, tetromino.x - 1, tetromino.y): tetromino.move(-1, 0) # Move left - elif event.key == pygame.K_UP: - tetromino.rotate() # Rotate shape + move_timer = current_time # Reset timer # Handle automatic falling based on timer if current_time - fall_timer > fall_interval: - tetromino.move(0, 1) + if not game_grid.check_collision(tetromino.shape, tetromino.x, tetromino.y + 1): + tetromino.move(0, 1) # Move down + else: + # Collision detected, lock the tetromino in place + game_grid.add_tetromino(tetromino) + game_grid.check_full_row() + tetromino = Tetrominos(cols, cell_size) # Spawn a new tetromino + + # Check if game is over + if game_grid.check_collision(tetromino.shape, tetromino.x, tetromino.y): + print("Game Over") + sys.exit() + fall_timer = current_time # Draw the grid and tetromino diff --git a/tetrominos.py b/tetrominos.py index ee1faa0..d9dc1ab 100644 --- a/tetrominos.py +++ b/tetrominos.py @@ -1,6 +1,17 @@ import random import pygame +def set_color(): + yellow = (255, 255, 0) + violet = (204, 0, 204) + green = (0, 153, 0) + orange = (255, 153, 0) + light_blue = (0, 255, 255) + red = (255, 0, 0) + blue = (0, 0, 255) + colors = [yellow, violet, green, orange, light_blue, red, blue] + return colors + class Tetrominos: SHAPES = [ @@ -15,11 +26,14 @@ class Tetrominos: def __init__(self, cols, cell_size): self.cell_size = cell_size - self.shape = random.choice(self.SHAPES) # Randomly pick a shape - self.color = (random.randint(50, 255), random.randint(50, 255), random.randint(50, 255)) # Random color + self.shape_number = random.choice([1, 2, 3, 4, 5, 6, 7]) # Randomly pick a shape + self.shape = self.SHAPES[self.shape_number - 1] + self.colors = set_color() self.x = cols // 2 - len(self.shape[0]) // 2 # Center horizontally self.y = 0 # Start at the top + + def draw(self, screen): """Draw the tetromino on the screen.""" for row_idx, row in enumerate(self.shape): @@ -29,7 +43,7 @@ class Tetrominos: y = (self.y + row_idx) * self.cell_size + 1 pygame.draw.rect( screen, - self.color, + self.colors[self.shape_number - 1], pygame.Rect(x, y, self.cell_size - 2, self.cell_size - 2) )