/****
* Classes
****/
var Block = Container.expand(function (board) {
var self = Container.call(this);
var hsvToRgb = function hsvToRgb(h, s, v) {
var r, g, b;
var i = Math.floor(h * 6);
var f = h * 6 - i;
var p = v * (1 - s);
var q = v * (1 - f * s);
var t = v * (1 - (1 - f) * s);
switch (i % 6) {
case 0:
r = v, g = t, b = p;
break;
case 1:
r = q, g = v, b = p;
break;
case 2:
r = p, g = v, b = t;
break;
case 3:
r = p, g = q, b = v;
break;
case 4:
r = t, g = p, b = v;
break;
case 5:
r = v, g = p, b = q;
break;
}
return (Math.round(r * 255) << 16) + (Math.round(g * 255) << 8) + Math.round(b * 255);
};
var ShapeTypes = {
SINGLE: [[1]],
TRI: [[1, 1, 1]],
QUAD: [[1, 1, 1, 1]],
LSHAPE: [[1, 0, 0], [1, 0, 0], [1, 1, 1]],
BLOCK: [[1, 1], [1, 1]],
SMALLLSHAPE: [[1, 0], [1, 1]]
};
var shapes = Object.values(ShapeTypes);
var offset = Math.floor(Math.random() * shapes.length);
self.offset = offset;
self.shape = shapes[offset];
var hue = offset % shapes.length / shapes.length;
self.color = hsvToRgb(hue, 0.6, 1);
self.rotateShapeRandomly = function () {
var rotations = Math.floor(Math.random() * 4);
for (var r = 0; r < rotations; r++) {
self.shape = self.shape[0].map(function (val, index) {
return self.shape.map(function (row) {
return row[index];
}).reverse();
});
}
};
self.rotateShapeRandomly();
self.blocks = [];
var background = self.attachAsset('background', {
anchorX: 0.5,
anchorY: 0.5
});
background.alpha = 0;
var blockSize = 160;
background.width = 4 * blockSize;
background.height = 4 * blockSize;
self.addChild(background);
self.offsetX = 0;
self.offsetY = 0;
var blockOffsetX = (background.width / 2 - self.shape[0].length * blockSize) / 2 - blockSize / 2;
var blockOffsetY = (background.height / 2 - self.shape.length * blockSize) / 2 - blockSize / 2;
for (var i = 0; i < self.shape.length; i++) {
for (var j = 0; j < self.shape[i].length; j++) {
if (self.shape[i][j] === 1) {
var block = self.createAsset('block_' + offset, {
anchorX: 0.5,
anchorY: 0.5
});
block.x = j * blockSize + blockOffsetX;
block.y = i * blockSize + blockOffsetY;
self.blocks.push(block);
self.addChild(block);
}
}
}
self.startX = 0;
self.startY = 0;
self.moveTowardsHomePosition = function () {
var dx = self.startX - self.x;
var dy = self.startY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 1) {
self.x += dx * 0.3;
self.y += dy * 0.3;
} else {
self.x = self.startX;
self.y = self.startY;
}
};
var currentX = 0;
var currentY = 0;
self.moveToDragTarget = function () {
var ox = -this.targetX;
var oy = (LK.is.mobile ? 400 : 0) - this.targetY;
this.targetX += ox / 5;
this.targetY += oy / 5;
this.x = currentX - this.targetX;
this.y = currentY - this.targetY;
};
self._move_migrated = function (x, y) {
currentX = x;
currentY = y;
self.x = x - this.targetX;
self.y = y - this.targetY;
};
self.setStartPosition = function (x, y) {
self.startX = x;
self.startY = y;
};
self.getOverlappingCells = function () {
var cells = [];
var boardPos = {
x: -board.x + self.x + 160 * 4 + blockOffsetX + 160,
y: -board.y + self.y + 160 * 4 + blockOffsetY + 160
};
var startX = Math.floor(boardPos.x / 160);
var startY = Math.floor(boardPos.y / 160);
for (var i = 0; i < self.shape.length; i++) {
for (var j = 0; j < self.shape[i].length; j++) {
if (self.shape[i][j] === 1) {
var cell = board.grid && board.grid[startY + i] && board.grid[startY + i][startX + j];
if (cell && !cell.filled) {
cells.push(cell);
} else {
return null;
}
}
}
}
return cells;
};
self.showOverlap = function () {
var cells = self.getOverlappingCells();
if (cells) {
for (var a = 0; a < cells.length; a++) {
var cell = cells[a];
cell.setTint(self.color);
}
}
};
self.rotateShapeRandomly = function () {
var rotations = Math.floor(Math.random() * 4);
for (var r = 0; r < rotations; r++) {
self.shape = self.shape[0].map(function (val, index) {
return self.shape.map(function (row) {
return row[index];
}).reverse();
});
}
};
});
var Board = Container.expand(function () {
var self = Container.call(this);
self.particles = [];
self.sortCellsByFilled = function () {
self.children.filter(function (child) {
return child instanceof Cell;
}).sort(function (a, b) {
if (a.filled !== b.filled) {
return a.filled ? 1 : -1;
}
return a.y - b.y;
}).forEach(function (cell, index) {
self.children[index] = cell;
});
};
Board.prototype.spawnParticles = function (x, y, tint) {
for (var i = 0; i < 10; i++) {
var particle = new Particle(tint);
particle.x = x;
particle.y = y;
this.particles.push(particle);
this.addChild(particle);
}
};
self.grid = new Array(10).fill(null).map(function () {
return new Array(10).fill(null);
});
var size = 158;
var totalWidth = 10 * size;
var totalHeight = 10 * size;
for (var i = 0; i < 10; i++) {
for (var j = 0; j < 10; j++) {
var cell = new Cell();
cell.x = i * size - totalWidth / 2 + size / 2;
cell.y = j * size - totalHeight / 2 + size / 2;
self.grid[j][i] = cell;
self.addChild(cell);
}
}
self.removeTint = function () {
for (var i = 0; i < 10; i++) {
for (var j = 0; j < 10; j++) {
if (!self.grid[i][j].filled) {
self.grid[i][j].setTint(0xffffff);
}
}
}
};
self.checkLines = function () {
var rowsRemoved = 0;
for (var i = 0; i < 10; i++) {
var rowFilled = true;
var colFilled = true;
for (var j = 0; j < 10; j++) {
if (!self.grid[i][j].filled) {
rowFilled = false;
}
if (!self.grid[j][i].filled) {
colFilled = false;
}
}
if (rowFilled || colFilled) {
rowsRemoved += (rowFilled ? 1 : 0) + (colFilled ? 1 : 0);
for (var j = 0; j < 10; j++) {
if (rowFilled) {
self.grid[i][j].setFill(false);
self.spawnParticles(self.grid[i][j].x, self.grid[i][j].y, self.grid[i][j].getTint());
}
if (colFilled) {
self.grid[j][i].setFill(false);
self.spawnParticles(self.grid[j][i].x, self.grid[j][i].y, self.grid[j][i].getTint());
}
}
}
}
return rowsRemoved;
};
self.tick = function () {
for (var i = self.particles.length - 1; i >= 0; i--) {
var particle = self.particles[i];
if (particle) {
particle.tick();
if (particle.alpha <= 0) {
self.particles.splice(i, 1);
}
}
}
for (var i = 0; i < 10; i++) {
for (var j = 0; j < 10; j++) {
self.grid[i][j].tick(i, j);
}
}
};
self.placeBlock = function () {};
});
var Cell = Container.expand(function () {
var self = Container.call(this);
self.filled = false;
var empty = self.attachAsset('cell', {
anchorX: 0.5,
anchorY: 0.5
});
empty.alpa = .8;
var filled;
var currentOffset;
empty.y = 2;
self.currentTint = 0xffffff;
self.setFill = function (isFilled, asset, offset) {
self.filled = isFilled;
empty.visible = !self.filled;
if (isFilled) {
if (asset) {
asset.x = 0;
asset.y = brickYOffsets[offset] || -15;
currentOffset = offset;
self.addChild(asset);
filled = asset;
}
} else {
if (filled) {
filled.destroy();
filled = null;
}
}
};
self.tick = function (i, j) {
if (filled) {
var offset = Math.cos(((i + j) * 3 + LK.ticks / 2) / 6) / 20;
var ty = brickYOffsets[currentOffset] || -15;
filled.y = ty + Math.abs(offset * 200) - 5;
filled.rotation = offset;
}
};
self.getTint = function () {
return self.currentTint;
};
self.setTint = function (tint) {
self.currentTint = tint;
empty.tint = tint;
};
self.setFill(false);
});
var Particle = Container.expand(function (tint) {
var self = Container.call(this);
self.tint = tint;
var particleGraphics = self.attachAsset('particle', {
anchorX: 0.5,
anchorY: 0.5
});
particleGraphics.rotation = Math.random() * Math.PI * 2;
particleGraphics.tint = self.tint;
self.vx = Math.random() * 4 - 2;
self.vy = Math.random() * 4 - 2;
self.alpha = 1;
self.lifetime = 60;
self.tick = function () {
self.x += self.vx;
self.y += self.vy;
self.alpha -= 1 / self.lifetime;
if (self.alpha <= 0) {
self.destroy();
}
};
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x80acc2
});
/****
* Game Code
****/
/****
* Game Code
* 'Match & Dance: Align the happy blocks and groove to victory!'
****/
var brickYOffsets = [2, -10, 2, 2, 2, -20];
var gameBackground = game.attachAsset('gameBackground', {
anchorX: 0.5,
anchorY: 0.5
});
gameBackground.x = 2048 / 2;
gameBackground.y = 2732 / 2 + 65;
// Insert tileBackground aligned at the bottom center
var tileBackground = game.attachAsset('tileBackground', {
anchorX: 0.5,
anchorY: 1
});
tileBackground.alpha = .5;
tileBackground.x = 2048 / 2;
tileBackground.y = 2732;
var blocks = [];
var dragTarget;
var board = game.addChild(new Board());
board.x = 2048 / 2;
board.y = 2732 / 2 - 250;
var targetOffset;
game.createBlock = function (index) {
var block = new Block(board);
block.x = 2048 / 2 + (index - 1) * (block.width + 30);
block.y = 2732 + block.height;
block.setStartPosition(block.x, 2732 - block.height / 2 - 30);
blocks.push(block);
game.addChild(block);
block.on('down', function (x, y, obj) {
LK.getSound('pickup').play();
dragTarget = this;
var pos = this.toLocal(obj.global);
var targetPos = game.toLocal(obj.global);
this.targetX = pos.x;
this.targetY = pos.y;
dragTarget._move_migrated(targetPos.x, targetPos.y);
});
};
game.on('move', function (x, y, obj) {
if (dragTarget) {
board.removeTint();
var pos = game.toLocal(obj.global);
dragTarget._move_migrated(pos.x, pos.y);
dragTarget.showOverlap();
}
});
game.on('up', function (x, y, obj) {
if (dragTarget) {
var cells = dragTarget.getOverlappingCells();
if (cells) {
for (var a = 0; a < cells.length; a++) {
cells[a].setFill(true, dragTarget.blocks[a], dragTarget.offset);
cells[a].setTint(dragTarget.color);
}
blocks[blocks.indexOf(dragTarget)] = undefined;
dragTarget.destroy();
if (!blocks.some(function (block) {
return block;
})) {
game.createBlocks();
}
var pointsToAdd = board.checkLines();
if (pointsToAdd) {
LK.getSound('score').play();
LK.setScore(LK.getScore() + Math.pow(pointsToAdd, 2) * 10);
scoreTxt.setText(LK.getScore());
} else {
LK.getSound('place').play();
}
} else {
LK.getSound('fail').play();
}
board.removeTint();
board.sortCellsByFilled();
dragTarget = undefined;
}
});
game.createBlocks = function () {
for (var i = 0; i < 3; i++) {
game.createBlock(i);
}
LK.getSound('swoop').play();
LK.setTimeout(function () {
LK.getSound('new').play();
}, 50);
};
// Score is now handled by LK score methods
game.createBlocks();
var scoreTxt = new Text2('0', {
size: 150,
fill: "#ffffff",
font: 'Impact',
stroke: '#2a636e',
strokeThickness: 16
});
scoreTxt.anchor.set(.5, 0);
LK.gui.top.addChild(scoreTxt);
game.isMovePossible = function () {
for (var a = 0; a < blocks.length; a++) {
if (blocks[a]) {
for (var i = 0; i < 10; i++) {
for (var j = 0; j < 10; j++) {
if (board.grid[i][j].filled) {
continue;
}
var canPlace = true;
for (var k = 0; k < blocks[a].shape.length; k++) {
for (var l = 0; l < blocks[a].shape[k].length; l++) {
if (blocks[a].shape[k][l] === 1) {
if (i + k < 0 || i + k >= 10 || j + l < 0 || j + l >= 10 || board.grid[i + k][j + l].filled) {
canPlace = false;
break;
}
}
}
if (!canPlace) {
break;
}
}
if (canPlace) {
return true;
}
}
}
}
}
return false;
};
var isGameOver = false;
LK.on('tick', function () {
board.tick();
if (isGameOver || !game.isMovePossible()) {
LK.getSound('gameover').play();
LK.effects.flashScreen(0xffffff, 1000);
LK.showGameOver();
}
for (var a = blocks.length - 1; a >= 0; a--) {
if (blocks[a]) {
if (blocks[a] != dragTarget) {
blocks[a].moveTowardsHomePosition();
} else {
blocks[a].moveToDragTarget();
}
}
}
});
White square with tight round corners, flat shaded, hyper casual game. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
White particle cloud. Cartoon. Bright outline. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Perfectly square yellow Christmas decoration. Cartoon style. Cute art style. Simple vector style.
Perfectly square bright purple Christmas decoration with cute happyy face. Cartoon style. Cute art style. Simple vector style.
Perfectly square bright green game piece with cute happy face. Cartoon style. Cute art style. Simple vector style. No Shadows. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
No background
Perfectly square red game piece with cute happy face. Cartoon style. Cute art style. Simple vector style. No Shadows. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Perfectly square bright dark blue game piece with cute happy face. Cartoon style. Cute art style. Simple vector style. No Shadows. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows..