Create a HTML5 game like Planet Revenge using Phaser and ARCADE physics – step 2

Read all posts about "" game
Let’s continue the step by step creation of Planet Revenge after the first four steps. We are going to add a deadly floor and ceiling, using Tiled Map Editor to create the tile based level. CREATING THE LEVEL First we create the map, a 30×20 tile based level with 32×32 tiles. Then we create the tileset, we are calling it “deadly” because tiles will be deadly. And finally we draw the floor and the ceiling Once you export the map as JSON, you will have something like this:
{ "height":20,
 "layers":[
        {
         "data":[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
         "height":20,
         "name":"Tile Layer 1",
         "opacity":1,
         "type":"tilelayer",
         "visible":true,
         "width":30,
         "x":0,
         "y":0
        }],
 "nextobjectid":1,
 "orientation":"orthogonal",
 "properties":
    {

    },
 "renderorder":"right-down",
 "tileheight":32,
 "tilesets":[
        {
         "firstgid":1,
         "image":"tiles\/deadly.png",
         "imageheight":32,
         "imagewidth":32,
         "margin":0,
         "name":"deadly",
         "properties":
            {

            },
         "spacing":0,
         "tilecount":1,
         "tileheight":32,
         "tilewidth":32
        }],
 "tilewidth":32,
 "version":1,
 "width":30
}
Be sure the paths to images have been set the right way, then it’s time to import the map into Phaser IMPORTING THE MAP Phaser has native support for tilemaps, so we just have to load both the map and the images, initialize the map and create the layer.
var game;

window.onload = function() {
	game = new Phaser.Game(960, 640, Phaser.AUTO, "");
     game.state.add("PlayGame", playGame);
     game.state.start("PlayGame");
}

var playGame = function(game){};
playGame.prototype = {
     preload: function(){
          game.load.image("spaceship", "assets/sprites/spaceship.png");
          game.load.image("particle", "assets/sprites/particle.png");
          game.load.tilemap("level_0001", "assets/maps/level_0001.json", null, Phaser.Tilemap.TILED_JSON);
          game.load.image("deadly", "assets/maps/tiles/deadly.png");
     },
     create: function(){
          game.scale.pageAlignHorizontally = true;
          game.scale.pageAlignVertically = true;
          game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
          this.map = game.add.tilemap("level_0001");
          this.map.addTilesetImage("deadly", "deadly");
          this.mapLayer = this.map.createLayer("Tile Layer 1");
          this.emitter = game.add.emitter(50, game.height / 2, 50);
          this.emitter.makeParticles("particle");
          this.emitter.gravity = 0;
          this.emitter.setXSpeed(0, 0);
          this.emitter.setYSpeed(0, 0);
          this.emitter.setAlpha(0.5, 1);
          this.emitter.minParticleScale = 0.5;
          this.emitter.maxParticleScale = 1;  
          this.spaceship = game.add.sprite(50, game.height / 2, "spaceship");
          this.spaceship.anchor.set(0.5); 
          game.physics.enable(this.spaceship, Phaser.Physics.ARCADE);
          game.input.onDown.add(this.startLevel, this);    
     },
     startLevel: function(){
          this.spaceship.body.velocity.setTo(200, 0);
          this.spaceship.body.gravity.y = 1000;
          this.engineOn();  
          this.emitter.start(false, 3000, 200);
          game.input.onDown.remove(this.startLevel, this);
          game.input.onDown.add(this.engineOn, this); 
          game.input.onUp.add(this.engineOff, this); 
     },
     engineOn: function(){
          this.spaceship.body.acceleration.y = -2000;
     },
     engineOff: function(){
          this.spaceship.body.acceleration.y = 0;          
     },
     update: function(){
          this.emitter.x = this.spaceship.x;
          this.emitter.y = this.spaceship.y;
          if(this.spaceship.x > game.width + this.spaceship.width){
               game.state.start("PlayGame");    
          }
     }
}
And now we have the tilemap displayed in game. You may have to click on the canvas to let the game start.
Unfortunately, the spaceship does not collide with the walls, so we have to enable collisions. ENABLING COLLISIONS To enable collisions we have to tell Phaser which tile is solid, then check for collision at each game update:
var game;

window.onload = function() {
	game = new Phaser.Game(960, 640, Phaser.AUTO, "");
     game.state.add("PlayGame", playGame);
     game.state.start("PlayGame");
}

var playGame = function(game){};
playGame.prototype = {
     preload: function(){
          game.load.image("spaceship", "assets/sprites/spaceship.png");
          game.load.image("particle", "assets/sprites/particle.png");
          game.load.tilemap("level_0001", "assets/maps/level_0001.json", null, Phaser.Tilemap.TILED_JSON);
          game.load.image("deadly", "assets/maps/tiles/deadly.png");
     },
     create: function(){
          game.scale.pageAlignHorizontally = true;
          game.scale.pageAlignVertically = true;
          game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
          this.map = game.add.tilemap("level_0001");
          this.map.addTilesetImage("deadly", "deadly");
          this.map.setCollision(1);
          this.mapLayer = this.map.createLayer("Tile Layer 1");
          this.emitter = game.add.emitter(50, game.height / 2, 50);
          this.emitter.makeParticles("particle");
          this.emitter.gravity = 0;
          this.emitter.setXSpeed(0, 0);
          this.emitter.setYSpeed(0, 0);
          this.emitter.setAlpha(0.5, 1);
          this.emitter.minParticleScale = 0.5;
          this.emitter.maxParticleScale = 1;  
          this.spaceship = game.add.sprite(50, game.height / 2, "spaceship");
          this.spaceship.anchor.set(0.5); 
          game.physics.enable(this.spaceship, Phaser.Physics.ARCADE);
          game.input.onDown.add(this.startLevel, this);    
     },
     startLevel: function(){
          this.spaceship.body.velocity.setTo(200, 0);
          this.spaceship.body.gravity.y = 1000;
          this.engineOn();  
          this.emitter.start(false, 3000, 200);
          game.input.onDown.remove(this.startLevel, this);
          game.input.onDown.add(this.engineOn, this); 
          game.input.onUp.add(this.engineOff, this); 
     },
     engineOn: function(){
          this.spaceship.body.acceleration.y = -2000;
     },
     engineOff: function(){
          this.spaceship.body.acceleration.y = 0;          
     },
     update: function(){
          game.physics.arcade.collide(this.spaceship, this.mapLayer);
          this.emitter.x = this.spaceship.x;
          this.emitter.y = this.spaceship.y;
          if(this.spaceship.x > game.width + this.spaceship.width){
               game.state.start("PlayGame");    
          }
     }
}
With just a couple of lines now we have collisions enabled.
If you try to drive your spaceship on the floor or on the ceiling you will see the collision in action. DESTROYING THE SPACESHIP We want the spaceship to be destroyed when it hits an obstacle, so we’ll add a callback function to the collision listener
var game;

window.onload = function() {
	game = new Phaser.Game(960, 640, Phaser.AUTO, "");
     game.state.add("PlayGame", playGame);
     game.state.start("PlayGame");
}

var playGame = function(game){};
playGame.prototype = {
     preload: function(){
          game.load.image("spaceship", "assets/sprites/spaceship.png");
          game.load.image("particle", "assets/sprites/particle.png");
          game.load.tilemap("level_0001", "assets/maps/level_0001.json", null, Phaser.Tilemap.TILED_JSON);
          game.load.image("deadly", "assets/maps/tiles/deadly.png");
     },
     create: function(){
          game.scale.pageAlignHorizontally = true;
          game.scale.pageAlignVertically = true;
          game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
          this.map = game.add.tilemap("level_0001");
          this.map.addTilesetImage("deadly", "deadly");
          this.map.setCollision(1);
          this.mapLayer = this.map.createLayer("Tile Layer 1");
          this.emitter = game.add.emitter(50, game.height / 2, 50);
          this.emitter.makeParticles("particle");
          this.emitter.gravity = 0;
          this.emitter.setXSpeed(0, 0);
          this.emitter.setYSpeed(0, 0);
          this.emitter.setAlpha(0.5, 1);
          this.emitter.minParticleScale = 0.5;
          this.emitter.maxParticleScale = 1;  
          this.spaceship = game.add.sprite(50, game.height / 2, "spaceship");
          this.spaceship.anchor.set(0.5); 
          game.physics.enable(this.spaceship, Phaser.Physics.ARCADE);
          game.input.onDown.add(this.startLevel, this);    
     },
     startLevel: function(){
          this.spaceship.body.velocity.setTo(200, 0);
          this.spaceship.body.gravity.y = 1000;
          this.engineOn();  
          this.emitter.start(false, 3000, 200);
          game.input.onDown.remove(this.startLevel, this);
          game.input.onDown.add(this.engineOn, this); 
          game.input.onUp.add(this.engineOff, this); 
     },
     engineOn: function(){
          this.spaceship.body.acceleration.y = -2000;
     },
     engineOff: function(){
          this.spaceship.body.acceleration.y = 0;          
     },
     update: function(){
          game.physics.arcade.collide(this.spaceship, this.mapLayer, function(){
               game.state.start("PlayGame");
          }, null, this);
          this.emitter.x = this.spaceship.x;
          this.emitter.y = this.spaceship.y;
          if(this.spaceship.x > game.width + this.spaceship.width){
               game.state.start("PlayGame");    
          }
     }
}
Now if you run into an obstacle, game will restart.
Now it’s time to add an eye candy effect MAKING THE SPACESHIP EXOLODE With another couple of lines we are going to add a particle explosion and a timer to make level restart, this will make the game look more professional:
var game;

window.onload = function() {
	game = new Phaser.Game(960, 640, Phaser.AUTO, "");
     game.state.add("PlayGame", playGame);
     game.state.start("PlayGame");
}

var playGame = function(game){};
playGame.prototype = {
     preload: function(){
          game.load.image("spaceship", "assets/sprites/spaceship.png");
          game.load.image("particle", "assets/sprites/particle.png");
          game.load.tilemap("level_0001", "assets/maps/level_0001.json", null, Phaser.Tilemap.TILED_JSON);
          game.load.image("deadly", "assets/maps/tiles/deadly.png");
     },
     create: function(){
          game.scale.pageAlignHorizontally = true;
          game.scale.pageAlignVertically = true;
          game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
          this.map = game.add.tilemap("level_0001");
          this.map.addTilesetImage("deadly", "deadly");
          this.map.setCollision(1);
          this.mapLayer = this.map.createLayer("Tile Layer 1");
          this.emitter = game.add.emitter(50, game.height / 2, 50);
          this.emitter.makeParticles("particle");
          this.emitter.gravity = 0;
          this.emitter.setXSpeed(0, 0);
          this.emitter.setYSpeed(0, 0);
          this.emitter.setAlpha(0.5, 1);
          this.emitter.minParticleScale = 0.5;
          this.emitter.maxParticleScale = 1;  
          this.spaceship = game.add.sprite(50, game.height / 2, "spaceship");
          this.spaceship.anchor.set(0.5); 
          game.physics.enable(this.spaceship, Phaser.Physics.ARCADE);
          game.input.onDown.add(this.startLevel, this); 
          this.gameOver = false;   
     },
     startLevel: function(){
          this.spaceship.body.velocity.setTo(200, 0);
          this.spaceship.body.gravity.y = 1000;
          this.engineOn();  
          this.emitter.start(false, 3000, 200);
          game.input.onDown.remove(this.startLevel, this);
          game.input.onDown.add(this.engineOn, this); 
          game.input.onUp.add(this.engineOff, this); 
     },
     engineOn: function(){
          this.spaceship.body.acceleration.y = -2000;
     },
     engineOff: function(){
          this.spaceship.body.acceleration.y = 0;          
     },
     update: function(){ 
          if(!this.gameOver){  
               game.physics.arcade.collide(this.spaceship, this.mapLayer, function(){
                    game.input.onDown.remove(this.engineOn, this); 
                    game.input.onUp.remove(this.engineOff, this);
                    this.emitter.on = false;
                    var explosion = game.add.emitter(this.spaceship.x, this.spaceship.y, 200);
                    explosion.makeParticles("particle");
                    explosion.gravity = 200;
                    explosion.setXSpeed(-150, 150);
                    explosion.setYSpeed(-150, 150);
                    explosion.setAlpha(0.5, 1);
                    explosion.minParticleScale = 0.2;
                    explosion.maxParticleScale = 0.5;  
                    explosion.start(true, 3000, null, 200);
                    this.spaceship.kill();
                    this.gameOver = true; 
                    game.time.events.add(Phaser.Timer.SECOND * 1, function(){
                         game.state.start("PlayGame");
                    }, this);
               }, null, this);               
               this.emitter.x = this.spaceship.x;
               this.emitter.y = this.spaceship.y;
               if(this.spaceship.x > game.width + this.spaceship.width){
                    game.state.start("PlayGame");    
               }
          }
     }
}
Now hit a wall and… BOOOM.
And that’s all for the second step. Next time I’ll show you how to play with levels and gravity. Meanwhile download the source code of each step.

Get the most popular Phaser 3 book

Through 202 pages, 32 source code examples and an Android Studio project you will learn how to build cross platform HTML5 games and create a complete game along the way.

Get the book

214 GAME PROTOTYPES EXPLAINED WITH SOURCE CODE
// 1+2=3
// 100 rounds
// 10000000
// 2 Cars
// 2048
// A Blocky Christmas
// A Jumping Block
// A Life of Logic
// Angry Birds
// Angry Birds Space
// Artillery
// Astro-PANIC!
// Avoider
// Back to Square One
// Ball Game
// Ball vs Ball
// Ball: Revamped
// Balloon Invasion
// BallPusher
// Ballz
// Bar Balance
// Bejeweled
// Biggification
// Block it
// Blockage
// Bloons
// Boids
// Bombuzal
// Boom Dots
// Bouncing Ball
// Bouncing Ball 2
// Bouncy Light
// BoxHead
// Breakout
// Bricks
// Bubble Chaos
// Bubbles 2
// Card Game
// Castle Ramble
// Chronotron
// Circle Chain
// Circle Path
// Circle Race
// Circular endless runner
// Cirplosion
// CLOCKS - The Game
// Color Hit
// Color Jump
// ColorFill
// Columns
// Concentration
// Crossy Road
// Crush the Castle
// Cube Jump
// CubesOut
// Dash N Blast
// Dashy Panda
// Deflection
// Diamond Digger Saga
// Don't touch the spikes
// Dots
// Down The Mountain
// Drag and Match
// Draw Game
// Drop Wizard
// DROP'd
// Dudeski
// Dungeon Raid
// Educational Game
// Elasticity
// Endless Runner
// Erase Box
// Eskiv
// Farm Heroes Saga
// Filler
// Flappy Bird
// Fling
// Flipping Legend
// Floaty Light
// Fuse Ballz
// GearTaker
// Gem Sweeper
// Globe
// Goat Rider
// Gold Miner
// Grindstone
// GuessNext
// Helicopter
// Hero Emblems
// Hero Slide
// Hexagonal Tiles
// HookPod
// Hop Hop Hop Underwater
// Horizontal Endless Runner
// Hundreds
// Hungry Hero
// Hurry it's Christmas
// InkTd
// Iromeku
// Jet Set Willy
// Jigsaw Game
// Knife Hit
// Knightfall
// Legends of Runeterra
// Lep's World
// Line Rider
// Lumines
// Magick
// MagOrMin
// Mass Attack
// Math Game
// Maze
// Meeblings
// Memdot
// Metro Siberia Underground
// Mike Dangers
// Mikey Hooks
// Nano War
// Nodes
// o:anquan
// One Button Game
// One Tap RPG
// Ononmin
// Pacco
// Perfect Square!
// Perfectionism
// Phyballs
// Pixel Purge
// PixelField
// Planet Revenge
// Plants Vs Zombies
// Platform
// Platform game
// Plus+Plus
// Pocket Snap
// Poker
// Pool
// Pop the Lock
// Pop to Save
// Poux
// Pudi
// Pumpkin Story
// Puppet Bird
// Pyramids of Ra
// qomp
// Quick Switch
// Racing
// Radical
// Rebuild Chile
// Renju
// Rise Above
// Risky Road
// Roguelike
// Roly Poly
// Run Around
// Rush Hour
// SameGame
// SamePhysics
// Save the Totem
// Security
// Serious Scramblers
// Shrink it
// Sling
// Slingy
// Snowflakes
// Sokoban
// Space Checkers
// Space is Key
// Spellfall
// Spinny Gun
// Splitter
// Spring Ninja
// Sproing
// Stabilize!
// Stack
// Stick Hero
// String Avoider
// Stringy
// Sudoku
// Super Mario Bros
// Surfingers
// Survival Horror
// Talesworth Adventure
// Tetris
// The Impossible Line
// The Moops - Combos of Joy
// The Next Arrow
// Threes
// Tic Tac Toe
// Timberman
// Tiny Wings
// Tipsy Tower
// Toony
// Totem Destroyer
// Tower Defense
// Trick Shot
// Tunnelball
// Turn
// Turnellio
// TwinSpin
// vvvvvv
// Warp Shift
// Way of an Idea
// Whack a Creep
// Wheel of Fortune
// Where's my Water
// Wish Upon a Star
// Word Game
// Wordle
// Worms
// Yanga
// Yeah Bunny
// Zhed
// zNumbers