Animação com Sprites

0

🎯 Objetivos da Lição

Ao final desta lição o aluno será capaz de:

  • Integrar animações com lógica de movimento e input
  • Compreender tecnicamente o funcionamento de sprite sheets
  • Configurar corretamente frameWidth e frameHeight
  • Criar animações reutilizáveis no Animation Manager do Phaser
  • Controlar frameRate e repetição
  • Implementar sistema básico de estados (idle, walk, attack)
  • Detectar final de animações (animationcomplete)
  • Organizar assets de forma escalável

🧱 1. Fundamentos Técnicos de Sprite Sheets

🔹 O que é um Sprite Sheet?

https://img.craftpix.net/2020/01/Free-3-Character-Sprite-Sheets-Pixel-Art6-720x480.webp
https://i.pinimg.com/736x/9a/e7/d9/9ae7d95c473e4456ba779f5e7299a15d.jpg
https://img.craftpix.net/2022/11/Free-Characters-With-Melee-Attack-Pixel-Art3-720x480.webp

4

Um sprite sheet é uma única imagem que contém múltiplos frames organizados em grade (linhas e colunas).

Em vez de carregar várias imagens separadas:

walk1.png
walk2.png
walk3.png

Carregamos apenas:

player.png

E informamos ao Phaser como dividir a imagem internamente.


🔹 Estrutura Matemática do Sprite Sheet

Se um sprite sheet possui:

  • 6 colunas
  • 4 linhas
  • 64px por frame

Então ele contém:

6 × 4 = 24 frames

Cada frame ocupa:

64px × 64px

Configuração no preload:

this.load.spritesheet("player", "assets/player/player.png", {
frameWidth: 64,
frameHeight: 64
});

⚠️ O frameWidth e frameHeight precisam corresponder exatamente ao tamanho real do frame.


🎬 2. Sistema de Animação no Phaser

O Phaser usa um Animation Manager global. Isso significa que:

  • As animações são criadas uma vez.
  • Podem ser reutilizadas por múltiplos sprites.
  • Evitamos recriações desnecessárias.

🔹 Criando animações corretamente

this.anims.create({
key: "walk_right",
frames: this.anims.generateFrameNumbers("player", {
start: 0,
end: 5
}),
frameRate: 10,
repeat: -1
});

Explicação detalhada:

PropriedadeFunção
keyIdentificador único
framesQuais frames usar
frameRateQuantos frames por segundo
repeat-1 significa loop infinito

🔹 Usando animação no sprite

player.anims.play("walk_right", true);

O segundo parâmetro (true) evita reinicialização se já estiver tocando.


🕹️ 3. Sistema de Estados do Personagem

Animação deve refletir estado lógico.

Estados comuns:

  • idle
  • walk
  • jump
  • attack
  • hurt
  • death

Criar máquina de estados simples:

if (cursors.left.isDown) {
player.setVelocityX(-160);
player.anims.play("walk_left", true);
} else if (cursors.right.isDown) {
player.setVelocityX(160);
player.anims.play("walk_right", true);
} else {
player.setVelocityX(0);
player.anims.play("idle", true);
}

Isso impede conflitos visuais.


⚡ 4. FrameRate e Percepção Visual

FrameRate controla fluidez da animação, não o FPS do jogo.

Exemplos práticos:

  • 6 fps → sensação retrô
  • 10–12 fps → padrão confortável
  • 15–20 fps → ação rápida
  • 24 fps → estética cinematográfica 2D

⚠️ FrameRate alto demais pode:

  • Perder impacto visual
  • Reduzir leitura da ação
  • Consumir mais processamento

🗂 5. Organização Profissional de Assets

Estrutura recomendada:

/assets
/characters
/player
/enemies
/effects
/ui
/background

Boas práticas:

✔ Nomear arquivos com padrão:

player_idle.png
player_walk.png

✔ Manter resolução consistente
✔ Separar personagens jogáveis de inimigos
✔ Usar compressão adequada


🧠 6. Animações Não-Lineares

Nem toda animação usa frames sequenciais.

frames: [
{ key: "player", frame: 0 },
{ key: "player", frame: 2 },
{ key: "player", frame: 4 }
]

Isso permite:

  • Frames alternados
  • Efeitos específicos
  • Economia visual

🧩 7. Animações Únicas (Ataque)

Ataque não deve repetir:

this.anims.create({
key: "attack",
frames: this.anims.generateFrameNumbers("player", {
start: 12,
end: 17
}),
frameRate: 15,
repeat: 0
});

Detectar final:

player.on("animationcomplete", function (anim) {
if (anim.key === "attack") {
player.anims.play("idle");
}
});

Isso evita travamento visual.


🎮 Atividade Prática Completa

🔹 Parte 1 – Animação de Caminhada

Requisitos:

  1. Criar sprite sheet
  2. Criar animações:
    • walk_right
    • walk_left
  3. Criar animação idle
  4. Ativar conforme movimento
  5. Parar animação ao soltar tecla

Desafio adicional:

  • Implementar flip horizontal ao invés de sprite duplicado

🔹 Parte 2 – Sistema de Ataque

  1. Criar animação attack
  2. Ativar com tecla SPACE
  3. Bloquear movimento durante ataque
  4. Retornar automaticamente para idle
  5. Impedir spam de ataque

Exemplo de controle simples:

let isAttacking = false;if (Phaser.Input.Keyboard.JustDown(spaceKey) && !isAttacking) {
isAttacking = true;
player.anims.play("attack");
}player.on("animationcomplete", () => {
isAttacking = false;
});

🏆 Objetivos de Aprendizagem (Nível Profissional)

Ao final desta lição o aluno deverá:

✅ Entender como o Phaser gerencia animações globalmente
✅ Criar e organizar múltiplas animações
✅ Implementar sistema simples de estados
✅ Controlar transições de animação
✅ Otimizar uso de assets
✅ Criar animações reativas ao input