batframework 1.0.8a3__tar.gz → 1.0.8a6__tar.gz

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 (70) hide show
  1. {batframework-1.0.8a3 → batframework-1.0.8a6}/PKG-INFO +3 -15
  2. {batframework-1.0.8a3 → batframework-1.0.8a6}/README.md +2 -14
  3. {batframework-1.0.8a3 → batframework-1.0.8a6}/pyproject.toml +1 -1
  4. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/__init__.py +16 -2
  5. batframework-1.0.8a6/src/batFramework/animatedSprite.py +176 -0
  6. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/audioManager.py +2 -2
  7. batframework-1.0.8a6/src/batFramework/character.py +27 -0
  8. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/cutscene.py +5 -2
  9. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/cutsceneBlocks.py +3 -5
  10. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/dynamicEntity.py +11 -4
  11. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/enums.py +2 -2
  12. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/fontManager.py +2 -2
  13. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/gui/clickableWidget.py +10 -9
  14. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/gui/constraints/constraints.py +282 -57
  15. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/gui/image.py +14 -14
  16. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/gui/interactiveWidget.py +16 -1
  17. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/gui/label.py +58 -37
  18. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/gui/layout.py +23 -14
  19. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/gui/meter.py +10 -7
  20. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/gui/radioButton.py +1 -1
  21. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/gui/root.py +7 -1
  22. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/gui/shape.py +21 -37
  23. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/gui/slider.py +52 -58
  24. batframework-1.0.8a6/src/batFramework/gui/textInput.py +247 -0
  25. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/gui/toggle.py +27 -41
  26. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/gui/widget.py +68 -35
  27. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/manager.py +17 -5
  28. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/object.py +17 -8
  29. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/particle.py +22 -8
  30. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/resourceManager.py +18 -2
  31. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/scene.py +50 -20
  32. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/sceneManager.py +52 -28
  33. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/scrollingSprite.py +7 -8
  34. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/stateMachine.py +9 -6
  35. batframework-1.0.8a6/src/batFramework/templates/__init__.py +2 -0
  36. batframework-1.0.8a6/src/batFramework/templates/character.py +44 -0
  37. batframework-1.0.8a6/src/batFramework/templates/states.py +166 -0
  38. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/time.py +54 -28
  39. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/transition.py +25 -12
  40. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/triggerZone.py +1 -1
  41. batframework-1.0.8a6/src/batFramework/utils.py +149 -0
  42. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batframework.egg-info/PKG-INFO +3 -15
  43. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batframework.egg-info/SOURCES.txt +4 -0
  44. batframework-1.0.8a3/src/batFramework/animatedSprite.py +0 -167
  45. batframework-1.0.8a3/src/batFramework/gui/textInput.py +0 -137
  46. batframework-1.0.8a3/src/batFramework/utils.py +0 -59
  47. {batframework-1.0.8a3 → batframework-1.0.8a6}/LICENCE +0 -0
  48. {batframework-1.0.8a3 → batframework-1.0.8a6}/setup.cfg +0 -0
  49. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/action.py +0 -0
  50. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/actionContainer.py +0 -0
  51. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/camera.py +0 -0
  52. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/constants.py +0 -0
  53. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/easingController.py +0 -0
  54. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/entity.py +0 -0
  55. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/gui/__init__.py +0 -0
  56. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/gui/button.py +0 -0
  57. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/gui/constraints/__init__.py +0 -0
  58. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/gui/container.py +0 -0
  59. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/gui/debugger.py +0 -0
  60. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/gui/dialogueBox.py +0 -0
  61. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/gui/draggableWidget.py +0 -0
  62. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/gui/indicator.py +0 -0
  63. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/gui/style.py +0 -0
  64. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/gui/styleManager.py +0 -0
  65. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/renderGroup.py +0 -0
  66. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/sprite.py +0 -0
  67. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batFramework/tileset.py +0 -0
  68. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batframework.egg-info/dependency_links.txt +0 -0
  69. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batframework.egg-info/requires.txt +0 -0
  70. {batframework-1.0.8a3 → batframework-1.0.8a6}/src/batframework.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: batframework
3
- Version: 1.0.8a3
3
+ Version: 1.0.8a6
4
4
  Summary: Pygame framework for making games easier.
5
5
  Author-email: Turan Baturay <baturayturan@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/TuranBaturay/batFramework
@@ -12,9 +12,9 @@ Description-Content-Type: text/markdown
12
12
  License-File: LICENCE
13
13
  Requires-Dist: pygame-ce
14
14
 
15
- # batFramework & gamejam Project
15
+ # batFramework
16
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.
17
+ Welcome to the `batFramework`. This README provides an overview of the game framework.
18
18
 
19
19
  ## batFramework
20
20
 
@@ -38,18 +38,6 @@ The `batFramework` is a Python game development framework based on pygame, desig
38
38
 
39
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
40
 
41
- ## gamejam Project
42
41
 
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
42
 
55
43
 
@@ -1,6 +1,6 @@
1
- # batFramework & gamejam Project
1
+ # batFramework
2
2
 
3
- 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.
3
+ Welcome to the `batFramework`. This README provides an overview of the game framework.
4
4
 
5
5
  ## batFramework
6
6
 
@@ -24,18 +24,6 @@ The `batFramework` is a Python game development framework based on pygame, desig
24
24
 
25
25
  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.
26
26
 
27
- ## gamejam Project
28
27
 
29
- 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.
30
-
31
- ### Play the gamejam Project
32
-
33
- 1. Install Python (version 3.10 or higher) and the latest stable version of pygame-ce.
34
- 2. Clone or download this repository.
35
- 3. Navigate to the `gamejam` directory.
36
- 4. Run the game by executing the main script (e.g., `python main.py`).
37
- 5. Play the game and have fun!
38
-
39
- 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.
40
28
 
41
29
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "batframework"
7
- version = "1.0.8a3"
7
+ version = "1.0.8a6"
8
8
  authors = [
9
9
  { name="Turan Baturay", email="baturayturan@gmail.com" }
10
10
  ]
@@ -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 TimeManager, Timer
11
+ from .time import *
12
12
  from .easingController import EasingController
13
13
  from .cutscene import Cutscene, CutsceneManager
14
14
  from .cutsceneBlocks import *
@@ -24,12 +24,15 @@ 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, AnimState
27
+ from .animatedSprite import AnimatedSprite, Animation
28
+ from .character import Character
28
29
  from .stateMachine import State, StateMachine
29
30
  from .scene import Scene
30
31
  from .gui import *
31
32
  from .sceneManager import SceneManager
32
33
  from .manager import Manager
34
+ from .templates import *
35
+ import importlib.metadata
33
36
 
34
37
 
35
38
  def init_screen(resolution: tuple[int, int], flags: int = 0, vsync: int = 0):
@@ -44,6 +47,16 @@ def init_screen(resolution: tuple[int, int], flags: int = 0, vsync: int = 0):
44
47
  )
45
48
 
46
49
 
50
+
51
+ def print_version():
52
+ package_name = "batFramework"
53
+ try:
54
+ version = importlib.metadata.version(package_name)
55
+ print(f"{package_name} version: {version}")
56
+ except importlib.metadata.PackageNotFoundError:
57
+ print(f"{package_name} is not installed")
58
+
59
+
47
60
  def init(
48
61
  resolution: tuple[int, int],
49
62
  flags: int = 0,
@@ -54,6 +67,7 @@ def init(
54
67
  window_title: str = "BatFramework Project",
55
68
  fps_limit: int = 0,
56
69
  ):
70
+ print_version()
57
71
  pygame.display.set_caption(window_title)
58
72
  init_screen(resolution, flags, vsync)
59
73
 
@@ -0,0 +1,176 @@
1
+ import batFramework as bf
2
+ import pygame
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
53
+
54
+ class AnimatedSprite(bf.Entity):
55
+ def __init__(self, size: Optional[Tuple[int, int]] = None) -> None:
56
+ super().__init__(size, no_surface=True)
57
+ self.float_counter: float = 0
58
+ self.animations: Dict[str, Animation] = {}
59
+ self.current_state: Optional[Animation] = None
60
+ self.flipX: bool = False
61
+ self._locked: bool = False
62
+ self._paused: bool = False
63
+ self.animation_end_callback = None
64
+ self.transition_end_animation = None
65
+
66
+ def set_animation_end_callback(self,callback)->Self:
67
+ self.animation_end_callback = callback
68
+ return self
69
+
70
+ @property
71
+ def paused(self) -> bool:
72
+ return self._paused
73
+
74
+ @paused.setter
75
+ def paused(self, value: bool) -> None:
76
+ self._paused = value
77
+
78
+ def toggle_pause(self) -> None:
79
+ self.paused = not self.paused
80
+
81
+ def set_counter(self, value: float) -> None:
82
+ self.float_counter = value
83
+
84
+ def set_frame(self, frame_index: int) -> None:
85
+ if not self.current_state:
86
+ return
87
+ self.set_counter(sum(self.current_state.duration_list[:frame_index]))
88
+
89
+ def lock(self) -> None:
90
+ self._locked = True
91
+
92
+ def unlock(self) -> None:
93
+ self._locked = False
94
+
95
+ def set_flipX(self, value: bool) -> None:
96
+ self.flipX = value
97
+
98
+ def remove_animation(self, name: str) -> bool:
99
+ if name not in self.animations:
100
+ return False
101
+ self.animations.pop(name)
102
+ if self.current_state and self.current_state.name == name:
103
+ self.current_state = (
104
+ list(self.animations.values())[0] if self.animations else None
105
+ )
106
+ return True
107
+
108
+ def add_animation(
109
+ self,
110
+ animation:Animation
111
+ ) -> bool:
112
+ if animation.name in self.animations:
113
+ return False
114
+ self.animations[animation.name] = animation
115
+ return True
116
+
117
+ def set_animation(
118
+ self, state: str, reset_counter: bool = True, lock: bool = False
119
+ ) -> bool:
120
+ if state not in self.animations or self._locked:
121
+ return False
122
+
123
+ animation = self.animations[state]
124
+ self.current_state = animation
125
+
126
+ if self.current_state.frames:
127
+ self.rect = self.current_state.frames[0].get_frect(center=self.rect.center)
128
+
129
+ if reset_counter or (self.float_counter > animation.duration_list_length):
130
+ self.float_counter = 0
131
+
132
+ if lock:
133
+ self.lock()
134
+
135
+ if self.transition_end_animation is not None:
136
+ self.transition_end_animation = None
137
+ return True
138
+
139
+ def transition_to_animation(self,transition:str,animation:str)->Self:
140
+ self.set_animation(transition)
141
+ self.transition_end_animation = animation
142
+ return self
143
+
144
+ def get_current_animation(self) -> Optional[Animation]:
145
+ return self.current_state
146
+
147
+ def update(self, dt: float) -> None:
148
+ s = self.get_current_animation()
149
+ if self.animations and s is not None:
150
+ if not self.paused:
151
+ self.float_counter += 60 * dt
152
+ if self.float_counter > s.duration_list_length:
153
+ if self.transition_end_animation is not None:
154
+ # print(f"{self.transition_end_animation=}, {self.get_current_animation()=}")
155
+ self.set_animation(self.transition_end_animation)
156
+ if self.animation_end_callback is not None:
157
+ self.animation_end_callback()
158
+ self.float_counter = 0
159
+ super().update(dt)
160
+
161
+
162
+ def get_current_frame(self)->pygame.Surface:
163
+ return self.current_state.get_frame(self.float_counter, self.flipX)
164
+
165
+ def draw(self, camera: bf.Camera) -> None:
166
+ if (
167
+ not self.visible
168
+ or not camera.rect.colliderect(self.rect)
169
+ or not self.current_state
170
+ ):
171
+ return
172
+ camera.surface.blit(
173
+ self.get_current_frame(),
174
+ camera.world_to_screen(self.rect),
175
+ )
176
+ return
@@ -68,7 +68,7 @@ class AudioManager(metaclass=bf.Singleton):
68
68
  self.sounds[name]["sound"].play()
69
69
  return True
70
70
  except KeyError:
71
- # print(f"Sound '{name}' not loaded in AudioManager.")
71
+ print(f"Sound '{name}' not loaded in AudioManager.")
72
72
  return False
73
73
 
74
74
  def stop_sound(self, name) -> bool:
@@ -77,7 +77,7 @@ class AudioManager(metaclass=bf.Singleton):
77
77
  return True
78
78
  except KeyError:
79
79
  return False
80
- # print(f"Sound '{name}' not loaded in AudioManager.")
80
+ print(f"Sound '{name}' not loaded in AudioManager.")
81
81
 
82
82
  def load_music(self, name, path):
83
83
  self.musics[name] = bf.ResourceManager().get_path(path)
@@ -0,0 +1,27 @@
1
+ import batFramework as bf
2
+ from .stateMachine import State
3
+ from .animatedSprite import AnimatedSprite
4
+ from .dynamicEntity import DynamicEntity
5
+
6
+ class Character(AnimatedSprite,DynamicEntity):
7
+ def __init__(self) -> None:
8
+ super().__init__()
9
+ self.state_machine = bf.StateMachine(self)
10
+ self.do_setup_animations()
11
+ self.do_setup_states()
12
+
13
+ def set_state(self,state_name:str):
14
+ self.state_machine.set_state(state_name)
15
+
16
+ def get_current_state(self)->State:
17
+ return self.state_machine.get_current_state()
18
+
19
+ def update(self, dt: float) -> None:
20
+ self.state_machine.update(dt)
21
+ super().update(dt)
22
+
23
+ def do_setup_states(self):
24
+ pass
25
+
26
+ def do_setup_animations(self):
27
+ pass
@@ -1,8 +1,11 @@
1
1
  import batFramework as bf
2
-
2
+ from typing import TYPE_CHECKING
3
3
 
4
4
  class CutsceneBlock: ...
5
5
 
6
+ if TYPE_CHECKING:
7
+ from .cutsceneBlocks import CutsceneBlock
8
+
6
9
 
7
10
  class Cutscene: ...
8
11
 
@@ -58,7 +61,7 @@ class CutsceneManager(metaclass=bf.Singleton):
58
61
 
59
62
  class Cutscene:
60
63
  def __init__(self) -> None:
61
- self.cutscene_blocks = []
64
+ self.cutscene_blocks : list[CutsceneBlock] = []
62
65
  self.block_index = 0
63
66
  self.end_blocks: list[CutsceneBlock] = []
64
67
  self.ended = False
@@ -1,7 +1,7 @@
1
1
  import batFramework as bf
2
2
  from .cutscene import Cutscene, CutsceneManager
3
3
  from .transition import *
4
-
4
+ from typing import Optional,Callable
5
5
 
6
6
  # Define the base CutsceneBlock class
7
7
  class CutsceneBlock:
@@ -150,7 +150,6 @@ class SceneTransitionBlock(CutsceneBlock):
150
150
  # Start the timer to handle the end of the transition
151
151
  self.timer.start()
152
152
 
153
-
154
153
  class DelayBlock(CutsceneBlock):
155
154
  def __init__(self, duration) -> None:
156
155
  super().__init__()
@@ -160,12 +159,11 @@ class DelayBlock(CutsceneBlock):
160
159
  super().start()
161
160
  self.timer.start()
162
161
 
163
-
164
162
  class FunctionBlock(CutsceneBlock):
165
- def __init__(self, func) -> None:
163
+ def __init__(self, func : Optional[Callable]) -> None:
166
164
  self.function = func
167
165
 
168
166
  def start(self):
169
167
  super().start()
170
- self.function()
168
+ if self.function : self.function()
171
169
  self.end()
@@ -8,15 +8,22 @@ class DynamicEntity(bf.Entity):
8
8
  self,
9
9
  size: None | tuple[int, int] = None,
10
10
  surface_flags: int = 0,
11
- convert_alpha: bool = False,
11
+ convert_alpha: bool = False,*args,**kwargs
12
12
  ) -> None:
13
- super().__init__(size, surface_flags, convert_alpha)
13
+ super().__init__(size, surface_flags, convert_alpha,*args,**kwargs)
14
14
  self.velocity = pygame.math.Vector2(0, 0)
15
+ self.ignore_collisions : bool = False
15
16
 
16
- def on_collideX(self, collider: Self):
17
+ def on_collideX(self, collider: "DynamicEntity"):
18
+ """
19
+ Return true if collision
20
+ """
17
21
  return False
18
22
 
19
- def on_collideY(self, collider: Self):
23
+ def on_collideY(self, collider: "DynamicEntity"):
24
+ """
25
+ Return true if collision
26
+ """
20
27
  return False
21
28
 
22
29
  def move_by_velocity(self, dt) -> None:
@@ -51,7 +51,7 @@ class easing(Enum):
51
51
  EASE_IN = (0.95, 0, 1, 0.55)
52
52
  EASE_OUT = (0.5, 1, 0.5, 1)
53
53
  EASE_IN_OUT = (0.55, 0, 0.45, 1)
54
- EASE_IN_OUT_ELASTIC = (0.39, -0.55, 0.3, 1.3)
54
+ EASE_IN_OUT_ELASTIC = (0.76,-0.36,0.41,1.34)
55
55
 
56
56
  def __init__(self, *control_points):
57
57
  self.control_points = control_points
@@ -110,4 +110,4 @@ class actionType(Enum):
110
110
  class textMode(Enum):
111
111
  ALPHABETICAL = 0
112
112
  NUMERICAL = 1
113
- ALPHANUMERIC = 3
113
+ ALPHANUMERICAL = 3
@@ -42,7 +42,7 @@ class FontManager(metaclass=Singleton):
42
42
  filename = name # if name is not given, name is the filename
43
43
  self.FONTS[filename] = {}
44
44
  # fill the dict
45
- for size in range(self.MIN_FONT_SIZE, self.MAX_FONT_SIZE, 2):
45
+ for size in range(self.MIN_FONT_SIZE, self.MAX_FONT_SIZE+1, 2):
46
46
  self.FONTS[filename][size] = pygame.font.Font(path, size=size)
47
47
 
48
48
  def load_sysfont(self, font_name: str | None, key: str | None = ""):
@@ -52,7 +52,7 @@ class FontManager(metaclass=Singleton):
52
52
  raise FileNotFoundError(f"Requested font '{font_name}' was not found")
53
53
  self.FONTS[font_name] = {}
54
54
 
55
- for size in range(self.MIN_FONT_SIZE, self.MAX_FONT_SIZE, 2):
55
+ for size in range(self.MIN_FONT_SIZE, self.MAX_FONT_SIZE+1, 2):
56
56
  self.FONTS[key][size] = pygame.font.SysFont(font_name, size=size)
57
57
 
58
58
  def get_font(
@@ -27,7 +27,7 @@ class ClickableWidget(Shape, InteractiveWidget):
27
27
  self.set_debug_color("cyan")
28
28
  self.set_relief(self.unpressed_relief)
29
29
 
30
- def set_unpressed_relief(self, relief: int = 0) -> Self:
30
+ def set_unpressed_relief(self, relief: int) -> Self:
31
31
  if relief == self.unpressed_relief:
32
32
  return self
33
33
  self.unpressed_relief = relief
@@ -36,18 +36,17 @@ class ClickableWidget(Shape, InteractiveWidget):
36
36
  self.set_relief(relief)
37
37
  return self
38
38
 
39
- def set_silent_focus(self, value: bool) -> Self:
40
- self.silent_focus = value
41
- return self
42
-
43
- def set_pressed_relief(self, relief: int = 0) -> Self:
39
+ def set_pressed_relief(self, relief: int) -> Self:
44
40
  if relief == self.pressed_relief:
45
41
  return self
46
42
  self.pressed_relief = relief
47
43
  self.dirty_shape = True
48
44
  if self.is_pressed:
49
45
  self.set_relief(relief)
46
+ return self
50
47
 
48
+ def set_silent_focus(self, value: bool) -> Self:
49
+ self.silent_focus = value
51
50
  return self
52
51
 
53
52
  def set_click_down_sound(self, sound_name: str) -> Self:
@@ -141,15 +140,16 @@ class ClickableWidget(Shape, InteractiveWidget):
141
140
  if not self.get_focus():
142
141
  return
143
142
  self.is_pressed = True
144
- bf.AudioManager().play_sound(self.click_down_sound)
145
-
143
+ if self.click_down_sound:
144
+ bf.AudioManager().play_sound(self.click_down_sound)
146
145
  pygame.mouse.set_cursor(self.click_cursor)
147
146
  self.set_relief(self.pressed_relief)
148
147
 
149
148
  def do_on_click_up(self, button) -> None:
150
149
  if self.enabled and button == 1 and self.is_pressed:
151
150
  self.is_pressed = False
152
- bf.AudioManager().play_sound(self.click_up_sound)
151
+ if self.click_up_sound:
152
+ bf.AudioManager().play_sound(self.click_up_sound)
153
153
  self.set_relief(self.unpressed_relief)
154
154
  self.click()
155
155
 
@@ -217,3 +217,4 @@ class ClickableWidget(Shape, InteractiveWidget):
217
217
  self._paint_disabled()
218
218
  elif self.is_hovered:
219
219
  self._paint_hovered()
220
+