batframework 1.0.8a1__py3-none-any.whl → 1.0.8a2__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 (63) hide show
  1. batFramework/__init__.py +50 -53
  2. batFramework/action.py +105 -116
  3. batFramework/actionContainer.py +11 -53
  4. batFramework/animatedSprite.py +65 -115
  5. batFramework/audioManager.py +26 -70
  6. batFramework/camera.py +68 -253
  7. batFramework/constants.py +54 -16
  8. batFramework/cutscene.py +25 -34
  9. batFramework/cutsceneBlocks.py +42 -37
  10. batFramework/debugger.py +48 -0
  11. batFramework/dynamicEntity.py +7 -9
  12. batFramework/easing.py +71 -0
  13. batFramework/entity.py +98 -42
  14. batFramework/gui/__init__.py +2 -8
  15. batFramework/gui/button.py +79 -7
  16. batFramework/gui/constraints.py +204 -0
  17. batFramework/gui/container.py +31 -155
  18. batFramework/gui/debugger.py +43 -124
  19. batFramework/gui/frame.py +19 -0
  20. batFramework/gui/image.py +17 -41
  21. batFramework/gui/indicator.py +21 -41
  22. batFramework/gui/interactiveWidget.py +13 -116
  23. batFramework/gui/label.py +73 -278
  24. batFramework/gui/layout.py +61 -148
  25. batFramework/gui/root.py +37 -102
  26. batFramework/gui/shape.py +57 -258
  27. batFramework/gui/toggle.py +46 -97
  28. batFramework/gui/widget.py +254 -268
  29. batFramework/manager.py +19 -40
  30. batFramework/particles.py +77 -0
  31. batFramework/scene.py +107 -214
  32. batFramework/sceneManager.py +107 -150
  33. batFramework/stateMachine.py +0 -1
  34. batFramework/time.py +57 -117
  35. batFramework/transition.py +126 -184
  36. batFramework/transitionManager.py +0 -0
  37. batFramework/utils.py +161 -34
  38. batframework-1.0.8a2.dist-info/METADATA +58 -0
  39. batframework-1.0.8a2.dist-info/RECORD +42 -0
  40. {batframework-1.0.8a1.dist-info → batframework-1.0.8a2.dist-info}/WHEEL +1 -1
  41. batFramework/easingController.py +0 -58
  42. batFramework/enums.py +0 -104
  43. batFramework/fontManager.py +0 -65
  44. batFramework/gui/clickableWidget.py +0 -206
  45. batFramework/gui/constraints/__init__.py +0 -1
  46. batFramework/gui/constraints/constraints.py +0 -378
  47. batFramework/gui/dialogueBox.py +0 -96
  48. batFramework/gui/draggableWidget.py +0 -38
  49. batFramework/gui/meter.py +0 -76
  50. batFramework/gui/radioButton.py +0 -62
  51. batFramework/gui/slider.py +0 -220
  52. batFramework/gui/textInput.py +0 -134
  53. batFramework/object.py +0 -115
  54. batFramework/particle.py +0 -101
  55. batFramework/renderGroup.py +0 -62
  56. batFramework/resourceManager.py +0 -84
  57. batFramework/scrollingSprite.py +0 -113
  58. batFramework/sprite.py +0 -45
  59. batFramework/tileset.py +0 -46
  60. batframework-1.0.8a1.dist-info/LICENCE +0 -21
  61. batframework-1.0.8a1.dist-info/METADATA +0 -55
  62. batframework-1.0.8a1.dist-info/RECORD +0 -56
  63. {batframework-1.0.8a1.dist-info → batframework-1.0.8a2.dist-info}/top_level.txt +0 -0
@@ -1,208 +1,165 @@
1
1
  import batFramework as bf
2
2
  import pygame
3
- from typing import Self
4
3
 
5
- def swap(lst, index1, index2):
6
- lst[index1], lst[index2] = lst[index2], lst[index1]
7
4
 
8
5
 
9
6
  class SceneManager:
10
- def __init__(self) -> None:
11
- self.scenes: list[bf.Scene] = []
12
- self.shared_variables: dict = {}
13
- self.shared_events = {pygame.WINDOWRESIZED}
7
+ def __init__(self, *initial_scenes: bf.Scene) -> None:
8
+ self._debugging = 0
9
+ self.sharedVarDict = {}
14
10
 
11
+ self.transitions: list[bf.BaseTransition] = []
12
+ self.set_sharedVar("is_debugging_func", lambda: self._debugging)
13
+ self.set_sharedVar("in_transition", False)
15
14
  self.set_sharedVar("in_cutscene", False)
16
- self.set_sharedVar("player_has_control", True)
17
15
 
18
- self.debug_mode: bf.enums.debugMode = bf.debugMode.HIDDEN
19
- self.current_transitions: dict[str, bf.transition.Transition] = {}
20
-
21
-
22
-
23
- def init_scenes(self,*initial_scenes):
24
- for index, s in enumerate(initial_scenes):
16
+ self._scenes: list[bf.Scene] = list(initial_scenes)
17
+ for index,s in enumerate(self._scenes):
18
+ s.set_manager(self)
25
19
  s.set_scene_index(index)
26
- for s in reversed(initial_scenes):
27
- self.add_scene(s)
28
- # self.scenes = list(initial_scenes)
29
- self.set_scene(initial_scenes[0].get_name())
20
+ s.do_when_added()
21
+ self.set_scene(self._scenes[0]._name)
30
22
  self.update_scene_states()
31
23
 
32
- def set_shared_event(self,event:pygame.Event)->None:
33
- """
34
- Add an event that will be propagated to all active scenes, not just the one on top.
35
- """
36
- self.shared_events.add(event)
37
-
38
24
  def print_status(self):
39
- """
40
- Print some information about the current state of the scenes.
41
- """
42
25
  print("-" * 40)
43
- print(
44
- '\n'.join(
45
- f" {s.name:<30}\t{'Active' if s.active else 'Inactive'}\t{'Visible' if s.visible else 'Invisible'}\tindex= {s.scene_index}"
46
- for s in self.scenes
47
- )
48
- )
49
- print(f"[Debugging] = {self.debug_mode}")
26
+ print([(s._name, s._active, s._visible,s.scene_index) for s in self._scenes])
27
+ print(f"[Debugging] = {self._debugging}")
50
28
  print("---SHARED VARIABLES---")
51
- for name, value in self.shared_variables.items():
29
+ _ = [
52
30
  print(f"[{str(name)} = {str(value)}]")
31
+ for name, value in self.sharedVarDict.items()
32
+ ]
53
33
  print("-" * 40)
54
34
 
55
35
  def set_sharedVar(self, name, value) -> bool:
56
- """
57
- Set a shared variable of any type. This will be accessible (read/write) from any scene
58
- """
59
- self.shared_variables[name] = value
36
+ self.sharedVarDict[name] = value
60
37
  return True
61
38
 
62
- def get_sharedVar(self, name, error_value=None):
63
- """
64
- Get a shared variable
65
- """
66
- return self.shared_variables.get(name,error_value)
67
-
68
- def get_current_scene_name(self) -> str:
69
- """get the name of the current scene"""
70
- return self.scenes[0].get_name()
71
-
72
- def get_current_scene(self) -> bf.Scene:
73
- return self.scenes[0]
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]
74
49
 
75
50
  def update_scene_states(self):
76
- self.active_scenes = [s for s in reversed(self.scenes) if s.active]
77
- self.visible_scenes = [s for s in reversed(self.scenes) if s.visible]
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]
78
53
 
79
54
  def add_scene(self, scene: bf.Scene):
80
- if scene in self.scenes and not self.has_scene(scene.name):
55
+ if scene in self._scenes and not self.has_scene(scene._name):
81
56
  return
82
57
  scene.set_manager(self)
83
58
  scene.do_when_added()
84
- self.scenes.insert(0, scene)
59
+ self._scenes.insert(0, scene)
85
60
 
86
61
  def remove_scene(self, name: str):
87
- self.scenes = [s for s in self.scenes if s.name != name]
62
+ self._scenes = [s for s in self._scenes if s._name != name]
88
63
 
89
64
  def has_scene(self, name):
90
- return any(name == scene.name for scene in self.scenes)
65
+ return any(name == scene._name for scene in self._scenes)
91
66
 
92
67
  def get_scene(self, name):
93
68
  if not self.has_scene(name):
94
69
  return None
95
- for scene in self.scenes:
96
- if scene.name == name:
70
+ for scene in self._scenes:
71
+ if scene._name == name:
97
72
  return scene
98
73
 
99
- def get_scene_at(self, index: int) -> bf.Scene | None:
100
- if index < 0 or index >= len(self.scenes):
101
- return None
102
- return self.scenes[index]
103
-
104
- def transition_to_scene(
105
- self,
106
- scene_name: str,
107
- transition: bf.transition.Transition = bf.transition.Fade(0.1),
108
- index: int = 0,
109
- ):
110
- target_scene = self.get_scene(scene_name)
111
- if not target_scene :
112
- print(f"Scene '{scene_name}' does not exist")
113
- return
114
- if (
115
- len(self.scenes) == 0
116
- or index >= len(self.scenes)
117
- or index < 0
118
- ):
119
- return
120
- source_surface = bf.const.SCREEN.copy()
121
- dest_surface = bf.const.SCREEN.copy()
122
-
123
- # self.draw(source_surface)
124
- target_scene.draw(dest_surface)
125
- target_scene.do_on_enter_early()
126
- self.get_scene_at(index).do_on_exit_early()
127
- self.current_transitions = {"scene_name": scene_name, "transition": transition}
128
- transition.set_start_callback(lambda: self._start_transition(target_scene))
129
- transition.set_end_callback(lambda: self._end_transition(scene_name, index))
130
- transition.set_source(source_surface)
131
- transition.set_dest(dest_surface)
132
- transition.start()
133
-
134
- def _start_transition(self, target_scene: bf.Scene):
135
- target_scene.set_active(True)
136
- target_scene.set_visible(True)
137
- self.set_sharedVar("player_has_control", False)
138
-
139
- def _end_transition(self, scene_name, index):
140
- self.set_scene(scene_name, index)
141
- self.set_sharedVar("player_has_control", True)
142
- self.current_transitions.clear()
143
-
144
- def set_scene(self, scene_name, index=0):
145
- target_scene = self.get_scene(scene_name)
146
- if not target_scene :
147
- print(f"'{scene_name}' does not exist")
148
- return
149
- if (
150
- len(self.scenes) == 0
151
- or index >= len(self.scenes)
152
- or index < 0
153
- ):
154
- return
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()
155
79
 
156
- # switch
157
- self.scenes[index].on_exit()
158
- # re-insert scene at index 0
159
- self.scenes.remove(target_scene)
160
- self.scenes.insert(index, target_scene)
161
- _ = [s.set_scene_index(i) for i, s in enumerate(self.scenes)]
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)]
162
115
  target_scene.on_enter()
163
116
 
164
- def cycle_debug_mode(self):
165
- current_index = self.debug_mode.value
166
- next_index = (current_index + 1) % len(bf.debugMode)
167
- return bf.debugMode(next_index)
168
117
 
169
118
  def process_event(self, event: pygame.Event):
119
+ if self.transitions:
120
+ return
170
121
  keys = pygame.key.get_pressed()
171
122
  if (
172
123
  keys[pygame.K_LCTRL]
173
- and keys[pygame.K_LSHIFT]
174
124
  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
175
133
  ):
176
- if event.key == pygame.K_d:
177
- self.debug_mode = self.cycle_debug_mode()
178
- self.set_sharedVar("debug_mode", self.debug_mode)
179
- return
180
- if event.key == pygame.K_p:
181
- self.print_status()
182
- return
183
- if event.type in self.shared_events:
184
- [s.process_event(event) for s in self.scenes]
185
- else:
186
- self.scenes[0].process_event(event)
134
+ self.print_status()
135
+ self._scenes[0].process_event(event)
187
136
 
188
137
  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
189
147
  for scene in self.active_scenes:
190
148
  scene.update(dt)
191
149
  self.do_update(dt)
192
150
 
193
151
  def do_update(self, dt: float):
194
- pass
152
+ return
195
153
 
196
154
  def draw(self, surface) -> None:
197
- for scene in self.visible_scenes:
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:
198
165
  scene.draw(surface)
199
- if self.current_transitions:
200
- self._draw_transition(surface)
201
-
202
- def _draw_transition(self, surface):
203
- self.current_transitions["transition"].set_source(surface)
204
- tmp = bf.const.SCREEN.copy()
205
- self.get_scene(self.current_transitions["scene_name"]).draw(tmp)
206
- self.current_transitions["transition"].set_dest(tmp)
207
- self.current_transitions["transition"].draw(surface)
208
- return
@@ -44,7 +44,6 @@ class StateMachine:
44
44
  self.current_state.on_exit()
45
45
  self.current_state = self.states[state_name]
46
46
  self.current_state.on_enter()
47
-
48
47
  def get_current_state(self) -> State:
49
48
  return self.current_state
50
49
 
batFramework/time.py CHANGED
@@ -1,135 +1,75 @@
1
+ import pygame
1
2
  import batFramework as bf
2
- from typing import Self
3
-
4
3
 
5
4
  class Timer:
6
- _count: int = 0
7
-
8
- def __init__(self, duration: float | int, end_callback, loop: bool = False) -> None:
9
- self.name: int = Timer._count
10
- Timer._count += 1
11
-
12
- self.duration: int | float = duration
5
+ _highest_count = 0
6
+ def __init__(self, name=None, duration=1000, loop=False, end_callback=None,reusable:bool=False):
7
+ # Initialize timer properties
8
+ self.start_time = None
9
+ self.stopped = True
10
+ self.name = name if name is not None else self._highest_count
11
+ Timer._highest_count += 1
12
+ self.duration = duration
13
+ self.loop = loop
14
+ self.elapsed_progress = 0.0
13
15
  self.end_callback = end_callback
16
+ self.reusable:bool = reusable
17
+ def start(self):
18
+ # Start the timer and set the start time
19
+ if self.start_time is None:
20
+ Time().add_timer(self)
21
+
22
+ self.start_time = pygame.time.get_ticks()
23
+ self.stopped = False
24
+ self.elapsed_progress = 0.0
25
+
26
+ def update(self):
27
+ if self.stopped : return False
28
+ current_time = pygame.time.get_ticks()
29
+ if self.elapsed_progress < 1:
30
+ # Calculate elapsed progress
31
+ self.elapsed_progress = (current_time - self.start_time) / self.duration
32
+ if self.elapsed_progress >= 1:
33
+ # Timer has completed
34
+ self.end()
35
+ return True
36
+ elif self.loop:
37
+ # If looping, restart the timer
38
+ self.start()
39
+ return False
14
40
 
15
- self.elapsed_time: float = -1
16
- self.is_over: bool = False
17
- self.is_looping: bool = loop
18
- self.is_paused: bool = False
19
- self.do_delete: bool = False
20
-
21
- def __repr__(self) -> str:
22
- return f"Timer ({self.name}) {self.elapsed_time}/{self.duration} | {'loop ' if self.is_looping else ''} {'(D) ' if self.do_delete else ''}"
23
-
24
- def stop(self) -> Self:
25
- self.elapsed_time = -1
26
- self.is_over = False
27
- self.is_paused = False
28
- return self
29
-
30
- def start(self, force: bool = False) -> Self:
31
- if self.elapsed_time != -1 and not force:
32
- return self
33
- if not bf.TimeManager().add_timer(self):
34
- return self
35
- self.elapsed_time = 0
36
- self.is_paused = False
37
- self.is_over = False
38
- return self
39
-
40
- def pause(self) -> Self:
41
- self.is_paused = True
42
- return self
43
-
44
- def resume(self) -> Self:
45
- self.is_paused = False
46
- return self
47
-
48
- def delete(self) -> Self:
49
- self.do_delete = True
50
- return self
51
-
52
- def has_started(self) -> bool:
53
- return self.elapsed_time != -1
54
-
55
- def get_progression(self) -> float:
56
- if self.elapsed_time < 0:
57
- return 0
58
- if self.elapsed_time >= self.duration:
59
- return 1
60
- return self.elapsed_time / self.duration
61
-
62
- def update(self, dt) -> None:
63
- if self.elapsed_time < 0 or self.is_paused or self.is_over:
64
- return
65
- self.elapsed_time += dt
66
- # print("update :",self.elapsed_time,self.duration)
67
- if self.get_progression() == 1:
68
- self.end()
41
+ def stop(self):
42
+ # Stop the timer
43
+ self.stopped = True
69
44
 
70
45
  def end(self):
46
+ self.elapsed_progress = 1
47
+ self.stopped = False
71
48
  if self.end_callback:
72
49
  self.end_callback()
73
- self.elapsed_time = -1
74
- self.is_over = True
75
- if self.is_looping:
76
- self.start()
77
- return
78
-
79
- def should_delete(self) -> bool:
80
- return self.is_over or self.do_delete
81
50
 
51
+ def ended(self):
52
+ if self.start_time is None:
53
+ return False
54
+ return (not self.loop) and (self.elapsed_progress >= 1) and (not self.stopped) and not self.reusable
82
55
 
83
- class TimerRegister:
84
- def __init__(self, active=True):
85
- self.active = active
86
- self.timers: dict[int | str, Timer] = {}
87
56
 
88
- def __iter__(self):
89
- return iter(self.timers.values())
57
+ class Time(metaclass=bf.Singleton):
58
+ def __init__(self):
59
+ # Initialize the Time class with a dictionary of timers
60
+ self.timers = {}
90
61
 
91
- def add_timer(self, timer: Timer):
62
+ def add_timer(self, timer):
63
+ # Add a timer to the dictionary
92
64
  self.timers[timer.name] = timer
93
65
 
94
- def update(self, dt):
95
- expired_timers = []
66
+ def update(self):
67
+ # Update all timers and remove completed ones
96
68
  for timer in list(self.timers.values()):
97
- if not timer.is_paused:
98
- timer.update(dt)
99
- if timer.should_delete():
100
- expired_timers.append(timer.name)
101
- for name in expired_timers:
102
- del self.timers[name]
103
-
104
-
105
- class TimeManager(metaclass=bf.Singleton):
106
- def __init__(self):
107
- self.registers = {"global": TimerRegister()}
108
-
109
- def add_register(self, name, active=True):
110
- if name not in self.registers:
111
- self.registers[name] = TimerRegister(active)
112
-
113
- def add_timer(self, timer, register="global") -> bool:
114
- if register in self.registers:
115
- self.registers[register].add_timer(timer)
116
- return True
117
- print(f"Register '{register}' does not exist.")
118
- return False
119
-
120
- def get_active_registers(self) -> list[TimerRegister]:
121
- return [t for t in self.registers.values() if t.active]
122
-
123
- def update(self, dt):
124
- for register_name, register in self.registers.items():
125
- if register.active:
126
- register.update(dt)
69
+ timer.update()
127
70
 
128
- def activate_register(self, name, active=True):
129
- if name in self.registers:
130
- self.registers[name].active = active
131
- else:
132
- print(f"Register '{name}' does not exist.")
71
+ to_remove = [name for name, timer in self.timers.items() if timer.ended()]
133
72
 
134
- def deactivate_register(self, name):
135
- self.activate_register(name, active=False)
73
+ for name in to_remove:
74
+ # print(self.timers.pop(name).name,"removed !")
75
+ self.timers.pop(name)