batframework 0.1.13__py3-none-any.whl → 1.0.1__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 +41 -46
- batFramework/action.py +42 -20
- batFramework/actionContainer.py +43 -4
- batFramework/animatedSprite.py +26 -20
- batFramework/camera.py +177 -47
- batFramework/constants.py +26 -51
- batFramework/cutscene.py +15 -15
- batFramework/cutsceneBlocks.py +11 -9
- batFramework/dynamicEntity.py +7 -6
- batFramework/easing.py +28 -23
- batFramework/entity.py +87 -49
- batFramework/enums.py +14 -0
- batFramework/fontManager.py +57 -0
- batFramework/gui/__init__.py +2 -2
- batFramework/gui/button.py +82 -31
- batFramework/gui/constraints.py +137 -104
- batFramework/gui/container.py +27 -28
- batFramework/gui/debugger.py +92 -42
- batFramework/gui/frame.py +15 -15
- batFramework/gui/image.py +37 -17
- batFramework/gui/indicator.py +18 -14
- batFramework/gui/interactiveWidget.py +11 -10
- batFramework/gui/label.py +60 -56
- batFramework/gui/layout.py +50 -47
- batFramework/gui/root.py +43 -30
- batFramework/gui/shape.py +34 -41
- batFramework/gui/slider.py +5 -0
- batFramework/gui/toggle.py +31 -27
- batFramework/gui/widget.py +148 -128
- batFramework/manager.py +18 -13
- batFramework/particles.py +16 -13
- batFramework/resourceManager.py +55 -0
- batFramework/scene.py +141 -83
- batFramework/sceneManager.py +21 -16
- batFramework/sprite.py +31 -0
- batFramework/stateMachine.py +1 -0
- batFramework/tileset.py +7 -9
- batFramework/time.py +61 -50
- batFramework/transition.py +20 -12
- batFramework/utils.py +2 -65
- batframework-1.0.1.dist-info/LICENCE +21 -0
- {batframework-0.1.13.dist-info → batframework-1.0.1.dist-info}/METADATA +3 -2
- batframework-1.0.1.dist-info/RECORD +48 -0
- {batframework-0.1.13.dist-info → batframework-1.0.1.dist-info}/WHEEL +1 -1
- batFramework/debugger.py +0 -48
- batframework-0.1.13.dist-info/RECORD +0 -43
- {batframework-0.1.13.dist-info → batframework-1.0.1.dist-info}/top_level.txt +0 -0
batFramework/__init__.py
CHANGED
@@ -1,67 +1,62 @@
|
|
1
1
|
import pygame
|
2
|
+
import batFramework as bf
|
3
|
+
import sys
|
2
4
|
from .constants import Constants as const
|
3
|
-
import os
|
4
|
-
import json
|
5
|
-
initialized = False
|
6
|
-
|
7
|
-
def init(
|
8
|
-
resolution:tuple[int,int],
|
9
|
-
flags:int=0,
|
10
|
-
vsync:int = 0,
|
11
|
-
default_text_size=None,
|
12
|
-
default_font=None,
|
13
|
-
resource_path:str|None=None,
|
14
|
-
window_title:str="BatFramework Project",
|
15
|
-
fps_limit : int = 0
|
16
|
-
):
|
17
|
-
global initialized
|
18
|
-
if not initialized:
|
19
|
-
pygame.init()
|
20
|
-
pygame.display.set_caption(window_title)
|
21
|
-
|
22
|
-
# Initialize display
|
23
|
-
const.init_screen(resolution,flags,vsync)
|
24
|
-
const.set_fps_limit(fps_limit)
|
25
|
-
|
26
|
-
# Initialize default text size
|
27
|
-
if default_text_size: const.set_default_text_size(default_text_size)
|
28
|
-
# Initialize resource path for game data
|
29
|
-
if resource_path: const.set_resource_path(resource_path)
|
30
|
-
|
31
|
-
# Initialize default font cache
|
32
|
-
from .utils import Utils
|
33
|
-
if default_font is None or isinstance(default_font,str):
|
34
|
-
Utils.init_font(default_font)
|
35
|
-
else:
|
36
|
-
raise ValueError(f"default_font '{default_font}' can be either string or None")
|
37
|
-
|
38
|
-
f = list(Utils.FONTS[None].values())[0]
|
39
|
-
print(f"Set default font to : {f.name} {'' if default_font is not None else '(default value)'}")
|
40
|
-
initialized = True
|
41
|
-
|
42
5
|
from .constants import Colors as color
|
43
|
-
from .constants import Axis as axis
|
44
6
|
from .utils import Singleton
|
7
|
+
from .enums import *
|
8
|
+
from .resourceManager import ResourceManager
|
9
|
+
from .fontManager import FontManager
|
10
|
+
# if const.BF_INITIALIZED:
|
45
11
|
from .utils import Utils as utils
|
46
12
|
from .tileset import Tileset
|
47
|
-
from .time import
|
48
|
-
from .cutscene import Cutscene,CutsceneManager
|
13
|
+
from .time import TimeManager, Timer
|
14
|
+
from .cutscene import Cutscene, CutsceneManager
|
49
15
|
from .cutsceneBlocks import *
|
50
16
|
from .easing import Easing, EasingAnimation
|
51
17
|
from .audioManager import AudioManager
|
52
|
-
|
53
|
-
from .transition import *
|
18
|
+
# import batFramework.transition as transition
|
54
19
|
from .action import Action
|
55
|
-
from .actionContainer import
|
20
|
+
from .actionContainer import *
|
56
21
|
from .camera import Camera
|
57
22
|
from .entity import Entity
|
58
23
|
from .dynamicEntity import DynamicEntity
|
24
|
+
from .sprite import Sprite
|
59
25
|
from .animatedSprite import AnimatedSprite, AnimState
|
60
26
|
from .stateMachine import State, StateMachine
|
61
|
-
from .particles import Particle, ParticleManager
|
62
27
|
# from .debugger import Debugger
|
63
28
|
from .scene import Scene
|
64
29
|
from .gui import *
|
65
30
|
from .sceneManager import SceneManager
|
66
31
|
from .manager import Manager
|
67
32
|
|
33
|
+
|
34
|
+
def init_screen(resolution: tuple[int, int], flags: int = 0, vsync: int = 0):
|
35
|
+
const.RESOLUTION = resolution
|
36
|
+
const.FLAGS = flags
|
37
|
+
const.VSYNC = vsync
|
38
|
+
const.SCREEN = pygame.display.set_mode(
|
39
|
+
const.RESOLUTION,const.FLAGS, vsync=const.VSYNC
|
40
|
+
)
|
41
|
+
print(
|
42
|
+
f"Window : {resolution[0]}x{resolution[1]} [vsync:{pygame.display.is_vsync()}]"
|
43
|
+
)
|
44
|
+
|
45
|
+
def init(
|
46
|
+
resolution: tuple[int, int],
|
47
|
+
flags: int = 0,
|
48
|
+
vsync: int = 0,
|
49
|
+
default_text_size=None,
|
50
|
+
default_font=None,
|
51
|
+
resource_path: str | None = None,
|
52
|
+
window_title: str = "BatFramework Project",
|
53
|
+
fps_limit: int = 0):
|
54
|
+
pygame.display.set_caption(window_title)
|
55
|
+
init_screen(resolution,flags,vsync)
|
56
|
+
|
57
|
+
ResourceManager().set_resource_path(resource_path if resource_path is not None else ".")
|
58
|
+
ResourceManager().load_dir(ResourceManager().RESOURCE_PATH)
|
59
|
+
if default_text_size is not None : FontManager().set_default_text_size(default_text_size)
|
60
|
+
FontManager().init_font(default_font)
|
61
|
+
const.BF_INITIALIZED = True
|
62
|
+
const.set_fps_limit(fps_limit)
|
batFramework/action.py
CHANGED
@@ -12,20 +12,21 @@ class Action:
|
|
12
12
|
Args:
|
13
13
|
name (str): The name of the action.
|
14
14
|
"""
|
15
|
-
self._name = name
|
16
|
-
self._active = False
|
17
|
-
self._type = ActionType.INSTANTANEOUS
|
18
|
-
self._key_control = set()
|
19
|
-
self._mouse_control = set()
|
20
|
-
self._gamepad_button_control = set()
|
21
|
-
self._gamepad_axis_control = set()
|
15
|
+
self._name :str= name
|
16
|
+
self._active :bool= False
|
17
|
+
self._type :ActionType = ActionType.INSTANTANEOUS
|
18
|
+
self._key_control : set= set()
|
19
|
+
self._mouse_control :set = set()
|
20
|
+
self._gamepad_button_control :set = set()
|
21
|
+
self._gamepad_axis_control :set = set()
|
22
22
|
self._holding = set()
|
23
23
|
self._unique = True
|
24
|
-
self.data
|
24
|
+
self.data: Any = None
|
25
25
|
|
26
26
|
def set_unique(self, val: bool) -> None:
|
27
27
|
"""
|
28
28
|
Set whether this action is unique (exclusive).
|
29
|
+
When in an action Container, unique actions -when active - break the propagation of their event to other actions.
|
29
30
|
|
30
31
|
Args:
|
31
32
|
val (bool): True if the action is unique, False otherwise.
|
@@ -51,7 +52,7 @@ class Action:
|
|
51
52
|
self._active = value
|
52
53
|
self._holding = set()
|
53
54
|
|
54
|
-
def add_key_control(self, *keys) ->
|
55
|
+
def add_key_control(self, *keys) -> "Action":
|
55
56
|
"""
|
56
57
|
Add key controls to the action.
|
57
58
|
|
@@ -64,7 +65,26 @@ class Action:
|
|
64
65
|
self._key_control.update(keys)
|
65
66
|
return self
|
66
67
|
|
67
|
-
def
|
68
|
+
def remove_key_control(self, *keys:int) -> "Action":
|
69
|
+
"""
|
70
|
+
Remove key controls to the action.
|
71
|
+
|
72
|
+
Args:
|
73
|
+
*keys (int): Key codes to control this action.
|
74
|
+
|
75
|
+
Returns:
|
76
|
+
Action: The updated Action object for method chaining.
|
77
|
+
"""
|
78
|
+
self._key_control = self._key_control - set(keys)
|
79
|
+
return self
|
80
|
+
|
81
|
+
def replace_key_control(self, key, new_key) -> "Action":
|
82
|
+
if not key in self._key_control : return self
|
83
|
+
self.remove_key_control(key)
|
84
|
+
self.add_key_control(new_key)
|
85
|
+
return self
|
86
|
+
|
87
|
+
def add_mouse_control(self, *mouse_buttons:int) -> "Action":
|
68
88
|
"""
|
69
89
|
Add mouse control to the action.
|
70
90
|
|
@@ -86,7 +106,7 @@ class Action:
|
|
86
106
|
"""
|
87
107
|
return self._name
|
88
108
|
|
89
|
-
def set_continuous(self) ->
|
109
|
+
def set_continuous(self) -> "Action":
|
90
110
|
"""
|
91
111
|
Set the action type to continuous.
|
92
112
|
|
@@ -106,7 +126,7 @@ class Action:
|
|
106
126
|
"""
|
107
127
|
return self._type == ActionType.CONTINUOUS
|
108
128
|
|
109
|
-
def set_instantaneous(self) ->
|
129
|
+
def set_instantaneous(self) -> "Action":
|
110
130
|
"""
|
111
131
|
Set the action type to instantaneous.
|
112
132
|
|
@@ -126,7 +146,7 @@ class Action:
|
|
126
146
|
"""
|
127
147
|
return self._type == ActionType.INSTANTANEOUS
|
128
148
|
|
129
|
-
def set_holding(self) ->
|
149
|
+
def set_holding(self) -> "Action":
|
130
150
|
"""
|
131
151
|
Set the action type to holding.
|
132
152
|
|
@@ -145,9 +165,14 @@ class Action:
|
|
145
165
|
"""
|
146
166
|
return self._type == ActionType.HOLDING
|
147
167
|
|
148
|
-
def process_update(self,event:pygame.Event)->None:
|
149
|
-
if
|
150
|
-
self.
|
168
|
+
def process_update(self, event: pygame.Event) -> None:
|
169
|
+
if (
|
170
|
+
self.is_active()
|
171
|
+
and event.type == pygame.MOUSEMOTION
|
172
|
+
and self.is_holding_type()
|
173
|
+
and pygame.MOUSEMOTION in self._mouse_control
|
174
|
+
):
|
175
|
+
self.data = {"pos": event.pos, "rel": event.rel}
|
151
176
|
|
152
177
|
def process_activate(self, event: pygame.event.Event) -> bool:
|
153
178
|
"""
|
@@ -205,10 +230,7 @@ class Action:
|
|
205
230
|
if not self._holding:
|
206
231
|
self._active = False
|
207
232
|
return True
|
208
|
-
elif
|
209
|
-
event.type == pygame.MOUSEMOTION
|
210
|
-
and event.type in self._mouse_control
|
211
|
-
):
|
233
|
+
elif event.type == pygame.MOUSEMOTION and event.type in self._mouse_control:
|
212
234
|
self.value = None
|
213
235
|
if event.type in self._holding:
|
214
236
|
self._holding.remove(event.type)
|
batFramework/actionContainer.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import batFramework as bf
|
2
|
+
import pygame
|
2
3
|
|
3
4
|
|
4
5
|
class ActionContainer:
|
@@ -14,14 +15,20 @@ class ActionContainer:
|
|
14
15
|
for action in actions:
|
15
16
|
self._actions[action.get_name()] = action
|
16
17
|
|
17
|
-
def get(self,name:str)->bf.Action:
|
18
|
+
def get(self, name: str) -> bf.Action:
|
18
19
|
return self._actions.get(name)
|
19
20
|
|
20
|
-
def has_action(self, name:str):
|
21
|
+
def has_action(self, name: str):
|
21
22
|
return name in self._actions
|
22
23
|
|
23
|
-
def
|
24
|
-
return
|
24
|
+
def get_all(self) -> list[bf.Action]:
|
25
|
+
return self._actions
|
26
|
+
|
27
|
+
def is_active(self, *names: str) -> bool:
|
28
|
+
return all(
|
29
|
+
self._actions.get(name).is_active() if name in self._actions else False
|
30
|
+
for name in names
|
31
|
+
)
|
25
32
|
|
26
33
|
def process_event(self, event):
|
27
34
|
for action in self._actions.values():
|
@@ -36,3 +43,35 @@ class ActionContainer:
|
|
36
43
|
def hard_reset(self):
|
37
44
|
for action in self._actions.values():
|
38
45
|
action.hard_reset()
|
46
|
+
|
47
|
+
|
48
|
+
class DirectionalKeyControls(ActionContainer):
|
49
|
+
def __init__(self):
|
50
|
+
super().__init__(
|
51
|
+
bf.Action("up").add_key_control(pygame.K_UP).set_holding(),
|
52
|
+
bf.Action("down").add_key_control(pygame.K_DOWN).set_holding(),
|
53
|
+
bf.Action("left").add_key_control(pygame.K_LEFT).set_holding(),
|
54
|
+
bf.Action("right").add_key_control(pygame.K_RIGHT).set_holding(),
|
55
|
+
)
|
56
|
+
|
57
|
+
|
58
|
+
class WASDControls(ActionContainer):
|
59
|
+
def __init__(self):
|
60
|
+
super().__init__(
|
61
|
+
bf.Action("up").add_key_control(pygame.K_w).set_holding(),
|
62
|
+
bf.Action("down").add_key_control(pygame.K_s).set_holding(),
|
63
|
+
bf.Action("left").add_key_control(pygame.K_a).set_holding(),
|
64
|
+
bf.Action("right").add_key_control(pygame.K_d).set_holding(),
|
65
|
+
)
|
66
|
+
|
67
|
+
|
68
|
+
class HybridControls(ActionContainer):
|
69
|
+
def __init__(self):
|
70
|
+
super().__init__(
|
71
|
+
bf.Action("up").add_key_control(pygame.K_UP, pygame.K_w).set_holding(),
|
72
|
+
bf.Action("down").add_key_control(pygame.K_DOWN, pygame.K_s).set_holding(),
|
73
|
+
bf.Action("left").add_key_control(pygame.K_LEFT, pygame.K_a).set_holding(),
|
74
|
+
bf.Action("right")
|
75
|
+
.add_key_control(pygame.K_RIGHT, pygame.K_r)
|
76
|
+
.set_holding(),
|
77
|
+
)
|
batFramework/animatedSprite.py
CHANGED
@@ -2,7 +2,6 @@ import batFramework as bf
|
|
2
2
|
import pygame
|
3
3
|
|
4
4
|
|
5
|
-
|
6
5
|
def search_index(target, lst):
|
7
6
|
cumulative_sum = 0
|
8
7
|
for index, value in enumerate(lst):
|
@@ -13,12 +12,14 @@ def search_index(target, lst):
|
|
13
12
|
|
14
13
|
|
15
14
|
class AnimState:
|
16
|
-
def __init__(
|
15
|
+
def __init__(
|
16
|
+
self, name: str, file, width, height, frame_length_list: list | int
|
17
|
+
) -> None:
|
17
18
|
self.frames: list[pygame.Surface] = bf.utils.img_slice(file, width, height)
|
18
19
|
self.frames_flipX: list[pygame.Surface] = bf.utils.img_slice(
|
19
20
|
file, width, height, True
|
20
21
|
)
|
21
|
-
self.name= name
|
22
|
+
self.name = name
|
22
23
|
self.frame_length_list = []
|
23
24
|
self.ffl_length = 0
|
24
25
|
self.set_frame_length_list(frame_length_list)
|
@@ -26,34 +27,33 @@ class AnimState:
|
|
26
27
|
def __repr__(self):
|
27
28
|
return f"AnimState({self.name})"
|
28
29
|
|
29
|
-
def get_frame_index(self, counter:float|int):
|
30
|
+
def get_frame_index(self, counter: float | int):
|
30
31
|
return search_index(int(counter % self.ffl_length), self.frame_length_list)
|
31
32
|
|
32
33
|
def get_frame(self, counter, flip):
|
33
34
|
i = self.get_frame_index(counter)
|
34
35
|
return self.frames_flipX[i] if flip else self.frames[i]
|
35
36
|
|
36
|
-
def set_frame_length_list(self,frame_length_list:list[int]|int):
|
37
|
-
if isinstance(frame_length_list,int):
|
37
|
+
def set_frame_length_list(self, frame_length_list: list[int] | int):
|
38
|
+
if isinstance(frame_length_list, int):
|
38
39
|
frame_length_list = [frame_length_list] * len(self.frames)
|
39
|
-
if len(frame_length_list) != len(self.frames)
|
40
|
+
if len(frame_length_list) != len(self.frames):
|
40
41
|
raise ValueError("frame_length_list should have values for all frames")
|
41
42
|
self.frame_length_list = frame_length_list
|
42
43
|
self.ffl_length = sum(self.frame_length_list)
|
43
|
-
|
44
|
+
|
44
45
|
|
45
46
|
class AnimatedSprite(bf.DynamicEntity):
|
46
47
|
def __init__(self, size=None) -> None:
|
47
48
|
super().__init__(size, no_surface=True)
|
48
49
|
self.float_counter = 0
|
49
50
|
self.animStates: dict[str, AnimState] = {}
|
50
|
-
self.current_animState
|
51
|
+
self.current_animState: str = ""
|
51
52
|
self.flipX = False
|
52
53
|
self._locked = False
|
53
54
|
|
54
|
-
def set_counter(self,value:float):
|
55
|
+
def set_counter(self, value: float):
|
55
56
|
self.float_counter = value
|
56
|
-
|
57
57
|
|
58
58
|
def lock_animState(self):
|
59
59
|
self._locked = True
|
@@ -64,20 +64,25 @@ class AnimatedSprite(bf.DynamicEntity):
|
|
64
64
|
def set_flipX(self, value):
|
65
65
|
self.flipX = value
|
66
66
|
|
67
|
-
def remove_animState(self, name:str):
|
68
|
-
if not name in self.animStates
|
69
|
-
|
70
|
-
|
67
|
+
def remove_animState(self, name: str):
|
68
|
+
if not name in self.animStates:
|
69
|
+
return
|
70
|
+
self.animStates.pop(name)
|
71
|
+
if self.current_animState == name:
|
72
|
+
self.current_animState = (
|
73
|
+
list(self.animStates.keys())[0] if self.animStates else ""
|
74
|
+
)
|
71
75
|
|
72
76
|
def add_animState(
|
73
77
|
self, name: str, file: str, size: tuple[int, int], frame_length_list: list[int]
|
74
78
|
):
|
75
79
|
if name in self.animStates:
|
76
80
|
return
|
77
|
-
self.animStates[name] = AnimState(name,file, *size, frame_length_list)
|
78
|
-
if len(self.animStates) == 1
|
81
|
+
self.animStates[name] = AnimState(name, file, *size, frame_length_list)
|
82
|
+
if len(self.animStates) == 1:
|
83
|
+
self.set_animState(name)
|
79
84
|
|
80
|
-
def set_animState(self, state:str, reset_counter=True, lock=False):
|
85
|
+
def set_animState(self, state: str, reset_counter=True, lock=False):
|
81
86
|
if state not in self.animStates or self._locked:
|
82
87
|
return False
|
83
88
|
self.current_animState = state
|
@@ -95,7 +100,7 @@ class AnimatedSprite(bf.DynamicEntity):
|
|
95
100
|
return True
|
96
101
|
|
97
102
|
def get_state(self):
|
98
|
-
return self.animStates.get(self.current_animState,None)
|
103
|
+
return self.animStates.get(self.current_animState, None)
|
99
104
|
|
100
105
|
def get_frame_index(self):
|
101
106
|
return self.animStates[self.current_animState].get_frame_index(
|
@@ -103,7 +108,8 @@ class AnimatedSprite(bf.DynamicEntity):
|
|
103
108
|
)
|
104
109
|
|
105
110
|
def update(self, dt: float):
|
106
|
-
if not self.animStates
|
111
|
+
if not self.animStates:
|
112
|
+
return
|
107
113
|
self.float_counter += 60 * dt
|
108
114
|
if self.float_counter > self.get_state().ffl_length:
|
109
115
|
self.float_counter = 0
|