From: Thomas Rimelen Date: Wed, 30 Sep 2026 14:38:01 +0000 (+0200) Subject: proper pacman movement added X-Git-Url: https://git.uwuaxy.net/Project%20Status.png?a=commitdiff_plain;h=1a8ecd9e50165e25359be3c7cc2e5cf6d7f08bd8;p=axy%2Fft%2Fpacman.git proper pacman movement added --- diff --git a/src/pacman/ecs/graphics.py b/src/pacman/ecs/graphics.py index dcc5871..1ea9c9e 100644 --- a/src/pacman/ecs/graphics.py +++ b/src/pacman/ecs/graphics.py @@ -41,9 +41,11 @@ class WindowEvents(Resource): if e.type == pygame.MOUSEBUTTONDOWN ) - def keys(self) -> Iterator[int]: + def keys_itr(self) -> Iterator[tuple[int, bool]]: return ( - cast(int, (e.key)) for e in self.events if e.type == pygame.KEYDOWN + (cast(int, (e.key)), e.type == pygame.KEYDOWN) + for e in self.events + if e.type == pygame.KEYDOWN or e.type == pygame.KEYUP ) @@ -66,6 +68,9 @@ class Sprite2D(Component, Asset): del ty return Sprite2D(pygame.image.load(path)) + def copy(self) -> "Sprite2D": + return Sprite2D(self.surface) + def poll_events(events: WindowEvents) -> None: events.events = pygame.event.get() @@ -118,7 +123,7 @@ def insert_animation_sprites( ) -> None: inserts = [] for ent, anim in query: - inserts.append((ent, anim.curr_frame)) + inserts.append((ent, anim.curr_frame.copy())) world.insert_many(Sprite2D, inserts) @@ -131,6 +136,7 @@ def update_animations( GraphicsSystems = SystemSet("graphics-systems") +InputsSystems = SystemSet("inputs-systems") def graphics_plugins(world: World) -> None: @@ -143,5 +149,7 @@ def graphics_plugins(world: World) -> None: ) .chain() .in_set(PostUpdate, GraphicsSystems), - Systems(poll_events, close_on_close).chain().in_set(PreUpdate), + Systems(poll_events, close_on_close) + .chain() + .in_set(PreUpdate, InputsSystems), ) diff --git a/src/pacman/game/__init__.py b/src/pacman/game/__init__.py index c5a8edf..de33de8 100644 --- a/src/pacman/game/__init__.py +++ b/src/pacman/game/__init__.py @@ -3,7 +3,7 @@ from dataclasses import dataclass from random import random from mazegenerator import MazeGenerator -from pygame import Vector3 +from pygame import K_a, K_d, K_s, K_w, Vector3 from pygame.math import clamp from pacman.ecs import minimal_plugins @@ -11,14 +11,17 @@ from pacman.ecs.assets import Assets from pacman.ecs.coord import Coord2D, CoordAbs2D from pacman.ecs.graphics import ( AnimationSet, + GraphicsSystems, + InputsSystems, ShouldRender, Sprite2D, + WindowEvents, graphics_plugins, ) from pacman.ecs.hierarchy import ChildOf from pacman.ecs.schedule import StartupSchedule, UpdateSchedule -from pacman.ecs.update import Update -from pacman.ecs.world import Component, Entity, Query, Systems, World +from pacman.ecs.update import PostUpdate, PreUpdate, Update +from pacman.ecs.world import Component, Entity, Query, Resource, Systems, World class Maze(Component): @@ -226,8 +229,24 @@ def move_to_target( motion.pos = nxt +@dataclass +class Inputs(Resource): + inputs: set[int] + + def get_dir(self) -> int | None: + if K_w in self.inputs: + return 0 + if K_d in self.inputs: + return 1 + if K_s in self.inputs: + return 2 + if K_a in self.inputs: + return 3 + + +@dataclass class Pacman(Component): - pass + current_direction: int def spawn_pacman( @@ -244,9 +263,9 @@ def spawn_pacman( AnimationSet, Pacman, ShouldRender, - TargetTile, InMotion, MoveSpeed, + TilePos, ], ( Coord2D(0, 0, -10), @@ -261,26 +280,77 @@ def spawn_pacman( ] for direction in "URDL" ], - 4, + 6, ), - Pacman(), + Pacman(1), ShouldRender(), - TargetTile(maze._cells[(14, 14)]), InMotion(maze._cells[(0, 0)], maze._cells[(0, 0)]), - MoveSpeed(4.0), + MoveSpeed(3.0), + TilePos(maze._cells[(0, 0)]), ), ) +def move_pacman( + pacman_q: Query[tuple[Pacman, Coord2D, InMotion, TilePos]], + inputs: Inputs, + cells: Query[tuple[Cell, Coord2D]], + maze_q: Query[Maze], +) -> None: + maze = maze_q.single() + if maze is None: + return + for pacman, coord, motion, pos in pacman_q: + direction = inputs.get_dir() + cell, cell_pos = cells[pos.pos] + if coord.xy.distance_to(cell_pos.xy) < 12.0: + if direction is None: + direction = pacman.current_direction + if cell.walls()[direction]: + direction = pacman.current_direction + if not cell.walls()[direction]: + motion.src = pos.pos + motion.pos = maze._cells[cell.neighbor(direction)] + pacman.current_direction = direction + elif ((pacman.current_direction + 2) % 4) == direction: + tmp = motion.pos + motion.pos = motion.src + motion.src = tmp + pacman.current_direction = direction + + +def update_pacman_anim(pacman_q: Query[tuple[Pacman, AnimationSet]]) -> None: + for pacman, anim in pacman_q: + anim.idx = pacman.current_direction + + +def setup_resources(world: World) -> None: + world.spawn(Inputs, Inputs(set())) + + +def update_inputs(inputs: Inputs, events: WindowEvents) -> None: + for key, state in events.keys_itr(): + if state: + inputs.inputs.add(key) + else: + inputs.inputs.remove(key) + + def run_game() -> None: World().with_plugins(graphics_plugins, minimal_plugins).with_systems( StartupSchedule, Systems( - setup_maze, spawn_superpacgums, spawn_pacgums, spawn_pacman + setup_resources, + setup_maze, + spawn_superpacgums, + spawn_pacgums, + spawn_pacman, ).chain(), ).with_systems( UpdateSchedule, - Systems(move_in_motion, update_tile_pos, move_to_target) + Systems(move_pacman, move_in_motion, update_tile_pos, move_to_target) .chain() .in_set(Update), + Systems(update_inputs).in_set(PreUpdate).after(InputsSystems), + Systems(update_pacman_anim).before(GraphicsSystems).in_set(PostUpdate), ).run_main()