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/__init__.py CHANGED
@@ -2,7 +2,6 @@ import pygame
2
2
  import batFramework as bf
3
3
  import sys
4
4
  from .constants import Constants as const
5
- from .constants import Colors as color
6
5
  from .utils import Singleton
7
6
  from .enums import *
8
7
  from .resourceManager import ResourceManager
@@ -10,36 +9,41 @@ from .fontManager import FontManager
10
9
  from .utils import Utils as utils
11
10
  from .tileset import Tileset
12
11
  from .time import TimeManager, Timer
12
+ from .easingController import EasingController
13
13
  from .cutscene import Cutscene, CutsceneManager
14
14
  from .cutsceneBlocks import *
15
- from .easing import Easing, EasingAnimation
16
15
  from .audioManager import AudioManager
17
16
  import batFramework.transition as transition
18
17
  from .action import Action
19
18
  from .actionContainer import *
20
19
  from .camera import Camera
20
+ from .object import Object
21
21
  from .entity import Entity
22
+ from .renderGroup import RenderGroup
22
23
  from .dynamicEntity import DynamicEntity
23
24
  from .sprite import Sprite
25
+ from .scrollingSprite import ScrollingSprite
26
+ from .particle import *
24
27
  from .animatedSprite import AnimatedSprite, AnimState
25
28
  from .stateMachine import State, StateMachine
26
29
  from .scene import Scene
27
- from .gui import *
30
+ from .gui import *
28
31
  from .sceneManager import SceneManager
29
32
  from .manager import Manager
30
33
 
31
-
34
+
32
35
  def init_screen(resolution: tuple[int, int], flags: int = 0, vsync: int = 0):
33
36
  const.RESOLUTION = resolution
34
37
  const.FLAGS = flags
35
38
  const.VSYNC = vsync
36
39
  const.SCREEN = pygame.display.set_mode(
37
- const.RESOLUTION,const.FLAGS, vsync=const.VSYNC
40
+ const.RESOLUTION, const.FLAGS, vsync=const.VSYNC
38
41
  )
39
42
  print(
40
43
  f"Window : {resolution[0]}x{resolution[1]} [vsync:{pygame.display.is_vsync()}]"
41
44
  )
42
45
 
46
+
43
47
  def init(
44
48
  resolution: tuple[int, int],
45
49
  flags: int = 0,
@@ -48,13 +52,18 @@ def init(
48
52
  default_font=None,
49
53
  resource_path: str | None = None,
50
54
  window_title: str = "BatFramework Project",
51
- fps_limit: int = 0):
52
- pygame.display.set_caption(window_title)
53
- init_screen(resolution,flags,vsync)
54
-
55
- ResourceManager().set_resource_path(resource_path if resource_path is not None else ".")
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:
56
64
  ResourceManager().load_dir(ResourceManager().RESOURCE_PATH)
57
- if default_text_size is not None : FontManager().set_default_text_size(default_text_size)
58
- FontManager().init_font(default_font)
59
- const.BF_INITIALIZED = True
60
- const.set_fps_limit(fps_limit)
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,8 +1,9 @@
1
- from typing import Any
1
+ from typing import Any,Self
2
2
  from enum import Enum
3
3
  import pygame
4
+ from .enums import actionType
5
+
4
6
 
5
- ActionType = Enum("type", "INSTANTANEOUS CONTINUOUS HOLDING")
6
7
 
7
8
  class Action:
8
9
  def __init__(self, name: str) -> None:
@@ -12,18 +13,19 @@ class Action:
12
13
  Args:
13
14
  name (str): The name of the action.
14
15
  """
15
- self._name :str= name
16
- self._active :bool= False
17
- self._type :ActionType = ActionType.INSTANTANEOUS
18
- self._key_control : set= set()
19
- self._mouse_control :set = set()
20
- self._gamepad_button_control :set = set()
21
- self._gamepad_axis_control :set = set()
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()
22
26
  self._holding = set()
23
- self._unique = True
24
- self.data: Any = None
25
27
 
26
- def set_unique(self, val: bool) -> None:
28
+ def set_consume_event(self, val: bool) -> Self:
27
29
  """
28
30
  Set whether this action is unique (exclusive).
29
31
  When in an action Container, unique actions -when active - break the propagation of their event to other actions.
@@ -31,16 +33,8 @@ class Action:
31
33
  Args:
32
34
  val (bool): True if the action is unique, False otherwise.
33
35
  """
34
- self._unique = val
35
-
36
- def is_active(self) -> bool:
37
- """
38
- Check if the action is currently active.
39
-
40
- Returns:
41
- bool: True if the action is active, False otherwise.
42
- """
43
- return self._active
36
+ self.consume_event = val
37
+ return self
44
38
 
45
39
  def set_active(self, value: bool) -> None:
46
40
  """
@@ -49,10 +43,20 @@ class Action:
49
43
  Args:
50
44
  value (bool): True to activate the action, False to deactivate it.
51
45
  """
52
- self._active = value
53
- self._holding = set()
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
+
54
58
 
55
- def add_key_control(self, *keys) -> "Action":
59
+ def add_key_control(self, *keys) -> Self:
56
60
  """
57
61
  Add key controls to the action.
58
62
 
@@ -65,7 +69,7 @@ class Action:
65
69
  self._key_control.update(keys)
66
70
  return self
67
71
 
68
- def remove_key_control(self, *keys:int) -> "Action":
72
+ def remove_key_control(self, *keys: int) -> Self:
69
73
  """
70
74
  Remove key controls to the action.
71
75
 
@@ -78,13 +82,14 @@ class Action:
78
82
  self._key_control = self._key_control - set(keys)
79
83
  return self
80
84
 
81
- def replace_key_control(self, key, new_key) -> "Action":
82
- if not key in self._key_control : return self
85
+ def replace_key_control(self, key, new_key) -> Self:
86
+ if not key in self._key_control:
87
+ return self
83
88
  self.remove_key_control(key)
84
89
  self.add_key_control(new_key)
85
90
  return self
86
91
 
87
- def add_mouse_control(self, *mouse_buttons:int) -> "Action":
92
+ def add_mouse_control(self, *mouse_buttons: int) -> Self:
88
93
  """
89
94
  Add mouse control to the action.
90
95
 
@@ -97,16 +102,7 @@ class Action:
97
102
  self._mouse_control.update(mouse_buttons)
98
103
  return self
99
104
 
100
- def get_name(self) -> str:
101
- """
102
- Get the name of the action.
103
-
104
- Returns:
105
- str: The name of the action.
106
- """
107
- return self._name
108
-
109
- def set_continuous(self) -> "Action":
105
+ def set_continuous(self) -> Self:
110
106
  """
111
107
  Set the action type to continuous.
112
108
 
@@ -114,7 +110,7 @@ class Action:
114
110
  Action: The updated Action object for method chaining.
115
111
  """
116
112
  self._holding = set()
117
- self._type = ActionType.CONTINUOUS
113
+ self._type = actionType.CONTINUOUS
118
114
  return self
119
115
 
120
116
  def is_continuous(self) -> bool:
@@ -124,16 +120,16 @@ class Action:
124
120
  Returns:
125
121
  bool: True if the action type is continuous, False otherwise.
126
122
  """
127
- return self._type == ActionType.CONTINUOUS
123
+ return self._type == actionType.CONTINUOUS
128
124
 
129
- def set_instantaneous(self) -> "Action":
125
+ def set_instantaneous(self) -> Self:
130
126
  """
131
127
  Set the action type to instantaneous.
132
128
 
133
129
  Returns:
134
130
  Action: The updated Action object for method chaining.
135
131
  """
136
- self._type = ActionType.INSTANTANEOUS
132
+ self._type = actionType.INSTANTANEOUS
137
133
  self._holding = set()
138
134
  return self
139
135
 
@@ -144,16 +140,16 @@ class Action:
144
140
  Returns:
145
141
  bool: True if the action type is instantaneous, False otherwise.
146
142
  """
147
- return self._type == ActionType.INSTANTANEOUS
143
+ return self._type == actionType.INSTANTANEOUS
148
144
 
149
- def set_holding(self) -> "Action":
145
+ def set_holding(self) -> Self:
150
146
  """
151
147
  Set the action type to holding.
152
148
 
153
149
  Returns:
154
150
  Action: The updated Action object for method chaining.
155
151
  """
156
- self._type = ActionType.HOLDING
152
+ self._type = actionType.HOLDING
157
153
  return self
158
154
 
159
155
  def is_holding_type(self) -> bool:
@@ -163,18 +159,17 @@ class Action:
163
159
  Returns:
164
160
  bool: True if the action type is holding, False otherwise.
165
161
  """
166
- return self._type == ActionType.HOLDING
162
+ return self._type == actionType.HOLDING
167
163
 
168
164
  def process_update(self, event: pygame.Event) -> None:
169
165
  if (
170
- self.is_active()
171
- and event.type == pygame.MOUSEMOTION
172
- and self.is_holding_type()
166
+ event.type == pygame.MOUSEMOTION
167
+ and self._type == actionType.HOLDING
173
168
  and pygame.MOUSEMOTION in self._mouse_control
174
- ):
175
- self.data = {"pos": event.pos, "rel": event.rel}
169
+ ) or self._event_control:
170
+ self.data = event.dict
176
171
 
177
- def process_activate(self, event: pygame.event.Event) -> bool:
172
+ def process_activate(self, event: pygame.event.Event):
178
173
  """
179
174
  Process activation of the action based on a pygame event.
180
175
 
@@ -184,91 +179,85 @@ class Action:
184
179
  Returns:
185
180
  bool: True if the action was activated by the event, False otherwise.
186
181
  """
182
+
187
183
  if event.type == pygame.KEYDOWN and event.key in self._key_control:
188
- self._active = True
189
- if self.is_holding_type():
190
- self._holding.add(event.key)
191
- return True
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)
192
188
 
193
- if event.type == pygame.MOUSEBUTTONDOWN and event.button in self._mouse_control:
194
- self._active = True
195
- if self.is_holding_type():
196
- self._holding.add(event.button)
197
- return True
189
+ elif event.type == pygame.MOUSEMOTION and event.type in self._mouse_control:
190
+ self._activate_action(event.type)
198
191
 
199
- if event.type == pygame.MOUSEMOTION and event.type in self._mouse_control:
200
- self._active = True
201
- if self.is_holding_type():
202
- self._holding.add(event.type)
203
- return True
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
204
198
 
205
- return False
199
+ def _activate_action(self, control):
200
+ self.active = True
201
+ if self._type == actionType.HOLDING:
202
+ self._holding.add(control)
206
203
 
207
- def process_deactivate(self, event: pygame.event.Event) -> bool:
204
+ def process_deactivate(self, event: pygame.event.Event):
208
205
  """
209
206
  Process deactivation of the action based on a pygame event.
210
207
 
211
208
  Args:
212
209
  event (pygame.event.Event): The pygame event to process.
213
210
 
214
- Returns:
215
- bool: True if the action was deactivated by the event, False otherwise.
216
211
  """
217
- if self._type == ActionType.HOLDING:
212
+ if self._type == actionType.HOLDING:
218
213
  if event.type == pygame.KEYUP and event.key in self._key_control:
219
- if event.key in self._holding:
220
- self._holding.remove(event.key)
221
- if not self._holding:
222
- self._active = False
223
- return True
224
- elif (
225
- event.type == pygame.MOUSEBUTTONUP
226
- and event.button in self._mouse_control
227
- ):
228
- if event.button in self._holding:
229
- self._holding.remove(event.button)
230
- if not self._holding:
231
- self._active = False
232
- return True
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)
233
217
  elif event.type == pygame.MOUSEMOTION and event.type in self._mouse_control:
234
- self.value = None
235
- if event.type in self._holding:
236
- self._holding.remove(event.type)
237
- if not self._holding:
238
- self._active = False
239
- return True
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
240
225
 
241
- return False
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
242
231
 
243
- def process_event(self, event: pygame.event.Event) -> bool:
232
+ def process_event(self, event: pygame.event.Event):
244
233
  """
245
234
  Process a pygame event and update the action's state.
246
235
 
247
236
  Args:
248
237
  event (pygame.event.Event): The pygame event to process.
249
-
250
- Returns:
251
- bool: True if the action state changed, False otherwise.
252
238
  """
253
- if not self._active:
254
- res = self.process_activate(event)
239
+
240
+ if event.consumed : return
241
+ if not self.active:
242
+ self.process_activate(event)
255
243
  else:
256
- res = self.process_deactivate(event)
257
- self.process_update(event)
258
- return res
244
+ self.process_deactivate(event)
245
+ if self.active:
246
+ self.process_update(event)
247
+ return
259
248
 
260
249
  def reset(self) -> None:
261
250
  """
262
251
  Reset the action's state to the default state.
263
252
  """
264
- if self._type in {ActionType.CONTINUOUS, ActionType.HOLDING}:
253
+ if self._type in {actionType.CONTINUOUS, actionType.HOLDING}:
265
254
  return
266
- elif self._type == ActionType.INSTANTANEOUS:
267
- self._active = False
255
+ elif self._type == actionType.INSTANTANEOUS:
256
+ self.active = False
268
257
 
269
258
  def hard_reset(self) -> None:
270
259
  """
271
260
  Hard reset the action, deactivating it and clearing any holding controls.
272
261
  """
273
- self._active = False
262
+ self.active = False
274
263
  self._holding = set()
@@ -6,14 +6,17 @@ class ActionContainer:
6
6
  def __init__(self, *actions: list[bf.Action]) -> None:
7
7
  self._actions: dict[str, bf.Action] = {}
8
8
  if actions:
9
- self.add_action(*actions)
9
+ self.add_actions(*actions)
10
+
11
+ def __iter__(self):
12
+ return iter(self._actions.values())
10
13
 
11
14
  def clear(self):
12
15
  self._actions = {}
13
16
 
14
- def add_action(self, *actions: bf.Action):
17
+ def add_actions(self, *actions: bf.Action):
15
18
  for action in actions:
16
- self._actions[action.get_name()] = action
19
+ self._actions[action.name] = action
17
20
 
18
21
  def get(self, name: str) -> bf.Action:
19
22
  return self._actions.get(name)
@@ -26,16 +29,16 @@ class ActionContainer:
26
29
 
27
30
  def is_active(self, *names: str) -> bool:
28
31
  return all(
29
- self._actions.get(name).is_active() if name in self._actions else False
32
+ self._actions.get(name).active if name in self._actions else False
30
33
  for name in names
31
34
  )
32
35
 
33
36
  def process_event(self, event):
37
+ if event.consumed : return
34
38
  for action in self._actions.values():
35
- a = action.process_event(event)
36
- if a and action._unique:
37
- break
38
-
39
+ action.process_event(event)
40
+ if event.consumed == True:break
41
+
39
42
  def reset(self):
40
43
  for action in self._actions.values():
41
44
  action.reset()
@@ -13,27 +13,34 @@ def search_index(target, lst):
13
13
 
14
14
  class AnimState:
15
15
  def __init__(
16
- self, name: str, file, width, height, duration_list: list | int,convert_alpha:bool=True
16
+ self,
17
+ name: str,
18
+ surface: pygame.Surface,
19
+ width,
20
+ height,
21
+ duration_list: list | int,
17
22
  ) -> None:
18
- self.frames: list[pygame.Surface] =bf.utils.img_slice(
19
- file, width, height,
20
- False,convert_alpha
23
+ self.frames: list[pygame.Surface] = list(
24
+ bf.utils.split_surface(
25
+ surface, width, height, False, convert_alpha
26
+ ).values()
21
27
  )
22
- self.frames_flipX: list[pygame.Surface] = bf.utils.img_slice(
23
- file, width, height,
24
- True,convert_alpha
28
+ self.frames_flipX: list[pygame.Surface] = list(
29
+ bf.utils.split_surface(surface, width, height, True, convert_alpha).values()
25
30
  )
26
-
31
+
27
32
  self.name = name
28
- self.duration_list :list[int]= []
33
+ self.duration_list: list[int] = []
29
34
  self.duration_list_length = 0
30
35
  self.set_duration_list(duration_list)
31
36
 
32
37
  def __repr__(self):
33
38
  return f"AnimState({self.name})"
34
39
 
35
- def counter_to_frame(self, counter: float | int)->int:
36
- return search_index(int(counter % self.duration_list_length), self.duration_list)
40
+ def counter_to_frame(self, counter: float | int) -> int:
41
+ return search_index(
42
+ int(counter % self.duration_list_length), self.duration_list
43
+ )
37
44
 
38
45
  def get_frame(self, counter, flip):
39
46
  i = self.counter_to_frame(counter)
@@ -51,47 +58,49 @@ class AnimState:
51
58
  class AnimatedSprite(bf.DynamicEntity):
52
59
  def __init__(self, size=None) -> None:
53
60
  super().__init__(size, no_surface=True)
54
- self.float_counter :float= 0
61
+ self.float_counter: float = 0
55
62
  self.animStates: dict[str, AnimState] = {}
56
- self.current_state: AnimState|None = None
63
+ self.current_state: AnimState | None = None
57
64
  self.flipX = False
58
65
  self._locked = False
59
- self.paused : bool = False
66
+ self.paused: bool = False
60
67
 
61
- def pause(self)->None:
68
+ def pause(self) -> None:
62
69
  self.paused = True
63
70
 
64
- def resume(self)->None:
71
+ def resume(self) -> None:
65
72
  self.paused = False
66
73
 
67
- def toggle_pause(self)->None:
74
+ def toggle_pause(self) -> None:
68
75
  self.paused = not self.paused
69
76
 
70
- def set_counter(self, value: float)->None:
77
+ def set_counter(self, value: float) -> None:
71
78
  self.float_counter = value
72
79
 
73
- def set_frame(self,frame_index:int)->None:
74
- if not self.current_state : return
80
+ def set_frame(self, frame_index: int) -> None:
81
+ if not self.current_state:
82
+ return
75
83
  total = sum(self.current_state.duration_list)
76
- frame_index = max(0,min(total,frame_index))
84
+ frame_index = max(0, min(total, frame_index))
77
85
  new_counter = 0
78
86
  i = 0
79
87
  while frame_index < total:
80
- if self.current_state.counter_to_frame(new_counter)>=frame_index:
88
+ if self.current_state.counter_to_frame(new_counter) >= frame_index:
81
89
  break
82
- new_counter +=self.current_state.duration_list[i]
83
- i+=1
90
+ new_counter += self.current_state.duration_list[i]
91
+ i += 1
84
92
  self.set_counter(new_counter)
85
- def lock(self)->None:
93
+
94
+ def lock(self) -> None:
86
95
  self._locked = True
87
96
 
88
- def unlock(self)->None:
97
+ def unlock(self) -> None:
89
98
  self._locked = False
90
99
 
91
- def set_flipX(self, value)->None:
100
+ def set_flipX(self, value) -> None:
92
101
  self.flipX = value
93
102
 
94
- def remove_animState(self, name: str)->bool:
103
+ def remove_animState(self, name: str) -> bool:
95
104
  if not name in self.animStates:
96
105
  return False
97
106
  self.animStates.pop(name)
@@ -100,51 +109,59 @@ class AnimatedSprite(bf.DynamicEntity):
100
109
  list(self.animStates.keys())[0] if self.animStates else ""
101
110
  )
102
111
  return True
103
-
112
+
104
113
  def add_animState(
105
- self, name: str, file: str, size: tuple[int, int], duration_list: list[int],
106
- convert_alpha:bool=True
107
- )->bool:
114
+ self,
115
+ name: str,
116
+ surface: pygame.Surface,
117
+ size: tuple[int, int],
118
+ duration_list: list[int],
119
+ convert_alpha: bool = True,
120
+ ) -> bool:
108
121
  if name in self.animStates:
109
122
  return False
110
- self.animStates[name] = AnimState(name, file, *size, duration_list,convert_alpha)
123
+ self.animStates[name] = AnimState(name, surface, *size, duration_list)
111
124
  if len(self.animStates) == 1:
112
125
  self.set_animState(name)
113
126
  return True
114
-
115
- def set_animState(self, state: str, reset_counter=True, lock=False)->bool:
127
+
128
+ def set_animState(self, state: str, reset_counter=True, lock=False) -> bool:
116
129
  if state not in self.animStates or self._locked:
117
130
  return False
118
131
 
119
132
  animState = self.animStates[state]
120
133
  self.current_state = animState
121
134
 
122
- self.rect = (self.current_state.frames[0].get_frect(center=self.rect.center))
123
-
135
+ self.rect = self.current_state.frames[0].get_frect(center=self.rect.center)
136
+
124
137
  if reset_counter or self.float_counter > sum(animState.duration_list):
125
138
  self.float_counter = 0
126
139
  if lock:
127
140
  self.lock()
128
141
  return True
129
142
 
130
- def get_animState(self)->AnimState|None:
143
+ def get_animState(self) -> AnimState | None:
131
144
  return self.current_state
132
145
 
133
- def update(self, dt: float)->None:
146
+ def update(self, dt: float) -> None:
134
147
  s = self.get_animState()
135
- if not self.animStates or s is None :
148
+ if not self.animStates or s is None:
136
149
  return
137
- if not self.paused :
150
+ if not self.paused:
138
151
  self.float_counter += 60 * dt
139
152
  if self.float_counter > s.duration_list_length:
140
153
  self.float_counter = 0
141
154
  self.do_update(dt)
142
155
 
143
156
  def draw(self, camera: bf.Camera) -> int:
144
- if not self.visible or not camera.intersects(self.rect) or not self.current_state:
157
+ if (
158
+ not self.visible
159
+ or not camera.rect.colliderect(self.rect)
160
+ or not self.current_state
161
+ ):
145
162
  return 0
146
163
  camera.surface.blit(
147
164
  self.current_state.get_frame(self.float_counter, self.flipX),
148
- camera.transpose(self.rect),
165
+ camera.world_to_screen(self.rect),
149
166
  )
150
167
  return 1