Tutorial de ZX Basic + Fourspriter #24: Boomerang

Lo siguiente que vamos a ver es una posible manera de darles caña a los enemigos porculeros que hemos creado. Podríamos hacerlo de mil formas, pero ya que nos queda un sprite libre, vamos a implementar un arma chula: un boomerang.

Nuestro boomerang tendrá un comportamiento sencillo, pero más complejo que el de un sencillo proyectil: cuando lo lancemos, avanzará en la dirección hacia la que esté mirando nuestro personaje un número determinado de casillas, y luego volverá en plan magia adonde nosotros estemos (vamos, que si nos movemos, el boomerang no se va a perder). El boomerang también volverá si choca contra algún obstáculo (aunque, volviendo, ignorará los obstáculos, por aquello de simplificar un poco) o si alcanza algún enemigo, al cual asesinará vilmente.

¿Os sugiere algo el párrafo de antes? Hay que aprender a pensar como programador de güegos. Examina el párrafo y verás algo interesante: el boomerang tiene que tener dos comportamientos diferentes: avanzando y volviendo. ¿A qué te suena eso? Exacto: a una máquina de estados. Otra.

Las máquinas de estados se usan mucho haciendo güegos. De hecho, aprender a diseñarlas es clave si quieres comportamientos más o menos elaborados y cosas que ocurran a la vez.

Intuitivamente, nos damos cuenta de que la máquina de estados que describe el comportamiento del boomerang tendrá tres estados:

  • Estado idle, BOOESTIDLE: no se hace nada. El boomerang no aparece en pantalla siquiera.
  • Estado avanzando, BOOESTAVANZANDO: Si el boomerang está en BOOESTIDLE y pulsamos “fire” (SPACE o M), pasaremos al estado BOOESTAVANZANDO. En este estado, decrementaremos un contador y haremos que el boomerang avance. Cuando el contador llegue a cero, golpeemos el escenario, o choquemos contra un enemigo pasaremos al siguiente estado.
  • Estado volviendo, BOOESTVOLVIENDO. En este estado, el boomerang avanza sin remedio hasta el jugador. Cuando lo alcanza, volvemos a BOOESTIDLE.

También hay que tener en cuenta que al entrar en una nueva pantalla habrá que colocar al boomerang en estado idle.

Con todo esto y un bizcocho, vamos crear e importar los gráficos y a plantear el esqueleto de nuestro manejador de boomerangs, el cual rellenaremos vilmente en el próximo capítulo. Por eso empezamos dibujando cuatro frames de rotatoria animación para nuestra siniestra arma:

 

Empecemos con el esqueleto de nuestro manejaboomeranes. Lo primero es crear un nuevo archivo boomerang.bas, que no tenemos que olvidar incluir en feoncio.bas a golpe de #include once. En nuestro nuevo boomerang.bas empezaremos definiendo alguna que otra constante:

'' Boomerang.bas
'' Controla el boomerang de feoncio
''

'' Constantes
Const BOOAVANCE as uByte = 12

Const BOOESTIDLE as uByte = 0
Const BOOESTAVANZANDO as uByte = 1
Const BOOESTVOLVIENDO as uByte = 2

La primera constante, BOOAVANCE, es la que indica cuántos caracteres avanzará nuestro boomerang. Empezaremos por 12… Luego siempre podemos afinar. Luego tenemos tres constantes para llamar a los estados de la máquina de estados finitos. Así el código es más legible (como ocurría con el tema bicharraquístico). Una vez definido todo esto, vamos con un set básico de variables:

'' Variables
Dim booX, booY as uByte
Dim booMX, booMY as Byte
Dim booFrame as uByte
Dim booState as uByte
Dim booCt as uByte

Lo de siempre: nuestras coordenadas (booX y booY), una pareja de variables para indicar la dirección del movimiento del boomerang (booMX y booMY), booFrame para indicar el frame de animación, booState para indicar en qué estado está la máquina de estados y booCt para contar pasos en el estado BOOESTAVANZANDO.

Acto seguido planteamos una función que servirá para ver si podemos lanzar el boomerang, y si eso, lanzarlo. Por ahora la dejaremos vacía, sólo codificaremos la cáscara:

Lo de siempre: nuestras coordenadas (booX y booY), una pareja de variables para indicar la dirección del movimiento del boomerang (booMX y booMY), booFrame para indicar el frame de animación, booState para indicar en qué estado está la máquina de estados y booCt para contar pasos en el estado BOOESTAVANZANDO.

Acto seguido planteamos una función que servirá para ver si podemos lanzar el boomerang, y si eso, lanzarlo. Por ahora la dejaremos vacía, sólo codificaremos la cáscara:

Sub fireBoomerang ()
   ' Lanzaremos el boomerang sólo si está en estado Idle
   ' Lo crearemos en una posición y en una dirección que 
   ' vendrán dadas por pFacing.
   ' Además, sólo lo crearemos si hay espacio libre en 
   ' la dirección a la que mire el player.
   
   If booState = BOOESTIDLE Then
      If pFacing = 0 Then
         ' Abajo
         
      ElseIf pFacing = 16 Then
         ' Arriba
         
      ElseIf pFacing = 32 Then
         ' Derecha
         
      Else
         ' Izquierda
         
      End If
   End If
End Sub

¿Qué hará esto? En primer lugar, comprobar que el boomerang esté en estado idle (no podemos lanzar el boomerang si no está en nuestras manos ¿no?). En caso positivo, mira para dónde mira el personaje principal, con el fin de asignar una dirección concreta al boomerang, y además comprobar que se puede lanzar el boomerang en esa dirección (por si se nos ocurre lanzar el boomerang mirando a la pared). Esta función será la que llamemos desde el bucle principal cuando el jugador pulse FIRE.

La siguiente función que plantearemos será la que implementa la máquina de estados finitos del boomerang y a la cual llamaremos en cada frame (como ya hacemos con muevePive y mueveBicharracos):

Sub mueveBoomerang ()
   ' Máquina de estados!
   If booState = BOOESTIDLE Then
   
   ElseIf booState = BOOESTAVANZANDO Then
   
   ElseIf booState = BOOESTVOLVIENDO Then
   
   End If
End Sub

Por ahora no hay nada, es solo el esqueleto básico y cascaroso de la máquina de estados. Queda rellenar de código cada estado.

Antes de terminar, vamos a integrar todo esto en nuestro engine. Abrimos feoncio.bas. Lo primero es, como hemos dicho, incluir el nuevo archivo al principio (lo repito porque, por ejemplo, a mí siempre se me olvida). Como vamos a necesitar las variables del boomerang en el módulo de los enemigos para detectar las colisiones (añadiremos código al estado activo de los enemigos), tenemos que incluir boomerang.bas ANTES que bicharracos.bas.

'' includes
#include once "fsp2.1.bas"
#include once "spriteset.bas"
#include once "udg.bas"
#include once "tileset.bas"
#include once "mapa.bas"
#include once "engine.bas"
#include once "boomerang.bas"
#include once "bicharracos.bas"

Ya son unos cuantos ¿eh? De todos modos, yo prefiero tener muchos archivos de código cortos que pocos archivos tochaquers. Cuestión de comodidad y orden, la verdad. Al compilador le da exactamente lo mismo y al Spectrum ya no te digo.

Seguimos. Tenemos que acordarnos de poner el boomerang a idle cada vez que entremos en una pantalla. Por tanto, modificamos nuestra rutina initScreen:

Sub initScreen ()
   ' Boomerang
   booState = BOOESTIDLE

   ' Bicharracos
   apagaBicharracos ()

   ' Pintar pantalla
   pintaMapa (MAPOFFSETX, MAPOFFSETY, nPant)
   
   ' Configurar sprite
   fsp21MoveSprite (3, pX, pY)
   fsp21DuplicateCoordinatesSprite (3)
   fsp21InitSprites ()
End Sub

Y lo último que queda es modificar el bucle principal. Lo primero es llamar a la función que mueve el boomerang en cada frame del juego. Tras la llamada que mueve a los bicharracos (o sea, mueveBicharracos), llamamos a:

   ' Mover boomerang
   mueveBoomerang ()

Justo después colocaremos el código que intenta lanzar el boomerang. Echamos mano de nuestra chuleta de detección de teclas para detectar la M y el SPACE y, si eso, llamar a la rutina correspondiente:

   ' Disparar boomerang
   If (In (32766) bAnd 1) = 0 Or (In (32766) bAnd 4) = 0 Then
      fireBoomerang ()
   End If

Y poco más. Podéis descargar el paquetito, aunque en rigor no haga nada nuevo… Pero para los completistas. En el próximo capítulo rellenaremos todo el esqueleto y a otra cosa, mariposa.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: