Atividade 7 - Permitindo que o Jogador Atire
Agora vamos adicionar uma das partes mais importantes do jogo — atirar nos inimigos!
Embora possamos derrotar inimigos colidindo com eles, isso não será uma boa ideia quando adicionarmos vidas mais tarde. Vamos criar o efeito de disparo criando um objeto beam (raio/tiro) usando um arquivo JavaScript separado (assim como fizemos para a explosão).
Começamos com o básico — carregando uma spritesheet e uma animação na Scene 1 para os tiros do jogador:

A localização da spritesheet é assets/beam.png
e cada quadro (frame) tem 32x32 pixels:

Na Scene 2, faremos algo parecido com o que fizemos com os inimigos: criar um grupo para os tiros, assim podemos manipulá-los facilmente.
Crie um grupo chamado "projectiles"
:

Agora vá para playerBeam.js
:

Assim como no Explosion.js
, ele estende Phaser.GameObjects.Sprite
e usa super()
no construtor.
Complete o construtor para:
- Reproduzir a animação do tiro
- Ativar o corpo físico
- Definir a velocidade no eixo Y para o valor desejado
Depois de configurar o beam, vamos permitir que o jogador o dispare quando pressionar a barra de espaço.
Assim como criamos uma variável para processar as setas de movimento, criaremos outra para processar a barra de espaço:

Agora vamos criar o método playerShoot()
:

E chamá-lo no update()
, como fizemos com movePlayer()
:

O método playerShoot()
vai verificar se a barra de espaço foi pressionada e criar um playerBeam (tiro) se o jogador estiver ativo (vivo).
Teste agora! Você vai notar dois problemas:
- O tiro não causa dano no inimigo
- O tiro continua para sempre por causa do canvas infinito do Phaser
Vamos corrigir primeiro o problema do tiro infinito.
Mesmo que isso não afete diretamente a jogabilidade, muitos tiros fora da tela podem causar lag.
Para resolver, vamos usar a função update()
no playerBeam.js
para destruir o tiro quando ele sair da tela.
No entanto, para essas funções update()
funcionarem, precisamos chamá-las no update()
da Scene 2:
for(var i = 0; i < this.projectiles.getChildren().length; i++) {
var beam = this.projectiles.getChildren()[i];
beam.update();
}

Para testar, podemos colocar a altura de destruição do tiro dentro da área visível:

Se o tiro desaparecer na altura especificada (por exemplo, 50), o código está funcionando.
Depois, basta alterar para um valor fora da tela (como 10).
Agora, vamos destruir o inimigo quando ele for atingido por um tiro.
Podemos fazer isso usando a mesma detecção overlap que usamos para verificar colisão entre jogador e inimigo:

Mas, como o jogador não está sendo atingido, não podemos usar hurtPlayer()
.
Em vez disso, criaremos um método hitEnemy()
:

Nesse método:
- Criamos uma explosão na posição do inimigo
- Removemos o tiro
- Removemos o inimigo
No final, o disparo ficará assim: