mini-arcade-core 0.9.8__py3-none-any.whl → 0.9.9__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -14,7 +14,12 @@ from mini_arcade_core.cheats import CheatCode, CheatManager
14
14
  from mini_arcade_core.entity import Entity, KinematicEntity, SpriteEntity
15
15
  from mini_arcade_core.game import Game, GameConfig
16
16
  from mini_arcade_core.keymaps.keys import Key, keymap
17
- from mini_arcade_core.scenes import Scene, SceneRegistry, register_scene
17
+ from mini_arcade_core.scenes import (
18
+ Scene,
19
+ SceneRegistry,
20
+ SceneServices,
21
+ register_scene,
22
+ )
18
23
  from mini_arcade_core.two_d import (
19
24
  Bounds2D,
20
25
  KinematicData,
@@ -108,6 +113,7 @@ __all__ = [
108
113
  "register_scene",
109
114
  "CheatManager",
110
115
  "CheatCode",
116
+ "SceneServices",
111
117
  ]
112
118
 
113
119
  PACKAGE_NAME = "mini-arcade-core" # or whatever is in your pyproject.toml
@@ -0,0 +1,14 @@
1
+ """
2
+ Managers module for Mini Arcade Core.
3
+ Provides various manager classes for handling game entities and resources.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ from mini_arcade_core.managers.entity_manager import EntityManager
9
+ from mini_arcade_core.managers.overlay_manager import OverlayManager
10
+
11
+ __all__ = [
12
+ "EntityManager",
13
+ "OverlayManager",
14
+ ]
@@ -0,0 +1,91 @@
1
+ """
2
+ Base manager classes for handling collections of items.
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+ from dataclasses import dataclass, field
8
+ from typing import Callable, Generic, Iterable, List, Protocol, TypeVar
9
+
10
+ from mini_arcade_core.backend.backend import Backend
11
+
12
+ # ---- shared types ----
13
+ T = TypeVar("T")
14
+ OverlayFunc = Callable[[Backend], None]
15
+
16
+
17
+ class Drawable(Protocol):
18
+ """Defines a drawable entity."""
19
+
20
+ def draw(self, surface: Backend):
21
+ """
22
+ Draw the entity on the given surface.
23
+
24
+ :param surface: The backend surface to draw on.
25
+ :type surface: Backend
26
+ """
27
+
28
+
29
+ class Updatable(Protocol):
30
+ """Defines an updatable entity."""
31
+
32
+ def update(self, dt: float):
33
+ """
34
+ Update the entity state.
35
+
36
+ :param dt: Time delta in seconds.
37
+ :type dt: float
38
+ """
39
+
40
+
41
+ class EntityLike(Drawable, Updatable, Protocol):
42
+ """Defines a game entity."""
43
+
44
+
45
+ @dataclass
46
+ class ListManager(Generic[T]):
47
+ """
48
+ Generic manager for a list of items.
49
+
50
+ :ivar items (List[T]): List of managed items.
51
+ """
52
+
53
+ items: List[T] = field(default_factory=list)
54
+
55
+ def add(self, *items: T):
56
+ """
57
+ Add one or more items to the manager.
58
+
59
+ :param items: One or more items to add.
60
+ :type items: T
61
+ """
62
+ self.items.extend(items)
63
+
64
+ def add_many(self, items: Iterable[T]):
65
+ """
66
+ Add multiple items to the manager.
67
+
68
+ :param items: An iterable of items to add.
69
+ :type items: Iterable[T]
70
+ """
71
+ self.items.extend(items)
72
+
73
+ def remove(self, item: T):
74
+ """
75
+ Remove a single item from the manager, if present.
76
+
77
+ :param item: The item to remove.
78
+ :type item: T
79
+ """
80
+ if item in self.items:
81
+ self.items.remove(item)
82
+
83
+ def clear(self):
84
+ """Clear all items from the manager."""
85
+ self.items.clear()
86
+
87
+ def __iter__(self):
88
+ return iter(self.items)
89
+
90
+ def __len__(self) -> int:
91
+ return len(self.items)
@@ -0,0 +1,38 @@
1
+ """
2
+ Entity manager for handling a collection of entities.
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+ from dataclasses import dataclass
8
+
9
+ from mini_arcade_core.backend import Backend
10
+
11
+ from .base import EntityLike, ListManager
12
+
13
+
14
+ @dataclass
15
+ class EntityManager(ListManager[EntityLike]):
16
+ """
17
+ Manages a collection of entities within a scene.
18
+ """
19
+
20
+ def update(self, dt: float):
21
+ """
22
+ Update all managed entities.
23
+
24
+ :param dt: Time delta in seconds.
25
+ :type dt: float
26
+ """
27
+ for ent in list(self.items):
28
+ ent.update(dt)
29
+
30
+ def draw(self, surface: "Backend"):
31
+ """
32
+ Draw all managed entities.
33
+
34
+ :param surface: The backend surface to draw on.
35
+ :type surface: Backend
36
+ """
37
+ for ent in list(self.items):
38
+ ent.draw(surface)
@@ -0,0 +1,33 @@
1
+ """
2
+ Overlay manager for handling a collection of overlays.
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+ from dataclasses import dataclass
8
+ from typing import TYPE_CHECKING, Callable
9
+
10
+ from mini_arcade_core.backend import Backend
11
+ from mini_arcade_core.managers.base import ListManager
12
+
13
+ if TYPE_CHECKING:
14
+ from mini_arcade_core.game import Game
15
+
16
+ OverlayFunc = Callable[[Backend], None]
17
+
18
+
19
+ @dataclass
20
+ class OverlayManager(ListManager[OverlayFunc]):
21
+ """
22
+ Manages a collection of overlays within a scene.
23
+ """
24
+
25
+ def draw(self, surface: "Backend"):
26
+ """
27
+ Call all overlays. Scenes should call this at the end of draw().
28
+
29
+ :param surface: The backend surface to draw on.
30
+ :type surface: Backend
31
+ """
32
+ for overlay in self.items:
33
+ overlay(surface)
@@ -7,6 +7,6 @@ from __future__ import annotations
7
7
 
8
8
  from .autoreg import register_scene
9
9
  from .registry import SceneRegistry
10
- from .scene import Scene
10
+ from .scene import Scene, SceneServices
11
11
 
12
- __all__ = ["Scene", "register_scene", "SceneRegistry"]
12
+ __all__ = ["Scene", "register_scene", "SceneRegistry", "SceneServices"]
@@ -5,22 +5,40 @@ Base class for game scenes (states/screens).
5
5
  from __future__ import annotations
6
6
 
7
7
  from abc import ABC, abstractmethod
8
- from typing import TYPE_CHECKING, Callable, List
8
+ from dataclasses import dataclass, field
9
+ from typing import TYPE_CHECKING, List, Optional
9
10
 
10
11
  from mini_arcade_core.backend import Backend, Event
11
12
  from mini_arcade_core.entity import Entity
13
+ from mini_arcade_core.managers import EntityManager, OverlayManager
12
14
  from mini_arcade_core.two_d import Size2D
13
15
 
14
16
  if TYPE_CHECKING:
15
17
  from mini_arcade_core.game import Game
16
18
 
17
- OverlayFunc = Callable[[Backend], None]
19
+
20
+ @dataclass
21
+ class SceneServices:
22
+ """
23
+ Container for scene services like entity and overlay managers.
24
+
25
+ :ivar entities: EntityManager for managing scene entities.
26
+ :ivar overlays: OverlayManager for managing scene overlays.
27
+ """
28
+
29
+ entities: EntityManager = field(default_factory=EntityManager)
30
+ overlays: OverlayManager = field(default_factory=OverlayManager)
18
31
 
19
32
 
20
33
  class Scene(ABC):
21
34
  """Base class for game scenes (states/screens)."""
22
35
 
23
- def __init__(self, game: Game):
36
+ def __init__(
37
+ self,
38
+ game: Game,
39
+ *,
40
+ services: Optional[SceneServices] = None,
41
+ ):
24
42
  """
25
43
  :param game: Reference to the main Game object.
26
44
  :type game: Game
@@ -28,84 +46,10 @@ class Scene(ABC):
28
46
  self.game = game
29
47
  self.entities: List[Entity] = []
30
48
  self.size: Size2D = Size2D(game.config.width, game.config.height)
31
- # overlays drawn on top of the scene
32
- self._overlays: List[OverlayFunc] = []
33
-
34
- def add_entity(self, *entities: Entity):
35
- """
36
- Register one or more entities in this scene.
37
-
38
- :param entities: One or more Entity instances to add.
39
- :type entities: Entity
40
- """
41
- self.entities.extend(entities)
42
-
43
- def remove_entity(self, entity: Entity):
44
- """
45
- Unregister a single entity, if present.
46
-
47
- :param entity: The Entity instance to remove.
48
- :type entity: Entity
49
- """
50
- if entity in self.entities:
51
- self.entities.remove(entity)
52
-
53
- def clear_entities(self):
54
- """Remove all entities from the scene."""
55
- self.entities.clear()
56
-
57
- def update_entities(self, dt: float):
58
- """
59
- Default update loop for all entities.
60
-
61
- :param dt: Time delta in seconds.
62
- :type dt: float
63
- """
64
- for ent in self.entities:
65
- ent.update(dt)
66
-
67
- def draw_entities(self, surface: Backend):
68
- """
69
- Default draw loop for all entities.
70
-
71
- :param surface: The backend surface to draw on.
72
- :type surface: Backend
73
- """
74
- for ent in self.entities:
75
- ent.draw(surface)
76
49
 
77
- def add_overlay(self, overlay: OverlayFunc):
78
- """
79
- Register an overlay (drawn every frame, after entities).
80
-
81
- :param overlay: A callable that takes a Backend and draws on it.
82
- :type overlay: OverlayFunc
83
- """
84
- self._overlays.append(overlay)
85
-
86
- def remove_overlay(self, overlay: OverlayFunc):
87
- """
88
- Unregister a previously added overlay.
89
-
90
- :param overlay: The overlay to remove.
91
- :type overlay: OverlayFunc
92
- """
93
- if overlay in self._overlays:
94
- self._overlays.remove(overlay)
95
-
96
- def clear_overlays(self):
97
- """Clear all registered overlays."""
98
- self._overlays.clear()
99
-
100
- def draw_overlays(self, surface: Backend):
101
- """
102
- Call all overlays. Scenes should call this at the end of draw().
103
-
104
- :param surface: The backend surface to draw on.
105
- :type surface: Backend
106
- """
107
- for overlay in self._overlays:
108
- overlay(surface)
50
+ self.services: SceneServices = (
51
+ services if services is not None else SceneServices()
52
+ )
109
53
 
110
54
  @abstractmethod
111
55
  def on_enter(self):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mini-arcade-core
3
- Version: 0.9.8
3
+ Version: 0.9.9
4
4
  Summary: Tiny scene-based game loop core for small arcade games.
5
5
  License: Copyright (c) 2025 Santiago Rincón
6
6
 
@@ -1,4 +1,4 @@
1
- mini_arcade_core/__init__.py,sha256=3gb_Q9j5jGlBljwmpExrsXDKZX9FLbCxms9KxhrCOA0,3747
1
+ mini_arcade_core/__init__.py,sha256=m9wELq1seQQE13tfU6DT7XinC07yzo5KTS1KEA0MQNs,3804
2
2
  mini_arcade_core/backend/__init__.py,sha256=w-6QTUngdIYZuvEU3B8zL-vXyKbyLDVucbt7yKZdLlc,379
3
3
  mini_arcade_core/backend/backend.py,sha256=dLXTtLn5qURftWOWOVQd2ouuZmJpbiOl11KMIDRk2us,4026
4
4
  mini_arcade_core/backend/events.py,sha256=usn2HTk5-5ZiaU2IjbrNRpEj_4uoaiqfY3qufQLYy0w,2929
@@ -9,10 +9,14 @@ mini_arcade_core/game.py,sha256=C8flMXn_DMHWDmr5FVrTey_nUHabwja8wSaialNMcLg,8526
9
9
  mini_arcade_core/keymaps/__init__.py,sha256=_5Y5_61XT5TsOhbb6p2EPzvjCNN9hCPoxTgj_TAfBvA,258
10
10
  mini_arcade_core/keymaps/keys.py,sha256=LTg20SwLBI3kpPIiTNpq2yBft_QUGj-iNFSNm9M-Fus,3010
11
11
  mini_arcade_core/keymaps/sdl.py,sha256=Tb0amkbmYjYkEkYnMZ6i9QWjwXBkEHIm13-gEMUYENM,2060
12
- mini_arcade_core/scenes/__init__.py,sha256=0zzGFejPZ4CkWHJSkhjRAWA7GbenyZbTGrKOrA5gON4,291
12
+ mini_arcade_core/managers/__init__.py,sha256=ZpWVxqUq2lbLdrtPR75ipSmykp3fpm9nQrQHP15sGJI,352
13
+ mini_arcade_core/managers/base.py,sha256=D2CCde_zbsrlLNzs3v3qgYpRu9QgmFlzOfdfFIwf5xs,2023
14
+ mini_arcade_core/managers/entity_manager.py,sha256=mBgSFgdZ73f5ZZ-_GtvnqOFWuSySX5QJZrZ77sH4qes,831
15
+ mini_arcade_core/managers/overlay_manager.py,sha256=LTywwhSigjGiCKqULBGjKJPT6xyYgeoKXfhPEoOw8Nk,801
16
+ mini_arcade_core/scenes/__init__.py,sha256=MXaWaDvwf0ycd5GZ_9DhPQ7tWqsp-ECWTOZpGZarcRE,323
13
17
  mini_arcade_core/scenes/autoreg.py,sha256=b4V0jaA65I2hnT2f___rg_pT556OjrtoNjIRdZrXBaI,1009
14
18
  mini_arcade_core/scenes/registry.py,sha256=0B3iSvepydwMpELQz8cRaQeAU0pR1Fz9O1YtWshLjQw,3226
15
- mini_arcade_core/scenes/scene.py,sha256=nAYr-T1RW-7s0a8JrxesJY36iAtpZsA2cqeIZgZWIeU,3962
19
+ mini_arcade_core/scenes/scene.py,sha256=MrHAHf-su6xrLXi4y1opxJWy0YF-yLfSN6rOvSHPqCc,2384
16
20
  mini_arcade_core/two_d/__init__.py,sha256=iWjm39RYDEshxSmiIWyGWa6Qr9O2gnHfOpzrl63FUro,626
17
21
  mini_arcade_core/two_d/boundaries2d.py,sha256=H1HkCR1422MkQIEve2DFKvnav4RpvtLx-qTMxzmdDMQ,2610
18
22
  mini_arcade_core/two_d/collision2d.py,sha256=jR5bOmqUaedxRzwFoKBgn7k-ozwklB4RP9pUTVk6aUw,1716
@@ -21,7 +25,7 @@ mini_arcade_core/two_d/kinematics2d.py,sha256=NFMiIzDYqDquyg_EhD7EQBJ_Sz4RncmkEj
21
25
  mini_arcade_core/two_d/physics2d.py,sha256=qIq86qWVuvcnLIMEPH6xx7XQO4tQhfiMZY6FseuVOR8,1636
22
26
  mini_arcade_core/ui/__init__.py,sha256=RmcZXfBFFmL09j_Bo1LHagRjiKYajuySPilIUNjc3KQ,248
23
27
  mini_arcade_core/ui/menu.py,sha256=J3hYY46xOHLN65WSet4-cnQU7L5pu48scjLJUW9IkEM,13681
24
- mini_arcade_core-0.9.8.dist-info/METADATA,sha256=YkzK5IIHDjJN4hTAu9dAUiOOAiOFLEm15zMwJMxDcTs,8188
25
- mini_arcade_core-0.9.8.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
26
- mini_arcade_core-0.9.8.dist-info/licenses/LICENSE,sha256=3lHAuV0584cVS5vAqi2uC6GcsVgxUijvwvtZckyvaZ4,1096
27
- mini_arcade_core-0.9.8.dist-info/RECORD,,
28
+ mini_arcade_core-0.9.9.dist-info/METADATA,sha256=G7IK6yFjXiaGPHQr9_DcedeRXQAmhWlgXCcjyHslr1U,8188
29
+ mini_arcade_core-0.9.9.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
30
+ mini_arcade_core-0.9.9.dist-info/licenses/LICENSE,sha256=3lHAuV0584cVS5vAqi2uC6GcsVgxUijvwvtZckyvaZ4,1096
31
+ mini_arcade_core-0.9.9.dist-info/RECORD,,