batframework 1.0.9a7__tar.gz → 1.0.9a9__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.9a7 → batframework-1.0.9a9}/PKG-INFO +24 -3
- batframework-1.0.9a9/pyproject.toml +25 -0
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/__init__.py +20 -11
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/action.py +1 -1
- batframework-1.0.9a9/src/batFramework/animatedSprite.py +59 -0
- batframework-1.0.9a9/src/batFramework/animation.py +77 -0
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/audioManager.py +8 -5
- batframework-1.0.9a9/src/batFramework/baseScene.py +240 -0
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/camera.py +4 -0
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/constants.py +6 -2
- batframework-1.0.9a9/src/batFramework/cutscene.py +253 -0
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/cutsceneManager.py +5 -2
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/drawable.py +7 -5
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/easingController.py +10 -11
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/entity.py +21 -2
- batframework-1.0.9a9/src/batFramework/enums.py +135 -0
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/gui/__init__.py +6 -3
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/gui/animatedLabel.py +10 -2
- batframework-1.0.9a9/src/batFramework/gui/button.py +18 -0
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/gui/clickableWidget.py +63 -50
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/gui/constraints/constraints.py +212 -136
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/gui/container.py +77 -58
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/gui/debugger.py +12 -17
- batframework-1.0.9a9/src/batFramework/gui/draggableWidget.py +44 -0
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/gui/image.py +3 -10
- batframework-1.0.9a9/src/batFramework/gui/indicator.py +113 -0
- batframework-1.0.9a9/src/batFramework/gui/interactiveWidget.py +239 -0
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/gui/label.py +73 -64
- batframework-1.0.9a9/src/batFramework/gui/layout.py +426 -0
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/gui/meter.py +42 -20
- batframework-1.0.9a9/src/batFramework/gui/radioButton.py +35 -0
- batframework-1.0.9a9/src/batFramework/gui/root.py +228 -0
- batframework-1.0.9a9/src/batFramework/gui/selector.py +250 -0
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/gui/shape.py +13 -5
- batframework-1.0.9a9/src/batFramework/gui/slider.py +397 -0
- batframework-1.0.9a9/src/batFramework/gui/syncedVar.py +49 -0
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/gui/textInput.py +46 -22
- batframework-1.0.9a9/src/batFramework/gui/toggle.py +128 -0
- batframework-1.0.9a9/src/batFramework/gui/tooltip.py +30 -0
- batframework-1.0.9a9/src/batFramework/gui/widget.py +521 -0
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/manager.py +7 -8
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/particle.py +4 -1
- batframework-1.0.9a9/src/batFramework/propertyEaser.py +79 -0
- batframework-1.0.9a9/src/batFramework/renderGroup.py +34 -0
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/resourceManager.py +43 -13
- batframework-1.0.9a9/src/batFramework/scene.py +31 -0
- batframework-1.0.9a9/src/batFramework/sceneLayer.py +138 -0
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/sceneManager.py +31 -36
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/scrollingSprite.py +8 -3
- batframework-1.0.9a9/src/batFramework/templates/__init__.py +1 -0
- batframework-1.0.9a9/src/batFramework/templates/controller.py +97 -0
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/timeManager.py +76 -22
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/transition.py +37 -103
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/utils.py +125 -66
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batframework.egg-info/PKG-INFO +24 -3
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batframework.egg-info/SOURCES.txt +8 -4
- batframework-1.0.9a7/pyproject.toml +0 -18
- batframework-1.0.9a7/src/batFramework/animatedSprite.py +0 -128
- batframework-1.0.9a7/src/batFramework/animation.py +0 -52
- batframework-1.0.9a7/src/batFramework/character.py +0 -27
- batframework-1.0.9a7/src/batFramework/cutscene.py +0 -53
- batframework-1.0.9a7/src/batFramework/enums.py +0 -120
- batframework-1.0.9a7/src/batFramework/gui/button.py +0 -45
- batframework-1.0.9a7/src/batFramework/gui/draggableWidget.py +0 -40
- batframework-1.0.9a7/src/batFramework/gui/indicator.py +0 -58
- batframework-1.0.9a7/src/batFramework/gui/interactiveWidget.py +0 -220
- batframework-1.0.9a7/src/batFramework/gui/layout.py +0 -585
- batframework-1.0.9a7/src/batFramework/gui/radioButton.py +0 -84
- batframework-1.0.9a7/src/batFramework/gui/root.py +0 -158
- batframework-1.0.9a7/src/batFramework/gui/slider.py +0 -242
- batframework-1.0.9a7/src/batFramework/gui/toggle.py +0 -110
- batframework-1.0.9a7/src/batFramework/gui/widget.py +0 -434
- batframework-1.0.9a7/src/batFramework/renderGroup.py +0 -67
- batframework-1.0.9a7/src/batFramework/scene.py +0 -351
- batframework-1.0.9a7/src/batFramework/templates/__init__.py +0 -2
- batframework-1.0.9a7/src/batFramework/templates/character.py +0 -43
- batframework-1.0.9a7/src/batFramework/templates/states.py +0 -166
- batframework-1.0.9a7/LICENCE → batframework-1.0.9a9/LICENSE +0 -0
- {batframework-1.0.9a7 → batframework-1.0.9a9}/README.md +0 -0
- {batframework-1.0.9a7 → batframework-1.0.9a9}/setup.cfg +0 -0
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/actionContainer.py +0 -0
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/dynamicEntity.py +0 -0
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/fontManager.py +0 -0
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/gui/constraints/__init__.py +0 -0
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/gui/style.py +0 -0
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/gui/styleManager.py +0 -0
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/sprite.py +1 -1
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/stateMachine.py +0 -0
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/tileset.py +0 -0
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batFramework/triggerZone.py +0 -0
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batframework.egg-info/dependency_links.txt +0 -0
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batframework.egg-info/requires.txt +0 -0
- {batframework-1.0.9a7 → batframework-1.0.9a9}/src/batframework.egg-info/top_level.txt +0 -0
@@ -1,15 +1,36 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.2
|
2
2
|
Name: batframework
|
3
|
-
Version: 1.0.
|
3
|
+
Version: 1.0.9a9
|
4
4
|
Summary: Pygame framework for making games easier.
|
5
5
|
Author-email: Turan Baturay <baturayturan@gmail.com>
|
6
|
+
License: MIT License
|
7
|
+
|
8
|
+
Copyright (c) [2023] [TURAN BATURAY]
|
9
|
+
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
12
|
+
in the Software without restriction, including without limitation the rights
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
15
|
+
furnished to do so, subject to the following conditions:
|
16
|
+
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
18
|
+
copies or substantial portions of the Software.
|
19
|
+
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
26
|
+
SOFTWARE.
|
6
27
|
Project-URL: Homepage, https://github.com/TuranBaturay/batFramework
|
7
28
|
Classifier: Programming Language :: Python :: 3
|
8
29
|
Classifier: License :: OSI Approved :: MIT License
|
9
30
|
Classifier: Operating System :: OS Independent
|
10
31
|
Requires-Python: >=3.11
|
11
32
|
Description-Content-Type: text/markdown
|
12
|
-
License-File:
|
33
|
+
License-File: LICENSE
|
13
34
|
Requires-Dist: pygame-ce
|
14
35
|
|
15
36
|
# batFramework
|
@@ -0,0 +1,25 @@
|
|
1
|
+
[build-system]
|
2
|
+
requires = ["setuptools==76.1.0 "]
|
3
|
+
build-backend = "setuptools.build_meta"
|
4
|
+
|
5
|
+
[project]
|
6
|
+
name = "batframework"
|
7
|
+
version = "1.0.9a9"
|
8
|
+
license = { file = "LICENSE" }
|
9
|
+
authors = [
|
10
|
+
{ name="Turan Baturay", email="baturayturan@gmail.com" }
|
11
|
+
]
|
12
|
+
description = "Pygame framework for making games easier."
|
13
|
+
readme = "README.md"
|
14
|
+
classifiers = [
|
15
|
+
"Programming Language :: Python :: 3",
|
16
|
+
"License :: OSI Approved :: MIT License",
|
17
|
+
"Operating System :: OS Independent",
|
18
|
+
]
|
19
|
+
requires-python = ">=3.11"
|
20
|
+
dependencies=[
|
21
|
+
"pygame-ce"
|
22
|
+
]
|
23
|
+
|
24
|
+
[project.urls]
|
25
|
+
"Homepage" = "https://github.com/TuranBaturay/batFramework"
|
@@ -1,4 +1,6 @@
|
|
1
|
+
import os
|
1
2
|
import pygame
|
3
|
+
import json
|
2
4
|
import batFramework as bf
|
3
5
|
from .constants import Constants as const
|
4
6
|
from .utils import Singleton
|
@@ -9,8 +11,9 @@ from .utils import Utils as utils
|
|
9
11
|
from .tileset import Tileset
|
10
12
|
from .timeManager import TimeManager,Timer,SceneTimer
|
11
13
|
from .easingController import EasingController
|
14
|
+
from .propertyEaser import PropertyEaser
|
12
15
|
from .cutsceneManager import CutsceneManager
|
13
|
-
|
16
|
+
import batFramework.cutscene as cutscene
|
14
17
|
from .audioManager import AudioManager
|
15
18
|
import batFramework.transition as transition
|
16
19
|
from .action import Action
|
@@ -25,18 +28,18 @@ from .scrollingSprite import ScrollingSprite
|
|
25
28
|
from .particle import *
|
26
29
|
from .animation import Animation
|
27
30
|
from .animatedSprite import AnimatedSprite
|
28
|
-
from .character import Character
|
29
31
|
from .stateMachine import State, StateMachine
|
32
|
+
from .sceneLayer import SceneLayer
|
30
33
|
from .scene import Scene
|
31
|
-
from
|
34
|
+
from .baseScene import BaseScene
|
35
|
+
import batFramework.gui as gui
|
32
36
|
from .sceneManager import SceneManager
|
33
37
|
from .manager import Manager
|
34
38
|
from .templates import *
|
35
|
-
import importlib.metadata
|
36
39
|
|
37
40
|
|
38
41
|
def init_screen(resolution: tuple[int, int], flags: int = 0, vsync: int = 0):
|
39
|
-
const.
|
42
|
+
const.set_resolution(resolution)
|
40
43
|
const.FLAGS = flags
|
41
44
|
const.VSYNC = vsync
|
42
45
|
const.SCREEN = pygame.display.set_mode(
|
@@ -46,13 +49,19 @@ def init_screen(resolution: tuple[int, int], flags: int = 0, vsync: int = 0):
|
|
46
49
|
f"Window : {resolution[0]}x{resolution[1]}"
|
47
50
|
)
|
48
51
|
|
52
|
+
|
49
53
|
def print_version():
|
50
|
-
|
54
|
+
# Dynamically construct the path to version.json
|
55
|
+
version_file = os.path.join(os.path.dirname(__file__), "version.json")
|
51
56
|
try:
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
57
|
+
with open(version_file, "r") as f:
|
58
|
+
version_data = json.load(f)
|
59
|
+
version = version_data.get("version", "unknown")
|
60
|
+
print(f"BatFramework version: {version}")
|
61
|
+
except FileNotFoundError:
|
62
|
+
print(f"Version file not found: {version_file}")
|
63
|
+
except json.JSONDecodeError:
|
64
|
+
print(f"Error decoding version file: {version_file}")
|
56
65
|
|
57
66
|
def init(
|
58
67
|
resolution: tuple[int, int],
|
@@ -73,7 +82,7 @@ def init(
|
|
73
82
|
resource_path if resource_path is not None else "."
|
74
83
|
)
|
75
84
|
if resource_path is not None:
|
76
|
-
ResourceManager().
|
85
|
+
ResourceManager().load_resources(ResourceManager().RESOURCE_PATH)
|
77
86
|
if default_font_size is not None:
|
78
87
|
FontManager().set_default_text_size(default_font_size)
|
79
88
|
FontManager().init_font(default_font)
|
@@ -0,0 +1,59 @@
|
|
1
|
+
import batFramework as bf
|
2
|
+
import pygame
|
3
|
+
from typing import List, Dict, Tuple, Union, Optional, Self, Callable, Any
|
4
|
+
from .animation import Animation
|
5
|
+
|
6
|
+
class AnimatedSprite(bf.Drawable):
|
7
|
+
def __init__(self,*args,**kwargs) -> None:
|
8
|
+
super().__init__(None, no_surface=True,*args,**kwargs)
|
9
|
+
self.animations : dict[str,Animation] = {}
|
10
|
+
self.counter = 0 # int counter
|
11
|
+
self._fcounter = 0.0 # counter
|
12
|
+
self.current_animation : str = None
|
13
|
+
self.end_callback : Callable[[],Any] = None
|
14
|
+
self._flipX : bool = False
|
15
|
+
|
16
|
+
@property
|
17
|
+
def flipX(self)->bool:
|
18
|
+
return self._flipX
|
19
|
+
|
20
|
+
@flipX.setter
|
21
|
+
def flipX(self,value:bool):
|
22
|
+
self._flipX = value
|
23
|
+
|
24
|
+
def set_end_callback(self,callback : Callable[[],Any]):
|
25
|
+
self.end_callback = callback
|
26
|
+
|
27
|
+
def add_animation(self,name:str,animation:Animation)->Self:
|
28
|
+
self.animations[name] = animation
|
29
|
+
if self.rect.size == (0,0):
|
30
|
+
self.rect.size = animation.frames[0].get_size()
|
31
|
+
return self
|
32
|
+
|
33
|
+
def set_animation(self,name:str,reset_counter:bool=True):
|
34
|
+
if name not in self.animations :
|
35
|
+
raise ValueError
|
36
|
+
self.current_animation = name
|
37
|
+
if reset_counter:
|
38
|
+
self._fcounter = 0
|
39
|
+
|
40
|
+
def get_current_frame(self)->int|None:
|
41
|
+
if not self.current_animation:
|
42
|
+
return None
|
43
|
+
return self.animations[self.current_animation].counter_to_frame(self._fcounter)
|
44
|
+
|
45
|
+
def update(self, dt):
|
46
|
+
super().update(dt)
|
47
|
+
if not self.current_animation:
|
48
|
+
return
|
49
|
+
self._fcounter += dt
|
50
|
+
self.counter = int(self._fcounter)
|
51
|
+
if self.counter >= self.animations[self.current_animation].numFrames:
|
52
|
+
if self.end_callback:
|
53
|
+
self.end_callback()
|
54
|
+
|
55
|
+
|
56
|
+
def draw(self, camera):
|
57
|
+
self.surface.blit(self.animations[self.current_animation].get_frame(self.counter,self.flipX),(0,0))
|
58
|
+
super().draw(camera)
|
59
|
+
|
@@ -0,0 +1,77 @@
|
|
1
|
+
import pygame
|
2
|
+
import batFramework as bf
|
3
|
+
from typing import List, Dict, Tuple, Union, Optional, Self
|
4
|
+
|
5
|
+
|
6
|
+
def search_index(target: int, lst: List[int]) -> int:
|
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 Animation:
|
16
|
+
def __init__(
|
17
|
+
self,
|
18
|
+
name: str
|
19
|
+
) -> None:
|
20
|
+
"""
|
21
|
+
Class to hold 2D animation data.
|
22
|
+
All frames are expected to have the same size.
|
23
|
+
This class does not do anything on its own, but can be used to easily manage
|
24
|
+
multiple animations using a simple counter.
|
25
|
+
The duration list provides a entry point for tweaking the timings,
|
26
|
+
so image data can be saved (no need for contiguous duplicate frames)
|
27
|
+
"""
|
28
|
+
self.name = name
|
29
|
+
self.frames: list[pygame.Surface] = []
|
30
|
+
self.frames_flipX : list[pygame.Surface] = []
|
31
|
+
self.duration_list = []
|
32
|
+
self.duration_list_length = 0 # prevents calling len() each frame
|
33
|
+
self.numFrames : int = 0
|
34
|
+
|
35
|
+
def from_surface(self,surface:pygame.Surface,frame_size : Tuple[int,int])->Self:
|
36
|
+
"""
|
37
|
+
Loads frames from a spritesheet containing all animation frames aligned horizontally, left to right
|
38
|
+
Frames are cut and stored in 2 versions, original and flipped on the horizontal axis.
|
39
|
+
Flipping sprites being pretty common, this serves as a builtin cache.
|
40
|
+
"""
|
41
|
+
self.frames : List[pygame.Surface] = list(
|
42
|
+
bf.utils.split_surface(surface, frame_size).values()
|
43
|
+
)
|
44
|
+
self.frames_flipX : List[pygame.Surface] = list(
|
45
|
+
bf.utils.split_surface(
|
46
|
+
surface, frame_size,
|
47
|
+
func=lambda s : pygame.transform.flip(s,True,False)
|
48
|
+
).values()
|
49
|
+
)
|
50
|
+
self.duration_list_length = len(self.frames)
|
51
|
+
self.numFrames = self.duration_list_length
|
52
|
+
if not self.duration_list:
|
53
|
+
self.duration_list = [1]*self.duration_list_length
|
54
|
+
return self
|
55
|
+
|
56
|
+
def __repr__(self):
|
57
|
+
return f"Animation({self.name})"
|
58
|
+
|
59
|
+
def counter_to_frame(self, counter: Union[float, int]) -> int:
|
60
|
+
if not self.frames :
|
61
|
+
raise ValueError("Animation has no frames")
|
62
|
+
return search_index(
|
63
|
+
int(counter % self.duration_list_length), self.duration_list
|
64
|
+
)
|
65
|
+
|
66
|
+
def get_frame(self, counter: Union[float, int], flip: bool) -> pygame.Surface:
|
67
|
+
i = self.counter_to_frame(counter)
|
68
|
+
return self.frames_flipX[i] if flip else self.frames[i]
|
69
|
+
|
70
|
+
def set_duration_list(self, duration_list: Union[List[int], int]) -> Self:
|
71
|
+
if isinstance(duration_list, int):
|
72
|
+
duration_list = [duration_list] * len(self.frames)
|
73
|
+
if len(duration_list) != self.numFrames:
|
74
|
+
raise ValueError("duration_list should have values for all frames")
|
75
|
+
self.duration_list = duration_list
|
76
|
+
self.duration_list_length = sum(self.duration_list)
|
77
|
+
return self
|
@@ -42,6 +42,9 @@ class AudioManager(metaclass=bf.Singleton):
|
|
42
42
|
return name in self.sounds
|
43
43
|
|
44
44
|
def load_sound(self, name, path, persistent=False) -> pygame.mixer.Sound:
|
45
|
+
"""
|
46
|
+
if persistent==True the sound won't be unloaded when sounds are freed (unless force is used)
|
47
|
+
"""
|
45
48
|
if name in self.sounds:
|
46
49
|
return self.sounds[name]["sound"]
|
47
50
|
path = bf.ResourceManager().get_path(path)
|
@@ -52,8 +55,8 @@ class AudioManager(metaclass=bf.Singleton):
|
|
52
55
|
}
|
53
56
|
return self.sounds[name]["sound"]
|
54
57
|
|
55
|
-
def load_sounds(self,
|
56
|
-
for data in
|
58
|
+
def load_sounds(self, sound_data: tuple[str, str, bool]) -> None:
|
59
|
+
for data in sound_data:
|
57
60
|
self.load_sound(*data)
|
58
61
|
return
|
59
62
|
|
@@ -83,8 +86,8 @@ class AudioManager(metaclass=bf.Singleton):
|
|
83
86
|
self.musics[name] = bf.ResourceManager().get_path(path)
|
84
87
|
return
|
85
88
|
|
86
|
-
def load_musics(self,
|
87
|
-
for data in
|
89
|
+
def load_musics(self, *music_data:tuple[str, str]):
|
90
|
+
for data in music_data:
|
88
91
|
self.load_music(*data)
|
89
92
|
return
|
90
93
|
|
@@ -101,8 +104,8 @@ class AudioManager(metaclass=bf.Singleton):
|
|
101
104
|
self.current_music = name
|
102
105
|
return True
|
103
106
|
except KeyError:
|
107
|
+
print(f"Music '{name}' not loaded in AudioManager.")
|
104
108
|
return False
|
105
|
-
# print(f"Music '{name}' not loaded in AudioManager.")
|
106
109
|
|
107
110
|
def stop_music(self):
|
108
111
|
if not self.current_music:
|
@@ -0,0 +1,240 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
from typing import TYPE_CHECKING, Any
|
3
|
+
if TYPE_CHECKING:
|
4
|
+
from .manager import Manager
|
5
|
+
from .sceneManager import SceneManager
|
6
|
+
|
7
|
+
import pygame
|
8
|
+
import itertools
|
9
|
+
import batFramework as bf
|
10
|
+
from .sceneLayer import SceneLayer
|
11
|
+
|
12
|
+
class BaseScene:
|
13
|
+
def __init__(self,name: str) -> None:
|
14
|
+
"""
|
15
|
+
Base Scene object.
|
16
|
+
Empty scene with no layers or gui setup
|
17
|
+
Args:
|
18
|
+
name: Name of the scene.
|
19
|
+
"""
|
20
|
+
bf.TimeManager().add_register(name,False)
|
21
|
+
self.scene_index = 0
|
22
|
+
self.name = name
|
23
|
+
self.manager: Manager | None = None
|
24
|
+
self.active = False
|
25
|
+
self.visible = False
|
26
|
+
self.clear_color = bf.color.BLACK
|
27
|
+
self.actions: bf.ActionContainer = bf.ActionContainer()
|
28
|
+
self.early_actions: bf.ActionContainer = bf.ActionContainer()
|
29
|
+
self.scene_layers : list[SceneLayer] = []
|
30
|
+
|
31
|
+
def set_clear_color(self,color):
|
32
|
+
"""
|
33
|
+
Sets the clear color of the entire scene.
|
34
|
+
This color will fill the scene before all layers are drawn.
|
35
|
+
Results will not show if a layer has an opaque fill color on top.
|
36
|
+
Set to None to skip.
|
37
|
+
"""
|
38
|
+
self.clear_color = color
|
39
|
+
|
40
|
+
def add_layer(self,layer:SceneLayer,index:int=0):
|
41
|
+
layer.set_scene(self)
|
42
|
+
self.scene_layers.insert(index,layer)
|
43
|
+
|
44
|
+
def remove_layer(self,index=0):
|
45
|
+
self.scene_layers.pop(index)
|
46
|
+
|
47
|
+
def set_layer(self,layername,layer):
|
48
|
+
for i,l in enumerate(self.scene_layers[::]):
|
49
|
+
if l.name == layername:
|
50
|
+
self.scene_layers[i] = layer
|
51
|
+
layer.set_scene(self)
|
52
|
+
|
53
|
+
def get_layer(self,name:str)->bf.SceneLayer:
|
54
|
+
for s in self.scene_layers:
|
55
|
+
if s.name == name:
|
56
|
+
return s
|
57
|
+
return None
|
58
|
+
|
59
|
+
def add(self,layer:str,*entities):
|
60
|
+
l = self.get_layer(layer)
|
61
|
+
if l is None : return
|
62
|
+
l.add(*entities)
|
63
|
+
|
64
|
+
def remove(self,layer:str,*entities):
|
65
|
+
l = self.get_layer(layer)
|
66
|
+
if l is None : return
|
67
|
+
l.remove(*entities)
|
68
|
+
|
69
|
+
def __str__(self)->str:
|
70
|
+
return f"Scene({self.name})"
|
71
|
+
|
72
|
+
def set_scene_index(self, index: int):
|
73
|
+
"""Set the scene index."""
|
74
|
+
self.scene_index = index
|
75
|
+
|
76
|
+
def get_scene_index(self) -> int:
|
77
|
+
"""Get the scene index."""
|
78
|
+
return self.scene_index
|
79
|
+
|
80
|
+
def when_added(self):
|
81
|
+
for s in self.scene_layers:
|
82
|
+
s.flush_entity_changes()
|
83
|
+
self.do_when_added()
|
84
|
+
|
85
|
+
def do_when_added(self):
|
86
|
+
pass
|
87
|
+
|
88
|
+
def set_manager(self, manager_link: Manager):
|
89
|
+
"""Set the manager link for the scene."""
|
90
|
+
self.manager = manager_link
|
91
|
+
self.manager.update_scene_states()
|
92
|
+
|
93
|
+
def set_visible(self, value: bool):
|
94
|
+
"""Set the visibility of the scene."""
|
95
|
+
self.visible = value
|
96
|
+
if self.manager:
|
97
|
+
self.manager.update_scene_states()
|
98
|
+
|
99
|
+
def set_active(self, value):
|
100
|
+
"""Set the activity of the scene."""
|
101
|
+
self.active = value
|
102
|
+
if self.manager:
|
103
|
+
self.manager.update_scene_states()
|
104
|
+
|
105
|
+
def is_active(self) -> bool:
|
106
|
+
"""Check if the scene is active."""
|
107
|
+
return self.active
|
108
|
+
|
109
|
+
def is_visible(self) -> bool:
|
110
|
+
"""Check if the scene is visible."""
|
111
|
+
return self.visible
|
112
|
+
|
113
|
+
def get_name(self) -> str:
|
114
|
+
"""Get the name of the scene."""
|
115
|
+
return self.name
|
116
|
+
|
117
|
+
def get_by_tags(self, *tags):
|
118
|
+
"""Get entities by their tags."""
|
119
|
+
return itertools.chain.from_iterable(l.get_by_tags(*tags) for l in self.scene_layers)
|
120
|
+
|
121
|
+
def get_by_uid(self, uid) -> bf.Entity | None:
|
122
|
+
"""Get an entity by its unique identifier."""
|
123
|
+
for l in self.scene_layers:
|
124
|
+
r = l.get_by_uid(uid)
|
125
|
+
if r is not None:
|
126
|
+
return r
|
127
|
+
return None
|
128
|
+
|
129
|
+
def add_actions(self, *action):
|
130
|
+
"""Add actions to the scene."""
|
131
|
+
self.actions.add_actions(*action)
|
132
|
+
|
133
|
+
def add_early_actions(self, *action):
|
134
|
+
"""Add actions to the scene."""
|
135
|
+
self.early_actions.add_actions(*action)
|
136
|
+
|
137
|
+
def process_event(self, event: pygame.Event):
|
138
|
+
"""
|
139
|
+
Propagates event while it is not consumed.
|
140
|
+
In order : do_early_handle_event
|
141
|
+
-> scene early_actions
|
142
|
+
-> propagate to all layers
|
143
|
+
-> do_handle_event
|
144
|
+
-> scene actions.
|
145
|
+
at each step, if the event is consumed the propagation stops
|
146
|
+
"""
|
147
|
+
self.do_early_handle_event(event)
|
148
|
+
if event.consumed: return
|
149
|
+
self.early_actions.process_event(event)
|
150
|
+
if event.consumed: return
|
151
|
+
|
152
|
+
if self.manager.current_transition and event.type in bf.enums.playerInput:
|
153
|
+
return
|
154
|
+
|
155
|
+
for l in self.scene_layers:
|
156
|
+
l.process_event(event)
|
157
|
+
if event.consumed : return
|
158
|
+
|
159
|
+
self.do_handle_event(event)
|
160
|
+
|
161
|
+
if event.consumed:return
|
162
|
+
self.actions.process_event(event)
|
163
|
+
|
164
|
+
# called before process event
|
165
|
+
def do_early_handle_event(self, event: pygame.Event):
|
166
|
+
"""Called early in event propagation"""
|
167
|
+
pass
|
168
|
+
|
169
|
+
def do_handle_event(self, event: pygame.Event):
|
170
|
+
"""called inside process_event but before resetting the scene's action container and propagating event to scene layers"""
|
171
|
+
pass
|
172
|
+
|
173
|
+
def update(self, dt):
|
174
|
+
"""Update the scene. Do NOT override"""
|
175
|
+
|
176
|
+
#update all scene layers
|
177
|
+
for l in self.scene_layers:
|
178
|
+
l.update(dt)
|
179
|
+
self.do_update(dt)
|
180
|
+
self.actions.reset()
|
181
|
+
self.early_actions.reset()
|
182
|
+
|
183
|
+
|
184
|
+
def do_update(self, dt):
|
185
|
+
"""Specific update within the scene."""
|
186
|
+
pass
|
187
|
+
|
188
|
+
|
189
|
+
def draw(self, surface: pygame.Surface):
|
190
|
+
if self.clear_color is not None:
|
191
|
+
surface.fill(self.clear_color)
|
192
|
+
|
193
|
+
self.do_early_draw(surface)
|
194
|
+
|
195
|
+
# Draw all layers back to front
|
196
|
+
for i,l in enumerate(reversed(self.scene_layers)):
|
197
|
+
#blit all layers onto surface
|
198
|
+
l.draw(surface)
|
199
|
+
if i < len(self.scene_layers)-1:
|
200
|
+
self.do_between_layer_draw(surface,l)
|
201
|
+
self.do_final_draw(surface)
|
202
|
+
|
203
|
+
|
204
|
+
def do_early_draw(self, surface: pygame.Surface):
|
205
|
+
"""Called before any layer draw"""
|
206
|
+
pass
|
207
|
+
|
208
|
+
def do_between_layer_draw(self, surface: pygame.Surface,layer:SceneLayer):
|
209
|
+
"""Called after drawing the argument layer (except the last layer)"""
|
210
|
+
pass
|
211
|
+
|
212
|
+
def do_final_draw(self, surface: pygame.Surface):
|
213
|
+
"Called after all layers"
|
214
|
+
pass
|
215
|
+
|
216
|
+
def on_enter(self):
|
217
|
+
self.set_active(True)
|
218
|
+
self.set_visible(True)
|
219
|
+
bf.TimeManager().activate_register(self.name)
|
220
|
+
self.do_on_enter()
|
221
|
+
|
222
|
+
def on_exit(self):
|
223
|
+
self.set_active(False)
|
224
|
+
self.set_visible(False)
|
225
|
+
self.actions.hard_reset()
|
226
|
+
self.early_actions.hard_reset()
|
227
|
+
bf.TimeManager().deactivate_register(self.name)
|
228
|
+
self.do_on_exit()
|
229
|
+
|
230
|
+
def do_on_enter(self) -> None:
|
231
|
+
pass
|
232
|
+
|
233
|
+
def do_on_exit(self) -> None:
|
234
|
+
pass
|
235
|
+
|
236
|
+
def do_on_enter_early(self) -> None:
|
237
|
+
pass
|
238
|
+
|
239
|
+
def do_on_exit_early(self) -> None:
|
240
|
+
pass
|
@@ -41,6 +41,9 @@ class Camera:
|
|
41
41
|
self.min_zoom = 0.1
|
42
42
|
self.zoom(1)
|
43
43
|
|
44
|
+
def get_mouse_pos(self)->tuple[float,float]:
|
45
|
+
return self.screen_to_world(pygame.mouse.get_pos())
|
46
|
+
|
44
47
|
def set_clear_color(self, color: pygame.Color | tuple | str) -> Self:
|
45
48
|
"""
|
46
49
|
Set the clear color for the camera surface.
|
@@ -84,6 +87,7 @@ class Camera:
|
|
84
87
|
"""
|
85
88
|
Clear the camera surface with the set clear color.
|
86
89
|
"""
|
90
|
+
if not self._clear_color: return
|
87
91
|
self.surface.fill(self._clear_color)
|
88
92
|
|
89
93
|
def get_center(self) -> tuple[float, float]:
|
@@ -22,12 +22,17 @@ class Constants:
|
|
22
22
|
def set_allow_debug(allow_debug:bool):
|
23
23
|
Constants.ALLOW_DEBUG = allow_debug
|
24
24
|
|
25
|
-
|
26
25
|
@staticmethod
|
27
26
|
def set_resolution(resolution: tuple[int, int]):
|
28
27
|
Constants.RESOLUTION = resolution
|
29
28
|
Constants.WIDTH = resolution[0]
|
30
29
|
Constants.HEIGHT = resolution[1]
|
30
|
+
Constants.update_screen()
|
31
|
+
|
32
|
+
@staticmethod
|
33
|
+
def update_screen():
|
34
|
+
if Constants.BF_INITIALIZED:
|
35
|
+
Constants.SCREEN = pygame.display.set_mode(Constants.RESOLUTION,Constants.FLAGS,vsync=Constants.VSYNC)
|
31
36
|
|
32
37
|
@staticmethod
|
33
38
|
def set_default_cursor(cursor: pygame.Cursor):
|
@@ -44,4 +49,3 @@ class Constants:
|
|
44
49
|
@staticmethod
|
45
50
|
def set_fps_limit(value: int):
|
46
51
|
Constants.FPS = value
|
47
|
-
print("FPS limit to : ", value)
|