batframework 1.0.6__py3-none-any.whl → 1.0.8a1__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 (59) hide show
  1. batFramework/__init__.py +23 -14
  2. batFramework/action.py +95 -106
  3. batFramework/actionContainer.py +11 -8
  4. batFramework/animatedSprite.py +60 -43
  5. batFramework/audioManager.py +52 -22
  6. batFramework/camera.py +87 -72
  7. batFramework/constants.py +19 -41
  8. batFramework/cutscene.py +12 -11
  9. batFramework/cutsceneBlocks.py +12 -14
  10. batFramework/dynamicEntity.py +5 -4
  11. batFramework/easingController.py +58 -0
  12. batFramework/entity.py +37 -130
  13. batFramework/enums.py +93 -3
  14. batFramework/fontManager.py +15 -7
  15. batFramework/gui/__init__.py +5 -1
  16. batFramework/gui/button.py +6 -144
  17. batFramework/gui/clickableWidget.py +206 -0
  18. batFramework/gui/constraints/__init__.py +1 -0
  19. batFramework/gui/constraints/constraints.py +378 -0
  20. batFramework/gui/container.py +147 -34
  21. batFramework/gui/debugger.py +39 -22
  22. batFramework/gui/dialogueBox.py +69 -43
  23. batFramework/gui/draggableWidget.py +38 -0
  24. batFramework/gui/image.py +33 -28
  25. batFramework/gui/indicator.py +30 -16
  26. batFramework/gui/interactiveWidget.py +72 -20
  27. batFramework/gui/label.py +240 -98
  28. batFramework/gui/layout.py +125 -53
  29. batFramework/gui/meter.py +76 -0
  30. batFramework/gui/radioButton.py +62 -0
  31. batFramework/gui/root.py +72 -48
  32. batFramework/gui/shape.py +257 -49
  33. batFramework/gui/slider.py +217 -2
  34. batFramework/gui/textInput.py +106 -60
  35. batFramework/gui/toggle.py +85 -42
  36. batFramework/gui/widget.py +259 -288
  37. batFramework/manager.py +30 -16
  38. batFramework/object.py +115 -0
  39. batFramework/{particles.py → particle.py} +37 -34
  40. batFramework/renderGroup.py +62 -0
  41. batFramework/resourceManager.py +36 -24
  42. batFramework/scene.py +94 -88
  43. batFramework/sceneManager.py +140 -57
  44. batFramework/scrollingSprite.py +113 -0
  45. batFramework/sprite.py +35 -23
  46. batFramework/tileset.py +34 -52
  47. batFramework/time.py +105 -56
  48. batFramework/transition.py +213 -1
  49. batFramework/utils.py +38 -18
  50. {batframework-1.0.6.dist-info → batframework-1.0.8a1.dist-info}/METADATA +1 -1
  51. batframework-1.0.8a1.dist-info/RECORD +56 -0
  52. {batframework-1.0.6.dist-info → batframework-1.0.8a1.dist-info}/WHEEL +1 -1
  53. batFramework/easing.py +0 -76
  54. batFramework/gui/constraints.py +0 -277
  55. batFramework/gui/frame.py +0 -25
  56. batFramework/transitionManager.py +0 -0
  57. batframework-1.0.6.dist-info/RECORD +0 -50
  58. {batframework-1.0.6.dist-info → batframework-1.0.8a1.dist-info}/LICENCE +0 -0
  59. {batframework-1.0.6.dist-info → batframework-1.0.8a1.dist-info}/top_level.txt +0 -0
batFramework/scene.py CHANGED
@@ -10,7 +10,12 @@ import batFramework as bf
10
10
 
11
11
 
12
12
  class Scene:
13
- def __init__(self, name: str, enable_alpha: bool = True) -> None:
13
+ def __init__(
14
+ self,
15
+ name: str,
16
+ hud_convert_alpha: bool = True,
17
+ world_convert_alpha: bool = False,
18
+ ) -> None:
14
19
  """
15
20
  Initialize the Scene object.
16
21
 
@@ -19,30 +24,32 @@ class Scene:
19
24
  enable_alpha (bool, optional): Enable alpha channel for the scene surfaces. Defaults to True.
20
25
  """
21
26
  self.scene_index = 0
22
- self._name = name
27
+ self.name = name
23
28
  self.manager: Manager | None = None
24
- self._active = False
25
- self._visible = False
26
- self._world_entities: list[bf.Entity] = []
27
- self._hud_entities: list[bf.Entity] = []
29
+ self.active = False
30
+ self.visible = False
31
+ self.world_entities: list[bf.Entity] = []
32
+ self.hud_entities: list[bf.Entity] = []
28
33
  self.actions: bf.ActionContainer = bf.ActionContainer()
29
34
  self.early_actions: bf.ActionContainer = bf.ActionContainer()
30
- self.camera: bf.Camera = bf.Camera(convert_alpha=enable_alpha)
31
- self.hud_camera: bf.Camera = bf.Camera(convert_alpha=True)
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)
32
37
 
33
38
  self.root: bf.Root = bf.Root(self.hud_camera)
34
- self.root.set_center(*self.hud_camera.get_center())
39
+ self.root.rect.center = self.hud_camera.get_center()
35
40
  self.add_hud_entity(self.root)
36
- self.blit_calls = 0
37
41
 
42
+ def get_world_entity_count(self) -> int:
43
+ return len(self.world_entities)
38
44
 
39
- def get_world_entity_count(self)->int:
40
- return len(self._world_entities)
41
-
42
-
43
- def get_hud_entity_count(self)->int:
44
- return len(self._hud_entities) + self.root.count_children_recursive() -1
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)
45
51
 
52
+ return len(self.hud_entities) + n
46
53
 
47
54
  def set_scene_index(self, index: int):
48
55
  """Set the scene index."""
@@ -67,7 +74,7 @@ class Scene:
67
74
  return False
68
75
  return self.manager.set_sharedVar(name, value)
69
76
 
70
- def get_sharedVar(self, name: str,error_value=None) -> Any:
77
+ def get_sharedVar(self, name: str, error_value=None) -> Any:
71
78
  """
72
79
  Get a shared variable from the manager.
73
80
 
@@ -79,7 +86,7 @@ class Scene:
79
86
  """
80
87
  if not self.manager:
81
88
  return error_value
82
- return self.manager.get_sharedVar(name,error_value)
89
+ return self.manager.get_sharedVar(name, error_value)
83
90
 
84
91
  def do_when_added(self):
85
92
  pass
@@ -95,32 +102,32 @@ class Scene:
95
102
 
96
103
  def set_visible(self, value: bool):
97
104
  """Set the visibility of the scene."""
98
- self._visible = value
105
+ self.visible = value
99
106
  if self.manager:
100
107
  self.manager.update_scene_states()
101
108
 
102
109
  def set_active(self, value):
103
110
  """Set the activity of the scene."""
104
- self._active = value
111
+ self.active = value
105
112
  if self.manager:
106
113
  self.manager.update_scene_states()
107
114
 
108
115
  def is_active(self) -> bool:
109
116
  """Check if the scene is active."""
110
- return self._active
117
+ return self.active
111
118
 
112
119
  def is_visible(self) -> bool:
113
120
  """Check if the scene is visible."""
114
- return self._visible
121
+ return self.visible
115
122
 
116
123
  def get_name(self) -> str:
117
124
  """Get the name of the scene."""
118
- return self._name
125
+ return self.name
119
126
 
120
127
  def add_world_entity(self, *entity: bf.Entity):
121
128
  """Add world entities to the scene."""
122
129
  for e in entity:
123
- self._world_entities.append(e)
130
+ self.world_entities.append(e)
124
131
  e.parent_scene = self
125
132
  e.do_when_added()
126
133
  self.sort_entities()
@@ -128,17 +135,17 @@ class Scene:
128
135
  def remove_world_entity(self, *entity: bf.Entity):
129
136
  """Remove world entities from the scene."""
130
137
  for e in entity:
131
- if e not in self._world_entities:
138
+ if e not in self.world_entities:
132
139
  return False
133
140
  e.do_when_removed()
134
141
  e.parent_scene = None
135
- self._world_entities.remove(e)
142
+ self.world_entities.remove(e)
136
143
  return True
137
144
 
138
145
  def add_hud_entity(self, *entity: bf.Entity):
139
146
  """Add HUD entities to the scene."""
140
147
  for e in entity:
141
- self._hud_entities.append(e)
148
+ self.hud_entities.append(e)
142
149
  e.parent_scene = self
143
150
  e.do_when_added()
144
151
  self.sort_entities()
@@ -147,24 +154,24 @@ class Scene:
147
154
  def remove_hud_entity(self, *entity: bf.Entity):
148
155
  """Remove HUD entities from the scene."""
149
156
  for e in entity:
150
- if e in self._hud_entities:
157
+ if e in self.hud_entities:
151
158
  e.do_when_removed()
152
159
  e.parent_scene = None
153
- self._hud_entities.remove(e)
160
+ self.hud_entities.remove(e)
154
161
 
155
162
  def add_actions(self, *action):
156
163
  """Add actions to the scene."""
157
- self.actions.add_action(*action)
164
+ self.actions.add_actions(*action)
158
165
 
159
166
  def add_early_actions(self, *action):
160
167
  """Add actions to the scene."""
161
- self.early_actions.add_action(*action)
168
+ self.early_actions.add_actions(*action)
162
169
 
163
170
  def get_by_tags(self, *tags):
164
171
  """Get entities by their tags."""
165
172
  res = [
166
173
  entity
167
- for entity in self._world_entities + self._hud_entities
174
+ for entity in self.world_entities + self.hud_entities
168
175
  if any(entity.has_tags(t) for t in tags)
169
176
  ]
170
177
  res.extend(list(self.root.get_by_tags(*tags)))
@@ -172,7 +179,7 @@ class Scene:
172
179
 
173
180
  def get_by_uid(self, uid) -> bf.Entity | None:
174
181
  """Get an entity by its unique identifier."""
175
- res = self._find_entity_by_uid(uid, self._world_entities + self._hud_entities)
182
+ res = self._find_entity_by_uid(uid, self.world_entities + self.hud_entities)
176
183
  if res is None:
177
184
  res = self._recursive_search_by_uid(uid, self.root)
178
185
  return res
@@ -193,34 +200,36 @@ class Scene:
193
200
  res = self._recursive_search_by_uid(uid, child)
194
201
  if res is not None:
195
202
  return res
196
-
197
- return None
198
203
 
199
- # called before process event
200
- def do_early_process_event(self, event: pygame.Event) -> bool:
201
- """return True if stop event propagation in child entities and scene's action container"""
202
- return False
204
+ return None
203
205
 
204
206
  # propagates event to all entities
205
207
  def process_event(self, event: pygame.Event):
206
208
  """
207
- 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.
208
- Finally resets the action_container, and propagates to all child entities. if any of them returns True, the propagation is stopped.
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
209
217
  """
210
-
211
- if self.do_early_process_event(event):
212
- return
218
+ if event.consumed : return
219
+ self.do_early_handle_event(event)
220
+ if event.consumed : return
213
221
  self.early_actions.process_event(event)
214
- self.do_handle_actions()
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
215
226
  self.do_handle_event(event)
216
- for entity in self._hud_entities + self._world_entities:
217
- if entity.process_event(event):
218
- return
227
+ if event.consumed : return
219
228
  self.actions.process_event(event)
220
229
 
221
-
222
- def do_handle_actions(self) -> None:
223
- """Handle actions within the scene."""
230
+ # called before process event
231
+ def do_early_handle_event(self, event: pygame.Event) :
232
+ """Called early in event propagation"""
224
233
  pass
225
234
 
226
235
  def do_handle_event(self, event: pygame.Event):
@@ -229,7 +238,7 @@ class Scene:
229
238
 
230
239
  def update(self, dt):
231
240
  """Update the scene. Do NOT override"""
232
- for entity in self._world_entities + self._hud_entities:
241
+ for entity in self.world_entities + self.hud_entities:
233
242
  entity.update(dt)
234
243
  self.do_update(dt)
235
244
  self.camera.update(dt)
@@ -242,57 +251,47 @@ class Scene:
242
251
  pass
243
252
 
244
253
  def debug_entity(self, entity: bf.Entity, camera: bf.Camera):
245
- if not entity.visible:
246
- return
247
- # bounding_box = entity.get_bounding_box()
248
- # if bounding_box is None : return
249
- for data in entity.get_bounding_box():
250
- if data is None : return
251
- if isinstance(data, pygame.FRect) or isinstance(data, pygame.Rect):
254
+ def draw_rect(data):
255
+ if data is None:
256
+ return
257
+ if isinstance(data, pygame.FRect) or isinstance(data, pygame.Rect):
252
258
  rect = data
253
259
  color = entity.debug_color
254
260
  else:
255
261
  rect = data[0]
256
262
  color = data[1]
263
+ pygame.draw.rect(camera.surface, color, camera.world_to_screen(rect), 1)
257
264
 
258
- pygame.draw.rect(camera.surface, color, camera.transpose(rect), 1)
265
+ [draw_rect(data) for data in entity.get_debug_outlines()]
259
266
 
260
267
  def sort_entities(self) -> None:
261
268
  """Sort entities within the scene based on their rendering order."""
262
- self._world_entities.sort(key=lambda e: e.render_order)
263
- self._hud_entities.sort(key=lambda e: e.render_order)
264
-
265
- def draw(self, surface: pygame.Surface):
266
- total_blit_calls = 0
267
- if not self.manager : return
268
- self.camera.clear()
269
- self.hud_camera.clear()
269
+ self.world_entities.sort(key=lambda e: e.render_order)
270
+ self.hud_entities.sort(key=lambda e: e.render_order)
270
271
 
271
- show_outlines = self.manager._debugging in [2, 3]
272
- show_only_visible_outlines = self.manager._debugging != 3
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]
273
278
 
274
279
 
275
- # draw all world entities
276
- total_blit_calls += sum(entity.draw(self.camera) for entity in self._world_entities)
277
-
278
- #
279
- if show_outlines:
280
- [self.debug_entity(entity, self.camera) for entity\
281
- in self._world_entities if not show_only_visible_outlines\
282
- or (show_only_visible_outlines and entity.visible)]
280
+ def draw(self, surface: pygame.Surface):
283
281
 
284
- total_blit_calls += sum(entity.draw(self.hud_camera) for entity in self._hud_entities)
282
+ self.camera.clear()
283
+ self.hud_camera.clear()
285
284
 
286
- if show_outlines:
287
- [self.debug_entity(entity, self.hud_camera) for entity\
288
- in self._hud_entities if not show_only_visible_outlines\
289
- or (show_only_visible_outlines and entity.visible)]
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)
290
289
 
291
290
  self.do_early_draw(surface)
292
291
  self.camera.draw(surface)
292
+ self.do_post_world_draw(surface)
293
293
  self.hud_camera.draw(surface)
294
294
  self.do_final_draw(surface)
295
- self.blit_calls = total_blit_calls
296
295
 
297
296
  def do_early_draw(self, surface: pygame.Surface):
298
297
  pass
@@ -307,21 +306,28 @@ class Scene:
307
306
  self.set_active(True)
308
307
  self.set_visible(True)
309
308
  self.root.clear_hovered()
310
- self.root.clear_focused()
309
+ # self.root.clear_focused()
311
310
  self.root.build()
312
311
  self.do_on_enter()
312
+ # self.root.visit(lambda e : e.resolve_constraints())
313
313
 
314
314
  def on_exit(self):
315
315
  self.root.clear_hovered()
316
- self.root.clear_focused()
316
+ # self.root.clear_focused()
317
317
  self.set_active(False)
318
318
  self.set_visible(False)
319
319
  self.actions.hard_reset()
320
320
  self.early_actions.hard_reset()
321
321
  self.do_on_exit()
322
322
 
323
- def do_on_enter(self)->None:
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:
324
330
  pass
325
331
 
326
- def do_on_exit(self)->None:
332
+ def do_on_exit_early(self) -> None:
327
333
  pass
@@ -1,116 +1,189 @@
1
1
  import batFramework as bf
2
2
  import pygame
3
+ from typing import Self
4
+
5
+ def swap(lst, index1, index2):
6
+ lst[index1], lst[index2] = lst[index2], lst[index1]
3
7
 
4
8
 
5
9
  class SceneManager:
6
- def __init__(self, *initial_scenes: bf.Scene) -> None:
7
- self._debugging :int = 0
8
- self._sharedVarDict : dict = {}
10
+ def __init__(self) -> None:
11
+ self.scenes: list[bf.Scene] = []
12
+ self.shared_variables: dict = {}
13
+ self.shared_events = {pygame.WINDOWRESIZED}
9
14
 
10
- self._scene_transitions: list = []
11
- self.set_sharedVar("debugging_mode",self._debugging)
12
15
  self.set_sharedVar("in_cutscene", False)
13
16
  self.set_sharedVar("player_has_control", True)
14
17
 
15
- self._scenes: list[bf.Scene] = list(initial_scenes)
16
- for index, s in enumerate(self._scenes):
17
- s.set_manager(self)
18
+ self.debug_mode: bf.enums.debugMode = bf.debugMode.HIDDEN
19
+ self.current_transitions: dict[str, bf.transition.Transition] = {}
20
+
21
+
22
+
23
+ def init_scenes(self,*initial_scenes):
24
+ for index, s in enumerate(initial_scenes):
18
25
  s.set_scene_index(index)
19
- s.do_when_added()
20
- self.set_scene(self._scenes[0]._name)
26
+ for s in reversed(initial_scenes):
27
+ self.add_scene(s)
28
+ # self.scenes = list(initial_scenes)
29
+ self.set_scene(initial_scenes[0].get_name())
21
30
  self.update_scene_states()
22
31
 
32
+ def set_shared_event(self,event:pygame.Event)->None:
33
+ """
34
+ Add an event that will be propagated to all active scenes, not just the one on top.
35
+ """
36
+ self.shared_events.add(event)
37
+
23
38
  def print_status(self):
39
+ """
40
+ Print some information about the current state of the scenes.
41
+ """
24
42
  print("-" * 40)
25
- print([(s._name, "Active" if s._active else "Inactive","Visible" if s._visible else "Invisible", f"index={s.scene_index}") for s in self._scenes])
26
- print(f"[Debugging] = {self._debugging}")
43
+ print(
44
+ '\n'.join(
45
+ f" {s.name:<30}\t{'Active' if s.active else 'Inactive'}\t{'Visible' if s.visible else 'Invisible'}\tindex= {s.scene_index}"
46
+ for s in self.scenes
47
+ )
48
+ )
49
+ print(f"[Debugging] = {self.debug_mode}")
27
50
  print("---SHARED VARIABLES---")
28
- for name, value in self._sharedVarDict.items():
51
+ for name, value in self.shared_variables.items():
29
52
  print(f"[{str(name)} = {str(value)}]")
30
53
  print("-" * 40)
31
54
 
32
55
  def set_sharedVar(self, name, value) -> bool:
33
- self._sharedVarDict[name] = value
56
+ """
57
+ Set a shared variable of any type. This will be accessible (read/write) from any scene
58
+ """
59
+ self.shared_variables[name] = value
34
60
  return True
35
61
 
36
- def get_sharedVar(self, name,error_value=None):
37
- if name not in self._sharedVarDict:
38
- return error_value
39
- return self._sharedVarDict[name]
62
+ def get_sharedVar(self, name, error_value=None):
63
+ """
64
+ Get a shared variable
65
+ """
66
+ return self.shared_variables.get(name,error_value)
40
67
 
41
68
  def get_current_scene_name(self) -> str:
42
- return self._scenes[0].get_name()
69
+ """get the name of the current scene"""
70
+ return self.scenes[0].get_name()
43
71
 
44
72
  def get_current_scene(self) -> bf.Scene:
45
- return self._scenes[0]
73
+ return self.scenes[0]
46
74
 
47
75
  def update_scene_states(self):
48
- self.active_scenes = [s for s in reversed(self._scenes) if s._active]
49
- self.visible_scenes = [s for s in reversed(self._scenes) if s._visible]
76
+ self.active_scenes = [s for s in reversed(self.scenes) if s.active]
77
+ self.visible_scenes = [s for s in reversed(self.scenes) if s.visible]
50
78
 
51
79
  def add_scene(self, scene: bf.Scene):
52
- if scene in self._scenes and not self.has_scene(scene._name):
80
+ if scene in self.scenes and not self.has_scene(scene.name):
53
81
  return
54
82
  scene.set_manager(self)
55
83
  scene.do_when_added()
56
- self._scenes.insert(0, scene)
84
+ self.scenes.insert(0, scene)
57
85
 
58
86
  def remove_scene(self, name: str):
59
- self._scenes = [s for s in self._scenes if s._name != name]
87
+ self.scenes = [s for s in self.scenes if s.name != name]
60
88
 
61
89
  def has_scene(self, name):
62
- return any(name == scene._name for scene in self._scenes)
90
+ return any(name == scene.name for scene in self.scenes)
63
91
 
64
92
  def get_scene(self, name):
65
93
  if not self.has_scene(name):
66
94
  return None
67
- for scene in self._scenes:
68
- if scene._name == name:
95
+ for scene in self.scenes:
96
+ if scene.name == name:
69
97
  return scene
70
98
 
71
- def get_scene_at(self,index:int)->bf.Scene|None:
72
- if index < 0 or index >= len(self._scenes) : return None
73
- return self._scenes[index]
74
-
75
- def transition_to_scene(self, dest_scene_name, transition, **kwargs):
76
- self.set_scene(dest_scene_name)
99
+ def get_scene_at(self, index: int) -> bf.Scene | None:
100
+ if index < 0 or index >= len(self.scenes):
101
+ return None
102
+ return self.scenes[index]
103
+
104
+ def transition_to_scene(
105
+ self,
106
+ scene_name: str,
107
+ transition: bf.transition.Transition = bf.transition.Fade(0.1),
108
+ index: int = 0,
109
+ ):
110
+ target_scene = self.get_scene(scene_name)
111
+ if not target_scene :
112
+ print(f"Scene '{scene_name}' does not exist")
113
+ return
114
+ if (
115
+ len(self.scenes) == 0
116
+ or index >= len(self.scenes)
117
+ or index < 0
118
+ ):
119
+ return
120
+ source_surface = bf.const.SCREEN.copy()
121
+ dest_surface = bf.const.SCREEN.copy()
122
+
123
+ # self.draw(source_surface)
124
+ target_scene.draw(dest_surface)
125
+ target_scene.do_on_enter_early()
126
+ self.get_scene_at(index).do_on_exit_early()
127
+ self.current_transitions = {"scene_name": scene_name, "transition": transition}
128
+ transition.set_start_callback(lambda: self._start_transition(target_scene))
129
+ transition.set_end_callback(lambda: self._end_transition(scene_name, index))
130
+ transition.set_source(source_surface)
131
+ transition.set_dest(dest_surface)
132
+ transition.start()
133
+
134
+ def _start_transition(self, target_scene: bf.Scene):
135
+ target_scene.set_active(True)
136
+ target_scene.set_visible(True)
137
+ self.set_sharedVar("player_has_control", False)
138
+
139
+ def _end_transition(self, scene_name, index):
140
+ self.set_scene(scene_name, index)
141
+ self.set_sharedVar("player_has_control", True)
142
+ self.current_transitions.clear()
77
143
 
78
- def set_scene(self, name, index=0):
79
- target_scene = self.get_scene(name)
144
+ def set_scene(self, scene_name, index=0):
145
+ target_scene = self.get_scene(scene_name)
146
+ if not target_scene :
147
+ print(f"'{scene_name}' does not exist")
148
+ return
80
149
  if (
81
- len(self._scenes) == 0
82
- or not target_scene
83
- or index >= len(self._scenes)
150
+ len(self.scenes) == 0
151
+ or index >= len(self.scenes)
84
152
  or index < 0
85
153
  ):
86
154
  return
87
155
 
88
- old_scene = self._scenes[index]
89
156
  # switch
90
- old_scene.on_exit()
91
- self.remove_scene(name)
92
- self._scenes.insert(index, target_scene)
93
- _ = [s.set_scene_index(i) for i, s in enumerate(self._scenes)]
157
+ self.scenes[index].on_exit()
158
+ # re-insert scene at index 0
159
+ self.scenes.remove(target_scene)
160
+ self.scenes.insert(index, target_scene)
161
+ _ = [s.set_scene_index(i) for i, s in enumerate(self.scenes)]
94
162
  target_scene.on_enter()
95
163
 
164
+ def cycle_debug_mode(self):
165
+ current_index = self.debug_mode.value
166
+ next_index = (current_index + 1) % len(bf.debugMode)
167
+ return bf.debugMode(next_index)
168
+
96
169
  def process_event(self, event: pygame.Event):
97
170
  keys = pygame.key.get_pressed()
98
171
  if (
99
172
  keys[pygame.K_LCTRL]
173
+ and keys[pygame.K_LSHIFT]
100
174
  and event.type == pygame.KEYDOWN
101
- and event.key == pygame.K_d
102
175
  ):
103
- self._debugging = (self._debugging + 1) % 4
104
- self.set_sharedVar("debugging_mode",self._debugging)
105
- return
106
- if (
107
- keys[pygame.K_LCTRL]
108
- and event.type == pygame.KEYDOWN
109
- and event.key == pygame.K_p
110
- ):
111
- self.print_status()
112
- return
113
- self._scenes[0].process_event(event)
176
+ if event.key == pygame.K_d:
177
+ self.debug_mode = self.cycle_debug_mode()
178
+ self.set_sharedVar("debug_mode", self.debug_mode)
179
+ return
180
+ if event.key == pygame.K_p:
181
+ self.print_status()
182
+ return
183
+ if event.type in self.shared_events:
184
+ [s.process_event(event) for s in self.scenes]
185
+ else:
186
+ self.scenes[0].process_event(event)
114
187
 
115
188
  def update(self, dt: float) -> None:
116
189
  for scene in self.active_scenes:
@@ -118,8 +191,18 @@ class SceneManager:
118
191
  self.do_update(dt)
119
192
 
120
193
  def do_update(self, dt: float):
121
- return
194
+ pass
122
195
 
123
196
  def draw(self, surface) -> None:
124
197
  for scene in self.visible_scenes:
125
198
  scene.draw(surface)
199
+ if self.current_transitions:
200
+ self._draw_transition(surface)
201
+
202
+ def _draw_transition(self, surface):
203
+ self.current_transitions["transition"].set_source(surface)
204
+ tmp = bf.const.SCREEN.copy()
205
+ self.get_scene(self.current_transitions["scene_name"]).draw(tmp)
206
+ self.current_transitions["transition"].set_dest(tmp)
207
+ self.current_transitions["transition"].draw(surface)
208
+ return