batframework 1.0.8a2__py3-none-any.whl → 1.0.8a4__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 +53 -50
- batFramework/action.py +126 -99
- batFramework/actionContainer.py +53 -9
- batFramework/animatedSprite.py +117 -73
- batFramework/audioManager.py +69 -26
- batFramework/camera.py +259 -69
- batFramework/constants.py +16 -54
- batFramework/cutscene.py +39 -29
- batFramework/cutsceneBlocks.py +36 -43
- batFramework/dynamicEntity.py +17 -9
- batFramework/easingController.py +58 -0
- batFramework/entity.py +48 -97
- batFramework/enums.py +113 -0
- batFramework/fontManager.py +65 -0
- batFramework/gui/__init__.py +10 -2
- batFramework/gui/button.py +9 -78
- batFramework/gui/clickableWidget.py +221 -0
- batFramework/gui/constraints/__init__.py +1 -0
- batFramework/gui/constraints/constraints.py +730 -0
- batFramework/gui/container.py +174 -32
- batFramework/gui/debugger.py +131 -43
- batFramework/gui/dialogueBox.py +99 -0
- batFramework/gui/draggableWidget.py +40 -0
- batFramework/gui/image.py +54 -18
- batFramework/gui/indicator.py +38 -21
- batFramework/gui/interactiveWidget.py +177 -13
- batFramework/gui/label.py +292 -74
- batFramework/gui/layout.py +219 -60
- batFramework/gui/meter.py +71 -0
- batFramework/gui/radioButton.py +84 -0
- batFramework/gui/root.py +134 -38
- batFramework/gui/shape.py +259 -57
- batFramework/gui/slider.py +230 -0
- batFramework/gui/style.py +10 -0
- batFramework/gui/styleManager.py +48 -0
- batFramework/gui/textInput.py +137 -0
- batFramework/gui/toggle.py +103 -51
- batFramework/gui/widget.py +329 -254
- batFramework/manager.py +40 -19
- batFramework/object.py +114 -0
- batFramework/particle.py +101 -0
- batFramework/renderGroup.py +67 -0
- batFramework/resourceManager.py +100 -0
- batFramework/scene.py +281 -123
- batFramework/sceneManager.py +141 -108
- batFramework/scrollingSprite.py +114 -0
- batFramework/sprite.py +51 -0
- batFramework/stateMachine.py +2 -2
- batFramework/tileset.py +46 -0
- batFramework/time.py +123 -58
- batFramework/transition.py +195 -124
- batFramework/utils.py +87 -151
- batframework-1.0.8a4.dist-info/LICENCE +21 -0
- batframework-1.0.8a4.dist-info/METADATA +55 -0
- batframework-1.0.8a4.dist-info/RECORD +58 -0
- batFramework/debugger.py +0 -48
- batFramework/easing.py +0 -71
- batFramework/gui/constraints.py +0 -204
- batFramework/gui/frame.py +0 -19
- batFramework/particles.py +0 -77
- batFramework/transitionManager.py +0 -0
- batframework-1.0.8a2.dist-info/METADATA +0 -58
- batframework-1.0.8a2.dist-info/RECORD +0 -42
- {batframework-1.0.8a2.dist-info → batframework-1.0.8a4.dist-info}/WHEEL +0 -0
- {batframework-1.0.8a2.dist-info → batframework-1.0.8a4.dist-info}/top_level.txt +0 -0
batFramework/animatedSprite.py
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
import batFramework as bf
|
2
2
|
import pygame
|
3
|
+
from typing import List, Dict, Tuple, Union, Optional
|
4
|
+
from enum import Enum
|
3
5
|
|
4
6
|
|
5
|
-
|
6
|
-
def search_index(target, lst):
|
7
|
+
def search_index(target: int, lst: List[int]) -> int:
|
7
8
|
cumulative_sum = 0
|
8
9
|
for index, value in enumerate(lst):
|
9
10
|
cumulative_sum += value
|
@@ -13,105 +14,148 @@ def search_index(target, lst):
|
|
13
14
|
|
14
15
|
|
15
16
|
class AnimState:
|
16
|
-
def __init__(
|
17
|
-
self
|
18
|
-
|
19
|
-
|
17
|
+
def __init__(
|
18
|
+
self,
|
19
|
+
name: str,
|
20
|
+
surface: pygame.Surface,
|
21
|
+
size: Tuple[int,int],
|
22
|
+
duration_list: Union[List[int], int],
|
23
|
+
) -> None:
|
24
|
+
self.frames: List[pygame.Surface] = list(
|
25
|
+
bf.utils.split_surface(
|
26
|
+
surface, size
|
27
|
+
).values()
|
28
|
+
)
|
29
|
+
self.frames_flipX: List[pygame.Surface] = list(
|
30
|
+
bf.utils.split_surface(surface, size,).values()
|
20
31
|
)
|
21
32
|
|
22
|
-
self.
|
23
|
-
self.
|
24
|
-
self.set_frame_length_list(frame_length_list)
|
33
|
+
self.name = name
|
34
|
+
self.set_duration_list(duration_list)
|
25
35
|
|
26
|
-
def
|
27
|
-
return
|
36
|
+
def __repr__(self):
|
37
|
+
return f"AnimState({self.name})"
|
38
|
+
|
39
|
+
def counter_to_frame(self, counter: Union[float, int]) -> int:
|
40
|
+
return search_index(
|
41
|
+
int(counter % self.duration_list_length), self.duration_list
|
42
|
+
)
|
28
43
|
|
29
|
-
def get_frame(self, counter, flip):
|
30
|
-
i = self.
|
44
|
+
def get_frame(self, counter: Union[float, int], flip: bool) -> pygame.Surface:
|
45
|
+
i = self.counter_to_frame(counter)
|
31
46
|
return self.frames_flipX[i] if flip else self.frames[i]
|
32
47
|
|
33
|
-
def
|
34
|
-
if isinstance(
|
35
|
-
|
36
|
-
if len(
|
37
|
-
raise ValueError("
|
38
|
-
self.
|
39
|
-
self.
|
40
|
-
|
41
|
-
|
42
|
-
class AnimatedSprite(bf.
|
43
|
-
def __init__(self, size=None) -> None:
|
48
|
+
def set_duration_list(self, duration_list: Union[List[int], int]):
|
49
|
+
if isinstance(duration_list, int):
|
50
|
+
duration_list = [duration_list] * len(self.frames)
|
51
|
+
if len(duration_list) != len(self.frames):
|
52
|
+
raise ValueError("duration_list should have values for all frames")
|
53
|
+
self.duration_list = duration_list
|
54
|
+
self.duration_list_length = sum(self.duration_list)
|
55
|
+
|
56
|
+
|
57
|
+
class AnimatedSprite(bf.Entity):
|
58
|
+
def __init__(self, size: Optional[Tuple[int, int]] = None) -> None:
|
44
59
|
super().__init__(size, no_surface=True)
|
45
|
-
self.float_counter = 0
|
46
|
-
self.animStates:
|
47
|
-
self.
|
48
|
-
self.flipX = False
|
49
|
-
self._locked = False
|
60
|
+
self.float_counter: float = 0
|
61
|
+
self.animStates: Dict[str, AnimState] = {}
|
62
|
+
self.current_state: Optional[AnimState] = None
|
63
|
+
self.flipX: bool = False
|
64
|
+
self._locked: bool = False
|
65
|
+
self._paused: bool = False
|
66
|
+
|
67
|
+
@property
|
68
|
+
def paused(self) -> bool:
|
69
|
+
return self._paused
|
50
70
|
|
51
|
-
|
71
|
+
@paused.setter
|
72
|
+
def paused(self, value: bool) -> None:
|
73
|
+
self._paused = value
|
74
|
+
|
75
|
+
def toggle_pause(self) -> None:
|
76
|
+
self.paused = not self.paused
|
77
|
+
|
78
|
+
def set_counter(self, value: float) -> None:
|
52
79
|
self.float_counter = value
|
53
|
-
|
54
80
|
|
55
|
-
def
|
81
|
+
def set_frame(self, frame_index: int) -> None:
|
82
|
+
if not self.current_state:
|
83
|
+
return
|
84
|
+
self.set_counter(sum(self.current_state.duration_list[:frame_index]))
|
85
|
+
|
86
|
+
def lock(self) -> None:
|
56
87
|
self._locked = True
|
57
88
|
|
58
|
-
def
|
89
|
+
def unlock(self) -> None:
|
59
90
|
self._locked = False
|
60
91
|
|
61
|
-
def set_flipX(self, value):
|
92
|
+
def set_flipX(self, value: bool) -> None:
|
62
93
|
self.flipX = value
|
63
94
|
|
64
|
-
def remove_animState(self, name:str):
|
65
|
-
if not
|
66
|
-
|
67
|
-
|
95
|
+
def remove_animState(self, name: str) -> bool:
|
96
|
+
if name not in self.animStates:
|
97
|
+
return False
|
98
|
+
self.animStates.pop(name)
|
99
|
+
if self.current_state and self.current_state.name == name:
|
100
|
+
self.current_state = (
|
101
|
+
list(self.animStates.values())[0] if self.animStates else None
|
102
|
+
)
|
103
|
+
return True
|
68
104
|
|
69
105
|
def add_animState(
|
70
|
-
self,
|
71
|
-
|
106
|
+
self,
|
107
|
+
name: str,
|
108
|
+
surface: pygame.Surface,
|
109
|
+
size: Tuple[int, int],
|
110
|
+
duration_list: Union[List[int], int],
|
111
|
+
) -> bool:
|
72
112
|
if name in self.animStates:
|
73
|
-
return
|
74
|
-
self.animStates[name] = AnimState(
|
75
|
-
|
113
|
+
return False
|
114
|
+
self.animStates[name] = AnimState(
|
115
|
+
name, surface, size, duration_list
|
116
|
+
)
|
117
|
+
if len(self.animStates) == 1:
|
118
|
+
self.set_animState(name)
|
119
|
+
return True
|
76
120
|
|
77
|
-
def set_animState(
|
121
|
+
def set_animState(
|
122
|
+
self, state: str, reset_counter: bool = True, lock: bool = False
|
123
|
+
) -> bool:
|
78
124
|
if state not in self.animStates or self._locked:
|
79
125
|
return False
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
if reset_counter or self.float_counter >
|
87
|
-
self.get_state().frame_length_list
|
88
|
-
):
|
126
|
+
|
127
|
+
animState = self.animStates[state]
|
128
|
+
self.current_state = animState
|
129
|
+
|
130
|
+
self.rect = self.current_state.frames[0].get_rect(center=self.rect.center)
|
131
|
+
|
132
|
+
if reset_counter or self.float_counter > animState.duration_list_length:
|
89
133
|
self.float_counter = 0
|
90
134
|
if lock:
|
91
|
-
self.
|
135
|
+
self.lock()
|
92
136
|
return True
|
93
137
|
|
94
|
-
def
|
95
|
-
return self.
|
138
|
+
def get_animState(self) -> Optional[AnimState]:
|
139
|
+
return self.current_state
|
96
140
|
|
97
|
-
def
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
self.float_counter += 60 * dt
|
105
|
-
if self.float_counter > self.get_state().ffl_length:
|
106
|
-
self.float_counter = 0
|
141
|
+
def update(self, dt: float) -> None:
|
142
|
+
s = self.get_animState()
|
143
|
+
if self.animStates and s is not None:
|
144
|
+
if not self.paused:
|
145
|
+
self.float_counter += 60 * dt
|
146
|
+
if self.float_counter > s.duration_list_length:
|
147
|
+
self.float_counter = 0
|
107
148
|
self.do_update(dt)
|
108
149
|
|
109
|
-
def draw(self, camera: bf.Camera) ->
|
110
|
-
if
|
111
|
-
|
112
|
-
|
150
|
+
def draw(self, camera: bf.Camera) -> None:
|
151
|
+
if (
|
152
|
+
not self.visible
|
153
|
+
or not camera.rect.colliderect(self.rect)
|
154
|
+
or not self.current_state
|
155
|
+
):
|
156
|
+
return
|
113
157
|
camera.surface.blit(
|
114
|
-
self.
|
115
|
-
camera.
|
158
|
+
self.current_state.get_frame(self.float_counter, self.flipX),
|
159
|
+
camera.world_to_screen(self.rect),
|
116
160
|
)
|
117
|
-
return
|
161
|
+
return
|
batFramework/audioManager.py
CHANGED
@@ -5,24 +5,25 @@ 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 = None
|
12
|
-
self.music_volume = 1
|
13
|
-
self.sound_volume = 1
|
8
|
+
def __init__(self) -> None:
|
9
|
+
self.sounds: dict = {}
|
10
|
+
self.musics: dict = {}
|
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=False):
|
16
|
+
def free_sounds(self, force: bool = False):
|
17
17
|
if force:
|
18
18
|
self.sounds = {}
|
19
19
|
return
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
to_remove.append(name)
|
20
|
+
self.sounds: dict = {
|
21
|
+
key: value for key, value in self.sounds.items() if value["persistent"]
|
22
|
+
}
|
24
23
|
|
25
|
-
|
24
|
+
def free_music(self):
|
25
|
+
if self.current_music:
|
26
|
+
pygame.mixer.music.unload(self.current_music)
|
26
27
|
|
27
28
|
def set_sound_volume(self, volume: float):
|
28
29
|
self.sound_volume = volume
|
@@ -31,13 +32,19 @@ class AudioManager(metaclass=bf.Singleton):
|
|
31
32
|
self.music_volume = volume
|
32
33
|
pygame.mixer_music.set_volume(volume)
|
33
34
|
|
34
|
-
def
|
35
|
+
def get_music_volume(self) -> float:
|
36
|
+
return self.music_volume
|
37
|
+
|
38
|
+
def get_sound_volume(self) -> float:
|
39
|
+
return self.sound_volume
|
40
|
+
|
41
|
+
def has_sound(self, name: str):
|
35
42
|
return name in self.sounds
|
36
43
|
|
37
44
|
def load_sound(self, name, path, persistent=False) -> pygame.mixer.Sound:
|
38
45
|
if name in self.sounds:
|
39
46
|
return self.sounds[name]["sound"]
|
40
|
-
path = bf.
|
47
|
+
path = bf.ResourceManager().get_path(path)
|
41
48
|
self.sounds[name] = {
|
42
49
|
"path": path,
|
43
50
|
"sound": pygame.mixer.Sound(path),
|
@@ -45,24 +52,57 @@ class AudioManager(metaclass=bf.Singleton):
|
|
45
52
|
}
|
46
53
|
return self.sounds[name]["sound"]
|
47
54
|
|
48
|
-
def
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
55
|
+
def load_sounds(self, sound_data_list: list[tuple[str, str, bool]]) -> None:
|
56
|
+
for data in sound_data_list:
|
57
|
+
self.load_sound(*data)
|
58
|
+
return
|
59
|
+
|
60
|
+
def play_sound(self, name, volume=1) -> bool:
|
61
|
+
"""
|
62
|
+
Play the sound file with the given name.
|
63
|
+
returns True if the sound was played
|
64
|
+
|
65
|
+
"""
|
66
|
+
try:
|
67
|
+
self.sounds[name]["sound"].set_volume(volume * self.sound_volume)
|
68
|
+
self.sounds[name]["sound"].play()
|
69
|
+
return True
|
70
|
+
except KeyError:
|
71
|
+
print(f"Sound '{name}' not loaded in AudioManager.")
|
72
|
+
return False
|
73
|
+
|
74
|
+
def stop_sound(self, name) -> bool:
|
75
|
+
try:
|
54
76
|
self.sounds[name]["sound"].stop()
|
77
|
+
return True
|
78
|
+
except KeyError:
|
79
|
+
return False
|
80
|
+
print(f"Sound '{name}' not loaded in AudioManager.")
|
55
81
|
|
56
82
|
def load_music(self, name, path):
|
57
|
-
self.musics[name] = bf.
|
58
|
-
|
59
|
-
|
60
|
-
|
83
|
+
self.musics[name] = bf.ResourceManager().get_path(path)
|
84
|
+
return
|
85
|
+
|
86
|
+
def load_musics(self, music_data_list: list[tuple[str, str]]):
|
87
|
+
for data in music_data_list:
|
88
|
+
self.load_music(*data)
|
89
|
+
return
|
90
|
+
|
91
|
+
def play_music(self, name, loop=0, fade=500) -> bool:
|
92
|
+
"""
|
93
|
+
Play the sound file with the given 'name'.
|
94
|
+
Fades with the given 'fade' time in ms.
|
95
|
+
Music will loop 'loop' times (indefinitely if -1).
|
96
|
+
returns True if the sound was played
|
97
|
+
"""
|
98
|
+
try:
|
61
99
|
pygame.mixer_music.load(self.musics[name])
|
62
100
|
pygame.mixer_music.play(loop, fade_ms=fade)
|
63
101
|
self.current_music = name
|
64
|
-
|
65
|
-
|
102
|
+
return True
|
103
|
+
except KeyError:
|
104
|
+
return False
|
105
|
+
# print(f"Music '{name}' not loaded in AudioManager.")
|
66
106
|
|
67
107
|
def stop_music(self):
|
68
108
|
if not self.current_music:
|
@@ -83,3 +123,6 @@ class AudioManager(metaclass=bf.Singleton):
|
|
83
123
|
if not self.current_music:
|
84
124
|
return
|
85
125
|
pygame.mixer_music.unpause()
|
126
|
+
|
127
|
+
def get_current_music(self) -> str | None:
|
128
|
+
return self.current_music
|