Fundamentos: Game estilo Frogger com Phaser 3 - Parte 2

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

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 1 nesse repositório.

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

Adicionando os Inimigos

No momento temos apenas o background adicionado ao jogo, a técnica para adicionar nossos inimigos será a mesma, você pode ver na pasta src/assets/ os arquivos car.png e truck.png, são apenas imagens comuns. Diferente do frog.png que é um spritesheet (falaremos sobre mais a frente). Dentro do método preload adicionaremos os nossos inimigos ficando assim:

preload () {
  // carregando arquivo do tipo imagem
  this.load.image('background', './src/assets/background.png');
  this.load.image('car', './src/assets/car.png');
  this.load.image('truck', './src/assets/truck.png');
}

Não irei detalhar, já que isso foi ensinado na parte 1. Agora precisamos renderiza-los na tela do nosso jogo. O método create ficará assim:

create () {
    // criando o objeto do tipo imagem
    const background = this.add.image(
      0, // X referente a tela do jogo
      0, // Y referente a tela do jogo
      'background', // chave da textura
    );
    // setando a origin do objeto para 0 (x, y)
    background.setOrigin(0);
 
    this.car = this.add.image(
      48,
      this.gameHeight - 140,
      'car',
    );
    // mudando a escala da imagem para 0.8
    this.car.setScale(0.8);
 
    this.truck = this.add.image(
      48,
      this.gameHeight - 306,
      'truck',
    );
    // mudando a escala da imagem para 0.8
    this.car.setScale(0.8);
  }

Repare que ao setar a posição Y dos inimigos eu usei uma variável chamada this.gameHeight, ela nos ajudará a posicionar com mais precisão nossos inimigos na tela do jogo, vamos adicionar no método init, ficando dessa forma:

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

Aproveitei para adicionar a variável this.gameWidth que e referente a largura do jogo, agora vamos entender um pouco como eu consegui esses valores.

Em uma Scene temos acesso a classe systems que pode ser acessada via this.sys, ela é responsável por gerenciar todos os plugins dentro da Scene no momento, assim como lidar com as etapas de renderização, além disso através dela conseguimos acessar as configurações globais do sistema, via this.sys.config, por isso conseguimos a largura (width) e altura (height) do nosso jogo.

Entendendo a propriedade Scale

Quando adicionamos os inimigos no jogo, logo após defini-los, alterei a propriedade Scale deles para 0.8, resumidamente ela irá alterar a escala da imagem, e muito parecida com a propriedade scale do CSS, quando coloquei 0.8 eu simplesmente disse que queria que a imagem fosse escalada para 80% do seu tamanho real.

NOTA: Você pode via console.log(this.car), ver todos os métodos e propriedades que esse objeto possui, caso de dúvidas sempre leia a documentação, veja aqui falando sobre os objetos do tipo image.

Adicionando o Jogador

Está na hora de falarmos sobre adicionarmos um spritesheet (jogador) ao nosso jogo, o nosso método preload ficará assim:

preload () {
  // carregando arquivo do tipo imagem
  this.load.image('background', './src/assets/background.png');
  this.load.image('car', './src/assets/car.png');
  this.load.image('truck', './src/assets/truck.png');

  // carregando spritesheet
  this.load.spritesheet('frog', './src/assets/frog.png', {
    frameWidth: 54, // largura do quadro
    frameHeight: 42, // altura do quadro
  });
}

O método spritesheet possui um parâmetro principal a mais, em comparação com o método image, que é o frameConfig(configuração de quadros), pelo menos precisa ser informado o frameWidth, basicamente precisamos definir para o Phaser conseguir "cortar" corretamente a nossa imagem, se você abrir a imagem src/assets/frog.png irá ver que possuímos 2 imagens, a do frog parado e a do frog em movimento, ambas com 54x42.

Agora precisamos renderiza-lo na tela do nosso jogo, o método create ficará assim:

create() {
  // criando o objeto do tipo imagem
  const background = this.add.image(
    0, // X referente a tela do jogo
    0, // Y referente a tela do jogo
    'background', // chave da textura
  );
  // setando a origin do objeto para 0 (x, y)
  background.setOrigin(0);

  this.car = this.add.image(
    48,
    this.gameHeight - 140,
    'car',
  );
  // mudando a escala da imagem para 0.8
  this.car.setScale(0.8);

  this.truck = this.add.image(
    48,
    this.gameHeight - 306,
    'truck',
  );
  // mudando a escala da imagem para 0.8
  this.car.setScale(0.8);

  // Object tipo sprite
  this.player = this.add.sprite(
    this.gameWidth / 2,
    this.gameHeight - 20,
    'frog', // 
    0, // frame index
  );
}

Note que a diferença agora é que precisamos passar qual é o frame inicial que o nosso jogador irá começar, neste caso estou estando para o 0 (frog parado).

NOTA: Repare que tanto os inimigos como o jogador, foram criados atribuindo ao objeto this (Scene), diferente do background. Isso é porque irei usá-los em outros métodos do nosso jogo, como o update, então sempre terei uma referência deles direto da Scene.

Conclusão

Nessa segunda parte vimos como adicionar os inimigos e o jogador ao jogo, nós vemos na parte 3!