batframework 0.1.13__py3-none-any.whl → 1.0.1__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 (47) hide show
  1. batFramework/__init__.py +41 -46
  2. batFramework/action.py +42 -20
  3. batFramework/actionContainer.py +43 -4
  4. batFramework/animatedSprite.py +26 -20
  5. batFramework/camera.py +177 -47
  6. batFramework/constants.py +26 -51
  7. batFramework/cutscene.py +15 -15
  8. batFramework/cutsceneBlocks.py +11 -9
  9. batFramework/dynamicEntity.py +7 -6
  10. batFramework/easing.py +28 -23
  11. batFramework/entity.py +87 -49
  12. batFramework/enums.py +14 -0
  13. batFramework/fontManager.py +57 -0
  14. batFramework/gui/__init__.py +2 -2
  15. batFramework/gui/button.py +82 -31
  16. batFramework/gui/constraints.py +137 -104
  17. batFramework/gui/container.py +27 -28
  18. batFramework/gui/debugger.py +92 -42
  19. batFramework/gui/frame.py +15 -15
  20. batFramework/gui/image.py +37 -17
  21. batFramework/gui/indicator.py +18 -14
  22. batFramework/gui/interactiveWidget.py +11 -10
  23. batFramework/gui/label.py +60 -56
  24. batFramework/gui/layout.py +50 -47
  25. batFramework/gui/root.py +43 -30
  26. batFramework/gui/shape.py +34 -41
  27. batFramework/gui/slider.py +5 -0
  28. batFramework/gui/toggle.py +31 -27
  29. batFramework/gui/widget.py +148 -128
  30. batFramework/manager.py +18 -13
  31. batFramework/particles.py +16 -13
  32. batFramework/resourceManager.py +55 -0
  33. batFramework/scene.py +141 -83
  34. batFramework/sceneManager.py +21 -16
  35. batFramework/sprite.py +31 -0
  36. batFramework/stateMachine.py +1 -0
  37. batFramework/tileset.py +7 -9
  38. batFramework/time.py +61 -50
  39. batFramework/transition.py +20 -12
  40. batFramework/utils.py +2 -65
  41. batframework-1.0.1.dist-info/LICENCE +21 -0
  42. {batframework-0.1.13.dist-info → batframework-1.0.1.dist-info}/METADATA +3 -2
  43. batframework-1.0.1.dist-info/RECORD +48 -0
  44. {batframework-0.1.13.dist-info → batframework-1.0.1.dist-info}/WHEEL +1 -1
  45. batFramework/debugger.py +0 -48
  46. batframework-0.1.13.dist-info/RECORD +0 -43
  47. {batframework-0.1.13.dist-info → batframework-1.0.1.dist-info}/top_level.txt +0 -0
batFramework/camera.py CHANGED
@@ -1,95 +1,199 @@
1
- import batFramework as bf
2
1
  import pygame
3
2
  from pygame.math import Vector2
3
+ import math
4
+ import batFramework as bf
4
5
 
5
6
 
6
7
  class Camera:
7
- def __init__(self, flags=0) -> None:
8
- self.rect = pygame.FRect(0, 0, *bf.const.RESOLUTION)
8
+ _transform_cache = {} # Cache for transformed surfaces
9
+
10
+ def __init__(self, flags=0, size: tuple[int,int] | None = None,convert_alpha:bool=False) -> None:
11
+ """
12
+ Initialize the Camera object.
13
+
14
+ Args:
15
+ flags (int): Flags for camera initialization.
16
+ size (tuple): Optional size for camera (defaults to window size)
17
+ """
18
+ # Initialize camera attributes
19
+ size = size if size else bf.const.RESOLUTION
20
+ self.rect = pygame.Rect(0, 0, *size)
9
21
  self.flags: int = flags
10
- # self.blit_special_flags : int =pygame.BLEND_PREMULTIPLIED if (flags & pygame.SRCALPHA) else 0
11
22
  self.blit_special_flags: int = pygame.BLEND_ALPHA_SDL2
12
- self._clear_color : pygame.Color = pygame.Color(0, 0, 0, 0)
23
+ self._clear_color: pygame.Color = pygame.Color(0, 0, 0, 0)
13
24
  self.zoom_factor = 1
14
25
  self.cached_surfaces: dict[float, pygame.Surface] = {}
15
- self.surface: pygame.Surface = pygame.Surface((0,0))
26
+ self.surface: pygame.Surface = pygame.Surface((0, 0))
27
+ if convert_alpha :
28
+ self.surface = self.surface.convert_alpha()
29
+ else:
30
+ self.surface = self.surface.convert()
16
31
  self.follow_point_func = None
17
32
  self.max_zoom = 2
18
33
  self.min_zoom = 0.1
19
34
  self.zoom(1)
20
35
 
21
- def set_clear_color(self, color: pygame.Color|tuple):
22
- if not isinstance(color,pygame.Color):
36
+ def set_clear_color(self, color: pygame.Color | tuple | str) -> "Camera":
37
+ """
38
+ Set the clear color for the camera surface.
39
+
40
+ Args:
41
+ color (pygame.Color | tuple): Color to set as the clear color.
42
+
43
+ Returns:
44
+ Camera: Returns the Camera object.
45
+ """
46
+ if not isinstance(color, pygame.Color):
23
47
  color = pygame.Color(color)
24
48
  self._clear_color = color
49
+ return self
50
+
51
+ def set_max_zoom(self, value: float) -> "Camera":
52
+ """
53
+ Set the maximum zoom value for the camera.
25
54
 
26
- def set_max_zoom(self,value:float):
55
+ Args:
56
+ value (float): Maximum zoom value.
57
+
58
+ Returns:
59
+ Camera: Returns the Camera object.
60
+ """
27
61
  self.max_zoom = value
62
+ return self
63
+
64
+ def set_min_zoom(self, value: float) -> "Camera":
65
+ """
66
+ Set the minimum zoom value for the camera.
28
67
 
29
- def set_min_zoom(self,value:float):
68
+ Args:
69
+ value (float): Minimum zoom value.
70
+
71
+ Returns:
72
+ Camera: Returns the Camera object.
73
+ """
30
74
  self.min_zoom = value
75
+ return self
31
76
 
32
- def clear(self):
77
+ def clear(self) -> None:
33
78
  """
34
- Clear the camera surface with the set clear color
35
- (default is tranparent)
79
+ Clear the camera surface with the set clear color.
36
80
  """
37
81
  self.surface.fill(self._clear_color)
38
82
 
39
- def get_center(self):
40
- return self.rect.center
83
+ def get_center(self) -> tuple[float,float]:
84
+ """
85
+ Get the center of the camera's view.
41
86
 
42
-
87
+ Returns:
88
+ Vector2: Returns the center coordinates.
89
+ """
90
+ return self.rect.center
43
91
 
44
- def move(self, x, y):
92
+ def move(self, x, y) -> "Camera":
45
93
  """
46
- Moves the camera rect by the given coordinates (+=)
94
+ Moves the camera rect by the given coordinates.
95
+
96
+ Args:
97
+ x: X-coordinate to move.
98
+ y: Y-coordinate to move.
99
+
100
+ Returns:
101
+ Camera: Returns the Camera object.
47
102
  """
48
103
  self.rect.topleft += Vector2(x, y)
104
+ return self
49
105
 
50
- def set_position(self, x, y):
106
+ def set_position(self, x, y) -> "Camera":
51
107
  """
52
- Set the camera rect topleft position
108
+ Set the camera rect top-left position.
109
+
110
+ Args:
111
+ x: X-coordinate to set.
112
+ y: Y-coordinate to set.
113
+
114
+ Returns:
115
+ Camera: Returns the Camera object.
53
116
  """
54
117
  self.rect.topleft = (x, y)
118
+ return self
55
119
 
56
- def set_center(self, x, y):
120
+ def set_center(self, x, y) -> "Camera":
57
121
  """
58
- Set the camera rect center position
122
+ Set the camera rect center position.
123
+
124
+ Args:
125
+ x: X-coordinate for the center.
126
+ y: Y-coordinate for the center.
127
+
128
+ Returns:
129
+ Camera: Returns the Camera object.
59
130
  """
60
131
  self.rect.center = (x, y)
132
+ return self
61
133
 
62
- def set_follow_dynamic_point(self, func):
134
+ def set_follow_point(self, func) -> "Camera":
63
135
  """
64
- Set the following function (returns tuple x y)
65
- (camera will center its position to the center of the given coordinates)
136
+ Set the following function (returns tuple x y).
137
+ Camera will center its position to the center of the given coordinates.
138
+
139
+ Args:
140
+ func: Function returning coordinates to follow.
141
+
142
+ Returns:
143
+ Camera: Returns the Camera object.
66
144
  """
67
145
  self.follow_point_func = func
146
+ return self
147
+
148
+ def zoom_by(self, amount: float) -> "Camera":
149
+ """
150
+ Zooms the camera by the given amount.
68
151
 
69
- def zoom_by(self, amount:float):
152
+ Args:
153
+ amount (float): Amount to zoom.
154
+
155
+ Returns:
156
+ Camera: Returns the Camera object.
157
+ """
70
158
  self.zoom(self.zoom_factor + amount)
159
+ return self
71
160
 
72
- def zoom(self, factor):
73
- if factor <self.min_zoom:
74
- return
75
- if factor > self.max_zoom:
76
- return
77
- factor = round(factor,2)
161
+ def zoom(self, factor) -> "Camera":
162
+ """
163
+ Zooms the camera to the given factor.
164
+
165
+ Args:
166
+ factor: Factor to set for zooming.
167
+
168
+ Returns:
169
+ Camera: Returns the Camera object.
170
+ """
171
+ if factor < self.min_zoom or factor > self.max_zoom:
172
+ return self
173
+
174
+ factor = round(factor, 2)
78
175
  self.zoom_factor = factor
176
+
79
177
  if factor not in self.cached_surfaces:
80
- # if factor != 1 : print("creating new surface in cache : ",tuple(i * factor for i in const.RESOLUTION), self.flags)
81
178
  self.cached_surfaces[factor] = pygame.Surface(
82
179
  tuple(i / factor for i in bf.const.RESOLUTION), flags=self.flags
83
180
  ).convert_alpha()
84
- # c = self.surface.get_colorkey() if self.surface else None
85
- # if c : self.cached_surfaces[factor].set_colorkey(c)
86
181
  self.cached_surfaces[factor].fill((0, 0, 0, 0))
87
182
 
88
183
  self.surface = self.cached_surfaces[self.zoom_factor]
89
- self.rect = self.surface.get_frect(center=self.rect.center)
90
- # if factor != 1 : print(self.cached_surfaces)
184
+ self.rect = self.surface.get_rect(center=self.rect.center)
185
+ return self
91
186
 
92
187
  def intersects(self, rect: pygame.Rect | pygame.FRect) -> bool:
188
+ """
189
+ Check if the camera view intersects with the given rectangle.
190
+
191
+ Args:
192
+ rect (pygame.Rect | pygame.FRect): Rectangle to check intersection with.
193
+
194
+ Returns:
195
+ bool: True if intersection occurs, False otherwise.
196
+ """
93
197
  return (
94
198
  self.rect.x < rect.right
95
199
  and self.rect.right > rect.x
@@ -97,27 +201,53 @@ class Camera:
97
201
  and self.rect.bottom > rect.y
98
202
  )
99
203
 
100
-
101
204
  def transpose(self, rect: pygame.Rect | pygame.FRect) -> pygame.Rect | pygame.FRect:
102
- x, y = round(rect.x - self.rect.left), round(rect.y - self.rect.top)
103
- return pygame.Rect(x, y, *rect.size)
205
+ """
206
+ Transpose the given rectangle coordinates relative to the camera.
207
+
208
+ Args:
209
+ rect (pygame.Rect | pygame.FRect): Rectangle to transpose.
210
+
211
+ Returns:
212
+ pygame.FRect: Transposed rectangle.
213
+ """
214
+ return pygame.FRect(rect.x - self.rect.left, rect.y - self.rect.top, *rect.size)
104
215
 
105
216
  def convert_screen_to_world(self, x, y):
217
+ """
218
+ Convert screen coordinates to world coordinates based on camera settings.
219
+
220
+ Args:
221
+ x: X-coordinate in screen space.
222
+ y: Y-coordinate in screen space.
223
+
224
+ Returns:
225
+ tuple: Converted world coordinates.
226
+ """
106
227
  return x / self.zoom_factor + self.rect.x, y / self.zoom_factor + self.rect.y
107
228
 
108
229
  def update(self, dt):
230
+ """
231
+ Update the camera position based on the follow point function.
232
+
233
+ Args:
234
+ dt: Time delta for updating the camera position.
235
+ """
109
236
  if self.follow_point_func:
110
237
  target = self.follow_point_func()
111
238
  self.rect.center = Vector2(self.rect.center).lerp(target, ((dt * 60) * 0.1))
112
239
 
113
240
  def draw(self, surface: pygame.Surface):
114
- # pygame.draw.circle(surface,bf.color.ORANGE,self.surface.get_rect().center,4)
241
+ """
242
+ Draw the camera view onto the provided surface with proper scaling.
243
+
244
+ Args:
245
+ surface (pygame.Surface): Surface to draw the camera view onto.
246
+ """
115
247
  if self.zoom_factor == 1:
116
248
  surface.blit(self.surface, (0, 0), special_flags=self.blit_special_flags)
117
249
  return
118
- # print("From",self.surface,"Target RESOLUTION",const.RESOLUTION,"Destination",surface)
119
- surface.blit(
120
- pygame.transform.scale(self.surface, bf.const.RESOLUTION),
121
- (0, 0),
122
- special_flags=self.blit_special_flags,
123
- )
250
+
251
+ # Scale the surface to match the resolution
252
+ scaled_surface = pygame.transform.scale(self.surface, bf.const.RESOLUTION)
253
+ surface.blit(scaled_surface, (0, 0), special_flags=self.blit_special_flags)
batFramework/constants.py CHANGED
@@ -3,60 +3,14 @@ from enum import Enum
3
3
  import sys, os
4
4
 
5
5
 
6
- if getattr(sys, 'frozen', False):
6
+ if getattr(sys, "frozen", False):
7
7
  # If the application is run as a bundle, the PyInstaller bootloader
8
- # extends the sys module by a flag frozen=True and sets the app
8
+ # extends the sys module by a flag frozen=True and sets the app
9
9
  # path into variable _MEIPASS'.
10
10
  application_path = sys._MEIPASS
11
11
  else:
12
12
  application_path = os.getcwd()
13
13
 
14
- class Constants:
15
- SCREEN = None
16
- RESOLUTION: tuple[int, int] = (1280,720)
17
- VSYNC = 0
18
- FLAGS: int = pygame.SCALED | pygame.RESIZABLE
19
- FPS: int = 60
20
- RESOURCE_PATH = "."
21
-
22
- @staticmethod
23
- def init_screen(resolution:tuple[int,int],flags:int= 0, vsync:int= 0):
24
- Constants.RESOLUTION = resolution
25
- Constants.FLAGS = flags
26
- Constants.VSYNC = vsync
27
- Constants.SCREEN = pygame.display.set_mode(Constants.RESOLUTION, Constants.FLAGS,vsync=Constants.VSYNC)
28
- print(f"Window : {resolution[0]}x{resolution[1]}px | flags:{flags.bit_count()}, vsync:{pygame.display.is_vsync()}")
29
- MUSIC_END_EVENT = pygame.event.custom_type()
30
-
31
- # ------------GUI SPECIFIC
32
- DEFAULT_TEXT_SIZE: int = 8
33
-
34
- GUI_SCALE: int = 1
35
- # ---------------------
36
-
37
- @staticmethod
38
- def set_resolution(resolution : tuple[int,int]):
39
- Constants.RESOLUTION = resolution
40
-
41
- @staticmethod
42
- def set_resource_path(path: str):
43
- print("set resource path :", path)
44
- Constants.RESOURCE_PATH = os.path.join(application_path,path)
45
-
46
- @staticmethod
47
- def set_fps_limit(value: int):
48
- Constants.FPS = value
49
- print("FPS limit to : ", value)
50
-
51
- @staticmethod
52
- def set_gui_scale(value: int):
53
- Constants.GUI_SCALE = value
54
- print("GUI_SCALE to : ", value)
55
-
56
- @staticmethod
57
- def set_default_text_size(size:int):
58
- Constants.DEFAULT_TEXT_SIZE = size
59
-
60
14
  class Colors:
61
15
  LIGHT_CYAN = (179, 229, 252)
62
16
  WASHED_BLUE = (52, 73, 94)
@@ -65,11 +19,15 @@ class Colors:
65
19
  LIGHT_BLUE = (3, 169, 244)
66
20
  DEEP_BLUE = (41, 121, 255)
67
21
  DARK_BLUE = (44, 62, 80)
22
+
68
23
  GREEN = (67, 160, 71)
69
24
  DARK_GREEN = (39, 174, 96)
25
+
70
26
  BROWN = (109, 76, 65)
71
27
  DARK_RED = (192, 57, 43)
28
+
72
29
  ORANGE = (251, 140, 0)
30
+
73
31
  CLOUD_WHITE = (236, 240, 241)
74
32
  SILVER = (189, 195, 199)
75
33
  DARK_GRAY = (66, 66, 66)
@@ -79,6 +37,23 @@ class Colors:
79
37
  BASE_GB = (73, 107, 34)
80
38
  LIGHT_GB = (154, 158, 63)
81
39
 
82
- class Axis(Enum):
83
- HORIZONTAL = 1
84
- VERTICAL = 2
40
+
41
+
42
+ class Constants:
43
+ SCREEN = None
44
+ RESOLUTION: tuple[int, int] = (1280, 720)
45
+ VSYNC = 0
46
+ FLAGS: int = pygame.SCALED | pygame.RESIZABLE
47
+ FPS: int = 60
48
+ MUSIC_END_EVENT = pygame.event.custom_type()
49
+
50
+ BF_INITIALIZED : bool = False
51
+ @staticmethod
52
+ def set_resolution(resolution: tuple[int, int]):
53
+ Constants.RESOLUTION = resolution
54
+
55
+ @staticmethod
56
+ def set_fps_limit(value: int):
57
+ Constants.FPS = value
58
+ print("FPS limit to : ", value)
59
+
batFramework/cutscene.py CHANGED
@@ -12,7 +12,7 @@ class Cutscene:
12
12
  class CutsceneManager(metaclass=bf.Singleton):
13
13
  def __init__(self, manager) -> None:
14
14
  self.current_cutscene: Cutscene = None
15
- self.cutscenes : list[bf.Cutscene] = []
15
+ self.cutscenes: list[bf.Cutscene] = []
16
16
  self.manager: bf.Manager = manager
17
17
 
18
18
  def get_flag(self, flag):
@@ -22,11 +22,11 @@ class CutsceneManager(metaclass=bf.Singleton):
22
22
  if self.current_cutscene:
23
23
  self.current_cutscene.process_event(event)
24
24
 
25
- def queue(self,*cutscenes):
25
+ def queue(self, *cutscenes):
26
26
  self.cutscenes.extend(cutscenes)
27
27
  if self.current_cutscene is None:
28
28
  self.play(self.cutscenes.pop(0))
29
-
29
+
30
30
  def play(self, cutscene: Cutscene):
31
31
  if self.current_cutscene is None:
32
32
  self.current_cutscene = cutscene
@@ -41,19 +41,21 @@ class CutsceneManager(metaclass=bf.Singleton):
41
41
  # print("cutscene manager update")
42
42
  if self.current_cutscene.has_ended():
43
43
  self.current_cutscene.on_exit()
44
- self.current_cutscene =None
44
+ self.current_cutscene = None
45
45
  if self.cutscenes:
46
46
  self.play(self.cutscenes.pop(0))
47
47
  else:
48
48
  self.current_cutscene = None
49
49
  self.manager.set_sharedVar("in_cutscene", False)
50
50
 
51
+
51
52
  class Cutscene:
52
- def __init__(self,*blocks) -> None:
53
+ def __init__(self, *blocks) -> None:
53
54
  self.cutscene_blocks: list[CutsceneBlock] = list(blocks)
54
55
  self.block_index = 0
55
- self.end_blocks : list[CutsceneBlock] = []
56
+ self.end_blocks: list[CutsceneBlock] = []
56
57
  self.ended = False
58
+
57
59
  def on_enter(self):
58
60
  pass
59
61
 
@@ -63,22 +65,22 @@ class Cutscene:
63
65
  def init_blocks(self):
64
66
  pass
65
67
 
66
- def add_end_block(self,block):
68
+ def add_end_block(self, block):
67
69
  block.set_parent_cutscene(self)
68
70
  self.end_blocks.append(block)
69
71
 
70
- def get_scene_at(self,index):
72
+ def get_scene_at(self, index):
71
73
  return bf.CutsceneManager().manager._scenes[index]
72
74
 
73
75
  def get_current_scene(self):
74
76
  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
77
 
79
- def get_scene(self,name):
78
+ def set_scene(self, name, index=0):
79
+ return bf.CutsceneManager().manager.set_scene(name, index)
80
+
81
+ def get_scene(self, name):
80
82
  return bf.CutsceneManager().manager.get_scene(name)
81
-
83
+
82
84
  def add_block(self, *blocks: list[CutsceneBlock]):
83
85
  for block in blocks:
84
86
  block.set_parent_cutscene(self)
@@ -115,5 +117,3 @@ class Cutscene:
115
117
 
116
118
  def has_ended(self):
117
119
  return self.ended
118
-
119
-
@@ -1,5 +1,5 @@
1
1
  import batFramework as bf
2
- from .cutscene import Cutscene,CutsceneManager
2
+ from .cutscene import Cutscene, CutsceneManager
3
3
 
4
4
 
5
5
  # Define the base CutsceneBlock class
@@ -17,18 +17,18 @@ class CutsceneBlock:
17
17
  self.ended = False
18
18
  self.started = False
19
19
 
20
- def get_scene_at(self,index):
20
+ def get_scene_at(self, index):
21
21
  return bf.CutsceneManager().manager._scenes[index]
22
22
 
23
- def set_scene(self,name,index=0):
24
- return CutsceneManager().manager.set_scene(name,index)
25
-
23
+ def set_scene(self, name, index=0):
24
+ return CutsceneManager().manager.set_scene(name, index)
25
+
26
26
  def get_current_scene(self):
27
27
  return CutsceneManager().manager.get_current_scene()
28
-
29
- def get_scene(self,name):
28
+
29
+ def get_scene(self, name):
30
30
  return CutsceneManager().manager.get_scene(name)
31
-
31
+
32
32
  # Set the parent cutscene for this block
33
33
  def set_parent_cutscene(self, parent):
34
34
  """
@@ -152,7 +152,9 @@ class SceneTransitionBlock(CutsceneBlock):
152
152
  self.duration = duration
153
153
  self.kwargs = kwargs
154
154
  # Timer to handle the end of the transition
155
- self.timer = bf.Timer(name = "scene_transition_block",duration=duration, end_callback=self.end)
155
+ self.timer = bf.Timer(
156
+ name="scene_transition_block", duration=duration, end_callback=self.end
157
+ )
156
158
 
157
159
  # Start the scene transition block
158
160
  def start(self):
@@ -2,15 +2,16 @@ import pygame
2
2
  import batFramework as bf
3
3
  from typing import Self
4
4
 
5
+
5
6
  class DynamicEntity(bf.Entity):
6
7
  def __init__(
7
8
  self,
8
- size : None|tuple[int,int]=None,
9
- no_surface : bool =False,
10
- surface_flags : int =0,
11
- convert_alpha : bool=False
9
+ size: None | tuple[int, int] = None,
10
+ no_surface: bool = False,
11
+ surface_flags: int = 0,
12
+ convert_alpha: bool = False,
12
13
  ) -> None:
13
- super().__init__(size,no_surface,surface_flags,convert_alpha)
14
+ super().__init__(size, no_surface, surface_flags, convert_alpha)
14
15
  self.velocity = pygame.math.Vector2(0, 0)
15
16
 
16
17
  def on_collideX(self, collider: Self):
@@ -19,5 +20,5 @@ class DynamicEntity(bf.Entity):
19
20
  def on_collideY(self, collider: Self):
20
21
  return False
21
22
 
22
- def move_by_velocity(self)->None:
23
+ def move_by_velocity(self) -> None:
23
24
  self.set_position(self.rect.x + self.velocity.x, self.rect.y + self.velocity.y)
batFramework/easing.py CHANGED
@@ -2,47 +2,51 @@ from enum import Enum
2
2
  import pygame
3
3
  import batFramework as bf
4
4
 
5
+
5
6
  class Easing(Enum):
6
- EASE_IN = (0.12, 0, 0.39, 0)
7
- EASE_OUT = (0.61, 1, 0.88, 1)
7
+ EASE_IN = (0.12, 0, 0.39, 0)
8
+ EASE_OUT = (0.61, 1, 0.88, 1)
8
9
  EASE_IN_OUT = (0.37, 0, 0.63, 1)
9
- EASE_IN_OUT_ELASTIC = (.7,-0.5,.3,1.5)
10
- LINEAR = (1, 1, 0, 0)
10
+ EASE_IN_OUT_ELASTIC = (0.7, -0.5, 0.3, 1.5)
11
+ LINEAR = (1, 1, 0, 0)
11
12
  # Add more easing functions as needed
12
13
 
13
14
  def __init__(self, *control_points):
14
15
  self.control_points = control_points
15
16
 
17
+
16
18
  class EasingAnimation(bf.Timer):
17
19
  _cache = {}
20
+
18
21
  def __init__(
19
22
  self,
20
- name:str=None,
21
- easing_function:Easing=Easing.LINEAR,
22
- duration:int=100,
23
+ name: str = '',
24
+ easing_function: Easing = Easing.LINEAR,
25
+ duration: int = 100,
23
26
  update_callback=None,
24
27
  end_callback=None,
25
- loop:bool=False,
26
- reusable:bool=False
27
- ):
28
+ loop: bool = False,
29
+ reusable: bool = False,
30
+ )->None:
28
31
  self.easing_function = easing_function
29
32
  self.update_callback = update_callback
30
33
  self.value = 0.0
31
- super().__init__(name,duration,loop,end_callback,reusable)
32
-
34
+ super().__init__(name, duration, loop, end_callback, reusable)
35
+
33
36
  def get_value(self):
34
37
  return self.value
35
38
 
36
39
  def start(self):
37
- self.value = 0
38
- super().start() # self.elapsed_progress set to 0 here
39
-
40
- def update(self)->bool:
41
- if super().update():
42
- return True# If timer ended now, end() is called. So don't process value.
40
+ self.value = 0
41
+ super().start() # self.elapsed_progress set to 0 here
42
+
43
+ def update(self,dt) -> bool:
44
+ if super().update(dt):
45
+ return True # If timer ended now, end() is called. So don't process value.
43
46
  self._process_value()
44
47
  # if self.name == 0: print("UPDATING (callback) in easing")
45
- if self.update_callback: self.update_callback(self.value)
48
+ if self.update_callback:
49
+ self.update_callback(self.value)
46
50
  return False
47
51
 
48
52
  def end(self):
@@ -50,13 +54,14 @@ class EasingAnimation(bf.Timer):
50
54
 
51
55
  self.elapsed_progress = 1
52
56
  self._process_value()
53
- if self.update_callback: self.update_callback(self.value)
54
- self.value = 0
55
- super().end() # sets elapsed_progress to 0
57
+ if self.update_callback:
58
+ self.update_callback(self.value)
59
+ self.value = 0
60
+ super().end() # sets elapsed_progress to 0
56
61
 
57
62
  def _process_value(self):
58
63
  p0, p1, p2, p3 = self.easing_function.control_points
59
- cache_key = (self.elapsed_progress, p0, p1, p2, p3)
64
+ cache_key = (self.easing_function,self.elapsed_progress, p0, p1, p2, p3)
60
65
  if cache_key in EasingAnimation._cache:
61
66
  y = EasingAnimation._cache[cache_key]
62
67
  else: