Supón que en tu juego quieres dar al jugador una cantidad de tiempo fija para completar cada pantalla. Y luego, quizá, darle una bonificación según el tiempo que le quede cuando complete con éxito los objetivos del nivel.
¿Cómo lo haríamos?
Primero, MPAGD funciona a 25 fotogramas por segundo, así que debería ser bastante sencillo crear un mecanismo de tiempo que cuente segundos.
Segundo, necesitaremos algunas variables para guardar (y mostrar) la cantidad actual de minutos/segundos restantes.
Tercero, puede que queramos cambiar el tiempo permitido pantalla por pantalla, o quizá usar niveles de dificultad para alterar el tiempo permitido.
MÉTODO 1 - Sencillo: la misma cantidad de tiempo en cada pantalla
Empezaremos con una versión sencilla, donde cada pantalla tiene una cantidad fija de segundos y minutos para completarla; si el temporizador llega a 0, el jugador muere.
Bien, MPAGD funciona a 25 fotogramas por segundo. Así que si tenemos una variable que se incrementa una vez por fotograma, cuando llegue a 25 habremos cronometrado un segundo.
Usaremos la variable G como nuestro tiempo general, contando 1/25 de segundo.
También necesitaremos variables que guarden el número de minutos y segundos permitidos por pantalla:
M = Minutos
S = Segundos.
Inicializaremos los valores de estas tres variables en nuestro evento RESTART SCREEN; así se reiniciarán cada vez que empecemos una pantalla, incluso después de una muerte. En tu evento restart screen añadirás:
LET G = 0 ; reset the 1/25s timer LET M = 1 ; countdown minutes allowed LET S = 0 ; countdown seconds allowed
A continuación, añadiremos código que haga y muestre la cuenta atrás. Para asegurarnos de que se ejecute de forma constante durante todo el juego, lo pondremos en el evento MAINLOOP 1, de modo que se ejecute al comienzo de cada fotograma:
; COUNTDOWN TIMER
;================
ADD 1 TO G ; increment the general timer
IF G = 25 ; when it reaches 25
LET G = 0 ; reset it
SUBTRACT 1 FROM S ; decrement seconds remaining
ENDIF
IF S = 0 ; if 0 seconds
IF M = 0 ; and 0 minutes left
KILL ; kill the player
EXIT ; exit processing this event
ENDIF
SUBTRACT 1 FROM M ; decrement the minutes
LET S = 59 ; reset the seconds
ENDIF
COLOUR 71 ; white text on black (zx spectrum)
AT 22 26
DISPLAY DOUBLEDIGITS M ; display minutes remaining
CHR 58 ; ':'
DISPLAY DOUBLEDIGITS S ; display seconds remainingAsí que incrementamos G; cuando llega a 25 lo reiniciamos a 0 y decrementamos el número de segundos (S); cuando S llega a 0 lo reiniciamos a 59 y decrementamos el número de minutos, salvo que no queden minutos, en cuyo caso se nos ha acabado el tiempo y matamos al jugador. Así es como debería verse...
MÉTODO 2 - Avanzado: distinta cantidad de tiempo por pantalla
Si queremos alterar el tiempo disponible, solo tenemos que cambiar el código de inicialización de variables de nuestro evento RESTART SCREEN para usar una tabla DATA y hacer READ de los valores de Minutos (M) y Segundos (S)
Podemos usar esto para la inicialización de variables en RESTART SCREEN
LET G = 0 ; reset the 1/25s timer RESTORE ; restore the data table so we read from the start READ M ; read the 1st data and put it in M READ S ; read 2nd value put it in S IF SCREEN >= 1 ; if it is screen 1 or above REPEAT SCREEN ; then repeat SCREEN-many times READ M ; read the next value for M READ S ; and the next value for S ENDREPEAT ; so we've found the right M & S values for the Screen ENDIF
Luego añadiremos esto como nuestra tabla DATA; los valores alternan entre minutos y segundos, así que el tiempo permitido en la SCREEN 0 es 0 minutos y 30 segundos (los 2 primeros valores), para la SCREEN 1 es 1 minuto y 0 segundos (valores 3 y 4), para la Screen 2 es 1 minuto y 15 segundos (valores 5 y 6), y así sucesivamente.
DATA 0 30 1 0 1 15 2 0 1 45 1 30 1 0 1 30
Añadir una bonificación por completar la pantalla
Todo lo que hemos hecho hasta ahora sirve para matar al jugador si se le acaba el tiempo, pero ¿y si completa los objetivos de la pantalla? Podríamos añadir una bonificación según el tiempo restante. Dependiendo de qué active la finalización de la pantalla (en Stinky Dog es recoger todos los huesos), tendrás que añadir tu rutina de bonificación en el evento adecuado. Podría ser algo así:
IF M > 0 ; if there are minutes left
REPEAT M ; repeat for each minute remaining
REPEAT 60 ; repeat 60 times (60 sec)
BONUS 10 ; increase bonus by 10
ENDREPEAT
ENDREPEAT
ENDIF
IF S > 0 ; if there are seconds left
REPEAT S ; repeat for each second
BONUS 10 ; increase the bonus by 10
ENDREPEAT
ENDIF
ADDBONUS ; add the bonus to the score
ZEROBONUS ; reset bonus to zeroAplicarlo a nuestro juego Stinky Dog
En nuestro juego Stinky Dog, sin embargo, hay un par de cambios que quiero hacer.
Primero, ya tenemos una tabla DATA en RESTART SCREEN 0, que guarda el número de huesos que hay que recoger por pantalla. No hay problema, a MPAGD no le importa qué datos guarda en la tabla DATA, así que solo tenemos que incluir los valores de huesos y hacer READ tres veces por ciclo para obtener el número correcto de huesos, minutos y segundos.
LET G = 0 ; reset the 1/25s timer RESTORE ; restore the data table so we read from the start READ M ; read the 1st data and put it in M READ S ; read 2nd value put it in S READ B ; read third value and put it in B for Bones IF SCREEN >= 1 ; if it is screen 1 or above REPEAT SCREEN ; then repeat SCREEN-many times READ M ; read the next value for M READ S ; and the next value for S READ B ; and the next values for B ENDREPEAT ; we've found the right M, S & B values for the Screen ENDIF
Y la tabla DATA al final de RESTART SCREEN:
DATA 0 30 6 1 0 7 1 15 3 2 0 4 1 45 6 1 DATA 30 4 1 0 8 1 30 6
A continuación, como ya hemos creado una rutina de muerte reutilizable a la que llamamos poniendo el valor SETTINGA de Stinky Dog en 99, voy a mover el código del temporizador de cuenta atrás de MAINLOOP 1 al evento del jugador, quitar el comando KILL y cambiarlo por LET SETTINGA = 99
NOTA: Coloca el código DESPUÉS de tu rutina IF SETTINGA = 99 ....ENDIF
; COUNTDOWN TIMER
;================
ADD 1 TO G ; increment the general timer
IF G = 25 ; when it reaches 25
LET G = 0 ; reset it
SUBTRACT 1 FROM S ; decrement seconds remaining
ENDIF
IF S = 0 ; if 0 seconds
IF M = 0 ; and 0 minutes left
LET SETTINGA = 99 ; kill the player
EXIT ; exit processing this event
ENDIF
SUBTRACT 1 FROM M ; decrement the minutes
LET S = 59 ; reset the seconds
ENDIF
COLOUR 71 ; white text on black (zx spectrum)
AT 22 26
DISPLAY DOUBLEDIGITS M ; display minutes remaining
CHR 58 ; ':'
DISPLAY DOUBLEDIGITS S ; display seconds remaining
Aquí lo tienes en acción cuando se nos acaba el tiempo
Para añadir una bonificación de tiempo nueva al completar la pantalla tendremos que actualizar nuestro evento COLLECT BLOCK:
EVENT COLLECTBLOCK
SCORE 100 ; score 100 points when we collect a Bone
AT 0 6
COLOUR 71
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 4 6
MESSAGE 1 ; "well done"
CHR 32
MESSAGE 0 ; "stinky dog"
CHR 33
DELAY 25 ; wait another second
COLOUR 65 ; bright blue on balck
AT 7 7
MESSAGE 2 ; "score"
CHR 32 ; <space>
DELAY 25 ; wait another second
SHOWSCORE
DELAY 25 ; wait another second
AT 9 2
COLOUR 70 ; bright yellow on black
MESSAGE 3 ; "fart"
CHR 32 ; <space>
MESSAGE 4 ; "bonus"
CHR 32 ; <space>
DELAY 25 ; wait another second
SHOWBONUS ; display the bonus
ADDBONUS ; add the bonus to the score
ZEROBONUS ; reset the bonus to 0 now we've added it
DELAY 25 ; wait another second
COLOUR 67 ; bright magenta on black
AT 11 2
MESSAGE 7 ; "time"
CHR 32 ; <space>
MESSAGE 4 ; "bonus"
CHR 32 ; <space>
DELAY 25 ; wait another second
IF M > 0 ; if there are minutes left
REPEAT M ; repeat for each minute remaining
REPEAT 60 ; repeat 60 times (60 sec)
BONUS 10 ; increase bonus by 10
ENDREPEAT
ENDREPEAT
ENDIF
IF S > 0 ; if there are seconds left
REPEAT S ; repeat for each second
BONUS 10 ; increase the bonus by 10
ENDREPEAT
ENDIF
SHOWBONUS
ADDBONUS ; add the bonus to the score
ZEROBONUS ; reset bonus to zero
AT 13 5
COLOUR 71
MESSAGE 8 ; "total"
CHR 32
CHR 61
CHR 32
SHOWSCORE ; display the score
DELAY 25 ; wait 1 second
AT 17 8 ; at line 15 column 8
COLOUR 215
MESSAGE 5 ; "press key to start"
WAITKEY ; wait for a key press
NEXTLEVEL ; if so move to the next screen
ENDIFFíjate en que he añadido dos mensajes nuevos a los TEXT MESSAGES:
DEFINEMESSAGES "STINKY DOG" ;0 "WELL DONE" ;1 "SCORE" ;2 "FART" ;3 "BONUS" ;4 "PRESS KEY TO START" ;5 "LIVES" ;6 "TIME" ;7 "TOTAL" ;8
¡Aquí está todo funcionando de maravilla!
