Source code for mini_arcade_core.scenes.systems.builtins.animation

"""
Animation system helpers for scene pipelines.
"""

from __future__ import annotations

from dataclasses import dataclass
from typing import Callable, Iterable, Protocol

from mini_arcade_core.engine.components import Anim2D
from mini_arcade_core.scenes.systems.phases import SystemPhase


[docs] class HasAnim(Protocol): """ Structural contract for entities with an animation component. """ anim: object | None life: object | None
def _is_alive(entity: object) -> bool: life = getattr(entity, "life", None) if life is not None: return bool(getattr(life, "alive", True)) return bool(getattr(entity, "alive", True))
[docs] @dataclass class AnimationTickSystem: """ Step entity animations during presentation. Current entities use ``Anim2D.step(dt)``. A small compatibility path is kept for older animation objects that still expose ``update/current_frame``. """ name: str = "common_anim_tick" phase: int = SystemPhase.PRESENTATION order: int = 0 get_entities: Callable[[object], Iterable[HasAnim]] = lambda _w: ()
[docs] def step(self, ctx: object) -> None: """ Advance animations for all alive entities provided by ``get_entities``. """ for entity in self.get_entities(ctx.world): if not _is_alive(entity): continue anim = getattr(entity, "anim", None) if anim is None: continue if isinstance(anim, Anim2D): anim.step(ctx.dt) continue if hasattr(anim, "step"): anim.step(ctx.dt) continue if hasattr(anim, "update"): anim.update(ctx.dt) if hasattr(entity, "texture") and hasattr( anim, "current_frame" ): entity.texture = anim.current_frame