HTML5 Game Development

with Phaser Part 2

Matt Wilber

@greenzeta

greenzeta.com

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

 

What Else can Phaser Do?

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 games.

Lots. But let's focus on two big ones:

(DEMO)

Advantages of using Tiled:

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

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

Let's Make a Game!

Start with 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.

  • 65
Loading comments...

More from Matthew Wilber