HTML5 Game Development

with Phaser Part 2

Matt Wilber

@greenzeta

Browser Game Portfolio

Combat 2077

Visionary Media 2000

Acme Agent Hunter

Warner Bros. 2003

Go Turtle Go!

Little Tikes 2011

Peanut Butter Art

Hormel 2015

Smashion

VFiles 2016

Puppy Club

Mini Trading Cards Co. 2018

Part 1 Recap

Phaser Game API

  • Scenes
  • Images
  • Sprites
    • Animation with
      sprite sheets
  • Physics
    • Colliders
  • ​Inputs

 

Links to source and tutorial available on GreenZeta.com

Two Powerful Features

Tile Maps

  • Build large play fields by reusing small images (tiles). 
  • Design levels without writing code.
  • Edit your game without re-compiling.

 

PlugIns

  • Extend Phaser's API.
  • Create reusable components to share between projects.

Let's Make a Game!

(DEMO)

  • No programming or compiling
  • Instant preview
  • Easy level tweaking
  • Add new artwork easily
  • Works with most game frameworks

iled

Create a New Tile Map

Add a ‘collide’ property to tiles

‘Fill’ & ‘Stamp’ Tools

Define ‘terrain’ tiles

‘Terrain Brush’ tool

Add an ‘Interactive’ layer

Add a ‘Script’ layer.

Export JSON file for Phaser

The Phaser Project

The complete project is available on GitHub

github.com/mwilber/the-legend-of-zeta

Based on the GreenZeta Webpack Boilerplate

github.com/mwilber/gz-webpack-boilerplate

Project Setup

github.com/mwilber/the-legend-of-zeta  >  Step1

Much of the project is built using the techniques discussed in the Zeta Bros. demo from Part 1. This demo focuses on the use of PlugIns and Tile Maps in building a game.

 

Start with the game scene and player character set up with a tracking camera, animations and input controls.

Global Plugins

import { GzRpgCharacterPlugin } from './plugins/GzRpgCharacter';

const gameConfig = {

  	...
  
	plugins: {
 		global: [
			{ key: 'GzRpgCharacterPlugin', plugin: GzRpgCharacterPlugin, start: true }
		]
	},

  	...
  
};

src/main.js

github.com/mwilber/the-legend-of-zeta  >  Step1

this.player = this.add.rpgcharacter({
	x: 400,
	y: 300,
	name: 'zeta',
	image: 'zeta',
	speed: 225
});

src/scenes/GameScene.js

Add Tilemap Layers

...
    
preload() {
	this.load.image('tiles', 'assets/tilemaps/Area-51.png');
	this.load.tilemapTiledJSON('map', 'assets/tilemaps/area-51.json');;
}

create(settings) {
 		
	...
        
	// Load map json from Tiled
	const map = this.make.tilemap({ key: 'map' });
	// settings.tiledKey is the name of the tileset in Tiled
	const tileset = map.addTilesetImage('Area-51', 'tiles');
	// layer key is the layer name set in Tiled
	const backgroundLayer = map.createStaticLayer('Background', tileset, 0, 0);
	const interactiveLayer = map.createStaticLayer('Interactive', tileset, 0, 0);
	const overheadLayer = map.createStaticLayer('Overhead', tileset, 0, 0);

	// Place the player above the tile layers
	this.player.setDepth(10);
	// Place the overhead layer above everything else
	overheadLayer.setDepth(20);

	...

}

src/scenes/GameScene.js

github.com/mwilber/the-legend-of-zeta  >  Step2

Tile Layer Interaction

...

create(settings) {

	...

	// Identify the collision property set in the interactive layer in Tiled
	interactiveLayer.setCollisionByProperty({ collide: true });
	// Set up collision detection between the player and interactive layer
	this.physics.add.collider(this.player, interactiveLayer);
  
  	...

src/scenes/GameScene.js

github.com/mwilber/the-legend-of-zeta  >  Step3

Scene PlugIn

github.com/mwilber/the-legend-of-zeta  >  Step4

import { GzDialog } from './plugins/GzDialog';

const gameConfig = {
	
  	...
  
	plugins: {
		
      	...
      
		scene: [
			{ key: 'gzDialog', plugin: GzDialog, mapping: 'gzDialog' }
		]
	},
	
  	...
  
};

src/main.js

this.gzDialog.setText('This is a test. Hello World!');

src/scenes/GameScene.js

Add Object Layer

export class GameScene extends Phaser.Scene {
	
  	...

	preload() {
		this.load.json('scriptdata', 'assets/data/script.json');
		
      	...
	}

	create(settings) {

		...

		// Extract objects from the object layer
		const objectLayer = map.getObjectLayer('Script');
		// Convert object layer objects to Phaser game objects
		if(objectLayer && objectLayer.objects){
			objectLayer.objects.forEach(
				(object) => {
					let tmp = this.add.rectangle((object.x+(object.width/2)), (object.y+(object.height/2)), object.width, object.height);
					tmp.properties = object.properties.reduce(
						(obj, item) => Object.assign(obj, { [item.name]: item.value }), {}
					);
					this.physics.world.enable(tmp, 1);
					this.physics.add.collider(this.player, tmp, this.HitScript, null, this);
				}
			);
		}

		...

		// Get script data preloaded from script.json
		this.script = this.cache.json.get('scriptdata');

	}

	update(time, delta) {

		// Close the dialog on spacebar press
		if( this.gzDialog.visible ){
			if( this.cursors.space.isDown ){
				this.gzDialog.display(false);
			}
			return false;
		}
		
      	...
	}


	HitScript(player, target){
		if(target.properties.name && !this.gzDialog.visible){
			player.anims.stopOnRepeat();
			this.gzDialog.setText(this.script[player.name][target.properties.name]);
		}
	}

}

src/scenes/GameScene.js

github.com/mwilber/the-legend-of-zeta  >  Step5

Follow @greenzeta on Twitter

greenzeta.com

Phaser Website

phaser.io

HTML5 Game Development with Phaser Part 2

By Matthew Wilber

HTML5 Game Development with Phaser Part 2

TBA Presentation for the Fredericksburg Developer Group.

  • 2,765