batframework 1.0.8a3__py3-none-any.whl → 1.0.8a6__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 (44) hide show
  1. batFramework/__init__.py +16 -2
  2. batFramework/animatedSprite.py +94 -85
  3. batFramework/audioManager.py +2 -2
  4. batFramework/character.py +27 -0
  5. batFramework/cutscene.py +5 -2
  6. batFramework/cutsceneBlocks.py +3 -5
  7. batFramework/dynamicEntity.py +11 -4
  8. batFramework/enums.py +2 -2
  9. batFramework/fontManager.py +2 -2
  10. batFramework/gui/clickableWidget.py +10 -9
  11. batFramework/gui/constraints/constraints.py +282 -57
  12. batFramework/gui/image.py +14 -14
  13. batFramework/gui/interactiveWidget.py +16 -1
  14. batFramework/gui/label.py +58 -37
  15. batFramework/gui/layout.py +23 -14
  16. batFramework/gui/meter.py +10 -7
  17. batFramework/gui/radioButton.py +1 -1
  18. batFramework/gui/root.py +7 -1
  19. batFramework/gui/shape.py +21 -37
  20. batFramework/gui/slider.py +52 -58
  21. batFramework/gui/textInput.py +161 -51
  22. batFramework/gui/toggle.py +27 -41
  23. batFramework/gui/widget.py +68 -35
  24. batFramework/manager.py +17 -5
  25. batFramework/object.py +17 -8
  26. batFramework/particle.py +22 -8
  27. batFramework/resourceManager.py +18 -2
  28. batFramework/scene.py +50 -20
  29. batFramework/sceneManager.py +52 -28
  30. batFramework/scrollingSprite.py +7 -8
  31. batFramework/stateMachine.py +9 -6
  32. batFramework/templates/__init__.py +2 -0
  33. batFramework/templates/character.py +44 -0
  34. batFramework/templates/states.py +166 -0
  35. batFramework/time.py +54 -28
  36. batFramework/transition.py +25 -12
  37. batFramework/triggerZone.py +1 -1
  38. batFramework/utils.py +92 -2
  39. {batframework-1.0.8a3.dist-info → batframework-1.0.8a6.dist-info}/METADATA +3 -15
  40. batframework-1.0.8a6.dist-info/RECORD +62 -0
  41. {batframework-1.0.8a3.dist-info → batframework-1.0.8a6.dist-info}/WHEEL +1 -1
  42. batframework-1.0.8a3.dist-info/RECORD +0 -58
  43. {batframework-1.0.8a3.dist-info → batframework-1.0.8a6.dist-info}/LICENCE +0 -0
  44. {batframework-1.0.8a3.dist-info → batframework-1.0.8a6.dist-info}/top_level.txt +0 -0
@@ -99,17 +99,16 @@ class ScrollingSprite(bf.Sprite):
99
99
  x += self.original_width
100
100
  return self
101
101
 
102
- def draw(self, camera: bf.Camera) -> int:
102
+ def draw(self, camera: bf.Camera) -> None:
103
103
  if not (
104
104
  self.visible
105
105
  and (self.surface is not None)
106
106
  and camera.rect.colliderect(self.rect)
107
107
  ):
108
- return 0
109
- self.surface.fill((0, 0, 0, 0))
110
- self.surface.fblits(
111
- [(self.original_surface, r) for r in self._get_mosaic_rect_list()]
108
+ return
109
+ # self.surface.fill((0, 0, 0, 0))
110
+ camera.surface.fblits(
111
+ [(self.original_surface, r.move(self.rect.x-camera.rect.x,self.rect.y-camera.rect.y)) for r in self._get_mosaic_rect_list()]
112
112
  )
113
- # pygame.draw.rect(camera.surface,"green",next(self._get_mosaic_rect_list()).move(*self.rect.topleft),1)
114
- camera.surface.blit(self.surface, camera.world_to_screen(self.rect))
115
- return 1
113
+ # camera.surface.blit(self.surface, camera.world_to_screen(self.rect))
114
+ return
@@ -7,11 +7,11 @@ class StateMachine: ...
7
7
  class State:
8
8
  def __init__(self, name: str) -> None:
9
9
  self.name = name
10
- self.parent_entity: bf.Entity | bf.AnimatedSprite = None
10
+ self.parent: bf.Entity | bf.AnimatedSprite = None
11
11
  self.state_machine: StateMachine = None
12
12
 
13
- def set_parent_entity(self, parent_entity: bf.Entity | bf.AnimatedSprite):
14
- self.parent_entity = parent_entity
13
+ def set_parent(self, parent: bf.Entity | bf.AnimatedSprite):
14
+ self.parent = parent
15
15
 
16
16
  def set_stateMachine(self, stateMachine):
17
17
  self.state_machine = stateMachine
@@ -27,16 +27,19 @@ class State:
27
27
 
28
28
 
29
29
  class StateMachine:
30
- def __init__(self, parent_entity) -> None:
30
+ def __init__(self, parent) -> None:
31
31
  self.states: dict[str, State] = {}
32
- self.parent_entity = parent_entity
32
+ self.parent = parent
33
33
  self.current_state = None
34
34
 
35
35
  def add_state(self, state: State):
36
36
  self.states[state.name] = state
37
- state.set_parent_entity(self.parent_entity)
37
+ state.set_parent(self.parent)
38
38
  state.set_stateMachine(self)
39
39
 
40
+ def remove_state(self,state_name: str):
41
+ self.states.pop(state_name,default=None)
42
+
40
43
  def set_state(self, state_name: str):
41
44
  if state_name in self.states:
42
45
  if self.current_state:
@@ -0,0 +1,2 @@
1
+ from .character import *
2
+ from .states import *
@@ -0,0 +1,44 @@
1
+ import batFramework as bf
2
+ import pygame
3
+ from .states import *
4
+
5
+ class Platform2DCharacter(bf.Character):
6
+ def __init__(self):
7
+ super().__init__()
8
+ self.actions = bf.ActionContainer(
9
+ *bf.DirectionalKeyControls(),
10
+ bf.Action("jump").add_key_control(pygame.K_SPACE).set_holding()
11
+ )
12
+ self.on_ground : bool = False
13
+ self.max_jumps = 2
14
+ self.jump_counter = 0
15
+ self.jump_force = 150
16
+ self.speed = 100
17
+ self.acceleration = 30
18
+ self.friction = 0.7
19
+ self.gravity = 300
20
+ self.terminal_velocity = 1000
21
+ self.state_machine.set_state("idle")
22
+
23
+
24
+ def do_setup_animations(self):
25
+ self.add_animation(bf.Animation("idle"))
26
+ self.add_animation(bf.Animation("run"))
27
+ self.add_animation(bf.Animation("jump"))
28
+ self.add_animation(bf.Animation("fall"))
29
+
30
+
31
+ def do_setup_states(self):
32
+ self.state_machine.add_state(Platform2DIdle())
33
+ self.state_machine.add_state(Platform2DRun())
34
+ self.state_machine.add_state(Platform2DJump())
35
+ self.state_machine.add_state(Platform2DFall())
36
+
37
+
38
+
39
+ def do_reset_actions(self) -> None:
40
+ self.actions.reset()
41
+
42
+ def do_process_actions(self, event: pygame.Event) -> None:
43
+ self.actions.process_event(event)
44
+
@@ -0,0 +1,166 @@
1
+ import batFramework as bf
2
+ from typing import TYPE_CHECKING
3
+
4
+ if TYPE_CHECKING:
5
+ from .character import Platform2DCharacter
6
+
7
+
8
+ class CharacterState(bf.State):
9
+ def set_parent(self, parent):
10
+ """Initialize the parent character."""
11
+ res = super().set_parent(parent)
12
+ if res:
13
+ self.parent: Platform2DCharacter = parent
14
+ return res
15
+
16
+ def on_enter(self):
17
+ """Handle state entry."""
18
+ self.parent.set_animation(self.name)
19
+
20
+ def handle_input(self):
21
+ """Process input and update movement direction."""
22
+ if self.parent.actions.is_active("right"):
23
+ self._apply_horizontal_input(self.parent.acceleration, self.parent.speed)
24
+ if self.parent.actions.is_active("left"):
25
+ self._apply_horizontal_input(-self.parent.acceleration, -self.parent.speed)
26
+
27
+ if self.parent.velocity.x > 0:
28
+ self.parent.set_flipX(False)
29
+ elif self.parent.velocity.x < 0:
30
+ self.parent.set_flipX(True)
31
+
32
+
33
+ def _apply_horizontal_input(self, acceleration, limit):
34
+ """Apply input acceleration and enforce speed limit."""
35
+
36
+ self.parent.velocity.x += acceleration
37
+ if abs(self.parent.velocity.x) > abs(limit):
38
+ self.parent.velocity.x = limit
39
+
40
+ def apply_friction(self):
41
+ """Apply friction to horizontal velocity."""
42
+ if (self.parent.actions.is_active("right") or self.parent.actions.is_active("left")):
43
+ return
44
+
45
+ if abs(self.parent.velocity.x) < 0.01: # Threshold for negligible velocity
46
+ self.parent.velocity.x = 0
47
+ else:
48
+ self.parent.velocity.x *= self.parent.friction
49
+
50
+ def apply_gravity(self, dt):
51
+ """Apply gravity to vertical velocity."""
52
+ self.parent.velocity.y += self.parent.gravity * dt
53
+ self.parent.velocity.y = min(self.parent.velocity.y, self.parent.terminal_velocity)
54
+
55
+ def move_character(self, dt):
56
+ """Move the character based on velocity."""
57
+ self.parent.rect.x += self.parent.velocity.x * dt
58
+ self.parent.rect.y += self.parent.velocity.y * dt
59
+
60
+ def update(self, dt):
61
+ """Update the character state."""
62
+ self.handle_input()
63
+ self.apply_physics(dt)
64
+ self.handle_collision()
65
+
66
+ def apply_physics(self, dt):
67
+ """Apply all physics effects."""
68
+ self.apply_friction()
69
+ self.move_character(dt)
70
+ if self.parent.on_ground:
71
+ self.parent.velocity.y = 0 # Stop downward movement on ground
72
+
73
+ def handle_collision(self):
74
+ """Placeholder for collision detection and resolution."""
75
+ pass # Future collision code goes here
76
+
77
+
78
+ class Platform2DIdle(CharacterState):
79
+ def __init__(self) -> None:
80
+ super().__init__("idle")
81
+
82
+ def on_enter(self):
83
+ self.parent.jump_counter = 0
84
+ super().on_enter()
85
+
86
+ def update(self, dt):
87
+ super().update(dt)
88
+
89
+ if not self.parent.on_ground:
90
+ self.parent.set_state("fall")
91
+ elif self.parent.velocity.x != 0:
92
+ self.parent.set_state("run")
93
+ elif self.parent.actions.is_active("jump"):
94
+ self.parent.set_state("jump")
95
+
96
+
97
+ class Platform2DRun(CharacterState):
98
+ def __init__(self) -> None:
99
+ super().__init__("run")
100
+
101
+
102
+ def on_enter(self):
103
+ self.parent.jump_counter = 0
104
+ super().on_enter()
105
+
106
+ def update(self, dt):
107
+ super().update(dt)
108
+
109
+ if self.parent.velocity.x :
110
+ if (self.parent.actions.is_active("right") or self.parent.actions.is_active("left")):
111
+ if self.parent.get_current_animation().name != "run" : self.parent.set_animation("run")
112
+ else:
113
+ if self.parent.get_current_animation().name != "idle" : self.parent.set_animation("idle")
114
+
115
+ if self.parent.actions.is_active("jump"):
116
+ self.parent.set_state("jump")
117
+ elif self.parent.velocity.x == 0:
118
+ if not (self.parent.actions.is_active("right") or self.parent.actions.is_active("left")):
119
+ self.parent.set_state("idle")
120
+ elif not self.parent.on_ground:
121
+ self.parent.set_state("fall")
122
+
123
+
124
+
125
+
126
+ class Platform2DJump(CharacterState):
127
+ def __init__(self) -> None:
128
+ super().__init__("jump")
129
+
130
+ def on_enter(self):
131
+ super().on_enter()
132
+ self.parent.on_ground = False
133
+ self.parent.velocity.y = -self.parent.jump_force
134
+ self.parent.jump_counter += 1
135
+
136
+ def update(self, dt):
137
+ super().update(dt)
138
+ self.apply_gravity(dt)
139
+
140
+
141
+ if self.parent.jump_counter < self.parent.max_jumps:
142
+ if self.parent.actions.is_active("jump") and (self.parent.velocity.y//10)*10 == 0:
143
+ self.parent.set_state("jump")
144
+ return
145
+
146
+
147
+ if self.parent.velocity.y > 0:
148
+ self.parent.set_state("fall")
149
+
150
+
151
+ class Platform2DFall(CharacterState):
152
+ def __init__(self) -> None:
153
+ super().__init__("fall")
154
+
155
+ def update(self, dt):
156
+ super().update(dt)
157
+ self.apply_gravity(dt)
158
+
159
+ if self.parent.on_ground:
160
+ if abs(self.parent.velocity.x) > 0.01:
161
+ self.parent.set_state("run")
162
+ else:
163
+ self.parent.set_state("idle")
164
+
165
+ if self.parent.actions.is_active("jump") and self.parent.jump_counter < self.parent.max_jumps:
166
+ self.parent.set_state("jump")
batFramework/time.py CHANGED
@@ -2,13 +2,21 @@ import batFramework as bf
2
2
  from typing import Self
3
3
 
4
4
 
5
+ from typing import Callable, Union, Self
6
+
7
+
5
8
  class Timer:
6
9
  _count: int = 0
10
+ _available_ids: set[int] = set()
7
11
 
8
- def __init__(self, duration: float | int, end_callback, loop: bool = False) -> None:
9
- self.name: int = Timer._count
10
- Timer._count += 1
12
+ def __init__(self, duration: Union[float, int], end_callback: Callable, loop: bool = False, register: str = "global") -> None:
13
+ if Timer._available_ids:
14
+ self.uid = Timer._available_ids.pop()
15
+ else:
16
+ self.uid = Timer._count
17
+ Timer._count += 1
11
18
 
19
+ self.register = register
12
20
  self.duration: int | float = duration
13
21
  self.end_callback = end_callback
14
22
 
@@ -18,8 +26,11 @@ class Timer:
18
26
  self.is_paused: bool = False
19
27
  self.do_delete: bool = False
20
28
 
21
- def __repr__(self) -> str:
22
- return f"Timer ({self.name}) {self.elapsed_time}/{self.duration} | {'loop ' if self.is_looping else ''} {'(D) ' if self.do_delete else ''}"
29
+ def __bool__(self)->bool:
30
+ return self.elapsed_time==-1 or self.is_over
31
+
32
+ def __str__(self) -> str:
33
+ return f"Timer ({self.uid}) {self.elapsed_time}/{self.duration} | {'loop ' if self.is_looping else ''} {'(D) ' if self.do_delete else ''}"
23
34
 
24
35
  def stop(self) -> Self:
25
36
  self.elapsed_time = -1
@@ -30,7 +41,7 @@ class Timer:
30
41
  def start(self, force: bool = False) -> Self:
31
42
  if self.elapsed_time != -1 and not force:
32
43
  return self
33
- if not bf.TimeManager().add_timer(self):
44
+ if not bf.TimeManager().add_timer(self,self.register):
34
45
  return self
35
46
  self.elapsed_time = 0
36
47
  self.is_paused = False
@@ -79,36 +90,42 @@ class Timer:
79
90
  def should_delete(self) -> bool:
80
91
  return self.is_over or self.do_delete
81
92
 
93
+ def _release_id(self):
94
+ Timer._available_ids.add(self.uid)
82
95
 
83
- class TimerRegister:
84
- def __init__(self, active=True):
85
- self.active = active
86
- self.timers: dict[int | str, Timer] = {}
87
-
88
- def __iter__(self):
89
- return iter(self.timers.values())
90
-
91
- def add_timer(self, timer: Timer):
92
- self.timers[timer.name] = timer
93
-
94
- def update(self, dt):
95
- expired_timers = []
96
- for timer in list(self.timers.values()):
97
- if not timer.is_paused:
98
- timer.update(dt)
99
- if timer.should_delete():
100
- expired_timers.append(timer.name)
101
- for name in expired_timers:
102
- del self.timers[name]
103
96
 
97
+ class SceneTimer(Timer):
98
+ def __init__(self, duration: float | int, end_callback, loop: bool = False, scene_name:str = "global") -> None:
99
+ super().__init__(duration, end_callback, loop, scene_name)
104
100
 
105
101
  class TimeManager(metaclass=bf.Singleton):
102
+ class TimerRegister:
103
+ def __init__(self, active=True):
104
+ self.active = active
105
+ self.timers: dict[int | str, Timer] = {}
106
+
107
+ def __iter__(self):
108
+ return iter(self.timers.values())
109
+
110
+ def add_timer(self, timer: Timer):
111
+ self.timers[timer.uid] = timer
112
+
113
+ def update(self, dt):
114
+ expired_timers = []
115
+ for timer in list(self.timers.values()):
116
+ if not timer.is_paused:
117
+ timer.update(dt)
118
+ if timer.should_delete():
119
+ expired_timers.append(timer.uid)
120
+ for uid in expired_timers:
121
+ del self.timers[uid]
122
+
106
123
  def __init__(self):
107
- self.registers = {"global": TimerRegister()}
124
+ self.registers = {"global": TimeManager.TimerRegister()}
108
125
 
109
126
  def add_register(self, name, active=True):
110
127
  if name not in self.registers:
111
- self.registers[name] = TimerRegister(active)
128
+ self.registers[name] = TimeManager.TimerRegister(active)
112
129
 
113
130
  def add_timer(self, timer, register="global") -> bool:
114
131
  if register in self.registers:
@@ -133,3 +150,12 @@ class TimeManager(metaclass=bf.Singleton):
133
150
 
134
151
  def deactivate_register(self, name):
135
152
  self.activate_register(name, active=False)
153
+
154
+ def __str__(self)->str:
155
+ res = ""
156
+ for name,reg in self.registers.items():
157
+ if not reg.timers:continue
158
+ res +=name+"\n"
159
+ for t in reg.timers.values():
160
+ res +="\t"+str(t)+"\n"
161
+ return res
@@ -87,10 +87,10 @@ class Transition:
87
87
  class FadeColor(Transition):
88
88
  def __init__(
89
89
  self,
90
- color: tuple | str,
90
+ color: tuple,
91
91
  middle_duration: float,
92
- first_duration: float = None,
93
- second_duration: float = None,
92
+ first_duration: float | None = None,
93
+ second_duration: float | None = None,
94
94
  easing_function: bf.easing = bf.easing.LINEAR,
95
95
  ) -> None:
96
96
  super().__init__(0, easing_function)
@@ -98,16 +98,25 @@ class FadeColor(Transition):
98
98
  first_duration = middle_duration
99
99
  if second_duration is None:
100
100
  second_duration = middle_duration
101
- self.index = 0
101
+
102
102
  self.first = Fade(first_duration)
103
+ self.second = Fade(second_duration)
103
104
  self.color = color
104
- self.second = Fade(second_duration).set_end_callback(
105
- lambda: self.next_step(self.end)
106
- )
107
- self.timer = bf.Timer(
108
- middle_duration, lambda: self.next_step(self.second.start)
109
- )
110
- self.first.set_end_callback(lambda: self.next_step(self.timer.start))
105
+ self.middle_duration = middle_duration
106
+ self.index = 0
107
+
108
+ self.timer = bf.Timer(middle_duration, self.transition_to_second)
109
+ self.first.set_end_callback(self.transition_to_middle)
110
+ self.second.set_end_callback(self.transition_to_end)
111
+
112
+ def transition_to_middle(self):
113
+ self.next_step(self.timer.start)
114
+
115
+ def transition_to_second(self):
116
+ self.next_step(self.second.start)
117
+
118
+ def transition_to_end(self):
119
+ self.next_step(self.end)
111
120
 
112
121
  def next_step(self, callback=None) -> None:
113
122
  self.index += 1
@@ -125,6 +134,7 @@ class FadeColor(Transition):
125
134
  def start(self):
126
135
  if self.start_callback:
127
136
  self.start_callback()
137
+
128
138
  self.color_surf = pygame.Surface(self.source.get_size())
129
139
  self.color_surf.fill(self.color)
130
140
 
@@ -141,7 +151,7 @@ class FadeColor(Transition):
141
151
  self.second.draw(surface)
142
152
 
143
153
  def skip(self, no_callback: bool = False):
144
- if (no_callback == False) and self.end_callback:
154
+ if not no_callback and self.end_callback:
145
155
  self.end_callback()
146
156
 
147
157
  self.first.controller.stop()
@@ -149,6 +159,7 @@ class FadeColor(Transition):
149
159
  self.second.controller.stop()
150
160
 
151
161
 
162
+
152
163
  class Fade(Transition):
153
164
  def end(self):
154
165
  self.dest.set_alpha(255)
@@ -213,3 +224,5 @@ class CircleIn(Transition):
213
224
  )
214
225
  mask = pygame.mask.from_surface(self.circle_surf)
215
226
  mask.to_surface(surface=surface, setsurface=self.source, unsetsurface=self.dest)
227
+
228
+
@@ -4,7 +4,7 @@ import batFramework as bf
4
4
  class TriggerZone(bf.Entity):
5
5
  def __init__(self, size, trigger, callback, active=True) -> None:
6
6
  super().__init__(size, True)
7
- self.set_debug_color(bf.color.RIVER_BLUE)
7
+ self.set_debug_color(bf.color.RED)
8
8
  self.active = active
9
9
  self.callback = callback
10
10
  self.trigger = trigger
batFramework/utils.py CHANGED
@@ -5,6 +5,11 @@ import batFramework as bf
5
5
  import json
6
6
  from .enums import *
7
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
8
13
 
9
14
 
10
15
  class Singleton(type):
@@ -27,8 +32,6 @@ class Utils:
27
32
  with their tuple coordinates as keys.
28
33
  Exemple : '(0,0) : Surface'
29
34
  """
30
- if surface is None:
31
- return None
32
35
  width, height = surface.get_size()
33
36
  res = {}
34
37
  for iy, y in enumerate(range(0, height, split_size[1])):
@@ -57,3 +60,90 @@ class Utils:
57
60
  return pattern.sub("", s)
58
61
 
59
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
+
@@ -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