Fundamentalmente, você está no caminho certo - você precisa saber quanto tempo uma animação dura para fazer esse tipo de coisa. As animações são mais do que apenas uma coleção de quadros; existem todos os tipos de informações que você precisa. Por exemplo, quantos quadros existem, a animação é reproduzida, com que rapidez é reproduzida (por exemplo, 10 quadros de animação por segundo ou 25 ou 60?). Toda animação pode ser definida em termos de alguns dados, os quais algum código de animação generalizado pode visualizar e reproduzir. Você deve encapsular a parte da animação em seu próprio pedaço de código, que não reconhece nada, exceto essas definições de animação e como exibir os quadros de imagem individuais. Ou seja, tenha um objeto de animação que você possa carregar, iniciar a reprodução, interromper a reprodução e dizer para renderizar em um local específico na tela.
Uma abordagem flexível é usar um tipo de definição de animação para encapsular esse tipo de informação. Então, em vez de apenas dizer "a animação X é todos esses quadros, basta reproduzi-los", você obtém algo um pouco mais complexo.
Por exemplo, com algum tipo de formato de dados simulado
animações =
{
{name = "walk", arquivos = "walk * .png", frameCount = "12", loop = "true"},
{name = "fire" arquivos = "fire * .png" frameCount = "6",
events = {
{name = "bulletLeavesGun", frame = "4", param1 = "43", param2 = "30"}
}
}
}
Portanto, seu código diz algo como:
currentAnimation = animations.Get("fire");
currentAnimation.Play();
Como você detecta eventos pode ser com o código de animação retornando a ligação (ou seja, quando ele detecta um novo evento porque a animação foi reproduzida em um determinado quadro, ele chama o código do jogo para informar sobre o novo evento) ou pesquisando o animação assim:
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);
}
}
Pontos a serem observados:
- O código de animação deve existir separadamente do código do jogo. Você realmente não quer que seu código de jogo esteja muito ligado aos detalhes da reprodução de animação.
- O código de animação sabe se deve ou não fazer loop com base na definição de animação
- O código da animação sabe quando a animação é concluída e pode retornar a outro código para dizer 'ei, a animação chamada "fogo" acabou de terminar, o que você deseja fazer agora?
- O código de animação não sabe nada sobre eventos, exceto que eles têm um nome e alguns dados arbitrários associados a eles (param1 e param2)
- O código de animação sabe em qual quadro ele está atualmente e, quando muda para um novo quadro, pode verificar e dizer 'oh, estou no quadro 4 agora, isso significa que esse evento chamado "fogo" acabou de acontecer, adicione isso a minha lista de eventos recentes, para que eu possa contar a quem perguntar '.
Se você não precisar que o disparo de bala aconteça na animação, mas apenas quando terminar, você poderá se safar de um sistema muito menos complexo sem a noção de eventos. Mas você ainda desejará um sistema em que as animações sejam reproduzidas por conta própria, saiba quanto tempo elas duram e poderá retornar ao código do jogo quando uma animação for concluída.