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/audioManager.py
CHANGED
@@ -5,19 +5,26 @@ pygame.mixer.init()
|
|
5
5
|
|
6
6
|
|
7
7
|
class AudioManager(metaclass=bf.Singleton):
|
8
|
-
def __init__(self)->None:
|
8
|
+
def __init__(self) -> None:
|
9
9
|
self.sounds: dict = {}
|
10
10
|
self.musics: dict = {}
|
11
|
-
self.current_music
|
12
|
-
self.music_volume
|
13
|
-
self.sound_volume
|
11
|
+
self.current_music: str | None = None
|
12
|
+
self.music_volume: float = 1
|
13
|
+
self.sound_volume: float = 1
|
14
14
|
pygame.mixer_music.set_endevent(bf.const.MUSIC_END_EVENT)
|
15
15
|
|
16
|
-
def free_sounds(self, force:bool=False):
|
16
|
+
def free_sounds(self, force: bool = False):
|
17
17
|
if force:
|
18
18
|
self.sounds = {}
|
19
19
|
return
|
20
|
-
self.sounds
|
20
|
+
self.sounds: dict = {
|
21
|
+
key: value for key, value in self.sounds.items() if value["persistent"]
|
22
|
+
}
|
23
|
+
|
24
|
+
def free_music(self):
|
25
|
+
if self.current_music:
|
26
|
+
pygame.mixer.music.unload(self.current_music)
|
27
|
+
|
21
28
|
|
22
29
|
def set_sound_volume(self, volume: float):
|
23
30
|
self.sound_volume = volume
|
@@ -26,7 +33,13 @@ class AudioManager(metaclass=bf.Singleton):
|
|
26
33
|
self.music_volume = volume
|
27
34
|
pygame.mixer_music.set_volume(volume)
|
28
35
|
|
29
|
-
def
|
36
|
+
def get_music_volume(self) -> float:
|
37
|
+
return self.music_volume
|
38
|
+
|
39
|
+
def get_sound_volume(self) -> float:
|
40
|
+
return self.sound_volume
|
41
|
+
|
42
|
+
def has_sound(self, name: str):
|
30
43
|
return name in self.sounds
|
31
44
|
|
32
45
|
def load_sound(self, name, path, persistent=False) -> pygame.mixer.Sound:
|
@@ -36,44 +49,61 @@ class AudioManager(metaclass=bf.Singleton):
|
|
36
49
|
self.sounds[name] = {
|
37
50
|
"path": path,
|
38
51
|
"sound": pygame.mixer.Sound(path),
|
39
|
-
"persistent": persistent
|
52
|
+
"persistent": persistent,
|
40
53
|
}
|
41
54
|
return self.sounds[name]["sound"]
|
42
55
|
|
43
|
-
def load_sounds(self,sound_data_list:list[tuple[str,str,bool]])->None:
|
56
|
+
def load_sounds(self, sound_data_list: list[tuple[str, str, bool]]) -> None:
|
44
57
|
for data in sound_data_list:
|
45
58
|
self.load_sound(*data)
|
46
|
-
return
|
47
|
-
|
48
|
-
def play_sound(self, name, volume=1):
|
59
|
+
return
|
60
|
+
|
61
|
+
def play_sound(self, name, volume=1) -> bool:
|
62
|
+
"""
|
63
|
+
Play the sound file with the given name.
|
64
|
+
returns True if the sound was played
|
65
|
+
|
66
|
+
"""
|
49
67
|
try:
|
50
68
|
self.sounds[name]["sound"].set_volume(volume * self.sound_volume)
|
51
69
|
self.sounds[name]["sound"].play()
|
70
|
+
return True
|
52
71
|
except KeyError:
|
53
|
-
print(f"Sound '{name}' not loaded in AudioManager.")
|
72
|
+
# print(f"Sound '{name}' not loaded in AudioManager.")
|
73
|
+
return False
|
54
74
|
|
55
|
-
def stop_sound(self, name):
|
75
|
+
def stop_sound(self, name) -> bool:
|
56
76
|
try:
|
57
77
|
self.sounds[name]["sound"].stop()
|
78
|
+
return True
|
58
79
|
except KeyError:
|
59
|
-
|
60
|
-
print(f"Sound '{name}' not loaded in AudioManager.")
|
80
|
+
return False
|
81
|
+
# print(f"Sound '{name}' not loaded in AudioManager.")
|
82
|
+
|
61
83
|
def load_music(self, name, path):
|
62
84
|
self.musics[name] = bf.ResourceManager().get_path(path)
|
63
85
|
return
|
64
|
-
|
65
|
-
def load_musics(self,music_data_list:list[tuple[str,str]]):
|
86
|
+
|
87
|
+
def load_musics(self, music_data_list: list[tuple[str, str]]):
|
66
88
|
for data in music_data_list:
|
67
89
|
self.load_music(*data)
|
68
90
|
return
|
69
|
-
|
70
|
-
def play_music(self, name, loop=0, fade=500):
|
91
|
+
|
92
|
+
def play_music(self, name, loop=0, fade=500) -> bool:
|
93
|
+
"""
|
94
|
+
Play the sound file with the given 'name'.
|
95
|
+
Fades with the given 'fade' time in ms.
|
96
|
+
Music will loop 'loop' times (indefinitely if -1).
|
97
|
+
returns True if the sound was played
|
98
|
+
"""
|
71
99
|
try:
|
72
100
|
pygame.mixer_music.load(self.musics[name])
|
73
101
|
pygame.mixer_music.play(loop, fade_ms=fade)
|
74
102
|
self.current_music = name
|
103
|
+
return True
|
75
104
|
except KeyError:
|
76
|
-
|
105
|
+
return False
|
106
|
+
# print(f"Music '{name}' not loaded in AudioManager.")
|
77
107
|
|
78
108
|
def stop_music(self):
|
79
109
|
if not self.current_music:
|
@@ -95,5 +125,5 @@ class AudioManager(metaclass=bf.Singleton):
|
|
95
125
|
return
|
96
126
|
pygame.mixer_music.unpause()
|
97
127
|
|
98
|
-
def get_current_music(self)->str|None:
|
128
|
+
def get_current_music(self) -> str | None:
|
99
129
|
return self.current_music
|
batFramework/camera.py
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
import pygame
|
2
2
|
from pygame.math import Vector2
|
3
|
-
import math
|
4
3
|
import batFramework as bf
|
4
|
+
from typing import Self
|
5
5
|
|
6
6
|
|
7
7
|
class Camera:
|
8
|
-
|
9
|
-
|
8
|
+
def __init__(
|
9
|
+
self, flags=0, size: tuple[int, int] | None = None, convert_alpha: bool = False
|
10
|
+
) -> None:
|
10
11
|
"""
|
11
12
|
Initialize the Camera object.
|
12
13
|
|
@@ -15,28 +16,30 @@ class Camera:
|
|
15
16
|
size (tuple): Optional size for camera (defaults to window size)
|
16
17
|
convert_alpha (bool): Convert surface to support alpha values
|
17
18
|
"""
|
18
|
-
|
19
|
-
|
20
|
-
self.
|
21
|
-
self.
|
22
|
-
|
23
|
-
self.
|
19
|
+
self.cached_surfaces: dict[tuple[int, int], pygame.Surface] = {}
|
20
|
+
|
21
|
+
self.target_size = size if size else bf.const.RESOLUTION
|
22
|
+
self.should_convert_alpha: bool = convert_alpha
|
23
|
+
self.rect = pygame.FRect(0, 0, *self.target_size)
|
24
|
+
self.vector_center = Vector2(0, 0)
|
25
|
+
|
26
|
+
self.surface: pygame.Surface = pygame.Surface((0, 0)) # tmp dummy
|
24
27
|
self.flags: int = flags | (pygame.SRCALPHA if convert_alpha else 0)
|
25
28
|
self.blit_special_flags: int = pygame.BLEND_ALPHA_SDL2
|
26
|
-
|
27
|
-
self._clear_color: pygame.Color = pygame.Color(0, 0, 0, 0
|
28
|
-
|
29
|
-
|
30
|
-
|
29
|
+
|
30
|
+
self._clear_color: pygame.Color = pygame.Color(0, 0, 0, 0)
|
31
|
+
if not convert_alpha:
|
32
|
+
self._clear_color = pygame.Color(0, 0, 0)
|
33
|
+
|
31
34
|
self.follow_point_func = None
|
32
|
-
self.
|
33
|
-
|
35
|
+
self.follow_friction: float = 0.5
|
36
|
+
|
34
37
|
self.zoom_factor = 1
|
35
38
|
self.max_zoom = 2
|
36
39
|
self.min_zoom = 0.1
|
37
40
|
self.zoom(1)
|
38
41
|
|
39
|
-
def set_clear_color(self, color: pygame.Color | tuple | str) ->
|
42
|
+
def set_clear_color(self, color: pygame.Color | tuple | str) -> Self:
|
40
43
|
"""
|
41
44
|
Set the clear color for the camera surface.
|
42
45
|
|
@@ -46,12 +49,10 @@ class Camera:
|
|
46
49
|
Returns:
|
47
50
|
Camera: Returns the Camera object.
|
48
51
|
"""
|
49
|
-
if not isinstance(color, pygame.Color):
|
50
|
-
color = pygame.Color(color)
|
51
52
|
self._clear_color = color
|
52
53
|
return self
|
53
54
|
|
54
|
-
def set_max_zoom(self, value: float) ->
|
55
|
+
def set_max_zoom(self, value: float) -> Self:
|
55
56
|
"""
|
56
57
|
Set the maximum zoom value for the camera.
|
57
58
|
|
@@ -64,7 +65,7 @@ class Camera:
|
|
64
65
|
self.max_zoom = value
|
65
66
|
return self
|
66
67
|
|
67
|
-
def set_min_zoom(self, value: float) ->
|
68
|
+
def set_min_zoom(self, value: float) -> Self:
|
68
69
|
"""
|
69
70
|
Set the minimum zoom value for the camera.
|
70
71
|
|
@@ -83,7 +84,7 @@ class Camera:
|
|
83
84
|
"""
|
84
85
|
self.surface.fill(self._clear_color)
|
85
86
|
|
86
|
-
def get_center(self) -> tuple[float,float]:
|
87
|
+
def get_center(self) -> tuple[float, float]:
|
87
88
|
"""
|
88
89
|
Get the center of the camera's view.
|
89
90
|
|
@@ -92,7 +93,7 @@ class Camera:
|
|
92
93
|
"""
|
93
94
|
return self.rect.center
|
94
95
|
|
95
|
-
def get_position(self) -> tuple[float,float]:
|
96
|
+
def get_position(self) -> tuple[float, float]:
|
96
97
|
"""
|
97
98
|
Get the center of the camera's view.
|
98
99
|
|
@@ -101,7 +102,7 @@ class Camera:
|
|
101
102
|
"""
|
102
103
|
return self.rect.topleft
|
103
104
|
|
104
|
-
def move_by(self, x
|
105
|
+
def move_by(self, x: float | int, y: float | int) -> Self:
|
105
106
|
"""
|
106
107
|
Moves the camera rect by the given coordinates.
|
107
108
|
|
@@ -113,10 +114,9 @@ class Camera:
|
|
113
114
|
Camera: Returns the Camera object.
|
114
115
|
"""
|
115
116
|
self.rect.move_ip(x, y)
|
116
|
-
self.vector_center.update(self.rect.center)
|
117
117
|
return self
|
118
118
|
|
119
|
-
def set_position(self, x, y) ->
|
119
|
+
def set_position(self, x, y) -> Self:
|
120
120
|
"""
|
121
121
|
Set the camera rect top-left position.
|
122
122
|
|
@@ -128,11 +128,10 @@ class Camera:
|
|
128
128
|
Camera: Returns the Camera object.
|
129
129
|
"""
|
130
130
|
self.rect.topleft = (x, y)
|
131
|
-
self.vector_center.update(self.rect.center)
|
132
131
|
|
133
132
|
return self
|
134
133
|
|
135
|
-
def set_center(self, x, y) ->
|
134
|
+
def set_center(self, x, y) -> Self:
|
136
135
|
"""
|
137
136
|
Set the camera rect center position.
|
138
137
|
|
@@ -144,10 +143,9 @@ class Camera:
|
|
144
143
|
Camera: Returns the Camera object.
|
145
144
|
"""
|
146
145
|
self.rect.center = (x, y)
|
147
|
-
self.vector_center.update(self.rect.center)
|
148
146
|
return self
|
149
147
|
|
150
|
-
def set_follow_point(self, func,follow_speed
|
148
|
+
def set_follow_point(self, func, follow_speed: float = 0.1) -> Self:
|
151
149
|
"""
|
152
150
|
Set the following function (returns tuple x y).
|
153
151
|
Camera will center its position to the center of the given coordinates.
|
@@ -159,10 +157,14 @@ class Camera:
|
|
159
157
|
Camera: Returns the Camera object.
|
160
158
|
"""
|
161
159
|
self.follow_point_func = func
|
162
|
-
self.follow_speed =
|
160
|
+
self.follow_speed = follow_speed if func else 0.1
|
163
161
|
return self
|
164
162
|
|
165
|
-
def
|
163
|
+
def set_follow_friction(self,friction:float)->Self:
|
164
|
+
self.follow_friction = friction
|
165
|
+
return self
|
166
|
+
|
167
|
+
def zoom_by(self, amount: float) -> Self:
|
166
168
|
"""
|
167
169
|
Zooms the camera by the given amount.
|
168
170
|
|
@@ -172,10 +174,10 @@ class Camera:
|
|
172
174
|
Returns:
|
173
175
|
Camera: Returns the Camera object.
|
174
176
|
"""
|
175
|
-
self.zoom(self.zoom_factor + amount)
|
177
|
+
self.zoom(max(self.min_zoom, min(self.max_zoom, self.zoom_factor + amount)))
|
176
178
|
return self
|
177
179
|
|
178
|
-
def zoom(self, factor) ->
|
180
|
+
def zoom(self, factor: float) -> Self:
|
179
181
|
"""
|
180
182
|
Zooms the camera to the given factor.
|
181
183
|
|
@@ -186,26 +188,41 @@ class Camera:
|
|
186
188
|
Camera: Returns the Camera object.
|
187
189
|
"""
|
188
190
|
if factor < self.min_zoom or factor > self.max_zoom:
|
191
|
+
print(
|
192
|
+
f"Zoom value {factor} is outside the zoom range : [{self.min_zoom},{self.max_zoom}]"
|
193
|
+
)
|
189
194
|
return self
|
190
195
|
|
191
196
|
factor = round(factor, 2)
|
192
197
|
self.zoom_factor = factor
|
193
|
-
|
194
|
-
|
195
|
-
self.cached_surfaces[factor] = pygame.Surface(
|
196
|
-
tuple(i / factor for i in bf.const.RESOLUTION), flags=self.flags
|
197
|
-
)
|
198
|
-
if self.should_convert_alpha :
|
199
|
-
self.cached_surfaces[factor].convert_alpha()
|
200
|
-
else:
|
201
|
-
self.cached_surfaces[factor].convert()
|
202
|
-
# self.cached_surfaces[factor].fill((self._clear_color))
|
203
|
-
|
204
|
-
self.surface = self.cached_surfaces[self.zoom_factor]
|
198
|
+
new_res = tuple(round((i / factor) / 2) * 2 for i in self.target_size)
|
199
|
+
self.surface = self._get_cached_surface(new_res)
|
205
200
|
self.rect = self.surface.get_frect(center=self.rect.center)
|
206
201
|
self.clear()
|
207
202
|
return self
|
208
203
|
|
204
|
+
def _free_cache(self):
|
205
|
+
self.cached_surfaces = {}
|
206
|
+
|
207
|
+
def _get_cached_surface(self, new_size: tuple[int, int]):
|
208
|
+
surface = self.cached_surfaces.get(new_size, None)
|
209
|
+
if surface is None:
|
210
|
+
surface = pygame.Surface(new_size, flags=self.flags)
|
211
|
+
if self.flags & pygame.SRCALPHA:
|
212
|
+
surface = surface.convert_alpha()
|
213
|
+
self.cached_surfaces[new_size] = surface
|
214
|
+
|
215
|
+
return surface
|
216
|
+
|
217
|
+
def resize(self, size: tuple[int, int] | None = None) -> Self:
|
218
|
+
if size is None:
|
219
|
+
size = bf.const.RESOLUTION
|
220
|
+
self.target_size = size
|
221
|
+
self.rect.center = (size[0] / 2, size[1] / 2)
|
222
|
+
self.zoom(self.zoom_factor)
|
223
|
+
|
224
|
+
return self
|
225
|
+
|
209
226
|
def intersects(self, rect: pygame.Rect | pygame.FRect) -> bool:
|
210
227
|
"""
|
211
228
|
Check if the camera view intersects with the given rectangle.
|
@@ -216,53 +233,51 @@ class Camera:
|
|
216
233
|
Returns:
|
217
234
|
bool: True if intersection occurs, False otherwise.
|
218
235
|
"""
|
219
|
-
# return (
|
220
|
-
# self.rect.x < rect.right
|
221
|
-
# and self.rect.right > rect.x
|
222
|
-
# and self.rect.y < rect.bottom
|
223
|
-
# and self.rect.bottom > rect.y
|
224
|
-
# )
|
225
236
|
return self.rect.colliderect(rect)
|
226
237
|
|
227
|
-
def
|
238
|
+
def world_to_screen(
|
239
|
+
self, rect: pygame.Rect | pygame.FRect
|
240
|
+
) -> pygame.Rect | pygame.FRect:
|
228
241
|
"""
|
229
|
-
|
242
|
+
world_to_screen the given rectangle coordinates relative to the camera.
|
230
243
|
|
231
244
|
Args:
|
232
|
-
rect (pygame.Rect | pygame.FRect): Rectangle to
|
245
|
+
rect (pygame.Rect | pygame.FRect): Rectangle to world_to_screen.
|
233
246
|
|
234
247
|
Returns:
|
235
248
|
pygame.FRect: Transposed rectangle.
|
236
249
|
"""
|
237
|
-
return pygame.FRect(rect
|
238
|
-
|
250
|
+
return pygame.FRect(rect[0] - self.rect.left, rect[1] - self.rect.top, rect[2],rect[3])
|
239
251
|
|
240
|
-
def
|
252
|
+
def world_to_screen_point(
|
253
|
+
self, point: tuple[float, float] | tuple[int, int]
|
254
|
+
) -> tuple[float, float]:
|
241
255
|
"""
|
242
|
-
|
256
|
+
world_to_screen the given 2D point coordinates relative to the camera.
|
243
257
|
|
244
258
|
Args:
|
245
|
-
point (tuple[float,float] | tuple[int,int]): Point to
|
259
|
+
point (tuple[float,float] | tuple[int,int]): Point to world_to_screen.
|
246
260
|
|
247
261
|
Returns:
|
248
262
|
tuple[float,float] : Transposed point.
|
249
263
|
"""
|
250
|
-
return point[0]-self.rect.x,point[1]-self.rect.y
|
251
|
-
|
264
|
+
return point[0] - self.rect.x, point[1] - self.rect.y
|
252
265
|
|
253
|
-
|
254
|
-
|
266
|
+
def screen_to_world(
|
267
|
+
self, point: tuple[float, float] | tuple[int, int]
|
268
|
+
) -> tuple[float, float]:
|
255
269
|
"""
|
256
270
|
Convert screen coordinates to world coordinates based on camera settings.
|
257
271
|
|
258
272
|
Args:
|
259
|
-
|
260
|
-
y: Y-coordinate in screen space.
|
261
|
-
|
273
|
+
point (tuple[float,float] | tuple[int,int]): Point to screen_to_world.
|
262
274
|
Returns:
|
263
275
|
tuple: Converted world coordinates.
|
264
276
|
"""
|
265
|
-
return
|
277
|
+
return (
|
278
|
+
point[0] / self.zoom_factor + self.rect.x,
|
279
|
+
point[1] / self.zoom_factor + self.rect.y,
|
280
|
+
)
|
266
281
|
|
267
282
|
def update(self, dt):
|
268
283
|
"""
|
@@ -272,9 +287,9 @@ class Camera:
|
|
272
287
|
dt: Time delta for updating the camera position.
|
273
288
|
"""
|
274
289
|
if self.follow_point_func:
|
275
|
-
|
276
|
-
|
277
|
-
self.set_center(*self.vector_center.lerp(
|
290
|
+
self.vector_center.update(*self.rect.center)
|
291
|
+
amount = pygame.math.clamp(self.follow_friction,0,1)
|
292
|
+
self.set_center(*self.vector_center.lerp(self.follow_point_func(), amount))
|
278
293
|
|
279
294
|
def draw(self, surface: pygame.Surface):
|
280
295
|
"""
|
@@ -289,5 +304,5 @@ class Camera:
|
|
289
304
|
return
|
290
305
|
|
291
306
|
# Scale the surface to match the resolution
|
292
|
-
scaled_surface = pygame.transform.scale(self.surface,
|
307
|
+
scaled_surface = pygame.transform.scale(self.surface, self.target_size)
|
293
308
|
surface.blit(scaled_surface, (0, 0), special_flags=self.blit_special_flags)
|
batFramework/constants.py
CHANGED
@@ -1,59 +1,37 @@
|
|
1
1
|
import pygame
|
2
|
-
from enum import Enum
|
3
|
-
import sys, os
|
4
|
-
|
5
|
-
|
6
|
-
if getattr(sys, "frozen", False):
|
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
|
9
|
-
# path into variable _MEIPASS'.
|
10
|
-
application_path = sys._MEIPASS
|
11
|
-
else:
|
12
|
-
application_path = os.getcwd()
|
13
|
-
|
14
|
-
class Colors:
|
15
|
-
LIGHT_CYAN = (179, 229, 252)
|
16
|
-
WASHED_BLUE = (52, 73, 94)
|
17
|
-
RIVER_BLUE = (52, 152, 219)
|
18
|
-
DARK_INDIGO = (40, 53, 147)
|
19
|
-
LIGHT_BLUE = (3, 169, 244)
|
20
|
-
DEEP_BLUE = (41, 121, 255)
|
21
|
-
DARK_BLUE = (44, 62, 80)
|
22
|
-
|
23
|
-
GREEN = (67, 160, 71)
|
24
|
-
DARK_GREEN = (39, 174, 96)
|
25
|
-
|
26
|
-
BROWN = (109, 76, 65)
|
27
|
-
DARK_RED = (192, 57, 43)
|
28
|
-
|
29
|
-
ORANGE = (251, 140, 0)
|
30
|
-
|
31
|
-
CLOUD_WHITE = (236, 240, 241)
|
32
|
-
SILVER = (189, 195, 199)
|
33
|
-
DARK_GRAY = (66, 66, 66)
|
34
|
-
|
35
|
-
DARK_GB = (27, 42, 9)
|
36
|
-
SHADE_GB = (14, 69, 11)
|
37
|
-
BASE_GB = (73, 107, 34)
|
38
|
-
LIGHT_GB = (154, 158, 63)
|
39
|
-
|
40
2
|
|
41
3
|
|
42
4
|
class Constants:
|
43
|
-
SCREEN = None
|
5
|
+
SCREEN: pygame.Surface = None
|
44
6
|
RESOLUTION: tuple[int, int] = (1280, 720)
|
45
7
|
VSYNC = 0
|
46
8
|
FLAGS: int = pygame.SCALED | pygame.RESIZABLE
|
47
9
|
FPS: int = 60
|
48
10
|
MUSIC_END_EVENT = pygame.event.custom_type()
|
49
11
|
|
50
|
-
|
12
|
+
DEFAULT_CURSOR = pygame.cursors.Cursor(pygame.SYSTEM_CURSOR_ARROW)
|
13
|
+
DEFAULT_HOVER_CURSOR = pygame.cursors.Cursor(pygame.SYSTEM_CURSOR_ARROW)
|
14
|
+
DEFAULT_CLICK_CURSOR = pygame.cursors.Cursor(pygame.SYSTEM_CURSOR_ARROW)
|
15
|
+
|
16
|
+
BF_INITIALIZED: bool = False
|
17
|
+
|
51
18
|
@staticmethod
|
52
19
|
def set_resolution(resolution: tuple[int, int]):
|
53
20
|
Constants.RESOLUTION = resolution
|
54
21
|
|
22
|
+
@staticmethod
|
23
|
+
def set_default_cursor(cursor: pygame.Cursor):
|
24
|
+
Constants.DEFAULT_CURSOR = cursor
|
25
|
+
|
26
|
+
@staticmethod
|
27
|
+
def set_default_hover_cursor(cursor: pygame.Cursor):
|
28
|
+
Constants.DEFAULT_HOVER_CURSOR = cursor
|
29
|
+
|
30
|
+
@staticmethod
|
31
|
+
def set_default_click_cursor(cursor: pygame.Cursor):
|
32
|
+
Constants.DEFAULT_CLICK_CURSOR = cursor
|
33
|
+
|
55
34
|
@staticmethod
|
56
35
|
def set_fps_limit(value: int):
|
57
36
|
Constants.FPS = value
|
58
37
|
print("FPS limit to : ", value)
|
59
|
-
|
batFramework/cutscene.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
import batFramework as bf
|
2
2
|
|
3
|
+
|
3
4
|
class CutsceneBlock:
|
4
5
|
...
|
5
6
|
|
@@ -12,9 +13,9 @@ class CutsceneManager(metaclass=bf.Singleton):
|
|
12
13
|
def __init__(self) -> None:
|
13
14
|
self.current_cutscene: Cutscene = None
|
14
15
|
self.cutscenes: list[bf.Cutscene] = []
|
15
|
-
self.manager = None
|
16
|
-
|
17
|
-
def set_manager(self,manager):
|
16
|
+
self.manager: bf.Manager = None
|
17
|
+
|
18
|
+
def set_manager(self, manager):
|
18
19
|
self.manager = manager
|
19
20
|
|
20
21
|
def get_flag(self, flag):
|
@@ -37,10 +38,11 @@ class CutsceneManager(metaclass=bf.Singleton):
|
|
37
38
|
self.current_cutscene.play()
|
38
39
|
self.manager.set_sharedVar("in_cutscene", True)
|
39
40
|
|
40
|
-
def enable_player_control(self)->None:
|
41
|
-
self.manager.set_sharedVar("player_has_control",True)
|
42
|
-
|
43
|
-
|
41
|
+
def enable_player_control(self) -> None:
|
42
|
+
self.manager.set_sharedVar("player_has_control", True)
|
43
|
+
|
44
|
+
def disable_player_control(self) -> None:
|
45
|
+
self.manager.set_sharedVar("player_has_control", False)
|
44
46
|
|
45
47
|
def update(self, dt):
|
46
48
|
if not self.current_cutscene is None:
|
@@ -72,15 +74,15 @@ class Cutscene:
|
|
72
74
|
def init_blocks(self):
|
73
75
|
pass
|
74
76
|
|
75
|
-
def add_blocks(self
|
77
|
+
def add_blocks(self, *blocks: CutsceneBlock):
|
76
78
|
self.cutscene_blocks.extend(blocks)
|
77
79
|
|
78
|
-
def add_end_blocks(self, *blocks:CutsceneBlock):
|
80
|
+
def add_end_blocks(self, *blocks: CutsceneBlock):
|
79
81
|
_ = [block.set_parent_cutscene(self) for block in blocks]
|
80
82
|
self.end_blocks.extend(blocks)
|
81
83
|
|
82
84
|
def get_scene_at(self, index):
|
83
|
-
return bf.CutsceneManager().manager.
|
85
|
+
return bf.CutsceneManager().manager.scenes[index]
|
84
86
|
|
85
87
|
def get_current_scene(self):
|
86
88
|
return bf.CutsceneManager().manager.get_current_scene()
|
@@ -122,6 +124,5 @@ class Cutscene:
|
|
122
124
|
self.end_blocks = []
|
123
125
|
self.cutscene_blocks[self.block_index].start()
|
124
126
|
|
125
|
-
|
126
127
|
def has_ended(self):
|
127
128
|
return self.ended
|
batFramework/cutsceneBlocks.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
import batFramework as bf
|
2
2
|
from .cutscene import Cutscene, CutsceneManager
|
3
|
+
from .transition import *
|
3
4
|
|
4
5
|
|
5
6
|
# Define the base CutsceneBlock class
|
@@ -18,7 +19,7 @@ class CutsceneBlock:
|
|
18
19
|
self.started = False
|
19
20
|
|
20
21
|
def get_scene_at(self, index):
|
21
|
-
return bf.CutsceneManager().manager.
|
22
|
+
return bf.CutsceneManager().manager.scenes[index]
|
22
23
|
|
23
24
|
def set_scene(self, name, index=0):
|
24
25
|
return CutsceneManager().manager.set_scene(name, index)
|
@@ -89,6 +90,7 @@ class ParallelBlock(CutsceneBlock):
|
|
89
90
|
"""
|
90
91
|
Represents a parallel execution block for multiple Cutscene blocks.
|
91
92
|
"""
|
93
|
+
|
92
94
|
def __init__(self, *blocks) -> None:
|
93
95
|
super().__init__()
|
94
96
|
# List of blocks to run in parallel
|
@@ -121,15 +123,16 @@ class SceneTransitionBlock(CutsceneBlock):
|
|
121
123
|
"""
|
122
124
|
|
123
125
|
# Constructor for SceneTransitionBlock
|
124
|
-
def __init__(
|
126
|
+
def __init__(
|
127
|
+
self, scene, transition: Transition = Fade(0.1), index: int = 0
|
128
|
+
) -> None:
|
125
129
|
super().__init__()
|
126
130
|
# Target scene, transition type, duration, and additional keyword arguments
|
127
131
|
self.target_scene = scene
|
128
132
|
self.transition = transition
|
129
|
-
self.
|
130
|
-
self.kwargs = kwargs
|
133
|
+
self.index = index
|
131
134
|
# Timer to handle the end of the transition
|
132
|
-
self.timer = bf.Timer(duration
|
135
|
+
self.timer = bf.Timer(transition.duration, self.end)
|
133
136
|
|
134
137
|
# Start the scene transition block
|
135
138
|
def start(self):
|
@@ -137,22 +140,16 @@ class SceneTransitionBlock(CutsceneBlock):
|
|
137
140
|
Start the scene transition block.
|
138
141
|
"""
|
139
142
|
super().start()
|
140
|
-
print(f"transition to {scene}")
|
141
|
-
|
142
143
|
# Initiate the scene transition
|
143
|
-
if self.get_current_scene().
|
144
|
+
if self.get_current_scene().name == self.target_scene:
|
144
145
|
self.end()
|
145
146
|
return
|
146
147
|
CutsceneManager().manager.transition_to_scene(
|
147
|
-
self.target_scene, self.transition,
|
148
|
+
self.target_scene, self.transition, self.index
|
148
149
|
)
|
149
150
|
# Start the timer to handle the end of the transition
|
150
151
|
self.timer.start()
|
151
152
|
|
152
|
-
def end(self):
|
153
|
-
return super().end()
|
154
|
-
|
155
|
-
|
156
153
|
|
157
154
|
class DelayBlock(CutsceneBlock):
|
158
155
|
def __init__(self, duration) -> None:
|
@@ -163,8 +160,9 @@ class DelayBlock(CutsceneBlock):
|
|
163
160
|
super().start()
|
164
161
|
self.timer.start()
|
165
162
|
|
163
|
+
|
166
164
|
class FunctionBlock(CutsceneBlock):
|
167
|
-
def __init__(self,func)->None:
|
165
|
+
def __init__(self, func) -> None:
|
168
166
|
self.function = func
|
169
167
|
|
170
168
|
def start(self):
|