batframework 1.1.0__py3-none-any.whl → 2.0.0__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 (81) hide show
  1. batFramework/__init__.py +84 -51
  2. batFramework/action.py +280 -252
  3. batFramework/actionContainer.py +105 -38
  4. batFramework/animatedSprite.py +81 -117
  5. batFramework/animation.py +91 -0
  6. batFramework/audioManager.py +156 -85
  7. batFramework/baseScene.py +249 -0
  8. batFramework/camera.py +245 -123
  9. batFramework/constants.py +57 -75
  10. batFramework/cutscene.py +239 -119
  11. batFramework/cutsceneManager.py +34 -0
  12. batFramework/drawable.py +107 -0
  13. batFramework/dynamicEntity.py +30 -23
  14. batFramework/easingController.py +58 -0
  15. batFramework/entity.py +130 -123
  16. batFramework/enums.py +171 -0
  17. batFramework/fontManager.py +65 -0
  18. batFramework/gui/__init__.py +28 -14
  19. batFramework/gui/animatedLabel.py +90 -0
  20. batFramework/gui/button.py +18 -84
  21. batFramework/gui/clickableWidget.py +244 -0
  22. batFramework/gui/collapseContainer.py +98 -0
  23. batFramework/gui/constraints/__init__.py +1 -0
  24. batFramework/gui/constraints/constraints.py +1066 -0
  25. batFramework/gui/container.py +220 -49
  26. batFramework/gui/debugger.py +140 -47
  27. batFramework/gui/draggableWidget.py +63 -0
  28. batFramework/gui/image.py +61 -23
  29. batFramework/gui/indicator.py +116 -40
  30. batFramework/gui/interactiveWidget.py +243 -22
  31. batFramework/gui/label.py +147 -110
  32. batFramework/gui/layout.py +442 -81
  33. batFramework/gui/meter.py +155 -0
  34. batFramework/gui/radioButton.py +43 -0
  35. batFramework/gui/root.py +228 -60
  36. batFramework/gui/scrollingContainer.py +282 -0
  37. batFramework/gui/selector.py +232 -0
  38. batFramework/gui/shape.py +286 -86
  39. batFramework/gui/slider.py +353 -0
  40. batFramework/gui/style.py +10 -0
  41. batFramework/gui/styleManager.py +49 -0
  42. batFramework/gui/syncedVar.py +43 -0
  43. batFramework/gui/textInput.py +331 -0
  44. batFramework/gui/textWidget.py +308 -0
  45. batFramework/gui/toggle.py +140 -62
  46. batFramework/gui/tooltip.py +35 -0
  47. batFramework/gui/widget.py +546 -307
  48. batFramework/manager.py +131 -50
  49. batFramework/particle.py +118 -0
  50. batFramework/propertyEaser.py +79 -0
  51. batFramework/renderGroup.py +34 -0
  52. batFramework/resourceManager.py +130 -0
  53. batFramework/scene.py +31 -226
  54. batFramework/sceneLayer.py +134 -0
  55. batFramework/sceneManager.py +200 -165
  56. batFramework/scrollingSprite.py +115 -0
  57. batFramework/sprite.py +46 -0
  58. batFramework/stateMachine.py +49 -51
  59. batFramework/templates/__init__.py +2 -0
  60. batFramework/templates/character.py +15 -0
  61. batFramework/templates/controller.py +158 -0
  62. batFramework/templates/stateMachine.py +39 -0
  63. batFramework/tileset.py +46 -0
  64. batFramework/timeManager.py +213 -0
  65. batFramework/transition.py +162 -157
  66. batFramework/triggerZone.py +22 -22
  67. batFramework/utils.py +306 -184
  68. {batframework-1.1.0.dist-info → batframework-2.0.0.dist-info}/LICENSE +1 -1
  69. {batframework-1.1.0.dist-info → batframework-2.0.0.dist-info}/METADATA +8 -4
  70. batframework-2.0.0.dist-info/RECORD +72 -0
  71. batFramework/cutsceneBlocks.py +0 -176
  72. batFramework/debugger.py +0 -48
  73. batFramework/easing.py +0 -71
  74. batFramework/gui/constraints.py +0 -204
  75. batFramework/gui/frame.py +0 -19
  76. batFramework/particles.py +0 -77
  77. batFramework/time.py +0 -75
  78. batFramework/transitionManager.py +0 -0
  79. batframework-1.1.0.dist-info/RECORD +0 -43
  80. {batframework-1.1.0.dist-info → batframework-2.0.0.dist-info}/WHEEL +0 -0
  81. {batframework-1.1.0.dist-info → batframework-2.0.0.dist-info}/top_level.txt +0 -0
batFramework/scene.py CHANGED
@@ -1,226 +1,31 @@
1
- from __future__ import annotations
2
- import re
3
- from typing import TYPE_CHECKING,Any
4
- if TYPE_CHECKING:
5
- from .manager import Manager
6
- import pygame
7
- import batFramework as bf
8
-
9
-
10
- class Scene:
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] = []
17
- self.manager: Manager | None = None
18
- self.actions: bf.ActionContainer = bf.ActionContainer()
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()
25
-
26
- self.camera.set_clear_color((0, 0, 0))
27
- self.hud_camera.set_clear_color((0, 0, 0, 0))
28
-
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
33
-
34
- def set_scene_index(self,index):
35
- self.scene_index = index
36
-
37
- def get_scene_index(self):
38
- return self.scene_index
39
-
40
- def set_sharedVar(self, name, value)->bool:
41
- if not self.manager : return False
42
- return self.manager.set_sharedVar(name, value)
43
-
44
- def get_sharedVar(self, name)->Any:
45
- if not self.manager : return False
46
- return self.manager.get_sharedVar(name)
47
-
48
- def do_when_added(self):
49
- pass
50
-
51
- def set_clear_color(self, color: pygame.Color|tuple):
52
- self.camera.set_clear_color(color)
53
- # self.hud_camera.set_clear_color(color)
54
-
55
- def set_manager(self, manager_link: Manager):
56
- self.manager = manager_link
57
-
58
- def set_visible(self, value: bool):
59
- self._visible = value
60
- if self.manager : self.manager.update_scene_states()
61
-
62
- def set_active(self, value):
63
- self._active = value
64
- if self.manager : self.manager.update_scene_states()
65
-
66
- def is_active(self) -> bool:
67
- return self._active
68
-
69
- def is_visible(self) -> bool:
70
- return self._visible
71
-
72
- def get_name(self) -> str:
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)
108
-
109
- def get_by_tags(self, *tags):
110
- return [
111
- entity
112
- for entity in self._world_entities + self._hud_entities
113
- if any(entity.has_tag(t) for t in tags)
114
- ]
115
-
116
- def get_by_uid(self, uid) -> bf.Entity | None:
117
- return next(
118
- (
119
- entity
120
- for entity in self._world_entities + self._hud_entities
121
- if entity.uid == uid
122
- ),
123
- None,
124
- )
125
-
126
- # called before process event
127
- def do_early_process_event(self, event: pygame.Event) -> bool:
128
- """return True if stop event propagation in child entities and scene's action container"""
129
- return False
130
-
131
- # propagates event to all entities
132
- def process_event(self, event: pygame.Event):
133
- """
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.
136
- """
137
- if self.get_sharedVar("in_transition"):
138
- return
139
- if self.do_early_process_event(event):
140
- return
141
- self.actions.process_event(event)
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()
147
-
148
- def do_handle_event(self, event: pygame.Event):
149
- """called inside process_event but before resetting the scene's action container and propagating event to child entities of the scene"""
150
- pass
151
-
152
- def update(self, dt):
153
- for entity in self._world_entities + self._hud_entities:
154
- entity.update(dt)
155
- self.do_update(dt)
156
- self.camera.update(dt)
157
- self.hud_camera.update(dt)
158
-
159
- def do_update(self, dt):
160
- pass
161
-
162
- def debug_entity(self, entity: bf.Entity, camera: bf.Camera):
163
- # return
164
- if not entity.visible:
165
- return
166
- for data in entity.get_bounding_box():
167
- if isinstance(data,pygame.FRect):
168
- rect = data
169
- color = entity._debug_color
170
- else:
171
- rect = data[0]
172
- color = data[1]
173
- if not isinstance(color,pygame.Color): color = pygame.Color(color)
174
-
175
- pygame.draw.rect(camera.surface, color , camera.transpose(rect), 1)
176
-
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
182
- self.camera.clear()
183
- self.hud_camera.clear()
184
-
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
-
201
-
202
- self.do_early_draw(surface)
203
- self.camera.draw(surface)
204
- self.do_post_world_draw(surface)
205
- self.hud_camera.draw(surface)
206
- self.do_final_draw(surface)
207
-
208
- self.blit_calls = total_blit_calls
209
-
210
- def do_early_draw(self, surface: pygame.Surface):
211
- pass
212
-
213
- def do_post_world_draw(self, surface: pygame.Surface):
214
- pass
215
-
216
- def do_final_draw(self, surface: pygame.Surface):
217
- pass
218
-
219
- def on_enter(self):
220
- self.set_active(True)
221
- self.set_visible(True)
222
-
223
- def on_exit(self):
224
- self.set_active(False)
225
- self.set_visible(False)
226
- self.actions.hard_reset()
1
+ from .baseScene import BaseScene
2
+ import batFramework as bf
3
+
4
+
5
+ class Scene(BaseScene):
6
+ def __init__(self,name: str) -> None:
7
+ """
8
+ Default Scene object.
9
+ Has 2 layers (world and hud) by default
10
+ Contains an exposed root gui object on the hud layer
11
+ Args:
12
+ name: Name of the scene.
13
+ """
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)
21
+ self.entities_to_remove = []
22
+ self.entities_to_add = []
23
+
24
+ def on_enter(self):
25
+ self.root.clear_hovered()
26
+ self.root.build()
27
+ super().on_enter()
28
+
29
+ def on_exit(self):
30
+ self.root.clear_hovered()
31
+ super().on_exit()
@@ -0,0 +1,134 @@
1
+ from __future__ import annotations
2
+ import math
3
+ import batFramework as bf
4
+ import pygame
5
+ from .entity import Entity
6
+ from .drawable import Drawable
7
+
8
+ from typing import TYPE_CHECKING, Any
9
+ if TYPE_CHECKING:
10
+ from .baseScene import BaseScene
11
+
12
+ class SceneLayer:
13
+ """
14
+ A scene layer is a 'dimension' bound to a scene
15
+ Each layer contains its own entities and camera
16
+ Allows sorting out different types of content in a single scene
17
+ One common use would be to separate GUI and game into two separate layers
18
+ Entities are drawn only if they inherit the Drawable class and are not in a RenderGroup
19
+ """
20
+ def __init__(self,name:str,convert_alpha:bool = False):
21
+ self.scene = None
22
+ self.name = name
23
+ self.entities : dict[int,Entity] = {} # contains all scene entities : key is uid
24
+ self.entities_to_add : set[Entity]= set() # entities to add to the scene, (1 frame delay after calling add)
25
+ self.entities_to_remove : set[Entity]= set() # entities to remove from the scene
26
+ self.draw_order : list[int] = [] # stores the uid of entities to draw (in draw order)
27
+ self.camera = bf.Camera(convert_alpha=convert_alpha)
28
+
29
+ def set_clear_color(self,color):
30
+ self.camera.set_clear_color(color)
31
+
32
+ def set_scene(self, scene:BaseScene):
33
+ self.scene = scene
34
+
35
+ def add(self,*entities:Entity):
36
+ for e in entities:
37
+ if e.uid not in self.entities and e not in self.entities_to_add:
38
+ self.entities_to_add.add(e)
39
+
40
+
41
+ def get_by_tags(self,*tags)->list[Entity]:
42
+ return [v for v in self.entities.values() if v.has_tags(*tags) ]
43
+
44
+ def get_by_uid(self,uid:int)->Entity|None:
45
+ return self.entities.get(uid,None)
46
+
47
+ def remove(self,*entities:Entity):
48
+ for e in entities:
49
+ if e.uid in self.entities and e not in self.entities_to_remove:
50
+ self.entities_to_remove.add(e)
51
+
52
+ def process_event(self,event:pygame.Event):
53
+ if self.camera.fullscreen and event.type == pygame.VIDEORESIZE and not pygame.SCALED & bf.const.FLAGS:
54
+ self.camera.set_size(bf.const.RESOLUTION)
55
+
56
+ for e in self.entities.values():
57
+ e.process_event(event)
58
+ if event.consumed : return
59
+
60
+ def update(self, dt):
61
+ # Update all entities
62
+ for e in self.entities.values():
63
+ e.update(dt)
64
+
65
+ self.flush_entity_changes()
66
+
67
+ # Update the camera
68
+ self.camera.update(dt)
69
+
70
+ def flush_entity_changes(self):
71
+ """
72
+ Synchronizes entity changes by removing entities marked for removal,
73
+ adding new entities, and updating the draw order if necessary.
74
+ """
75
+ # Remove entities marked for removal
76
+ for e in self.entities_to_remove:
77
+ if e.uid in self.entities.keys():
78
+ e.set_parent_scene(None)
79
+ self.entities.pop(e.uid)
80
+ self.entities_to_remove.clear()
81
+
82
+ # Add new entities
83
+ reorder = False
84
+ for e in self.entities_to_add:
85
+ self.entities[e.uid] = e
86
+ e.set_parent_layer(self)
87
+ e.set_parent_scene(self.scene)
88
+ if not reorder and isinstance(e, Drawable):
89
+ reorder = True
90
+ self.entities_to_add.clear()
91
+
92
+ # Reorder draw order if necessary
93
+ if reorder:
94
+ self.update_draw_order()
95
+
96
+
97
+ def draw(self, surface: pygame.Surface):
98
+ self.camera.clear()
99
+ debugMode = bf.ResourceManager().get_sharedVar("debug_mode")
100
+ # Draw entities in the correct order
101
+ for uid in self.draw_order:
102
+ if uid in self.entities and not self.entities[uid].drawn_by_group: # Ensure the entity still exists
103
+ self.entities[uid].draw(self.camera)
104
+
105
+ # Draw debug outlines if in debug mode
106
+ if debugMode == bf.debugMode.OUTLINES:
107
+ [self.debug_entity(uid) for uid in self.draw_order if uid in self.entities]
108
+
109
+ # surface.fill("white")
110
+ self.camera.draw(surface)
111
+
112
+ def update_draw_order(self):
113
+ self.draw_order = sorted(
114
+ (k for k,v in self.entities.items() if isinstance(v,Drawable) and not v.drawn_by_group),
115
+ key= lambda uid : self.entities[uid].render_order
116
+ )
117
+
118
+ def debug_entity(self, uid: int):
119
+ entity = self.entities[uid]
120
+ def draw_rect(data):
121
+ if data is None:
122
+ return
123
+ if isinstance(data, pygame.FRect) or isinstance(data, pygame.Rect):
124
+ rect = data
125
+ color = entity.debug_color
126
+ else:
127
+ rect = data[0]
128
+ color = data[1]
129
+ if self.camera.intersects(rect):
130
+ line_width = 1 if self.camera.zoom_factor >= 1 else int(-math.log2(self.camera.zoom_factor)) + 2
131
+ pygame.draw.rect(self.camera.surface, color, self.camera.world_to_screen(rect), line_width )
132
+
133
+ for data in entity.get_debug_outlines():
134
+ draw_rect(data)