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.
- batFramework/__init__.py +41 -46
- batFramework/action.py +42 -20
- batFramework/actionContainer.py +43 -4
- batFramework/animatedSprite.py +26 -20
- batFramework/camera.py +177 -47
- batFramework/constants.py +26 -51
- batFramework/cutscene.py +15 -15
- batFramework/cutsceneBlocks.py +11 -9
- batFramework/dynamicEntity.py +7 -6
- batFramework/easing.py +28 -23
- batFramework/entity.py +87 -49
- batFramework/enums.py +14 -0
- batFramework/fontManager.py +57 -0
- batFramework/gui/__init__.py +2 -2
- batFramework/gui/button.py +82 -31
- batFramework/gui/constraints.py +137 -104
- batFramework/gui/container.py +27 -28
- batFramework/gui/debugger.py +92 -42
- batFramework/gui/frame.py +15 -15
- batFramework/gui/image.py +37 -17
- batFramework/gui/indicator.py +18 -14
- batFramework/gui/interactiveWidget.py +11 -10
- batFramework/gui/label.py +60 -56
- batFramework/gui/layout.py +50 -47
- batFramework/gui/root.py +43 -30
- batFramework/gui/shape.py +34 -41
- batFramework/gui/slider.py +5 -0
- batFramework/gui/toggle.py +31 -27
- batFramework/gui/widget.py +148 -128
- batFramework/manager.py +18 -13
- batFramework/particles.py +16 -13
- batFramework/resourceManager.py +55 -0
- batFramework/scene.py +141 -83
- batFramework/sceneManager.py +21 -16
- batFramework/sprite.py +31 -0
- batFramework/stateMachine.py +1 -0
- batFramework/tileset.py +7 -9
- batFramework/time.py +61 -50
- batFramework/transition.py +20 -12
- batFramework/utils.py +2 -65
- batframework-1.0.1.dist-info/LICENCE +21 -0
- {batframework-0.1.13.dist-info → batframework-1.0.1.dist-info}/METADATA +3 -2
- batframework-1.0.1.dist-info/RECORD +48 -0
- {batframework-0.1.13.dist-info → batframework-1.0.1.dist-info}/WHEEL +1 -1
- batFramework/debugger.py +0 -48
- batframework-0.1.13.dist-info/RECORD +0 -43
- {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
|
-
|
8
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
134
|
+
def set_follow_point(self, func) -> "Camera":
|
63
135
|
"""
|
64
|
-
Set the following function (returns tuple x y)
|
65
|
-
|
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
|
-
|
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
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
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.
|
90
|
-
|
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
|
-
|
103
|
-
|
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
|
-
|
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
|
-
|
119
|
-
surface
|
120
|
-
|
121
|
-
|
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,
|
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
|
-
|
83
|
-
|
84
|
-
|
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
|
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
|
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
|
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
|
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
|
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
|
-
|
batFramework/cutsceneBlocks.py
CHANGED
@@ -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(
|
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):
|
batFramework/dynamicEntity.py
CHANGED
@@ -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
|
9
|
-
no_surface
|
10
|
-
surface_flags
|
11
|
-
convert_alpha
|
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
|
7
|
-
EASE_OUT
|
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
|
10
|
-
LINEAR
|
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=
|
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 =
|
38
|
-
super().start()
|
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:
|
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:
|
54
|
-
|
55
|
-
|
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:
|