Como Criar um Jogo com Phaser (JavaScript) do Zero

Aprenda a criar um jogo com Phaser, o framework JavaScript para jogos 2D no navegador: config, cenas, sprites, física arcade e movimento com teclado.
Se você já vive no ecossistema JavaScript, ou está aprendendo a linguagem, criar um jogo com Phaser é provavelmente o caminho mais curto entre "sei programar um pouco" e "tenho um jogo rodando num link que qualquer pessoa abre". O Phaser é um framework de código aberto para jogos 2D que roda direto no navegador, usando as mesmas ferramentas que você já usaria para fazer um site. Neste guia você vai montar um projeto do zero, entender como o Phaser organiza um jogo e sair com um personagem se mexendo na tela com as setas do teclado.
Vou ser honesto sobre o que o Phaser é e o que ele não é logo de cara, porque isso evita frustração lá na frente. Ele é excelente para jogo 2D na web e para quem já respira JavaScript. Em compensação, é só código: não existe editor visual onde você arrasta objetos para a cena. Para um primeiro jogo de navegador, isso é ótimo, você aprende a programar de verdade. Para projetos maiores ou qualquer coisa em 3D, uma engine com editor tende a poupar muito trabalho, e eu volto nesse ponto no fim.
O que é o Phaser 3 e quando ele faz sentido
O Phaser 3 é a versão atual do framework. Ele cuida da parte chata de um jogo para você: o loop principal que redesenha a tela dezenas de vezes por segundo, o carregamento de imagens e sons, a detecção de colisão, a entrada de teclado e mouse, animação de sprites, câmera e por aí vai. Você escreve a lógica do seu jogo em JavaScript e o Phaser executa isso quadro a quadro.
Ele faz sentido em três situações bem específicas. A primeira é quando você já conhece JavaScript e não quer aprender uma ferramenta nova só para fazer um jogo simples. A segunda é quando o alvo é a web desde o começo, porque o Phaser nasceu para o navegador e exporta jogo HTML5 sem drama. A terceira é quando você quer controle total sobre o código, sem uma interface no meio do caminho.
Se o seu caso é outro, vale pesquisar antes de escolher. Não sabe nem qual linguagem estudar? Dá uma olhada em qual linguagem aprender para fazer jogos antes de fechar em JavaScript. E se você ainda está decidindo a ferramenta, o comparativo de melhores engines de jogos ajuda a ver onde o Phaser se encaixa perto de opções como Godot, Unity e GDevelop.
Rodando o Phaser sem build complicado
A parte boa: para começar você não precisa de Node, npm nem empacotador. Um arquivo index.html que puxa o Phaser via CDN já resolve. Crie uma pasta para o projeto e, dentro dela, um arquivo index.html com isto:
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="UTF-8">
<title>Meu primeiro jogo Phaser</title>
<style>
body { margin: 0; background: #1d1d2b; }
canvas { display: block; margin: 0 auto; }
</style>
</head>
<body>
<!-- Phaser via CDN: sem instalar nada -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/phaser.min.js"></script>
<script src="game.js"></script>
</body>
</html>
Agora crie um arquivo game.js na mesma pasta. É nele que o jogo vai viver. Um detalhe importante: assim que você começar a carregar imagens, abrir o index.html com clique duplo (protocolo file://) costuma dar erro de carregamento por causa das regras de segurança do navegador. A solução é rodar um servidor local simples. Se você tem Python instalado, dentro da pasta do projeto basta um comando:
python -m http.server 8000
Depois é só abrir http://localhost:8000 no navegador. Com Node instalado, npx serve faz o mesmo. Nenhum dos dois exige configuração. Você segue sem build de verdade, só com um servidor servindo os arquivos.
O objeto de configuração do jogo
Todo jogo Phaser começa por um objeto de config. Ele descreve o tamanho da tela, o motor de renderização, a física e quais cenas existem. Comece o game.js assim:
const config = {
type: Phaser.AUTO, // WebGL se disponível, senão Canvas
width: 800,
height: 600,
backgroundColor: '#1d1d2b',
physics: {
default: 'arcade',
arcade: {
gravity: { y: 0 }, // sem gravidade neste exemplo top-down
debug: false
}
},
scene: {
preload: preload,
create: create,
update: update
}
};
const game = new Phaser.Game(config);
Vale entender cada pedaço. O type: Phaser.AUTO deixa o Phaser escolher entre WebGL e Canvas conforme o navegador, e você quase nunca mexe nisso. O width e height definem o tamanho do canvas em pixels. O bloco physics liga o sistema de física arcade, que é o mais leve e o mais usado para jogos 2D. E o scene aponta para as três funções que fazem o jogo acontecer.
As três funções de uma cena: preload, create e update
Uma cena é uma tela do seu jogo: o menu, a fase 1, o game over. Cada cena tem, no mínimo, esses três momentos. O preload roda primeiro e carrega tudo que o jogo vai usar. O create roda uma vez, logo depois, e monta a cena. O update roda a cada quadro, dezenas de vezes por segundo, e é onde fica a lógica que precisa acontecer o tempo todo.
Começando pelo preload. Aqui você diz ao Phaser quais imagens carregar e dá um apelido (a "key") para cada uma. Para o exemplo, vou carregar um fundo e um sprite do jogador. Você pode usar qualquer PNG que tiver na pasta, dentro de uma subpasta assets:
function preload() {
// this.load.image(key, caminho)
this.load.image('fundo', 'assets/fundo.png');
this.load.image('jogador', 'assets/jogador.png');
}
O this dentro dessas funções é a própria cena, e é por ele que você acessa tudo: o carregador, os objetos, a física, o teclado. Guarde isso, porque é o padrão que se repete o jogo inteiro.
Agora o create. Depois que as imagens carregaram, você as coloca na tela. Adicionar uma imagem de fundo é uma linha. Já o jogador, como queremos que ele se mova e colida, criamos como um sprite com física:
let jogador;
let teclas;
function create() {
// Fundo posicionado pelo centro da tela
this.add.image(400, 300, 'fundo');
// Sprite com física arcade, posicionado em x=400, y=300
jogador = this.physics.add.sprite(400, 300, 'jogador');
// Impede o jogador de sair da tela
jogador.setCollideWorldBounds(true);
// Cria os controles de setas do teclado
teclas = this.input.keyboard.createCursorKeys();
}
Repare em três coisas úteis. O this.add.image cria uma imagem estática, sem física, ideal para cenário. O this.physics.add.sprite cria um objeto que participa do sistema de física, então pode ter velocidade e colidir. E createCursorKeys devolve um objeto pronto com as setas up, down, left e right, além de espaço e shift.
Movendo o sprite com o teclado
Chegamos ao coração do jogo: o update. Ele roda a cada quadro, então é o lugar certo para ler o teclado e ajustar a velocidade do jogador. Na física arcade, você não move o objeto somando pixels na posição na mão. Em vez disso, você define a velocidade dele, e o Phaser cuida do movimento suave respeitando o tempo entre quadros. Isso deixa o jogo consistente mesmo em máquinas diferentes.
function update() {
const velocidade = 200; // pixels por segundo
// Zera a velocidade a cada quadro antes de ler as teclas
jogador.setVelocity(0);
if (teclas.left.isDown) {
jogador.setVelocityX(-velocidade);
} else if (teclas.right.isDown) {
jogador.setVelocityX(velocidade);
}
if (teclas.up.isDown) {
jogador.setVelocityY(-velocidade);
} else if (teclas.down.isDown) {
jogador.setVelocityY(velocidade);
}
}
A lógica é direta. No começo de cada quadro, zeramos a velocidade. Depois, se a seta esquerda está pressionada, damos velocidade negativa no eixo X (para a esquerda); se a direita, positiva. O mesmo vale para cima e baixo no eixo Y, lembrando que no Phaser o Y cresce para baixo, então "cima" é velocidade negativa. Como zeramos tudo no início, soltar a tecla para o movimento na hora.
Se você juntar o config, o preload, o create e o update num único game.js, servir a pasta com python -m http.server e abrir no navegador, já tem um jogo funcional: um personagem que anda em quatro direções e não sai da tela. É pouco código para um resultado que roda em qualquer navegador e você compartilha por link.
Um passo além: colisão entre objetos
Movimento sozinho vira jogo rápido quando você adiciona algo com que interagir. A física arcade facilita isso. Suponha que você carregou uma imagem moeda no preload e quer que o jogador colete moedas encostando nelas. No create, você cria um grupo de moedas e registra uma verificação de sobreposição:
// dentro do create, depois de criar o jogador
const moedas = this.physics.add.group();
moedas.create(200, 150, 'moeda');
moedas.create(600, 450, 'moeda');
// Quando o jogador sobrepõe uma moeda, chama coletarMoeda
this.physics.add.overlap(jogador, moedas, coletarMoeda, null, this);
E a função de coleta, que pode ficar solta no arquivo, remove a moeda tocada:
function coletarMoeda(jogador, moeda) {
moeda.disableBody(true, true); // some com a moeda
// aqui você somaria pontos, tocaria um som, etc.
}
Com overlap você detecta encostar sem empurrar; com collider (o outro método) os objetos se bloqueiam fisicamente, o que serve para paredes e chão. Esses dois métodos resolvem a maior parte da interação de um jogo 2D simples, e a partir daqui é questão de ir empilhando: pontuação, inimigos, fases, som. Se quiser um panorama de como distribuir o resultado, o guia de como criar um jogo para o navegador e onde publicar mostra os portais que aceitam jogo HTML5.
O ponto honesto: até onde o Phaser leva você
O Phaser entrega o que promete. Para jogo 2D na web, para prototipar ideia rápido e para quem já programa em JavaScript, ele é uma escolha sólida e madura. Você viu que dá para ter algo rodando com pouquíssima configuração, e isso tem valor real quando o objetivo é terminar e publicar.
Onde ele cobra o preço é na escala. Por ser só código, tudo que num editor visual seria arrastar e posicionar, no Phaser é escrever coordenada e testar no navegador. Montar uma fase grande na mão cansa. Não há inspetor para ajustar valores ao vivo, não há cena visual, e recursos como partículas complexas, iluminação 2D e tilemaps grandes dão mais trabalho de orquestrar. E, importante, o Phaser não faz 3D: se em algum momento você quiser sair do 2D, vai trocar de ferramenta de qualquer jeito.
Por isso a recomendação prática é: use o Phaser para o seu primeiro jogo de navegador e para sentir na pele como um game loop funciona, é um aprendizado que viaja com você. Mas se o plano é crescer para projetos maiores ou 3D, considere investir esse esforço numa engine como a Godot desde cedo, porque o editor visual e as ferramentas prontas costumam poupar semanas de infraestrutura que, no Phaser, você teria que montar sozinho.
Seja qual for o caminho, o segredo é o mesmo: terminar jogos pequenos e ir aumentando. Se você quer aprender desenvolvimento de jogos com método, do primeiro sprite ao jogo publicado, sem se perder no meio, é exatamente isso que a gente ensina no CursoGame.Dev. Escolha uma ferramenta, faça o menor jogo possível hoje e construa a partir dali.
Perguntas frequentes
Preciso instalar alguma coisa para usar o Phaser?
Não para começar. Dá para carregar o Phaser via CDN dentro de um index.html comum e abrir o arquivo no navegador. Você só precisa de um editor de texto e um navegador moderno. Quando o projeto cresce, aí sim vale usar um servidor local e um empacotador como o Vite, principalmente por causa do carregamento de imagens e áudio.
Phaser serve para jogos 3D?
Não. O Phaser é focado em jogos 2D no navegador: plataforma, puzzle, top-down, shoot em up e afins. Para 3D você usaria Three.js e Babylon.js no ecossistema web, ou uma engine como a Godot e a Unity. Se o seu plano inclui 3D no futuro, comece pensando na engine desde já.
Qual a diferença entre preload, create e update?
São os três métodos principais de uma cena. O preload carrega os recursos (imagens, sprites, áudio) antes do jogo começar. O create roda uma vez, quando a cena inicia, e é onde você cria os objetos na tela. O update roda a cada quadro e é onde fica a lógica contínua, como ler o teclado e mover o jogador.
Phaser é uma boa primeira ferramenta para aprender jogos?
É boa se você já programa em JavaScript ou está aprendendo e quer publicar rápido na web. Como é só código, você aprende programação de verdade no processo. Mas se o seu objetivo é crescer para projetos maiores ou 3D, uma engine com editor visual como a Godot costuma poupar muito trabalho de infraestrutura.
Dá para publicar um jogo Phaser em portais como o itch.io?
Dá. Um jogo Phaser é HTML, JavaScript e alguns assets, então você compacta a pasta em um zip e sobe como jogo HTML5 no itch.io, no CrazyGames ou no Poki. Como roda no navegador sem instalação, a barreira de entrada para o jogador é mínima, o que é uma das maiores vantagens de fazer jogo para web.


