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.
Files changed (65) hide show
  1. batFramework/__init__.py +53 -50
  2. batFramework/action.py +126 -99
  3. batFramework/actionContainer.py +53 -9
  4. batFramework/animatedSprite.py +115 -65
  5. batFramework/audioManager.py +69 -26
  6. batFramework/camera.py +259 -69
  7. batFramework/constants.py +16 -54
  8. batFramework/cutscene.py +36 -29
  9. batFramework/cutsceneBlocks.py +37 -42
  10. batFramework/dynamicEntity.py +9 -7
  11. batFramework/easingController.py +58 -0
  12. batFramework/entity.py +48 -97
  13. batFramework/enums.py +113 -0
  14. batFramework/fontManager.py +65 -0
  15. batFramework/gui/__init__.py +10 -2
  16. batFramework/gui/button.py +9 -78
  17. batFramework/gui/clickableWidget.py +219 -0
  18. batFramework/gui/constraints/__init__.py +1 -0
  19. batFramework/gui/constraints/constraints.py +590 -0
  20. batFramework/gui/container.py +174 -32
  21. batFramework/gui/debugger.py +131 -43
  22. batFramework/gui/dialogueBox.py +99 -0
  23. batFramework/gui/draggableWidget.py +40 -0
  24. batFramework/gui/image.py +54 -18
  25. batFramework/gui/indicator.py +38 -21
  26. batFramework/gui/interactiveWidget.py +177 -13
  27. batFramework/gui/label.py +288 -74
  28. batFramework/gui/layout.py +219 -60
  29. batFramework/gui/meter.py +71 -0
  30. batFramework/gui/radioButton.py +84 -0
  31. batFramework/gui/root.py +128 -38
  32. batFramework/gui/shape.py +253 -57
  33. batFramework/gui/slider.py +246 -0
  34. batFramework/gui/style.py +10 -0
  35. batFramework/gui/styleManager.py +48 -0
  36. batFramework/gui/textInput.py +137 -0
  37. batFramework/gui/toggle.py +115 -51
  38. batFramework/gui/widget.py +329 -254
  39. batFramework/manager.py +40 -19
  40. batFramework/object.py +114 -0
  41. batFramework/particle.py +101 -0
  42. batFramework/renderGroup.py +67 -0
  43. batFramework/resourceManager.py +84 -0
  44. batFramework/scene.py +242 -114
  45. batFramework/sceneManager.py +145 -107
  46. batFramework/scrollingSprite.py +115 -0
  47. batFramework/sprite.py +51 -0
  48. batFramework/stateMachine.py +2 -2
  49. batFramework/tileset.py +46 -0
  50. batFramework/time.py +117 -57
  51. batFramework/transition.py +184 -126
  52. batFramework/utils.py +31 -156
  53. batframework-1.0.8a3.dist-info/LICENCE +21 -0
  54. batframework-1.0.8a3.dist-info/METADATA +55 -0
  55. batframework-1.0.8a3.dist-info/RECORD +58 -0
  56. batFramework/debugger.py +0 -48
  57. batFramework/easing.py +0 -71
  58. batFramework/gui/constraints.py +0 -204
  59. batFramework/gui/frame.py +0 -19
  60. batFramework/particles.py +0 -77
  61. batFramework/transitionManager.py +0 -0
  62. batframework-1.0.8a2.dist-info/METADATA +0 -58
  63. batframework-1.0.8a2.dist-info/RECORD +0 -42
  64. {batframework-1.0.8a2.dist-info → batframework-1.0.8a3.dist-info}/WHEEL +0 -0
  65. {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 load_json_from_file(path: str) -> dict:
48
- try:
49
- with open(Utils.get_path(path), "r") as file:
50
- data = json.load(file)
51
- return data
52
- except FileNotFoundError:
53
- print(f"File '{path}' not found")
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
- @staticmethod
57
- def save_json_to_file(path: str, data) -> bool:
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
- for size in range(MIN_FONT_SIZE, MAX_FONT_SIZE, 2):
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 get_tileset(name: str) -> Tileset:
172
- if name not in Utils.tilesets:
173
- return None
174
- return Utils.tilesets[name]
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
- def move_points(delta, *points):
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
@@ -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
-