Tutorial de ZX Basic + Fourspriter #23: Colisiones

Una vez resueltos los problemas del parpadeo (aunque, como os adelanto, no será la última vez que nos pongamos a modificar la biblioteca fourspriter), lo siguiente es ponerse a detectar colisiones entre bicharracos y el protagonista principal del güego. Actuaremos de la siguiente forma: cuando un enemigo y el protagonista principal choquen (sus sprites se toquen), pasaremos el bicharraco al estado de morirse, para que explote y desaparezca, y restaremos 1 de la vida del jugador.

Por lo tanto, lo primero que necesitamos es almacenar la vida del jugador. Nos vamos a la zona de variables de engine.bas, y justo debajo de donde definimos pX y compañía añadimos una variable más:

Dim pEn as uByte

A esa variable habrá que darle un valor inicial. Nos vamos a feoncio.bas y, en la parte donde inicializamos a nuestro jugador (a partir de la linea 30), añadimos

pEn = 10

Ponemos 10 porque está bien para empezar. Luego ya afinaremos… Es lo típico: si el juego te queda muy facilorro ponemos menos vidas y listo. Eso se llama “diseño de gameplay cutre de cojones“, pero funciona. Ahora hacemos una subrutina para imprimir la vida que tenemos. Por ahora iremos a lo sencillo, creando esta rutina en la zona de subrutinas de feoncio.bas. Ya lo pondremos más bello cuando diseñemos un marco de juego en condiciones. Por ahora nos vale así:

Sub imprimeVida ()
   Print At 0,0; "E"; pEn; " ";
End Sub

Y llamamos a esta subrutina al principio del juego, antes de entrar en el bucle principal. Además, nos vamos a cargar nuestro bucle infinito, ya que ahora podremos morirnos. En la zona de variables de feoncio.bas creamos una nueva:

Dim gameOver as uByte

Esta variable actuará como bandera, de forma que justo antes de empezar el bucle tendremos que ponerla a 0. Cambiamos, por tanto, nuestro WHILE 1 original por:

gameOver = 0
While Not gameOver

Bien. Pongámonos al lío de verdad. Lo que tendremos que hacer, básicamente, es detectar una colisión en el bucle principal del juego. Si esto ocurre, mataremos al enemigo en implicado. Luego, en nuestra máquina de estados de los bicharracos, añadiremos código para gestionar el estado “muriendo”. Lo que haremos será que se muestre una pequeña animación con una explosión durante un tiempo, y luego se pase al estado Idle, con lo que, al poco rato, el enemigo volverá a aparecer de nuevo en otro sitio (y con otro color, sprite y comportamiento).

Lo primero que necesitamos, por tanto, es ampliar un poco nuestro spriteset. Nosotros hemos dibujado dos frames de explosión que quedarán realmente aparentes en el juego (ya lo veréis). Haremos lo de siempre: pintamos los frames, reordenamos la imagen, importamos con SevenuP, pasamos a BASIC.

 

Hecho esto, vamos a añadir el código. Lo primero será detectar la colisión. Si cogemos una hoja de cuadritos y nos pintamos los dos sprites, veremos que la colisión se dará si el enemigo (en realidad, su casilla superior izquierda, que es la que lleva su posición real) está dentro del cuadrado que va desde (pX – 1, pY – 1) hasta (pX + 1, pY + 1). Como véis, hacer juegos en 2D y pintarse 300 diagramillas son uno. Por lo menos hasta que no tengamos lo conceptos grabados a fuego.

Metemos esa comprobación dentro de un bucle que recorra todos los enemigos, y sólo la haremos si el enemigo en cuestión está en estado activo (para que no nos mate si está apareciendo, idle, o muriéndose). Metemos, por tanto, este bloque de código en el bucle principal. Por ejemplo, justo antes de las comprobaciones de cambio de pantalla:

   '' Colisiones
   
   For i = 0 To BICHNUMENEMS - 1
      If enState (i) = BICHESTACTIVO Then
         If enX (i) >= pX - 1 And enX (i) <= pX + 1 And _
            enY (i) >= pY - 1 And enY (i) <= pY + 1 Then
            mataBicharraco (i)
            mataPersonaje ()
         End If
      End If
   Next i

Como vemos, si se cumplen todas las condiciones, llamamos a dos subrutinas: mataBicharraco (pasándole el bicharraco indicado) y mataPersonaje. Empecemos por matar al personaje:

Sub mataPersonaje ()
   If pEn > 0 Then
      pEn = pEn - 1
   Else
      gameOver = 1
   End If
   imprimeVida ()
End Sub

Sencillo y directo ¿verdad? Si tenemos más de 0 vidas, restamos 1. En caso contrario, ponemos a cierto nuestra bandera de gameOver, con lo que terminaría el bucle principal (recordad el WHILE NOT gameOver que hemos puesto al principio).

Ahora toca matar al bicharraco. Nos vamos a bicharracos.bas para crear la subrutina mataBicharraco. En esta función nos prepararemos el estado BICHESTMURIENDO: pondremos el color a blanco, seleccionaremos el primer frame de explosión (que, en nuestro spriteset, empieza en el bloque número 128) y reutilizaremos el contador de los enemigos tipo “paso de tu culo” para contar 4 frames de explosión. Además, reiniciaremos el contador de frame de animación:

Sub mataBicharraco (i as uByte)
   enCt (i) = 4
   enState (i) = BICHESTMURIENDO
   enColorReal (i) = 7
   enSprite (i) = 128
   enFrame (i) = 0
End Sub

Ok – esto prepara el estado “muriendo” y lo activa. Sólo queda, por tanto, definir el comportamiento de dicho estado en nuestra máquina de estados. Básicamente cambiaremos de frame de animación mientras no se consuma el contador en enCt. Cuando esto ocurra, volveremos al estado BICHESTIDLE, con lo que volveríamos a empezar (el enemigo desaparece, y ya volverá a crearse). Como verás, se cumple la regla no escrita de que siempre que vayamos a activar o desactivar un sprite, hay que borrar los que estén en pantalla. Bueno, ya está escrita. Y tampoco permanecerá escrita mucho tiempo. Esto se hace así ahora porque fourspriter aún necesita una modificación que haremos dentro de poco:

        ElseIf enState (i) = BICHESTMURIENDO Then
            enCt (i) = enCt (i) - 1
            enFrame (i) = 4 - enFrame (i)
            If enCt (i) = 0 Then
               enState (i) = BICHESTIDLE
               fsp21BorraSprites ()
               fsp21DeactivateSprite (i)
            End If
        End If

Lo que hemos dicho: decrementar el contador enCt, cambiar de frame (pasa de 0 a 4, de 4 a 0, etc.), y comprobar si se ha agotado el contador. En ese caso, desactivar el sprite y volver el bicharraco al estado idle.

¡Probadlo, probadlo, veréis qué chulada! Lo próximo será hacer que nuestro prota sea un poco más beligerante. El paquetico, como siempre, para descargar.

 

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: