Minilop Retroware

MPAGD Avanzado

Crear bichos que caen al acercarse el jugador en MPAGD

15 de noviembre de 2020

...bueno, no se me ocurrió un nombre mejor para ellos. Son peligros que caen del techo justo cuando el jugador está a punto de pasar por debajo. Es otra mecánica que usé en Cocoa and the Time Machine y que mejoré en 24 Hour Parsley People.

Son bastante fáciles de implementar, y en el código de más abajo te mostraré cómo adaptarlos a tus propios juegos.

Primero veamos cómo funcionan. Aquí tienes un ejemplo en una pantalla de demostración....

Bien, hay un par de cosas que conviene tener en cuenta.

1. Solo quiero activar la caída cuando el jugador esté justo debajo

2. El jugador debe estar dentro de un rango vertical concreto respecto al enemigo que cae para activarlo

En otras palabras, hay que tener cuidado de no activarlos si el jugador pasa por encima del enemigo. Y en mi ejemplo no quiero que el jugador, estando en el nivel del suelo, active la caída del nivel de arriba.

Obviamente, tu caso puede necesitar reglas distintas, pero el código de abajo debería ser fácil de adaptar.

Primero, pensemos en cómo funcionan los sprites de MPAGD, y en concreto sus coordenadas. Cada sprite es un cuadrado de 16px por 16px. Y cada instancia de un sprite tiene un valor X y un valor Y, que son las coordenadas x & y de la esquina superior izquierda del sprite tal como aparece en la pantalla. Así que si tu sprite está en la esquina superior izquierda de la pantalla, su X sería 0 y su Y sería 0.

Ahora bien, el problema es que, con un enemigo que cae, necesitaremos conocer la X y la Y tanto del enemigo COMO del jugador. Y como nuestro código tendrá que vivir en uno de los eventos de sprite, probablemente tenga sentido usar uno de nuestros EVENTSPRITETYPE para el enemigo que cae. Así que necesitaremos un par de variables que guarden los valores X & Y del jugador. Yo suelo usar F & G para esto, simplemente por costumbre...puedes usar las que quieras. De cualquier forma, abre el evento del jugador y añadamos algo de código (yo suelo ponerlo al final del script del jugador):

LET F = X
LET G = Y

Bien, ahora podremos usar los valores X & Y del jugador cuando estemos en el script del enemigo que cae...

; FALLING NASTY
=============================
;variables
;F = the X coord of the player sprite
;G = the y coord of the player
;M - a temporary variable we will use to see if the player is close enough to trigger the fall
;SETTINGA - the x value 18 px to the left of the falling nasty
;SETTINGB - used as a timer for when the falling nasty hits the ground before it is removed


IF IMAGE 12                          
   SPRITEINK 13
   LET M = F                           ; set M to the X co-ord of the player
   ADD 18 TO M                         ; M is now 18px to the right of the player
   LET SETTINGA = F                    ; store the player x value in SettingA of the falling nasty
   SUBTRACT 18 FROM SETTINGA           ; SettingA is now 18 px to the left of the player
   
   IF Y <= G                           ; is the player beneath the falling nasty?
      SUBTRACT Y FROM G                ; if so, by how many pixels?
      IF G <= 63                       ; less than 63px?
         IF X = M                      ; is the player 18px to the right of the falling nasty?
	    LET DIRECTION = 1          ; if so trigger the fall
	 ENDIF
		 
         IF X = SETTINGA               ; is the player 18 px to the left of the falling nasty?
	    LET DIRECTION = 1          ; if so, trigger the fall
         ENDIF
      ENDIF
   ENDIF	
	
   IF DIRECTION = 1                    ; THE FALL
      IF CANGODOWN 		       ; can the falling nasty continue falling?
         SPRITEDOWN                    ; if so, fall (use spritedown's to control the speed of the fall
         SPRITEDOWN
         SPRITEDOWN
         IF COLLISION PLAYER           ; has it his the player?
            SUBTRACT 1 FROM L          ; (I was using L as the players health...but include what ever damage you want here)
         ENDIF
      ELSE	                       ; if it cant go down any further, if must have landed    
         ADD 1 TO SETTINGB             ; start a count to time the crashed animation
         CRASH 10                      ; make a crash sound
         IF SETTINGB = 21              ; crash has finished
            LET SETTINGB = 0 	       ; reset settingb
	        LET DIRECTION = 0      ; reset the direction
            REMOVE                     ; remove the falling nasty
         ENDIF
      ENDIF
   ENDIF
ENDIF

En este ejemplo usaba IMAGE 12; obviamente, quita ese IF/ENDIF según necesites, o cámbialo para que haga referencia a la imagen del sprite de tu enemigo que cae.

Lo que hacemos aquí es comprobar, en la práctica, la posición del jugador respecto al enemigo que cae: primero, si el jugador está debajo del enemigo que cae y, de ser así, si está dentro de nuestro rango de altura.

En el SETTINGA del enemigo que cae estoy guardando el valor X del jugador menos 18, es decir, 18 píxeles a la izquierda del jugador

Estoy haciendo algo parecido con la variable M, pero esta vez guardo el valor X de la posición actual del jugador MÁS 18, es decir, 18 píxeles a la derecha del jugador

Puedes cambiar 18 por cualquier valor que quieras, según lo pronto o lo tarde que quieras que se active la caída.

Así que, en cuanto M o SETTINGA coinciden con el valor x del enemigo que cae, activamos la caída.

NOTA: En este script uso varios 'SPRITEDOWNS' para marcar la velocidad de la caída; puedes usar tantos (o tan pocos) como necesite tu juego para hacer más fácil o más difícil esquivarlo. Como alternativa, podrías sustituir los SPRITEDOWNS por FALL (gracias a Alessandro Grussu por la sugerencia). Con FALL el sprite acelerará mientras cae.

Lo que hagas dentro de tu sentencia IF de colisión depende de ti; yo lo he dejado simple para los fines del tutorial. Después he usado el parámetro SETTINGB del enemigo que cae como temporizador (cuánto tiempo permanece en el suelo antes de desaparecer)...de nuevo, puedes adaptarlo como quieras, ¡quizá con un sprite de explosión, o algo totalmente distinto!

También sería fácil adaptar este código para, por ejemplo, activarlo desde arriba, ¡quizá como una forma divertida de matar a un enemigo!

¡Espero que te sirva de ayuda!

Todo MPAGD Avanzado