Minilop Retroware

MPAGD Principiantes · Parte 20 de 29

Vamos a crear un juego con MPAGD, Parte 20: SCOREs, LIVES y mostrar cosas en pantalla.

30 de octubre de 2021

Nuestro juego empieza a tomar forma; ahora es probablemente un buen momento para ordenar el desastre que es ahora mismo la barra de puntuación en la parte superior de la pantalla. Antes de eso, veamos cómo almacena MPAGD la puntuación del jugador, cómo podemos sumarle puntos y cómo la mostramos en pantalla.

Primero, la puntuación no es una variable normal de 8 bits. Como recordarás, las variables de 8 bits pueden contener un número de 0 a 255. La puntuación en un juego de MPAGD puede contener un valor de 0 a 999,999, tras lo cual se reinicia a 0. No necesitas entender cómo lo hace, ¡solo que lo hace!

Recuerda que en la Parte 11 añadimos puntos cada vez que Stinky Dog recogía un hueso. Lo hicimos añadiendo el comando

SCORE 100

en el evento COLLECTBLOCK. El comando SCORE acepta un número de 16 bits, es decir, cualquier número de 0 a 65,535 (2 elevado a 16). El número que pongas después del comando SCORE se suma a la puntuación actual del jugador.

Ten en cuenta que SCORE no es una variable, así que no puedes hacer código que la consulte, como IF SCORE >50000 ADD 1 TO LIVES.

También actualizamos la puntuación en pantalla incluyendo el comando:

AT 0 6
SHOWSCORE

El comando AT es una forma abreviada de posicionar el cursor en la pantalla, así que el código de arriba equivale a:

LET LINE = 0
LET COLUMN = 6
SHOWSCORE

Pero ¿y si también quisiéramos la palabra 'SCORE:' antes de la puntuación, de modo que se muestre: SCORE: 000000... eso podría verse más ordenado.

Abramos nuestro script de GAME INITIALISATION:

EVENT GAMEINIT


LET LIVES = 3
AT 0 27
DISPLAY LIVES

AT 0 6
SHOWSCORE

...y vamos a ordenarlo un poco:

EVENT GAMEINIT

AT 0 0 
PRINT "SCORE:"
SHOWSCORE


LET LIVES = 3
AT 0 21
PRINT "LIVES:"
DISPLAY LIVES

Ahora nuestra barra de puntuación se ve un poco más ordenada:

Captura de pantalla del tutorial

Vemos que AT 0 0 coloca el cursor en la celda de carácter de arriba a la izquierda de la pantalla; luego hacemos PRINT de la palabra 'SCORE:' y mostramos la puntuación real al lado (fíjate en que el cursor pasa automáticamente a la siguiente columna disponible, por lo que en nuestro evento de inicialización del juego podemos ahorrar unos bytes quitando el AT 0 6 antes de SHOWSCORE... ya que tras imprimir 'SCORE:' ¡el cursor ya está ahí!).

Luego pasamos el cursor a 0 21 para mostrar las vidas que quedan.

Otra bonificación relacionada con la puntuación en MPAGD es... BONUS. Funciona de forma parecida a SCORE, en el sentido de que puedes sumar al bonus del jugador con un comando como:

BONUS 50

Que activas cuando el jugador hace algo. Vamos a darle a Stinky Dog un BONUS si uno de sus nocivos pedos aturde a Sideways Clive...

Abre tu evento SPRITETYPE 1 y busca la parte que trata de la colisión del pedo con Sideways Clive...

IF COLLISION 2             ; if Clive touches a Type 2 sprite (the fart)
   IF DIRECTION = LEFT     ; if Clive is going left
      LET SETTINGB = 0     ; remember the direction he was going, 0 = Left
   ELSE                    ; if he wasn't going left
      LET SETTINGB = 1     ; he was going RIGHT, 1 = RIGHT
   ENDIF
   LET DIRECTION = 5       ; set the direction to STUNNED
   LET SETTINGA = 0        ; start the stunned timer
   OTHER                   ; switch to the Fart 
   REMOVE                  ; remove the fart 
   ENDSPRITE               ; switch back to this event
   LET F = 0               ; reset the Fart in play to no fart in play
   BONUS 50                ; add 50 to the bonus
ENDIF

Ahora, cuando un pedo golpee a Clive, aumentaremos el bonus.

Ten en cuenta que el BONUS no se suma automáticamente a la puntuación: se irá acumulando mientras jugamos, y lo sumaremos más adelante, cuando Stinky Dog complete un nivel del juego.

Como SCORE, solo puedes incrementar el BONUS con números de hasta 65535 y llegará como máximo a 999999.

Ahora mismo, en nuestro juego, un nivel se completa cuando Stinky Dog recoge todos los huesos de la pantalla; comprobamos si se han recogido todos en nuestro evento COLLECTBLOCK, que actualmente tiene este aspecto:

EVENT COLLECTBLOCK

SCORE 100                  	; score 100 points when we collect a Bone
AT 0 6 
SHOWSCORE			; display the score

SUBTRACT 1 FROM B	; decrement the number of bones left on screen
IF B = 0                ; have all Bones been collected?
   NEXTLEVEL            ; if so move to the next screen
ENDIF

Hagámoslo un poco más interesante: borraremos la pantalla, mostraremos el bonus, lo sumaremos a la puntuación y luego empezaremos el siguiente nivel.

A la hora de borrar la pantalla, tenemos dos comandos entre los que elegir:

CLS: borra toda la pantalla

CLW: borra solo la ventana de juego y no la barra de puntuación que tenemos arriba (o donde hayas puesto la tuya)

Vamos a borrar la pantalla, mostrar la puntuación, el bonus, sumar el bonus a la puntuación y mostrar la nueva puntuación total, y luego esperaremos a que el jugador pulse una tecla para empezar el siguiente nivel.

EVENT COLLECTBLOCK

SCORE 100                  	; score 100 points when we collect a Bone
AT 0 6 
SHOWSCORE			; display the score

SUBTRACT 1 FROM B	; decrement the number of bones left on screen
IF B = 0                ; have all Bones been collected?
   CLS                  ; clear the screen
   AT 10 2              ; at line 10, column 2...
   SHOWSCORE            ; display the score
   DELAY 25             ; wait 1 second
   PRINT " + "          ; display +
   DELAY 25             ; wait another second
   SHOWBONUS            ; display the bonus
   DELAY 25             ; wait another second
   PRINT " = "          ; display =
   DELAY 25             ; wait another second
   ADDBONUS             ; add the bonus to the score
   ZEROBONUS            ; reset the bonus to 0 now we've added it
   SHOWSCORE            ; display the new score
   AT 15 8              ; at line 15 column 8
   PRINT "PRESS KEY TO START"
   WAITKEY              ; wait for a key press
   NEXTLEVEL            ; if so move to the next screen
ENDIF

Probémoslo...

Parece que funcionó... pero ¿te fijaste en el problema?

Justo al final, cuando empezó el siguiente nivel, la barra superior desapareció por completo. Pero luego vuelven el valor de la puntuación y el de las vidas...

¿Por qué ocurre eso?

Bueno, primero usamos el comando CLS cuando Stinky Dog recoge el último hueso. CLS borra por completo toda la pantalla, así que la barra de puntuación también desaparece.

Entonces, ¿por qué no se restablece cuando empieza el siguiente nivel?

En pocas palabras, la respuesta es que nuestro código no se lo dice. Ahora mismo ponemos el código PRINT "SCORE:" y PRINT "LIVES" en nuestro evento GAME INITIALISATION. Este evento solo se ejecuta cuando el juego arranca por primera vez. La puntuación aparece cuando recogemos el primer hueso, y las vidas aparecen cuando nos matan, porque tenemos los comandos SHOWSCORE y SHOWLIVES en los eventos COLLECTBLOCK y KILL PLAYER respectivamente.

Para solucionarlo, vamos a mover los comandos PRINT al evento RESTARTSCREEN. Este evento se ejecuta cada vez que reiniciamos una pantalla (incluso después de una muerte y cuando empezamos un nivel nuevo).

Así que abre tu script GAME INITIALISATION y corta todo lo que hay debajo de EVENT GAMEINIT excepto LET LIVES = 3, de modo que ahora debería quedar así:

EVENT GAMEINIT

LET LIVES = 3

Después abre tu evento RESTART SCREEN y pega el código encima de la sentencia DATA... ahora debería quedar así:

EVENT RESTARTSCREEN
RESTORE
READ B              ; read the first value of the DATA and put it in B
IF SCREEN >= 1      ; if it is screen 1 or above
   REPEAT SCREEN    ; then repeat SCREEN-many times
   READ B           ; read the next value
   ENDREPEAT        ; so we've found the right B value for the Screen
ENDIF

AT 0 0 
PRINT "SCORE:"
AT 0 6
SHOWSCORE

AT 0 21
PRINT "LIVES:"
DISPLAY DOUBLEDIGITS LIVES


;-------------------number of Bones per screen-------------------------
DATA 5 7 3 4 6 9 5 8 5 6 4 8 6 9 3 8 9
DATA 4 7 8 10 

Dejamos la sentencia LET LIVES = 3 en Game initialisation porque solo queremos que se ejecute una vez, cuando el juego arranca por primera vez. Si la pusiéramos en el evento RESTARTSCREEN, el número de vidas se restablecería cada vez que se reiniciara la pantalla.

La variable de vidas en MPAGD puede contener un número de 8 bits (0-255) y, a diferencia de SCORE y BONUS, podemos escribir código alrededor de ella. Por ejemplo, podríamos usar 'ADD 1 TO LIVES' si el jugador recogiera un objeto concreto.

Se comporta de forma un poco distinta a las variables normales: si llega a 0 (no quedan vidas), MPAGD ejecutará el evento 'LOST GAME'.

Como LIVES es una variable de 8 bits, también necesitamos usar el comando DISPLAY para mostrarla.

El comando DISPLAY también tiene parámetros adicionales que podemos usar para controlar cómo se muestra en pantalla. Son estos: DISPLAY SINGLEDIGIT: solo mostrará de 0 a 9,

DISPLAY DOUBLEDIGITS: solo mostrará de 0 a 99, con un 0 delante de 0 a 9 (00, 01, 02, etc.)

DISPLAY TRIPLEDIGITS: mostrará de 0 a 255, con 00 delante de 0 a 9 y un 0 delante de 10 a 99

En nuestro juego voy a limitar el número de vidas que se pueden ganar a un máximo de 10, así que he añadido el parámetro DOUBLEDIGITS al comando en el código de arriba (resaltado). En cuanto a cómo limitar las vidas a un máximo de 10... volveremos a eso más adelante.

Como hemos usado DOUBLEDIGITS para mostrar las vidas en el evento RESTARTSCREEN, tendremos que hacer lo mismo allí donde nuestro código le diga al juego que muestre las vidas. Ahora mismo solo debería haber otra referencia a LIVES, que está en nuestro evento KILL PLAYER, que se activa cada vez que matamos al jugador. Abre tu evento KILL PLAYER y añade DOUBLEDIGITS...

EVENT KILLPLAYER


SUBTRACT 1 FROM LIVES
AT 0 27
DISPLAY DOUBLEDIGITS LIVES
ZEROBONUS

También quiero retocar un poco el juego, así que he añadido ZEROBONUS al evento KILLPLAYER. De ese modo, si matan a Stinky Dog, perderá las bonificaciones de pedos que haya acumulado.

Vamos a probar el juego...

Vale, parece que funciona como esperábamos, pero no me convencen mucho la fuente ni los colores que rodean el área de juego. Creo que ya es hora de ocuparnos de eso...

SIGUIENTE: PARTE 21: Cambiar fuentes, COLOUR, PAPER, INK y CLUT

Todo MPAGD Principiantes