Animação com Sprites
Voltar para: Games com Phaser + Reactjs
🎯 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
frameWidtheframeHeight - Criar animações reutilizáveis no Animation Manager do Phaser
- Controlar
frameRatee 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?



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:
| Propriedade | Função |
|---|---|
| key | Identificador único |
| frames | Quais frames usar |
| frameRate | Quantos 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:
- Criar sprite sheet
- Criar animações:
- walk_right
- walk_left
- Criar animação idle
- Ativar conforme movimento
- Parar animação ao soltar tecla
Desafio adicional:
- Implementar flip horizontal ao invés de sprite duplicado
🔹 Parte 2 – Sistema de Ataque
- Criar animação attack
- Ativar com tecla SPACE
- Bloquear movimento durante ataque
- Retornar automaticamente para idle
- 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
