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
pass
+class GameOver(Component):
+ """Component for game menu items.
+ """
+
+ pass
+
+
class GameGui(Component):
"""Component for game graphical user interface items."""
tuple[CoordAbs2D, GhostStatus, Ghost, InMotion, Coord2D],
Ghost,
],
- score: GameState,
world: World,
state: GameState,
config: Config,
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
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(),
),
)
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(),
),
)
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))
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()))
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}"
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)
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,
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.
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 = [
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)),
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:
update_chase_status,
update_ghost_speed,
update_game_timer,
+ test,
)
.chain()
.run_if(initial_pause_done, in_game)