Consideremos una situación en la que tienes un juego de rol con hechizos y cada animación de hechizo tiene un número diferente de fotogramas y tienen requisitos muy diferentes para los efectos de sonido. Supongamos que cada hechizo tiene solo 1 animación continua asociada (a diferencia de las múltiples piezas modulares que se utilizan para formar una animación completa) en los viejos juegos de 16 bits de Final Fantasy.
La única forma en que puedo pensar para asegurarme de que los sonidos y las animaciones se sincronicen es:
- Obtener el número de cuadros de una animación.
- Obtenga el tiempo entre cada cuadro de la animación. (si son 30 fps, entonces es 1/30 de segundo por fotograma).
- Luego, cree un archivo de sonido que tenga exactamente la misma longitud que la animación.
Esto significa que si una animación dura 5 segundos y se ejecuta a 30 fps, con un total de 150 fotogramas, el archivo de sonido también durará 5 segundos. Si la animación debe tener un sonido de "impacto" en el cuadro 30, eso significa que el archivo de sonido incluirá el sonido de impacto en la marca de 1.0 segundo.
Al final, comenzamos la animación y el efecto de sonido exactamente al mismo tiempo y esperamos que los cuadros y el sonido se sincronicen.
Parece que podría plantear problemas cuando se omiten los fotogramas o sucede algo durante la animación y el sonido se reproduce un poco demasiado pronto o demasiado tarde, y hará que el sonido y la animación no estén sincronizados. ¿Es este el mejor enfoque o generalmente hay una mejor manera que simplemente no estoy viendo?
La respuesta no necesariamente tiene que ser para Cocos2D específicamente si es conceptual, pero si hay una solución específica para cocos2d, me encantaría escucharla.
EDITAR: también me doy cuenta de que con este método, si entramos y ajustamos el número de fotogramas o el tiempo de la animación más tarde, también DEBEMOS regresar y cambiar el archivo de sonido. Esto suena como una causa terrible de error humano (olvidando actualizar los archivos de sonido después del cambio de animación). Espero que haya mejores métodos disponibles.
Respuestas:
Hazlo a través de eventos.
El hechizo comienza es un evento . Comience a reproducir el sonido para ese evento.
Enemigo ser golpeado por un hechizo también es un evento. Si el enemigo está más lejos y arrojas un dardo, por ejemplo, solo juegas el segundo sonido (dardo) una vez que el dardo alcanza el objetivo (si consideras Lanzar como un hechizo).
Si necesita vincularlo a un cuadro (por ejemplo, reproduzca el sonido de "explosión" dentro de 30 cuadros a pesar de las velocidades de cuadro en tiempo real ), la forma más fácil de hacerlo es mediante devoluciones de llamada . Las devoluciones de llamada son solo "bloques de código que programa para ejecutar en el futuro". Aquí hay un ejemplo de mi creador de creación de devolución de llamada:
A
TimedCallback
es solo un contenedor alrededor de unstd::function
(o podría usar un Objective-C^{block}
. Elstd::function
se ejecuta cuando su marco está activo.Otra forma (menos global) es incluir eventos en su animación . Entonces, si necesita reproducir sonidos específicos en cuadros de animación específicos, almacene un
map<int,Sound*>
en laAnimation
clase. En cada cuadro de la animación, verifique si hay unSound*
juego correspondiente para ese cuadro.También podría almacenar un
map<int, std::function>
, en elAnimation
objeto, que le permitiría devolver la llamada afunction
durante la animación.fuente
{ 'images':'sprite-%02d.png', 'beginRange':1, 'endRange':32, 'sounds':{ 0 : 'startSpell.wav', 30 : 'impact.wav' } }
. Si su juego está en una etapa muy temprana y el tiempo de compilación aún es bajo, puede comenzar codificando las estructuras de datos para ver si funciona.La forma en que lo hago es hacer oyentes de eventos personalizados para mi clase de animación y hacer que controlen mi sonido. así que si mi animación ha comenzado callback.start (); y empiezo mi sonido en ese método. si se pausó mi animación do callback.pause (); y pausa el sonido. cuando la animación ha terminado, callback.end (); y que el sonido también termine.
pero para una sincronización perfecta, iría tan lejos como contar cuadros de sonido y dormir (pausar) mi sonido si llega a un extremo y hacer lo mismo para mi animación.
Nunca he tenido que hacer eso hasta este día porque la primera sugerencia satisface mis necesidades perfectamente por ahora.
fuente