batframework 1.0.7__tar.gz → 1.0.8a2__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.8a2/PKG-INFO +58 -0
- batframework-1.0.8a2/README.md +45 -0
- {batframework-1.0.7 → batframework-1.0.8a2}/pyproject.toml +2 -2
- batframework-1.0.8a2/src/batFramework/__init__.py +66 -0
- {batframework-1.0.7 → batframework-1.0.8a2}/src/batFramework/action.py +20 -42
- batframework-1.0.8a2/src/batFramework/actionContainer.py +38 -0
- batframework-1.0.8a2/src/batFramework/animatedSprite.py +117 -0
- {batframework-1.0.7 → batframework-1.0.8a2}/src/batFramework/audioManager.py +25 -39
- batframework-1.0.8a2/src/batFramework/camera.py +123 -0
- batframework-1.0.8a2/src/batFramework/constants.py +75 -0
- {batframework-1.0.7 → batframework-1.0.8a2}/src/batFramework/cutscene.py +24 -32
- {batframework-1.0.7 → batframework-1.0.8a2}/src/batFramework/cutsceneBlocks.py +33 -30
- batframework-1.0.8a2/src/batFramework/debugger.py +48 -0
- batframework-1.0.8a2/src/batFramework/dynamicEntity.py +23 -0
- {batframework-1.0.7 → batframework-1.0.8a2}/src/batFramework/easing.py +23 -28
- batframework-1.0.8a2/src/batFramework/entity.py +123 -0
- {batframework-1.0.7 → batframework-1.0.8a2}/src/batFramework/gui/__init__.py +1 -3
- batframework-1.0.8a2/src/batFramework/gui/button.py +84 -0
- batframework-1.0.8a2/src/batFramework/gui/constraints.py +204 -0
- batframework-1.0.8a2/src/batFramework/gui/container.py +49 -0
- batframework-1.0.8a2/src/batFramework/gui/debugger.py +47 -0
- batframework-1.0.8a2/src/batFramework/gui/frame.py +19 -0
- batframework-1.0.8a2/src/batFramework/gui/image.py +23 -0
- batframework-1.0.8a2/src/batFramework/gui/indicator.py +40 -0
- batframework-1.0.8a2/src/batFramework/gui/interactiveWidget.py +22 -0
- batframework-1.0.8a2/src/batFramework/gui/label.py +110 -0
- batframework-1.0.8a2/src/batFramework/gui/layout.py +81 -0
- batframework-1.0.8a2/src/batFramework/gui/root.py +60 -0
- batframework-1.0.8a2/src/batFramework/gui/shape.py +86 -0
- batframework-1.0.8a2/src/batFramework/gui/toggle.py +62 -0
- batframework-1.0.8a2/src/batFramework/gui/widget.py +307 -0
- {batframework-1.0.7 → batframework-1.0.8a2}/src/batFramework/manager.py +14 -21
- {batframework-1.0.7 → batframework-1.0.8a2}/src/batFramework/particles.py +20 -41
- batframework-1.0.8a2/src/batFramework/scene.py +226 -0
- batframework-1.0.8a2/src/batFramework/sceneManager.py +165 -0
- {batframework-1.0.7 → batframework-1.0.8a2}/src/batFramework/stateMachine.py +0 -1
- batframework-1.0.8a2/src/batFramework/time.py +75 -0
- batframework-1.0.8a2/src/batFramework/transition.py +157 -0
- batframework-1.0.8a2/src/batFramework/utils.py +184 -0
- batframework-1.0.8a2/src/batframework.egg-info/PKG-INFO +58 -0
- {batframework-1.0.7 → batframework-1.0.8a2}/src/batframework.egg-info/SOURCES.txt +1 -9
- batframework-1.0.7/LICENCE +0 -21
- batframework-1.0.7/PKG-INFO +0 -55
- batframework-1.0.7/README.md +0 -41
- batframework-1.0.7/src/batFramework/__init__.py +0 -60
- batframework-1.0.7/src/batFramework/actionContainer.py +0 -77
- batframework-1.0.7/src/batFramework/animatedSprite.py +0 -150
- batframework-1.0.7/src/batFramework/camera.py +0 -293
- batframework-1.0.7/src/batFramework/constants.py +0 -59
- batframework-1.0.7/src/batFramework/dynamicEntity.py +0 -24
- batframework-1.0.7/src/batFramework/entity.py +0 -160
- batframework-1.0.7/src/batFramework/enums.py +0 -14
- batframework-1.0.7/src/batFramework/fontManager.py +0 -57
- batframework-1.0.7/src/batFramework/gui/button.py +0 -150
- batframework-1.0.7/src/batFramework/gui/constraints.py +0 -277
- batframework-1.0.7/src/batFramework/gui/container.py +0 -60
- batframework-1.0.7/src/batFramework/gui/debugger.py +0 -111
- batframework-1.0.7/src/batFramework/gui/dialogueBox.py +0 -70
- batframework-1.0.7/src/batFramework/gui/frame.py +0 -25
- batframework-1.0.7/src/batFramework/gui/image.py +0 -42
- batframework-1.0.7/src/batFramework/gui/indicator.py +0 -46
- batframework-1.0.7/src/batFramework/gui/interactiveWidget.py +0 -73
- batframework-1.0.7/src/batFramework/gui/label.py +0 -173
- batframework-1.0.7/src/batFramework/gui/layout.py +0 -96
- batframework-1.0.7/src/batFramework/gui/root.py +0 -101
- batframework-1.0.7/src/batFramework/gui/shape.py +0 -79
- batframework-1.0.7/src/batFramework/gui/slider.py +0 -5
- batframework-1.0.7/src/batFramework/gui/textInput.py +0 -88
- batframework-1.0.7/src/batFramework/gui/toggle.py +0 -70
- batframework-1.0.7/src/batFramework/gui/widget.py +0 -350
- batframework-1.0.7/src/batFramework/resourceManager.py +0 -72
- batframework-1.0.7/src/batFramework/scene.py +0 -327
- batframework-1.0.7/src/batFramework/sceneManager.py +0 -125
- batframework-1.0.7/src/batFramework/sprite.py +0 -33
- batframework-1.0.7/src/batFramework/tileset.py +0 -64
- batframework-1.0.7/src/batFramework/time.py +0 -86
- batframework-1.0.7/src/batFramework/transition.py +0 -3
- batframework-1.0.7/src/batFramework/utils.py +0 -37
- batframework-1.0.7/src/batframework.egg-info/PKG-INFO +0 -55
- {batframework-1.0.7 → batframework-1.0.8a2}/setup.cfg +0 -0
- {batframework-1.0.7 → batframework-1.0.8a2}/src/batFramework/transitionManager.py +0 -0
- {batframework-1.0.7 → batframework-1.0.8a2}/src/batFramework/triggerZone.py +0 -0
- {batframework-1.0.7 → batframework-1.0.8a2}/src/batframework.egg-info/dependency_links.txt +0 -0
- {batframework-1.0.7 → batframework-1.0.8a2}/src/batframework.egg-info/requires.txt +0 -0
- {batframework-1.0.7 → batframework-1.0.8a2}/src/batframework.egg-info/top_level.txt +0 -0
@@ -0,0 +1,58 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: batframework
|
3
|
+
Version: 1.0.8a2
|
4
|
+
Summary: Pygame framework for making games easier.
|
5
|
+
Author-email: Turan Baturay <baturayturan@gmail.com>
|
6
|
+
Project-URL: Homepage, https://github.com/TuranBaturay/batFramework
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
9
|
+
Classifier: Operating System :: OS Independent
|
10
|
+
Requires-Python: >=3.10
|
11
|
+
Description-Content-Type: text/markdown
|
12
|
+
Requires-Dist: pygame-ce
|
13
|
+
|
14
|
+
# batFramework
|
15
|
+
|
16
|
+
batFramework is a Python game framework built using Pygame, designed to simplify game development by providing entities, scenes, a scene manager, and various utilities.
|
17
|
+
|
18
|
+
## Purpose and Overview
|
19
|
+
The primary objective of batFramework is to streamline game development by utilizing entities and scenes that hold entities. It employs a manager, which inherits from the scene manager, to handle scenes, propagate events, and manage updates and rendering.
|
20
|
+
|
21
|
+
## Installation and Setup
|
22
|
+
To install batFramework, you can use pip:
|
23
|
+
```pip install batFramework```
|
24
|
+
|
25
|
+
|
26
|
+
The only dependency required is pygame-ce.
|
27
|
+
|
28
|
+
## Usage Instructions
|
29
|
+
To create a basic app using batFramework, here's an example:
|
30
|
+
|
31
|
+
```python
|
32
|
+
import batFramework as bf
|
33
|
+
|
34
|
+
# Initialize the framework
|
35
|
+
bf.init((1280, 720), window_title="My Amazing Program")
|
36
|
+
|
37
|
+
# Create a manager and a scene
|
38
|
+
bf.Manager(bf.Scene("main")).run()
|
39
|
+
```
|
40
|
+
In practice, users can inherit bf.Scene to create their own scenes, adding specific behaviors, entities, etc.
|
41
|
+
|
42
|
+
## Features and Functionalities
|
43
|
+
|
44
|
+
- Scene management for organizing game components
|
45
|
+
- Cutscene support to facilitate storytelling sequences
|
46
|
+
- Audio management for music and sound effects with volume control
|
47
|
+
- Entity, sprite, and animated sprite support
|
48
|
+
- Utility modules such as time management and easingAnimation
|
49
|
+
|
50
|
+
Users can leverage these functionalities to build games efficiently using batFramework.
|
51
|
+
|
52
|
+
For more detailed usage and examples, please refer to the documentation or codebase.
|
53
|
+
|
54
|
+
|
55
|
+
# License
|
56
|
+
MIT License
|
57
|
+
|
58
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# batFramework
|
2
|
+
|
3
|
+
batFramework is a Python game framework built using Pygame, designed to simplify game development by providing entities, scenes, a scene manager, and various utilities.
|
4
|
+
|
5
|
+
## Purpose and Overview
|
6
|
+
The primary objective of batFramework is to streamline game development by utilizing entities and scenes that hold entities. It employs a manager, which inherits from the scene manager, to handle scenes, propagate events, and manage updates and rendering.
|
7
|
+
|
8
|
+
## Installation and Setup
|
9
|
+
To install batFramework, you can use pip:
|
10
|
+
```pip install batFramework```
|
11
|
+
|
12
|
+
|
13
|
+
The only dependency required is pygame-ce.
|
14
|
+
|
15
|
+
## Usage Instructions
|
16
|
+
To create a basic app using batFramework, here's an example:
|
17
|
+
|
18
|
+
```python
|
19
|
+
import batFramework as bf
|
20
|
+
|
21
|
+
# Initialize the framework
|
22
|
+
bf.init((1280, 720), window_title="My Amazing Program")
|
23
|
+
|
24
|
+
# Create a manager and a scene
|
25
|
+
bf.Manager(bf.Scene("main")).run()
|
26
|
+
```
|
27
|
+
In practice, users can inherit bf.Scene to create their own scenes, adding specific behaviors, entities, etc.
|
28
|
+
|
29
|
+
## Features and Functionalities
|
30
|
+
|
31
|
+
- Scene management for organizing game components
|
32
|
+
- Cutscene support to facilitate storytelling sequences
|
33
|
+
- Audio management for music and sound effects with volume control
|
34
|
+
- Entity, sprite, and animated sprite support
|
35
|
+
- Utility modules such as time management and easingAnimation
|
36
|
+
|
37
|
+
Users can leverage these functionalities to build games efficiently using batFramework.
|
38
|
+
|
39
|
+
For more detailed usage and examples, please refer to the documentation or codebase.
|
40
|
+
|
41
|
+
|
42
|
+
# License
|
43
|
+
MIT License
|
44
|
+
|
45
|
+
|
@@ -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.8a2"
|
8
8
|
authors = [
|
9
9
|
{ name="Turan Baturay", email="baturayturan@gmail.com" }
|
10
10
|
]
|
@@ -15,7 +15,7 @@ classifiers = [
|
|
15
15
|
"License :: OSI Approved :: MIT License",
|
16
16
|
"Operating System :: OS Independent",
|
17
17
|
]
|
18
|
-
requires-python = ">=3.
|
18
|
+
requires-python = ">=3.10"
|
19
19
|
dependencies=[
|
20
20
|
"pygame-ce"
|
21
21
|
]
|
@@ -0,0 +1,66 @@
|
|
1
|
+
import pygame
|
2
|
+
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
|
+
from .constants import Colors as color
|
43
|
+
from .constants import Axis as axis
|
44
|
+
from .utils import Singleton
|
45
|
+
from .utils import Utils as utils
|
46
|
+
from .time import Time, Timer
|
47
|
+
from .cutscene import Cutscene,CutsceneManager
|
48
|
+
from .cutsceneBlocks import *
|
49
|
+
from .easing import Easing, EasingAnimation
|
50
|
+
from .audioManager import AudioManager
|
51
|
+
from .utils import Layout, Alignment, Direction
|
52
|
+
from .transition import *
|
53
|
+
from .action import Action
|
54
|
+
from .actionContainer import ActionContainer
|
55
|
+
from .camera import Camera
|
56
|
+
from .entity import Entity
|
57
|
+
from .dynamicEntity import DynamicEntity
|
58
|
+
from .animatedSprite import AnimatedSprite, AnimState
|
59
|
+
from .stateMachine import State, StateMachine
|
60
|
+
from .particles import Particle, ParticleManager
|
61
|
+
# from .debugger import Debugger
|
62
|
+
from .scene import Scene
|
63
|
+
from .gui import *
|
64
|
+
from .sceneManager import SceneManager
|
65
|
+
from .manager import Manager
|
66
|
+
|
@@ -12,21 +12,20 @@ class Action:
|
|
12
12
|
Args:
|
13
13
|
name (str): The name of the action.
|
14
14
|
"""
|
15
|
-
self._name
|
16
|
-
self._active
|
17
|
-
self._type
|
18
|
-
self._key_control
|
19
|
-
self._mouse_control
|
20
|
-
self._gamepad_button_control
|
21
|
-
self._gamepad_axis_control
|
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()
|
22
22
|
self._holding = set()
|
23
23
|
self._unique = True
|
24
|
-
self.data: Any = None
|
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.
|
30
29
|
|
31
30
|
Args:
|
32
31
|
val (bool): True if the action is unique, False otherwise.
|
@@ -52,7 +51,7 @@ class Action:
|
|
52
51
|
self._active = value
|
53
52
|
self._holding = set()
|
54
53
|
|
55
|
-
def add_key_control(self, *keys) ->
|
54
|
+
def add_key_control(self, *keys) -> 'Action':
|
56
55
|
"""
|
57
56
|
Add key controls to the action.
|
58
57
|
|
@@ -65,26 +64,7 @@ class Action:
|
|
65
64
|
self._key_control.update(keys)
|
66
65
|
return self
|
67
66
|
|
68
|
-
def
|
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":
|
67
|
+
def add_mouse_control(self, *mouse_buttons) -> 'Action':
|
88
68
|
"""
|
89
69
|
Add mouse control to the action.
|
90
70
|
|
@@ -106,7 +86,7 @@ class Action:
|
|
106
86
|
"""
|
107
87
|
return self._name
|
108
88
|
|
109
|
-
def set_continuous(self) ->
|
89
|
+
def set_continuous(self) -> 'Action':
|
110
90
|
"""
|
111
91
|
Set the action type to continuous.
|
112
92
|
|
@@ -126,7 +106,7 @@ class Action:
|
|
126
106
|
"""
|
127
107
|
return self._type == ActionType.CONTINUOUS
|
128
108
|
|
129
|
-
def set_instantaneous(self) ->
|
109
|
+
def set_instantaneous(self) -> 'Action':
|
130
110
|
"""
|
131
111
|
Set the action type to instantaneous.
|
132
112
|
|
@@ -146,7 +126,7 @@ class Action:
|
|
146
126
|
"""
|
147
127
|
return self._type == ActionType.INSTANTANEOUS
|
148
128
|
|
149
|
-
def set_holding(self) ->
|
129
|
+
def set_holding(self) -> 'Action':
|
150
130
|
"""
|
151
131
|
Set the action type to holding.
|
152
132
|
|
@@ -165,14 +145,9 @@ class Action:
|
|
165
145
|
"""
|
166
146
|
return self._type == ActionType.HOLDING
|
167
147
|
|
168
|
-
def process_update(self,
|
169
|
-
if (
|
170
|
-
self.
|
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}
|
148
|
+
def process_update(self,event:pygame.Event)->None:
|
149
|
+
if self.is_active() and event.type == pygame.MOUSEMOTION and self.is_holding_type() and pygame.MOUSEMOTION in self._mouse_control:
|
150
|
+
self.data = {"pos":event.pos,"rel":event.rel}
|
176
151
|
|
177
152
|
def process_activate(self, event: pygame.event.Event) -> bool:
|
178
153
|
"""
|
@@ -230,7 +205,10 @@ class Action:
|
|
230
205
|
if not self._holding:
|
231
206
|
self._active = False
|
232
207
|
return True
|
233
|
-
elif
|
208
|
+
elif (
|
209
|
+
event.type == pygame.MOUSEMOTION
|
210
|
+
and event.type in self._mouse_control
|
211
|
+
):
|
234
212
|
self.value = None
|
235
213
|
if event.type in self._holding:
|
236
214
|
self._holding.remove(event.type)
|
@@ -0,0 +1,38 @@
|
|
1
|
+
import batFramework as bf
|
2
|
+
|
3
|
+
|
4
|
+
class ActionContainer:
|
5
|
+
def __init__(self, *actions: list[bf.Action]) -> None:
|
6
|
+
self._actions: dict[str, bf.Action] = {}
|
7
|
+
if actions:
|
8
|
+
self.add_action(*actions)
|
9
|
+
|
10
|
+
def clear(self):
|
11
|
+
self._actions = {}
|
12
|
+
|
13
|
+
def add_action(self, *actions: bf.Action):
|
14
|
+
for action in actions:
|
15
|
+
self._actions[action.get_name()] = action
|
16
|
+
|
17
|
+
def get(self,name:str)->bf.Action:
|
18
|
+
return self._actions.get(name)
|
19
|
+
|
20
|
+
def has_action(self, name:str):
|
21
|
+
return name in self._actions
|
22
|
+
|
23
|
+
def is_active(self, *names:str)->bool:
|
24
|
+
return all(self._actions.get(name).is_active() if name in self._actions else False for name in names)
|
25
|
+
|
26
|
+
def process_event(self, event):
|
27
|
+
for action in self._actions.values():
|
28
|
+
a = action.process_event(event)
|
29
|
+
if a and action._unique:
|
30
|
+
break
|
31
|
+
|
32
|
+
def reset(self):
|
33
|
+
for action in self._actions.values():
|
34
|
+
action.reset()
|
35
|
+
|
36
|
+
def hard_reset(self):
|
37
|
+
for action in self._actions.values():
|
38
|
+
action.hard_reset()
|
@@ -0,0 +1,117 @@
|
|
1
|
+
import batFramework as bf
|
2
|
+
import pygame
|
3
|
+
|
4
|
+
|
5
|
+
|
6
|
+
def search_index(target, lst):
|
7
|
+
cumulative_sum = 0
|
8
|
+
for index, value in enumerate(lst):
|
9
|
+
cumulative_sum += value
|
10
|
+
if cumulative_sum >= target:
|
11
|
+
return index
|
12
|
+
return -1
|
13
|
+
|
14
|
+
|
15
|
+
class AnimState:
|
16
|
+
def __init__(self, file, width, height, frame_length_list:list|int) -> None:
|
17
|
+
self.frames: list[pygame.Surface] = bf.utils.img_slice(file, width, height)
|
18
|
+
self.frames_flipX: list[pygame.Surface] = bf.utils.img_slice(
|
19
|
+
file, width, height, True
|
20
|
+
)
|
21
|
+
|
22
|
+
self.frame_length_list = []
|
23
|
+
self.ffl_length = 0
|
24
|
+
self.set_frame_length_list(frame_length_list)
|
25
|
+
|
26
|
+
def get_frame_index(self, counter:float|int):
|
27
|
+
return search_index(int(counter % self.ffl_length), self.frame_length_list)
|
28
|
+
|
29
|
+
def get_frame(self, counter, flip):
|
30
|
+
i = self.get_frame_index(counter)
|
31
|
+
return self.frames_flipX[i] if flip else self.frames[i]
|
32
|
+
|
33
|
+
def set_frame_length_list(self,frame_length_list:list[int]|int):
|
34
|
+
if isinstance(frame_length_list,int):
|
35
|
+
frame_length_list = [frame_length_list] * len(self.frames)
|
36
|
+
if len(frame_length_list) != len(self.frames) :
|
37
|
+
raise ValueError("frame_length_list should have values for all frames")
|
38
|
+
self.frame_length_list = frame_length_list
|
39
|
+
self.ffl_length = sum(self.frame_length_list)
|
40
|
+
|
41
|
+
|
42
|
+
class AnimatedSprite(bf.DynamicEntity):
|
43
|
+
def __init__(self, size=None) -> None:
|
44
|
+
super().__init__(size, no_surface=True)
|
45
|
+
self.float_counter = 0
|
46
|
+
self.animStates: dict[str, AnimState] = {}
|
47
|
+
self.current_animState :str = ""
|
48
|
+
self.flipX = False
|
49
|
+
self._locked = False
|
50
|
+
|
51
|
+
def set_counter(self,value:float):
|
52
|
+
self.float_counter = value
|
53
|
+
|
54
|
+
|
55
|
+
def lock_animState(self):
|
56
|
+
self._locked = True
|
57
|
+
|
58
|
+
def unlock_animState(self):
|
59
|
+
self._locked = False
|
60
|
+
|
61
|
+
def set_flipX(self, value):
|
62
|
+
self.flipX = value
|
63
|
+
|
64
|
+
def remove_animState(self, name:str):
|
65
|
+
if not name in self.animStates :return
|
66
|
+
self.animStates.pop(name)
|
67
|
+
if self.current_animState == name : self.current_animState = list(self.animStates.keys())[0] if self.animStates else ""
|
68
|
+
|
69
|
+
def add_animState(
|
70
|
+
self, name: str, file: str, size: tuple[int, int], frame_length_list: list[int]
|
71
|
+
):
|
72
|
+
if name in self.animStates:
|
73
|
+
return
|
74
|
+
self.animStates[name] = AnimState(file, *size, frame_length_list)
|
75
|
+
if len(self.animStates) == 1 : self.set_animState(name)
|
76
|
+
|
77
|
+
def set_animState(self, state:str, reset_counter=True, lock=False):
|
78
|
+
if state not in self.animStates or self._locked:
|
79
|
+
return False
|
80
|
+
self.current_animState = state
|
81
|
+
self.rect = (
|
82
|
+
self.animStates[self.current_animState]
|
83
|
+
.frames[0]
|
84
|
+
.get_frect(center=self.rect.center)
|
85
|
+
)
|
86
|
+
if reset_counter or self.float_counter > sum(
|
87
|
+
self.get_state().frame_length_list
|
88
|
+
):
|
89
|
+
self.float_counter = 0
|
90
|
+
if lock:
|
91
|
+
self.lock_animState()
|
92
|
+
return True
|
93
|
+
|
94
|
+
def get_state(self):
|
95
|
+
return self.animStates.get(self.current_animState,None)
|
96
|
+
|
97
|
+
def get_frame_index(self):
|
98
|
+
return self.animStates[self.current_animState].get_frame_index(
|
99
|
+
self.float_counter
|
100
|
+
)
|
101
|
+
|
102
|
+
def update(self, dt: float):
|
103
|
+
if not self.animStates : return
|
104
|
+
self.float_counter += 60 * dt
|
105
|
+
if self.float_counter > self.get_state().ffl_length:
|
106
|
+
self.float_counter = 0
|
107
|
+
self.do_update(dt)
|
108
|
+
|
109
|
+
def draw(self, camera: bf.Camera) -> bool:
|
110
|
+
if not self.visible or not camera.intersects(self.rect) or not self.animStates:
|
111
|
+
return False
|
112
|
+
# pygame.draw.rect(camera.surface,"purple",camera.transpose(self.rect).move(2,2))
|
113
|
+
camera.surface.blit(
|
114
|
+
self.get_state().get_frame(self.float_counter, self.flipX),
|
115
|
+
camera.transpose(self.rect),
|
116
|
+
)
|
117
|
+
return True
|
@@ -5,19 +5,24 @@ pygame.mixer.init()
|
|
5
5
|
|
6
6
|
|
7
7
|
class AudioManager(metaclass=bf.Singleton):
|
8
|
-
def __init__(self)
|
9
|
-
self.sounds: dict = {}
|
10
|
-
self.musics: dict = {}
|
11
|
-
self.current_music
|
12
|
-
self.music_volume
|
13
|
-
self.sound_volume
|
8
|
+
def __init__(self):
|
9
|
+
self.sounds: dict[str : dict[str, pygame.mixer.Sound, bool]] = {}
|
10
|
+
self.musics: dict[str:str] = {}
|
11
|
+
self.current_music = None
|
12
|
+
self.music_volume = 1
|
13
|
+
self.sound_volume = 1
|
14
14
|
pygame.mixer_music.set_endevent(bf.const.MUSIC_END_EVENT)
|
15
15
|
|
16
|
-
def free_sounds(self, force
|
16
|
+
def free_sounds(self, force=False):
|
17
17
|
if force:
|
18
18
|
self.sounds = {}
|
19
19
|
return
|
20
|
-
|
20
|
+
to_remove = []
|
21
|
+
for name, data in self.sounds.items():
|
22
|
+
if not data["persistent"]:
|
23
|
+
to_remove.append(name)
|
24
|
+
|
25
|
+
_ = [self.sounds.pop(i) for i in to_remove]
|
21
26
|
|
22
27
|
def set_sound_volume(self, volume: float):
|
23
28
|
self.sound_volume = volume
|
@@ -26,54 +31,38 @@ class AudioManager(metaclass=bf.Singleton):
|
|
26
31
|
self.music_volume = volume
|
27
32
|
pygame.mixer_music.set_volume(volume)
|
28
33
|
|
29
|
-
def has_sound(self, name
|
34
|
+
def has_sound(self, name):
|
30
35
|
return name in self.sounds
|
31
36
|
|
32
37
|
def load_sound(self, name, path, persistent=False) -> pygame.mixer.Sound:
|
33
38
|
if name in self.sounds:
|
34
39
|
return self.sounds[name]["sound"]
|
35
|
-
path = bf.
|
40
|
+
path = bf.utils.get_path(path)
|
36
41
|
self.sounds[name] = {
|
37
42
|
"path": path,
|
38
43
|
"sound": pygame.mixer.Sound(path),
|
39
|
-
"persistent": persistent
|
44
|
+
"persistent": persistent,
|
40
45
|
}
|
41
46
|
return self.sounds[name]["sound"]
|
42
47
|
|
43
|
-
def load_sounds(self,sound_data_list:list[tuple[str,str,bool]])->None:
|
44
|
-
for data in sound_data_list:
|
45
|
-
self.load_sound(*data)
|
46
|
-
return
|
47
|
-
|
48
48
|
def play_sound(self, name, volume=1):
|
49
|
-
|
50
|
-
|
51
|
-
self.sounds[name]["sound"].play()
|
52
|
-
except KeyError:
|
53
|
-
print(f"Sound '{name}' not loaded in AudioManager.")
|
49
|
+
self.sounds[name]["sound"].set_volume(volume * self.sound_volume)
|
50
|
+
self.sounds[name]["sound"].play()
|
54
51
|
|
55
52
|
def stop_sound(self, name):
|
56
|
-
|
53
|
+
if name in self.sounds:
|
57
54
|
self.sounds[name]["sound"].stop()
|
58
|
-
|
59
|
-
|
60
|
-
print(f"Sound '{name}' not loaded in AudioManager.")
|
55
|
+
|
61
56
|
def load_music(self, name, path):
|
62
|
-
self.musics[name] = bf.
|
63
|
-
|
64
|
-
|
65
|
-
def load_musics(self,music_data_list:list[tuple[str,str]]):
|
66
|
-
for data in music_data_list:
|
67
|
-
self.load_music(*data)
|
68
|
-
return
|
69
|
-
|
57
|
+
self.musics[name] = bf.utils.get_path(path)
|
58
|
+
|
70
59
|
def play_music(self, name, loop=0, fade=500):
|
71
|
-
|
60
|
+
if name in self.musics:
|
72
61
|
pygame.mixer_music.load(self.musics[name])
|
73
62
|
pygame.mixer_music.play(loop, fade_ms=fade)
|
74
63
|
self.current_music = name
|
75
|
-
|
76
|
-
print(f"Music '{name}' not
|
64
|
+
else:
|
65
|
+
print(f"Music '{name}' not found in AudioManager.")
|
77
66
|
|
78
67
|
def stop_music(self):
|
79
68
|
if not self.current_music:
|
@@ -94,6 +83,3 @@ class AudioManager(metaclass=bf.Singleton):
|
|
94
83
|
if not self.current_music:
|
95
84
|
return
|
96
85
|
pygame.mixer_music.unpause()
|
97
|
-
|
98
|
-
def get_current_music(self)->str|None:
|
99
|
-
return self.current_music
|