batframework 1.0.8a8__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.
Files changed (70) hide show
  1. batFramework/__init__.py +68 -51
  2. batFramework/action.py +126 -99
  3. batFramework/actionContainer.py +53 -9
  4. batFramework/animatedSprite.py +141 -82
  5. batFramework/audioManager.py +69 -26
  6. batFramework/camera.py +259 -69
  7. batFramework/character.py +27 -0
  8. batFramework/constants.py +16 -54
  9. batFramework/cutscene.py +39 -29
  10. batFramework/cutsceneBlocks.py +36 -43
  11. batFramework/dynamicEntity.py +18 -9
  12. batFramework/easingController.py +58 -0
  13. batFramework/entity.py +48 -97
  14. batFramework/enums.py +113 -0
  15. batFramework/fontManager.py +65 -0
  16. batFramework/gui/__init__.py +10 -2
  17. batFramework/gui/button.py +9 -78
  18. batFramework/gui/clickableWidget.py +220 -0
  19. batFramework/gui/constraints/__init__.py +1 -0
  20. batFramework/gui/constraints/constraints.py +815 -0
  21. batFramework/gui/container.py +174 -32
  22. batFramework/gui/debugger.py +131 -43
  23. batFramework/gui/dialogueBox.py +99 -0
  24. batFramework/gui/draggableWidget.py +40 -0
  25. batFramework/gui/image.py +56 -20
  26. batFramework/gui/indicator.py +38 -21
  27. batFramework/gui/interactiveWidget.py +192 -13
  28. batFramework/gui/label.py +309 -74
  29. batFramework/gui/layout.py +231 -63
  30. batFramework/gui/meter.py +74 -0
  31. batFramework/gui/radioButton.py +84 -0
  32. batFramework/gui/root.py +134 -38
  33. batFramework/gui/shape.py +237 -57
  34. batFramework/gui/slider.py +240 -0
  35. batFramework/gui/style.py +10 -0
  36. batFramework/gui/styleManager.py +48 -0
  37. batFramework/gui/textInput.py +247 -0
  38. batFramework/gui/toggle.py +101 -51
  39. batFramework/gui/widget.py +358 -250
  40. batFramework/manager.py +52 -19
  41. batFramework/object.py +123 -0
  42. batFramework/particle.py +115 -0
  43. batFramework/renderGroup.py +67 -0
  44. batFramework/resourceManager.py +100 -0
  45. batFramework/scene.py +281 -123
  46. batFramework/sceneManager.py +178 -116
  47. batFramework/scrollingSprite.py +114 -0
  48. batFramework/sprite.py +51 -0
  49. batFramework/stateMachine.py +11 -8
  50. batFramework/templates/__init__.py +2 -0
  51. batFramework/templates/character.py +44 -0
  52. batFramework/templates/states.py +166 -0
  53. batFramework/tileset.py +46 -0
  54. batFramework/time.py +145 -58
  55. batFramework/transition.py +195 -124
  56. batFramework/triggerZone.py +1 -1
  57. batFramework/utils.py +112 -147
  58. batframework-1.0.8a10.dist-info/LICENCE +21 -0
  59. batframework-1.0.8a10.dist-info/METADATA +43 -0
  60. batframework-1.0.8a10.dist-info/RECORD +62 -0
  61. batFramework/debugger.py +0 -48
  62. batFramework/easing.py +0 -71
  63. batFramework/gui/constraints.py +0 -204
  64. batFramework/gui/frame.py +0 -19
  65. batFramework/particles.py +0 -77
  66. batFramework/transitionManager.py +0 -0
  67. batframework-1.0.8a8.dist-info/METADATA +0 -53
  68. batframework-1.0.8a8.dist-info/RECORD +0 -42
  69. {batframework-1.0.8a8.dist-info → batframework-1.0.8a10.dist-info}/WHEEL +0 -0
  70. {batframework-1.0.8a8.dist-info → batframework-1.0.8a10.dist-info}/top_level.txt +0 -0
@@ -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, *initial_scenes: bf.Scene) -> None:
8
- self._debugging = 0
9
- self.sharedVarDict = {}
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
- self._scenes: list[bf.Scene] = list(initial_scenes)
17
- for index,s in enumerate(self._scenes):
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
- s.do_when_added()
21
- self.set_scene(self._scenes[0]._name)
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
- print("-" * 40)
26
- print([(s._name, s._active, s._visible,s.scene_index) for s in self._scenes])
27
- print(f"[Debugging] = {self._debugging}")
28
- print("---SHARED VARIABLES---")
29
- _ = [
30
- print(f"[{str(name)} = {str(value)}]")
31
- for name, value in self.sharedVarDict.items()
32
- ]
33
- print("-" * 40)
34
-
35
- def set_sharedVar(self, name, value) -> bool:
36
- self.sharedVarDict[name] = value
37
- return True
38
-
39
- def get_sharedVar(self, name):
40
- if name not in self.sharedVarDict:
41
- return None
42
- return self.sharedVarDict[name]
43
-
44
- def get_current_scene_name(self)-> str:
45
- return self._scenes[0].name
46
-
47
- def get_current_scene(self)->bf.Scene:
48
- return self._scenes[0]
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._scenes) if s._active]
52
- self.visible_scenes = [s for s in reversed(self._scenes) if s._visible]
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._scenes and not self.has_scene(scene._name):
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._scenes.insert(0, scene)
104
+ self.scenes.insert(0, scene)
60
105
 
61
106
  def remove_scene(self, name: str):
62
- self._scenes = [s for s in self._scenes if s._name != name]
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._name for scene in self._scenes)
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._scenes:
71
- if scene._name == name:
115
+ for scene in self.scenes:
116
+ if scene.name == name:
72
117
  return scene
73
118
 
74
- def transition_to_scene(self, dest_scene_name, transition, **kwargs):
75
- if not self.has_scene(dest_scene_name):
76
- return False
77
- source_surf = pygame.Surface(bf.const.RESOLUTION,pygame.SRCALPHA).convert_alpha()
78
- dest_surf = pygame.Surface(bf.const.RESOLUTION,pygame.SRCALPHA).convert_alpha()
79
-
80
- index = kwargs.pop("index",0)
81
- #draw the surfaces
82
- source_scenes = [s for s in self.visible_scenes if s.scene_index >= index and s._visible]
83
- # source_scenes = self.visible_scenes
84
- _ = [s.draw(source_surf) for s in source_scenes]
85
- # self._scenes[index].draw(source_surf)
86
-
87
- # pygame.image.save_extended:(source_surf,"source_surface.png")
88
- self.get_scene(dest_scene_name).draw(dest_surf)
89
- # pygame.image.save_extended(dest_surf,"dest_surface.png")
90
-
91
- # print(f"start transition from {self._scenes[index]._name} to {dest_scene_name}")
92
-
93
- instance: bf.BaseTransition = transition(
94
- source_surf, dest_surf, **kwargs
95
- )
96
- instance.set_scene_index(index)
97
- instance.set_source_name(self._scenes[index]._name)
98
- instance.set_dest_name(dest_scene_name)
99
- self.transitions.append(instance)
100
- self.set_sharedVar("in_transition", True)
101
-
102
- def set_scene(self, name,index=0):
103
- if len(self._scenes)==0 or not self.has_scene(name) or index>=len(self._scenes):return
104
-
105
- target_scene = self.get_scene(name)
106
- old_scene = self._scenes[index]
107
-
108
- # print(f"switch from {old_scene._name} to {target_scene._name} in index {index}")
109
-
110
- #switch
111
- old_scene.on_exit()
112
- self.remove_scene(name)
113
- self._scenes.insert(index,target_scene)
114
- _ = [s.set_scene_index(i) for i,s in enumerate(self._scenes)]
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
- self.print_status()
135
- self._scenes[0].process_event(event)
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
- return
213
+ pass
153
214
 
154
215
  def draw(self, surface) -> None:
155
- transition_scene_index = -1
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
@@ -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.parent_entity: bf.Entity | bf.AnimatedSprite = None
10
+ self.parent: bf.Entity | bf.AnimatedSprite = None
12
11
  self.state_machine: StateMachine = None
13
12
 
14
- def set_parent_entity(self, parent_entity: bf.Entity | bf.AnimatedSprite):
15
- self.parent_entity = parent_entity
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, parent_entity) -> None:
30
+ def __init__(self, parent) -> None:
32
31
  self.states: dict[str, State] = {}
33
- self.parent_entity = parent_entity
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.set_parent_entity(self.parent_entity)
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,2 @@
1
+ from .character import *
2
+ from .states import *
@@ -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
+