batframework 1.0.8a4__py3-none-any.whl → 1.0.8a7__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 +15 -1
- batFramework/animatedSprite.py +65 -50
- batFramework/character.py +27 -0
- batFramework/dynamicEntity.py +1 -0
- batFramework/enums.py +2 -2
- batFramework/fontManager.py +2 -2
- batFramework/gui/clickableWidget.py +6 -7
- batFramework/gui/constraints/constraints.py +125 -40
- batFramework/gui/image.py +14 -14
- batFramework/gui/interactiveWidget.py +15 -0
- batFramework/gui/label.py +44 -27
- batFramework/gui/layout.py +23 -14
- batFramework/gui/meter.py +10 -7
- batFramework/gui/radioButton.py +1 -1
- batFramework/gui/shape.py +3 -25
- batFramework/gui/slider.py +40 -30
- batFramework/gui/textInput.py +160 -50
- batFramework/gui/toggle.py +20 -22
- batFramework/gui/widget.py +65 -32
- batFramework/manager.py +17 -5
- batFramework/object.py +17 -8
- batFramework/particle.py +18 -4
- batFramework/scene.py +1 -1
- batFramework/sceneManager.py +42 -13
- batFramework/stateMachine.py +9 -6
- batFramework/templates/__init__.py +2 -0
- batFramework/templates/character.py +44 -0
- batFramework/templates/states.py +166 -0
- batFramework/time.py +31 -9
- batFramework/transition.py +2 -2
- batFramework/triggerZone.py +1 -1
- batFramework/utils.py +35 -6
- {batframework-1.0.8a4.dist-info → batframework-1.0.8a7.dist-info}/METADATA +3 -15
- batframework-1.0.8a7.dist-info/RECORD +62 -0
- {batframework-1.0.8a4.dist-info → batframework-1.0.8a7.dist-info}/WHEEL +1 -1
- batframework-1.0.8a4.dist-info/RECORD +0 -58
- {batframework-1.0.8a4.dist-info → batframework-1.0.8a7.dist-info}/LICENCE +0 -0
- {batframework-1.0.8a4.dist-info → batframework-1.0.8a7.dist-info}/top_level.txt +0 -0
batFramework/gui/toggle.py
CHANGED
@@ -6,7 +6,7 @@ import pygame
|
|
6
6
|
|
7
7
|
|
8
8
|
class Toggle(Button):
|
9
|
-
def __init__(self, text: str, callback=None, default_value: bool = False) -> None:
|
9
|
+
def __init__(self, text: str = "", callback=None, default_value: bool = False) -> None:
|
10
10
|
self.value: bool = default_value
|
11
11
|
self.indicator: ToggleIndicator = ToggleIndicator(default_value)
|
12
12
|
self.gap: float | int = 0
|
@@ -55,37 +55,31 @@ class Toggle(Button):
|
|
55
55
|
def get_min_required_size(self) -> tuple[float, float]:
|
56
56
|
if not self.text_rect:
|
57
57
|
self.text_rect.size = self._get_text_rect_required_size()
|
58
|
-
w, h = self.text_rect.size
|
59
|
-
outline_offset = self._get_outline_offset()
|
60
|
-
|
61
58
|
size = (
|
62
59
|
max(
|
63
|
-
self.indicator.
|
64
|
-
w + self.font_object.point_size + (self.gap if self.text else 0),
|
60
|
+
self.indicator.get_min_required_size()[0],
|
61
|
+
self.text_rect.w + self.font_object.point_size + (self.gap if self.text else 0),
|
65
62
|
),
|
66
|
-
self.text_rect.h
|
63
|
+
self.text_rect.h,
|
67
64
|
)
|
68
65
|
return self.inflate_rect_by_padding((0, 0, *size)).size
|
69
66
|
|
70
67
|
def _build_layout(self) -> None:
|
71
|
-
|
72
68
|
gap = self.gap if self.text else 0
|
73
|
-
|
74
69
|
self.text_rect.size = self._get_text_rect_required_size()
|
75
70
|
|
76
|
-
|
71
|
+
#right part size
|
72
|
+
right_part_height = min(self.text_rect.h, self.font_object.point_size)
|
73
|
+
self.indicator.set_size_if_autoresize((right_part_height,right_part_height))
|
77
74
|
|
78
|
-
|
79
|
-
|
80
|
-
self.text_rect.w + gap + self.indicator.rect.w
|
81
|
-
self.text_rect.h + outline_offset[1]
|
75
|
+
#join left and right
|
76
|
+
joined_rect = pygame.FRect(
|
77
|
+
0, 0, self.text_rect.w + gap + self.indicator.rect.w, self.text_rect.h
|
82
78
|
)
|
83
79
|
|
84
|
-
point_size = min(tmp_rect.h, self.font_object.point_size)
|
85
|
-
self.indicator.set_size_if_autoresize((point_size,point_size))
|
86
80
|
|
87
81
|
if self.autoresize_h or self.autoresize_w:
|
88
|
-
target_rect = self.inflate_rect_by_padding(
|
82
|
+
target_rect = self.inflate_rect_by_padding(joined_rect)
|
89
83
|
if not self.autoresize_w:
|
90
84
|
target_rect.w = self.rect.w
|
91
85
|
if not self.autoresize_h:
|
@@ -95,14 +89,15 @@ class Toggle(Button):
|
|
95
89
|
self.build()
|
96
90
|
return
|
97
91
|
|
92
|
+
# ------------------------------------ size is ok
|
98
93
|
|
94
|
+
offset = self._get_outline_offset() if self.show_text_outline else (0,0)
|
99
95
|
padded_rect = self.get_padded_rect()
|
100
96
|
padded_relative = padded_rect.move(-self.rect.x, -self.rect.y)
|
101
97
|
|
102
|
-
|
98
|
+
self.align_text(joined_rect, padded_relative.move( offset), self.alignment)
|
99
|
+
self.text_rect.midleft = joined_rect.midleft
|
103
100
|
|
104
|
-
self.align_text(tmp_rect, padded_relative, self.alignment)
|
105
|
-
self.text_rect.midleft = tmp_rect.midleft
|
106
101
|
if self.text:
|
107
102
|
match self.spacing:
|
108
103
|
case bf.spacing.MAX:
|
@@ -110,5 +105,8 @@ class Toggle(Button):
|
|
110
105
|
case bf.spacing.MIN:
|
111
106
|
gap = 0
|
112
107
|
|
113
|
-
|
114
|
-
|
108
|
+
pos = self.text_rect.move(
|
109
|
+
self.rect.x + gap -offset[0],
|
110
|
+
self.rect.y + (self.text_rect.h / 2) - (right_part_height/ 2) -offset[1],
|
111
|
+
).topright
|
112
|
+
self.indicator.rect.topleft = pos
|
batFramework/gui/widget.py
CHANGED
@@ -35,6 +35,8 @@ class Widget(bf.Entity, metaclass=WidgetMeta):
|
|
35
35
|
self.is_root: bool = False
|
36
36
|
self.autoresize_w, self.autoresize_h = True, True
|
37
37
|
self.__constraint_iteration = 0
|
38
|
+
self.__constraints_to_ignore = []
|
39
|
+
self.__constraints_capture = None
|
38
40
|
|
39
41
|
def show(self) -> Self:
|
40
42
|
self.visit(lambda w: w.set_visible(True))
|
@@ -110,7 +112,7 @@ class Widget(bf.Entity, metaclass=WidgetMeta):
|
|
110
112
|
]
|
111
113
|
return self
|
112
114
|
|
113
|
-
def set_parent_scene(self, parent_scene: bf.Scene) -> Self:
|
115
|
+
def set_parent_scene(self, parent_scene: bf.Scene | None) -> Self:
|
114
116
|
super().set_parent_scene(parent_scene)
|
115
117
|
if parent_scene is None:
|
116
118
|
bf.StyleManager().remove_widget(self)
|
@@ -122,8 +124,8 @@ class Widget(bf.Entity, metaclass=WidgetMeta):
|
|
122
124
|
def set_parent(self, parent: "Widget") -> Self:
|
123
125
|
if parent == self.parent:
|
124
126
|
return self
|
125
|
-
if self.parent is not None:
|
126
|
-
|
127
|
+
# if self.parent is not None and self.parent != parent:
|
128
|
+
# self.parent.remove(self)
|
127
129
|
self.parent = parent
|
128
130
|
return self
|
129
131
|
|
@@ -194,41 +196,69 @@ class Widget(bf.Entity, metaclass=WidgetMeta):
|
|
194
196
|
self.constraints = result
|
195
197
|
self.constraints.sort(key=lambda c: c.priority)
|
196
198
|
self.dirty_constraints = True
|
199
|
+
self.__constraint_to_ignore = []
|
200
|
+
|
201
|
+
return self
|
202
|
+
|
203
|
+
|
204
|
+
def remove_constraints(self, *names: str) -> Self:
|
205
|
+
for c in self.constraints:
|
206
|
+
if c.name in names:
|
207
|
+
c.on_removal(self)
|
208
|
+
self.constraints = [c for c in self.constraints if c.name not in names]
|
209
|
+
self.__constraint_to_ignore = []
|
197
210
|
return self
|
198
211
|
|
199
212
|
def resolve_constraints(self) -> None:
|
200
213
|
if self.parent is None or not self.constraints:
|
201
214
|
self.dirty_constraints = False
|
202
215
|
return
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
216
|
+
|
217
|
+
if not self.__constraint_iteration:
|
218
|
+
self.__constraints_capture = None
|
219
|
+
else:
|
220
|
+
capture = tuple([c.priority for c in self.constraints])
|
221
|
+
if capture != self.__constraints_capture:
|
222
|
+
self.__constraints_capture = capture
|
223
|
+
self.__constraint_to_ignore = []
|
224
|
+
|
225
|
+
constraints = self.constraints.copy()
|
226
|
+
# If all are resolved early exit
|
227
|
+
if all(c.evaluate(self.parent,self) for c in constraints if c not in self.__constraint_to_ignore):
|
228
|
+
self.dirty_constraints = False
|
229
|
+
return
|
230
|
+
|
231
|
+
# # Here there might be a conflict between 2 or more constraints
|
232
|
+
# we have to determine which ones causes conflict and ignore the one with least priority
|
233
|
+
|
234
|
+
stop = False
|
235
|
+
|
236
|
+
while True:
|
237
|
+
stop = True
|
238
|
+
# first pass with 2 iterations to sort out the transformative constraints
|
239
|
+
for _ in range(2):
|
240
|
+
for c in constraints:
|
241
|
+
if c in self.__constraints_to_ignore:continue
|
242
|
+
if not c.evaluate(self.parent,self) :
|
243
|
+
c.apply(self.parent,self)
|
244
|
+
# second pass where we check conflicts
|
245
|
+
for c in constraints:
|
246
|
+
if c in self.__constraints_to_ignore:
|
247
|
+
continue
|
248
|
+
if not c.evaluate(self.parent,self):
|
249
|
+
# first pass invalidated this constraint
|
250
|
+
self.__constraints_to_ignore.append(c)
|
251
|
+
stop = False
|
252
|
+
break
|
253
|
+
|
254
|
+
if stop:
|
213
255
|
break
|
214
|
-
elif self.__constraint_iteration > MAX_CONSTRAINTS:
|
215
|
-
print(
|
216
|
-
self,
|
217
|
-
"CONSTRAINTS ERROR",
|
218
|
-
list(
|
219
|
-
c.name
|
220
|
-
for c in self.constraints
|
221
|
-
if not c.evaluate(self.parent, self)
|
222
|
-
),
|
223
|
-
)
|
224
|
-
self.dirty_constraints = False
|
225
|
-
return
|
226
|
-
# print("DONE")
|
227
|
-
self.dirty_constraints = False
|
228
256
|
|
229
|
-
|
230
|
-
|
231
|
-
|
257
|
+
if self.__constraints_to_ignore:
|
258
|
+
print("Constraints ignored : ",[str(c) for c in self.__constraints_to_ignore])
|
259
|
+
|
260
|
+
|
261
|
+
self.dirty_constraints = False
|
232
262
|
|
233
263
|
def has_constraint(self, name: str) -> bool:
|
234
264
|
return any(c.name == name for c in self.constraints)
|
@@ -236,7 +266,9 @@ class Widget(bf.Entity, metaclass=WidgetMeta):
|
|
236
266
|
def get_root(self) -> "Root":
|
237
267
|
if self.is_root:
|
238
268
|
return self
|
239
|
-
|
269
|
+
if self.parent:
|
270
|
+
return self.parent.get_root()
|
271
|
+
return None
|
240
272
|
|
241
273
|
def top_at(self, x: float | int, y: float | int) -> "None|Widget":
|
242
274
|
if self.children:
|
@@ -251,6 +283,7 @@ class Widget(bf.Entity, metaclass=WidgetMeta):
|
|
251
283
|
self.children.extend(children)
|
252
284
|
i = len(self.children)
|
253
285
|
for child in children:
|
286
|
+
|
254
287
|
child.set_render_order(i).set_parent(self).set_parent_scene(
|
255
288
|
self.parent_scene
|
256
289
|
)
|
@@ -262,8 +295,8 @@ class Widget(bf.Entity, metaclass=WidgetMeta):
|
|
262
295
|
def remove(self, *children: "Widget") -> Self:
|
263
296
|
for child in self.children:
|
264
297
|
if child in children:
|
265
|
-
self.children.remove(child)
|
266
298
|
child.set_parent(None).set_parent_scene(None)
|
299
|
+
self.children.remove(child)
|
267
300
|
if self.parent:
|
268
301
|
self.parent.do_sort_children = True
|
269
302
|
|
batFramework/manager.py
CHANGED
@@ -24,12 +24,24 @@ class Manager(bf.SceneManager):
|
|
24
24
|
pygame.display.set_icon(surf)
|
25
25
|
|
26
26
|
def print_status(self):
|
27
|
+
"""
|
28
|
+
Print detailed information about the current state of the scenes, shared variables,
|
29
|
+
and additional timers managed by the subclass.
|
30
|
+
"""
|
31
|
+
# Call the parent class's print_status method to include its information
|
27
32
|
super().print_status()
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
print("
|
33
|
+
|
34
|
+
# Add the timers information in a cohesive manner
|
35
|
+
print("\n" + "=" * 50)
|
36
|
+
print(" TIMERS".center(50))
|
37
|
+
print("=" * 50)
|
38
|
+
|
39
|
+
# Print the timers information
|
40
|
+
print(self._timeManager)
|
41
|
+
|
42
|
+
# End with a visual separator
|
43
|
+
print("=" * 50 + "\n")
|
44
|
+
|
33
45
|
|
34
46
|
def get_fps(self) -> float:
|
35
47
|
return self._clock.get_fps()
|
batFramework/object.py
CHANGED
@@ -8,7 +8,9 @@ if TYPE_CHECKING:
|
|
8
8
|
|
9
9
|
|
10
10
|
class Object:
|
11
|
-
|
11
|
+
__count = 0
|
12
|
+
__available_uid = set()
|
13
|
+
__used_uid = set()
|
12
14
|
|
13
15
|
def __init__(self) -> None:
|
14
16
|
self.rect = pygame.FRect(0, 0, 0, 0)
|
@@ -16,14 +18,17 @@ class Object:
|
|
16
18
|
self.parent_scene: bf.Scene | None = None
|
17
19
|
self.debug_color: tuple | str = "red"
|
18
20
|
self.render_order: int = 0
|
19
|
-
self.uid: int = Object.
|
20
|
-
Object.
|
21
|
+
self.uid: int = Object.__count
|
22
|
+
Object.__used_uid.add(self.uid)
|
21
23
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
if Object.__available_uid:
|
25
|
+
self.name = Object.__available_uid.pop()
|
26
|
+
else:
|
27
|
+
self.name = Object.__count
|
28
|
+
Object.__count += 1
|
29
|
+
|
30
|
+
def __del__(self):
|
31
|
+
Object.__available_uid.add(self.uid)
|
27
32
|
|
28
33
|
def set_position(self, x, y) -> Self:
|
29
34
|
self.rect.topleft = x, y
|
@@ -57,7 +62,11 @@ class Object:
|
|
57
62
|
pass
|
58
63
|
|
59
64
|
def set_uid(self, uid: int) -> Self:
|
65
|
+
if uid in Object.__used_uid:
|
66
|
+
print(f"set_uid error : UID '{uid}' is already in use")
|
67
|
+
return self
|
60
68
|
self.uid = uid
|
69
|
+
Object.__used_uid.add(uid)
|
61
70
|
return self
|
62
71
|
|
63
72
|
def add_tags(self, *tags) -> Self:
|
batFramework/particle.py
CHANGED
@@ -7,6 +7,10 @@ class Particle:
|
|
7
7
|
def __init__(self, *args, **kwargs):
|
8
8
|
self.dead = False
|
9
9
|
self.surface = None
|
10
|
+
self.generator = None
|
11
|
+
|
12
|
+
def do_when_added(self):
|
13
|
+
pass
|
10
14
|
|
11
15
|
def update(self, dt):
|
12
16
|
pass
|
@@ -21,7 +25,15 @@ class Particle:
|
|
21
25
|
class TimedParticle(Particle):
|
22
26
|
def __init__(self, duration):
|
23
27
|
super().__init__()
|
24
|
-
self.
|
28
|
+
self.duration = duration
|
29
|
+
|
30
|
+
def do_when_added(self):
|
31
|
+
if self.generator and self.generator.parent_scene:
|
32
|
+
self.timer = bf.SceneTimer(
|
33
|
+
self.duration, end_callback=self.kill,
|
34
|
+
scene_name=self.generator.parent_scene.name).start()
|
35
|
+
else:
|
36
|
+
self.timer = bf.Timer(self.duration, end_callback=self.kill).start()
|
25
37
|
|
26
38
|
|
27
39
|
class BasicParticle(TimedParticle):
|
@@ -72,6 +84,7 @@ class ParticleGenerator(bf.Entity):
|
|
72
84
|
self.particles: list[Particle] = []
|
73
85
|
|
74
86
|
def get_debug_outlines(self):
|
87
|
+
return
|
75
88
|
for particle in self.particles:
|
76
89
|
yield (
|
77
90
|
particle.rect.move(particle.rect.w // 2, particle.rect.h // 2),
|
@@ -79,7 +92,9 @@ class ParticleGenerator(bf.Entity):
|
|
79
92
|
)
|
80
93
|
yield (self.rect, "cyan")
|
81
94
|
|
82
|
-
def add_particle(self, particle):
|
95
|
+
def add_particle(self, particle:Particle):
|
96
|
+
particle.generator = self
|
97
|
+
particle.do_when_added()
|
83
98
|
self.particles.append(particle)
|
84
99
|
|
85
100
|
def clear(self):
|
@@ -94,8 +109,7 @@ class ParticleGenerator(bf.Entity):
|
|
94
109
|
for p in particles_to_remove:
|
95
110
|
self.particles.remove(p)
|
96
111
|
|
97
|
-
def draw(self, camera) ->
|
112
|
+
def draw(self, camera) -> None:
|
98
113
|
camera.surface.fblits(
|
99
114
|
[(p.surface, camera.world_to_screen(p.rect)) for p in self.particles]
|
100
115
|
)
|
101
|
-
return len(self.particles)
|
batFramework/scene.py
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
import re
|
3
|
-
from typing import TYPE_CHECKING, Any
|
4
3
|
from collections import OrderedDict
|
5
4
|
import itertools
|
6
5
|
|
6
|
+
from typing import TYPE_CHECKING, Any
|
7
7
|
if TYPE_CHECKING:
|
8
8
|
from .manager import Manager
|
9
9
|
from .sceneManager import SceneManager
|
batFramework/sceneManager.py
CHANGED
@@ -35,20 +35,49 @@ class SceneManager:
|
|
35
35
|
|
36
36
|
def print_status(self):
|
37
37
|
"""
|
38
|
-
Print
|
38
|
+
Print detailed information about the current state of the scenes and shared variables.
|
39
39
|
"""
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
)
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
print("
|
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
|
+
|
52
81
|
|
53
82
|
def set_sharedVar(self, name, value) -> None:
|
54
83
|
bf.ResourceManager().set_sharedVar(name,value)
|
batFramework/stateMachine.py
CHANGED
@@ -7,11 +7,11 @@ class StateMachine: ...
|
|
7
7
|
class State:
|
8
8
|
def __init__(self, name: str) -> None:
|
9
9
|
self.name = name
|
10
|
-
self.
|
10
|
+
self.parent: bf.Entity | bf.AnimatedSprite = None
|
11
11
|
self.state_machine: StateMachine = None
|
12
12
|
|
13
|
-
def
|
14
|
-
self.
|
13
|
+
def set_parent(self, parent: bf.Entity | bf.AnimatedSprite):
|
14
|
+
self.parent = parent
|
15
15
|
|
16
16
|
def set_stateMachine(self, stateMachine):
|
17
17
|
self.state_machine = stateMachine
|
@@ -27,16 +27,19 @@ class State:
|
|
27
27
|
|
28
28
|
|
29
29
|
class StateMachine:
|
30
|
-
def __init__(self,
|
30
|
+
def __init__(self, parent) -> None:
|
31
31
|
self.states: dict[str, State] = {}
|
32
|
-
self.
|
32
|
+
self.parent = parent
|
33
33
|
self.current_state = None
|
34
34
|
|
35
35
|
def add_state(self, state: State):
|
36
36
|
self.states[state.name] = state
|
37
|
-
state.
|
37
|
+
state.set_parent(self.parent)
|
38
38
|
state.set_stateMachine(self)
|
39
39
|
|
40
|
+
def remove_state(self,state_name: str):
|
41
|
+
self.states.pop(state_name,default=None)
|
42
|
+
|
40
43
|
def set_state(self, state_name: str):
|
41
44
|
if state_name in self.states:
|
42
45
|
if self.current_state:
|
@@ -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
|
+
|