Asteroids: colisiones de disparos con asteroides (paso II) #Programación retro del Commodore 64

La solución esbozada para las colisiones en la entrada anterior adolece de dos problemas:

  • Se puede identificar si algún asteroide ha colisionado con un disparo, pero no qué asteroide ha sido exactamente. Por tanto, de momento, no es posible hacer la animación de la explosión.
  • Los disparos son texto, pero las letras de la derecha también lo son. Por tanto, salvo que evitemos escrupulosamente que los asteroides pisen la zona derecha, en cuanto pisen lo más mínimo (un pixel), se producirá una colisión igual que si hubieran colisionado con un disparo.

En esta entrada vamos a resolver el primero de los dos problemas, es decir, la individualización de las colisiones. Dejamos para más adelante la solución del segundo problema que, en realidad, tiene una solución mejor que la esbozada en el punto anterior. Esa solución mejor –y también más compleja– es mover la información de posición, ángulo, velocidad, puntos, vidas, etc., a la línea inferior de la pantalla.

Bueno, pues vamos con la individualización de las colisiones. Se trata de saber exactamente qué asteroide es el que ha colisionado.

Desde un punto de vista teórico no parece difícil. En el fondo, se trata de recorrer los asteroides activos (sólo los asteroides activos pueden colisionar) y detectar si han colisionado o no leyendo el registro SPBGCL y, más en particular, el bit asociado al asteroide / sprite que estamos analizando.

Ahora bien, si nos ponemos manos a la obra sin más, la cosa no acaba de funcionar bien. El problema radica en que al leer el registro SPBGCL, igual que con SPSPCL y otros registros del C64, el registro se borra. Por tanto, si leemos el registro SPBGCL en bucle, una vez por cada asteroide activo, ya sólo con la primera lectura se nos borra.

La solución a este problema radica en leer el registro SPBGCL y guardarlo en una variable temporal ("acaTemp" en el código de más abajo). El valor guardado en esa variable temporal, que ya es una posición de memoria convencional, se puede leer N veces, una vez por cada iteración del bucle, porque ya no se borra como SPBGCL.

Esta forma de proceder puede verse en la nueva rutina "actualizaColisionesAsteroides":

Asteroids - Actualiza colisiones asteroides nueva

Es decir:

  • Leemos el registro SPBGCL. Al leerlo se borra.
  • Guardamos el valor de SPGBCL en "acaTemp". De este modo podemos leerlo varias veces, una vez por cada asteroide activo.
  • Recorremos los asteroides con el registro Y. Si el asteroide no está activo pasamos al siguiente.
  • Si el asteroide sí está activo, hacemos una "and" del bit que corresponde a su sprite (2 = %00000010 para el asteroide 1, 4 = %00000100 para el asteroide 2, 8 = %00001000 para el asteroide 2, …, 128 = %10000000 para el asteroide 7; recordemos que 1 = %00000001 sería la nave) y del valor de "acaTemp", es decir, del valor de SPBGCL. De este modo, sabemos si ese asteroide en particular colisionó.
  • Si no colisionó, pasamos al siguiente asteroide.
  • Si sí colisionó, incrementamos los puntos en 10, desactivamos el asteroide en la aplicación (poniendo $00 en "asteroidesActivos"), y también desactivamos su sprite en SPENA.

En definitiva, con esta nueva rutina "actualizaColisionesAsteroides" ya somos capaces de saber específicamente qué asteroide o asteroides colisionaron, y somos capaces de desactivarlos. Todavía nos queda la animación de la explosión, que será objeto de la entrada siguiente porque hay algún detalle adicional que meditar.

De hecho, como ya somos capaces de matar asteroides (aunque todavía no explotan, sí nos dan puntos y desaparecen), interesa descomentar la rutina "actualizaAsteroidesActivos", que se encarga de activar nuevos asteroides de forma paulatina. Por eso, vuelve a estar sin comentar, después de llevar varias entradas comentada:

Asteroids - Activa asteroides descomentada

Es más, en la rutina "actualizaAsteroidesActivos" hemos metido un par de pequeños cambios para que los nuevos asteroides que van activándose no nazcan siempre en la diagonal (ver "asl a" en la línea 193) y no puedan estar parados (ver "beq aaaVelocidad" en la línea 201):

Asteroids - Novedades actualiza asteroides

En esta rutina seguiremos metiendo novedades en el futuro. Las iremos comentando.

Con esto hemos llegado a un punto en que el juego está bastante completo. Tenemos una nave que se mueve, que dispara, que choca contra los asteroides y explota, y que puede matar asteroides, si bien estos todavía no explotan. Pero vamos avanzando poco a poco…

Asteroids - Juego btte completo

Todo esto puede verse en la versión 15 del proyecto. En la próxima entrada haremos que los asteroides exploten.


Código del proyecto: Asteroids15


Editar

Josepzin

No hay comentarios:

Publicar un comentario