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.
Files changed (59) hide show
  1. batFramework/__init__.py +23 -14
  2. batFramework/action.py +95 -106
  3. batFramework/actionContainer.py +11 -8
  4. batFramework/animatedSprite.py +60 -43
  5. batFramework/audioManager.py +52 -22
  6. batFramework/camera.py +87 -72
  7. batFramework/constants.py +19 -41
  8. batFramework/cutscene.py +12 -11
  9. batFramework/cutsceneBlocks.py +12 -14
  10. batFramework/dynamicEntity.py +5 -4
  11. batFramework/easingController.py +58 -0
  12. batFramework/entity.py +37 -130
  13. batFramework/enums.py +93 -3
  14. batFramework/fontManager.py +15 -7
  15. batFramework/gui/__init__.py +5 -1
  16. batFramework/gui/button.py +6 -144
  17. batFramework/gui/clickableWidget.py +206 -0
  18. batFramework/gui/constraints/__init__.py +1 -0
  19. batFramework/gui/constraints/constraints.py +378 -0
  20. batFramework/gui/container.py +147 -34
  21. batFramework/gui/debugger.py +39 -22
  22. batFramework/gui/dialogueBox.py +69 -43
  23. batFramework/gui/draggableWidget.py +38 -0
  24. batFramework/gui/image.py +33 -28
  25. batFramework/gui/indicator.py +30 -16
  26. batFramework/gui/interactiveWidget.py +72 -20
  27. batFramework/gui/label.py +240 -98
  28. batFramework/gui/layout.py +125 -53
  29. batFramework/gui/meter.py +76 -0
  30. batFramework/gui/radioButton.py +62 -0
  31. batFramework/gui/root.py +72 -48
  32. batFramework/gui/shape.py +257 -49
  33. batFramework/gui/slider.py +217 -2
  34. batFramework/gui/textInput.py +106 -60
  35. batFramework/gui/toggle.py +85 -42
  36. batFramework/gui/widget.py +259 -288
  37. batFramework/manager.py +30 -16
  38. batFramework/object.py +115 -0
  39. batFramework/{particles.py → particle.py} +37 -34
  40. batFramework/renderGroup.py +62 -0
  41. batFramework/resourceManager.py +36 -24
  42. batFramework/scene.py +94 -88
  43. batFramework/sceneManager.py +140 -57
  44. batFramework/scrollingSprite.py +113 -0
  45. batFramework/sprite.py +35 -23
  46. batFramework/tileset.py +34 -52
  47. batFramework/time.py +105 -56
  48. batFramework/transition.py +213 -1
  49. batFramework/utils.py +38 -18
  50. {batframework-1.0.6.dist-info → batframework-1.0.8a1.dist-info}/METADATA +1 -1
  51. batframework-1.0.8a1.dist-info/RECORD +56 -0
  52. {batframework-1.0.6.dist-info → batframework-1.0.8a1.dist-info}/WHEEL +1 -1
  53. batFramework/easing.py +0 -76
  54. batFramework/gui/constraints.py +0 -277
  55. batFramework/gui/frame.py +0 -25
  56. batFramework/transitionManager.py +0 -0
  57. batframework-1.0.6.dist-info/RECORD +0 -50
  58. {batframework-1.0.6.dist-info → batframework-1.0.8a1.dist-info}/LICENCE +0 -0
  59. {batframework-1.0.6.dist-info → batframework-1.0.8a1.dist-info}/top_level.txt +0 -0
@@ -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 :str|None= None
12
- self.music_volume :float= 1
13
- self.sound_volume :float= 1
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 = {key:value for key,value in self.sounds.items() if value["persistent"]}
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 has_sound(self, name:str):
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
- print(f"Music '{name}' not loaded in AudioManager.")
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
- def __init__(self, flags=0, size: tuple[int,int] | None = None,convert_alpha:bool=False) -> None:
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
- size = size if size else bf.const.RESOLUTION
19
- self.should_convert_alpha :bool = convert_alpha
20
- self.rect = pygame.FRect(0, 0, *size)
21
- self.vector_center = Vector2(0,0)
22
-
23
- self.surface: pygame.Surface = pygame.Surface((0, 0)) #tmp dummy
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 if convert_alpha else 255)
28
-
29
- self.cached_surfaces: dict[float, pygame.Surface] = {}
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.follow_speed :float= 0.1
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) -> "Camera":
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) -> "Camera":
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) -> "Camera":
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 : float|int, y:float|int) -> "Camera":
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) -> "Camera":
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) -> "Camera":
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 :float = 0.1) -> "Camera":
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 = follow_speed if func else 0.1
160
+ self.follow_speed = follow_speed if func else 0.1
163
161
  return self
164
162
 
165
- def zoom_by(self, amount: float) -> "Camera":
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) -> "Camera":
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
- if factor not in self.cached_surfaces:
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 transpose(self, rect: pygame.Rect | pygame.FRect) -> pygame.Rect | pygame.FRect:
238
+ def world_to_screen(
239
+ self, rect: pygame.Rect | pygame.FRect
240
+ ) -> pygame.Rect | pygame.FRect:
228
241
  """
229
- Transpose the given rectangle coordinates relative to the camera.
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 transpose.
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.x - self.rect.left, rect.y - self.rect.top, *rect.size)
238
-
250
+ return pygame.FRect(rect[0] - self.rect.left, rect[1] - self.rect.top, rect[2],rect[3])
239
251
 
240
- def transpose_point(self, point: tuple[float,float] | tuple[int,int]) -> tuple[float,float]:
252
+ def world_to_screen_point(
253
+ self, point: tuple[float, float] | tuple[int, int]
254
+ ) -> tuple[float, float]:
241
255
  """
242
- Transpose the given 2D point coordinates relative to the camera.
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 transpose.
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
- def convert_screen_to_world(self, x, y):
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
- x: X-coordinate in screen space.
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 x / self.zoom_factor + self.rect.x, y / self.zoom_factor + self.rect.y
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
- amount = ((dt * 60) * self.follow_speed)
276
- target = self.follow_point_func()
277
- self.set_center(*self.vector_center.lerp(target, amount))
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, bf.const.RESOLUTION)
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
- BF_INITIALIZED : bool = False
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
- def disable_player_control(self)->None:
43
- self.manager.set_sharedVar("player_has_control",False)
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,*blocks:CutsceneBlock):
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._scenes[index]
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
@@ -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._scenes[index]
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__(self, scene, transition, duration, **kwargs) -> None:
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.duration = duration
130
- self.kwargs = kwargs
133
+ self.index = index
131
134
  # Timer to handle the end of the transition
132
- self.timer = bf.Timer(duration=duration, end_callback=self.end)
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()._name == self.target_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, duration=self.duration, **self.kwargs
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):