from typing import override
import pygame
-from pygame import Color
+from pygame import Color, Vector2
from pacman.ecs.assets import Asset
-from pacman.ecs.coord import CoordAbs2D, PropagateTransform
+from pacman.ecs.coord import (
+ CoordAbs2D,
+ CoordBundle,
+ PropagateTransform,
+)
from pacman.ecs.graphics import (
AnimationSet,
GraphicsSystems,
path, size = path.split(":")
return Font(pygame.font.Font(path, int(size)))
+ def center_text_for(self, text: str, dims: Vector2) -> CoordBundle:
+ width, _ = self.font.size(text)
+ height = self.font.get_ascent() + self.font.get_descent()
+ return CoordBundle(
+ (dims.x - width) / 2,
+ (dims.y - height) / 2 + self.font.get_descent(),
+ )
+
@dataclass
class TextDisplay(Component):
return kv[ty]
return map(self._components[ty].__getitem__, positions)
- itr = range(len(dst._entities) - len(components), len(dst._entities))
+ itr = lambda: range(
+ len(dst._entities) - len(components), len(dst._entities)
+ )
dst._extend(cb)
self._discard(positions)
for k, lst in moved_comps:
hooks = self._world._components_cache[k][1]
hooks._remove(
- zip((dst._entities[i] for i in itr), lst, strict=True)
+ zip((dst._entities[i] for i in itr()), lst, strict=True)
)
for k in comps_ty:
lst = dst._components[k]
hooks = self._world._components_cache[k][1]
- hooks._insert((dst._entities[i], lst[i]) for i in itr)
+ hooks._insert((dst._entities[i], lst[i]) for i in itr())
return res
SelectedButton,
TextDisplay,
)
-from pacman.ecs.hierarchy import ChildOf, Hierarchy
+from pacman.ecs.hierarchy import ChildOf, Children, Hierarchy
from pacman.ecs.schedule import StartupSchedule, UpdateSchedule
from pacman.ecs.update import PostUpdate, Update
from pacman.ecs.world import (
Not,
Query,
Resource,
+ System,
Systems,
World,
+ WorldShouldExit,
)
_DIR_OFFSETS = [(0, -1), (1, 0), (0, 1), (-1, 0)]
return f"{time // 60}"
-def print_a() -> None:
- print("a")
+def start_game() -> None:
+ print("Game started")
-def print_b() -> None:
- print("b")
+def quit_game(world: World) -> None:
+ world.spawn_resource(WorldShouldExit())
-def print_c() -> None:
- print("c")
+def spawn_button(
+ world: World, fonts: Assets[Font], sprites: Assets[Sprite2D]
+) -> Callable[[Vector2, str, System], Entity]:
+ def inner(pos: Vector2, s: str, cb: System) -> Entity:
+ parent = world.spawn(
+ tuple[CoordBundle, ShouldRender, AnimationSet, Button],
+ (
+ CoordBundle(*pos.xy, depth=-100),
+ ShouldRender(),
+ AnimationSet(
+ [
+ [sprites.load("./asset/gui/button_unselected.png")],
+ [sprites.load("./asset/gui/button_selected.png")],
+ [sprites.load("./asset/gui/button_selected.png")],
+ ],
+ 1,
+ ),
+ Button(cb),
+ ),
+ )
+ font = fonts.load("./asset/fonts/JetBrainsMonoNL-Regular.ttf:30")
+ world.spawn(
+ tuple[CoordBundle, ShouldRender, TextDisplay, ChildOf],
+ (
+ font.center_text_for(s, Vector2(300, 80)),
+ ShouldRender(),
+ TextDisplay(s, font),
+ ChildOf(parent),
+ ),
+ )
+ return parent
+
+ return inner
def setup_text(world: World, fonts: Assets[Font]) -> None:
- spawned = world.spawn_many(
- tuple[CoordBundle, ShouldRender, ComputedText, TextDisplay, Button],
+ world.spawn_many(
+ tuple[CoordBundle, ShouldRender, ComputedText, TextDisplay],
[
(
CoordBundle(depth=-20),
"",
fonts.load("./asset/fonts/JetBrainsMonoNL-Regular.ttf:30"),
),
- Button(print_a),
),
(
CoordBundle(y=100, depth=-20),
"",
fonts.load("./asset/fonts/JetBrainsMonoNL-Regular.ttf:30"),
),
- Button(print_b),
),
(
CoordBundle(y=200, depth=-20),
"",
fonts.load("./asset/fonts/JetBrainsMonoNL-Regular.ttf:30"),
),
- Button(print_c),
),
],
)
- world.spawn_resource(SelectedButton(spawned[0]))
+
+ selected = world.run_system(
+ spawn_button,
+ Vector2((1600 - 300) / 2, (1200 - 200) / 2),
+ "Start game",
+ start_game,
+ )
+
+ world.run_system(
+ spawn_button,
+ Vector2((1600 - 300) / 2, (1200 - 200) / 2 + 120),
+ "Quit",
+ quit_game,
+ )
+
+ world.spawn_resource(SelectedButton(selected))
def run_game() -> None: