batframework 1.0.8a2__py3-none-any.whl → 1.0.8a3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- batFramework/__init__.py +53 -50
- batFramework/action.py +126 -99
- batFramework/actionContainer.py +53 -9
- batFramework/animatedSprite.py +115 -65
- batFramework/audioManager.py +69 -26
- batFramework/camera.py +259 -69
- batFramework/constants.py +16 -54
- batFramework/cutscene.py +36 -29
- batFramework/cutsceneBlocks.py +37 -42
- batFramework/dynamicEntity.py +9 -7
- batFramework/easingController.py +58 -0
- batFramework/entity.py +48 -97
- batFramework/enums.py +113 -0
- batFramework/fontManager.py +65 -0
- batFramework/gui/__init__.py +10 -2
- batFramework/gui/button.py +9 -78
- batFramework/gui/clickableWidget.py +219 -0
- batFramework/gui/constraints/__init__.py +1 -0
- batFramework/gui/constraints/constraints.py +590 -0
- batFramework/gui/container.py +174 -32
- batFramework/gui/debugger.py +131 -43
- batFramework/gui/dialogueBox.py +99 -0
- batFramework/gui/draggableWidget.py +40 -0
- batFramework/gui/image.py +54 -18
- batFramework/gui/indicator.py +38 -21
- batFramework/gui/interactiveWidget.py +177 -13
- batFramework/gui/label.py +288 -74
- batFramework/gui/layout.py +219 -60
- batFramework/gui/meter.py +71 -0
- batFramework/gui/radioButton.py +84 -0
- batFramework/gui/root.py +128 -38
- batFramework/gui/shape.py +253 -57
- batFramework/gui/slider.py +246 -0
- batFramework/gui/style.py +10 -0
- batFramework/gui/styleManager.py +48 -0
- batFramework/gui/textInput.py +137 -0
- batFramework/gui/toggle.py +115 -51
- batFramework/gui/widget.py +329 -254
- batFramework/manager.py +40 -19
- batFramework/object.py +114 -0
- batFramework/particle.py +101 -0
- batFramework/renderGroup.py +67 -0
- batFramework/resourceManager.py +84 -0
- batFramework/scene.py +242 -114
- batFramework/sceneManager.py +145 -107
- batFramework/scrollingSprite.py +115 -0
- batFramework/sprite.py +51 -0
- batFramework/stateMachine.py +2 -2
- batFramework/tileset.py +46 -0
- batFramework/time.py +117 -57
- batFramework/transition.py +184 -126
- batFramework/utils.py +31 -156
- batframework-1.0.8a3.dist-info/LICENCE +21 -0
- batframework-1.0.8a3.dist-info/METADATA +55 -0
- batframework-1.0.8a3.dist-info/RECORD +58 -0
- batFramework/debugger.py +0 -48
- batFramework/easing.py +0 -71
- batFramework/gui/constraints.py +0 -204
- batFramework/gui/frame.py +0 -19
- batFramework/particles.py +0 -77
- batFramework/transitionManager.py +0 -0
- batframework-1.0.8a2.dist-info/METADATA +0 -58
- batframework-1.0.8a2.dist-info/RECORD +0 -42
- {batframework-1.0.8a2.dist-info → batframework-1.0.8a3.dist-info}/WHEEL +0 -0
- {batframework-1.0.8a2.dist-info → batframework-1.0.8a3.dist-info}/top_level.txt +0 -0
batFramework/utils.py
CHANGED
@@ -3,9 +3,9 @@ from enum import Enum
|
|
3
3
|
import os
|
4
4
|
import batFramework as bf
|
5
5
|
import json
|
6
|
+
from .enums import *
|
7
|
+
import re
|
6
8
|
|
7
|
-
MAX_FONT_SIZE = 100
|
8
|
-
MIN_FONT_SIZE = 8
|
9
9
|
|
10
10
|
class Singleton(type):
|
11
11
|
_instances = {}
|
@@ -16,169 +16,44 @@ class Singleton(type):
|
|
16
16
|
return cls._instances[cls]
|
17
17
|
|
18
18
|
|
19
|
-
class Direction(Enum):
|
20
|
-
HORIZONTAL = "horizontal"
|
21
|
-
VERTICAL = "vertical"
|
22
|
-
|
23
|
-
|
24
|
-
class Alignment(Enum):
|
25
|
-
LEFT = "left"
|
26
|
-
RIGHT = "right"
|
27
|
-
CENTER = "center"
|
28
|
-
TOP = "top"
|
29
|
-
BOTTOM = "bottom"
|
30
|
-
|
31
|
-
|
32
|
-
class Layout(Enum):
|
33
|
-
FILL = "fill"
|
34
|
-
FIT = "fit"
|
35
|
-
|
36
|
-
|
37
19
|
class Utils:
|
38
|
-
pygame.font.init()
|
39
|
-
FONTS = {}
|
40
|
-
tilesets = {}
|
41
|
-
|
42
|
-
@staticmethod
|
43
|
-
def get_path(path: str):
|
44
|
-
return os.path.join(bf.const.RESOURCE_PATH, path)
|
45
20
|
|
46
21
|
@staticmethod
|
47
|
-
def
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
22
|
+
def split_surface(
|
23
|
+
surface: pygame.Surface, split_size: tuple[int, int], func=None
|
24
|
+
) -> dict[tuple[int, int], pygame.Surface]:
|
25
|
+
"""
|
26
|
+
Splits a surface into subsurfaces and returns a dictionnary of them
|
27
|
+
with their tuple coordinates as keys.
|
28
|
+
Exemple : '(0,0) : Surface'
|
29
|
+
"""
|
30
|
+
if surface is None:
|
54
31
|
return None
|
32
|
+
width, height = surface.get_size()
|
33
|
+
res = {}
|
34
|
+
for iy, y in enumerate(range(0, height, split_size[1])):
|
35
|
+
for ix, x in enumerate(range(0, width, split_size[0])):
|
36
|
+
sub = surface.subsurface((x, y, split_size[0], split_size[1]))
|
55
37
|
|
56
|
-
|
57
|
-
|
58
|
-
try:
|
59
|
-
with open(Utils.get_path(path), "w") as file:
|
60
|
-
json.dump(data, file, indent=2)
|
61
|
-
return True
|
62
|
-
except FileNotFoundError:
|
63
|
-
return False
|
64
|
-
|
65
|
-
@staticmethod
|
66
|
-
def init_font(raw_path:str):
|
67
|
-
try :
|
68
|
-
if raw_path is not None:
|
69
|
-
Utils.load_font(raw_path if raw_path else None,None)
|
70
|
-
Utils.load_font(raw_path)
|
71
|
-
except FileNotFoundError:
|
72
|
-
Utils.load_sysfont(raw_path)
|
73
|
-
Utils.load_sysfont(raw_path,None)
|
74
|
-
|
75
|
-
|
76
|
-
@staticmethod
|
77
|
-
def load_font(path:str,name:str=''):
|
78
|
-
if path is not None: path = Utils.get_path(path) # convert path if given
|
79
|
-
filename = os.path.basename(path).split('.')[0] if path is not None else None # get filename if path is given, else None
|
80
|
-
if name != '' : filename = name # if name is not given, name is the filename
|
81
|
-
Utils.FONTS[filename] = {}
|
82
|
-
# fill the dict
|
83
|
-
for size in range(MIN_FONT_SIZE, MAX_FONT_SIZE, 2):
|
84
|
-
Utils.FONTS[filename][size] = pygame.font.Font(path,size=size)
|
85
|
-
|
86
|
-
def load_sysfont(font_name:str,key:str=''):
|
87
|
-
if key == '' : key = font_name
|
88
|
-
if pygame.font.match_font(font_name) is None:
|
89
|
-
raise FileNotFoundError(f"Requested font '{font_namey}' was not found")
|
90
|
-
Utils.FONTS[font_name] = {}
|
38
|
+
if func is not None:
|
39
|
+
sub = func(sub)
|
91
40
|
|
92
|
-
|
93
|
-
Utils.FONTS[key][size] = pygame.font.SysFont(font_name,size=size)
|
94
|
-
|
41
|
+
res[(ix, iy)] = sub
|
95
42
|
|
96
|
-
@staticmethod
|
97
|
-
def get_font(name:str|None=None,text_size:int=12) -> pygame.Font:
|
98
|
-
if not name in Utils.FONTS: return None
|
99
|
-
if not text_size in Utils.FONTS[name]: return None
|
100
|
-
return Utils.FONTS[name][text_size]
|
101
|
-
|
102
|
-
class Tileset:
|
103
|
-
_flip_cache = {} # {"tileset":tileset,"index","flipX","flipY"}
|
104
|
-
|
105
|
-
def __init__(self, surface: pygame.Surface, tilesize) -> None:
|
106
|
-
self.tile_dict = {}
|
107
|
-
self.surface = surface
|
108
|
-
self.tile_size = tilesize
|
109
|
-
self.split_surface(surface)
|
110
|
-
|
111
|
-
def split_surface(self, surface: pygame.Surface):
|
112
|
-
width, height = surface.get_size()
|
113
|
-
num_tiles_x = width // self.tile_size
|
114
|
-
num_tiles_y = height // self.tile_size
|
115
|
-
# Iterate over the tiles vertically and horizontally
|
116
|
-
for y in range(num_tiles_y):
|
117
|
-
for x in range(num_tiles_x):
|
118
|
-
# Calculate the coordinates of the current tile in the tileset
|
119
|
-
tile_x = x * self.tile_size
|
120
|
-
tile_y = y * self.tile_size
|
121
|
-
# Create a subsurface for the current tile
|
122
|
-
tile_surface = surface.subsurface(
|
123
|
-
pygame.Rect(tile_x, tile_y, self.tile_size, self.tile_size)
|
124
|
-
)
|
125
|
-
# Calculate the unique key for the tile (e.g., based on its coordinates)
|
126
|
-
tile_key = (x, y)
|
127
|
-
# Store the subsurface in the dictionary with the corresponding key
|
128
|
-
self.tile_dict[tile_key] = tile_surface
|
129
|
-
# print(self.tile_dict)
|
130
|
-
|
131
|
-
def get_tile(self, x, y, flipX=False, flipY=False) -> pygame.Surface | None:
|
132
|
-
if (x, y) not in self.tile_dict:
|
133
|
-
return None
|
134
|
-
if flipX or flipY:
|
135
|
-
key = f"{x}{y}:{flipX}{flipY}"
|
136
|
-
if not key in self._flip_cache:
|
137
|
-
self._flip_cache[key] = pygame.transform.flip(
|
138
|
-
self.tile_dict[(x, y)], flipX, flipY
|
139
|
-
)
|
140
|
-
return self._flip_cache[key]
|
141
|
-
return self.tile_dict[(x, y)]
|
142
|
-
|
143
|
-
@staticmethod
|
144
|
-
def img_slice(file, cell_width, cell_height, flipX=False) -> list[pygame.Surface]:
|
145
|
-
src = pygame.image.load(
|
146
|
-
os.path.join(bf.const.RESOURCE_PATH, file)
|
147
|
-
).convert_alpha()
|
148
|
-
width, height = src.get_size()
|
149
|
-
res = []
|
150
|
-
for y in range(0, height, cell_height):
|
151
|
-
for x in range(0, width, cell_width):
|
152
|
-
sub = src.subsurface((x, y, cell_width, cell_height))
|
153
|
-
if flipX:
|
154
|
-
sub = pygame.transform.flip(sub, True, False)
|
155
|
-
|
156
|
-
res.append(sub)
|
157
43
|
return res
|
158
44
|
|
159
|
-
def load_tileset(path: str, name: str, tilesize):
|
160
|
-
if name in Utils.tilesets:
|
161
|
-
return Utils.tilesets[name]
|
162
|
-
else:
|
163
|
-
img = pygame.image.load(
|
164
|
-
os.path.join(bf.const.RESOURCE_PATH, path)
|
165
|
-
).convert_alpha()
|
166
|
-
tileset = Utils.Tileset(img, tilesize)
|
167
|
-
Utils.tilesets[name] = tileset
|
168
|
-
return tileset
|
169
|
-
|
170
45
|
@staticmethod
|
171
|
-
def
|
172
|
-
if
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
46
|
+
def filter_text(text_mode: textMode):
|
47
|
+
if text_mode == textMode.ALPHABETICAL:
|
48
|
+
pattern = re.compile(r"[^a-zA-Z]")
|
49
|
+
elif text_mode == textMode.NUMERICAL:
|
50
|
+
pattern = re.compile(r"[^0-9]")
|
51
|
+
elif text_mode == textMode.ALPHANUMERICAL:
|
52
|
+
pattern = re.compile(r"[^a-zA-Z0-9]")
|
53
|
+
else:
|
54
|
+
raise ValueError("Unsupported text mode")
|
178
55
|
|
56
|
+
def filter_function(s: str) -> str:
|
57
|
+
return pattern.sub("", s)
|
179
58
|
|
180
|
-
|
181
|
-
res = []
|
182
|
-
for point in points:
|
183
|
-
res.append((point[0] + delta[0], point[1] + delta[1]))
|
184
|
-
return res
|
59
|
+
return filter_function
|
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) [2023] [TURAN BATURAY]
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
@@ -0,0 +1,55 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: batframework
|
3
|
+
Version: 1.0.8a3
|
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.11
|
11
|
+
Description-Content-Type: text/markdown
|
12
|
+
License-File: LICENCE
|
13
|
+
Requires-Dist: pygame-ce
|
14
|
+
|
15
|
+
# batFramework & gamejam Project
|
16
|
+
|
17
|
+
Welcome to the `batFramework` and the accompanying `gamejam` project. This README provides an overview of both the game framework and the specific game project developed using the framework.
|
18
|
+
|
19
|
+
## batFramework
|
20
|
+
|
21
|
+
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.
|
22
|
+
|
23
|
+
### Features
|
24
|
+
|
25
|
+
- Scene management
|
26
|
+
- Cutscene support
|
27
|
+
- Audio management (music and sound effects with volume control)
|
28
|
+
- Entity, sprite, and animated sprite handling
|
29
|
+
- Transition effects
|
30
|
+
- Utility modules (time management, constants, etc.)
|
31
|
+
- No external dependency except for pygame
|
32
|
+
|
33
|
+
### Explore batFramework
|
34
|
+
|
35
|
+
1. Install Python (version 3.11 or higher) and the latest stable version of pygame-ce.
|
36
|
+
2. Clone or download this repository.
|
37
|
+
4. Explore the framework's modules in the `batFramework` directory and integrate them into your own game project.
|
38
|
+
|
39
|
+
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.
|
40
|
+
|
41
|
+
## gamejam Project
|
42
|
+
|
43
|
+
The `gamejam` project is a specific game developed using the `batFramework`. It serves as an example of how the framework can be used to create a game from scratch.
|
44
|
+
|
45
|
+
### Play the gamejam Project
|
46
|
+
|
47
|
+
1. Install Python (version 3.10 or higher) and the latest stable version of pygame-ce.
|
48
|
+
2. Clone or download this repository.
|
49
|
+
3. Navigate to the `gamejam` directory.
|
50
|
+
4. Run the game by executing the main script (e.g., `python main.py`).
|
51
|
+
5. Play the game and have fun!
|
52
|
+
|
53
|
+
Feel free to explore the code in the `gamejam` directory to see how the `batFramework` is utilized to create the game. You can modify, extend, or use the project as a starting point for your own games.
|
54
|
+
|
55
|
+
|
@@ -0,0 +1,58 @@
|
|
1
|
+
batFramework/__init__.py,sha256=5KS96Y0uDx8sue3NyDl2HTFh-CqEZc9otmnUXRCHXws,2189
|
2
|
+
batFramework/action.py,sha256=919IVYKviLyVYDtQL7oZvlVuE_aodjJCuwz6fGi5sCk,8420
|
3
|
+
batFramework/actionContainer.py,sha256=qy6-YY3iX26KJ8NqFMSYo6JExohD8HFk0sC1qhb7qA8,2602
|
4
|
+
batFramework/animatedSprite.py,sha256=1KmhUCX8q2JTyOr0ClLovJ21i6c2SkllTtqygmDSZvo,5168
|
5
|
+
batFramework/audioManager.py,sha256=BnfJz5GMMhvyL05mMRM9AyWtyHjyt7lIxScbzY2lmVQ,3873
|
6
|
+
batFramework/camera.py,sha256=u1EPSitZ9mEEa32yQB7K6ywnWgWCSumbhrc4HRjimEY,9406
|
7
|
+
batFramework/constants.py,sha256=5PyZQZ4fCcLA8k_Upby9KGVF-3pnV2ZZ6t26CxiocPM,1102
|
8
|
+
batFramework/cutscene.py,sha256=0gdGJZTslv0d9JcF-brVgjk56jZeDa-ZTgG5DR47y_c,3888
|
9
|
+
batFramework/cutsceneBlocks.py,sha256=Uezggx1XgmLvXW1GnuVkGj3tOM8AOxXYx1F9nFGvL-w,4788
|
10
|
+
batFramework/dynamicEntity.py,sha256=zp5ShM6fQ-a_hXTHA6UthbInfJl2XazsN6C2hll9nK8,665
|
11
|
+
batFramework/easingController.py,sha256=4N8GIp1fsaWBUlDxXx3SMwOq1Mrhn10MZZIO51_CRnk,1677
|
12
|
+
batFramework/entity.py,sha256=34gYC6uEMmLkqWtoTG9bgMWRmHRSxhQfxXZKzWS7H2o,2127
|
13
|
+
batFramework/enums.py,sha256=Iee21l4BajM7PXXrZF8SWAURX4qwMqKpQ7f12btqIbM,2077
|
14
|
+
batFramework/fontManager.py,sha256=VX3HmtyeiOBtv64XZjjJrvk29w6lawHKLfCGBwAa-4g,2242
|
15
|
+
batFramework/manager.py,sha256=YRKKv5qWVUs7D8ZqP8ZkfUeTCc3lHxfCfJSYdO5Ep8A,2375
|
16
|
+
batFramework/object.py,sha256=SnwnAmfC-7_QTGomQVpBQGSMQjN5NngZoNuvGdqHUrE,3021
|
17
|
+
batFramework/particle.py,sha256=yGGKjGtwzL-m48akGNsReLM82IPV1DzrsDy5SN_kMAw,2672
|
18
|
+
batFramework/renderGroup.py,sha256=_VDvmP4iB-XarFJo_Uh5YKwWq1cazHmOBmTXZkqKk40,2020
|
19
|
+
batFramework/resourceManager.py,sha256=8ysiVDMVRKOGo_kNRH2BiqiUj07kddgi04iNcTt9T-Q,3094
|
20
|
+
batFramework/scene.py,sha256=4KHzaIU2fIU2IfXUE8fTX_nlI_iXkylW3B09c3e79KE,11158
|
21
|
+
batFramework/sceneManager.py,sha256=BBEd0ngCO42nPxWnBPSTpHmzV4sBTKBrcd4uX7hna98,7151
|
22
|
+
batFramework/scrollingSprite.py,sha256=WYVCzuqGTQP7qauT_thzAtghPXnLsZFYNTD0KzYVxp8,4185
|
23
|
+
batFramework/sprite.py,sha256=t_kSyUXGOSXQbSBwrKgBUTp5mITeFQbAKNzugjL5SgY,1625
|
24
|
+
batFramework/stateMachine.py,sha256=tDQIfQH_4cVZyVNYJ2APe8-yhos3uGk5uSMo_XvktdQ,1335
|
25
|
+
batFramework/tileset.py,sha256=3AJBWHx90PC43BdLYCBFm811XBrMvWoB-nsUgyo6s-I,1728
|
26
|
+
batFramework/time.py,sha256=IGRIY_g9kpdJxR5wt1lOnLsY9gMReuBJZqnpWRyR-CQ,3963
|
27
|
+
batFramework/transition.py,sha256=ioxT5KQQmgSY5yPXDV1CEAj6J_62D6YVU5NUk_Fude0,6442
|
28
|
+
batFramework/triggerZone.py,sha256=ikOOlJT1KIND0MO2xiilCHuKlb1eQhkCMEhZTi1btsI,586
|
29
|
+
batFramework/utils.py,sha256=esMCG8Yh1MT1V0QsBAPaulCr3pthvxDi2-S_dUJs-3k,1699
|
30
|
+
batFramework/gui/__init__.py,sha256=17ij7mrCBCoehqCq1PV6MSXPOfMoLPmrV_G8d6ax4Tk,687
|
31
|
+
batFramework/gui/button.py,sha256=Ozs6VKHf9FCQXQODDiLQywGN3hwfXtQ6s2I-rzdjnQg,429
|
32
|
+
batFramework/gui/clickableWidget.py,sha256=t7U2m2TSS0cjTjca86xFn0v7C0PtfBV9m8cpecFnRnI,6976
|
33
|
+
batFramework/gui/container.py,sha256=wXjuhwCJc71KKSgY2cYgoRscAKB_hIw5N4njJk3Z9lk,5925
|
34
|
+
batFramework/gui/debugger.py,sha256=XogxF3J31GO-DZZn6YBrgwpYA5WjadzEfHkQHeMLU7o,3925
|
35
|
+
batFramework/gui/dialogueBox.py,sha256=3Z76l9obrpQImI8hjoBS_8G9sY3UILj2d3nJsaxtaI4,3221
|
36
|
+
batFramework/gui/draggableWidget.py,sha256=SKG7oMInZ_GTnrbv2T0aqlppuiuLX1tkVSCQJtRMlk8,1392
|
37
|
+
batFramework/gui/image.py,sha256=3J1v_YGDPUE_5CwD0ca9PXhHYOdItxUbXakovDjKms4,1750
|
38
|
+
batFramework/gui/indicator.py,sha256=leCvxsGxt00-oTn0N5MTmLstLH9uLG3RjQ02KlXtZCQ,1549
|
39
|
+
batFramework/gui/interactiveWidget.py,sha256=gcJnMhd4o74oEwZ6AVfxFwLUdNoCaK24ZPFriwh-ld0,5303
|
40
|
+
batFramework/gui/label.py,sha256=O48qjfeihyBiGKuHqwQ88ur0YZArXKS4YZHre70o0gg,10636
|
41
|
+
batFramework/gui/layout.py,sha256=sslcKULrWKZzaJw_fyb3f9A3PTT3Bm85C8-RbMHeDzo,8377
|
42
|
+
batFramework/gui/meter.py,sha256=-5FwPpwWJm3nn8_SoWJNrOqIZ2wiHHTWmpkJyNNaCCY,2282
|
43
|
+
batFramework/gui/radioButton.py,sha256=MAlu1_EiPzbvm6TyQ-IITWR6Mv38W2qEOaOKu1MArNQ,2406
|
44
|
+
batFramework/gui/root.py,sha256=7yfO4u-21bEL3jiK1ITuTGk8RMFZLZ0vjau0mBuxFfQ,4811
|
45
|
+
batFramework/gui/shape.py,sha256=t-DOLYO2V2f85QS0aI6fUZEZKPe1W8J8nvzNoo6Lk-Y,9657
|
46
|
+
batFramework/gui/slider.py,sha256=6n4tr3XpF2fGMpxcts16nXq0bxFrBXbjUyKokyrruJw,8587
|
47
|
+
batFramework/gui/style.py,sha256=OeLbft0RkIslQ2IcZpBeF6TaQDONIoBcAHj_Bkh9gFw,131
|
48
|
+
batFramework/gui/styleManager.py,sha256=rALKJ-AmRbDAiyu8hVAYRAlkQxw677DiPoNKJZ4xtJ4,1245
|
49
|
+
batFramework/gui/textInput.py,sha256=Vy-wxED1rk1h_VavCd6lCOpm5aYgFUDfnkv-i4AsHV4,4633
|
50
|
+
batFramework/gui/toggle.py,sha256=l-N5koIPp2HYQ0WEGzI2SdZrISe84KhD8MCQIJkZJNA,4410
|
51
|
+
batFramework/gui/widget.py,sha256=8zLLoLyyXzb99So-gnl8ovh9ZxVOYgIuAlFvn0JMllE,12608
|
52
|
+
batFramework/gui/constraints/__init__.py,sha256=qqXE8nnSrEvCSeHdqY8UYPZLetqdubFPI7IdZuh35QE,26
|
53
|
+
batFramework/gui/constraints/constraints.py,sha256=IUcq0jY5--pt9S-GgmXE-79yoPnww3UGjS19iC-8A2U,20004
|
54
|
+
batframework-1.0.8a3.dist-info/LICENCE,sha256=A65iXbMDbOxQLDNOODJLqA7o5RxszYlEqIgNSzBQRf4,1073
|
55
|
+
batframework-1.0.8a3.dist-info/METADATA,sha256=dFBMbRPDXT-skce0UxDZd-Y2jh-SOsMzzaZorp2Mgbw,2501
|
56
|
+
batframework-1.0.8a3.dist-info/WHEEL,sha256=Z4pYXqR_rTB7OWNDYFOm1qRk0RX6GFP2o8LgvP453Hk,91
|
57
|
+
batframework-1.0.8a3.dist-info/top_level.txt,sha256=vxAKBIk1oparFTxeXGBrgfIO7iq_YR5Fv1JvPVAIwmA,13
|
58
|
+
batframework-1.0.8a3.dist-info/RECORD,,
|
batFramework/debugger.py
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
import batFramework as bf
|
2
|
-
import pygame
|
3
|
-
|
4
|
-
|
5
|
-
class Debugger(bf.Label):
|
6
|
-
def __init__(self, manager) -> None:
|
7
|
-
super().__init__()
|
8
|
-
self.manager: bf.Manager = manager
|
9
|
-
self.refresh_rate = 0
|
10
|
-
self._refresh_counter = 0
|
11
|
-
self.dynamic_data = {}
|
12
|
-
self.static_data = {}
|
13
|
-
self.render_order = 99
|
14
|
-
self.set_outline_color((20, 20, 20))
|
15
|
-
# self.set_background_color((0,0,0,0))
|
16
|
-
self.set_text_color("white")
|
17
|
-
# self.set_padding((30,30))
|
18
|
-
self.set_refresh_rate(20)
|
19
|
-
self.add_dynamic_data("FPS", lambda: str(round(self.manager.get_fps())))
|
20
|
-
self.add_dynamic_data("BLITS", lambda: str(self.parent_scene.blit_calls))
|
21
|
-
self.set_visible(False)
|
22
|
-
|
23
|
-
def set_refresh_rate(self, val: int):
|
24
|
-
self.refresh_rate = val
|
25
|
-
|
26
|
-
def update(self, dt: float):
|
27
|
-
visible = self.manager._debugging == 1
|
28
|
-
self.set_visible(visible)
|
29
|
-
if not visible:
|
30
|
-
return
|
31
|
-
self._refresh_counter -= dt * 60
|
32
|
-
if self._refresh_counter < 0:
|
33
|
-
self._refresh_counter = self.refresh_rate
|
34
|
-
self._refresh_debug_info()
|
35
|
-
|
36
|
-
def add_dynamic_data(self, key, func):
|
37
|
-
self.dynamic_data[key] = func
|
38
|
-
|
39
|
-
def set_static_data(self, key, value):
|
40
|
-
self.static_data[key] = value
|
41
|
-
|
42
|
-
def _refresh_debug_info(self):
|
43
|
-
lines = []
|
44
|
-
lines.extend([f"{key}:{value}" for key, value in self.static_data.items()])
|
45
|
-
lines.extend([f"{key}:{func()}" for key, func in self.dynamic_data.items()])
|
46
|
-
debug_text = "\n".join(lines)
|
47
|
-
self.set_text(debug_text)
|
48
|
-
self.update_surface() # Update the surface after modifying the text
|
batFramework/easing.py
DELETED
@@ -1,71 +0,0 @@
|
|
1
|
-
from enum import Enum
|
2
|
-
import pygame
|
3
|
-
import batFramework as bf
|
4
|
-
|
5
|
-
class Easing(Enum):
|
6
|
-
EASE_IN = (0.12, 0, 0.39, 0)
|
7
|
-
EASE_OUT = (0.61, 1, 0.88, 1)
|
8
|
-
EASE_IN_OUT = (0.37, 0, 0.63, 1)
|
9
|
-
EASE_IN_OUT_ELASTIC = (.7,-0.5,.3,1.5)
|
10
|
-
LINEAR = (1, 1, 0, 0)
|
11
|
-
# Add more easing functions as needed
|
12
|
-
|
13
|
-
def __init__(self, *control_points):
|
14
|
-
self.control_points = control_points
|
15
|
-
|
16
|
-
class EasingAnimation(bf.Timer):
|
17
|
-
_cache = {}
|
18
|
-
def __init__(
|
19
|
-
self,
|
20
|
-
name:str=None,
|
21
|
-
easing_function:Easing=Easing.LINEAR,
|
22
|
-
duration:int=100,
|
23
|
-
update_callback=None,
|
24
|
-
end_callback=None,
|
25
|
-
loop:bool=False,
|
26
|
-
reusable:bool=False
|
27
|
-
):
|
28
|
-
self.easing_function = easing_function
|
29
|
-
self.update_callback = update_callback
|
30
|
-
self.value = 0.0
|
31
|
-
super().__init__(name,duration,loop,end_callback,reusable)
|
32
|
-
|
33
|
-
def get_value(self):
|
34
|
-
return self.value
|
35
|
-
|
36
|
-
def start(self):
|
37
|
-
self.value = 0
|
38
|
-
super().start() # self.elapsed_progress set to 0 here
|
39
|
-
|
40
|
-
def update(self)->bool:
|
41
|
-
if super().update():
|
42
|
-
return True# If timer ended now, end() is called. So don't process value.
|
43
|
-
self._process_value()
|
44
|
-
# if self.name == 0: print("UPDATING (callback) in easing")
|
45
|
-
if self.update_callback: self.update_callback(self.value)
|
46
|
-
return False
|
47
|
-
|
48
|
-
def end(self):
|
49
|
-
# Call update 1 last time with the last value
|
50
|
-
|
51
|
-
self.elapsed_progress = 1
|
52
|
-
self._process_value()
|
53
|
-
if self.update_callback: self.update_callback(self.value)
|
54
|
-
self.value = 0
|
55
|
-
super().end() # sets elapsed_progress to 0
|
56
|
-
|
57
|
-
def _process_value(self):
|
58
|
-
p0, p1, p2, p3 = self.easing_function.control_points
|
59
|
-
cache_key = (self.elapsed_progress, p0, p1, p2, p3)
|
60
|
-
if cache_key in EasingAnimation._cache:
|
61
|
-
y = EasingAnimation._cache[cache_key]
|
62
|
-
else:
|
63
|
-
t = self.elapsed_progress
|
64
|
-
t_inv = 1.0 - t
|
65
|
-
t2 = t * t
|
66
|
-
t3 = t * t2
|
67
|
-
t_inv2 = t_inv * t_inv
|
68
|
-
|
69
|
-
y = 3 * t_inv2 * t * p1 + 3 * t_inv * t2 * p3 + t3
|
70
|
-
EasingAnimation._cache[cache_key] = y
|
71
|
-
self.value = y
|
batFramework/gui/constraints.py
DELETED
@@ -1,204 +0,0 @@
|
|
1
|
-
from .widget import Widget
|
2
|
-
import batFramework as bf
|
3
|
-
|
4
|
-
|
5
|
-
class Constraint:
|
6
|
-
def __init__(self,name="Constraint", priority=0):
|
7
|
-
self.priority = priority
|
8
|
-
self.name = name
|
9
|
-
def set_priority(self, priority)->"Constraint":
|
10
|
-
self.priority = priority
|
11
|
-
return self
|
12
|
-
def to_string(self)->str:
|
13
|
-
return f"{self.name.upper()}"
|
14
|
-
|
15
|
-
def evaluate(self, parent_widget:Widget, child_widget:Widget) -> bool:
|
16
|
-
raise NotImplementedError("Subclasses must implement evaluate method")
|
17
|
-
|
18
|
-
def apply(self, parent_widget:Widget, child_widget:Widget=None) -> bool:
|
19
|
-
if not self.evaluate(parent_widget, child_widget):
|
20
|
-
self.apply_constraint(parent_widget, child_widget)
|
21
|
-
return False
|
22
|
-
return True
|
23
|
-
|
24
|
-
def apply_constraint(self, parent_widget:Widget, child_widget:Widget):
|
25
|
-
raise NotImplementedError("Subclasses must implement apply_constraint method")
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
class ConstraintMinWidth(Constraint):
|
43
|
-
def __init__(self, width):
|
44
|
-
super().__init__(name="min_width")
|
45
|
-
self.min_width = width
|
46
|
-
|
47
|
-
def evaluate(self, parent_widget, child_widget):
|
48
|
-
return child_widget.rect.width >= self.min_width
|
49
|
-
|
50
|
-
def apply_constraint(self, parent_widget, child_widget):
|
51
|
-
if not self.evaluate(parent_widget, child_widget):
|
52
|
-
child_widget.set_size(self.min_width,child_widget.rect.h)
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
class ConstraintCenterX(Constraint):
|
58
|
-
def __init__(self):
|
59
|
-
super().__init__(name="centerx")
|
60
|
-
|
61
|
-
def evaluate(self, parent_widget, child_widget):
|
62
|
-
return child_widget.rect.centerx == parent_widget.get_content_center()[0]
|
63
|
-
|
64
|
-
def apply_constraint(self,parent_widget,child_widget):
|
65
|
-
if not self.evaluate(parent_widget,child_widget):
|
66
|
-
child_widget.set_center(parent_widget.get_content_center()[0],child_widget.rect.centery)
|
67
|
-
|
68
|
-
class ConstraintCenterY(Constraint):
|
69
|
-
def __init__(self):
|
70
|
-
super().__init__(name="centery")
|
71
|
-
|
72
|
-
def evaluate(self, parent_widget, child_widget):
|
73
|
-
return child_widget.rect.centery == parent_widget.get_content_center()[1]
|
74
|
-
|
75
|
-
def apply_constraint(self,parent_widget,child_widget):
|
76
|
-
if not self.evaluate(parent_widget,child_widget):
|
77
|
-
child_widget.set_center(child_widget.rect.centerx,parent_widget.get_content_center()[1])
|
78
|
-
|
79
|
-
class ConstraintCenter(Constraint):
|
80
|
-
def __init__(self):
|
81
|
-
super().__init__(name="center")
|
82
|
-
|
83
|
-
def evaluate(self, parent_widget, child_widget):
|
84
|
-
return child_widget.rect.center == parent_widget.get_content_center()
|
85
|
-
|
86
|
-
def apply_constraint(self,parent_widget,child_widget):
|
87
|
-
if not self.evaluate(parent_widget,child_widget):
|
88
|
-
child_widget.set_center(*parent_widget.get_content_center())
|
89
|
-
|
90
|
-
class ConstraintPercentageWidth(Constraint):
|
91
|
-
def __init__(self,percentage:float,keep_autoresize:bool=True):
|
92
|
-
super().__init__(name="percentage_width")
|
93
|
-
self.percentage:float = percentage
|
94
|
-
self.keep_autoresize: bool = keep_autoresize
|
95
|
-
def to_string(self)->str:
|
96
|
-
return f"{super().to_string()}.[{self.percentage},{self.keep_autoresize}]"
|
97
|
-
def evaluate(self, parent_widget, child_widget):
|
98
|
-
return child_widget.rect.width == round(parent_widget.get_content_width() * self.percentage)
|
99
|
-
|
100
|
-
def apply_constraint(self,parent_widget,child_widget):
|
101
|
-
if not self.evaluate(parent_widget,child_widget):
|
102
|
-
if child_widget.autoresize:
|
103
|
-
if self.keep_autoresize:
|
104
|
-
print(f"Warning: Constraint on {child_widget.to_string()} can't resize, autoresize set to True")
|
105
|
-
return
|
106
|
-
child_widget.set_autoresize(False)
|
107
|
-
child_widget.set_size(round(parent_widget.get_content_width() * self.percentage) ,child_widget.rect.h)
|
108
|
-
|
109
|
-
|
110
|
-
class ConstraintPercentageHeight(Constraint):
|
111
|
-
def __init__(self,percentage:float,keep_autoresize:bool=True):
|
112
|
-
super().__init__(name="percentage_height")
|
113
|
-
self.percentage:float = percentage
|
114
|
-
self.keep_autoresize: bool = keep_autoresize
|
115
|
-
|
116
|
-
def evaluate(self, parent_widget, child_widget):
|
117
|
-
return child_widget.rect.height == round(parent_widget.get_content_height() * self.percentage)
|
118
|
-
|
119
|
-
def apply_constraint(self,parent_widget,child_widget):
|
120
|
-
if not self.evaluate(parent_widget,child_widget):
|
121
|
-
if child_widget.autoresize:
|
122
|
-
if self.keep_autoresize:
|
123
|
-
print(f"Warning: Constraint on {child_widget.to_string()} can't resize, autoresize set to True")
|
124
|
-
return
|
125
|
-
child_widget.set_autoresize(False)
|
126
|
-
child_widget.set_size(child_widget.rect.w,round(parent_widget.get_content_height() * self.percentage))
|
127
|
-
|
128
|
-
class ConstraintHeight(Constraint):
|
129
|
-
def __init__(self,height:float):
|
130
|
-
if height < 0 :
|
131
|
-
raise ValueError("height can't be negative")
|
132
|
-
super().__init__(name="height")
|
133
|
-
self.height = height
|
134
|
-
|
135
|
-
def to_string(self)->str:
|
136
|
-
return f"{super().to_string()}.({self.height})"
|
137
|
-
|
138
|
-
def evaluate(self, parent_widget, child_widget):
|
139
|
-
return child_widget.rect.height == self.height
|
140
|
-
|
141
|
-
def apply_constraint(self,parent_widget,child_widget):
|
142
|
-
if not self.evaluate(parent_widget,child_widget):
|
143
|
-
child_widget.set_size(child_widget.rect.w,self.height)
|
144
|
-
|
145
|
-
class ConstraintWidth(Constraint):
|
146
|
-
def __init__(self,width:float):
|
147
|
-
if width < 0 :
|
148
|
-
raise ValueError("width can't be negative")
|
149
|
-
super().__init__(name="width")
|
150
|
-
self.width = width
|
151
|
-
|
152
|
-
def to_string(self)->str:
|
153
|
-
return f"{super().to_string()}.({self.width})"
|
154
|
-
|
155
|
-
def evaluate(self, parent_widget, child_widget):
|
156
|
-
return child_widget.rect.width == self.width
|
157
|
-
|
158
|
-
def apply_constraint(self,parent_widget,child_widget):
|
159
|
-
if not self.evaluate(parent_widget,child_widget):
|
160
|
-
child_widget.set_size(self.width,child_widget.rect.h)
|
161
|
-
|
162
|
-
|
163
|
-
class ConstraintAspectRatio(Constraint):
|
164
|
-
def __init__(self,ratio:int|float=1):
|
165
|
-
super().__init__(name="aspect_ratio")
|
166
|
-
if isinstance(ratio, float|int):
|
167
|
-
self.ratio = ratio
|
168
|
-
elif isinstance(ratio,Widget):
|
169
|
-
self.ratio = ratio.rect.w / ratio.rect.h
|
170
|
-
else:
|
171
|
-
raise TypeError(f"Ratio must be float or Widget")
|
172
|
-
def evaluate(self, parent_widget,child_widget):
|
173
|
-
return self.ratio == child_widget.rect.w / child_widget.rect.h
|
174
|
-
|
175
|
-
def apply_constraint(self,parent_widget,child_widget):
|
176
|
-
if not self.evaluate(parent_widget,child_widget):
|
177
|
-
return # TODO
|
178
|
-
|
179
|
-
class ConstraintAnchorBottom(Constraint):
|
180
|
-
def __init__(self):
|
181
|
-
super().__init__(name="anchor_bottom")
|
182
|
-
|
183
|
-
def evaluate(self, parent_widget,child_widget):
|
184
|
-
return child_widget.rect.bottom == parent_widget.rect.bottom
|
185
|
-
|
186
|
-
def apply_constraint(self,parent_widget,child_widget):
|
187
|
-
if not self.evaluate(parent_widget,child_widget):
|
188
|
-
child_widget.set_y(parent_widget.get_content_bottom() - child_widget.rect.h)
|
189
|
-
|
190
|
-
|
191
|
-
class ConstraintAnchorTopRight(Constraint):
|
192
|
-
def __init__(self):
|
193
|
-
super().__init__(name="anchor_topright")
|
194
|
-
|
195
|
-
def evaluate(self, parent_widget,child_widget):
|
196
|
-
return child_widget.rect.topright == parent_widget.rect.topright
|
197
|
-
|
198
|
-
def apply_constraint(self,parent_widget,child_widget):
|
199
|
-
if not self.evaluate(parent_widget,child_widget):
|
200
|
-
child_widget.set_position(parent_widget.get_content_right()-child_widget.rect.w, parent_widget.get_content_top())
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|