batframework 1.0.8a6__py3-none-any.whl → 1.0.8a8__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 (70) hide show
  1. batFramework/__init__.py +51 -68
  2. batFramework/action.py +99 -126
  3. batFramework/actionContainer.py +9 -53
  4. batFramework/animatedSprite.py +82 -141
  5. batFramework/audioManager.py +26 -69
  6. batFramework/camera.py +69 -259
  7. batFramework/constants.py +54 -16
  8. batFramework/cutscene.py +29 -39
  9. batFramework/cutsceneBlocks.py +43 -36
  10. batFramework/debugger.py +48 -0
  11. batFramework/dynamicEntity.py +9 -18
  12. batFramework/easing.py +71 -0
  13. batFramework/entity.py +97 -48
  14. batFramework/gui/__init__.py +2 -10
  15. batFramework/gui/button.py +78 -9
  16. batFramework/gui/constraints.py +204 -0
  17. batFramework/gui/container.py +32 -174
  18. batFramework/gui/debugger.py +43 -131
  19. batFramework/gui/frame.py +19 -0
  20. batFramework/gui/image.py +20 -56
  21. batFramework/gui/indicator.py +21 -38
  22. batFramework/gui/interactiveWidget.py +13 -192
  23. batFramework/gui/label.py +74 -309
  24. batFramework/gui/layout.py +63 -231
  25. batFramework/gui/root.py +38 -134
  26. batFramework/gui/shape.py +57 -237
  27. batFramework/gui/toggle.py +51 -101
  28. batFramework/gui/widget.py +250 -358
  29. batFramework/manager.py +19 -52
  30. batFramework/particles.py +77 -0
  31. batFramework/scene.py +123 -281
  32. batFramework/sceneManager.py +116 -178
  33. batFramework/stateMachine.py +8 -11
  34. batFramework/time.py +58 -144
  35. batFramework/transition.py +124 -195
  36. batFramework/transitionManager.py +0 -0
  37. batFramework/triggerZone.py +1 -1
  38. batFramework/utils.py +147 -112
  39. batframework-1.0.8a8.dist-info/METADATA +53 -0
  40. batframework-1.0.8a8.dist-info/RECORD +42 -0
  41. {batframework-1.0.8a6.dist-info → batframework-1.0.8a8.dist-info}/WHEEL +1 -1
  42. batFramework/character.py +0 -27
  43. batFramework/easingController.py +0 -58
  44. batFramework/enums.py +0 -113
  45. batFramework/fontManager.py +0 -65
  46. batFramework/gui/clickableWidget.py +0 -220
  47. batFramework/gui/constraints/__init__.py +0 -1
  48. batFramework/gui/constraints/constraints.py +0 -815
  49. batFramework/gui/dialogueBox.py +0 -99
  50. batFramework/gui/draggableWidget.py +0 -40
  51. batFramework/gui/meter.py +0 -74
  52. batFramework/gui/radioButton.py +0 -84
  53. batFramework/gui/slider.py +0 -240
  54. batFramework/gui/style.py +0 -10
  55. batFramework/gui/styleManager.py +0 -48
  56. batFramework/gui/textInput.py +0 -247
  57. batFramework/object.py +0 -123
  58. batFramework/particle.py +0 -115
  59. batFramework/renderGroup.py +0 -67
  60. batFramework/resourceManager.py +0 -100
  61. batFramework/scrollingSprite.py +0 -114
  62. batFramework/sprite.py +0 -51
  63. batFramework/templates/__init__.py +0 -2
  64. batFramework/templates/character.py +0 -44
  65. batFramework/templates/states.py +0 -166
  66. batFramework/tileset.py +0 -46
  67. batframework-1.0.8a6.dist-info/LICENCE +0 -21
  68. batframework-1.0.8a6.dist-info/METADATA +0 -43
  69. batframework-1.0.8a6.dist-info/RECORD +0 -62
  70. {batframework-1.0.8a6.dist-info → batframework-1.0.8a8.dist-info}/top_level.txt +0 -0
batFramework/manager.py CHANGED
@@ -2,82 +2,49 @@ import batFramework as bf
2
2
  import pygame
3
3
  import random
4
4
 
5
-
6
5
  class Manager(bf.SceneManager):
7
6
  def __init__(self, *initial_scene_list) -> None:
8
- # random.seed("random")
9
- super().__init__()
10
- self._screen: pygame.Surface | None = bf.const.SCREEN
11
- self._timeManager = bf.TimeManager()
12
- self._cutsceneManager = bf.CutsceneManager()
13
- self._cutsceneManager.set_manager(self)
7
+ random.seed("random")
8
+ self._screen: pygame.Surface = bf.const.SCREEN
9
+ self._timeManager = bf.Time()
10
+ self._cutsceneManager = bf.CutsceneManager(self)
14
11
  self._clock: pygame.Clock = pygame.Clock()
15
- pygame.mouse.set_cursor(bf.const.DEFAULT_CURSOR)
16
- self.do_pre_init()
17
- self.init_scenes(*initial_scene_list)
12
+ super().__init__(*initial_scene_list)
18
13
  self.set_sharedVar("clock", self._clock)
19
14
  self.do_init()
20
15
 
21
16
  @staticmethod
22
- def set_icon(path: str) -> None:
23
- surf = pygame.image.load(bf.ResourceManager().get_path(path)).convert_alpha()
17
+ def set_icon(path: str):
18
+ surf = pygame.image.load(bf.utils.get_path(path)).convert_alpha()
24
19
  pygame.display.set_icon(surf)
25
20
 
26
- def print_status(self):
27
- """
28
- Print detailed information about the current state of the scenes, shared variables,
29
- and additional timers managed by the subclass.
30
- """
31
- # Call the parent class's print_status method to include its information
32
- super().print_status()
33
-
34
- # Add the timers information in a cohesive manner
35
- print("\n" + "=" * 50)
36
- print(" TIMERS".center(50))
37
- print("=" * 50)
38
-
39
- # Print the timers information
40
- print(self._timeManager)
41
-
42
- # End with a visual separator
43
- print("=" * 50 + "\n")
44
-
45
-
46
- def get_fps(self) -> float:
21
+ def get_fps(self):
47
22
  return self._clock.get_fps()
48
23
 
49
- def do_init(self) -> None:
50
- pass
51
-
52
- def do_pre_init(self) -> None:
24
+ def do_init(self):
53
25
  pass
54
26
 
55
- def stop(self) -> None:
27
+ def stop(self)->None:
56
28
  self._running = False
57
29
 
58
- def run(self) -> None:
30
+ def run(self):
59
31
  self._running = True
60
32
  dt: float = 0
61
33
  while self._running:
62
34
  for event in pygame.event.get():
63
- event.consumed = False
35
+ if event.type == pygame.QUIT:
36
+ self._running = False
37
+ break
38
+ if event.type == pygame.VIDEORESIZE:
39
+ bf.const.set_resolution((event.w,event.h))
64
40
  self.process_event(event)
65
- if not event.consumed:
66
- if event.type == pygame.QUIT:
67
- self._running = False
68
- break
69
- if event.type == pygame.VIDEORESIZE and not (
70
- bf.const.FLAGS & pygame.SCALED
71
- ):
72
- bf.const.set_resolution((event.w, event.h))
73
41
  # update
74
- dt = self._clock.tick(bf.const.FPS) / 1000
75
- # dt = min(dt, 0.02) dirty fix for dt being too high when window not focused for a long time
76
- self._timeManager.update(dt)
42
+ dt = self._clock.tick(bf.const.FPS if not bf.const.VSYNC else 0) / 1000
43
+ dt = min(dt, 0.02)
77
44
  self._cutsceneManager.update(dt)
45
+ self._timeManager.update()
78
46
  self.update(dt)
79
47
  # render
80
- self._screen.fill((0, 0, 0))
81
48
  self.draw(self._screen)
82
49
  pygame.display.flip()
83
50
  pygame.quit()
@@ -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,333 +1,203 @@
1
1
  from __future__ import annotations
2
2
  import re
3
- from collections import OrderedDict
4
- import itertools
5
-
6
- from typing import TYPE_CHECKING, Any
3
+ from typing import TYPE_CHECKING,Any
7
4
  if TYPE_CHECKING:
8
5
  from .manager import Manager
9
- from .sceneManager import SceneManager
10
6
  import pygame
11
7
  import batFramework as bf
12
8
 
13
9
 
14
10
  class Scene:
15
- def __init__(
16
- self,
17
- name: str,
18
- hud_convert_alpha: bool = True,
19
- world_convert_alpha: bool = False,
20
- ) -> None:
21
- """
22
- Initialize the Scene object.
23
-
24
- Args:
25
- name: Name of the scene.
26
- enable_alpha (bool, optional): Enable alpha channel for the scene surfaces. Defaults to True.
27
- """
28
- self.scene_index = 0
29
- self.name = name
30
- bf.TimeManager().add_register(self.name,False)
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] = []
31
17
  self.manager: Manager | None = None
32
- self.active = False
33
- self.visible = False
34
- self.world_entities: OrderedDict[bf.Entity, None] = OrderedDict()
35
- self.hud_entities: OrderedDict[bf.Entity, None] = OrderedDict()
36
18
  self.actions: bf.ActionContainer = bf.ActionContainer()
37
- self.early_actions: bf.ActionContainer = bf.ActionContainer()
38
- self.camera: bf.Camera = bf.Camera(convert_alpha=world_convert_alpha)
39
- self.hud_camera: bf.Camera = bf.Camera(convert_alpha=hud_convert_alpha)
40
- self.should_sort :bool = True
41
- self.root: bf.Root = bf.Root(self.hud_camera)
42
- self.root.rect.center = self.hud_camera.get_center()
43
- self.add_hud_entity(self.root)
44
- self.entities_to_remove = []
45
- self.entities_to_add = []
46
-
47
-
48
- def __str__(self)->str:
49
- return f"Scene({self.name})"
50
-
51
- def get_world_entity_count(self) -> int:
52
- return len(self.world_entities)
53
-
54
- def get_hud_entity_count(self) -> int:
55
- n = 0
56
-
57
- def adder(e):
58
- nonlocal n
59
- n += len(e.children)
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()
60
25
 
61
- self.root.visit(adder)
26
+ self.camera.set_clear_color((0, 0, 0))
27
+ self.hud_camera.set_clear_color((0, 0, 0, 0))
62
28
 
63
- 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
64
33
 
65
- def set_scene_index(self, index: int):
66
- """Set the scene index."""
34
+ def set_scene_index(self,index):
67
35
  self.scene_index = index
68
36
 
69
- def get_scene_index(self) -> int:
70
- """Get the scene index."""
37
+ def get_scene_index(self):
71
38
  return self.scene_index
72
39
 
73
- def set_sharedVar(self, name: str, value: Any) -> bool:
74
- """
75
- Set a shared variable in the manager.
76
-
77
- Args:
78
- name: Name of the shared variable.
79
- value: Value to set.
80
-
81
- Returns:
82
- bool: True if setting was successful, False otherwise.
83
- """
84
- if not self.manager:
85
- return False
40
+ def set_sharedVar(self, name, value)->bool:
41
+ if not self.manager : return False
86
42
  return self.manager.set_sharedVar(name, value)
87
43
 
88
- def get_sharedVar(self, name: str, error_value=None) -> Any:
89
- """
90
- Get a shared variable from the manager.
91
-
92
- Args:
93
- name: Name of the shared variable.
94
-
95
- Returns:
96
- Any: Value of the shared variable.
97
- """
98
- if not self.manager:
99
- return error_value
100
- 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)
101
47
 
102
48
  def do_when_added(self):
103
49
  pass
104
50
 
105
- def set_clear_color(self, color: pygame.Color | tuple):
106
- """Set the clear color for the camera."""
51
+ def set_clear_color(self, color: pygame.Color|tuple):
107
52
  self.camera.set_clear_color(color)
53
+ # self.hud_camera.set_clear_color(color)
108
54
 
109
55
  def set_manager(self, manager_link: Manager):
110
- """Set the manager link for the scene."""
111
56
  self.manager = manager_link
112
- self.manager.update_scene_states()
113
57
 
114
58
  def set_visible(self, value: bool):
115
- """Set the visibility of the scene."""
116
- self.visible = value
117
- if self.manager:
118
- self.manager.update_scene_states()
59
+ self._visible = value
60
+ if self.manager : self.manager.update_scene_states()
119
61
 
120
62
  def set_active(self, value):
121
- """Set the activity of the scene."""
122
- self.active = value
123
- if self.manager:
124
- self.manager.update_scene_states()
63
+ self._active = value
64
+ if self.manager : self.manager.update_scene_states()
125
65
 
126
66
  def is_active(self) -> bool:
127
- """Check if the scene is active."""
128
- return self.active
67
+ return self._active
129
68
 
130
69
  def is_visible(self) -> bool:
131
- """Check if the scene is visible."""
132
- return self.visible
70
+ return self._visible
133
71
 
134
72
  def get_name(self) -> str:
135
- """Get the name of the scene."""
136
- return self.name
137
-
138
- def add_world_entity(self, *entities: bf.Entity):
139
- """Add world entities to the scene."""
140
- change = False
141
- for e in entities:
142
- if e not in self.world_entities and e not in self.entities_to_add:
143
- change = True
144
- # self.world_entities[e] = None
145
- self.entities_to_add.append(e)
146
- e.set_parent_scene(self)
147
- # self.sort_entities()
148
- return change
149
-
150
- # Updated remove_world_entity method to add entities to the removal list
151
- def remove_world_entity(self, *entities: bf.Entity):
152
- """Mark world entities for removal from the scene."""
153
- change = False
154
- for e in entities:
155
- if e in self.world_entities:
156
- change = True
157
- self.entities_to_remove.append(e)
158
- e.set_parent_scene(None)
159
- return change
160
-
161
- def add_hud_entity(self, *entities: bf.Entity):
162
- """Add HUD entities to the scene."""
163
- for e in entities:
164
- if e not in self.hud_entities:
165
- self.hud_entities[e] = None
166
- e.set_parent_scene(self)
167
- self.sort_entities()
168
- return True
169
-
170
- def remove_hud_entity(self, *entities: bf.Entity):
171
- """Remove HUD entities from the scene."""
172
- for e in entities:
173
- if e in self.hud_entities:
174
- e.set_parent_scene(None)
175
- self.hud_entities.pop(e)
176
-
177
- def add_actions(self, *action):
178
- """Add actions to the scene."""
179
- self.actions.add_actions(*action)
180
-
181
- def add_early_actions(self, *action):
182
- """Add actions to the scene."""
183
- self.early_actions.add_actions(*action)
73
+ return self._name
74
+
75
+ def add_world_entity(self, *entity: bf.Entity):
76
+ for e in entity:
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()
82
+
83
+ def remove_world_entity(self, *entity: bf.Entity):
84
+ for e in entity:
85
+ if e not in self._world_entities:
86
+ return False
87
+ e.do_when_removed()
88
+ e.parent_scene = None
89
+ self._world_entities.remove(e)
90
+ return True
91
+
92
+ def add_hud_entity(self, *entity: bf.Entity):
93
+ for e in entity:
94
+ if e not in self._hud_entities:
95
+ self._hud_entities.append(e)
96
+ e.parent_scene = self
97
+ e.do_when_added()
98
+
99
+ def remove_hud_entity(self, *entity: bf.Entity):
100
+ for e in entity:
101
+ if e in self._hud_entities:
102
+ e.do_when_removed()
103
+ e.parent_scene = None
104
+ self._hud_entities.remove(e)
105
+
106
+ def add_action(self, *action):
107
+ self.actions.add_action(*action)
184
108
 
185
109
  def get_by_tags(self, *tags):
186
- """Get entities by their tags."""
187
- res = [
110
+ return [
188
111
  entity
189
- for entity in itertools.chain(
190
- self.world_entities.keys(), self.hud_entities.keys()
191
- )
192
- 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)
193
114
  ]
194
- res.extend(list(self.root.get_by_tags(*tags)))
195
- return res
196
115
 
197
116
  def get_by_uid(self, uid) -> bf.Entity | None:
198
- """Get an entity by its unique identifier."""
199
- res = self._find_entity_by_uid(
200
- uid, itertools.chain(self.world_entities.keys(), self.hud_entities.keys())
117
+ return next(
118
+ (
119
+ entity
120
+ for entity in self._world_entities + self._hud_entities
121
+ if entity.uid == uid
122
+ ),
123
+ None,
201
124
  )
202
- if res is None:
203
- res = self._recursive_search_by_uid(uid, self.root)
204
- return res
205
-
206
- def _find_entity_by_uid(self, uid, entities) -> bf.Entity | None:
207
- """Search for entity by uid in a list of entities."""
208
- for entity in entities:
209
- if entity.uid == uid:
210
- return entity
211
- return None
212
125
 
213
- def _recursive_search_by_uid(self, uid, widget) -> bf.Entity | None:
214
- """Recursively search for entity by uid in the widget's children."""
215
- if widget.uid == uid:
216
- return widget
217
-
218
- for child in widget.children:
219
- res = self._recursive_search_by_uid(uid, child)
220
- if res is not None:
221
- return res
222
-
223
- return None
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
224
130
 
131
+ # propagates event to all entities
225
132
  def process_event(self, event: pygame.Event):
226
133
  """
227
- Propagates event while it is not consumed.
228
- In order :
229
- -do_early_handle_event()
230
- -scene early_actions
231
- -propagate to scene entities (hud then world)
232
- -do_handle_event()
233
- -scene actions
234
- 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.
235
136
  """
236
- if event.consumed:
237
- return
238
- self.do_early_handle_event(event)
239
- if event.consumed:
137
+ if self.get_sharedVar("in_transition"):
240
138
  return
241
- self.early_actions.process_event(event)
242
- if event.consumed:
243
- return
244
- for entity in itertools.chain(
245
- self.hud_entities.keys(), self.world_entities.keys()
246
- ):
247
- entity.process_event(event)
248
- if event.consumed:
249
- return
250
- self.do_handle_event(event)
251
- if event.consumed:
139
+ if self.do_early_process_event(event):
252
140
  return
253
141
  self.actions.process_event(event)
254
-
255
- # called before process event
256
- def do_early_handle_event(self, event: pygame.Event):
257
- """Called early in event propagation"""
258
- 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()
259
147
 
260
148
  def do_handle_event(self, event: pygame.Event):
261
149
  """called inside process_event but before resetting the scene's action container and propagating event to child entities of the scene"""
262
150
  pass
263
151
 
264
152
  def update(self, dt):
265
- """Update the scene. Do NOT override"""
266
- if self.should_sort:
267
- self._sort_entities_internal()
268
-
269
- for entity in itertools.chain(
270
- self.hud_entities.keys(), self.world_entities.keys()
271
- ):
153
+ for entity in self._world_entities + self._hud_entities:
272
154
  entity.update(dt)
273
-
274
155
  self.do_update(dt)
275
156
  self.camera.update(dt)
276
157
  self.hud_camera.update(dt)
277
- self.actions.reset()
278
- self.early_actions.reset()
279
-
280
-
281
- if self.entities_to_add:
282
- for e in self.entities_to_add:
283
- self.world_entities[e] = None
284
- self.entities_to_add.clear()
285
-
286
- # Remove marked entities after updating
287
- if self.entities_to_remove:
288
- for e in self.entities_to_remove:
289
- self.world_entities.pop(e, None)
290
- self.entities_to_remove.clear()
291
158
 
292
159
  def do_update(self, dt):
293
- """Specific update within the scene."""
294
160
  pass
295
161
 
296
162
  def debug_entity(self, entity: bf.Entity, camera: bf.Camera):
297
- def draw_rect(data):
298
- if data is None:
299
- return
300
- 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):
301
168
  rect = data
302
- color = entity.debug_color
169
+ color = entity._debug_color
303
170
  else:
304
171
  rect = data[0]
305
172
  color = data[1]
306
- pygame.draw.rect(camera.surface, color, camera.world_to_screen(rect), 1)
173
+ if not isinstance(color,pygame.Color): color = pygame.Color(color)
307
174
 
308
- [draw_rect(data) for data in entity.get_debug_outlines()]
309
-
310
- def sort_entities(self) -> None:
311
- self.should_sort = True
312
-
313
- def _sort_entities_internal(self):
314
- """Sort entities within the scene based on their rendering order."""
315
- self.world_entities = OrderedDict(
316
- sorted(self.world_entities.items(), key=lambda e: e[0].render_order)
317
- )
318
- self.hud_entities = OrderedDict(
319
- sorted(self.hud_entities.items(), key=lambda e: e[0].render_order)
320
- )
321
- self.should_sort = False
175
+ pygame.draw.rect(camera.surface, color , camera.transpose(rect), 1)
322
176
 
323
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))
180
+
181
+ total_blit_calls = 0
324
182
  self.camera.clear()
325
183
  self.hud_camera.clear()
326
184
 
327
- # Draw all world entities
328
- self._draw_camera(self.camera, self.world_entities.keys())
329
- # Draw all HUD entities
330
- self._draw_camera(self.hud_camera, self.hud_entities.keys())
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
+
331
201
 
332
202
  self.do_early_draw(surface)
333
203
  self.camera.draw(surface)
@@ -335,12 +205,7 @@ class Scene:
335
205
  self.hud_camera.draw(surface)
336
206
  self.do_final_draw(surface)
337
207
 
338
- def _draw_camera(self, camera: bf.Camera, entity_list):
339
- _ = [entity.draw(camera) for entity in entity_list]
340
- debugMode = self.manager.debug_mode
341
- # Draw outlines for world entities if required
342
- if debugMode == bf.debugMode.OUTLINES:
343
- [self.debug_entity(e, camera) for e in entity_list]
208
+ self.blit_calls = total_blit_calls
344
209
 
345
210
  def do_early_draw(self, surface: pygame.Surface):
346
211
  pass
@@ -354,31 +219,8 @@ class Scene:
354
219
  def on_enter(self):
355
220
  self.set_active(True)
356
221
  self.set_visible(True)
357
- self.root.clear_hovered()
358
- # self.root.clear_focused()
359
- self.root.build()
360
- bf.TimeManager().activate_register(self.name)
361
- self.do_on_enter()
362
- # self.root.visit(lambda e : e.resolve_constraints())
363
222
 
364
223
  def on_exit(self):
365
- self.root.clear_hovered()
366
- # self.root.clear_focused()
367
224
  self.set_active(False)
368
225
  self.set_visible(False)
369
226
  self.actions.hard_reset()
370
- self.early_actions.hard_reset()
371
- bf.TimeManager().deactivate_register(self.name)
372
- self.do_on_exit()
373
-
374
- def do_on_enter(self) -> None:
375
- pass
376
-
377
- def do_on_exit(self) -> None:
378
- pass
379
-
380
- def do_on_enter_early(self) -> None:
381
- pass
382
-
383
- def do_on_exit_early(self) -> None:
384
- pass