From d6d3779465bffd2b2ed237ac13959aff7fc4ae9f Mon Sep 17 00:00:00 2001 From: omagdy7 Date: Sat, 15 Apr 2023 22:13:10 +0200 Subject: Fixed collision between pacman and obstacles --- src/Game.py | 117 ++++++++++++++++++++++++++++++++++++++++---------------- src/Player.py | 34 +++++++++------- src/macpan.py | 1 - src/map.py | 84 ++++++++++++++++++++-------------------- src/settings.py | 2 +- 5 files changed, 148 insertions(+), 90 deletions(-) diff --git a/src/Game.py b/src/Game.py index 9d93786..58b8987 100644 --- a/src/Game.py +++ b/src/Game.py @@ -1,8 +1,11 @@ +from pygame.mouse import get_pressed import Player from Direction import DIRECTION import settings as Settings import map as Map import pygame +import math + class Game(): def __init__(self): @@ -13,14 +16,16 @@ class Game(): pygame.init() # Set the dimensions of the window - screen = pygame.display.set_mode((Settings.settings.width, Settings.settings.height)) + screen = pygame.display.set_mode( + (Settings.settings.width, Settings.settings.height)) # Sprite sheet for pacman - sprite_sheet = pygame.image.load('../assets/pacman_left_sprite.png').convert_alpha(); + sprite_sheet = pygame.image.load( + '../assets/pacman_left_sprite.png').convert_alpha() player = Player.Player(sprite_sheet) - # Set the circle's velocity + # Set the pacman velocity dx = 0 dy = 0 @@ -29,32 +34,46 @@ class Game(): clock = pygame.time.Clock() - sprite_width, sprite_height = 32, 32 + maze = Map.Map() + + # length of the map grid size + grid_x = Settings.settings.width // len(maze.maze[0]) + grid_y = Settings.settings.height // len(maze.maze) - map = Map.Map() + # Checks collision with walls - grid_x = Settings.settings.width // len(map.maze[0]) - grid_y = (Settings.settings.height - 50) // len(map.maze) + # checks if the current position of pacman is either a dot, big dot or free + def is_valid(x, y): + is_dot = maze.maze[y][x] == Map.D + is_big_dot = maze.maze[y][x] == Map.BD + is_free = maze.maze[y][x] == 0 + return (is_dot or is_free or is_big_dot) - # Checks collision with walls + # checks collision with pacman and obstacles returns false if there is a collision and true otherwise def check_collision(dx, dy): - print(grid_x, grid_y) - x = int((player.x + dx) / grid_x) - y = int((player.y + dy) / grid_y) - print(x, y) - print(map.maze[x][y]) - is_dot = map.maze[x][y] == Map.D - is_big_dot = map.maze[x][y] == Map.BD - is_free = map.maze[x][y] == 0 - return not (is_dot or is_free or is_big_dot) + 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)): + nx = (player.x + dx) + direct_x[i] * 14 + ny = (player.y + dy) + direct_y[i] * 14 + x = nx // grid_x + y = ny // grid_y + if not is_valid(x, y): + return False + + return True + + + + # Main game loop running = True - while running: # setting game fps clock.tick(Settings.settings.fps) @@ -65,6 +84,12 @@ class Game(): else: counter = 0 + screen.fill((0, 0, 0)) # Clear the screen + + # Temporary values for delta_x and delta_y in the position of pacman + tx = dx + ty = dy + # Handling events for event in pygame.event.get(): if event.type == pygame.QUIT: @@ -73,35 +98,61 @@ class Game(): # Move the circle based on the pressed key if event.key == pygame.K_w: player.direction = DIRECTION.UP - dy = -player.speed - dx = 0 # Necssarry to move only horizontal or vertical + ty = -player.speed + tx = 0 # Necssarry to move only horizontal or vertical elif event.key == pygame.K_s: player.direction = DIRECTION.DOWN - dy = player.speed - dx = 0 # Necssarry to move only horizontal or vertical + ty = player.speed + tx = 0 # Necssarry to move only horizontal or vertical elif event.key == pygame.K_a: player.direction = DIRECTION.LEFT - dx = -player.speed - dy = 0 # Necssarry to move only horizontal or vertical + tx = -player.speed + ty = 0 # Necssarry to move only horizontal or vertical elif event.key == pygame.K_d: player.direction = DIRECTION.RIGHT - dx = player.speed - dy = 0 # Necssarry to move only horizontal or vertical - - - # Update the circle's position and checking for collisions - if not check_collision(dx, dy): + tx = player.speed + ty = 0 # Necssarry to move only horizontal or vertical + + keys = pygame.key.get_pressed() + if keys[pygame.K_w]: + ty = -player.speed + tx = 0 + elif keys[pygame.K_s]: + ty = player.speed + tx = 0 + elif keys[pygame.K_a]: + tx = -player.speed + ty = 0 + elif keys[pygame.K_d]: + tx = player.speed + ty = 0 + + + # 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 check_collision(tx, ty): + dx = tx + dy = ty + + if dx < 0: + player.direction = DIRECTION.LEFT + elif dx > 0: + player.direction = DIRECTION.RIGHT + elif dy < 0: + player.direction = DIRECTION.UP + elif dy > 0: + player.direction = DIRECTION.DOWN + + if check_collision(dx, dy): player.x += dx player.y += dy - screen.fill((0, 0, 0)) # Clear the screen - map.draw_map(screen) + maze.draw_map(screen) player.draw(screen, counter) # Update the screen pygame.display.flip() - # Quit Pygame pygame.quit() diff --git a/src/Player.py b/src/Player.py index e0128d9..76dfe19 100644 --- a/src/Player.py +++ b/src/Player.py @@ -1,7 +1,6 @@ from typing import List from Direction import DIRECTION import pygame -import settings as Settings def get_sprites(sprite_sheet) -> List: @@ -15,12 +14,15 @@ def get_sprites(sprite_sheet) -> List: for col in range(columns): x = col * sprite_width y = row * sprite_height - - # Create a new surface for the current sprite and blit it from the sprite sheet onto this new surface - new_sprite_surface = pygame.Surface((sprite_width, sprite_height), pygame.SRCALPHA) - new_sprite_surface.blit(sprite_sheet, (0, 0), (x, y, x + sprite_width, y +sprite_height)) - # Add this new surface to our list of sprites + # Create a new surface for the current sprite and blit it from the + # sprite sheet onto this new surface + new_sprite_surface = pygame.Surface( + (sprite_width, sprite_height), pygame.SRCALPHA) + new_sprite_surface.blit( + sprite_sheet, (0, 0), (x, y, x + sprite_width, y + sprite_height)) + + # Add this new surface to our list of sprites sprites.append(new_sprite_surface) return sprites @@ -28,20 +30,24 @@ def get_sprites(sprite_sheet) -> List: class Player(): def __init__(self, sprite_sheet): - self.x = 450 - self.y = 663 + self.x = 75 + self.y = 75 self.sprite = get_sprites(sprite_sheet) - self.speed = 10 + self.speed = 5 self.direction = DIRECTION.LEFT def draw(self, screen, counter): - pos = (self.x, self.y) + radius = 30 // 2 + pos = (self.x - radius , self.y - radius) + # pygame.draw.circle(screen, 'green', pos, radius) if self.direction == DIRECTION.UP: - screen.blit(pygame.transform.rotate(self.sprite[counter // 5], 270), pos) + screen.blit(pygame.transform.rotate( + self.sprite[counter // 5], 270), pos) elif self.direction == DIRECTION.DOWN: - screen.blit(pygame.transform.rotate(self.sprite[counter // 5], 90), pos) + screen.blit(pygame.transform.rotate( + self.sprite[counter // 5], 90), pos) elif self.direction == DIRECTION.RIGHT: - screen.blit(pygame.transform.flip(self.sprite[counter // 5], True, False), pos) + screen.blit(pygame.transform.flip( + self.sprite[counter // 5], True, False), pos) elif self.direction == DIRECTION.LEFT: screen.blit(self.sprite[counter // 5], pos) - diff --git a/src/macpan.py b/src/macpan.py index 93b81b3..a96a5fc 100644 --- a/src/macpan.py +++ b/src/macpan.py @@ -3,4 +3,3 @@ import Game if __name__ == "__main__": game = Game.Game() game.init() - diff --git a/src/map.py b/src/map.py index e05fc2f..9248241 100644 --- a/src/map.py +++ b/src/map.py @@ -3,7 +3,6 @@ import math import settings as Settings - H = 1 V = 2 D = 4 @@ -20,7 +19,7 @@ PI = math.pi class Map(): def __init__(self): self.maze = [ - [TL, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, TR], + [TL, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H,H, H, H, H, H, H, H, H, H, H, H, H, H, TR], [V, TL, H, H, H, H, H, H, H, H, H, H, H, H, TR, TL, H, H, H, H, H, H, H, H, H, H, H, H, TR, V], [V, V, D, D, D, D, D, D, D, D, D, D, D, D, V, V, D, D, D, D, D, D, D, D, D, D, D, D, V, V], [V, V, D, TL, H, H, TR, D, TL, H, H, H, TR, D, V, V, D, TL, H, H, H, TR, D, TL, H, H, TR, D, V, V], @@ -53,55 +52,68 @@ class Map(): [V, V, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, V, V], [V, BL, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, BR, V], [BL, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, BR] - ] - self.dot_color = (255, 255, 255) # white + ] + self.dot_color = (255, 255, 255) # white self.small_dot_radius = 4 self.big_dot_radius = 8 - self.line_color = (0, 0, 255) # Blue + self.line_color = (0, 0, 255) # Blue self.line_vertical = Settings.settings.height // len(self.maze) self.line_horizontal = Settings.settings.width // len(self.maze[0]) - self.line_stroke = 3 + self.line_stroke = 1 def consturct_map(self): pass - - def draw_wall(self, screen, flag , pos): + def draw_wall(self, screen, flag, pos): if flag & V: pos1 = (pos[0] + self.line_vertical * 0.5, pos[1]) pos2 = (pos1[0], pos1[1] + self.line_horizontal) - pygame.draw.line(screen, self.line_color, pos1, pos2, self.line_stroke) + pygame.draw.line(screen, self.line_color, + pos1, pos2, self.line_stroke) if flag & H: pos1 = (pos[0], pos[1] + self.line_vertical * 0.5) pos2 = (pos1[0] + self.line_horizontal, pos1[1]) - pygame.draw.line(screen, self.line_color, pos1, pos2, self.line_stroke) + pygame.draw.line(screen, self.line_color, + pos1, pos2, self.line_stroke) if flag & D: - pos1 = (pos[0] + self.line_vertical * 0.5, pos[1] + self.line_horizontal * 0.5) - pygame.draw.circle(screen, self.dot_color, pos1, self.small_dot_radius) + pos1 = (pos[0] + self.line_vertical * 0.5, + pos[1] + self.line_horizontal * 0.5) + pygame.draw.circle(screen, self.dot_color, + pos1, self.small_dot_radius) if flag & BD: - pos1 = (pos[0] + self.line_vertical * 0.5, pos[1] + self.line_horizontal * 0.5) - pygame.draw.circle(screen, self.dot_color, pos1, self.big_dot_radius) + pos1 = (pos[0] + self.line_vertical * 0.5, + pos[1] + self.line_horizontal * 0.5) + pygame.draw.circle(screen, self.dot_color, + pos1, self.big_dot_radius) if flag & TR: - pos1 = (pos[0] - self.line_vertical * 0.5, pos[1] + self.line_horizontal * 0.5) - arc_rect = pygame.Rect(pos1[0], pos1[1], self.line_vertical, self.line_horizontal) - pygame.draw.arc(screen, self.line_color, arc_rect, 0, PI / 2, self.line_stroke) + pos1 = (pos[0] - self.line_vertical * 0.5, + pos[1] + self.line_horizontal * 0.5) + arc_rect = pygame.Rect( + pos1[0], pos1[1], self.line_vertical, self.line_horizontal) + pygame.draw.arc(screen, self.line_color, arc_rect, + 0, PI / 2, self.line_stroke) if flag & TL: - pos1 = (pos[0] + self.line_vertical * 0.5, pos[1] + self.line_horizontal * 0.5) - arc_rect = pygame.Rect(pos1[0], pos1[1], self.line_vertical, self.line_horizontal) - pygame.draw.arc(screen, self.line_color, arc_rect, PI / 2, PI, self.line_stroke) + pos1 = (pos[0] + self.line_vertical * 0.5, + pos[1] + self.line_horizontal * 0.5) + arc_rect = pygame.Rect( + pos1[0], pos1[1], self.line_vertical, self.line_horizontal) + pygame.draw.arc(screen, self.line_color, arc_rect, + PI / 2, PI, self.line_stroke) if flag & BL: - pos1 = (pos[0] + self.line_vertical * 0.5, pos[1] - self.line_horizontal * 0.5) - arc_rect = pygame.Rect(pos1[0], pos1[1], self.line_vertical, self.line_horizontal) - pygame.draw.arc(screen, self.line_color, arc_rect, PI, 3*PI / 2, self.line_stroke) + pos1 = (pos[0] + self.line_vertical * 0.5, + pos[1] - self.line_horizontal * 0.5) + arc_rect = pygame.Rect( + pos1[0], pos1[1], self.line_vertical, self.line_horizontal) + pygame.draw.arc(screen, self.line_color, arc_rect, + PI, 3*PI / 2, self.line_stroke) if flag & BR: - pos1 = (pos[0] - self.line_vertical * 0.5, pos[1] - self.line_horizontal * 0.5) - arc_rect = pygame.Rect(pos1[0], pos1[1], self.line_vertical, self.line_horizontal) - pygame.draw.arc(screen, self.line_color, arc_rect, 3*PI / 2, PI * 2, self.line_stroke) - - + pos1 = (pos[0] - self.line_vertical * 0.5, + pos[1] - self.line_horizontal * 0.5) + arc_rect = pygame.Rect( + pos1[0], pos1[1], self.line_vertical, self.line_horizontal) + pygame.draw.arc(screen, self.line_color, arc_rect, + 3*PI / 2, PI * 2, self.line_stroke) - - def draw_map(self, screen): rows = len(self.maze) cols = len(self.maze[0]) @@ -109,14 +121,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/settings.py b/src/settings.py index cdda2a4..9f0f118 100644 --- a/src/settings.py +++ b/src/settings.py @@ -1,7 +1,7 @@ class Settings(): def __init__(self): self.width = 900 - self.height = 950 + self.height = 990 self.fps = 60 settings = Settings() -- cgit v1.2.3