batframework 1.0.8a1__py3-none-any.whl → 1.0.8a2__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 (63) hide show
  1. batFramework/__init__.py +50 -53
  2. batFramework/action.py +105 -116
  3. batFramework/actionContainer.py +11 -53
  4. batFramework/animatedSprite.py +65 -115
  5. batFramework/audioManager.py +26 -70
  6. batFramework/camera.py +68 -253
  7. batFramework/constants.py +54 -16
  8. batFramework/cutscene.py +25 -34
  9. batFramework/cutsceneBlocks.py +42 -37
  10. batFramework/debugger.py +48 -0
  11. batFramework/dynamicEntity.py +7 -9
  12. batFramework/easing.py +71 -0
  13. batFramework/entity.py +98 -42
  14. batFramework/gui/__init__.py +2 -8
  15. batFramework/gui/button.py +79 -7
  16. batFramework/gui/constraints.py +204 -0
  17. batFramework/gui/container.py +31 -155
  18. batFramework/gui/debugger.py +43 -124
  19. batFramework/gui/frame.py +19 -0
  20. batFramework/gui/image.py +17 -41
  21. batFramework/gui/indicator.py +21 -41
  22. batFramework/gui/interactiveWidget.py +13 -116
  23. batFramework/gui/label.py +73 -278
  24. batFramework/gui/layout.py +61 -148
  25. batFramework/gui/root.py +37 -102
  26. batFramework/gui/shape.py +57 -258
  27. batFramework/gui/toggle.py +46 -97
  28. batFramework/gui/widget.py +254 -268
  29. batFramework/manager.py +19 -40
  30. batFramework/particles.py +77 -0
  31. batFramework/scene.py +107 -214
  32. batFramework/sceneManager.py +107 -150
  33. batFramework/stateMachine.py +0 -1
  34. batFramework/time.py +57 -117
  35. batFramework/transition.py +126 -184
  36. batFramework/transitionManager.py +0 -0
  37. batFramework/utils.py +161 -34
  38. batframework-1.0.8a2.dist-info/METADATA +58 -0
  39. batframework-1.0.8a2.dist-info/RECORD +42 -0
  40. {batframework-1.0.8a1.dist-info → batframework-1.0.8a2.dist-info}/WHEEL +1 -1
  41. batFramework/easingController.py +0 -58
  42. batFramework/enums.py +0 -104
  43. batFramework/fontManager.py +0 -65
  44. batFramework/gui/clickableWidget.py +0 -206
  45. batFramework/gui/constraints/__init__.py +0 -1
  46. batFramework/gui/constraints/constraints.py +0 -378
  47. batFramework/gui/dialogueBox.py +0 -96
  48. batFramework/gui/draggableWidget.py +0 -38
  49. batFramework/gui/meter.py +0 -76
  50. batFramework/gui/radioButton.py +0 -62
  51. batFramework/gui/slider.py +0 -220
  52. batFramework/gui/textInput.py +0 -134
  53. batFramework/object.py +0 -115
  54. batFramework/particle.py +0 -101
  55. batFramework/renderGroup.py +0 -62
  56. batFramework/resourceManager.py +0 -84
  57. batFramework/scrollingSprite.py +0 -113
  58. batFramework/sprite.py +0 -45
  59. batFramework/tileset.py +0 -46
  60. batframework-1.0.8a1.dist-info/LICENCE +0 -21
  61. batframework-1.0.8a1.dist-info/METADATA +0 -55
  62. batframework-1.0.8a1.dist-info/RECORD +0 -56
  63. {batframework-1.0.8a1.dist-info → batframework-1.0.8a2.dist-info}/top_level.txt +0 -0
batFramework/__init__.py CHANGED
@@ -1,69 +1,66 @@
1
1
  import pygame
2
- import batFramework as bf
3
- import sys
4
2
  from .constants import Constants as const
3
+ import os
4
+ import json
5
+ initialized = False
6
+
7
+ def init(
8
+ resolution:tuple[int,int],
9
+ flags:int=0,
10
+ vsync:int = 0,
11
+ default_text_size=None,
12
+ default_font=None,
13
+ resource_path:str|None=None,
14
+ window_title:str="BatFramework Project",
15
+ fps_limit : int = 0
16
+ ):
17
+ global initialized
18
+ if not initialized:
19
+ pygame.init()
20
+ pygame.display.set_caption(window_title)
21
+
22
+ # Initialize display
23
+ const.init_screen(resolution,flags,vsync)
24
+ const.set_fps_limit(fps_limit)
25
+
26
+ # Initialize default text size
27
+ if default_text_size: const.set_default_text_size(default_text_size)
28
+ # Initialize resource path for game data
29
+ if resource_path: const.set_resource_path(resource_path)
30
+
31
+ # Initialize default font cache
32
+ from .utils import Utils
33
+ if default_font is None or isinstance(default_font,str):
34
+ Utils.init_font(default_font)
35
+ else:
36
+ raise ValueError(f"default_font '{default_font}' can be either string or None")
37
+
38
+ f = list(Utils.FONTS[None].values())[0]
39
+ print(f"Set default font to : {f.name} {'' if default_font is not None else '(default value)'}")
40
+ initialized = True
41
+
42
+ from .constants import Colors as color
43
+ from .constants import Axis as axis
5
44
  from .utils import Singleton
6
- from .enums import *
7
- from .resourceManager import ResourceManager
8
- from .fontManager import FontManager
9
45
  from .utils import Utils as utils
10
- from .tileset import Tileset
11
- from .time import TimeManager, Timer
12
- from .easingController import EasingController
13
- from .cutscene import Cutscene, CutsceneManager
46
+ from .time import Time, Timer
47
+ from .cutscene import Cutscene,CutsceneManager
14
48
  from .cutsceneBlocks import *
49
+ from .easing import Easing, EasingAnimation
15
50
  from .audioManager import AudioManager
16
- import batFramework.transition as transition
51
+ from .utils import Layout, Alignment, Direction
52
+ from .transition import *
17
53
  from .action import Action
18
- from .actionContainer import *
54
+ from .actionContainer import ActionContainer
19
55
  from .camera import Camera
20
- from .object import Object
21
56
  from .entity import Entity
22
- from .renderGroup import RenderGroup
23
57
  from .dynamicEntity import DynamicEntity
24
- from .sprite import Sprite
25
- from .scrollingSprite import ScrollingSprite
26
- from .particle import *
27
58
  from .animatedSprite import AnimatedSprite, AnimState
28
59
  from .stateMachine import State, StateMachine
60
+ from .particles import Particle, ParticleManager
61
+ # from .debugger import Debugger
29
62
  from .scene import Scene
30
- from .gui import *
63
+ from .gui import *
31
64
  from .sceneManager import SceneManager
32
65
  from .manager import Manager
33
66
 
34
-
35
- def init_screen(resolution: tuple[int, int], flags: int = 0, vsync: int = 0):
36
- const.RESOLUTION = resolution
37
- const.FLAGS = flags
38
- const.VSYNC = vsync
39
- const.SCREEN = pygame.display.set_mode(
40
- const.RESOLUTION, const.FLAGS, vsync=const.VSYNC
41
- )
42
- print(
43
- f"Window : {resolution[0]}x{resolution[1]} [vsync:{pygame.display.is_vsync()}]"
44
- )
45
-
46
-
47
- def init(
48
- resolution: tuple[int, int],
49
- flags: int = 0,
50
- vsync: int = 0,
51
- default_text_size=None,
52
- default_font=None,
53
- resource_path: str | None = None,
54
- window_title: str = "BatFramework Project",
55
- fps_limit: int = 0,
56
- ):
57
- pygame.display.set_caption(window_title)
58
- init_screen(resolution, flags, vsync)
59
-
60
- ResourceManager().set_resource_path(
61
- resource_path if resource_path is not None else "."
62
- )
63
- if resource_path is not None:
64
- ResourceManager().load_dir(ResourceManager().RESOURCE_PATH)
65
- if default_text_size is not None:
66
- FontManager().set_default_text_size(default_text_size)
67
- FontManager().init_font(default_font)
68
- const.BF_INITIALIZED = True
69
- const.set_fps_limit(fps_limit)
batFramework/action.py CHANGED
@@ -1,9 +1,8 @@
1
- from typing import Any,Self
1
+ from typing import Any
2
2
  from enum import Enum
3
3
  import pygame
4
- from .enums import actionType
5
-
6
4
 
5
+ ActionType = Enum("type", "INSTANTANEOUS CONTINUOUS HOLDING")
7
6
 
8
7
  class Action:
9
8
  def __init__(self, name: str) -> None:
@@ -13,28 +12,34 @@ class Action:
13
12
  Args:
14
13
  name (str): The name of the action.
15
14
  """
16
- self.name: str = name
17
- self.active: bool = False
18
- self.data: dict = {}
19
- self.consume_event : bool = False
20
- self._type: actionType = actionType.INSTANTANEOUS
21
- self._key_control: set = set()
22
- self._mouse_control: set = set()
23
- self._event_control: set = set()
24
- self._gamepad_button_control: set = set()
25
- self._gamepad_axis_control: set = set()
15
+ self._name = name
16
+ self._active = False
17
+ self._type = ActionType.INSTANTANEOUS
18
+ self._key_control = set()
19
+ self._mouse_control = set()
20
+ self._gamepad_button_control = set()
21
+ self._gamepad_axis_control = set()
26
22
  self._holding = set()
23
+ self._unique = True
24
+ self.data : Any = None
27
25
 
28
- def set_consume_event(self, val: bool) -> Self:
26
+ def set_unique(self, val: bool) -> None:
29
27
  """
30
28
  Set whether this action is unique (exclusive).
31
- When in an action Container, unique actions -when active - break the propagation of their event to other actions.
32
29
 
33
30
  Args:
34
31
  val (bool): True if the action is unique, False otherwise.
35
32
  """
36
- self.consume_event = val
37
- return self
33
+ self._unique = val
34
+
35
+ def is_active(self) -> bool:
36
+ """
37
+ Check if the action is currently active.
38
+
39
+ Returns:
40
+ bool: True if the action is active, False otherwise.
41
+ """
42
+ return self._active
38
43
 
39
44
  def set_active(self, value: bool) -> None:
40
45
  """
@@ -43,20 +48,10 @@ class Action:
43
48
  Args:
44
49
  value (bool): True to activate the action, False to deactivate it.
45
50
  """
46
- self.active = value
47
- # self._holding = set()
48
-
49
-
50
- def add_event_control(self,*events)->Self:
51
- self._event_control.update(events)
52
- return self
53
-
54
- def remove_event_control(self,*events)->Self:
55
- self._event_control = self._event_control - events
56
- return self
57
-
51
+ self._active = value
52
+ self._holding = set()
58
53
 
59
- def add_key_control(self, *keys) -> Self:
54
+ def add_key_control(self, *keys) -> 'Action':
60
55
  """
61
56
  Add key controls to the action.
62
57
 
@@ -69,40 +64,29 @@ class Action:
69
64
  self._key_control.update(keys)
70
65
  return self
71
66
 
72
- def remove_key_control(self, *keys: int) -> Self:
67
+ def add_mouse_control(self, *mouse_buttons) -> 'Action':
73
68
  """
74
- Remove key controls to the action.
69
+ Add mouse control to the action.
75
70
 
76
71
  Args:
77
- *keys (int): Key codes to control this action.
72
+ *mouse_buttons (int): Mouse button codes to control this action.
78
73
 
79
74
  Returns:
80
75
  Action: The updated Action object for method chaining.
81
76
  """
82
- self._key_control = self._key_control - set(keys)
83
- return self
84
-
85
- def replace_key_control(self, key, new_key) -> Self:
86
- if not key in self._key_control:
87
- return self
88
- self.remove_key_control(key)
89
- self.add_key_control(new_key)
77
+ self._mouse_control.update(mouse_buttons)
90
78
  return self
91
79
 
92
- def add_mouse_control(self, *mouse_buttons: int) -> Self:
80
+ def get_name(self) -> str:
93
81
  """
94
- Add mouse control to the action.
95
-
96
- Args:
97
- *mouse_buttons (int): Mouse button codes to control this action.
82
+ Get the name of the action.
98
83
 
99
84
  Returns:
100
- Action: The updated Action object for method chaining.
85
+ str: The name of the action.
101
86
  """
102
- self._mouse_control.update(mouse_buttons)
103
- return self
87
+ return self._name
104
88
 
105
- def set_continuous(self) -> Self:
89
+ def set_continuous(self) -> 'Action':
106
90
  """
107
91
  Set the action type to continuous.
108
92
 
@@ -110,7 +94,7 @@ class Action:
110
94
  Action: The updated Action object for method chaining.
111
95
  """
112
96
  self._holding = set()
113
- self._type = actionType.CONTINUOUS
97
+ self._type = ActionType.CONTINUOUS
114
98
  return self
115
99
 
116
100
  def is_continuous(self) -> bool:
@@ -120,16 +104,16 @@ class Action:
120
104
  Returns:
121
105
  bool: True if the action type is continuous, False otherwise.
122
106
  """
123
- return self._type == actionType.CONTINUOUS
107
+ return self._type == ActionType.CONTINUOUS
124
108
 
125
- def set_instantaneous(self) -> Self:
109
+ def set_instantaneous(self) -> 'Action':
126
110
  """
127
111
  Set the action type to instantaneous.
128
112
 
129
113
  Returns:
130
114
  Action: The updated Action object for method chaining.
131
115
  """
132
- self._type = actionType.INSTANTANEOUS
116
+ self._type = ActionType.INSTANTANEOUS
133
117
  self._holding = set()
134
118
  return self
135
119
 
@@ -140,16 +124,16 @@ class Action:
140
124
  Returns:
141
125
  bool: True if the action type is instantaneous, False otherwise.
142
126
  """
143
- return self._type == actionType.INSTANTANEOUS
127
+ return self._type == ActionType.INSTANTANEOUS
144
128
 
145
- def set_holding(self) -> Self:
129
+ def set_holding(self) -> 'Action':
146
130
  """
147
131
  Set the action type to holding.
148
132
 
149
133
  Returns:
150
134
  Action: The updated Action object for method chaining.
151
135
  """
152
- self._type = actionType.HOLDING
136
+ self._type = ActionType.HOLDING
153
137
  return self
154
138
 
155
139
  def is_holding_type(self) -> bool:
@@ -159,17 +143,13 @@ class Action:
159
143
  Returns:
160
144
  bool: True if the action type is holding, False otherwise.
161
145
  """
162
- return self._type == actionType.HOLDING
146
+ return self._type == ActionType.HOLDING
163
147
 
164
- def process_update(self, event: pygame.Event) -> None:
165
- if (
166
- event.type == pygame.MOUSEMOTION
167
- and self._type == actionType.HOLDING
168
- and pygame.MOUSEMOTION in self._mouse_control
169
- ) or self._event_control:
170
- self.data = event.dict
148
+ def process_update(self,event:pygame.Event)->None:
149
+ if self.is_active() and event.type == pygame.MOUSEMOTION and self.is_holding_type() and pygame.MOUSEMOTION in self._mouse_control:
150
+ self.data = {"pos":event.pos,"rel":event.rel}
171
151
 
172
- def process_activate(self, event: pygame.event.Event):
152
+ def process_activate(self, event: pygame.event.Event) -> bool:
173
153
  """
174
154
  Process activation of the action based on a pygame event.
175
155
 
@@ -179,85 +159,94 @@ class Action:
179
159
  Returns:
180
160
  bool: True if the action was activated by the event, False otherwise.
181
161
  """
182
-
183
162
  if event.type == pygame.KEYDOWN and event.key in self._key_control:
184
- self._activate_action(event.key)
185
-
186
- elif event.type == pygame.MOUSEBUTTONDOWN and event.button in self._mouse_control:
187
- self._activate_action(event.button)
163
+ self._active = True
164
+ if self.is_holding_type():
165
+ self._holding.add(event.key)
166
+ return True
188
167
 
189
- elif event.type == pygame.MOUSEMOTION and event.type in self._mouse_control:
190
- self._activate_action(event.type)
168
+ if event.type == pygame.MOUSEBUTTONDOWN and event.button in self._mouse_control:
169
+ self._active = True
170
+ if self.is_holding_type():
171
+ self._holding.add(event.button)
172
+ return True
191
173
 
192
- elif event.type in self._event_control:
193
- self._activate_action(event.type)
194
- self.data = event.dict
195
- else:
196
- return
197
- if self.consume_event : event.consumed = True
174
+ if event.type == pygame.MOUSEMOTION and event.type in self._mouse_control:
175
+ self._active = True
176
+ if self.is_holding_type():
177
+ self._holding.add(event.type)
178
+ return True
198
179
 
199
- def _activate_action(self, control):
200
- self.active = True
201
- if self._type == actionType.HOLDING:
202
- self._holding.add(control)
180
+ return False
203
181
 
204
- def process_deactivate(self, event: pygame.event.Event):
182
+ def process_deactivate(self, event: pygame.event.Event) -> bool:
205
183
  """
206
184
  Process deactivation of the action based on a pygame event.
207
185
 
208
186
  Args:
209
187
  event (pygame.event.Event): The pygame event to process.
210
188
 
189
+ Returns:
190
+ bool: True if the action was deactivated by the event, False otherwise.
211
191
  """
212
- if self._type == actionType.HOLDING:
192
+ if self._type == ActionType.HOLDING:
213
193
  if event.type == pygame.KEYUP and event.key in self._key_control:
214
- self._deactivate_action(event.key)
215
- elif event.type == pygame.MOUSEBUTTONUP and event.button in self._mouse_control:
216
- self._deactivate_action(event.button)
217
- elif event.type == pygame.MOUSEMOTION and event.type in self._mouse_control:
218
- self._deactivate_action(event.type)
219
- elif event.type in self._event_control:
220
- self._deactivate_action(event.type)
221
- else:
222
- event.consumed = False
223
-
224
- if self.consume_event: event.consumed = True
225
-
226
- def _deactivate_action(self, control) -> bool:
227
- if control in self._holding:
228
- self._holding.remove(control)
229
- if not self._holding:
230
- self.active = False
231
-
232
- def process_event(self, event: pygame.event.Event):
194
+ if event.key in self._holding:
195
+ self._holding.remove(event.key)
196
+ if not self._holding:
197
+ self._active = False
198
+ return True
199
+ elif (
200
+ event.type == pygame.MOUSEBUTTONUP
201
+ and event.button in self._mouse_control
202
+ ):
203
+ if event.button in self._holding:
204
+ self._holding.remove(event.button)
205
+ if not self._holding:
206
+ self._active = False
207
+ return True
208
+ elif (
209
+ event.type == pygame.MOUSEMOTION
210
+ and event.type in self._mouse_control
211
+ ):
212
+ self.value = None
213
+ if event.type in self._holding:
214
+ self._holding.remove(event.type)
215
+ if not self._holding:
216
+ self._active = False
217
+ return True
218
+
219
+ return False
220
+
221
+ def process_event(self, event: pygame.event.Event) -> bool:
233
222
  """
234
223
  Process a pygame event and update the action's state.
235
224
 
236
225
  Args:
237
226
  event (pygame.event.Event): The pygame event to process.
238
- """
239
227
 
240
- if event.consumed : return
241
- if not self.active:
242
- self.process_activate(event)
228
+ Returns:
229
+ bool: True if the action state changed, False otherwise.
230
+ """
231
+ if not self._active:
232
+ res = self.process_activate(event)
243
233
  else:
244
- self.process_deactivate(event)
245
- if self.active:
246
- self.process_update(event)
247
- return
234
+ res = self.process_deactivate(event)
235
+ self.process_update(event)
236
+ return res
248
237
 
249
238
  def reset(self) -> None:
250
239
  """
251
240
  Reset the action's state to the default state.
252
241
  """
253
- if self._type in {actionType.CONTINUOUS, actionType.HOLDING}:
242
+ if self._type in {ActionType.CONTINUOUS, ActionType.HOLDING}:
254
243
  return
255
- elif self._type == actionType.INSTANTANEOUS:
256
- self.active = False
244
+ elif self._type == ActionType.INSTANTANEOUS:
245
+ self._active = False
257
246
 
258
247
  def hard_reset(self) -> None:
259
248
  """
260
249
  Hard reset the action, deactivating it and clearing any holding controls.
261
250
  """
262
- self.active = False
251
+ self._active = False
263
252
  self._holding = set()
@@ -1,44 +1,34 @@
1
1
  import batFramework as bf
2
- import pygame
3
2
 
4
3
 
5
4
  class ActionContainer:
6
5
  def __init__(self, *actions: list[bf.Action]) -> None:
7
6
  self._actions: dict[str, bf.Action] = {}
8
7
  if actions:
9
- self.add_actions(*actions)
10
-
11
- def __iter__(self):
12
- return iter(self._actions.values())
8
+ self.add_action(*actions)
13
9
 
14
10
  def clear(self):
15
11
  self._actions = {}
16
12
 
17
- def add_actions(self, *actions: bf.Action):
13
+ def add_action(self, *actions: bf.Action):
18
14
  for action in actions:
19
- self._actions[action.name] = action
15
+ self._actions[action.get_name()] = action
20
16
 
21
- def get(self, name: str) -> bf.Action:
17
+ def get(self,name:str)->bf.Action:
22
18
  return self._actions.get(name)
23
19
 
24
- def has_action(self, name: str):
20
+ def has_action(self, name:str):
25
21
  return name in self._actions
26
22
 
27
- def get_all(self) -> list[bf.Action]:
28
- return self._actions
29
-
30
- def is_active(self, *names: str) -> bool:
31
- return all(
32
- self._actions.get(name).active if name in self._actions else False
33
- for name in names
34
- )
23
+ def is_active(self, *names:str)->bool:
24
+ return all(self._actions.get(name).is_active() if name in self._actions else False for name in names)
35
25
 
36
26
  def process_event(self, event):
37
- if event.consumed : return
38
27
  for action in self._actions.values():
39
- action.process_event(event)
40
- if event.consumed == True:break
41
-
28
+ a = action.process_event(event)
29
+ if a and action._unique:
30
+ break
31
+
42
32
  def reset(self):
43
33
  for action in self._actions.values():
44
34
  action.reset()
@@ -46,35 +36,3 @@ class ActionContainer:
46
36
  def hard_reset(self):
47
37
  for action in self._actions.values():
48
38
  action.hard_reset()
49
-
50
-
51
- class DirectionalKeyControls(ActionContainer):
52
- def __init__(self):
53
- super().__init__(
54
- bf.Action("up").add_key_control(pygame.K_UP).set_holding(),
55
- bf.Action("down").add_key_control(pygame.K_DOWN).set_holding(),
56
- bf.Action("left").add_key_control(pygame.K_LEFT).set_holding(),
57
- bf.Action("right").add_key_control(pygame.K_RIGHT).set_holding(),
58
- )
59
-
60
-
61
- class WASDControls(ActionContainer):
62
- def __init__(self):
63
- super().__init__(
64
- bf.Action("up").add_key_control(pygame.K_w).set_holding(),
65
- bf.Action("down").add_key_control(pygame.K_s).set_holding(),
66
- bf.Action("left").add_key_control(pygame.K_a).set_holding(),
67
- bf.Action("right").add_key_control(pygame.K_d).set_holding(),
68
- )
69
-
70
-
71
- class HybridControls(ActionContainer):
72
- def __init__(self):
73
- super().__init__(
74
- bf.Action("up").add_key_control(pygame.K_UP, pygame.K_w).set_holding(),
75
- bf.Action("down").add_key_control(pygame.K_DOWN, pygame.K_s).set_holding(),
76
- bf.Action("left").add_key_control(pygame.K_LEFT, pygame.K_a).set_holding(),
77
- bf.Action("right")
78
- .add_key_control(pygame.K_RIGHT, pygame.K_r)
79
- .set_holding(),
80
- )