From: Thomas Rimelen Date: Wed, 21 Oct 2026 12:12:12 +0000 (+0200) Subject: game over and end score added + minor fix X-Git-Url: https://git.uwuaxy.net/Project%20Status.png?a=commitdiff_plain;h=f5a7299e2c171b4cc6e7a03da73a4ba62fd8f78e;p=axy%2Fft%2Fpacman.git game over and end score added + minor fix --- diff --git a/src/pacman/game/__init__.py b/src/pacman/game/__init__.py index cdd2142..39af5ec 100644 --- a/src/pacman/game/__init__.py +++ b/src/pacman/game/__init__.py @@ -7,7 +7,7 @@ from typing import cast, override from mazegenerator import MazeGenerator # type: ignore[import-untyped] from pydantic import BaseModel, Field -from pygame import K_ESCAPE, Vector2 +from pygame import K_BACKSPACE, K_ESCAPE, K_RETURN, K_a, K_z, Vector2 from pygame.math import clamp from pacman.ecs import minimal_plugins @@ -180,6 +180,13 @@ class GameMenu(Component): pass +class GameOver(Component): + """Component for game menu items. + """ + + pass + + class GameGui(Component): """Component for game graphical user interface items.""" @@ -674,7 +681,6 @@ def collide_ghost( tuple[CoordAbs2D, GhostStatus, Ghost, InMotion, Coord2D], Ghost, ], - score: GameState, world: World, state: GameState, config: Config, @@ -698,7 +704,7 @@ def collide_ghost( break case GhostState.flee: - score.score += config.score_ghost + state.score += config.score_ghost status.state = GhostState.dead status.tick = 0 motion.src = ghost.home_entity @@ -924,31 +930,37 @@ def level_is_lost( return config.level_timer < state.timer or state.lives <= 0 -# def lose( -# world: World, -# queue: CommandQueue, -# ) -> None: -# """ -# System called when the player lose the game. -# """ -# world.run_raw_system(close_current_game) -# queue.queue(lambda world: world.add_raw_system(game_over)()) - - def spawn_game_over(world: World, fonts: Assets[Font]) -> None: # FIXME + world.spawn( + tuple[WindowPositionned, ShouldRender, TextDisplay, GameOver], + ( + WindowPositionned(Vector2(0.5, 0), Vector2(-300, 100)), + ShouldRender(), + TextDisplay( + "GAME OVER", + fonts.load("./asset/fonts/JetBrainsMonoNL-Regular.ttf:100"), + ), + GameOver(), + ), + ) + world.spawn( tuple[ WindowPositionned, ShouldRender, + ComputedText, TextDisplay, + GameOver, ], ( - WindowPositionned(Vector2(0.5, 0), Vector2(-200, 100)), + WindowPositionned(Vector2(0.5, 0), Vector2(-100, 300)), ShouldRender(), + ComputedText(cast(System[str], print_score)), TextDisplay( - "GAME OVER", - fonts.load("./asset/fonts/JetBrainsMonoNL-Regular.ttf:100"), + "Score", + fonts.load("./asset/fonts/JetBrainsMonoNL-Regular.ttf:40"), ), + GameOver(), ), ) @@ -958,15 +970,17 @@ def spawn_game_over(world: World, fonts: Assets[Font]) -> None: # FIXME ShouldRender, ComputedText, TextDisplay, + GameOver, ], ( - WindowPositionned(Vector2(0.5, 0), Vector2(-200, 300)), + WindowPositionned(Vector2(0.5, 0), Vector2(-300, 400)), ShouldRender(), - ComputedText(cast(System[str], print_score)), # FIXME + ComputedText(cast(System[str], print_name)), TextDisplay( "Score", - fonts.load("./asset/fonts/JetBrainsMonoNL-Regular.ttf:50"), + fonts.load("./asset/fonts/JetBrainsMonoNL-Regular.ttf:30"), ), + GameOver(), ), ) @@ -979,7 +993,6 @@ def lose( queue: CommandQueue, ) -> None: """System called when the player lose the game.""" - world.despawn_resource(GameState) world.despawn_many(list(gui)) for maze in mazes: queue.queue(hierarchy.despawn_with_children(maze)) @@ -988,7 +1001,6 @@ def lose( def game_over(queue: CommandQueue) -> None: - # FIXME """System called when game is finish.""" queue.queue(lambda world: world.spawn_resource(GameIsOver())) queue.queue(lambda world: world.spawn_resource(PlayerName())) @@ -1009,6 +1021,12 @@ def initial_pause_done(timer: InitialPauseTimer, config: Config) -> bool: return True +def print_name(name: PlayerName) -> str: + """Return a string with the player score. + """ + return f"Enter your name: {name.name}" + + def print_score(state: GameState) -> str: """Return a string with the player score.""" return f"Score: {state.score}" @@ -1210,7 +1228,7 @@ def close_game_menu( menus: Query[Entity, GameMenu], animated: Query[Entity, Pacman | Ghost], ) -> None: - """System closing the game menu.""" + """Close the game menu.""" world.remove_many(StopAnimation, list(animated)) for menu in menus: hierarchy.despawn_with_children(menu)(world) @@ -1220,7 +1238,7 @@ def close_game_menu( def setup_game_menu( world: World, animated: Query[Entity, Pacman | Ghost] ) -> None: - """System opening the game menu.""" + """Open the game menu.""" world.insert_many(StopAnimation, [(e, StopAnimation()) for e in animated]) selected = world.run_system( spawn_button, @@ -1256,7 +1274,7 @@ def setup_game_menu( def set_up_instructions(world: World, fonts: Assets[Font]) -> list[Entity]: - """System adding instructions to main menu.""" + """Add instructions to main menu.""" text = """Use 'WASD'to move pacman in the maze. Collect all pacgums to go to the next level. Complete all levels to win the game. @@ -1314,7 +1332,7 @@ When you eat a super pacgum, you can eat ghost. def set_up_highsores( world: World, scores: Highscores, fonts: Assets[Font] ) -> list[Entity]: - """System adding highscores to main menu.""" + """Add highscores to main menu.""" highscores = [(name, value) for name, value in scores.scores.items()] highscores.sort(key=lambda x: x[1], reverse=True) entities = [ @@ -1363,7 +1381,7 @@ def set_up_highsores( def setup_main_menu(world: World) -> None: - """System creating the main menu by adding button, instruction and highscores.""" + """Create the main menu by adding button, instruction and highscores.""" selected = world.run_system( spawn_button, WindowPositionned(Vector2(0.5), Vector2(-150, -100)), @@ -1399,13 +1417,27 @@ def test(events: WindowEvents) -> None: # FIXME print(key) -def get_player_name(events: WindowEvents, name: PlayerName) -> None: +def add_score( + world: World, name: PlayerName, state: GameState, scores: Highscores +) -> None: + # FIXME + scores.scores[name.name] = state.score + world.run_simple_system(save_highscores) + world.run_simple_system(setup_main_menu) + + +def get_player_name( + world: World, events: WindowEvents, name: PlayerName +) -> None: for key, state in events.keys_itr(): - if state and key == 8 and name.name != "": + if state and key == K_BACKSPACE and name.name != "": name.name = name.name[: len(name.name) - 1] - if state and key in range(97, 124): - char = "abcdefghijklmnopqrstuvwxyz"[key - 97] + if state and key in range(K_a, K_z) and len(name.name) < 10: + char = "abcdefghijklmnopqrstuvwxyz"[key - K_a] name.name += char + if state and key == K_RETURN: + world.run_simple_system(add_score) + return def run_game() -> None: @@ -1426,6 +1458,7 @@ def run_game() -> None: update_chase_status, update_ghost_speed, update_game_timer, + test, ) .chain() .run_if(initial_pause_done, in_game)