Aller au contenu principal
Voir

Fondations de l'animation

PSDK anime tout via Yuki::Animation, un système basé sur le temps où l'on construit de petits blocs d'animation et où on les combine en séquence ou en parallèle. Cette page explique cette logique de base ; les usages spécifiques sont couverts dans leurs propres guides.

Comment fonctionne une animation

Une animation Yuki est basée sur le temps, pas sur les frames. Elle a une duration en secondes et progresse de 0 (début) à 1 (fin) sur cette durée, en lisant le temps écoulé sur l'horloge de la scène courante, ce qui la rend cohérente quel que soit le taux de rafraîchissement.

Quel que soit ce qu'elle anime, elle répond aux mêmes quatre messages : start, update, done? et duration. La piloter, c'est toujours la même boucle : on la démarre, puis on la met à jour à chaque frame jusqu'à ce qu'elle se déclare terminée.

animation.start
until animation.done?
animation.update
Graphics.update
end

Dans une scène, on n'écrit pas cette boucle soi-même : la scène met l'animation à jour à notre place, à chaque frame. On l'écrit dans des scripts autonomes, ou pour se représenter ce que fait le système.

Tous les helpers vivent dans le module Yuki::Animation, en général aliasé sur une variable locale courte :

ya = Yuki::Animation

Les briques de base

Une brique anime une seule chose, et elles partagent toutes la même forme : la durée d'abord, puis l'objet à animer, puis les valeurs de départ et d'arrivée. La plus générale est scalar, qui interpole une seule propriété numérique via sa méthode de modification :

# Fade a sprite out over 0.5s (opacity 255 -> 0)
ya.scalar(0.5, sprite, :opacity=, 255, 0)

move est la même idée pour une position sous forme de vecteur (x, y) :

# Move a sprite from (0, 5) to (100, 32) in 3s
ya.move(3, sprite, 0, 5, 100, 32)

Et wait ne fait simplement rien pendant une durée, pour tenir une pause dans une séquence :

ya.wait(1.0)

C'est tout le patron. Des helpers dédiés existent pour les autres cas courants (opacité, rotation, décalage d'origine, cellules de planche de sprites) ; ils suivent tous la même forme durée, objet, départ, arrivée.

Séquencer et paralléliser

La vraie force, c'est la composition. Deux combinateurs assemblent les briques, et tous deux se comportent comme une seule animation, on peut donc les imbriquer librement :

  • ya.player(a, b, c) joue ses animations l'une après l'autre (séquentiel).
  • ya.parallel(a, b, c) les joue en même temps (simultané).
ya = Yuki::Animation

# Fade in while sliding down, hold one second, then fade out
animation = ya.player(
ya.parallel(
ya.scalar(0.3, sprite, :opacity=, 0, 255),
ya.move(0.3, sprite, sprite.x, sprite.y - 20, sprite.x, sprite.y)
),
ya.wait(1.0),
ya.scalar(0.3, sprite, :opacity=, 255, 0)
)

animation.start
until animation.done?
animation.update
Graphics.update
end

player attend que chaque étape (y compris un groupe parallel qu'elle contient) soit terminée avant de passer à la suivante. Cette imbrication séquentiel/parallèle suffit à décrire la plupart des animations.

Conclusion

  • Une animation Yuki est basée sur le temps : une duration, une progression de 0 à 1, pilotée par start / update / done?.
  • On construit avec des briques qui partagent une seule forme : ya.scalar pour une propriété numérique, ya.move pour une position, ya.wait pour une pause ; les autres helpers suivent la même forme.
  • On compose avec ya.player (séquentiel) et ya.parallel (simultané), imbriqués selon le besoin.
  • Dans une scène, c'est la scène qui pilote update ; en autonome, on boucle jusqu'à done?.
  • Tout le reste (intégration UI, distorsions, sauvegarde, commandes) vit dans des guides dédiés.