Do you like my tutorials?

Then consider supporting me on Ko-fi

Talking about Pyramids of Ra game, Game development, HTML5, Javascript and Phaser.

One month ago I showed you how the HTML5 game engine to create GameBoy blockbuster “Pyramids of Ra” with the first playable level, but the game gets much harder as you progress through the levels, adding new types of tiles. The first new tile you will find is a harder tile which needs the player to cross it twice before disappearing. I placed it on level two of the game, so I am sorry but you have to solve level one before seeing the new tile.
You control the grey circle with a swipe, and you have to walk over all white tiles before returning back to start tile (marked with “S”). The problem is tiles fall down once you stepped over them, so mind your moves. Harder tiles are marked in yellow, and will turn white once you cross them the first time, to disappear when you cross them twice. The source code is still uncommented because I need to optimize it a bit, but it’s nothing new if you are used to Phaser.
var game;

// main game options
var gameOptions = {
	gameWidth: 1000, 
	gameHeight: 800, 
	tileSize: 100, 
	fieldSize: {
          rows: 8,
          cols: 10
     }
}

// game levels
var levels = [
     {
          level:[
               [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
               [0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
               [0, 0, 1, 1, 1, 1, 1, 1, 0, 0],
               [0, 0, 0, 1, 1, 1, 1, 0, 0, 0],
               [0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
               [0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
               [0, 0, 0, 0, 0, 1, 1, 0, 0, 0],
               [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
               ],
          playerPos: new Phaser.Point(5, 2)      
     },
     {
          level:[
               [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 0, 1, 1, 1, 1, 0],
               [0, 1, 1, 0, 0, 1, 1, 1, 1, 0],
               [0, 1, 1, 3, 3, 1, 1, 1, 0, 0],
               [0, 1, 1, 3, 3, 1, 1, 1, 0, 0],
               [0, 0, 0, 0, 0, 0, 3, 3, 0, 0],
               [0, 0, 0, 0, 0, 0, 3, 3, 0, 0],
               [0, 0, 0, 0, 0, 0, 1, 1, 0, 0]
               ],
          playerPos: new Phaser.Point(5, 3)      
     }
];

//

levelNumber = 0;

// when the window finishes loading...
window.onload = function() {	
	game = new Phaser.Game(gameOptions.gameWidth, gameOptions.gameHeight);
     game.state.add("TheGame", TheGame);
     game.state.start("TheGame");
}

var TheGame = function(){};

TheGame.prototype = {
     
     // preloading assets
     preload: function(){
          game.load.spritesheet("tiles", "assets/sprites/tile.png", gameOptions.tileSize, gameOptions.tileSize);
          game.load.image("player", "assets/sprites/player.png"); 
     },
     
     // when the game starts
  	create: function(){
          game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
		game.scale.pageAlignHorizontally = true;
		game.scale.pageAlignVertically = true; 
  		this.createLevel();
          game.input.onDown.add(this.beginSwipe, this);   
  	}, 
     
     // function to create a level
	createLevel: function(){
          this.tilesArray = [];
		this.tileGroup = game.add.group();
          this.tileGroup.x = (game.width - gameOptions.tileSize * gameOptions.fieldSize.cols) / 2;
          this.tileGroup.y = (game.height -  gameOptions.tileSize * gameOptions.fieldSize.rows) / 2;
  		for(var i = 0; i < gameOptions.fieldSize.rows; i++){
               this.tilesArray[i] = [];
			for(var j = 0; j < gameOptions.fieldSize.cols; j++){
                    if(levels[levelNumber].level[i][j] !=0 ){
                         this.addTile(i, j, levels[levelNumber].level[i][j]);
                    }
			}
		}
          this.playerPosition = new Phaser.Point(0, 0);
          levels[levelNumber].playerPos.clone(this.playerPosition);
          this.player = game.add.sprite(levels[levelNumber].playerPos.x * gameOptions.tileSize + gameOptions.tileSize / 2, this.playerPosition.y * gameOptions.tileSize + gameOptions.tileSize / 2, "player");
          this.player.anchor.set(0.5);
          this.tileGroup.add(this.player);
          this.firstMove = true;
	},
     
     // function add a tile at "row" row, "col" column with "val" value
	addTile: function(row, col, val){
		var tileXPos = col * gameOptions.tileSize + gameOptions.tileSize / 2;
		var tileYPos = row * gameOptions.tileSize + gameOptions.tileSize / 2;
		var theTile = game.add.sprite(tileXPos, tileYPos, "tiles");
          if(val == 3){
               theTile.tint = 0xffff88;
          }
		theTile.anchor.set(0.5);
          theTile.tileValue = val;
          theTile.falling = false;
          theTile.tilePosition = new Phaser.Point(col, row);
          this.tilesArray[row][col] = theTile;
	     this.tileGroup.add(theTile);	
	},
     
     // start checking for swipes
     beginSwipe: function(e){
		game.input.onDown.remove(this.beginSwipe, this);
     	game.input.onUp.add(this.endSwipe, this);
     },
     
     // end checking for swipes
     endSwipe: function(e){
          game.input.onUp.remove(this.endSwipe, this);
          var swipeTime = e.timeUp - e.timeDown;
          var swipeDistance = Phaser.Point.subtract(e.position, e.positionDown);
          var swipeMagnitude = swipeDistance.getMagnitude();
          var swipeNormal = Phaser.Point.normalize(swipeDistance);
          if(swipeMagnitude > 20 && swipeTime < 1000 && (Math.abs(swipeNormal.x) > 0.8 || Math.abs(swipeNormal.y) > 0.8)){
               if(swipeNormal.x > 0.8){
                    this.handleMovement(new Phaser.Point(1, 0));
               }
               if(swipeNormal.x < -0.8){
                    this.handleMovement(new Phaser.Point(-1, 0));
               }
               if(swipeNormal.y > 0.8){
                    this.handleMovement(new Phaser.Point(0, 1));
               }
               if(swipeNormal.y < -0.8){
                    this.handleMovement(new Phaser.Point(0, -1));
               }     
          }
          else{
               game.input.onDown.add(this.beginSwipe, this);  
          }
     },
     
     // handling swipes
     handleMovement: function(p){
          if(this.firstMove){
               this.firstMove = false;
               this.tilesArray[this.playerPosition.y][this.playerPosition.x].tileValue = 2;
               this.tilesArray[this.playerPosition.y][this.playerPosition.x].frame = 1;
          }
          else{
               switch(this.tilesArray[this.playerPosition.y][this.playerPosition.x].tileValue){
                    case 1:
                         this.tilesArray[this.playerPosition.y][this.playerPosition.x].falling = true;
                         var tween = game.add.tween(this.tilesArray[this.playerPosition.y][this.playerPosition.x]).to({
                              alpha: 0,
                              width: gameOptions.tileSize / 4,
                              height: gameOptions.tileSize / 4,
                              angle: game.rnd.integerInRange(-15, 15)
                         }, 500, Phaser.Easing.Linear.None, true);
                         tween.onComplete.add(function(target){
                              this.tilesArray[target.tilePosition.y][target.tilePosition.x] = null;
                              target.destroy();
                         }, this);
                         break;
                    case 3:
                         this.tilesArray[this.playerPosition.y][this.playerPosition.x].tileValue = 1;
                         this.tilesArray[this.playerPosition.y][this.playerPosition.x].tint = 0xffffff;
                         break;
               }
          }
          this.playerPosition.add(p.x, p.y);
          var playerTween = game.add.tween(this.player).to({
               x: this.playerPosition.x * gameOptions.tileSize + gameOptions.tileSize / 2,
               y: this.playerPosition.y * gameOptions.tileSize + gameOptions.tileSize / 2
          }, 100, Phaser.Easing.Linear.None, true);
          playerTween.onComplete.add(function(){
               if(this.playerPosition.y == gameOptions.fieldSize.rows || this.playerPosition.x == gameOptions.fieldSize.cols || this.tilesArray[this.playerPosition.y][this.playerPosition.x] == null || this.tilesArray[this.playerPosition.y][this.playerPosition.x].falling){
                    this.levelRestart();
               }
               else{
                    if(this.tilesArray[this.playerPosition.y][this.playerPosition.x].tileValue == 2){
                         if(this.isLevelComplete()){
                              if(levelNumber == 0){
                                   levelNumber ++;
                                   this.levelRestart();
                              }
                              else{
                                   alert("ok you completed the game");
                              }
                         }
                         else{
                              var tween = game.add.tween(this.tilesArray[this.playerPosition.y][this.playerPosition.x]).to({
                                   alpha: 0,
                              }, 100, Phaser.Easing.Linear.None, true);
                              this.levelRestart();
                         }
                    }
                    else{
                         game.input.onDown.add(this.beginSwipe, this);     
                    }
               }     
          }, this)
          
     },
     
     // function to check if the level is completed
     isLevelComplete: function(){
          for(var i = 0; i < gameOptions.fieldSize.rows; i++){
			for(var j = 0; j < gameOptions.fieldSize.cols; j++){
                    if(this.tilesArray[i][j] != null && !this.tilesArray[i][j].falling && this.tilesArray[i][j].tileValue != 2){
                         return false;
                    }
			}
		}
          return true;     
     },
     
     // routine to start when the level is failed
     levelRestart: function(){ 
          var tween = game.add.tween(this.player).to({
               alpha: 0,
               width: gameOptions.tileSize / 4,
               height: gameOptions.tileSize / 4
          }, 500, Phaser.Easing.Linear.None, true); 
          tween.onComplete.add(function(){
               game.state.start("TheGame");     
          }, this);  
     }
}
I will be adding more levels and features during next days, as well as a clearly commented source code. Meanwhile you can download the source code and play on your own.

Never miss an update! Subscribe, and I will bother you by email only when a new game or full source code comes out.