batframework 1.0.8a13__tar.gz → 1.0.8a14__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 (69) hide show
  1. {batframework-1.0.8a13/src/batframework.egg-info → batframework-1.0.8a14}/PKG-INFO +1 -1
  2. {batframework-1.0.8a13 → batframework-1.0.8a14}/pyproject.toml +1 -1
  3. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/__init__.py +2 -2
  4. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/animatedSprite.py +1 -1
  5. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/character.py +1 -1
  6. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/constants.py +4 -0
  7. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/cutscene.py +7 -5
  8. batframework-1.0.8a13/src/batFramework/entity.py → batframework-1.0.8a14/src/batFramework/drawable.py +3 -2
  9. batframework-1.0.8a13/src/batFramework/object.py → batframework-1.0.8a14/src/batFramework/entity.py +14 -13
  10. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/container.py +1 -1
  11. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/debugger.py +1 -1
  12. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/label.py +18 -40
  13. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/root.py +0 -6
  14. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/widget.py +1 -1
  15. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/manager.py +33 -32
  16. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/particle.py +1 -1
  17. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/scene.py +1 -34
  18. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/sceneManager.py +5 -23
  19. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/sprite.py +2 -2
  20. batframework-1.0.8a13/src/batFramework/time.py → batframework-1.0.8a14/src/batFramework/timeManager.py +0 -2
  21. batframework-1.0.8a14/src/batFramework/utils.py +248 -0
  22. {batframework-1.0.8a13 → batframework-1.0.8a14/src/batframework.egg-info}/PKG-INFO +1 -1
  23. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batframework.egg-info/SOURCES.txt +2 -2
  24. batframework-1.0.8a13/src/batFramework/utils.py +0 -149
  25. {batframework-1.0.8a13 → batframework-1.0.8a14}/LICENCE +0 -0
  26. {batframework-1.0.8a13 → batframework-1.0.8a14}/README.md +0 -0
  27. {batframework-1.0.8a13 → batframework-1.0.8a14}/setup.cfg +0 -0
  28. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/action.py +0 -0
  29. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/actionContainer.py +0 -0
  30. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/animation.py +0 -0
  31. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/audioManager.py +0 -0
  32. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/camera.py +0 -0
  33. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/cutsceneBlocks.py +0 -0
  34. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/dynamicEntity.py +0 -0
  35. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/easingController.py +0 -0
  36. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/enums.py +0 -0
  37. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/fontManager.py +0 -0
  38. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/__init__.py +0 -0
  39. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/button.py +0 -0
  40. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/clickableWidget.py +0 -0
  41. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/constraints/__init__.py +0 -0
  42. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/constraints/constraints.py +0 -0
  43. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/dialogueBox.py +0 -0
  44. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/draggableWidget.py +0 -0
  45. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/image.py +0 -0
  46. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/indicator.py +0 -0
  47. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/interactiveWidget.py +0 -0
  48. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/layout.py +0 -0
  49. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/meter.py +0 -0
  50. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/radioButton.py +0 -0
  51. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/shape.py +0 -0
  52. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/slider.py +0 -0
  53. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/style.py +0 -0
  54. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/styleManager.py +0 -0
  55. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/textInput.py +0 -0
  56. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/gui/toggle.py +0 -0
  57. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/renderGroup.py +0 -0
  58. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/resourceManager.py +0 -0
  59. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/scrollingSprite.py +0 -0
  60. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/stateMachine.py +0 -0
  61. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/templates/__init__.py +0 -0
  62. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/templates/character.py +0 -0
  63. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/templates/states.py +0 -0
  64. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/tileset.py +0 -0
  65. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/transition.py +0 -0
  66. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batFramework/triggerZone.py +0 -0
  67. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batframework.egg-info/dependency_links.txt +0 -0
  68. {batframework-1.0.8a13 → batframework-1.0.8a14}/src/batframework.egg-info/requires.txt +0 -0
  69. {batframework-1.0.8a13 → batframework-1.0.8a14}/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.8a13
3
+ Version: 1.0.8a14
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
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "batframework"
7
- version = "1.0.8a13"
7
+ version = "1.0.8a14"
8
8
  description = "Pygame framework for making games easier."
9
9
  readme = "README.md"
10
10
  classifiers = [ "Programming Language :: Python :: 3", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent",]
@@ -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,8 +17,8 @@ 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
@@ -3,7 +3,7 @@ import pygame
3
3
  from typing import List, Dict, Tuple, Union, Optional, Self
4
4
  from .animation import Animation
5
5
 
6
- class AnimatedSprite(bf.Entity):
6
+ class AnimatedSprite(bf.Drawable):
7
7
  def __init__(self, size: Optional[Tuple[int, int]] = None,*args,**kwargs) -> None:
8
8
  super().__init__(size, no_surface=True,*args,**kwargs)
9
9
  self.float_counter: float = 0
@@ -3,7 +3,7 @@ from .stateMachine import State
3
3
  from .animatedSprite import AnimatedSprite
4
4
  from .dynamicEntity import DynamicEntity
5
5
 
6
- class Character(AnimatedSprite,DynamicEntity):
6
+ class Character(DynamicEntity,AnimatedSprite):
7
7
  def __init__(self,*args,**kwargs) -> None:
8
8
  super().__init__(*args,**kwargs)
9
9
  self.state_machine = bf.StateMachine(self)
@@ -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):
@@ -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
 
@@ -1,10 +1,10 @@
1
1
  from typing import Any, Self
2
2
  import pygame
3
3
  import batFramework as bf
4
- from .object import Object
4
+ from .entity import Entity
5
5
 
6
6
 
7
- class Entity(Object):
7
+ class Drawable(Entity):
8
8
  """
9
9
  Basic entity class
10
10
  """
@@ -19,6 +19,7 @@ class Entity(Object):
19
19
  ) -> None:
20
20
  super().__init__()
21
21
  self.visible: bool = True
22
+ self.render_order: int = 0
22
23
  self.rect.size = (10, 10) if size is None else size
23
24
  self.convert_alpha: bool = convert_alpha
24
25
  self.surface_flags: int = surface_flags
@@ -7,7 +7,7 @@ if TYPE_CHECKING:
7
7
  from .camera import Camera
8
8
 
9
9
 
10
- class Object:
10
+ class Entity:
11
11
  __count = 0
12
12
  __available_uid = set()
13
13
  __used_uid = set()
@@ -17,18 +17,17 @@ class Object:
17
17
  self.tags: list[str] = []
18
18
  self.parent_scene: bf.Scene | None = None
19
19
  self.debug_color: tuple | str = "red"
20
- self.render_order: int = 0
21
- self.uid: int = Object.__count
22
- Object.__used_uid.add(self.uid)
20
+ self.uid: int = Entity.__count
21
+ Entity.__used_uid.add(self.uid)
23
22
 
24
- if Object.__available_uid:
25
- self.name = Object.__available_uid.pop()
23
+ if Entity.__available_uid:
24
+ self.name = Entity.__available_uid.pop()
26
25
  else:
27
- self.name = Object.__count
28
- Object.__count += 1
26
+ self.name = Entity.__count
27
+ Entity.__count += 1
29
28
 
30
29
  def __del__(self):
31
- Object.__available_uid.add(self.uid)
30
+ Entity.__available_uid.add(self.uid)
32
31
 
33
32
  def set_position(self, x, y) -> Self:
34
33
  self.rect.topleft = x, y
@@ -62,11 +61,13 @@ class Object:
62
61
  pass
63
62
 
64
63
  def set_uid(self, uid: int) -> Self:
65
- if uid in Object.__used_uid:
64
+ if uid in Entity.__used_uid:
66
65
  print(f"set_uid error : UID '{uid}' is already in use")
67
66
  return self
68
67
  self.uid = uid
69
- Object.__used_uid.add(uid)
68
+ if uid in Entity.__used_uid:
69
+ Entity.__used_uid.remove(uid)
70
+ Entity.__used_uid.add(uid)
70
71
  return self
71
72
 
72
73
  def add_tags(self, *tags) -> Self:
@@ -87,7 +88,7 @@ class Object:
87
88
 
88
89
  def process_event(self, event: pygame.Event) -> bool:
89
90
  """
90
- Returns bool : True if the method is blocking (no propagation to next object of the scene)
91
+ Returns bool : True if the method is blocking (no propagation to next Entity of the scene)
91
92
  """
92
93
  if event.consumed:
93
94
  return
@@ -112,7 +113,7 @@ class Object:
112
113
 
113
114
  def update(self, dt: float) -> None:
114
115
  """
115
- Update method to be overriden by subclasses of object (must call do_update and do_reset_actions)
116
+ Update method to be overriden by subclasses of Entity (must call do_update and do_reset_actions)
116
117
  """
117
118
  self.do_update(dt)
118
119
  self.do_reset_actions()
@@ -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)
@@ -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
@@ -205,35 +192,26 @@ class Label(Shape):
205
192
  return self.text
206
193
 
207
194
  def _render_font(self, params: dict) -> pygame.Surface:
208
- key = tuple(params.values())
209
-
210
- cached_value = Label._text_cache.get(key, None)
211
195
 
212
196
  if self.draw_mode == bf.drawMode.SOLID:
213
- if cached_value is None:
214
- params.pop("font_name")
215
-
216
- # save old settings
217
- old_italic = self.font_object.get_italic()
218
- old_bold = self.font_object.get_bold()
219
- old_underline = self.font_object.get_underline()
220
-
221
- # setup font
222
- self.font_object.set_italic(self.is_italic)
223
- self.font_object.set_bold(self.is_bold)
224
- self.font_object.set_underline(self.is_underlined)
225
-
226
- surf = self.font_object.render(**params)
227
-
228
- # reset font
229
- self.font_object.set_italic(old_italic)
230
- self.font_object.set_bold(old_bold)
231
- self.font_object.set_underline(old_underline)
232
-
233
- if self.do_caching:
234
- Label._text_cache[key] = surf
235
- else:
236
- 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)
237
215
  else:
238
216
  params.pop("font_name")
239
217
  surf = self.font_object.render(**params)
@@ -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"] = []
@@ -1,23 +1,24 @@
1
1
  import batFramework as bf
2
2
  import pygame
3
3
  import asyncio
4
- import random
5
4
 
6
5
  class Manager(bf.SceneManager):
7
6
  def __init__(self, *initial_scene_list) -> None:
8
- # random.seed("random")
9
7
  super().__init__()
10
- self._screen: pygame.Surface | None = bf.const.SCREEN
11
- self._timeManager = bf.TimeManager()
12
- self._cutsceneManager = bf.CutsceneManager()
13
- self._cutsceneManager.set_manager(self)
14
- self._clock: pygame.Clock = pygame.Clock()
15
- self._is_async_running : bool = False
16
- self._running = False
8
+ self.debug_mode: bf.enums.debugMode = bf.debugMode.HIDDEN
9
+ self.screen: pygame.Surface | None = bf.const.SCREEN
10
+ self.timeManager = bf.TimeManager()
11
+ self.cutsceneManager = bf.CutsceneManager()
12
+ self.cutsceneManager.set_manager(self)
13
+ self.clock: pygame.Clock = pygame.Clock()
14
+ self.is_async_running : bool = False
15
+ self.running = False
17
16
  pygame.mouse.set_cursor(bf.const.DEFAULT_CURSOR)
18
17
  self.do_pre_init()
19
18
  self.init_scenes(*initial_scene_list)
20
- self.set_sharedVar("clock", self._clock)
19
+ bf.ResourceManager().set_sharedVar("clock", self.clock)
20
+ bf.ResourceManager().set_sharedVar("debug_mode", self.debug_mode)
21
+
21
22
  self.do_init()
22
23
 
23
24
  @staticmethod
@@ -39,14 +40,14 @@ class Manager(bf.SceneManager):
39
40
  print("=" * 50)
40
41
 
41
42
  # Print the timers information
42
- print(self._timeManager)
43
+ print(self.timeManager)
43
44
 
44
45
  # End with a visual separator
45
46
  print("=" * 50 + "\n")
46
47
 
47
48
 
48
49
  def get_fps(self) -> float:
49
- return self._clock.get_fps()
50
+ return self.clock.get_fps()
50
51
 
51
52
  def do_init(self) -> None:
52
53
  pass
@@ -55,67 +56,67 @@ class Manager(bf.SceneManager):
55
56
  pass
56
57
 
57
58
  def stop(self) -> None:
58
- self._running = False
59
+ self.running = False
59
60
 
60
61
  async def run_async(self):
61
- if self._running:
62
+ if self.running:
62
63
  print("Error : Already running")
63
64
  return
64
- self._is_async_running = True
65
- self._running = True
65
+ self.is_async_running = True
66
+ self.running = True
66
67
  dt: float = 0
67
- while self._running:
68
+ while self.running:
68
69
  for event in pygame.event.get():
69
70
  event.consumed = False
70
71
  self.process_event(event)
71
72
  if not event.consumed:
72
73
  if event.type == pygame.QUIT:
73
- self._running = False
74
+ self.running = False
74
75
  break
75
76
  if event.type == pygame.VIDEORESIZE and not (
76
77
  bf.const.FLAGS & pygame.SCALED
77
78
  ):
78
79
  bf.const.set_resolution((event.w, event.h))
79
80
  # update
80
- self._timeManager.update(dt)
81
- self._cutsceneManager.update(dt)
81
+ self.timeManager.update(dt)
82
+ self.cutsceneManager.update(dt)
82
83
  self.update(dt)
83
84
  # render
84
- self._screen.fill((0, 0, 0))
85
- self.draw(self._screen)
85
+ self.screen.fill((0, 0, 0))
86
+ self.draw(self.screen)
86
87
  pygame.display.flip()
87
- dt = self._clock.tick(bf.const.FPS) / 1000
88
+ dt = self.clock.tick(bf.const.FPS) / 1000
88
89
  # dt = min(dt, 0.02) dirty fix for dt being too high when window not focused for a long time
89
90
  await asyncio.sleep(0)
90
91
  pygame.quit()
91
92
 
92
93
 
93
94
  def run(self) -> None:
94
- if self._running:
95
+ if self.running:
95
96
  print("Error : Already running")
96
97
  return
97
- self._running = True
98
+ self.running = True
98
99
  dt: float = 0
99
- while self._running:
100
+ while self.running:
100
101
  for event in pygame.event.get():
101
102
  event.consumed = False
102
103
  self.process_event(event)
103
104
  if not event.consumed:
104
105
  if event.type == pygame.QUIT:
105
- self._running = False
106
+ self.running = False
106
107
  break
107
108
  if event.type == pygame.VIDEORESIZE and not (
108
109
  bf.const.FLAGS & pygame.SCALED
109
110
  ):
110
111
  bf.const.set_resolution((event.w, event.h))
111
112
  # update
112
- self._timeManager.update(dt)
113
- self._cutsceneManager.update(dt)
113
+ self.timeManager.update(dt)
114
+ self.cutsceneManager.update(dt)
114
115
  self.update(dt)
115
116
  # render
116
- self._screen.fill((0, 0, 0))
117
- self.draw(self._screen)
117
+ self.screen.fill((0, 0, 0))
118
+ self.draw(self.screen)
118
119
  pygame.display.flip()
119
- dt = self._clock.tick(bf.const.FPS) / 1000
120
+ dt = self.clock.tick(bf.const.FPS) / 1000
120
121
  # dt = min(dt, 0.02) dirty fix for dt being too high when window not focused for a long time
121
122
  pygame.quit()
@@ -78,7 +78,7 @@ class DirectionalParticle(BasicParticle):
78
78
  super().update_surface()
79
79
 
80
80
 
81
- class ParticleGenerator(bf.Entity):
81
+ class ParticleGenerator(bf.Drawable):
82
82
  def __init__(self) -> None:
83
83
  super().__init__((0, 0))
84
84
  self.particles: list[Particle] = []
@@ -70,35 +70,6 @@ class Scene:
70
70
  """Get the scene index."""
71
71
  return self.scene_index
72
72
 
73
- def set_sharedVar(self, name: str, value: Any) -> bool:
74
- """
75
- Set a shared variable in the manager.
76
-
77
- Args:
78
- name: Name of the shared variable.
79
- value: Value to set.
80
-
81
- Returns:
82
- bool: True if setting was successful, False otherwise.
83
- """
84
- if not self.manager:
85
- return False
86
- return self.manager.set_sharedVar(name, value)
87
-
88
- def get_sharedVar(self, name: str, error_value=None) -> Any:
89
- """
90
- Get a shared variable from the manager.
91
-
92
- Args:
93
- name: Name of the shared variable.
94
-
95
- Returns:
96
- Any: Value of the shared variable.
97
- """
98
- if not self.manager:
99
- return error_value
100
- return self.manager.get_sharedVar(name, error_value)
101
-
102
73
  def do_when_added(self):
103
74
  pass
104
75
 
@@ -277,7 +248,6 @@ class Scene:
277
248
  self.actions.reset()
278
249
  self.early_actions.reset()
279
250
 
280
-
281
251
  if self.entities_to_add:
282
252
  for e in self.entities_to_add:
283
253
  self.world_entities[e] = None
@@ -337,7 +307,7 @@ class Scene:
337
307
 
338
308
  def _draw_camera(self, camera: bf.Camera, entity_list):
339
309
  _ = [entity.draw(camera) for entity in entity_list]
340
- debugMode = self.manager.debug_mode
310
+ debugMode = bf.ResourceManager().get_sharedVar("debug_mode")
341
311
  # Draw outlines for world entities if required
342
312
  if debugMode == bf.debugMode.OUTLINES:
343
313
  [self.debug_entity(e, camera) for e in entity_list]
@@ -355,15 +325,12 @@ class Scene:
355
325
  self.set_active(True)
356
326
  self.set_visible(True)
357
327
  self.root.clear_hovered()
358
- # self.root.clear_focused()
359
328
  self.root.build()
360
329
  bf.TimeManager().activate_register(self.name)
361
330
  self.do_on_enter()
362
- # self.root.visit(lambda e : e.resolve_constraints())
363
331
 
364
332
  def on_exit(self):
365
333
  self.root.clear_hovered()
366
- # self.root.clear_focused()
367
334
  self.set_active(False)
368
335
  self.set_visible(False)
369
336
  self.actions.hard_reset()
@@ -2,7 +2,6 @@ import batFramework as bf
2
2
  import pygame
3
3
  from typing import Self
4
4
 
5
-
6
5
  def swap(lst, index1, index2):
7
6
  lst[index1], lst[index2] = lst[index2], lst[index1]
8
7
 
@@ -11,11 +10,6 @@ class SceneManager:
11
10
  def __init__(self) -> None:
12
11
  self.scenes: list[bf.Scene] = []
13
12
  self.shared_events = {pygame.WINDOWRESIZED}
14
-
15
- self.set_sharedVar("in_cutscene", False)
16
- self.set_sharedVar("player_has_control", True)
17
- self.old_player_control = True
18
- self.debug_mode: bf.enums.debugMode = bf.debugMode.HIDDEN
19
13
  self.current_transitions: dict[str, bf.transition.Transition] = {}
20
14
 
21
15
  def init_scenes(self, *initial_scenes:bf.Scene):
@@ -23,7 +17,6 @@ class SceneManager:
23
17
  s.set_scene_index(index)
24
18
  for s in reversed(initial_scenes):
25
19
  self.add_scene(s)
26
- # self.scenes = list(initial_scenes)
27
20
  self.set_scene(initial_scenes[0].get_name())
28
21
  self.update_scene_states()
29
22
 
@@ -38,7 +31,7 @@ class SceneManager:
38
31
  Print detailed information about the current state of the scenes and shared variables.
39
32
  """
40
33
 
41
- def format_scene_info(scene):
34
+ def format_scene_info(scene:bf.Scene):
42
35
  status = 'Active' if scene.active else 'Inactive'
43
36
  visibility = 'Visible' if scene.visible else 'Invisible'
44
37
  return f"{scene.name:<30} | {status:<8} | {visibility:<10} | Index={scene.scene_index}"
@@ -78,13 +71,6 @@ class SceneManager:
78
71
 
79
72
  print("=" * 50 + "\n")
80
73
 
81
-
82
- def set_sharedVar(self, name, value) -> None:
83
- bf.ResourceManager().set_sharedVar(name,value)
84
-
85
- def get_sharedVar(self, name, error_value=None):
86
- return bf.ResourceManager().get_sharedVar(name, error_value)
87
-
88
74
  def get_current_scene_name(self) -> str:
89
75
  """get the name of the current scene"""
90
76
  return self.scenes[0].get_name()
@@ -106,10 +92,10 @@ class SceneManager:
106
92
  def remove_scene(self, name: str):
107
93
  self.scenes = [s for s in self.scenes if s.name != name]
108
94
 
109
- def has_scene(self, name):
95
+ def has_scene(self, name:str):
110
96
  return any(name == scene.name for scene in self.scenes)
111
97
 
112
- def get_scene(self, name):
98
+ def get_scene(self, name:str):
113
99
  if not self.has_scene(name):
114
100
  return None
115
101
  for scene in self.scenes:
@@ -150,8 +136,6 @@ class SceneManager:
150
136
  def _start_transition(self, target_scene: bf.Scene):
151
137
  target_scene.set_active(True)
152
138
  target_scene.set_visible(True)
153
- self.old_player_control = bool(self.get_sharedVar("player_has_control"))
154
- self.set_sharedVar("player_has_control", False)
155
139
 
156
140
  def _end_transition(self, scene_name, index):
157
141
  self.set_scene(scene_name, index, True)
@@ -177,11 +161,10 @@ class SceneManager:
177
161
  self.scenes[index].do_on_enter_early()
178
162
  target_scene.on_enter()
179
163
 
180
- self.set_sharedVar("player_has_control", self.old_player_control)
181
164
 
182
165
 
183
166
  def cycle_debug_mode(self):
184
- current_index = self.debug_mode.value
167
+ current_index = bf.ResourceManager().get_sharedVar("debug_mode").value
185
168
  next_index = (current_index + 1) % len(bf.debugMode)
186
169
  return bf.debugMode(next_index)
187
170
 
@@ -193,8 +176,7 @@ class SceneManager:
193
176
  and event.type == pygame.KEYDOWN
194
177
  ):
195
178
  if event.key == pygame.K_d:
196
- self.debug_mode = self.cycle_debug_mode()
197
- self.set_sharedVar("debug_mode", self.debug_mode)
179
+ bf.ResourceManager().set_sharedVar("debug_mode", self.cycle_debug_mode())
198
180
  return
199
181
  if event.key == pygame.K_p:
200
182
  self.print_status()
@@ -3,11 +3,11 @@ import pygame
3
3
  from typing import Self
4
4
 
5
5
 
6
- class Sprite(bf.Entity):
6
+ class Sprite(bf.Drawable):
7
7
  def __init__(
8
8
  self,
9
- path=None,
10
9
  size: None | tuple[int, int] = None,
10
+ path=None,
11
11
  convert_alpha: bool = True,
12
12
  ):
13
13
  self.original_surface: pygame.Surface = None
@@ -1,7 +1,5 @@
1
1
  import batFramework as bf
2
2
  from typing import Self
3
-
4
-
5
3
  from typing import Callable, Union, Self
6
4
 
7
5
 
@@ -0,0 +1,248 @@
1
+ import pygame
2
+ import batFramework as bf
3
+ import random
4
+ from .enums import *
5
+ import re
6
+ from typing import Callable, TYPE_CHECKING
7
+ from functools import cache
8
+ if TYPE_CHECKING:
9
+ from .drawable import Drawable
10
+ from .entity import Entity
11
+
12
+
13
+
14
+ class Singleton(type):
15
+ _instances = {}
16
+
17
+ def __call__(cls, *args, **kwargs):
18
+ if cls not in cls._instances:
19
+ cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
20
+ return cls._instances[cls]
21
+
22
+
23
+ class Utils:
24
+
25
+ @staticmethod
26
+ def split_surface(
27
+ surface: pygame.Surface, split_size: tuple[int, int], func=None
28
+ ) -> dict[tuple[int, int], pygame.Surface]:
29
+ """
30
+ Splits a surface into subsurfaces based on a given size and returns a dictionary of them with their coordinates as keys.
31
+
32
+ Args:
33
+ surface (pygame.Surface): The surface to be split.
34
+ split_size (tuple[int, int]): The size of each subsurface (width, height).
35
+ func (callable, optional): A function to apply to each subsurface. Defaults to None.
36
+
37
+ Returns:
38
+ dict[tuple[int, int], pygame.Surface]: A dictionary with (x, y) coordinates as keys and the corresponding subsurfaces as values.
39
+ """
40
+ width, height = surface.get_size()
41
+ res = {}
42
+ for iy, y in enumerate(range(0, height, split_size[1])):
43
+ for ix, x in enumerate(range(0, width, split_size[0])):
44
+ sub = surface.subsurface((x, y, split_size[0], split_size[1]))
45
+
46
+ if func is not None:
47
+ sub = func(sub)
48
+
49
+ res[(ix, iy)] = sub
50
+
51
+ return res
52
+
53
+ @staticmethod
54
+ def filter_text(text_mode: textMode):
55
+ """
56
+ Filters a string based on the specified text mode.
57
+
58
+ Args:
59
+ text_mode (textMode): Mode specifying the type of filtering (ALPHABETICAL, NUMERICAL, ALPHANUMERICAL).
60
+
61
+ Returns:
62
+ callable: A function that takes a string and removes all characters not allowed by the text mode.
63
+
64
+ Raises:
65
+ ValueError: If an unsupported text mode is provided.
66
+ """
67
+
68
+ if text_mode == textMode.ALPHABETICAL:
69
+ pattern = re.compile(r"[^a-zA-Z]")
70
+ elif text_mode == textMode.NUMERICAL:
71
+ pattern = re.compile(r"[^0-9]")
72
+ elif text_mode == textMode.ALPHANUMERICAL:
73
+ pattern = re.compile(r"[^a-zA-Z0-9]")
74
+ else:
75
+ raise ValueError("Unsupported text mode")
76
+
77
+ def filter_function(s: str) -> str:
78
+ return pattern.sub("", s)
79
+
80
+ return filter_function
81
+
82
+
83
+ @staticmethod
84
+ @cache
85
+ def create_spotlight(inside_color, outside_color, radius, radius_stop=None, dest_surf=None,size=None):
86
+ """
87
+ Creates a spotlight effect on a surface with a gradient from inside_color to outside_color.
88
+
89
+ Args:
90
+ inside_color (tuple[int, int, int]): RGB color at the center of the spotlight.
91
+ outside_color (tuple[int, int, int]): RGB color at the outer edge of the spotlight.
92
+ radius (int): Radius of the inner circle.
93
+ radius_stop (int, optional): Radius where the spotlight ends. Defaults to the value of radius.
94
+ dest_surf (pygame.Surface, optional): Surface to draw the spotlight on. Defaults to None.
95
+ size (tuple[int, int], optional): Size of the surface if dest_surf is None. Defaults to a square based on radius_stop.
96
+
97
+ Returns:
98
+ pygame.Surface: The surface with the spotlight effect drawn on it.
99
+ """
100
+
101
+ if radius_stop is None:
102
+ radius_stop = radius
103
+ diameter = radius_stop * 2
104
+
105
+ if dest_surf is None:
106
+ if size is None:
107
+ size = (diameter,diameter)
108
+ dest_surf = pygame.Surface(size, pygame.SRCALPHA)
109
+
110
+ dest_surf.fill((0,0,0,0))
111
+
112
+
113
+ center = dest_surf.get_rect().center
114
+
115
+ if radius_stop != radius:
116
+ for r in range(radius_stop, radius - 1, -1):
117
+ color = [
118
+ inside_color[i] + (outside_color[i] - inside_color[i]) * (r - radius) / (radius_stop - radius)
119
+ for i in range(3)
120
+ ] + [255] # Preserve the alpha channel as fully opaque
121
+ pygame.draw.circle(dest_surf, color, center, r)
122
+ else:
123
+ pygame.draw.circle(dest_surf, inside_color, center, radius)
124
+
125
+ return dest_surf
126
+
127
+ @staticmethod
128
+ def draw_spotlight(dest_surf:pygame.Surface,inside_color,outside_color,radius,radius_stop=None,center=None):
129
+ """
130
+ Draws a spotlight effect directly onto an existing surface.
131
+
132
+ Args:
133
+ dest_surf (pygame.Surface): The surface to draw the spotlight on.
134
+ inside_color (tuple[int, int, int]): RGB color at the center of the spotlight.
135
+ outside_color (tuple[int, int, int]): RGB color at the outer edge of the spotlight.
136
+ radius (int): Radius of the inner circle.
137
+ radius_stop (int, optional): Radius where the spotlight ends. Defaults to the value of radius.
138
+ center (tuple[int, int], optional): Center point of the spotlight. Defaults to the center of dest_surf.
139
+ """
140
+
141
+ if radius_stop is None:
142
+ radius_stop = radius
143
+ center = dest_surf.get_rect().center if center is None else center
144
+ if radius_stop != radius:
145
+ for r in range(radius_stop, radius - 1, -1):
146
+ color = [
147
+ inside_color[i] + (outside_color[i] - inside_color[i]) * (r - radius) / (radius_stop - radius)
148
+ for i in range(3)
149
+ ] + [255]
150
+ pygame.draw.circle(dest_surf, color, center, r)
151
+ else:
152
+ pygame.draw.circle(dest_surf, inside_color, center, radius)
153
+
154
+ @staticmethod
155
+ def animate_move(entity:"Entity", start_pos : tuple[float,float], end_pos:tuple[float,float])->Callable[[float],None]:
156
+ """
157
+ Creates a function to animate the movement of an entity from start_pos to end_pos.
158
+
159
+ Args:
160
+ entity (Entity): The entity to move.
161
+ start_pos (tuple[float, float]): The starting position of the entity.
162
+ end_pos (tuple[float, float]): The ending position of the entity.
163
+
164
+ Returns:
165
+ Callable[[float], None]: A function that updates the entity's position based on a progression value (0 to 1).
166
+ """
167
+ def func(x):
168
+ entity.set_center(start_pos[0]+(end_pos[0]-start_pos[0])*x,start_pos[1]+(end_pos[1]-start_pos[1])*x)
169
+ return func
170
+
171
+ def animate_move_to(entity: "Entity", end_pos: tuple[float, float]) -> Callable[[float], None]:
172
+ """
173
+ Creates a function to animate the movement of an entity to a specified end position, capturing the start position at the start of the animation.
174
+
175
+ Args:
176
+ entity (Entity): The entity to move.
177
+ end_pos (tuple[float, float]): The target position of the entity.
178
+
179
+ Returns:
180
+ Callable[[float], None]: A function that updates the entity's position based on a progression value (0 to 1).
181
+ """
182
+
183
+ # Start position will be captured once when the animation starts
184
+ start_pos = [None]
185
+
186
+ def update_position(progression: float):
187
+ if start_pos[0] is None:
188
+ start_pos[0] = entity.rect.center # Capture the start position at the start of the animation
189
+
190
+ # Calculate new position based on progression
191
+ new_x = start_pos[0][0] + (end_pos[0] - start_pos[0][0]) * progression
192
+ new_y = start_pos[0][1] + (end_pos[1] - start_pos[0][1]) * progression
193
+
194
+ # Set the entity's new position
195
+ entity.set_center(new_x, new_y)
196
+
197
+ return update_position
198
+
199
+ @staticmethod
200
+ def animate_alpha(entity:"Drawable", start : int, end:int)->Callable[[float],None]:
201
+ """
202
+ Creates a function to animate the alpha (transparency) of a drawable entity between a start and end value.
203
+
204
+ Args:
205
+ entity (Drawable): The entity to animate.
206
+ start (int): The starting alpha value (0 to 255).
207
+ end (int): The ending alpha value (0 to 255).
208
+
209
+ Returns:
210
+ Callable[[float], None]: A function that updates the entity's alpha based on a progression value (0 to 1).
211
+ """
212
+ def func(x):
213
+ entity.set_alpha(int(pygame.math.clamp(start+(end-start)*x,0,255)))
214
+ return func
215
+
216
+
217
+
218
+ @staticmethod
219
+ def random_color(min_value: int = 0, max_value: int = 255) -> tuple[int, int, int]:
220
+ """
221
+ Generates a random color as an RGB tuple.
222
+
223
+ Args:
224
+ min_value (int): Minimum value for each RGB component (inclusive). Defaults to 0.
225
+ max_value (int): Maximum value for each RGB component (inclusive). Defaults to 255.
226
+
227
+ Returns:
228
+ tuple[int, int, int]: A tuple representing a random color in RGB format, with each component
229
+ between min_value and max_value.
230
+ """
231
+ return random.randint(min_value, max_value), random.randint(min_value, max_value), random.randint(min_value, max_value)
232
+
233
+ @staticmethod
234
+ def random_point_on_screen(margin: int = 0) -> tuple[int, int]:
235
+ """
236
+ Generates a random point on the screen, considering a margin from the edges.
237
+
238
+ Args:
239
+ margin (int): Margin from the screen edges, where the point won't be generated.
240
+ If margin is less than 0 or greater than the screen resolution, returns (0, 0).
241
+
242
+ Returns:
243
+ tuple[int, int]: A tuple representing a random point (x, y) on the screen within the screen
244
+ resolution minus the margin.
245
+ """
246
+ if margin < 0 or margin > bf.const.RESOLUTION[0] or margin > bf.const.RESOLUTION[1]:
247
+ return 0, 0
248
+ return random.randint(margin, bf.const.RESOLUTION[0] - margin), random.randint(margin, bf.const.RESOLUTION[1] - margin)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: batframework
3
- Version: 1.0.8a13
3
+ Version: 1.0.8a14
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,13 +12,13 @@ src/batFramework/character.py
12
12
  src/batFramework/constants.py
13
13
  src/batFramework/cutscene.py
14
14
  src/batFramework/cutsceneBlocks.py
15
+ src/batFramework/drawable.py
15
16
  src/batFramework/dynamicEntity.py
16
17
  src/batFramework/easingController.py
17
18
  src/batFramework/entity.py
18
19
  src/batFramework/enums.py
19
20
  src/batFramework/fontManager.py
20
21
  src/batFramework/manager.py
21
- src/batFramework/object.py
22
22
  src/batFramework/particle.py
23
23
  src/batFramework/renderGroup.py
24
24
  src/batFramework/resourceManager.py
@@ -28,7 +28,7 @@ src/batFramework/scrollingSprite.py
28
28
  src/batFramework/sprite.py
29
29
  src/batFramework/stateMachine.py
30
30
  src/batFramework/tileset.py
31
- src/batFramework/time.py
31
+ src/batFramework/timeManager.py
32
32
  src/batFramework/transition.py
33
33
  src/batFramework/triggerZone.py
34
34
  src/batFramework/utils.py
@@ -1,149 +0,0 @@
1
- import pygame
2
- from enum import Enum
3
- import os
4
- import batFramework as bf
5
- import json
6
- from .enums import *
7
- import re
8
- from typing import Callable, TYPE_CHECKING, Any
9
- from functools import cache
10
- if TYPE_CHECKING:
11
- from .object import Object
12
- from .entity import Entity
13
-
14
-
15
- class Singleton(type):
16
- _instances = {}
17
-
18
- def __call__(cls, *args, **kwargs):
19
- if cls not in cls._instances:
20
- cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
21
- return cls._instances[cls]
22
-
23
-
24
- class Utils:
25
-
26
- @staticmethod
27
- def split_surface(
28
- surface: pygame.Surface, split_size: tuple[int, int], func=None
29
- ) -> dict[tuple[int, int], pygame.Surface]:
30
- """
31
- Splits a surface into subsurfaces and returns a dictionnary of them
32
- with their tuple coordinates as keys.
33
- Exemple : '(0,0) : Surface'
34
- """
35
- width, height = surface.get_size()
36
- res = {}
37
- for iy, y in enumerate(range(0, height, split_size[1])):
38
- for ix, x in enumerate(range(0, width, split_size[0])):
39
- sub = surface.subsurface((x, y, split_size[0], split_size[1]))
40
-
41
- if func is not None:
42
- sub = func(sub)
43
-
44
- res[(ix, iy)] = sub
45
-
46
- return res
47
-
48
- @staticmethod
49
- def filter_text(text_mode: textMode):
50
- if text_mode == textMode.ALPHABETICAL:
51
- pattern = re.compile(r"[^a-zA-Z]")
52
- elif text_mode == textMode.NUMERICAL:
53
- pattern = re.compile(r"[^0-9]")
54
- elif text_mode == textMode.ALPHANUMERICAL:
55
- pattern = re.compile(r"[^a-zA-Z0-9]")
56
- else:
57
- raise ValueError("Unsupported text mode")
58
-
59
- def filter_function(s: str) -> str:
60
- return pattern.sub("", s)
61
-
62
- return filter_function
63
-
64
-
65
- @staticmethod
66
- @cache
67
- def create_spotlight(inside_color, outside_color, radius, radius_stop=None, dest_surf=None,size=None):
68
- """
69
- Draws a circle spotlight centered on a surface
70
- inner color on the center
71
- gradient towards outside color from radius to radius stop
72
- surface background is made transparent
73
- if des_surf is None:
74
- if size is None : size is radius_stop*radius_stop
75
- returns the newly created surface of size 'size' with the spotlight drawn
76
-
77
- """
78
- if radius_stop is None:
79
- radius_stop = radius
80
- diameter = radius_stop * 2
81
-
82
- if dest_surf is None:
83
- if size is None:
84
- size = (diameter,diameter)
85
- dest_surf = pygame.Surface(size, pygame.SRCALPHA)
86
-
87
- dest_surf.fill((0,0,0,0))
88
-
89
-
90
- center = dest_surf.get_rect().center
91
-
92
- if radius_stop != radius:
93
- for r in range(radius_stop, radius - 1, -1):
94
- color = [
95
- inside_color[i] + (outside_color[i] - inside_color[i]) * (r - radius) / (radius_stop - radius)
96
- for i in range(3)
97
- ] + [255] # Preserve the alpha channel as fully opaque
98
- pygame.draw.circle(dest_surf, color, center, r)
99
- else:
100
- pygame.draw.circle(dest_surf, inside_color, center, radius)
101
-
102
- return dest_surf
103
-
104
- @staticmethod
105
- def draw_spotlight(dest_surf:pygame.Surface,inside_color,outside_color,radius,radius_stop=None,center=None):
106
- if radius_stop is None:
107
- radius_stop = radius
108
- center = dest_surf.get_rect().center if center is None else center
109
- if radius_stop != radius:
110
- for r in range(radius_stop, radius - 1, -1):
111
- color = [
112
- inside_color[i] + (outside_color[i] - inside_color[i]) * (r - radius) / (radius_stop - radius)
113
- for i in range(3)
114
- ] + [255]
115
- pygame.draw.circle(dest_surf, color, center, r)
116
- else:
117
- pygame.draw.circle(dest_surf, inside_color, center, radius)
118
-
119
- @staticmethod
120
- def animate_move(entity:"Object", start_pos : tuple[float,float], end_pos:tuple[float,float])->Callable[[float],None]:
121
- def func(x):
122
- entity.set_center(start_pos[0]+(end_pos[0]-start_pos[0])*x,start_pos[1]+(end_pos[1]-start_pos[1])*x)
123
- return func
124
-
125
- def animate_move_to(entity: "Object", end_pos: tuple[float, float]) -> Callable[[float], None]:
126
- # Start position will be captured once when the animation starts
127
- start_pos = [None]
128
-
129
- def update_position(progression: float):
130
- if start_pos[0] is None:
131
- start_pos[0] = entity.rect.center # Capture the start position at the start of the animation
132
-
133
- # Calculate new position based on progression
134
- new_x = start_pos[0][0] + (end_pos[0] - start_pos[0][0]) * progression
135
- new_y = start_pos[0][1] + (end_pos[1] - start_pos[0][1]) * progression
136
-
137
- # Set the entity's new position
138
- entity.set_center(new_x, new_y)
139
-
140
- return update_position
141
-
142
- @staticmethod
143
- def animate_alpha(entity:"Entity", start : int, end:int)->Callable[[float],None]:
144
- def func(x):
145
- entity.set_alpha(int(pygame.math.clamp(start+(end-start)*x,0,255)))
146
- return func
147
-
148
-
149
-
File without changes