MPAGD incluye de serie un script para una plataforma móvil vertical (ascensores). Es bastante básico y no era lo que buscaba, pero con un poco de trabajo conseguí un efecto con el que quedé lo bastante satisfecho como para usarlo en mi primer juego, Cocoa and the Time Machine. También escribí para ese juego un script para aplastadores, bloques que suben y bajan y que el jugador tiene que esquivar para no sufrir un golpe aplastante. No pude evitar notar las similitudes en el código de los dos eventos, así que cuando me puse a escribir 24 Hour Parsley People los combiné, para poder usar el mismo script para un ascensor y un aplastador, ahorrando de paso unos preciosos bytes.
Primero veamos la plataforma móvil de serie. En el vídeo de abajo, el bloque amarillo es la plataforma móvil vertical estándar de MPAGD (los cian son mi versión... ya llegaremos a ellos más adelante)
La versión estándar funciona bastante bien como plataforma móvil, el jugador puede subirse y bajarse sin problema. Cuando el ascensor baja, visualmente no queda muy bien... se ve cómo el sprite del jugador rebota. Otra cosa que no me gustaba es que el jugador parece poder atravesarlo caminando, algo que nunca queda bien, y que no iba a servir para que funcionara como aplastador. Además, la versión estándar deja de subir si el jugador puede quedar atrapado arriba; de nuevo, yo quería que funcionara de forma algo distinta: para añadir peligro quiero que el jugador salga herido si se queda en el ascensor (¡al fin y al cabo es un ascensor aplastador!)
Otro efecto que quería añadir era que el ascensor suba lentamente y luego caiga más deprisa.
Aquí tienes un vídeo con una versión simplificada de mi código, que usaremos para este tutorial:
Si te fijas (mira el valor de Health), los ascensores aplastadores causarán daño si el jugador queda aplastado arriba y si un aplastador cae sobre él.
Y aquí está el código:
IF IMAGE 9
SPRITEINK 13
IF COLLISION 0 ; if cocoa collides with the lift
LET P = Y ; Store the lift Y value in P
LET K = X ; STORE LIFT X VALUE IN K
OTHER ; switch to Cocoa
IF P > Y ; is crusher beneath cocoa?
SUBTRACT Y FROM P ; If so, by how many pixels?
IF P >= 6 ; more than 6?
SUBTRACT 8 FROM Y ; If so, lets look at what kind of block is above the player
GETBLOCK X Y
ADD 8 TO Y
IF BLOCK = WALLBLOCK ; is it a wall bock?
SPRITEDOWN ; if so, make the player fall off
FALL
ENDIF
IF CANGOUP ; Can the player go up?
ADD Y TO P ; lets reset the players Y value back to its original
LET Y = P
SUBTRACT 16 FROM Y ; and subtract 16 from it sp the player is now standing on the crusher/platform
STOPFALL ; and keep the player standing there
ELSE ; player cant go up any more?
SPRITEDOWN ; knock them off!
FALL
ENDIF
ELSE ; player must be stuck at the top!
SUBTRACT 10 FROM L ; that must hurt! inflict damage now!
ENDIF
ELSE ; players is BELOW THE CRUSHER
IF K < X ; is the player to the right?
IF CANGORIGHT ; if they can go right
ADD 2 TO X ; prevent the player passing through the crusher from the right
ENDIF
ELSE
IF CANGOLEFT ; player is to the left of the crusher
SUBTRACT 2 FROM X ; prevent the player passing through the crusher from the left
ENDIF
ENDIF
FALL
ENDIF
ENDSPRITE ; switch back to the Crusher
IF SETTINGA = 0
IF Y < G
SUBTRACT 10 FROM L
ENDIF
ENDIF
ENDIF
IF SETTINGA = 0 ; CRUSHER - GO DOWN
REPEAT 4 ; We'll use a repeat so the crusher goes downward quickly
IF CANGODOWN ; can it still go down?
SPRITEDOWN
ELSE ; if not
BEEP 20
LET SETTINGA = 2 ; lets make the crusher stay at the bottom
LET SETTINGB = 0 ; we use SETTINGB as a timer so lets reset it
ENDIF
ENDREPEAT
ENDIF
IF SETTINGA = 1 ; CRUSHER - GO UP
IF CANGOUP ; can the crusher go up?
IF Y >= 16 ; and is it at least 16px from the top of the Screen?
SPRITEUP ; go up!
ELSE ; if not
LET SETTINGA = 3 ; let's make the crusher wait at the top
LET SETTINGB = 0 ; SETTINGB is the timer, so reset it
ENDIF
ELSE ; if it cant go up any more
LET SETTINGA = 3 ; let's make it wait
LET SETTINGB = 0 ; and reset the timer
ENDIF
ENDIF
IF SETTINGA = 2 ; CRUSHER - WAIT AT BOTTOM
IF SETTINGB = DIRECTION ; Has the timer finished?
LET SETTINGA = 1 ; if so, tell the crusher to go up
LET SETTINGB = 0 ; and reset the timer
ELSE
ADD 1 TO SETTINGB ; timer hasnt finished so increment it 1
ENDIF
ENDIF
IF SETTINGA = 3 ; CRUSHER - WAIT AT TOP
IF SETTINGB = DIRECTION ; Has the timer finished?
LET SETTINGA = 0 ; if so, tell the crusher to go down
LET SETTINGB = 0 ; and reset the timer
ELSE
ADD 1 TO SETTINGB ; timer hasnt finished so increment it 1
ENDIF
ENDIF
ENDIFAdemás, vamos a necesitar poner algunos ajustes en el script Sprite Initialisation...
IF TYPE {WHATEVER THE NUMBER OF YOUR SPRITE EVENT IS}
LET SETTINGA = 0 ; the initial direction of the crusher/lift
LET SETTINGB = 0 ; the counter for waiting at the top/bottom
LET DIRECTION = 16 ; the number of cycles to wait
ENDIFComo puedes ver, el código principal se divide en dos partes. La primera es qué hacer si el jugador colisiona con el aplastador/ascensor, ya sea encima de él, yendo de paseo, o siendo aplastado arriba o abajo; también gestiona qué hacer si el jugador choca con un lado.
La segunda parte son las cuatro acciones principales del aplastador/ascensor: está subiendo, esperando arriba, cayendo o esperando abajo.
No recuerdo por qué usé SETTINGA para, en la práctica, las direcciones, y el parámetro DIRECTION como el número de ciclos que controla el tiempo de espera hasta el que SETTINGB se incrementa cuando el aplastador/ascensor está arriba o abajo... pero si no está roto, ¡no lo voy a arreglar!
Hay mucho que pasa en este script, pero es bastante flexible y te da dos funciones nuevas en una. Por supuesto, siéntete libre de adaptarlo a las necesidades de tus propios juegos y entornos.
¡Espero que te sirva de ayuda!
