diff options
| author | omagdy7 <omar.professional8777@gmail.com> | 2023-05-08 23:02:03 +0300 |
|---|---|---|
| committer | omagdy7 <omar.professional8777@gmail.com> | 2023-05-08 23:02:03 +0300 |
| commit | aaf0194f9b5d93bd6612bc0b419c4b8f89b4aa21 (patch) | |
| tree | 5c8950e0cb7adb4782e35bb26a0aa8242ea71398 | |
| parent | 241e41892a10d3913c63935a8f9e14306e8a73cd (diff) | |
| download | Macpan-aaf0194f9b5d93bd6612bc0b419c4b8f89b4aa21.tar.xz Macpan-aaf0194f9b5d93bd6612bc0b419c4b8f89b4aa21.zip | |
Added a simple Wining screen when the user collects all the food
| -rw-r--r-- | src/clyde.py | 10 | ||||
| -rw-r--r-- | src/game.py | 77 | ||||
| -rw-r--r-- | src/game_state.py | 4 | ||||
| -rw-r--r-- | src/ghost.py | 19 | ||||
| -rw-r--r-- | src/inky.py | 6 | ||||
| -rw-r--r-- | src/map.py | 2 | ||||
| -rw-r--r-- | src/pinky.py | 9 | ||||
| -rw-r--r-- | src/player.py | 18 |
8 files changed, 118 insertions, 27 deletions
diff --git a/src/clyde.py b/src/clyde.py index e48a439..755eafd 100644 --- a/src/clyde.py +++ b/src/clyde.py @@ -19,7 +19,11 @@ class Clyde(Ghost): @override def get_default_tile(self): - return (27 * 30 + 15, 2 * 30 + 15) + return (2 * 30 + 15, 30 * 30 + 15) + + @override + def get_intial_tile(self): + return (14 * 30 + 15, 12 * 30 + 15) @override def get_next_move(self, game_state, screen): @@ -45,6 +49,10 @@ class Clyde(Ghost): if game_state.pacman.powerup is False and self.mode == MODE.FRIGHETENED: self.mode = MODE.CHASING + if settings.debug: + pygame.draw.line(screen, self.color, (game_state.pacman.x, game_state.pacman.y), + (self.x, self.y), 1) + for i in range(len(dx)): nx = self.x + dx[i] * self.speed ny = self.y + dy[i] * self.speed diff --git a/src/game.py b/src/game.py index 4787c00..a7efb67 100644 --- a/src/game.py +++ b/src/game.py @@ -11,16 +11,66 @@ class Game(): self.settings = settings def show_gameover_screen(self, screen, game_state, sprites): - font = pygame.font.SysFont(None, 48) + font = pygame.font.SysFont(None, 64) # Render the "Game Over" text to a surface - game_over_text = font.render( - "Game Over. Press R to try again.", True, (255, 255, 255)) + game_over_text_1 = font.render( + "Game Over", True, (255, 255, 255)) + game_over_text_2 = font.render( + "Press R to try again or Q to quit.", True, (255, 255, 255)) # Blit the "Game Over" text onto the screen - text_rect = game_over_text.get_rect( + text_rect_1 = game_over_text_1.get_rect( + center=(WIDTH/2, HEIGHT/2 - 75)) + text_rect_2 = game_over_text_2.get_rect( center=(WIDTH/2, HEIGHT/2)) - screen.blit(game_over_text, text_rect) + + screen.blit(game_over_text_1, text_rect_1) + screen.blit(game_over_text_2, text_rect_2) + + # Update the display + pygame.display.flip() + + quit_game = False # Initialize the flag variable + while not quit_game: + for event in pygame.event.get(): + if event.type == pygame.KEYDOWN and event.key == pygame.K_r: + # Reset the game and start again + # Add your own code here to reset the game state + self.reset_game(game_state, sprites) + game_state.game_over = False + quit_game = True # Set the flag to True to break out of both loops + break + elif event.type == pygame.KEYDOWN and event.key == pygame.K_q: + game_state.game_over = True + quit_game = True + break + elif event.type == pygame.QUIT: + game_state.game_over = True + quit_game = True # Set the flag to True to break out of both loops + break + + def show_wining_screen(self, screen, game_state, sprites): + font = pygame.font.SysFont(None, 64) + + # Render the "Game Over" text to a surface + wining_text_1 = font.render( + "Congratulation You Won!!", True, (255, 255, 255)) + wining_text_2 = font.render( + "Press R to play again or Q to quit", True, (255, 255, 255)) + + text_rect_1 = wining_text_1.get_rect( + center=(WIDTH/2, HEIGHT/2 - 75)) + text_rect_2 = wining_text_2.get_rect( + center=(WIDTH/2, HEIGHT/2)) + + # Blit the "Game Over" text onto the screen + text_rect_1 = wining_text_1.get_rect( + center=(WIDTH/2, HEIGHT/2)) + text_rect_2 = wining_text_2.get_rect( + center=(WIDTH/2, HEIGHT/2 + 100)) + screen.blit(wining_text_1, text_rect_1) + screen.blit(wining_text_2, text_rect_2) # Update the display pygame.display.flip() @@ -35,6 +85,10 @@ class Game(): game_state.game_over = False quit_game = True # Set the flag to True to break out of both loops break + elif event.type == pygame.KEYDOWN and event.key == pygame.K_q: + game_state.game_over = True + quit_game = True + break elif event.type == pygame.QUIT: game_state.game_over = True quit_game = True # Set the flag to True to break out of both loops @@ -62,7 +116,7 @@ class Game(): inky_sprite = pygame.image.load('../assets/inky.png').convert_alpha() sprites = [sprite_sheet, blinky_sprite, - pinky_sprite, clyde_sprite, inky_sprite] + pinky_sprite, inky_sprite, clyde_sprite] # Set the timer to trigger after 10,000 milliseconds (10 seconds) timer_event = pygame.USEREVENT + 1 @@ -155,7 +209,7 @@ class Game(): # if tx and ty doesn't lead to colliding change the current # dx and dy to them and other wise # let pacman move in his previous direction - if game_state.pacman.check_collision(game_state.map, tx, ty, TILE_WIDTH, TILE_HEIGHT): + if game_state.pacman.check_collision(game_state, tx, ty, TILE_WIDTH, TILE_HEIGHT): dx = tx dy = ty @@ -168,10 +222,10 @@ class Game(): elif dy > 0: game_state.pacman.direction = DIRECTION.DOWN - if game_state.pacman.check_collision(game_state.map, dx, dy, TILE_WIDTH, TILE_HEIGHT): + if game_state.pacman.check_collision(game_state, dx, dy, TILE_WIDTH, TILE_HEIGHT): game_state.pacman.x += dx game_state.pacman.y += dy - game_state.pacman.x %= 900 + game_state.pacman.x %= 900 # logic for portal # Move ghosts game_state.blinky.move(game_state, screen) @@ -189,6 +243,10 @@ class Game(): game_state.inky.draw(screen, game_state.pacman.powerup, counter) game_state.clyde.draw(screen, game_state.pacman.powerup, counter) + if game_state.food == 246: + self.show_wining_screen(screen, game_state, sprites) + + if not game_state.is_pacman_alive: self.show_gameover_screen( screen, game_state, sprites) @@ -198,4 +256,5 @@ class Game(): pygame.display.flip() # Quit Pygame + print(game_state.score) pygame.quit() diff --git a/src/game_state.py b/src/game_state.py index f722873..5ed98c0 100644 --- a/src/game_state.py +++ b/src/game_state.py @@ -26,7 +26,9 @@ class GameState(): self.clyde = Clyde(sprites[4], 14 * TILE_WIDTH + 15, 12 * TILE_HEIGHT + 15) self.map = Map.Map() + self.food = 0 self.game_over = False + self.score = 0 self.is_pacman_alive = True def reset(self, sprites): @@ -40,7 +42,9 @@ class GameState(): self.clyde = Clyde(sprites[4], 14 * TILE_WIDTH + 15, 12 * TILE_HEIGHT + 15) self.map = Map.Map() + self.food = 0 self.game_over = False self.is_pacman_alive = True + self.score = 0 timer_event = pygame.USEREVENT + 1 pygame.time.set_timer(timer_event, 1000 * 10, 1) diff --git a/src/ghost.py b/src/ghost.py index fc3adfe..c05eb1b 100644 --- a/src/ghost.py +++ b/src/ghost.py @@ -1,4 +1,5 @@ import pygame +import time import random import math from util import get_sprites @@ -34,7 +35,6 @@ class Ghost(): return abs(next_pos[0] - tx) + abs(next_pos[1] - ty) # checks if the current position of pacman is either a dot, big dot or free - def is_valid(self, maze, x, y): if x >= 0 and x < 30: # Necessary to make portals work is_dot = maze[y][x] == Map.D @@ -46,6 +46,9 @@ class Ghost(): def get_default_tile(self): return (75, 75) + def get_intial_tile(self): + return (12 * 30 + 15, 12 * 30 + 15) + # checks collision with pacman and obstacles returns false if there is # a collision and true otherwise @@ -63,6 +66,17 @@ class Ghost(): return True + def check_pacman_collision(self, game_state): + if game_state.pacman.powerup and abs(game_state.pacman.x - self.x) <= 30 and abs(game_state.pacman.y - self.y) <= 30: + initial_position = self.get_intial_tile() + time.sleep(1) + game_state.score += 200 + self.x = initial_position[0] + self.y = initial_position[1] + elif not game_state.pacman.powerup and abs(game_state.pacman.x - self.x) <= 30 and abs(game_state.pacman.y - self.y) <= 30: + if abs(game_state.pacman.x - self.x) <= 30 and abs(game_state.pacman.y - self.y) <= 30: + game_state.is_pacman_alive = False + def get_next_move(self, game_state, screen): default_tile = self.get_default_tile() @@ -110,8 +124,7 @@ class Ghost(): return min_idx def move(self, game_state, screen): - if abs(game_state.pacman.x - self.x) <= 15 and abs(game_state.pacman.y - self.y) <= 15: - game_state.is_pacman_alive = False + self.check_pacman_collision(game_state) min_idx = self.get_next_move(game_state, screen) new_dx = dx[min_idx] * self.speed new_dy = dy[min_idx] * self.speed diff --git a/src/inky.py b/src/inky.py index 840b60b..2b48ede 100644 --- a/src/inky.py +++ b/src/inky.py @@ -40,7 +40,11 @@ class Inky(Ghost): @override def get_default_tile(self): - return (2 * 30 + 15, 30 * 30 + 15) + return (27 * 30 + 15, 2 * 30 + 15) + + @override + def get_intial_tile(self): + return (13 * 30 + 15, 12 * 30 + 15) def get_target(self, inter_tile, blinky): target = (max(inter_tile[0] - (blinky.x - inter_tile[0]) % 900, 0), @@ -118,4 +118,4 @@ class Map(): for j in range(cols): pos = (j * self.line_horizontal, i * self.line_vertical) self.draw_wall(screen, self.maze[i][j], pos) - # pygame.draw.rect(screen, 'red', (pos[0], pos[1], 32, 32), 2) + diff --git a/src/pinky.py b/src/pinky.py index be9e5dc..5f58f54 100644 --- a/src/pinky.py +++ b/src/pinky.py @@ -43,6 +43,10 @@ class Pinky(Ghost): return (27 * 30 + 15, 30 * 30 + 15) @override + def get_intial_tile(self): + return (11 * 30 + 15, 12 * 30 + 15) + + @override def get_next_move(self, game_state, screen): default_tile = self.get_default_tile() @@ -65,11 +69,6 @@ class Pinky(Ghost): rand_pos = (0, 0) new_target = self.get_four_tiles_ahead_of_pacman(game_state.pacman) - if settings.debug: - pygame.draw.circle(screen, self.color, - (new_target[0], new_target[1]), 15) - pygame.draw.circle(screen, self.color, - default_tile, 15) if game_state.pacman.powerup: self.mode = MODE.FRIGHETENED diff --git a/src/player.py b/src/player.py index 97d2ea5..92c4a84 100644 --- a/src/player.py +++ b/src/player.py @@ -17,22 +17,26 @@ class Player(): self.timer = None # checks if the current position of pacman is either a dot, big dot or free - def is_valid(self, maze, x, y): + def is_valid(self, game_state, x, y): if x >= 0 and x < 30: - is_dot = maze.maze[y][x] == Map.D - is_big_dot = maze.maze[y][x] == Map.BD - is_free = maze.maze[y][x] == 0 + is_dot = game_state.map.maze[y][x] == Map.D + is_big_dot = game_state.map.maze[y][x] == Map.BD + is_free = game_state.map.maze[y][x] == 0 if is_dot or is_big_dot: - maze.maze[y][x] = 0 + game_state.map.maze[y][x] = 0 + game_state.food += 1 + if is_dot: + game_state.score += 10 if is_big_dot: self.powerup = True self.timer = Timer(5 * 1000) + game_state.score += 50 return (is_dot or is_free or is_big_dot) return True # checks collision with pacman and obstacles returns false # if there is a collision and true otherwise - def check_collision(self, maze, dx, dy, tile_width, tile_height): + def check_collision(self, game_state, dx, dy, tile_width, tile_height): direct_x = [1, 0, -1, 0, 1, 1, -1, -1] direct_y = [0, 1, 0, -1, -1, 1, -1, 1] @@ -43,7 +47,7 @@ class Player(): ny = (self.y + ddy) + direct_y[i] * 14 x = nx // tile_width y = ny // tile_height - if not self.is_valid(maze, x, y): + if not self.is_valid(game_state, x, y): return False return True |
