batframework 1.0.7__py3-none-any.whl → 1.0.8a2__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 +47 -41
- batFramework/action.py +20 -42
- batFramework/actionContainer.py +4 -43
- batFramework/animatedSprite.py +65 -98
- batFramework/audioManager.py +25 -39
- batFramework/camera.py +56 -226
- batFramework/constants.py +48 -32
- batFramework/cutscene.py +24 -32
- batFramework/cutsceneBlocks.py +33 -30
- batFramework/debugger.py +48 -0
- batFramework/dynamicEntity.py +7 -8
- batFramework/easing.py +23 -28
- batFramework/entity.py +52 -89
- batFramework/gui/__init__.py +1 -3
- batFramework/gui/button.py +58 -124
- batFramework/gui/constraints.py +90 -163
- batFramework/gui/container.py +18 -29
- batFramework/gui/debugger.py +42 -106
- batFramework/gui/frame.py +9 -15
- batFramework/gui/image.py +17 -36
- batFramework/gui/indicator.py +14 -20
- batFramework/gui/interactiveWidget.py +12 -63
- batFramework/gui/label.py +50 -113
- batFramework/gui/layout.py +51 -66
- batFramework/gui/root.py +29 -70
- batFramework/gui/shape.py +41 -34
- batFramework/gui/toggle.py +29 -37
- batFramework/gui/widget.py +131 -174
- batFramework/manager.py +14 -21
- batFramework/particles.py +20 -41
- batFramework/scene.py +72 -173
- batFramework/sceneManager.py +80 -40
- batFramework/stateMachine.py +0 -1
- batFramework/time.py +51 -62
- batFramework/transition.py +154 -0
- batFramework/utils.py +150 -3
- batframework-1.0.8a2.dist-info/METADATA +58 -0
- batframework-1.0.8a2.dist-info/RECORD +42 -0
- {batframework-1.0.7.dist-info → batframework-1.0.8a2.dist-info}/WHEEL +1 -1
- batFramework/enums.py +0 -14
- batFramework/fontManager.py +0 -57
- batFramework/gui/dialogueBox.py +0 -70
- batFramework/gui/slider.py +0 -5
- batFramework/gui/textInput.py +0 -88
- batFramework/resourceManager.py +0 -72
- batFramework/sprite.py +0 -33
- batFramework/tileset.py +0 -64
- batframework-1.0.7.dist-info/LICENCE +0 -21
- batframework-1.0.7.dist-info/METADATA +0 -55
- batframework-1.0.7.dist-info/RECORD +0 -50
- {batframework-1.0.7.dist-info → batframework-1.0.8a2.dist-info}/top_level.txt +0 -0
batFramework/__init__.py
CHANGED
@@ -1,60 +1,66 @@
|
|
1
1
|
import pygame
|
2
|
-
import batFramework as bf
|
3
|
-
import sys
|
4
2
|
from .constants import Constants as const
|
3
|
+
import os
|
4
|
+
import json
|
5
|
+
initialized = False
|
6
|
+
|
7
|
+
def init(
|
8
|
+
resolution:tuple[int,int],
|
9
|
+
flags:int=0,
|
10
|
+
vsync:int = 0,
|
11
|
+
default_text_size=None,
|
12
|
+
default_font=None,
|
13
|
+
resource_path:str|None=None,
|
14
|
+
window_title:str="BatFramework Project",
|
15
|
+
fps_limit : int = 0
|
16
|
+
):
|
17
|
+
global initialized
|
18
|
+
if not initialized:
|
19
|
+
pygame.init()
|
20
|
+
pygame.display.set_caption(window_title)
|
21
|
+
|
22
|
+
# Initialize display
|
23
|
+
const.init_screen(resolution,flags,vsync)
|
24
|
+
const.set_fps_limit(fps_limit)
|
25
|
+
|
26
|
+
# Initialize default text size
|
27
|
+
if default_text_size: const.set_default_text_size(default_text_size)
|
28
|
+
# Initialize resource path for game data
|
29
|
+
if resource_path: const.set_resource_path(resource_path)
|
30
|
+
|
31
|
+
# Initialize default font cache
|
32
|
+
from .utils import Utils
|
33
|
+
if default_font is None or isinstance(default_font,str):
|
34
|
+
Utils.init_font(default_font)
|
35
|
+
else:
|
36
|
+
raise ValueError(f"default_font '{default_font}' can be either string or None")
|
37
|
+
|
38
|
+
f = list(Utils.FONTS[None].values())[0]
|
39
|
+
print(f"Set default font to : {f.name} {'' if default_font is not None else '(default value)'}")
|
40
|
+
initialized = True
|
41
|
+
|
5
42
|
from .constants import Colors as color
|
43
|
+
from .constants import Axis as axis
|
6
44
|
from .utils import Singleton
|
7
|
-
from .enums import *
|
8
|
-
from .resourceManager import ResourceManager
|
9
|
-
from .fontManager import FontManager
|
10
45
|
from .utils import Utils as utils
|
11
|
-
from .
|
12
|
-
from .
|
13
|
-
from .cutscene import Cutscene, CutsceneManager
|
46
|
+
from .time import Time, Timer
|
47
|
+
from .cutscene import Cutscene,CutsceneManager
|
14
48
|
from .cutsceneBlocks import *
|
15
49
|
from .easing import Easing, EasingAnimation
|
16
50
|
from .audioManager import AudioManager
|
17
|
-
|
51
|
+
from .utils import Layout, Alignment, Direction
|
52
|
+
from .transition import *
|
18
53
|
from .action import Action
|
19
|
-
from .actionContainer import
|
54
|
+
from .actionContainer import ActionContainer
|
20
55
|
from .camera import Camera
|
21
56
|
from .entity import Entity
|
22
57
|
from .dynamicEntity import DynamicEntity
|
23
|
-
from .sprite import Sprite
|
24
58
|
from .animatedSprite import AnimatedSprite, AnimState
|
25
59
|
from .stateMachine import State, StateMachine
|
60
|
+
from .particles import Particle, ParticleManager
|
61
|
+
# from .debugger import Debugger
|
26
62
|
from .scene import Scene
|
27
63
|
from .gui import *
|
28
64
|
from .sceneManager import SceneManager
|
29
65
|
from .manager import Manager
|
30
66
|
|
31
|
-
|
32
|
-
def init_screen(resolution: tuple[int, int], flags: int = 0, vsync: int = 0):
|
33
|
-
const.RESOLUTION = resolution
|
34
|
-
const.FLAGS = flags
|
35
|
-
const.VSYNC = vsync
|
36
|
-
const.SCREEN = pygame.display.set_mode(
|
37
|
-
const.RESOLUTION,const.FLAGS, vsync=const.VSYNC
|
38
|
-
)
|
39
|
-
print(
|
40
|
-
f"Window : {resolution[0]}x{resolution[1]} [vsync:{pygame.display.is_vsync()}]"
|
41
|
-
)
|
42
|
-
|
43
|
-
def init(
|
44
|
-
resolution: tuple[int, int],
|
45
|
-
flags: int = 0,
|
46
|
-
vsync: int = 0,
|
47
|
-
default_text_size=None,
|
48
|
-
default_font=None,
|
49
|
-
resource_path: str | None = None,
|
50
|
-
window_title: str = "BatFramework Project",
|
51
|
-
fps_limit: int = 0):
|
52
|
-
pygame.display.set_caption(window_title)
|
53
|
-
init_screen(resolution,flags,vsync)
|
54
|
-
|
55
|
-
ResourceManager().set_resource_path(resource_path if resource_path is not None else ".")
|
56
|
-
if resource_path is not None : ResourceManager().load_dir(ResourceManager().RESOURCE_PATH)
|
57
|
-
if default_text_size is not None : FontManager().set_default_text_size(default_text_size)
|
58
|
-
FontManager().init_font(default_font)
|
59
|
-
const.BF_INITIALIZED = True
|
60
|
-
const.set_fps_limit(fps_limit)
|
batFramework/action.py
CHANGED
@@ -12,21 +12,20 @@ class Action:
|
|
12
12
|
Args:
|
13
13
|
name (str): The name of the action.
|
14
14
|
"""
|
15
|
-
self._name
|
16
|
-
self._active
|
17
|
-
self._type
|
18
|
-
self._key_control
|
19
|
-
self._mouse_control
|
20
|
-
self._gamepad_button_control
|
21
|
-
self._gamepad_axis_control
|
15
|
+
self._name = name
|
16
|
+
self._active = False
|
17
|
+
self._type = ActionType.INSTANTANEOUS
|
18
|
+
self._key_control = set()
|
19
|
+
self._mouse_control = set()
|
20
|
+
self._gamepad_button_control = set()
|
21
|
+
self._gamepad_axis_control = set()
|
22
22
|
self._holding = set()
|
23
23
|
self._unique = True
|
24
|
-
self.data: Any = None
|
24
|
+
self.data : Any = None
|
25
25
|
|
26
26
|
def set_unique(self, val: bool) -> None:
|
27
27
|
"""
|
28
28
|
Set whether this action is unique (exclusive).
|
29
|
-
When in an action Container, unique actions -when active - break the propagation of their event to other actions.
|
30
29
|
|
31
30
|
Args:
|
32
31
|
val (bool): True if the action is unique, False otherwise.
|
@@ -52,7 +51,7 @@ class Action:
|
|
52
51
|
self._active = value
|
53
52
|
self._holding = set()
|
54
53
|
|
55
|
-
def add_key_control(self, *keys) ->
|
54
|
+
def add_key_control(self, *keys) -> 'Action':
|
56
55
|
"""
|
57
56
|
Add key controls to the action.
|
58
57
|
|
@@ -65,26 +64,7 @@ class Action:
|
|
65
64
|
self._key_control.update(keys)
|
66
65
|
return self
|
67
66
|
|
68
|
-
def
|
69
|
-
"""
|
70
|
-
Remove key controls to the action.
|
71
|
-
|
72
|
-
Args:
|
73
|
-
*keys (int): Key codes to control this action.
|
74
|
-
|
75
|
-
Returns:
|
76
|
-
Action: The updated Action object for method chaining.
|
77
|
-
"""
|
78
|
-
self._key_control = self._key_control - set(keys)
|
79
|
-
return self
|
80
|
-
|
81
|
-
def replace_key_control(self, key, new_key) -> "Action":
|
82
|
-
if not key in self._key_control : return self
|
83
|
-
self.remove_key_control(key)
|
84
|
-
self.add_key_control(new_key)
|
85
|
-
return self
|
86
|
-
|
87
|
-
def add_mouse_control(self, *mouse_buttons:int) -> "Action":
|
67
|
+
def add_mouse_control(self, *mouse_buttons) -> 'Action':
|
88
68
|
"""
|
89
69
|
Add mouse control to the action.
|
90
70
|
|
@@ -106,7 +86,7 @@ class Action:
|
|
106
86
|
"""
|
107
87
|
return self._name
|
108
88
|
|
109
|
-
def set_continuous(self) ->
|
89
|
+
def set_continuous(self) -> 'Action':
|
110
90
|
"""
|
111
91
|
Set the action type to continuous.
|
112
92
|
|
@@ -126,7 +106,7 @@ class Action:
|
|
126
106
|
"""
|
127
107
|
return self._type == ActionType.CONTINUOUS
|
128
108
|
|
129
|
-
def set_instantaneous(self) ->
|
109
|
+
def set_instantaneous(self) -> 'Action':
|
130
110
|
"""
|
131
111
|
Set the action type to instantaneous.
|
132
112
|
|
@@ -146,7 +126,7 @@ class Action:
|
|
146
126
|
"""
|
147
127
|
return self._type == ActionType.INSTANTANEOUS
|
148
128
|
|
149
|
-
def set_holding(self) ->
|
129
|
+
def set_holding(self) -> 'Action':
|
150
130
|
"""
|
151
131
|
Set the action type to holding.
|
152
132
|
|
@@ -165,14 +145,9 @@ class Action:
|
|
165
145
|
"""
|
166
146
|
return self._type == ActionType.HOLDING
|
167
147
|
|
168
|
-
def process_update(self,
|
169
|
-
if (
|
170
|
-
self.
|
171
|
-
and event.type == pygame.MOUSEMOTION
|
172
|
-
and self.is_holding_type()
|
173
|
-
and pygame.MOUSEMOTION in self._mouse_control
|
174
|
-
):
|
175
|
-
self.data = {"pos": event.pos, "rel": event.rel}
|
148
|
+
def process_update(self,event:pygame.Event)->None:
|
149
|
+
if self.is_active() and event.type == pygame.MOUSEMOTION and self.is_holding_type() and pygame.MOUSEMOTION in self._mouse_control:
|
150
|
+
self.data = {"pos":event.pos,"rel":event.rel}
|
176
151
|
|
177
152
|
def process_activate(self, event: pygame.event.Event) -> bool:
|
178
153
|
"""
|
@@ -230,7 +205,10 @@ class Action:
|
|
230
205
|
if not self._holding:
|
231
206
|
self._active = False
|
232
207
|
return True
|
233
|
-
elif
|
208
|
+
elif (
|
209
|
+
event.type == pygame.MOUSEMOTION
|
210
|
+
and event.type in self._mouse_control
|
211
|
+
):
|
234
212
|
self.value = None
|
235
213
|
if event.type in self._holding:
|
236
214
|
self._holding.remove(event.type)
|
batFramework/actionContainer.py
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
import batFramework as bf
|
2
|
-
import pygame
|
3
2
|
|
4
3
|
|
5
4
|
class ActionContainer:
|
@@ -15,20 +14,14 @@ class ActionContainer:
|
|
15
14
|
for action in actions:
|
16
15
|
self._actions[action.get_name()] = action
|
17
16
|
|
18
|
-
def get(self,
|
17
|
+
def get(self,name:str)->bf.Action:
|
19
18
|
return self._actions.get(name)
|
20
19
|
|
21
|
-
def has_action(self, name:
|
20
|
+
def has_action(self, name:str):
|
22
21
|
return name in self._actions
|
23
22
|
|
24
|
-
def
|
25
|
-
return self._actions
|
26
|
-
|
27
|
-
def is_active(self, *names: str) -> bool:
|
28
|
-
return all(
|
29
|
-
self._actions.get(name).is_active() if name in self._actions else False
|
30
|
-
for name in names
|
31
|
-
)
|
23
|
+
def is_active(self, *names:str)->bool:
|
24
|
+
return all(self._actions.get(name).is_active() if name in self._actions else False for name in names)
|
32
25
|
|
33
26
|
def process_event(self, event):
|
34
27
|
for action in self._actions.values():
|
@@ -43,35 +36,3 @@ class ActionContainer:
|
|
43
36
|
def hard_reset(self):
|
44
37
|
for action in self._actions.values():
|
45
38
|
action.hard_reset()
|
46
|
-
|
47
|
-
|
48
|
-
class DirectionalKeyControls(ActionContainer):
|
49
|
-
def __init__(self):
|
50
|
-
super().__init__(
|
51
|
-
bf.Action("up").add_key_control(pygame.K_UP).set_holding(),
|
52
|
-
bf.Action("down").add_key_control(pygame.K_DOWN).set_holding(),
|
53
|
-
bf.Action("left").add_key_control(pygame.K_LEFT).set_holding(),
|
54
|
-
bf.Action("right").add_key_control(pygame.K_RIGHT).set_holding(),
|
55
|
-
)
|
56
|
-
|
57
|
-
|
58
|
-
class WASDControls(ActionContainer):
|
59
|
-
def __init__(self):
|
60
|
-
super().__init__(
|
61
|
-
bf.Action("up").add_key_control(pygame.K_w).set_holding(),
|
62
|
-
bf.Action("down").add_key_control(pygame.K_s).set_holding(),
|
63
|
-
bf.Action("left").add_key_control(pygame.K_a).set_holding(),
|
64
|
-
bf.Action("right").add_key_control(pygame.K_d).set_holding(),
|
65
|
-
)
|
66
|
-
|
67
|
-
|
68
|
-
class HybridControls(ActionContainer):
|
69
|
-
def __init__(self):
|
70
|
-
super().__init__(
|
71
|
-
bf.Action("up").add_key_control(pygame.K_UP, pygame.K_w).set_holding(),
|
72
|
-
bf.Action("down").add_key_control(pygame.K_DOWN, pygame.K_s).set_holding(),
|
73
|
-
bf.Action("left").add_key_control(pygame.K_LEFT, pygame.K_a).set_holding(),
|
74
|
-
bf.Action("right")
|
75
|
-
.add_key_control(pygame.K_RIGHT, pygame.K_r)
|
76
|
-
.set_holding(),
|
77
|
-
)
|
batFramework/animatedSprite.py
CHANGED
@@ -2,6 +2,7 @@ import batFramework as bf
|
|
2
2
|
import pygame
|
3
3
|
|
4
4
|
|
5
|
+
|
5
6
|
def search_index(target, lst):
|
6
7
|
cumulative_sum = 0
|
7
8
|
for index, value in enumerate(lst):
|
@@ -12,139 +13,105 @@ def search_index(target, lst):
|
|
12
13
|
|
13
14
|
|
14
15
|
class AnimState:
|
15
|
-
def __init__(
|
16
|
-
self
|
17
|
-
) -> None:
|
18
|
-
self.frames: list[pygame.Surface] =bf.utils.img_slice(
|
19
|
-
file, width, height,
|
20
|
-
False,convert_alpha
|
21
|
-
)
|
16
|
+
def __init__(self, file, width, height, frame_length_list:list|int) -> None:
|
17
|
+
self.frames: list[pygame.Surface] = bf.utils.img_slice(file, width, height)
|
22
18
|
self.frames_flipX: list[pygame.Surface] = bf.utils.img_slice(
|
23
|
-
file, width, height,
|
24
|
-
True,convert_alpha
|
19
|
+
file, width, height, True
|
25
20
|
)
|
26
|
-
|
27
|
-
self.name = name
|
28
|
-
self.duration_list :list[int]= []
|
29
|
-
self.duration_list_length = 0
|
30
|
-
self.set_duration_list(duration_list)
|
31
21
|
|
32
|
-
|
33
|
-
|
22
|
+
self.frame_length_list = []
|
23
|
+
self.ffl_length = 0
|
24
|
+
self.set_frame_length_list(frame_length_list)
|
34
25
|
|
35
|
-
def
|
36
|
-
return search_index(int(counter % self.
|
26
|
+
def get_frame_index(self, counter:float|int):
|
27
|
+
return search_index(int(counter % self.ffl_length), self.frame_length_list)
|
37
28
|
|
38
29
|
def get_frame(self, counter, flip):
|
39
|
-
i = self.
|
30
|
+
i = self.get_frame_index(counter)
|
40
31
|
return self.frames_flipX[i] if flip else self.frames[i]
|
41
32
|
|
42
|
-
def
|
43
|
-
if isinstance(
|
44
|
-
|
45
|
-
if len(
|
46
|
-
raise ValueError("
|
47
|
-
self.
|
48
|
-
self.
|
49
|
-
|
33
|
+
def set_frame_length_list(self,frame_length_list:list[int]|int):
|
34
|
+
if isinstance(frame_length_list,int):
|
35
|
+
frame_length_list = [frame_length_list] * len(self.frames)
|
36
|
+
if len(frame_length_list) != len(self.frames) :
|
37
|
+
raise ValueError("frame_length_list should have values for all frames")
|
38
|
+
self.frame_length_list = frame_length_list
|
39
|
+
self.ffl_length = sum(self.frame_length_list)
|
40
|
+
|
50
41
|
|
51
42
|
class AnimatedSprite(bf.DynamicEntity):
|
52
43
|
def __init__(self, size=None) -> None:
|
53
44
|
super().__init__(size, no_surface=True)
|
54
|
-
self.float_counter
|
45
|
+
self.float_counter = 0
|
55
46
|
self.animStates: dict[str, AnimState] = {}
|
56
|
-
self.
|
47
|
+
self.current_animState :str = ""
|
57
48
|
self.flipX = False
|
58
49
|
self._locked = False
|
59
|
-
self.paused : bool = False
|
60
|
-
|
61
|
-
def pause(self)->None:
|
62
|
-
self.paused = True
|
63
|
-
|
64
|
-
def resume(self)->None:
|
65
|
-
self.paused = False
|
66
50
|
|
67
|
-
def
|
68
|
-
self.paused = not self.paused
|
69
|
-
|
70
|
-
def set_counter(self, value: float)->None:
|
51
|
+
def set_counter(self,value:float):
|
71
52
|
self.float_counter = value
|
53
|
+
|
72
54
|
|
73
|
-
def
|
74
|
-
if not self.current_state : return
|
75
|
-
total = sum(self.current_state.duration_list)
|
76
|
-
frame_index = max(0,min(total,frame_index))
|
77
|
-
new_counter = 0
|
78
|
-
i = 0
|
79
|
-
while frame_index < total:
|
80
|
-
if self.current_state.counter_to_frame(new_counter)>=frame_index:
|
81
|
-
break
|
82
|
-
new_counter +=self.current_state.duration_list[i]
|
83
|
-
i+=1
|
84
|
-
self.set_counter(new_counter)
|
85
|
-
def lock(self)->None:
|
55
|
+
def lock_animState(self):
|
86
56
|
self._locked = True
|
87
57
|
|
88
|
-
def
|
58
|
+
def unlock_animState(self):
|
89
59
|
self._locked = False
|
90
60
|
|
91
|
-
def set_flipX(self, value)
|
61
|
+
def set_flipX(self, value):
|
92
62
|
self.flipX = value
|
93
63
|
|
94
|
-
def remove_animState(self, name:
|
95
|
-
if not name in self.animStates:
|
96
|
-
|
97
|
-
self.animStates.
|
98
|
-
|
99
|
-
self.current_animState = (
|
100
|
-
list(self.animStates.keys())[0] if self.animStates else ""
|
101
|
-
)
|
102
|
-
return True
|
103
|
-
|
64
|
+
def remove_animState(self, name:str):
|
65
|
+
if not name in self.animStates :return
|
66
|
+
self.animStates.pop(name)
|
67
|
+
if self.current_animState == name : self.current_animState = list(self.animStates.keys())[0] if self.animStates else ""
|
68
|
+
|
104
69
|
def add_animState(
|
105
|
-
self, name: str, file: str, size: tuple[int, int],
|
106
|
-
|
107
|
-
)->bool:
|
70
|
+
self, name: str, file: str, size: tuple[int, int], frame_length_list: list[int]
|
71
|
+
):
|
108
72
|
if name in self.animStates:
|
109
|
-
return
|
110
|
-
self.animStates[name] = AnimState(
|
111
|
-
if len(self.animStates) == 1:
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
def set_animState(self, state: str, reset_counter=True, lock=False)->bool:
|
73
|
+
return
|
74
|
+
self.animStates[name] = AnimState(file, *size, frame_length_list)
|
75
|
+
if len(self.animStates) == 1 : self.set_animState(name)
|
76
|
+
|
77
|
+
def set_animState(self, state:str, reset_counter=True, lock=False):
|
116
78
|
if state not in self.animStates or self._locked:
|
117
79
|
return False
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
if reset_counter or self.float_counter > sum(
|
80
|
+
self.current_animState = state
|
81
|
+
self.rect = (
|
82
|
+
self.animStates[self.current_animState]
|
83
|
+
.frames[0]
|
84
|
+
.get_frect(center=self.rect.center)
|
85
|
+
)
|
86
|
+
if reset_counter or self.float_counter > sum(
|
87
|
+
self.get_state().frame_length_list
|
88
|
+
):
|
125
89
|
self.float_counter = 0
|
126
90
|
if lock:
|
127
|
-
self.
|
91
|
+
self.lock_animState()
|
128
92
|
return True
|
129
93
|
|
130
|
-
def
|
131
|
-
return self.
|
94
|
+
def get_state(self):
|
95
|
+
return self.animStates.get(self.current_animState,None)
|
132
96
|
|
133
|
-
def
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
97
|
+
def get_frame_index(self):
|
98
|
+
return self.animStates[self.current_animState].get_frame_index(
|
99
|
+
self.float_counter
|
100
|
+
)
|
101
|
+
|
102
|
+
def update(self, dt: float):
|
103
|
+
if not self.animStates : return
|
104
|
+
self.float_counter += 60 * dt
|
105
|
+
if self.float_counter > self.get_state().ffl_length:
|
106
|
+
self.float_counter = 0
|
141
107
|
self.do_update(dt)
|
142
108
|
|
143
|
-
def draw(self, camera: bf.Camera) ->
|
144
|
-
if not self.visible or not camera.intersects(self.rect) or not self.
|
145
|
-
return
|
109
|
+
def draw(self, camera: bf.Camera) -> bool:
|
110
|
+
if not self.visible or not camera.intersects(self.rect) or not self.animStates:
|
111
|
+
return False
|
112
|
+
# pygame.draw.rect(camera.surface,"purple",camera.transpose(self.rect).move(2,2))
|
146
113
|
camera.surface.blit(
|
147
|
-
self.
|
114
|
+
self.get_state().get_frame(self.float_counter, self.flipX),
|
148
115
|
camera.transpose(self.rect),
|
149
116
|
)
|
150
|
-
return
|
117
|
+
return True
|
batFramework/audioManager.py
CHANGED
@@ -5,19 +5,24 @@ pygame.mixer.init()
|
|
5
5
|
|
6
6
|
|
7
7
|
class AudioManager(metaclass=bf.Singleton):
|
8
|
-
def __init__(self)
|
9
|
-
self.sounds: dict = {}
|
10
|
-
self.musics: dict = {}
|
11
|
-
self.current_music
|
12
|
-
self.music_volume
|
13
|
-
self.sound_volume
|
8
|
+
def __init__(self):
|
9
|
+
self.sounds: dict[str : dict[str, pygame.mixer.Sound, bool]] = {}
|
10
|
+
self.musics: dict[str:str] = {}
|
11
|
+
self.current_music = None
|
12
|
+
self.music_volume = 1
|
13
|
+
self.sound_volume = 1
|
14
14
|
pygame.mixer_music.set_endevent(bf.const.MUSIC_END_EVENT)
|
15
15
|
|
16
|
-
def free_sounds(self, force
|
16
|
+
def free_sounds(self, force=False):
|
17
17
|
if force:
|
18
18
|
self.sounds = {}
|
19
19
|
return
|
20
|
-
|
20
|
+
to_remove = []
|
21
|
+
for name, data in self.sounds.items():
|
22
|
+
if not data["persistent"]:
|
23
|
+
to_remove.append(name)
|
24
|
+
|
25
|
+
_ = [self.sounds.pop(i) for i in to_remove]
|
21
26
|
|
22
27
|
def set_sound_volume(self, volume: float):
|
23
28
|
self.sound_volume = volume
|
@@ -26,54 +31,38 @@ class AudioManager(metaclass=bf.Singleton):
|
|
26
31
|
self.music_volume = volume
|
27
32
|
pygame.mixer_music.set_volume(volume)
|
28
33
|
|
29
|
-
def has_sound(self, name
|
34
|
+
def has_sound(self, name):
|
30
35
|
return name in self.sounds
|
31
36
|
|
32
37
|
def load_sound(self, name, path, persistent=False) -> pygame.mixer.Sound:
|
33
38
|
if name in self.sounds:
|
34
39
|
return self.sounds[name]["sound"]
|
35
|
-
path = bf.
|
40
|
+
path = bf.utils.get_path(path)
|
36
41
|
self.sounds[name] = {
|
37
42
|
"path": path,
|
38
43
|
"sound": pygame.mixer.Sound(path),
|
39
|
-
"persistent": persistent
|
44
|
+
"persistent": persistent,
|
40
45
|
}
|
41
46
|
return self.sounds[name]["sound"]
|
42
47
|
|
43
|
-
def load_sounds(self,sound_data_list:list[tuple[str,str,bool]])->None:
|
44
|
-
for data in sound_data_list:
|
45
|
-
self.load_sound(*data)
|
46
|
-
return
|
47
|
-
|
48
48
|
def play_sound(self, name, volume=1):
|
49
|
-
|
50
|
-
|
51
|
-
self.sounds[name]["sound"].play()
|
52
|
-
except KeyError:
|
53
|
-
print(f"Sound '{name}' not loaded in AudioManager.")
|
49
|
+
self.sounds[name]["sound"].set_volume(volume * self.sound_volume)
|
50
|
+
self.sounds[name]["sound"].play()
|
54
51
|
|
55
52
|
def stop_sound(self, name):
|
56
|
-
|
53
|
+
if name in self.sounds:
|
57
54
|
self.sounds[name]["sound"].stop()
|
58
|
-
|
59
|
-
|
60
|
-
print(f"Sound '{name}' not loaded in AudioManager.")
|
55
|
+
|
61
56
|
def load_music(self, name, path):
|
62
|
-
self.musics[name] = bf.
|
63
|
-
|
64
|
-
|
65
|
-
def load_musics(self,music_data_list:list[tuple[str,str]]):
|
66
|
-
for data in music_data_list:
|
67
|
-
self.load_music(*data)
|
68
|
-
return
|
69
|
-
|
57
|
+
self.musics[name] = bf.utils.get_path(path)
|
58
|
+
|
70
59
|
def play_music(self, name, loop=0, fade=500):
|
71
|
-
|
60
|
+
if name in self.musics:
|
72
61
|
pygame.mixer_music.load(self.musics[name])
|
73
62
|
pygame.mixer_music.play(loop, fade_ms=fade)
|
74
63
|
self.current_music = name
|
75
|
-
|
76
|
-
print(f"Music '{name}' not
|
64
|
+
else:
|
65
|
+
print(f"Music '{name}' not found in AudioManager.")
|
77
66
|
|
78
67
|
def stop_music(self):
|
79
68
|
if not self.current_music:
|
@@ -94,6 +83,3 @@ class AudioManager(metaclass=bf.Singleton):
|
|
94
83
|
if not self.current_music:
|
95
84
|
return
|
96
85
|
pygame.mixer_music.unpause()
|
97
|
-
|
98
|
-
def get_current_music(self)->str|None:
|
99
|
-
return self.current_music
|