batframework 1.0.9a11__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.
Files changed (111) hide show
  1. {batframework-1.0.9a11 → batframework-1.1.0}/PKG-INFO +24 -22
  2. batframework-1.1.0/README.md +36 -0
  3. batframework-1.1.0/pyproject.toml +23 -0
  4. batframework-1.1.0/src/batFramework/__init__.py +66 -0
  5. batframework-1.1.0/src/batFramework/action.py +252 -0
  6. batframework-1.1.0/src/batFramework/actionContainer.py +38 -0
  7. batframework-1.1.0/src/batFramework/animatedSprite.py +117 -0
  8. batframework-1.1.0/src/batFramework/audioManager.py +85 -0
  9. batframework-1.1.0/src/batFramework/camera.py +123 -0
  10. batframework-1.1.0/src/batFramework/constants.py +75 -0
  11. batframework-1.1.0/src/batFramework/cutscene.py +119 -0
  12. batframework-1.1.0/src/batFramework/cutsceneBlocks.py +176 -0
  13. batframework-1.1.0/src/batFramework/debugger.py +48 -0
  14. batframework-1.1.0/src/batFramework/dynamicEntity.py +23 -0
  15. batframework-1.1.0/src/batFramework/easing.py +71 -0
  16. batframework-1.1.0/src/batFramework/entity.py +123 -0
  17. batframework-1.1.0/src/batFramework/gui/__init__.py +14 -0
  18. batframework-1.1.0/src/batFramework/gui/button.py +84 -0
  19. batframework-1.1.0/src/batFramework/gui/constraints.py +204 -0
  20. batframework-1.1.0/src/batFramework/gui/container.py +49 -0
  21. batframework-1.1.0/src/batFramework/gui/debugger.py +47 -0
  22. batframework-1.1.0/src/batFramework/gui/frame.py +19 -0
  23. batframework-1.1.0/src/batFramework/gui/image.py +23 -0
  24. batframework-1.1.0/src/batFramework/gui/indicator.py +40 -0
  25. batframework-1.1.0/src/batFramework/gui/interactiveWidget.py +22 -0
  26. batframework-1.1.0/src/batFramework/gui/label.py +110 -0
  27. batframework-1.1.0/src/batFramework/gui/layout.py +81 -0
  28. batframework-1.1.0/src/batFramework/gui/root.py +60 -0
  29. batframework-1.1.0/src/batFramework/gui/shape.py +86 -0
  30. batframework-1.1.0/src/batFramework/gui/toggle.py +62 -0
  31. batframework-1.1.0/src/batFramework/gui/widget.py +307 -0
  32. batframework-1.1.0/src/batFramework/manager.py +50 -0
  33. batframework-1.1.0/src/batFramework/particles.py +77 -0
  34. batframework-1.1.0/src/batFramework/scene.py +226 -0
  35. batframework-1.1.0/src/batFramework/sceneManager.py +165 -0
  36. {batframework-1.0.9a11 → batframework-1.1.0}/src/batFramework/stateMachine.py +8 -11
  37. batframework-1.1.0/src/batFramework/time.py +75 -0
  38. batframework-1.1.0/src/batFramework/transition.py +157 -0
  39. batframework-1.1.0/src/batFramework/transitionManager.py +0 -0
  40. {batframework-1.0.9a11 → batframework-1.1.0}/src/batFramework/triggerZone.py +4 -4
  41. batframework-1.1.0/src/batFramework/utils.py +184 -0
  42. {batframework-1.0.9a11 → batframework-1.1.0}/src/batframework.egg-info/PKG-INFO +24 -22
  43. batframework-1.1.0/src/batframework.egg-info/SOURCES.txt +46 -0
  44. batframework-1.0.9a11/README.md +0 -29
  45. batframework-1.0.9a11/pyproject.toml +0 -25
  46. batframework-1.0.9a11/src/batFramework/__init__.py +0 -90
  47. batframework-1.0.9a11/src/batFramework/action.py +0 -279
  48. batframework-1.0.9a11/src/batFramework/actionContainer.py +0 -82
  49. batframework-1.0.9a11/src/batFramework/animatedSprite.py +0 -59
  50. batframework-1.0.9a11/src/batFramework/animation.py +0 -77
  51. batframework-1.0.9a11/src/batFramework/audioManager.py +0 -131
  52. batframework-1.0.9a11/src/batFramework/baseScene.py +0 -240
  53. batframework-1.0.9a11/src/batFramework/camera.py +0 -317
  54. batframework-1.0.9a11/src/batFramework/constants.py +0 -51
  55. batframework-1.0.9a11/src/batFramework/cutscene.py +0 -253
  56. batframework-1.0.9a11/src/batFramework/cutsceneManager.py +0 -34
  57. batframework-1.0.9a11/src/batFramework/drawable.py +0 -77
  58. batframework-1.0.9a11/src/batFramework/dynamicEntity.py +0 -30
  59. batframework-1.0.9a11/src/batFramework/easingController.py +0 -58
  60. batframework-1.0.9a11/src/batFramework/entity.py +0 -130
  61. batframework-1.0.9a11/src/batFramework/enums.py +0 -135
  62. batframework-1.0.9a11/src/batFramework/fontManager.py +0 -65
  63. batframework-1.0.9a11/src/batFramework/gui/__init__.py +0 -25
  64. batframework-1.0.9a11/src/batFramework/gui/animatedLabel.py +0 -89
  65. batframework-1.0.9a11/src/batFramework/gui/button.py +0 -18
  66. batframework-1.0.9a11/src/batFramework/gui/clickableWidget.py +0 -244
  67. batframework-1.0.9a11/src/batFramework/gui/constraints/__init__.py +0 -1
  68. batframework-1.0.9a11/src/batFramework/gui/constraints/constraints.py +0 -980
  69. batframework-1.0.9a11/src/batFramework/gui/container.py +0 -206
  70. batframework-1.0.9a11/src/batFramework/gui/debugger.py +0 -130
  71. batframework-1.0.9a11/src/batFramework/gui/draggableWidget.py +0 -44
  72. batframework-1.0.9a11/src/batFramework/gui/image.py +0 -58
  73. batframework-1.0.9a11/src/batFramework/gui/indicator.py +0 -113
  74. batframework-1.0.9a11/src/batFramework/gui/interactiveWidget.py +0 -239
  75. batframework-1.0.9a11/src/batFramework/gui/label.py +0 -344
  76. batframework-1.0.9a11/src/batFramework/gui/layout.py +0 -429
  77. batframework-1.0.9a11/src/batFramework/gui/meter.py +0 -96
  78. batframework-1.0.9a11/src/batFramework/gui/radioButton.py +0 -35
  79. batframework-1.0.9a11/src/batFramework/gui/root.py +0 -228
  80. batframework-1.0.9a11/src/batFramework/gui/selector.py +0 -250
  81. batframework-1.0.9a11/src/batFramework/gui/shape.py +0 -276
  82. batframework-1.0.9a11/src/batFramework/gui/slider.py +0 -397
  83. batframework-1.0.9a11/src/batFramework/gui/style.py +0 -10
  84. batframework-1.0.9a11/src/batFramework/gui/styleManager.py +0 -54
  85. batframework-1.0.9a11/src/batFramework/gui/syncedVar.py +0 -49
  86. batframework-1.0.9a11/src/batFramework/gui/textInput.py +0 -306
  87. batframework-1.0.9a11/src/batFramework/gui/toggle.py +0 -128
  88. batframework-1.0.9a11/src/batFramework/gui/tooltip.py +0 -30
  89. batframework-1.0.9a11/src/batFramework/gui/widget.py +0 -521
  90. batframework-1.0.9a11/src/batFramework/manager.py +0 -134
  91. batframework-1.0.9a11/src/batFramework/particle.py +0 -118
  92. batframework-1.0.9a11/src/batFramework/propertyEaser.py +0 -79
  93. batframework-1.0.9a11/src/batFramework/renderGroup.py +0 -34
  94. batframework-1.0.9a11/src/batFramework/resourceManager.py +0 -130
  95. batframework-1.0.9a11/src/batFramework/scene.py +0 -31
  96. batframework-1.0.9a11/src/batFramework/sceneLayer.py +0 -138
  97. batframework-1.0.9a11/src/batFramework/sceneManager.py +0 -197
  98. batframework-1.0.9a11/src/batFramework/scrollingSprite.py +0 -115
  99. batframework-1.0.9a11/src/batFramework/sprite.py +0 -51
  100. batframework-1.0.9a11/src/batFramework/templates/__init__.py +0 -1
  101. batframework-1.0.9a11/src/batFramework/templates/controller.py +0 -97
  102. batframework-1.0.9a11/src/batFramework/tileset.py +0 -46
  103. batframework-1.0.9a11/src/batFramework/timeManager.py +0 -213
  104. batframework-1.0.9a11/src/batFramework/transition.py +0 -162
  105. batframework-1.0.9a11/src/batFramework/utils.py +0 -306
  106. batframework-1.0.9a11/src/batframework.egg-info/SOURCES.txt +0 -70
  107. {batframework-1.0.9a11 → batframework-1.1.0}/LICENSE +0 -0
  108. {batframework-1.0.9a11 → batframework-1.1.0}/setup.cfg +0 -0
  109. {batframework-1.0.9a11 → batframework-1.1.0}/src/batframework.egg-info/dependency_links.txt +0 -0
  110. {batframework-1.0.9a11 → batframework-1.1.0}/src/batframework.egg-info/requires.txt +0 -0
  111. {batframework-1.0.9a11 → 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.9a11
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
- Welcome to the `batFramework`. This README provides an overview of the game framework.
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
- ## batFramework
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
- The `batFramework` is a Python game development framework based on pygame, designed to streamline the process of creating 2D games. It provides a set of tools and components to handle scenes, transitions, cutscenes, audio, sprites, and more. The framework is built with flexibility in mind, allowing you to focus on game design while abstracting away low-level details.
38
+ ## Installation and Setup
39
+ To install batFramework, you can use pip:
40
+ ```pip install batFramework```
43
41
 
44
- ### Features
42
+ The only dependency required is pygame-ce.
45
43
 
46
- - Scene management
47
- - Cutscene support
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
- ### Explore batFramework
47
+ ```python
48
+ import batFramework as bf
55
49
 
56
- 1. Install Python (version 3.11 or higher) and the latest stable version of pygame-ce.
57
- 2. Clone or download this repository.
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
- For more detailed information on how to use the framework, refer to the documentation (if available) or explore the source code in the `batFramework` directory.
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()