Files
PyGame-Pacman/pman.py

181 lines
7.0 KiB
Python

import pygame
import pygameControls as PC
from actors.enums import Colors, PlayerDirection
from actors.pacman import ActorPacman
from actors.ghost import Blinky, Pinky, Inky, Clyde # adjust import path as needed
from actors.ghost_mode_controller import GhostModeController
from hud import HUD
from maze import Maze
__version__ = "0.3.4"
# Constants
HAT_REPEAT_DELAY = 300 # milliseconds before first repeat
HAT_REPEAT_INTERVAL = 100 # milliseconds between repeats
# State
hat_direction = (0, 0)
hat_timer = 0
hat_first_press = True
def spawn_ghosts(center_position):
"""
Spawns up to 4 ghosts at the center of the maze ("ghost house").
Args:
center_position (tuple): (x, y) coordinates for spawn point.
Returns:
pygame.sprite.Group: A group containing all ghost instances.
"""
offset = 20 # spread out a little bit inside ghost home
blinky = Blinky((center_position[0] - offset, center_position[1] - offset))
pinky = Pinky((center_position[0] + offset, center_position[1] - offset))
inky = Inky((center_position[0] - offset, center_position[1] + offset))
clyde = Clyde((center_position[0] + offset, center_position[1] + offset))
return pygame.sprite.Group(blinky, pinky, inky, clyde)
def handle_hat_repeat():
global hat_timer, hat_first_press
now = pygame.time.get_ticks()
if hat_direction != (0, 0):
if hat_first_press:
if now - hat_timer >= HAT_REPEAT_DELAY:
hat_timer = now
hat_first_press = False
post_hat_repeat_event()
else:
if now - hat_timer >= HAT_REPEAT_INTERVAL:
hat_timer = now
post_hat_repeat_event()
def post_hat_repeat_event():
pygame.event.post(pygame.event.Event(pygame.USEREVENT, {
"type_name": "JOYHATREPEAT",
"value": hat_direction
}))
def main() -> None:
global hat_direction, hat_timer, hat_first_press
pygame.init()
pygame.key.set_repeat(200)
joystick_count = pygame.joystick.get_count()
joysticks = {}
screen_width, screen_height = (32*29), (32*30)+32
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Pac-Man " + __version__)
cherry_img = pygame.image.load("assets/cherry.png").convert_alpha()
hud = HUD(screen_width, screen_height, cherry_image=cherry_img)
maze = Maze("maze/pacman_maze.txt")
player = ActorPacman(screen, center=maze.pacman_start, start_location=maze.pacman_location, maze=maze)
ghost_mode_controller = GhostModeController()
ghost_home_center = (screen_width // 2, (screen_height) // 2)
ghosts = spawn_ghosts(ghost_home_center)
clock = pygame.time.Clock()
running = True
while running:
screen.fill(Colors.Black.value)
pygame.event.pump()
for event in pygame.event.get():
match event.type:
case pygame.QUIT:
running = False
case pygame.KEYDOWN:
match event.key:
case pygame.K_RIGHT:
if maze.is_wall(player.location[0] + 1, player.location[1]):
break
player.direction = PlayerDirection.DirectionRight
player.move_right()
case pygame.K_LEFT:
if maze.is_wall(player.location[0] - 1, player.location[1]):
break
player.direction = PlayerDirection.DirectionLeft
player.move_left()
case pygame.K_UP:
if maze.is_wall(player.location[0], player.location[1] - 1):
break
player.direction = PlayerDirection.DirectionUp
player.move_up()
case pygame.K_DOWN:
if maze.is_wall(player.location[0], player.location[1] + 1):
break
player.direction = PlayerDirection.DirectionDown
player.move_down()
case pygame.JOYHATMOTION:
hat_x, hat_y = hat_direction = event.value
hat_timer = pygame.time.get_ticks()
hat_first_press = True
if event.type == pygame.USEREVENT and event.dict.get("type_name") == "JOYHATREPEAT":
print(f"Repeated hat: {event.dict['value']}")
if hat_x == 1:
if maze.is_wall(player.location[0] + 1, player.location[1]):
break
player.direction = PlayerDirection.DirectionRight
player.move_right()
elif hat_x == -1:
if maze.is_wall(player.location[0] - 1, player.location[1]):
break
player.direction = PlayerDirection.DirectionLeft
player.move_left()
elif hat_y == 1:
if maze.is_wall(player.location[0], player.location[1] - 1):
break
player.direction = PlayerDirection.DirectionUp
player.move_up()
elif hat_y == -1:
if maze.is_wall(player.location[0], player.location[1] + 1):
break
player.direction = PlayerDirection.DirectionDown
player.move_down()
# Handle hotplugging
case pygame.JOYDEVICEADDED:
# This event will be generated when the program starts for every
# joystick, filling up the list without needing to create them manually.
joy = pygame.joystick.Joystick(event.device_index)
joysticks[joy.get_instance_id()] = PC.controller.Controllers(joy)
case pygame.JOYDEVICEREMOVED:
del joysticks[event.instance_id]
print(f"Joystick {event.instance_id} disconnected")
match maze.collect_dot(player.location[0], player.location[1]):
case "dot":
hud.add_points(10)
case "power":
hud.add_points(50)
# In your main game loop:
handle_hat_repeat()
hud.draw(screen)
maze.draw(screen)
player.update()
player.draw()
ghost_mode_controller.update()
current_mode = ghost_mode_controller.mode
for ghost in ghosts:
ghost.set_mode(current_mode)
#ghost.update(maze, pacman)
ghosts.draw(screen)
pygame.display.flip()
clock.tick(60)
if joysticks:
joysticks[joy.get_instance_id()].controllers[0].close()
pygame.quit()
if __name__ == "__main__":
main()