batframework 1.0.9a7__py3-none-any.whl → 1.0.9a8__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.
- batFramework/__init__.py +20 -11
- batFramework/action.py +1 -1
- batFramework/animatedSprite.py +47 -116
- batFramework/animation.py +30 -5
- batFramework/audioManager.py +8 -5
- batFramework/baseScene.py +240 -0
- batFramework/camera.py +4 -0
- batFramework/constants.py +6 -1
- batFramework/cutscene.py +221 -21
- batFramework/cutsceneManager.py +5 -2
- batFramework/drawable.py +7 -5
- batFramework/easingController.py +10 -11
- batFramework/entity.py +21 -2
- batFramework/enums.py +48 -33
- batFramework/gui/__init__.py +3 -1
- batFramework/gui/animatedLabel.py +10 -2
- batFramework/gui/button.py +4 -31
- batFramework/gui/clickableWidget.py +42 -30
- batFramework/gui/constraints/constraints.py +212 -136
- batFramework/gui/container.py +72 -48
- batFramework/gui/debugger.py +12 -17
- batFramework/gui/draggableWidget.py +8 -11
- batFramework/gui/image.py +3 -10
- batFramework/gui/indicator.py +73 -1
- batFramework/gui/interactiveWidget.py +117 -100
- batFramework/gui/label.py +73 -63
- batFramework/gui/layout.py +221 -452
- batFramework/gui/meter.py +21 -7
- batFramework/gui/radioButton.py +0 -1
- batFramework/gui/root.py +99 -29
- batFramework/gui/selector.py +257 -0
- batFramework/gui/shape.py +13 -5
- batFramework/gui/slider.py +260 -93
- batFramework/gui/textInput.py +45 -21
- batFramework/gui/toggle.py +70 -52
- batFramework/gui/tooltip.py +30 -0
- batFramework/gui/widget.py +203 -125
- batFramework/manager.py +7 -8
- batFramework/particle.py +4 -1
- batFramework/propertyEaser.py +79 -0
- batFramework/renderGroup.py +17 -50
- batFramework/resourceManager.py +43 -13
- batFramework/scene.py +15 -335
- batFramework/sceneLayer.py +138 -0
- batFramework/sceneManager.py +31 -36
- batFramework/scrollingSprite.py +8 -3
- batFramework/sprite.py +1 -1
- batFramework/templates/__init__.py +1 -2
- batFramework/templates/controller.py +97 -0
- batFramework/timeManager.py +76 -22
- batFramework/transition.py +37 -103
- batFramework/utils.py +121 -3
- {batframework-1.0.9a7.dist-info → batframework-1.0.9a8.dist-info}/METADATA +24 -3
- batframework-1.0.9a8.dist-info/RECORD +66 -0
- {batframework-1.0.9a7.dist-info → batframework-1.0.9a8.dist-info}/WHEEL +1 -1
- batFramework/character.py +0 -27
- batFramework/templates/character.py +0 -43
- batFramework/templates/states.py +0 -166
- batframework-1.0.9a7.dist-info/RECORD +0 -63
- /batframework-1.0.9a7.dist-info/LICENCE → /batframework-1.0.9a8.dist-info/LICENSE +0 -0
- {batframework-1.0.9a7.dist-info → batframework-1.0.9a8.dist-info}/top_level.txt +0 -0
batFramework/scene.py
CHANGED
@@ -1,351 +1,31 @@
|
|
1
|
-
from
|
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
|
-
|
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
|
-
|
29
|
-
self.
|
30
|
-
bf.
|
31
|
-
self.
|
32
|
-
self.
|
33
|
-
self.
|
34
|
-
self.
|
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
|
-
|
330
|
-
self.do_on_enter()
|
27
|
+
super().on_enter()
|
331
28
|
|
332
29
|
def on_exit(self):
|
333
30
|
self.root.clear_hovered()
|
334
|
-
|
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()
|
@@ -0,0 +1,138 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
import batFramework as bf
|
3
|
+
import pygame
|
4
|
+
from .entity import Entity
|
5
|
+
from .drawable import Drawable
|
6
|
+
|
7
|
+
from typing import TYPE_CHECKING, Any
|
8
|
+
if TYPE_CHECKING:
|
9
|
+
from .baseScene import BaseScene
|
10
|
+
|
11
|
+
class SceneLayer:
|
12
|
+
"""
|
13
|
+
A scene layer is a 'dimension' bound to a scene
|
14
|
+
Each layer contains its own entities and camera
|
15
|
+
One common use would be to separate GUI and game into two separate layers
|
16
|
+
"""
|
17
|
+
def __init__(self,name:str,convert_alpha:bool = False):
|
18
|
+
self.scene = None
|
19
|
+
self.name = name
|
20
|
+
self.entities : dict[int,Entity] = {}
|
21
|
+
self.entities_to_add : set[Entity]= set()
|
22
|
+
self.entities_to_remove : set[Entity]= set()
|
23
|
+
self.draw_order : list[int] = []
|
24
|
+
self.camera = bf.Camera(convert_alpha=convert_alpha)
|
25
|
+
|
26
|
+
def set_clear_color(self,color):
|
27
|
+
self.camera.set_clear_color(color)
|
28
|
+
|
29
|
+
def set_scene(self, scene:BaseScene):
|
30
|
+
self.scene = scene
|
31
|
+
|
32
|
+
def add(self,*entities:Entity):
|
33
|
+
for e in entities:
|
34
|
+
if e.uid not in self.entities and e not in self.entities_to_add:
|
35
|
+
self.entities_to_add.add(e)
|
36
|
+
|
37
|
+
|
38
|
+
def get_by_tags(self,*tags)->list[Entity]:
|
39
|
+
return [v for v in self.entities.values() if v.has_tags(*tags) ]
|
40
|
+
|
41
|
+
def get_by_uid(self,uid:int)->Entity|None:
|
42
|
+
return self.entities.get(uid,None)
|
43
|
+
|
44
|
+
def remove(self,*entities:Entity):
|
45
|
+
for e in entities:
|
46
|
+
if e.uid in self.entities and e not in self.entities_to_remove:
|
47
|
+
self.entities_to_remove.add(e)
|
48
|
+
|
49
|
+
def process_event(self,event:pygame.Event):
|
50
|
+
if event.type == pygame.VIDEORESIZE:
|
51
|
+
self.camera.set_size(bf.const.RESOLUTION)
|
52
|
+
|
53
|
+
for e in self.entities.values():
|
54
|
+
e.process_event(event)
|
55
|
+
if event.consumed : return
|
56
|
+
|
57
|
+
def update(self, dt):
|
58
|
+
# Update all entities
|
59
|
+
for e in self.entities.values():
|
60
|
+
e.update(dt)
|
61
|
+
|
62
|
+
self.flush_entity_changes()
|
63
|
+
|
64
|
+
# Update the camera
|
65
|
+
self.camera.update(dt)
|
66
|
+
|
67
|
+
def flush_entity_changes(self):
|
68
|
+
"""
|
69
|
+
Synchronizes entity changes by removing entities marked for removal,
|
70
|
+
adding new entities, and updating the draw order if necessary.
|
71
|
+
"""
|
72
|
+
|
73
|
+
|
74
|
+
# Remove entities marked for removal
|
75
|
+
for e in self.entities_to_remove:
|
76
|
+
if e.uid in self.entities.keys():
|
77
|
+
e.set_parent_scene(None)
|
78
|
+
self.entities.pop(e.uid)
|
79
|
+
self.entities_to_remove.clear()
|
80
|
+
|
81
|
+
# Add new entities
|
82
|
+
reorder = False
|
83
|
+
for e in self.entities_to_add:
|
84
|
+
self.entities[e.uid] = e
|
85
|
+
e.set_parent_layer(self)
|
86
|
+
e.set_parent_scene(self.scene)
|
87
|
+
if not reorder and isinstance(e, Drawable):
|
88
|
+
reorder = True
|
89
|
+
self.entities_to_add.clear()
|
90
|
+
|
91
|
+
# Reorder draw order if necessary
|
92
|
+
if reorder:
|
93
|
+
self.update_draw_order()
|
94
|
+
|
95
|
+
def clear(self):
|
96
|
+
"""
|
97
|
+
Clear the camera surface
|
98
|
+
"""
|
99
|
+
self.camera.clear()
|
100
|
+
|
101
|
+
def draw(self, surface: pygame.Surface):
|
102
|
+
self.camera.clear()
|
103
|
+
debugMode = bf.ResourceManager().get_sharedVar("debug_mode")
|
104
|
+
# Draw entities in the correct order
|
105
|
+
for uid in self.draw_order:
|
106
|
+
if uid in self.entities and not self.entities[uid].drawn_by_group: # Ensure the entity still exists
|
107
|
+
self.entities[uid].draw(self.camera)
|
108
|
+
|
109
|
+
# Draw debug outlines if in debug mode
|
110
|
+
if debugMode == bf.debugMode.OUTLINES:
|
111
|
+
[self.debug_entity(uid) for uid in self.draw_order if uid in self.entities]
|
112
|
+
|
113
|
+
# Blit the camera surface onto the provided surface
|
114
|
+
# surface.blit(self.camera.surface, (0, 0))
|
115
|
+
self.camera.draw(surface)
|
116
|
+
|
117
|
+
def update_draw_order(self):
|
118
|
+
self.draw_order = sorted(
|
119
|
+
(k for k,v in self.entities.items() if isinstance(v,Drawable) and not v.drawn_by_group),
|
120
|
+
key= lambda uid : self.entities[uid].render_order
|
121
|
+
)
|
122
|
+
|
123
|
+
def debug_entity(self, uid: int):
|
124
|
+
entity = self.entities[uid]
|
125
|
+
def draw_rect(data):
|
126
|
+
if data is None:
|
127
|
+
return
|
128
|
+
if isinstance(data, pygame.FRect) or isinstance(data, pygame.Rect):
|
129
|
+
rect = data
|
130
|
+
color = entity.debug_color
|
131
|
+
else:
|
132
|
+
rect = data[0]
|
133
|
+
color = data[1]
|
134
|
+
if self.camera.intersects(rect):
|
135
|
+
pygame.draw.rect(self.camera.surface, color, self.camera.world_to_screen(rect), 1)
|
136
|
+
|
137
|
+
for data in entity.get_debug_outlines():
|
138
|
+
draw_rect(data)
|
batFramework/sceneManager.py
CHANGED
@@ -8,9 +8,9 @@ def swap(lst, index1, index2):
|
|
8
8
|
|
9
9
|
class SceneManager:
|
10
10
|
def __init__(self) -> None:
|
11
|
-
self.scenes: list[bf.
|
11
|
+
self.scenes: list[bf.BaseScene] = []
|
12
12
|
self.shared_events = {pygame.WINDOWRESIZED}
|
13
|
-
self.
|
13
|
+
self.current_transition : tuple[str,bf.transition.Transition,int] | None= None
|
14
14
|
|
15
15
|
def init_scenes(self, *initial_scenes:bf.Scene):
|
16
16
|
for index, s in enumerate(initial_scenes):
|
@@ -56,7 +56,7 @@ class SceneManager:
|
|
56
56
|
print("\n" + "=" * 50)
|
57
57
|
print(" DEBUGGING STATUS".center(50))
|
58
58
|
print("=" * 50)
|
59
|
-
print(f"[Debugging Mode] = {
|
59
|
+
print(f"[Debugging Mode] = {bf.ResourceManager().get_sharedVar("debug_mode")}")
|
60
60
|
|
61
61
|
# Print shared variables
|
62
62
|
print("\n" + "=" * 50)
|
@@ -86,7 +86,7 @@ class SceneManager:
|
|
86
86
|
if scene in self.scenes and not self.has_scene(scene.name):
|
87
87
|
return
|
88
88
|
scene.set_manager(self)
|
89
|
-
scene.
|
89
|
+
scene.when_added()
|
90
90
|
self.scenes.insert(0, scene)
|
91
91
|
|
92
92
|
def remove_scene(self, name: str):
|
@@ -110,36 +110,34 @@ class SceneManager:
|
|
110
110
|
def transition_to_scene(
|
111
111
|
self,
|
112
112
|
scene_name: str,
|
113
|
-
transition: bf.transition.Transition =
|
113
|
+
transition: bf.transition.Transition = None,
|
114
114
|
index: int = 0,
|
115
115
|
):
|
116
|
-
|
117
|
-
|
116
|
+
if transition is None:
|
117
|
+
transition = bf.transition.Fade(0.1)
|
118
|
+
if not (target_scene := self.get_scene(scene_name)):
|
118
119
|
print(f"Scene '{scene_name}' does not exist")
|
119
120
|
return
|
120
|
-
if
|
121
|
-
|
121
|
+
if not (source_scene := self.get_scene_at(index)):
|
122
|
+
print(f"No scene exists at index {index}.")
|
123
|
+
return
|
124
|
+
|
122
125
|
source_surface = bf.const.SCREEN.copy()
|
123
126
|
dest_surface = bf.const.SCREEN.copy()
|
124
127
|
|
125
|
-
|
126
|
-
target_scene.
|
127
|
-
target_scene.
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
128
|
+
target_scene.draw(dest_surface) # draw at least once to ensure smooth transition
|
129
|
+
target_scene.set_active(True)
|
130
|
+
target_scene.set_visible(True)
|
131
|
+
|
132
|
+
target_scene.do_on_enter_early()
|
133
|
+
source_scene.do_on_exit_early()
|
134
|
+
|
135
|
+
self.current_transition :tuple[str,bf.transition.Transition]=(scene_name,transition,index)
|
132
136
|
transition.set_source(source_surface)
|
133
137
|
transition.set_dest(dest_surface)
|
134
138
|
transition.start()
|
135
139
|
|
136
|
-
def _start_transition(self, target_scene: bf.Scene):
|
137
|
-
target_scene.set_active(True)
|
138
|
-
target_scene.set_visible(True)
|
139
140
|
|
140
|
-
def _end_transition(self, scene_name, index):
|
141
|
-
self.set_scene(scene_name, index, True)
|
142
|
-
self.current_transitions.clear()
|
143
141
|
|
144
142
|
def set_scene(self, scene_name, index=0, ignore_early: bool = False):
|
145
143
|
target_scene = self.get_scene(scene_name)
|
@@ -171,9 +169,6 @@ class SceneManager:
|
|
171
169
|
|
172
170
|
def process_event(self, event: pygame.Event):
|
173
171
|
|
174
|
-
if self.current_transitions and event in bf.enums.playerInput:
|
175
|
-
return
|
176
|
-
|
177
172
|
if event.type in self.shared_events:
|
178
173
|
[s.process_event(event) for s in self.scenes]
|
179
174
|
else:
|
@@ -182,21 +177,21 @@ class SceneManager:
|
|
182
177
|
def update(self, dt: float) -> None:
|
183
178
|
for scene in self.active_scenes:
|
184
179
|
scene.update(dt)
|
180
|
+
if self.current_transition and self.current_transition[1].is_over:
|
181
|
+
self.set_scene(self.current_transition[0],self.current_transition[2],True)
|
182
|
+
self.current_transition = None
|
185
183
|
self.do_update(dt)
|
186
184
|
|
187
185
|
def do_update(self, dt: float):
|
188
186
|
pass
|
189
187
|
|
190
|
-
def draw(self, surface) -> None:
|
188
|
+
def draw(self, surface:pygame.Surface) -> None:
|
191
189
|
for scene in self.visible_scenes:
|
192
190
|
scene.draw(surface)
|
193
|
-
if self.
|
194
|
-
self.
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
self.current_transitions["transition"].set_dest(tmp)
|
201
|
-
self.current_transitions["transition"].draw(surface)
|
202
|
-
return
|
191
|
+
if self.current_transition is not None:
|
192
|
+
self.current_transition[1].set_source(surface)
|
193
|
+
tmp = surface.copy()
|
194
|
+
self.get_scene(self.current_transition[0]).draw(tmp)
|
195
|
+
self.current_transition[1].set_dest(tmp)
|
196
|
+
self.current_transition[1].draw(surface)
|
197
|
+
|
batFramework/scrollingSprite.py
CHANGED
@@ -66,7 +66,7 @@ class ScrollingSprite(bf.Sprite):
|
|
66
66
|
self.rect = self.surface.get_frect(topleft=self.rect.topleft)
|
67
67
|
return self
|
68
68
|
|
69
|
-
def _get_mosaic_rect_list(self) -> Iterator[pygame.Rect]:
|
69
|
+
def _get_mosaic_rect_list(self,camera:bf.Camera=None) -> Iterator[pygame.Rect]:
|
70
70
|
# Use integer values for the starting points, converted from floating point scroll values
|
71
71
|
start_x = int(self.scroll_value.x % self.original_width)
|
72
72
|
start_y = int(self.scroll_value.y % self.original_height)
|
@@ -90,7 +90,12 @@ class ScrollingSprite(bf.Sprite):
|
|
90
90
|
while x < end_x:
|
91
91
|
y = y_position
|
92
92
|
while y < end_y:
|
93
|
-
|
93
|
+
r = pygame.Rect(x, y, self.original_width, self.original_height)
|
94
|
+
|
95
|
+
if camera and camera.rect.colliderect((x+camera.rect.x,y+camera.rect.y,self.original_width,self.original_height)):
|
96
|
+
yield r
|
97
|
+
else:
|
98
|
+
yield r
|
94
99
|
y += self.original_height
|
95
100
|
x += self.original_width
|
96
101
|
return self
|
@@ -104,7 +109,7 @@ class ScrollingSprite(bf.Sprite):
|
|
104
109
|
return
|
105
110
|
# self.surface.fill((0, 0, 0, 0))
|
106
111
|
camera.surface.fblits(
|
107
|
-
[(self.original_surface, r.move(self.rect.x-camera.rect.x,self.rect.y-camera.rect.y)) for r in self._get_mosaic_rect_list()]
|
112
|
+
[(self.original_surface, r.move(self.rect.x-camera.rect.x,self.rect.y-camera.rect.y)) for r in self._get_mosaic_rect_list(camera)]
|
108
113
|
)
|
109
114
|
# camera.surface.blit(self.surface, camera.world_to_screen(self.rect))
|
110
115
|
return
|
batFramework/sprite.py
CHANGED
@@ -1,2 +1 @@
|
|
1
|
-
from .
|
2
|
-
from .states import *
|
1
|
+
from .controller import *
|