Image for post
Image for post

HTML5 Game Development with Phaser

Let’s Make a Game

Image for post
Image for post

Step 1: Installing Phaser

npm install — save phaser
npm install
npm start

Step 2: Game Object

import ‘phaser’;
import { GameScene } from ‘./scenes/GameScene’;
const gameConfig = {
type: Phaser.AUTO,
width: 800,
height: 600,
parent: ‘phaser-game’,
dom: {
createContainer: true
},
physics: {
default: ‘arcade’,
arcade: {
gravity: { y: 900 },
debug: false
}
},
scene: [
GameScene
]
};
new Phaser.Game(gameConfig);

Step 3: Adding a Background Image

import Phaser from ‘phaser’;export class GameScene extends Phaser.Scene {
constructor() {
super({
key: ‘GameScene’
});
}
preload() {
this.load.image(‘background’, ‘assets/images/background.png’);
}
create() {
// Add the background image
this.add.image(400, 300, ‘background’);
}
update() { }}

Step 4: Add a Player Character

Image for post
Image for post
this.load.spritesheet(‘zeta’,
‘assets/images/zeta_spritesheet.png’,
{ frameWidth: 40, frameHeight: 60 }
);
this.player = this.createPlayer();
createPlayer() {
let player = this.physics.add.sprite(100, 450, ‘zeta’);
player.setBounce(0.2);
player.setCollideWorldBounds(true);
return player;
}

Step 5: Add Simple Keyboard Controls

this.cursors = this.input.keyboard.createCursorKeys();
if (this.cursors.left.isDown){
this.player.setVelocityX(-200);
}else if (this.cursors.right.isDown){
this.player.setVelocityX(200);
}else{
this.player.setVelocityX(0);
}
if (this.cursors.up.isDown && this.player.body.touching.down){
this.player.setVelocityY(-750);
}

Step 6: Define Character Animation

this.initAnimation();
initAnimation() {
this.anims.create({
key: ‘left’,
frames: this.anims.generateFrameNumbers(‘zeta’, { start: 0, end: 3 }),
frameRate: 30,
repeat: -1
});
this.anims.create({
key: ‘turn’,
frames: [ { key: ‘zeta’, frame: 4 } ],
frameRate: 30
});
this.anims.create({
key: ‘right’,
frames: this.anims.generateFrameNumbers(‘zeta’, { start: 5, end: 8 }),
frameRate: 30,
repeat: -1
});
}
if (this.cursors.left.isDown){
this.player.setVelocityX(-200);
this.player.anims.play(‘left’, true);
}else if (this.cursors.right.isDown){
this.player.setVelocityX(200);
this.player.anims.play(‘right’, true);
}else{
this.player.setVelocityX(0);
this.player.anims.play(‘turn’);
}

Step 7: Add Some Platforms

Image for post
Image for post
this.load.image(‘ground’, ‘assets/images/ground.png’);
this.load.image(‘wall’, ‘assets/images/wall.png’);
this.load.image(‘platform’, ‘assets/images/platform.png’);
this.platforms = this.createPlatforms();
createPlatforms() {
let platforms = this.physics.add.staticGroup();
platforms.create(400, 270, ‘platform’);
platforms.create(400, 572, ‘ground’);
return platforms;
}
this.physics.add.collider(this.player, this.platforms);

Step 8: Enemy Bot

Image for post
Image for post
this.load.image(‘bot’, ‘assets/images/security_bot.png’);
this.bots = this.physics.add.group();
this.physics.add.collider(this.bots, this.platforms);
this.spawnBot();
spawnBot(){
this.bots.create(100, 75, ‘bot’).setVelocityX(100);
}

Steps 9&10: Collision Handlers

this.walls = this.createWalls();createWalls() {
let walls = this.physics.add.staticGroup();
walls.create(0, 300, ‘wall’).setActive(true);
walls.create(800, 300, ‘wall’).setActive(true);
return walls;
}
this.physics.add.collider(this.bots, this.walls, this.handleCollisionWall.bind(this));this.physics.add.collider(this.player, this.bots, this.handleCollisionEnemy.bind(this));handleCollisionWall(event, collider){
if(collider.body.touching.left){
event.setVelocityX(-100);
}else if(collider.body.touching.right){
event.setVelocityX(100);
}
return true;
}
handleCollisionEnemy(event, collider) {
this.scene.start(‘EndScene’);
}

Step 11: End Scene

Image for post
Image for post
import { EndScene } from ‘./scenes/EndScene’;
scene: [
GameScene,
EndScene
]
import Phaser from ‘phaser’;export class EndScene extends Phaser.Scene {  constructor() {
super({
key: ‘EndScene’
});
}
preload() {
this.load.image(‘end_splash’, ‘assets/images/end_splash.png’);
}
create() {
// Add the background image
this.splash = this.add.image(400, 300, ‘end_splash’);
this.splash.setInteractive().on(‘pointerdown’, () => {
this.scene.start(‘IntroScene’);
});
}
}

Step 12: Door Switch

this.levelCt = 1;
this.load.spritesheet(‘door’,
‘assets/images/door.png’,
{ frameWidth: 64, frameHeight: 64 });

this.door = this.createDoors();
this.doorsign = this.createDoorSign();

this.physics.add.overlap(this.player, this.door, this.handleOverlapDoor.bind(this));
this.doorsign.setText(this.levelCt);

createDoors(){
let door = this.physics.add.staticGroup();
// Entry door is inactive
door.create(400, 508, ‘door’, 0, true, false);
// Add an exit door
door.create(700, 508, ‘door’, 3);
return door;
}
createDoorSign(){
this.add.text(380, 410, ‘LEVEL’, { fontSize: ‘12px’, fill: ‘#ff0000’, align: ‘center’, fontFamily: ‘sans-serif’ });
return this.add.text(385, 420, ‘0’, { fontSize: ‘48px’, fill: ‘#ff0000’, align: ‘center’, fontFamily: ‘sans-serif’ });
}
handleCollisionEnemy(player, bot) {
if(bot.active){
this.scene.start(‘EndScene’);
}else{
let tmpbot = this.physics.add.staticSprite(bot.x, bot.y, ‘bot’);
tmpbot.anims.play(‘botAsplode’);
bot.destroy();
this.botKillCount++;
}
}
handleOverlapDoor(event, collider) {
if(collider.active){
// Load the next scene
this.scene.start(
this.scene.manager.getAt(this.scene.getIndex()+1) );
}
}

Step 13: Level System

Image for post
Image for post
import { Level1 } from ‘./levels/level1’;
import { Level2 } from ‘./levels/level2’;

scene: [
Level1,
Level2,
EndScene
]
import { GameScene } from ‘../scenes/GameScene’;export class Level1 extends GameScene{
constructor() {
super({ key: ‘Level1’ });
this.levelCt = 1;
}
createPlatforms() {
let platforms = super.createPlatforms();
platforms.create(100, 180, ‘platform’);
platforms.create(500, 180, ‘platform’);
platforms.create(700, 360, ‘platform’);
platforms.create(300, 360, ‘platform’);
return platforms;
}
createDoors(){
let door = super.createDoors();
// Add an exit door
door.create(100, 132, ‘door’, 3);
return door;
}
create() {
super.create();
this.time.addEvent({
delay: 5000,
callback: (event)=>{
this.spawnBot(‘left’);
},
callbackScope: this,
repeat: 1
});
}
}

Step14 (master branch): Splash Screen

Image for post
Image for post
import { IntroScene } from ‘./scenes/IntroScene’;scene: [
IntroScene,
Level1,
Level2,
EndScene
]
import Phaser from ‘phaser’;export class IntroScene extends Phaser.Scene {  constructor() {
super({ key: ‘IntroScene’ });
}
preload() {
this.load.image(‘splash’, ‘assets/images/intro_splash.png’);
}
create() {
// Add the background image
this.splash = this.add.image(400, 300, ‘splash’);
this.splash.setInteractive().on(‘pointerdown’, () => {
this.scene.start(‘Level1’);
});
}
}

A professional web developer for over 15 years. For more information, visit greenzeta.com and follow his latest web experiments @greenzeta on twitter.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store