batframework 1.1.0__py3-none-any.whl → 2.0.0__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 +84 -51
- batFramework/action.py +280 -252
- batFramework/actionContainer.py +105 -38
- batFramework/animatedSprite.py +81 -117
- batFramework/animation.py +91 -0
- batFramework/audioManager.py +156 -85
- batFramework/baseScene.py +249 -0
- batFramework/camera.py +245 -123
- batFramework/constants.py +57 -75
- batFramework/cutscene.py +239 -119
- batFramework/cutsceneManager.py +34 -0
- batFramework/drawable.py +107 -0
- batFramework/dynamicEntity.py +30 -23
- batFramework/easingController.py +58 -0
- batFramework/entity.py +130 -123
- batFramework/enums.py +171 -0
- batFramework/fontManager.py +65 -0
- batFramework/gui/__init__.py +28 -14
- batFramework/gui/animatedLabel.py +90 -0
- batFramework/gui/button.py +18 -84
- batFramework/gui/clickableWidget.py +244 -0
- batFramework/gui/collapseContainer.py +98 -0
- batFramework/gui/constraints/__init__.py +1 -0
- batFramework/gui/constraints/constraints.py +1066 -0
- batFramework/gui/container.py +220 -49
- batFramework/gui/debugger.py +140 -47
- batFramework/gui/draggableWidget.py +63 -0
- batFramework/gui/image.py +61 -23
- batFramework/gui/indicator.py +116 -40
- batFramework/gui/interactiveWidget.py +243 -22
- batFramework/gui/label.py +147 -110
- batFramework/gui/layout.py +442 -81
- batFramework/gui/meter.py +155 -0
- batFramework/gui/radioButton.py +43 -0
- batFramework/gui/root.py +228 -60
- batFramework/gui/scrollingContainer.py +282 -0
- batFramework/gui/selector.py +232 -0
- batFramework/gui/shape.py +286 -86
- batFramework/gui/slider.py +353 -0
- batFramework/gui/style.py +10 -0
- batFramework/gui/styleManager.py +49 -0
- batFramework/gui/syncedVar.py +43 -0
- batFramework/gui/textInput.py +331 -0
- batFramework/gui/textWidget.py +308 -0
- batFramework/gui/toggle.py +140 -62
- batFramework/gui/tooltip.py +35 -0
- batFramework/gui/widget.py +546 -307
- batFramework/manager.py +131 -50
- batFramework/particle.py +118 -0
- batFramework/propertyEaser.py +79 -0
- batFramework/renderGroup.py +34 -0
- batFramework/resourceManager.py +130 -0
- batFramework/scene.py +31 -226
- batFramework/sceneLayer.py +134 -0
- batFramework/sceneManager.py +200 -165
- batFramework/scrollingSprite.py +115 -0
- batFramework/sprite.py +46 -0
- batFramework/stateMachine.py +49 -51
- batFramework/templates/__init__.py +2 -0
- batFramework/templates/character.py +15 -0
- batFramework/templates/controller.py +158 -0
- batFramework/templates/stateMachine.py +39 -0
- batFramework/tileset.py +46 -0
- batFramework/timeManager.py +213 -0
- batFramework/transition.py +162 -157
- batFramework/triggerZone.py +22 -22
- batFramework/utils.py +306 -184
- {batframework-1.1.0.dist-info → batframework-2.0.0.dist-info}/LICENSE +1 -1
- {batframework-1.1.0.dist-info → batframework-2.0.0.dist-info}/METADATA +8 -4
- batframework-2.0.0.dist-info/RECORD +72 -0
- batFramework/cutsceneBlocks.py +0 -176
- 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/time.py +0 -75
- batFramework/transitionManager.py +0 -0
- batframework-1.1.0.dist-info/RECORD +0 -43
- {batframework-1.1.0.dist-info → batframework-2.0.0.dist-info}/WHEEL +0 -0
- {batframework-1.1.0.dist-info → batframework-2.0.0.dist-info}/top_level.txt +0 -0
batFramework/cutsceneBlocks.py
DELETED
@@ -1,176 +0,0 @@
|
|
1
|
-
import batFramework as bf
|
2
|
-
from .cutscene import Cutscene,CutsceneManager
|
3
|
-
|
4
|
-
|
5
|
-
# Define the base CutsceneBlock class
|
6
|
-
class CutsceneBlock:
|
7
|
-
"""
|
8
|
-
Base class for cutscene blocks. Represents a unit of action in a cutscene.
|
9
|
-
"""
|
10
|
-
|
11
|
-
# Constructor for the CutsceneBlock
|
12
|
-
def __init__(self) -> None:
|
13
|
-
# Callback function, parent cutscene, and state variables
|
14
|
-
self.callback = None
|
15
|
-
self.parent_cutscene: Cutscene = None
|
16
|
-
self.get_flag = CutsceneManager().get_flag
|
17
|
-
self.ended = False
|
18
|
-
self.started = False
|
19
|
-
|
20
|
-
def get_scene_at(self,index):
|
21
|
-
return bf.CutsceneManager().manager._scenes[index]
|
22
|
-
|
23
|
-
def set_scene(self,name,index=0):
|
24
|
-
return CutsceneManager().manager.set_scene(name,index)
|
25
|
-
|
26
|
-
def get_current_scene(self):
|
27
|
-
return CutsceneManager().manager.get_current_scene()
|
28
|
-
|
29
|
-
def get_scene(self,name):
|
30
|
-
return CutsceneManager().manager.get_scene(name)
|
31
|
-
|
32
|
-
# Set the parent cutscene for this block
|
33
|
-
def set_parent_cutscene(self, parent):
|
34
|
-
"""
|
35
|
-
Set the parent cutscene for this block.
|
36
|
-
|
37
|
-
Args:
|
38
|
-
parent: The parent cutscene object.
|
39
|
-
"""
|
40
|
-
self.parent_cutscene = parent
|
41
|
-
|
42
|
-
# Process an event (placeholder implementation, to be overridden in subclasses)
|
43
|
-
def process_event(self, event):
|
44
|
-
"""
|
45
|
-
Process an event for this cutscene block.
|
46
|
-
|
47
|
-
Args:
|
48
|
-
event: The event to be processed.
|
49
|
-
"""
|
50
|
-
pass
|
51
|
-
|
52
|
-
# Update the block (placeholder implementation, to be overridden in subclasses)
|
53
|
-
def update(self, dt):
|
54
|
-
"""
|
55
|
-
Update the cutscene block.
|
56
|
-
|
57
|
-
Args:
|
58
|
-
dt: Time elapsed since the last update.
|
59
|
-
"""
|
60
|
-
pass
|
61
|
-
|
62
|
-
# Start the block
|
63
|
-
def start(self):
|
64
|
-
"""
|
65
|
-
Start the cutscene block.
|
66
|
-
"""
|
67
|
-
self.started = True
|
68
|
-
|
69
|
-
# Mark the block as ended
|
70
|
-
def end(self):
|
71
|
-
"""
|
72
|
-
Mark the cutscene block as ended.
|
73
|
-
"""
|
74
|
-
self.ended = True
|
75
|
-
|
76
|
-
# Check if the block has ended
|
77
|
-
def has_ended(self):
|
78
|
-
"""
|
79
|
-
Check if the cutscene block has ended.
|
80
|
-
|
81
|
-
Returns:
|
82
|
-
bool: True if the block has ended, False otherwise.
|
83
|
-
"""
|
84
|
-
return self.ended
|
85
|
-
|
86
|
-
|
87
|
-
# Define the ParallelBlock class, a type of CutsceneBlock
|
88
|
-
class ParallelBlock(CutsceneBlock):
|
89
|
-
"""
|
90
|
-
Represents a parallel execution block for multiple Cutscene blocks.
|
91
|
-
"""
|
92
|
-
|
93
|
-
# Constructor for ParallelBlock, taking a variable number of blocks as arguments
|
94
|
-
def __init__(self, *blocks) -> None:
|
95
|
-
super().__init__()
|
96
|
-
# List of blocks to run in parallel
|
97
|
-
self.blocks: list[CutsceneBlock] = blocks
|
98
|
-
|
99
|
-
# Start the parallel block (override the base class method)
|
100
|
-
def start(self):
|
101
|
-
"""
|
102
|
-
Start the parallel execution block.
|
103
|
-
"""
|
104
|
-
super().start()
|
105
|
-
# Start each block in parallel
|
106
|
-
for block in self.blocks:
|
107
|
-
block.start()
|
108
|
-
|
109
|
-
# Process an event for each block in parallel
|
110
|
-
def process_event(self, event):
|
111
|
-
"""
|
112
|
-
Process an event for each block in the parallel execution block.
|
113
|
-
|
114
|
-
Args:
|
115
|
-
event: The event to be processed.
|
116
|
-
"""
|
117
|
-
_ = [b.process_event(event) for b in self.blocks]
|
118
|
-
|
119
|
-
# Update each block in parallel
|
120
|
-
def update(self, dt):
|
121
|
-
"""
|
122
|
-
Update each block in the parallel execution block.
|
123
|
-
|
124
|
-
Args:
|
125
|
-
dt: Time elapsed since the last update.
|
126
|
-
"""
|
127
|
-
_ = [b.update(dt) for b in self.blocks]
|
128
|
-
|
129
|
-
# Check if all blocks have ended
|
130
|
-
def has_ended(self):
|
131
|
-
"""
|
132
|
-
Check if all blocks in the parallel execution block have ended.
|
133
|
-
|
134
|
-
Returns:
|
135
|
-
bool: True if all blocks have ended, False otherwise.
|
136
|
-
"""
|
137
|
-
return all(b.has_ended() for b in self.blocks)
|
138
|
-
|
139
|
-
|
140
|
-
# Define the SceneTransitionBlock class, a type of CutsceneBlock
|
141
|
-
class SceneTransitionBlock(CutsceneBlock):
|
142
|
-
"""
|
143
|
-
Represents a scene transition Cutscene block.
|
144
|
-
"""
|
145
|
-
|
146
|
-
# Constructor for SceneTransitionBlock
|
147
|
-
def __init__(self, scene, transition, duration, **kwargs) -> None:
|
148
|
-
super().__init__()
|
149
|
-
# Target scene, transition type, duration, and additional keyword arguments
|
150
|
-
self.target_scene = scene
|
151
|
-
self.transition = transition
|
152
|
-
self.duration = duration
|
153
|
-
self.kwargs = kwargs
|
154
|
-
# Timer to handle the end of the transition
|
155
|
-
self.timer = bf.Timer(name = "scene_transition_block",duration=duration, end_callback=self.end)
|
156
|
-
|
157
|
-
# Start the scene transition block
|
158
|
-
def start(self):
|
159
|
-
"""
|
160
|
-
Start the scene transition block.
|
161
|
-
"""
|
162
|
-
super().start()
|
163
|
-
print(f"transition to {scene}")
|
164
|
-
|
165
|
-
# Initiate the scene transition
|
166
|
-
if self.get_current_scene()._name == self.target_scene:
|
167
|
-
self.end()
|
168
|
-
return
|
169
|
-
CutsceneManager().manager.transition_to_scene(
|
170
|
-
self.target_scene, self.transition, duration=self.duration, **self.kwargs
|
171
|
-
)
|
172
|
-
# Start the timer to handle the end of the transition
|
173
|
-
self.timer.start()
|
174
|
-
|
175
|
-
def end(self):
|
176
|
-
return super().end()
|
batFramework/debugger.py
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
import batFramework as bf
|
2
|
-
import pygame
|
3
|
-
|
4
|
-
|
5
|
-
class Debugger(bf.Label):
|
6
|
-
def __init__(self, manager) -> None:
|
7
|
-
super().__init__()
|
8
|
-
self.manager: bf.Manager = manager
|
9
|
-
self.refresh_rate = 0
|
10
|
-
self._refresh_counter = 0
|
11
|
-
self.dynamic_data = {}
|
12
|
-
self.static_data = {}
|
13
|
-
self.render_order = 99
|
14
|
-
self.set_outline_color((20, 20, 20))
|
15
|
-
# self.set_background_color((0,0,0,0))
|
16
|
-
self.set_text_color("white")
|
17
|
-
# self.set_padding((30,30))
|
18
|
-
self.set_refresh_rate(20)
|
19
|
-
self.add_dynamic_data("FPS", lambda: str(round(self.manager.get_fps())))
|
20
|
-
self.add_dynamic_data("BLITS", lambda: str(self.parent_scene.blit_calls))
|
21
|
-
self.set_visible(False)
|
22
|
-
|
23
|
-
def set_refresh_rate(self, val: int):
|
24
|
-
self.refresh_rate = val
|
25
|
-
|
26
|
-
def update(self, dt: float):
|
27
|
-
visible = self.manager._debugging == 1
|
28
|
-
self.set_visible(visible)
|
29
|
-
if not visible:
|
30
|
-
return
|
31
|
-
self._refresh_counter -= dt * 60
|
32
|
-
if self._refresh_counter < 0:
|
33
|
-
self._refresh_counter = self.refresh_rate
|
34
|
-
self._refresh_debug_info()
|
35
|
-
|
36
|
-
def add_dynamic_data(self, key, func):
|
37
|
-
self.dynamic_data[key] = func
|
38
|
-
|
39
|
-
def set_static_data(self, key, value):
|
40
|
-
self.static_data[key] = value
|
41
|
-
|
42
|
-
def _refresh_debug_info(self):
|
43
|
-
lines = []
|
44
|
-
lines.extend([f"{key}:{value}" for key, value in self.static_data.items()])
|
45
|
-
lines.extend([f"{key}:{func()}" for key, func in self.dynamic_data.items()])
|
46
|
-
debug_text = "\n".join(lines)
|
47
|
-
self.set_text(debug_text)
|
48
|
-
self.update_surface() # Update the surface after modifying the text
|
batFramework/easing.py
DELETED
@@ -1,71 +0,0 @@
|
|
1
|
-
from enum import Enum
|
2
|
-
import pygame
|
3
|
-
import batFramework as bf
|
4
|
-
|
5
|
-
class Easing(Enum):
|
6
|
-
EASE_IN = (0.12, 0, 0.39, 0)
|
7
|
-
EASE_OUT = (0.61, 1, 0.88, 1)
|
8
|
-
EASE_IN_OUT = (0.37, 0, 0.63, 1)
|
9
|
-
EASE_IN_OUT_ELASTIC = (.7,-0.5,.3,1.5)
|
10
|
-
LINEAR = (1, 1, 0, 0)
|
11
|
-
# Add more easing functions as needed
|
12
|
-
|
13
|
-
def __init__(self, *control_points):
|
14
|
-
self.control_points = control_points
|
15
|
-
|
16
|
-
class EasingAnimation(bf.Timer):
|
17
|
-
_cache = {}
|
18
|
-
def __init__(
|
19
|
-
self,
|
20
|
-
name:str=None,
|
21
|
-
easing_function:Easing=Easing.LINEAR,
|
22
|
-
duration:int=100,
|
23
|
-
update_callback=None,
|
24
|
-
end_callback=None,
|
25
|
-
loop:bool=False,
|
26
|
-
reusable:bool=False
|
27
|
-
):
|
28
|
-
self.easing_function = easing_function
|
29
|
-
self.update_callback = update_callback
|
30
|
-
self.value = 0.0
|
31
|
-
super().__init__(name,duration,loop,end_callback,reusable)
|
32
|
-
|
33
|
-
def get_value(self):
|
34
|
-
return self.value
|
35
|
-
|
36
|
-
def start(self):
|
37
|
-
self.value = 0
|
38
|
-
super().start() # self.elapsed_progress set to 0 here
|
39
|
-
|
40
|
-
def update(self)->bool:
|
41
|
-
if super().update():
|
42
|
-
return True# If timer ended now, end() is called. So don't process value.
|
43
|
-
self._process_value()
|
44
|
-
# if self.name == 0: print("UPDATING (callback) in easing")
|
45
|
-
if self.update_callback: self.update_callback(self.value)
|
46
|
-
return False
|
47
|
-
|
48
|
-
def end(self):
|
49
|
-
# Call update 1 last time with the last value
|
50
|
-
|
51
|
-
self.elapsed_progress = 1
|
52
|
-
self._process_value()
|
53
|
-
if self.update_callback: self.update_callback(self.value)
|
54
|
-
self.value = 0
|
55
|
-
super().end() # sets elapsed_progress to 0
|
56
|
-
|
57
|
-
def _process_value(self):
|
58
|
-
p0, p1, p2, p3 = self.easing_function.control_points
|
59
|
-
cache_key = (self.elapsed_progress, p0, p1, p2, p3)
|
60
|
-
if cache_key in EasingAnimation._cache:
|
61
|
-
y = EasingAnimation._cache[cache_key]
|
62
|
-
else:
|
63
|
-
t = self.elapsed_progress
|
64
|
-
t_inv = 1.0 - t
|
65
|
-
t2 = t * t
|
66
|
-
t3 = t * t2
|
67
|
-
t_inv2 = t_inv * t_inv
|
68
|
-
|
69
|
-
y = 3 * t_inv2 * t * p1 + 3 * t_inv * t2 * p3 + t3
|
70
|
-
EasingAnimation._cache[cache_key] = y
|
71
|
-
self.value = y
|
batFramework/gui/constraints.py
DELETED
@@ -1,204 +0,0 @@
|
|
1
|
-
from .widget import Widget
|
2
|
-
import batFramework as bf
|
3
|
-
|
4
|
-
|
5
|
-
class Constraint:
|
6
|
-
def __init__(self,name="Constraint", priority=0):
|
7
|
-
self.priority = priority
|
8
|
-
self.name = name
|
9
|
-
def set_priority(self, priority)->"Constraint":
|
10
|
-
self.priority = priority
|
11
|
-
return self
|
12
|
-
def to_string(self)->str:
|
13
|
-
return f"{self.name.upper()}"
|
14
|
-
|
15
|
-
def evaluate(self, parent_widget:Widget, child_widget:Widget) -> bool:
|
16
|
-
raise NotImplementedError("Subclasses must implement evaluate method")
|
17
|
-
|
18
|
-
def apply(self, parent_widget:Widget, child_widget:Widget=None) -> bool:
|
19
|
-
if not self.evaluate(parent_widget, child_widget):
|
20
|
-
self.apply_constraint(parent_widget, child_widget)
|
21
|
-
return False
|
22
|
-
return True
|
23
|
-
|
24
|
-
def apply_constraint(self, parent_widget:Widget, child_widget:Widget):
|
25
|
-
raise NotImplementedError("Subclasses must implement apply_constraint method")
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
class ConstraintMinWidth(Constraint):
|
43
|
-
def __init__(self, width):
|
44
|
-
super().__init__(name="min_width")
|
45
|
-
self.min_width = width
|
46
|
-
|
47
|
-
def evaluate(self, parent_widget, child_widget):
|
48
|
-
return child_widget.rect.width >= self.min_width
|
49
|
-
|
50
|
-
def apply_constraint(self, parent_widget, child_widget):
|
51
|
-
if not self.evaluate(parent_widget, child_widget):
|
52
|
-
child_widget.set_size(self.min_width,child_widget.rect.h)
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
class ConstraintCenterX(Constraint):
|
58
|
-
def __init__(self):
|
59
|
-
super().__init__(name="centerx")
|
60
|
-
|
61
|
-
def evaluate(self, parent_widget, child_widget):
|
62
|
-
return child_widget.rect.centerx == parent_widget.get_content_center()[0]
|
63
|
-
|
64
|
-
def apply_constraint(self,parent_widget,child_widget):
|
65
|
-
if not self.evaluate(parent_widget,child_widget):
|
66
|
-
child_widget.set_center(parent_widget.get_content_center()[0],child_widget.rect.centery)
|
67
|
-
|
68
|
-
class ConstraintCenterY(Constraint):
|
69
|
-
def __init__(self):
|
70
|
-
super().__init__(name="centery")
|
71
|
-
|
72
|
-
def evaluate(self, parent_widget, child_widget):
|
73
|
-
return child_widget.rect.centery == parent_widget.get_content_center()[1]
|
74
|
-
|
75
|
-
def apply_constraint(self,parent_widget,child_widget):
|
76
|
-
if not self.evaluate(parent_widget,child_widget):
|
77
|
-
child_widget.set_center(child_widget.rect.centerx,parent_widget.get_content_center()[1])
|
78
|
-
|
79
|
-
class ConstraintCenter(Constraint):
|
80
|
-
def __init__(self):
|
81
|
-
super().__init__(name="center")
|
82
|
-
|
83
|
-
def evaluate(self, parent_widget, child_widget):
|
84
|
-
return child_widget.rect.center == parent_widget.get_content_center()
|
85
|
-
|
86
|
-
def apply_constraint(self,parent_widget,child_widget):
|
87
|
-
if not self.evaluate(parent_widget,child_widget):
|
88
|
-
child_widget.set_center(*parent_widget.get_content_center())
|
89
|
-
|
90
|
-
class ConstraintPercentageWidth(Constraint):
|
91
|
-
def __init__(self,percentage:float,keep_autoresize:bool=True):
|
92
|
-
super().__init__(name="percentage_width")
|
93
|
-
self.percentage:float = percentage
|
94
|
-
self.keep_autoresize: bool = keep_autoresize
|
95
|
-
def to_string(self)->str:
|
96
|
-
return f"{super().to_string()}.[{self.percentage},{self.keep_autoresize}]"
|
97
|
-
def evaluate(self, parent_widget, child_widget):
|
98
|
-
return child_widget.rect.width == round(parent_widget.get_content_width() * self.percentage)
|
99
|
-
|
100
|
-
def apply_constraint(self,parent_widget,child_widget):
|
101
|
-
if not self.evaluate(parent_widget,child_widget):
|
102
|
-
if child_widget.autoresize:
|
103
|
-
if self.keep_autoresize:
|
104
|
-
print(f"Warning: Constraint on {child_widget.to_string()} can't resize, autoresize set to True")
|
105
|
-
return
|
106
|
-
child_widget.set_autoresize(False)
|
107
|
-
child_widget.set_size(round(parent_widget.get_content_width() * self.percentage) ,child_widget.rect.h)
|
108
|
-
|
109
|
-
|
110
|
-
class ConstraintPercentageHeight(Constraint):
|
111
|
-
def __init__(self,percentage:float,keep_autoresize:bool=True):
|
112
|
-
super().__init__(name="percentage_height")
|
113
|
-
self.percentage:float = percentage
|
114
|
-
self.keep_autoresize: bool = keep_autoresize
|
115
|
-
|
116
|
-
def evaluate(self, parent_widget, child_widget):
|
117
|
-
return child_widget.rect.height == round(parent_widget.get_content_height() * self.percentage)
|
118
|
-
|
119
|
-
def apply_constraint(self,parent_widget,child_widget):
|
120
|
-
if not self.evaluate(parent_widget,child_widget):
|
121
|
-
if child_widget.autoresize:
|
122
|
-
if self.keep_autoresize:
|
123
|
-
print(f"Warning: Constraint on {child_widget.to_string()} can't resize, autoresize set to True")
|
124
|
-
return
|
125
|
-
child_widget.set_autoresize(False)
|
126
|
-
child_widget.set_size(child_widget.rect.w,round(parent_widget.get_content_height() * self.percentage))
|
127
|
-
|
128
|
-
class ConstraintHeight(Constraint):
|
129
|
-
def __init__(self,height:float):
|
130
|
-
if height < 0 :
|
131
|
-
raise ValueError("height can't be negative")
|
132
|
-
super().__init__(name="height")
|
133
|
-
self.height = height
|
134
|
-
|
135
|
-
def to_string(self)->str:
|
136
|
-
return f"{super().to_string()}.({self.height})"
|
137
|
-
|
138
|
-
def evaluate(self, parent_widget, child_widget):
|
139
|
-
return child_widget.rect.height == self.height
|
140
|
-
|
141
|
-
def apply_constraint(self,parent_widget,child_widget):
|
142
|
-
if not self.evaluate(parent_widget,child_widget):
|
143
|
-
child_widget.set_size(child_widget.rect.w,self.height)
|
144
|
-
|
145
|
-
class ConstraintWidth(Constraint):
|
146
|
-
def __init__(self,width:float):
|
147
|
-
if width < 0 :
|
148
|
-
raise ValueError("width can't be negative")
|
149
|
-
super().__init__(name="width")
|
150
|
-
self.width = width
|
151
|
-
|
152
|
-
def to_string(self)->str:
|
153
|
-
return f"{super().to_string()}.({self.width})"
|
154
|
-
|
155
|
-
def evaluate(self, parent_widget, child_widget):
|
156
|
-
return child_widget.rect.width == self.width
|
157
|
-
|
158
|
-
def apply_constraint(self,parent_widget,child_widget):
|
159
|
-
if not self.evaluate(parent_widget,child_widget):
|
160
|
-
child_widget.set_size(self.width,child_widget.rect.h)
|
161
|
-
|
162
|
-
|
163
|
-
class ConstraintAspectRatio(Constraint):
|
164
|
-
def __init__(self,ratio:int|float=1):
|
165
|
-
super().__init__(name="aspect_ratio")
|
166
|
-
if isinstance(ratio, float|int):
|
167
|
-
self.ratio = ratio
|
168
|
-
elif isinstance(ratio,Widget):
|
169
|
-
self.ratio = ratio.rect.w / ratio.rect.h
|
170
|
-
else:
|
171
|
-
raise TypeError(f"Ratio must be float or Widget")
|
172
|
-
def evaluate(self, parent_widget,child_widget):
|
173
|
-
return self.ratio == child_widget.rect.w / child_widget.rect.h
|
174
|
-
|
175
|
-
def apply_constraint(self,parent_widget,child_widget):
|
176
|
-
if not self.evaluate(parent_widget,child_widget):
|
177
|
-
return # TODO
|
178
|
-
|
179
|
-
class ConstraintAnchorBottom(Constraint):
|
180
|
-
def __init__(self):
|
181
|
-
super().__init__(name="anchor_bottom")
|
182
|
-
|
183
|
-
def evaluate(self, parent_widget,child_widget):
|
184
|
-
return child_widget.rect.bottom == parent_widget.rect.bottom
|
185
|
-
|
186
|
-
def apply_constraint(self,parent_widget,child_widget):
|
187
|
-
if not self.evaluate(parent_widget,child_widget):
|
188
|
-
child_widget.set_y(parent_widget.get_content_bottom() - child_widget.rect.h)
|
189
|
-
|
190
|
-
|
191
|
-
class ConstraintAnchorTopRight(Constraint):
|
192
|
-
def __init__(self):
|
193
|
-
super().__init__(name="anchor_topright")
|
194
|
-
|
195
|
-
def evaluate(self, parent_widget,child_widget):
|
196
|
-
return child_widget.rect.topright == parent_widget.rect.topright
|
197
|
-
|
198
|
-
def apply_constraint(self,parent_widget,child_widget):
|
199
|
-
if not self.evaluate(parent_widget,child_widget):
|
200
|
-
child_widget.set_position(parent_widget.get_content_right()-child_widget.rect.w, parent_widget.get_content_top())
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
batFramework/gui/frame.py
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
import batFramework as bf
|
2
|
-
from .shape import Shape
|
3
|
-
import pygame
|
4
|
-
|
5
|
-
|
6
|
-
class Frame(Shape):
|
7
|
-
def __init__(self,width:float,height:float):
|
8
|
-
super().__init__(width,height)
|
9
|
-
self.set_debug_color("magenta")
|
10
|
-
|
11
|
-
def to_string_id(self)->str:
|
12
|
-
return "Frame"
|
13
|
-
|
14
|
-
def children_modified(self)->None:
|
15
|
-
print(self.children)
|
16
|
-
self.set_size(
|
17
|
-
*self.inflate_rect_by_padding(self.rect.unionall(list(c.rect for c in self.children))).size
|
18
|
-
)
|
19
|
-
super().children_modified()
|
batFramework/particles.py
DELETED
@@ -1,77 +0,0 @@
|
|
1
|
-
import batFramework as bf
|
2
|
-
import pygame
|
3
|
-
from pygame.math import Vector2
|
4
|
-
|
5
|
-
|
6
|
-
class Particle:
|
7
|
-
def __init__(
|
8
|
-
self,
|
9
|
-
start_pos: tuple[float, float],
|
10
|
-
start_vel: tuple[float, float],
|
11
|
-
duration=1000,
|
12
|
-
color=None,
|
13
|
-
size = (4,4)
|
14
|
-
):
|
15
|
-
self.rect = pygame.FRect(*start_pos, 0, 0)
|
16
|
-
self.surface = pygame.Surface(size).convert()
|
17
|
-
if color:
|
18
|
-
self.surface.fill(color)
|
19
|
-
self.velocity = Vector2(*start_vel)
|
20
|
-
self.start_time = pygame.time.get_ticks()
|
21
|
-
self.duration = duration
|
22
|
-
self.dead = False
|
23
|
-
self.progression = 0
|
24
|
-
self.z_depth = 1
|
25
|
-
|
26
|
-
def update(self, dt):
|
27
|
-
if self.dead:
|
28
|
-
return
|
29
|
-
elapsed_time = pygame.time.get_ticks() - self.start_time
|
30
|
-
self.progression = elapsed_time / self.duration
|
31
|
-
self.dead = elapsed_time >= self.duration
|
32
|
-
self.rect.center += self.velocity * dt
|
33
|
-
self.update_surface()
|
34
|
-
|
35
|
-
def kill(self):
|
36
|
-
self.dead = True
|
37
|
-
|
38
|
-
def update_surface(self):
|
39
|
-
self.surface.set_alpha(255 - int(self.progression * 255))
|
40
|
-
|
41
|
-
|
42
|
-
class ParticleManager(bf.Entity):
|
43
|
-
def __init__(self) -> None:
|
44
|
-
super().__init__(size=bf.const.RESOLUTION)
|
45
|
-
self.particles: list[Particle] = []
|
46
|
-
|
47
|
-
def get_bounding_box(self):
|
48
|
-
for particle in self.particles:
|
49
|
-
yield particle.rect
|
50
|
-
|
51
|
-
def add_particle(self, particle_class=Particle, **kwargs):
|
52
|
-
self.particles.append(particle_class(**kwargs))
|
53
|
-
|
54
|
-
|
55
|
-
def clear(self):
|
56
|
-
self.particles = []
|
57
|
-
|
58
|
-
|
59
|
-
def update(self, dt: float):
|
60
|
-
particles_to_remove = []
|
61
|
-
for particle in self.particles:
|
62
|
-
particle.update(dt)
|
63
|
-
if particle.dead:
|
64
|
-
particles_to_remove.append(particle)
|
65
|
-
for p in particles_to_remove:
|
66
|
-
self.particles.remove(p)
|
67
|
-
|
68
|
-
def draw(self, camera) -> bool:
|
69
|
-
camera.surface.fblits(
|
70
|
-
[
|
71
|
-
(
|
72
|
-
p.surface,
|
73
|
-
tuple(round(i * self.z_depth) for i in camera.transpose(self.rect).topleft)
|
74
|
-
) for p in self.particles
|
75
|
-
]
|
76
|
-
)
|
77
|
-
return len(self.particles)
|
batFramework/time.py
DELETED
@@ -1,75 +0,0 @@
|
|
1
|
-
import pygame
|
2
|
-
import batFramework as bf
|
3
|
-
|
4
|
-
class Timer:
|
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
|
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
|
40
|
-
|
41
|
-
def stop(self):
|
42
|
-
# Stop the timer
|
43
|
-
self.stopped = True
|
44
|
-
|
45
|
-
def end(self):
|
46
|
-
self.elapsed_progress = 1
|
47
|
-
self.stopped = False
|
48
|
-
if self.end_callback:
|
49
|
-
self.end_callback()
|
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
|
55
|
-
|
56
|
-
|
57
|
-
class Time(metaclass=bf.Singleton):
|
58
|
-
def __init__(self):
|
59
|
-
# Initialize the Time class with a dictionary of timers
|
60
|
-
self.timers = {}
|
61
|
-
|
62
|
-
def add_timer(self, timer):
|
63
|
-
# Add a timer to the dictionary
|
64
|
-
self.timers[timer.name] = timer
|
65
|
-
|
66
|
-
def update(self):
|
67
|
-
# Update all timers and remove completed ones
|
68
|
-
for timer in list(self.timers.values()):
|
69
|
-
timer.update()
|
70
|
-
|
71
|
-
to_remove = [name for name, timer in self.timers.items() if timer.ended()]
|
72
|
-
|
73
|
-
for name in to_remove:
|
74
|
-
# print(self.timers.pop(name).name,"removed !")
|
75
|
-
self.timers.pop(name)
|
File without changes
|