Tutorial Phaser – Parte 3 – Movimentar personagem
Tutorial Phaser – Este é o terceiro artigo da série “Phaser para iniciantes”. No segundo artigo (https://programandojuntos.com.br/tutorial-phaser-parte-2/) criamos nosso personagem e agora nesse terceiro artigo vamos fazer nosso personagem se movimentar pelo mapa.
Conheça nosso canal e assista o vídeo dessa aula.
Iniciando controles para movimentar personagem
Para fazer o nosso personagem se movimentar pela tela, usaremos as setas do teclado (cima, baixo, direita e esquerda), e para o personagem efetuar o movimento de ataque, usaremos a tecla de espaço do teclado.
Inicialmente iremos criar um arquivo chamado “controls.ts” dentro do diretório “src”, ficando assim “src/controls.ts”.
Dentro desse arquivo criado, cole o seguinte código:
export const createControls = (
scene: Phaser.Scene
): Phaser.Types.Input.Keyboard.CursorKeys => {
return scene.input.keyboard.createCursorKeys();
};
Aqui basicamente estamos exportando uma função que irá criar o objeto responsável por gerenciar os controles do jogo. Esse objeto é criado com a função “scene.input.keyboard.createCursorKeys()”. E como parâmetro vamos esperar a própria “scene” onde está sendo executado o game.
Agora no arquivo “src/game.ts” importe a função que acabamos de criar:
import { createControls } from "./controls";
Crie também a propriedade “controls” na “Scene” que estamos trabalhando, ficando assim:
import * as Phaser from "phaser";
import { createPlayer, loadSprites } from "./player";
import { createControls } from "./controls";
export default class Demo extends Phaser.Scene {
player;
controls; // Inicie a propriedade aqui
...
E finalmente dentro da função “create()” iremos executar a função “createControls”.
Faça isso bem na última linha da função:
this.controls = createControls(this);
Agora essa variável terá o objeto responsável por identificar as teclas pressionadas no teclado.
Implementando função de movimentação do personagem (Direita)
Agora dentro do arquivo “src/controls.ts”iremos implementar as funções responsáveis por fazer nosso personagem se movimentar na tela.
A primeira coisa a ser feita é instanciar a seguinte constante no arquivo:
const defaultVelocity = 200;
Essa constante está definindo a velocidade padrão de movimento do personagem. Para faze-lo movimentar mais rápido, basta aumentar o valor, e para diminuir a velocidade, basta diminuir o valor.
Em seguida usaremos o seguinte código para criar função que movimenta o personagem para a direita:
const moveRight = (player): void => {
player.setFlipX(false);
player.anims.play("player_walk", true);
player.setVelocityX(defaultVelocity);
};
Essa função irá esperar o “player” como parâmetro, pois é ele que será movido pela tela.
Usaremos a função “player.setFlipX(false);” para fazer o sprite do personagem alterar a orientação na horizontal. Ou seja, passando o valor “false” ele vai ser apresentado na direção normal, caso passe como “true” ele ficará virado para o outro lado. Isso será necessário para nosso personagem não andar de costas pelo mapa.
Vamos usar a função “player.anims.play(“player_walk”, true);” para reproduzir a animação “player_walk” criada na aula anterior, responsável por executar os sprites com a animação do personagem andando.
E por fim vamos usar a função “player.setVelocityX(defaultVelocity);” para setar a velocidade de movimento no player no eixo X, ou seja, na vertical. E iremos passar como parâmetro pra essa função a velocidade padrão configurada anteriormente. Um número positivo faz o personagem se movimentar em direção ascendente no eixo, seja ele X ou Y, e uma velocidade negativa faz o personagem se movimentar em direção descendente no eixo.
Implementando função de movimentação do personagem (Esquerda)
Faça a mesma coisa para criar a função que movimenta o personagem para esquerda, se atentando aos valores passados para as funções executadas:
const moveLeft = (player): void => {
player.setFlipX(true);
player.anims.play("player_walk", true);
player.setVelocityX(-defaultVelocity);
};
Dessa vez na função “player.setFlipX(true);” passa o parâmetro “true”, pois queremos que o personagem vire para o lado esquerdo antes de começar a se movimentar para a esquerda.
Mantenha a função “player.anims.play(“player_walk”, true);” responsável por executar a animação de “caminhada” do personagem.
E por último executa a função “player.setVelocityX(-defaultVelocity);” passando um valor negativo, fazendo o personagem andar em posição descendente.
Implementando função de movimentação do personagem (Cima)
Para movimentar o personagem para cima é ainda mais simples, pois não precisamos nos preocupar em virar ele para direita ou esquerda:
const moveUp = (player): void => {
player.anims.play("player_walk", true);
player.setVelocityY(-defaultVelocity);
};
Mantenha a execução da função “player.anims.play(“player_walk”, true);” assim o personagem irá aparentar estar caminhando.
E execute a função “player.setVelocityY(-defaultVelocity);”, dessa vez alterando a velocidade do eixo Y do personagem.
Implementando função de movimentação do personagem (Baixo)
A função para movimentar o personagem para baixo é quase a mesma coisa que para movimentar para cima:
const moveDown = (player): void => {
player.anims.play("player_walk", true);
player.setVelocityY(defaultVelocity);
};
A diferença é que iremos passar um valor positivo para a função “player.setVelocityY(defaultVelocity);” pois agora queremos que o personagem se mova em direção ascendente no eixo Y.
Função de ataque do personagem
Para executar a animação de ataque do personagem iremos utilizar o seguinte código:
const attack = (player): void => {
player.anims.play("player_attack", true);
}
Nessa função execute apenas o método “player.anims.play(“player_attack”, true);” para dispara a animação de ataque do personagem.
Capturando teclas pressionadas no teclado e movimentar personagem
Finalmente vamos capturar quando o usuário pressionar as teclas para movimentação do personagem e executar as funções implementadas nos passos anteriores.
Ainda dentro do arquivo “src/controls.ts” exporte a seguinte função:
export const configControls = (
player,
controls: Phaser.Types.Input.Keyboard.CursorKeys,
scene: Phaser.Scene
): void => {
// Aqui iremos escrever nosso código.
player.setVelocity(0);
}
Essa função espera 3 parâmetros.
1 – O player que estamos querendo fazer se movimentar.
2 – O objeto controls criado na nossa “Scene”.
3 – E a “Scene” onde estamos implementando o game.
E a função irá ter um retorno “void”, ou seja, vazio.
Dentro da função já começamos chamando o método “player.setVelocity(0);” para poder setar a velocidade do personagem como “0”, pois nesse momento ainda consideramos que o usuário não está pressionando nenhuma tecla
Agora dentro dessa função vamos capturar o momento que o usuário aperta a seta “baixo” no teclado. Para isso, insira o seguinte código dentro da função:
if (controls.down.isDown) {
moveDown(player);
return;
}
Ficando assim:
export const configControls = (
player,
controls: Phaser.Types.Input.Keyboard.CursorKeys,
scene: Phaser.Scene
): void => {
player.setVelocity(0);
if (controls.down.isDown) {
moveDown(player);
return;
}
}
Essa função basicamente verifica se a tecla “baixo” do teclado está pressionada, caso esteja, vamos chamar a função “moveDown” passando o “player” para parâmetro para ela. E retorne vazio para encerrar a execução da função naquele ponto, garantindo que nenhum código abaixo disso seja executado.
Faça o mesmo para as outras teclas, ficando asssim:
export const configControls = (
player,
controls: Phaser.Types.Input.Keyboard.CursorKeys,
scene: Phaser.Scene
): void => {
player.setVelocity(0);
if (controls.down.isDown) {
moveDown(player);
return;
}
if (controls.up.isDown) {
moveUp(player);
return;
}
if (controls.right.isDown) {
moveRight(player);
return;
}
if (controls.left.isDown) {
moveLeft(player);
return;
}
if (controls.space.isDown) {
attack(player, scene);
return;
}
};
No fim dessa função execute a animação do nosso personagem “parado”. E como resultado final, nossa função ficará assim:
export const configControls = (
player,
controls: Phaser.Types.Input.Keyboard.CursorKeys,
scene: Phaser.Scene
): void => {
player.setVelocity(0);
if (controls.down.isDown) {
moveDown(player);
return;
}
if (controls.up.isDown) {
moveUp(player);
return;
}
if (controls.right.isDown) {
moveRight(player);
return;
}
if (controls.left.isDown) {
moveLeft(player);
return;
}
if (controls.space.isDown) {
attack(player, scene);
return;
}
player.anims.play("player_idle", true);
};
Configurando controles na Scene
Agora no arquivo “src/game.ts” importe a função “configControls” que acabamos de criar:
import { configControls } from "./controls";
Agora crie uma função chamada “update” na classe “Demo” dentro do arquivo “src/game.ts”.
Essa função é uma função padrão do Phaser. Ela é executada toda vez que a tela do jogo é atualizada, ou seja, várias vezes por segundo.
Dentro dessa função, execute a função “configControls”, ficando assim:
update() {
configControls(this.player, this.controls, this);
}
Finalmente salve todos os arquivos, atualize a página do game e nesse momento você já conseguirá movimentar o personagem pela tela e também atacar com a barra de espaço.
Conclusões – Movimentar personagem
Nessa aula focamos em aprender como implementar a captura das teclas do teclado e executar funções de movimentação e animação do personagem.
Se você apertar a barra de espaço várias vezes rapidamente, verá que a animação de ataque é executada antes que a última termine. Na próxima aula iremos tratar esse comportamento.
Outro comportamento que iremos tratar na próxima aula é o fato do personagem conseguir andar por cima da água e sair do mapa. Iremos fazer ele parar quando encontrar água, sendo assim não conseguirá sair do mapa.
Veja a continuação aqui: https://programandojuntos.com.br/tutorial-phaser-colisao/