batframework 1.0.9a7__py3-none-any.whl → 1.0.9a9__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 (62) hide show
  1. batFramework/__init__.py +20 -11
  2. batFramework/action.py +1 -1
  3. batFramework/animatedSprite.py +47 -116
  4. batFramework/animation.py +30 -5
  5. batFramework/audioManager.py +8 -5
  6. batFramework/baseScene.py +240 -0
  7. batFramework/camera.py +4 -0
  8. batFramework/constants.py +6 -2
  9. batFramework/cutscene.py +221 -21
  10. batFramework/cutsceneManager.py +5 -2
  11. batFramework/drawable.py +7 -5
  12. batFramework/easingController.py +10 -11
  13. batFramework/entity.py +21 -2
  14. batFramework/enums.py +48 -33
  15. batFramework/gui/__init__.py +6 -3
  16. batFramework/gui/animatedLabel.py +10 -2
  17. batFramework/gui/button.py +4 -31
  18. batFramework/gui/clickableWidget.py +63 -50
  19. batFramework/gui/constraints/constraints.py +212 -136
  20. batFramework/gui/container.py +77 -58
  21. batFramework/gui/debugger.py +12 -17
  22. batFramework/gui/draggableWidget.py +21 -17
  23. batFramework/gui/image.py +3 -10
  24. batFramework/gui/indicator.py +56 -1
  25. batFramework/gui/interactiveWidget.py +127 -108
  26. batFramework/gui/label.py +73 -64
  27. batFramework/gui/layout.py +286 -445
  28. batFramework/gui/meter.py +42 -20
  29. batFramework/gui/radioButton.py +20 -69
  30. batFramework/gui/root.py +99 -29
  31. batFramework/gui/selector.py +250 -0
  32. batFramework/gui/shape.py +13 -5
  33. batFramework/gui/slider.py +262 -107
  34. batFramework/gui/syncedVar.py +49 -0
  35. batFramework/gui/textInput.py +46 -22
  36. batFramework/gui/toggle.py +70 -52
  37. batFramework/gui/tooltip.py +30 -0
  38. batFramework/gui/widget.py +222 -135
  39. batFramework/manager.py +7 -8
  40. batFramework/particle.py +4 -1
  41. batFramework/propertyEaser.py +79 -0
  42. batFramework/renderGroup.py +17 -50
  43. batFramework/resourceManager.py +43 -13
  44. batFramework/scene.py +15 -335
  45. batFramework/sceneLayer.py +138 -0
  46. batFramework/sceneManager.py +31 -36
  47. batFramework/scrollingSprite.py +8 -3
  48. batFramework/sprite.py +1 -1
  49. batFramework/templates/__init__.py +1 -2
  50. batFramework/templates/controller.py +97 -0
  51. batFramework/timeManager.py +76 -22
  52. batFramework/transition.py +37 -103
  53. batFramework/utils.py +125 -66
  54. {batframework-1.0.9a7.dist-info → batframework-1.0.9a9.dist-info}/METADATA +24 -3
  55. batframework-1.0.9a9.dist-info/RECORD +67 -0
  56. {batframework-1.0.9a7.dist-info → batframework-1.0.9a9.dist-info}/WHEEL +1 -1
  57. batFramework/character.py +0 -27
  58. batFramework/templates/character.py +0 -43
  59. batFramework/templates/states.py +0 -166
  60. batframework-1.0.9a7.dist-info/RECORD +0 -63
  61. /batframework-1.0.9a7.dist-info/LICENCE → /batframework-1.0.9a9.dist-info/LICENSE +0 -0
  62. {batframework-1.0.9a7.dist-info → batframework-1.0.9a9.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,79 @@
1
+ from .easingController import EasingController
2
+ import pygame
3
+ from typing import Callable, Any, Self
4
+ import batFramework as bf
5
+
6
+ class PropertyEaser(EasingController):
7
+ class EasedProperty:
8
+ def __init__(self, getter: Callable[[], Any], setter: Callable[[Any], None], end_value: Any, start_value: Any = None):
9
+ self.getter = getter
10
+ self.setter = setter
11
+ self.start_value = start_value if start_value is not None else getter()
12
+ self.end_value = end_value
13
+
14
+ def interpolate(self, t: float):
15
+ a, b = self.start_value, self.end_value
16
+ if isinstance(a, (int, float)):
17
+ return a + (b - a) * t
18
+ elif isinstance(a, pygame.Vector2):
19
+ return a.lerp(b, t)
20
+ elif isinstance(a, pygame.Color):
21
+ return pygame.Color(
22
+ round(a.r + (b.r - a.r) * t),
23
+ round(a.g + (b.g - a.g) * t),
24
+ round(a.b + (b.b - a.b) * t),
25
+ round(a.a + (b.a - a.a) * t),
26
+ )
27
+ else:
28
+ raise TypeError(f"Unsupported type for interpolation: {type(a)}")
29
+
30
+ def apply(self, t: float):
31
+ self.setter(self.interpolate(t))
32
+
33
+ def __init__(
34
+ self,
35
+ duration: float = 1,
36
+ easing: bf.easing = bf.easing.LINEAR,
37
+ loop: int = 0,
38
+ register: str = "global",
39
+ end_callback: Callable[[], Any] = None,
40
+ ):
41
+ self.properties: list[PropertyEaser.EasedProperty] = []
42
+
43
+ def update_all(progress):
44
+ for prop in self.properties:
45
+ prop.apply(progress)
46
+
47
+ super().__init__(duration, easing, update_all, end_callback, loop, register)
48
+
49
+ def __str__(self):
50
+ return f"(PROP){super().__str__()}"
51
+
52
+ def add_attr(
53
+ self,
54
+ obj: Any,
55
+ attr: str,
56
+ end_value: Any,
57
+ start_value: Any = None,
58
+ )->Self:
59
+ self.properties.append(
60
+ PropertyEaser.EasedProperty(
61
+ getter=lambda o=obj, a=attr: getattr(o, a),
62
+ setter=lambda v, o=obj, a=attr: setattr(o, a, v),
63
+ end_value=end_value,
64
+ start_value=start_value,
65
+ )
66
+ )
67
+ return self
68
+
69
+ def add_custom(
70
+ self,
71
+ getter: Callable[[], Any],
72
+ setter: Callable[[Any], None],
73
+ end_value: Any,
74
+ start_value: Any = None,
75
+ )->Self:
76
+ self.properties.append(
77
+ PropertyEaser.EasedProperty(getter, setter, end_value, start_value)
78
+ )
79
+ return self
@@ -1,11 +1,6 @@
1
1
  import batFramework as bf
2
2
  import pygame
3
- from typing import Self, Iterator, Callable
4
-
5
- """
6
- + same render order
7
- + fblits
8
- """
3
+ from typing import Callable, Iterator
9
4
 
10
5
 
11
6
  class RenderGroup(bf.Drawable):
@@ -14,54 +9,26 @@ class RenderGroup(bf.Drawable):
14
9
  ) -> None:
15
10
  super().__init__()
16
11
  self.entity_iterator = entity_iterator
17
- # self.set_blit_flags(blit_flags)
12
+ self.blit_flags = blit_flags
18
13
  self.set_debug_color("white")
19
14
 
20
- def get_debug_outlines(self):
21
- # yield (self.rect, self.debug_color)
22
- for e in self.entity_iterator():
23
- yield from e.get_debug_outlines()
24
-
25
- def set_parent_scene(self, scene) -> Self:
26
- self.parent_scene = scene
27
- for e in self.entity_iterator():
28
- e.set_parent_scene(scene)
29
- return self
30
-
31
- def process_event(self, event: pygame.Event) -> bool:
32
- """
33
- Returns bool : True if the method is blocking (no propagation to next children of the scene)
34
- """
35
- self.do_process_actions(event)
36
- res = self.do_handle_event(event)
37
- if res:
38
- return res
39
- for e in self.entity_iterator():
40
- if e.process_event(event):
41
- return True
42
- return False
15
+ def draw(self, camera: bf.Camera) -> None:
16
+ if not self.visible:
17
+ return
43
18
 
44
- def update(self, dt: float) -> None:
45
- """
46
- Update method to be overriden by subclasses of entity
47
- """
19
+ fblits_data = []
48
20
  for e in self.entity_iterator():
49
- e.update(dt)
50
- # gen = self.entity_iterator()
51
- # self.rect = next(gen).rect.unionall([e.rect for e in gen])
21
+ if not getattr(e, "drawn_by_group", False):
22
+ # Set flag to skip their individual draw call
23
+ e.drawn_by_group = True
52
24
 
53
- self.do_update(dt)
54
- self.do_reset_actions()
25
+ if e.visible and camera.rect.colliderect(e.rect):
26
+ fblits_data.append(
27
+ (e.surface, (e.rect.x - camera.rect.x, e.rect.y - camera.rect.y))
28
+ )
55
29
 
56
- def draw(self, camera: bf.Camera) -> None:
57
- """
58
- Draw the entity onto the camera with coordinate transposing
59
- """
60
- if not self.visible:
61
- return
62
- fblits_data = (
63
- (e.surface, (e.rect.x - camera.rect.x, e.rect.y - camera.rect.y))
64
- for e in self.entity_iterator()
65
- if camera.rect.colliderect(e.rect)
66
- )
67
30
  camera.surface.fblits(fblits_data, self.blit_flags)
31
+
32
+ def get_debug_outlines(self):
33
+ for e in self.entity_iterator():
34
+ yield from e.get_debug_outlines()
@@ -3,8 +3,10 @@ import os
3
3
  import pygame
4
4
  import sys
5
5
  import json
6
- from typing import Any
6
+ from typing import Any, Callable
7
7
  from .utils import Singleton
8
+ import asyncio
9
+
8
10
 
9
11
  if getattr(sys, "frozen", False):
10
12
  # If the application is run as a bundle, the PyInstaller bootloader
@@ -17,32 +19,50 @@ else:
17
19
 
18
20
  class ResourceManager(metaclass=Singleton):
19
21
  def __init__(self):
20
- self.shared_variables: dict[str,Any] = {}
22
+ self.shared_variables: dict[str, Any] = {}
21
23
  self.convert_image_cache = {}
22
24
  self.convert_alpha_image_cache = {}
23
25
  self.sound_cache = {}
24
26
  self.RESOURCE_PATH = "."
27
+ self.loading_thread = None
25
28
 
26
- def load_dir(self, path) -> None:
27
- for root, dirs, files in os.walk(path):
28
- files = [f for f in files if not f[0] == "."]
29
- dirs[:] = [d for d in dirs if not d[0] == "."]
29
+ def load_resources(self, path: str, progress_callback: Callable[[float], Any] = None):
30
+ """
31
+ loads resources from a directory.
32
+ Progress is reported through the callback.
33
+ Supposed to be asynchronous but don't use it as such yet
34
+ """
35
+ self.progress_callback = progress_callback
36
+
37
+ total_files = sum(
38
+ len(files) for _, _, files in os.walk(path) if not any(f.startswith(".") for f in files)
39
+ )
40
+
41
+ loaded_files = 0
30
42
 
43
+ for root, dirs, files in os.walk(path):
44
+ files = [f for f in files if not f.startswith(".")]
45
+ dirs[:] = [d for d in dirs if not (d.startswith(".") or d.startswith("__"))]
31
46
  for file in files:
32
47
  file_path = os.path.join(root, file)
48
+
49
+ # Simulate resource loading
50
+ # await asyncio.sleep(0) # Yield control to the event loop
51
+
33
52
  if file.lower().endswith((".png", ".jpg", ".jpeg", ".gif")):
34
53
  self.load_image(file_path)
35
- # print(f"Loaded image : '{file_path}'")
36
-
37
- elif file.lower().endswith((".mp3", ".wav")):
54
+ elif file.lower().endswith((".mp3", ".wav", ".ogg")):
38
55
  bf.AudioManager().load_sound(file.split(".")[0], file_path)
39
- # print(f"Loaded sound : '{file_path}'")
40
-
41
56
  elif file.lower().endswith((".ttf", ".otf")):
42
57
  bf.FontManager().load_font(file_path, file.split(".")[0])
43
- # print(f"Loaded font : '{file_path}'")
44
58
 
45
- print(f"Loaded resources in directory : '{path}'")
59
+ loaded_files += 1
60
+ # Report progress
61
+ # if self.progress_callback:
62
+ # self.progress_callback(loaded_files / total_files)
63
+
64
+ print(f"Loaded resources in directory: '{path}'")
65
+
46
66
 
47
67
  def set_resource_path(self, path: str):
48
68
  self.RESOURCE_PATH = os.path.join(application_path, path)
@@ -60,6 +80,7 @@ class ResourceManager(metaclass=Singleton):
60
80
  self.convert_image_cache[key] = pygame.image.load(path).convert()
61
81
  self.convert_alpha_image_cache[key] = pygame.image.load(path).convert_alpha()
62
82
 
83
+
63
84
  def get_image(self, path, convert_alpha: bool = False) -> pygame.Surface | None:
64
85
  key = self.get_path(path)
65
86
  return (
@@ -93,6 +114,15 @@ class ResourceManager(metaclass=Singleton):
93
114
  self.shared_variables[name] = value
94
115
  return True
95
116
 
117
+ def set_sharedVars(self, variables: dict) -> bool:
118
+ """
119
+ Set multiple shared variables at once. This will be accessible (read/write) from any scene.
120
+ """
121
+ if not isinstance(variables, dict):
122
+ raise ValueError("Input must be a dictionary")
123
+ self.shared_variables.update(variables)
124
+ return True
125
+
96
126
  def get_sharedVar(self, name, error_value=None):
97
127
  """
98
128
  Get a shared variable
batFramework/scene.py CHANGED
@@ -1,351 +1,31 @@
1
- from __future__ import annotations
2
- import re
3
- from collections import OrderedDict
4
- import itertools
5
-
6
- from typing import TYPE_CHECKING, Any
7
- if TYPE_CHECKING:
8
- from .manager import Manager
9
- from .sceneManager import SceneManager
10
- import pygame
1
+ from .baseScene import BaseScene
11
2
  import batFramework as bf
12
3
 
13
4
 
14
- class Scene:
15
- def __init__(
16
- self,
17
- name: str,
18
- hud_convert_alpha: bool = True,
19
- world_convert_alpha: bool = False,
20
- ) -> None:
5
+ class Scene(BaseScene):
6
+ def __init__(self,name: str) -> None:
21
7
  """
22
- Initialize the Scene object.
23
-
8
+ Default Scene object.
9
+ Has 2 layers (world and hud) by default
10
+ Contains an exposed root gui object on the hud layer
24
11
  Args:
25
12
  name: Name of the scene.
26
- enable_alpha (bool, optional): Enable alpha channel for the scene surfaces. Defaults to True.
27
13
  """
28
- self.scene_index = 0
29
- self.name = name
30
- bf.TimeManager().add_register(self.name,False)
31
- 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
- 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)
14
+ super().__init__(name)
15
+ self.add_layer(bf.SceneLayer("world",True))
16
+ hud_layer = bf.SceneLayer("hud",True)
17
+ self.add_layer(hud_layer)
18
+ self.root: bf.gui.Root = bf.gui.Root(hud_layer.camera)
19
+ self.root.rect.center = hud_layer.camera.get_center()
20
+ self.add("hud",self.root)
44
21
  self.entities_to_remove = []
45
22
  self.entities_to_add = []
46
23
 
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)
60
-
61
- self.root.visit(adder)
62
-
63
- return len(self.hud_entities) + n
64
-
65
- def set_scene_index(self, index: int):
66
- """Set the scene index."""
67
- self.scene_index = index
68
-
69
- def get_scene_index(self) -> int:
70
- """Get the scene index."""
71
- return self.scene_index
72
-
73
- def do_when_added(self):
74
- pass
75
-
76
- def set_clear_color(self, color: pygame.Color | tuple):
77
- """Set the clear color for the camera."""
78
- self.camera.set_clear_color(color)
79
-
80
- def set_manager(self, manager_link: Manager):
81
- """Set the manager link for the scene."""
82
- self.manager = manager_link
83
- self.manager.update_scene_states()
84
-
85
- def set_visible(self, value: bool):
86
- """Set the visibility of the scene."""
87
- self.visible = value
88
- if self.manager:
89
- self.manager.update_scene_states()
90
-
91
- def set_active(self, value):
92
- """Set the activity of the scene."""
93
- self.active = value
94
- if self.manager:
95
- self.manager.update_scene_states()
96
-
97
- def is_active(self) -> bool:
98
- """Check if the scene is active."""
99
- return self.active
100
-
101
- def is_visible(self) -> bool:
102
- """Check if the scene is visible."""
103
- return self.visible
104
-
105
- def get_name(self) -> str:
106
- """Get the name of the scene."""
107
- return self.name
108
-
109
- def add_world_entity(self, *entities: bf.Entity):
110
- """Add world entities to the scene."""
111
- change = False
112
- for e in entities:
113
- if e not in self.world_entities and e not in self.entities_to_add:
114
- change = True
115
- # self.world_entities[e] = None
116
- self.entities_to_add.append(e)
117
- e.set_parent_scene(self)
118
- # self.sort_entities()
119
- return change
120
-
121
- # Updated remove_world_entity method to add entities to the removal list
122
- def remove_world_entity(self, *entities: bf.Entity):
123
- """Mark world entities for removal from the scene."""
124
- change = False
125
- for e in entities:
126
- if e in self.world_entities:
127
- change = True
128
- self.entities_to_remove.append(e)
129
- e.set_parent_scene(None)
130
- return change
131
-
132
- def add_hud_entity(self, *entities: bf.Entity):
133
- """Add HUD entities to the scene."""
134
- for e in entities:
135
- if e not in self.hud_entities:
136
- self.hud_entities[e] = None
137
- e.set_parent_scene(self)
138
- self.sort_entities()
139
- return True
140
-
141
- def remove_hud_entity(self, *entities: bf.Entity):
142
- """Remove HUD entities from the scene."""
143
- for e in entities:
144
- if e in self.hud_entities:
145
- e.set_parent_scene(None)
146
- self.hud_entities.pop(e)
147
-
148
- def add_actions(self, *action):
149
- """Add actions to the scene."""
150
- self.actions.add_actions(*action)
151
-
152
- def add_early_actions(self, *action):
153
- """Add actions to the scene."""
154
- self.early_actions.add_actions(*action)
155
-
156
- def get_by_tags(self, *tags):
157
- """Get entities by their tags."""
158
- res = [
159
- entity
160
- for entity in itertools.chain(
161
- self.world_entities.keys(), self.hud_entities.keys()
162
- )
163
- if any(entity.has_tags(t) for t in tags)
164
- ]
165
- res.extend(list(self.root.get_by_tags(*tags)))
166
- return res
167
-
168
- def get_by_uid(self, uid) -> bf.Entity | None:
169
- """Get an entity by its unique identifier."""
170
- res = self._find_entity_by_uid(
171
- uid, itertools.chain(self.world_entities.keys(), self.hud_entities.keys())
172
- )
173
- if res is None:
174
- res = self._recursive_search_by_uid(uid, self.root)
175
- return res
176
-
177
- def _find_entity_by_uid(self, uid, entities) -> bf.Entity | None:
178
- """Search for entity by uid in a list of entities."""
179
- for entity in entities:
180
- if entity.uid == uid:
181
- return entity
182
- return None
183
-
184
- def _recursive_search_by_uid(self, uid, widget) -> bf.Entity | None:
185
- """Recursively search for entity by uid in the widget's children."""
186
- if widget.uid == uid:
187
- return widget
188
-
189
- for child in widget.children:
190
- res = self._recursive_search_by_uid(uid, child)
191
- if res is not None:
192
- return res
193
-
194
- return None
195
-
196
- def process_event(self, event: pygame.Event):
197
- """
198
- Propagates event while it is not consumed.
199
- In order :
200
- -do_early_handle_event()
201
- -scene early_actions
202
- -propagate to scene entities (hud then world)
203
- -do_handle_event()
204
- -scene actions
205
- at each step, if the event is consumed the propagation stops
206
- """
207
- if event.consumed:
208
- return
209
- self.do_early_handle_event(event)
210
- if event.consumed:
211
- return
212
- self.early_actions.process_event(event)
213
- if event.consumed:
214
- return
215
- for entity in itertools.chain(
216
- self.hud_entities.keys(), self.world_entities.keys()
217
- ):
218
- entity.process_event(event)
219
- if event.consumed:
220
- return
221
- self.do_handle_event(event)
222
- if event.consumed:
223
- return
224
- self.actions.process_event(event)
225
-
226
- # called before process event
227
- def do_early_handle_event(self, event: pygame.Event):
228
- """Called early in event propagation"""
229
- pass
230
-
231
- def do_handle_event(self, event: pygame.Event):
232
- """called inside process_event but before resetting the scene's action container and propagating event to child entities of the scene"""
233
- pass
234
-
235
- def update(self, dt):
236
- """Update the scene. Do NOT override"""
237
- if self.should_sort:
238
- self._sort_entities_internal()
239
-
240
- for entity in itertools.chain(
241
- self.hud_entities.keys(), self.world_entities.keys()
242
- ):
243
- entity.update(dt)
244
-
245
- self.do_update(dt)
246
- self.camera.update(dt)
247
- self.hud_camera.update(dt)
248
- self.actions.reset()
249
- self.early_actions.reset()
250
-
251
- if self.entities_to_add:
252
- for e in self.entities_to_add:
253
- self.world_entities[e] = None
254
- self.entities_to_add.clear()
255
-
256
- # Remove marked entities after updating
257
- if self.entities_to_remove:
258
- for e in self.entities_to_remove:
259
- self.world_entities.pop(e, None)
260
- self.entities_to_remove.clear()
261
-
262
- def do_update(self, dt):
263
- """Specific update within the scene."""
264
- pass
265
-
266
- def debug_entity(self, entity: bf.Entity, camera: bf.Camera):
267
- def draw_rect(data):
268
- if data is None:
269
- return
270
- if isinstance(data, pygame.FRect) or isinstance(data, pygame.Rect):
271
- rect = data
272
- color = entity.debug_color
273
- else:
274
- rect = data[0]
275
- color = data[1]
276
- pygame.draw.rect(camera.surface, color, camera.world_to_screen(rect), 1)
277
-
278
- [draw_rect(data) for data in entity.get_debug_outlines()]
279
-
280
- def sort_entities(self) -> None:
281
- self.should_sort = True
282
-
283
- def _sort_entities_internal(self):
284
- """Sort entities within the scene based on their rendering order."""
285
- self.world_entities = OrderedDict(
286
- sorted(self.world_entities.items(), key=lambda e: e[0].render_order)
287
- )
288
- self.hud_entities = OrderedDict(
289
- sorted(self.hud_entities.items(), key=lambda e: e[0].render_order)
290
- )
291
- self.should_sort = False
292
-
293
- def draw(self, surface: pygame.Surface):
294
- self.camera.clear()
295
- self.hud_camera.clear()
296
-
297
- # Draw all world entities
298
- self._draw_camera(self.camera, self.world_entities.keys())
299
- # Draw all HUD entities
300
- self._draw_camera(self.hud_camera, self.hud_entities.keys())
301
-
302
- self.do_early_draw(surface)
303
- self.camera.draw(surface)
304
- self.do_post_world_draw(surface)
305
- self.hud_camera.draw(surface)
306
- self.do_final_draw(surface)
307
-
308
- def _draw_camera(self, camera: bf.Camera, entity_list):
309
- _ = [entity.draw(camera) for entity in entity_list]
310
- debugMode = bf.ResourceManager().get_sharedVar("debug_mode")
311
- # Draw outlines for world entities if required
312
- if debugMode == bf.debugMode.OUTLINES:
313
- [self.debug_entity(e, camera) for e in entity_list]
314
-
315
- def do_early_draw(self, surface: pygame.Surface):
316
- pass
317
-
318
- def do_post_world_draw(self, surface: pygame.Surface):
319
- pass
320
-
321
- def do_final_draw(self, surface: pygame.Surface):
322
- pass
323
-
324
24
  def on_enter(self):
325
- self.set_active(True)
326
- self.set_visible(True)
327
25
  self.root.clear_hovered()
328
26
  self.root.build()
329
- bf.TimeManager().activate_register(self.name)
330
- self.do_on_enter()
27
+ super().on_enter()
331
28
 
332
29
  def on_exit(self):
333
30
  self.root.clear_hovered()
334
- self.set_active(False)
335
- self.set_visible(False)
336
- self.actions.hard_reset()
337
- self.early_actions.hard_reset()
338
- bf.TimeManager().deactivate_register(self.name)
339
- self.do_on_exit()
340
-
341
- def do_on_enter(self) -> None:
342
- pass
343
-
344
- def do_on_exit(self) -> None:
345
- pass
346
-
347
- def do_on_enter_early(self) -> None:
348
- pass
349
-
350
- def do_on_exit_early(self) -> None:
351
- pass
31
+ super().on_exit()