]> Untitled Git - axy/ft/pacman.git/commitdiff
game over and end score added + minor fix
authorThomas Rimelen <trimelen@k1r3p4.42mulhouse.fr>
Wed, 21 Oct 2026 12:12:12 +0000 (14:12 +0200)
committerThomas Rimelen <trimelen@k1r3p4.42mulhouse.fr>
Wed, 21 Oct 2026 12:22:04 +0000 (14:22 +0200)
src/pacman/game/__init__.py

index cdd2142c826d0bc99380a8131c52db8cf07f13e9..39af5ec7bdd191254de0b16c04792f6ef4089b64 100644 (file)
@@ -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)