Code edit (9 edits merged)
Please save this source code
Code edit (4 edits merged)
Please save this source code
User prompt
Play a sound effect just before calling showGameOver
Code edit (1 edits merged)
Please save this source code
User prompt
In mouse up use a different sound effect, let's call it place
User prompt
Add a sound effect on mouse up that plays if cells exists
User prompt
Play a pickup sound when you press a block
User prompt
Migrate to the latest version of LK
User prompt
Write the tagline for this game
User prompt
in sortCellsByFilled first sort on filtered, then sort on y position. Make sure you modify the original array
Code edit (1 edits merged)
Please save this source code
User prompt
in sortCellsByFilled first sort on filtered, then sort on y position
User prompt
in sortCellsByFilled reverse the sort order
Code edit (1 edits merged)
Please save this source code
/****
* Classes
****/
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();
}
};
});
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 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 = 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.sort(function (a, b) {
if (a instanceof Cell && b instanceof Cell) {
return a.filled === b.filled ? 0 : a.filled ? 1 : -1;
}
return 0;
});
console.log(self.children);
};
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 () {};
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x80acc2
});
/****
* Game Code
****/
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 (obj) {
dragTarget = this;
var pos = obj.event.getLocalPosition(this);
var targetPos = obj.event.getLocalPosition(game);
this.targetX = pos.x;
this.targetY = pos.y;
dragTarget.move(targetPos.x, targetPos.y);
});
};
game.on('move', function (obj) {
if (dragTarget) {
board.removeTint();
var pos = obj.event.getLocalPosition(game);
dragTarget.move(pos.x, pos.y);
dragTarget.showOverlap();
}
});
game.on('up', function (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.setScore(LK.getScore() + Math.pow(pointsToAdd, 2) * 10);
scoreTxt.setText(LK.getScore());
}
}
board.removeTint();
board.sortCellsByFilled();
dragTarget = undefined;
}
});
game.createBlocks = function () {
for (var i = 0; i < 3; i++) {
game.createBlock(i);
}
};
// 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.topCenter.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.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..