batframework 1.0.9a10__tar.gz → 1.1.0__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.9a10 → batframework-1.1.0}/PKG-INFO +24 -22
- batframework-1.1.0/README.md +36 -0
- batframework-1.1.0/pyproject.toml +23 -0
- batframework-1.1.0/src/batFramework/__init__.py +66 -0
- batframework-1.1.0/src/batFramework/action.py +252 -0
- batframework-1.1.0/src/batFramework/actionContainer.py +38 -0
- batframework-1.1.0/src/batFramework/animatedSprite.py +117 -0
- batframework-1.1.0/src/batFramework/audioManager.py +85 -0
- batframework-1.1.0/src/batFramework/camera.py +123 -0
- batframework-1.1.0/src/batFramework/constants.py +75 -0
- batframework-1.1.0/src/batFramework/cutscene.py +119 -0
- batframework-1.1.0/src/batFramework/cutsceneBlocks.py +176 -0
- batframework-1.1.0/src/batFramework/debugger.py +48 -0
- batframework-1.1.0/src/batFramework/dynamicEntity.py +23 -0
- batframework-1.1.0/src/batFramework/easing.py +71 -0
- batframework-1.1.0/src/batFramework/entity.py +123 -0
- batframework-1.1.0/src/batFramework/gui/__init__.py +14 -0
- batframework-1.1.0/src/batFramework/gui/button.py +84 -0
- batframework-1.1.0/src/batFramework/gui/constraints.py +204 -0
- batframework-1.1.0/src/batFramework/gui/container.py +49 -0
- batframework-1.1.0/src/batFramework/gui/debugger.py +47 -0
- batframework-1.1.0/src/batFramework/gui/frame.py +19 -0
- batframework-1.1.0/src/batFramework/gui/image.py +23 -0
- batframework-1.1.0/src/batFramework/gui/indicator.py +40 -0
- batframework-1.1.0/src/batFramework/gui/interactiveWidget.py +22 -0
- batframework-1.1.0/src/batFramework/gui/label.py +110 -0
- batframework-1.1.0/src/batFramework/gui/layout.py +81 -0
- batframework-1.1.0/src/batFramework/gui/root.py +60 -0
- batframework-1.1.0/src/batFramework/gui/shape.py +86 -0
- batframework-1.1.0/src/batFramework/gui/toggle.py +62 -0
- batframework-1.1.0/src/batFramework/gui/widget.py +307 -0
- batframework-1.1.0/src/batFramework/manager.py +50 -0
- batframework-1.1.0/src/batFramework/particles.py +77 -0
- batframework-1.1.0/src/batFramework/scene.py +226 -0
- batframework-1.1.0/src/batFramework/sceneManager.py +165 -0
- {batframework-1.0.9a10 → batframework-1.1.0}/src/batFramework/stateMachine.py +8 -11
- batframework-1.1.0/src/batFramework/time.py +75 -0
- batframework-1.1.0/src/batFramework/transition.py +157 -0
- batframework-1.1.0/src/batFramework/transitionManager.py +0 -0
- {batframework-1.0.9a10 → batframework-1.1.0}/src/batFramework/triggerZone.py +4 -4
- batframework-1.1.0/src/batFramework/utils.py +184 -0
- {batframework-1.0.9a10 → batframework-1.1.0}/src/batframework.egg-info/PKG-INFO +24 -22
- batframework-1.1.0/src/batframework.egg-info/SOURCES.txt +46 -0
- batframework-1.0.9a10/README.md +0 -29
- batframework-1.0.9a10/pyproject.toml +0 -25
- batframework-1.0.9a10/src/batFramework/__init__.py +0 -90
- batframework-1.0.9a10/src/batFramework/action.py +0 -279
- batframework-1.0.9a10/src/batFramework/actionContainer.py +0 -82
- batframework-1.0.9a10/src/batFramework/animatedSprite.py +0 -59
- batframework-1.0.9a10/src/batFramework/animation.py +0 -77
- batframework-1.0.9a10/src/batFramework/audioManager.py +0 -131
- batframework-1.0.9a10/src/batFramework/baseScene.py +0 -240
- batframework-1.0.9a10/src/batFramework/camera.py +0 -317
- batframework-1.0.9a10/src/batFramework/constants.py +0 -51
- batframework-1.0.9a10/src/batFramework/cutscene.py +0 -253
- batframework-1.0.9a10/src/batFramework/cutsceneManager.py +0 -34
- batframework-1.0.9a10/src/batFramework/drawable.py +0 -77
- batframework-1.0.9a10/src/batFramework/dynamicEntity.py +0 -30
- batframework-1.0.9a10/src/batFramework/easingController.py +0 -58
- batframework-1.0.9a10/src/batFramework/entity.py +0 -130
- batframework-1.0.9a10/src/batFramework/enums.py +0 -135
- batframework-1.0.9a10/src/batFramework/fontManager.py +0 -65
- batframework-1.0.9a10/src/batFramework/gui/__init__.py +0 -25
- batframework-1.0.9a10/src/batFramework/gui/animatedLabel.py +0 -89
- batframework-1.0.9a10/src/batFramework/gui/button.py +0 -18
- batframework-1.0.9a10/src/batFramework/gui/clickableWidget.py +0 -245
- batframework-1.0.9a10/src/batFramework/gui/constraints/__init__.py +0 -1
- batframework-1.0.9a10/src/batFramework/gui/constraints/constraints.py +0 -980
- batframework-1.0.9a10/src/batFramework/gui/container.py +0 -201
- batframework-1.0.9a10/src/batFramework/gui/debugger.py +0 -130
- batframework-1.0.9a10/src/batFramework/gui/draggableWidget.py +0 -44
- batframework-1.0.9a10/src/batFramework/gui/image.py +0 -58
- batframework-1.0.9a10/src/batFramework/gui/indicator.py +0 -113
- batframework-1.0.9a10/src/batFramework/gui/interactiveWidget.py +0 -239
- batframework-1.0.9a10/src/batFramework/gui/label.py +0 -344
- batframework-1.0.9a10/src/batFramework/gui/layout.py +0 -426
- batframework-1.0.9a10/src/batFramework/gui/meter.py +0 -96
- batframework-1.0.9a10/src/batFramework/gui/radioButton.py +0 -35
- batframework-1.0.9a10/src/batFramework/gui/root.py +0 -228
- batframework-1.0.9a10/src/batFramework/gui/selector.py +0 -250
- batframework-1.0.9a10/src/batFramework/gui/shape.py +0 -276
- batframework-1.0.9a10/src/batFramework/gui/slider.py +0 -397
- batframework-1.0.9a10/src/batFramework/gui/style.py +0 -10
- batframework-1.0.9a10/src/batFramework/gui/styleManager.py +0 -54
- batframework-1.0.9a10/src/batFramework/gui/syncedVar.py +0 -49
- batframework-1.0.9a10/src/batFramework/gui/textInput.py +0 -306
- batframework-1.0.9a10/src/batFramework/gui/toggle.py +0 -128
- batframework-1.0.9a10/src/batFramework/gui/tooltip.py +0 -30
- batframework-1.0.9a10/src/batFramework/gui/widget.py +0 -521
- batframework-1.0.9a10/src/batFramework/manager.py +0 -134
- batframework-1.0.9a10/src/batFramework/particle.py +0 -118
- batframework-1.0.9a10/src/batFramework/propertyEaser.py +0 -79
- batframework-1.0.9a10/src/batFramework/renderGroup.py +0 -34
- batframework-1.0.9a10/src/batFramework/resourceManager.py +0 -130
- batframework-1.0.9a10/src/batFramework/scene.py +0 -31
- batframework-1.0.9a10/src/batFramework/sceneLayer.py +0 -138
- batframework-1.0.9a10/src/batFramework/sceneManager.py +0 -197
- batframework-1.0.9a10/src/batFramework/scrollingSprite.py +0 -115
- batframework-1.0.9a10/src/batFramework/sprite.py +0 -51
- batframework-1.0.9a10/src/batFramework/templates/__init__.py +0 -1
- batframework-1.0.9a10/src/batFramework/templates/controller.py +0 -97
- batframework-1.0.9a10/src/batFramework/tileset.py +0 -46
- batframework-1.0.9a10/src/batFramework/timeManager.py +0 -213
- batframework-1.0.9a10/src/batFramework/transition.py +0 -162
- batframework-1.0.9a10/src/batFramework/utils.py +0 -306
- batframework-1.0.9a10/src/batframework.egg-info/SOURCES.txt +0 -70
- {batframework-1.0.9a10 → batframework-1.1.0}/LICENSE +0 -0
- {batframework-1.0.9a10 → batframework-1.1.0}/setup.cfg +0 -0
- {batframework-1.0.9a10 → batframework-1.1.0}/src/batframework.egg-info/dependency_links.txt +0 -0
- {batframework-1.0.9a10 → batframework-1.1.0}/src/batframework.egg-info/requires.txt +0 -0
- {batframework-1.0.9a10 → batframework-1.1.0}/src/batframework.egg-info/top_level.txt +0 -0
@@ -1,8 +1,7 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: batframework
|
3
|
-
Version: 1.0
|
3
|
+
Version: 1.1.0
|
4
4
|
Summary: Pygame framework for making games easier.
|
5
|
-
Author-email: Turan Baturay <baturayturan@gmail.com>
|
6
5
|
License: MIT License
|
7
6
|
|
8
7
|
Copyright (c) [2023] [TURAN BATURAY]
|
@@ -24,10 +23,6 @@ License: MIT License
|
|
24
23
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
25
24
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
26
25
|
SOFTWARE.
|
27
|
-
Project-URL: Homepage, https://github.com/TuranBaturay/batFramework
|
28
|
-
Classifier: Programming Language :: Python :: 3
|
29
|
-
Classifier: License :: OSI Approved :: MIT License
|
30
|
-
Classifier: Operating System :: OS Independent
|
31
26
|
Requires-Python: >=3.11
|
32
27
|
Description-Content-Type: text/markdown
|
33
28
|
License-File: LICENSE
|
@@ -35,30 +30,37 @@ Requires-Dist: pygame-ce
|
|
35
30
|
|
36
31
|
# batFramework
|
37
32
|
|
38
|
-
|
33
|
+
batFramework is a Python game framework built using Pygame, designed to simplify game development by providing entities, scenes, a scene manager, and various utilities.
|
39
34
|
|
40
|
-
##
|
35
|
+
## Purpose and Overview
|
36
|
+
The primary objective of batFramework is to streamline game development. It is mainly designed to program small 2D games
|
41
37
|
|
42
|
-
|
38
|
+
## Installation and Setup
|
39
|
+
To install batFramework, you can use pip:
|
40
|
+
```pip install batFramework```
|
43
41
|
|
44
|
-
|
42
|
+
The only dependency required is pygame-ce.
|
45
43
|
|
46
|
-
|
47
|
-
|
48
|
-
- Audio management (music and sound effects with volume control)
|
49
|
-
- Entity, sprite, and animated sprite handling
|
50
|
-
- Transition effects
|
51
|
-
- Utility modules (time management, constants, etc.)
|
52
|
-
- No external dependency except for pygame
|
44
|
+
## Usage Instructions
|
45
|
+
To create a basic app using batFramework, here's an example:
|
53
46
|
|
54
|
-
|
47
|
+
```python
|
48
|
+
import batFramework as bf
|
55
49
|
|
56
|
-
|
57
|
-
|
58
|
-
4. Explore the framework's modules in the `batFramework` directory and integrate them into your own game project.
|
50
|
+
# Initialize the framework
|
51
|
+
bf.init(resolution=(1280, 720), window_caption="My Amazing Program")
|
59
52
|
|
60
|
-
|
53
|
+
# Create a manager and a scene
|
54
|
+
bf.Manager(bf.Scene("main")).run()
|
55
|
+
```
|
56
|
+
In practice, users can inherit bf.Scene to create their own scenes, adding specific behaviors, entities, etc.
|
61
57
|
|
58
|
+
## Features and Functionalities
|
62
59
|
|
60
|
+
For more detailed information, please refer to the [documentation](https://batframework.github.io/batDocumentation/).
|
61
|
+
|
62
|
+
|
63
|
+
# License
|
64
|
+
MIT License
|
63
65
|
|
64
66
|
|
@@ -0,0 +1,36 @@
|
|
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. It is mainly designed to program small 2D games
|
7
|
+
|
8
|
+
## Installation and Setup
|
9
|
+
To install batFramework, you can use pip:
|
10
|
+
```pip install batFramework```
|
11
|
+
|
12
|
+
The only dependency required is pygame-ce.
|
13
|
+
|
14
|
+
## Usage Instructions
|
15
|
+
To create a basic app using batFramework, here's an example:
|
16
|
+
|
17
|
+
```python
|
18
|
+
import batFramework as bf
|
19
|
+
|
20
|
+
# Initialize the framework
|
21
|
+
bf.init(resolution=(1280, 720), window_caption="My Amazing Program")
|
22
|
+
|
23
|
+
# Create a manager and a scene
|
24
|
+
bf.Manager(bf.Scene("main")).run()
|
25
|
+
```
|
26
|
+
In practice, users can inherit bf.Scene to create their own scenes, adding specific behaviors, entities, etc.
|
27
|
+
|
28
|
+
## Features and Functionalities
|
29
|
+
|
30
|
+
For more detailed information, please refer to the [documentation](https://batframework.github.io/batDocumentation/).
|
31
|
+
|
32
|
+
|
33
|
+
# License
|
34
|
+
MIT License
|
35
|
+
|
36
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
[build-system]
|
2
|
+
requires = ["setuptools==76.1.0 "]
|
3
|
+
build-backend = "setuptools.build_meta"
|
4
|
+
|
5
|
+
[project]
|
6
|
+
name = "batframework"
|
7
|
+
description = "Pygame framework for making games easier."
|
8
|
+
readme = "README.md"
|
9
|
+
requires-python = ">=3.11"
|
10
|
+
dependencies = ["pygame-ce"]
|
11
|
+
version = "1.1.0"
|
12
|
+
license = { file = "LICENSE" }
|
13
|
+
|
14
|
+
[tool.commitizen]
|
15
|
+
name = "cz_conventional_commits"
|
16
|
+
version = "1.1.0"
|
17
|
+
tag_format = "v$version"
|
18
|
+
update_changelog_on_bump = true
|
19
|
+
changelog_file = "CHANGELOG.md"
|
20
|
+
version_files = [
|
21
|
+
"src/batFramework/version.json:version",
|
22
|
+
"pyproject.toml:version"
|
23
|
+
]
|
@@ -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
|
+
|
@@ -0,0 +1,252 @@
|
|
1
|
+
from typing import Any
|
2
|
+
from enum import Enum
|
3
|
+
import pygame
|
4
|
+
|
5
|
+
ActionType = Enum("type", "INSTANTANEOUS CONTINUOUS HOLDING")
|
6
|
+
|
7
|
+
class Action:
|
8
|
+
def __init__(self, name: str) -> None:
|
9
|
+
"""
|
10
|
+
Create a new action with the given name.
|
11
|
+
|
12
|
+
Args:
|
13
|
+
name (str): The name of the action.
|
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()
|
22
|
+
self._holding = set()
|
23
|
+
self._unique = True
|
24
|
+
self.data : Any = None
|
25
|
+
|
26
|
+
def set_unique(self, val: bool) -> None:
|
27
|
+
"""
|
28
|
+
Set whether this action is unique (exclusive).
|
29
|
+
|
30
|
+
Args:
|
31
|
+
val (bool): True if the action is unique, False otherwise.
|
32
|
+
"""
|
33
|
+
self._unique = val
|
34
|
+
|
35
|
+
def is_active(self) -> bool:
|
36
|
+
"""
|
37
|
+
Check if the action is currently active.
|
38
|
+
|
39
|
+
Returns:
|
40
|
+
bool: True if the action is active, False otherwise.
|
41
|
+
"""
|
42
|
+
return self._active
|
43
|
+
|
44
|
+
def set_active(self, value: bool) -> None:
|
45
|
+
"""
|
46
|
+
Set the action's active state.
|
47
|
+
|
48
|
+
Args:
|
49
|
+
value (bool): True to activate the action, False to deactivate it.
|
50
|
+
"""
|
51
|
+
self._active = value
|
52
|
+
self._holding = set()
|
53
|
+
|
54
|
+
def add_key_control(self, *keys) -> 'Action':
|
55
|
+
"""
|
56
|
+
Add key controls to the action.
|
57
|
+
|
58
|
+
Args:
|
59
|
+
*keys (int): Key codes to control this action.
|
60
|
+
|
61
|
+
Returns:
|
62
|
+
Action: The updated Action object for method chaining.
|
63
|
+
"""
|
64
|
+
self._key_control.update(keys)
|
65
|
+
return self
|
66
|
+
|
67
|
+
def add_mouse_control(self, *mouse_buttons) -> 'Action':
|
68
|
+
"""
|
69
|
+
Add mouse control to the action.
|
70
|
+
|
71
|
+
Args:
|
72
|
+
*mouse_buttons (int): Mouse button codes to control this action.
|
73
|
+
|
74
|
+
Returns:
|
75
|
+
Action: The updated Action object for method chaining.
|
76
|
+
"""
|
77
|
+
self._mouse_control.update(mouse_buttons)
|
78
|
+
return self
|
79
|
+
|
80
|
+
def get_name(self) -> str:
|
81
|
+
"""
|
82
|
+
Get the name of the action.
|
83
|
+
|
84
|
+
Returns:
|
85
|
+
str: The name of the action.
|
86
|
+
"""
|
87
|
+
return self._name
|
88
|
+
|
89
|
+
def set_continuous(self) -> 'Action':
|
90
|
+
"""
|
91
|
+
Set the action type to continuous.
|
92
|
+
|
93
|
+
Returns:
|
94
|
+
Action: The updated Action object for method chaining.
|
95
|
+
"""
|
96
|
+
self._holding = set()
|
97
|
+
self._type = ActionType.CONTINUOUS
|
98
|
+
return self
|
99
|
+
|
100
|
+
def is_continuous(self) -> bool:
|
101
|
+
"""
|
102
|
+
Check if the action type is continuous.
|
103
|
+
|
104
|
+
Returns:
|
105
|
+
bool: True if the action type is continuous, False otherwise.
|
106
|
+
"""
|
107
|
+
return self._type == ActionType.CONTINUOUS
|
108
|
+
|
109
|
+
def set_instantaneous(self) -> 'Action':
|
110
|
+
"""
|
111
|
+
Set the action type to instantaneous.
|
112
|
+
|
113
|
+
Returns:
|
114
|
+
Action: The updated Action object for method chaining.
|
115
|
+
"""
|
116
|
+
self._type = ActionType.INSTANTANEOUS
|
117
|
+
self._holding = set()
|
118
|
+
return self
|
119
|
+
|
120
|
+
def is_instantaneous(self) -> bool:
|
121
|
+
"""
|
122
|
+
Check if the action type is instantaneous.
|
123
|
+
|
124
|
+
Returns:
|
125
|
+
bool: True if the action type is instantaneous, False otherwise.
|
126
|
+
"""
|
127
|
+
return self._type == ActionType.INSTANTANEOUS
|
128
|
+
|
129
|
+
def set_holding(self) -> 'Action':
|
130
|
+
"""
|
131
|
+
Set the action type to holding.
|
132
|
+
|
133
|
+
Returns:
|
134
|
+
Action: The updated Action object for method chaining.
|
135
|
+
"""
|
136
|
+
self._type = ActionType.HOLDING
|
137
|
+
return self
|
138
|
+
|
139
|
+
def is_holding_type(self) -> bool:
|
140
|
+
"""
|
141
|
+
Check if the action type is holding.
|
142
|
+
|
143
|
+
Returns:
|
144
|
+
bool: True if the action type is holding, False otherwise.
|
145
|
+
"""
|
146
|
+
return self._type == ActionType.HOLDING
|
147
|
+
|
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}
|
151
|
+
|
152
|
+
def process_activate(self, event: pygame.event.Event) -> bool:
|
153
|
+
"""
|
154
|
+
Process activation of the action based on a pygame event.
|
155
|
+
|
156
|
+
Args:
|
157
|
+
event (pygame.event.Event): The pygame event to process.
|
158
|
+
|
159
|
+
Returns:
|
160
|
+
bool: True if the action was activated by the event, False otherwise.
|
161
|
+
"""
|
162
|
+
if event.type == pygame.KEYDOWN and event.key in self._key_control:
|
163
|
+
self._active = True
|
164
|
+
if self.is_holding_type():
|
165
|
+
self._holding.add(event.key)
|
166
|
+
return True
|
167
|
+
|
168
|
+
if event.type == pygame.MOUSEBUTTONDOWN and event.button in self._mouse_control:
|
169
|
+
self._active = True
|
170
|
+
if self.is_holding_type():
|
171
|
+
self._holding.add(event.button)
|
172
|
+
return True
|
173
|
+
|
174
|
+
if event.type == pygame.MOUSEMOTION and event.type in self._mouse_control:
|
175
|
+
self._active = True
|
176
|
+
if self.is_holding_type():
|
177
|
+
self._holding.add(event.type)
|
178
|
+
return True
|
179
|
+
|
180
|
+
return False
|
181
|
+
|
182
|
+
def process_deactivate(self, event: pygame.event.Event) -> bool:
|
183
|
+
"""
|
184
|
+
Process deactivation of the action based on a pygame event.
|
185
|
+
|
186
|
+
Args:
|
187
|
+
event (pygame.event.Event): The pygame event to process.
|
188
|
+
|
189
|
+
Returns:
|
190
|
+
bool: True if the action was deactivated by the event, False otherwise.
|
191
|
+
"""
|
192
|
+
if self._type == ActionType.HOLDING:
|
193
|
+
if event.type == pygame.KEYUP and event.key in self._key_control:
|
194
|
+
if event.key in self._holding:
|
195
|
+
self._holding.remove(event.key)
|
196
|
+
if not self._holding:
|
197
|
+
self._active = False
|
198
|
+
return True
|
199
|
+
elif (
|
200
|
+
event.type == pygame.MOUSEBUTTONUP
|
201
|
+
and event.button in self._mouse_control
|
202
|
+
):
|
203
|
+
if event.button in self._holding:
|
204
|
+
self._holding.remove(event.button)
|
205
|
+
if not self._holding:
|
206
|
+
self._active = False
|
207
|
+
return True
|
208
|
+
elif (
|
209
|
+
event.type == pygame.MOUSEMOTION
|
210
|
+
and event.type in self._mouse_control
|
211
|
+
):
|
212
|
+
self.value = None
|
213
|
+
if event.type in self._holding:
|
214
|
+
self._holding.remove(event.type)
|
215
|
+
if not self._holding:
|
216
|
+
self._active = False
|
217
|
+
return True
|
218
|
+
|
219
|
+
return False
|
220
|
+
|
221
|
+
def process_event(self, event: pygame.event.Event) -> bool:
|
222
|
+
"""
|
223
|
+
Process a pygame event and update the action's state.
|
224
|
+
|
225
|
+
Args:
|
226
|
+
event (pygame.event.Event): The pygame event to process.
|
227
|
+
|
228
|
+
Returns:
|
229
|
+
bool: True if the action state changed, False otherwise.
|
230
|
+
"""
|
231
|
+
if not self._active:
|
232
|
+
res = self.process_activate(event)
|
233
|
+
else:
|
234
|
+
res = self.process_deactivate(event)
|
235
|
+
self.process_update(event)
|
236
|
+
return res
|
237
|
+
|
238
|
+
def reset(self) -> None:
|
239
|
+
"""
|
240
|
+
Reset the action's state to the default state.
|
241
|
+
"""
|
242
|
+
if self._type in {ActionType.CONTINUOUS, ActionType.HOLDING}:
|
243
|
+
return
|
244
|
+
elif self._type == ActionType.INSTANTANEOUS:
|
245
|
+
self._active = False
|
246
|
+
|
247
|
+
def hard_reset(self) -> None:
|
248
|
+
"""
|
249
|
+
Hard reset the action, deactivating it and clearing any holding controls.
|
250
|
+
"""
|
251
|
+
self._active = False
|
252
|
+
self._holding = set()
|
@@ -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
|
@@ -0,0 +1,85 @@
|
|
1
|
+
import batFramework as bf
|
2
|
+
import pygame
|
3
|
+
|
4
|
+
pygame.mixer.init()
|
5
|
+
|
6
|
+
|
7
|
+
class AudioManager(metaclass=bf.Singleton):
|
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
|
+
pygame.mixer_music.set_endevent(bf.const.MUSIC_END_EVENT)
|
15
|
+
|
16
|
+
def free_sounds(self, force=False):
|
17
|
+
if force:
|
18
|
+
self.sounds = {}
|
19
|
+
return
|
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]
|
26
|
+
|
27
|
+
def set_sound_volume(self, volume: float):
|
28
|
+
self.sound_volume = volume
|
29
|
+
|
30
|
+
def set_music_volume(self, volume: float):
|
31
|
+
self.music_volume = volume
|
32
|
+
pygame.mixer_music.set_volume(volume)
|
33
|
+
|
34
|
+
def has_sound(self, name):
|
35
|
+
return name in self.sounds
|
36
|
+
|
37
|
+
def load_sound(self, name, path, persistent=False) -> pygame.mixer.Sound:
|
38
|
+
if name in self.sounds:
|
39
|
+
return self.sounds[name]["sound"]
|
40
|
+
path = bf.utils.get_path(path)
|
41
|
+
self.sounds[name] = {
|
42
|
+
"path": path,
|
43
|
+
"sound": pygame.mixer.Sound(path),
|
44
|
+
"persistent": persistent,
|
45
|
+
}
|
46
|
+
return self.sounds[name]["sound"]
|
47
|
+
|
48
|
+
def play_sound(self, name, volume=1):
|
49
|
+
self.sounds[name]["sound"].set_volume(volume * self.sound_volume)
|
50
|
+
self.sounds[name]["sound"].play()
|
51
|
+
|
52
|
+
def stop_sound(self, name):
|
53
|
+
if name in self.sounds:
|
54
|
+
self.sounds[name]["sound"].stop()
|
55
|
+
|
56
|
+
def load_music(self, name, path):
|
57
|
+
self.musics[name] = bf.utils.get_path(path)
|
58
|
+
|
59
|
+
def play_music(self, name, loop=0, fade=500):
|
60
|
+
if name in self.musics:
|
61
|
+
pygame.mixer_music.load(self.musics[name])
|
62
|
+
pygame.mixer_music.play(loop, fade_ms=fade)
|
63
|
+
self.current_music = name
|
64
|
+
else:
|
65
|
+
print(f"Music '{name}' not found in AudioManager.")
|
66
|
+
|
67
|
+
def stop_music(self):
|
68
|
+
if not self.current_music:
|
69
|
+
return
|
70
|
+
pygame.mixer_music.stop()
|
71
|
+
|
72
|
+
def fadeout_music(self, fade_ms: int):
|
73
|
+
if not self.current_music:
|
74
|
+
return
|
75
|
+
pygame.mixer_music.fadeout(fade_ms)
|
76
|
+
|
77
|
+
def pause_music(self):
|
78
|
+
if not self.current_music:
|
79
|
+
return
|
80
|
+
pygame.mixer_music.pause()
|
81
|
+
|
82
|
+
def resume_music(self):
|
83
|
+
if not self.current_music:
|
84
|
+
return
|
85
|
+
pygame.mixer_music.unpause()
|