mini-arcade-core 0.9.7__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.
- mini_arcade_core/__init__.py +10 -1
- mini_arcade_core/cheats.py +235 -0
- mini_arcade_core/managers/__init__.py +14 -0
- mini_arcade_core/managers/base.py +91 -0
- mini_arcade_core/managers/entity_manager.py +38 -0
- mini_arcade_core/managers/overlay_manager.py +33 -0
- mini_arcade_core/scenes/__init__.py +2 -2
- mini_arcade_core/scenes/scene.py +24 -80
- {mini_arcade_core-0.9.7.dist-info → mini_arcade_core-0.9.9.dist-info}/METADATA +1 -1
- {mini_arcade_core-0.9.7.dist-info → mini_arcade_core-0.9.9.dist-info}/RECORD +12 -7
- {mini_arcade_core-0.9.7.dist-info → mini_arcade_core-0.9.9.dist-info}/WHEEL +0 -0
- {mini_arcade_core-0.9.7.dist-info → mini_arcade_core-0.9.9.dist-info}/licenses/LICENSE +0 -0
mini_arcade_core/__init__.py
CHANGED
|
@@ -10,10 +10,16 @@ from importlib.metadata import PackageNotFoundError, version
|
|
|
10
10
|
from typing import Callable, Type, Union
|
|
11
11
|
|
|
12
12
|
from mini_arcade_core.backend import Backend, Event, EventType
|
|
13
|
+
from mini_arcade_core.cheats import CheatCode, CheatManager
|
|
13
14
|
from mini_arcade_core.entity import Entity, KinematicEntity, SpriteEntity
|
|
14
15
|
from mini_arcade_core.game import Game, GameConfig
|
|
15
16
|
from mini_arcade_core.keymaps.keys import Key, keymap
|
|
16
|
-
from mini_arcade_core.scenes import
|
|
17
|
+
from mini_arcade_core.scenes import (
|
|
18
|
+
Scene,
|
|
19
|
+
SceneRegistry,
|
|
20
|
+
SceneServices,
|
|
21
|
+
register_scene,
|
|
22
|
+
)
|
|
17
23
|
from mini_arcade_core.two_d import (
|
|
18
24
|
Bounds2D,
|
|
19
25
|
KinematicData,
|
|
@@ -105,6 +111,9 @@ __all__ = [
|
|
|
105
111
|
"keymap",
|
|
106
112
|
"SceneRegistry",
|
|
107
113
|
"register_scene",
|
|
114
|
+
"CheatManager",
|
|
115
|
+
"CheatCode",
|
|
116
|
+
"SceneServices",
|
|
108
117
|
]
|
|
109
118
|
|
|
110
119
|
PACKAGE_NAME = "mini-arcade-core" # or whatever is in your pyproject.toml
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Cheats module for Mini Arcade Core.
|
|
3
|
+
Provides cheat codes and related functionality.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
from collections import deque
|
|
9
|
+
from dataclasses import dataclass
|
|
10
|
+
from enum import Enum
|
|
11
|
+
from typing import Callable, Deque, Dict, Optional, Sequence, TypeVar
|
|
12
|
+
|
|
13
|
+
# Justification: We want to keep the type variable name simple here.
|
|
14
|
+
# pylint: disable=invalid-name
|
|
15
|
+
TContext = TypeVar("TContext")
|
|
16
|
+
# pylint: enable=invalid-name
|
|
17
|
+
|
|
18
|
+
CheatCallback = Callable[[TContext], None]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dataclass(frozen=True)
|
|
22
|
+
class CheatCode:
|
|
23
|
+
"""
|
|
24
|
+
Represents a registered cheat code.
|
|
25
|
+
|
|
26
|
+
:ivar name (str): Unique name of the cheat code.
|
|
27
|
+
:ivar sequence (tuple[str, ...]): Sequence of key strings that trigger the cheat.
|
|
28
|
+
:ivar callback (CheatCallback): Function to call when the cheat is activated.
|
|
29
|
+
:ivar clear_buffer_on_match (bool): Whether to clear the input buffer after a match.
|
|
30
|
+
:ivar enabled (bool): Whether the cheat code is enabled.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
name: str
|
|
34
|
+
sequence: tuple[str, ...]
|
|
35
|
+
callback: CheatCallback
|
|
36
|
+
clear_buffer_on_match: bool = False
|
|
37
|
+
enabled: bool = True
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class CheatManager:
|
|
41
|
+
"""
|
|
42
|
+
Reusable cheat code matcher.
|
|
43
|
+
Keeps a rolling buffer of recent keys and triggers callbacks on sequence match.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
def __init__(
|
|
47
|
+
self,
|
|
48
|
+
buffer_size: int = 16,
|
|
49
|
+
*,
|
|
50
|
+
enabled: bool = True,
|
|
51
|
+
normalize: Optional[Callable[[str], str]] = None,
|
|
52
|
+
key_getter: Optional[Callable[[object], Optional[str]]] = None,
|
|
53
|
+
):
|
|
54
|
+
"""
|
|
55
|
+
:param buffer_size: Maximum size of the input buffer.
|
|
56
|
+
:type buffer_size: int
|
|
57
|
+
|
|
58
|
+
:param enabled: Whether the cheat manager is enabled.
|
|
59
|
+
:type enabled: bool
|
|
60
|
+
|
|
61
|
+
:param normalize: Optional function to normalize key strings.
|
|
62
|
+
:type normalize: Callable[[str], str] | None
|
|
63
|
+
|
|
64
|
+
:param key_getter: Optional function to extract key string from event object.
|
|
65
|
+
:type key_getter: Callable[[object], Optional[str]] | None
|
|
66
|
+
"""
|
|
67
|
+
self.enabled = enabled
|
|
68
|
+
self._buffer: Deque[str] = deque(maxlen=buffer_size)
|
|
69
|
+
self._codes: Dict[str, CheatCode] = {}
|
|
70
|
+
|
|
71
|
+
self._normalize = normalize or (lambda s: s.strip().upper())
|
|
72
|
+
# key_getter: how to extract a key from an engine/backend event object
|
|
73
|
+
self._key_getter = key_getter or self._default_key_getter
|
|
74
|
+
|
|
75
|
+
# Justification: We want to keep the number of arguments manageable here.
|
|
76
|
+
# pylint: disable=too-many-arguments
|
|
77
|
+
def register_code(
|
|
78
|
+
self,
|
|
79
|
+
name: str,
|
|
80
|
+
sequence: Sequence[str],
|
|
81
|
+
callback: CheatCallback,
|
|
82
|
+
*,
|
|
83
|
+
clear_buffer_on_match: bool = False,
|
|
84
|
+
enabled: bool = True,
|
|
85
|
+
):
|
|
86
|
+
"""
|
|
87
|
+
Register a new cheat code.
|
|
88
|
+
|
|
89
|
+
:param name: Unique name for the cheat code.
|
|
90
|
+
:type name: str
|
|
91
|
+
|
|
92
|
+
:param sequence: Sequence of key strings that trigger the cheat.
|
|
93
|
+
:type sequence: Sequence[str]
|
|
94
|
+
|
|
95
|
+
:param callback: Function to call when the cheat is activated.
|
|
96
|
+
:type callback: CheatCallback
|
|
97
|
+
|
|
98
|
+
:param clear_buffer_on_match: Whether to clear the input buffer after a match.
|
|
99
|
+
:type clear_buffer_on_match: bool
|
|
100
|
+
|
|
101
|
+
:param enabled: Whether the cheat code is enabled.
|
|
102
|
+
:type enabled: bool
|
|
103
|
+
"""
|
|
104
|
+
if not name:
|
|
105
|
+
raise ValueError("Cheat code name must be non-empty.")
|
|
106
|
+
if not sequence:
|
|
107
|
+
raise ValueError(
|
|
108
|
+
f"Cheat code '{name}' sequence must be non-empty."
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
norm_seq = tuple(self._normalize(k) for k in sequence)
|
|
112
|
+
self._codes[name] = CheatCode(
|
|
113
|
+
name=name,
|
|
114
|
+
sequence=norm_seq,
|
|
115
|
+
callback=callback,
|
|
116
|
+
clear_buffer_on_match=clear_buffer_on_match,
|
|
117
|
+
enabled=enabled,
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
# pylint: enable=too-many-arguments
|
|
121
|
+
|
|
122
|
+
def unregister_code(self, name: str):
|
|
123
|
+
"""
|
|
124
|
+
Unregister a cheat code by name.
|
|
125
|
+
|
|
126
|
+
:param name: Name of the cheat code to unregister.
|
|
127
|
+
:type name: str
|
|
128
|
+
"""
|
|
129
|
+
self._codes.pop(name, None)
|
|
130
|
+
|
|
131
|
+
def clear_buffer(self):
|
|
132
|
+
"""Clear the input buffer."""
|
|
133
|
+
self._buffer.clear()
|
|
134
|
+
|
|
135
|
+
def process_event(self, event: object, context: TContext) -> list[str]:
|
|
136
|
+
"""
|
|
137
|
+
Call from Scene when a key is pressed.
|
|
138
|
+
Returns list of cheat names matched (often 0 or 1).
|
|
139
|
+
|
|
140
|
+
:param event: The event object from the backend/engine.
|
|
141
|
+
:type event: object
|
|
142
|
+
|
|
143
|
+
:param context: Context object passed to cheat callbacks.
|
|
144
|
+
:type context: TContext
|
|
145
|
+
"""
|
|
146
|
+
if not self.enabled:
|
|
147
|
+
return []
|
|
148
|
+
key = self._key_getter(event)
|
|
149
|
+
if not key:
|
|
150
|
+
return []
|
|
151
|
+
return self.process_key(key, context)
|
|
152
|
+
|
|
153
|
+
def process_key(self, key: str, context: TContext) -> list[str]:
|
|
154
|
+
"""
|
|
155
|
+
Pure method for tests: feed a key string directly.
|
|
156
|
+
|
|
157
|
+
:param key: The key string to process.
|
|
158
|
+
:type key: str
|
|
159
|
+
|
|
160
|
+
:param context: Context object passed to cheat callbacks.
|
|
161
|
+
:type context: TContext
|
|
162
|
+
|
|
163
|
+
:return: List of cheat names matched.
|
|
164
|
+
:rtype: list[str]
|
|
165
|
+
"""
|
|
166
|
+
if not self.enabled:
|
|
167
|
+
return []
|
|
168
|
+
|
|
169
|
+
k = self._normalize(key)
|
|
170
|
+
if not k:
|
|
171
|
+
return []
|
|
172
|
+
|
|
173
|
+
self._buffer.append(k)
|
|
174
|
+
buf = tuple(self._buffer)
|
|
175
|
+
|
|
176
|
+
matched: list[str] = []
|
|
177
|
+
# Check if buffer ends with any cheat sequence
|
|
178
|
+
for code in self._codes.values():
|
|
179
|
+
if not code.enabled:
|
|
180
|
+
continue
|
|
181
|
+
seq = code.sequence
|
|
182
|
+
if len(seq) > len(buf):
|
|
183
|
+
continue
|
|
184
|
+
if buf[-len(seq) :] == seq:
|
|
185
|
+
code.callback(context)
|
|
186
|
+
matched.append(code.name)
|
|
187
|
+
if code.clear_buffer_on_match:
|
|
188
|
+
self.clear_buffer()
|
|
189
|
+
break # buffer changed; stop early
|
|
190
|
+
|
|
191
|
+
return matched
|
|
192
|
+
|
|
193
|
+
@staticmethod
|
|
194
|
+
def _default_key_getter(event: object) -> Optional[str]:
|
|
195
|
+
"""
|
|
196
|
+
Best-effort extraction:
|
|
197
|
+
- event.key
|
|
198
|
+
- event.key_code
|
|
199
|
+
- event.code
|
|
200
|
+
- event.scancode
|
|
201
|
+
- dict-like {"key": "..."}
|
|
202
|
+
Adjust/override with key_getter in your engine if needed.
|
|
203
|
+
|
|
204
|
+
:param event: The event object.
|
|
205
|
+
:type event: object
|
|
206
|
+
|
|
207
|
+
:return: Extracted key string, or None if not found.
|
|
208
|
+
:rtype: Optional[str]
|
|
209
|
+
"""
|
|
210
|
+
if event is None:
|
|
211
|
+
return None
|
|
212
|
+
|
|
213
|
+
# dict-like
|
|
214
|
+
if isinstance(event, dict):
|
|
215
|
+
v = (
|
|
216
|
+
event.get("key")
|
|
217
|
+
or event.get("key_code")
|
|
218
|
+
or event.get("code")
|
|
219
|
+
or event.get("scancode")
|
|
220
|
+
)
|
|
221
|
+
if isinstance(v, Enum):
|
|
222
|
+
return v.name
|
|
223
|
+
return str(v) if v is not None else None
|
|
224
|
+
|
|
225
|
+
# object-like
|
|
226
|
+
for attr in ("key", "key_code", "code", "scancode"):
|
|
227
|
+
if hasattr(event, attr):
|
|
228
|
+
v = getattr(event, attr)
|
|
229
|
+
if v is None:
|
|
230
|
+
continue
|
|
231
|
+
if isinstance(v, Enum):
|
|
232
|
+
return v.name # <-- THIS is the important bit
|
|
233
|
+
return str(v)
|
|
234
|
+
|
|
235
|
+
return None
|
|
@@ -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"]
|
mini_arcade_core/scenes/scene.py
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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__(
|
|
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
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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,17 +1,22 @@
|
|
|
1
|
-
mini_arcade_core/__init__.py,sha256=
|
|
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
|
|
5
5
|
mini_arcade_core/backend/types.py,sha256=SuiwXGNmXCZxfPsww6zj3V_NK7k4jpoCuzMn19afS-g,175
|
|
6
|
+
mini_arcade_core/cheats.py,sha256=J0HPLUC6sARXNl_CtUaWhWoo9A0vEjQcIHP6XJUPrNQ,7133
|
|
6
7
|
mini_arcade_core/entity.py,sha256=vDe2v7GajyGaqckBYeD3cjs--pOTFrDNhMIdf7PZsJQ,1759
|
|
7
8
|
mini_arcade_core/game.py,sha256=C8flMXn_DMHWDmr5FVrTey_nUHabwja8wSaialNMcLg,8526
|
|
8
9
|
mini_arcade_core/keymaps/__init__.py,sha256=_5Y5_61XT5TsOhbb6p2EPzvjCNN9hCPoxTgj_TAfBvA,258
|
|
9
10
|
mini_arcade_core/keymaps/keys.py,sha256=LTg20SwLBI3kpPIiTNpq2yBft_QUGj-iNFSNm9M-Fus,3010
|
|
10
11
|
mini_arcade_core/keymaps/sdl.py,sha256=Tb0amkbmYjYkEkYnMZ6i9QWjwXBkEHIm13-gEMUYENM,2060
|
|
11
|
-
mini_arcade_core/
|
|
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
|
|
12
17
|
mini_arcade_core/scenes/autoreg.py,sha256=b4V0jaA65I2hnT2f___rg_pT556OjrtoNjIRdZrXBaI,1009
|
|
13
18
|
mini_arcade_core/scenes/registry.py,sha256=0B3iSvepydwMpELQz8cRaQeAU0pR1Fz9O1YtWshLjQw,3226
|
|
14
|
-
mini_arcade_core/scenes/scene.py,sha256=
|
|
19
|
+
mini_arcade_core/scenes/scene.py,sha256=MrHAHf-su6xrLXi4y1opxJWy0YF-yLfSN6rOvSHPqCc,2384
|
|
15
20
|
mini_arcade_core/two_d/__init__.py,sha256=iWjm39RYDEshxSmiIWyGWa6Qr9O2gnHfOpzrl63FUro,626
|
|
16
21
|
mini_arcade_core/two_d/boundaries2d.py,sha256=H1HkCR1422MkQIEve2DFKvnav4RpvtLx-qTMxzmdDMQ,2610
|
|
17
22
|
mini_arcade_core/two_d/collision2d.py,sha256=jR5bOmqUaedxRzwFoKBgn7k-ozwklB4RP9pUTVk6aUw,1716
|
|
@@ -20,7 +25,7 @@ mini_arcade_core/two_d/kinematics2d.py,sha256=NFMiIzDYqDquyg_EhD7EQBJ_Sz4RncmkEj
|
|
|
20
25
|
mini_arcade_core/two_d/physics2d.py,sha256=qIq86qWVuvcnLIMEPH6xx7XQO4tQhfiMZY6FseuVOR8,1636
|
|
21
26
|
mini_arcade_core/ui/__init__.py,sha256=RmcZXfBFFmL09j_Bo1LHagRjiKYajuySPilIUNjc3KQ,248
|
|
22
27
|
mini_arcade_core/ui/menu.py,sha256=J3hYY46xOHLN65WSet4-cnQU7L5pu48scjLJUW9IkEM,13681
|
|
23
|
-
mini_arcade_core-0.9.
|
|
24
|
-
mini_arcade_core-0.9.
|
|
25
|
-
mini_arcade_core-0.9.
|
|
26
|
-
mini_arcade_core-0.9.
|
|
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,,
|
|
File without changes
|
|
File without changes
|