Talking about Zhed game, Game development, HTML5, Javascript and Phaser.
If you enjoyed the “Zhed” puzzle game prototype made with Construct 3, and you also are a Phaser enthusiast, you’ll probably like this version I made using the latest version pf Phaser CE, 2.7.8 I tried to write the code following the same line of concept I used when I made the Construct 3 version. Obviously coding from scratch gives you more opportunities to optimize your work, but I wanted to keep the code similar to the Constrcut 3 version for you to compare them. I will also write some kind of “Phaser Vs Construct” from a programmer point of view, once I made a couple of games. Now, this is the Phaser version of the game: Tap a square and select a direction (upwards, downwards, to the left and to the right). See how the square reacts when they intersect with each other, and build a path to fill the goal square. When you finished, the next level will show up! If you get stuck, press “Restart” button. If you have a mobile device, play the game from this link. About the source code, here it is, uncommented at the moment but I will add comments as soon as I add some more levels.
var game;
var gameOptions = {
tileSize: 100,
gameWidth: 800,
gameHeight: 1000
}
var levels = [[[0,0,0,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,10,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0]],[[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,2,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,10,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0]],[[0,0,0,0,0,0,0,0],[0,0,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,0,10,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0]],[[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,10,0,0,0],[0,0,0,0,0,0,0,0],[0,0,2,0,0,0,0,0],[0,0,0,0,2,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0]],[[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,2,0,0,10,0],[0,0,0,0,0,0,0,0],[0,2,0,0,0,0,0,0],[0,0,1,0,2,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0]],[[0,0,0,0,0,0,0,0],[0,0,10,0,0,0,3,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,2,0,0,0,0,0],[0,0,0,0,0,3,0,0],[0,0,0,2,0,0,0,0],[0,0,0,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,0,0,0,0],[0,10,0,0,0,0,1,0],[0,0,0,0,0,1,0,0],[0,0,2,0,2,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,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,0,0],[0,1,0,0,0,0,10,0],[0,0,0,1,1,0,0,0],[0,0,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,1,2,0,0],[0,0,0,1,0,0,0,0],[0,0,1,0,0,0,0,0],[0,0,0,0,0,0,3,0],[0,0,10,0,0,0,0,0],[0,0,0,0,0,0,0,0]],[[0,0,0,0,0,0,0,0],[0,0,0,2,0,0,0,0],[0,0,0,0,1,2,0,0],[0,0,0,0,0,0,0,0],[0,0,2,0,0,0,0,0],[0,0,0,0,0,1,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,10,0,0]]]
window.onload = function() {
game = new Phaser.Game(gameOptions.gameWidth, gameOptions.gameHeight);
game.state.add("PreloadGame", preloadGame);
game.state.add("PlayGame", playGame);
game.state.start("PreloadGame");
}
var preloadGame = function(game){}
preloadGame.prototype = {
preload: function(){
game.stage.backgroundColor = 0x2c3e50;
game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
game.scale.pageAlignHorizontally = true;
game.scale.pageAlignVertically = true;
game.stage.disableVisibilityChange = true;
game.load.spritesheet("tiles", "tiles.png", gameOptions.tileSize, gameOptions.tileSize);
},
create: function(){
game.state.start("PlayGame", true, false, 0);
}
}
var playGame = function(game){}
playGame.prototype = {
init: function(currentLevel){
this.currentLevel = currentLevel;
},
create: function(){
this.undoArray = [];
this.drawLevel();
game.input.onTap.add(this.handleTap, this);
},
drawLevel: function(){
this.localLevel = [];
this.tileGroup = game.add.group();
this.stepsGroup = game.add.group();
for(var i = 0; i < levels[this.currentLevel].length; i++){
this.localLevel[i] = [];
for(var j = 0; j < levels[this.currentLevel][i].length; j++){
var tile = game.add.sprite(j * gameOptions.tileSize, i * gameOptions.tileSize, "tiles", levels[this.currentLevel][i][j]);
if(levels[this.currentLevel][i][j] == 0){
tile.alpha = 0.6 + game.rnd.realInRange(0, 0.3);
}
this.tileGroup.add(tile);
this.localLevel[i][j] = {
sprite: tile,
value: levels[this.currentLevel][i][j]
}
var step = game.add.sprite(j * gameOptions.tileSize, i * gameOptions.tileSize, "tiles", 11);
step.row = i;
step.col = j;
step.visible = false;
this.stepsGroup.add(step);
}
}
var restartButton = game.add.button(game.width / 2 - gameOptions.tileSize / 2, game.height - gameOptions.tileSize * 1.5, "tiles", function(){
game.state.start("PlayGame", true, false, this.currentLevel);
}, this, 13, 13);
},
handleTap: function(pointer, doubleTap){
var turnTiles = false;
var tileTapRow = Math.floor(pointer.y / gameOptions.tileSize);
var tileTapCol = Math.floor(pointer.x / gameOptions.tileSize);
if(tileTapRow < 0 || tileTapCol < 0 || tileTapRow >= this.localLevel.length || tileTapCol >= this.localLevel[tileTapRow].length){
return;
}
var tileValue = this.localLevel[tileTapRow][tileTapCol].value;
if(tileValue == 11 || tileValue == 21){
turnTiles = true;
this.localLevel[this.selectedRow][this.selectedCol].sprite.frame = 12;
this.localLevel[this.selectedRow][this.selectedCol].value = 11;
var deltaX = game.math.clamp(tileTapCol - this.selectedCol, -1, 1);
var deltaY = game.math.clamp(tileTapRow - this.selectedRow, -1, 1);
}
this.stepsGroup.forEach(function(item) {
if(item.visible){
if(!turnTiles){
this.localLevel[item.row][item.col].value -= 11;
}
else{
if((deltaX > 0 && item.col > this.selectedCol) || (deltaX < 0 && item.col < this.selectedCol) || (deltaY > 0 && item.row > this.selectedRow) || (deltaY < 0 && item.row < this.selectedRow)){
this.localLevel[item.row][item.col].sprite.frame = 12;
if(this.localLevel[item.row][item.col].value == 21){
game.time.events.add(Phaser.Timer.SECOND, function(){
game.state.start("PlayGame", true, false, (this.currentLevel + 1) % 10);
}, this);
}
}
else{
this.localLevel[item.row][item.col].value -= 11;
}
}
item.visible = false;
}
}, this);
if(tileValue > 0 && tileValue < 10){
this.showSteps(tileTapRow, tileTapCol, tileValue, 0, 1);
this.showSteps(tileTapRow, tileTapCol, tileValue, 0, -1);
this.showSteps(tileTapRow, tileTapCol, tileValue, 1, 0);
this.showSteps(tileTapRow, tileTapCol, tileValue, -1, 0);
this.selectedRow = tileTapRow;
this.selectedCol = tileTapCol;
}
},
showSteps: function(row, col, steps, deltaRow, deltaCol){
var stepsMade = 0;
while(stepsMade < steps){
while(this.localLevel[row][col].value != 0 && this.localLevel[row][col].value != 10){
row += deltaRow;
col += deltaCol;
if(row < 0 || col < 0 || row >= this.localLevel.length || col >= this.localLevel[row].length){
return;
}
}
this.stepsGroup.getChildAt(row * this.localLevel[col].length + col).visible = true;
this.localLevel[row][col].value += 11;
stepsMade ++;
row += deltaRow;
col += deltaCol;
if(row < 0 || col < 0 || row >= this.localLevel.length || col >= this.localLevel[row].length){
break;
}
}
}
}
Never miss an update! Subscribe, and I will bother you by email only when a new game or full source code comes out.