batframework 1.1.0__py3-none-any.whl → 2.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. batFramework/__init__.py +84 -51
  2. batFramework/action.py +280 -252
  3. batFramework/actionContainer.py +105 -38
  4. batFramework/animatedSprite.py +81 -117
  5. batFramework/animation.py +91 -0
  6. batFramework/audioManager.py +156 -85
  7. batFramework/baseScene.py +249 -0
  8. batFramework/camera.py +245 -123
  9. batFramework/constants.py +57 -75
  10. batFramework/cutscene.py +239 -119
  11. batFramework/cutsceneManager.py +34 -0
  12. batFramework/drawable.py +107 -0
  13. batFramework/dynamicEntity.py +30 -23
  14. batFramework/easingController.py +58 -0
  15. batFramework/entity.py +130 -123
  16. batFramework/enums.py +171 -0
  17. batFramework/fontManager.py +65 -0
  18. batFramework/gui/__init__.py +28 -14
  19. batFramework/gui/animatedLabel.py +90 -0
  20. batFramework/gui/button.py +18 -84
  21. batFramework/gui/clickableWidget.py +244 -0
  22. batFramework/gui/collapseContainer.py +98 -0
  23. batFramework/gui/constraints/__init__.py +1 -0
  24. batFramework/gui/constraints/constraints.py +1066 -0
  25. batFramework/gui/container.py +220 -49
  26. batFramework/gui/debugger.py +140 -47
  27. batFramework/gui/draggableWidget.py +63 -0
  28. batFramework/gui/image.py +61 -23
  29. batFramework/gui/indicator.py +116 -40
  30. batFramework/gui/interactiveWidget.py +243 -22
  31. batFramework/gui/label.py +147 -110
  32. batFramework/gui/layout.py +442 -81
  33. batFramework/gui/meter.py +155 -0
  34. batFramework/gui/radioButton.py +43 -0
  35. batFramework/gui/root.py +228 -60
  36. batFramework/gui/scrollingContainer.py +282 -0
  37. batFramework/gui/selector.py +232 -0
  38. batFramework/gui/shape.py +286 -86
  39. batFramework/gui/slider.py +353 -0
  40. batFramework/gui/style.py +10 -0
  41. batFramework/gui/styleManager.py +49 -0
  42. batFramework/gui/syncedVar.py +43 -0
  43. batFramework/gui/textInput.py +331 -0
  44. batFramework/gui/textWidget.py +308 -0
  45. batFramework/gui/toggle.py +140 -62
  46. batFramework/gui/tooltip.py +35 -0
  47. batFramework/gui/widget.py +546 -307
  48. batFramework/manager.py +131 -50
  49. batFramework/particle.py +118 -0
  50. batFramework/propertyEaser.py +79 -0
  51. batFramework/renderGroup.py +34 -0
  52. batFramework/resourceManager.py +130 -0
  53. batFramework/scene.py +31 -226
  54. batFramework/sceneLayer.py +134 -0
  55. batFramework/sceneManager.py +200 -165
  56. batFramework/scrollingSprite.py +115 -0
  57. batFramework/sprite.py +46 -0
  58. batFramework/stateMachine.py +49 -51
  59. batFramework/templates/__init__.py +2 -0
  60. batFramework/templates/character.py +15 -0
  61. batFramework/templates/controller.py +158 -0
  62. batFramework/templates/stateMachine.py +39 -0
  63. batFramework/tileset.py +46 -0
  64. batFramework/timeManager.py +213 -0
  65. batFramework/transition.py +162 -157
  66. batFramework/triggerZone.py +22 -22
  67. batFramework/utils.py +306 -184
  68. {batframework-1.1.0.dist-info → batframework-2.0.0.dist-info}/LICENSE +1 -1
  69. {batframework-1.1.0.dist-info → batframework-2.0.0.dist-info}/METADATA +8 -4
  70. batframework-2.0.0.dist-info/RECORD +72 -0
  71. batFramework/cutsceneBlocks.py +0 -176
  72. batFramework/debugger.py +0 -48
  73. batFramework/easing.py +0 -71
  74. batFramework/gui/constraints.py +0 -204
  75. batFramework/gui/frame.py +0 -19
  76. batFramework/particles.py +0 -77
  77. batFramework/time.py +0 -75
  78. batFramework/transitionManager.py +0 -0
  79. batframework-1.1.0.dist-info/RECORD +0 -43
  80. {batframework-1.1.0.dist-info → batframework-2.0.0.dist-info}/WHEEL +0 -0
  81. {batframework-1.1.0.dist-info → batframework-2.0.0.dist-info}/top_level.txt +0 -0
batFramework/cutscene.py CHANGED
@@ -1,119 +1,239 @@
1
- import batFramework as bf
2
-
3
-
4
- class CutsceneBlock:
5
- ...
6
-
7
-
8
- class Cutscene:
9
- ...
10
-
11
-
12
- class CutsceneManager(metaclass=bf.Singleton):
13
- def __init__(self, manager) -> None:
14
- self.current_cutscene: Cutscene = None
15
- self.cutscenes : list[bf.Cutscene] = []
16
- self.manager: bf.Manager = manager
17
-
18
- def get_flag(self, flag):
19
- return None
20
-
21
- def process_event(self, event):
22
- if self.current_cutscene:
23
- self.current_cutscene.process_event(event)
24
-
25
- def queue(self,*cutscenes):
26
- self.cutscenes.extend(cutscenes)
27
- if self.current_cutscene is None:
28
- self.play(self.cutscenes.pop(0))
29
-
30
- def play(self, cutscene: Cutscene):
31
- if self.current_cutscene is None:
32
- self.current_cutscene = cutscene
33
- self.current_cutscene.on_enter()
34
- self.current_cutscene.init_blocks()
35
- self.current_cutscene.play()
36
- self.manager.set_sharedVar("in_cutscene", True)
37
-
38
- def update(self, dt):
39
- if not self.current_cutscene is None:
40
- self.current_cutscene.update(dt)
41
- # print("cutscene manager update")
42
- if self.current_cutscene.has_ended():
43
- self.current_cutscene.on_exit()
44
- self.current_cutscene =None
45
- if self.cutscenes:
46
- self.play(self.cutscenes.pop(0))
47
- else:
48
- self.current_cutscene = None
49
- self.manager.set_sharedVar("in_cutscene", False)
50
-
51
- class Cutscene:
52
- def __init__(self,*blocks) -> None:
53
- self.cutscene_blocks: list[CutsceneBlock] = list(blocks)
54
- self.block_index = 0
55
- self.end_blocks : list[CutsceneBlock] = []
56
- self.ended = False
57
- def on_enter(self):
58
- pass
59
-
60
- def on_exit(self):
61
- pass
62
-
63
- def init_blocks(self):
64
- pass
65
-
66
- def add_end_block(self,block):
67
- block.set_parent_cutscene(self)
68
- self.end_blocks.append(block)
69
-
70
- def get_scene_at(self,index):
71
- return bf.CutsceneManager().manager._scenes[index]
72
-
73
- def get_current_scene(self):
74
- return bf.CutsceneManager().manager.get_current_scene()
75
-
76
- def set_scene(self,name,index=0):
77
- return bf.CutsceneManager().manager.set_scene(name,index)
78
-
79
- def get_scene(self,name):
80
- return bf.CutsceneManager().manager.get_scene(name)
81
-
82
- def add_block(self, *blocks: list[CutsceneBlock]):
83
- for block in blocks:
84
- block.set_parent_cutscene(self)
85
- self.cutscene_blocks.append(block)
86
-
87
- def process_event(self, event):
88
- if not self.ended and self.block_index < len(self.cutscene_blocks):
89
- self.cutscene_blocks[self.block_index].process_event(event)
90
-
91
- def play(self):
92
- self.block_index = 0
93
- if self.cutscene_blocks:
94
- self.cutscene_blocks[self.block_index].start()
95
- else:
96
- self.ended
97
-
98
- def update(self, dt):
99
- if self.ended:
100
- return
101
- # print("cutscene update",self.cutscene_blocks[self.block_index])
102
- self.cutscene_blocks[self.block_index].update(dt)
103
- if self.cutscene_blocks[self.block_index].has_ended():
104
- self.block_index += 1
105
- if self.block_index == len(self.cutscene_blocks):
106
- if not self.end_blocks:
107
- self.ended = True
108
- return
109
- else:
110
- self.cutscene_blocks.extend(self.end_blocks)
111
- self.end_blocks = []
112
- self.cutscene_blocks[self.block_index].start()
113
-
114
- # print("NEXT BLOCK")
115
-
116
- def has_ended(self):
117
- return self.ended
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
@@ -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
+ )
@@ -1,23 +1,30 @@
1
- import pygame
2
- import batFramework as bf
3
- from typing import Self
4
-
5
- class DynamicEntity(bf.Entity):
6
- def __init__(
7
- self,
8
- size : None|tuple[int,int]=None,
9
- no_surface : bool =False,
10
- surface_flags : int =0,
11
- convert_alpha : bool=False
12
- ) -> None:
13
- super().__init__(size,no_surface,surface_flags,convert_alpha)
14
- self.velocity = pygame.math.Vector2(0, 0)
15
-
16
- def on_collideX(self, collider: Self):
17
- return False
18
-
19
- def on_collideY(self, collider: Self):
20
- return False
21
-
22
- def move_by_velocity(self)->None:
23
- self.set_position(self.rect.x + self.velocity.x, self.rect.y + self.velocity.y)
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()