Desenvolvimento de Jogos em HTML5 com Phaser

#cpbr9 #inovacaoedesenvolvimento

Talita Pagani | @talitapagani

Quem sou

Bacharel e mestranda em Ciência da Computação.

 

Pesquisadora em Interação Humano-Computador (IHC) e Acessibilidade Web.

Professora.

 

Membro do Grupo de Especialistas em Acessibilidade Web do W3C.

Um pouco da minha história com jogos em HTML5...

2012

2013

Tentativa de fazer uma engine própria, mas não levei adiante.

2014

@soapdog

Vieses do desenvolvimento de jogos em HTML5

Canvas é uma API de propósito geral para desenho e não focada em jogos

Vieses do desenvolvimento de jogos em HTML5

Alguns jogos consumiam muito processamento por não utilizar de forma eficiente o canvas

Vieses do desenvolvimento de jogos em HTML5

Ainda hoje, nem todo framework/engine de jogos é adequada para mobile

Vieses do desenvolvimento de jogos em HTML5

Muitos frameworks centralizam o jogo em um único canvas.

Vieses do desenvolvimento de jogos em HTML5

1 Jogo != 1 Canvas

Princípios para uma boa arquitetura de jogos em HTML5

Canvas para cenário

Múltiplos canvas

Elementos em HTML

Canvas do cenário

Canvas 2

Canvas 3

1000 x 1

HTML

Por que HTML5?

  • Interoperabilidade
  • Uso de tecnologias abertas
  • Sem plugins
  • Integração com features de redes sociais com maior facilidade
  • Não vou precisar comparar com o Flash, né?

Anatomia básica de um jogo

Assets

Os recursos do jogo, como imagens, spritesheets e sons

Lógica

O próprio JavaScript

Gráficos

O Canvas

Input

Eventos de interação do usuário com o jogo, como pressionar uma tecla ou tocar na tela

Multiplayer

WebSockets

Sons e Música

A tag <audio>

Anatomia básica de um jogo

JavaScript

Comportamentos, eventos, lógica, mecânica do jogo

HTML

<canvas>, <audio>, <video>, conteúdo textual

SVG

Gráficos, cenários vetoriais e animações

CSS

Transições, controles, formatação e apresentação

Anatomia básica de um jogo

Sprites

Fluxo de um jogo

Start /

Input

Update

Render

Draw

Loop

Por que o Phaser?

Leve e otimizado para uso em dispositivos móveis.

Uso híbrido de Canvas e tags HTML5.

Open-source.

Rápida curva de aprendizagem.

Comunidade ativa.

Principais recursos

WebGL e Canvas

Preloader

Physics

Sprites

Groups

Animation

Particles

Camera

Input (incluindo touch)

Sound

Tilemaps

Device Scaling

Plugin System

Mobile Browser

Suporte para desenvolvedores

Vantagens

  • Suporte nativo para mobile
  • Documentação extensa com vários exemplos
  • Uma das engines com a sintaxe mais fácil
  • Pouco código para realizar diversas ações

E ainda possui um editor online!

http://phaser.io/sandbox

Recursos básicos

var game = new Phaser.Game(800, 600, 
                            Phaser.AUTO, 'game_canvas', 
                            { preload: funcao_de_preload, 
                              create: funcao_de_create, 
                              update: funcao_de_update });

Criando um novo jogo

Recursos básicos

function preload() {
    // Onde todos os assets do jogo são carregados
}

function create() {
    /* É onde os elementos do jogo são criados e posicionados,
        como os personagens, o tilemap, etc. */
}

function update() {
    /* É o game loop, ou seja, onde o jogo acontece de fato */
}

Os principais estados do jogo

Recursos básicos

var game = new Phaser.Game(800, 600, Phaser.AUTO, '');

var Start_Screen = {
    preload: function () { /*...*/ },

    create:  function () { /*...*/ },

    outra_funcao:  function () { /*...*/ }
};

game.state.add('Start', StartScreen);

game.state.start('Start');

E se eu precisar adicionar várias telas (cenas) ao jogo?

Exemplo

Exemplo: preload

function preload() {

    game.load.image('sky', 'assets/sky.png');
    game.load.image('ground', 'assets/platform.png');
    game.load.image('star', 'assets/star.png');
    game.load.spritesheet('dude', 'assets/dude.png', 32, 48);

}

Exemplo: create

function create() {
    game.physics.startSystem(Phaser.Physics.ARCADE);

    game.add.sprite(0, 0, 'sky');

    var platforms = game.add.group();
    platforms.enableBody = true;

    var ground = platforms.create(0, game.world.height - 64, 'ground');
    ground.scale.setTo(2, 2);
    ground.body.immovable = true;

    var ledge = platforms.create(400, 400, 'ground');
    ledge.body.immovable = true;
    ledge = platforms.create(-150, 250, 'ground');
    ledge.body.immovable = true;
}

Exemplo: update

function update () {

    game.physics.arcade.collide(player, platforms);

    player.body.velocity.x = 0;

    if (cursors.left.isDown)
    {
        player.body.velocity.x = -250;
    }
    else if (cursors.right.isDown)
    {
        player.body.velocity.x = 250;
    }

    if (jumpButton.isDown && (player.body.onFloor() || player.body.touching.down))
    {
        player.body.velocity.y = -400;
    }
}

Sprites e personagens

player = game.add.sprite(32, game.world.height - 150, 'dude');
game.physics.arcade.enable(player);

// Propriedades físicas do personagem
player.body.bounce.y = 0.2;
player.body.gravity.y = 300;
player.body.collideWorldBounds = true;

Animações para andar para a esquerda e direita
player.animations.add('left', [0, 1, 2, 3], 10, true);
player.animations.add('right', [5, 6, 7, 8], 10, true);

E mais...

// Gerenciando pontuação e adicionando textos
var score = 0, scoreText;

scoreText = game.add.text(16, 16, 'Score: 0', 
            { fontSize: '32px', fill: '#000' });

score += 10;
scoreText.text = 'Score: ' + score;

// Removendo objeto depois de colidir

meu_sprite.kill();

Agora compare...

// Escrevendo um texto em outra engine

var loadingText = Crafty.e("2D, DOM, Text")
		.attr({w: 500, 
                       h: 20, x: ((Crafty.viewport.width) / 2), 
                       y: (Crafty.viewport.height / 2), z: 2})
		.text('Carregando...')
		.css({fontFamily: 'Impact', fontSize: '12px', color: '#FFF'});
entity
    .attr({x: ((parent.x+(parent.w/2))-8), y: ((parent.y+(parent.h/2))-8), z: 300})
    .collision(new Crafty.polygon([8,0],[5,3],[5,12],[3,13],[3,15],[14,15],[14,13],[12,3],[9,0]))
    .onHit("nave", function(hit) {
    	if (!explodiu)
    	{
    		Crafty.audio.add("boom", "web/audio/bullet_boom.mp3");
    		Crafty.audio.play("boom",1);
    		
    		explodiu = true;
    	}
    	
    	for(i = 0; i < hit.length; i++) {
    		var nave = hit[i]['obj'];
    					
		var explosion = Crafty.e("2D, Canvas, SpriteAnimation, explosion")
					.attr({x: nave.x, y: nave.y, z: 300})
					.animate('explosion', 0, 0, 8) // setup animation
					.animate('explosion', 8, 0) // start animation
    								    
    		nave.destroy();
    	}
    	
    	this.destroy();
    	
    	var evt = document.createEvent("Event");
    	evt.initEvent("SpaceshipEvent", true, true);
    	document.dispatchEvent(evt);
    	
    }, function() {
    	explodiu = false;
    })

Para saber mais

http://phaser.io/examples

https://leanpub.com/buildinggamesforfirefoxos

http://tutorialzine.com/2015/06/making-your-first-html5-game-with-phaser/

Obrigada!

Perguntas?

@talitapagani

talita.cpb@gmail.com

slides.com/talitapagani/cpbr9-phaser/

Made with Slides.com