ShouldRender,
Sprite2D,
StopAnimation,
+ WindowEvents,
WindowPositionned,
graphics_plugins,
key_just_pressed,
class Config(Resource, BaseModel):
"""
- Configuration of the game.
+ Resource storing the configuration of the game.
"""
ghost_chase_speed: float = Field(default=2.5, ge=0.1, le=100.0)
pass
+@dataclass
+class PlayerName(Resource):
+ name: str = ""
+
+
@dataclass
class GameState(Resource):
"""
lives: int = 3
+class CheatMode(Component):
+ """
+ Component for the cheat mod.
+ """
+
+ pass
+
+
class MainMenu(Component):
"""
Component for main menu items.
continue
match status.state:
case GhostState.wander | GhostState.chase:
+ if world.run_raw_system(cheat_mode_enabled):
+ continue
world.run_raw_system(respawn_pacman)
world.run_raw_system(respawn_ghost)
world.run_raw_system(start_pause_timer)
return next(itr.__iter__(), None) is not None
+def game_is_over(game_over: Query[GameIsOver]) -> bool:
+ return next(game_over.__iter__(), None) is not None
+
+
def in_game(world: World) -> bool:
"""
System cheking that the game is running.
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,
+ ],
+ (
+ WindowPositionned(Vector2(0.5, 0), Vector2(-200, 100)),
+ ShouldRender(),
+ TextDisplay(
+ "GAME OVER",
+ fonts.load("./asset/fonts/JetBrainsMonoNL-Regular.ttf:100"),
+ ),
+ ),
+ )
+
+ world.spawn(
+ tuple[
+ WindowPositionned,
+ ShouldRender,
+ ComputedText,
+ TextDisplay,
+ ],
+ (
+ WindowPositionned(Vector2(0.5, 0), Vector2(-200, 300)),
+ ShouldRender(),
+ ComputedText(cast(System[str], print_score)), # FIXME
+ TextDisplay(
+ "Score",
+ fonts.load("./asset/fonts/JetBrainsMonoNL-Regular.ttf:50"),
+ ),
+ ),
+ )
+
+
def lose(
+ world: World,
+ gui: Query[Entity, GameGui],
hierarchy: Hierarchy[tuple[()]],
mazes: Query[Entity, Maze],
queue: CommandQueue,
"""
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))
queue.queue(lambda world: world.add_raw_system(game_over)())
+ world.run_raw_system(spawn_game_over)
def game_over(queue: CommandQueue) -> None:
System called when game is finish.
"""
queue.queue(lambda world: world.spawn_resource(GameIsOver()))
- print("Game over")
+ queue.queue(lambda world: world.spawn_resource(PlayerName()))
-def update_game_timer(state: GameState) -> None:
+def update_game_timer(world: World, state: GameState) -> None:
"""
System updating the levels timer.
"""
+ if world.run_raw_system(cheat_mode_enabled):
+ return
state.timer += 1
return inner
-def back_to_main_menu(
+def spawn_cheat_info(world: World, fonts: Assets[Font]) -> None:
+ world.spawn(
+ tuple[
+ WindowPositionned,
+ CoordBundle,
+ ShouldRender,
+ TextDisplay,
+ CheatMode,
+ ],
+ (
+ WindowPositionned(Vector2(0.5, 0), Vector2(-500, 60)),
+ CoordBundle(depth=-20),
+ ShouldRender(),
+ TextDisplay(
+ "CHEAT MODE ENABLED",
+ fonts.load("./asset/fonts/JetBrainsMonoNL-Regular.ttf:100"),
+ ),
+ CheatMode(),
+ ),
+ )
+
+
+def cheat_mode_enabled(cheat: Query[CheatMode]) -> bool:
+ return next(cheat.__iter__(), None) is not None
+
+
+def enable_cheat_mode(world: World) -> None:
+ world.run_raw_system(spawn_cheat_info)
+ world.spawn(CheatMode, CheatMode())
+
+
+def disable_cheat_mode(world: World, cheats: Query[Entity, CheatMode]) -> None:
+ items: list[Entity] = [cheat for cheat in cheats]
+ world.despawn_many(items)
+
+
+def toggle_cheat_mode(world: World) -> None:
+ if world.run_raw_system(cheat_mode_enabled):
+ world.run_raw_system(disable_cheat_mode)
+ else:
+ world.run_raw_system(enable_cheat_mode)
+
+
+def close_current_game(
world: World,
hierarchy: Hierarchy[tuple[()]],
mazes: Query[Entity, Maze],
queue: CommandQueue,
) -> None:
"""
- System closing the current game and opening the main menu.
+ System removing maze with childrens and game graphical user interface.
"""
world.run_raw_system(close_game_menu)
world.despawn_resource(GameState)
world.despawn_many(list(gui))
for maze in mazes:
queue.queue(hierarchy.despawn_with_children(maze))
+ if world.run_raw_system(cheat_mode_enabled):
+ world.run_raw_system(disable_cheat_mode)
+
+
+def back_to_main_menu(world: World) -> None:
+ """
+ System closing the current game and opening the main menu.
+ """
+ world.run_raw_system(close_current_game)
world.run_raw_system(setup_main_menu)
spawn_button,
WindowPositionned(Vector2(0.5), Vector2(-150, -40)),
"Cheat mod",
- quit_game,
+ toggle_cheat_mode,
)
quit_button = world.run_system(
world.spawn_resource(SelectedButton(selected))
+def test(events: WindowEvents) -> None: # FIXME
+ for key, state in events.keys_itr():
+ if state:
+ print(key)
+
+
+def get_player_name(events: WindowEvents, name: PlayerName) -> None:
+ for key, state in events.keys_itr():
+ if state and key == 8 and name.name != "":
+ name.name = name.name[: len(name.name) - 1]
+ if state and key in range(97, 124):
+ char = "abcdefghijklmnopqrstuvwxyz"[key - 97]
+ name.name += char
+
+
def run_game() -> None:
"""
Start with all necessary plugins and system to run the game.
.before(GraphicsSystems),
Systems(victory).run_if(level_is_finished, in_game),
Systems(lose).run_if(level_is_lost),
+ Systems(get_player_name).run_if(game_is_over),
).run_main()