...bem, não me ocorreu um nome melhor para eles. São perigos que caem do teto mesmo quando o jogador está prestes a passar por baixo. É outra mecânica que usei em Cocoa and the Time Machine e que melhorei em 24 Hour Parsley People.
São bastante fáceis de implementar e, no código mais abaixo, vou mostrar-te como os podes adaptar aos teus próprios jogos.
Primeiro, vejamos como funcionam. Aqui tens um exemplo num ecrã de demonstração....
Bem, há duas ou três coisas a ter em conta.
1. Só quero ativar a queda quando o jogador estiver mesmo por baixo
2. O jogador tem de estar dentro de um intervalo vertical específico em relação ao inimigo que cai para o ativar
Por outras palavras, temos de ter cuidado para não os ativar se o jogador passar por cima do inimigo. E, no meu exemplo, não quero que o jogador, no nível do chão, ative a queda no nível de cima.
Obviamente, o teu caso pode precisar de regras diferentes, mas o código abaixo deve ser fácil de adaptar.
Primeiro, pensemos em como funcionam os sprites do MPAGD, e em concreto as suas coordenadas. Cada sprite é um quadrado de 16px por 16px. E cada instância de um sprite tem um valor X e um valor Y, que são as coordenadas x & y do canto superior esquerdo do sprite tal como aparece no ecrã. Por isso, se o teu sprite estiver no canto superior esquerdo do ecrã, o seu X seria 0 e o seu Y seria 0.
Ora, o problema é que, com um inimigo que cai, vamos precisar de saber o X e o Y tanto do inimigo COMO do jogador. E como o nosso código vai ter de viver num dos eventos de sprite, provavelmente faz sentido usar um dos nossos EVENTSPRITETYPE para o inimigo que cai. Por isso vamos precisar de um par de variáveis que guardem os valores X & Y do jogador. Eu costumo usar F & G para isto, simplesmente por hábito...podes usar as que quiseres. Seja como for, abre o evento do jogador e vamos acrescentar algum código (eu costumo pô-lo no fim do script do jogador):
LET F = X LET G = Y
Bem, agora poderemos usar os valores X & Y do jogador quando estivermos no script do inimigo que cai...
; 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
ENDIFNeste exemplo estava a usar IMAGE 12; obviamente, remove esse IF/ENDIF conforme necessário, ou altera-o para fazer referência à imagem do sprite do teu inimigo que cai.
O que estamos a fazer aqui é, na prática, verificar a posição do jogador em relação ao inimigo que cai: primeiro, se o jogador está por baixo do inimigo que cai e, se estiver, se está dentro do nosso intervalo de altura.
No SETTINGA do inimigo que cai estou a guardar o valor X do jogador menos 18, ou seja, 18 píxeis à esquerda do jogador
Estou a fazer algo semelhante com a variável M, mas desta vez guardo o valor X da posição atual do jogador MAIS 18, ou seja, 18 píxeis à direita do jogador
Podes mudar o 18 para qualquer valor que quiseres, consoante queiras que a queda seja ativada mais cedo ou mais tarde.
Assim, assim que M ou SETTINGA coincidirem com o valor x do inimigo que cai, ativamos a queda.
NOTA: Neste script uso vários 'SPRITEDOWNS' para ditar a velocidade da queda; podes usar tantos (ou tão poucos) quantos o teu jogo precisar para tornar mais fácil ou mais difícil evitá-lo. Como alternativa, podes substituir os SPRITEDOWNS por FALL (obrigado a Alessandro Grussu pela sugestão). Com FALL o sprite acelera à medida que cai.
O que fizeres dentro da tua instrução IF de colisão fica ao teu critério; eu mantive-o simples para efeitos do tutorial. Depois usei o parâmetro SETTINGB do inimigo que cai como temporizador (durante quanto tempo permanece no chão antes de ser removido)...mais uma vez, podes adaptá-lo como quiseres, talvez com um sprite de explosão, ou algo completamente diferente!
Também seria fácil adaptar este código para, por exemplo, o ativares a partir de cima, talvez como uma forma divertida de matar um inimigo!
Espero que isto ajude!
