batframework 1.0.9a11__py3-none-any.whl → 1.0.9a12__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 +2 -0
- batFramework/action.py +280 -279
- batFramework/actionContainer.py +105 -82
- batFramework/animatedSprite.py +80 -58
- batFramework/animation.py +91 -77
- batFramework/audioManager.py +156 -131
- batFramework/baseScene.py +249 -240
- batFramework/camera.py +245 -317
- batFramework/constants.py +57 -51
- batFramework/cutscene.py +239 -253
- batFramework/cutsceneManager.py +34 -34
- batFramework/drawable.py +107 -77
- batFramework/dynamicEntity.py +30 -30
- batFramework/easingController.py +58 -58
- batFramework/entity.py +130 -130
- batFramework/enums.py +171 -135
- batFramework/fontManager.py +65 -65
- batFramework/gui/__init__.py +28 -25
- batFramework/gui/animatedLabel.py +90 -89
- batFramework/gui/button.py +17 -17
- batFramework/gui/clickableWidget.py +244 -244
- batFramework/gui/collapseContainer.py +98 -0
- batFramework/gui/constraints/__init__.py +1 -1
- batFramework/gui/constraints/constraints.py +1066 -980
- batFramework/gui/container.py +220 -206
- batFramework/gui/debugger.py +140 -130
- batFramework/gui/draggableWidget.py +63 -44
- batFramework/gui/image.py +61 -58
- batFramework/gui/indicator.py +116 -113
- batFramework/gui/interactiveWidget.py +243 -239
- batFramework/gui/label.py +147 -344
- batFramework/gui/layout.py +442 -429
- batFramework/gui/meter.py +155 -96
- batFramework/gui/radioButton.py +43 -35
- batFramework/gui/root.py +228 -228
- batFramework/gui/scrollingContainer.py +282 -0
- batFramework/gui/selector.py +232 -250
- batFramework/gui/shape.py +286 -276
- batFramework/gui/slider.py +353 -397
- batFramework/gui/style.py +10 -10
- batFramework/gui/styleManager.py +49 -54
- batFramework/gui/syncedVar.py +43 -49
- batFramework/gui/textInput.py +331 -306
- batFramework/gui/textWidget.py +308 -0
- batFramework/gui/toggle.py +140 -128
- batFramework/gui/tooltip.py +35 -30
- batFramework/gui/widget.py +546 -521
- batFramework/manager.py +131 -134
- batFramework/particle.py +118 -118
- batFramework/propertyEaser.py +79 -79
- batFramework/renderGroup.py +34 -34
- batFramework/resourceManager.py +130 -130
- batFramework/scene.py +31 -31
- batFramework/sceneLayer.py +134 -138
- batFramework/sceneManager.py +200 -197
- batFramework/scrollingSprite.py +115 -115
- batFramework/sprite.py +46 -51
- batFramework/stateMachine.py +49 -54
- batFramework/templates/__init__.py +2 -1
- batFramework/templates/character.py +15 -0
- batFramework/templates/controller.py +158 -97
- batFramework/templates/stateMachine.py +39 -0
- batFramework/tileset.py +46 -46
- batFramework/timeManager.py +213 -213
- batFramework/transition.py +162 -162
- batFramework/triggerZone.py +22 -22
- batFramework/utils.py +306 -306
- {batframework-1.0.9a11.dist-info → batframework-1.0.9a12.dist-info}/LICENSE +20 -20
- {batframework-1.0.9a11.dist-info → batframework-1.0.9a12.dist-info}/METADATA +24 -17
- batframework-1.0.9a12.dist-info/RECORD +72 -0
- batframework-1.0.9a11.dist-info/RECORD +0 -67
- {batframework-1.0.9a11.dist-info → batframework-1.0.9a12.dist-info}/WHEEL +0 -0
- {batframework-1.0.9a11.dist-info → batframework-1.0.9a12.dist-info}/top_level.txt +0 -0
batFramework/camera.py
CHANGED
@@ -1,317 +1,245 @@
|
|
1
|
-
import pygame
|
2
|
-
from pygame.math import Vector2
|
3
|
-
import batFramework as bf
|
4
|
-
from typing import Self
|
5
|
-
import math
|
6
|
-
|
7
|
-
|
8
|
-
class Camera:
|
9
|
-
def __init__(
|
10
|
-
self, flags=0, size: tuple[int, int] | None = None, convert_alpha: bool = False
|
11
|
-
) -> None:
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
self.
|
21
|
-
|
22
|
-
|
23
|
-
self.
|
24
|
-
self.
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
self.
|
29
|
-
|
30
|
-
|
31
|
-
self.
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
self.
|
36
|
-
self.
|
37
|
-
self.
|
38
|
-
|
39
|
-
|
40
|
-
self.
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
self.
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
self.
|
84
|
-
return self
|
85
|
-
|
86
|
-
def
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
self.
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
return self
|
101
|
-
|
102
|
-
def
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
return
|
139
|
-
|
140
|
-
def
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
return self
|
153
|
-
|
154
|
-
def
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
if
|
194
|
-
|
195
|
-
|
196
|
-
)
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
self.zoom_factor
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
if
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
Args:
|
248
|
-
rect (pygame.Rect | pygame.FRect): Rectangle to world_to_screen.
|
249
|
-
|
250
|
-
Returns:
|
251
|
-
pygame.FRect: Transposed rectangle.
|
252
|
-
"""
|
253
|
-
return pygame.FRect(
|
254
|
-
rect[0] - self.rect.left, rect[1] - self.rect.top, rect[2], rect[3]
|
255
|
-
)
|
256
|
-
|
257
|
-
def world_to_screen_point(
|
258
|
-
self, point: tuple[float, float] | tuple[int, int]
|
259
|
-
) -> tuple[float, float]:
|
260
|
-
"""
|
261
|
-
world_to_screen the given 2D point coordinates relative to the camera.
|
262
|
-
|
263
|
-
Args:
|
264
|
-
point (tuple[float,float] | tuple[int,int]): Point to world_to_screen.
|
265
|
-
|
266
|
-
Returns:
|
267
|
-
tuple[float,float] : Transposed point.
|
268
|
-
"""
|
269
|
-
return point[0] - self.rect.x, point[1] - self.rect.y
|
270
|
-
|
271
|
-
def screen_to_world(
|
272
|
-
self, point: tuple[float, float] | tuple[int, int]
|
273
|
-
) -> tuple[float, float]:
|
274
|
-
"""
|
275
|
-
Convert screen coordinates to world coordinates based on camera settings.
|
276
|
-
|
277
|
-
Args:
|
278
|
-
point (tuple[float,float] | tuple[int,int]): Point to screen_to_world.
|
279
|
-
Returns:
|
280
|
-
tuple: Converted world coordinates.
|
281
|
-
"""
|
282
|
-
return (
|
283
|
-
point[0] / self.zoom_factor + self.rect.x,
|
284
|
-
point[1] / self.zoom_factor + self.rect.y,
|
285
|
-
)
|
286
|
-
|
287
|
-
def update(self, dt):
|
288
|
-
if not self.follow_point_func or not (math.isfinite(dt) and dt > 0):
|
289
|
-
return
|
290
|
-
|
291
|
-
target = Vector2(self.follow_point_func())
|
292
|
-
self.vector_center.update(self.rect.center)
|
293
|
-
|
294
|
-
if self.damping == float("inf"):
|
295
|
-
self.vector_center = target
|
296
|
-
elif math.isfinite(self.damping) and self.damping > 0:
|
297
|
-
damping_factor = 1 - math.exp(-self.damping * dt)
|
298
|
-
if not math.isnan(damping_factor):
|
299
|
-
self.vector_center += (target - self.vector_center) * damping_factor
|
300
|
-
|
301
|
-
self.rect.center = self.vector_center
|
302
|
-
|
303
|
-
def draw(self, surface: pygame.Surface):
|
304
|
-
"""
|
305
|
-
Draw the camera view onto the provided surface with proper scaling.
|
306
|
-
|
307
|
-
Args:
|
308
|
-
surface (pygame.Surface): Surface to draw the camera view onto.
|
309
|
-
"""
|
310
|
-
if self.zoom_factor == 1:
|
311
|
-
surface.blit(self.surface, (0, 0), special_flags=self.blit_special_flags)
|
312
|
-
# surface.blit(self.surface, (0, 0))
|
313
|
-
return
|
314
|
-
|
315
|
-
# Scale the surface to match the resolution
|
316
|
-
scaled_surface = pygame.transform.scale(self.surface, self.target_size)
|
317
|
-
surface.blit(scaled_surface, (0, 0), special_flags=self.blit_special_flags)
|
1
|
+
import pygame
|
2
|
+
from pygame.math import Vector2
|
3
|
+
import batFramework as bf
|
4
|
+
from typing import Self
|
5
|
+
import math
|
6
|
+
|
7
|
+
|
8
|
+
class Camera:
|
9
|
+
def __init__(
|
10
|
+
self, flags=0, size: tuple[int, int] | None = None, convert_alpha: bool = False,fullscreen:bool=True
|
11
|
+
) -> None:
|
12
|
+
self.cached_surfaces: dict[tuple[int, int], pygame.Surface] = {}
|
13
|
+
self.fullscreen : bool = fullscreen # auto fill the screen (i.e react to VIDEORESIZE event)
|
14
|
+
self.flags: int = flags | (pygame.SRCALPHA if convert_alpha else 0)
|
15
|
+
self.blit_special_flags: int = pygame.BLEND_ALPHA_SDL2
|
16
|
+
|
17
|
+
size = size if size else bf.const.RESOLUTION
|
18
|
+
self.rect = pygame.FRect(0, 0, *size)
|
19
|
+
self.transform_target_surface : pygame.Surface = pygame.Surface(self.rect.size,self.flags)
|
20
|
+
self.should_convert_alpha: bool = convert_alpha
|
21
|
+
self.world_rect = pygame.FRect(0, 0, *self.rect.size)
|
22
|
+
|
23
|
+
self.vector_center = Vector2(0, 0)
|
24
|
+
self.rotation = 0.0 # Rotation in degrees
|
25
|
+
|
26
|
+
self.surface: pygame.Surface = pygame.Surface((0, 0)) # dynamic : create new at each new zoom value
|
27
|
+
|
28
|
+
self._clear_color: pygame.typing.ColorLike = pygame.Color(0, 0, 0, 0) if convert_alpha else pygame.Color(0, 0, 0)
|
29
|
+
|
30
|
+
self.follow_point_func = None
|
31
|
+
self.damping = float("inf")
|
32
|
+
self.dead_zone_radius = 10
|
33
|
+
|
34
|
+
self.zoom_factor = 1
|
35
|
+
self.max_zoom = 2
|
36
|
+
self.min_zoom = 0.1
|
37
|
+
self.zoom(1,force=True)
|
38
|
+
|
39
|
+
def get_mouse_pos(self) -> tuple[float, float]:
|
40
|
+
return self.screen_to_world(pygame.mouse.get_pos())
|
41
|
+
|
42
|
+
def set_clear_color(self, color: pygame.Color | tuple | str) -> Self:
|
43
|
+
self._clear_color = color
|
44
|
+
return self
|
45
|
+
|
46
|
+
def set_max_zoom(self, value: float) -> Self:
|
47
|
+
self.max_zoom = value
|
48
|
+
return self
|
49
|
+
|
50
|
+
def set_min_zoom(self, value: float) -> Self:
|
51
|
+
self.min_zoom = value
|
52
|
+
return self
|
53
|
+
|
54
|
+
def set_rotation(self, angle: float) -> Self:
|
55
|
+
"""
|
56
|
+
Set the camera rotation in degrees.
|
57
|
+
"""
|
58
|
+
self.rotation = angle % 360
|
59
|
+
return self
|
60
|
+
|
61
|
+
def rotate_by(self,angle:float)->Self:
|
62
|
+
"""
|
63
|
+
Increment rotation by given angle in degrees.
|
64
|
+
"""
|
65
|
+
self.rotation+=angle
|
66
|
+
self.rotation%=360
|
67
|
+
return self
|
68
|
+
|
69
|
+
def clear(self) -> None:
|
70
|
+
if self._clear_color is None:
|
71
|
+
return
|
72
|
+
self.surface.fill(self._clear_color)
|
73
|
+
|
74
|
+
def get_center(self) -> tuple[float, float]:
|
75
|
+
return self.world_rect.center
|
76
|
+
|
77
|
+
def get_position(self) -> tuple[float, float]:
|
78
|
+
return self.world_rect.topleft
|
79
|
+
|
80
|
+
def move_by(self, x: float | int, y: float | int) -> Self:
|
81
|
+
# self.world_rect.move_ip(x, y)
|
82
|
+
self.world_rect.x += x
|
83
|
+
self.world_rect.y += y
|
84
|
+
return self
|
85
|
+
|
86
|
+
def set_position(self, x, y) -> Self:
|
87
|
+
self.world_rect.topleft = (x, y)
|
88
|
+
return self
|
89
|
+
|
90
|
+
def set_center(self, x, y) -> Self:
|
91
|
+
self.world_rect.center = (x, y)
|
92
|
+
return self
|
93
|
+
|
94
|
+
def set_follow_point_func(self, func) -> Self:
|
95
|
+
self.follow_point_func = func
|
96
|
+
return self
|
97
|
+
|
98
|
+
def set_follow_speed(self, speed: float) -> Self:
|
99
|
+
self.follow_speed = speed
|
100
|
+
return self
|
101
|
+
|
102
|
+
def set_follow_damping(self, damping: float) -> Self:
|
103
|
+
self.damping = damping
|
104
|
+
return self
|
105
|
+
|
106
|
+
def set_dead_zone_radius(self, radius: float) -> Self:
|
107
|
+
self.dead_zone_radius = radius
|
108
|
+
return self
|
109
|
+
|
110
|
+
def zoom_by(self, amount: float) -> Self:
|
111
|
+
return self.zoom(self.zoom_factor + amount)
|
112
|
+
|
113
|
+
def zoom(self, factor: float,force:bool=False) -> Self:
|
114
|
+
clamped = max(self.min_zoom, min(self.max_zoom, round(factor, 2)))
|
115
|
+
if clamped == self.zoom_factor and not force:
|
116
|
+
return self
|
117
|
+
|
118
|
+
self.zoom_factor = clamped
|
119
|
+
new_res = tuple([round((i / clamped) / 2) * 2 for i in self.rect.size])
|
120
|
+
|
121
|
+
if self.surface.get_size() != new_res:
|
122
|
+
self.surface = self._get_cached_surface((new_res[0],new_res[1]))
|
123
|
+
|
124
|
+
self.world_rect = self.surface.get_frect(center=self.world_rect.center)
|
125
|
+
self.clear()
|
126
|
+
return self
|
127
|
+
|
128
|
+
def _free_cache(self):
|
129
|
+
self.cached_surfaces.clear()
|
130
|
+
|
131
|
+
def _get_cached_surface(self, new_size: tuple[int, int]):
|
132
|
+
surface = self.cached_surfaces.get(new_size)
|
133
|
+
if surface is None:
|
134
|
+
surface = pygame.Surface(new_size, flags=self.flags)
|
135
|
+
# if self.flags & pygame.SRCALPHA:
|
136
|
+
# surface = surface.convert_alpha()
|
137
|
+
self.cached_surfaces[new_size] = surface
|
138
|
+
return surface
|
139
|
+
|
140
|
+
def set_size(self, size: tuple[int, int] | None = None) -> Self:
|
141
|
+
if size is None:
|
142
|
+
size = bf.const.RESOLUTION
|
143
|
+
center = self.rect.center
|
144
|
+
self.rect.size = size
|
145
|
+
self.rect.center = center
|
146
|
+
self.transform_target_surface = pygame.Surface(self.rect.size,self.flags)
|
147
|
+
self.world_rect.center = (size[0] / 2, size[1] / 2)
|
148
|
+
self.zoom(self.zoom_factor)
|
149
|
+
return self
|
150
|
+
|
151
|
+
def intersects(self, rect: pygame.Rect | pygame.FRect) -> bool:
|
152
|
+
return self.world_rect.colliderect(rect)
|
153
|
+
|
154
|
+
def world_to_screen(self, rect: pygame.Rect | pygame.FRect) -> pygame.FRect:
|
155
|
+
return pygame.FRect(
|
156
|
+
(rect[0] - self.world_rect.left), (rect[1] - self.world_rect.top), rect[2], rect[3]
|
157
|
+
)
|
158
|
+
|
159
|
+
def world_to_screen_scaled(self, rect: pygame.Rect | pygame.FRect) -> pygame.FRect:
|
160
|
+
screen_rect = self.world_to_screen(rect)
|
161
|
+
return pygame.FRect(
|
162
|
+
screen_rect.x * self.zoom_factor,
|
163
|
+
screen_rect.y * self.zoom_factor,
|
164
|
+
screen_rect.w * self.zoom_factor,
|
165
|
+
screen_rect.h * self.zoom_factor,
|
166
|
+
)
|
167
|
+
|
168
|
+
def world_to_screen_point(self, point: tuple[float, float] | tuple[int, int]) -> tuple[float, float]:
|
169
|
+
return (
|
170
|
+
(point[0] - self.world_rect.x),
|
171
|
+
(point[1] - self.world_rect.y),
|
172
|
+
)
|
173
|
+
|
174
|
+
def world_to_screen_point_scaled(self, point: tuple[float, float] | tuple[int, int]) -> tuple[float, float]:
|
175
|
+
return (
|
176
|
+
(point[0] - self.world_rect.x) * self.zoom_factor,
|
177
|
+
(point[1] - self.world_rect.y) * self.zoom_factor,
|
178
|
+
)
|
179
|
+
|
180
|
+
|
181
|
+
def screen_to_world(self, point: tuple[float, float] | tuple[int, int]) -> tuple[float, float]:
|
182
|
+
"""
|
183
|
+
roates, scales and translates point to world coordinates
|
184
|
+
|
185
|
+
"""
|
186
|
+
# Center of the screen (zoomed+rotated surface)
|
187
|
+
cx, cy = self.rect.w / 2, self.rect.h / 2
|
188
|
+
|
189
|
+
# Offset from center
|
190
|
+
dx, dy = point[0] - cx, point[1] - cy
|
191
|
+
|
192
|
+
# rotate that offset
|
193
|
+
if self.rotation != 0:
|
194
|
+
angle_rad = math.radians(self.rotation)
|
195
|
+
cos_a = math.cos(angle_rad)
|
196
|
+
sin_a = math.sin(angle_rad)
|
197
|
+
dx, dy = cos_a * dx - sin_a * dy, sin_a * dx + cos_a * dy
|
198
|
+
|
199
|
+
# Un-zoom and add camera position
|
200
|
+
wx = (dx + cx) / self.zoom_factor + self.world_rect.x
|
201
|
+
wy = (dy + cy) / self.zoom_factor + self.world_rect.y
|
202
|
+
return wx, wy
|
203
|
+
|
204
|
+
|
205
|
+
def update(self, dt: float):
|
206
|
+
if not self.follow_point_func or not (math.isfinite(dt) and dt > 0):
|
207
|
+
return
|
208
|
+
|
209
|
+
target = Vector2(self.follow_point_func())
|
210
|
+
self.vector_center.xy.update(self.world_rect.center)
|
211
|
+
|
212
|
+
if self.damping == float("inf"):
|
213
|
+
self.vector_center.xy = target.xy
|
214
|
+
elif math.isfinite(self.damping) and self.damping > 0:
|
215
|
+
damping_factor = 1 - math.exp(-self.damping * dt)
|
216
|
+
if not math.isnan(damping_factor):
|
217
|
+
diff = target - self.vector_center
|
218
|
+
self.vector_center += diff * damping_factor
|
219
|
+
|
220
|
+
self.world_rect.center = self.vector_center
|
221
|
+
|
222
|
+
|
223
|
+
def draw(self, surface: pygame.Surface):
|
224
|
+
"""
|
225
|
+
Draw the camera view onto the provided surface with proper scaling and rotation.
|
226
|
+
|
227
|
+
Args:
|
228
|
+
surface (pygame.Surface): Surface to draw the camera view onto.
|
229
|
+
"""
|
230
|
+
# Scale the camera surface to the target size
|
231
|
+
if self.zoom_factor == 1 and self.rotation == 0:
|
232
|
+
surface.blit(self.surface, (0, 0), special_flags=self.blit_special_flags)
|
233
|
+
return
|
234
|
+
|
235
|
+
pygame.transform.scale(self.surface, self.rect.size, self.transform_target_surface)
|
236
|
+
|
237
|
+
result_surface = self.transform_target_surface
|
238
|
+
|
239
|
+
if self.rotation != 0:
|
240
|
+
# Rotate around the center of the target surface
|
241
|
+
rotated_surface = pygame.transform.rotate(result_surface, self.rotation)
|
242
|
+
rect = rotated_surface.get_rect(center=(self.rect.w // 2, self.rect.h // 2))
|
243
|
+
surface.blit(rotated_surface, rect.topleft, special_flags=self.blit_special_flags)
|
244
|
+
else:
|
245
|
+
surface.blit(result_surface, (0, 0), special_flags=self.blit_special_flags)
|