batframework 1.0.8a9__py3-none-any.whl → 1.0.8a10__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 +68 -51
- batFramework/action.py +126 -99
- batFramework/actionContainer.py +53 -9
- batFramework/animatedSprite.py +141 -82
- batFramework/audioManager.py +69 -26
- batFramework/camera.py +259 -69
- batFramework/character.py +27 -0
- batFramework/constants.py +16 -54
- batFramework/cutscene.py +39 -29
- batFramework/cutsceneBlocks.py +36 -43
- batFramework/dynamicEntity.py +18 -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 +220 -0
- batFramework/gui/constraints/__init__.py +1 -0
- batFramework/gui/constraints/constraints.py +815 -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 +56 -20
- batFramework/gui/indicator.py +38 -21
- batFramework/gui/interactiveWidget.py +192 -13
- batFramework/gui/label.py +309 -74
- batFramework/gui/layout.py +231 -63
- batFramework/gui/meter.py +74 -0
- batFramework/gui/radioButton.py +84 -0
- batFramework/gui/root.py +134 -38
- batFramework/gui/shape.py +237 -57
- batFramework/gui/slider.py +240 -0
- batFramework/gui/style.py +10 -0
- batFramework/gui/styleManager.py +48 -0
- batFramework/gui/textInput.py +247 -0
- batFramework/gui/toggle.py +101 -51
- batFramework/gui/widget.py +358 -250
- batFramework/manager.py +52 -19
- batFramework/object.py +123 -0
- batFramework/particle.py +115 -0
- batFramework/renderGroup.py +67 -0
- batFramework/resourceManager.py +100 -0
- batFramework/scene.py +281 -123
- batFramework/sceneManager.py +178 -116
- batFramework/scrollingSprite.py +114 -0
- batFramework/sprite.py +51 -0
- batFramework/stateMachine.py +11 -8
- batFramework/templates/__init__.py +2 -0
- batFramework/templates/character.py +44 -0
- batFramework/templates/states.py +166 -0
- batFramework/tileset.py +46 -0
- batFramework/time.py +145 -58
- batFramework/transition.py +195 -124
- batFramework/triggerZone.py +1 -1
- batFramework/utils.py +112 -147
- batframework-1.0.8a10.dist-info/LICENCE +21 -0
- batframework-1.0.8a10.dist-info/METADATA +43 -0
- batframework-1.0.8a10.dist-info/RECORD +62 -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.8a9.dist-info/METADATA +0 -53
- batframework-1.0.8a9.dist-info/RECORD +0 -42
- {batframework-1.0.8a9.dist-info → batframework-1.0.8a10.dist-info}/WHEEL +0 -0
- {batframework-1.0.8a9.dist-info → batframework-1.0.8a10.dist-info}/top_level.txt +0 -0
batFramework/sceneManager.py
CHANGED
@@ -1,165 +1,227 @@
|
|
1
1
|
import batFramework as bf
|
2
2
|
import pygame
|
3
|
+
from typing import Self
|
3
4
|
|
4
5
|
|
6
|
+
def swap(lst, index1, index2):
|
7
|
+
lst[index1], lst[index2] = lst[index2], lst[index1]
|
8
|
+
|
5
9
|
|
6
10
|
class SceneManager:
|
7
|
-
def __init__(self
|
8
|
-
self.
|
9
|
-
self.
|
11
|
+
def __init__(self) -> None:
|
12
|
+
self.scenes: list[bf.Scene] = []
|
13
|
+
self.shared_events = {pygame.WINDOWRESIZED}
|
10
14
|
|
11
|
-
self.transitions: list[bf.BaseTransition] = []
|
12
|
-
self.set_sharedVar("is_debugging_func", lambda: self._debugging)
|
13
|
-
self.set_sharedVar("in_transition", False)
|
14
15
|
self.set_sharedVar("in_cutscene", False)
|
16
|
+
self.set_sharedVar("player_has_control", True)
|
17
|
+
self.old_player_control = True
|
18
|
+
self.debug_mode: bf.enums.debugMode = bf.debugMode.HIDDEN
|
19
|
+
self.current_transitions: dict[str, bf.transition.Transition] = {}
|
15
20
|
|
16
|
-
|
17
|
-
for index,s in enumerate(
|
18
|
-
s.set_manager(self)
|
21
|
+
def init_scenes(self, *initial_scenes:bf.Scene):
|
22
|
+
for index, s in enumerate(initial_scenes):
|
19
23
|
s.set_scene_index(index)
|
20
|
-
|
21
|
-
|
24
|
+
for s in reversed(initial_scenes):
|
25
|
+
self.add_scene(s)
|
26
|
+
# self.scenes = list(initial_scenes)
|
27
|
+
self.set_scene(initial_scenes[0].get_name())
|
22
28
|
self.update_scene_states()
|
23
29
|
|
30
|
+
def set_shared_event(self, event: pygame.Event) -> None:
|
31
|
+
"""
|
32
|
+
Add an event that will be propagated to all active scenes, not just the one on top.
|
33
|
+
"""
|
34
|
+
self.shared_events.add(event)
|
35
|
+
|
24
36
|
def print_status(self):
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
37
|
+
"""
|
38
|
+
Print detailed information about the current state of the scenes and shared variables.
|
39
|
+
"""
|
40
|
+
|
41
|
+
def format_scene_info(scene):
|
42
|
+
status = 'Active' if scene.active else 'Inactive'
|
43
|
+
visibility = 'Visible' if scene.visible else 'Invisible'
|
44
|
+
return f"{scene.name:<30} | {status:<8} | {visibility:<10} | Index={scene.scene_index}"
|
45
|
+
|
46
|
+
def format_shared_variable(name, value):
|
47
|
+
return f"[{name}] = {value}"
|
48
|
+
|
49
|
+
print("\n" + "=" * 50)
|
50
|
+
print(" SCENE STATUS".center(50))
|
51
|
+
print("=" * 50)
|
52
|
+
|
53
|
+
# Print scene information
|
54
|
+
if self.scenes:
|
55
|
+
header = f"{'Scene Name':<30} | {'Status':<8} | {'Visibility':<10} | {'Index':<7}"
|
56
|
+
print(header)
|
57
|
+
print("-" * 50)
|
58
|
+
print("\n".join(format_scene_info(s) for s in self.scenes))
|
59
|
+
else:
|
60
|
+
print("No scenes available.")
|
61
|
+
|
62
|
+
# Print debugging mode status
|
63
|
+
print("\n" + "=" * 50)
|
64
|
+
print(" DEBUGGING STATUS".center(50))
|
65
|
+
print("=" * 50)
|
66
|
+
print(f"[Debugging Mode] = {self.debug_mode}")
|
67
|
+
|
68
|
+
# Print shared variables
|
69
|
+
print("\n" + "=" * 50)
|
70
|
+
print(" SHARED VARIABLES".center(50))
|
71
|
+
print("=" * 50)
|
72
|
+
|
73
|
+
if bf.ResourceManager().shared_variables:
|
74
|
+
for name, value in bf.ResourceManager().shared_variables.items():
|
75
|
+
print(format_shared_variable(name, value))
|
76
|
+
else:
|
77
|
+
print("No shared variables available.")
|
78
|
+
|
79
|
+
print("=" * 50 + "\n")
|
80
|
+
|
81
|
+
|
82
|
+
def set_sharedVar(self, name, value) -> None:
|
83
|
+
bf.ResourceManager().set_sharedVar(name,value)
|
84
|
+
|
85
|
+
def get_sharedVar(self, name, error_value=None):
|
86
|
+
return bf.ResourceManager().get_sharedVar(name, error_value)
|
87
|
+
|
88
|
+
def get_current_scene_name(self) -> str:
|
89
|
+
"""get the name of the current scene"""
|
90
|
+
return self.scenes[0].get_name()
|
91
|
+
|
92
|
+
def get_current_scene(self) -> bf.Scene:
|
93
|
+
return self.scenes[0]
|
49
94
|
|
50
95
|
def update_scene_states(self):
|
51
|
-
self.active_scenes = [s for s in reversed(self.
|
52
|
-
self.visible_scenes = [s for s in reversed(self.
|
96
|
+
self.active_scenes = [s for s in reversed(self.scenes) if s.active]
|
97
|
+
self.visible_scenes = [s for s in reversed(self.scenes) if s.visible]
|
53
98
|
|
54
99
|
def add_scene(self, scene: bf.Scene):
|
55
|
-
if scene in self.
|
100
|
+
if scene in self.scenes and not self.has_scene(scene.name):
|
56
101
|
return
|
57
102
|
scene.set_manager(self)
|
58
103
|
scene.do_when_added()
|
59
|
-
self.
|
104
|
+
self.scenes.insert(0, scene)
|
60
105
|
|
61
106
|
def remove_scene(self, name: str):
|
62
|
-
self.
|
107
|
+
self.scenes = [s for s in self.scenes if s.name != name]
|
63
108
|
|
64
109
|
def has_scene(self, name):
|
65
|
-
return any(name == scene.
|
110
|
+
return any(name == scene.name for scene in self.scenes)
|
66
111
|
|
67
112
|
def get_scene(self, name):
|
68
113
|
if not self.has_scene(name):
|
69
114
|
return None
|
70
|
-
for scene in self.
|
71
|
-
if scene.
|
115
|
+
for scene in self.scenes:
|
116
|
+
if scene.name == name:
|
72
117
|
return scene
|
73
118
|
|
74
|
-
def
|
75
|
-
if
|
76
|
-
return
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
)
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
self.
|
100
|
-
self.
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
self.
|
113
|
-
self.
|
114
|
-
|
119
|
+
def get_scene_at(self, index: int) -> bf.Scene | None:
|
120
|
+
if index < 0 or index >= len(self.scenes):
|
121
|
+
return None
|
122
|
+
return self.scenes[index]
|
123
|
+
|
124
|
+
def transition_to_scene(
|
125
|
+
self,
|
126
|
+
scene_name: str,
|
127
|
+
transition: bf.transition.Transition = bf.transition.Fade(0.1),
|
128
|
+
index: int = 0,
|
129
|
+
):
|
130
|
+
target_scene = self.get_scene(scene_name)
|
131
|
+
if not target_scene:
|
132
|
+
print(f"Scene '{scene_name}' does not exist")
|
133
|
+
return
|
134
|
+
if len(self.scenes) == 0 or index >= len(self.scenes) or index < 0:
|
135
|
+
return
|
136
|
+
source_surface = bf.const.SCREEN.copy()
|
137
|
+
dest_surface = bf.const.SCREEN.copy()
|
138
|
+
|
139
|
+
# self.draw(source_surface)
|
140
|
+
target_scene.draw(dest_surface)
|
141
|
+
target_scene.do_on_enter_early()
|
142
|
+
self.get_scene_at(index).do_on_exit_early()
|
143
|
+
self.current_transitions = {"scene_name": scene_name, "transition": transition}
|
144
|
+
transition.set_start_callback(lambda: self._start_transition(target_scene))
|
145
|
+
transition.set_end_callback(lambda: self._end_transition(scene_name, index))
|
146
|
+
transition.set_source(source_surface)
|
147
|
+
transition.set_dest(dest_surface)
|
148
|
+
transition.start()
|
149
|
+
|
150
|
+
def _start_transition(self, target_scene: bf.Scene):
|
151
|
+
target_scene.set_active(True)
|
152
|
+
target_scene.set_visible(True)
|
153
|
+
self.old_player_control = bool(self.get_sharedVar("player_has_control"))
|
154
|
+
self.set_sharedVar("player_has_control", False)
|
155
|
+
|
156
|
+
def _end_transition(self, scene_name, index):
|
157
|
+
self.set_scene(scene_name, index, True)
|
158
|
+
self.current_transitions.clear()
|
159
|
+
|
160
|
+
def set_scene(self, scene_name, index=0, ignore_early: bool = False):
|
161
|
+
target_scene = self.get_scene(scene_name)
|
162
|
+
if not target_scene:
|
163
|
+
print(f"'{scene_name}' does not exist")
|
164
|
+
return
|
165
|
+
if len(self.scenes) == 0 or index >= len(self.scenes) or index < 0:
|
166
|
+
return
|
167
|
+
|
168
|
+
# switch
|
169
|
+
if not ignore_early:
|
170
|
+
self.scenes[index].do_on_exit_early()
|
171
|
+
self.scenes[index].on_exit()
|
172
|
+
# re-insert scene at index 0
|
173
|
+
self.scenes.remove(target_scene)
|
174
|
+
self.scenes.insert(index, target_scene)
|
175
|
+
_ = [s.set_scene_index(i) for i, s in enumerate(self.scenes)]
|
176
|
+
if not ignore_early:
|
177
|
+
self.scenes[index].do_on_enter_early()
|
115
178
|
target_scene.on_enter()
|
116
179
|
|
180
|
+
self.set_sharedVar("player_has_control", self.old_player_control)
|
181
|
+
|
182
|
+
|
183
|
+
def cycle_debug_mode(self):
|
184
|
+
current_index = self.debug_mode.value
|
185
|
+
next_index = (current_index + 1) % len(bf.debugMode)
|
186
|
+
return bf.debugMode(next_index)
|
117
187
|
|
118
188
|
def process_event(self, event: pygame.Event):
|
119
|
-
if self.transitions:
|
120
|
-
return
|
121
189
|
keys = pygame.key.get_pressed()
|
122
190
|
if (
|
123
191
|
keys[pygame.K_LCTRL]
|
192
|
+
and keys[pygame.K_LSHIFT]
|
124
193
|
and event.type == pygame.KEYDOWN
|
125
|
-
and event.key == pygame.K_d
|
126
|
-
):
|
127
|
-
self._debugging = (self._debugging + 1) % 3
|
128
|
-
return
|
129
|
-
elif (
|
130
|
-
keys[pygame.K_LCTRL]
|
131
|
-
and event.type == pygame.KEYDOWN
|
132
|
-
and event.key == pygame.K_p
|
133
194
|
):
|
134
|
-
|
135
|
-
|
195
|
+
if event.key == pygame.K_d:
|
196
|
+
self.debug_mode = self.cycle_debug_mode()
|
197
|
+
self.set_sharedVar("debug_mode", self.debug_mode)
|
198
|
+
return
|
199
|
+
if event.key == pygame.K_p:
|
200
|
+
self.print_status()
|
201
|
+
return
|
202
|
+
if event.type in self.shared_events:
|
203
|
+
[s.process_event(event) for s in self.scenes]
|
204
|
+
else:
|
205
|
+
self.scenes[0].process_event(event)
|
136
206
|
|
137
207
|
def update(self, dt: float) -> None:
|
138
|
-
if self.transitions:
|
139
|
-
transition = self.transitions[0]
|
140
|
-
transition.update(dt)
|
141
|
-
if transition.has_ended():
|
142
|
-
self.set_sharedVar("in_transition", False)
|
143
|
-
self.set_scene(transition.dest_scene_name,transition.index)
|
144
|
-
|
145
|
-
self.transitions.pop(0)
|
146
|
-
return
|
147
208
|
for scene in self.active_scenes:
|
148
209
|
scene.update(dt)
|
149
210
|
self.do_update(dt)
|
150
211
|
|
151
212
|
def do_update(self, dt: float):
|
152
|
-
|
213
|
+
pass
|
153
214
|
|
154
215
|
def draw(self, surface) -> None:
|
155
|
-
|
156
|
-
visible_scenes = self.visible_scenes.copy()
|
157
|
-
if self.transitions:
|
158
|
-
transition_scene_index = self.transitions[0].index
|
159
|
-
|
160
|
-
if transition_scene_index >=0:
|
161
|
-
self.transitions[0].draw(surface)
|
162
|
-
visible_scenes = [s for s in visible_scenes if s.scene_index < transition_scene_index]
|
163
|
-
|
164
|
-
for scene in visible_scenes:
|
216
|
+
for scene in self.visible_scenes:
|
165
217
|
scene.draw(surface)
|
218
|
+
if self.current_transitions:
|
219
|
+
self._draw_transition(surface)
|
220
|
+
|
221
|
+
def _draw_transition(self, surface):
|
222
|
+
self.current_transitions["transition"].set_source(surface)
|
223
|
+
tmp = bf.const.SCREEN.copy()
|
224
|
+
self.get_scene(self.current_transitions["scene_name"]).draw(tmp)
|
225
|
+
self.current_transitions["transition"].set_dest(tmp)
|
226
|
+
self.current_transitions["transition"].draw(surface)
|
227
|
+
return
|
@@ -0,0 +1,114 @@
|
|
1
|
+
from typing import Self, Iterator
|
2
|
+
from pygame.math import Vector2
|
3
|
+
import batFramework as bf
|
4
|
+
import pygame
|
5
|
+
|
6
|
+
|
7
|
+
class ScrollingSprite(bf.Sprite):
|
8
|
+
def __init__(
|
9
|
+
self,
|
10
|
+
data: pygame.Surface | str,
|
11
|
+
size: None | tuple[int, int] = None,
|
12
|
+
convert_alpha: bool = True,
|
13
|
+
):
|
14
|
+
self.scroll_value = Vector2(0, 0)
|
15
|
+
self.auto_scroll = Vector2(0, 0)
|
16
|
+
|
17
|
+
# Use integer values for the starting points, converted from floating point scroll values
|
18
|
+
|
19
|
+
super().__init__(data, size, convert_alpha)
|
20
|
+
self.original_width, self.original_height = self.original_surface.get_size()
|
21
|
+
|
22
|
+
def get_debug_outlines(self):
|
23
|
+
yield from super().get_debug_outlines()
|
24
|
+
for r in self._get_mosaic_rect_list():
|
25
|
+
yield r.move(*self.rect.topleft)
|
26
|
+
|
27
|
+
def set_image(
|
28
|
+
self, data: pygame.Surface | str, size: None | tuple[int, int] = None
|
29
|
+
) -> Self:
|
30
|
+
super().set_image(data, size)
|
31
|
+
self.original_width, self.original_height = self.original_surface.get_size()
|
32
|
+
return self
|
33
|
+
|
34
|
+
def set_autoscroll(self, x: float, y: float) -> Self:
|
35
|
+
self.auto_scroll.update(x, y)
|
36
|
+
return self
|
37
|
+
|
38
|
+
def set_scroll(self, x: float = None, y: float = None) -> Self:
|
39
|
+
self.scroll_value.update(
|
40
|
+
x if x else self.scroll_value.x, y if y else self.scroll_value.y
|
41
|
+
)
|
42
|
+
return self
|
43
|
+
|
44
|
+
def scroll(self, x: float, y: float) -> Self:
|
45
|
+
self.scroll_value += x, y
|
46
|
+
return self
|
47
|
+
|
48
|
+
def update(self, dt: float) -> None:
|
49
|
+
if self.auto_scroll:
|
50
|
+
self.scroll(*self.auto_scroll * dt)
|
51
|
+
original_width, original_height = self.original_surface.get_size()
|
52
|
+
|
53
|
+
# Use integer values for the starting points, converted from floating point scroll values
|
54
|
+
|
55
|
+
if self.scroll_value.x > self.original_width:
|
56
|
+
self.scroll_value.x -= self.original_width
|
57
|
+
if self.scroll_value.y > self.original_height:
|
58
|
+
self.scroll_value.y -= self.original_height
|
59
|
+
|
60
|
+
super().update(dt)
|
61
|
+
|
62
|
+
def set_size(self, size: tuple[int | None, int | None]) -> Self:
|
63
|
+
size = list(size)
|
64
|
+
if size[0] is None:
|
65
|
+
size[0] = self.rect.w
|
66
|
+
if size[1] is None:
|
67
|
+
size[1] = self.rect.h
|
68
|
+
|
69
|
+
self.surface = pygame.Surface(size).convert_alpha()
|
70
|
+
self.rect = self.surface.get_frect(topleft=self.rect.topleft)
|
71
|
+
return self
|
72
|
+
|
73
|
+
def _get_mosaic_rect_list(self) -> Iterator[pygame.Rect]:
|
74
|
+
# Use integer values for the starting points, converted from floating point scroll values
|
75
|
+
start_x = int(self.scroll_value.x % self.original_width)
|
76
|
+
start_y = int(self.scroll_value.y % self.original_height)
|
77
|
+
|
78
|
+
# Adjust start_x and start_y to begin tiling off-screen to the top-left, covering all visible area
|
79
|
+
if start_x != 0:
|
80
|
+
start_x -= self.original_width
|
81
|
+
if start_y != 0:
|
82
|
+
start_y -= self.original_height
|
83
|
+
|
84
|
+
# Set the region in which to tile
|
85
|
+
end_x = self.rect.w
|
86
|
+
end_y = self.rect.h
|
87
|
+
|
88
|
+
# Starting y_position for the inner loop
|
89
|
+
y_position = start_y
|
90
|
+
|
91
|
+
# if self.rect.w-1 < self.scroll_value.x < self.rect.w+1 : print(self.scroll_value.x,int(self.scroll_value.x % self.rect.w),start_x,self.rect.w,original_width)
|
92
|
+
# Generate all necessary rectangles
|
93
|
+
x = start_x
|
94
|
+
while x < end_x:
|
95
|
+
y = y_position
|
96
|
+
while y < end_y:
|
97
|
+
yield pygame.Rect(x, y, self.original_width, self.original_height)
|
98
|
+
y += self.original_height
|
99
|
+
x += self.original_width
|
100
|
+
return self
|
101
|
+
|
102
|
+
def draw(self, camera: bf.Camera) -> None:
|
103
|
+
if not (
|
104
|
+
self.visible
|
105
|
+
and (self.surface is not None)
|
106
|
+
and camera.rect.colliderect(self.rect)
|
107
|
+
):
|
108
|
+
return
|
109
|
+
# self.surface.fill((0, 0, 0, 0))
|
110
|
+
camera.surface.fblits(
|
111
|
+
[(self.original_surface, r.move(self.rect.x-camera.rect.x,self.rect.y-camera.rect.y)) for r in self._get_mosaic_rect_list()]
|
112
|
+
)
|
113
|
+
# camera.surface.blit(self.surface, camera.world_to_screen(self.rect))
|
114
|
+
return
|
batFramework/sprite.py
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
import batFramework as bf
|
2
|
+
import pygame
|
3
|
+
from typing import Self
|
4
|
+
|
5
|
+
|
6
|
+
class Sprite(bf.Entity):
|
7
|
+
def __init__(
|
8
|
+
self,
|
9
|
+
path=None,
|
10
|
+
size: None | tuple[int, int] = None,
|
11
|
+
convert_alpha: bool = True,
|
12
|
+
):
|
13
|
+
self.original_surface: pygame.Surface = None
|
14
|
+
|
15
|
+
super().__init__(convert_alpha=convert_alpha)
|
16
|
+
if path is not None:
|
17
|
+
self.from_path(path)
|
18
|
+
if size is not None and self.original_surface:
|
19
|
+
self.set_size(self.original_surface.get_size())
|
20
|
+
|
21
|
+
def set_size(self, size: tuple[float, float]) -> Self:
|
22
|
+
if size == self.rect.size:
|
23
|
+
return self
|
24
|
+
self.rect.size = size
|
25
|
+
self.surface = pygame.Surface(
|
26
|
+
(int(self.rect.w), int(self.rect.h)), self.surface_flags
|
27
|
+
)
|
28
|
+
if self.convert_alpha:
|
29
|
+
self.surface = self.surface.convert_alpha()
|
30
|
+
self.surface.fill((0, 0, 0, 0 if self.convert_alpha else 255))
|
31
|
+
self.surface.blit(
|
32
|
+
pygame.transform.scale(self.original_surface, self.rect.size), (0, 0)
|
33
|
+
)
|
34
|
+
return self
|
35
|
+
|
36
|
+
def from_path(self, path: str) -> Self:
|
37
|
+
tmp = bf.ResourceManager().get_image(path, self.convert_alpha)
|
38
|
+
if tmp is None:
|
39
|
+
return self
|
40
|
+
self.original_surface = tmp
|
41
|
+
size = self.original_surface.get_size()
|
42
|
+
self.set_size(size)
|
43
|
+
return self
|
44
|
+
|
45
|
+
def from_surface(self, surface: pygame.Surface) -> Self:
|
46
|
+
if surface is None:
|
47
|
+
return self
|
48
|
+
self.original_surface = surface
|
49
|
+
size = self.original_surface.get_size()
|
50
|
+
self.set_size(size)
|
51
|
+
return self
|
batFramework/stateMachine.py
CHANGED
@@ -1,18 +1,17 @@
|
|
1
1
|
import batFramework as bf
|
2
2
|
|
3
3
|
|
4
|
-
class StateMachine:
|
5
|
-
...
|
4
|
+
class StateMachine: ...
|
6
5
|
|
7
6
|
|
8
7
|
class State:
|
9
8
|
def __init__(self, name: str) -> None:
|
10
9
|
self.name = name
|
11
|
-
self.
|
10
|
+
self.parent: bf.Entity | bf.AnimatedSprite = None
|
12
11
|
self.state_machine: StateMachine = None
|
13
12
|
|
14
|
-
def
|
15
|
-
self.
|
13
|
+
def set_parent(self, parent: bf.Entity | bf.AnimatedSprite):
|
14
|
+
self.parent = parent
|
16
15
|
|
17
16
|
def set_stateMachine(self, stateMachine):
|
18
17
|
self.state_machine = stateMachine
|
@@ -28,22 +27,26 @@ class State:
|
|
28
27
|
|
29
28
|
|
30
29
|
class StateMachine:
|
31
|
-
def __init__(self,
|
30
|
+
def __init__(self, parent) -> None:
|
32
31
|
self.states: dict[str, State] = {}
|
33
|
-
self.
|
32
|
+
self.parent = parent
|
34
33
|
self.current_state = None
|
35
34
|
|
36
35
|
def add_state(self, state: State):
|
37
36
|
self.states[state.name] = state
|
38
|
-
state.
|
37
|
+
state.set_parent(self.parent)
|
39
38
|
state.set_stateMachine(self)
|
40
39
|
|
40
|
+
def remove_state(self,state_name: str):
|
41
|
+
self.states.pop(state_name,default=None)
|
42
|
+
|
41
43
|
def set_state(self, state_name: str):
|
42
44
|
if state_name in self.states:
|
43
45
|
if self.current_state:
|
44
46
|
self.current_state.on_exit()
|
45
47
|
self.current_state = self.states[state_name]
|
46
48
|
self.current_state.on_enter()
|
49
|
+
|
47
50
|
def get_current_state(self) -> State:
|
48
51
|
return self.current_state
|
49
52
|
|
@@ -0,0 +1,44 @@
|
|
1
|
+
import batFramework as bf
|
2
|
+
import pygame
|
3
|
+
from .states import *
|
4
|
+
|
5
|
+
class Platform2DCharacter(bf.Character):
|
6
|
+
def __init__(self):
|
7
|
+
super().__init__()
|
8
|
+
self.actions = bf.ActionContainer(
|
9
|
+
*bf.DirectionalKeyControls(),
|
10
|
+
bf.Action("jump").add_key_control(pygame.K_SPACE).set_holding()
|
11
|
+
)
|
12
|
+
self.on_ground : bool = False
|
13
|
+
self.max_jumps = 2
|
14
|
+
self.jump_counter = 0
|
15
|
+
self.jump_force = 150
|
16
|
+
self.speed = 100
|
17
|
+
self.acceleration = 30
|
18
|
+
self.friction = 0.7
|
19
|
+
self.gravity = 300
|
20
|
+
self.terminal_velocity = 1000
|
21
|
+
self.state_machine.set_state("idle")
|
22
|
+
|
23
|
+
|
24
|
+
def do_setup_animations(self):
|
25
|
+
self.add_animation(bf.Animation("idle"))
|
26
|
+
self.add_animation(bf.Animation("run"))
|
27
|
+
self.add_animation(bf.Animation("jump"))
|
28
|
+
self.add_animation(bf.Animation("fall"))
|
29
|
+
|
30
|
+
|
31
|
+
def do_setup_states(self):
|
32
|
+
self.state_machine.add_state(Platform2DIdle())
|
33
|
+
self.state_machine.add_state(Platform2DRun())
|
34
|
+
self.state_machine.add_state(Platform2DJump())
|
35
|
+
self.state_machine.add_state(Platform2DFall())
|
36
|
+
|
37
|
+
|
38
|
+
|
39
|
+
def do_reset_actions(self) -> None:
|
40
|
+
self.actions.reset()
|
41
|
+
|
42
|
+
def do_process_actions(self, event: pygame.Event) -> None:
|
43
|
+
self.actions.process_event(event)
|
44
|
+
|