batframework 1.0.8a9__py3-none-any.whl → 1.0.8a10__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- batFramework/__init__.py +68 -51
- batFramework/action.py +126 -99
- batFramework/actionContainer.py +53 -9
- batFramework/animatedSprite.py +141 -82
- batFramework/audioManager.py +69 -26
- batFramework/camera.py +259 -69
- batFramework/character.py +27 -0
- batFramework/constants.py +16 -54
- batFramework/cutscene.py +39 -29
- batFramework/cutsceneBlocks.py +36 -43
- batFramework/dynamicEntity.py +18 -9
- batFramework/easingController.py +58 -0
- batFramework/entity.py +48 -97
- batFramework/enums.py +113 -0
- batFramework/fontManager.py +65 -0
- batFramework/gui/__init__.py +10 -2
- batFramework/gui/button.py +9 -78
- batFramework/gui/clickableWidget.py +220 -0
- batFramework/gui/constraints/__init__.py +1 -0
- batFramework/gui/constraints/constraints.py +815 -0
- batFramework/gui/container.py +174 -32
- batFramework/gui/debugger.py +131 -43
- batFramework/gui/dialogueBox.py +99 -0
- batFramework/gui/draggableWidget.py +40 -0
- batFramework/gui/image.py +56 -20
- batFramework/gui/indicator.py +38 -21
- batFramework/gui/interactiveWidget.py +192 -13
- batFramework/gui/label.py +309 -74
- batFramework/gui/layout.py +231 -63
- batFramework/gui/meter.py +74 -0
- batFramework/gui/radioButton.py +84 -0
- batFramework/gui/root.py +134 -38
- batFramework/gui/shape.py +237 -57
- batFramework/gui/slider.py +240 -0
- batFramework/gui/style.py +10 -0
- batFramework/gui/styleManager.py +48 -0
- batFramework/gui/textInput.py +247 -0
- batFramework/gui/toggle.py +101 -51
- batFramework/gui/widget.py +358 -250
- batFramework/manager.py +52 -19
- batFramework/object.py +123 -0
- batFramework/particle.py +115 -0
- batFramework/renderGroup.py +67 -0
- batFramework/resourceManager.py +100 -0
- batFramework/scene.py +281 -123
- batFramework/sceneManager.py +178 -116
- batFramework/scrollingSprite.py +114 -0
- batFramework/sprite.py +51 -0
- batFramework/stateMachine.py +11 -8
- batFramework/templates/__init__.py +2 -0
- batFramework/templates/character.py +44 -0
- batFramework/templates/states.py +166 -0
- batFramework/tileset.py +46 -0
- batFramework/time.py +145 -58
- batFramework/transition.py +195 -124
- batFramework/triggerZone.py +1 -1
- batFramework/utils.py +112 -147
- batframework-1.0.8a10.dist-info/LICENCE +21 -0
- batframework-1.0.8a10.dist-info/METADATA +43 -0
- batframework-1.0.8a10.dist-info/RECORD +62 -0
- batFramework/debugger.py +0 -48
- batFramework/easing.py +0 -71
- batFramework/gui/constraints.py +0 -204
- batFramework/gui/frame.py +0 -19
- batFramework/particles.py +0 -77
- batFramework/transitionManager.py +0 -0
- batframework-1.0.8a9.dist-info/METADATA +0 -53
- batframework-1.0.8a9.dist-info/RECORD +0 -42
- {batframework-1.0.8a9.dist-info → batframework-1.0.8a10.dist-info}/WHEEL +0 -0
- {batframework-1.0.8a9.dist-info → batframework-1.0.8a10.dist-info}/top_level.txt +0 -0
batFramework/transition.py
CHANGED
@@ -1,157 +1,228 @@
|
|
1
|
-
import pygame
|
2
1
|
import batFramework as bf
|
2
|
+
from typing import Self
|
3
|
+
import pygame
|
4
|
+
|
5
|
+
"""
|
6
|
+
Both surfaces to transition need to be the same size
|
3
7
|
|
8
|
+
"""
|
4
9
|
|
5
|
-
|
10
|
+
|
11
|
+
class Transition:
|
12
|
+
def __init__(
|
13
|
+
self, duration: float, easing_function: bf.easing = bf.easing.LINEAR
|
14
|
+
) -> None:
|
15
|
+
"""
|
16
|
+
duration : time in seconds
|
17
|
+
easing function : controls the progression rate
|
18
|
+
"""
|
19
|
+
self.duration: float = duration
|
20
|
+
self.controller = bf.EasingController(
|
21
|
+
easing_function,
|
22
|
+
duration,
|
23
|
+
update_callback=self.update,
|
24
|
+
end_callback=self.end,
|
25
|
+
)
|
26
|
+
self.start_callback = None
|
27
|
+
self.update_callback = None
|
28
|
+
self.end_callback = None
|
29
|
+
self.source: pygame.Surface = None
|
30
|
+
self.dest: pygame.Surface = None
|
31
|
+
|
32
|
+
def __repr__(self) -> str:
|
33
|
+
return f"Transition {self.__class__},{self.duration}"
|
34
|
+
|
35
|
+
def set_start_callback(self, func) -> Self:
|
36
|
+
self.start_callback = func
|
37
|
+
return self
|
38
|
+
|
39
|
+
def set_update_callback(self, func) -> Self:
|
40
|
+
self.update_callback = func
|
41
|
+
return self
|
42
|
+
|
43
|
+
def set_end_callback(self, func) -> Self:
|
44
|
+
self.end_callback = func
|
45
|
+
return self
|
46
|
+
|
47
|
+
def set_source(self, surface: pygame.Surface) -> None:
|
48
|
+
self.source = surface
|
49
|
+
|
50
|
+
def set_dest(self, surface: pygame.Surface) -> None:
|
51
|
+
self.dest = surface
|
52
|
+
|
53
|
+
def start(self):
|
54
|
+
if self.controller.has_started():
|
55
|
+
return
|
56
|
+
if self.duration:
|
57
|
+
self.controller.start()
|
58
|
+
if self.start_callback:
|
59
|
+
self.start_callback()
|
60
|
+
return
|
61
|
+
|
62
|
+
self.controller.start()
|
63
|
+
if self.start_callback:
|
64
|
+
self.start_callback()
|
65
|
+
self.controller.end()
|
66
|
+
self.update(1)
|
67
|
+
self.end()
|
68
|
+
|
69
|
+
def update(self, progression: float) -> None:
|
70
|
+
if self.update_callback:
|
71
|
+
self.update_callback(progression)
|
72
|
+
|
73
|
+
def end(self):
|
74
|
+
self.controller.stop()
|
75
|
+
if self.end_callback:
|
76
|
+
self.end_callback()
|
77
|
+
|
78
|
+
def draw(self, surface: pygame.Surface) -> None:
|
79
|
+
pass
|
80
|
+
|
81
|
+
def skip(self, no_callback: bool = False):
|
82
|
+
self.controller.stop()
|
83
|
+
if self.end_callback and (no_callback == False):
|
84
|
+
self.end_callback()
|
85
|
+
|
86
|
+
|
87
|
+
class FadeColor(Transition):
|
6
88
|
def __init__(
|
7
89
|
self,
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
90
|
+
color: tuple,
|
91
|
+
middle_duration: float,
|
92
|
+
first_duration: float | None = None,
|
93
|
+
second_duration: float | None = None,
|
94
|
+
easing_function: bf.easing = bf.easing.LINEAR,
|
12
95
|
) -> None:
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
96
|
+
super().__init__(0, easing_function)
|
97
|
+
if first_duration is None:
|
98
|
+
first_duration = middle_duration
|
99
|
+
if second_duration is None:
|
100
|
+
second_duration = middle_duration
|
101
|
+
|
102
|
+
self.first = Fade(first_duration)
|
103
|
+
self.second = Fade(second_duration)
|
104
|
+
self.color = color
|
105
|
+
self.middle_duration = middle_duration
|
19
106
|
self.index = 0
|
20
107
|
|
21
|
-
|
22
|
-
self.
|
108
|
+
self.timer = bf.Timer(middle_duration, self.transition_to_second)
|
109
|
+
self.first.set_end_callback(self.transition_to_middle)
|
110
|
+
self.second.set_end_callback(self.transition_to_end)
|
23
111
|
|
24
|
-
def
|
25
|
-
self.
|
112
|
+
def transition_to_middle(self):
|
113
|
+
self.next_step(self.timer.start)
|
26
114
|
|
27
|
-
def
|
28
|
-
self.
|
115
|
+
def transition_to_second(self):
|
116
|
+
self.next_step(self.second.start)
|
29
117
|
|
30
|
-
def
|
31
|
-
|
118
|
+
def transition_to_end(self):
|
119
|
+
self.next_step(self.end)
|
32
120
|
|
33
|
-
def
|
34
|
-
|
121
|
+
def next_step(self, callback=None) -> None:
|
122
|
+
self.index += 1
|
123
|
+
if callback:
|
124
|
+
callback()
|
35
125
|
|
36
|
-
def
|
37
|
-
|
126
|
+
def set_source(self, surface) -> None:
|
127
|
+
super().set_source(surface)
|
128
|
+
self.first.set_source(surface)
|
38
129
|
|
39
|
-
def
|
40
|
-
|
130
|
+
def set_dest(self, surface) -> None:
|
131
|
+
super().set_dest(surface)
|
132
|
+
self.second.set_dest(surface)
|
41
133
|
|
134
|
+
def start(self):
|
135
|
+
if self.start_callback:
|
136
|
+
self.start_callback()
|
42
137
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
color_duration=200,
|
50
|
-
color=bf.color.CLOUD_WHITE,
|
51
|
-
**kwargs,
|
52
|
-
) -> None:
|
53
|
-
super().__init__(source_surf, dest_surf, duration)
|
54
|
-
self.target_time = duration * 2 + color_duration
|
55
|
-
self.color_surf = pygame.Surface((source_surf.get_rect().size)).convert_alpha()
|
56
|
-
self.color_surf.fill(color)
|
57
|
-
self.ease_out = bf.EasingAnimation(
|
58
|
-
easing_function=bf.Easing.EASE_IN,
|
59
|
-
duration=(duration-color_duration)//2,
|
60
|
-
update_callback = lambda x: self.color_surf.set_alpha(int(255 - (255 * x))),
|
61
|
-
end_callback=lambda: self.set_ended(True))
|
62
|
-
|
63
|
-
self.color_timer = bf.Timer(
|
64
|
-
duration=color_duration,
|
65
|
-
end_callback=lambda: self.set_state("out"))
|
66
|
-
self.ease_in = bf.EasingAnimation(
|
67
|
-
easing_function=bf.Easing.EASE_IN,
|
68
|
-
duration=(duration-color_duration)//2,
|
69
|
-
update_callback=lambda x: self.color_surf.set_alpha(int(255 * x)),
|
70
|
-
# update_callback=lambda x: print(x),
|
71
|
-
end_callback=lambda: self.set_state("color"))
|
72
|
-
self.state = None
|
73
|
-
|
74
|
-
self.state = "in"
|
75
|
-
self.ease_in.start()
|
76
|
-
|
77
|
-
def set_state(self, state: str):
|
78
|
-
self.state = state
|
79
|
-
if state == "in":
|
80
|
-
self.ease_in.start()
|
81
|
-
elif state == "color":
|
82
|
-
self.color_timer.start()
|
83
|
-
elif state == "out":
|
84
|
-
self.ease_out.start()
|
85
|
-
|
86
|
-
def has_ended(self):
|
87
|
-
return self.ended
|
88
|
-
|
89
|
-
def set_ended(self, val):
|
90
|
-
super().set_ended(val)
|
138
|
+
self.color_surf = pygame.Surface(self.source.get_size())
|
139
|
+
self.color_surf.fill(self.color)
|
140
|
+
|
141
|
+
self.first.set_dest(self.color_surf)
|
142
|
+
self.second.set_source(self.color_surf)
|
143
|
+
self.first.start()
|
91
144
|
|
92
145
|
def draw(self, surface):
|
93
|
-
if self.
|
94
|
-
|
95
|
-
|
146
|
+
if self.index == 0:
|
147
|
+
self.first.draw(surface)
|
148
|
+
elif self.index == 1:
|
149
|
+
surface.blit(self.color_surf, (0, 0))
|
150
|
+
else:
|
151
|
+
self.second.draw(surface)
|
96
152
|
|
153
|
+
def skip(self, no_callback: bool = False):
|
154
|
+
if not no_callback and self.end_callback:
|
155
|
+
self.end_callback()
|
97
156
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
self.anim = bf.EasingAnimation(None,bf.Easing.EASE_IN_OUT,duration,self.update_surface,lambda : self.set_ended(True))
|
102
|
-
self.anim.start()
|
157
|
+
self.first.controller.stop()
|
158
|
+
self.timer.stop()
|
159
|
+
self.second.controller.stop()
|
103
160
|
|
104
|
-
def update_surface(self,progress):
|
105
|
-
self.source.set_alpha(int(255 - (255 * progress)))
|
106
|
-
self.dest.set_alpha(int(255 * progress))
|
107
161
|
|
108
|
-
|
109
|
-
|
162
|
+
|
163
|
+
class Fade(Transition):
|
164
|
+
def end(self):
|
165
|
+
self.dest.set_alpha(255)
|
166
|
+
return super().end()
|
110
167
|
|
111
168
|
def draw(self, surface):
|
169
|
+
dest_alpha = 255 * self.controller.get_value()
|
170
|
+
self.dest.set_alpha(dest_alpha)
|
112
171
|
surface.blit(self.source, (0, 0))
|
113
172
|
surface.blit(self.dest, (0, 0))
|
114
173
|
|
115
174
|
|
116
|
-
class
|
117
|
-
def
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
175
|
+
class GlideRight(Transition):
|
176
|
+
def draw(self, surface):
|
177
|
+
width = surface.get_width()
|
178
|
+
source_x = -self.controller.get_value() * width
|
179
|
+
surface.blit(self.source, (source_x, 0))
|
180
|
+
surface.blit(self.dest, (width + source_x, 0))
|
181
|
+
|
182
|
+
|
183
|
+
class GlideLeft(Transition):
|
184
|
+
def draw(self, surface):
|
185
|
+
width = surface.get_width()
|
186
|
+
source_x = self.controller.get_value() * width
|
187
|
+
surface.blit(self.source, (source_x, 0))
|
188
|
+
surface.blit(self.dest, (source_x - width, 0))
|
189
|
+
|
190
|
+
|
191
|
+
class CircleOut(Transition):
|
192
|
+
def start(self):
|
193
|
+
super().start()
|
194
|
+
self.circle_surf = self.source.copy()
|
195
|
+
self.circle_surf.set_colorkey((0, 0, 0))
|
196
|
+
self.circle_surf.fill((0, 0, 0))
|
197
|
+
self.surface_width = self.circle_surf.get_width()
|
198
|
+
|
199
|
+
def draw(self, surface):
|
200
|
+
v = self.controller.get_value()
|
201
|
+
|
202
|
+
radius = self.surface_width * v
|
203
|
+
pygame.draw.circle(
|
204
|
+
self.circle_surf, "white", self.circle_surf.get_rect().center, radius
|
146
205
|
)
|
147
|
-
|
206
|
+
mask = pygame.mask.from_surface(self.circle_surf)
|
207
|
+
mask.to_surface(surface=surface, setsurface=self.dest, unsetsurface=self.source)
|
148
208
|
|
149
|
-
def update_offset(self, vec):
|
150
|
-
self.offset.update(vec)
|
151
209
|
|
152
|
-
|
153
|
-
|
210
|
+
class CircleIn(Transition):
|
211
|
+
def start(self):
|
212
|
+
super().start()
|
213
|
+
self.circle_surf = self.source.copy()
|
214
|
+
self.circle_surf.set_colorkey((0, 0, 0))
|
215
|
+
self.circle_surf.fill((0, 0, 0))
|
216
|
+
self.surface_width = self.circle_surf.get_width()
|
154
217
|
|
155
218
|
def draw(self, surface):
|
156
|
-
|
157
|
-
|
219
|
+
v = self.controller.get_value()
|
220
|
+
radius = self.surface_width - (self.surface_width * v)
|
221
|
+
self.circle_surf.fill((0, 0, 0))
|
222
|
+
pygame.draw.circle(
|
223
|
+
self.circle_surf, "white", self.circle_surf.get_rect().center, radius
|
224
|
+
)
|
225
|
+
mask = pygame.mask.from_surface(self.circle_surf)
|
226
|
+
mask.to_surface(surface=surface, setsurface=self.source, unsetsurface=self.dest)
|
227
|
+
|
228
|
+
|
batFramework/triggerZone.py
CHANGED
@@ -4,7 +4,7 @@ import batFramework as bf
|
|
4
4
|
class TriggerZone(bf.Entity):
|
5
5
|
def __init__(self, size, trigger, callback, active=True) -> None:
|
6
6
|
super().__init__(size, True)
|
7
|
-
self.set_debug_color(bf.color.
|
7
|
+
self.set_debug_color(bf.color.RED)
|
8
8
|
self.active = active
|
9
9
|
self.callback = callback
|
10
10
|
self.trigger = trigger
|
batFramework/utils.py
CHANGED
@@ -3,9 +3,14 @@ from enum import Enum
|
|
3
3
|
import os
|
4
4
|
import batFramework as bf
|
5
5
|
import json
|
6
|
+
from .enums import *
|
7
|
+
import re
|
8
|
+
from typing import Callable, TYPE_CHECKING, Any
|
9
|
+
from functools import cache
|
10
|
+
if TYPE_CHECKING:
|
11
|
+
from .object import Object
|
12
|
+
from .entity import Entity
|
6
13
|
|
7
|
-
MAX_FONT_SIZE = 100
|
8
|
-
MIN_FONT_SIZE = 8
|
9
14
|
|
10
15
|
class Singleton(type):
|
11
16
|
_instances = {}
|
@@ -16,169 +21,129 @@ class Singleton(type):
|
|
16
21
|
return cls._instances[cls]
|
17
22
|
|
18
23
|
|
19
|
-
class
|
20
|
-
HORIZONTAL = "horizontal"
|
21
|
-
VERTICAL = "vertical"
|
22
|
-
|
23
|
-
|
24
|
-
class Alignment(Enum):
|
25
|
-
LEFT = "left"
|
26
|
-
RIGHT = "right"
|
27
|
-
CENTER = "center"
|
28
|
-
TOP = "top"
|
29
|
-
BOTTOM = "bottom"
|
24
|
+
class Utils:
|
30
25
|
|
26
|
+
@staticmethod
|
27
|
+
def split_surface(
|
28
|
+
surface: pygame.Surface, split_size: tuple[int, int], func=None
|
29
|
+
) -> dict[tuple[int, int], pygame.Surface]:
|
30
|
+
"""
|
31
|
+
Splits a surface into subsurfaces and returns a dictionnary of them
|
32
|
+
with their tuple coordinates as keys.
|
33
|
+
Exemple : '(0,0) : Surface'
|
34
|
+
"""
|
35
|
+
width, height = surface.get_size()
|
36
|
+
res = {}
|
37
|
+
for iy, y in enumerate(range(0, height, split_size[1])):
|
38
|
+
for ix, x in enumerate(range(0, width, split_size[0])):
|
39
|
+
sub = surface.subsurface((x, y, split_size[0], split_size[1]))
|
40
|
+
|
41
|
+
if func is not None:
|
42
|
+
sub = func(sub)
|
43
|
+
|
44
|
+
res[(ix, iy)] = sub
|
31
45
|
|
32
|
-
|
33
|
-
FILL = "fill"
|
34
|
-
FIT = "fit"
|
46
|
+
return res
|
35
47
|
|
48
|
+
@staticmethod
|
49
|
+
def filter_text(text_mode: textMode):
|
50
|
+
if text_mode == textMode.ALPHABETICAL:
|
51
|
+
pattern = re.compile(r"[^a-zA-Z]")
|
52
|
+
elif text_mode == textMode.NUMERICAL:
|
53
|
+
pattern = re.compile(r"[^0-9]")
|
54
|
+
elif text_mode == textMode.ALPHANUMERICAL:
|
55
|
+
pattern = re.compile(r"[^a-zA-Z0-9]")
|
56
|
+
else:
|
57
|
+
raise ValueError("Unsupported text mode")
|
36
58
|
|
37
|
-
|
38
|
-
|
39
|
-
FONTS = {}
|
40
|
-
tilesets = {}
|
59
|
+
def filter_function(s: str) -> str:
|
60
|
+
return pattern.sub("", s)
|
41
61
|
|
42
|
-
|
43
|
-
def get_path(path: str):
|
44
|
-
return os.path.join(bf.const.RESOURCE_PATH, path)
|
62
|
+
return filter_function
|
45
63
|
|
46
|
-
@staticmethod
|
47
|
-
def load_json_from_file(path: str) -> dict:
|
48
|
-
try:
|
49
|
-
with open(Utils.get_path(path), "r") as file:
|
50
|
-
data = json.load(file)
|
51
|
-
return data
|
52
|
-
except FileNotFoundError:
|
53
|
-
print(f"File '{path}' not found")
|
54
|
-
return None
|
55
64
|
|
56
65
|
@staticmethod
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
66
|
+
@cache
|
67
|
+
def create_spotlight(inside_color, outside_color, radius, radius_stop=None, dest_surf=None,size=None):
|
68
|
+
"""
|
69
|
+
Draws a circle spotlight centered on a surface
|
70
|
+
inner color on the center
|
71
|
+
gradient towards outside color from radius to radius stop
|
72
|
+
surface background is made transparent
|
73
|
+
if des_surf is None:
|
74
|
+
if size is None : size is radius_stop*radius_stop
|
75
|
+
returns the newly created surface of size 'size' with the spotlight drawn
|
76
|
+
|
77
|
+
"""
|
78
|
+
if radius_stop is None:
|
79
|
+
radius_stop = radius
|
80
|
+
diameter = radius_stop * 2
|
81
|
+
|
82
|
+
if dest_surf is None:
|
83
|
+
if size is None:
|
84
|
+
size = (diameter,diameter)
|
85
|
+
dest_surf = pygame.Surface(size, pygame.SRCALPHA)
|
86
|
+
|
87
|
+
dest_surf.fill((0,0,0,0))
|
88
|
+
|
89
|
+
|
90
|
+
center = dest_surf.get_rect().center
|
91
|
+
|
92
|
+
if radius_stop != radius:
|
93
|
+
for r in range(radius_stop, radius - 1, -1):
|
94
|
+
color = [
|
95
|
+
inside_color[i] + (outside_color[i] - inside_color[i]) * (r - radius) / (radius_stop - radius)
|
96
|
+
for i in range(3)
|
97
|
+
] + [255] # Preserve the alpha channel as fully opaque
|
98
|
+
pygame.draw.circle(dest_surf, color, center, r)
|
99
|
+
else:
|
100
|
+
pygame.draw.circle(dest_surf, inside_color, center, radius)
|
74
101
|
|
102
|
+
return dest_surf
|
75
103
|
|
76
104
|
@staticmethod
|
77
|
-
def
|
78
|
-
if
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
Utils.FONTS[font_name] = {}
|
91
|
-
|
92
|
-
for size in range(MIN_FONT_SIZE, MAX_FONT_SIZE, 2):
|
93
|
-
Utils.FONTS[key][size] = pygame.font.SysFont(font_name,size=size)
|
94
|
-
|
105
|
+
def draw_spotlight(dest_surf:pygame.Surface,inside_color,outside_color,radius,radius_stop=None,center=None):
|
106
|
+
if radius_stop is None:
|
107
|
+
radius_stop = radius
|
108
|
+
center = dest_surf.get_rect().center if center is None else center
|
109
|
+
if radius_stop != radius:
|
110
|
+
for r in range(radius_stop, radius - 1, -1):
|
111
|
+
color = [
|
112
|
+
inside_color[i] + (outside_color[i] - inside_color[i]) * (r - radius) / (radius_stop - radius)
|
113
|
+
for i in range(3)
|
114
|
+
] + [255]
|
115
|
+
pygame.draw.circle(dest_surf, color, center, r)
|
116
|
+
else:
|
117
|
+
pygame.draw.circle(dest_surf, inside_color, center, radius)
|
95
118
|
|
96
119
|
@staticmethod
|
97
|
-
def
|
98
|
-
|
99
|
-
|
100
|
-
return
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
def __init__(self, surface: pygame.Surface, tilesize) -> None:
|
106
|
-
self.tile_dict = {}
|
107
|
-
self.surface = surface
|
108
|
-
self.tile_size = tilesize
|
109
|
-
self.split_surface(surface)
|
110
|
-
|
111
|
-
def split_surface(self, surface: pygame.Surface):
|
112
|
-
width, height = surface.get_size()
|
113
|
-
num_tiles_x = width // self.tile_size
|
114
|
-
num_tiles_y = height // self.tile_size
|
115
|
-
# Iterate over the tiles vertically and horizontally
|
116
|
-
for y in range(num_tiles_y):
|
117
|
-
for x in range(num_tiles_x):
|
118
|
-
# Calculate the coordinates of the current tile in the tileset
|
119
|
-
tile_x = x * self.tile_size
|
120
|
-
tile_y = y * self.tile_size
|
121
|
-
# Create a subsurface for the current tile
|
122
|
-
tile_surface = surface.subsurface(
|
123
|
-
pygame.Rect(tile_x, tile_y, self.tile_size, self.tile_size)
|
124
|
-
)
|
125
|
-
# Calculate the unique key for the tile (e.g., based on its coordinates)
|
126
|
-
tile_key = (x, y)
|
127
|
-
# Store the subsurface in the dictionary with the corresponding key
|
128
|
-
self.tile_dict[tile_key] = tile_surface
|
129
|
-
# print(self.tile_dict)
|
130
|
-
|
131
|
-
def get_tile(self, x, y, flipX=False, flipY=False) -> pygame.Surface | None:
|
132
|
-
if (x, y) not in self.tile_dict:
|
133
|
-
return None
|
134
|
-
if flipX or flipY:
|
135
|
-
key = f"{x}{y}:{flipX}{flipY}"
|
136
|
-
if not key in self._flip_cache:
|
137
|
-
self._flip_cache[key] = pygame.transform.flip(
|
138
|
-
self.tile_dict[(x, y)], flipX, flipY
|
139
|
-
)
|
140
|
-
return self._flip_cache[key]
|
141
|
-
return self.tile_dict[(x, y)]
|
120
|
+
def animate_move(entity:"Object", start_pos : tuple[float,float], end_pos:tuple[float,float])->Callable[[float],None]:
|
121
|
+
def func(x):
|
122
|
+
entity.set_center(start_pos[0]+(end_pos[0]-start_pos[0])*x,start_pos[1]+(end_pos[1]-start_pos[1])*x)
|
123
|
+
return func
|
124
|
+
|
125
|
+
def animate_move_to(entity: "Object", end_pos: tuple[float, float]) -> Callable[[float], None]:
|
126
|
+
# Start position will be captured once when the animation starts
|
127
|
+
start_pos = [None]
|
142
128
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
os.path.join(bf.const.RESOURCE_PATH, file)
|
147
|
-
).convert_alpha()
|
148
|
-
width, height = src.get_size()
|
149
|
-
res = []
|
150
|
-
for y in range(0, height, cell_height):
|
151
|
-
for x in range(0, width, cell_width):
|
152
|
-
sub = src.subsurface((x, y, cell_width, cell_height))
|
153
|
-
if flipX:
|
154
|
-
sub = pygame.transform.flip(sub, True, False)
|
155
|
-
|
156
|
-
res.append(sub)
|
157
|
-
return res
|
129
|
+
def update_position(progression: float):
|
130
|
+
if start_pos[0] is None:
|
131
|
+
start_pos[0] = entity.rect.center # Capture the start position at the start of the animation
|
158
132
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
else:
|
163
|
-
img = pygame.image.load(
|
164
|
-
os.path.join(bf.const.RESOURCE_PATH, path)
|
165
|
-
).convert_alpha()
|
166
|
-
tileset = Utils.Tileset(img, tilesize)
|
167
|
-
Utils.tilesets[name] = tileset
|
168
|
-
return tileset
|
133
|
+
# Calculate new position based on progression
|
134
|
+
new_x = start_pos[0][0] + (end_pos[0] - start_pos[0][0]) * progression
|
135
|
+
new_y = start_pos[0][1] + (end_pos[1] - start_pos[0][1]) * progression
|
169
136
|
|
170
|
-
|
171
|
-
|
172
|
-
if name not in Utils.tilesets:
|
173
|
-
return None
|
174
|
-
return Utils.tilesets[name]
|
137
|
+
# Set the entity's new position
|
138
|
+
entity.set_center(new_x, new_y)
|
175
139
|
|
140
|
+
return update_position
|
176
141
|
|
142
|
+
@staticmethod
|
143
|
+
def animate_alpha(entity:"Entity", start : int, end:int)->Callable[[float],None]:
|
144
|
+
def func(x):
|
145
|
+
entity.set_alpha(int(pygame.math.clamp(start+(end-start)*x,0,255)))
|
146
|
+
return func
|
177
147
|
|
178
148
|
|
179
149
|
|
180
|
-
def move_points(delta, *points):
|
181
|
-
res = []
|
182
|
-
for point in points:
|
183
|
-
res.append((point[0] + delta[0], point[1] + delta[1]))
|
184
|
-
return res
|
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) [2023] [TURAN BATURAY]
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|