Quero dar um pouco de acabamento ao jogo melhorando o que acontece quando o Stinky Dog é morto.
Neste momento, há três formas de matar o Stinky Dog:
Se colidir com o Sideways Clive
Se cair sobre um bloco de picos DEADLY
Se o ar da sala se tornar demasiado tóxico
E quando o Stinky Dog é morto, simplesmente reaparece na sua posição original.
Vamos torná-lo um pouco mais interessante: vamos acrescentar um som e uma animação.
A animação será uma lápide que surge do chão.
Vou criar um sprite de 4 frames para a lápide.
Primeiro desenhei a lápide completa; no Sprite Editor prime X para adicionar um novo sprite

A seguir, vou copiar e colar este frame 3 vezes, o que me dará quatro frames idênticos para este sprite. Para isso, uso as teclas:
M - copiar o frame
I - inserir um novo frame
K - colar o frame
I - inserir outro frame
K - colar o frame nele
I - inserir o último frame
K - colar o frame nele
Agora temos um sprite de 4 frames com a lápide completa em cada um.
Para isso podes usar as teclas D e F para percorrer os frames (D para trás, F para a frente)
Para dar o efeito de a lápide surgir do chão, vou precisar de a deslocar para cima 4 píxeis de cada vez (4 x 4 = 16, o nosso sprite tem 16 píxeis de altura)
Certifica-te de que estás a ver o Frame 000 (usa D ou F para chegar a ele, se não estiveres)
Agora prime o cursor PARA CIMA quatro vezes

O teu sprite deve agora ficar assim: o que eram as 4 linhas de cima são agora as quatro linhas de baixo.
Agora clica com o botão direito nos píxeis coloridos das 12 linhas de cima para os apagar. O teu Frame 0 deve ficar assim:

Quando estiver assim, prime F para passar ao frame seguinte.
Desta vez temos de o deslocar 8 píxeis para cima: prime a tecla para cima 8 vezes e depois apaga as 8 linhas de cima. O Frame 1 deve ficar assim:

Quando estiver assim, prime F para passar ao frame seguinte.
Desta vez prime o cursor PARA CIMA 12 vezes (ou o cursor para baixo 4 vezes) e apaga as 4 linhas de cima. Deve ficar assim:

Prime F para ir ao último frame. Deve mostrar a lápide completa, que é o que queremos, por isso não é preciso editá-lo.
Prime F outra vez e deves voltar ao Frame 0. Se criaste frames adicionais por engano, podes premir R para os remover.
Mantém o dedo em F e deves ver a animação na pré-visualização. Vai ser bastante rápida, mas não te preocupes, podemos controlar a velocidade no nosso código.
Agora que temos um sprite de lápide, vamos escrever código para ele. Vou colocá-lo em SPRITE TYPE 8; no teu menu Events seleciona Sprite Type 8.
Aqui está o código:
EVENT SPRITETYPE8
IF IMAGE 7 ; is it the tombstone
FALL ; make it subject to gravity
IF FRAME <> 3 ; if we are not on the last frame
ANIMATE MEDIUM ; animate the tombstone
ELSE
LET RND = 5 ; use RND as a temporary variable staring value of 5
REPEAT 20 ; do the following 20 times
BEEP RND ; make sound based on current RND
DELAY 2 ; a very brief pause
ADD 5 TO RND ; increase the BEEP value by 5
ENDREPEAT
KILL ; kill the player
EXIT ; stop processing this event
ENDIF
ENDIFPrimeiro, envolvi tudo numa instrução IF IMAGE 7. Fi-lo porque é provável que venha a usar o Type 8 para outros sprites não relacionados no futuro; assim, este código só será executado para o sprite da lápide.
Depois sujeitei-o à gravidade para que caia (FALL) até aos blocos de baixo, para não acabarmos com lápides suspensas no ar!
A seguir testo se NÃO estamos a mostrar o último sprite. IF FRAME <> 3 significa Se NÃO é o Frame 3.
E se não estamos a mostrar o Frame 3, quero que o frame seja ANIMADO (ou seja, percorra os frames) a velocidade MEDIUM.
ANIMATE aceita os argumentos:
VERYSLOW
SLOW
MEDIUM
FAST
VERYFAST
Depois tenho um ELSE, ou seja, o que deve acontecer quando chegámos ao FRAME 3. Isto reproduz um som. Repara que, mais uma vez, estou a usar RND como variável temporária para controlar o efeito sonoro.
Depois de o som tocar, vamos matar o jogador com KILL, o que ativará a rotina KILL PLAYER.
Por fim, acrescentei um comando EXIT, que diz ao MPAGD para parar de processar este evento. Pode ser que não precisemos dele, mas costumo pô-lo quando é provável que venha a haver mais código neste evento que não quero que seja executado se o jogador já tiver morrido.
A seguir, vamos precisar de atualizar o nosso PLAYER EVENT para podermos ativar a lápide quando o Stinky Dog for morto. Abre o teu evento do jogador e procura a instrução IF DEADLY, que controla o que acontece quando o Stinky Dog toca num bloco mortal como os picos do nosso jogo. Provavelmente tem este aspeto:
IF DEADLY KILL ENDIF
Vamos mudá-lo para isto:
IF DEADLY ; am I touching something deadly? LET IMAGE = 7 ; if so, turn me into the tombstone sprite LET FRAME = 0 ; reset me to frame 0 LET TYPE = 8 ; make me a type 8 sprite EXIT ; stop processing this event ENDIF
Assim, quando o Stinky Dog tocar num pico mortal, vamos mudar a imagem do seu sprite para 7 (a lápide). Vamos também transformá-lo em TYPE 8 para que, a partir de agora, o código do evento TYPE 8 controle a lápide.
Repara que também quero garantir que, da primeira vez que executarmos o código do TYPE 8, o fazemos a partir do FRAME 0. Quando fazes um TYPE SWITCH a um sprite, todas as variáveis do sprite original, incluindo o número do FRAME, passam para o novo sprite. Como não podemos ter a certeza de em que frame o Stinky Dog estava quando toca num bloco mortal, queremos garantir que a lápide começa a partir do seu primeiro frame (FRAME 0).
Ok, vamos compilá-lo e testá-lo:
Funciona! Quando o Stinky Dog toca num bloco mortal aparece a lápide e ele morre.
Mas não acontece quando ele é morto pelo Sideways Clive, nem acontecerá se o medidor de pureza do ar chegar a 0. Porque até agora só mudámos o tipo de sprite no código IF DEADLY.
Por isso poderíamos acrescentar o mesmo código no código de COLLISION que deteta quando o Sideways Clive toca no Stinky Dog, e no código que mata o Stinky Dog quando a pureza do ar chega a 0.
Isso é muito código repetido e, à medida que o jogo se desenvolver, é provável que acrescentemos novas formas de matar o Stinky Dog. Seria melhor escrever uma rotina que possamos ativar sempre que quisermos matar o cão. O evento KILL PLAYER não é o melhor para isto, porque na verdade queremos controlar o que acontece JUSTO ANTES de matarmos o jogador no código.
É melhor, então, mantê-lo no PLAYER EVENT.
E para isso vamos usar uma das variáveis especiais de sprite para o ativar.
Vou usar SETTINGA como variável; é uma variável LOCAL, ou seja, é única para cada SPRITE. No Player Event, adiciona o seguinte código:
IF SETTINGA = 99 ; do we want to kill Stinky Dog LET IMAGE = 7 ; if so, turn me into the tombstone sprite LET FRAME = 0 ; reset me to frame 0 LET TYPE = 8 ; make me a type 8 sprite ENDIF
Assim, agora, sempre que quisermos matar o cão, só temos de fazer LET SETTINGA = 99
Agora podemos atualizar o código mortal para:
IF DEADLY ; am I touching something deadly? LET SETTINGA = 99 ; run the kill code ENDIF
E o teste da pureza do ar para:
IF P <= 0 ; if air purity is 0 LET SETTINGA = 99 ; run the kill code ENDIF
Ok, isto serve para o que testamos no PLAYER EVENT, mas e a deteção de colisão com o Sideways Clive? Porque esse código está no evento do Clive (Sprite Event 1) e neste momento tem este aspeto:
IF COLLISION PLAYER ; if Clive touches Stinky Dog
IF DIRECTION <> 5 ; and if Clive is not stunned
KILL ; Kill Stinky Dog
ENDIF
ENDIFComo SETTINGA é local do Stinky Dog, não podemos simplesmente substituir o comando KILL por LET SETTINGA = 99 no código acima, uma vez que isso alteraria, na prática, o valor SETTINGA do Sideways Clive para 99. Felizmente, o MPAGD tem uma solução: OTHER...ENDSPRITE.
IF COLLISION PLAYER ; if Clive touches Stinky Dog
IF DIRECTION <> 5 ; and if Clive is not stunned
OTHER ; switch to Stinky Dog
LET SETTINGA = 99 ; run the death code
ENDSPRITE ; switch back to Sideways Clive
ENDIF
ENDIFOTHER só pode ser usado dentro de uma instrução IF COLLISION. Permite-nos mudar para o OUTRO sprite com o qual o sprite atual (neste caso o Clive) está a colidir. Temos sempre de voltar ao sprite atual com o comando ENDSPRITE.
Muito bem, vamos testar!
Nada mau: agora aparece a lápide quando o Stinky Dog toca num bloco DEADLY ou no Clive, e se a pureza do ar chegar a 0.
O único problema que vejo é que o Clive continua a andar por cima da lápide, por isso os gráficos sobrepõem-se e fica um pouco desarrumado.
Vamos ver como podemos melhorar isso.
Vamos acrescentar código no Type 1 (Clive):
IF COLLISION 8 ; if we touch a type 8 (tombstone) UNDOSPRITEMOVE ; move clive off the tombstone ENDIF
O que isto deve fazer é que, se o Clive colidir com um sprite TYPE 8 (como a lápide), UNDOSPRITEMOVE desfaz o movimento que causou a colisão e, na prática, afasta-o da lápide.
Vamos testar outra vez!
Por agora está ótimo!
