Asteroids: niveles de dificultad progresivos #Programación retro del Commodore 64

Si habéis jugado a la versión 18 del proyecto, habréis visto que el juego se pone extremadamente difícil nada más empezar. Hay demasiados asteroides (aunque el máximo es sólo siete) y se mueven muy deprisa. Total, enseguida se agotan las vidas del jugador, aunque de momento todavía no estamos controlando si han llegado a cero.

Además, lo anterior ocurre a pesar de que la rutina que activa los asteroides ("actualizaAsteroidesActivos") no los activa todos de golpe, sino que sólo activa uno en cada ciclo de juego. Pero el código máquina es tan rápido que, sin darnos cuenta, enseguida tenemos todos los asteroides activos.

Lo normal es que, según va avanzando un juego, éste se vaya poniendo paulatinamente más difícil. La mayor dificultad puede consistir en tener más enemigos, tener enemigos más listos o más rápidos, recibir retos más difíciles de resolver, etc.

Por otro lado, el "avance" del juego suele determinarse por el mero paso del tiempo, por el número de enemigos eliminados, por los puntos conseguidos, por las pantallas superadas, etc.

En nuestro caso particular, la mayor dificultad va a consistir en que aparezcan más asteroides (hasta siete), pero de una forma verdaderamente progresiva. Además, también podríamos hacer que éstos se movieran más rápido, de modo que fuera más difícil esquivarlos y destruirlos.

Y el "avance" del juego lo determinaremos en función de un nivel del jugador, que irá subiendo según éste vaya destruyendo asteroides.

La definición del nivel podemos verla en las variables del jugador. Obsérvese que ahora definimos dos variables nuevas, "jugadorNivel" y "jugadorRetardoNivel":

Asteroids - Nivel del jugador

La variable "jugadorNivel" es el nivel del jugador. Irá subiendo de valor según el jugador vaya matando asteroides. Y la segunda variable, "jugadorRetardoNivel", la usaremos para lo mismo que el resto de retardos del juego (giros de la nave, disparos, animaciones, etc.), para no incrementar el nivel con cada asteroide destruido, sino con cada N.

De este modo, al destruir un asteroide seguimos haciendo lo mismo que hasta ahora:

  • En la rutina "actualizaColisionesAsteroides", detectamos la colisión entre el disparo y un asteroide (registro SPBGCL). Señalizamos la colisión cambiando a $02 el estado del asteroide afectado.
  • En la rutina "animaExplosionAsteroide", hacemos la animación de la explosión para el asteroide afectado.
  • Siguiendo con la rutina "animaExplosionAsteroide", cuando termina la animación de la explosión, incrementamos en diez los puntos del jugador, restauramos la animación, y ponemos el asteroide inactivo ($00), de modo que la rutina "actualizaAsteroidesActivos" puede volver a activarlo cuando estime oportuno.

Pero ahora tenemos una novedad. Además de incrementar en diez los puntos del jugador, tenemos que incrementar su nivel (cuando proceda). Esto lo hacemos con este trocito de código (etiqueta "aeaFinAnimacion" de la rutina "animaExplosionAsteroide"):

Asteroids - Incremento de nivel

Es decir, además de incrementar los puntos:

  • Decrementamos el retardo del nivel.
  • Sólo si el retardo ha llegado a cero, volvemos a ponerlo en cinco e incrementamos el nivel.
  • El nivel tiene un tope de seis. De ahí no dejamos que pase.

Por tanto, el jugador ya tiene un nivel (desde 0 hasta 6) que va ligado al número de asteroides que ha matado. Cuantos más asteroides destruidos, más nivel.

Por último, nos queda vincular la activación de nuevos asteroides al nivel del jugador. Cuanto mayor sea el nivel, más asteroides activos permitiremos.

Esto lo hacemos en una nueva versión de la rutina "actualizaAsteroidesActivos":

  • Recorremos la tabla "asteroidesActivos".
  • Si el asteroide está activo, pasamos al siguiente. Hasta un tope, claro.
  • Si el asteroide no está activo, lo activamos y determinamos aleatoriamente a partir del Jiffy Clock su coordenada X (dos bytes), su coordenada Y, su velocidad, su ángulo y su expansión. Lo posicionamos con "posicionaSprite" y lo configuramos con "configuraBasica" y "configuraAvanzada".

Hasta aquí, todo básicamente igual que en versiones anteriores. La principal novedad es que ahora el bucle no recorre los siete asteroides posibles, sino que sólo los recorre hasta el nivel actual del jugador (ver "cpy jugadorNivel"):

Asteroids - Activa asteroides nivel jugador

Esto hace que el número de asteroides activos en un momento dado esté limitado superiormente por el nivel del jugador.

Efectivamente, ese es el objetivo: que según el jugador va matando asteroides y ganando puntos, su nivel va subiendo, y el juego, a su vez, va respondiendo con más asteroides activos, es decir, se lo va poniendo más difícil.

Adicionalmente, podríamos meter otro factor de complejidad: la velocidad de los asteroides. Hasta ahora, esa velocidad la hemos venido determinando aleatoriamente a partir del Jiffy Clock:

Asteroids - Velocidad aleatoria

Sin embargo, también podemos ligarla al nivel del jugador con un código como éste (velocidad del asteroide = nivel del jugador + 1):

Asteroids - Velocidad por nivel

Sin embargo, con un código así, cuando el usuario llega al nivel seis, los asteroides se mueven de siete en siete pixels, lo cual es una locura. Por ello, se hace necesario volver al esquema inicial (velocidad aleatoria) o reducir un poco la velocidad utilizando alguna otra fórmula que la vincule con el nivel. En nuestro caso, volvemos al esquema aleatorio.

Por lo demás, la nueva rutina "actualizaAsteroidesActivos" incluye alguna otra novedad, por ejemplo, sendas llamadas a "verificaLimitesXAsteroides" y "verificaLimitesYAsteroides", de modo que, si las coordenadas aleatorias arrojadas por el Jiffy Clock no caen dentro de los límites permitidos, éstas son corregidas:

Asteroids - Verificación límites nuevos asteroides

Todo esto podéis verlo en la versión 19 del proyecto que, además, incluye una corrección para que los asteroides puedan ser expandidos o sin expandir. Esta corrección está un poco oculta en el código, así que dejaremos un poco más de tiempo para quien quiera responder al reto planteado en la entrada anterior.

Asteroids - Niveles progresivos

En la siguiente entrada dotaremos al juego de una pantalla inicial. Hasta ahora sólo hemos trabajado con la pantalla de juego propiamente dicha.


Editar

Josepzin

No hay comentarios:

Publicar un comentario