Fundamentos: Game estilo Frogger com Phaser 3 - Parte 4

Cover image

Esse artigo faz parte de uma série de tutoriais referente a criação de um game estilo frogger, você está na parte 4.

Se você não viu o primeiro post dessa série. Você pode continuar a partir daqui, basta iniciar a partir do commit referente a parte 3 nesse repositório.

Essa e uma série finalizada, você pode ver todos os posts aqui:

Movimentando o Jogador

No momento os inimigos já estão se movimentando, agora iremos adicionar a movimentação ao nosso jogador, usando a tecla space para se movimentar.

NOTA: Na próxima série de tutoriais iremos fazer um jogo bem mais complexo referente a movimentação do jogador.

No método init iremos adicionar uma variável que irá salvar as informações da tecla space, assim em qualquer método da nossa scene iremos ter acesso a ela.

init () {
  // largura da tela
  this.gameWidth = this.sys.game.config.width;
  // altura da tela
  this.gameHeight = this.sys.game.config.height;

  // min e max velocidade de movimento do inimigo
  this.enemyMinSpeed = 1;
  this.enemyMaxSpeed = 4;

  // utilizando KeyboardPlugin para utilizar a tecla "space"
  this.spaceKey = this.input.keyboard.createCursorKeys().space;
}

O KeyboardPlugin nos auxilia nos eventos de teclas, basicamente evita ter trabalho desnecessário reinventando a roda. Essa e uma das vantagens de utilizarmos um framework =)

Da mesma forma que fizemos com os inimigos, vamos criar um método que será responsável pela movimentação do jogador, abaixo do método truckMovement, ficará:

/* Movimentação do jogador */
playerMovement () {
  // justDown = só irá executar 1 vez ao pressionar
  if (Phaser.Input.Keyboard.JustDown(this.spaceKey)) {
    // cada vez que a tecla for pressionada, o jogador irá para cima
    this.player.y -= this.player.height;
    // muda para o frame de movimento (o jogador possui o 0 e 1)
    this.player.setFrame(1);
  } else {
    // muda para o frame parado
    this.player.setFrame(0);
  }
}

um método bem mais simples comparado com os do inimigo, né?

NOTA: Existem melhores formas de gerar uma movimentação ao jogador, mas neste momento ainda seria muito complexo ensinar, lembre-se que estamos aprendendo os fundamentos.

Agora dentro do método update, basta adicionar o método para o jogador se movimentar, ficando assim:

update () {
  // a cada loop o método é executado novamente
  this.carMovement();
  this.truckMovement();
  this.playerMovement();
}

Se você for na tela do jogo, e apertar a tecla space irá notar o jogador se movimentando! Bem agora temos 2 problemas:

  • 1) O jogador não colide com os inimigos
  • 2) O jogador vai infinitamente para cima até sumir da tela

Verificando Colisões

Agora vamos resolver os 2 problemas citados acima. Abaixo do método playerMovement, adicione:

// verifica colisões entre jogador/inimigo e jogador/topo da tela
  checkCollisions () {
    /*
      getBounds retorna um objeto com a posição e tamanho do jogador/inimigo
    */
    const playerRect = this.player.getBounds();
    const carRect = this.car.getBounds();
    const truckRect = this.truck.getBounds();
    
    // RectangleToRectangle verifica se o jogador está colidindo com os inigmios
    if (Phaser.Geom.Intersects.RectangleToRectangle(playerRect, carRect)
      || Phaser.Geom.Intersects.RectangleToRectangle(playerRect, truckRect)) {
      console.log('o carro/caminhão me acertou, perdi!')
      return;
    }
 
    // verifica se o jogador passou por todas as pistas e terminou o jogo
    if (this.player.y <= 80) {
      console.log('venci!')
      return;
    }
  }
}

O método getBounds, retorna um objeto como este: retorno do Getbounds

Assim é possível usar uma função auxiliar do Phaser que verifica se 2 retângulos estão se colidindo.

NOTA: Essa não é a forma mais performática de verificar colisões, mas e a forma mais simples de introduzir ao assunto.

Perceba que no método temos uma verificação this.player.y <= 80, basicamente vamos verificar se o jogador passou por todas as pistas e chegou do outro lado, se sim ele venceu!

Também note que possuímos 2 console.log dentro desse método, na próxima parte iremos trocá-los por outros métodos.

Agora é hora de adicionar dentro do método update, ficando assim:

update () {
  // a cada loop o método e executado novamente
  this.carMovement();
  this.truckMovement();
  this.playerMovement();
  this.checkCollisions();
}

Pronto, verifique a aba console do seu navegador, e veja os logs que nós colocamos quando ocorre as colisões.

Conclusão

Nessa quarta parte vimos como movimentar o jogador e verificar colisões, nós vemos na última parte!