batframework 1.0.7__py3-none-any.whl → 1.0.8a2__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 +47 -41
- batFramework/action.py +20 -42
- batFramework/actionContainer.py +4 -43
- batFramework/animatedSprite.py +65 -98
- batFramework/audioManager.py +25 -39
- batFramework/camera.py +56 -226
- batFramework/constants.py +48 -32
- batFramework/cutscene.py +24 -32
- batFramework/cutsceneBlocks.py +33 -30
- batFramework/debugger.py +48 -0
- batFramework/dynamicEntity.py +7 -8
- batFramework/easing.py +23 -28
- batFramework/entity.py +52 -89
- batFramework/gui/__init__.py +1 -3
- batFramework/gui/button.py +58 -124
- batFramework/gui/constraints.py +90 -163
- batFramework/gui/container.py +18 -29
- batFramework/gui/debugger.py +42 -106
- batFramework/gui/frame.py +9 -15
- batFramework/gui/image.py +17 -36
- batFramework/gui/indicator.py +14 -20
- batFramework/gui/interactiveWidget.py +12 -63
- batFramework/gui/label.py +50 -113
- batFramework/gui/layout.py +51 -66
- batFramework/gui/root.py +29 -70
- batFramework/gui/shape.py +41 -34
- batFramework/gui/toggle.py +29 -37
- batFramework/gui/widget.py +131 -174
- batFramework/manager.py +14 -21
- batFramework/particles.py +20 -41
- batFramework/scene.py +72 -173
- batFramework/sceneManager.py +80 -40
- batFramework/stateMachine.py +0 -1
- batFramework/time.py +51 -62
- batFramework/transition.py +154 -0
- batFramework/utils.py +150 -3
- batframework-1.0.8a2.dist-info/METADATA +58 -0
- batframework-1.0.8a2.dist-info/RECORD +42 -0
- {batframework-1.0.7.dist-info → batframework-1.0.8a2.dist-info}/WHEEL +1 -1
- batFramework/enums.py +0 -14
- batFramework/fontManager.py +0 -57
- batFramework/gui/dialogueBox.py +0 -70
- batFramework/gui/slider.py +0 -5
- batFramework/gui/textInput.py +0 -88
- batFramework/resourceManager.py +0 -72
- batFramework/sprite.py +0 -33
- batFramework/tileset.py +0 -64
- batframework-1.0.7.dist-info/LICENCE +0 -21
- batframework-1.0.7.dist-info/METADATA +0 -55
- batframework-1.0.7.dist-info/RECORD +0 -50
- {batframework-1.0.7.dist-info → batframework-1.0.8a2.dist-info}/top_level.txt +0 -0
batFramework/time.py
CHANGED
@@ -1,85 +1,74 @@
|
|
1
1
|
import pygame
|
2
2
|
import batFramework as bf
|
3
|
-
from typing import Self
|
4
3
|
|
5
4
|
class Timer:
|
6
|
-
|
7
|
-
def __init__(self,duration
|
8
|
-
|
9
|
-
|
5
|
+
_highest_count = 0
|
6
|
+
def __init__(self, name=None, duration=1000, loop=False, end_callback=None,reusable:bool=False):
|
7
|
+
# Initialize timer properties
|
8
|
+
self.start_time = None
|
9
|
+
self.stopped = True
|
10
|
+
self.name = name if name is not None else self._highest_count
|
11
|
+
Timer._highest_count += 1
|
12
|
+
self.duration = duration
|
13
|
+
self.loop = loop
|
14
|
+
self.elapsed_progress = 0.0
|
10
15
|
self.end_callback = end_callback
|
11
|
-
self.
|
12
|
-
|
13
|
-
|
14
|
-
self.
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
self.
|
20
|
-
self.over = False
|
21
|
-
self.paused = False
|
22
|
-
return self
|
23
|
-
|
24
|
-
def start(self)->Self:
|
25
|
-
if self.elapsed_time >= 0 : return self
|
26
|
-
self.elapsed_time = 0
|
27
|
-
self.paused = False
|
28
|
-
self.over = False
|
29
|
-
bf.TimeManager().add_timer(self)
|
30
|
-
return self
|
16
|
+
self.reusable:bool = reusable
|
17
|
+
def start(self):
|
18
|
+
# Start the timer and set the start time
|
19
|
+
if self.start_time is None:
|
20
|
+
Time().add_timer(self)
|
21
|
+
|
22
|
+
self.start_time = pygame.time.get_ticks()
|
23
|
+
self.stopped = False
|
24
|
+
self.elapsed_progress = 0.0
|
31
25
|
|
32
|
-
def
|
33
|
-
self.
|
34
|
-
|
26
|
+
def update(self):
|
27
|
+
if self.stopped : return False
|
28
|
+
current_time = pygame.time.get_ticks()
|
29
|
+
if self.elapsed_progress < 1:
|
30
|
+
# Calculate elapsed progress
|
31
|
+
self.elapsed_progress = (current_time - self.start_time) / self.duration
|
32
|
+
if self.elapsed_progress >= 1:
|
33
|
+
# Timer has completed
|
34
|
+
self.end()
|
35
|
+
return True
|
36
|
+
elif self.loop:
|
37
|
+
# If looping, restart the timer
|
38
|
+
self.start()
|
39
|
+
return False
|
40
|
+
|
41
|
+
def stop(self):
|
42
|
+
# Stop the timer
|
43
|
+
self.stopped = True
|
35
44
|
|
36
|
-
def resume(self)->Self:
|
37
|
-
self.paused = False
|
38
|
-
return self
|
39
|
-
def delete(self)->Self:
|
40
|
-
self.do_delete = True
|
41
|
-
return self
|
42
|
-
def get_progression(self)->float:
|
43
|
-
if self.elapsed_time < 0 : return 0
|
44
|
-
if self.elapsed_time >= self.duration: return 1
|
45
|
-
return self.elapsed_time / self.duration
|
46
|
-
|
47
|
-
def update(self,dt)->None:
|
48
|
-
if self.elapsed_time < 0 or self.paused: return
|
49
|
-
self.elapsed_time += dt
|
50
|
-
# print("update :",self.elapsed_time,self.duration)
|
51
|
-
if self.get_progression() == 1:
|
52
|
-
self.end()
|
53
|
-
|
54
45
|
def end(self):
|
55
|
-
self.
|
56
|
-
|
57
|
-
|
58
|
-
self.
|
59
|
-
return
|
60
|
-
|
61
|
-
self.over = True
|
46
|
+
self.elapsed_progress = 1
|
47
|
+
self.stopped = False
|
48
|
+
if self.end_callback:
|
49
|
+
self.end_callback()
|
62
50
|
|
63
|
-
def
|
64
|
-
|
51
|
+
def ended(self):
|
52
|
+
if self.start_time is None:
|
53
|
+
return False
|
54
|
+
return (not self.loop) and (self.elapsed_progress >= 1) and (not self.stopped) and not self.reusable
|
65
55
|
|
66
56
|
|
67
|
-
class
|
57
|
+
class Time(metaclass=bf.Singleton):
|
68
58
|
def __init__(self):
|
69
|
-
# Initialize the
|
59
|
+
# Initialize the Time class with a dictionary of timers
|
70
60
|
self.timers = {}
|
71
61
|
|
72
62
|
def add_timer(self, timer):
|
73
63
|
# Add a timer to the dictionary
|
74
64
|
self.timers[timer.name] = timer
|
75
65
|
|
76
|
-
def update(self
|
66
|
+
def update(self):
|
77
67
|
# Update all timers and remove completed ones
|
78
|
-
|
79
|
-
|
80
|
-
timer.update(dt)
|
68
|
+
for timer in list(self.timers.values()):
|
69
|
+
timer.update()
|
81
70
|
|
82
|
-
to_remove = [name for name, timer in self.timers.items() if timer.
|
71
|
+
to_remove = [name for name, timer in self.timers.items() if timer.ended()]
|
83
72
|
|
84
73
|
for name in to_remove:
|
85
74
|
# print(self.timers.pop(name).name,"removed !")
|
batFramework/transition.py
CHANGED
@@ -1,3 +1,157 @@
|
|
1
1
|
import pygame
|
2
2
|
import batFramework as bf
|
3
3
|
|
4
|
+
|
5
|
+
class BaseTransition:
|
6
|
+
def __init__(
|
7
|
+
self,
|
8
|
+
source_surf: pygame.Surface,
|
9
|
+
dest_surf: pygame.Surface,
|
10
|
+
duration=100,
|
11
|
+
**kwargs,
|
12
|
+
) -> None:
|
13
|
+
self.source = source_surf
|
14
|
+
self.dest = dest_surf
|
15
|
+
self.ended = False
|
16
|
+
self.source_scene_name = ""
|
17
|
+
self.dest_scene_name = ""
|
18
|
+
self.duration = duration
|
19
|
+
self.index = 0
|
20
|
+
|
21
|
+
def set_scene_index(self,index):
|
22
|
+
self.index = index
|
23
|
+
|
24
|
+
def set_source_name(self, name):
|
25
|
+
self.source_scene_name = name
|
26
|
+
|
27
|
+
def set_dest_name(self, name):
|
28
|
+
self.dest_scene_name = name
|
29
|
+
|
30
|
+
def update(self, dt):
|
31
|
+
pass
|
32
|
+
|
33
|
+
def draw(self, surface):
|
34
|
+
pass
|
35
|
+
|
36
|
+
def has_ended(self):
|
37
|
+
return False
|
38
|
+
|
39
|
+
def set_ended(self, val):
|
40
|
+
self.ended = val
|
41
|
+
|
42
|
+
|
43
|
+
class FadeColorTransition(BaseTransition):
|
44
|
+
def __init__(
|
45
|
+
self,
|
46
|
+
source_surf,
|
47
|
+
dest_surf,
|
48
|
+
duration=600,
|
49
|
+
color_duration=200,
|
50
|
+
color=bf.color.CLOUD_WHITE,
|
51
|
+
**kwargs,
|
52
|
+
) -> None:
|
53
|
+
super().__init__(source_surf, dest_surf, duration)
|
54
|
+
self.target_time = duration * 2 + color_duration
|
55
|
+
self.color_surf = pygame.Surface((source_surf.get_rect().size)).convert_alpha()
|
56
|
+
self.color_surf.fill(color)
|
57
|
+
self.ease_out = bf.EasingAnimation(
|
58
|
+
easing_function=bf.Easing.EASE_IN,
|
59
|
+
duration=(duration-color_duration)//2,
|
60
|
+
update_callback = lambda x: self.color_surf.set_alpha(int(255 - (255 * x))),
|
61
|
+
end_callback=lambda: self.set_ended(True))
|
62
|
+
|
63
|
+
self.color_timer = bf.Timer(
|
64
|
+
duration=color_duration,
|
65
|
+
end_callback=lambda: self.set_state("out"))
|
66
|
+
self.ease_in = bf.EasingAnimation(
|
67
|
+
easing_function=bf.Easing.EASE_IN,
|
68
|
+
duration=(duration-color_duration)//2,
|
69
|
+
update_callback=lambda x: self.color_surf.set_alpha(int(255 * x)),
|
70
|
+
# update_callback=lambda x: print(x),
|
71
|
+
end_callback=lambda: self.set_state("color"))
|
72
|
+
self.state = None
|
73
|
+
|
74
|
+
self.state = "in"
|
75
|
+
self.ease_in.start()
|
76
|
+
|
77
|
+
def set_state(self, state: str):
|
78
|
+
self.state = state
|
79
|
+
if state == "in":
|
80
|
+
self.ease_in.start()
|
81
|
+
elif state == "color":
|
82
|
+
self.color_timer.start()
|
83
|
+
elif state == "out":
|
84
|
+
self.ease_out.start()
|
85
|
+
|
86
|
+
def has_ended(self):
|
87
|
+
return self.ended
|
88
|
+
|
89
|
+
def set_ended(self, val):
|
90
|
+
super().set_ended(val)
|
91
|
+
|
92
|
+
def draw(self, surface):
|
93
|
+
if self.state != "color":
|
94
|
+
surface.blit(self.source if self.state == "in" else self.dest, (0, 0))
|
95
|
+
surface.blit(self.color_surf, (0, 0))
|
96
|
+
|
97
|
+
|
98
|
+
class FadeTransition(BaseTransition):
|
99
|
+
def __init__(self, source_surf, dest_surf, duration=500) -> None:
|
100
|
+
super().__init__(source_surf, dest_surf)
|
101
|
+
self.anim = bf.EasingAnimation(None,bf.Easing.EASE_IN_OUT,duration,self.update_surface,lambda : self.set_ended(True))
|
102
|
+
self.anim.start()
|
103
|
+
|
104
|
+
def update_surface(self,progress):
|
105
|
+
self.source.set_alpha(int(255 - (255 * progress)))
|
106
|
+
self.dest.set_alpha(int(255 * progress))
|
107
|
+
|
108
|
+
def has_ended(self):
|
109
|
+
return self.ended
|
110
|
+
|
111
|
+
def draw(self, surface):
|
112
|
+
surface.blit(self.source, (0, 0))
|
113
|
+
surface.blit(self.dest, (0, 0))
|
114
|
+
|
115
|
+
|
116
|
+
class SlideTransition(BaseTransition):
|
117
|
+
def __init__(
|
118
|
+
self,
|
119
|
+
source_surf,
|
120
|
+
dest_surf,
|
121
|
+
duration=1000,
|
122
|
+
source_alignment: bf.Alignment = bf.Alignment.BOTTOM,
|
123
|
+
easing: bf.Easing = bf.Easing.EASE_IN_OUT,
|
124
|
+
**kwargs,
|
125
|
+
) -> None:
|
126
|
+
super().__init__(source_surf, dest_surf, duration)
|
127
|
+
self.offset = pygame.Vector2(0, 0)
|
128
|
+
if source_alignment in [bf.Alignment.TOP, bf.Alignment.BOTTOM]:
|
129
|
+
self.offset.y = bf.const.RESOLUTION[1]
|
130
|
+
if source_alignment == bf.Alignment.TOP:
|
131
|
+
self.offset.y *= -1
|
132
|
+
elif source_alignment in [bf.Alignment.LEFT, bf.Alignment.RIGHT]:
|
133
|
+
self.offset.x = bf.const.RESOLUTION[0]
|
134
|
+
if source_alignment == bf.Alignment.LEFT:
|
135
|
+
self.offset.x *= -1
|
136
|
+
else:
|
137
|
+
self.offset.x = -bf.const.RESOLUTION[0]
|
138
|
+
print(
|
139
|
+
f"Unsupported Alignment : {source_alignment.value}, set to default : {bf.Alignment.LEFT.value} "
|
140
|
+
)
|
141
|
+
self.anim = bf.EasingAnimation(
|
142
|
+
easing_function=easing,
|
143
|
+
duration=duration,
|
144
|
+
update_callback =lambda x: self.update_offset(self.offset.lerp((0, 0), x)),
|
145
|
+
end_callback =lambda: self.set_ended(True),
|
146
|
+
)
|
147
|
+
self.anim.start()
|
148
|
+
|
149
|
+
def update_offset(self, vec):
|
150
|
+
self.offset.update(vec)
|
151
|
+
|
152
|
+
def has_ended(self):
|
153
|
+
return self.ended
|
154
|
+
|
155
|
+
def draw(self, surface):
|
156
|
+
surface.blit(self.source, (0, 0))
|
157
|
+
surface.blit(self.dest, self.offset)
|
batFramework/utils.py
CHANGED
@@ -4,6 +4,9 @@ import os
|
|
4
4
|
import batFramework as bf
|
5
5
|
import json
|
6
6
|
|
7
|
+
MAX_FONT_SIZE = 100
|
8
|
+
MIN_FONT_SIZE = 8
|
9
|
+
|
7
10
|
class Singleton(type):
|
8
11
|
_instances = {}
|
9
12
|
|
@@ -13,11 +16,135 @@ class Singleton(type):
|
|
13
16
|
return cls._instances[cls]
|
14
17
|
|
15
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
|
+
|
16
37
|
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
|
+
|
46
|
+
@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")
|
54
|
+
return None
|
55
|
+
|
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
|
+
|
17
76
|
@staticmethod
|
18
|
-
def
|
19
|
-
|
20
|
-
if
|
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] = {}
|
91
|
+
|
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
|
+
|
95
|
+
|
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()
|
21
148
|
width, height = src.get_size()
|
22
149
|
res = []
|
23
150
|
for y in range(0, height, cell_height):
|
@@ -29,6 +156,26 @@ class Utils:
|
|
29
156
|
res.append(sub)
|
30
157
|
return res
|
31
158
|
|
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
|
+
@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
|
+
|
178
|
+
|
32
179
|
|
33
180
|
def move_points(delta, *points):
|
34
181
|
res = []
|
@@ -0,0 +1,58 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: batframework
|
3
|
+
Version: 1.0.8a2
|
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.10
|
11
|
+
Description-Content-Type: text/markdown
|
12
|
+
Requires-Dist: pygame-ce
|
13
|
+
|
14
|
+
# batFramework
|
15
|
+
|
16
|
+
batFramework is a Python game framework built using Pygame, designed to simplify game development by providing entities, scenes, a scene manager, and various utilities.
|
17
|
+
|
18
|
+
## Purpose and Overview
|
19
|
+
The primary objective of batFramework is to streamline game development by utilizing entities and scenes that hold entities. It employs a manager, which inherits from the scene manager, to handle scenes, propagate events, and manage updates and rendering.
|
20
|
+
|
21
|
+
## Installation and Setup
|
22
|
+
To install batFramework, you can use pip:
|
23
|
+
```pip install batFramework```
|
24
|
+
|
25
|
+
|
26
|
+
The only dependency required is pygame-ce.
|
27
|
+
|
28
|
+
## Usage Instructions
|
29
|
+
To create a basic app using batFramework, here's an example:
|
30
|
+
|
31
|
+
```python
|
32
|
+
import batFramework as bf
|
33
|
+
|
34
|
+
# Initialize the framework
|
35
|
+
bf.init((1280, 720), window_title="My Amazing Program")
|
36
|
+
|
37
|
+
# Create a manager and a scene
|
38
|
+
bf.Manager(bf.Scene("main")).run()
|
39
|
+
```
|
40
|
+
In practice, users can inherit bf.Scene to create their own scenes, adding specific behaviors, entities, etc.
|
41
|
+
|
42
|
+
## Features and Functionalities
|
43
|
+
|
44
|
+
- Scene management for organizing game components
|
45
|
+
- Cutscene support to facilitate storytelling sequences
|
46
|
+
- Audio management for music and sound effects with volume control
|
47
|
+
- Entity, sprite, and animated sprite support
|
48
|
+
- Utility modules such as time management and easingAnimation
|
49
|
+
|
50
|
+
Users can leverage these functionalities to build games efficiently using batFramework.
|
51
|
+
|
52
|
+
For more detailed usage and examples, please refer to the documentation or codebase.
|
53
|
+
|
54
|
+
|
55
|
+
# License
|
56
|
+
MIT License
|
57
|
+
|
58
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
batFramework/__init__.py,sha256=MLVXC2ymkO3k8LdCgB6TbahgJfhxk4GKAbmndmEgZS4,2146
|
2
|
+
batFramework/action.py,sha256=Phk6-q2P-XyV2GVlXPpxyje0due4fIrKnhI1_4anfjI,7600
|
3
|
+
batFramework/actionContainer.py,sha256=K9dIgG559ckxzRB3t-lpON4dFTcM2mcKZfsf4bhuJ1k,1092
|
4
|
+
batFramework/animatedSprite.py,sha256=kJPKrTOfkbQu2uYDziIEop1z6-gjBwZxkC1Rxd_vBwE,3992
|
5
|
+
batFramework/audioManager.py,sha256=5UsDPy4zsDO7Va1y1kM4lSpEJXU95o9F01E-Sts3osg,2546
|
6
|
+
batFramework/camera.py,sha256=wt4TyWTgQmQElBVeFI7ONzNI75r0FKtB3KmNH00GeFM,4322
|
7
|
+
batFramework/constants.py,sha256=FSyEYLxdAb3JaXA11sAwZBfAImedASohpFcd_7qnG0I,2075
|
8
|
+
batFramework/cutscene.py,sha256=5aiIQeWGmvHCb-N3vjmwxhE4dCXv3iZRFHiexSNxCXM,3650
|
9
|
+
batFramework/cutsceneBlocks.py,sha256=1gmof0jKJ8SqE-RoErm6n1A0JJ4Ang9Q30xEZnW9NaI,5123
|
10
|
+
batFramework/debugger.py,sha256=gh5kOUmGr4t-BFXA17tImid4nzxUqrhsUhE_JV9srNg,1671
|
11
|
+
batFramework/dynamicEntity.py,sha256=REIqH0jnfX6yUThoQNkQrsG0390TR6C5la1h2MAioYk,665
|
12
|
+
batFramework/easing.py,sha256=vGkk7FDPj27X7NCJXALCEyVKDbpXXebWYtMvxkbhOh0,2217
|
13
|
+
batFramework/entity.py,sha256=Tw4_PIA_sY8fhbj9TjE6wPcDTrZZX_Tj7l8oKquqe8U,3178
|
14
|
+
batFramework/manager.py,sha256=LdiQVyuPQE23jwO4EjR4zqDymxtRmthUJ7VE7RIEDpU,1583
|
15
|
+
batFramework/particles.py,sha256=PX8zSqOS1gyDloGAz3fAlrto51lWMUpBXDIM152EYWc,2172
|
16
|
+
batFramework/scene.py,sha256=KM1e53ZfPvuJoSGQZaEl_IouWRYCbFq0QOYTuXYCr-E,7324
|
17
|
+
batFramework/sceneManager.py,sha256=sFkQbfMuR19M4duvCf0SOxSY7MkMrkmiiKh72-tC1nI,5743
|
18
|
+
batFramework/stateMachine.py,sha256=_er9_dcm6MLmlTjXTVm175eqZ9puaKb31PFmNPRhcSU,1338
|
19
|
+
batFramework/time.py,sha256=iGV9mxUFrdXsvm4fJ1faX-VYNsOH7DX2N_aXsDRHhmM,2403
|
20
|
+
batFramework/transition.py,sha256=wmL1Mgg_xopzeDbEPJyAmllLB2BCRJZtuMOR7Mez480,4873
|
21
|
+
batFramework/transitionManager.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
22
|
+
batFramework/triggerZone.py,sha256=ikOOlJT1KIND0MO2xiilCHuKlb1eQhkCMEhZTi1btsI,586
|
23
|
+
batFramework/utils.py,sha256=EUB3bMldWTYFVZxcJk5_7XAWcEz080P7PT5ZtkO5TAQ,6164
|
24
|
+
batFramework/gui/__init__.py,sha256=azu5HpC8Q9kupythU5GN5blt7K9oH55oXlOeXsIw1Mw,391
|
25
|
+
batFramework/gui/button.py,sha256=05RMQ20P5npgU9QmiT8v6abJhnhjqRgYbpZGaQXr6Bg,2703
|
26
|
+
batFramework/gui/constraints.py,sha256=pUTNwJqI2Tu57l8ZeQXVXg3b5F5t3aR4Us-CD5qXwnM,7544
|
27
|
+
batFramework/gui/container.py,sha256=XAkPZ0BOVXxzxWP5mKDF_MjYPPPAmUBY-J5zIadO0wQ,1480
|
28
|
+
batFramework/gui/debugger.py,sha256=JORHcSYQQCZ0tDzjnNQvDSOOjZVwEQLeqlr8e6xk2RI,1379
|
29
|
+
batFramework/gui/frame.py,sha256=zjHwbQT1fpRuvNgfBGZhMO_GdMEWqExa5dNlN9kUnUM,514
|
30
|
+
batFramework/gui/image.py,sha256=goOcPntsJeTb3LR7avzi4cXfYHwyGb0KXYttbCiE6fA,777
|
31
|
+
batFramework/gui/indicator.py,sha256=OgqDFsi2HCfbSzVjHkHO_shmo4q4ro3wfd0LWSLTJeQ,957
|
32
|
+
batFramework/gui/interactiveWidget.py,sha256=rRElxI1eFkvOeTfTaA6f8kVTOswOD-DFLAJDUCAI_Yk,641
|
33
|
+
batFramework/gui/label.py,sha256=EO1J5zPVe1skHz-KVqXKBZVKug8UVJUCXyHnvdRDuig,3586
|
34
|
+
batFramework/gui/layout.py,sha256=HyVhYTy1AQacALg6XMY5aX5lj7WY__HCCh8sTSBXwgI,3210
|
35
|
+
batFramework/gui/root.py,sha256=mhlu8ohqq8N-8q__ugv_tGRgPv-1jIHXBFezMFZ4mUM,1763
|
36
|
+
batFramework/gui/shape.py,sha256=CYaD0BdCiuGJO_tS2pALfKPlNGaGRNPzvy-Lk08_R8g,2490
|
37
|
+
batFramework/gui/toggle.py,sha256=jAeEyQXA893gDBUmjN7aoGgfsVln5RTODpSFB4LxwTY,2020
|
38
|
+
batFramework/gui/widget.py,sha256=1PkxThmet8nI5rvSDE6-iPtD_DsZkk-OxriZHbBZaFc,10509
|
39
|
+
batframework-1.0.8a2.dist-info/METADATA,sha256=YnyIVG7YvAIqBiqWVbeQ6h4tWUT7VHAHUr_Is1uQyJw,1980
|
40
|
+
batframework-1.0.8a2.dist-info/WHEEL,sha256=Z4pYXqR_rTB7OWNDYFOm1qRk0RX6GFP2o8LgvP453Hk,91
|
41
|
+
batframework-1.0.8a2.dist-info/top_level.txt,sha256=vxAKBIk1oparFTxeXGBrgfIO7iq_YR5Fv1JvPVAIwmA,13
|
42
|
+
batframework-1.0.8a2.dist-info/RECORD,,
|
batFramework/enums.py
DELETED
batFramework/fontManager.py
DELETED
@@ -1,57 +0,0 @@
|
|
1
|
-
from .utils import Singleton
|
2
|
-
# put font stuff here later
|
3
|
-
import pygame
|
4
|
-
import os
|
5
|
-
import batFramework as bf
|
6
|
-
class FontManager(metaclass=Singleton):
|
7
|
-
def __init__(self):
|
8
|
-
pygame.font.init()
|
9
|
-
self.DEFAULT_TEXT_SIZE = 16
|
10
|
-
self.MIN_FONT_SIZE = 8
|
11
|
-
self.MAX_FONT_SIZE = 64
|
12
|
-
self.DEFAULT_ANTIALIAS = False
|
13
|
-
self.FONTS = {}
|
14
|
-
|
15
|
-
def set_default_text_size(self,size: int):
|
16
|
-
self.DEFAULT_TEXT_SIZE = size
|
17
|
-
|
18
|
-
def init_font(self,raw_path: str|None):
|
19
|
-
try:
|
20
|
-
if raw_path is not None:
|
21
|
-
self.load_font(raw_path if raw_path else None, None)
|
22
|
-
self.load_font(raw_path)
|
23
|
-
except FileNotFoundError:
|
24
|
-
self.load_sysfont(raw_path)
|
25
|
-
self.load_sysfont(raw_path, None)
|
26
|
-
|
27
|
-
def load_font(self,path: str|None, name: str|None = ""):
|
28
|
-
if path is not None:
|
29
|
-
path = bf.ResourceManager().get_path(path) # convert path if given
|
30
|
-
filename = None
|
31
|
-
if path is not None:
|
32
|
-
filename = os.path.basename(path).split(".")[0]
|
33
|
-
|
34
|
-
# get filename if path is given, else None
|
35
|
-
if name != "":
|
36
|
-
filename = name # if name is not given, name is the filename
|
37
|
-
self.FONTS[filename] = {}
|
38
|
-
# fill the dict
|
39
|
-
for size in range(self.MIN_FONT_SIZE, self.MAX_FONT_SIZE, 2):
|
40
|
-
self.FONTS[filename][size] = pygame.font.Font(path, size=size)
|
41
|
-
|
42
|
-
def load_sysfont(self,font_name: str|None, key: str |None= ""):
|
43
|
-
if key == "":
|
44
|
-
key = font_name
|
45
|
-
if font_name is None or pygame.font.match_font(font_name) is None:
|
46
|
-
raise FileNotFoundError(f"Requested font '{font_name}' was not found")
|
47
|
-
self.FONTS[font_name] = {}
|
48
|
-
|
49
|
-
for size in range(self.MIN_FONT_SIZE, self.MAX_FONT_SIZE, 2):
|
50
|
-
self.FONTS[key][size] = pygame.font.SysFont(font_name, size=size)
|
51
|
-
|
52
|
-
def get_font(self,name: str | None = None, text_size: int = 12) -> pygame.Font|None:
|
53
|
-
if not name in self.FONTS:
|
54
|
-
return None
|
55
|
-
if not text_size in self.FONTS[name]:
|
56
|
-
return None
|
57
|
-
return self.FONTS[name][text_size]
|