Minilop Retroware

MPAGD Avançado

Criar padrões para bichos estáticos em MPAGD

16 de novembro de 2020

Aqui está uma forma muito simples de acrescentar um padrão à aparição e desaparecimento de um vilão estático... sem o tornar aleatório. Para isso vamos usar os comandos DATA e READ do MPAGD.

O efeito que eu estava a tentar criar em 24 Hour Parsley People: Episode 2 era o de vapor a sair de um cano partido (clichés dos jogos de plataformas FTW!). Mas em vez de libertar vapor durante x segundos e parar durante y segundos, queria que funcionasse segundo um padrão, por exemplo:

...e assim por diante (com um número razoável, mas não ridículo, de variações)

Isto obrigaria o jogador a tentar descobrir o padrão antes de fazer o seu movimento.

Aqui está um exemplo do código a funcionar num ecrã de demonstração. Estou a usar a variável DIRECTION para guardar a definição de tempo atual do padrão: repara que um valor mais alto de DIRECTION = um período de tempo mais longo no padrão:

Este tipo de padrão é ideal para as funções 'DATA' e 'READ' do MPAGD. Mas primeiro vamos criar um sprite. No mínimo vais precisar de 2 fotogramas, 1 para o vilão e um em branco. No meu exemplo estou a usar 5 fotogramas: os primeiros 4 (números 0 a 3) são a animação do vapor e o quinto (#4) está em branco...

Assim, quando o vapor está a sair, vamos percorrer os fotogramas 0-3 e, quando deixa de sair, vamos manter o sprite no fotograma 4.

Isto significa que podemos causar dano se o jogador colidir com o sprite do vapor APENAS quando o fotograma do vapor estiver no intervalo de 0 a 3.

E aqui está o código do teu evento do vapor...

;=============================STEAM
IF IMAGE 4                       ; image number of the Steam sprite
   IF FRAME <> 4                 ; this part ensures the steam is white
      SPRITEINK 7                ; when venting
   ELSE                          ; but uses the players sprite colour when 
      SPRITEINK 6                ; off, else the sprite would take on the steams colour
   ENDIF
                                 ; STEAM IS VENTING
   IF SETTINGB = 0               ; I'm using SETTINGB as the ON/OFF state,  of the stem
      IF A = 1                   ; I'm using A in my main loop, used for slowing down
         ADD 1 TO SETTINGA       ; Im using SETTING A as the counter, spo let's increment iy
         ADD 1 TO FRAME          ; I cant use animate so lets increment the frame
         IF FRAME = 4            ; if the next frame is the Blank one
            LET FRAME = 0        ; dont show it, instead go back to the first frame
         ENDIF
      ENDIF

      IF SETTINGA >= DIRECTION   ; I'm using DIRECTION to hold the length of the pattern, has the counter reached it?
         LET FRAME = 4           ; If so, switch to the blank frame
         LET SETTINGB = 1        ; And switch to the OFF state routine
         LET SETTINGA = 0        ; Reset the counter
         READ DIRECTION          ; Get the next time length from the DATA and store it in DIRECTION
      ENDIF
   ENDIF
   IF SETTINGB = 1               ; STEAM IS OFF
      ADD 1 TO SETTINGA          ; Increment the counter
      LET FRAME = 4              ; Remain on the Blank frame
      IF SETTINGA >= DIRECTION   ; have we reached the end of the timer?
         LET FRAME = 0           ; If so,switch to the first frame
         LET SETTINGB = 0        ; Switch to the ON routine (venting)
         LET SETTINGA = 0        ; Reset the counter
         READ DIRECTION          ; Get the next time length from the DATA and store it in DIRECTION
      ENDIF
   ENDIF

   IF COLLISION 0                ; Player has collided with the steam,
      IF FRAME <> 4              ; If the steam is active
         SUBTRACT 1 FROM L       ; do some damage
         BEEP 25                 ; ouchy noise!
         OTHER                   ; turn the player red...because it hurts!
         SPRITEINK 2
	 ENDSPRITE
      ENDIF
   ENDIF
ENDIF




DATA 50 40 20 40 80 30 50 40 10 30 ; add your timings (alternate between OFF and ON)

Agora, isto não vai funcionar totalmente por si só. Precisamos de inicializar alguns dos parâmetros quando o sprite é desenhado pela primeira vez no ecrã.

Vamos definir uma duração inicial em DIRECTION (uma vez que, no código acima, DIRECTION só é definida quando é igual a SETTINGA. Por predefinição, a DIRECTION de um sprite é sempre 0 inicialmente, a menos que a alteres no ecrã de inicialização do sprite.

mas também podemos acrescentar alguma variedade aqui, por exemplo, podíamos tornar aleatório se o vapor está LIGADO ou DESLIGADO inicialmente (SETTINGB), pelo que o teu código no evento Sprite Initialisation poderá ser algo como:

IF TYPE 4                ; this is the event type that contains our Steam sprite
   LET SETTINGA = 0      ; start the counter at 0
   GETRANDOM 2           ; get a random number (either 0 or 1) 
   LET SETTINGB = RND    ; make the steam either ON or OFF at random initally
   LET DIRECTION = 50    ; set the time to remain in the current state to 50 cycles
ENDIF

E pronto. Agora os teus vilões estáticos podem aparecer e desaparecer segundo um padrão, inteiramente às tuas ordens :)

Espero que isto ajude!

Todo o MPAGD Avançado