mini-arcade-core 0.6.0__py3-none-any.whl → 0.7.0__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.
@@ -57,6 +57,11 @@ class Backend(Protocol):
57
57
  Concrete backends will translate their native events into core Event objects.
58
58
  """
59
59
 
60
+ def set_clear_color(self, r: int, g: int, b: int) -> None:
61
+ """
62
+ Set the background/clear color used by begin_frame.
63
+ """
64
+
60
65
  def begin_frame(self) -> None:
61
66
  """
62
67
  Prepare for drawing a new frame (e.g. clear screen).
@@ -67,9 +72,34 @@ class Backend(Protocol):
67
72
  Present the frame to the user (swap buffers).
68
73
  """
69
74
 
70
- def draw_rect(self, x: int, y: int, w: int, h: int) -> None:
75
+ # Justification: Simple drawing API for now
76
+ # pylint: disable=too-many-arguments,too-many-positional-arguments
77
+ def draw_rect(
78
+ self,
79
+ x: int,
80
+ y: int,
81
+ w: int,
82
+ h: int,
83
+ color: tuple[int, int, int] = (255, 255, 255),
84
+ ) -> None:
71
85
  """
72
86
  Draw a filled rectangle in some default color.
73
87
 
74
88
  We'll keep this minimal for now; later we can extend with colors/sprites.
75
89
  """
90
+
91
+ # pylint: enable=too-many-arguments,too-many-positional-arguments
92
+
93
+ def draw_text(
94
+ self,
95
+ x: int,
96
+ y: int,
97
+ text: str,
98
+ color: tuple[int, int, int] = (255, 255, 255),
99
+ ) -> None:
100
+ """
101
+ Draw text at the given position in a default font and color.
102
+
103
+ Backends may ignore advanced styling for now; this is just to render
104
+ simple labels like menu items, scores, etc.
105
+ """
mini_arcade_core/game.py CHANGED
@@ -5,6 +5,7 @@ Game core module defining the Game class and configuration.
5
5
  from __future__ import annotations
6
6
 
7
7
  from dataclasses import dataclass
8
+ from time import perf_counter, sleep
8
9
  from typing import TYPE_CHECKING
9
10
 
10
11
  from .backend import Backend
@@ -31,7 +32,7 @@ class GameConfig:
31
32
  title: str = "Mini Arcade Game"
32
33
  fps: int = 60
33
34
  background_color: tuple[int, int, int] = (0, 0, 0)
34
- backend: type[Backend] | None = None
35
+ backend: Backend | None = None
35
36
 
36
37
 
37
38
  class Game:
@@ -40,22 +41,31 @@ class Game:
40
41
  def __init__(self, config: GameConfig):
41
42
  """
42
43
  :param config: Game configuration options.
44
+ :type config: GameConfig
43
45
  """
44
46
  self.config = config
45
47
  self._current_scene: Scene | None = None
46
48
  self._running: bool = False
47
49
  self.backend: Backend | None = config.backend
48
50
 
51
+ if config.backend is None:
52
+ raise ValueError(
53
+ "GameConfig.backend must be set to a Backend instance"
54
+ )
55
+ self.backend: Backend = config.backend
56
+
49
57
  def change_scene(self, scene: Scene):
50
58
  """
51
59
  Swap the active scene. Concrete implementations should call
52
60
  ``on_exit``/``on_enter`` appropriately.
53
61
 
54
62
  :param scene: The new scene to activate.
63
+ :type scene: Scene
55
64
  """
56
- raise NotImplementedError(
57
- "Game.change_scene must be implemented by a concrete backend."
58
- )
65
+ if self._current_scene is not None:
66
+ self._current_scene.on_exit()
67
+ self._current_scene = scene
68
+ self._current_scene.on_enter()
59
69
 
60
70
  def quit(self):
61
71
  """Request that the main loop stops."""
@@ -69,7 +79,40 @@ class Game:
69
79
  or another backend.
70
80
 
71
81
  :param initial_scene: The scene to start the game with.
82
+ :type initial_scene: Scene
72
83
  """
73
- raise NotImplementedError(
74
- "Game.run must be implemented by a concrete backend."
75
- )
84
+ backend = self.backend
85
+ backend.init(self.config.width, self.config.height, self.config.title)
86
+
87
+ br, bg, bb = self.config.background_color
88
+ backend.set_clear_color(br, bg, bb)
89
+
90
+ self.change_scene(initial_scene)
91
+
92
+ self._running = True
93
+ target_dt = 1.0 / self.config.fps if self.config.fps > 0 else 0.0
94
+ last_time = perf_counter()
95
+
96
+ while self._running:
97
+ now = perf_counter()
98
+ dt = now - last_time
99
+ last_time = now
100
+
101
+ scene = self._current_scene
102
+ if scene is None:
103
+ break
104
+
105
+ for ev in backend.poll_events():
106
+ scene.handle_event(ev)
107
+
108
+ scene.update(dt)
109
+
110
+ backend.begin_frame()
111
+ scene.draw(backend)
112
+ backend.end_frame()
113
+
114
+ if target_dt > 0 and dt < target_dt:
115
+ sleep(target_dt - dt)
116
+
117
+ if self._current_scene is not None:
118
+ self._current_scene.on_exit()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mini-arcade-core
3
- Version: 0.6.0
3
+ Version: 0.7.0
4
4
  Summary: Tiny scene-based game loop core for small arcade games.
5
5
  License: Copyright (c) 2025 Santiago Rincón
6
6
 
@@ -0,0 +1,9 @@
1
+ mini_arcade_core/__init__.py,sha256=0PFa04KRSY3kT8YoD24zfFt92HYfrk6QrH8IlHbmeo4,1753
2
+ mini_arcade_core/backend.py,sha256=Vus-TIU16ySSGKuy1S-sBWkpb2WUZCbUHYBPcwGpW9o,2665
3
+ mini_arcade_core/entity.py,sha256=mAkedH0j14giBQFRpQjaym46uczbQDln6nbxy0WFAqU,1077
4
+ mini_arcade_core/game.py,sha256=G9x5FCzJN0KsnCy063sBgWkr3WkbPOJ8_SOHaslZ1mQ,3369
5
+ mini_arcade_core/scene.py,sha256=FEtywrnOBU8p0-t8oWGDELYBRRXOs4-Phe0dF7iSjKI,927
6
+ mini_arcade_core-0.7.0.dist-info/METADATA,sha256=wRO23CTApLzioWwh50uJQPU823HRURJCRLueAabity0,8296
7
+ mini_arcade_core-0.7.0.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
8
+ mini_arcade_core-0.7.0.dist-info/licenses/LICENSE,sha256=3lHAuV0584cVS5vAqi2uC6GcsVgxUijvwvtZckyvaZ4,1096
9
+ mini_arcade_core-0.7.0.dist-info/RECORD,,
@@ -1,9 +0,0 @@
1
- mini_arcade_core/__init__.py,sha256=0PFa04KRSY3kT8YoD24zfFt92HYfrk6QrH8IlHbmeo4,1753
2
- mini_arcade_core/backend.py,sha256=6_3-ni0EQJXfaSReavcrOeUOCNkdrjGctFn5q0D9nrw,1847
3
- mini_arcade_core/entity.py,sha256=mAkedH0j14giBQFRpQjaym46uczbQDln6nbxy0WFAqU,1077
4
- mini_arcade_core/game.py,sha256=OkQIFkFLqFailZDPY1fAq6Tyi7IQ9EKxloW1UgDaHko,2123
5
- mini_arcade_core/scene.py,sha256=FEtywrnOBU8p0-t8oWGDELYBRRXOs4-Phe0dF7iSjKI,927
6
- mini_arcade_core-0.6.0.dist-info/METADATA,sha256=hz6l1G6Oh3tm2UDzALEIAIKyG6YjYrZRr32_jz67K4o,8296
7
- mini_arcade_core-0.6.0.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
8
- mini_arcade_core-0.6.0.dist-info/licenses/LICENSE,sha256=3lHAuV0584cVS5vAqi2uC6GcsVgxUijvwvtZckyvaZ4,1096
9
- mini_arcade_core-0.6.0.dist-info/RECORD,,