batframework 1.0.8a13__tar.gz → 1.0.8a14__tar.gz
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-1.0.8a13/src/batframework.egg-info → batframework-1.0.8a14}/PKG-INFO +1 -1
- {batframework-1.0.8a13 → batframework-1.0.8a14}/pyproject.toml +1 -1
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/__init__.py +2 -2
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/animatedSprite.py +1 -1
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/character.py +1 -1
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/constants.py +4 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/cutscene.py +7 -5
- batframework-1.0.8a13/src/batFramework/entity.py → batframework-1.0.8a14/src/batFramework/drawable.py +3 -2
- batframework-1.0.8a13/src/batFramework/object.py → batframework-1.0.8a14/src/batFramework/entity.py +14 -13
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/container.py +1 -1
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/debugger.py +1 -1
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/label.py +18 -40
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/root.py +0 -6
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/widget.py +1 -1
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/manager.py +33 -32
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/particle.py +1 -1
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/scene.py +1 -34
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/sceneManager.py +5 -23
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/sprite.py +2 -2
- batframework-1.0.8a13/src/batFramework/time.py → batframework-1.0.8a14/src/batFramework/timeManager.py +0 -2
- batframework-1.0.8a14/src/batFramework/utils.py +248 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14/src/batframework.egg-info}/PKG-INFO +1 -1
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batframework.egg-info/SOURCES.txt +2 -2
- batframework-1.0.8a13/src/batFramework/utils.py +0 -149
- {batframework-1.0.8a13 → batframework-1.0.8a14}/LICENCE +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/README.md +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/setup.cfg +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/action.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/actionContainer.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/animation.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/audioManager.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/camera.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/cutsceneBlocks.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/dynamicEntity.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/easingController.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/enums.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/fontManager.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/__init__.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/button.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/clickableWidget.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/constraints/__init__.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/constraints/constraints.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/dialogueBox.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/draggableWidget.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/image.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/indicator.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/interactiveWidget.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/layout.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/meter.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/radioButton.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/shape.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/slider.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/style.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/styleManager.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/textInput.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/toggle.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/renderGroup.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/resourceManager.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/scrollingSprite.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/stateMachine.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/templates/__init__.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/templates/character.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/templates/states.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/tileset.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/transition.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/triggerZone.py +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batframework.egg-info/dependency_links.txt +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batframework.egg-info/requires.txt +0 -0
- {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batframework.egg-info/top_level.txt +0 -0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "batframework"
|
7
|
-
version = "1.0.
|
7
|
+
version = "1.0.8a14"
|
8
8
|
description = "Pygame framework for making games easier."
|
9
9
|
readme = "README.md"
|
10
10
|
classifiers = [ "Programming Language :: Python :: 3", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent",]
|
@@ -8,7 +8,7 @@ from .resourceManager import ResourceManager
|
|
8
8
|
from .fontManager import FontManager
|
9
9
|
from .utils import Utils as utils
|
10
10
|
from .tileset import Tileset
|
11
|
-
from .
|
11
|
+
from .timeManager import TimeManager,Timer,SceneTimer
|
12
12
|
from .easingController import EasingController
|
13
13
|
from .cutscene import Cutscene, CutsceneManager
|
14
14
|
from .cutsceneBlocks import *
|
@@ -17,8 +17,8 @@ import batFramework.transition as transition
|
|
17
17
|
from .action import Action
|
18
18
|
from .actionContainer import *
|
19
19
|
from .camera import Camera
|
20
|
-
from .object import Object
|
21
20
|
from .entity import Entity
|
21
|
+
from .drawable import Drawable
|
22
22
|
from .renderGroup import RenderGroup
|
23
23
|
from .dynamicEntity import DynamicEntity
|
24
24
|
from .sprite import Sprite
|
@@ -3,7 +3,7 @@ import pygame
|
|
3
3
|
from typing import List, Dict, Tuple, Union, Optional, Self
|
4
4
|
from .animation import Animation
|
5
5
|
|
6
|
-
class AnimatedSprite(bf.
|
6
|
+
class AnimatedSprite(bf.Drawable):
|
7
7
|
def __init__(self, size: Optional[Tuple[int, int]] = None,*args,**kwargs) -> None:
|
8
8
|
super().__init__(size, no_surface=True,*args,**kwargs)
|
9
9
|
self.float_counter: float = 0
|
@@ -3,7 +3,7 @@ from .stateMachine import State
|
|
3
3
|
from .animatedSprite import AnimatedSprite
|
4
4
|
from .dynamicEntity import DynamicEntity
|
5
5
|
|
6
|
-
class Character(AnimatedSprite
|
6
|
+
class Character(DynamicEntity,AnimatedSprite):
|
7
7
|
def __init__(self,*args,**kwargs) -> None:
|
8
8
|
super().__init__(*args,**kwargs)
|
9
9
|
self.state_machine = bf.StateMachine(self)
|
@@ -4,6 +4,8 @@ import pygame
|
|
4
4
|
class Constants:
|
5
5
|
SCREEN: pygame.Surface = None
|
6
6
|
RESOLUTION: tuple[int, int] = (1280, 720)
|
7
|
+
WIDTH = 1280
|
8
|
+
HEIGHT = 720
|
7
9
|
VSYNC = 0
|
8
10
|
FLAGS: int = pygame.SCALED | pygame.RESIZABLE
|
9
11
|
FPS: int = 60
|
@@ -18,6 +20,8 @@ class Constants:
|
|
18
20
|
@staticmethod
|
19
21
|
def set_resolution(resolution: tuple[int, int]):
|
20
22
|
Constants.RESOLUTION = resolution
|
23
|
+
Constants.WIDTH = resolution[0]
|
24
|
+
Constants.HEIGHT = resolution[1]
|
21
25
|
|
22
26
|
@staticmethod
|
23
27
|
def set_default_cursor(cursor: pygame.Cursor):
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import batFramework as bf
|
2
|
-
from typing import TYPE_CHECKING
|
2
|
+
from typing import TYPE_CHECKING,Self
|
3
3
|
|
4
4
|
class CutsceneBlock: ...
|
5
5
|
|
@@ -75,13 +75,15 @@ class Cutscene:
|
|
75
75
|
def init_blocks(self):
|
76
76
|
pass
|
77
77
|
|
78
|
-
def add_blocks(self, *blocks: CutsceneBlock):
|
78
|
+
def add_blocks(self, *blocks: CutsceneBlock)->Self:
|
79
79
|
self.cutscene_blocks.extend(blocks)
|
80
|
-
|
81
|
-
|
80
|
+
return self
|
81
|
+
|
82
|
+
def add_end_blocks(self, *blocks: CutsceneBlock)->Self:
|
82
83
|
_ = [block.set_parent_cutscene(self) for block in blocks]
|
83
84
|
self.end_blocks.extend(blocks)
|
84
|
-
|
85
|
+
return self
|
86
|
+
|
85
87
|
def get_scene_at(self, index):
|
86
88
|
return bf.CutsceneManager().manager.scenes[index]
|
87
89
|
|
@@ -1,10 +1,10 @@
|
|
1
1
|
from typing import Any, Self
|
2
2
|
import pygame
|
3
3
|
import batFramework as bf
|
4
|
-
from .
|
4
|
+
from .entity import Entity
|
5
5
|
|
6
6
|
|
7
|
-
class Entity
|
7
|
+
class Drawable(Entity):
|
8
8
|
"""
|
9
9
|
Basic entity class
|
10
10
|
"""
|
@@ -19,6 +19,7 @@ class Entity(Object):
|
|
19
19
|
) -> None:
|
20
20
|
super().__init__()
|
21
21
|
self.visible: bool = True
|
22
|
+
self.render_order: int = 0
|
22
23
|
self.rect.size = (10, 10) if size is None else size
|
23
24
|
self.convert_alpha: bool = convert_alpha
|
24
25
|
self.surface_flags: int = surface_flags
|
batframework-1.0.8a13/src/batFramework/object.py → batframework-1.0.8a14/src/batFramework/entity.py
RENAMED
@@ -7,7 +7,7 @@ if TYPE_CHECKING:
|
|
7
7
|
from .camera import Camera
|
8
8
|
|
9
9
|
|
10
|
-
class
|
10
|
+
class Entity:
|
11
11
|
__count = 0
|
12
12
|
__available_uid = set()
|
13
13
|
__used_uid = set()
|
@@ -17,18 +17,17 @@ class Object:
|
|
17
17
|
self.tags: list[str] = []
|
18
18
|
self.parent_scene: bf.Scene | None = None
|
19
19
|
self.debug_color: tuple | str = "red"
|
20
|
-
self.
|
21
|
-
self.uid
|
22
|
-
Object.__used_uid.add(self.uid)
|
20
|
+
self.uid: int = Entity.__count
|
21
|
+
Entity.__used_uid.add(self.uid)
|
23
22
|
|
24
|
-
if
|
25
|
-
self.name =
|
23
|
+
if Entity.__available_uid:
|
24
|
+
self.name = Entity.__available_uid.pop()
|
26
25
|
else:
|
27
|
-
self.name =
|
28
|
-
|
26
|
+
self.name = Entity.__count
|
27
|
+
Entity.__count += 1
|
29
28
|
|
30
29
|
def __del__(self):
|
31
|
-
|
30
|
+
Entity.__available_uid.add(self.uid)
|
32
31
|
|
33
32
|
def set_position(self, x, y) -> Self:
|
34
33
|
self.rect.topleft = x, y
|
@@ -62,11 +61,13 @@ class Object:
|
|
62
61
|
pass
|
63
62
|
|
64
63
|
def set_uid(self, uid: int) -> Self:
|
65
|
-
if uid in
|
64
|
+
if uid in Entity.__used_uid:
|
66
65
|
print(f"set_uid error : UID '{uid}' is already in use")
|
67
66
|
return self
|
68
67
|
self.uid = uid
|
69
|
-
|
68
|
+
if uid in Entity.__used_uid:
|
69
|
+
Entity.__used_uid.remove(uid)
|
70
|
+
Entity.__used_uid.add(uid)
|
70
71
|
return self
|
71
72
|
|
72
73
|
def add_tags(self, *tags) -> Self:
|
@@ -87,7 +88,7 @@ class Object:
|
|
87
88
|
|
88
89
|
def process_event(self, event: pygame.Event) -> bool:
|
89
90
|
"""
|
90
|
-
Returns bool : True if the method is blocking (no propagation to next
|
91
|
+
Returns bool : True if the method is blocking (no propagation to next Entity of the scene)
|
91
92
|
"""
|
92
93
|
if event.consumed:
|
93
94
|
return
|
@@ -112,7 +113,7 @@ class Object:
|
|
112
113
|
|
113
114
|
def update(self, dt: float) -> None:
|
114
115
|
"""
|
115
|
-
Update method to be overriden by subclasses of
|
116
|
+
Update method to be overriden by subclasses of Entity (must call do_update and do_reset_actions)
|
116
117
|
"""
|
117
118
|
self.do_update(dt)
|
118
119
|
self.do_reset_actions()
|
@@ -174,7 +174,7 @@ class Container(Shape, InteractiveWidget):
|
|
174
174
|
self.paint()
|
175
175
|
self.dirty_surface = False
|
176
176
|
|
177
|
-
bf.
|
177
|
+
bf.Drawable.draw(self, camera)
|
178
178
|
|
179
179
|
if self.clip_children:
|
180
180
|
new_clip = camera.world_to_screen(self.get_padded_rect())
|
@@ -72,7 +72,7 @@ class Debugger(Label):
|
|
72
72
|
def update(self, dt: float) -> None:
|
73
73
|
if not self.parent_scene:
|
74
74
|
return
|
75
|
-
if
|
75
|
+
if bf.ResourceManager().get_sharedVar("debug_mode") != bf.debugMode.DEBUGGER:
|
76
76
|
self.set_visible(False)
|
77
77
|
return
|
78
78
|
self.set_visible(True)
|
@@ -37,7 +37,6 @@ class Label(Shape):
|
|
37
37
|
self.text_rect = pygame.FRect(0, 0, 0, 0)
|
38
38
|
# text surface (result of font.render)
|
39
39
|
self.text_surface: pygame.Surface = pygame.Surface((0, 0))
|
40
|
-
self.do_caching: bool = False
|
41
40
|
|
42
41
|
self.show_text_outline: bool = False
|
43
42
|
|
@@ -54,21 +53,9 @@ class Label(Shape):
|
|
54
53
|
self.set_autoresize(True)
|
55
54
|
self.set_font(force=True)
|
56
55
|
|
57
|
-
@staticmethod
|
58
|
-
def clear_cache():
|
59
|
-
Label._text_cache = {}
|
60
|
-
|
61
56
|
def __str__(self) -> str:
|
62
57
|
return f"Label({repr(self.text)})"
|
63
58
|
|
64
|
-
def enable_caching(self) -> Self:
|
65
|
-
self.do_caching = True
|
66
|
-
return self
|
67
|
-
|
68
|
-
def disable_caching(self) -> Self:
|
69
|
-
self.do_caching = False
|
70
|
-
return self
|
71
|
-
|
72
59
|
def set_text_color(self, color) -> Self:
|
73
60
|
self.text_color = color
|
74
61
|
self.dirty_surface = True
|
@@ -205,35 +192,26 @@ class Label(Shape):
|
|
205
192
|
return self.text
|
206
193
|
|
207
194
|
def _render_font(self, params: dict) -> pygame.Surface:
|
208
|
-
key = tuple(params.values())
|
209
|
-
|
210
|
-
cached_value = Label._text_cache.get(key, None)
|
211
195
|
|
212
196
|
if self.draw_mode == bf.drawMode.SOLID:
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
self.font_object.set_underline(old_underline)
|
232
|
-
|
233
|
-
if self.do_caching:
|
234
|
-
Label._text_cache[key] = surf
|
235
|
-
else:
|
236
|
-
surf = cached_value
|
197
|
+
params.pop("font_name")
|
198
|
+
|
199
|
+
# save old settings
|
200
|
+
old_italic = self.font_object.get_italic()
|
201
|
+
old_bold = self.font_object.get_bold()
|
202
|
+
old_underline = self.font_object.get_underline()
|
203
|
+
|
204
|
+
# setup font
|
205
|
+
self.font_object.set_italic(self.is_italic)
|
206
|
+
self.font_object.set_bold(self.is_bold)
|
207
|
+
self.font_object.set_underline(self.is_underlined)
|
208
|
+
|
209
|
+
surf = self.font_object.render(**params)
|
210
|
+
|
211
|
+
# reset font
|
212
|
+
self.font_object.set_italic(old_italic)
|
213
|
+
self.font_object.set_bold(old_bold)
|
214
|
+
self.font_object.set_underline(old_underline)
|
237
215
|
else:
|
238
216
|
params.pop("font_name")
|
239
217
|
surf = self.font_object.render(**params)
|
@@ -95,8 +95,6 @@ class Root(InteractiveWidget):
|
|
95
95
|
return self
|
96
96
|
|
97
97
|
def do_handle_event(self, event):
|
98
|
-
if not self.parent_scene.get_sharedVar("player_has_control"):
|
99
|
-
return
|
100
98
|
if self.focused:
|
101
99
|
if event.type == pygame.KEYDOWN:
|
102
100
|
if self.focused.on_key_down(event.key):
|
@@ -130,8 +128,6 @@ class Root(InteractiveWidget):
|
|
130
128
|
|
131
129
|
def update(self, dt: float) -> None:
|
132
130
|
super().update(dt)
|
133
|
-
if not self.parent_scene.get_sharedVar("player_has_control",True):
|
134
|
-
return
|
135
131
|
old = self.hovered
|
136
132
|
transposed = self.drawing_camera.screen_to_world(pygame.mouse.get_pos())
|
137
133
|
self.hovered = self.top_at(*transposed) if self.top_at(*transposed) else None
|
@@ -145,8 +141,6 @@ class Root(InteractiveWidget):
|
|
145
141
|
|
146
142
|
def draw(self, camera: bf.Camera) -> None:
|
147
143
|
super().draw(camera)
|
148
|
-
if not self.parent_scene.get_sharedVar("player_has_control"):
|
149
|
-
return
|
150
144
|
if (
|
151
145
|
self.parent_scene
|
152
146
|
and self.parent_scene.active
|
@@ -18,7 +18,7 @@ class WidgetMeta(type):
|
|
18
18
|
return obj
|
19
19
|
|
20
20
|
|
21
|
-
class Widget(bf.
|
21
|
+
class Widget(bf.Drawable, metaclass=WidgetMeta):
|
22
22
|
def __init__(self, *args, **kwargs) -> None:
|
23
23
|
super().__init__(*args, **kwargs)
|
24
24
|
self.children: list["Widget"] = []
|
@@ -1,23 +1,24 @@
|
|
1
1
|
import batFramework as bf
|
2
2
|
import pygame
|
3
3
|
import asyncio
|
4
|
-
import random
|
5
4
|
|
6
5
|
class Manager(bf.SceneManager):
|
7
6
|
def __init__(self, *initial_scene_list) -> None:
|
8
|
-
# random.seed("random")
|
9
7
|
super().__init__()
|
10
|
-
self.
|
11
|
-
self.
|
12
|
-
self.
|
13
|
-
self.
|
14
|
-
self.
|
15
|
-
self.
|
16
|
-
self.
|
8
|
+
self.debug_mode: bf.enums.debugMode = bf.debugMode.HIDDEN
|
9
|
+
self.screen: pygame.Surface | None = bf.const.SCREEN
|
10
|
+
self.timeManager = bf.TimeManager()
|
11
|
+
self.cutsceneManager = bf.CutsceneManager()
|
12
|
+
self.cutsceneManager.set_manager(self)
|
13
|
+
self.clock: pygame.Clock = pygame.Clock()
|
14
|
+
self.is_async_running : bool = False
|
15
|
+
self.running = False
|
17
16
|
pygame.mouse.set_cursor(bf.const.DEFAULT_CURSOR)
|
18
17
|
self.do_pre_init()
|
19
18
|
self.init_scenes(*initial_scene_list)
|
20
|
-
|
19
|
+
bf.ResourceManager().set_sharedVar("clock", self.clock)
|
20
|
+
bf.ResourceManager().set_sharedVar("debug_mode", self.debug_mode)
|
21
|
+
|
21
22
|
self.do_init()
|
22
23
|
|
23
24
|
@staticmethod
|
@@ -39,14 +40,14 @@ class Manager(bf.SceneManager):
|
|
39
40
|
print("=" * 50)
|
40
41
|
|
41
42
|
# Print the timers information
|
42
|
-
print(self.
|
43
|
+
print(self.timeManager)
|
43
44
|
|
44
45
|
# End with a visual separator
|
45
46
|
print("=" * 50 + "\n")
|
46
47
|
|
47
48
|
|
48
49
|
def get_fps(self) -> float:
|
49
|
-
return self.
|
50
|
+
return self.clock.get_fps()
|
50
51
|
|
51
52
|
def do_init(self) -> None:
|
52
53
|
pass
|
@@ -55,67 +56,67 @@ class Manager(bf.SceneManager):
|
|
55
56
|
pass
|
56
57
|
|
57
58
|
def stop(self) -> None:
|
58
|
-
self.
|
59
|
+
self.running = False
|
59
60
|
|
60
61
|
async def run_async(self):
|
61
|
-
if self.
|
62
|
+
if self.running:
|
62
63
|
print("Error : Already running")
|
63
64
|
return
|
64
|
-
self.
|
65
|
-
self.
|
65
|
+
self.is_async_running = True
|
66
|
+
self.running = True
|
66
67
|
dt: float = 0
|
67
|
-
while self.
|
68
|
+
while self.running:
|
68
69
|
for event in pygame.event.get():
|
69
70
|
event.consumed = False
|
70
71
|
self.process_event(event)
|
71
72
|
if not event.consumed:
|
72
73
|
if event.type == pygame.QUIT:
|
73
|
-
self.
|
74
|
+
self.running = False
|
74
75
|
break
|
75
76
|
if event.type == pygame.VIDEORESIZE and not (
|
76
77
|
bf.const.FLAGS & pygame.SCALED
|
77
78
|
):
|
78
79
|
bf.const.set_resolution((event.w, event.h))
|
79
80
|
# update
|
80
|
-
self.
|
81
|
-
self.
|
81
|
+
self.timeManager.update(dt)
|
82
|
+
self.cutsceneManager.update(dt)
|
82
83
|
self.update(dt)
|
83
84
|
# render
|
84
|
-
self.
|
85
|
-
self.draw(self.
|
85
|
+
self.screen.fill((0, 0, 0))
|
86
|
+
self.draw(self.screen)
|
86
87
|
pygame.display.flip()
|
87
|
-
dt = self.
|
88
|
+
dt = self.clock.tick(bf.const.FPS) / 1000
|
88
89
|
# dt = min(dt, 0.02) dirty fix for dt being too high when window not focused for a long time
|
89
90
|
await asyncio.sleep(0)
|
90
91
|
pygame.quit()
|
91
92
|
|
92
93
|
|
93
94
|
def run(self) -> None:
|
94
|
-
if self.
|
95
|
+
if self.running:
|
95
96
|
print("Error : Already running")
|
96
97
|
return
|
97
|
-
self.
|
98
|
+
self.running = True
|
98
99
|
dt: float = 0
|
99
|
-
while self.
|
100
|
+
while self.running:
|
100
101
|
for event in pygame.event.get():
|
101
102
|
event.consumed = False
|
102
103
|
self.process_event(event)
|
103
104
|
if not event.consumed:
|
104
105
|
if event.type == pygame.QUIT:
|
105
|
-
self.
|
106
|
+
self.running = False
|
106
107
|
break
|
107
108
|
if event.type == pygame.VIDEORESIZE and not (
|
108
109
|
bf.const.FLAGS & pygame.SCALED
|
109
110
|
):
|
110
111
|
bf.const.set_resolution((event.w, event.h))
|
111
112
|
# update
|
112
|
-
self.
|
113
|
-
self.
|
113
|
+
self.timeManager.update(dt)
|
114
|
+
self.cutsceneManager.update(dt)
|
114
115
|
self.update(dt)
|
115
116
|
# render
|
116
|
-
self.
|
117
|
-
self.draw(self.
|
117
|
+
self.screen.fill((0, 0, 0))
|
118
|
+
self.draw(self.screen)
|
118
119
|
pygame.display.flip()
|
119
|
-
dt = self.
|
120
|
+
dt = self.clock.tick(bf.const.FPS) / 1000
|
120
121
|
# dt = min(dt, 0.02) dirty fix for dt being too high when window not focused for a long time
|
121
122
|
pygame.quit()
|
@@ -70,35 +70,6 @@ class Scene:
|
|
70
70
|
"""Get the scene index."""
|
71
71
|
return self.scene_index
|
72
72
|
|
73
|
-
def set_sharedVar(self, name: str, value: Any) -> bool:
|
74
|
-
"""
|
75
|
-
Set a shared variable in the manager.
|
76
|
-
|
77
|
-
Args:
|
78
|
-
name: Name of the shared variable.
|
79
|
-
value: Value to set.
|
80
|
-
|
81
|
-
Returns:
|
82
|
-
bool: True if setting was successful, False otherwise.
|
83
|
-
"""
|
84
|
-
if not self.manager:
|
85
|
-
return False
|
86
|
-
return self.manager.set_sharedVar(name, value)
|
87
|
-
|
88
|
-
def get_sharedVar(self, name: str, error_value=None) -> Any:
|
89
|
-
"""
|
90
|
-
Get a shared variable from the manager.
|
91
|
-
|
92
|
-
Args:
|
93
|
-
name: Name of the shared variable.
|
94
|
-
|
95
|
-
Returns:
|
96
|
-
Any: Value of the shared variable.
|
97
|
-
"""
|
98
|
-
if not self.manager:
|
99
|
-
return error_value
|
100
|
-
return self.manager.get_sharedVar(name, error_value)
|
101
|
-
|
102
73
|
def do_when_added(self):
|
103
74
|
pass
|
104
75
|
|
@@ -277,7 +248,6 @@ class Scene:
|
|
277
248
|
self.actions.reset()
|
278
249
|
self.early_actions.reset()
|
279
250
|
|
280
|
-
|
281
251
|
if self.entities_to_add:
|
282
252
|
for e in self.entities_to_add:
|
283
253
|
self.world_entities[e] = None
|
@@ -337,7 +307,7 @@ class Scene:
|
|
337
307
|
|
338
308
|
def _draw_camera(self, camera: bf.Camera, entity_list):
|
339
309
|
_ = [entity.draw(camera) for entity in entity_list]
|
340
|
-
debugMode =
|
310
|
+
debugMode = bf.ResourceManager().get_sharedVar("debug_mode")
|
341
311
|
# Draw outlines for world entities if required
|
342
312
|
if debugMode == bf.debugMode.OUTLINES:
|
343
313
|
[self.debug_entity(e, camera) for e in entity_list]
|
@@ -355,15 +325,12 @@ class Scene:
|
|
355
325
|
self.set_active(True)
|
356
326
|
self.set_visible(True)
|
357
327
|
self.root.clear_hovered()
|
358
|
-
# self.root.clear_focused()
|
359
328
|
self.root.build()
|
360
329
|
bf.TimeManager().activate_register(self.name)
|
361
330
|
self.do_on_enter()
|
362
|
-
# self.root.visit(lambda e : e.resolve_constraints())
|
363
331
|
|
364
332
|
def on_exit(self):
|
365
333
|
self.root.clear_hovered()
|
366
|
-
# self.root.clear_focused()
|
367
334
|
self.set_active(False)
|
368
335
|
self.set_visible(False)
|
369
336
|
self.actions.hard_reset()
|
@@ -2,7 +2,6 @@ import batFramework as bf
|
|
2
2
|
import pygame
|
3
3
|
from typing import Self
|
4
4
|
|
5
|
-
|
6
5
|
def swap(lst, index1, index2):
|
7
6
|
lst[index1], lst[index2] = lst[index2], lst[index1]
|
8
7
|
|
@@ -11,11 +10,6 @@ class SceneManager:
|
|
11
10
|
def __init__(self) -> None:
|
12
11
|
self.scenes: list[bf.Scene] = []
|
13
12
|
self.shared_events = {pygame.WINDOWRESIZED}
|
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
13
|
self.current_transitions: dict[str, bf.transition.Transition] = {}
|
20
14
|
|
21
15
|
def init_scenes(self, *initial_scenes:bf.Scene):
|
@@ -23,7 +17,6 @@ class SceneManager:
|
|
23
17
|
s.set_scene_index(index)
|
24
18
|
for s in reversed(initial_scenes):
|
25
19
|
self.add_scene(s)
|
26
|
-
# self.scenes = list(initial_scenes)
|
27
20
|
self.set_scene(initial_scenes[0].get_name())
|
28
21
|
self.update_scene_states()
|
29
22
|
|
@@ -38,7 +31,7 @@ class SceneManager:
|
|
38
31
|
Print detailed information about the current state of the scenes and shared variables.
|
39
32
|
"""
|
40
33
|
|
41
|
-
def format_scene_info(scene):
|
34
|
+
def format_scene_info(scene:bf.Scene):
|
42
35
|
status = 'Active' if scene.active else 'Inactive'
|
43
36
|
visibility = 'Visible' if scene.visible else 'Invisible'
|
44
37
|
return f"{scene.name:<30} | {status:<8} | {visibility:<10} | Index={scene.scene_index}"
|
@@ -78,13 +71,6 @@ class SceneManager:
|
|
78
71
|
|
79
72
|
print("=" * 50 + "\n")
|
80
73
|
|
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
74
|
def get_current_scene_name(self) -> str:
|
89
75
|
"""get the name of the current scene"""
|
90
76
|
return self.scenes[0].get_name()
|
@@ -106,10 +92,10 @@ class SceneManager:
|
|
106
92
|
def remove_scene(self, name: str):
|
107
93
|
self.scenes = [s for s in self.scenes if s.name != name]
|
108
94
|
|
109
|
-
def has_scene(self, name):
|
95
|
+
def has_scene(self, name:str):
|
110
96
|
return any(name == scene.name for scene in self.scenes)
|
111
97
|
|
112
|
-
def get_scene(self, name):
|
98
|
+
def get_scene(self, name:str):
|
113
99
|
if not self.has_scene(name):
|
114
100
|
return None
|
115
101
|
for scene in self.scenes:
|
@@ -150,8 +136,6 @@ class SceneManager:
|
|
150
136
|
def _start_transition(self, target_scene: bf.Scene):
|
151
137
|
target_scene.set_active(True)
|
152
138
|
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
139
|
|
156
140
|
def _end_transition(self, scene_name, index):
|
157
141
|
self.set_scene(scene_name, index, True)
|
@@ -177,11 +161,10 @@ class SceneManager:
|
|
177
161
|
self.scenes[index].do_on_enter_early()
|
178
162
|
target_scene.on_enter()
|
179
163
|
|
180
|
-
self.set_sharedVar("player_has_control", self.old_player_control)
|
181
164
|
|
182
165
|
|
183
166
|
def cycle_debug_mode(self):
|
184
|
-
current_index =
|
167
|
+
current_index = bf.ResourceManager().get_sharedVar("debug_mode").value
|
185
168
|
next_index = (current_index + 1) % len(bf.debugMode)
|
186
169
|
return bf.debugMode(next_index)
|
187
170
|
|
@@ -193,8 +176,7 @@ class SceneManager:
|
|
193
176
|
and event.type == pygame.KEYDOWN
|
194
177
|
):
|
195
178
|
if event.key == pygame.K_d:
|
196
|
-
|
197
|
-
self.set_sharedVar("debug_mode", self.debug_mode)
|
179
|
+
bf.ResourceManager().set_sharedVar("debug_mode", self.cycle_debug_mode())
|
198
180
|
return
|
199
181
|
if event.key == pygame.K_p:
|
200
182
|
self.print_status()
|
@@ -3,11 +3,11 @@ import pygame
|
|
3
3
|
from typing import Self
|
4
4
|
|
5
5
|
|
6
|
-
class Sprite(bf.
|
6
|
+
class Sprite(bf.Drawable):
|
7
7
|
def __init__(
|
8
8
|
self,
|
9
|
-
path=None,
|
10
9
|
size: None | tuple[int, int] = None,
|
10
|
+
path=None,
|
11
11
|
convert_alpha: bool = True,
|
12
12
|
):
|
13
13
|
self.original_surface: pygame.Surface = None
|
@@ -0,0 +1,248 @@
|
|
1
|
+
import pygame
|
2
|
+
import batFramework as bf
|
3
|
+
import random
|
4
|
+
from .enums import *
|
5
|
+
import re
|
6
|
+
from typing import Callable, TYPE_CHECKING
|
7
|
+
from functools import cache
|
8
|
+
if TYPE_CHECKING:
|
9
|
+
from .drawable import Drawable
|
10
|
+
from .entity import Entity
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
class Singleton(type):
|
15
|
+
_instances = {}
|
16
|
+
|
17
|
+
def __call__(cls, *args, **kwargs):
|
18
|
+
if cls not in cls._instances:
|
19
|
+
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
|
20
|
+
return cls._instances[cls]
|
21
|
+
|
22
|
+
|
23
|
+
class Utils:
|
24
|
+
|
25
|
+
@staticmethod
|
26
|
+
def split_surface(
|
27
|
+
surface: pygame.Surface, split_size: tuple[int, int], func=None
|
28
|
+
) -> dict[tuple[int, int], pygame.Surface]:
|
29
|
+
"""
|
30
|
+
Splits a surface into subsurfaces based on a given size and returns a dictionary of them with their coordinates as keys.
|
31
|
+
|
32
|
+
Args:
|
33
|
+
surface (pygame.Surface): The surface to be split.
|
34
|
+
split_size (tuple[int, int]): The size of each subsurface (width, height).
|
35
|
+
func (callable, optional): A function to apply to each subsurface. Defaults to None.
|
36
|
+
|
37
|
+
Returns:
|
38
|
+
dict[tuple[int, int], pygame.Surface]: A dictionary with (x, y) coordinates as keys and the corresponding subsurfaces as values.
|
39
|
+
"""
|
40
|
+
width, height = surface.get_size()
|
41
|
+
res = {}
|
42
|
+
for iy, y in enumerate(range(0, height, split_size[1])):
|
43
|
+
for ix, x in enumerate(range(0, width, split_size[0])):
|
44
|
+
sub = surface.subsurface((x, y, split_size[0], split_size[1]))
|
45
|
+
|
46
|
+
if func is not None:
|
47
|
+
sub = func(sub)
|
48
|
+
|
49
|
+
res[(ix, iy)] = sub
|
50
|
+
|
51
|
+
return res
|
52
|
+
|
53
|
+
@staticmethod
|
54
|
+
def filter_text(text_mode: textMode):
|
55
|
+
"""
|
56
|
+
Filters a string based on the specified text mode.
|
57
|
+
|
58
|
+
Args:
|
59
|
+
text_mode (textMode): Mode specifying the type of filtering (ALPHABETICAL, NUMERICAL, ALPHANUMERICAL).
|
60
|
+
|
61
|
+
Returns:
|
62
|
+
callable: A function that takes a string and removes all characters not allowed by the text mode.
|
63
|
+
|
64
|
+
Raises:
|
65
|
+
ValueError: If an unsupported text mode is provided.
|
66
|
+
"""
|
67
|
+
|
68
|
+
if text_mode == textMode.ALPHABETICAL:
|
69
|
+
pattern = re.compile(r"[^a-zA-Z]")
|
70
|
+
elif text_mode == textMode.NUMERICAL:
|
71
|
+
pattern = re.compile(r"[^0-9]")
|
72
|
+
elif text_mode == textMode.ALPHANUMERICAL:
|
73
|
+
pattern = re.compile(r"[^a-zA-Z0-9]")
|
74
|
+
else:
|
75
|
+
raise ValueError("Unsupported text mode")
|
76
|
+
|
77
|
+
def filter_function(s: str) -> str:
|
78
|
+
return pattern.sub("", s)
|
79
|
+
|
80
|
+
return filter_function
|
81
|
+
|
82
|
+
|
83
|
+
@staticmethod
|
84
|
+
@cache
|
85
|
+
def create_spotlight(inside_color, outside_color, radius, radius_stop=None, dest_surf=None,size=None):
|
86
|
+
"""
|
87
|
+
Creates a spotlight effect on a surface with a gradient from inside_color to outside_color.
|
88
|
+
|
89
|
+
Args:
|
90
|
+
inside_color (tuple[int, int, int]): RGB color at the center of the spotlight.
|
91
|
+
outside_color (tuple[int, int, int]): RGB color at the outer edge of the spotlight.
|
92
|
+
radius (int): Radius of the inner circle.
|
93
|
+
radius_stop (int, optional): Radius where the spotlight ends. Defaults to the value of radius.
|
94
|
+
dest_surf (pygame.Surface, optional): Surface to draw the spotlight on. Defaults to None.
|
95
|
+
size (tuple[int, int], optional): Size of the surface if dest_surf is None. Defaults to a square based on radius_stop.
|
96
|
+
|
97
|
+
Returns:
|
98
|
+
pygame.Surface: The surface with the spotlight effect drawn on it.
|
99
|
+
"""
|
100
|
+
|
101
|
+
if radius_stop is None:
|
102
|
+
radius_stop = radius
|
103
|
+
diameter = radius_stop * 2
|
104
|
+
|
105
|
+
if dest_surf is None:
|
106
|
+
if size is None:
|
107
|
+
size = (diameter,diameter)
|
108
|
+
dest_surf = pygame.Surface(size, pygame.SRCALPHA)
|
109
|
+
|
110
|
+
dest_surf.fill((0,0,0,0))
|
111
|
+
|
112
|
+
|
113
|
+
center = dest_surf.get_rect().center
|
114
|
+
|
115
|
+
if radius_stop != radius:
|
116
|
+
for r in range(radius_stop, radius - 1, -1):
|
117
|
+
color = [
|
118
|
+
inside_color[i] + (outside_color[i] - inside_color[i]) * (r - radius) / (radius_stop - radius)
|
119
|
+
for i in range(3)
|
120
|
+
] + [255] # Preserve the alpha channel as fully opaque
|
121
|
+
pygame.draw.circle(dest_surf, color, center, r)
|
122
|
+
else:
|
123
|
+
pygame.draw.circle(dest_surf, inside_color, center, radius)
|
124
|
+
|
125
|
+
return dest_surf
|
126
|
+
|
127
|
+
@staticmethod
|
128
|
+
def draw_spotlight(dest_surf:pygame.Surface,inside_color,outside_color,radius,radius_stop=None,center=None):
|
129
|
+
"""
|
130
|
+
Draws a spotlight effect directly onto an existing surface.
|
131
|
+
|
132
|
+
Args:
|
133
|
+
dest_surf (pygame.Surface): The surface to draw the spotlight on.
|
134
|
+
inside_color (tuple[int, int, int]): RGB color at the center of the spotlight.
|
135
|
+
outside_color (tuple[int, int, int]): RGB color at the outer edge of the spotlight.
|
136
|
+
radius (int): Radius of the inner circle.
|
137
|
+
radius_stop (int, optional): Radius where the spotlight ends. Defaults to the value of radius.
|
138
|
+
center (tuple[int, int], optional): Center point of the spotlight. Defaults to the center of dest_surf.
|
139
|
+
"""
|
140
|
+
|
141
|
+
if radius_stop is None:
|
142
|
+
radius_stop = radius
|
143
|
+
center = dest_surf.get_rect().center if center is None else center
|
144
|
+
if radius_stop != radius:
|
145
|
+
for r in range(radius_stop, radius - 1, -1):
|
146
|
+
color = [
|
147
|
+
inside_color[i] + (outside_color[i] - inside_color[i]) * (r - radius) / (radius_stop - radius)
|
148
|
+
for i in range(3)
|
149
|
+
] + [255]
|
150
|
+
pygame.draw.circle(dest_surf, color, center, r)
|
151
|
+
else:
|
152
|
+
pygame.draw.circle(dest_surf, inside_color, center, radius)
|
153
|
+
|
154
|
+
@staticmethod
|
155
|
+
def animate_move(entity:"Entity", start_pos : tuple[float,float], end_pos:tuple[float,float])->Callable[[float],None]:
|
156
|
+
"""
|
157
|
+
Creates a function to animate the movement of an entity from start_pos to end_pos.
|
158
|
+
|
159
|
+
Args:
|
160
|
+
entity (Entity): The entity to move.
|
161
|
+
start_pos (tuple[float, float]): The starting position of the entity.
|
162
|
+
end_pos (tuple[float, float]): The ending position of the entity.
|
163
|
+
|
164
|
+
Returns:
|
165
|
+
Callable[[float], None]: A function that updates the entity's position based on a progression value (0 to 1).
|
166
|
+
"""
|
167
|
+
def func(x):
|
168
|
+
entity.set_center(start_pos[0]+(end_pos[0]-start_pos[0])*x,start_pos[1]+(end_pos[1]-start_pos[1])*x)
|
169
|
+
return func
|
170
|
+
|
171
|
+
def animate_move_to(entity: "Entity", end_pos: tuple[float, float]) -> Callable[[float], None]:
|
172
|
+
"""
|
173
|
+
Creates a function to animate the movement of an entity to a specified end position, capturing the start position at the start of the animation.
|
174
|
+
|
175
|
+
Args:
|
176
|
+
entity (Entity): The entity to move.
|
177
|
+
end_pos (tuple[float, float]): The target position of the entity.
|
178
|
+
|
179
|
+
Returns:
|
180
|
+
Callable[[float], None]: A function that updates the entity's position based on a progression value (0 to 1).
|
181
|
+
"""
|
182
|
+
|
183
|
+
# Start position will be captured once when the animation starts
|
184
|
+
start_pos = [None]
|
185
|
+
|
186
|
+
def update_position(progression: float):
|
187
|
+
if start_pos[0] is None:
|
188
|
+
start_pos[0] = entity.rect.center # Capture the start position at the start of the animation
|
189
|
+
|
190
|
+
# Calculate new position based on progression
|
191
|
+
new_x = start_pos[0][0] + (end_pos[0] - start_pos[0][0]) * progression
|
192
|
+
new_y = start_pos[0][1] + (end_pos[1] - start_pos[0][1]) * progression
|
193
|
+
|
194
|
+
# Set the entity's new position
|
195
|
+
entity.set_center(new_x, new_y)
|
196
|
+
|
197
|
+
return update_position
|
198
|
+
|
199
|
+
@staticmethod
|
200
|
+
def animate_alpha(entity:"Drawable", start : int, end:int)->Callable[[float],None]:
|
201
|
+
"""
|
202
|
+
Creates a function to animate the alpha (transparency) of a drawable entity between a start and end value.
|
203
|
+
|
204
|
+
Args:
|
205
|
+
entity (Drawable): The entity to animate.
|
206
|
+
start (int): The starting alpha value (0 to 255).
|
207
|
+
end (int): The ending alpha value (0 to 255).
|
208
|
+
|
209
|
+
Returns:
|
210
|
+
Callable[[float], None]: A function that updates the entity's alpha based on a progression value (0 to 1).
|
211
|
+
"""
|
212
|
+
def func(x):
|
213
|
+
entity.set_alpha(int(pygame.math.clamp(start+(end-start)*x,0,255)))
|
214
|
+
return func
|
215
|
+
|
216
|
+
|
217
|
+
|
218
|
+
@staticmethod
|
219
|
+
def random_color(min_value: int = 0, max_value: int = 255) -> tuple[int, int, int]:
|
220
|
+
"""
|
221
|
+
Generates a random color as an RGB tuple.
|
222
|
+
|
223
|
+
Args:
|
224
|
+
min_value (int): Minimum value for each RGB component (inclusive). Defaults to 0.
|
225
|
+
max_value (int): Maximum value for each RGB component (inclusive). Defaults to 255.
|
226
|
+
|
227
|
+
Returns:
|
228
|
+
tuple[int, int, int]: A tuple representing a random color in RGB format, with each component
|
229
|
+
between min_value and max_value.
|
230
|
+
"""
|
231
|
+
return random.randint(min_value, max_value), random.randint(min_value, max_value), random.randint(min_value, max_value)
|
232
|
+
|
233
|
+
@staticmethod
|
234
|
+
def random_point_on_screen(margin: int = 0) -> tuple[int, int]:
|
235
|
+
"""
|
236
|
+
Generates a random point on the screen, considering a margin from the edges.
|
237
|
+
|
238
|
+
Args:
|
239
|
+
margin (int): Margin from the screen edges, where the point won't be generated.
|
240
|
+
If margin is less than 0 or greater than the screen resolution, returns (0, 0).
|
241
|
+
|
242
|
+
Returns:
|
243
|
+
tuple[int, int]: A tuple representing a random point (x, y) on the screen within the screen
|
244
|
+
resolution minus the margin.
|
245
|
+
"""
|
246
|
+
if margin < 0 or margin > bf.const.RESOLUTION[0] or margin > bf.const.RESOLUTION[1]:
|
247
|
+
return 0, 0
|
248
|
+
return random.randint(margin, bf.const.RESOLUTION[0] - margin), random.randint(margin, bf.const.RESOLUTION[1] - margin)
|
@@ -12,13 +12,13 @@ src/batFramework/character.py
|
|
12
12
|
src/batFramework/constants.py
|
13
13
|
src/batFramework/cutscene.py
|
14
14
|
src/batFramework/cutsceneBlocks.py
|
15
|
+
src/batFramework/drawable.py
|
15
16
|
src/batFramework/dynamicEntity.py
|
16
17
|
src/batFramework/easingController.py
|
17
18
|
src/batFramework/entity.py
|
18
19
|
src/batFramework/enums.py
|
19
20
|
src/batFramework/fontManager.py
|
20
21
|
src/batFramework/manager.py
|
21
|
-
src/batFramework/object.py
|
22
22
|
src/batFramework/particle.py
|
23
23
|
src/batFramework/renderGroup.py
|
24
24
|
src/batFramework/resourceManager.py
|
@@ -28,7 +28,7 @@ src/batFramework/scrollingSprite.py
|
|
28
28
|
src/batFramework/sprite.py
|
29
29
|
src/batFramework/stateMachine.py
|
30
30
|
src/batFramework/tileset.py
|
31
|
-
src/batFramework/
|
31
|
+
src/batFramework/timeManager.py
|
32
32
|
src/batFramework/transition.py
|
33
33
|
src/batFramework/triggerZone.py
|
34
34
|
src/batFramework/utils.py
|
@@ -1,149 +0,0 @@
|
|
1
|
-
import pygame
|
2
|
-
from enum import Enum
|
3
|
-
import os
|
4
|
-
import batFramework as bf
|
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
|
13
|
-
|
14
|
-
|
15
|
-
class Singleton(type):
|
16
|
-
_instances = {}
|
17
|
-
|
18
|
-
def __call__(cls, *args, **kwargs):
|
19
|
-
if cls not in cls._instances:
|
20
|
-
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
|
21
|
-
return cls._instances[cls]
|
22
|
-
|
23
|
-
|
24
|
-
class Utils:
|
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
|
45
|
-
|
46
|
-
return res
|
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")
|
58
|
-
|
59
|
-
def filter_function(s: str) -> str:
|
60
|
-
return pattern.sub("", s)
|
61
|
-
|
62
|
-
return filter_function
|
63
|
-
|
64
|
-
|
65
|
-
@staticmethod
|
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)
|
101
|
-
|
102
|
-
return dest_surf
|
103
|
-
|
104
|
-
@staticmethod
|
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)
|
118
|
-
|
119
|
-
@staticmethod
|
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]
|
128
|
-
|
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
|
132
|
-
|
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
|
136
|
-
|
137
|
-
# Set the entity's new position
|
138
|
-
entity.set_center(new_x, new_y)
|
139
|
-
|
140
|
-
return update_position
|
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
|
147
|
-
|
148
|
-
|
149
|
-
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/constraints/__init__.py
RENAMED
File without changes
|
{batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/constraints/constraints.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{batframework-1.0.8a13 → batframework-1.0.8a14}/src/batframework.egg-info/dependency_links.txt
RENAMED
File without changes
|
File without changes
|
File without changes
|