batframework 1.0.9a11__py3-none-any.whl → 1.0.9a12__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 (73) hide show
  1. batFramework/__init__.py +2 -0
  2. batFramework/action.py +280 -279
  3. batFramework/actionContainer.py +105 -82
  4. batFramework/animatedSprite.py +80 -58
  5. batFramework/animation.py +91 -77
  6. batFramework/audioManager.py +156 -131
  7. batFramework/baseScene.py +249 -240
  8. batFramework/camera.py +245 -317
  9. batFramework/constants.py +57 -51
  10. batFramework/cutscene.py +239 -253
  11. batFramework/cutsceneManager.py +34 -34
  12. batFramework/drawable.py +107 -77
  13. batFramework/dynamicEntity.py +30 -30
  14. batFramework/easingController.py +58 -58
  15. batFramework/entity.py +130 -130
  16. batFramework/enums.py +171 -135
  17. batFramework/fontManager.py +65 -65
  18. batFramework/gui/__init__.py +28 -25
  19. batFramework/gui/animatedLabel.py +90 -89
  20. batFramework/gui/button.py +17 -17
  21. batFramework/gui/clickableWidget.py +244 -244
  22. batFramework/gui/collapseContainer.py +98 -0
  23. batFramework/gui/constraints/__init__.py +1 -1
  24. batFramework/gui/constraints/constraints.py +1066 -980
  25. batFramework/gui/container.py +220 -206
  26. batFramework/gui/debugger.py +140 -130
  27. batFramework/gui/draggableWidget.py +63 -44
  28. batFramework/gui/image.py +61 -58
  29. batFramework/gui/indicator.py +116 -113
  30. batFramework/gui/interactiveWidget.py +243 -239
  31. batFramework/gui/label.py +147 -344
  32. batFramework/gui/layout.py +442 -429
  33. batFramework/gui/meter.py +155 -96
  34. batFramework/gui/radioButton.py +43 -35
  35. batFramework/gui/root.py +228 -228
  36. batFramework/gui/scrollingContainer.py +282 -0
  37. batFramework/gui/selector.py +232 -250
  38. batFramework/gui/shape.py +286 -276
  39. batFramework/gui/slider.py +353 -397
  40. batFramework/gui/style.py +10 -10
  41. batFramework/gui/styleManager.py +49 -54
  42. batFramework/gui/syncedVar.py +43 -49
  43. batFramework/gui/textInput.py +331 -306
  44. batFramework/gui/textWidget.py +308 -0
  45. batFramework/gui/toggle.py +140 -128
  46. batFramework/gui/tooltip.py +35 -30
  47. batFramework/gui/widget.py +546 -521
  48. batFramework/manager.py +131 -134
  49. batFramework/particle.py +118 -118
  50. batFramework/propertyEaser.py +79 -79
  51. batFramework/renderGroup.py +34 -34
  52. batFramework/resourceManager.py +130 -130
  53. batFramework/scene.py +31 -31
  54. batFramework/sceneLayer.py +134 -138
  55. batFramework/sceneManager.py +200 -197
  56. batFramework/scrollingSprite.py +115 -115
  57. batFramework/sprite.py +46 -51
  58. batFramework/stateMachine.py +49 -54
  59. batFramework/templates/__init__.py +2 -1
  60. batFramework/templates/character.py +15 -0
  61. batFramework/templates/controller.py +158 -97
  62. batFramework/templates/stateMachine.py +39 -0
  63. batFramework/tileset.py +46 -46
  64. batFramework/timeManager.py +213 -213
  65. batFramework/transition.py +162 -162
  66. batFramework/triggerZone.py +22 -22
  67. batFramework/utils.py +306 -306
  68. {batframework-1.0.9a11.dist-info → batframework-1.0.9a12.dist-info}/LICENSE +20 -20
  69. {batframework-1.0.9a11.dist-info → batframework-1.0.9a12.dist-info}/METADATA +24 -17
  70. batframework-1.0.9a12.dist-info/RECORD +72 -0
  71. batframework-1.0.9a11.dist-info/RECORD +0 -67
  72. {batframework-1.0.9a11.dist-info → batframework-1.0.9a12.dist-info}/WHEEL +0 -0
  73. {batframework-1.0.9a11.dist-info → batframework-1.0.9a12.dist-info}/top_level.txt +0 -0
@@ -1,82 +1,105 @@
1
- import batFramework as bf
2
- import pygame
3
-
4
-
5
- class ActionContainer:
6
- def __init__(self, *actions: list[bf.Action]) -> None:
7
- self._actions: dict[str, bf.Action] = {}
8
- if actions:
9
- self.add_actions(*actions)
10
-
11
- def __iter__(self):
12
- return iter(self._actions.values())
13
-
14
- def clear(self):
15
- self._actions = {}
16
-
17
- def add_actions(self, *actions: bf.Action):
18
- for action in actions:
19
- self._actions[action.name] = action
20
-
21
- def get(self, name: str) -> bf.Action:
22
- return self._actions.get(name)
23
-
24
- def has_action(self, name: str):
25
- return name in self._actions
26
-
27
- def get_all(self) -> list[bf.Action]:
28
- return self._actions
29
-
30
- def is_active(self, *names: str) -> bool:
31
- return all(
32
- self._actions.get(name).active if name in self._actions else False
33
- for name in names
34
- )
35
-
36
- def process_event(self, event):
37
- if event.consumed:
38
- return
39
- for action in self._actions.values():
40
- action.process_event(event)
41
- if event.consumed == True:
42
- break
43
-
44
- def reset(self):
45
- for action in self._actions.values():
46
- action.reset()
47
-
48
- def hard_reset(self):
49
- for action in self._actions.values():
50
- action.hard_reset()
51
-
52
-
53
- class DirectionalKeyControls(ActionContainer):
54
- def __init__(self):
55
- super().__init__(
56
- bf.Action("up").add_key_control(pygame.K_UP).set_holding(),
57
- bf.Action("down").add_key_control(pygame.K_DOWN).set_holding(),
58
- bf.Action("left").add_key_control(pygame.K_LEFT).set_holding(),
59
- bf.Action("right").add_key_control(pygame.K_RIGHT).set_holding(),
60
- )
61
-
62
-
63
- class WASDControls(ActionContainer):
64
- def __init__(self):
65
- super().__init__(
66
- bf.Action("up").add_key_control(pygame.K_w).set_holding(),
67
- bf.Action("down").add_key_control(pygame.K_s).set_holding(),
68
- bf.Action("left").add_key_control(pygame.K_a).set_holding(),
69
- bf.Action("right").add_key_control(pygame.K_d).set_holding(),
70
- )
71
-
72
-
73
- class HybridControls(ActionContainer):
74
- def __init__(self):
75
- super().__init__(
76
- bf.Action("up").add_key_control(pygame.K_UP, pygame.K_w).set_holding(),
77
- bf.Action("down").add_key_control(pygame.K_DOWN, pygame.K_s).set_holding(),
78
- bf.Action("left").add_key_control(pygame.K_LEFT, pygame.K_a).set_holding(),
79
- bf.Action("right")
80
- .add_key_control(pygame.K_RIGHT, pygame.K_r)
81
- .set_holding(),
82
- )
1
+ import batFramework as bf
2
+ import pygame
3
+
4
+
5
+ class ActionContainer:
6
+ def __init__(self, *actions: list[bf.Action]) -> None:
7
+ self._actions: dict[str, bf.Action] = {}
8
+ if actions:
9
+ self.add_actions(*actions)
10
+
11
+ def __iter__(self):
12
+ return iter(self._actions.values())
13
+
14
+ def __getitem__(self, key):
15
+ return self._actions[key]
16
+
17
+ def __setitem__(self, key, value):
18
+ self._actions[key] = value
19
+
20
+ def __delitem__(self, key):
21
+ del self._actions[key]
22
+
23
+ def __contains__(self, key):
24
+ return key in self._actions
25
+
26
+ def __repr__(self):
27
+ return repr(self._actions)
28
+
29
+
30
+
31
+ def clear(self):
32
+ self._actions = {}
33
+
34
+ def add_actions(self, *actions: bf.Action):
35
+ for action in actions:
36
+ self._actions[action.name] = action
37
+
38
+ def get(self, name: str) -> bf.Action:
39
+ return self._actions.get(name)
40
+
41
+ def has_action(self, name: str):
42
+ return name in self._actions
43
+
44
+ def get_all(self) -> list[bf.Action]:
45
+ return self._actions
46
+
47
+ def is_active(self, *names: str) -> bool:
48
+ return all(
49
+ self._actions.get(name).active if name in self._actions else False
50
+ for name in names
51
+ )
52
+
53
+ def is_any_active(self,*names:str) -> bool:
54
+ return any(
55
+ self._actions.get(name).active if name in self._actions else False
56
+ for name in names
57
+ )
58
+
59
+ def process_event(self, event):
60
+ if event.consumed:
61
+ return
62
+ for action in self._actions.values():
63
+ action.process_event(event)
64
+ if event.consumed == True:
65
+ break
66
+
67
+ def reset(self):
68
+ for action in self._actions.values():
69
+ action.reset()
70
+
71
+ def hard_reset(self):
72
+ for action in self._actions.values():
73
+ action.hard_reset()
74
+
75
+
76
+ class DirectionalKeyControls(ActionContainer):
77
+ def __init__(self):
78
+ super().__init__(
79
+ bf.Action("up").add_key_control(pygame.K_UP).set_holding(),
80
+ bf.Action("down").add_key_control(pygame.K_DOWN).set_holding(),
81
+ bf.Action("left").add_key_control(pygame.K_LEFT).set_holding(),
82
+ bf.Action("right").add_key_control(pygame.K_RIGHT).set_holding(),
83
+ )
84
+
85
+
86
+ class WASDControls(ActionContainer):
87
+ def __init__(self):
88
+ super().__init__(
89
+ bf.Action("up").add_key_control(pygame.K_w).set_holding(),
90
+ bf.Action("down").add_key_control(pygame.K_s).set_holding(),
91
+ bf.Action("left").add_key_control(pygame.K_a).set_holding(),
92
+ bf.Action("right").add_key_control(pygame.K_d).set_holding(),
93
+ )
94
+
95
+
96
+ class HybridControls(ActionContainer):
97
+ def __init__(self):
98
+ super().__init__(
99
+ bf.Action("up").add_key_control(pygame.K_UP, pygame.K_w).set_holding(),
100
+ bf.Action("down").add_key_control(pygame.K_DOWN, pygame.K_s).set_holding(),
101
+ bf.Action("left").add_key_control(pygame.K_LEFT, pygame.K_a).set_holding(),
102
+ bf.Action("right")
103
+ .add_key_control(pygame.K_RIGHT, pygame.K_r)
104
+ .set_holding(),
105
+ )
@@ -1,59 +1,81 @@
1
- import batFramework as bf
2
- import pygame
3
- from typing import List, Dict, Tuple, Union, Optional, Self, Callable, Any
4
- from .animation import Animation
5
-
6
- class AnimatedSprite(bf.Drawable):
7
- def __init__(self,*args,**kwargs) -> None:
8
- super().__init__(None, no_surface=True,*args,**kwargs)
9
- self.animations : dict[str,Animation] = {}
10
- self.counter = 0 # int counter
11
- self._fcounter = 0.0 # counter
12
- self.current_animation : str = None
13
- self.end_callback : Callable[[],Any] = None
14
- self._flipX : bool = False
15
-
16
- @property
17
- def flipX(self)->bool:
18
- return self._flipX
19
-
20
- @flipX.setter
21
- def flipX(self,value:bool):
22
- self._flipX = value
23
-
24
- def set_end_callback(self,callback : Callable[[],Any]):
25
- self.end_callback = callback
26
-
27
- def add_animation(self,name:str,animation:Animation)->Self:
28
- self.animations[name] = animation
29
- if self.rect.size == (0,0):
30
- self.rect.size = animation.frames[0].get_size()
31
- return self
32
-
33
- def set_animation(self,name:str,reset_counter:bool=True):
34
- if name not in self.animations :
35
- raise ValueError
36
- self.current_animation = name
37
- if reset_counter:
38
- self._fcounter = 0
39
-
40
- def get_current_frame(self)->int|None:
41
- if not self.current_animation:
42
- return None
43
- return self.animations[self.current_animation].counter_to_frame(self._fcounter)
44
-
45
- def update(self, dt):
46
- super().update(dt)
47
- if not self.current_animation:
48
- return
49
- self._fcounter += dt
50
- self.counter = int(self._fcounter)
51
- if self.counter >= self.animations[self.current_animation].numFrames:
52
- if self.end_callback:
53
- self.end_callback()
54
-
55
-
56
- def draw(self, camera):
57
- self.surface.blit(self.animations[self.current_animation].get_frame(self.counter,self.flipX),(0,0))
58
- super().draw(camera)
1
+ import batFramework as bf
2
+ import pygame
3
+ from typing import List, Dict, Tuple, Union, Optional, Self, Callable, Any
4
+ from .animation import Animation
5
+
6
+ class AnimatedSprite(bf.Drawable):
7
+ def __init__(self,*args,**kwargs) -> None:
8
+ super().__init__((0,0),*args,**kwargs)
9
+ self.animations : dict[str,Animation] = {}
10
+ self.counter = 0 # int counter
11
+ self._fcounter = 0.0 # counter
12
+ self.current_animation : str = None
13
+ self.end_callback : Callable[[],Any] = None
14
+ self._flipX : bool = False
15
+ self.animation_loop : int = -1
16
+ self.queued_animation : str = None
17
+
18
+ @property
19
+ def flipX(self)->bool:
20
+ return self._flipX
21
+
22
+ @flipX.setter
23
+ def flipX(self,value:bool):
24
+ self._flipX = value
25
+
26
+ def set_animation_end_callback(self,callback : Callable[[],Any]):
27
+ self.end_callback = callback
28
+
29
+ def add_animation(self,animation:Animation)->Self:
30
+ self.animations[animation.name] = animation
31
+ if self.rect.size == (0,0):
32
+ self.rect.size = animation.frames[0].get_size()
33
+ self.surface = animation.frames[0].copy()
34
+ return self
35
+
36
+ def set_animation(self,name:str,reset_counter:bool=True,loop:int=-1,queued_animation:str=None):
37
+ """
38
+ Sets the current animation,
39
+ if animation with given name hasn't been added, nothing happens
40
+ """
41
+ if name not in self.animations :
42
+ return
43
+ self.current_animation = name
44
+ if reset_counter:
45
+ self._fcounter = 0
46
+ self.counter = 0
47
+ self.animation_loop = loop
48
+ if loop != -1:
49
+ self.queued_animation = queued_animation
50
+ else:
51
+ self.queued_animation = None
52
+
53
+ def get_current_frame(self)->int|None:
54
+ if not self.current_animation:
55
+ return None
56
+ return self.animations[self.current_animation].counter_to_frame(self._fcounter)
57
+
58
+ def update(self, dt):
59
+ super().update(dt)
60
+ if not self.current_animation:
61
+ return
62
+ self._fcounter += dt * 60
63
+ self.counter = int(self._fcounter)
64
+ # self.counter = self.get_current_frame()
65
+ # print(f"{self.current_animation}:{self.counter}/{self.animations[self.current_animation].duration_list_length}")
66
+ if self.counter >= self.animations[self.current_animation].duration_list_length:
67
+ #one animation cycle ended
68
+ if self.animation_loop > 0:
69
+ self.animation_loop -= 1
70
+ elif self.queued_animation is not None:
71
+ # print("set to queued :",self.queued_animation)
72
+ self.set_animation(self.queued_animation,True)
73
+
74
+ if self.end_callback:
75
+ self.end_callback()
76
+
77
+ def draw(self, camera):
78
+ # print(self.current_animation, f"{self.counter}/{self.animations[self.current_animation].duration_list_length}")
79
+ self.surface = self.animations[self.current_animation].get_frame(self.counter,self.flipX)#,(0,0)
80
+ super().draw(camera)
59
81
 
batFramework/animation.py CHANGED
@@ -1,77 +1,91 @@
1
- import pygame
2
- import batFramework as bf
3
- from typing import List, Dict, Tuple, Union, Optional, Self
4
-
5
-
6
- def search_index(target: int, lst: List[int]) -> int:
7
- cumulative_sum = 0
8
- for index, value in enumerate(lst):
9
- cumulative_sum += value
10
- if cumulative_sum >= target:
11
- return index
12
- return -1
13
-
14
-
15
- class Animation:
16
- def __init__(
17
- self,
18
- name: str
19
- ) -> None:
20
- """
21
- Class to hold 2D animation data.
22
- All frames are expected to have the same size.
23
- This class does not do anything on its own, but can be used to easily manage
24
- multiple animations using a simple counter.
25
- The duration list provides a entry point for tweaking the timings,
26
- so image data can be saved (no need for contiguous duplicate frames)
27
- """
28
- self.name = name
29
- self.frames: list[pygame.Surface] = []
30
- self.frames_flipX : list[pygame.Surface] = []
31
- self.duration_list = []
32
- self.duration_list_length = 0 # prevents calling len() each frame
33
- self.numFrames : int = 0
34
-
35
- def from_surface(self,surface:pygame.Surface,frame_size : Tuple[int,int])->Self:
36
- """
37
- Loads frames from a spritesheet containing all animation frames aligned horizontally, left to right
38
- Frames are cut and stored in 2 versions, original and flipped on the horizontal axis.
39
- Flipping sprites being pretty common, this serves as a builtin cache.
40
- """
41
- self.frames : List[pygame.Surface] = list(
42
- bf.utils.split_surface(surface, frame_size).values()
43
- )
44
- self.frames_flipX : List[pygame.Surface] = list(
45
- bf.utils.split_surface(
46
- surface, frame_size,
47
- func=lambda s : pygame.transform.flip(s,True,False)
48
- ).values()
49
- )
50
- self.duration_list_length = len(self.frames)
51
- self.numFrames = self.duration_list_length
52
- if not self.duration_list:
53
- self.duration_list = [1]*self.duration_list_length
54
- return self
55
-
56
- def __repr__(self):
57
- return f"Animation({self.name})"
58
-
59
- def counter_to_frame(self, counter: Union[float, int]) -> int:
60
- if not self.frames :
61
- raise ValueError("Animation has no frames")
62
- return search_index(
63
- int(counter % self.duration_list_length), self.duration_list
64
- )
65
-
66
- def get_frame(self, counter: Union[float, int], flip: bool) -> pygame.Surface:
67
- i = self.counter_to_frame(counter)
68
- return self.frames_flipX[i] if flip else self.frames[i]
69
-
70
- def set_duration_list(self, duration_list: Union[List[int], int]) -> Self:
71
- if isinstance(duration_list, int):
72
- duration_list = [duration_list] * len(self.frames)
73
- if len(duration_list) != self.numFrames:
74
- raise ValueError("duration_list should have values for all frames")
75
- self.duration_list = duration_list
76
- self.duration_list_length = sum(self.duration_list)
77
- return self
1
+ import pygame
2
+ import batFramework as bf
3
+ from typing import List, Dict, Tuple, Union, Optional, Self, Iterable
4
+
5
+
6
+ def search_index(target: int, lst: List[int]) -> int:
7
+ cumulative_sum = 0
8
+ for index, value in enumerate(lst):
9
+ cumulative_sum += value
10
+ if cumulative_sum >= target:
11
+ return index
12
+ return -1
13
+
14
+
15
+ class Animation:
16
+ def __init__(
17
+ self,
18
+ name: str
19
+ ) -> None:
20
+ """
21
+ Class to hold 2D animation data.
22
+ All frames are expected to have the same size.
23
+ This class does not do anything on its own, but can be used to easily manage
24
+ multiple animations using a simple counter.
25
+ The duration list provides a entry point for tweaking the timings,
26
+ so image data can be saved (no need for contiguous duplicate frames)
27
+ """
28
+ self.name = name
29
+ self.frames: list[pygame.Surface] = []
30
+ self.frames_flipX : list[pygame.Surface] = []
31
+ self.duration_list = []
32
+ self.duration_list_length = 0
33
+ self.numFrames : int = 0
34
+
35
+ def from_surface(self,surface:pygame.Surface,frame_size : Tuple[int,int])->Self:
36
+ """
37
+ Loads frames from a spritesheet containing all animation frames aligned horizontally, left to right
38
+ Frames are cut and stored in 2 versions, original and flipped on the horizontal axis.
39
+ Flipping sprites being pretty common, this serves as a builtin cache.
40
+ """
41
+ self.frames : List[pygame.Surface] = list(
42
+ bf.utils.split_surface(surface, frame_size).values()
43
+ )
44
+ self.frames_flipX : List[pygame.Surface] = list(
45
+ bf.utils.split_surface(
46
+ surface, frame_size,
47
+ func=lambda s : pygame.transform.flip(s,True,False)
48
+ ).values()
49
+ )
50
+ self.duration_list_length = len(self.frames)
51
+ self.numFrames = self.duration_list_length
52
+ if not self.duration_list:
53
+ self.duration_list = [1]*self.duration_list_length
54
+ return self
55
+
56
+ def from_path(
57
+ self,
58
+ path: str,
59
+ frame_size: Tuple[int, int],
60
+ convert_alpha: bool = True
61
+ ) -> Self:
62
+ """
63
+ Loads frames from a spritesheet at the given path.
64
+ Uses ResourceManager to load the image.
65
+ """
66
+ surface = bf.ResourceManager().get_image(path, convert_alpha)
67
+ return self.from_surface(surface, frame_size)
68
+
69
+
70
+ def __repr__(self):
71
+ return f"Animation({self.name})"
72
+
73
+ def counter_to_frame(self, counter: Union[float, int]) -> int:
74
+ if not self.frames :
75
+ raise ValueError("Animation has no frames")
76
+ return search_index(
77
+ int(counter % self.duration_list_length), self.duration_list
78
+ )
79
+
80
+ def get_frame(self, counter: Union[float, int], flip: bool) -> pygame.Surface:
81
+ i = self.counter_to_frame(counter)
82
+ return self.frames_flipX[i] if flip else self.frames[i]
83
+
84
+ def set_duration_list(self, duration_list: Union[List[int], int]) -> Self:
85
+ if not isinstance(duration_list, Iterable):
86
+ duration_list = [duration_list] * len(self.frames)
87
+ if len(duration_list) != self.numFrames:
88
+ raise ValueError("duration_list should have values for all frames")
89
+ self.duration_list = duration_list
90
+ self.duration_list_length = sum(self.duration_list)
91
+ return self