batframework 1.0.10__py3-none-any.whl → 2.0.0a1__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 +83 -52
- batFramework/action.py +280 -252
- batFramework/actionContainer.py +105 -38
- batFramework/animatedSprite.py +81 -117
- batFramework/animation.py +91 -0
- batFramework/audioManager.py +156 -85
- batFramework/baseScene.py +249 -0
- batFramework/camera.py +245 -123
- batFramework/constants.py +57 -75
- batFramework/cutscene.py +239 -119
- batFramework/cutsceneManager.py +34 -0
- batFramework/drawable.py +107 -0
- batFramework/dynamicEntity.py +30 -23
- batFramework/easingController.py +58 -0
- batFramework/entity.py +130 -123
- batFramework/enums.py +171 -0
- batFramework/fontManager.py +65 -0
- batFramework/gui/__init__.py +28 -14
- batFramework/gui/animatedLabel.py +90 -0
- batFramework/gui/button.py +18 -84
- batFramework/gui/clickableWidget.py +244 -0
- batFramework/gui/collapseContainer.py +98 -0
- batFramework/gui/constraints/__init__.py +1 -0
- batFramework/gui/constraints/constraints.py +1066 -0
- batFramework/gui/container.py +220 -49
- batFramework/gui/debugger.py +140 -47
- batFramework/gui/draggableWidget.py +63 -0
- batFramework/gui/image.py +61 -23
- batFramework/gui/indicator.py +116 -40
- batFramework/gui/interactiveWidget.py +243 -22
- batFramework/gui/label.py +147 -110
- batFramework/gui/layout.py +442 -81
- batFramework/gui/meter.py +155 -0
- batFramework/gui/radioButton.py +43 -0
- batFramework/gui/root.py +228 -60
- batFramework/gui/scrollingContainer.py +282 -0
- batFramework/gui/selector.py +232 -0
- batFramework/gui/shape.py +286 -86
- batFramework/gui/slider.py +353 -0
- batFramework/gui/style.py +10 -0
- batFramework/gui/styleManager.py +49 -0
- batFramework/gui/syncedVar.py +43 -0
- batFramework/gui/textInput.py +331 -0
- batFramework/gui/textWidget.py +308 -0
- batFramework/gui/toggle.py +140 -62
- batFramework/gui/tooltip.py +35 -0
- batFramework/gui/widget.py +546 -307
- batFramework/manager.py +131 -50
- batFramework/particle.py +118 -0
- batFramework/propertyEaser.py +79 -0
- batFramework/renderGroup.py +34 -0
- batFramework/resourceManager.py +130 -0
- batFramework/scene.py +31 -226
- batFramework/sceneLayer.py +134 -0
- batFramework/sceneManager.py +200 -165
- batFramework/scrollingSprite.py +115 -0
- batFramework/sprite.py +46 -0
- batFramework/stateMachine.py +49 -51
- batFramework/templates/__init__.py +2 -0
- batFramework/templates/character.py +15 -0
- batFramework/templates/controller.py +158 -0
- batFramework/templates/stateMachine.py +39 -0
- batFramework/tileset.py +46 -0
- batFramework/timeManager.py +213 -0
- batFramework/transition.py +162 -157
- batFramework/triggerZone.py +22 -22
- batFramework/utils.py +306 -184
- {batframework-1.0.10.dist-info → batframework-2.0.0a1.dist-info}/LICENSE +20 -20
- {batframework-1.0.10.dist-info → batframework-2.0.0a1.dist-info}/METADATA +2 -2
- batframework-2.0.0a1.dist-info/RECORD +72 -0
- batFramework/cutsceneBlocks.py +0 -176
- batFramework/debugger.py +0 -48
- batFramework/easing.py +0 -71
- batFramework/gui/constraints.py +0 -204
- batFramework/gui/frame.py +0 -19
- batFramework/particles.py +0 -77
- batFramework/time.py +0 -75
- batFramework/transitionManager.py +0 -0
- batframework-1.0.10.dist-info/RECORD +0 -43
- {batframework-1.0.10.dist-info → batframework-2.0.0a1.dist-info}/WHEEL +0 -0
- {batframework-1.0.10.dist-info → batframework-2.0.0a1.dist-info}/top_level.txt +0 -0
batFramework/cutscene.py
CHANGED
@@ -1,119 +1,239 @@
|
|
1
|
-
import batFramework as bf
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
self.
|
17
|
-
|
18
|
-
def
|
19
|
-
|
20
|
-
|
21
|
-
def
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
def
|
83
|
-
for
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
self.
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
1
|
+
import batFramework as bf
|
2
|
+
from .transition import Transition
|
3
|
+
from typing import Callable,Any
|
4
|
+
|
5
|
+
class Cutscene:
|
6
|
+
def __init__(self):
|
7
|
+
"""
|
8
|
+
Create a base Cutscene (ends immediately)
|
9
|
+
"""
|
10
|
+
|
11
|
+
def start(self):
|
12
|
+
"""
|
13
|
+
Called by the manager or the parent cutscene
|
14
|
+
Has to return to blank init state
|
15
|
+
"""
|
16
|
+
self.end()
|
17
|
+
|
18
|
+
def process_event(self,event):
|
19
|
+
pass
|
20
|
+
|
21
|
+
def update(self,dt):
|
22
|
+
pass
|
23
|
+
|
24
|
+
def __str__(self)->str:
|
25
|
+
return self.__class__.__name__
|
26
|
+
|
27
|
+
def end(self):
|
28
|
+
"""
|
29
|
+
Mark self as over
|
30
|
+
"""
|
31
|
+
print("Start ",self)
|
32
|
+
|
33
|
+
self.is_over = True
|
34
|
+
|
35
|
+
class Sequence(Cutscene):
|
36
|
+
def __init__(self,*cutscenes):
|
37
|
+
self.sub_cutscenes :list[Cutscene] = list(cutscenes)
|
38
|
+
self.index = 0
|
39
|
+
|
40
|
+
def start(self):
|
41
|
+
self.is_over = False
|
42
|
+
self.index = 0
|
43
|
+
if self.sub_cutscenes:
|
44
|
+
self.sub_cutscenes[0].start()
|
45
|
+
|
46
|
+
def process_event(self,event):
|
47
|
+
"""
|
48
|
+
propagate process event for current sub cutscene
|
49
|
+
"""
|
50
|
+
if self.index >0 and not self.is_over:
|
51
|
+
self.sub_cutscenes[self.index].process_event(event)
|
52
|
+
|
53
|
+
|
54
|
+
|
55
|
+
def update(self,dt):
|
56
|
+
"""
|
57
|
+
Update current sub cutscene (if any)
|
58
|
+
if current is over, start next one
|
59
|
+
if current was last, then end self
|
60
|
+
"""
|
61
|
+
if self.index < len(self.sub_cutscenes):
|
62
|
+
self.sub_cutscenes[self.index].update(dt)
|
63
|
+
if self.sub_cutscenes[self.index].is_over:
|
64
|
+
self.index += 1
|
65
|
+
if self.index == len(self.sub_cutscenes):
|
66
|
+
self.end()
|
67
|
+
return
|
68
|
+
self.sub_cutscenes[self.index].start()
|
69
|
+
|
70
|
+
|
71
|
+
class Parallel(Cutscene):
|
72
|
+
def __init__(self,*cutscenes:Cutscene):
|
73
|
+
self.sub_cutscenes : list[Cutscene] = list(cutscenes)
|
74
|
+
|
75
|
+
def start(self):
|
76
|
+
self.is_over = False
|
77
|
+
if not self.sub_cutscenes:
|
78
|
+
self.end()
|
79
|
+
for s in self.sub_cutscenes:
|
80
|
+
s.start()
|
81
|
+
|
82
|
+
def update(self,dt):
|
83
|
+
for s in self.sub_cutscenes:
|
84
|
+
s.update(dt)
|
85
|
+
if all(s.is_over for s in self.sub_cutscenes):
|
86
|
+
self.end()
|
87
|
+
|
88
|
+
class Wait(Cutscene):
|
89
|
+
def __init__(self,duration:float,scene_name:str="global"):
|
90
|
+
self.duration = duration
|
91
|
+
self.scene_name = scene_name
|
92
|
+
def start(self):
|
93
|
+
self.is_over = False
|
94
|
+
self.timer = bf.SceneTimer(duration=self.duration,end_callback=self.end,scene_name=self.scene_name)
|
95
|
+
self.timer.start()
|
96
|
+
|
97
|
+
|
98
|
+
|
99
|
+
class TransitionToScene(Cutscene):
|
100
|
+
def __init__(self,scene_name:str,transition:Transition):
|
101
|
+
self.scene_name = scene_name
|
102
|
+
self.transition: Transition = transition
|
103
|
+
|
104
|
+
def start(self):
|
105
|
+
self.is_over = False
|
106
|
+
bf.CutsceneManager().manager.transition_to_scene(self.scene_name,self.transition)
|
107
|
+
bf.Timer(self.transition.duration,end_callback=self.end).start()
|
108
|
+
|
109
|
+
|
110
|
+
|
111
|
+
|
112
|
+
|
113
|
+
|
114
|
+
class GlideWorldCameraFromTo(Cutscene):
|
115
|
+
def __init__(self,start:tuple[float,float], stop:tuple[float,float],duration:float=1,easing:bf.easing=bf.easing.EASE_IN_OUT,scene_name:str=None):
|
116
|
+
super().__init__()
|
117
|
+
self.scene = None
|
118
|
+
self.scene_name = scene_name
|
119
|
+
self.start_pos = start
|
120
|
+
self.stop_pos = stop
|
121
|
+
self.controller = bf.EasingController(duration,easing,update_callback=self.internal,end_callback=self.end)
|
122
|
+
|
123
|
+
|
124
|
+
def start(self):
|
125
|
+
self.is_over = False
|
126
|
+
if self.scene_name is None:
|
127
|
+
self.scene_name = bf.CutsceneManager().manager.get_scene_at(0).name
|
128
|
+
|
129
|
+
self.scene = bf.CutsceneManager().manager.get_scene(self.scene_name)
|
130
|
+
self.controller.start()
|
131
|
+
|
132
|
+
|
133
|
+
def internal(self,progression:float):
|
134
|
+
if not self.scene:
|
135
|
+
self.end()
|
136
|
+
return
|
137
|
+
self.scene.camera.set_center(
|
138
|
+
self.start_pos[0]+progression*(self.stop_pos[0]-self.start_pos[0]),
|
139
|
+
self.start_pos[1]+progression*(self.stop_pos[1]-self.start_pos[1])
|
140
|
+
)
|
141
|
+
|
142
|
+
def end(self):
|
143
|
+
if self.scene:
|
144
|
+
self.scene.camera.set_center(self.stop_pos[0],self.stop_pos[1])
|
145
|
+
|
146
|
+
super().end()
|
147
|
+
|
148
|
+
|
149
|
+
|
150
|
+
class Function(Cutscene):
|
151
|
+
def __init__(self, function:Callable[[],Any],*args,**kwargs):
|
152
|
+
super().__init__()
|
153
|
+
self.function:Callable[[],Any] = function
|
154
|
+
self.args = args
|
155
|
+
self.kwargs = kwargs
|
156
|
+
|
157
|
+
def start(self):
|
158
|
+
self.is_over = False
|
159
|
+
self.function(*self.args,**self.kwargs)
|
160
|
+
self.end()
|
161
|
+
|
162
|
+
class GlideCamera(Cutscene):
|
163
|
+
def __init__(
|
164
|
+
self,
|
165
|
+
start: tuple[float, float] | None,
|
166
|
+
stop: tuple[float, float] | None,
|
167
|
+
duration: float = 1,
|
168
|
+
easing: bf.easing = bf.easing.EASE_IN_OUT,
|
169
|
+
scene_name: str | None = None,
|
170
|
+
layer_name: str = "world",
|
171
|
+
):
|
172
|
+
"""
|
173
|
+
If start is None, it will be defaulted to the current camera center position.
|
174
|
+
Stop must be provided
|
175
|
+
"""
|
176
|
+
super().__init__()
|
177
|
+
self.scene = None
|
178
|
+
self.layer = None
|
179
|
+
self.scene_name = scene_name
|
180
|
+
self.layer_name = layer_name
|
181
|
+
self.start_pos = start
|
182
|
+
self.stop_pos = stop
|
183
|
+
self.controller = bf.EasingController(
|
184
|
+
duration, easing, update_callback=self.internal, end_callback=self.end
|
185
|
+
)
|
186
|
+
|
187
|
+
def start(self):
|
188
|
+
self.is_over = False
|
189
|
+
|
190
|
+
if self.scene_name is None:
|
191
|
+
self.scene_name = bf.CutsceneManager().manager.get_scene_at(0).name
|
192
|
+
|
193
|
+
self.scene = bf.CutsceneManager().manager.get_scene(self.scene_name)
|
194
|
+
self.layer = self.scene.get_layer(self.layer_name)
|
195
|
+
|
196
|
+
if not self.layer:
|
197
|
+
raise ValueError(f"Layer '{self.layer_name}' not found in scene '{self.scene_name}'.")
|
198
|
+
|
199
|
+
# Fallback to current camera position
|
200
|
+
if self.start_pos is None:
|
201
|
+
self.start_pos = self.layer.camera.get_center()
|
202
|
+
|
203
|
+
self.controller.start()
|
204
|
+
|
205
|
+
def internal(self, progression: float):
|
206
|
+
self.layer.camera.set_center(
|
207
|
+
self.start_pos[0] + progression * (self.stop_pos[0] - self.start_pos[0]),
|
208
|
+
self.start_pos[1] + progression * (self.stop_pos[1] - self.start_pos[1]),
|
209
|
+
)
|
210
|
+
|
211
|
+
def end(self):
|
212
|
+
if self.layer:
|
213
|
+
self.layer.camera.set_center(*self.stop_pos)
|
214
|
+
super().end()
|
215
|
+
|
216
|
+
|
217
|
+
|
218
|
+
class GlideCameraBy(GlideCamera):
|
219
|
+
def __init__(
|
220
|
+
self,
|
221
|
+
delta: tuple[float, float],
|
222
|
+
duration: float = 1,
|
223
|
+
easing: bf.easing = bf.easing.EASE_IN_OUT,
|
224
|
+
scene_name: str | None = None,
|
225
|
+
layer_name: str = "world",
|
226
|
+
):
|
227
|
+
stop_pos = (
|
228
|
+
start_pos[0] + self.delta[0],
|
229
|
+
start_pos[1] + self.delta[1],
|
230
|
+
)
|
231
|
+
super().__init__(
|
232
|
+
start=None,
|
233
|
+
stop=None,
|
234
|
+
delta=delta,
|
235
|
+
duration=duration,
|
236
|
+
easing=easing,
|
237
|
+
scene_name=scene_name,
|
238
|
+
layer_name=layer_name,
|
239
|
+
)
|
@@ -0,0 +1,34 @@
|
|
1
|
+
import batFramework as bf
|
2
|
+
from typing import TYPE_CHECKING,Self
|
3
|
+
import pygame
|
4
|
+
# if TYPE_CHECKING:
|
5
|
+
from .cutscene import Cutscene
|
6
|
+
|
7
|
+
|
8
|
+
class CutsceneManager(metaclass=bf.Singleton):
|
9
|
+
def __init__(self) -> None:
|
10
|
+
self.current_cutscene: Cutscene = None
|
11
|
+
self.manager: bf.Manager = None
|
12
|
+
self.is_playing : bool = False
|
13
|
+
def set_manager(self, manager):
|
14
|
+
self.manager = manager
|
15
|
+
|
16
|
+
def process_event(self, event):
|
17
|
+
if self.current_cutscene is not None:
|
18
|
+
self.current_cutscene.process_event(event)
|
19
|
+
if event.type in bf.enums.playerInput:
|
20
|
+
event.consumed = True
|
21
|
+
|
22
|
+
def play(self,cutscene:Cutscene):
|
23
|
+
if self.current_cutscene is not None:return
|
24
|
+
|
25
|
+
self.current_cutscene = cutscene
|
26
|
+
cutscene.start()
|
27
|
+
self.is_playing = True
|
28
|
+
|
29
|
+
def update(self,dt):
|
30
|
+
if self.current_cutscene:
|
31
|
+
self.current_cutscene.update(dt)
|
32
|
+
if self.current_cutscene.is_over:
|
33
|
+
self.current_cutscene = None
|
34
|
+
self.is_playing = False
|
batFramework/drawable.py
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
from typing import Any, Self
|
2
|
+
import pygame
|
3
|
+
import batFramework as bf
|
4
|
+
from .entity import Entity
|
5
|
+
|
6
|
+
|
7
|
+
class Drawable(Entity):
|
8
|
+
"""
|
9
|
+
Basic entity class
|
10
|
+
"""
|
11
|
+
|
12
|
+
def __init__(
|
13
|
+
self,
|
14
|
+
size: None | tuple[int|float] = None,
|
15
|
+
surface_flags: int = 0,
|
16
|
+
convert_alpha: bool = False,
|
17
|
+
*args,
|
18
|
+
**kwargs,
|
19
|
+
) -> None:
|
20
|
+
super().__init__()
|
21
|
+
self.visible: bool = True
|
22
|
+
self.render_order: int = 0
|
23
|
+
if size is not None:
|
24
|
+
self.rect.size = size
|
25
|
+
self.convert_alpha: bool = convert_alpha
|
26
|
+
self.surface_flags: int = surface_flags
|
27
|
+
self.blit_flags: int = 0
|
28
|
+
self.drawn_by_group : bool = False # flag for render group
|
29
|
+
self.surface: pygame.Surface = pygame.Surface(self.rect.size, surface_flags)
|
30
|
+
if convert_alpha:
|
31
|
+
self.surface = self.surface.convert_alpha()
|
32
|
+
self.surface.fill((0, 0, 0, 0))
|
33
|
+
|
34
|
+
def set_alpha(self, alpha: int) -> Self:
|
35
|
+
self.surface.set_alpha(min(max(0, alpha), 255))
|
36
|
+
return self
|
37
|
+
|
38
|
+
def get_alpha(self) -> int:
|
39
|
+
return self.surface.get_alpha()
|
40
|
+
|
41
|
+
def set_surface_flags(self, surface_flags: int) -> Self:
|
42
|
+
self.surface_flags = surface_flags
|
43
|
+
return self
|
44
|
+
|
45
|
+
def set_convert_alpha(self, value: bool) -> Self:
|
46
|
+
self.convert_alpha = value
|
47
|
+
return self
|
48
|
+
|
49
|
+
def set_blit_flags(self, blit_flags: int) -> Self:
|
50
|
+
self.blit_flags = blit_flags
|
51
|
+
return self
|
52
|
+
|
53
|
+
def get_debug_outlines(self):
|
54
|
+
if self.visible:
|
55
|
+
yield (self.rect, self.debug_color)
|
56
|
+
|
57
|
+
def set_render_order(self, render_order: int) -> Self:
|
58
|
+
self.render_order = render_order
|
59
|
+
if self.parent_layer:
|
60
|
+
self.parent_layer.update_draw_order()
|
61
|
+
return self
|
62
|
+
|
63
|
+
def set_visible(self, value: bool) -> Self:
|
64
|
+
self.visible = value
|
65
|
+
return self
|
66
|
+
|
67
|
+
def get_mask(self)->pygame.Mask:
|
68
|
+
return pygame.mask.from_surface(self.surface)
|
69
|
+
|
70
|
+
def mask_collide_point(self,point)->bool:
|
71
|
+
if not self.rect.collidepoint(point):
|
72
|
+
return False
|
73
|
+
mask = pygame.mask.from_surface(self.surface)
|
74
|
+
x = point[0]- self.rect.x
|
75
|
+
y = point[1] - self.rect.y
|
76
|
+
return mask.get_at((x,y))==1
|
77
|
+
|
78
|
+
|
79
|
+
|
80
|
+
|
81
|
+
def set_size(self, size: tuple[float, float]) -> Self:
|
82
|
+
"""
|
83
|
+
Will erase surface data and create new empty surface
|
84
|
+
"""
|
85
|
+
if size == self.rect.size:
|
86
|
+
return self
|
87
|
+
self.rect.size = size
|
88
|
+
self.surface = pygame.Surface(
|
89
|
+
(int(self.rect.w), int(self.rect.h)), self.surface_flags
|
90
|
+
)
|
91
|
+
if self.convert_alpha:
|
92
|
+
self.surface = self.surface.convert_alpha()
|
93
|
+
self.surface.fill((0, 0, 0, 0 if self.convert_alpha else 255))
|
94
|
+
|
95
|
+
return self
|
96
|
+
|
97
|
+
def draw(self, camera: bf.Camera) -> None:
|
98
|
+
"""
|
99
|
+
Draw the entity onto the camera surface
|
100
|
+
"""
|
101
|
+
if not self.visible or self.drawn_by_group or not camera.world_rect.colliderect(self.rect) or self.surface.get_alpha() == 0:
|
102
|
+
return
|
103
|
+
camera.surface.blit(
|
104
|
+
self.surface,
|
105
|
+
camera.world_to_screen(self.rect),
|
106
|
+
special_flags=self.blit_flags,
|
107
|
+
)
|
batFramework/dynamicEntity.py
CHANGED
@@ -1,23 +1,30 @@
|
|
1
|
-
import pygame
|
2
|
-
import batFramework as bf
|
3
|
-
from typing import Self
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
1
|
+
import pygame
|
2
|
+
import batFramework as bf
|
3
|
+
from typing import Self
|
4
|
+
|
5
|
+
|
6
|
+
class DynamicEntity(bf.Entity):
|
7
|
+
def __init__(
|
8
|
+
self,
|
9
|
+
*args,**kwargs
|
10
|
+
) -> None:
|
11
|
+
super().__init__(*args,**kwargs)
|
12
|
+
self.velocity = pygame.math.Vector2(0, 0)
|
13
|
+
self.ignore_collisions : bool = False
|
14
|
+
|
15
|
+
def on_collideX(self, collider: "DynamicEntity"):
|
16
|
+
"""
|
17
|
+
Return true if collision
|
18
|
+
"""
|
19
|
+
return False
|
20
|
+
|
21
|
+
def on_collideY(self, collider: "DynamicEntity"):
|
22
|
+
"""
|
23
|
+
Return true if collision
|
24
|
+
"""
|
25
|
+
return False
|
26
|
+
|
27
|
+
def move_by_velocity(self, dt) -> None:
|
28
|
+
self.set_position(
|
29
|
+
self.rect.x + self.velocity.x * dt, self.rect.y + self.velocity.y * dt
|
30
|
+
)
|
@@ -0,0 +1,58 @@
|
|
1
|
+
import pygame
|
2
|
+
import batFramework as bf
|
3
|
+
from functools import lru_cache
|
4
|
+
from typing import Callable,Any
|
5
|
+
|
6
|
+
|
7
|
+
@lru_cache(maxsize=None)
|
8
|
+
def process_value(progress: float, p0: float, p1: float, p2: float, p3: float) -> float:
|
9
|
+
if p0 == 0 and p1 == 0 and p2 == 1 and p3 == 1: # Linear easing control points
|
10
|
+
return progress
|
11
|
+
t = progress
|
12
|
+
t_inv = 1.0 - t
|
13
|
+
t2 = t * t
|
14
|
+
t3 = t * t2
|
15
|
+
t_inv2 = t_inv * t_inv
|
16
|
+
return 3 * t_inv2 * t * p1 + 3 * t_inv * t2 * p3 + t3
|
17
|
+
|
18
|
+
|
19
|
+
class EasingController(bf.Timer):
|
20
|
+
def __init__(
|
21
|
+
self,
|
22
|
+
duration: float = 1,
|
23
|
+
easing: bf.easing = bf.easing.LINEAR,
|
24
|
+
update_callback=None,
|
25
|
+
end_callback: Callable[[], Any] = None,
|
26
|
+
loop: int = 0,
|
27
|
+
register:str="global"
|
28
|
+
) -> None:
|
29
|
+
self.easing_function = easing
|
30
|
+
self.update_callback: Callable[[float], Any] = update_callback
|
31
|
+
self.value: float = 0.0
|
32
|
+
super().__init__(duration, end_callback, loop, register)
|
33
|
+
|
34
|
+
def get_value(self) -> float:
|
35
|
+
return self.value
|
36
|
+
|
37
|
+
def start(self, force: bool = False):
|
38
|
+
super().start(force)
|
39
|
+
self.value = 0
|
40
|
+
|
41
|
+
def update(self, dt: float) -> None:
|
42
|
+
if self.get_progression() == 1:
|
43
|
+
return
|
44
|
+
super().update(dt)
|
45
|
+
if self.get_progression() == 0:
|
46
|
+
return
|
47
|
+
if self.easing_function == bf.easing.LINEAR: # avoid calculating if linear (just use progression as is)
|
48
|
+
self.value = self.get_progression()
|
49
|
+
else:
|
50
|
+
self.value = process_value(self.get_progression(), *self.easing_function.control_points)
|
51
|
+
|
52
|
+
if self.update_callback:
|
53
|
+
self.update_callback(self.value)
|
54
|
+
|
55
|
+
def end(self):
|
56
|
+
if self.update_callback:
|
57
|
+
self.update_callback(1)
|
58
|
+
super().end()
|