Você está na página 1de 269

Criação de jogos HTML5 com

Javascript e Phaser

Gidenilson Alves Santiago


Criação de jogos HTML5 com Javascript e
Phaser
Gidenilson Alves Santiago

Esse é um livro Leanpub. A Leanpub dá poderes aos autores e editores a partir do processo de
Publicação Lean. Publicação Lean é a ação de publicar um ebook em desenvolvimento com
ferramentas leves e muitas iterações para conseguir feedbas dos leitores, pivotar até que você
tenha o livro ideal e então conseguir tração.

© 2019 - 2020 Gidenilson Alves Santiago


Primeiramente minha gratidão a Deus que me proporcionou a oportunidade de escrever esse
livro e fazer muitas outras coisas.
À minha esposa Tânia e aos meus filhos pelo apoio de sempre.
Conteúdo

Autor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

Prefácio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

Sobre o livro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Como ler o livro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Download do Phaser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

Introdução . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Multiplataforma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Onde aprender . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
e tipo de jogo pode ser feito com o Phaser . . . . . . . . . . . . . . . . . . . . . . . . . 10

Fundamentos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Estrutura de um jogo Phaser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Código mínimo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

Preparação do ambiente de desenvolvimento . . . . . . . . . . . . . . . . . . . . . . . . . . 15


GitBash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
NodeJs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
hp-server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Olá mundo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

Trabalhando com texto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19


Texto simples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
setOrigin([x . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Web fontes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Bitmap fontes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

Littera . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

Bitmap Font Generator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33


Configuração da fonte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Configuração de exportação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
exportação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

Imagens e sprites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

TextureAtlas e Spritesheet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


CONTEÚDO

Free Texture Paer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

Animação de sprites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Animação com spritesheet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Animação com TextureAtlas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

Sons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

Partículas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

Teclado e mouse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Teclado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Mouse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

Botões . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69

Tween . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73

Timeline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75

Path e follower . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79

Configuração do Phaser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81

Física no Phaser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
Habilitando a física . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
Movimento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
Detecção de colisões . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91

Tilemap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Tiled . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
Construção de um autódromo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
Layer de objetos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
Tiles de colisão . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118

Cenas (scene) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127

Beth . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
index.html . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
game.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
scenes/BootScene.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
scenes/PreloaderScene.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
scenes/MenuScene.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
scenes/CreditsScene.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
scenes/GameScene.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
config/phaser.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
classes/Beth.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
classes/Audio.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
classes/Botao.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
classes/Colisoes.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


Chain of responsibility (Responsabilidades.js, ResponsabilidadeMorreu.js, Responsa-
bilidadeVitoria.js) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
classes/Inimigo.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176
classes/Moeda.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
classes/GrupoMoedas.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
classes/Gui.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181

Flying bee . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185

Chien . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
Estrutura de pastas e arquivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
index.html . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
game.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
scenes/BootScene.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
scenes/PreloaderScene.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
scenes/MenuScene.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
scenes/CreditsScene.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
scenes/GameScene.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
classes/Mundo.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208
classes/Chien.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
classes/Vehicle.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
classes/VehiclesGroup.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
classes/Colisoes.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
classes/Animacoes.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224
classes/Audio.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225
classes/Buon.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225

Flying bee . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227


Estrutura de arquivos e pastas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
index.html . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231
game.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
scene/BootScene.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234
scene/CreditsScene.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234
scene/PreloaderScene.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235
scene/MenuScene.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240
Classes do game . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240
scene/GameScene.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255

Conclusão . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259

Links importantes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


Autor

Gidenilson A Santigo

Gidenilson Alves Santiago nasceu no ‘ano que não acabou’ (1968). Aos 15 anos ganhou do seu
tipo o microcomputador CP200, com 16K de RAM e processador Z-80. Iniciou seus estudos de
programação, aos 15 anos, em BASIC lendo o manual do micro. Ao esgotar o estudo do BASIC
partiu para ASSEMBLY Z-80. Seu próximo micro foi o TK2000 da Microdigital que era bem mais
poderoso com incríves 64K de RAM e cores. Como já fizera antes, aprendeu a programar o BASIC
e depois a linguagem ASSEMBLY do processador 6502.
Desde então o autor vem acompanhando o desenvolvimento da programação, sendo progra-
mador baend (PHP) e frontend (Javascript), tendo trabalhado em empresas de soware e
como freelancer. Atualmente se dedica ao estudo de JavaScript, jogos 2D e jogos educativos
com destaque para educação musical.
Paralelamente o autor é músico e habilitado em educação musical pela Universidade Federal de
São Carlos - UFSCar.
Prefácio
Em um mundo de acentuados avanços tecnológicos, um dos mercados que mais cresce é o
de jogos eletrônicos. Com isto em vista, mais e mais pessoas se aventuraram no estudo do
desenvolvimento de jogos de todos os gêneros, modalidades e em diferentes plataformas. Além
de novos jogos, novas formas de desenvolvê-los e projetá-los foram surgindo. Uma destas formas
é o uso de frameworks, e neste livro você aprenderá como usar o Phaser para desenvolver
seus próprios jogos. A escolha do Phaser é devida ao intuito do autor em usar ferramentas
gratuitas, acessíveis a qualquer um que quiser iniciar seus estudos em desenvolvimento de jogos
sem gastar muito. Para o autor, usar ferramentas de baixo custo e fácil acesso contribui para a
democratização do conhecimento, viabilizando a mais pessoas prosseguirem seus estudos sem
se preocupar com grandes gastos em ferramentas de trabalho, pesquisa e lazer. Criar jogos é
uma atividade que pode ser muito divertida e cativante, e neste livro você poderá iniciar seus
estudos, ou aprender mais sobre esta poderosa ferramenta de criação de jogos que é o Phaser.
Bom proveito e boa leitura!
Daniel Lopes Santiago\
(Gamer Senior)
Sobre o livro
O objetivo deste livro é iniciar o leitor na criação de jogos 2D, em HTML2 e Javascript, com o
framework Phaser.
Esse livro deve ser lido por quem está pelo menos familiarizado com Javascript nos seguintes
aspectos:

1. Orientação a objetos
2. Arow functions
3. Classes e extends

Nos primeiros capítulos estudaremos as principais funcionalidades separadamente para facilitar


a assimilação e nos capítulos finais desenvolveremos alguns jogos completos.

Como ler o livro


O código fonte de todos exemplos estão disponíveis no Github hps://github.com/gidenilson/phaser3book¹
Para tirar o máximo proveito deste livro, meu conselho é que você leia cada capítulo 2 vezes.
Faça a primeira leitura sem se preocupar com o completo entendimento do assunto e nem
com os códigos mostrados. A segunda leitura deve ser mais lenta e acompanhada do estudo
e desenvolvimento do código apresentado. Para ajudas você vai encontrar todos os exemplo
prontos no código fonte do livro. Você não precisa necessariamente codificar, pois acredito que o
estudo do código pronto é suficiente para aprender a desenvolver com o Phaser. Mas é importante
que enquanto aprende você já comece a criar seus próprios exemplos conforme vai ganhando
conhecimento.

Download do Phaser
O Phaser é um framework muito ativo, com várias atualizações por ano. Isso é muito bom pois
estamos trabalhando com uma ferramenta em constante desenvolvimento. Por isso para você
acompanhar os exemplos desse curso é importante que utilize a mesma versão do Phaser que
estamos usando, a 3.20.
Por conveniência em todos exemplos aqui mostrados estamos utilizando o Phaser a partir de um
CDN <script src="//cdn.jsdelivr.net/npm/phaser@3.20.0/dist/phaser.js"></script>
Em desenvolvimento é melhor usar a versão não minificada, para termos a ajuda do Phaser na
hora de encontrar algum erro no nosso código.
¹https://github.com/gidenilson/cursophaser3
6 Sobre o livro

Para produção, como sempre, usamos a versão minificada a partir do CDN ou baixada direta-
mente na pasta do no nosso game.
Na página de download do Phaser encontramos todas essas possibilidades.

fig A

Se quando você estiver acompanhando este curso a versão do Phaser for diferente da 3.20, você
pode escolher a versão acessando o repositório do Phaser no Github, ou escolhendo a versão no
CDN do Phaser em https://www.jsdelivr.com/package/gh/photonstorm/phaser

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


7

fig B

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


Introdução
O Phaser é um framework Javascript para a criação de jogos em HTML5, de código aberto rápido,
gratuito e divertido, que oferece renderização WebGL e Canvas em navegadores da Web para
desktop e dispositivos móveis.
Os jogos podem ser compilados para iOS, Android e aplicativos nativos usando ferramentas de
terceiros. Você pode usar JavaScript ou TypeScript para desenvolvimento.
Juntamente com a fantástica comunidade de código aberto, o Phaser é ativamente desenvolvido
e mantido pela Photon Storm. Como resultado do suporte rápido e de uma API amigável para
desenvolvedores, o Phaser é atualmente um dos frameworks de jogos mais marcadas no GitHub.
Milhares de desenvolvedores de agências digitais independentes e multinacionais e universidades
de todo o mundo usam o Phaser.

Features
As features do Phaser são as seguintes:
WEBGL & CANVAS,
PRELOADER,
PHYSICS,
SPRITES,
GROUPS,
ANIMATION,
PARTICLES,
CAMERA,
INPUT,
SOUND,
TILEMAPS,
DEVICE SCALING,
PLUGIN SYSTEM,
MOBILE BROWSER,
DEVELOPER SUPPORT,
WEB FIRST

Multiplataforma
Uma grande vantagem no desenvolvimento de jogos em HTML5 é a possibilidade de publicar os
jogos para várias plataformas com apenas o mesmo código. Um jogo desenvolvido com o Phaser
pode ser exportado para iOS, Android, browser e etc.
10 Introdução

Onde aprender
O Phaser conta com uma excelente documentação (em inglês) e mais de 1700 exemplos dos seus
recursos e funcionalidades. No site encontramos também muitos tutorias bastante didáticos.
Por isso antes de continuar lendo este livro faça uma visita e navegue no site do Phaser.
hp://phaser.io

Que tipo de jogo pode ser feito com o Phaser


Teoricamente podemos dizer que com o Phaser podemos desenvolver qualquer tipo de jogo, até
mesmo alguns jogos 3D. Mas de fato o Phaser se propõe a ser uma engine para desenvolvimento
de jogos 2D.
Outra coisa importante a ser dita é que qualquer engine de jogos tem seus pontos fortes e
fracos. Com o Phaser podemos desenvolver inúmeros tipos de jogos, mas é sempre bom, antes
de começar a por a mão na massa para criar um jogo, conhecer esses pontos fortes e fracos.
ero dizer com isso que quando utilizamos qualquer engine de jogos, devemos conhecer os
pontos fracos e fortes, e procurar trabalhar em cima desses pontos fortes.
Para se ter uma ideia do que é feito com o Phaser, visite o blog do site (hp://phaser.io/news) e
navegue nos exemplos de features da engine (hp://phaser.io/examples).

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


Fundamentos
Estrutura de um jogo Phaser
No Phaser um jogo é composto por scenes (cenas), onde cada scene corresponde a uma tela do
jogo. É possível navegar facilmente de uma scene para outra. Podemos desenvolver um jogo de
forma monolítica, com todo o código dentro de um único arquivo. Para o Phaser não faz diferença
se todo o código está em um arquivo só, mas para organização e facilidade de desenvolvimento
e manutenção é melhor dividimos o código em blocos menores. Uma primeira divisão a ser feita
é criar um arquivo para cada cena e para cada entidade do jogo.
Na figura temos um exemplo de como podemos estruturar as cenas de um jogo. Temos aí um
arquivo para cada scene.

fig 1

Também é um bom momento dizer que todas as scenes do jogo podem ter 4 métodos especiais:
init(), preload(), create(), update().

1 class BootScene extends Phaser.Scene {


2 constructor() {
3 super('Boot');
4 }
5
6 init(){
7 // code
8 }
9 preload() {
10 // code
11 }
12
13 create() {
14 // code
15 }
16 update(time, delta){
17 // code
12 Fundamentos

18 }
19 }

O método init() é o primeiro bloco a ser executado na inicialização da scene. Neste bloco
podemos colocar nossas variáveis de inicialização.
O método preload() é onde os assets do jogo são carregados para o cae do jogo.
O método create() é executado em seguida do método preload() e é onde fica a maior parte da
lógica do nosso jogo.
Esses 3 métodos são executados uma vez na amada da scene. Mas o próximo método, update(),
é executado repetidamente numa taxa de 60 fps (frames por segundo). É neste método que
escrevemos partes da lógica que necessitam atualização a cada frame.

Código mínimo
Como já dissemos anteriormente, um jogo em Phaser pode ser um único arquivo de código.
Vamos então nesse momento ver como fica o código mínimo para um jogo nascer:
index.html

1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>Text</title>
6 </head>
7 <body>
8 <script src="//cdn.jsdelivr.net/npm/phaser@3.20.0/dist/phaser.js"></script>
9 <script src="game1.js"></script>
10 </body>
11 </html>

game1.js

1 var config = {
2 type: Phaser.AUTO,
3 width: 800,
4 height: 600,
5 scene: {
6 create: create
7 }
8 }
9 var game = new Phaser.Game(config);
10 function create ()
11 {
12 // code
13 }

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


13

Com este código teremos o seguinte na tela:

fig 2

Ou seja, só uma quadro preto na tela. Mas se abrirmos o console do desenvolvedor no browser
veremos que o Phaser já está rodando:

fig 3

No código acima podemos observar que só temos um objeto de configuração e apenas o método
create(). A referência a uma scene está neste arquivo de configuração, mas não temos nenhum
outro código designando uma scene. Isso acontece porque com um código mínimo podemos ter
apenas uma scene, que será o próprio código.
Os métodos init(), preload(), create(), e update() não são obrigatórios, mas aparecem só
quando necessário.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


Preparação do ambiente de
desenvolvimento
Para trabalharmos com o Phaser precisaremos ter em nosso computador o GitBash (ou algum
outro console de linha de comando), o NodeJs e o script hp-server
Precisamos do hp-server para servir nossos arquivos localmente na nossa máquina, pois o
Javascript, por questões de segurança, não vai ler arquivos diretamente do nosso sistema de
arquivos.
Para rodar o hp-server precisamos do NodeJs e no npm instalados. E para trabalhar com o
NodeJs utilizaremos o console de linha de comando GitBash.
Além desses aplicativos você precisará de um bom editor de texto, dentre as muitas alter-
nativas disponíveis. Use o que aar melhor, mas para este curso estarei utilizando o Atom
(hps://atom.io).
É claro que você é livre para utilizar outras alternativas à esses aplicativos aqui sugeridos. Mas de
qualquer maneira vamos ver como instalar cada um deles para deixar o nosso ambiente pronto
para trabalharmos.

GitBash
Baixe o Git no site hps://git-scm.com
Não tem nenhum segredo para instalar o Git (que já vem com o GitBash. Siga as instruções do
site.
Se você fez a instalação padrão, o programa de instalação do Git criou um atalho de contexto
para abrir o GitBash nas pastas, escolhendo essa opção clicando com o botão direito do mouse.
16 Preparação do ambiente de desenvolvimento

fig 5

NodeJs
A instalação do NodeJs também é corriqueira. Acesse o site, baixe o arquivo de instalação e
instale na sua máquina (hps://nodejs.org).

http-server
Já tendo instalado o GitBash e o Nodejs, você já pode instalar o servidor hp-server com o
comando npm.
Crie uma pasta para o seu projeto e abra o GitBash clicando com o botão direito do mouse sobre
a pasta e selecionando ‘Git Bash Here’ no menu de contexto.
Agora digite o comando npm install http-server -g
Isto instalará o hp-server de forma global, para estar acessível de qualquer pasta dentro do
console de linha de comando.
Para testar, digite no console o comando http-server
Você deverá ter a seguinte saída no console:

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


17

fig 6a

Agora se você abrir o browser no endereço http://localhost:8080 ainda não acontecerá nada.
Mas se você criar nesta pasta um arquivo index.html e amar http://localhost:8080/index.html
você verá que o hp-server está funcionando.
Nos nossos exemplos o procedimento para testar o jogo será sempre este:

1. Abrir o terminal GitBash na pasta onde está o arquivo index.HTML.


2. Executar o comando http-server.
3. Abrir o browser em http://localhost:8080/index.html

Você encontra um pequeno vídeo tutorial em https://youtu.be/XfQrsBQAu-k

Olá mundo
Vamos agora criar o nosso ‘olá mundo’?

1. Crie uma pasta para o nosso ‘olá mundo’.


2. Crie os arquivos index.html e game1.js.
3. No arquivo index.html coloque o seguinte:

1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 <title>Olá mundo</title>
7 </head>
8 <body>
9 <script src="//cdn.jsdelivr.net/npm/phaser@3.20.0/dist/phaser.js"></script>
10 <script src="game1.js"></script>
11 </body>
12 </html>

4. Agora no arquivo game1.js:

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


18 Preparação do ambiente de desenvolvimento

1 var config = {
2 type: Phaser.AUTO,
3 scene: {
4 create: create
5 }
6 }
7 var game = new Phaser.Game(config)
8 function create() {
9 this.add.text(400, 300, 'Olá, mundo!')
10 }

5. Abra o GitBash na pasta do projeto e digite o comando http-server


6. Abra o browser e acesse http://localhost:8080/index.html
7. Pronto. Nosso olá mundo está funcionando.

fig 6b

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


Trabalhando com texto
O Phaser disponibiliza algumas formas de trabalhar diretamente com textos, que são: texto
simples, webfontes e texto bitmap.

Texto simples
No modo de texto simples o Phaser utiliza as fontes que normalmente estão disponíveis por
padrão do browser tais como: Arial, Helvetica, Times New Roman, Times, Courier New,
Courier, Verdana, Georgia, Palatino, Garamond, Bookman, Comic Sans MS, Trebuchet MS,
Arial Black e Impact.

Para criar textos simples no Phaser precisamos instanciar a classe Phaser.GameObjects.Text.


A instanciação é feita com a ajuda do método add.text disponível na nossa scene. Por exemplo:

1 this.add.text(0, 0, 'Hello World', { fontFamily: 'Arial' });

Onde passamos os parâmetros (x, y, text, style). x e y é o posicionamento do texto na tela,


text é o texto propriamente dito, style é um objeto de configuração com os seguintes parâmetros:

fontFamily, fontSize, fontStyle, backgroundColor, color, stroke, strokeThickness,


shadow, padding, align, maxLines, fixedWidth, fixedHeight, resolution, rtl, testString,
baselineX, baselineY, wordWrap, metrics

Durante o curso utilizaremos algumas dessas propriedades. Mas se você quiser descobrir o que
faz cada uma delas procure por Phaser.Types.GameObjects.Text na documentação do Phaser.
Para experimentar as formas de trabalhar com texto no Phaser utilizaremos uma pequena
estrutura com 2 arquivos: index.html e game.js. Então crie uma pasta e coloque dentro estes
2 arquivos.
index.html

1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>Text</title>
6 </head>
7 <body>
8 <script src="//cdn.jsdelivr.net/npm/phaser@3.20.0/dist/phaser.js"></script>
9 <script src="game1.js"></script>
10 </body>
11 </html>

game1.js
20 Trabalhando com texto

1 var config = {
2 type: Phaser.AUTO,
3 scene: {
4 create
5 }
6 }
7 var game = new Phaser.Game(config);
8
9 function create() {
10 this.texto = this.add.text(400, 300, 'Trabalhando com texto', {
11 fontSize: 40,
12 fontFamily: "Arial"
13 })
14 this.texto.setStroke('#aa0000', 4);
15 this.texto.setShadow(2, 2, "#333333", 2, true, true);
16 this.texto.setOrigin(0.5);
17 }

Como você pode observar, além da criação do texto com this.add.text, temos mais 3 linhas
de código que amam métodos que transformam o texto. O objeto Phaser.GameObjects.Text
possui ainda muitos outros métodos. Para conhecer todos volte a consultar a documentação e
faça testes com cada um dos métodos.
Agora vamos fazer uma brincadeira. Crie outro arquivo javascript, por exemplo game2.js, e insira
o seguinte código:

1 var config = {
2 type: Phaser.AUTO,
3 scene: {
4 create: create
5 },
6 backgroundColor: 0xbdbdbd
7 }
8
9 var game = new Phaser.Game(config);
10
11 function create() {
12 this.counter = 0
13 this.texto = this.add.text(400, 300, 'contagem: 0', {
14 fontSize: 40,
15 fontFamily: "Arial"
16
17 });
18 this.texto.setStroke('#aa0000', 4);
19 this.texto.setShadow(2, 2, "#333333", 2, true, true);
20 this.texto.setOrigin(0.5);
21

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


21

22
23 this.texto.setInteractive();
24 this.texto.on('pointerdown', (pointer) => {
25 this.texto.text = `contagem: ${this.counter} family: ${fonts[this.counter]}`;
26 this.texto.setFontFamily(fonts[this.counter]);
27 this.counter++;
28 });
29 }
30 var fonts = [
31 "Arial",
32 "Helvetica",
33 "Times New Roman",
34 "Times",
35 "Courier New",
36 "Courier",
37 "Verdana",
38 "Georgia",
39 "Palatino",
40 "Garamond",
41 "Bookman",
42 "Comic Sans MS",
43 "Trebuchet MS",
44 "Arial Black",
45 "Impact",
46 ];

Agora dê um refresh (CTRL F5) no browser e clique com o mouse no texto.


Não esqueça de alterar o nome o script no arquivo html.

1 <script src="game2.js"></script>

Isto é só um exemplo para você começar a perceber o que pode ser feito com o Phaser. Se este
código não está claro agora para você, não se preocupe; vamos ver o que significa tudo isso no
decorrer do curso.

[
,y])]setOrigin([x] [,y])
Todos os objetos do Phaser têm um ponto de origem a partir do qual ocorre o posicionamento
na tela, a rotação e etc.
Esse ponto de origem de divide em originX, que é a posição de origem em relação ao eixo
horizontal, e originY, que é a posição em relação ao eixo vertical.
O valor padrão da origem X e Y é 0.5, isso significa que todos os objetos são posicionados com
base no seu centro.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


22 Trabalhando com texto

Se definirmos a originX como 0 o ponto de origem horizontal passa a ser o canto esquerdo do
objeto, e se o valor for definido para 1 a origem horizontal passa a ser o lado direito do objeto.
No eixo vertical, definido em originY, o valor 0 faz que a origem do objeto passe a ser o topo,
enquanto que o valor 1 define a origem para a base inferior do objeto.
Para definirmos o ponto de origem dos objetos amamos o método setOrigin( [x] [, y]).
Podemos tambem amar esse método passando apenas 1 valor. Nesse caso estaremos definindo
originX e originY com o mesmo valor passado.

fig 6c

Web fontes
No Phaser podemos utilizar web fontes a partir dos arquivos de fonte (TTF) disponíveis no código
fonte dos nossos jogos. Para isso basta incluir o arquivo da fonte no CSS no index.html que
carrega o jogo e fazer uma referência a essa fonte em alguma tag do html.
Como exemplo vamos incluir e utilizar a fonte Mansalva que pode ser encontrada no repositório
Google Fonts. (este arquivo está no código fonte do curso)
Vamos criar a seguinte estrutura de pasta e arquivos:

1 + webfontes
2 + font
3 - Mansalva-Regular.ttf
4 - index.html
5 - game1.js

Nossa webfonte está localizada dentro da pasta font.


Agora coloque o seguinte código dentro do index.html:

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


23

1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>Font</title>
6 <style media='screen' type='text/css'>
7 @font-face {
8 font-family: Mansalva;
9 src: url('font/Mansalva-Regular.ttf');
10 }
11 </style>
12 </head>
13 <body>
14 <div style="font-family:BigShoulders; position:absolute;
15 left:-1000px; visibility:hidden;">.</div>
16
17 <script src="//cdn.jsdelivr.net/npm/phaser@3.20.0/dist/phaser.js"></script>
18 <script src="game1.js"></script>
19
20 </body>
21 </html>

E no game1.js:

1 var config = {
2 type: Phaser.AUTO,
3 scene: {
4 create
5 },
6 backgroundColor: 0xbdbdbd
7 }
8 var game = new Phaser.Game(config);
9 function create() {
10 this.counter = 0
11 this.texto = this.add.text(400, 300, 'Fonte Mansalva', {
12 fontSize: 40,
13 fontFamily: "Mansalva"
14 })
15 this.texto.setStroke('#aa0000', 4)
16 this.texto.setShadow(2, 2, "#333333", 2, true, true)
17 this.texto.setOrigin(0.5)
18 }

Rode o hp-server na pasta onde está o index.html, acesse http://localhost:8080/index.html


e dê um refresh no browser.
O resultado deve ser:

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


24 Trabalhando com texto

fig 7

Bitmap fontes

Classe Phaser.GameObjects.BitmapText
Um objeto BitmapText é uma instância dessa classe. Na documentação do Phaser você poderá
ver todos os métodos e propriedades que podem ser usados para trabalhar com esse objeto.
O objeto BitmapText funciona usando um arquivo de textura e um arquivo XML ou JSON que
mapeia os caracteres dentro da textura. Durante a renderização, cada letra do texto é renderizada
na tela, espaçada proporcionalmente e alinhada para corresponder ao mapeamento da fonte.
Os objetos BitmapText são menos flexíveis que os objetos de texto, pois possuem menos recursos,
como sombras, preenimentos e a capacidade de usar fontes da Web; no entanto, você troca essa
flexibilidade pela velocidade de renderização. Você também pode criar BitmapTexts visualmente
atraentes, processando a textura da fonte em um editor de imagens, aplicando preenimentos e
quaisquer outros efeitos necessários.
Bitmap fonte é uma técnica que utiliza 2 arquivos para escrever os caracteres na tela: um arquivo
de imagem e um arquivo de texto com o mapeamento dos caracteres dentro do respectivo arquivo
de imagem. O arquivo texto pode estar nos formatos XML, JSON ou CSV. Geralmente para o
formato XML, temos um arquivo com a extensão FNT.
Por exemplo:
imagem font.png

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


25

fig 8

arquivo xml font.fnt

fig 9

Bitmap fontes são muito fáceis de serem utilizadas no Phaser. A classe responsável por essa
feature é Phaser.GameObjects.BitmapText.
Para criar uma instância desta classe utilizamos o metódo this.add.bitmapText(x, y, font [,
text] [, size] [, align]).

O this representa a scene em que estamos instanciando o objeto. Vamos ao exemplo.


Crie a seguinte estrutura de pasta/arquivo:

1 + BitmapText
2 font.png
3 font.fnt
4 index.html
5 game1.js

Você vai encontrar estes arquivos no código fonte do curso.


No arquivo index.html insira o seguinte código:

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


26 Trabalhando com texto

1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>BitmapText</title>
6 </head>
7 <body>
8 <script src="//cdn.jsdelivr.net/npm/phaser@3.20.0/dist/phaser.js"></script>
9 <script src="game1.js"></script>
10
11 </body>
12 </html>

E no arquivo game1.js:

1 var config = {
2 type: Phaser.AUTO,
3 scene: {
4 preload,
5 create
6 },
7 backgroundColor: 0x000
8 }
9 var game = new Phaser.Game(config)
10 function preload(){
11 this.load.bitmapFont('fonte', 'font.png', 'font.fnt');
12 }
13 function create() {
14 this.counter = 0;
15 this.texto = this.add.bitmapText(100, 100, 'fonte', 'Minha Fonte', 32)
16 }

Isto irá imprimir “Minha Fonte” na tela do jogo.


Para alterar o texto do objeto bitmapText criado utilize o método this.texto.setText('Outro
texto aqui')

A partir de um arquivo de webfont (f) podemos criar nossos arquivos font.png e font.fnt,
usando para isso um aplicativo.
Vamos neste curso apresentar dois aplicativos para essa finalidade: um aplicativo on-line
denominado Liera acessível em http://kvazars.com/littera, e o Bitmap Font Generator que
roda na sua máquina e pode ser baixado em http://www.angelcode.com/products/bmfont

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


Littera
Vamos primeiramente aprender como criar bitmap fontes com o Liera.
Passo a passo:

Abra o Littera no browser


O Liera é um aplicativo feito em Flash. Infelizmente o Google Chrome anunciou que a partir
de 2020 o Chrome não dará mais suporte a aplicativos Flash. Mas enquanto isso não acontece
vamos aprender como utilizar esse poderoso aplicativo.
Primeiramente acesse o endereço do aplicativo em http://kvazars.com/littera

A interface do Littera
Visão geral:
28 Liera

fig 10

Vamos apresentar aqui só os pontos indispensáveis da interface, que lhe permita gerar sua fontes.
Mas você deve brincar um pouco com todas as features do aplicativo.
No lado esquerdo do topo, na seção Project você tem a opção de salvar um projeto de webfonte
ou carregá-lo do seu computador.
Logo abaixo dos botões de Load project e Save project temos uma caixa de texto para
inserirmos algum texto para testar.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


29

fig 11

Descendo mais ainda, temos a seção Included glyphs que é onde inserimos quais caracteres
queremos gerar na nossa webfont. Na caixa de texto podemos digitar os caracteres que queremos
ou utilizar alguns dos presets disponíveis. Mas lembre que quanto mais caracteres você utilizar,
maior será o arquivo PNG gerado.
Temos também o botão Select Font que faz o que o nome indica. Nesta seção temos ainda a
possibilidade de definir o tamanho da fonte e o espaçamento entre os caracteres. Brinque um
pouco com esta seção para descobrir o que pode ser feito.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


30 Liera

fig 12

Na seção de controles no topo do aplicativo temos as configurações de exportação. Você pode


deixar tudo como está e utilizar o botão Export para exportar sua bitmapFont.

fig 13

Com isso abrirá uma janela com duas caixas de texto. A primeira permite que você coloque
várias escalas que deseja exportar como bitmapFont. No exemplo abaixo nós estamos gerando
três escalas: 0.5, 1 e 2.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


31

fig 14

Ao clicar no botão Start outra janela se abrirá para que você faça download da fonte gerada. O
arquivo baixado será um ZIP com os arquivos png e fnt da sua fonte.

fig 15

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


Bitmap Font Generator
Vamos agora trabalhar um pouco com o Bitmap Font Generator. Vá até o site do aplicativo, faça
o download e instale. A instalação é muito corriqueira e não há necessidade de entrarmos em
detalhes aqui.
Par baixar o aplicativo acesse https://www.angelcode.com/products/bmfont
Depois de instalado abra o aplicativo e vamos ver os tópicos essenciais para gerar nossas bitmap
fontes.

fig 16

A primeira coisa a fazer é selecionar o conjunto de caracteres que iremos trabalhar. O primeiro
conjunto localizado na parte de cima do lado direito da figura é o Latin + Latin Supplement.
Selecionando este conjunto você já terá todos os caracteres alfanuméricos do português e outras
línguas latinas.
34 Bitmap Font Generator

Configuração da fonte

fig 17
Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com
35

Clicando Options no menu do aplicativo e selecionando Font settings abre-se a janela de


configuração da fonte.
As opções de configuração são auto-explicativas, mas o mais importante aqui é você escolher
a fonte na caixa de seleção Font. Nesta caixa você poderá escolher qualquer fonte instalada no
sistema. Mas na caixa de seleção logo abaixo, Add font file, você poderá carregar um arquivo
de fonte de formato TTF para trabalhar.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


36 Bitmap Font Generator

Configuração de exportação

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


37

Agora selecionando no menu a opção Export Options teremos a janela de configuração de


exportação da nossa bitmap fonte.
Um pouco acima da metade dessa janela temos a seleção do Bit depth. Selecione 32.
Na caixa de seleção Presets escolha a opção White text with alpha. Em File format selecione
a opção XML. Na caixa de seleção Textures selecione o formato PNG.
Com estas configurações iremos exportar uma bitmap fonte com fundo transparente e cor de
texto branco. Infelizmente este aplicativo não oferece opções de cor, sombra, stroke e etc como
o Liera. Mas particularmente eu prefiro no Phaser usar a técnica de webfonts.

exportação

fig 19

Agora vá no menu Options e exporte a bitmap selecionando Save bitmap font as... Pronto, não
tem segredo. Serão gerados os 2 arquivos da bitmap fonte: o arquivo PNG e o FNT (lembrando
que esse fnt é na verdade um XML).

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


Imagens e sprites
Uma imagem no Phaser é uma instância da classe Phaser.GameObjects.Image.
Uma imagem é um objeto de jogo leve, útil para a exibição de imagens estáticas no seu jogo,
como logotipos, planos de fundo, cenário ou outros elementos não animados. As imagens podem
receber eventos do mouse, podem ter corpos físicos, ou serem interpoladas, coloridas ou roladas.
A principal diferença entre uma imagem e um Sprite é que você não pode animar uma imagem,
pois ela não possui o componente Animação.
Para utilizar uma imagem a primeira coisa a fazer é carregar tal imagem para o cae do Phaser
amando this.load.image(key, url), onde this referência à scene de onde estamos amando
o método.
Exemplo:

1 function preload ()
2 {
3 this.load.image('logo', 'images/logotipo.png')
4 }

Ao invés de passar argumentos, podemos passar um objeto de configuração para carregar a


imagem.

1 function preload()
2 {
3 this.load.image({
4 key: 'logo',
5 url: 'images/logotipo.png'
6 })
7 }

Para mais detalhes sobre o objeto de configuração de imagem, procure na documentação do


Phaser por Phaser.Types.Loader.FileTypes.ImageFileConfig.
Depois do carregamento, podemos utilizar a imagem na nossa cena amando o método
this.add.image(x, y, key).

Exemplo:
40 Imagens e sprites

1 function create()
2 {
3 this.add.image(x, y, 'logo')
4 }

Um sprite é uma instância da classe Phaser.GameObjects.Sprite


É um objeto usado para mostrar imagens estáticas ou animados em nosso game. Assim como as
imagens, os sprites podem receber eventos de mouse (ou tou) e podem ganhar corpos físicos.
Tabém podem trabalhar com tween e scroll.
Para adicionar um sprite à nossa scene devemos, como sempre, primeiro carregar a imagem
dentro do método preload() da scene.
Por enquanto vamos apenas carregar uma imagem comum em nosso sprite. Mas na frente iremos
aprender a trabalhar com sprites animados.
Uma vez que a imagem já foi carregada no método preload() criamos o sprite amando o
método this.add.sprite(x, y, texture [, frame]) onde this faz referência à scene onde
estamos carregando o sprite. Por enquanto não vamos trabalhar com o último parâmetro frame.
Veremos isso mais a frente quando estudarmos sprites animados.
Exemplo:

1 function create()
2 {
3 this.add.sprite(x, y, 'imagem')
4 }

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


TextureAtlas e Spritesheet
O termo ‘Sprite Sheet’ no Phaser significa uma imagem formada por inúmeros frames onde todos
eles tem exatamente o mesmo tamanho. Você faz referência a esses frames usando números e
não os seus nomes.
Exemplo de sprite sheet:

fig 20

Já num ‘Textura Atlas’ os frames são arranjados dentro da imagem de maneira que ocupem o
menor espaço possível, e esses frames são referenciados pelos seus nomes com o auxílio de uma
arquivo XML ou JSON que contém todos os dados de cada frame.
É bom salientar que alguns artigos e sowares usam o termo ‘Sprite Sheet’ como sinônimo de
‘Texture Atlas’. Então temos que ter cuidado para não confundir as coisas quando trabalhamos
com o Phaser.
Exemplo de texture atlas:
42 TextureAtlas e Spritesheet

fig 21

Nós podemos criar imagens estáticas ou animações utilizando tanto sprite sheet quanto texture
atlas.
Por enquanto vamos ver um exemplo de imagem estática criada com sprite sheet e textura atlas.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


43

1 function preload ()
2 {
3 // sprite sheet
4 this.load.spritesheet('bot', 'images/robot.png', {
5 frameWidth: 32, frameHeight: 38 })
6
7 // texture Atlas
8 this.load.atlas('mainmenu', 'images/MainMenu.png', 'images/MainMenu.json')
9 }

Exemplos de utilização:

1 function create()
2 {
3 // criando sprites
4 this.add.sprite(100, 50, 'bot', 2)
5 this.add.sprite(200, 300, 'mainmenu', 'btnStart')
6
7 // criando imagens
8 this.add.image(200, 50, 'bot', 2)
9 this.add.image(200, 400, 'mainmenu', 'btnStart')
10 }

A princípio não faz diferença se colocamos uma figura na tela com sprite ou com image. Mas,
como já dissemos antes, se queremos uma animação temos que usar os sprites. Então não utilize
sprites para imagens estáticas por motivo de economia de recursos da máquina.
Vamos agora criar uma scene com alguns objetos sprite e image:
index.html

1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>Phaser3</title>
6 </head>
7 <body>
8 <script src="//cdn.jsdelivr.net/npm/phaser@3.20.0/dist/phaser.js"></script>
9 <script src="game1.js"></script>
10 </body>
11 </html>

game1.js

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


44 TextureAtlas e Spritesheet

1 var config = {
2 type: Phaser.AUTO,
3 width: 800,
4 height: 600,
5 scene: {
6 preload: preload,
7 create: create
8 }
9 }
10 var game = new Phaser.Game(config);
11
12 function preload ()
13 {
14 // sprite sheet
15 this.load.spritesheet('sheet', 'spritesheet.png', {
16 frameWidth: 54, frameHeight: 59 })
17
18 // texture Atlas
19 this.load.atlas('atlas', 'atlas.png', 'atlas.json')
20 }
21
22 function create ()
23 {
24 // criando sprites
25 this.add.sprite(50, 100, 'sheet', 2)
26 this.add.sprite(300, 150, 'atlas', 'btnJogarOut')
27
28 // criando imagens
29 this.add.image(50, 150, 'sheet', 10)
30 this.add.image(300, 300, 'atlas', 'parabens')
31 }

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


45

fig 22

Dê uma olhada no conteúdo dos arquivos, atlas.png, atlas.json e spritesheet.png, e observe


como são e as diferenças entre eles. No decorrer do curso vamos ver bastante esse assunto.

Free Texture Packer


O Free Texture Paer é um soware open source que tem uma interface gráfica muito simples
e intuitiva. Com ele você poderá gerar facilmente seus texture atlas.
Ao abrir o programa temos do lado esquerdo uma área para onde podemos arrastar as figuras
ou adicionar uma pasta inteira.
No centro fica o preview da textura, e do lado direito uma seção de configuração com valores
padrão que não precisam nem de ajustes.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


46 TextureAtlas e Spritesheet

fig 23

Talvez a única configuração que você vai querer fazer é definir a largura máxima do arquivo
PNG que será gerado. Isso pode ser feito na caixa Width que fica bem na metade da seção de
configuração. Neste exemplo estou deixando o tamanho máximo de 512 pixels de largura. Outra
configuração comumente ajustada é a opção de recortar as imagens, tirando as sobras, e a opção
de permitir que o programa rotacione as imagens individualmente para economizar espaço.
No mais, é só você dar uma mexidinha no programa para aprender rapidamente a utilizá-lo.
Você pode baixá-lo em hp://free-tex-paer.com

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


Animação de sprites
Sprites são instâncias da classe Phaser.GameObjects.Sprite, e são os elementos que podem ser
animados na scene. Podemos animar um sprite com base em um spritesheet ou um textureAtlas.
No Phaser as animações são objetos independentes que podem ser atribuídos a qualquer sprite.
Isso significa que uma mesma animação pode ser atribuída a diferentes sprites.
Assim como muitos objetos do Phaser, as animações criadas são identificadas por uma key de
identificação, definida na criação da animação.

Animação com spritesheet


Para criar um sprite animado, usando um spritesheet, temos os seguintes passos.

1. carregar o spritesheet.
2. criar um sprite com uma imagem (textura) qualquer.
3. criar um array com os frames de animação com o método generateFramesNumbers.
4. criar o objeto de configuração da animação
5. criar a animação passando o objeto de configuração
6. executar a animação no sprite criado no passo 2.

A princípio parece algo muito trabalhoso. Na versão 2 do Phaser a configuração de uma animação
era mais simples, porém mais limitada. Vamos ver um exemplo primeiramente bem detalhado,
e logo em seguida o mesmo exemplo com o código mais enxuto.
Para estes exemplos utilizaremos o seguinte spritesheet:

fig 24

Exemplo extenso:
48 Animação de sprites

1 function preload(){
2 this.load.spritesheet('bee', 'bee.png', {
3 frameWidth: 64,
4 frameHeight: 64
5 })
6 }
7 function create() {
8 this.bee = this.add.sprite(100, 100, 'bee', 0)
9 this.frames = this.anims.generateFrameNumbers('bee', {
10 start: 0,
11 end: 7
12 })
13 this.config = {
14 key: 'voando',
15 frames: this.frames,
16 frameRate: 40,
17 repeat: -1
18 }
19 this.anims.create(this.config)
20 this.bee.anims.play('voando')
21 }

Exemplo enxuto:

1 function preload(){
2 this.load.spritesheet('bee', 'bee.png', {
3 frameWidth: 64,
4 frameHeight: 64
5 })
6 }
7 function create() {
8 this.bee = this.add.sprite(100, 100, 'bee', 0)
9 this.anims.create({
10 key: 'voando',
11 frames: this.anims.generateFrameNumbers('bee', {
12 start: 0,
13 end: 7
14 }),
15 frameRate: 40,
16 repeat: -1
17 })
18 this.bee.anims.play('voando')
19 }

Neste segundo exemplo o que fizemos foi amar o método generateFramesNumbers dentro do
método this.anims.create, e já definimos o objeto de configuração também diretamente dentro
do método this.anims.create.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


49

No código fonte você pode explorar estes exemplos.

Animação com TextureAtlas


O que vai mudar aqui é o tipo de recurso carregado e a substituição do método generateFramesNumbers
por generateFramesNames.
Os passos para animar um sprite usando textureAtlas são:

1. carregar o textureAtlas (a imagem e o json).


2. criar um sprite com uma textura qualquer.
3. criar a animação fazendo uso do método generateFrameNames.
4. adicionar a animação do sprite criado.

Vamos ao exemplo:

1 function preload ()
2 {
3 this.load.atlas('creatures', 'creatures.png', 'creatures.json')
4 }
5
6 function create() {
7
8 this.ray = this.add.sprite(200, 200, 'creatures')
9 this.anims.create({
10 key: 'stingray',
11 frames: this.anims.generateFrameNames('creatures', {
12 prefix: 'stingray',
13 end: 23,
14 zeroPad: 4
15 }),
16 repeat: -1
17 })
18
19 this.ray.play('stingray')
20 }

No textureAtlas o peixe stingray usa frames com o nome stingray0000 até stingray0023.
O parâmetro zeropad é a quantidade de zero máximo que aparece na numeração dos nomes.
O textureAtlas é indicado para animações mais complexas enquanto que para animações simples
podemos usar facilmente um spritesheet.
Em seguida temos o textureAtlas utilizado nestes exemplos.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


50 Animação de sprites

fig 25

E aqui temos uma pequena parte do arquivo JSON.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


51

1 {"frames": [
2
3 {
4 "filename": "blueJellyfish0000",
5 "frame": {"x":484,"y":770,"w":64,"h":64},
6 "rotated": false,
7 "trimmed": true,
8 "spriteSourceSize": {"x":0,"y":0,"w":66,"h":66},
9 "sourceSize": {"w":66,"h":66}
10 }
11 ,{
12 "filename": "blueJellyfish0001",
13 "frame": {"x":484,"y":836,"w":63,"h":65},
14 "rotated": false,
15 "trimmed": true,
16 "spriteSourceSize": {"x":1,"y":0,"w":66,"h":66},
17 "sourceSize": {"w":66,"h":66}
18 }
19 ,{
20 "filename": "blueJellyfish0002",
21 "frame": {"x":322,"y":1621,"w":62,"h":65},
22 "rotated": false,
23 "trimmed": true,
24 "spriteSourceSize": {"x":2,"y":0,"w":66,"h":66},
25 "sourceSize": {"w":66,"h":66}
26 }

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


Sons
Tocar um som no Phaser é uma tarefa bem simples. Basicamente precisamos primeiro carregar o
som no preloader e depois utilizá-lo no jogo criando uma instância da classe Phaser.Sound.BaseSound
através do método this.sound.add(key [, config]), onde this é uma referência à scene em
que estamos trabalhando. key é o nome do som carregado no preload, e config é um objeto
de configuração opcional, mas que é muito útil; por isso vamos ver mais detalhadamente os
parâmetros desse objeto:

tabela 1

Observação: O Chrome não permite o autoplay na página. Isso significa que os sons nesse browser
só serão ouvidos quando o usuário clicar ou fizer qualquer ação na página. Isto não é um bug,
mas uma política de privacidade do Chrome.
O método this.sound.add retorna uma instância de Phaser.Sound.BaseSound que disponibiliza,
entre outros, os seguintes métodos:
54 Sons

tabela 2

A seguir temos o código para carregar e tocar um som:

1 var config = {
2 type: Phaser.AUTO,
3 width: 300,
4 height: 300,
5 scene: {
6 preload: preload,
7 create: create
8 }
9 }
10 var game = new Phaser.Game(config)
11 function preload() {
12 this.load.audio('trilha', ['trilinha.mp3', 'trilinha.ogg'])
13 }
14 function create() {
15 this.music = this.sound.play('trilha', { loop: true})
16 this.music.play()
17 }

(lembre-se de que para o som começar a tocar no Chrome você precisa clicar na tela do browser)
No site https://opengameart.org você encontrará muitas trilhas e efeitos sonoros livres para uso.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


Partículas
O Phaser tem um poderoso sistema de partículas que compreende desde emissões mais simples
até bem complexas.
Para emitir de forma simples partículas temos os seguintes passos.

1. carregar a imagem base no método preload().


2. criar um gerenciador de partículas.
3. criar um emissor (emier) a partir do gerenciador criado no passo anterior.
4. configurar os atributos do emissor

Exemplo:

1 var config = {
2 type: Phaser.WEBGL,
3 width: 400,
4 height: 400,
5 backgroundColor: '#000',
6 scene: {
7 preload: preload,
8 create: create
9 }
10 }
11 var game = new Phaser.Game(config);
12 function preload ()
13 {
14 this.load.image('spark', 'blue.png')
15 }
16 function create ()
17 {
18 this.particles = this.add.particles('spark')
19 this.emitter = this.particles.createEmitter()
20
21 this.emitter.setPosition(200, 200);
22 this.emitter.setSpeed(200);
23 this.emitter.setBlendMode(Phaser.BlendModes.ADD);
24 }

O resultado será o seguinte:


56 Partículas

fig 26

O método this.particles.createEmitter retorna uma instância de


Phaser.GameObjects.Particles.ParticleEmitterManager que possui muitos métodos de confi-
guração para a emissão das partículas. No decorrer no curso vamos trabalhar com alguns desses
métodos. Pesquise na documentação do Phaser por
Phaser.GameObjects.Particles.ParticleEmitterManager para ter acesso à lista completa de
métodos de configuração.
Vamos ver alguns desses métodos?

emitParticle( [count] [, x] [, y])

Emite Partículas em uma dada posição, ou na posição atual do emier.


x e y definem a posição na tela, enquanto que count define a quantidade de partículas emitidas.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


57

explode(count, x, y)

Coloca o emissor no modo de explosão (frequency = -1), interrompendo qualquer fluxo de


partículas atual e emitindo todas as partículas (count) de uma vez.

flow(frequency [, count])

Coloca o emissor no modo de fluxo (frequency >= 0) e inicia (ou reinicia) um fluxo de partículas.

forEachAlive(callback, context)

Chama uma função callba para cada partícula ativa neste emissor.

forEachDead(callback, context)

Chama uma função callba para cada partícula inativa neste emissor.

getAliveParticleCount()

Retorna o número de partículas ativas (em uso) do emissor.

getDeadParticleCount()

Retorna o número de partículas inativas (disponíveis) do emissor.

getParticleCount()

Retorna o número total de partículas do emissor.

killAll()

Desativa todas as partículas do emissor.

onParticleDeath(callback [, context])

Define uma função callba a ser amada para cada partícula ‘morta’.

onParticleEmit(callback [, context])

Define uma função callba para cada nova partícula emitida.

setAngle( [degrees])

Define o ângulo da direção da emissão.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


58 Partículas

pause()

Pausa a emissão.

resume()

Volta a emitir.

stop()

Para a emissão.

start()

Se o emissor estiver em modo de fluxo (frequency >= 0), o fluxo de partículas ira iniciar. E se
estiver em modo de explosão, nada acontecerá.
Vamos fazer um outro exemplo mais complexo, utilizando um objeto de configuração para o
emissor de partículas.

1 var config = {
2 type: Phaser.WEBGL,
3 width: 400,
4 height: 400,
5 backgroundColor: '#000',
6 scene: {
7 preload: preload,
8 create: create
9 }
10 }
11 var game = new Phaser.Game(config)
12 function preload() {
13 this.load.image('gude', 'gude.png')
14 }
15 function create() {
16 this.particles = this.add.particles('gude')
17 this.particles.createEmitter({
18 x: 200,
19 y: 200,
20 lifespan: 2000,
21 frequency: 300,
22 speed: {
23 min: 100,
24 max: 100
25 },
26 angle: 330,
27 gravityY: 50,

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


59

28 scale: {
29 start: 1,
30 end: 0.2
31 }
32 })
33 }

O resultado será algo como:

fig 28

Como já dissemos existem ainda muitos outros métodos para controlar a emissão das partículas,
como por exemplo controlar a gravidade, a direção, o ângulo e etc. Veja a documentação do
Phaser para descobrir mais. Não esqueça também de estudar os exemplos que estão disponíveis
no site do Phaser.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


60 Partículas

Um dos exemplos bem interessantes no site é o editor de configuração de partículas, que gera
automaticamente um json de configuração do emier. http://phaser.io/examples/v3/view/game-
objects/particle-emitter/particle-editor

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


Teclado e mouse
O Phaser tem muitos recursos par trabalhar com teclado e mouse. Neste curso não vamos focar
nas funcionalidades básicas para utilizar-mos nos jogos que iremos programar. Mas uma vez
fica a recomendação de que você pesquise os exemplos do Phaser para aprender sobre todos os
recursos de entrada de teclado e mouse.

Teclado

É muito simples capturar uma tecla pressionada com o Phaser.

1 var config = {
2 type: Phaser.AUTO,
3 scene: {
4 create: create
5 }
6 }
7 var game = new Phaser.Game(config)
8 function create() {
9 this.input.keyboard.on('keydown', function(event) {
10 console.dir(event.key)
11 })
12 }

Com este código nós capturamos qualquer tecla pressionada e imprimimos o valor no console
de desenvolvimento do browser.
Mas e se quisermos saber se uma tecla específica foi pressionada dentre outras acionadas simul-
taneamente, precisamos fazer de outra forma. Vamos por exemplo querer saber quais as setas
do teclado estão pressionadas. Neste caso precisaremos “escutar” essas teclas individualmente.
Felizmente o Phaser já traz uma funcionalidade específica para trabalhar com as setas do teclado,
que é amada de “cursor”.
Com o código seguinte imprimiremos no console a identificação das setas do teclado. Este será
um recurso que utilizaremos bastante.
62 Teclado e mouse

1 var config = {
2 type: Phaser.AUTO,
3 scene: {
4 create: create,
5 update: update
6 }
7 }
8 var game = new Phaser.Game(config)
9 function create() {
10 cursors = this.input.keyboard.createCursorKeys()
11 }
12 function update() {
13 if (cursors.left.isDown) {
14 console.log('esquerda')
15 } else if (cursors.right.isDown) {
16 console.log('direita')
17 }
18 if (cursors.up.isDown) {
19 console.log('cima')
20 } else if (cursors.down.isDown) {
21 console.log('baixo')
22 }
23 }

Uma outra forma de capturar o teclado é criando um objeto key para uma tecla específica e
testando o acionamento da mesma no método update ou em um callba. No exemplo a seguir
vemos como isso pode ser feito:

1 var config = {
2 type: Phaser.AUTO,
3 scene: {
4 create: create,
5 update: update
6 }
7 }
8 var game = new Phaser.Game(config)
9 function create() {
10 keyA = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.A)
11 }
12 function update() {
13 if (keyA.isDown) {
14 console.log('A')
15 }
16 }

Uma coisa interessante nesta forma de capturar o teclado é que as teclas são capturadas
independentemente de estarem com o capslook, shi ou tab pressionados.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


63

Observe que devemos passar como parâmetro do método this.input.keyboard.addKey() um


valor de uma constante declarada no código do Phaser. A seguir temos uma relação de todas
essas constantes:

1 Phaser.Input.Keyboard.KeyCodes.BACKSPACE
2 Phaser.Input.Keyboard.KeyCodes.TAB
3 Phaser.Input.Keyboard.KeyCodes.ENTER
4 Phaser.Input.Keyboard.KeyCodes.SHIFT
5 Phaser.Input.Keyboard.KeyCodes.CTRL
6 Phaser.Input.Keyboard.KeyCodes.ALT
7 Phaser.Input.Keyboard.KeyCodes.PAUSE
8 Phaser.Input.Keyboard.KeyCodes.CAPS_LOCK
9 Phaser.Input.Keyboard.KeyCodes.ESC
10 Phaser.Input.Keyboard.KeyCodes.SPACE
11 Phaser.Input.Keyboard.KeyCodes.PAGE_UP
12 Phaser.Input.Keyboard.KeyCodes.PAGE_DOWN
13 Phaser.Input.Keyboard.KeyCodes.END
14 Phaser.Input.Keyboard.KeyCodes.HOME
15 Phaser.Input.Keyboard.KeyCodes.LEFT
16 Phaser.Input.Keyboard.KeyCodes.UP
17 Phaser.Input.Keyboard.KeyCodes.RIGHT
18 Phaser.Input.Keyboard.KeyCodes.DOWN
19 Phaser.Input.Keyboard.KeyCodes.PRINT_SCREEN
20 Phaser.Input.Keyboard.KeyCodes.INSERT
21 Phaser.Input.Keyboard.KeyCodes.DELETE
22 Phaser.Input.Keyboard.KeyCodes.ZERO
23 Phaser.Input.Keyboard.KeyCodes.ONE
24 Phaser.Input.Keyboard.KeyCodes.TWO
25 Phaser.Input.Keyboard.KeyCodes.THREE
26 Phaser.Input.Keyboard.KeyCodes.FOUR
27 Phaser.Input.Keyboard.KeyCodes.FIVE
28 Phaser.Input.Keyboard.KeyCodes.SIX
29 Phaser.Input.Keyboard.KeyCodes.SEVEN
30 Phaser.Input.Keyboard.KeyCodes.EIGHT
31 Phaser.Input.Keyboard.KeyCodes.NINE
32 Phaser.Input.Keyboard.KeyCodes.NUMPAD_ZERO
33 Phaser.Input.Keyboard.KeyCodes.NUMPAD_ONE
34 Phaser.Input.Keyboard.KeyCodes.NUMPAD_TWO
35 Phaser.Input.Keyboard.KeyCodes.NUMPAD_THREE
36 Phaser.Input.Keyboard.KeyCodes.NUMPAD_FOUR
37 Phaser.Input.Keyboard.KeyCodes.NUMPAD_FIVE
38 Phaser.Input.Keyboard.KeyCodes.NUMPAD_SIX
39 Phaser.Input.Keyboard.KeyCodes.NUMPAD_SEVEN
40 Phaser.Input.Keyboard.KeyCodes.NUMPAD_EIGHT
41 Phaser.Input.Keyboard.KeyCodes.NUMPAD_NINE
42 Phaser.Input.Keyboard.KeyCodes.A

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


64 Teclado e mouse

43 Phaser.Input.Keyboard.KeyCodes.B
44 Phaser.Input.Keyboard.KeyCodes.C
45 Phaser.Input.Keyboard.KeyCodes.D
46 Phaser.Input.Keyboard.KeyCodes.E
47 Phaser.Input.Keyboard.KeyCodes.F
48 Phaser.Input.Keyboard.KeyCodes.G
49 Phaser.Input.Keyboard.KeyCodes.H
50 Phaser.Input.Keyboard.KeyCodes.I
51 Phaser.Input.Keyboard.KeyCodes.J
52 Phaser.Input.Keyboard.KeyCodes.K
53 Phaser.Input.Keyboard.KeyCodes.L
54 Phaser.Input.Keyboard.KeyCodes.M
55 Phaser.Input.Keyboard.KeyCodes.N
56 Phaser.Input.Keyboard.KeyCodes.O
57 Phaser.Input.Keyboard.KeyCodes.P
58 Phaser.Input.Keyboard.KeyCodes.Q
59 Phaser.Input.Keyboard.KeyCodes.R
60 Phaser.Input.Keyboard.KeyCodes.S
61 Phaser.Input.Keyboard.KeyCodes.T
62 Phaser.Input.Keyboard.KeyCodes.U
63 Phaser.Input.Keyboard.KeyCodes.V
64 Phaser.Input.Keyboard.KeyCodes.W
65 Phaser.Input.Keyboard.KeyCodes.X
66 Phaser.Input.Keyboard.KeyCodes.Y
67 Phaser.Input.Keyboard.KeyCodes.Z
68 Phaser.Input.Keyboard.KeyCodes.F1
69 Phaser.Input.Keyboard.KeyCodes.F2
70 Phaser.Input.Keyboard.KeyCodes.F3
71 Phaser.Input.Keyboard.KeyCodes.F4
72 Phaser.Input.Keyboard.KeyCodes.F5
73 Phaser.Input.Keyboard.KeyCodes.F6
74 Phaser.Input.Keyboard.KeyCodes.F7
75 Phaser.Input.Keyboard.KeyCodes.F8
76 Phaser.Input.Keyboard.KeyCodes.F9
77 Phaser.Input.Keyboard.KeyCodes.F10
78 Phaser.Input.Keyboard.KeyCodes.F11
79 Phaser.Input.Keyboard.KeyCodes.F12
80 Phaser.Input.Keyboard.KeyCodes.SEMICOLON
81 Phaser.Input.Keyboard.KeyCodes.PLUS
82 Phaser.Input.Keyboard.KeyCodes.COMMA
83 Phaser.Input.Keyboard.KeyCodes.MINUS
84 Phaser.Input.Keyboard.KeyCodes.PERIOD
85 Phaser.Input.Keyboard.KeyCodes.FORWARD_SLASH
86 Phaser.Input.Keyboard.KeyCodes.BACK_SLASH
87 Phaser.Input.Keyboard.KeyCodes.QUOTES
88 Phaser.Input.Keyboard.KeyCodes.BACKTICK

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


65

89 Phaser.Input.Keyboard.KeyCodes.OPEN_BRACKET
90 Phaser.Input.Keyboard.KeyCodes.CLOSED_BRACKET
91 Phaser.Input.Keyboard.KeyCodes.SEMICOLON_FIREFOX
92 Phaser.Input.Keyboard.KeyCodes.COLON
93 Phaser.Input.Keyboard.KeyCodes.COMMA_FIREFOX_WINDOWS
94 Phaser.Input.Keyboard.KeyCodes.COMMA_FIREFOX
95 Phaser.Input.Keyboard.KeyCodes.BRACKET_RIGHT_FIREFOX
96 Phaser.Input.Keyboard.KeyCodes.BRACKET_LEFT_FIREFOX

Mouse
O Phaser tem também muitas funcionalidades para trabalharmos com os eventos do mouse.
Vamos começar com um exemplo bem simples:

1 var config = {
2 scene: {
3 create: create,
4 update: update
5 }
6 }
7 var game = new Phaser.Game(config)
8 function create() {
9 this.pointer = this.input.activePointer
10 this.text1 = this.add.text(10, 10, 'ponto do click:')
11 this.text2 = this.add.text(10, 50, 'distância:')
12 this.text3 = this.add.text(10, 100, 'ângulo em radianos:')
13 this.input.on('pointerdown', (pointer) => {
14 this.text1.setText(`ponto do click: ${pointer.x}, ${pointer.y}`)
15 })
16 }
17 function update() {
18 this.text2.setText(`distância: ${this.pointer.getDistance()}`)
19 this.text3.setText(`ângulo em radianos: ${this.pointer.getAngle()}`)
20 }

Rode este código e em seguida clique e arraste o mouse pela tela.


Primeiro atribuimos a this.pointer a instância da classe Phaser.Input.Pointer. Este objeto
encapsula tanto o mouse como o tou.
Você terá a posição inicial do clique, a distância entre o ponto de arraste e a posição inicial, e
também o ângulo em radianos. Este exemplo funciona tanto para o mouse como para o tou.
Interessante, não?
O Phaser suporta até 10 pontos multitou. Para os jogos que vamos fazer neste curso só
utilizaremos 1 ponto. Nos exemplos do site você vai poder ver como habilitar isso.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


66 Teclado e mouse

Também é possível fazer com que os objetos (sprites, imagens e etc.) fiquem sensíveis a eventos do
mouse. Ou seja, os objetos do jogo podem receber eventos de mouseOver, mouseDonw, mouseUp,
mouseOut e etc.
Vamos criar um exemplo onde colocaremos uma imagem na tela e escutaremos os eventos do
mouse nessa imagem:

1 var config = {
2 scene: {
3 preload: preload,
4 create: create
5 }
6 }
7 var game = new Phaser.Game(config)
8
9 function preload() {
10 this.load.image('rato', 'mouse.png')
11 }
12
13 function create() {
14 this.rato = this.add.image(400, 300, 'rato')
15 this.rato.setInteractive()
16 this.rato.on('pointerover', () => this.rato.setTint(0xff0000))
17 this.rato.on('pointerdown', () => this.rato.setTint(0x00ff00))
18 this.rato.on('pointerup', () => this.rato.setTint(0x0000ff))
19 this.rato.on('pointerout', () => this.rato.clearTint())
20 }

Para tornar um objeto interativo com o mouse devemos executar o método setInteractive(true)
e para desabilitar a interatividade setInteractive(false). O valor padrão do método é true.
Também podemos capturar eventos da “rodinha” do mouse…

1 var config = {
2 scene: {
3 create: create
4 }
5 }
6 var game = new Phaser.Game(config)
7 function create() {
8 this.y = 0
9 this.texto = this.add.text(10, 10, '0', {
10 font: '28px Courier',
11 fill: '#00ff00'
12 })
13 this.input.on('wheel', (pointer, gameObjects, deltaX, deltaY, deltaZ) => {
14 this.texto.setText(this.y += deltaY / 100)

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


67

15 })
16 }

Nos exemplo do site você encontrará muitas outras possibilidades.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


Botões
Até a versão 2 do Phaser havia uma classe específica para criar botões no jogo. A partir do Phaser3
essa classe deixou de existir, até mesmo porque é muito fácil implementarmos nossos próprios
botões utilizando os eventos do mouse.
Neste capítulo vamos fazer exatamente isto. Vamos lá?
Faremos o seguinte:

1. criar a classe ImageBuon extendendo de Phaser.GameObjects.Image.


2. instanciar 2 botões a partir de spritesheets diferentes, para um botão redondo e para outro
botão retangular.

Primeiro vamos escrever nosso arquivo index.html, porque acrescentaremos um detalhe que não
tínhamos usado até agora, o atributo type="module" na tag script.
index.html

1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>Phaser3</title>
6 </head>
7 <body>
8 <script src="//cdn.jsdelivr.net/npm/phaser@3.20.0/dist/phaser.js"></script>
9 <script type="module" src="game1.js"></script>
10 </body>
11 </html>

Com esse atributo com o uso de type="module" poderemos trabalhar diretamente com módulos
no javascript. Atualmente a grande maioria dos browsers dão suporte a essa forma de trabalho
modular.
Vamos agora ver como fica a classe do nosso componente “ImageBuon”:
ImageBuon.js
70 Botões

1 class ImageButton extends Phaser.GameObjects.Image {


2 constructor(scene, x, y, texture) {
3 super(scene, x, y, texture, 0)
4 scene.add.existing(this)
5 this.setInteractive()
6 this.on('pointerover', () => this.setFrame(1))
7 this.on('pointerout', () => this.setFrame(0))
8 this.on('pointerdown', () => this.setFrame(2))
9 this.on('pointerup', () => {
10 this.setFrame(0)
11 this.emit('click')
12 })
13 }
14 }
15 export default ImageButton

Vamos analisar linha por linha.


Na linha 1 estamos declarando nossa classe ImageButton que herda de Phaser.GameObjects.Image
Na segunda linha amamos o constructor que recebe a scene, a posição x e y do botão e o
spritesheet a ser utilizado.
Na linha 3 amamos o constructor da super classe (classe pai), passando os parâmetros para
inicializá-la, por meio do método super. Esse passo é obrigatório, ou seja: toda vez que herdamos
de algo precisaremos amar o método super passando os parâmetros que a classe pai exige.
Na linha 4 adicionamos o nosso botão (referenciado por this) na nossa scene com o método
scene.add.existing(this).

Na linha 5 amamos o método setInteractive() para habilitar a escuta dos eventos do mouse
em nosso botão.
Nas linha de 6 a 9 definimos que frame do spritesheet será utilizado em cada estado do mouse.
Iremos padronizar que os spritesheets dos botões terão 3 frames. Um para o estado normal,
outro para o estado pointerover, e outro para o estado pointerdown. Para o estado pointerup
utilizaremos o mesmo frame do estado pointerup.
Na linha 11 disparamos o evento personalizado click para podermos ‘escutá-lo’ no game [todos
os objetos do Phaser podem emitir eventos por meio do método on(event, fn [, context])].
Na última linha exportamos nossa classe como um módulo.
Vamos agora ao código do game1.js

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


71

1 import ImageButton from './ImageButton.js'


2 var config = {
3 type: Phaser.AUTO,
4 scene: {
5 preload: preload,
6 create: create
7 }
8 }
9 var game = new Phaser.Game(config)
10 function preload() {
11 this.load.spritesheet('botao', 'botao.png', {
12 frameWidth: 80,
13 frameHeight: 80
14 })
15 this.load.spritesheet('btnIniciar', 'botao2.png', {
16 frameWidth: 100,
17 frameHeight: 34
18 })
19 }
20 function create() {
21 this.botao = new ImageButton(this, 100, 100, 'botao')
22 this.botao.on('click', () => console.log('click botão'))
23
24 this.btnIniciar = new ImageButton(this, 100, 200, 'btnIniciar')
25 this.btnIniciar.on('click', () => console.log('click botão iniciar'))
26 }

Na linha 1 importamos a classe ImageBuon.


Na linha 11 carregamos o primeiro spritesheet (botao.png)
Na linha 15 carregamos o segundo spritesheet (botao2.png)
Na linha 21 criamos uma instância da nossa classe ImageButton passando como parâmetros a
scene, a posição x e y, e a referência ao spritesheet ‘botao’.
Na linha 22 definimos a escuta do evento click axecuntando a função de callba que irá apenas
imprimir uma mensagem no console do browser.
Nas linha 24 e 25 fazemos um segundo botão, só que desta vez utilizando o spritesheet ‘btnIniciar’.
Aqui temos a figura dos 2 spritesheets utilizados neste exemplo:

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


72 Botões

fig 28

fig 29

Acabamos de desenvolver nosso botão personalizável com o Phaser. Fizemos o botão com
imagens, mas é possível fazer outros botões que trabalhem com texto simples e bitmapfontes.
Iremos voltar a falar de botões quando estivermos desenvolvendo os jogos deste curso.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


Tween
Tween é uma funcionalidade que permite criar “movimentos” para alterar dinamicamente as
propriedades dos objetos. Existem várias equações que definem o comportamento do tween,
onde cada uma delas descreve um padrão de movimento.
As equações disponíveis são:
Linear
ad.easeIn, Cubic.easeIn, art.easeIn, int.easeIn, Sine.easeIn, Expo.easeIn, Circ.easeIn,
Elastic.easeIn, Ba.easeIn, Bounce.easeIn, ad.easeOut, Cubic.easeOut, art.easeOut, int.easeOut,
Sine.easeOut, Expo.easeOut, Circ.easeOut, Elastic.easeOut, Ba.easeOut, Bounce.easeOut, ad.easeInOut,
Cubic.easeInOut, art.easeInOut, int.easeInOut, Sine.easeInOut, Expo.easeInOut, Circ.easeInOut,
Elastic.easeInOut, Ba.easeInOut, Bounce.easeInOut
Observe este exemplo:

1 var config = {
2 scene: {
3 preload: preload,
4 create: create
5 }
6 }
7 var game = new Phaser.Game(config)
8 function preload() {
9 this.load.spritesheet('peixes', 'spritesheet_peixes.png', {
10 frameWidth: 136,
11 frameHeight: 80
12 })
13 }
14 function create() {
15 var amarelo = this.add.image(0, 80, 'peixes', 0)
16 var verde = this.add.image(250, 80, 'peixes', 1)
17 var rosa = this.add.image(400, 80, 'peixes', 2)
18 //tween do peixe amarelo
19 this.tweens.add({
20 targets: amarelo,
21 props: {
22 x: {
23 value: 700,
24 duration: 4000,
25 flipX: true
26 }
27 },
74 Tween

28 ease: 'Sine.easeInOut',
29 yoyo: true,
30 repeat: -1
31 })
32 //tween do peixe verde
33 this.tweens.add({
34 targets: verde,
35 props: {
36 y: {
37 value: 500,
38 duration: 4000
39 }
40 },
41 ease: 'Sine.easeInOut',
42 yoyo: true,
43 repeat: -1
44 })
45 //tween do peixe rosa
46 this.tweens.add({
47 targets: rosa,
48 props: {
49 x: {
50 value: 700,
51 duration: 4000,
52 flipX: true
53 },
54 y: {
55 value: 500,
56 duration: 4000
57 },
58 scale: {
59 value: 2,
60 duration: 4000
61 }
62 },
63 ease: 'Sine.easeInOut',
64 yoyo: true,
65 repeat: -1
66 })
67 }

No peixe amarelo estamos alterando o propriedade x, no verde apenas a propriedade y e no rosa


estamos alterando x, y e scale. Em todos os tweens estamos utilizando a equação Sine.easeInOut.
Experimente trocar por outras equações para observar a mudança do comportamento. Para ver
outros exemplos visite a documentação e os exemplos no site do Phaser.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


Timeline
Timeline é um funcionalidade que permite que apliquemos vários tweens consecutivos em um
objeto.
Vamos ao exemplo:

1 var config = {
2 scene: {
3 preload: preload,
4 create: create
5 }
6 }
7
8 var game = new Phaser.Game(config)
9
10 function preload() {
11
12 this.load.spritesheet('peixes', 'spritesheet_peixes.png', {
13 frameWidth: 136,
14 frameHeight: 80
15 })
16 }
17
18 function create() {
19 var amarelo = this.add.image(0, 80, 'peixes', 0)
20 var timeline = this.tweens.createTimeline()
21 //tween em x
22 timeline.add({
23 targets: amarelo,
24 props: {x: 600},
25 ease: 'Linear',
26 duration: 3000
27 })
28 //tween em y
29 timeline.add({
30 targets: amarelo,
31 props: {y: 500},
32 ease: 'Linear',
33 duration: 3000
34 })
35 //tween em x
36 timeline.add({
76 Timeline

37 targets: amarelo,
38 props: {x: 100},
39 ease: 'Linear',
40 duration: 3000
41 })
42 //tween em y
43 timeline.add({
44 targets: amarelo,
45 props: {y: 100},
46 ease: 'Linear',
47 duration: 3000
48 })
49
50 timeline.play();
51 }

Também podemos criar timelines nas outras propriedades…

1 var config = {
2 scene: {
3 preload: preload,
4 create: create
5 }
6 }
7 var game = new Phaser.Game(config)
8 function preload() {
9 this.load.spritesheet('peixes', 'spritesheet_peixes.png', {
10 frameWidth: 136,
11 frameHeight: 80
12 })
13 }
14 function create() {
15 var verde = this.add.image(0, 200, 'peixes', 1)
16 var timeline = this.tweens.createTimeline()
17 //tween em x
18 timeline.add({
19 targets: verde,
20 props: {
21 x: 600
22 },
23 ease: 'Elastic.easeOut',
24 duration: 3000
25 })
26 //tween em scale
27 timeline.add({
28 targets: verde,

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


77

29 props: {
30 scale: 2
31 },
32 ease: 'Linear',
33 duration: 3000
34 })
35 //tween em rotation
36 timeline.add({
37 targets: verde,
38 props: {
39 rotation: 3
40 },
41 ease: 'Linear',
42 duration: 3000
43 })
44 timeline.play();
45 }

Observe que no primeiro tween utilizamos a equação Elastic.easeOut, o que causou um


comportamento de elástico.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


Path e follower
No Phaser podemos fazer com que sprites percorram um caminho pré-traçado. Isso é feito
criando-se o caminho path e um sprite especial que é uma instância da classe
Phaser.GameObjects.PathFollower. Um PathFollower é um sprite que possui funcionalidades
adicionais para atuar como Follower (seguidor). Tudo que podemos fazer com um sprite comum
podemos também aplicar a um sprite do tipo Follower.
A forma mais comum de instanciar a um PathFollower é usando o método this.add.follower(path,
x, y, texture [, frame]), onde this referencia a scene em que estamos trabalhando.

Vamos ver como fazer com que um sprite follower percorra um caminho?

1 var config = {
2 scene: {
3 preload: preload,
4 create: create
5 }
6 }
7 var game = new Phaser.Game(config)
8 function preload() {
9 //Carrega o spritesheet dos peixes
10 this.load.spritesheet('peixes', 'spritesheet_peixes.png', {
11 frameWidth: 136,
12 frameHeight: 80
13 })
14 }
15 function create() {
16 //cria um path com 4 vértices (cantos)
17 this.path = new Phaser.Curves.Path(50, 50).lineTo(500, 50).lineTo(500, 300).lin\
18 eTo(50, 300)
19 //pinta o path para que fique visível (isto é opcional)
20 this.graphics = this.add.graphics()
21 this.graphics.lineStyle(1, 0xffffff, 1)
22 this.path.draw(this.graphics, 128)
23 //instancia o sprite follower, definindo o path a ser seguido
24 this.peixe = this.add.follower(this.path, 0, 0, 'peixes', 0);
25 //inicializa o movimento do follower no path
26 this.peixe.startFollow({
27 positionOnPath: true,
28 duration: 3000,
29 yoyo: true,
30 repeat: -1,
31 rotateToPath: true,
80 Path e follower

32 verticalAdjust: true
33 })
34 }

Neste exemplos usamos o método lineTo para criar um path formado por linhas retas, mas
também podemos traçar curvas como no próximo exemplo:

1 var config = {
2 scene: {
3 preload: preload,
4 create: create
5 }
6 }
7 var game = new Phaser.Game(config)
8 function preload() {
9 //Carrega o spritesheet dos peixes
10 this.load.spritesheet('peixes', 'spritesheet_peixes.png', {
11 frameWidth: 136,
12 frameHeight: 80
13 })
14 }
15 function create() {
16 //cria um path com curvas
17 this.path = new Phaser.Curves.Path(50, 100).splineTo([ 164, 46, 274, 142, 412, \
18 57, 522, 141, 664, 64 ])
19 //pinta o path para que fique visível (isto é opcional)
20 this.graphics = this.add.graphics()
21 this.graphics.lineStyle(1, 0xffffff, 1)
22 this.path.draw(this.graphics, 128)
23 //instancia o sprite follower, definindo o path a ser seguido
24 this.peixe = this.add.follower(this.path, 0, 0, 'peixes', 0);
25 //inicializa o movimento do follower no path
26 this.peixe.startFollow({
27 positionOnPath: true,
28 duration: 3000,
29 yoyo: true,
30 repeat: -1,
31 rotateToPath: true,
32 verticalAdjust: true
33 })
34 }

O método splineTo é responsável por criar uma curva, a partir dos vértices passados num
array. Este array contém as coordenadas x e y de cada vértice pretendido seguindo a seguinte
convenção:
“spliteTo([x1, y1, x2, y2, x3, y3, … xn, yn])

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


Configuração do Phaser
Até agora já criamos muitos exemplos com o Phaser, e em todos eles formatamos um objeto de
configuração que é passado na criação do objeto da classe Phaser.Game. Neste capítulo vamos
estudar mais a fundo este objeto de configuração.
Aqui está a relação completa das propriedades que um objeto de configuração do Phaser pode
ter:
82 Configuração do Phaser

tabela 3-a

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


83

tabela 3-b

A maioria das propriedades desse objeto de configuração são auto-descritivas, mas você pode
consultar a documentação do Phaser para saber mais.
Agora vamos estudar mas detalhadamente a propriedade scale.
O objeto de configuração dessa propriedade tem o seguinte conteúdo:

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


84 Configuração do Phaser

tabela 4

Neste último objeto temos a propriedade mode que define diretamente o modo como o game será
escalonado. Vejamos os valores possíveis:

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


85

tabela 5

Veremos na prática algumas dessas configurações quando desenvolvermos os jogos do curso.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


Física no Phaser
O Phaser suporta 3 sistemas de física: Arcade, Impact e Maer.
O Arcade é um sistema de física bem leve o que o torna perfeito para economizar os recursos do
dispositivo mas que ao mesmo tempo permite fazer muita coisa com uma física mais simples.
O Impact é um sistema de física mais avançado que permite trabalharmos com física em tilemaps.
Já o Maer é um sistema de física muito completo com muitas funcionalidades avançadas tais
como molas, constraints e sistema avançado de física em polígonos.
No escopo deste curso vamos trabalhar apenas com o sistema Arcade por ser o mais simples e
atender perfeitamente a todo desenvolvimento que faremos. Mas, como sempre, no site do Phaser
você vai encontrar centenas de exemplos de como trabalhar com o Impact e o Maer.

Habilitando a física
Para habilitar um sistema de física no Phaser precisamos adicioná-lo no objeto de configuração,
como no exemplo seguinte:

1 var config = {
2 width: 800,
3 height: 600,
4 physics: {
5 default: 'arcade',
6 arcade: {
7 gravity: {
8 y: 100
9 },
10 debug: true
11 }
12 },
13 scene: {
14 preload: preload,
15 create: create
16 }
17 }

Na linha 5 definimos o sistema de física padrão para utilizar o Arcade (O Phaser permite utilizar
mais de um sistema de física ao mesmo tempo).
Nas linhas 7 e 8 definimos um valor para a gravidade do eixo Y.
Na linha 10 acionamos o debug da física, que serve para mostrar na tela os contornos dos corpos
físicos dos objetos.
88 Física no Phaser

Movimento
A primeira coisa que podemos fazer usando a física é mover objetos atribuindo uma velocidade
nos seus eixos X e Y. O sentido do movimento em relação às velocidades aplicadas nos eixos são:

velocidade deslocamento
X<0 esquerda
X=0 sem movimento horizontal
X>0 direita
Y<0 para cima
Y=0 sem movimento vertical
Y>0 para baixo

No próximo exemplo iremos controlar o movimento de uma imagem aplicando uma velocidade
aos eixos X e Y dependendo da seta do teclado pressionada. Vamos lá?
O nosso index.html vai ser o de sempre…

1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 <title>Phaser</title>
7 </head>
8 <body>
9 <script src="//cdn.jsdelivr.net/npm/phaser@3.20.0/dist/phaser.js"></script>
10 <script src="game1.js"></script>
11 </body>
12 </html>

Agora o game1.js

1 var config = {
2 physics: {
3 default: 'arcade',
4 arcade: {
5 debug: true
6 }
7 },
8 scene: {
9 preload: preload,
10 create: create,
11 update: update
12 }
13 }
14 var game = new Phaser.Game(config)

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


89

15 function preload() {
16 this.load.image('ball', 'ball.png')
17 this.load.image('block', 'block.png')
18 }
19 function create() {
20 this.bola = this.physics.add.image(100, 100, 'ball')
21 this.cursors = this.input.keyboard.createCursorKeys()
22 }
23 function update() {
24 this.bola.setVelocity(0)
25 if (this.cursors.left.isDown) {
26 this.bola.setVelocityX(-100)
27 } else if (this.cursors.right.isDown) {
28 this.bola.setVelocityX(100)
29 }
30 if (this.cursors.up.isDown) {
31 this.bola.setVelocityY(-100)
32 } else if (this.cursors.down.isDown) {
33 this.bola.setVelocityY(100)
34 }
35 }

Agora podemos movimentar a bola acionando as setas do teclado. O resultado visual é…

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


90 Física no Phaser

fig 30a

A caixa vermelha em volta da bola é o corpo da física, e o traço verde indica a direção
da velocidade. Isto está aparecendo porque nós habilitamos o debug da física no objeto de
configuração do Phaser.
Vamos analisar o código em game1.js:
Na linha 19 nós criamos uma imagem com um corpo físico com o método this.physics.add.image.
A imagem criada dessa forma tem as mesmas funcionalidades que uma imagem comum, mas
a diferença é que agora ela tem um corpo físico que pode interagir com outros corpos e com o
‘mundo’ físico.
Na linha 20 nós criamos o objeto cursors para podermos ler o acionamentos das setas do teclado.
Na linha 23, no método update(), primeiramente zeramos as velocidades vertical (Y) e horizontal
(X) da bola.
Na linha 25 definimos a velocidade X como -100, caso a seta esquerda esteja acionada.
Na linha 27 definimos a velocidade X como 100 positivo, caso a seta direita esteja acionada.
Nas próximas linhas fazemos o mesmo para a velocidade no eixo Y.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


91

Detecção de colisões

Colisão entre objeto e mundo


O sistema Arcade tem a funcionalidade de detecção de colisões entre objetos e mundo, entre
objetos e objetos, entre objetos e grupos, e entre grupos. Vamos primeiro ver como trabalhar
com colisão de objetos com o mundo físico.
Para um objeto colidir com o mundo precisamos amar o método setCollideWorldBounds(true).
O valor padrão para esse método é true, mas para desabilitar a colisão com o mundo, utilize false.
Vamos então adicionar essa linha no método create():

1 function create() {
2 this.bola = this.physics.add.image(100, 100, 'ball')
3 // habilita colisão da bola com o mundo
4 this.bola.setCollideWorldBounds()
5 this.cursors = this.input.keyboard.createCursorKeys()
6 }

Muito bem. Agora a bola não ultrapassa os limites do mundo.


Vamos acrescentar mais 2 linhas para capturarmos o evento da bola tocar nas bordas do mundo?

1 function create() {
2 this.bola = this.physics.add.image(100, 100, 'ball')
3 // habilita colisão da bola com o mundo
4 this.bola.setCollideWorldBounds()
5 // habilita o disparo do evento de colisão da bola com o mundo
6 this.bola.body.onWorldBounds = true
7 // checa se houve colisão de algum objeto com o mundo
8 this.physics.world.on('worldbounds', (body) => console.log(body))
9 this.cursors = this.input.keyboard.createCursorKeys()
10 }

Colisão entre objetos


Agora vamos criar outra bola no método create() e fazer com que colidam.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


92 Física no Phaser

1 function create() {
2 this.bola = this.physics.add.image(100, 100, 'ball')
3 this.bola2 = this.physics.add.image(200, 200, 'ball')
4 // habilita colisão da bola com o mundo
5 this.bola.setCollideWorldBounds()
6 this.bola2.setCollideWorldBounds()
7 // habilita o disparo do evento de colisão da cola com o mundo
8 this.bola.body.onWorldBounds = true
9 this.bola2.body.onWorldBounds = true
10 // define que a bola2 vai `recochetear`
11 this.bola2.body.setBounce(1, 1)
12 // habilita colisão entre as bolas e checa quando colidem
13 this.physics.add.collider(this.bola, this.bola2, (a, b) => console.log(`${a} co\
14 lide com ${b}`))
15 this.cursors = this.input.keyboard.createCursorKeys()
16 }

A próxima tarefa é criar um grupo de imagens e fazer com que colida com a bola.
A seguir temos o método create() atualizado com essa tarefa:

1 function create() {
2 // cria bola
3 this.bola = this.physics.add.image(100, 100, 'ball')
4 // habilita colisão da bola com o mundo
5 this.bola.setCollideWorldBounds()
6 // cria grupo de física passando um objeto de configuração.
7 this.group = this.physics.add.group({
8 bounceX: 1,
9 bounceY: 1,
10 collideWorldBounds: true
11 })
12 // cria 6 caixas e adiciona ao grupo de física.
13 for (let i = 1; i < 7; i++) {
14 let block = this.add.image(i * 150, 250, 'block')
15 this.group.add(block)
16 }
17 // habilita colisão entre a bola e o grupo.
18 this.physics.add.collider(this.bola, this.group, (a, b) => console.log(`${a} co\
19 lisão com ${b}`))
20 this.cursors = this.input.keyboard.createCursorKeys()
21 }

Se você prestar atenção, vai perceber que a bola colide com as caixas mas as caixas não colidem
entre si.
Para habilitar a colisão entre as caixas precisamos habilitar a colisão do grupo com ele mesmo:

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


93

1 function create() {
2 // cria bola
3 this.bola = this.physics.add.image(100, 100, 'ball')
4 // habilita colisão da bola com o mundo
5 this.bola.setCollideWorldBounds()
6 // cria grupo de física passando um objeto de configuração.
7 this.group = this.physics.add.group({
8 bounceX: 1,
9 bounceY: 1,
10 collideWorldBounds: true
11 })
12 // cria 6 caixas e adiciona ao grupo de física.
13 for (let i = 1; i < 7; i++) {
14 let block = this.add.image(i * 150, 250, 'block')
15 this.group.add(block)
16 }
17 // habilita colisão entre a bola e o grupo.
18 this.physics.add.collider(this.bola, this.group, (a, b) => console.log(`${a} co\
19 lisão com ${b}`))
20 this.physics.add.collider(this.group, this.group, (a, b) => console.log(`${a} c\
21 olisão com ${b}`))
22 this.cursors = this.input.keyboard.createCursorKeys()
23 }

Dimensões do corpo físico.


Por padrão o tamanho (size) do corpo físico é o tamanho da imagem ou objeto, mas as vezes
vamos querer ajustar esse tamanho. Por exemplo quando temos uma personagem e queremos
que a colisão com os objetos ocorra só na altura dos pés.
Esse redimensionamento é feito com 2 métodos: body.setSize(largura, altura) e body.setOffset(x,
y). Trabalhando com esse métodos podemos ajudar a posição e o tamanho do corpo físico de
qualquer objeto.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


94 Física no Phaser

fig 30b

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


Tilemap
Tilemap é uma técnica para criar um mundo para jogo a partir de blocos de construção modulares.
O objetivo principal é economizar memória, melhorar o desempenho mesmo com um mundo
bem grande e, além de tudo é uma forma muito divertida e criativa de criar o mundo para o
nosso game.
Cada tile (ladrilho) faz parte de uma imagem maior, o tileset. A seguir temos um exemplo de
tileset.
96 Tilemap

tileset

Em seguida temos uma tilemap construido a partir desse tileset.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


97

tilemap - mundo

É importante observar que esta imagem final é construída dentro do Phaser em tempo de
execução.
Para montar o tilemap o Phaser precisa de 2 arquivos: uma imagem (geralmente um png com
fundo transparente) e um JSON com o mapeamento do tilemap.

Tiled
Para gerar o mapa JSON a partir de um tileset, utilizaremos um aplicativo open source muito
conhecido entre os desenvolvedores de games que é o Tiled, disponível para Windows, Mac e
Linux.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


98 Tilemap

Tiled

A instalação é simples e corrigueira, e está disponível em https://www.mapeditor.org


Então, para continuarmos, baixe e instale o Tiled na sua máquina.

Construção de um autódromo
Como nosso primeiro trabalho com o Tiled vamos construir um autódromo bem simples a partir
do seguinte tileset:

fig 32

O resultado será um tilemap como a figura a seguir. Você não precisa fazer exatamente igual, use
a sua criatividade.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


99

fig 33

Temos aqui um passo a passo para a criação do tilemap, mas você pode também acessar esse
mesmo tutorial em vídeo no Youtube em
https://youtu.be/yh-7Xrnlf2k.

Passo a Passo
Abrir o Tiled e criar um novo mapa:

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


100 Tilemap

fig 34

Configurar tamanho do mapa com 16 x 12 tiles.


fig 35

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


101

fig 35

Salvar como autodromo.tmx.


fig 36

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


102 Tilemap

fig 36

Clicar no botão “Novo Tileset…” e abrir a imagem tiles-rua-02.png (esta imagem está na pasta
assets no código fonte baixado).

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


103

fig 37

No primeiro parâmetro Nome: devemos colocar um nome pelo qual o tileset vai ser identificado
no Phaser. No nosso caso vamos deixar como tiles-rua-02‘ mesmo.
Em seguida configurar o tileset: Largura e altura = 100px, Margem e Espaçamento = 0px.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


104 Tilemap

fig 38

Criar 3 camadas (layers) de tiles: pista, arbusto e terreno (nesta ordem).


[Obs. podemos nos referir a camadas com a nomeclatura na língua inglesa “layers”]

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


105

fig 39

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


106 Tilemap

Selecionar a camada pista e desenhar a pista.

fig 40

Selecionar a camada arbusto e desenhar os arbustos.

fig 41

Selecionar a camada terreno e desenha o terreno.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


107

fig 42

Exportar o map como autodromo.json (este é o JSON que vamos importar no Phaser)

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


108 Tilemap

fig 43

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


109

fig 44

Salvar o Tiled como autodromo.tmx.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


110 Tilemap

fig 45

Para ver o resultado abra no seu editor de texto o arquivo autodromo.json que acabamos de criar.

Usando o Tilemap
Vamos agora aprender como importar o tilemap para dentro do Phaser.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


111

1 var config = {
2 width: 800,
3 height: 600,
4 scene: {
5 preload: preload,
6 create: create
7 }
8 }
9 var game = new Phaser.Game(config)
10 function preload() {
11 // carrega o JSON
12 this.load.tilemapTiledJSON('map', 'autodromo.json')
13 // carrega o tileset
14 this.load.image('tiles', 'tiles-rua-02.png')
15 }
16 function create() {
17 // cria o tilemap
18 var map = this.make.tilemap({key: 'map'})
19 // cria o tileset onde o primeiro parâmetro é o nome do
20 // mapa definido no Tiled.
21 var tileset = map.addTilesetImage('tiles-rua-02', 'tiles')
22 // cria o layer do terreno
23 var terreno = map.createStaticLayer('terreno', tileset, 0, 0)
24 // cria o layer do arbusto
25 var arbusto = map.createStaticLayer('arbusto', tileset, 0, 0)
26 // cria o layer da pista
27 var pista = map.createStaticLayer('pista', tileset, 0, 0)
28 // reduz escala dos layers para o tamanho da tela
29 terreno.setScale(0.5)
30 arbusto.setScale(0.5)
31 pista.setScale(0.5)
32 }

Na linha 12 carregamos o tilemap.json gerado pelo Tiled.


Na linha 14 carregamos a imagem do tileset.
Na linha 18 criamos o mapa.
Na linha 21 criamos o tileset adicionando a imagem ao mapa. O primeiro parâmetro é o nome
do mapa que foi definido no Tiled, e o segundo é o key da imagem que carregamos na linha 14.
Nas linha 23 a 27 criamos os layers. Observe na ordem em que estão os layers. No Phaser nós
podemos configura a profundidade de cada layer, mas nesse exemplo vamos deixá-los já nas
devidas profundidades.
Nas linha de 29 a 31 ajustamos a escala dos layers para caber na tela que definimos no objeto de
configuração do game.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


112 Tilemap

Layer de objetos
Podemos ter no tilemap um layer para marcar posição de objetos no mapa. No próximo exemplo
iremos criar um layer de objetos no Tiled e exportar novamente o JSON. Então usaremos a
camada de objetos do novo mapa para posicionar algumas joias no mundo. Você pode também
assistir o vídeo sobre como criar layers de objetos em https://youtu.be/NgoEUH_FWvA
Primeiro criamos uma camada de objetos:

fig 46

Chamamos essa camada de joia e a arrastamos para o topo das camadas, acima de pista. Para
o Phaser, não importa em que nível esteja a camada de objetos, mas para nossa visualização no
Tiled, deixamos acima das outras.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


113

fig 47

Agora na barra de ferramentas selecionamos Insert Point.

fig 48

Selecionamos a camada de objetos na lista de camadas e já podemos marcar pontos onde ficarão
os objetos.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


114 Tilemap

fig 49

Crie vários pontos de objetos sobre o terreno. Em cada ponto marcado iremos colocar um sprite
de moeda no Phaser.
Faça algo do tipo…

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


115

fig 50

Agora exporte novamente o mapa JSON.

Colocando moedas nas posições de objetos do mapa


Para colocar as moedas no mapa precisamos fazer o seguinte:

1. Carregar o spritesheet da moeda.


2. Criar a animação da moeda girando.
3. Carregar todos os objetos da camada ‘joia’ num array.
4. Iterar sobre esse array criando uma moeda para cada objeto com os valores x e y tirados do
objeto.
5. Dentro do laço for criar cada moeda e rodar a animação.

A seguir temos o código completo:


game2.js

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


116 Tilemap

1 var config = {
2 width: 800,
3 height: 600,
4 scene: {
5 preload: preload,
6 create: create
7 }
8 }
9 var game = new Phaser.Game(config)
10 function preload() {
11 // carrega o JSON
12 this.load.tilemapTiledJSON('map', 'autodromo.json')
13 // carrega o tileset
14 this.load.image('tiles', 'tiles-rua-02.png')
15 //carrega spritesheet das moedas (coins)
16 this.load.spritesheet('moedas', 'moedas.png', {
17 frameWidth: 16,
18 frameHeight: 16
19 })
20 }
21 function create() {
22 // cria o tilemap
23 var map = this.make.tilemap({
24 key: 'map'
25 })
26 // cria animação da moeda girando
27 this.anims.create({
28 key: 'moeda-girando',
29 frames: this.anims.generateFrameNumbers('moedas', {
30 start: 0,
31 end: 7
32 }),
33 frameRate: 10,
34 repeat: -1
35 })
36 // cria o tileset onde o primeiro parâmetro é o nome do
37 // mapa definido no Tiled.
38 var tileset = map.addTilesetImage('tiles-rua-02', 'tiles')
39 // cria o layer do terreno
40 var terreno = map.createStaticLayer('terreno', tileset, 0, 0)
41 // cria o layer do arbusto
42 var arbusto = map.createStaticLayer('arbusto', tileset, 0, 0)
43 // cria o layer da pista
44 var pista = map.createStaticLayer('pista', tileset, 0, 0)
45 /* cria moedas nos pontos da camada 'joia' */
46 // pega array de objetos da camada 'joia'

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


117

47 var objetos = map.getObjectLayer('joia').objects


48 // laço para pegar todos os objetos do array
49 for (let i = 0; i < objetos.length; i++) {
50 // cria sprite 'moeda' com a posição do objeto
51 // os valores de x e y estão divididos por 2 para reduzir a escala
52 // conforme estamos fazendo com as camadas
53 let moeda = this.add.sprite(objetos[i].x / 2, objetos[i].y / 2, 'moedas')
54 // roda animação na moeda
55 moeda.anims.play('moeda-girando')
56 }
57 // reduz escala dos layers para o tamanho da tela
58 terreno.setScale(0.5)
59 arbusto.setScale(0.5)
60 pista.setScale(0.5)
61 }

Na linha 16 carregamos o spritesheet da moeda. Na linha 27 criamos a animação com base no


spritesheet. Na linha 47 lemos todos os objetos do layer joia para dentro do array objetos. Na
linha 49 criamos o laço for para iterar sobre todos os elementos do array. Na linha 53 criamos
o sprite da moeda, com a posição x e y do objeto iterado. Na linha 55 adicionamos e rodamos a
animação na moeda recém criada.
O resultado será algo como…

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


118 Tilemap

fig 51

Tiles de colisão
Num mapa de jogo sempre temos elementos de colisão, tais como paredes, ão, objetos e etc.
Para fazer isso no Phaser usaremos uma técnica de marcar tiles de colisão no mapa.
A ideia é criar uma propriedade booleana personalizada no tileset (por exemplo “colisao”) e
marcar alguns tiles específicos com o valor de colisão = true. Feito isso podemos, dentro do
Phaser, fazer com que objetos do jogo colidam com esses tiles marcados.
Vamos ao passo a passo:
[Um vídeo tutorial está disponível em https://youtu.be/jiVNp0V-m5Y]
Clique no botão Editar Tileset.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


119

fig 52

Selecione todos os tiles.

fig 53

Clique no botão Adicionar propriedade.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


120 Tilemap

fig 54

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


121

Crie uma propriedade amada ‘colisao’, do tipo bool.

fig 55

Agora selecione só os tiles de grama e de terra. E marque a propriedade “colisão” como true no
ebox da propriedade.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


122 Tilemap

fig 56

Salve o arquivo.

fig 57

E novamente o autodromo.json.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


123

fig 58

Agora já temos o nosso mapa com os tiles de colisão devidamente configurados.


Para ver como utilizar os tiles de colisão, vamos criar um game bem simples. e consistirá em
um objeto controlado pelas setas do teclado caminhando pelo autódromo.
game3.js

1 var config = {
2 width: 800,
3 height: 600,
4 pixelArt: true,
5 physics: {
6 default: 'arcade',
7 arcade: {
8 // desabilita debug da física
9 debug: false
10 }
11 },
12 scene: {
13 preload: preload,
14 create: create,
15 update: update

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


124 Tilemap

16 }
17 }
18 var game = new Phaser.Game(config)
19 function preload() {
20 // carrega o JSON
21 this.load.tilemapTiledJSON('map', 'autodromo.json')
22 // carrega o tileset
23 this.load.image('tiles', 'tiles-rua-02.png')
24 // carrega o carro
25 this.load.image('carro', 'circle.png')
26 }
27 function create() {
28 // cria o tilemap
29 var map = this.make.tilemap({
30 key: 'map'
31 })
32 // cria o tileset onde o primeiro parâmetro é o nome do
33 // mapa definido no Tiled.
34 var tileset = map.addTilesetImage('tiles-rua-02', 'tiles')
35 // cria o layer do terreno
36 var terreno = map.createStaticLayer('terreno', tileset, 0, 0)
37 // cria o layer do arbusto
38 var arbusto = map.createStaticLayer('arbusto', tileset, 0, 0)
39 // cria o layer da pista
40 var pista = map.createStaticLayer('pista', tileset, 0, 0)
41 // cria o carro com imagem pois não precisamos de animação
42 this.carro = this.physics.add.image(150, 150, 'carro')
43 // habilita tiles de colisão do terreno
44 terreno.setCollisionByProperty({
45 colisao: true
46 })
47 // habilita colisão entre o carro e o terreno
48 this.physics.add.collider(this.carro, terreno)
49 //câmera segue o carro
50 this.camera = this.cameras.main
51 this.camera.startFollow(this.carro)
52 this.camera.setBounds(0, 0, map.widthInPixels, map.heightInPixels)
53 // cria o cursos para detectar as setas do teclado
54 this.cursors = this.input.keyboard.createCursorKeys()
55 }
56 function update() {
57 // as próximas linhas definem a velocidade do carro
58 // com base nas setas pressionadas no teclado
59 this.carro.setVelocity(0)
60 if (this.cursors.left.isDown) {
61 this.carro.setVelocityX(-200)

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


125

62 } else if (this.cursors.right.isDown) {
63 this.carro.setVelocityX(200)
64 }
65 if (this.cursors.up.isDown) {
66 this.carro.setVelocityY(-200)
67 } else if (this.cursors.down.isDown) {
68 this.carro.setVelocityY(200)
69 }
70 }

Vamos analisar o código:

• Linha 9: desabilitamos o debug da física, para não aparecer as bordas físicas do objeto e
nem o indicador da velocidade.
• Linhas de 19 a 25: carregamos o mapa json e as imagens do jogo.
• Linha 29: criação do tilemap.
• Linha 34: criação do tileset.
• Linhas 36 a 40: criação dos layer (camadas).
• Linha 42: criação do carro com um corpo físico.
• Linha 44: habilitamos os tiles de colisão do terreno. Apenas os tiles com a propriedade
colisao marcada como true.
• Linha 48: habilita colisão do carro com o terreno.
• Linhas 50 a 52: Faz a câmera seguir o carro.
• Linha 54: cria o cursos para controlar o carro pelas setas do teclado.
• Linhas 59 a 68: controla o carro com as setas do teclado.

Perceba que agora não estamos alterando a escala das camadas.


O resultado será:

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


126 Tilemap

fig 59

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


Cenas (scene)
Um jogo com Phaser se compõe de 1 ou mais scenes. Num jogo completo queremos ter pelo
menos 4 scenes: BootScene, PreloaderScene, MenuScene, GameScene, mas você pode ter menos
ou mais de acordo como você estruturar o seu jogo. Os nomes das scenes também são livres.
Podemos, por exemplo, querer uma scene de créditos.
Na primeira scene, BootScene, nós instanciamos e iniciamos o Phaser, com a sua configuração,
e definir todas as scenes do jogo. Carregamos também o logotipo.
Em PreloaderScene carregamos todos os assets do jogo tais como, tilesets, imagens, sons e etc. Na
MenuScene temos o botão para iniciar o jogo. Na GameScene temos o jogo propriamente dito.
No Phaser é muito fácil navegar de uma scene para outra.
No próximo exemplo faremos um game só com as 4 scenes básicas com um mínimo de código,
apenas para a navegação entre elas.
Para este exemplo criaremos o arquivo game.js e mais os 4 arquivos referentes às scenes.
Criaremos um diretório amado scenes onde colocaremos as scenes. Os únicos assets a serem
carregados serão o logotipo do jogo e uma barra de progresso, que estarão dentro do diretório
assets. Além disso criaremos um diretório amado config onde colocaremos o arquivo de
configuração config.js. Então teremos a seguinte estrutura:
128 Cenas (scene)

fig 60

Vamos então estudar esse código?


Começando com o arquivo index.html.

1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>Phaser</title>
6 </head>
7 <body>
8 <script src="//cdn.jsdelivr.net/npm/phaser@3.20.0/dist/phaser.js"></script>
9 <script src="game.js" type="module"></script>
10 </body>
11 </html>

Na linha 9 temos o parâmetro type="module". Com esse parâmetro estamos dizendo ao browser

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


129

que estamos trabalhando modularmente com o Javascript.


Dessa forma podemos importar os treos de código como módulos a partir do arquivo game.js.
Arquivo game.js.

1 // importa o objeto de configuração e todas as scenes


2 import phaser_config from './config/config.js'
3 import GameScene from './scenes/GameScene.js'
4 import PreloaderScene from './scenes/PreloaderScene.js'
5 import BootScene from './scenes/BootScene.js'
6 import MenuScene from './scenes/MenuScene.js'
7 // cria classe game, estendendo de Phaser.Game
8 class Game extends Phaser.Game {
9 constructor() {
10 // é obrigatório chamar o super da classe pai
11 // passando o objeto de configuração
12 super(phaser_config)
13 // registra todas as scene do game
14 this.scene.add('Boot', BootScene)
15 this.scene.add('Preloader', PreloaderScene)
16 this.scene.add('Menu', MenuScene)
17 this.scene.add('Game', GameScene)
18 // vai para a scene Boot
19 this.scene.start('Boot')
20 }
21 }
22 // instancia Game
23 const game = new Game()

Da linha 2 até a 6 carregamos todos os módulos do game.


Na linha 8 criamos a classe Game, que estende de Phaser.Game. Das linhas 14 a 17 registramos
as scenes no game. Na linha 19 amamos a primeira scene a ser executada. E finalmente, na
linha 23 instanciamos a classe Game.
Após esse código ser carregado, ele amará automaticamente a primeira cena: Boot
Vamos agora analisar o arquivo BootScene.js:

1 export default class BootScene extends Phaser.Scene {


2 constructor() {
3 super('Boot');
4 }
5 preload() {
6 // carregamento da barra de progresso e do logotipo
7 this.load.image('bar', 'assets/bar.png')
8 this.load.image('logo', 'assets/logo.png')
9 }
10 create() {

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


130 Cenas (scene)

11 // texto
12 this.texto = this.add.text(200, 150, 'Boot', {
13 fontSize: 40,
14 fontFamily: "Arial"
15 })
16 this.texto.setOrigin(0.5)
17 // chama a próxima cena após 3 segundos
18 this.time.delayedCall(3000, () => this.scene.start('Preloader'), [], this)
19 }
20 }

Na primeira linha criamos a classe BootScene estendendo de Phaser.Scene e exportando como


um módulo. e será carregado pelo arquivo game.js. Nas linhas 7 e 8 carregamos as imagens
que utilizaremos em PreloaderScene. Na linha 12 e 13 colocamos na tela um texto com o nome
da cena. Na linha 15 programamos uma amada a uma função callba utilizando o méthodo
this.time.delayedCall, que amará a próxima cena após 3 segundos.

O código mais longo deste exemplo é o que encontramos no arquivo PreloaderScene.js

1 export default class PreloaderScene extends Phaser.Scene {


2 constructor() {
3 super('Preloader');
4 }
5 preload() {
6 // simula carregamento de 300 assets
7 for (let i = 0; i < 300; i++) {
8 this.load.image('image' + Phaser.Math.RND.integer(), 'assets/logo.png')
9 }
10 //progress bar
11 this.progressbar = this.add.image(200, 250, 'bar').setOrigin(0.5)
12 //percent text
13 this.percentText = this.add.text(200, 270, '0 %', {
14 fontSize: 16,
15 fontFamily: "Arial"
16 })
17 this.percentText.setOrigin(0.5, 0.5)
18 // update progress
19 this.load.on('progress', (value) => {
20 this.progressbar.setScale(value, 1)
21 this.percentText.setText(parseInt(value * 100) + '%')
22 })
23 // remove progress
24 this.load.on('complete', () => {
25 this.progressbar.destroy()
26 this.percentText.destroy()
27 // chama a próxima cena após 1 segundo
28 this.time.delayedCall(1000, () => this.scene.start('Menu'), [], this)

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


131

29 })
30 }
31 }

Vamos comentar apenas as linhas principais desse código:


Nas linhas de 7 a 9, simulamos o carregamento de 300 imagens. O método Phaser.Math.RND.integer()
é utilizado aqui para concatenar um número aleatório à key que será atribuída à imagem. Isso
é necessário para que o Phaser não leia o mesmo arquivo em cae. Na linha 11 colocamos a
imagem da barra de progresso na tela e setamos sua origem para 0.5.
Na linha 13 criamos o texto para mostrar a porcentagem do carregamento.
Na linha 19 criamos um listener para o evento progress da cena onde atualizaremos o tamanho
da barra de progresso e o texto com a porcentagem.
Na linha 24 criamos outro listener para o evento complete que destruirá a barra de progresso e
o texto, e amará a scene Menu após 1 segundo.
Os outros arquivos scenes são semelhantes ao BootScene, não sendo necessário comentar sobre
eles.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


Beth
O primeiro game que iremos estudar é um jogo topdown (vista de cima) onde nossa personagem
precisa coletar as moedas enquanto foge do inimigo. Antes de começar o estudo é importante
que você baixe o código do jogo e jogue um pouco para conhecer o que iremos estudar. Nosso
método de estudo será pela análise e comentários sobre o código pronto. Enquanto vai avançando
na leitura, dedique um tempo para olhar dentro do código do jogo, fazendo testes.

fig 61

Começaremos analisando a estrutura de diretórios e arquivos:


134 Beth

fig 62

Na primeira pasta assets temos os áudios, as imagens, os arquivos do tilemap e um arquivo de


fonte.
Na pasta classes temos as classes dos objetos de jogo. Estudaremos individualmente cada uma
dessas classes.
Na pasta config temos um arquivo com o objeto de configuração do Phaser.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


135

Na pasta scenes estão as 5 cenas que utilizaremos no jogo.


Na parta raiz temos o favicon, o arquivo index.html, o game.js e o phaser.min.js (no projeto
final é bom carregar a biblioteca direto da estrutura de arquivos em vez de utilizar os CDNs, a
não ser que você tenha certeza que o jogo sempre será utilizado em um dispositivo conectado à
Internet).

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


136 Beth

index.html

fig 63
Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com
137

Já vimos em exemplos anteriores a estrutura do nosso index.html para carregar o Phaser. Mas
vale à pena ressaltar algumas linhas.
Nas linhas 5 e 6 definimos a meta viewport para que nossa página seja responsiva, se adaptando
ao tamanho da tela do dispositivo.
Nas linhas de 8 a 17 definimos a margin e padding do body como 0, definimos a cor de fundo
como preto, carregamos a webfonte PressStart2P para ser utilizada no game.
Nas linha 18 a 22 estilizamos a classe .texto para posicionar um elemento div fora da área visível
do dispositivo. Como já vimos em capítulos anteriores, a função dessa div é carregar a webfonte
no documento para garantir que estará disponível para ser utilizada pelo Phaser.
Na linha 28 carregamos a biblioteca do Phaser na sua versão minificada.
Na linha 29 amamos o arquivo game.js que é responsável por dar início ao game. Repare que
estamos definindo um parâmetro type="module", para que o browser saiba que iremos trabalhar
com módulos no javascript.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


138 Beth

game.js

fig 64

Este código é responsável por preparar tudo para instanciar o Phaser e iniciá-lo.
Primeiro importamos o objeto de configuração que está definido no arquivo ./config/phaser.js.
Em seguida, nas linhas de 2 a 6 carregamos as scenes do game.
Nas linhas de 8 a 16 criamos a classe Game que herda de Phaser.Game. Dentro do bloco de criação
da classe passamos o objeto de configuração para a classe pai amando o método super, e
em seguida registramos todas as scenes do game para que possamos amá-las no momento

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


139

oportuno.
Na linha 20 instanciamos a classe Game e iniciamos o game.
Nas linhas de 21 a 24 adicionamos a game um objeto de dados o qual iremos utilizar em algumas
scenes do game.

scenes/BootScene.js

fig 65

Essa é a primeira cena a ser amada, e é nela que carregamos alguns assets mínimos que iremos
utilizar na PreloaderScene.
Criamos a classe herdando de Phaser.Scene. No constructor Passamos para a classe pai o nome
da scene pelo método super.
Nas linhas de 6 a 9 carregamos a imagem do logotipo e a barra de progresso.
No método create definimos valores para o objeto de dados que foi criado em game.js. Observe
o caminho para se egar a esse objeto a partir de uma scene: this.sys.game.model, onde this
faz referência à própria scene.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


140 Beth

Na linha 16 passamos o controle para a scene Preloader.


E na linha 20 exportamos o módulo para que possa ser carregado no arquivo game.js.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


141

scenes/PreloaderScene.js

fig 66

Nas 3 primeiras linhas declaramos a classe herdando de Phaser.Scene e passando o nome da


scene com o método super. Estas primeiras linhas são semelhantes para todas as scenes criadas.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


142 Beth

método preload()
No método preload() adicionamos todos os assets do game à fila de carregamento. Nesse método
podemos também monitorar esse carregamento sendo possível assim criar barras de progresso e
mostrar o carregamento dos assets.
Na linha 12 carregamos a imagem do tileset do tilemap. Lembrando que o primeiro parâmetro é
sempre a key pela qual iremos amar o assets quando necessário.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


143

tuxmon.png

Na linha 15 carregamos o map.json que exportamos do Tiled, atribuindo uma key “map”. Perceba
que para criar o tilemap os 2 arquivos, o tileset e o json, são carregados separadamente.
Na linha 17 carregamos o spritesheet da “beth”. Nos parâmetros frameWidth e frameHeight
passamos as dimensões de cada sprite desse spritesheet. É a partir dessas dimensões que o Phaser
irá “separar” cada frame do spritesheet.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


144 Beth

beth.png

Na linha 24 caregamos uma imagem que será utilizada na scene dos créditos.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


145

creditos.png

Na linha 27 carregamos outro spritesheet: as moedas.

moedas.png

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


146 Beth

fig 67

Na linha 32 carregamos o spritesheet do inimigo.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


147

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


148 Beth

Nas linhas 39 a 57 carregamos os sons do game. O método this.load.audio(key, audio.ogg,


audio.mp3) recebe como primeiro argumento akeypala qual acessaremos o som posteriormente,
o segundo parâmetro é o caminho para o arquivo de áudio no formatoogg, e o último
parâmetro o caminho para o mesmo som, porém no formatomp3“. O fornecimento dos sons
nos 2 formatos (ogg e mp3) serve para garantir que o browser poderá tocar o som num formato
ou em outro.

fig 68

Nas linhas 61 a 62 declaramos as constantes width e height com a largura e altura do canvas do
game respectivamente.
Na linha 65 colocamos o logo na tela, lembrando que a imagem do logo foi carregada previamente
em SceneBoot, assim como a barra de progresso.
Na linha 68 colocamos na tela a barra de progresso utilizando como referência as constantes
width e height.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


149

Na linha 70 definimos o ponto de origem na barra de progresso para o topo do canto esquerdo. Isso
é necessário para que o redimensionamento desta barra que será feito durante o carregamento
dos assets tenha como origim o início da barra de progresso.
Nas linhas 73 criamos um texto para mostrar a porcentagem do carregamento. Este texto também
é posicionado na tela tomando como referência as constantes width e height. Perceba que
estamos utilizando a webfonte “PressStart2P”, que foi carregada lá no nosso index.html. Na
linha 82 definimos a origem do texto como sendo o centro do mesmo (essa linha é desnecessária
já que por padrão o pivô dos objetos é o centro mesmo).

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


150 Beth

fig 69

Nas linhas 85 a 93 colocamos na tela outro texto para mostrar o nome do asset que está sendo
carregado.
Nas linhas 96 a 98 criamos um evento do tip progress para “escutar” o carregamento dos assets.
A função callba vai atualizar a escala da barra de progresso e a porcentagem de carregamento
dos assets.
Nas linha 102 e 103 criamos outro evento, do tipo fileprogress. A função callba vai atualizar
o texto com o nome dos assets conforme vão sendo carregados.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


151

E nas linhas de 107 a 110 criamos mais um evento agora do tipo complete cuja função callba
destrói a barra de progresso e os textos de porcentagem e nome do asset.

Método create()

fig 70

Depois de carregados todos os assets, o método create é amado automaticamente. Dentro


deste método definimos um objeto time do Phaser para amar a próxima scene depois de meio
segundo. Esse delay é puramente “estético”, ele evita que, caso os assests sejam carregados muito
rápido, a tela de preload passe despercebida.
Finalmente, na linha 120, exportamos a classe para que possa ser importada no arquivo game.js

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


152 Beth

scenes/MenuScene.js

fig 71

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


153

fig 72

Depois de carregar todos os assets paramos nesta scene onde temos 2 botões: [iniciar] e
[créditos].

Nas 2 primeiras linhas importamos as classes Botao e Audio (essas classes serão estudadas

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


154 Beth

posteriormente).
Nas linhas 3 a 4, constructor(), criamos a classe MenuScene que herda de Phaser.Scene, e
passamos o nome da scene amando o método super.
Nas linhas de 8 a 11 temos o método init() que por padrão é o primeiro a ser executado
automaticamente quando a scene iniciar. Dentro deste método instanciamos a classe Audio e
anexamos ao objeto de dados do jogo (aquele objeto criado no game.js). Criamos também uma
variável da scene, this.audio e colocamos o objeto de áudio criado.
Nas linhas 13 e 14 criamos as constantes width e height com as dimensões da tela.
Nas linhas 18 e 19 criamos a variável this.btnIniciar instanciando a classe Botao, que será vista
adiante. Posicionamos o botao na tela tendo como referência as constantes width e height. Na
linha 20 definimos o valor Game para a propriedade target do botão criado. Isso fará com que ao
ser pressionado o game passe para a scene com o nome Game.
Nas linhas 23 a 25 criamos outro botão, para navegar até a scene Credits.
Nas linhas 28 a 30 tocamos a música de espera com o volume em 30% e em loop.
E por fim, na linha 35 exportamos a classe.

scenes/CreditsScene.js

fig 73

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


155

Esta scene é nossa tela de créditos, nela colocamos a imagem com os créditos e um botão para
acessar o menu. O código dispensa comentários.

scenes/GameScene.js
Esta é a scene onde o game acontece.

fig 74

Até a linha 12 carregamos as classes e estendemos a classe Phaser.Scene da mesma forma como
nas outras scenes.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


156 Beth

Método create()

fig 75

Na linha 16 colocamos a string jogando no objeto de dados do game.


Na linha 19 recuperamos o objeto audio para gerenciar as músicas nesta scene. Na linha 20
paramos a música de espera, e nas linhas de 21 a 23 tocamos a música do game.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


157

fig 76

Nas linhas de 28 a 40 instanciamos os objetos do game. Cada um desses objetos está implementado
num arquivo separado por questões de organização do código do nosso game. Veremos cada
classe mais adiante.

fig 77

Nas linhas 43 e 44 posicionamos a personagem na posição inicial. Esta posição vem de um objeto
específico no JSON do tilemap. Este código ficará claro quando estudarmos a classe Mundo.
Nas linhas 46 a 48 habilitamos as colisões entre a personagem e as camadas (layers) do tilemap.
Nas linhas de 51 a 54 habilitamos a câmera do game a acompanhar a personagem.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


158 Beth

fig 78

Na linha 57 instanciamos a classe GrupoMoedas. O segundo parâmetro deste constructor é um


array com os objetos moedas vindos do JSON do tilemap.
Nas linhas 60 a 62 instanciamos o gerenciador de colisões e atribuimos 2 eventos que serão
executados quando as moedas acabarem e quando o inimigo pegar a personagem. O callba
desses eventos está definido na classe Estados que estudaremos a seu tempo.
Nas linhas 65 e 66 definimos um callba a ser amado quando houver sobreposição das
moedas com a personagem. O método this.colisoes.bethMoedas(b) irá tratar esse evento,
como veremos adiante.
Nas linhas 69 e 70 fazemos o mesmo para a sobreposição do inimigo e a personagem.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


159

Método update()

fig 79

O método update() é executado a cada frame do game a 60fps (60 frames por segundo). Neste
método atualizamos os objetos beth e inimigo caso o estado do jogo seja “jogando”.
Na linha 81 exportamos a scene.
Podemos perceber que o código da SceneGame é relativamente pequeno para um jogo. Isso é
porque a lógica do game está distribuída nas classes dos objetos do jogo que iremos estudar em
seguida. Mas antes vamos olhar rapidamente o código do script config/phaser.js.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


160 Beth

config/phaser.js

fig 80

Vejamos o significado de cada propriedade deste objeto de configuração:

type
Phaser.AUTO
Deixa o Phaser escolher automaticamente o modo de renderização.

backgroundColor
#fcf8e8

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


161

Como o nome sugere é a cor de fundo do canvas do game.

pixelArt
true
Esta propriedade sendo true define que o Phaser vai deixar o game com aspecto pixelado quando
as imagens são renderizadas com escalas aplicadas.

physics
Aqui configuramos a física do jogo para “arcade”, que é um dos motores de física suportados
disponíveis no Phaser.

scale

mode: Phaser.Scale.FIT

Define que o canvas do game será redimensionado para o preenar o tamanho da tela do
dispositivo.

autoCenter: Phaser.Scale.CENTER_BOTH

Define que o cavas ficará centralizado horizontal e verticalmente.

width: 800

Largura do canvas.

height: altura do canvas.

classes/Beth.js
Vamos agora analisar uma das classes mais importantes do jogo, que é a classe Beth que define
o player do jogo.

O que está classe faz?


• Se auto adiciona na scene.
• Cria um corpo físico.
• Redimensiona o corpo físico para melhor efeito de colisão com os objetos.
• Ajusta a profundidade da Beth na scene.
• Cria as animações para a Beth.
• Movimenta a personagem com o uso das setas do teclado.
• Ajusta a animação da personagem de acordo com o estado.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


162 Beth

fig 81

Nas primeiras linhas criamos a classe Beth herdando de Phaser.GamObjects.Sprite. Como a


personagem conterá animações, precisamos criá-la com sprite. No constructor recebemos 4
parâmetros: a scene, as posições x e y, e a texture (que é a key do sprite que carregamos na
scene PreloaderScene).
Na linha 6 adicionamos a própria instância da classe na scene. Na linha 7 habilitamos o corpo
físico da personagem, e nas linhas 8 e 9 redimensionamos esse corpo físico para dar um melhor
efeito na colisão com os objetos.
Na linha 10 ajustamos a profundidade da personagem.
Na linha 11 amamos o método criarAnimacoes() que veremos adiante. Na linha 13 criamos a
variável this.cursors que recebe uma instância do objeto de cursor do teclado. Este objeto será
utilizado no médoto update() da scene.
Na linha 145 exportamos nossa classe.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


163

Método update()

fig 82

Na linha 16 definimos inicialmente a velocidade do personagem como zero, tanto em X como


em Y.
Na linha 17 testamos se o estado do game é “jogando”. Caso não seja, abandonamos o método
update() sem fazer mais nada.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


164 Beth

fig 83

Nas linhas 20 a 43 desenvolvemos a lógica do movimento da personagem de acordo com a seta


do teclado pressionada. A lógica consiste em ajustar a velocidade x e y, e também definir uma
animação de acordo com a seta pressionada. Também utilizamos o método setData(key, value)
para marcar a direção em que a personagem se move.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


165

fig 84

Se nenhuma seta estiver pressionada, as linhas de 46 a 57 fazem a personagem parar definindo a


velocidade x e y para zero. Em seguida a animação da personagem é definida de acordo com o
valor da propriedade “direcao”, que foi definida no bloco anterior.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


166 Beth

fig 85

No método criarAnimacoes(), a partir da linha 61, criamos todas as animações da personagem


conforme já vimos em capítulos anteriores.
Você pode observar que a maior quantidade de linha de código é para criar as animações, mas
por outro lado é um código simples e só é extenso porque são muitas animações. Por isso é uma
boa prática criar as animações dentro da própria classe ou criar uma classe exclusiva para criar
todas as animações do game. Nós optamos pelo primeiro modo.

classes/Audio.js
Nesta classe colocamos todos os objetos de sons do game, para serem amados no mo-
mento oportuno. Lembrando que todos os assets de sons já foram previamente carregados na
PreloaderScene.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


167

fig 86

Esta classe dispensa muito comentários pois creio que a implementação está bastante clara.
Veremos mais adiante como executar os sons a partir dessa classe.

classes/Botao.js
Esta classe é responsável por criar os botões que temos no jogo. São botões de texto que quando
clicados amam uma scene.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


168 Beth

fig 87

Na linha 3 a 7 amamos a classe pai passando para o método super() a scene, a posição x e y,
e um objeto de configuração do texto.
Na linha 10 definimos uma propriedade “privada” this._target, que irá conter o nome da scene
a ser amada quando o botão for clicado. Nós setamos o valor dessa propriedade amando o
método seer target definido na linha 17.
Na linha 11 definimos a origem do botão para o centro do mesmo (isso já era padrão e não
precisaria ser definido aqui, mas fica como exemplo).
Na linha 12 adicionamos o botão na scene.
Na linha 13 tornamos o botão clicável.
Na linha 14 definimos o evento “pointerdown”, que mudará o tamanho da fonte quando
pressionarmos o botão.
Na linha 15 definimos o evento “pointerup” que amará a scene alvo quando soltarmos o botão.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


169

classes/Colisoes.js
Esta classe não é um objeto de exibição, ela é responsável por tratar as colisões entre a personagem
e as moedas, e a personagem e o inimigo.
O código é bem simples. Temos 2 métodos que serão utilizados como callba no evento de
colisões que veremos mais adiante.

fig 88

Método bethMoedas(moeda)
Na linha 7 destruimos a moeda que colidiu com a personagem. Nas linhas 8 e 9 atualizamos a
contagem de pontos e as moedas colhidas no objeto de dados que criamos lá no nosso arquivo

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


170 Beth

game.js.

Na linha 10 atualizamos a exibição de pontos e moedas no objeto da classe Gui que ve-
remos mais a frente. Este objeto está anexado à scene, por isso podemos acessá-lo com
this.scene.gui.update().

Na linha 11 e 12 testamos se as moedas acabaram e nesse caso emitimos um evento “acabou_-


moedas” que será escutado na scene GameScene, na linha 61.
Na linha 16 tocamos o som da moeda executando o método play() do objeto audio.moeda que
foi declarado na classe Audio, como já vimos. Este objeto foi anexado ao game na MenuScene,
linhas 9 e 10. Por isso podemos acessá-lo com this.scene.sys.game.audio.moeda.play().

Método bethInimigo()
Nas linhas 18 e 19 temos o método bethInimigo que será usado como callba da colisão entre
a personagem e o inimigo. Este método apenas emite o evento “pegou”, que será escutado em
GameScene, linha 62.

Chain of responsibility (Responsabilidades.js,


ResponsabilidadeMorreu.js,
ResponsabilidadeVitoria.js)
Com estas 3 classes montamos o padrão de projetos “ain of responsibility” (corrente de
resposabilidades) para lidar com a vitória ou morte da personagem.

fig 89

Na figura temos um esquema de como as 3 classes interagem.


Na GameScene.js instanciamos a classe Responsabilidades. Dentro da classe da classe Responsa-
bilidades instanciamos ResponsabilidadeVitoria e responsabilidadsMorreu.
Na classe GameScene amamos o método this.responsabilidades.executa(‘vitoria’) ou this.responsabilidades.executa
A partir daí a classe Responsabilidades ama o método executa() da classe Responsabilidade-
Vitoria que executa a ação “vitória” ou passa a responsabilidade para a classe responsabilidade-
Morreu se a ação não é “vitória”.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


171

A vantagem de montar esse padrão é que poderíamos ter muitas outras ações e só precisaríamos
para isso criar uma classe para cada nova ação, sem precisar mexer nas outras classes.
Vamos agora analisar as 3 classes dessa corrente.

classes/Responsabilidades.js

fig 90

Nas linhas nas primeiras 2 linhas importamos as 2 classes auxiliares correspondentes as ações
“vitoria” e “morreu”.
Na linha 6 colocamos o objeto this.escene.sys.game.audio na variável this.audio (), lembrando
que o objeto this.scene.sys.game.audio foi criado na linha 9 em SceneMenu.js.
No método executa(acao) primeiramente paramos a música do jogo e iniciamos tocamos a música
de espera.
Na linha 16 instanciamos a classe ResponsabilidadeMorreu, passando como parâmetro this.scene.
Na linha 17 instanciamos a classe ResponsabilidadeVitoria, passando como parâmetro this.scene
e a this.morreu.
Na linha 18 amamos this.vitoria.executa(acao), que dará início à corrente de responsabilidades.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


172 Beth

classes/ResponsabilidadeVitoria.js

fig 91

Na primeira linha importamos a classe Botao.


Na linha 5 definimos a variável this.next com o a classe que passada no segundo parâmetro do
constructor. No nosso caso a classe passada aqui foi responsabilidadeMorreu.
Nas linhas 6 e 7 pegamos as dimensões da tela do game.

fig 92

Aqui temos definido o método executa(acao).


Na linha 10 verificamos se a ação a ser executada é “vitoria”. Se for, tratamos essa ação nas
próximas linha. E caso não seja, passamos para a linha 36 que veremos mais a frente.
Na linha 11 definimos o estado do gama para ‘vitoria’.
Nas linha 12 a 16 criamos um botão que amará SceneGame quando pressionado.
Na linha 15 definimos a propriedade this.btnReiniciar.setScrollFactor(0), que fará com que o botão
fique fixo na tela independentemente da posição da câmera.
Na linha 16 definimos a profundidade do botão como 100 para garantir que não será sobreposto
por outros objetos do game.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


173

fig 93

Nas linha 17 a 27 criamos um objeto para mostrar o texto “VITÓRIA ‼!” na tela.
Nas linhas 29 e 30 definimos o fator de scroll para 0 fixando o texto na tela e definimos a
profundidade com 100 para, da mesma forma, garantir que o texto não seja sobreposto por outros
objetos.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


174 Beth

fig 94

Na linha 33 destruímos o inimigo.


Se a ação não for “vitoria” todo o bloco anterior não será executado e a linha 36 ama o método
executa da próxima classe, que no nosso caso é responsabilidadeMorreu.

classes/ResponsabilidadeMorreu.js

fig 95

Na primeira linha importamos a classe Botao.


Na linha 5 definimos a variável this.next com o a classe que passada no segundo parâmetro do

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


175

constructor. No nosso caso a classe passada aqui foi responsabilidadeMorreu.


Nas linhas 6 e 7 pegamos as dimensões da tela do game.

fig 96

Na linha 10 verificamos se a ação é “morreu”. Se for, executaremos o bloco de código a partir da


linha 11.
Nas linhas 11 a 13 definimos as variáveis de dados do game.

fig 97

Nas linhas de 14 a 28 colocamos na tela o texto “MORREU :-(“, com o fator de scroll 0 e
profundidade 100 como nos textos anteriores.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


176 Beth

fig 98

Nas linhas 29 a 33 colocamos o botão “[reiniciar]” na tela.

fig 99

Na linha 35 destruímos a personagem e na linha 38 tocamos o som da morte.


A linha 40 passaríamos a execução para a classe seguinte se a ação não fosse “morreu”. No nosso
caso isso não ocorrerá porque esta classe é a última da corrente de responsabilidade.

classes/Inimigo.js
Aqui criamos a classe Inimigo.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


177

fig 100

Na linha 5 adicionamos o inimigo na scene.


Na linha 17 habilitamos a física no inimigo.
Nas linhas 7 e 8 redefinimos o tamanho do corpo físico para que a colisão ocorra nos pés do
inimigo.
Na linha 9 definimos a profundidade do inimigo na scene.
Na linha 10 amamos o método para criar as animações do inimigo.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


178 Beth

Método update().

fig 101

Este método rodará a cada frame pois será amado pelo update() da GameScene.
Na linha 14 movemos o inimigo na direção da personagem a cada frame, com uma velocidade
de 100 pixels por segundo com o método moveToObjects() que é fornecido pelo motor de física
arcade do Phaser.
Na linha 19 carregamos a animação atual na variável animação.
Na linha 20 calculamos o ângulo de movimento do inimigo por meio do método this.body.velocity.angle().
Este método é fornecido pelo corpo físico do objeto. Na documentação do Phaser você encontrará
outros métodos do corpo físico de um objeto.
Nas linhas 21 a 30 definimos qual será a animação aplicada ao inimigo correspondente ao ângulo

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


179

do movimento.
Nas linhas 32 a 34 aplicamos a nova animação caso a animação atual seja diferente da nova
animação.

Método criaAnimacoes().

fig 102

Das linhas 37 a 82 criamos todas as animações que serão utilizadas pelo inimigo.

classes/Moeda.js
Nesta classe definimos as moedas do game.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


180 Beth

fig 103

Na linha 6 adicionamos a moeda na scene.


Na linha 5 ajustamos a escala da moeda para 150%.
Nas linhas 9 a 16 criamos a animação da moeda, e na linha 19 executamos a animação.

classes/GrupoMoedas.js
A função dessa classe é criar as moedas nas posições de objetos do layer de objetos do tilemap
que foi carregado na linha 31 da classe Mundo.js (this.map.getObjectLayer("Moedas")).

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


181

fig 104

Nas linhas 6 e 7 iteramos no array moedas e criamos no grupo 1 moedas para cada objeto do
array.

classes/Gui.js
Essa classe é um container responsável por mostrar na tela do game o score e as moedas colhidas.
Criamos esta classe herdando de Phaser.GameObjects.Container, que é uma classe do Phaser
que serve de container para objetos de exibição.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


182 Beth

fig 105

Nas linhas de 5 a 13 criamos o objeto de texto que mostrará o score do game. Na linha 16
adicionamos esse texto à própria classe.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


183

fig 106

Da mesma forma nas linhas de 17 a 28 criamos o objeto de texto para mostrar as moedas colhidas
e adicionamos na própria classe.

fig 107

Na linha 29 adicionamos o container na scene, e nas linhas 30 e 31 fixamos o container na scene e


definimos a sua profundidade para 100, para garantir que não seja sobreposto por outros objetos
da scene.
Nas linhas 32 e 33 colocamos o texto dentro dos objetos.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


184 Beth

Método update()

fig 108

No método update atualizamos os textos. Esse roda a cada frame do game, pois será amado a
partir do método update() na classe GameScene.
Todo o código do jogo está nos arquivos fontes do curso. Estudar o código do jogo é uma excelente
forma de aprender e fixar os conhecimentos.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


Flying bee
Chicken
Vamos agora estudar o código de um jogo que tem um tema bastante tradicional. É um jogo onde
você tem que conduzir uma galinha para atravessar uma auto estrada enquanto colhe os ovos
espalhados pela via.

ien

Primeiramente examinaremos a estrutura de pastas e arquivos. Depois disso, e antes de come-


çarmos estudar o código, é bom você baixar o código fonte e rodar o jogo para conhecê-lo. Isso
vai ajudar a compreender melhor o código.
188 Chien

Estrutura de pastas e arquivos

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com

fig 109
189

assets

Como sempre, nesta pasta encontram-se todos as imagens mapas sons e todos os assets do game.
assets/atlas

Nesta pasta temos os arquivos referentes aos textureatlas botoes e vehicles.


assets/audio

É onde ficam todos os arquivo de áudio do game.


assets/font

Aqui temos o arquivo de fonte que utilizaremos no game.


assets/img

Todas as imagens estão aqui.


assets/map

Os 2 arquivos referentes ao tilemap do game.


asssets/spritesheet

Temos aqui o spritesheet da galinha.

classes

Nesta pasta temos as classes do game.

config

Nesta pasta temos o arquivo de configuração do game.

scenes

Aqui temos as classes que definem as scenes (cenas) do game.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


190 Chien

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


191

index.html

fig 110

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


192 Chien

Este arquivo é semelhante ao index.html do game Beth, mas vamos analisar as linhas mais
importantes.
Na tag style nós definimos magin e padding para que não fique nenhuma borda no can-
vas do game. Nesta tag também configuramos e carregamos a fonte a partir do arquivo
assets/font/PressStart2P-Regular.tff.

Configuramos também uma classe .texto que fará com que o texto que utilizaremos somente
para carregar efetivamente a fonte e deixá-la disponível para o Phaser fique fora da tela.
Na linha 27 temos a div com a classe texto.
Na linha 28 carregamos a biblioteca do Phaser e na linha 29 carregamos o nosso arquivo inicial
game.js. Acrescentamos o atributo type="module" para podermos importar nossas classes para
o game de forma modular. Sem esse atributo o browser não saberá que estamos trabalhando com
módulos javascript.

game.js
Aqui está o arquivo inicial responsável por carregar as configuração e iniciar o game.

fig 111

Na primeira linha importamos as configurações do game.


Nas linhas 2 a 6 importamos as scenes (cenas).

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


193

fig 112

Nas linha de 8 a 16 criamos a classe Game que herda de Phaser.Game.


No constructor da classe adicionamos as scenes e iniciamos o game pela scene Boot.

fig 113

Na linha 20 criamos a variável game e iniciamos o jogo. Nas linha 22 a 27 anexamos ao game um
objeto de dados game.model. Este objeto de dados poderá ser acessado a partis das scenes pelo
atalho this.sys.game.model.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


194 Chien

fig 114

No método preload() carregamos as imagens necessárias para a scene PreloaderScene.


No método create() inicializamos a o score com zero e partimos para PreloaderScene.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


195

scenes/BootScene.js

fig 115

Está é a a primeira scene do game. A função dessa classe é carregar previamente os assets que
serão utilizados na PreloadesScene. No método preload() estamos carregando apenas o logotipo
e a barra de progresso. No método create() inicializamos o score do game e passamos o controle
para a próxima scene.

scenes/PreloaderScene.js
Aqui carregamos todos os assets do game enquanto mostramos na tela uma barra de progresso,
um texto mostrando a porcentagem do carregamento e um texto com o nome do asset que está
sendo carregado.
Na primeira linha importamos a classe Animação que será utilizada mais adiante para criar todas
as animações do game.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


196 Chien

método preload()

fig 116

Neste método carregamos todos os assets do game, começando na linha 10 a 13 a carregas os


assets relativos ao tilemap.

fig 117

Carregamos o spritesheet da personagem

fig 118a

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


197

Na linha 22 carregamos a imagem que iremos utilizar no ovo.


Na linha 25 carregamos o textureatlas dos botões.

fig 118b

Na linha 29 carregamos o textureatlas dos veículos.

fig 118c

fig 119

A partir da linha 33 começamos a carregas os sons do game. Como vimos antes cada som carrega
2 arquivos de áudo nos formatos ogg e mp3, para garantir que o browser execute o som.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


198 Chien

fig 120

Nas linhas 63 e 64 pegamos as dimensões da tela.


Nas linha 70 adicionamos a barra de progresso na tela, configurando a sua origem para o topo do
lado direito da imagem. Isso fará com que a escala que aplicaremos na imagem comece a partir
desse ponto.

fig 121

Nas linhas 75 a 84 criamos o objeto texto da porcentagem e definimos sua origem para o centro
do objeto.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


199

fig 122

Nas linhas de 86 a 95 criamos o objeto texto dos assets e definimos sua origem para o centro do
objeto.

fig 123

Nas linhas 98 a 100 escutamos o evento ‘progress’ onde atualizaremos a escala da barra de
progresso e o texto da porcentagem.
fig 124

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


200 Chien

fig 124

Nas linhas 104 a 105 escutamos o evento ‘fileprogress’ para atualizar o texto dos assets enquanto
são carregados.
Nas linhas 109 a 111 escutamos o evento ‘complete’ para destruir a barra de progresso, o texto
dos assets e o texto da porcentagem.

método create()
fig 125

fig 125

Na linha 118 invocamos a classe responsável por criar toda as animações do game. E depois de
meio segundo, na linha 120, passamos o controle para MenuScene.

scenes/MenuScene.js
fig 126

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


201

fig 126

Nas primeiras linha importamos as classes Buon e Audio que serão utilizadas adiante para criar
os botões do menu e tocar a música de espera.
### método init()
fig 127

fig 127

Este método é o primeiro a ser executado na scene.


Na linha 9 instanciamos a classe Audio e salvamos anexamos ao objeto game como this.sys.game.audio.
Este objeto estará disponível para todas as scenes como na linha 10.
### método create()
fig 128

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


202 Chien

fig 128

Na linha 15 nós paramos a música do jogo.


Nas linha 16 a 18 tocamos a música de espera passando um objeto de configuração com o volume
da música, e habilitando a execução em loop.
fig 129

fig 129

Nas linhas 22 e 23 pegamos as dimensões da tela e salvamos nas variáveis constantes width e
height.

fig 130

fig 130

Nas linhas 26 e 27 criamos um botão para iniciar o game instanciando a classe Buon
(estudaremos essa classe detalhadamente mais adiante). Na linha 28 definimos a scene alvo desse
botão.
fig 131

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


203

fig 131

Nas linhas 31 e 32 criamos um botão para acessar a scene dos créditos do game.

scenes/CreditsScene.js
Nesta cena apenas apresentamos os créditos do game. E colocamos um botão para voltar ao
menu.

fig 132

Na linha 1 importamos a classe Buon.


Na linha 7 recuperamos o objeto de áudio. Nesta scne esse objeto será utilizamos apenas para
parar a música.

fig 133

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


204 Chien

Na linha 11 paramos a música de espera.


Nas linhas 14 e 15 carregamos, posicionamos e ajustamos a escala do logotipo.

fig 134

Nas linhas18 a 26 colocamos e posicionamos o texto dos créditos na tela.

fig 135

Nas linhas 30 a 32 colocamos e posicionamos um botão que quando acionado retorna o controle
para MenuScene.
Nesta scene podemos colocar outras informações sobre o game, conforme sua vontade. No lugar
do texto poderíamos colocar uma imagem ou até mesmo um sprite animado. Isto que colocamos
é apenas um exemplo.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


205

scenes/GameScene.js

fig 136

A scene principal do game.


Nas linhas de 1 a 7 importamos todas as classes necessárias. Estas classes serão analisadas
individualmente mais adiante.

fig 137

Na linha 15 recuperamos o objeto de áudio.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


206 Chien

fig 138

Na linha 20 definimos o valor “jogando” para a variável de dados this.sys.game.model.state.


Na linha 22 paramos a música de espera, e nas linhas de 23 a 25 tocamos a música do jogo em
loop.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


207

fig 139

Nas linhas acima instanciamos as classes do game.

fig 140

Na linha 46 escutamos o evento “egou”, emitido pela classe Chien, para executarmos
this.acao.egou(). Examinaremos a classe Acao posteriormente.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


208 Chien

fig 141

Nessas linhas escutamos os eventos “pegou_ovo”, “pegou_tudo” e “atropelou”, executando as


ações correspondentes.
(Tratar as ações em uma classe separada facilita a manuntenção e expansão do game)

fig 142

Na linha 59 executamos o método update() da classe Chien a cada frame do game. A classe
ien também será estudada posteriormente.

classes/Mundo.js

fig 143

Esta classe tem a responsabilidade de criar o nosso mundo, instanciando o tilemap, os layers e
layers de objetos.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


209

Nas linha 4 a 5 instanciamos o mapa na variável this.map.


Na linha 7 adicionamos a imagem “autoestrada”, carregada na PreloaderScene, no nosso mapa.
Na linha 8 criamos o leyer estrada na cena.
Na linha 9 reduzimos a escala desse layer para a metade porque, como o nosso mapa tem uma
formação de 16 x 12 tiles com 100px cada, o tamanho final desse layer é 1600 x 1200, sendo que
as dimensões do nosso game são 800 x 600 px.
Na linha 10 carregamos no variável this._player o objeto do mapa nomeado por “player” no
layer “posicao”. Na linha 11 carregamos na variável this._arrival o objeto do mapa nomeado
por “arrival” (egada).
Na linha 12 carregamos na variável this._eggs um array com todos os objetos denominados
“ovo” do layer “posicao”.
Vamos aproveitar o momento e dar uma olhada na construção do tilemap do game.
Utilizamos a ferramenta Tiled para criar o mapa.

fig 145

Neste mapa fizemos o seguinte:

• Carregamos o tileset “autoestrada.png”.


• Criamos o layer “estrada” e o objectlayer “posicao”.
• Montamos a estrada.
• Criamos no objetclayer as marcaçãos para o “player”, “arrival” (egada), e as possíveis
posições onde um “ovo” pode aparecer.

Abra do Tiled o mapa (está no código fonte) para estudá-lo.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


210 Chien

fig 146

Na linha 15 a 23 criamos métodos get para fornecer acesso às variáveis this._player, this._-
arrival e this._eggs.

classes/Chicken.js

fig 147

Esta é a classe onde criamos a personagem. Aqui criamos o sprite, capturamos as setas do teclado
para alterar o movimento e as animações correspondentes.
Na linha 3 passamos para a classe herdada a posição x e y do player, a textura (spritesheet
carregado em PreloaderScene) e o número do frame com o qual iremos iniciar a exibição da
personagem.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


211

A posição x e y é dada dividindo-se o valor das variáveis mundo.player.x e mundo.player.y por


2. Isso é necessário pois como já vimos o nosso realmente tem o dobro das dimensões da tela do
game.
Na linha 5 definimos a variável this.arrival com o objeto do ponto de egada da personagem,
e na linha 6 temos a definição da variável this.player com o objeto de posicionamento inicial
da personagem.
Na linha 7 adicionamos a personagem à scene.
Nas linhas de 8 a 10 habilitamos um corpo físico para a personagem, habilitamos a colisão com
as bordas do mundo para evitar que a personagem ultrapasse os limites do game, e ajustamos o
tamanho do corpo físico para melhor efeito da colisão da personagem com os outro objetos.
Na linha 11 definimos a profundidade da personagem na tela como sendo 10.
Na linha 12 criamos um objeto de cursor na variável this.cursors para capturamos as setas
pressionadas.

fig 148

Na linhas 14 a 16 tocamos o som dos passos em loop e logo em seguida, na linha 18, colocamos
os sons dos passos em pausa.

fig 149

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


212 Chien

método reset()

fig 149

Nas linhas 20 a 23 criamos o método reset() que servirá para posicionar o player na posição
inicial. Os valores divididos por 2 se devem a que, como já vimos, o tamanha original no nosso
tilemap é o dobro do tamanho da tela do game.

fig 150

Na linha 25 definimos inicialmente a velocidade do player como 0 horizontalmente e vertical-


mente.
Na linha 26 verificamos se o game está em algum estado diferente de “jogando”, caso afirmativo
pausamos o som dos passos, definimos a animação da personagem para “frente” e abandonamos
o resto do método update().

fig 151

Nas linha 32 e 33 emitimos o evento “egou” caso a personagem tenha alcançado a posição de
egada.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


213

fig 152

Da linha 36 em diante definimos o movimento e as animações da personagem conforme a seta


do teclado pressionada. Também voltamos a tocar a som dos passos.

fig 153

Se nenhuma seta está pressionada definimos a velocidade com 0, pausamos o som dos passos
e ajustamos a animação da personagem conforme o valor de this.getData('direcao') que
definimos no bloco anterior com a ajuda do método this.setData('direcao', direcao)

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


214 Chien

classes/Vehicle.js

fig 154

Está é a classe onde definimos os objetos dos veículos.


Na linha 3 amamos a classe hedada passando como parâmetro a scene, a posição x e y, a textura
do textureatlas ‘vehicles’ e a textura inicial do veículo.
Na linha 4 habilitamos o corpo físico do veículo e na linha 5 adicionamos o veículo na cena
(GameScene).
E, feando o método constructor, amamos o método this.setMoviment() estudado adiante.

método setMoviment()

fig 155

Este método é responsável por:

• Definir aleatoriamente a textura do veículo (‘car-tru1’ a ‘car-tru5’).


• Ajustar o tamanho do corpo físico conforme o tamanho da textura.
• Definir aleatoriamente a direção do veículo.
• Ajustar o flip em X conforme a diração definida.
• Definir aleatoriamente a velocidade do veículo.

Na linha 9 definimos aleatoriamente a textura concatenando a string ‘car-tru’ com um número


entre 1 e 5 fornecido pelo método Phaser.Math.RND.integerInRange(1, 5). Este método é um

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


215

helper do Phaser. Procure saber mais sobre ele na documentação do Phaser procurando por
Phaser.Math.RND.

Na linha 13 ajustamos o tamanho do corpo físico conforme o tamanho da textura escolhida.


Na linha 15 definimos uma direção aleatoriamente e na linha 18 definimos uma velocidade
aleatoria também.

fig 156

Nas linhas 20 a 27 ajustamos a posição horizontal do veículo de acordo com a direção do mesmo.

fig 157

Método update()
No método update() redefinimos o veículo caso tenha ultrapassado o lado esquerdo ou direito
da tela, executando novamente o método this.setMoviment().

fig 158

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


216 Chien

classes/VehiclesGroup.js
Nesta classe instanciamos 9 veículos e adicionamos os mesmos dentro do grupo.

fig 159

Na figura seguinte temos a tela do game com a posição dos 9 veículos.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


217

fig 160

Voltando ao código. Na linha 4 amamos a classe herdada passando como parâmetros o mundo
físico e a scene.
Na linha 5 adicionamos o grupo da scene.
Na linha 6 habilitamos que o método this.update() desta classe rode a cada frame do game.
Nas linhas 7 e 8 criamos e adicionamos ao grupo 9 veículos com posições y variando de 100 a
500px.
Na linha 10 amamos o método this.setDepth(200, 1) este método definirá a profundidade
dos veículos deste grupo a partir de 200, incrementando 1 para cada veículo. Então a profundidade
dos veículos será: 200, 201, 202, 203, 204, 205, 206, 207, 208.

classes/Egg.js
Nesta classe definimos a imagem do ovo.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


218 Chien

fig 161

Na linha 3 amamos a classe herdada passando a scene, a posição x e y do ovo, e a imagem do


ovo carregada na PreloaderScene.
Na linha 4 habilitamos o corpo físico do ovo para que a personagem possa colidir com o mesmo.
Na linha 5 adicionamos o ovo na scene.

classes/EggsGroup.js

fig 162

Esta classe é responsável por espalhar os ovos pela scene do game.


Comentaremos apenas o método reset(). Este método quando é amado primeiramente
“limpa” o grupo apagando todos os ovos.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


219

Na linha 13 nós carregamos na variável ovos um array com a posição dos ovos embaralhados
(com o helper Phaser.Math.RND.suffle). O array this.mundo.eggs vem do objectlayer “posicao”
no tilemap.
Na linha 14 definimos que colocaremos na tela apenas 20 ovos, ignorando o resto. Como o array
foi embaralhado aleatoriamente, esses 20 ovos ocuparam posições aleatórias.
Na linha 15 instanciamos a classe Egg dentro do grupo.

classes/Gui.js

fig 163

Esta é a classe, que herda de Phaser.GameObjects.Container, exibe o score e a quantidade de


ovos capturados.
A classe pai, Phaser.GameObjects.Container, é um container de objetos de exibição. É muito
útil para agrupar objetos de exibição de forma a controlar suas posições relativa por meio da
posição do container.
Nas linhas de 5 a 13 criamos um objeto de texto this.txtScore definindo a fonte “PressStart2P”
com tamanho 20px, definimos também uma cor para o texto, uma cor para o contorno e a cor do
contorno.
Na linha 16 adicionamos o objeto ao container.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


220 Chien

fig 164

Nas linhas de 17 a 25 criamos um objeto de texto this.txtOvos definindo a fonte “PressStart2P”


com tamanho 20px, definimos também uma cor para o texto, uma cor para o contorno e a cor do
contorno.
Na linha 28 adicionamos o objeto no container.
fig 165

fig 165

Na linha 29 adicionamos o container na scene.


Na linha 30 definimos o fator de scroll como 0 (como nosso map é do mesmo tamanho da tela e
a nossa câmera não de move, esta linha pode ser suprimida).
Na linha 31 definimos a profundidade do container como 100 para garantir que não será
sobreposto por outro objetos na scene.
Nas linhas 32 e 33 imprimimos os textos na tela.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


221

### Método update()


Este método será adicionado posteriormente ao método update() da GameScene.
## classes/Acao.js
Esta classe é responsável por tratar as ações necessárias no jogo.
fig 166

fig 166

Na linha 1 importamos a classe GameOver que veremos mais adiante.


Nas linhas 5 a 7 carregamos as variáveis this.gui, this.ovosethis.iencom os objetos
correspondentes a partir do parâmetroscene“. Para que isso ocorra é necessário que a esta
classe seja instanciada após as classes Gui, Ovos e Chien, na GameScene.
fig 167

fig 167

Nas linhas de 9 a 13 tratamos a ação “atropelou”.


Primeiramente paramos a música do jogo. Em seguida mudamos a variável this.scene.sys.game.model.sta
para “perdeu”.
Na linha 12 amamos o método this.chicken.reset() já estudado anteriormente.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


222 Chien

Na linha 13 instanciamos a classe GameOver que é responsável por colocar na tela alguns objetos
de exibição como textos e um botão para reiniciar e outro para voltar ao MenuScene.
fig 168

fig 168

No método pegouOvo() atualizamos as variáves de dados e a gui do game.


fig 169

fig 169

O método pegouTudo() ainda não tem nenhuma lógica implementada. Você pode aproveitar e
criar alguma coisa aqui.
fig 170

fig 170

No método chegou() tocamos a música de vitória e implementamos a seguinda lógica para somar
pontos:

• O jogador só pontua se colheu ovos.


• anto mais ovos colhidos, maior é a pontuação.
• Na pontuação existe um fator aleatório para quebrar a pontuação em valores unitários.

Na linha 29 amamos o método this.ovos.reset() que vem da classe EggsGroup. Da mesma


forma na linha 30 amamos a classe this.chicken.reset(), e na linha 31 atualizamos a gui.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


223

classes/Colisoes.js
Esta classe, como o nome sugere, trata as colisões entre os objetos do game.

fig 171

Nas linha 5 a 7 carregamos nas variáveis this.chicken, this.ovos e this.veiculos os objetos


correspondentes passados por parâmetro. Lembrando que ovos e veiculos são grupos, e chicken
é um objeto só.

fig 172

Nas linhas 11 e 12 amamos o método this.ovoChicken(ovo) quando houver sobreposição entre


a personagem e o vo.

fig 173

Nas linha 16 a 17 idem.

Método ovoChicken()
Este método trata a sobreposição da personagem com o ovo.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


224 Chien

fig 174

Na linha 22 o ovo é destruído e na linha 24 tocamos o som do ovo.


Na linha 26 emitimos o evento ‘pegou_ovo’.
Se os ovos acabaram emitimos o evento ‘pegou_tudo’ na linha 29.

Método veiculoChicken().

fig 175

Toca o som da personagem na linha 36, e na linha 38 emite o evento ‘atropelou’.

classes/Animacoes.js
Nesta classe criamos todas as animações do game e não necessita comentários. Abra o arquivo
para ver mais.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


225

classes/Audio.js
Nesta classe criamos todos os objetos de áudio do game.

fig 176

classes/Button.js
Nesta classe criamos o botão que será instanciado em algumas scenes.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


226 Chien

fig 177

Na linha 5 adicionamos o botão na scene.


Nas linhas 8 e 9 habilitamos a interatividade, para que o botão responda aos eventos do mouse.
Nas linhas 14 e 15, quando o botão é pressionado, diminuímos a sua escala para 90%.
Nas linhas 21 e 22, quando o botão é solto, voltamos a escala para 100% e amamos a scene alvo.
Nas linhas 27 e 28 criamos o seer para a variável this._target.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


Flying bee
Neste jogo nosso objetivo é matar as abelhas clicando sobre elas. Inicialmente este jogo foi
pensado para mobile, pois a jogabilidade fica bem melhor com o tou do que com o mouse,
por isso você vai perceber que a tela do game está em formato retrato (altura > largura). No
entanto optamos por incluí-lo no curso como um bonus. Você encontra gratuitamente um curso
na Udemy que ensina publicar um app HTML5 na PlayStore. https://www.udemy.com/course/
phonegap-android-playstore
228 Flying bee

fig 178

A base de implementação desse game são as funcionalidades Path e Follower do Phaser, que já
estudamos anteriormente.
Basicamente fazemos o seguinte:

• Criamos um path de 4 pontos aleatórios.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


229

• Criamos o sprite da abelha e o fazemos seguir o path criado.


• ando o jogador consegue clicar na abelha o tempo é resetado.
• O jogador tem 10 segundos para clicar na abelha, e esse tempo diminui a cada nível.

Se você for rodar esse jogo como mobile eu aconselho a diminuir o tempo para 5 segundos pois,
como já dissemos, a jogabilidade com o tou é bem melhor.
Passemos então ao código.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


230 Flying bee

Estrutura de arquivos e pastas

fig 179

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


231

index.html

fig 180

Para este game utlizaremos a fonte BigShouldersDisplay-Medium.tff, que pode ser encontrada no
GoogleFonts. Mas no código fonte já temos disponível. Neste treo de código definimos também
padding e margin para 0 e deixamos um baground preto.

fig 181

Nas linhas 19 e 20 adicionamos uma div que não será visível na tela, só com a função de forçar
o carregamento da fonte.
A partir da linha 21 temos um caso diferente que nos games anteriores. Aqui não vamos
importar as scenes e as classes como módulos, mas como arquivos simples de Javascript. Então
precisaremos importar cada scene e classe como um script no body do html.
Nas linhas 21 e 22 carregamos a biblioteca do Phaser e o script de configuração.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


232 Flying bee

fig 182

Nas linhas 24 a 29 carregamos as classes do game.

fig 183

Nas linhas 31 a 35 carregamos as scenes, e na linha 37 carregamos o script de inicialização do


game.
Os scripts precisam ser carregados nesta ordem para que o código funcione.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


233

game.js

fig 184

Aqui registramos as scenes e na linha 13 instanciamos e damos início ao game. Observe que não
precisamos utilizar de import porque já carregamos todos os scripts no index.html.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


234 Flying bee

scene/BootScene.js

fig 185

scene/CreditsScene.js
Esta classe não está implementada, mas o código roda sem ela.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


235

fig 186

scene/PreloaderScene.js
Aqui são carregados os assets do game.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


236 Flying bee

fig 187

fig 188

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


237

fig 189

fig 190

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


238 Flying bee

fig 191

fig 192

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


239

fig 193

fig 194

fig 195

fig 196

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


240 Flying bee

scene/MenuScene.js

fig 197

fig 198

Classes do game
Antes de continuarmos a análise da GameScene, vamos estudar as classes dos objetos do jogo.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


241

class/Gui.js
Esta classe é responsável por mostrar o score e o level em que o jogo se encontra. A implementa-
ção herda de Phaser.GameObjects.Container, sendo portanto um container onde estão os textos
que mostram as informações.

fig 199

fig 200

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


242 Flying bee

fig 201

fig 202

class/Timer.js
Esta classe é responsável por executar a contagem regressiva e emitir o evento ‘endtime’ se a
contagem egar a zero.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


243

fig 203

fig 204

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


244 Flying bee

fig 205

fig 206

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


245

fig 207

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


246 Flying bee

fig 208

class/Bee.js
Esta é a classe que define a abelha. Ela é responsável por criar a curva a ser seguida pela abelha,
criar as animações, escutar os eventos de cli na abelha, entre outras coisas.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


247

fig 209

fig 210

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


248 Flying bee

fig 211

fig 212

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


249

fig 213

fig 214

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


250 Flying bee

fig 215

fig 216

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


251

fig 217

fig 218

class/Death.js
Esta classe herda de Phaser.GameObjects.Sprite e é responsável por mostrar a abelha morrendo.
A lógica consiste em substituir a abelha por esse sprite adicionado exatamente da posição da
abelha. Vamos entender melhor quando estudarmos a GameScene.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


252 Flying bee

fig 219

class/Message.js
Esta classe é bem simple. A função dela é mostrar no centro da tela uma mensagem de texto. Ela
será utilizada apenas para colocar a mensagem de “Game Over” na tela. Não seria tão necessário
criar uma classe só para isso ao invés de criar o objeto texto diretamente na GameScene, no
entanto optamos por fazer dessa forma por questões de não quebrar a padrão de desenvolvimento
que estamos utilizando no game.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


253

fig 220

class/GameSound.js
Aqui definimos a música e os sons do game, como já vimos nos games anteriores.

fig 221

Nas linhas 4 a 6 instanciamos os objetos de som a partir do método this.scene.sound.add().


Este método vem da scene passada como parâmetro.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


254 Flying bee

fig 222

No método play() tocamos em loop a música e o som da abelha. E no método stop() paramos
esses sons.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


255

fig 223

No método pause() pausamos a música e o som da abelha, e no método splash() tocamos o som
da morte.

scene/GameScene.js
Aqui temos a alma do game. Dentro desta classe instanciamos todas as outras classes já vistas
até aqui.

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


256 Flying bee

fig 224

fig 225

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


257

fig 226

fig 227

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


258 Flying bee

fig 228

fig 229

fig 230

Criação de jogos HTML5 com Javascript e Phaser - gidenilson@gmail.com


Conclusão
Neste curso iniciamos o desenvolvimento de Jogos HTML5 utilizando o Javascript e a biblioteca
Phaser. Este material não esgota o tema, pelo contrário, dá apenas uma iniciação no Phaser e
incentiva a continuação dos estudos pois esse framework tem muito mais a oferecer.
Links importantes
título link
Phaser http://phaser.io
Phaser learn http://phaser.io/learn
Phaser exemplos hp://phaser.io/examples
Phaser 3.20.1 hps://github.com/photonstorm/phaser/tree/v3.20.1
Phaser documentação hps://photonstorm.github.io/phaser3-docs
Liera hp://kvazars.com/liera
Tiled hps://www.mapeditor.org
Curso Phonegap hps://www.udemy.com/course/phonegap-android-
playstore
OpenGameArt hps://opengameart.org
GoogleFonts hps://fonts.google.com
FreeSound hps://freesound.org
Free Texture Paer hp://free-tex-paer.com
Código fonte do livro hps://github.com/gidenilson/cursophaser3

Você também pode gostar