Asteroids: sonido y música – eventos con sonido

Los eventos que queremos que tengan sonidos son los disparos y la explosiones, tanto las explosiones de la nave como las de los asteroides.

Y lo que hemos dicho es que, ante estos eventos, no vamos a reproducir los sonidos de forma directa o inmediata, dado que ello dejaría “enganchado” el juego, sino que vamos a tomar nota de ellos en unas estructuras de datos (tablas) y luego vamos a reproducir los sonidos (a lo largo de varios ciclos) igual que actualizamos el jugador, la pantalla, los disparos o los asteroides.

Vamos primero con las tablas para tomar nota de los eventos. Son así (fichero “Sonidos.asm”):

Asteroids - Tablas tomar notas eventos.PNG

En este trozo de código nos encontramos la declaración de cuatro tablas:

  • Tabla “vocesActivas”: Sirve para llevar cuenta de qué voces están activas (porque ha ocurrido un evento) y, por tanto, deben dar lugar a reproducción de sonido. La tabla tiene tres entradas porque el SID tiene tres voces, pero de momento sólo usamos las entradas / voces 0 y 1. La 0 para los disparos; la 1 para las explosiones.
  • Tabla “vocesEntradas”: Como cada sonido puede tener varias entradas en su tabla de definición del sonido (recordar que el disparo tenía dos entradas, mientras que la explosión sólo tenía una), debemos llevar cuenta de por qué entrada vamos en la reproducción. Lo hacemos con esta tabla.
  • Tabla “vocesRetardos”: Cada entrada en la tabla de definición del sonido tenía asociada una duración (5 y 5 para los disparos; 20 para las explosiones). Esta duración se medía en ciclos del bucle de juego. Debemos llegar cuenta de por qué ciclo vamos para detectar cuándo acaba una entrada y debemos pasar a la siguiente o terminar la reproducción.
  • Tabla “vocesSonidos” (partes lo y hi): Esta tabla contiene punteros a las tablas de definición de los sonidos. Estos punteros nos facilitan el acceso a estas tablas usando el modo de direccionamiento indirecto – indexado.

En realidad, de las cuatro tablas, sólo la primera sirve para llevar cuenta de qué eventos han ocurrido y qué sonidos deben reproducirse. Las otras tres tablas son tablas de apoyo que facilitan la reproducción de los sonidos (la entrada por la que voy, el número de ciclos que quedan para esa entrada, y el puntero a la tabla con la definición del sonido).

Ahora que ya conocemos la tabla “vocesActivas”, vamos a ver cómo tomar nota de que se ha producido un disparo o una explosión. Esto se hace con las rutinas “activaSonidoDisparo” y “activaSonidoColision” del fichero “Sonidos.asm”. La primera es así:

Asteroids - Activa sonido disparo.PNG

Y la segunda es así:

Asteroids - Activa sonido colisión.PNG

Ambas rutinas son muy parecidas, y básicamente lo que hacen en grabar el valor $01 en la entrada correspondiente a la voz del disparo (voz 0) o a la voz de la colisión (voz 1). Este valor sirve de señal a la rutina que “actualiza” o reproduce el sonido (la veremos más adelante), para que sepa que tiene que reproducir o continuar reproduciendo ese sonido.

Pero luego hay un matiz. Debemos pensar en la situación en que el usuario dispara constantemente, o se producen varias colisiones muy seguidas. ¿Qué queremos que ocurra en este caso? ¿Qué debe ocurrir ante los sucesivos disparos o colisiones? Una opción es volver a empezar la reproducción del sonido desde el comienzo; otra opción es continuar por donde íbamos y no darnos por enterados.

Lo mejor es probar ambas soluciones y ver qué queda mejor en cada caso. En el caso de los disparos, que constan de dos entradas / frecuencias en la tabla de definición, si el usuario dispara de forma continuada, nunca llega a completarse la reproducción del sonido. Por ello, en este caso mejor si continuamos por dónde íbamos. Por eso no tocamos “vocesEntradas” ni “vocesRetardos”.

En el caso de las explosiones o colisiones, queda bien si volvemos a empezar la reproducción del sonido desde el comienzo. Hace un efecto como de acumulación de explosiones. Por eso en este caso, además de guardar $01 en “vocesActivas”, guardamos $00 en “vocesEntradas” y “vocesRetardos”. A todos los efectos, lo que estamos haciendo es volver al comienzo de la reproducción si ya hubiera una explosión sonando.

Estas rutinas que “toman nota” de los disparos y las explosiones lógicamente hay que llamarlas desde algún sitio. Y esos sitios son los evidentes:

  • La rutina “actualizaColisionesJugador” de “Jugador.asm”.
  • La rutina “creaDisparo” de “Disparos.asm”.
  • La rutina “actualizaColisionesAsteroides” de “Asteroides.asm”.

A modo de ejemplo, reproducimos aquí cómo se llama a “activaSonidoColision” desde “actualizaColisionesJugador” de “Jugador.asm”:

Asteroids - Activa sonido colisión - Llamada.PNG

Con esto ya hemos encajado tres de las cuatro piezas del puzle (inicialización del SID y las voces, definición de los sonidos, y eventos que dan lugar a sonidos). Nos queda la última pieza, que es la reproducción a lo largo de varios ciclos de juego.

Seguimos con la versión 22 del proyecto.


Código del proyecto: Asteroids22

Deja un comentario