Como adelantamos en la entrada anterior, no es posible pasar toda la animación de la explosión en un único ciclo del bucle de juego. Si se hace sin bucle de demora apenas es perceptible. Y si se hace con bucle de demora parece que el juego se "engancha" en las explosiones.
Por tanto, la solución es también la ya adelantada: meter un retardo en las explosiones, es decir, cambiar de "frame" cada N ciclos del bucle de juego.
Para hacer esto nos hace falta:
- Definir una nueva variable "jugadorActivo", de modo que podamos distinguir si el jugador está activo ($01), es decir, moviéndose y disparando, o si está explotando ($00).
- Definir una nueva variable "jugadorRetardoExplosion" de modo que, si el jugador está explotando, en cada ciclo del bucle de juego se va descontando uno y, al llegar a cero, se avanza el "frame" de la explosión. Esto mismo ya lo hicimos con los giros y los disparos de la nave.
- Definir una nueva variable "jugadorExplosionFrame". Esta variable nos servirá para llevar cuenta por qué "frame" de la explosión vamos y, junto con "jugadorRetardoExplosión", nos permitirá llevar el control de la animación.
- Definir una nueva variable "jugadorVidas". Hasta ahora no la habíamos definido, pero en todos los juegos el jugador tiene una serie de vidas y, al producirse determinados eventos –colisiones con asteroides en nuestro caso– éstas se van descontando.
Todo esto podemos verlo en la nueva sección de variables del jugador:

Pues bien, si ahora el jugador puede estar activo ($01) o explotando ($00), la actualización del jugador será diferente en uno y otro caso:

Es decir, si el jugador está activo ($01) haremos lo mismo que hasta ahora (actualizar su posición, tomar nota de sus disparos, y detectar sus colisiones). Ahora bien, si el jugador está explotando ($00), lo que haremos será animar la explosión.
Al empezar la partida el jugador nace activo ($01), y la transición a la situación de explotando se produce en la rutina "actualizaColisionesJugador", que ahora tiene una codificación diferente:

Efectivamente, si recordáis de la entrada anterior, cuando la rutina "actualizaColisionesJugador" detectaba una colisión mediante el registro SPSPCL = $d01e, inmediatamente hacía la animación llamando a "jsr animaExplosion". Ahora, sin embargo, se limita a cambiar el estado del jugador (lo pone a $00), y delega en la rutina "actualizaJugador" ya vista para que ésta haga lo que corresponda a esa situación. Y lo que corresponde es, nuevamente, ejecutar la animación.
Por último, la rutina "animaExplosion" también cambia, ya que es aquí donde se utiliza el nuevo retardo que va a permitir cambiar el "frame" de la explosión cada N ciclos del bucle de juego:

Como se puede observar, ahora una llamada a la rutina "animaExplosion", en principio, sólo reduce la variable "jugadorRetardoExplosion" y termina ("rts"). Ahora bien, cuando esa variable llega a cero, entonces sí, el retardo vuelve a ponerse a cinco y, además, se avanza el "frame" de la animación. Para saber por qué "frame" vamos y cuál corresponde ahora, utilizamos la variable "jugadorExplosionFrame".
Pero la rutina anterior no está completa, porque cuando termina la animación, es decir, cuando ya se han pintado los tres "frames" de la explosión, llama a una sección de la rutina "animaExplosion" etiquetada con "aeFinAnimacion":

Por tanto, al terminar la animación de la explosión, lo que hacemos es:
- Decrementar en uno las vidas del jugador. Por cierto, ahora las vidas del jugador también se muestran en pantalla (ver rutina "actualizaPantalla"). Lo que no hacemos todavía es controlar si las vidas han llegado a cero; lo dejamos para un poco más adelante.
- Volver a poner la variable "jugadorExplosionFrame" a cero, de modo que, si el jugador vuelve a colisionar, volvamos a empezar la animación de la explosión desde el primer "frame".
- Volver a poner al jugador como activo ($01), para que pueda volver a moverse y disparar.
- Y volver a leer el registro de colisiones SPSPCL. Esto es un truco y necesita explicación. Si no lo hacemos, siempre que la nave colisiona con un asteroide, la aplicación detecta dos colisiones seguidas y descuenta dos vidas. La forma de evitarlo es leyendo el registro SPSPCL por segunda vez al final de la animación. Recordemos que la lectura de este registro lo borra.
Y llegados a este punto (el final de la animación de explosión), podríamos volver a poner el juego en la situación inicial (nave en el centro de la pantalla, pocos asteroides, etc.), o continuar desde la situación actual no tocando nada más. Hemos optado por esto último.
Y ahora ya sí, por fin, podemos explotar a gusto:
En la versión 12 del proyecto podéis apreciar los avances.
Código del proyecto: Asteroids12
No hay comentarios:
Publicar un comentario