HTML5 prototype of iOS “o:anquan” puzzle game powered with Phaser
Talking about o:anquan game, Game development, HTML5, Javascript and Phaser.
Learn cross platform HTML5 game development
Check my Gumroad page for commented source code, games and books.

var game;
var gameOptions = {
gameWidth: 800,
gameHeight: 1400,
tileSize: 120,
fieldSize: {
rows: 6,
cols: 6
},
fallSpeed: 250,
diagonal: false,
colors: [0xff0000, 0x00ff00, 0x0000ff, 0xffff00, 0xff00ff]
}
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 = {
preload: function(){
game.stage.backgroundColor = 0x222222;
game.load.spritesheet("tiles", "assets/sprites/tiles.png", gameOptions.tileSize, gameOptions.tileSize);
},
create: function(){
game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
game.scale.pageAlignHorizontally = true;
game.scale.pageAlignVertically = true;
this.createLevel();
game.input.onDown.add(this.pickTile, this);
},
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++){
this.addTile(i, j);
}
}
this.placeNumbers();
},
placeNumbers: function(){
var emptySpots = [];
for(var i = 0; i < gameOptions.fieldSize.rows; i++){
for(var j = 0; j < gameOptions.fieldSize.cols; j++){
if(this.tilesArray[i][j].value == 0){
emptySpots.push(this.tilesArray[i][j].coordinate);
}
}
}
for(i = 0; i < 3; i++){
var item = Phaser.ArrayUtils.removeRandomItem(emptySpots);
if(item){
var randomValue = game.rnd.integerInRange(1, 9);
this.tilesArray[item.y][item.x].value = randomValue;
this.tilesArray[item.y][item.x].frame = randomValue;
}
}
},
addTile: function(row, col){
var tileXPos = col * gameOptions.tileSize + gameOptions.tileSize / 2;
var tileYPos = row * gameOptions.tileSize + gameOptions.tileSize / 2;
var theTile = game.add.sprite(tileXPos, tileYPos, "tiles");
theTile.anchor.set(0.5);
theTile.value = 0;
theTile.picked = false;
theTile.coordinate = new Phaser.Point(col, row);
this.tilesArray[row][col] = theTile;
this.tileGroup.add(theTile);
},
pickTile: function(e){
this.visitedTiles = [];
this.visitedTiles.length = 0;
if(this.tileGroup.getBounds().contains(e.position.x, e.position.y)){
var col = Math.floor((e.position.x - this.tileGroup.x) / gameOptions.tileSize);
var row = Math.floor((e.position.y - this.tileGroup.y) / gameOptions.tileSize);
if(this.tilesArray[row][col].value > 0){
this.tilesArray[row][col].alpha = 0.5;
game.input.onDown.remove(this.pickTile, this);
game.input.onUp.add(this.releaseTile, this);
game.input.addMoveCallback(this.moveTile, this);
this.visitedTiles.push(this.tilesArray[row][col].coordinate);
}
}
},
moveTile: function(e){
if(this.tileGroup.getBounds().contains(e.position.x, e.position.y)){
var col = Math.floor((e.position.x - this.tileGroup.x) / gameOptions.tileSize);
var row = Math.floor((e.position.y - this.tileGroup.y) / gameOptions.tileSize);
if(row != this.visitedTiles[this.visitedTiles.length - 1].y || col != this.visitedTiles[this.visitedTiles.length - 1].x){
var distance = new Phaser.Point(e.position.x - this.tileGroup.x, e.position.y - this.tileGroup.y).distance(this.tilesArray[row][col]);
if(distance < gameOptions.tileSize * 0.4){
var previousTileValue = this.tilesArray[this.visitedTiles[this.visitedTiles.length - 1].y][this.visitedTiles[this.visitedTiles.length - 1].x].value;
if(!this.tilesArray[row][col].picked && this.checkAdjacent(new Phaser.Point(col, row), this.visitedTiles[this.visitedTiles.length - 1]) && previousTileValue > 1 && this.tilesArray[row][col].value == 0){
this.tilesArray[row][col].picked = true;
this.tilesArray[row][col].alpha = 0.5;
this.tilesArray[row][col].value = previousTileValue - 1;
this.tilesArray[row][col].frame = previousTileValue - 1;
this.tilesArray[this.visitedTiles[this.visitedTiles.length - 1].y][this.visitedTiles[this.visitedTiles.length - 1].x].value = 1;
this.tilesArray[this.visitedTiles[this.visitedTiles.length - 1].y][this.visitedTiles[this.visitedTiles.length - 1].x].frame = 1;
this.visitedTiles.push(this.tilesArray[row][col].coordinate);
}
else{
if(this.visitedTiles.length > 1 && row == this.visitedTiles[this.visitedTiles.length - 2].y && col == this.visitedTiles[this.visitedTiles.length - 2].x){
this.tilesArray[this.visitedTiles[this.visitedTiles.length - 1].y][this.visitedTiles[this.visitedTiles.length - 1].x].value = 0;
this.tilesArray[this.visitedTiles[this.visitedTiles.length - 1].y][this.visitedTiles[this.visitedTiles.length - 1].x].frame = 0;
this.tilesArray[this.visitedTiles[this.visitedTiles.length - 1].y][this.visitedTiles[this.visitedTiles.length - 1].x].picked = false;
this.tilesArray[this.visitedTiles[this.visitedTiles.length - 1].y][this.visitedTiles[this.visitedTiles.length - 1].x].alpha = 1;
this.visitedTiles.pop();
this.tilesArray[this.visitedTiles[this.visitedTiles.length - 1].y][this.visitedTiles[this.visitedTiles.length - 1].x].value = previousTileValue + 1;
this.tilesArray[this.visitedTiles[this.visitedTiles.length - 1].y][this.visitedTiles[this.visitedTiles.length - 1].x].frame = previousTileValue + 1;
}
}
}
}
}
},
releaseTile: function(){
game.input.onUp.remove(this.releaseTile, this);
game.input.deleteMoveCallback(this.moveTile, this);
game.input.onDown.add(this.pickTile, this);
for(var i = 0; i < this.visitedTiles.length; i++){
this.tilesArray[this.visitedTiles[i].y][this.visitedTiles[i].x].picked = false;
this.tilesArray[this.visitedTiles[i].y][this.visitedTiles[i].x].alpha = 1;
}
if(this.visitedTiles.length > 1){
this.placeNumbers();
}
},
checkAdjacent: function(p1, p2){
if(gameOptions.diagonal){
return (Math.abs(p1.x - p2.x) <= 1) && (Math.abs(p1.y - p2.y) <= 1);
}
else{
return (Math.abs(p1.x - p2.x) == 1 && p1.y - p2.y == 0) || (Math.abs(p1.y - p2.y) == 1 && p1.x - p2.x == 0);
}
}
}
Never miss an update! Subscribe, and I will bother you by email only when a new game or full source code comes out.