Básicamente está en el camino correcto: necesita saber cuánto dura una animación para hacer este tipo de cosas. Las animaciones son más que una simple colección de cuadros, hay todo tipo de información a su alrededor que necesita. Por ejemplo, ¿cuántos cuadros hay, se repite la animación, qué tan rápido se reproduce (por ejemplo, 10 cuadros de animación por segundo o 25, o 60?). Cada animación se puede definir en términos de unos pocos datos, que algunos códigos de animación generalizados pueden ver y reproducir. Debería encapsular la parte de animación en su propio código, que no conoce nada excepto estas definiciones de animación y cómo mostrar los cuadros de imagen individuales. Es decir, tenga un objeto de animación que pueda cargar, comenzar a reproducir, detener la reproducción y decirle que renderice en una ubicación particular en la pantalla.
Un enfoque flexible es utilizar una especie de definición de animación para encapsular este tipo de información. Entonces, en lugar de solo decir "la animación X es todos estos cuadros, solo juega a través de ellos", obtienes algo un poco más complejo.
Por ejemplo, con algún tipo de formato de datos simulado
animaciones =
{
{name = "walk", files = "walk * .png", frameCount = "12", loop = "true"},
{nombre = "fuego" archivos = "fuego * .png" frameCount = "6",
eventos = {
{name = "bulletLeavesGun", frame = "4", param1 = "43", param2 = "30"}
}
}
}
Entonces su código dice algo como:
currentAnimation = animations.Get("fire");
currentAnimation.Play();
La forma en que detecta eventos puede ser con el código de animación que le devuelve la llamada (es decir, cuando detecta un nuevo evento porque la animación se ha reproducido en un marco determinado, llama al código de su juego para informarle sobre el nuevo evento) o sondeando el animación así:
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);
}
}
Puntos a tener en cuenta:
- El código de animación debe existir por separado del código del juego. Realmente no quieres que tu código de juego esté demasiado ligado a los detalles básicos de la reproducción de animación.
- El código de animación sabe si hacer un bucle o no en función de la definición de animación
- El código de animación sabe cuándo se realiza la animación, y puede volver a llamar a otro código para decir 'oye, la animación llamada "fuego" acaba de terminar, ¿qué quieres hacer ahora?
- El código de animación no sabe nada sobre eventos aparte de que tienen un nombre y algunos datos arbitrarios asociados con ellos (param1 y param2)
- El código de animación sabe en qué cuadro está actualmente, y cuando cambia a un nuevo cuadro, puede verificar y decir 'oh, estoy en el cuadro 4 ahora, eso significa que acaba de ocurrir un evento llamado "fuego", agrégalo a mi lista de eventos recientes para poder contarle a cualquiera que pregunte al respecto '.
Si no necesita que se dispare la bala dentro de la animación, pero solo una vez que haya terminado, puede salirse con la suya con un sistema mucho menos complejo sin la noción de eventos. Pero aún querrá un sistema donde las animaciones se reproduzcan por sí mismas, sepan cuánto duran y puedan volver a llamar al código del juego cuando se complete una animación.