Source code for arcade.clock

__all__ = (
    "Clock",
    "FixedClock",
    "GLOBAL_CLOCK",
    "GLOBAL_FIXED_CLOCK",
)


[docs] class Clock: """ A time keeping class which provides a method for easily tracking the elapsed time, delta_time, and number of ticks. Arcade provides a global clock which is automatically ticked by the window. *Coming post 3.0:* you can add 'sub-clocks' to Arcade's top level clock which will tick at the same time, and have cumulative tick_speeds. This allows you to slow down only certain elements rather than everything. Args: initial_elapsed: The amount of time the clock should assume has already occurred. Defaults to 0.0 initial_tick: The number of ticks the clock should assume has already occurred. Defaults to 0. tick_speed: A multiplier on how the 'speed' of time. i.e. a value of 0.5 means time elapsed half as fast for this clock. Defaults to 1.0. """ def __init__( self, initial_elapsed: float = 0.0, initial_tick: int = 0, tick_speed: float = 1.0 ): self._elapsed_time: float = initial_elapsed self._tick: int = initial_tick self._tick_delta_time: float = 0.0 self._tick_speed: float = tick_speed self._max_deltatime: float | None = None
[docs] def tick(self, delta_time: float): """ Update the clock with the time that has passed since the last tick. Args: delta_time: The amount of time that has passed since the last tick. """ if self._max_deltatime is not None: delta_time = min(self._max_deltatime, delta_time) self._tick_delta_time = delta_time * self._tick_speed self._elapsed_time += self._tick_delta_time self._tick += 1
[docs] def set_tick_speed(self, new_tick_speed: float): """ Set the speed of time for this clock. Args: new_tick_speed: A multiplier on the 'speed' of time. i.e. a value of 0.5 means time elapsed half as fast for this clock. """ self._tick_speed = new_tick_speed
[docs] def set_max_deltatime(self, max_deltatime: float | None = None): """ Set the maximum deltatime that the clock will allow. If a large dt is passed into the clock's tick method it will be clamped. This will desync the game's time with the real world elapsed time, but can help protect against lag-spikes, debugger pauses, and other pauses to the event loop. This impacts the 'raw' dt so it does not take the clock's tick speed into account Args: max_deltatime: The maximum number of seconds that a clock can have as it's deltatime. If set to None the clock has no limit. Defaults to None. """ self._max_deltatime = max_deltatime
[docs] def time_since(self, time: float) -> float: """ Calculate the amount of time that has passed since the given time. Args: time: The time to compare against. """ return self._elapsed_time - time
[docs] def ticks_since(self, tick: int) -> int: """ Calculate the number of ticks that have occurred since the given tick. Args: tick: The tick to compare against. """ return self._tick - tick
@property def max_deltatime(self) -> float | None: """ The maximum deltatime that the clock will allow. If a large dt is passed into """ return self._max_deltatime @property def time(self) -> float: """The total number of seconds that have elapsed for this clock""" return self._elapsed_time @property def t(self) -> float: """Alias to Clock.time""" return self._elapsed_time @property def delta_time(self) -> float: """The amount of time that elapsed during the last tick""" return self._tick_delta_time @property def dt(self) -> float: """Alias to Clock.delta_time""" return self.delta_time @property def speed(self) -> float: """ A modifier on the delta time that elapsed each tick. Decreasing the speed will 'slow down' time for this clock Immutable in 3.0 """ return self._tick_speed @property def ticks(self) -> int: """The number of ticks that have occurred for this clock.""" return self._tick @property def tick_count(self) -> int: """Alias to Clock.ticks""" return self._tick
[docs] class FixedClock(Clock): """ A fixed clock which expects its delta_time to stay constant. If it doesn't it will throw an error. Arcade provides a global fixed clock which is automatically ticked every update Args: sibling: The unfixed clock which this clock will sync with. fixed_tick_rate: The fixed number of seconds that pass for this clock every tick. Defaults to ``1.0 / 60.0``. """ def __init__(self, sibling: Clock, fixed_tick_rate: float = 1.0 / 60.0): self._sibling_clock: Clock = sibling self._fixed_rate: float = fixed_tick_rate super().__init__()
[docs] def set_tick_speed(self, new_tick_speed: float): """ Set the speed of time for this clock. Args: new_tick_speed: A multiplier on the 'speed' of time. i.e. a value of 0.5 means time elapsed half as fast for this clock """ raise ValueError( "It is not safe to change the tick speed of a fixed clock post initialization." )
[docs] def tick(self, delta_time: float): """ Update the clock with the time that has passed since the last tick. Args: delta_time: The amount of time that has passed since the last tick. """ if delta_time != self._fixed_rate: raise ValueError( f"the delta_time {delta_time}, " f"does not match the fixed clock's required delta_time {self._fixed_rate}" ) super().tick(self._fixed_rate)
@property def rate(self) -> float: """The fixed number of seconds that pass for this clock every tick.""" return self._fixed_rate @property def accumulated(self) -> float: """The total number of seconds that have elapsed for this clock""" return self._sibling_clock.time - self._elapsed_time @property def fraction(self) -> float: """The fraction of a fixed tick that has passed since the last tick.""" return self.accumulated / self._fixed_rate
GLOBAL_CLOCK = Clock() GLOBAL_FIXED_CLOCK = FixedClock(sibling=GLOBAL_CLOCK) def _setup_clock(initial_elapsed: float = 0.0, initial_tick: int = 0, tick_speed: float = 1.0): """ Private method used by the Arcade window to setup the global clock post initialization. Args: initial_elapsed: The amount of time the clock should assume has already occurred. Defaults to 0.0 initial_tick: The number of ticks the clock should assume has already occurred. Defaults to 0. tick_speed: A multiplier on the 'speed' of time. i.e. a value of 0.5 means time elapsed half as fast for this clock. Defaults to 1.0. """ GLOBAL_CLOCK._elapsed_time = initial_elapsed # noqa: SLF001 GLOBAL_CLOCK._tick = initial_tick # noqa: SLF001 GLOBAL_CLOCK._tick_speed = tick_speed # noqa: SLF001 def _setup_fixed_clock(fixed_tick_rate: float = 1.0 / 60.0): """ Private method used by the Arcade window to setup the global fixed clock post initialization. Args: fixed_tick_rate: The fixed number of seconds that pass for this clock every tick. Defaults to 1.0 / 60.0 """ GLOBAL_FIXED_CLOCK._elapsed_time = GLOBAL_CLOCK.time # noqa: SLF001 GLOBAL_FIXED_CLOCK._tick = GLOBAL_CLOCK.tick_count # noqa: SLF001 GLOBAL_FIXED_CLOCK._fixed_rate = fixed_tick_rate # noqa: SLF001