Minilop Retroware

MPAGD Avançado

Como fazer cair objetos de bónus e mostrar mensagens chamativas em MPAGD

17 de novembro de 2020

Um tutorial um pouco diferente hoje: em vez de me concentrar nos eventos de sprites inimigos, aqui está um método para adicionar quedas aleatórias de itens de bónus...e mensagens de faixa chamativas nos teus jogos MPAGD.

É algo que escrevi pela primeira vez para Cocoa and the Time Machine e que depois melhorei em 24 Hour Parsley People.

O que eu queria conseguir era...

  1. O jogador derrota um inimigo

  2. Cai aleatoriamente um item de bónus (escolhido entre 4 possíveis, ponderados de modo a que os mais potentes caiam com menos frequência)

  3. O jogador apanha o item de bónus

  4. O item de bónus concede energia/pontos/o que for

  5. Aparece uma faixa a piscar no ecrã

Aqui está um exemplo em ação num ecrã de demonstração, usando parte do código do meu último jogo, em que o nosso herói Cocoa consegue desviar as balas dos Agentes com o Tesla Device...e quando um Agente é derrotado, largamos um item de bónus para o Cocoa apanhar.

Neste exemplo tenho quatro possíveis itens de bónus:

O que nos deixa com 10% de probabilidade de não cair nada

Aqui está em ação:

Primeiro vamos precisar de desenhar alguns OBJECTS que serão usados como os itens colecionáveis que caem; criei 4 objetos e defini-os todos como 'Hidden' (porque não serão posicionados num ecrã específico nem estarão automaticamente no inventário do jogador)

Também vamos precisar de algum texto para a nossa faixa intermitente. Vou manter o código o mais eficiente possível, por isso será boa ideia que cada número de MESSAGE corresponda ao respetivo número de OBJECT.

i.e

Por isso, abre o teu ficheiro de TEXT MESSAGES, certifica-te de que começa com DEFINEMESSAGES e adiciona as tuas mensagens. Acrescentei alguns espaços no início de algumas delas porque vamos imprimi-las no mesmo sítio do ecrã e quero que fiquem o mais centradas possível:

Captura de ecrã do tutorial

A seguir, vamos escrever um pouco de código que irá ativar a nossa rotina de bónus. Vou usar a variável B para a própria rotina de bónus, e em concreto o valor 2 será usado para chamar a rotina.

Vou ativar a rotina de bónus quando o inimigo for morto por uma bala ressaltada. (Por isso, poderia pô-lo no evento do sprite da bala ou no do Agente.) Neste caso coloquei-o no evento do Agente, e o sprite da bala é do Tipo 2,

   IF COLLISION 2        ; has the bullet hit the agent?
      LET N = X          ; if so, remember the agents X & Y co-ords
      LET O = Y          ; store them in N & O
      LET B = 2          ; start the bonus routine
      REMOVE             ; remove the agent
   ENDIF

A seguir, vamos criar a própria rotina de bónus, que selecionará um item de bónus aleatório com base nas ponderações que preferirmos; tens de a colocar num script MAIN LOOP:

IF B = 2                           ; BONUS ROUTINE
   GETRANDOM 50                    ; get a random number from 0 to 49
   IF RND <= 19                    ; is it less than 20? (i.e. 40%)
      PUT N O 0                    ; if so, put the PARSLEY object at N O
   ELSE                            ; if not
      IF RND <= 34                 ; is it less than 35 (i.e. is it 20-34 30%)
         PUT N O 3                 ; if so, put the DEVICE FUEL CELL object at N O
      ELSE                         ; if not
         IF RND <= 40              ; is it less than 40? (i.e 35-40 or 12%)
            PUT N O 1              ; if so, put the ULTRA PARSLEY object at N O
         ELSE                      ; if not
            IF RND <= 44           ; is it less than 45? (i.e 41-44 or 8%)
               PUT N O 2           ; if so, put the ONE UP object at NO
	    ENDIF
         ENDIF
      ENDIF
   ENDIF
   LET B = 3                       ; we've slected the bonus so we change B to stop it running again
ENDIF

Assim, agora, quando o jogador derrota o inimigo, há 90% de probabilidade de ser recompensado com um item de bónus para apanhar. O bónus aparecerá em N,O (que eram as coordenadas x e y do AGENTE quando foi neutralizado).

Agora vamos adicionar algum código ao evento do jogador que tratará do que acontece quando o jogador apanha o seu bónus:

DETECTOBJ                    ; has the player touched an object?
IF OBJ <> 255                ; is it valid?
   BEEP 25                   ; make a sound
   GET OBJ                   ; collect the object
   IF OBJ = 0                ; is it the standard parsley?
      ADD 33 TO L            ; if so, increase health by 33
   ENDIF
   IF OBJ = 1                ; is it the mega parsley?         
      LET L = 99             ; if so, max the health
   ENDIF
   IF OBJ = 2                ; is it the one-up?               
      ADD 1 TO LIVES         ; add an extra life
   ENDIF
   IF OBJ = 3                ; is it the device fuel cell?                 
      ADD 33 TO V            ; increase the device power by 33
   ENDIF
   IF OBJ > 0                ; if it was a Bonus drop object collectded
      IF OBJ <= 3
	 LET B = 5           ; trigger the banner
         LET N = OBJ      ; we'll store the object number in N so that we can call the correct message in the banner
      ENDIF
   ENDIF
ENDIF

Bem, isso tratará da recompensa do jogador quando apanhar o bónus; agora queremos imprimir no ecrã uma faixa chamativa, só por diversão

Voltemos ao script MAIN LOOP e, por baixo do nosso IF B=2 ...ENDIF, vamos acrescentar o código da faixa:

IF B = 5            ; the banner routine
   PRINTMODE 1      ; let's use big text!
   GETRANDOM 8      ; get a random number from 0 to 7
   INK RND          ; make the ink that colour
   AT 9 9           ; this is where the banner will appear on screen
   MESSAGE N        ; display the objects corresponding message
   ADD 1 TO C       ; we'll use C as a counter
   IF C = 30        ; has the banner flashed 30 times?
      LET C = 0     ; reset the counter
      LET B = 0     ; end the bonus
      REDRAW        ; remove the banner from the screen
      PRINTMODE 0   ; go back to normal text size
   ENDIF   
ENDIF

Como podes ver no código acima, uso a variável C como contador para que a faixa pisque 30 vezes. Escolhi este método em vez de um ciclo REPEAT porque queria que o jogo continuasse enquanto a faixa está ativa, em vez de ter de esperar que a faixa termine antes de avançar.

E é isto na sua forma mais simples.

Obviamente, podes personalizá-lo ao teu gosto. Uso a rotina da faixa para várias outras coisas nos meus jogos, mas, no essencial, é assim que o faço.

Espero que isto ajude!

Todo o MPAGD Avançado