HTML5 “2048” game made with Phaser updated to CE 2.10.1 with bug fixes, visual effect and most code rewritten
Talking about 2048 game, Game development, HTML5, Javascript and Phaser.
Do you like my tutorials?
Then consider supporting me on Ko-fi.
var game;
var gameOptions = {
tileSize: 200,
colors: {
0: 0xFFFFFF,
2: 0xFFFFFF,
4: 0xFFEEEE,
8: 0xFFDDDD,
16: 0xFFCCCC,
32: 0xFFBBBB,
64: 0xFFAAAA,
128: 0xFF9999,
256: 0xFF8888,
512: 0xFF7777,
1024: 0xFF6666,
2048: 0xFF5555,
4096: 0xFF4444,
8192: 0xFF3333,
16384: 0xFF2222,
32768: 0xFF1111,
65536: 0xFF0000
},
tweenSpeed: 50
}
window.onload = function() {
game = new Phaser.Game(gameOptions.tileSize * 4, gameOptions.tileSize * 4, Phaser.CANVAS);
game.state.add("PlayGame", playGame);
game.state.start("PlayGame", true);
}
var playGame = function(){};
playGame.prototype = {
preload: function(){
game.load.image("tile", "tile.png");
},
create: function(){
game.scale.pageAlignHorizontally = true;
game.scale.pageAlignVertically = true;
game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
game.stage.backgroundColor = 0x444444;
this.fieldArray = [];
this.fieldGroup = game.add.group();
for(var i = 0; i < 4; i++){
this.fieldArray[i] = [];
for(var j = 0; j < 4; j++){
var two = game.add.sprite(j * gameOptions.tileSize + gameOptions.tileSize / 2, i * gameOptions.tileSize + gameOptions.tileSize / 2, "tile");
two.anchor.set(0.5);
var text = game.add.text(0, 0, "2", {
font: "bold 64px Arial",
align: "center"
});
text.anchor.set(0.5);
two.addChild(text);
two.alpha = 0;
two.visible = false;
this.fieldArray[i][j] = {
tileValue: 0,
tileSprite: two,
canUpgrade: true
}
this.fieldGroup.add(two);
}
}
this.upKey = game.input.keyboard.addKey(Phaser.Keyboard.W);
this.upKey.onDown.add(this.handleKey, this);
this.downKey = game.input.keyboard.addKey(Phaser.Keyboard.S);
this.downKey.onDown.add(this.handleKey, this);
this.leftKey = game.input.keyboard.addKey(Phaser.Keyboard.A);
this.leftKey.onDown.add(this.handleKey, this);
this.rightKey = game.input.keyboard.addKey(Phaser.Keyboard.D);
this.rightKey.onDown.add(this.handleKey, this);
this.canMove = false;
this.addTwo();
this.addTwo();
},
addTwo: function(){
var emptyTiles = [];
for(var i = 0; i < 4; i++){
for(var j = 0; j < 4; j++){
if(this.fieldArray[i][j].tileValue == 0){
emptyTiles.push({
row: i,
col: j
})
}
}
}
var choosenTile = Phaser.ArrayUtils.getRandomItem(emptyTiles);
this.fieldArray[choosenTile.row][choosenTile.col].tileValue = 2;
this.fieldArray[choosenTile.row][choosenTile.col].tileSprite.visible = true;
this.fieldArray[choosenTile.row][choosenTile.col].tileSprite.children[0].text = "2";
var fadeIn = game.add.tween(this.fieldArray[choosenTile.row][choosenTile.col].tileSprite);
fadeIn.to({
alpha: 1
}, gameOptions.tweenSpeed, Phaser.Easing.Linear.None, true);
fadeIn.onComplete.add(function(){
this.canMove = true;
}, this);
},
handleKey: function(e){
if(this.canMove){
switch(e.keyCode){
case Phaser.Keyboard.A:
this.fieldGroup.sort("x", Phaser.Group.SORT_ASCENDING);
this.handleMove(0, -1);
break;
case Phaser.Keyboard.D:
this.fieldGroup.sort("x", Phaser.Group.SORT_DESCENDING);
this.handleMove(0, 1);
break;
case Phaser.Keyboard.W:
this.fieldGroup.sort("y", Phaser.Group.SORT_ASCENDING);
this.handleMove(-1, 0);
break;
case Phaser.Keyboard.S:
this.fieldGroup.sort("y", Phaser.Group.SORT_DESCENDING);
this.handleMove(1, 0);
break;
}
}
},
handleMove: function(deltaRow, deltaCol){
this.canMove = false;
var somethingMoved = false;
this.movingTiles = 0;
for(var i = 0; i < 4; i++){
for(var j = 0; j < 4; j++){
var colToWatch = deltaCol == 1 ? (4 - 1) - j : j;
var rowToWatch = deltaRow == 1 ? (4 - 1) - i : i;
var tileValue = this.fieldArray[rowToWatch][colToWatch].tileValue;
if(tileValue != 0){
var colSteps = deltaCol;
var rowSteps = deltaRow;
while(this.isInsideBoard(rowToWatch + rowSteps, colToWatch + colSteps) && this.fieldArray[rowToWatch + rowSteps][colToWatch + colSteps].tileValue == 0){
colSteps += deltaCol;
rowSteps += deltaRow;
}
if(this.isInsideBoard(rowToWatch + rowSteps, colToWatch + colSteps) && (this.fieldArray[rowToWatch + rowSteps][colToWatch + colSteps].tileValue == tileValue) && this.fieldArray[rowToWatch + rowSteps][colToWatch + colSteps].canUpgrade && this.fieldArray[rowToWatch][colToWatch].canUpgrade){
this.fieldArray[rowToWatch + rowSteps][colToWatch + colSteps].tileValue = tileValue * 2;
this.fieldArray[rowToWatch + rowSteps][colToWatch + colSteps].canUpgrade = false;
this.fieldArray[rowToWatch][colToWatch].tileValue = 0;
this.moveTile(this.fieldArray[rowToWatch][colToWatch].tileSprite, rowToWatch + rowSteps, colToWatch + colSteps, Math.abs(rowSteps + colSteps), true);
somethingMoved = true;
}
else{
colSteps = colSteps - deltaCol;
rowSteps = rowSteps - deltaRow;
if(colSteps != 0 || rowSteps != 0){
this.fieldArray[rowToWatch + rowSteps][colToWatch + colSteps].tileValue = tileValue;
this.fieldArray[rowToWatch][colToWatch].tileValue = 0;
this.moveTile(this.fieldArray[rowToWatch][colToWatch].tileSprite, rowToWatch + rowSteps, colToWatch + colSteps, Math.abs(rowSteps + colSteps), false);
somethingMoved = true;
}
}
}
}
}
if(!somethingMoved){
this.canMove = true;
}
},
moveTile: function(tile, row, col, distance, changeNumber){
this.movingTiles ++;
var moveTween = game.add.tween(tile).to({
x: col * gameOptions.tileSize + gameOptions.tileSize / 2,
y: row * gameOptions.tileSize + gameOptions.tileSize / 2
}, gameOptions.tweenSpeed * distance, Phaser.Easing.Linear.None, true);
moveTween.onComplete.add(function(){
this.movingTiles --;
if(changeNumber){
this.movingTiles ++;
tile.children[0].text = this.fieldArray[row][col].tileValue.toString();
tile.tint = gameOptions.colors[this.fieldArray[row][col].tileValue];
var growTween = game.add.tween(tile.scale).to({
x: 1.1,
y: 1.1
}, gameOptions.tweenSpeed, Phaser.Easing.Cubic.InOut, true, 0, 1, true);
growTween.onComplete.add(function(){
this.movingTiles --;
if(this.movingTiles == 0){
this.resetTiles();
this.addTwo();
}
}, this)
}
if(this.movingTiles == 0){
this.resetTiles();
this.addTwo();
}
}, this);
},
resetTiles: function(){
for(var i = 0; i < 4; i++){
for(var j = 0; j < 4; j++){
this.fieldArray[i][j].canUpgrade = true;
this.fieldArray[i][j].tileSprite.x = j * gameOptions.tileSize + gameOptions.tileSize / 2;
this.fieldArray[i][j].tileSprite.y = i * gameOptions.tileSize + gameOptions.tileSize / 2;
if(this.fieldArray[i][j].tileValue > 0){
this.fieldArray[i][j].tileSprite.alpha = 1;
this.fieldArray[i][j].tileSprite.visible = true;
this.fieldArray[i][j].tileSprite.children[0].text = this.fieldArray[i][j].tileValue.toString();
}
else{
this.fieldArray[i][j].tileValue = 0;
this.fieldArray[i][j].tileSprite.alpha = 0;
this.fieldArray[i][j].tileSprite.visible = false;
}
this.fieldArray[i][j].tileSprite.tint = gameOptions.colors[this.fieldArray[i][j].tileValue];
}
}
},
isInsideBoard: function(row, col){
return (row >= 0) && (col >= 0) && (row < 4) && (col < 4);
}
}
Never miss an update! Subscribe, and I will bother you by email only when a new game or full source code comes out.