diff --git a/README.md b/README.md index 173e360..c8fd9fd 100644 --- a/README.md +++ b/README.md @@ -37,8 +37,8 @@ This isn't just about coding; it's about building something I love from the grou ### **Step 2: Additional Game Features** 1. [x] **Next Tetromino Preview**: - [x] Show the upcoming Tetromino in a small box. -2. [ ] **Ghost Piece**: - - [ ] Display a transparent outline where the current Tetromino will land. +2. [x] **Ghost Piece**: + - [x] Display a transparent outline where the current Tetromino will land. 3. [x] **Pause and Resume**: - [x] Allow the game to pause (e.g., with the Escape key) and resume. 4. [ ] **Basic Leaderboard**: diff --git a/game/game.py b/game/game.py index 447cc88..3629f77 100644 --- a/game/game.py +++ b/game/game.py @@ -21,6 +21,7 @@ class Game: self.game_grid = Grid(rows, cols, cell_size) self.current_tetromino = Tetrominos(cols, cell_size) + self.ghost_tetromino = Tetrominos(cols, cell_size) self.next_tetromino = Tetrominos(cols, cell_size) self.hold_tetromino = None @@ -33,6 +34,10 @@ class Game: def run(self): """Main game loop.""" self.playing = True + if settings.gamestate == False: + self.game_grid = Grid(rows, cols, cell_size) + settings.gamestate = True + while self.playing: self.clock.tick(fps) self.handle_events() @@ -84,6 +89,8 @@ class Game: self.fall_timer = current_time + self.update_ghost_tetromino() + def draw(self): """Render the game elements.""" self.screen.fill((138, 138, 138)) @@ -93,6 +100,8 @@ class Game: self.game_grid.draw_grid(self.grid_surface) self.current_tetromino.draw(self.grid_surface) + self.ghost_tetromino.draw_ghost_tetromino(self.grid_surface) + # Draw next and hold previews self.next_surface.fill((0, 0, 0)) self.next_tetromino.draw_next_tetromino(self.next_surface) @@ -136,6 +145,14 @@ class Game: self.current_tetromino.y = 0 self.hold_used = True + def update_ghost_tetromino(self): + self.ghost_tetromino.shape = self.current_tetromino.shape + self.ghost_tetromino.x = self.current_tetromino.x + self.ghost_tetromino.y = self.current_tetromino.y + + while not self.game_grid.check_collision(self.ghost_tetromino.shape, self.ghost_tetromino.x, self.ghost_tetromino.y + 1): + self.ghost_tetromino.y += 1 + def show_game_over(self): """Handle game over screen.""" settings.gamestate = False diff --git a/game/game_manager.py b/game/game_manager.py index 1d74120..1880b43 100644 --- a/game/game_manager.py +++ b/game/game_manager.py @@ -1,4 +1,5 @@ import pygame +from game.tetrominos import set_color import game.settings as settings class Grid(): @@ -6,13 +7,30 @@ class Grid(): self.cell_size = cell_size self.rows = rows self.cols = cols + self.color = set_color() self.grid = [[0 for j in range(self.cols)] for k in range(self.rows)] def draw_grid(self, surface): for row in range(self.rows): for col in range(self.cols): cell_value = self.grid[row][col] - color = (0, 0, 0) if cell_value == 0 else (255, 0, 0) # Black for empty, red for filled + if cell_value == 0: + color = (0, 0, 0) + elif cell_value == 1: + color = self.color[0] + elif cell_value == 2: + color = self.color[1] + elif cell_value == 3: + color = self.color[2] + elif cell_value == 4: + color = self.color[3] + elif cell_value == 5: + color = self.color[4] + elif cell_value == 6: + color = self.color[5] + else: + color = self.color[6] + cell_rect = pygame.Rect( col * self.cell_size + 1, row * self.cell_size + 1, @@ -29,7 +47,7 @@ class Grid(): 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 + self.grid[grid_y][grid_x] = tetromino.shape_number def check_collision(self, shape, x, y): """Check if the tetromino collides with the grid or boundaries.""" @@ -49,11 +67,9 @@ class Grid(): 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)] + new_grid = [row for row in self.grid if not all(cell != 0 for cell in row)] cleared_rows = len(self.grid) - len(new_grid) self.grid = [[0] * self.cols for _ in range(cleared_rows)] + new_grid - if cleared_rows >= 4: - settings.game_score += 100 * cleared_rows * 2 - else: - settings.game_score += 100 * cleared_rows \ No newline at end of file + score_table = {1: 100, 2: 300, 3: 500, 4: 800} + settings.game_score += score_table.get(cleared_rows, 0) \ No newline at end of file diff --git a/game/menu.py b/game/menu.py index e48ecfd..0337b0a 100644 --- a/game/menu.py +++ b/game/menu.py @@ -1,5 +1,6 @@ import pygame as pg from game.settings import * +import game.settings as setting from game.util import draw_text import sys @@ -72,11 +73,11 @@ class GameMenu: self.screen.fill((0, 0, 0)) - if gamestate: + if setting.gamestate: draw_text(self.screen, "Game Paused", 50, width // 2, HEIGHT // 2 - 50, (255, 255, 255)) draw_text(self.screen, "Press ESC to Resume", 30, width // 2, HEIGHT // 2 + 10, (200, 200, 200)) else: - draw_text(self.screen, "Game Over", 50, WIDTH // 2, HEIGHT // 2 - 50, (255, 0, 0)) - draw_text(self.screen, "Press Enter to Restart", 30, WIDTH // 2, HEIGHT // 2 + 50, (200, 200, 200)) + draw_text(self.screen, "Game Over", 50, width // 2, HEIGHT // 2 - 50, (255, 0, 0)) + draw_text(self.screen, "Press Enter to Restart", 30, width // 2, HEIGHT // 2 + 50, (200, 200, 200)) pg.display.update() \ No newline at end of file diff --git a/game/tetrominos.py b/game/tetrominos.py index 4602bc8..e0e8703 100644 --- a/game/tetrominos.py +++ b/game/tetrominos.py @@ -30,7 +30,7 @@ class Tetrominos: 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 + self.y = 0 @@ -80,4 +80,16 @@ class Tetrominos: cell_size, cell_size ) - pygame.draw.rect(surface, self.colors[self.shape_number - 1], cell_rect) # Red color for tetromino \ No newline at end of file + pygame.draw.rect(surface, self.colors[self.shape_number - 1], cell_rect) + + def draw_ghost_tetromino(self, screen): + """Draw the tetromino on the screen.""" + for row_idx, row in enumerate(self.shape): + for col_idx, cell in enumerate(row): + if cell: + x = (self.x + col_idx) * self.cell_size + 1 + y = (self.y + row_idx) * self.cell_size + 1 + rect = pygame.Rect(x, y, self.cell_size - 2, self.cell_size - 2) + pygame.draw.rect(screen, (61, 61, 61), rect) + pygame.draw.rect(screen, (255, 255, 255), rect, 1) +