diff options
| author | Omar Magdy <99906646+omagdy7@users.noreply.github.com> | 2023-04-16 17:50:36 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-16 17:50:36 +0200 |
| commit | b673be7fc9e94a5a8245797be6a62547c4efa579 (patch) | |
| tree | 5983f58f8512ca7386932a1549302d3e9fd7f3ba | |
| parent | aa2162d1c2c873161b08efa3affff8ac73e27824 (diff) | |
| parent | 3634fcc4f9f62d40ea03ba890a3290e05ed20ed8 (diff) | |
| download | Macpan-b673be7fc9e94a5a8245797be6a62547c4efa579.tar.xz Macpan-b673be7fc9e94a5a8245797be6a62547c4efa579.zip | |
Merge pull request #4 from omagdy7/Ghost
Added Ghosts with A* implementation
| -rw-r--r-- | src/Game.py | 22 | ||||
| -rw-r--r-- | src/Ghost.py | 95 | ||||
| -rw-r--r-- | src/Player.py | 2 | ||||
| -rw-r--r-- | src/map.py | 3 |
4 files changed, 111 insertions, 11 deletions
diff --git a/src/Game.py b/src/Game.py index 58b8987..e4784c9 100644 --- a/src/Game.py +++ b/src/Game.py @@ -1,5 +1,6 @@ from pygame.mouse import get_pressed import Player +import Ghost from Direction import DIRECTION import settings as Settings import map as Map @@ -24,6 +25,10 @@ class Game(): '../assets/pacman_left_sprite.png').convert_alpha() player = Player.Player(sprite_sheet) + blinky = Ghost.Ghost("red", 75, 75) + pinky = Ghost.Ghost("pink", 27 * 30, 30 * 30 + 15) + inky = Ghost.Ghost("orange", 75, 30 * 30 + 15) + clyde = Ghost.Ghost("cyan", 27 * 30 + 15, 75) # Set the pacman velocity dx = 0 @@ -41,6 +46,8 @@ class Game(): grid_x = Settings.settings.width // len(maze.maze[0]) grid_y = Settings.settings.height // len(maze.maze) + print(grid_x, grid_y) + # Checks collision with walls # checks if the current position of pacman is either a dot, big dot or free @@ -48,6 +55,8 @@ class Game(): is_dot = maze.maze[y][x] == Map.D is_big_dot = maze.maze[y][x] == Map.BD is_free = maze.maze[y][x] == 0 + if is_dot or is_big_dot: + maze.maze[y][x] = 0 return (is_dot or is_free or is_big_dot) @@ -66,11 +75,6 @@ class Game(): return True - - - - - # Main game loop running = True @@ -148,8 +152,16 @@ class Game(): player.y += dy + blinky.move(maze.maze, (player.x, player.y)) + pinky.move(maze.maze, (player.x, player.y)) + inky.move(maze.maze, (player.x, player.y)) + clyde.move(maze.maze, (player.x, player.y)) maze.draw_map(screen) player.draw(screen, counter) + blinky.draw(screen) + pinky.draw(screen) + inky.draw(screen) + clyde.draw(screen) # Update the screen pygame.display.flip() diff --git a/src/Ghost.py b/src/Ghost.py index 33086a1..d4bc683 100644 --- a/src/Ghost.py +++ b/src/Ghost.py @@ -1,7 +1,94 @@ +import pygame +import math +from Direction import DIRECTION +import map as Map + class Ghost(): - def __init__(self): - self.x = None - self.y = None + def __init__(self, color, x, y): + self.x = x + self.y = y + self.color = color + self.last_move = 3 + self.speed = 3 + + def heuristic(self, pacman_pos, next_pos): + return abs(next_pos[0] - pacman_pos[0]) + abs(next_pos[1] - pacman_pos[1]) + + + + + # checks if the current position of pacman is either a dot, big dot or free + def is_valid(self, maze, x, y): + is_dot = maze[y][x] == Map.D + is_big_dot = maze[y][x] == Map.BD + is_free = maze[y][x] == 0 + return (is_dot or is_free or is_big_dot) + + + # checks collision with pacman and obstacles returns false if there is a collision and true otherwise + def check_collision(self, nx, ny, gx, gy, maze): + direct_x = [1, 0, -1, 0, 1, 1, -1, -1] + direct_y = [0, 1, 0, -1, -1, 1, -1, 1] + + + for i in range(len(direct_x)): + px = nx + direct_x[i] * 14 + py = ny + direct_y[i] * 14 + x = px // gx + y = py // gy + if not self.is_valid(maze, x, y): + return False + + return True + + + def get_next_move(self, pacman_pos, maze): + dx = [1, 0, -1, 0] + dy = [0, 1, 0, -1] + + ret = len(dx) * [math.inf] + + forbidden = 0 + + if self.last_move == 0: + forbidden = 2 + if self.last_move == 1: + forbidden = 3 + if self.last_move == 2: + forbidden = 0 + if self.last_move == 3: + forbidden = 1 + + + for i in range(len(dx)): + if i != forbidden: + nx = self.x + dx[i] * self.speed + ny = self.y + dy[i] * self.speed + if self.check_collision(nx, ny, 30, 30, maze): + ret[i] = self.heuristic((nx, ny), pacman_pos) + + min_idx = ret.index(min(ret)) + return min_idx + + + + + + + + def move(self, maze, player_pos): + min_idx = self.get_next_move(player_pos, maze) + dx = [1, 0, -1, 0] + dy = [0, 1, 0, -1] + new_dx = dx[min_idx] * self.speed + new_dy = dy[min_idx] * self.speed + self.x += new_dx + self.y += new_dy + self.last_move = min_idx + + def draw(self, screen): + radius = 30 // 2 + pos = (self.x , self.y) + pygame.draw.circle(screen, self.color, pos, radius) - # def heuristic(self): diff --git a/src/Player.py b/src/Player.py index eac2d62..430a974 100644 --- a/src/Player.py +++ b/src/Player.py @@ -33,7 +33,7 @@ class Player(): self.x = 30 * 17 - 15 self.y = 30 * 25 - 15 self.sprite = get_sprites(sprite_sheet) - self.speed = 5 + self.speed = 6 self.direction = DIRECTION.LEFT def draw(self, screen, counter): @@ -12,6 +12,7 @@ TL = 32 BL = 64 BR = 128 G = 256 +P = 512 PI = math.pi @@ -34,7 +35,7 @@ class Map(): [V, 0, 0, 0, 0, 0, V, D, V, V, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, V, V, D, V, 0, 0, 0, 0, 0, V], [BR, 0, 0, 0, 0, 0, V, D, V, V, 0, TL, H, H, G, G, H, H, TR, 0, V, V, D, V, 0, 0, 0, 0, 0, BL], [H, H, H, H, H, H, BR, D, BL, BR, 0, V, 0, 0, 0, 0, 0, 0, V, 0, BL, BR, D, BL, H, H, H, H, H, H], - [0, 0, 0, 0, 0, 0, 0, D, 0, 0, 0, V, 0, 0, 0, 0, 0, 0, V, 0, 0, 0, D, 0, 0, 0, 0, 0, 0, 0], + [P, 0, 0, 0, 0, 0, 0, D, 0, 0, 0, V, 0, 0, 0, 0, 0, 0, V, 0, 0, 0, D, 0, 0, 0, 0, 0, 0, P], [H, H, H, H, H, H, TR, D, TL, TR, 0, V, 0, 0, 0, 0, 0, 0, V, 0, TL, TR, D, TL, H, H, H, H, H, H], [TR, 0, 0, 0, 0, 0, V, D, V, V, 0, BL, H, H, H, H, H, H, BR, 0, V, V, D, V, 0, 0, 0, 0, 0, TL], [V, 0, 0, 0, 0, 0, V, D, V, V, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, V, V, D, V, 0, 0, 0, 0, 0, V], |
