batframework 1.0.8a2__py3-none-any.whl → 1.0.8a3__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 +115 -65
- batFramework/audioManager.py +69 -26
- batFramework/camera.py +259 -69
- batFramework/constants.py +16 -54
- batFramework/cutscene.py +36 -29
- batFramework/cutsceneBlocks.py +37 -42
- batFramework/dynamicEntity.py +9 -7
- 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 +219 -0
- batFramework/gui/constraints/__init__.py +1 -0
- batFramework/gui/constraints/constraints.py +590 -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 +288 -74
- batFramework/gui/layout.py +219 -60
- batFramework/gui/meter.py +71 -0
- batFramework/gui/radioButton.py +84 -0
- batFramework/gui/root.py +128 -38
- batFramework/gui/shape.py +253 -57
- batFramework/gui/slider.py +246 -0
- batFramework/gui/style.py +10 -0
- batFramework/gui/styleManager.py +48 -0
- batFramework/gui/textInput.py +137 -0
- batFramework/gui/toggle.py +115 -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 +84 -0
- batFramework/scene.py +242 -114
- batFramework/sceneManager.py +145 -107
- batFramework/scrollingSprite.py +115 -0
- batFramework/sprite.py +51 -0
- batFramework/stateMachine.py +2 -2
- batFramework/tileset.py +46 -0
- batFramework/time.py +117 -57
- batFramework/transition.py +184 -126
- batFramework/utils.py +31 -156
- batframework-1.0.8a3.dist-info/LICENCE +21 -0
- batframework-1.0.8a3.dist-info/METADATA +55 -0
- batframework-1.0.8a3.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.8a3.dist-info}/WHEEL +0 -0
- {batframework-1.0.8a2.dist-info → batframework-1.0.8a3.dist-info}/top_level.txt +0 -0
batFramework/animatedSprite.py
CHANGED
@@ -2,7 +2,6 @@ import batFramework as bf
|
|
2
2
|
import pygame
|
3
3
|
|
4
4
|
|
5
|
-
|
6
5
|
def search_index(target, lst):
|
7
6
|
cumulative_sum = 0
|
8
7
|
for index, value in enumerate(lst):
|
@@ -13,105 +12,156 @@ def search_index(target, lst):
|
|
13
12
|
|
14
13
|
|
15
14
|
class AnimState:
|
16
|
-
def __init__(
|
17
|
-
self
|
18
|
-
|
19
|
-
|
15
|
+
def __init__(
|
16
|
+
self,
|
17
|
+
name: str,
|
18
|
+
surface: pygame.Surface,
|
19
|
+
width,
|
20
|
+
height,
|
21
|
+
duration_list: list | int,
|
22
|
+
) -> None:
|
23
|
+
self.frames: list[pygame.Surface] = list(
|
24
|
+
bf.utils.split_surface(
|
25
|
+
surface, width, height, False, convert_alpha
|
26
|
+
).values()
|
27
|
+
)
|
28
|
+
self.frames_flipX: list[pygame.Surface] = list(
|
29
|
+
bf.utils.split_surface(surface, width, height, True, convert_alpha).values()
|
20
30
|
)
|
21
31
|
|
22
|
-
self.
|
23
|
-
self.
|
24
|
-
self.
|
32
|
+
self.name = name
|
33
|
+
self.duration_list: list[int] = []
|
34
|
+
self.duration_list_length = 0
|
35
|
+
self.set_duration_list(duration_list)
|
25
36
|
|
26
|
-
def
|
27
|
-
return
|
37
|
+
def __repr__(self):
|
38
|
+
return f"AnimState({self.name})"
|
39
|
+
|
40
|
+
def counter_to_frame(self, counter: float | int) -> int:
|
41
|
+
return search_index(
|
42
|
+
int(counter % self.duration_list_length), self.duration_list
|
43
|
+
)
|
28
44
|
|
29
45
|
def get_frame(self, counter, flip):
|
30
|
-
i = self.
|
46
|
+
i = self.counter_to_frame(counter)
|
31
47
|
return self.frames_flipX[i] if flip else self.frames[i]
|
32
48
|
|
33
|
-
def
|
34
|
-
if isinstance(
|
35
|
-
|
36
|
-
if len(
|
37
|
-
raise ValueError("
|
38
|
-
self.
|
39
|
-
self.
|
40
|
-
|
49
|
+
def set_duration_list(self, duration_list: list[int] | int):
|
50
|
+
if isinstance(duration_list, int):
|
51
|
+
duration_list = [duration_list] * len(self.frames)
|
52
|
+
if len(duration_list) != len(self.frames):
|
53
|
+
raise ValueError("duration_list should have values for all frames")
|
54
|
+
self.duration_list = duration_list
|
55
|
+
self.duration_list_length = sum(self.duration_list)
|
56
|
+
|
41
57
|
|
42
58
|
class AnimatedSprite(bf.DynamicEntity):
|
43
59
|
def __init__(self, size=None) -> None:
|
44
60
|
super().__init__(size, no_surface=True)
|
45
|
-
self.float_counter = 0
|
61
|
+
self.float_counter: float = 0
|
46
62
|
self.animStates: dict[str, AnimState] = {}
|
47
|
-
self.
|
63
|
+
self.current_state: AnimState | None = None
|
48
64
|
self.flipX = False
|
49
65
|
self._locked = False
|
66
|
+
self.paused: bool = False
|
67
|
+
|
68
|
+
def pause(self) -> None:
|
69
|
+
self.paused = True
|
70
|
+
|
71
|
+
def resume(self) -> None:
|
72
|
+
self.paused = False
|
50
73
|
|
51
|
-
def
|
74
|
+
def toggle_pause(self) -> None:
|
75
|
+
self.paused = not self.paused
|
76
|
+
|
77
|
+
def set_counter(self, value: float) -> None:
|
52
78
|
self.float_counter = value
|
53
|
-
|
54
79
|
|
55
|
-
def
|
80
|
+
def set_frame(self, frame_index: int) -> None:
|
81
|
+
if not self.current_state:
|
82
|
+
return
|
83
|
+
total = sum(self.current_state.duration_list)
|
84
|
+
frame_index = max(0, min(total, frame_index))
|
85
|
+
new_counter = 0
|
86
|
+
i = 0
|
87
|
+
while frame_index < total:
|
88
|
+
if self.current_state.counter_to_frame(new_counter) >= frame_index:
|
89
|
+
break
|
90
|
+
new_counter += self.current_state.duration_list[i]
|
91
|
+
i += 1
|
92
|
+
self.set_counter(new_counter)
|
93
|
+
|
94
|
+
def lock(self) -> None:
|
56
95
|
self._locked = True
|
57
96
|
|
58
|
-
def
|
97
|
+
def unlock(self) -> None:
|
59
98
|
self._locked = False
|
60
99
|
|
61
|
-
def set_flipX(self, value):
|
100
|
+
def set_flipX(self, value) -> None:
|
62
101
|
self.flipX = value
|
63
102
|
|
64
|
-
def remove_animState(self, name:str):
|
65
|
-
if not name in self.animStates
|
66
|
-
|
67
|
-
|
103
|
+
def remove_animState(self, name: str) -> bool:
|
104
|
+
if not name in self.animStates:
|
105
|
+
return False
|
106
|
+
self.animStates.pop(name)
|
107
|
+
if self.current_state and self.current_state.name == name:
|
108
|
+
self.current_animState = (
|
109
|
+
list(self.animStates.keys())[0] if self.animStates else ""
|
110
|
+
)
|
111
|
+
return True
|
68
112
|
|
69
113
|
def add_animState(
|
70
|
-
self,
|
71
|
-
|
114
|
+
self,
|
115
|
+
name: str,
|
116
|
+
surface: pygame.Surface,
|
117
|
+
size: tuple[int, int],
|
118
|
+
duration_list: list[int],
|
119
|
+
convert_alpha: bool = True,
|
120
|
+
) -> bool:
|
72
121
|
if name in self.animStates:
|
73
|
-
return
|
74
|
-
self.animStates[name] = AnimState(
|
75
|
-
if len(self.animStates) == 1
|
122
|
+
return False
|
123
|
+
self.animStates[name] = AnimState(name, surface, *size, duration_list)
|
124
|
+
if len(self.animStates) == 1:
|
125
|
+
self.set_animState(name)
|
126
|
+
return True
|
76
127
|
|
77
|
-
def set_animState(self, state:str, reset_counter=True, lock=False):
|
128
|
+
def set_animState(self, state: str, reset_counter=True, lock=False) -> bool:
|
78
129
|
if state not in self.animStates or self._locked:
|
79
130
|
return False
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
if reset_counter or self.float_counter > sum(
|
87
|
-
self.get_state().frame_length_list
|
88
|
-
):
|
131
|
+
|
132
|
+
animState = self.animStates[state]
|
133
|
+
self.current_state = animState
|
134
|
+
|
135
|
+
self.rect = self.current_state.frames[0].get_frect(center=self.rect.center)
|
136
|
+
|
137
|
+
if reset_counter or self.float_counter > sum(animState.duration_list):
|
89
138
|
self.float_counter = 0
|
90
139
|
if lock:
|
91
|
-
self.
|
140
|
+
self.lock()
|
92
141
|
return True
|
93
142
|
|
94
|
-
def
|
95
|
-
return self.
|
143
|
+
def get_animState(self) -> AnimState | None:
|
144
|
+
return self.current_state
|
96
145
|
|
97
|
-
def
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
if self.float_counter > self.get_state().ffl_length:
|
106
|
-
self.float_counter = 0
|
146
|
+
def update(self, dt: float) -> None:
|
147
|
+
s = self.get_animState()
|
148
|
+
if not self.animStates or s is None:
|
149
|
+
return
|
150
|
+
if not self.paused:
|
151
|
+
self.float_counter += 60 * dt
|
152
|
+
if self.float_counter > s.duration_list_length:
|
153
|
+
self.float_counter = 0
|
107
154
|
self.do_update(dt)
|
108
155
|
|
109
|
-
def draw(self, camera: bf.Camera) ->
|
110
|
-
if
|
111
|
-
|
112
|
-
|
156
|
+
def draw(self, camera: bf.Camera) -> int:
|
157
|
+
if (
|
158
|
+
not self.visible
|
159
|
+
or not camera.rect.colliderect(self.rect)
|
160
|
+
or not self.current_state
|
161
|
+
):
|
162
|
+
return 0
|
113
163
|
camera.surface.blit(
|
114
|
-
self.
|
115
|
-
camera.
|
164
|
+
self.current_state.get_frame(self.float_counter, self.flipX),
|
165
|
+
camera.world_to_screen(self.rect),
|
116
166
|
)
|
117
|
-
return
|
167
|
+
return 1
|
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
|