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.
- batFramework/__init__.py +23 -14
- batFramework/action.py +95 -106
- batFramework/actionContainer.py +11 -8
- batFramework/animatedSprite.py +60 -43
- batFramework/audioManager.py +52 -22
- batFramework/camera.py +87 -72
- batFramework/constants.py +19 -41
- batFramework/cutscene.py +12 -11
- batFramework/cutsceneBlocks.py +12 -14
- batFramework/dynamicEntity.py +5 -4
- batFramework/easingController.py +58 -0
- batFramework/entity.py +37 -130
- batFramework/enums.py +93 -3
- batFramework/fontManager.py +15 -7
- batFramework/gui/__init__.py +5 -1
- batFramework/gui/button.py +6 -144
- batFramework/gui/clickableWidget.py +206 -0
- batFramework/gui/constraints/__init__.py +1 -0
- batFramework/gui/constraints/constraints.py +378 -0
- batFramework/gui/container.py +147 -34
- batFramework/gui/debugger.py +39 -22
- batFramework/gui/dialogueBox.py +69 -43
- batFramework/gui/draggableWidget.py +38 -0
- batFramework/gui/image.py +33 -28
- batFramework/gui/indicator.py +30 -16
- batFramework/gui/interactiveWidget.py +72 -20
- batFramework/gui/label.py +240 -98
- batFramework/gui/layout.py +125 -53
- batFramework/gui/meter.py +76 -0
- batFramework/gui/radioButton.py +62 -0
- batFramework/gui/root.py +72 -48
- batFramework/gui/shape.py +257 -49
- batFramework/gui/slider.py +217 -2
- batFramework/gui/textInput.py +106 -60
- batFramework/gui/toggle.py +85 -42
- batFramework/gui/widget.py +259 -288
- batFramework/manager.py +30 -16
- batFramework/object.py +115 -0
- batFramework/{particles.py → particle.py} +37 -34
- batFramework/renderGroup.py +62 -0
- batFramework/resourceManager.py +36 -24
- batFramework/scene.py +94 -88
- batFramework/sceneManager.py +140 -57
- batFramework/scrollingSprite.py +113 -0
- batFramework/sprite.py +35 -23
- batFramework/tileset.py +34 -52
- batFramework/time.py +105 -56
- batFramework/transition.py +213 -1
- batFramework/utils.py +38 -18
- {batframework-1.0.6.dist-info → batframework-1.0.8a1.dist-info}/METADATA +1 -1
- batframework-1.0.8a1.dist-info/RECORD +56 -0
- {batframework-1.0.6.dist-info → batframework-1.0.8a1.dist-info}/WHEEL +1 -1
- batFramework/easing.py +0 -76
- batFramework/gui/constraints.py +0 -277
- batFramework/gui/frame.py +0 -25
- batFramework/transitionManager.py +0 -0
- batframework-1.0.6.dist-info/RECORD +0 -50
- {batframework-1.0.6.dist-info → batframework-1.0.8a1.dist-info}/LICENCE +0 -0
- {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
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
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
|
-
|
58
|
-
FontManager().
|
59
|
-
|
60
|
-
|
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.
|
16
|
-
self.
|
17
|
-
self.
|
18
|
-
self.
|
19
|
-
self.
|
20
|
-
self.
|
21
|
-
self.
|
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
|
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.
|
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.
|
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) ->
|
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) ->
|
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) ->
|
82
|
-
if not key in self._key_control
|
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) ->
|
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
|
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 =
|
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 ==
|
123
|
+
return self._type == actionType.CONTINUOUS
|
128
124
|
|
129
|
-
def set_instantaneous(self) ->
|
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 =
|
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 ==
|
143
|
+
return self._type == actionType.INSTANTANEOUS
|
148
144
|
|
149
|
-
def set_holding(self) ->
|
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 =
|
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 ==
|
162
|
+
return self._type == actionType.HOLDING
|
167
163
|
|
168
164
|
def process_update(self, event: pygame.Event) -> None:
|
169
165
|
if (
|
170
|
-
|
171
|
-
and
|
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 =
|
169
|
+
) or self._event_control:
|
170
|
+
self.data = event.dict
|
176
171
|
|
177
|
-
def process_activate(self, event: pygame.event.Event)
|
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.
|
189
|
-
|
190
|
-
|
191
|
-
|
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
|
-
|
194
|
-
self.
|
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
|
-
|
200
|
-
self.
|
201
|
-
|
202
|
-
|
203
|
-
return
|
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
|
-
|
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)
|
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 ==
|
212
|
+
if self._type == actionType.HOLDING:
|
218
213
|
if event.type == pygame.KEYUP and event.key in self._key_control:
|
219
|
-
|
220
|
-
|
221
|
-
|
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.
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
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
|
-
|
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)
|
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
|
-
|
254
|
-
|
239
|
+
|
240
|
+
if event.consumed : return
|
241
|
+
if not self.active:
|
242
|
+
self.process_activate(event)
|
255
243
|
else:
|
256
|
-
|
257
|
-
self.
|
258
|
-
|
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 {
|
253
|
+
if self._type in {actionType.CONTINUOUS, actionType.HOLDING}:
|
265
254
|
return
|
266
|
-
elif self._type ==
|
267
|
-
self.
|
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.
|
262
|
+
self.active = False
|
274
263
|
self._holding = set()
|
batFramework/actionContainer.py
CHANGED
@@ -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.
|
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
|
17
|
+
def add_actions(self, *actions: bf.Action):
|
15
18
|
for action in actions:
|
16
|
-
self._actions[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).
|
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
|
-
|
36
|
-
if
|
37
|
-
|
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()
|
batFramework/animatedSprite.py
CHANGED
@@ -13,27 +13,34 @@ def search_index(target, lst):
|
|
13
13
|
|
14
14
|
class AnimState:
|
15
15
|
def __init__(
|
16
|
-
self,
|
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] =
|
19
|
-
|
20
|
-
|
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] =
|
23
|
-
|
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
|
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(
|
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
|
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
|
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
|
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
|
-
|
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,
|
106
|
-
|
107
|
-
|
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,
|
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 =
|
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
|
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.
|
165
|
+
camera.world_to_screen(self.rect),
|
149
166
|
)
|
150
167
|
return 1
|