22
33from typing import TYPE_CHECKING
44
5+ from pygame .math import Vector2
6+
57if TYPE_CHECKING :
68 from pygame .rect import Rect
79
810 from pyscroll .camera import BaseCamera
911
1012
1113class CameraManager :
14+ """
15+ Manages active cameras and smooth transitions between them.
16+ """
17+
1218 def __init__ (self , initial_camera : BaseCamera ):
1319 self .current = initial_camera
1420 self .next_cam : BaseCamera | None = None
15- self .transition_time : float = 0
16- self .transition_duration : float = 0
21+ self .transition_time : float = 0.0
22+ self .transition_duration : float = 0.0
1723 self ._last_position : tuple [float , float ] | None = None
1824
1925 @property
@@ -27,15 +33,15 @@ def is_transitioning(self) -> bool:
2733 return self .next_cam is not None
2834
2935 def set_camera (self , cam : BaseCamera , duration : float = 0.0 ) -> None :
30- if duration <= 0 :
36+ if duration <= 0.0 :
3137 self .current = cam
3238 self .next_cam = None
33- self .transition_time = 0
39+ self .transition_time = 0.0
3440 return
3541
3642 self .next_cam = cam
3743 self .transition_duration = duration
38- self .transition_time = 0
44+ self .transition_time = 0.0
3945
4046 def update (
4147 self , current_view : Rect , target_rect : Rect , dt : float
@@ -45,21 +51,22 @@ def update(
4551 self ._last_position = pos
4652 return pos
4753
48- # Both cameras update every frame so their internal state stays current
49- pos_a = self .current .update (current_view , target_rect , dt )
50- pos_b = self .next_cam .update (current_view , target_rect , dt )
54+ # Update both cameras to keep internal state in sync
55+ pos_a = Vector2 ( * self .current .update (current_view , target_rect , dt ) )
56+ pos_b = Vector2 ( * self .next_cam .update (current_view , target_rect , dt ) )
5157
5258 self .transition_time += dt
5359 t = min (self .transition_time / self .transition_duration , 1.0 )
54- t = t * t * (3 - 2 * t ) # smoothstep
5560
56- x = pos_a [0 ] + (pos_b [0 ] - pos_a [0 ]) * t
57- y = pos_a [1 ] + (pos_b [1 ] - pos_a [1 ]) * t
61+ # smoothstep
62+ t_smooth = t * t * (3.0 - 2.0 * t )
63+
64+ final_pos = pos_a .lerp (pos_b , t_smooth )
5865
5966 if t >= 1.0 :
6067 self .current = self .next_cam
6168 self .next_cam = None
6269
63- pos = (x , y )
64- self ._last_position = pos
65- return pos
70+ result = (final_pos . x , final_pos . y )
71+ self ._last_position = result
72+ return result
0 commit comments