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:

scene1_preload

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

scene1_create

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":

projectiles

Agora vá para playerBeam.js:

constructor_xy

Assim como no Explosion.js, ele estende Phaser.GameObjects.Sprite e usa super() no construtor.
Complete o construtor para:


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:

control_space

Agora vamos criar o método playerShoot():

player_shoot

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

update_player_shoot

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:

  1. O tiro não causa dano no inimigo
  2. O tiro continua para sempre por causa do canvas infinito do Phaser

blast


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();
}
update_projectiles

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

player_bullet_update

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).

blast


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:

overlap projectiles

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

hit_enemy

Nesse método:


No final, o disparo ficará assim:

blast