Vamos dar uma situação em que você tem um RPG com feitiços e cada animação de feitiço tem um número diferente de quadros e eles têm requisitos muito diferentes para efeitos sonoros. Vamos supor que cada feitiço tenha apenas 1 animação contínua associada (em oposição a várias peças modulares usadas para formar uma animação completa), além dos antigos jogos de 16 bits de Final Fantasy.
A única maneira de pensar para garantir a sincronização de sons e animações é:
- Obter o número de quadros de uma animação.
- Obtenha o tempo entre cada quadro da animação. (se for 30 qps, será 1/30 de segundo por quadro.)
- Em seguida, crie um arquivo de som com exatamente o mesmo comprimento da animação.
Portanto, isso significa que se uma animação tiver 5 segundos, rodando a 30 qps, com um total de 150 quadros, o arquivo de som também terá 5 segundos. Se a animação tiver um som de "impacto" no 30º quadro, isso significa que o arquivo de som incluirá o som do impacto na marca de 1,0 segundo.
No final, iniciamos a animação e o efeito sonoro exatamente ao mesmo tempo e esperamos que os quadros e o som sejam sincronizados.
Parece que isso pode causar problemas quando os quadros são ignorados ou algo acontece durante a animação e o som é reproduzido um pouco cedo ou tarde demais, e fará com que o som e a animação fiquem fora de sincronia. Essa é a melhor abordagem ou geralmente há uma maneira melhor que eu simplesmente não estou vendo?
A resposta não precisa necessariamente ser para o Cocos2D especificamente se for conceitual, mas se houver uma solução específica para o cocos2d, eu adoraria ouvi-lo.
EDIT: Eu também percebi que, com esse método, se ajustarmos o número de quadros ou o tempo da animação posteriormente, DEVEMOS também voltar e alterar o arquivo de som. Isso soa como uma causa terrível de erro humano (esquecendo de atualizar os arquivos de som após a alteração da animação.) Espero que haja métodos melhores por aí.
Respostas:
Faça isso através de eventos.
O feitiço começa é um evento . Comece a tocar o som para esse evento.
O inimigo atingido pelo feitiço também é um evento. Se o inimigo estiver mais longe e você jogar um dardo, por exemplo, você só toca o segundo som (dardo) quando o dardo atinge o alvo (se você considerar o lançamento como um feitiço).
Se você precisar amarrá-lo a um quadro (por exemplo, toque o som "explodir" daqui a 30 quadros, independentemente das taxas de quadros em tempo real )), a maneira mais fácil de fazer isso é usando retornos de chamada . Retornos de chamada são apenas "blocos de código que você planeja executar no futuro". Aqui está um exemplo do meu configurador de criação de retorno de chamada:
A
TimedCallback
é apenas um invólucro em torno de umstd::function
(ou você pode usar um Objective-C^{block}
. Ostd::function
é executado quando seu quadro está ativo.Outra maneira (menos global) é incluir eventos em sua animação . Portanto, se você precisar reproduzir sons específicos em quadros específicos de animação, armazene um
map<int,Sound*>
naAnimation
classe. Em cada quadro da animação, verifique se há um correspondenteSound*
para reproduzir nesse quadro.Você também pode armazenar a
map<int, std::function>
, noAnimation
objeto, o que permitiria retornar uma chamadafunction
durante a animação.fonte
{ 'images':'sprite-%02d.png', 'beginRange':1, 'endRange':32, 'sounds':{ 0 : 'startSpell.wav', 30 : 'impact.wav' } }
. Se o seu jogo está em estágio inicial e o tempo de compilação ainda é baixo, você pode começar codificando as estruturas de dados para ver se funciona.A maneira como faço isso é criar ouvintes de eventos personalizados para minha aula de animação e controlá-los. portanto, se minha animação começou callback.start (); e comece meu som nesse método. se minha animação foi pausada, faça callback.pause (); e pausar o som. quando a animação termina, você callback.end (); e ter o som final também.
mas, para uma sincronização perfeita, eu chegaria ao ponto de contar os quadros de som e adormecer (pausar) meu som, se ele chegar muito longe e fazer o mesmo com a minha animação.
Eu nunca tive que fazer isso até hoje, porque a primeira sugestão satisfaz minhas necessidades muito bem por enquanto.
fonte