batframework 1.0.8a1__py3-none-any.whl → 1.0.8a2__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.
Files changed (63) hide show
  1. batFramework/__init__.py +50 -53
  2. batFramework/action.py +105 -116
  3. batFramework/actionContainer.py +11 -53
  4. batFramework/animatedSprite.py +65 -115
  5. batFramework/audioManager.py +26 -70
  6. batFramework/camera.py +68 -253
  7. batFramework/constants.py +54 -16
  8. batFramework/cutscene.py +25 -34
  9. batFramework/cutsceneBlocks.py +42 -37
  10. batFramework/debugger.py +48 -0
  11. batFramework/dynamicEntity.py +7 -9
  12. batFramework/easing.py +71 -0
  13. batFramework/entity.py +98 -42
  14. batFramework/gui/__init__.py +2 -8
  15. batFramework/gui/button.py +79 -7
  16. batFramework/gui/constraints.py +204 -0
  17. batFramework/gui/container.py +31 -155
  18. batFramework/gui/debugger.py +43 -124
  19. batFramework/gui/frame.py +19 -0
  20. batFramework/gui/image.py +17 -41
  21. batFramework/gui/indicator.py +21 -41
  22. batFramework/gui/interactiveWidget.py +13 -116
  23. batFramework/gui/label.py +73 -278
  24. batFramework/gui/layout.py +61 -148
  25. batFramework/gui/root.py +37 -102
  26. batFramework/gui/shape.py +57 -258
  27. batFramework/gui/toggle.py +46 -97
  28. batFramework/gui/widget.py +254 -268
  29. batFramework/manager.py +19 -40
  30. batFramework/particles.py +77 -0
  31. batFramework/scene.py +107 -214
  32. batFramework/sceneManager.py +107 -150
  33. batFramework/stateMachine.py +0 -1
  34. batFramework/time.py +57 -117
  35. batFramework/transition.py +126 -184
  36. batFramework/transitionManager.py +0 -0
  37. batFramework/utils.py +161 -34
  38. batframework-1.0.8a2.dist-info/METADATA +58 -0
  39. batframework-1.0.8a2.dist-info/RECORD +42 -0
  40. {batframework-1.0.8a1.dist-info → batframework-1.0.8a2.dist-info}/WHEEL +1 -1
  41. batFramework/easingController.py +0 -58
  42. batFramework/enums.py +0 -104
  43. batFramework/fontManager.py +0 -65
  44. batFramework/gui/clickableWidget.py +0 -206
  45. batFramework/gui/constraints/__init__.py +0 -1
  46. batFramework/gui/constraints/constraints.py +0 -378
  47. batFramework/gui/dialogueBox.py +0 -96
  48. batFramework/gui/draggableWidget.py +0 -38
  49. batFramework/gui/meter.py +0 -76
  50. batFramework/gui/radioButton.py +0 -62
  51. batFramework/gui/slider.py +0 -220
  52. batFramework/gui/textInput.py +0 -134
  53. batFramework/object.py +0 -115
  54. batFramework/particle.py +0 -101
  55. batFramework/renderGroup.py +0 -62
  56. batFramework/resourceManager.py +0 -84
  57. batFramework/scrollingSprite.py +0 -113
  58. batFramework/sprite.py +0 -45
  59. batFramework/tileset.py +0 -46
  60. batframework-1.0.8a1.dist-info/LICENCE +0 -21
  61. batframework-1.0.8a1.dist-info/METADATA +0 -55
  62. batframework-1.0.8a1.dist-info/RECORD +0 -56
  63. {batframework-1.0.8a1.dist-info → batframework-1.0.8a2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,77 @@
1
+ import batFramework as bf
2
+ import pygame
3
+ from pygame.math import Vector2
4
+
5
+
6
+ class Particle:
7
+ def __init__(
8
+ self,
9
+ start_pos: tuple[float, float],
10
+ start_vel: tuple[float, float],
11
+ duration=1000,
12
+ color=None,
13
+ size = (4,4)
14
+ ):
15
+ self.rect = pygame.FRect(*start_pos, 0, 0)
16
+ self.surface = pygame.Surface(size).convert()
17
+ if color:
18
+ self.surface.fill(color)
19
+ self.velocity = Vector2(*start_vel)
20
+ self.start_time = pygame.time.get_ticks()
21
+ self.duration = duration
22
+ self.dead = False
23
+ self.progression = 0
24
+ self.z_depth = 1
25
+
26
+ def update(self, dt):
27
+ if self.dead:
28
+ return
29
+ elapsed_time = pygame.time.get_ticks() - self.start_time
30
+ self.progression = elapsed_time / self.duration
31
+ self.dead = elapsed_time >= self.duration
32
+ self.rect.center += self.velocity * dt
33
+ self.update_surface()
34
+
35
+ def kill(self):
36
+ self.dead = True
37
+
38
+ def update_surface(self):
39
+ self.surface.set_alpha(255 - int(self.progression * 255))
40
+
41
+
42
+ class ParticleManager(bf.Entity):
43
+ def __init__(self) -> None:
44
+ super().__init__(size=bf.const.RESOLUTION)
45
+ self.particles: list[Particle] = []
46
+
47
+ def get_bounding_box(self):
48
+ for particle in self.particles:
49
+ yield particle.rect
50
+
51
+ def add_particle(self, particle_class=Particle, **kwargs):
52
+ self.particles.append(particle_class(**kwargs))
53
+
54
+
55
+ def clear(self):
56
+ self.particles = []
57
+
58
+
59
+ def update(self, dt: float):
60
+ particles_to_remove = []
61
+ for particle in self.particles:
62
+ particle.update(dt)
63
+ if particle.dead:
64
+ particles_to_remove.append(particle)
65
+ for p in particles_to_remove:
66
+ self.particles.remove(p)
67
+
68
+ def draw(self, camera) -> bool:
69
+ camera.surface.fblits(
70
+ [
71
+ (
72
+ p.surface,
73
+ tuple(round(i * self.z_depth) for i in camera.transpose(self.rect).topleft)
74
+ ) for p in self.particles
75
+ ]
76
+ )
77
+ return len(self.particles)
batFramework/scene.py CHANGED
@@ -1,291 +1,203 @@
1
1
  from __future__ import annotations
2
2
  import re
3
- from typing import TYPE_CHECKING, Any
4
-
3
+ from typing import TYPE_CHECKING,Any
5
4
  if TYPE_CHECKING:
6
5
  from .manager import Manager
7
- from .sceneManager import SceneManager
8
6
  import pygame
9
7
  import batFramework as bf
10
8
 
11
9
 
12
10
  class Scene:
13
- def __init__(
14
- self,
15
- name: str,
16
- hud_convert_alpha: bool = True,
17
- world_convert_alpha: bool = False,
18
- ) -> None:
19
- """
20
- Initialize the Scene object.
21
-
22
- Args:
23
- name: Name of the scene.
24
- enable_alpha (bool, optional): Enable alpha channel for the scene surfaces. Defaults to True.
25
- """
26
- self.scene_index = 0
27
- self.name = name
11
+ def __init__(self, name, enable_alpha=True) -> None:
12
+ self._name = name
13
+ self._active = False
14
+ self._visible = False
15
+ self._world_entities: list[bf.Entity] = []
16
+ self._hud_entities: list[bf.Entity] = []
28
17
  self.manager: Manager | None = None
29
- self.active = False
30
- self.visible = False
31
- self.world_entities: list[bf.Entity] = []
32
- self.hud_entities: list[bf.Entity] = []
33
18
  self.actions: bf.ActionContainer = bf.ActionContainer()
34
- self.early_actions: bf.ActionContainer = bf.ActionContainer()
35
- self.camera: bf.Camera = bf.Camera(convert_alpha=world_convert_alpha)
36
- self.hud_camera: bf.Camera = bf.Camera(convert_alpha=hud_convert_alpha)
37
-
38
- self.root: bf.Root = bf.Root(self.hud_camera)
39
- self.root.rect.center = self.hud_camera.get_center()
40
- self.add_hud_entity(self.root)
41
-
42
- def get_world_entity_count(self) -> int:
43
- return len(self.world_entities)
19
+ self.camera: bf.Camera = bf.Camera()
20
+ self.scene_index = 0
21
+ self.hud_camera: bf.Camera = bf.Camera()
22
+ if enable_alpha:
23
+ self.camera.surface = self.camera.surface.convert_alpha()
24
+ self.hud_camera.surface = self.camera.surface.convert_alpha()
44
25
 
45
- def get_hud_entity_count(self) -> int:
46
- n = 0
47
- def adder(e):
48
- nonlocal n
49
- n += len(e.children)
50
- self.root.visit(adder)
26
+ self.camera.set_clear_color((0, 0, 0))
27
+ self.hud_camera.set_clear_color((0, 0, 0, 0))
51
28
 
52
- return len(self.hud_entities) + n
29
+ self.root : bf.Root = bf.Root()
30
+ self.root.set_center(*self.hud_camera.get_center())
31
+ self.add_hud_entity(self.root)
32
+ self.blit_calls = 0
53
33
 
54
- def set_scene_index(self, index: int):
55
- """Set the scene index."""
34
+ def set_scene_index(self,index):
56
35
  self.scene_index = index
57
36
 
58
- def get_scene_index(self) -> int:
59
- """Get the scene index."""
37
+ def get_scene_index(self):
60
38
  return self.scene_index
61
39
 
62
- def set_sharedVar(self, name: str, value: Any) -> bool:
63
- """
64
- Set a shared variable in the manager.
65
-
66
- Args:
67
- name: Name of the shared variable.
68
- value: Value to set.
69
-
70
- Returns:
71
- bool: True if setting was successful, False otherwise.
72
- """
73
- if not self.manager:
74
- return False
40
+ def set_sharedVar(self, name, value)->bool:
41
+ if not self.manager : return False
75
42
  return self.manager.set_sharedVar(name, value)
76
43
 
77
- def get_sharedVar(self, name: str, error_value=None) -> Any:
78
- """
79
- Get a shared variable from the manager.
80
-
81
- Args:
82
- name: Name of the shared variable.
83
-
84
- Returns:
85
- Any: Value of the shared variable.
86
- """
87
- if not self.manager:
88
- return error_value
89
- return self.manager.get_sharedVar(name, error_value)
44
+ def get_sharedVar(self, name)->Any:
45
+ if not self.manager : return False
46
+ return self.manager.get_sharedVar(name)
90
47
 
91
48
  def do_when_added(self):
92
49
  pass
93
50
 
94
- def set_clear_color(self, color: pygame.Color | tuple):
95
- """Set the clear color for the camera."""
51
+ def set_clear_color(self, color: pygame.Color|tuple):
96
52
  self.camera.set_clear_color(color)
53
+ # self.hud_camera.set_clear_color(color)
97
54
 
98
55
  def set_manager(self, manager_link: Manager):
99
- """Set the manager link for the scene."""
100
56
  self.manager = manager_link
101
- self.manager.update_scene_states()
102
57
 
103
58
  def set_visible(self, value: bool):
104
- """Set the visibility of the scene."""
105
- self.visible = value
106
- if self.manager:
107
- self.manager.update_scene_states()
59
+ self._visible = value
60
+ if self.manager : self.manager.update_scene_states()
108
61
 
109
62
  def set_active(self, value):
110
- """Set the activity of the scene."""
111
- self.active = value
112
- if self.manager:
113
- self.manager.update_scene_states()
63
+ self._active = value
64
+ if self.manager : self.manager.update_scene_states()
114
65
 
115
66
  def is_active(self) -> bool:
116
- """Check if the scene is active."""
117
- return self.active
67
+ return self._active
118
68
 
119
69
  def is_visible(self) -> bool:
120
- """Check if the scene is visible."""
121
- return self.visible
70
+ return self._visible
122
71
 
123
72
  def get_name(self) -> str:
124
- """Get the name of the scene."""
125
- return self.name
73
+ return self._name
126
74
 
127
75
  def add_world_entity(self, *entity: bf.Entity):
128
- """Add world entities to the scene."""
129
76
  for e in entity:
130
- self.world_entities.append(e)
131
- e.parent_scene = self
132
- e.do_when_added()
133
- self.sort_entities()
77
+ if e not in self._world_entities:
78
+
79
+ self._world_entities.append(e)
80
+ e.parent_scene = self
81
+ e.do_when_added()
134
82
 
135
83
  def remove_world_entity(self, *entity: bf.Entity):
136
- """Remove world entities from the scene."""
137
84
  for e in entity:
138
- if e not in self.world_entities:
85
+ if e not in self._world_entities:
139
86
  return False
140
87
  e.do_when_removed()
141
88
  e.parent_scene = None
142
- self.world_entities.remove(e)
89
+ self._world_entities.remove(e)
143
90
  return True
144
91
 
145
92
  def add_hud_entity(self, *entity: bf.Entity):
146
- """Add HUD entities to the scene."""
147
93
  for e in entity:
148
- self.hud_entities.append(e)
149
- e.parent_scene = self
150
- e.do_when_added()
151
- self.sort_entities()
152
- return True
94
+ if e not in self._hud_entities:
95
+ self._hud_entities.append(e)
96
+ e.parent_scene = self
97
+ e.do_when_added()
153
98
 
154
99
  def remove_hud_entity(self, *entity: bf.Entity):
155
- """Remove HUD entities from the scene."""
156
100
  for e in entity:
157
- if e in self.hud_entities:
101
+ if e in self._hud_entities:
158
102
  e.do_when_removed()
159
103
  e.parent_scene = None
160
- self.hud_entities.remove(e)
161
-
162
- def add_actions(self, *action):
163
- """Add actions to the scene."""
164
- self.actions.add_actions(*action)
104
+ self._hud_entities.remove(e)
165
105
 
166
- def add_early_actions(self, *action):
167
- """Add actions to the scene."""
168
- self.early_actions.add_actions(*action)
106
+ def add_action(self, *action):
107
+ self.actions.add_action(*action)
169
108
 
170
109
  def get_by_tags(self, *tags):
171
- """Get entities by their tags."""
172
- res = [
110
+ return [
173
111
  entity
174
- for entity in self.world_entities + self.hud_entities
175
- if any(entity.has_tags(t) for t in tags)
112
+ for entity in self._world_entities + self._hud_entities
113
+ if any(entity.has_tag(t) for t in tags)
176
114
  ]
177
- res.extend(list(self.root.get_by_tags(*tags)))
178
- return res
179
115
 
180
116
  def get_by_uid(self, uid) -> bf.Entity | None:
181
- """Get an entity by its unique identifier."""
182
- res = self._find_entity_by_uid(uid, self.world_entities + self.hud_entities)
183
- if res is None:
184
- res = self._recursive_search_by_uid(uid, self.root)
185
- return res
186
-
187
- def _find_entity_by_uid(self, uid, entities) -> bf.Entity | None:
188
- """Search for entity by uid in a list of entities."""
189
- for entity in entities:
190
- if entity.uid == uid:
191
- return entity
192
- return None
193
-
194
- def _recursive_search_by_uid(self, uid, widget) -> bf.Entity | None:
195
- """Recursively search for entity by uid in the widget's children."""
196
- if widget.uid == uid:
197
- return widget
198
-
199
- for child in widget.children:
200
- res = self._recursive_search_by_uid(uid, child)
201
- if res is not None:
202
- return res
203
-
204
- return None
117
+ return next(
118
+ (
119
+ entity
120
+ for entity in self._world_entities + self._hud_entities
121
+ if entity.uid == uid
122
+ ),
123
+ None,
124
+ )
125
+
126
+ # called before process event
127
+ def do_early_process_event(self, event: pygame.Event) -> bool:
128
+ """return True if stop event propagation in child entities and scene's action container"""
129
+ return False
205
130
 
206
131
  # propagates event to all entities
207
132
  def process_event(self, event: pygame.Event):
208
133
  """
209
- Propagates event while it is not consumed.
210
- In order :
211
- -do_early_handle_event()
212
- -scene early_actions
213
- -propagate to scene entities (hud then world)
214
- -do_handle_event()
215
- -scene actions
216
- at each step, if the event is consumed the propagation stops
134
+ Propagates event to child events. Calls early process event first, if returns False then stops. Processes scene's action_container, then custom do_handle_event function.
135
+ Finally resets the action_container, and propagates to all child entities. if any of them returns True, the propagation is stopped.
217
136
  """
218
- if event.consumed : return
219
- self.do_early_handle_event(event)
220
- if event.consumed : return
221
- self.early_actions.process_event(event)
222
- if event.consumed : return
223
- for entity in self.hud_entities + self.world_entities:
224
- entity.process_event(event)
225
- if event.consumed : return
226
- self.do_handle_event(event)
227
- if event.consumed : return
137
+ if self.get_sharedVar("in_transition"):
138
+ return
139
+ if self.do_early_process_event(event):
140
+ return
228
141
  self.actions.process_event(event)
229
-
230
- # called before process event
231
- def do_early_handle_event(self, event: pygame.Event) :
232
- """Called early in event propagation"""
233
- pass
142
+ self.do_handle_event(event)
143
+ for entity in self._world_entities + self._hud_entities:
144
+ if entity.process_event(event):
145
+ break
146
+ self.actions.reset()
234
147
 
235
148
  def do_handle_event(self, event: pygame.Event):
236
149
  """called inside process_event but before resetting the scene's action container and propagating event to child entities of the scene"""
237
150
  pass
238
151
 
239
152
  def update(self, dt):
240
- """Update the scene. Do NOT override"""
241
- for entity in self.world_entities + self.hud_entities:
153
+ for entity in self._world_entities + self._hud_entities:
242
154
  entity.update(dt)
243
155
  self.do_update(dt)
244
156
  self.camera.update(dt)
245
157
  self.hud_camera.update(dt)
246
- self.actions.reset()
247
- self.early_actions.reset()
248
158
 
249
159
  def do_update(self, dt):
250
- """Specific update within the scene."""
251
160
  pass
252
161
 
253
162
  def debug_entity(self, entity: bf.Entity, camera: bf.Camera):
254
- def draw_rect(data):
255
- if data is None:
256
- return
257
- if isinstance(data, pygame.FRect) or isinstance(data, pygame.Rect):
163
+ # return
164
+ if not entity.visible:
165
+ return
166
+ for data in entity.get_bounding_box():
167
+ if isinstance(data,pygame.FRect):
258
168
  rect = data
259
- color = entity.debug_color
169
+ color = entity._debug_color
260
170
  else:
261
171
  rect = data[0]
262
172
  color = data[1]
263
- pygame.draw.rect(camera.surface, color, camera.world_to_screen(rect), 1)
264
-
265
- [draw_rect(data) for data in entity.get_debug_outlines()]
266
-
267
- def sort_entities(self) -> None:
268
- """Sort entities within the scene based on their rendering order."""
269
- self.world_entities.sort(key=lambda e: e.render_order)
270
- self.hud_entities.sort(key=lambda e: e.render_order)
271
-
272
- def _draw_camera(self, camera: bf.Camera, entity_list: list[bf.Entity]) ->None:
273
- _ = [entity.draw(camera) for entity in entity_list]
274
- debugMode = self.manager.debug_mode
275
- # Draw outlines for world entities if required
276
- if debugMode == bf.debugMode.OUTLINES:
277
- [self.debug_entity(e, camera) for e in entity_list]
173
+ if not isinstance(color,pygame.Color): color = pygame.Color(color)
278
174
 
175
+ pygame.draw.rect(camera.surface, color , camera.transpose(rect), 1)
279
176
 
280
177
  def draw(self, surface: pygame.Surface):
178
+ self._world_entities.sort(key=lambda e: (e.z_depth,e.render_order))
179
+ self._hud_entities.sort(key=lambda e: (e.z_depth,e.render_order))
281
180
 
181
+ total_blit_calls = 0
282
182
  self.camera.clear()
283
183
  self.hud_camera.clear()
284
184
 
285
- # Draw all world entities
286
- self._draw_camera(self.camera, self.world_entities)
287
- # Draw all HUD entities
288
- self._draw_camera(self.hud_camera, self.hud_entities)
185
+
186
+ total_blit_calls += sum(
187
+ entity.draw(self.camera) for entity in self._world_entities
188
+ )
189
+
190
+ if self.manager and self.manager._debugging == 2:
191
+ for entity in self._world_entities:
192
+ self.debug_entity(entity, self.camera)
193
+
194
+ total_blit_calls += sum(
195
+ entity.draw(self.hud_camera) for entity in self._hud_entities
196
+ )
197
+ if self.manager and self.manager._debugging == 2:
198
+ for entity in self._hud_entities:
199
+ self.debug_entity(entity, self.hud_camera)
200
+
289
201
 
290
202
  self.do_early_draw(surface)
291
203
  self.camera.draw(surface)
@@ -293,6 +205,8 @@ class Scene:
293
205
  self.hud_camera.draw(surface)
294
206
  self.do_final_draw(surface)
295
207
 
208
+ self.blit_calls = total_blit_calls
209
+
296
210
  def do_early_draw(self, surface: pygame.Surface):
297
211
  pass
298
212
 
@@ -305,29 +219,8 @@ class Scene:
305
219
  def on_enter(self):
306
220
  self.set_active(True)
307
221
  self.set_visible(True)
308
- self.root.clear_hovered()
309
- # self.root.clear_focused()
310
- self.root.build()
311
- self.do_on_enter()
312
- # self.root.visit(lambda e : e.resolve_constraints())
313
222
 
314
223
  def on_exit(self):
315
- self.root.clear_hovered()
316
- # self.root.clear_focused()
317
224
  self.set_active(False)
318
225
  self.set_visible(False)
319
226
  self.actions.hard_reset()
320
- self.early_actions.hard_reset()
321
- self.do_on_exit()
322
-
323
- def do_on_enter(self) -> None:
324
- pass
325
-
326
- def do_on_exit(self) -> None:
327
- pass
328
-
329
- def do_on_enter_early(self) -> None:
330
- pass
331
-
332
- def do_on_exit_early(self) -> None:
333
- pass