Fondamentalement, vous êtes sur la bonne voie - vous devez savoir combien de temps dure une animation pour faire ce genre de chose. Les animations sont plus qu'une simple collection de cadres, il y a toutes sortes d'autres informations autour d'eux dont vous avez besoin. Par exemple, combien d'images y a-t-il, la boucle d'animation est-elle bouclée, à quelle vitesse est-elle lue (par exemple 10 images d'animation par seconde ou 25, ou 60?). Chaque animation peut être définie en termes de quelques éléments de données, que certains codes d'animation généralisés peuvent regarder et lire. Vous devez encapsuler la partie d'animation dans son propre morceau de code, qui ne connaît rien à part ces définitions d'animation et comment afficher les images individuelles. C'est-à-dire, avoir un objet d'animation que vous pouvez charger, commencer à jouer, arrêter de jouer et dire de rendre à un emplacement particulier à l'écran.
Une approche flexible consiste à utiliser une sorte de définition d'animation pour encapsuler ce type d'informations. Donc, plutôt que de simplement dire "l'animation X est l'ensemble de ces images, il suffit de les lire", vous obtenez quelque chose d'un peu plus complexe.
Par exemple, avec une sorte de format de données simulé
animations =
{
{name = "walk", files = "walk * .png", frameCount = "12", loop = "true"},
{name = "fire" files = "fire * .png" frameCount = "6",
événements = {
{name = "bulletLeavesGun", frame = "4", param1 = "43", param2 = "30"}
}
}
}
Donc, votre code dit quelque chose comme:
currentAnimation = animations.Get("fire");
currentAnimation.Play();
La façon dont vous détectez les événements peut être soit avec le code d'animation qui vous rappelle (c'est-à-dire quand il détecte un nouvel événement parce que l'animation a joué sur une certaine image, il appelle votre code de jeu pour lui parler du nouvel événement), ou en interrogeant le animation comme ça:
List<Event> events = currentAnimation.EventsSinceLastCheck();
foreach (AnimationEvent event in events)
{
if (event.name == "bulletLeavesGun")
{
Vector2 bulletPosition = new Vector2(event.param1, event.param2);
Vector2 actualBulletPosition = new Vector2(
character.x + bulletPosition.x,
character.y + bulletPosition.y);
CreateBulletAt(actualBulletPosition);
}
}
Points à noter:
- Le code d'animation doit exister séparément du code de jeu. Vous ne voulez vraiment pas que votre code de jeu soit trop étroitement lié aux écrous et boulons de la lecture d'animation.
- Le code d'animation sait s'il faut ou non boucler en fonction de la définition de l'animation
- Le code d'animation sait quand l'animation est terminée et peut rappeler un autre code pour dire «hé, l'animation appelée« feu »vient de se terminer, que voulez-vous faire maintenant?
- Le code d'animation ne sait rien des événements autres que le fait qu'ils ont un nom et des données arbitraires qui leur sont associées (param1 et param2)
- Le code d'animation sait sur quelle image il se trouve actuellement, et lorsqu'il passe à une nouvelle image, il peut vérifier et dire «oh, je suis sur l'image 4 maintenant, cela signifie que cet événement appelé« feu »vient de se produire, ajoutez cela à ma liste des événements récents pour que je puisse en parler à tous ceux qui le demandent ».
Si vous n'avez pas besoin que le tir de balle se produise dans l'animation, mais seulement une fois qu'elle est terminée, vous pouvez vous en sortir avec un système beaucoup moins complexe sans notion d'événements. Mais vous voudrez toujours un système dans lequel les animations sont lues par elles-mêmes, sachez combien de temps elles sont et pouvez rappeler le code du jeu lorsqu'une animation se termine.