Trazendo seus personagens para a vida em Phaser
Adicionar animações de jogo é fácil de fazer no Phaser. A animação dá vida aos personagens dos videogames. Uma maneira de incorporar animação ao jogo é animar os movimentos do personagem. Você pode até dar a eles uma animação de estado inativo que será executada quando o player não estiver se movendo. Isso dará aos seus personagens mais personalidade.
Configuração do jogo
Você precisará de um conhecimento básico do Phaser para trabalhar com animações. Se você não estiver familiarizado com o Phaser, comece com um tutorial básico do jogo antes de continuar. Este tutorial se baseará nessas bases.
Para começar, crie um jogo com um personagem móvel. Em nosso exemplo, começaremos com um bloco que é movido com as teclas de seta. Abaixo está o código inicial:
var config = {
type: Phaser.AUTO,
backgroundColor: 0xCCFFFF ,
width: 600,
height: 600,
physics: {
default: 'arcade'
},
scene: {
preload: preload,
create: create,
update: update
}
};
var gamePiece;
var keyInputs;
var game = new Phaser.Game(config);
function preload(){
this.load.image('gamePiece', 'img/gamePiece.png');
}
function create(){
gamePiece = this.physics.add.sprite(270, 450, 'gamePiece');
keyInputs = this.input.keyboard.createCursorKeys();
}
function update(){
if(keyInputs.left.isDown){
gamePiece.x = gamePiece.x - 2;
}
if(keyInputs.right.isDown){
gamePiece.x = gamePiece.x + 2;
}
if(keyInputs.up.isDown){
gamePiece.y = gamePiece.y - 2;
}
if(keyInputs.down.isDown){
gamePiece.y = gamePiece.y + 2;
}
}
Este código criará uma peça do jogo que pode se mover em um fundo azul. Para simplificar, o exemplo usa apenas um bloco laranja para o personagem do jogo. Se parece com isso:
Criando uma Folha Sprite
A primeira etapa é criar a animação. Existem muitas maneiras de criar animações, mas isso está além do que podemos cobrir aqui. Para nossos propósitos, é apenas importante que você salve sua animação como uma folha de sprite.
Uma folha de sprite é um arquivo de imagem única que contém um conjunto de quadros de animação. Cada quadro na animação é colocado próximo ao que segue. Cada quadro deve ter o mesmo tamanho. Os programas de animação cortarão a imagem em quadros individuais com base nas dimensões de um único quadro.
As imagens são armazenadas em uma matriz. Como todas as matrizes, isso significa que a primeira imagem está na posição zero. Portanto, no exemplo acima, a animação para baixo começa em zero e termina em três. A animação à esquerda começa às quatro e termina às sete.
Adicionando uma Spritesheet ao Phaser
Carregar uma folha de sprite é semelhante a carregar uma imagem no Phaser. No entanto, seu programa exigirá um pouco mais de informações sobre o arquivo de imagem. Anteriormente, carregávamos nossa imagem com este texto:
this.load.image('gamePiece', 'img/gamePiece.png');
Folhas de Sprite, entretanto, precisam de mais alguns parâmetros. Também temos que especificar as dimensões de uma moldura. Portanto, para carregar uma folha de sprite, precisamos ajustar o código da seguinte maneira:
this.load.spritesheet('gamePiece', 'img/spriteSheet.png', {
frameWidth: 60,
frameHeight: 60
});
O código é muito semelhante. A grande diferença é que adicionamos um terceiro parâmetro que especifica a largura e a altura de nossos quadros de animação. Neste caso, os quadros têm 60 pixels por 60 pixels.
Este exemplo usará uma folha de sprite simples. Adicionamos uma seta e indicadores intermitentes ao sprite do jogo. A seta apontará na direção em que nosso sprite se move, enquanto um indicador pisca nessa direção. Se o personagem não estiver se movendo, a animação percorrerá todos os quadros.
Criação de animações
Antes de animarmos nosso personagem, temos que criar a animação. Já carregamos a folha de sprite, agora temos que dizer quais frames estão em uma animação. Para criar uma animação, adicione o seguinte código à função de criação:
this.anims.create({
key: "up",
frameRate: 2,
frames: this.anims.generateFrameNumbers("gamePiece", {start: 0, end:2}),
repeat: -1
});
Acima está a animação para a direção para cima .
- A palavra-chave anims é uma abreviatura de animações. As versões anteriores usavam animações de palavras-chave completas, mas a versão atual usa esse atalho.
- A chave é o nome da animação. Você usará a tecla para chamar a animação.
- FrameRate controla quantos quadros são mostrados por segundo. Este exemplo terá apenas dois quadros por segundo.
- A próxima linha aponta para quais imagens e quadros são usados na animação. A animação para cima usa a imagem gamePiece e começa no frame 0 e termina no frame 2.
- Se você quiser que a animação seja repetida continuamente, defina a repetição como -1. Caso contrário, você pode inserir quantas vezes a animação deve ser repetida antes de parar.
Você precisará criar uma animação para cada direção e o estado ocioso.
Como animar seu personagem
É muito fácil adicionar uma animação a um personagem. A parte complicada é a transição entre as animações. Você pode definir uma animação inicial na função de criação.
gamePiece = this.add.sprite(270, 450, 'gamePiece');
gamePiece.anims.play("spin");
A primeira linha cria o jogador. É o mesmo que criar um sprite com uma única imagem, como fizemos antes. A segunda linha define a animação para girar . Spin é uma animação ociosa que percorre todos os quadros de zero a onze.
Agora, quando você recarregar o jogo, a animação ociosa começará a ser reproduzida. Mas, você notará que ele continua a jogar mesmo depois de mover seu personagem. Configurar as animações com base no movimento é um pouco mais complicado.
A tentação é mudar a animação quando o jogador pressiona o botão como fizemos para definir o movimento. O problema com esta abordagem é que verificamos se o jogador está pressionando uma tecla na função de atualização. A função de atualização executa todos os quadros. Se colocarmos uma animação lá, a animação irá reiniciar a cada frame que o jogador estiver pressionando a tecla.
Para resolver isso, precisamos usar um método diferente. Em vez de verificar se uma chave está JustDown , queremos saber se uma chave está JustDown . JustDown só é verdadeiro quando a tecla é pressionada pela primeira vez. Se a chave estiver segura, isso não é verdade. Se definirmos a animação com JustDown, a animação não redefinirá cada quadro.
Você precisará criar uma variável para a entrada principal que deseja monitorar na função de criação:
leftKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.LEFT);
rightKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.RIGHT);
upKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.UP);
downKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.DOWN);
Então, você vai querer verificar se a tecla está pressionada na função de atualização:
if(Phaser.Input.Keyboard.JustDown(upKey)){
gamePiece.anims.play("up");
}
Agora, o jogo mudará para a animação para cima assim que a tecla para cima for pressionada pela primeira vez. Você precisará escrever uma instrução if semelhante para cada tecla de direção.
Ainda temos uma modificação final a fazer. Agora, quando o jogador para de pressionar uma tecla, a última animação continua a ser reproduzida. Queremos que volte à nossa animação ociosa. Para fazer isso, usamos o método JustUp . Semelhante ao JustDown , ele será acionado quando o jogador soltar uma tecla.
if(Phaser.Input.Keyboard.JustUp(upKey)){
gamePiece.anims.play("spin");
}
Assim que o jogador parar de pressionar a tecla para cima, ele definirá a animação de volta para a animação de rotação ociosa. Você precisará escrever uma declaração semelhante para cada tecla de direção.
Para ver o código final, vá para pastebin .
Próxima etapa: crie sua própria animação
Criar animações no Phaser não é muito diferente de usar uma imagem estática. Mas vai levar o desenvolvimento do seu jogo para o próximo nível! O Phaser facilita a adição de animações para que você possa se concentrar na parte difícil: fazer a animação!
Ao criar sua própria planilha de sprite, não se esqueça destas dicas:
- Os frames da animação devem ter todas as mesmas dimensões
- Os frames serão armazenados em uma matriz que começa em zero
- As animações geralmente exigem gatilhos diferentes dos gatilhos que definem o movimento.