batframework 1.0.8a12__py3-none-any.whl → 1.0.8a14__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 CHANGED
@@ -8,7 +8,7 @@ from .resourceManager import ResourceManager
8
8
  from .fontManager import FontManager
9
9
  from .utils import Utils as utils
10
10
  from .tileset import Tileset
11
- from .time import *
11
+ from .timeManager import TimeManager,Timer,SceneTimer
12
12
  from .easingController import EasingController
13
13
  from .cutscene import Cutscene, CutsceneManager
14
14
  from .cutsceneBlocks import *
@@ -17,14 +17,15 @@ import batFramework.transition as transition
17
17
  from .action import Action
18
18
  from .actionContainer import *
19
19
  from .camera import Camera
20
- from .object import Object
21
20
  from .entity import Entity
21
+ from .drawable import Drawable
22
22
  from .renderGroup import RenderGroup
23
23
  from .dynamicEntity import DynamicEntity
24
24
  from .sprite import Sprite
25
25
  from .scrollingSprite import ScrollingSprite
26
26
  from .particle import *
27
- from .animatedSprite import AnimatedSprite, Animation
27
+ from .animation import Animation
28
+ from .animatedSprite import AnimatedSprite
28
29
  from .character import Character
29
30
  from .stateMachine import State, StateMachine
30
31
  from .scene import Scene
@@ -1,59 +1,11 @@
1
1
  import batFramework as bf
2
2
  import pygame
3
3
  from typing import List, Dict, Tuple, Union, Optional, Self
4
+ from .animation import Animation
4
5
 
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
- self.name = name
21
- self.frames: list[pygame.Surface] = []
22
- self.frames_flipX : list[pygame.Surface] = []
23
- self.duration_list = []
24
- self.duration_list_length = 1
25
-
26
- def from_surface(self,surface:pygame.Surface,size : Tuple[int,int])->Self:
27
- self.frames : List[pygame.Surface] = list(bf.utils.split_surface(surface, size).values())
28
- self.frames_flipX : List[pygame.Surface] = list(bf.utils.split_surface(surface, size,func=lambda s : pygame.transform.flip(s,True,False)).values())
29
- return self
30
-
31
- def __repr__(self):
32
- return f"Animation({self.name})"
33
-
34
- def counter_to_frame(self, counter: Union[float, int]) -> int:
35
- if not self.frames :
36
- raise ValueError("Animation has no frames")
37
- return search_index(
38
- int(counter % self.duration_list_length), self.duration_list
39
- )
40
-
41
- def get_frame(self, counter: Union[float, int], flip: bool) -> pygame.Surface:
42
- i = self.counter_to_frame(counter)
43
- return self.frames_flipX[i] if flip else self.frames[i]
44
-
45
- def set_duration_list(self, duration_list: Union[List[int], int]) -> Self:
46
- if isinstance(duration_list, int):
47
- duration_list = [duration_list] * len(self.frames)
48
- if len(duration_list) != len(self.frames):
49
- raise ValueError("duration_list should have values for all frames")
50
- self.duration_list = duration_list
51
- self.duration_list_length = sum(self.duration_list)
52
- return self
53
-
54
- class AnimatedSprite(bf.Entity):
55
- def __init__(self, size: Optional[Tuple[int, int]] = None) -> None:
56
- super().__init__(size, no_surface=True)
6
+ class AnimatedSprite(bf.Drawable):
7
+ def __init__(self, size: Optional[Tuple[int, int]] = None,*args,**kwargs) -> None:
8
+ super().__init__(size, no_surface=True,*args,**kwargs)
57
9
  self.float_counter: float = 0
58
10
  self.animations: Dict[str, Animation] = {}
59
11
  self.current_state: Optional[Animation] = None
@@ -0,0 +1,52 @@
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
+ self.name = name
21
+ self.frames: list[pygame.Surface] = []
22
+ self.frames_flipX : list[pygame.Surface] = []
23
+ self.duration_list = []
24
+ self.duration_list_length = 1
25
+
26
+ def from_surface(self,surface:pygame.Surface,size : Tuple[int,int])->Self:
27
+ self.frames : List[pygame.Surface] = list(bf.utils.split_surface(surface, size).values())
28
+ self.frames_flipX : List[pygame.Surface] = list(bf.utils.split_surface(surface, size,func=lambda s : pygame.transform.flip(s,True,False)).values())
29
+ return self
30
+
31
+ def __repr__(self):
32
+ return f"Animation({self.name})"
33
+
34
+ def counter_to_frame(self, counter: Union[float, int]) -> int:
35
+ if not self.frames :
36
+ raise ValueError("Animation has no frames")
37
+ return search_index(
38
+ int(counter % self.duration_list_length), self.duration_list
39
+ )
40
+
41
+ def get_frame(self, counter: Union[float, int], flip: bool) -> pygame.Surface:
42
+ i = self.counter_to_frame(counter)
43
+ return self.frames_flipX[i] if flip else self.frames[i]
44
+
45
+ def set_duration_list(self, duration_list: Union[List[int], int]) -> Self:
46
+ if isinstance(duration_list, int):
47
+ duration_list = [duration_list] * len(self.frames)
48
+ if len(duration_list) != len(self.frames):
49
+ raise ValueError("duration_list should have values for all frames")
50
+ self.duration_list = duration_list
51
+ self.duration_list_length = sum(self.duration_list)
52
+ return self
batFramework/character.py CHANGED
@@ -3,9 +3,9 @@ from .stateMachine import State
3
3
  from .animatedSprite import AnimatedSprite
4
4
  from .dynamicEntity import DynamicEntity
5
5
 
6
- class Character(AnimatedSprite,DynamicEntity):
7
- def __init__(self) -> None:
8
- super().__init__()
6
+ class Character(DynamicEntity,AnimatedSprite):
7
+ def __init__(self,*args,**kwargs) -> None:
8
+ super().__init__(*args,**kwargs)
9
9
  self.state_machine = bf.StateMachine(self)
10
10
  self.do_setup_animations()
11
11
  self.do_setup_states()
batFramework/constants.py CHANGED
@@ -4,6 +4,8 @@ import pygame
4
4
  class Constants:
5
5
  SCREEN: pygame.Surface = None
6
6
  RESOLUTION: tuple[int, int] = (1280, 720)
7
+ WIDTH = 1280
8
+ HEIGHT = 720
7
9
  VSYNC = 0
8
10
  FLAGS: int = pygame.SCALED | pygame.RESIZABLE
9
11
  FPS: int = 60
@@ -18,6 +20,8 @@ class Constants:
18
20
  @staticmethod
19
21
  def set_resolution(resolution: tuple[int, int]):
20
22
  Constants.RESOLUTION = resolution
23
+ Constants.WIDTH = resolution[0]
24
+ Constants.HEIGHT = resolution[1]
21
25
 
22
26
  @staticmethod
23
27
  def set_default_cursor(cursor: pygame.Cursor):
batFramework/cutscene.py CHANGED
@@ -1,5 +1,5 @@
1
1
  import batFramework as bf
2
- from typing import TYPE_CHECKING
2
+ from typing import TYPE_CHECKING,Self
3
3
 
4
4
  class CutsceneBlock: ...
5
5
 
@@ -75,13 +75,15 @@ class Cutscene:
75
75
  def init_blocks(self):
76
76
  pass
77
77
 
78
- def add_blocks(self, *blocks: CutsceneBlock):
78
+ def add_blocks(self, *blocks: CutsceneBlock)->Self:
79
79
  self.cutscene_blocks.extend(blocks)
80
-
81
- def add_end_blocks(self, *blocks: CutsceneBlock):
80
+ return self
81
+
82
+ def add_end_blocks(self, *blocks: CutsceneBlock)->Self:
82
83
  _ = [block.set_parent_cutscene(self) for block in blocks]
83
84
  self.end_blocks.extend(blocks)
84
-
85
+ return self
86
+
85
87
  def get_scene_at(self, index):
86
88
  return bf.CutsceneManager().manager.scenes[index]
87
89
 
@@ -0,0 +1,75 @@
1
+ from typing import Any, Self
2
+ import pygame
3
+ import batFramework as bf
4
+ from .entity import Entity
5
+
6
+
7
+ class Drawable(Entity):
8
+ """
9
+ Basic entity class
10
+ """
11
+
12
+ def __init__(
13
+ self,
14
+ size: None | tuple[int, int] = None,
15
+ surface_flags: int = 0,
16
+ convert_alpha: bool = False,
17
+ *args,
18
+ **kwargs,
19
+ ) -> None:
20
+ super().__init__()
21
+ self.visible: bool = True
22
+ self.render_order: int = 0
23
+ self.rect.size = (10, 10) if size is None else size
24
+ self.convert_alpha: bool = convert_alpha
25
+ self.surface_flags: int = surface_flags
26
+ self.blit_flags: int = 0
27
+ self.surface: pygame.Surface = pygame.Surface(self.rect.size, surface_flags)
28
+ if convert_alpha:
29
+ self.surface = self.surface.convert_alpha()
30
+ self.surface.fill((0, 0, 0, 0))
31
+
32
+ def set_alpha(self, alpha: int) -> Self:
33
+ self.surface.set_alpha(min(max(0, alpha), 255))
34
+ return self
35
+
36
+ def get_alpha(self) -> int:
37
+ return self.surface.get_alpha()
38
+
39
+ def set_surface_flags(self, surface_flags: int) -> Self:
40
+ self.surface_flags = surface_flags
41
+ return self
42
+
43
+ def set_convert_alpha(self, value: bool) -> Self:
44
+ self.convert_alpha = value
45
+ return self
46
+
47
+ def set_blit_flags(self, blit_flags: int) -> Self:
48
+ self.blit_flags = blit_flags
49
+ return self
50
+
51
+ def get_debug_outlines(self):
52
+ if self.visible:
53
+ yield (self.rect, self.debug_color)
54
+
55
+ def set_render_order(self, render_order: int) -> Self:
56
+ self.render_order = render_order
57
+ if self.parent_scene:
58
+ self.parent_scene.sort_entities()
59
+ return self
60
+
61
+ def set_visible(self, value: bool) -> Self:
62
+ self.visible = value
63
+ return self
64
+
65
+ def draw(self, camera: bf.Camera) -> None:
66
+ """
67
+ Draw the entity onto the camera surface
68
+ """
69
+ if not self.visible or not camera.rect.colliderect(self.rect):
70
+ return
71
+ camera.surface.blit(
72
+ self.surface,
73
+ camera.world_to_screen(self.rect),
74
+ special_flags=self.blit_flags,
75
+ )
batFramework/entity.py CHANGED
@@ -1,74 +1,124 @@
1
1
  from typing import Any, Self
2
2
  import pygame
3
3
  import batFramework as bf
4
- from .object import Object
5
-
6
-
7
- class Entity(Object):
8
- """
9
- Basic entity class
10
- """
11
-
12
- def __init__(
13
- self,
14
- size: None | tuple[int, int] = None,
15
- surface_flags: int = 0,
16
- convert_alpha: bool = False,
17
- *args,
18
- **kwargs,
19
- ) -> None:
20
- super().__init__()
21
- self.visible: bool = True
22
- self.rect.size = (10, 10) if size is None else size
23
- self.convert_alpha: bool = convert_alpha
24
- self.surface_flags: int = surface_flags
25
- self.blit_flags: int = 0
26
- self.surface: pygame.Surface = pygame.Surface(self.rect.size, surface_flags)
27
- if convert_alpha:
28
- self.surface = self.surface.convert_alpha()
29
- self.surface.fill((0, 0, 0, 0))
30
-
31
- def set_alpha(self, alpha: int) -> Self:
32
- self.surface.set_alpha(min(max(0, alpha), 255))
33
- return self
4
+ from typing import TYPE_CHECKING
34
5
 
35
- def get_alpha(self) -> int:
36
- return self.surface.get_alpha()
6
+ if TYPE_CHECKING:
7
+ from .camera import Camera
37
8
 
38
- def set_surface_flags(self, surface_flags: int) -> Self:
39
- self.surface_flags = surface_flags
40
- return self
41
9
 
42
- def set_convert_alpha(self, value: bool) -> Self:
43
- self.convert_alpha = value
10
+ class Entity:
11
+ __count = 0
12
+ __available_uid = set()
13
+ __used_uid = set()
14
+
15
+ def __init__(self) -> None:
16
+ self.rect = pygame.FRect(0, 0, 0, 0)
17
+ self.tags: list[str] = []
18
+ self.parent_scene: bf.Scene | None = None
19
+ self.debug_color: tuple | str = "red"
20
+ self.uid: int = Entity.__count
21
+ Entity.__used_uid.add(self.uid)
22
+
23
+ if Entity.__available_uid:
24
+ self.name = Entity.__available_uid.pop()
25
+ else:
26
+ self.name = Entity.__count
27
+ Entity.__count += 1
28
+
29
+ def __del__(self):
30
+ Entity.__available_uid.add(self.uid)
31
+
32
+ def set_position(self, x, y) -> Self:
33
+ self.rect.topleft = x, y
44
34
  return self
45
35
 
46
- def set_blit_flags(self, blit_flags: int) -> Self:
47
- self.blit_flags = blit_flags
36
+ def set_center(self, x, y) -> Self:
37
+ self.rect.center = x, y
48
38
  return self
49
39
 
50
40
  def get_debug_outlines(self):
51
- if self.visible:
52
- yield (self.rect, self.debug_color)
41
+ yield (self.rect, self.debug_color)
53
42
 
54
- def set_render_order(self, render_order: int) -> Self:
55
- self.render_order = render_order
56
- if self.parent_scene:
57
- self.parent_scene.sort_entities()
43
+ def set_debug_color(self, color) -> Self:
44
+ self.debug_color = color
58
45
  return self
59
46
 
60
- def set_visible(self, value: bool) -> Self:
61
- self.visible = value
47
+ def set_parent_scene(self, scene) -> Self:
48
+ if scene == self.parent_scene:
49
+ return self
50
+ if self.parent_scene is not None:
51
+ self.do_when_removed()
52
+ self.parent_scene = scene
53
+ if scene is not None:
54
+ self.do_when_added()
62
55
  return self
63
56
 
64
- def draw(self, camera: bf.Camera) -> None:
57
+ def do_when_added(self):
58
+ pass
59
+
60
+ def do_when_removed(self):
61
+ pass
62
+
63
+ def set_uid(self, uid: int) -> Self:
64
+ if uid in Entity.__used_uid:
65
+ print(f"set_uid error : UID '{uid}' is already in use")
66
+ return self
67
+ self.uid = uid
68
+ if uid in Entity.__used_uid:
69
+ Entity.__used_uid.remove(uid)
70
+ Entity.__used_uid.add(uid)
71
+ return self
72
+
73
+ def add_tags(self, *tags) -> Self:
74
+ for tag in tags:
75
+ if tag not in self.tags:
76
+ self.tags.append(tag)
77
+ self.tags.sort()
78
+ return self
79
+
80
+ def remove_tags(self, *tags):
81
+ self.tags = [tag for tag in self.tags if tag not in tags]
82
+
83
+ def has_tags(self, *tags) -> bool:
84
+ return all(tag in self.tags for tag in tags)
85
+
86
+ def get_tags(self) -> list[str]:
87
+ return self.tags
88
+
89
+ def process_event(self, event: pygame.Event) -> bool:
65
90
  """
66
- Draw the entity onto the camera surface
91
+ Returns bool : True if the method is blocking (no propagation to next Entity of the scene)
67
92
  """
68
- if not self.visible or not camera.rect.colliderect(self.rect):
93
+ if event.consumed:
69
94
  return
70
- camera.surface.blit(
71
- self.surface,
72
- camera.world_to_screen(self.rect),
73
- special_flags=self.blit_flags,
74
- )
95
+ self.do_process_actions(event)
96
+ self.do_handle_event(event)
97
+
98
+ def do_process_actions(self, event: pygame.Event) -> None:
99
+ """
100
+ Process entity actions you may have set
101
+ """
102
+
103
+ def do_reset_actions(self) -> None:
104
+ """
105
+ Reset entity actions you may have set
106
+ """
107
+
108
+ def do_handle_event(self, event: pygame.Event):
109
+ """
110
+ Handle specific events with no action support
111
+ """
112
+ return False
113
+
114
+ def update(self, dt: float) -> None:
115
+ """
116
+ Update method to be overriden by subclasses of Entity (must call do_update and do_reset_actions)
117
+ """
118
+ self.do_update(dt)
119
+ self.do_reset_actions()
120
+
121
+ def do_update(self, dt: float) -> None:
122
+ """
123
+ Update method to be overriden for specific behavior by the end user
124
+ """
@@ -174,7 +174,7 @@ class Container(Shape, InteractiveWidget):
174
174
  self.paint()
175
175
  self.dirty_surface = False
176
176
 
177
- bf.Entity.draw(self, camera)
177
+ bf.Drawable.draw(self, camera)
178
178
 
179
179
  if self.clip_children:
180
180
  new_clip = camera.world_to_screen(self.get_padded_rect())
@@ -72,7 +72,7 @@ class Debugger(Label):
72
72
  def update(self, dt: float) -> None:
73
73
  if not self.parent_scene:
74
74
  return
75
- if self.parent_scene.get_sharedVar("debug_mode") != bf.debugMode.DEBUGGER:
75
+ if bf.ResourceManager().get_sharedVar("debug_mode") != bf.debugMode.DEBUGGER:
76
76
  self.set_visible(False)
77
77
  return
78
78
  self.set_visible(True)
batFramework/gui/label.py CHANGED
@@ -37,7 +37,6 @@ class Label(Shape):
37
37
  self.text_rect = pygame.FRect(0, 0, 0, 0)
38
38
  # text surface (result of font.render)
39
39
  self.text_surface: pygame.Surface = pygame.Surface((0, 0))
40
- self.do_caching: bool = False
41
40
 
42
41
  self.show_text_outline: bool = False
43
42
 
@@ -54,21 +53,9 @@ class Label(Shape):
54
53
  self.set_autoresize(True)
55
54
  self.set_font(force=True)
56
55
 
57
- @staticmethod
58
- def clear_cache():
59
- Label._text_cache = {}
60
-
61
56
  def __str__(self) -> str:
62
57
  return f"Label({repr(self.text)})"
63
58
 
64
- def enable_caching(self) -> Self:
65
- self.do_caching = True
66
- return self
67
-
68
- def disable_caching(self) -> Self:
69
- self.do_caching = False
70
- return self
71
-
72
59
  def set_text_color(self, color) -> Self:
73
60
  self.text_color = color
74
61
  self.dirty_surface = True
@@ -197,7 +184,6 @@ class Label(Shape):
197
184
  self.text_rect.size = self._get_text_rect_required_size()
198
185
  res = self.inflate_rect_by_padding((0, 0, *self.text_rect.size)).size
199
186
 
200
- return res
201
187
  return res[0] if self.autoresize_w else self.rect.w, (
202
188
  res[1] if self.autoresize_h else self.rect.h
203
189
  )
@@ -206,35 +192,26 @@ class Label(Shape):
206
192
  return self.text
207
193
 
208
194
  def _render_font(self, params: dict) -> pygame.Surface:
209
- key = tuple(params.values())
210
-
211
- cached_value = Label._text_cache.get(key, None)
212
195
 
213
196
  if self.draw_mode == bf.drawMode.SOLID:
214
- if cached_value is None:
215
- params.pop("font_name")
216
-
217
- # save old settings
218
- old_italic = self.font_object.get_italic()
219
- old_bold = self.font_object.get_bold()
220
- old_underline = self.font_object.get_underline()
221
-
222
- # setup font
223
- self.font_object.set_italic(self.is_italic)
224
- self.font_object.set_bold(self.is_bold)
225
- self.font_object.set_underline(self.is_underlined)
226
-
227
- surf = self.font_object.render(**params)
228
-
229
- # reset font
230
- self.font_object.set_italic(old_italic)
231
- self.font_object.set_bold(old_bold)
232
- self.font_object.set_underline(old_underline)
233
-
234
- if self.do_caching:
235
- Label._text_cache[key] = surf
236
- else:
237
- surf = cached_value
197
+ params.pop("font_name")
198
+
199
+ # save old settings
200
+ old_italic = self.font_object.get_italic()
201
+ old_bold = self.font_object.get_bold()
202
+ old_underline = self.font_object.get_underline()
203
+
204
+ # setup font
205
+ self.font_object.set_italic(self.is_italic)
206
+ self.font_object.set_bold(self.is_bold)
207
+ self.font_object.set_underline(self.is_underlined)
208
+
209
+ surf = self.font_object.render(**params)
210
+
211
+ # reset font
212
+ self.font_object.set_italic(old_italic)
213
+ self.font_object.set_bold(old_bold)
214
+ self.font_object.set_underline(old_underline)
238
215
  else:
239
216
  params.pop("font_name")
240
217
  surf = self.font_object.render(**params)
@@ -1,8 +1,8 @@
1
1
  import batFramework as bf
2
2
  from .widget import Widget
3
3
  from .constraints.constraints import *
4
- from typing import Self, TYPE_CHECKING,override
5
- from abc import ABC,abstractmethod
4
+ from typing import Self, TYPE_CHECKING
5
+ from abc import ABC
6
6
  import pygame
7
7
 
8
8
  if TYPE_CHECKING:
batFramework/gui/root.py CHANGED
@@ -95,8 +95,6 @@ class Root(InteractiveWidget):
95
95
  return self
96
96
 
97
97
  def do_handle_event(self, event):
98
- if not self.parent_scene.get_sharedVar("player_has_control"):
99
- return
100
98
  if self.focused:
101
99
  if event.type == pygame.KEYDOWN:
102
100
  if self.focused.on_key_down(event.key):
@@ -130,8 +128,6 @@ class Root(InteractiveWidget):
130
128
 
131
129
  def update(self, dt: float) -> None:
132
130
  super().update(dt)
133
- if not self.parent_scene.get_sharedVar("player_has_control",True):
134
- return
135
131
  old = self.hovered
136
132
  transposed = self.drawing_camera.screen_to_world(pygame.mouse.get_pos())
137
133
  self.hovered = self.top_at(*transposed) if self.top_at(*transposed) else None
@@ -145,8 +141,6 @@ class Root(InteractiveWidget):
145
141
 
146
142
  def draw(self, camera: bf.Camera) -> None:
147
143
  super().draw(camera)
148
- if not self.parent_scene.get_sharedVar("player_has_control"):
149
- return
150
144
  if (
151
145
  self.parent_scene
152
146
  and self.parent_scene.active
@@ -18,7 +18,7 @@ class WidgetMeta(type):
18
18
  return obj
19
19
 
20
20
 
21
- class Widget(bf.Entity, metaclass=WidgetMeta):
21
+ class Widget(bf.Drawable, metaclass=WidgetMeta):
22
22
  def __init__(self, *args, **kwargs) -> None:
23
23
  super().__init__(*args, **kwargs)
24
24
  self.children: list["Widget"] = []