mini-arcade-core 0.9.0__py3-none-any.whl → 0.9.2__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.
@@ -19,6 +19,7 @@ from .collision2d import RectCollider
19
19
  from .entity import Entity, KinematicEntity, SpriteEntity
20
20
  from .game import Game, GameConfig
21
21
  from .geometry2d import Bounds2D, Position2D, Size2D
22
+ from .keys import Key, keymap
22
23
  from .kinematics2d import KinematicData
23
24
  from .physics2d import Velocity2D
24
25
  from .scene import Scene
@@ -69,6 +70,8 @@ __all__ = [
69
70
  "VerticalWrap",
70
71
  "RectSprite",
71
72
  "RectKinematic",
73
+ "Key",
74
+ "keymap",
72
75
  ]
73
76
 
74
77
  PACKAGE_NAME = "mini-arcade-core" # or whatever is in your pyproject.toml
@@ -9,6 +9,8 @@ from dataclasses import dataclass
9
9
  from enum import Enum, auto
10
10
  from typing import Iterable, Optional, Protocol, Tuple, Union
11
11
 
12
+ from .keys import Key
13
+
12
14
  Color = Union[Tuple[int, int, int], Tuple[int, int, int, int]]
13
15
 
14
16
 
@@ -57,7 +59,8 @@ class Event:
57
59
  - key: integer key code (e.g. ESC = 27), or None if not applicable
58
60
 
59
61
  :ivar type (EventType): The type of event.
60
- :ivar key (int | None): The key code associated with the event, if any.
62
+ :ivar key (Key | None): The key associated with the event, if any.
63
+ :ivar key_code (int | None): The key code associated with the event, if any.
61
64
  :ivar scancode (int | None): The hardware scancode of the key, if any.
62
65
  :ivar mod (int | None): Modifier keys bitmask, if any.
63
66
  :ivar repeat (bool | None): Whether this key event is a repeat, if any.
@@ -72,7 +75,8 @@ class Event:
72
75
  """
73
76
 
74
77
  type: EventType
75
- key: Optional[int] = None
78
+ key: Key | None = None # Use Key enum for better clarity
79
+ key_code: Optional[int] = None
76
80
 
77
81
  # Keyboard extras (optional)
78
82
  scancode: Optional[int] = None
@@ -210,6 +214,18 @@ class Backend(Protocol):
210
214
  :type color: Color
211
215
  """
212
216
 
217
+ def measure_text(self, text: str) -> tuple[int, int]:
218
+ """
219
+ Measure the width and height of the given text string in pixels.
220
+
221
+ :param text: The text string to measure.
222
+ :type text: str
223
+
224
+ :return: A tuple (width, height) in pixels.
225
+ :rtype: tuple[int, int]
226
+ """
227
+ raise NotImplementedError
228
+
213
229
  def capture_frame(self, path: str | None = None) -> bytes | None:
214
230
  """
215
231
  Capture the current frame.
File without changes
@@ -0,0 +1,98 @@
1
+ """
2
+ SDL keymap for mini arcade core.
3
+ Maps SDL keycodes to mini arcade core Key enums.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ from mini_arcade_core.keys import Key
9
+
10
+ # SDL keycodes you need (minimal set)
11
+ SDLK_ESCAPE = 27
12
+ SDLK_RETURN = 13
13
+ SDLK_SPACE = 32
14
+ SDLK_TAB = 9
15
+ SDLK_BACKSPACE = 8
16
+
17
+ SDLK_UP = 1073741906
18
+ SDLK_DOWN = 1073741905
19
+ SDLK_LEFT = 1073741904
20
+ SDLK_RIGHT = 1073741903
21
+
22
+ F1 = 1073741882
23
+ F2 = 1073741883
24
+ F3 = 1073741884
25
+ F4 = 1073741885
26
+ F5 = 1073741886
27
+ F6 = 1073741887
28
+ F7 = 1073741888
29
+ F8 = 1073741889
30
+ F9 = 1073741890
31
+ F10 = 1073741891
32
+ F11 = 1073741892
33
+ F12 = 1073741893
34
+
35
+ SDL_KEYCODE_TO_KEY: dict[int, Key] = {
36
+ # Letters
37
+ ord("a"): Key.A,
38
+ ord("b"): Key.B,
39
+ ord("c"): Key.C,
40
+ ord("d"): Key.D,
41
+ ord("e"): Key.E,
42
+ ord("f"): Key.F,
43
+ ord("g"): Key.G,
44
+ ord("h"): Key.H,
45
+ ord("i"): Key.I,
46
+ ord("j"): Key.J,
47
+ ord("k"): Key.K,
48
+ ord("l"): Key.L,
49
+ ord("m"): Key.M,
50
+ ord("n"): Key.N,
51
+ ord("o"): Key.O,
52
+ ord("p"): Key.P,
53
+ ord("q"): Key.Q,
54
+ ord("r"): Key.R,
55
+ ord("s"): Key.S,
56
+ ord("t"): Key.T,
57
+ ord("u"): Key.U,
58
+ ord("v"): Key.V,
59
+ ord("w"): Key.W,
60
+ ord("x"): Key.X,
61
+ ord("y"): Key.Y,
62
+ ord("z"): Key.Z,
63
+ # Arrows
64
+ SDLK_UP: Key.UP,
65
+ SDLK_DOWN: Key.DOWN,
66
+ SDLK_LEFT: Key.LEFT,
67
+ SDLK_RIGHT: Key.RIGHT,
68
+ # Common
69
+ SDLK_ESCAPE: Key.ESCAPE,
70
+ SDLK_SPACE: Key.SPACE,
71
+ SDLK_RETURN: Key.ENTER,
72
+ SDLK_TAB: Key.TAB,
73
+ SDLK_BACKSPACE: Key.BACKSPACE,
74
+ # Numbers
75
+ ord("0"): Key.NUM_0,
76
+ ord("1"): Key.NUM_1,
77
+ ord("2"): Key.NUM_2,
78
+ ord("3"): Key.NUM_3,
79
+ ord("4"): Key.NUM_4,
80
+ ord("5"): Key.NUM_5,
81
+ ord("6"): Key.NUM_6,
82
+ ord("7"): Key.NUM_7,
83
+ ord("8"): Key.NUM_8,
84
+ ord("9"): Key.NUM_9,
85
+ # Function keys
86
+ F1: Key.F1,
87
+ F2: Key.F2,
88
+ F3: Key.F3,
89
+ F4: Key.F4,
90
+ F5: Key.F5,
91
+ F6: Key.F6,
92
+ F7: Key.F7,
93
+ F8: Key.F8,
94
+ F9: Key.F9,
95
+ F10: Key.F10,
96
+ F11: Key.F11,
97
+ F12: Key.F12,
98
+ }
@@ -0,0 +1,160 @@
1
+ """
2
+ Mini Arcade Core key definitions.
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+ from dataclasses import dataclass
8
+ from enum import Enum, auto
9
+
10
+
11
+ class Key(Enum):
12
+ """
13
+ Enumeration of common keyboard keys.
14
+
15
+ :ivar A-Z: Letter keys.
16
+ :ivar arrow_up, arrow_down, arrow_left, arrow_right: Arrow keys.
17
+ :ivar escape, space, enter, tab, backspace: Common control keys.
18
+ :ivar num_0 - num_9: Number keys.
19
+ :ivar f1 - f12: Function keys.
20
+ """
21
+
22
+ # Letters
23
+ A = auto()
24
+ B = auto()
25
+ C = auto()
26
+ D = auto()
27
+ E = auto()
28
+ F = auto()
29
+ G = auto()
30
+ H = auto()
31
+ I = auto()
32
+ J = auto()
33
+ K = auto()
34
+ L = auto()
35
+ M = auto()
36
+ N = auto()
37
+ O = auto()
38
+ P = auto()
39
+ Q = auto()
40
+ R = auto()
41
+ S = auto()
42
+ T = auto()
43
+ U = auto()
44
+ V = auto()
45
+ W = auto()
46
+ X = auto()
47
+ Y = auto()
48
+ Z = auto()
49
+
50
+ # Arrows
51
+ UP = auto()
52
+ DOWN = auto()
53
+ LEFT = auto()
54
+ RIGHT = auto()
55
+
56
+ # Common
57
+ ESCAPE = auto()
58
+ SPACE = auto()
59
+ ENTER = auto()
60
+ TAB = auto()
61
+ BACKSPACE = auto()
62
+
63
+ # Numbers
64
+ NUM_0 = auto()
65
+ NUM_1 = auto()
66
+ NUM_2 = auto()
67
+ NUM_3 = auto()
68
+ NUM_4 = auto()
69
+ NUM_5 = auto()
70
+ NUM_6 = auto()
71
+ NUM_7 = auto()
72
+ NUM_8 = auto()
73
+ NUM_9 = auto()
74
+
75
+ # Function keys
76
+ F1 = auto()
77
+ F2 = auto()
78
+ F3 = auto()
79
+ F4 = auto()
80
+ F5 = auto()
81
+ F6 = auto()
82
+ F7 = auto()
83
+ F8 = auto()
84
+ F9 = auto()
85
+ F10 = auto()
86
+ F11 = auto()
87
+ F12 = auto()
88
+
89
+
90
+ # Justification: Simple alias object for keys
91
+ # pylint: disable=too-many-instance-attributes
92
+ @dataclass(frozen=True)
93
+ class _Keys:
94
+ # alias object so user code can do keys.w, keys.arrow_up, etc.
95
+ a: Key = Key.A
96
+ b: Key = Key.B
97
+ c: Key = Key.C
98
+ d: Key = Key.D
99
+ e: Key = Key.E
100
+ f: Key = Key.F
101
+ g: Key = Key.G
102
+ h: Key = Key.H
103
+ i: Key = Key.I
104
+ j: Key = Key.J
105
+ k: Key = Key.K
106
+ l: Key = Key.L
107
+ m: Key = Key.M
108
+ n: Key = Key.N
109
+ o: Key = Key.O
110
+ p: Key = Key.P
111
+ q: Key = Key.Q
112
+ r: Key = Key.R
113
+ s: Key = Key.S
114
+ t: Key = Key.T
115
+ u: Key = Key.U
116
+ v: Key = Key.V
117
+ w: Key = Key.W
118
+ x: Key = Key.X
119
+ y: Key = Key.Y
120
+ z: Key = Key.Z
121
+
122
+ up: Key = Key.UP
123
+ down: Key = Key.DOWN
124
+ left: Key = Key.LEFT
125
+ right: Key = Key.RIGHT
126
+
127
+ escape: Key = Key.ESCAPE
128
+ space: Key = Key.SPACE
129
+ enter: Key = Key.ENTER
130
+ tab: Key = Key.TAB
131
+ backspace: Key = Key.BACKSPACE
132
+
133
+ num_0: Key = Key.NUM_0
134
+ num_1: Key = Key.NUM_1
135
+ num_2: Key = Key.NUM_2
136
+ num_3: Key = Key.NUM_3
137
+ num_4: Key = Key.NUM_4
138
+ num_5: Key = Key.NUM_5
139
+ num_6: Key = Key.NUM_6
140
+ num_7: Key = Key.NUM_7
141
+ num_8: Key = Key.NUM_8
142
+ num_9: Key = Key.NUM_9
143
+
144
+ f1: Key = Key.F1
145
+ f2: Key = Key.F2
146
+ f3: Key = Key.F3
147
+ f4: Key = Key.F4
148
+ f5: Key = Key.F5
149
+ f6: Key = Key.F6
150
+ f7: Key = Key.F7
151
+ f8: Key = Key.F8
152
+ f9: Key = Key.F9
153
+ f10: Key = Key.F10
154
+ f11: Key = Key.F11
155
+ f12: Key = Key.F12
156
+
157
+
158
+ # pylint: enable=too-many-instance-attributes
159
+
160
+ keymap = _Keys()
@@ -8,6 +8,7 @@ from dataclasses import dataclass
8
8
  from typing import Callable, Sequence
9
9
 
10
10
  from mini_arcade_core.backend import Backend, Color, Event, EventType
11
+ from mini_arcade_core.geometry2d import Size2D
11
12
 
12
13
  MenuAction = Callable[[], None]
13
14
 
@@ -25,6 +26,9 @@ class MenuItem:
25
26
  on_select: MenuAction
26
27
 
27
28
 
29
+ # Justification: Data container for styling options needs
30
+ # some attributes.
31
+ # pylint: disable=too-many-instance-attributes
28
32
  @dataclass
29
33
  class MenuStyle:
30
34
  """
@@ -37,7 +41,42 @@ class MenuStyle:
37
41
 
38
42
  normal: Color = (220, 220, 220)
39
43
  selected: Color = (255, 255, 0)
44
+
45
+ # Layout
40
46
  line_height: int = 28
47
+ title_color: Color = (255, 255, 255)
48
+ title_spacing: int = 18
49
+
50
+ # Scene background (solid)
51
+ background_color: Color | None = None # e.g. BACKGROUND
52
+
53
+ # Optional full-screen overlay (dim)
54
+ overlay_color: Color | None = None # e.g. (0,0,0,0.5) for pause
55
+
56
+ # Panel behind content (optional)
57
+ panel_color: Color | None = None
58
+ panel_padding_x: int = 24
59
+ panel_padding_y: int = 18
60
+
61
+ # Button rendering (optional)
62
+ button_enabled: bool = False
63
+ button_fill: Color = (30, 30, 30, 1.0)
64
+ button_border: Color = (120, 120, 120, 1.0)
65
+ button_selected_border: Color = (255, 255, 0, 1.0)
66
+ button_width: int | None = (
67
+ None # if None -> auto-fit to longest label + padding
68
+ )
69
+ button_height: int = 40
70
+ button_gap: int = 20
71
+ button_padding_x: int = 20 # used for auto-fit + text centering
72
+
73
+ # Hint footer (optional)
74
+ hint: str | None = None
75
+ hint_color: Color = (200, 200, 200)
76
+ hint_margin_bottom: int = 50
77
+
78
+
79
+ # pylint: enable=too-many-instance-attributes
41
80
 
42
81
 
43
82
  class Menu:
@@ -47,8 +86,8 @@ class Menu:
47
86
  self,
48
87
  items: Sequence[MenuItem],
49
88
  *,
50
- x: int = 40,
51
- y: int = 40,
89
+ viewport: Size2D | None = None,
90
+ title: str | None = None,
52
91
  style: MenuStyle | None = None,
53
92
  ):
54
93
  """
@@ -62,8 +101,8 @@ class Menu:
62
101
  :type style: MenuStyle | None
63
102
  """
64
103
  self.items = list(items)
65
- self.x = x
66
- self.y = y
104
+ self.viewport = viewport
105
+ self.title = title
67
106
  self.style = style or MenuStyle()
68
107
  self.selected_index = 0
69
108
 
@@ -114,6 +153,36 @@ class Menu:
114
153
  elif event.key == select_key:
115
154
  self.select()
116
155
 
156
+ def _measure_content(self, surface: Backend) -> tuple[int, int, int]:
157
+ """
158
+ Returns (content_width, content_height, title_height)
159
+ where content is items-only (no padding).
160
+ """
161
+ if not self.items and not self.title:
162
+ return 0, 0, 0
163
+
164
+ max_w = 0
165
+ title_h = 0
166
+
167
+ if self.title:
168
+ tw, th = surface.measure_text(self.title)
169
+ max_w = max(max_w, tw)
170
+ title_h = th
171
+
172
+ # Items
173
+ for it in self.items:
174
+ w, _ = surface.measure_text(it.label)
175
+ max_w = max(max_w, w)
176
+
177
+ items_h = len(self.items) * self.style.line_height
178
+
179
+ # Total content height includes title block if present
180
+ content_h = items_h
181
+ if self.title:
182
+ content_h += title_h + self.style.title_spacing
183
+
184
+ return max_w, content_h, title_h
185
+
117
186
  def draw(self, surface: Backend):
118
187
  """
119
188
  Draw the menu onto the given backend surface.
@@ -121,15 +190,182 @@ class Menu:
121
190
  :param surface: The backend surface to draw on.
122
191
  :type surface: Backend
123
192
  """
193
+ if self.viewport is None:
194
+ raise ValueError(
195
+ "Menu requires viewport=Size2D for centering/layout"
196
+ )
197
+
198
+ vw, vh = self.viewport.width, self.viewport.height
199
+
200
+ # 0) Solid background (for main menus)
201
+ if self.style.background_color is not None:
202
+ surface.draw_rect(0, 0, vw, vh, color=self.style.background_color)
203
+
204
+ # 1) Overlay (for pause, etc.)
205
+ if self.style.overlay_color is not None:
206
+ surface.draw_rect(0, 0, vw, vh, color=self.style.overlay_color)
207
+
208
+ # 2) Compute menu content bounds (panel area)
209
+ content_w, content_h, title_h = self._measure_content(surface)
210
+
211
+ pad_x, pad_y = self.style.panel_padding_x, self.style.panel_padding_y
212
+ panel_w = content_w + pad_x * 2
213
+ panel_h = content_h + pad_y * 2
214
+
215
+ x0 = (vw - panel_w) // 2
216
+ y0 = (vh - panel_h) // 2
217
+
218
+ # Optional vertical offset if you add it later:
219
+ # y0 += self.style.center_offset_y
220
+
221
+ # 3) Panel (optional)
222
+ if self.style.panel_color is not None:
223
+ surface.draw_rect(
224
+ x0, y0, panel_w, panel_h, color=self.style.panel_color
225
+ )
226
+
227
+ # 4) Draw title + items
228
+ cursor_y = y0 + pad_y
229
+ x_center = x0 + (panel_w // 2)
230
+
231
+ if self.title:
232
+ self._draw_text_center_x(
233
+ surface,
234
+ x_center,
235
+ cursor_y,
236
+ self.title,
237
+ color=self.style.title_color,
238
+ )
239
+ cursor_y += title_h + self.style.title_spacing
240
+
241
+ if self.style.button_enabled:
242
+ self._draw_buttons(surface, x_center, cursor_y)
243
+ else:
244
+ self._draw_text_items(surface, x_center, cursor_y)
245
+
246
+ # 5) Hint footer (optional)
247
+ if self.style.hint:
248
+ self._draw_text_center_x(
249
+ surface,
250
+ vw // 2,
251
+ vh - self.style.hint_margin_bottom,
252
+ self.style.hint,
253
+ color=self.style.hint_color,
254
+ )
255
+
256
+ def _draw_text_items(
257
+ self, surface: Backend, x_center: int, cursor_y: int
258
+ ) -> None:
124
259
  for i, item in enumerate(self.items):
125
260
  color = (
126
261
  self.style.selected
127
262
  if i == self.selected_index
128
263
  else self.style.normal
129
264
  )
130
- surface.draw_text(
131
- self.x,
132
- self.y + i * self.style.line_height,
265
+ self._draw_text_center_x(
266
+ surface,
267
+ x_center,
268
+ cursor_y + i * self.style.line_height,
133
269
  item.label,
134
270
  color=color,
135
271
  )
272
+
273
+ # Justification: Local variables for layout calculations
274
+ # pylint: disable=too-many-locals
275
+ def _draw_buttons(
276
+ self, surface: Backend, x_center: int, cursor_y: int
277
+ ) -> None:
278
+ # Determine button width: fixed or auto-fit
279
+ if self.style.button_width is not None:
280
+ bw = self.style.button_width
281
+ else:
282
+ max_label_w = 0
283
+ for it in self.items:
284
+ w, _ = surface.measure_text(it.label)
285
+ max_label_w = max(max_label_w, w)
286
+ bw = max_label_w + self.style.button_padding_x * 2
287
+
288
+ bh = self.style.button_height
289
+ gap = self.style.button_gap
290
+
291
+ # We treat cursor_y as “top of first button”
292
+ for i, item in enumerate(self.items):
293
+ y = cursor_y + i * (bh + gap)
294
+ x = x_center - bw // 2
295
+
296
+ selected = i == self.selected_index
297
+ border = (
298
+ self.style.button_selected_border
299
+ if selected
300
+ else self.style.button_border
301
+ )
302
+
303
+ # Border rect
304
+ surface.draw_rect(x - 4, y - 4, bw + 8, bh + 8, color=border)
305
+ # Fill rect
306
+ surface.draw_rect(x, y, bw, bh, color=self.style.button_fill)
307
+
308
+ # Label color
309
+ text_color = self.style.selected if selected else self.style.normal
310
+ tw, th = surface.measure_text(item.label)
311
+ tx = x + (bw - tw) // 2
312
+ ty = y + (bh - th) // 2
313
+ surface.draw_text(tx, ty, item.label, color=text_color)
314
+
315
+ # pylint: enable=too-many-locals
316
+
317
+ def _measure_content(self, surface: Backend) -> tuple[int, int, int]:
318
+ # If button mode: content height differs (button_height + gaps)
319
+ max_w = 0
320
+ title_h = 0
321
+
322
+ if self.title:
323
+ tw, th = surface.measure_text(self.title)
324
+ max_w = max(max_w, tw)
325
+ title_h = th
326
+
327
+ if not self.items:
328
+ content_h = 0
329
+ if self.title:
330
+ content_h = title_h
331
+ return max_w, content_h, title_h
332
+
333
+ if self.style.button_enabled:
334
+ # width: either fixed or auto-fit
335
+ if self.style.button_width is not None:
336
+ items_w = self.style.button_width
337
+ else:
338
+ max_label_w = 0
339
+ for it in self.items:
340
+ w, _ = surface.measure_text(it.label)
341
+ max_label_w = max(max_label_w, w)
342
+ items_w = max_label_w + self.style.button_padding_x * 2
343
+
344
+ max_w = max(max_w, items_w)
345
+
346
+ bh = self.style.button_height
347
+ gap = self.style.button_gap
348
+ items_h = len(self.items) * bh + (len(self.items) - 1) * gap
349
+ else:
350
+ for it in self.items:
351
+ w, _ = surface.measure_text(it.label)
352
+ max_w = max(max_w, w)
353
+ items_h = len(self.items) * self.style.line_height
354
+
355
+ content_h = items_h
356
+ if self.title:
357
+ content_h += title_h + self.style.title_spacing
358
+
359
+ return max_w, content_h, title_h
360
+
361
+ @staticmethod
362
+ def _draw_text_center_x(
363
+ surface: Backend,
364
+ x_center: int,
365
+ y: int,
366
+ text: str,
367
+ *,
368
+ color: Color,
369
+ ) -> None:
370
+ w, _ = surface.measure_text(text)
371
+ surface.draw_text(x_center - (w // 2), y, text, color=color)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mini-arcade-core
3
- Version: 0.9.0
3
+ Version: 0.9.2
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,16 +1,19 @@
1
- mini_arcade_core/__init__.py,sha256=2PBNxk-rxjJxPvF6PvpdJ_rat0knyo6a-VRI8sROofI,2554
2
- mini_arcade_core/backend.py,sha256=Q1yNNLX0Hh-1ItUWDV8k1QHuoGPNKHYeoTHT_CxKGPk,6339
1
+ mini_arcade_core/__init__.py,sha256=7Ioji-MpfSQq4Ok3agVzP4mvcTNiThrY-DTDmVYFKo0,2609
2
+ mini_arcade_core/backend.py,sha256=kB666RiMSpFaxVEi0KIOPGjh4cdCPWDs5vz8MdY37G4,6854
3
3
  mini_arcade_core/boundaries2d.py,sha256=H1HkCR1422MkQIEve2DFKvnav4RpvtLx-qTMxzmdDMQ,2610
4
4
  mini_arcade_core/collision2d.py,sha256=iq800wsoYQNft3SA-W4jeY1wXhbpz2E7IkIorZBI238,1718
5
5
  mini_arcade_core/entity.py,sha256=1AuE-_iMJYHxSyG783fsyByKK8Gx4vWWKMCEPjtgHXw,1776
6
6
  mini_arcade_core/game.py,sha256=2DaFRdu7ogrwukh2MRnTh0Hy2r1XcaGSHEpLBNxfqIU,7273
7
7
  mini_arcade_core/geometry2d.py,sha256=js791mMpsE_YbEoqtTOsOxNSflvKgSk6VeVKhj9N318,1282
8
+ mini_arcade_core/keymaps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ mini_arcade_core/keymaps/sdl.py,sha256=lRBvgTfdT7enN0qV7S2ZoLsPAWpaiSHzsyVGDlyTzQA,1924
10
+ mini_arcade_core/keys.py,sha256=LTg20SwLBI3kpPIiTNpq2yBft_QUGj-iNFSNm9M-Fus,3010
8
11
  mini_arcade_core/kinematics2d.py,sha256=twBx-1jEwdknIJEyYBUg4VZyAvw1d7pGHaGFd36TPbo,2085
9
12
  mini_arcade_core/physics2d.py,sha256=qIq86qWVuvcnLIMEPH6xx7XQO4tQhfiMZY6FseuVOR8,1636
10
13
  mini_arcade_core/scene.py,sha256=e0E81aHt6saYiGfA-1V2II1yWwcZfvqGTRAv8pZnQtY,3865
11
14
  mini_arcade_core/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
- mini_arcade_core/ui/menu.py,sha256=2CbsMvqebZWbUdhilhyTNDL1LGcdaPqHFsIM_J2MWK8,3636
13
- mini_arcade_core-0.9.0.dist-info/METADATA,sha256=eLtfBDXL_S0FRergm-Jr4JqgS4S0kDnfmdsVFuVAgEM,8188
14
- mini_arcade_core-0.9.0.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
15
- mini_arcade_core-0.9.0.dist-info/licenses/LICENSE,sha256=3lHAuV0584cVS5vAqi2uC6GcsVgxUijvwvtZckyvaZ4,1096
16
- mini_arcade_core-0.9.0.dist-info/RECORD,,
15
+ mini_arcade_core/ui/menu.py,sha256=79krwtWkGXKLSxG37PZsIIeFLayx9OTDN6esJepthlE,11343
16
+ mini_arcade_core-0.9.2.dist-info/METADATA,sha256=6NW5an292zZXvaDVoLUKayukctCRzizdbHqM0a9vZ5g,8188
17
+ mini_arcade_core-0.9.2.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
18
+ mini_arcade_core-0.9.2.dist-info/licenses/LICENSE,sha256=3lHAuV0584cVS5vAqi2uC6GcsVgxUijvwvtZckyvaZ4,1096
19
+ mini_arcade_core-0.9.2.dist-info/RECORD,,