/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * 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 = []; Board.prototype.spawnParticles = function (x, y, tint) { for (var i = 0; i < 10; i++) { var particle = new Particle(tint); particle.x = x + (Math.random() - 0.5) * 50; particle.y = y + (Math.random() - 0.5) * 50; this.particles.push(particle); this.addChild(particle); // Add tween effect for particles with matching block color tween(particle, { scaleX: 0, scaleY: 0, alpha: 0, x: particle.x + (Math.random() - 0.5) * 100, y: particle.y + (Math.random() - 0.5) * 100 }, { duration: 800, easing: tween.easeOut, onFinish: function onFinish() { if (particle.parent) { particle.destroy(); } } }); } }; 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); // Play destruction sound when blocks are destroyed LK.getSound('blockDestroy').play(); // Handle streak system var currentTime = Date.now(); if (currentTime - lastLinesClearedTime <= streakTimeout && lastLinesClearedTime > 0) { streakLevel = Math.min(streakLevel + 1, 6); // Cap at level 6 } else { streakLevel = 1; } lastLinesClearedTime = currentTime; // Show streak text game.showStreakText(streakLevel); for (var j = 0; j < 10; j++) { if (rowFilled) { var blockColor = self.grid[i][j].getBlockColor() || 0xffffff; self.spawnParticles(self.grid[i][j].x, self.grid[i][j].y, blockColor); self.grid[i][j].setFill(false); } if (colFilled) { var blockColor = self.grid[j][i].getBlockColor() || 0xffffff; self.spawnParticles(self.grid[j][i].x, self.grid[j][i].y, blockColor); self.grid[j][i].setFill(false); } } } } return rowsRemoved; }; self.tick = function () { // Process particles every other tick to reduce overhead if (LK.ticks % 2 === 0) { 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); } } } } // Optimize grid animation by processing fewer cells when not dragging var processEveryNthCell = dragTarget ? 1 : 2; for (var i = 0; i < 10; i += processEveryNthCell) { for (var j = 0; j < 10; j += processEveryNthCell) { self.grid[i][j].tick(i, j); } } }; self.placeBlock = function () {}; }); var Cell = Container.expand(function () { var self = Container.call(this); self.filled = false; var yOffsetArray = [-25, -10, -20, -25, -25, -20]; 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, color) { self.filled = isFilled; empty.visible = !self.filled; if (isFilled) { if (asset) { asset.x = 0; asset.y = yOffsetArray[offset] || -15; currentOffset = offset; self.addChild(asset); filled = asset; if (color) { self.currentTint = color; self.blockColor = color; // Store the original block color } } } else { if (filled) { filled.destroy(); filled = null; } } }; self.tick = function (i, j) { if (filled) { // Reduce animation frequency to improve performance var animationSpeed = LK.ticks / 4; // Slower animation var offset = Math.cos(((i + j) * 3 + animationSpeed) / 6) / 20; var ty = yOffsetArray[currentOffset] || -15; filled.y = ty + Math.abs(offset * 200) - 5; filled.rotation = offset; } }; self.getTint = function () { return self.currentTint; }; self.getBlockColor = function () { return self.blockColor || 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: 0x000000 }); /**** * Game Code ****/ var gameBackground = game.attachAsset('gameBackground', { anchorX: 0.5, anchorY: 0.5 }); gameBackground.x = 2048 / 2; gameBackground.y = 2732 / 2 + 65; // Add asset1 to the front of the screen var asset1Display = game.attachAsset('asset1', { anchorX: 0.5, anchorY: 0.5 }); asset1Display.x = 2048 / 2 + 30; asset1Display.y = 2732 / 2 - 315; // Add asset2 display with same positioning and properties as asset1 var asset2Display = game.attachAsset('asset2', { anchorX: 0.5, anchorY: 0.5 }); asset2Display.x = 2048 / 2 + 30; asset2Display.y = 2732 / 2 - 315; asset2Display.alpha = 0; // Add asset3 display with same positioning and properties as asset1 var asset3Display = game.attachAsset('asset3', { anchorX: 0.5, anchorY: 0.5 }); asset3Display.x = 2048 / 2 + 30; asset3Display.y = 2732 / 2 - 315; asset3Display.alpha = 0; // Add asset4 display with same positioning and properties as asset1 var asset4Display = game.attachAsset('asset4', { anchorX: 0.5, anchorY: 0.5 }); asset4Display.x = 2048 / 2 + 30; asset4Display.y = 2732 / 2 - 315; asset4Display.alpha = 0; var blocks = []; var dragTarget; var board = game.addChild(new Board()); board.x = 2048 / 2; board.y = 2732 / 2 - 250 + 30; var targetOffset; game.createBlock = function (index) { var block = new Block(board); block.x = 2048 / 2 + (index - 1) * (block.width + 50); 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) { 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, dragTarget.color); 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) { score += Math.pow(pointsToAdd, 2) * 10; LK.setScore(score); scoreTxt.setText(score); } } board.removeTint(); dragTarget = undefined; } }); game.createBlocks = function () { for (var i = 0; i < 3; i++) { game.createBlock(i); } }; game.showStreakText = function (level) { // Remove existing streak text if any if (streakText && streakText.parent) { streakText.destroy(); } var message = ''; var color = 0xFFFFFF; if (level === 1) { message = 'GOOD'; color = 0x00FF00; // Green } else if (level === 2) { message = 'SUPER'; color = 0x80FF00; // Green-Yellow } else if (level === 3) { message = 'WOW'; color = 0xFFFF00; // Yellow } else if (level === 4) { message = 'AMAZING'; color = 0xFF8000; // Yellow-Orange } else if (level === 5) { message = 'MANIAC'; color = 0xFF4000; // Orange-Red } else if (level >= 6) { message = 'CRAZYY!!!'; color = 0xFF0000; // Red } if (message) { var newStreakText = new Text2(message, { size: 200, fill: color, font: 'Impact', stroke: '#000000', strokeThickness: 8 }); // Position diagonally across screen (top-right diagonal style) newStreakText.anchor.set(0.5, 0.5); newStreakText.x = 2048 - 300; // Move to right side newStreakText.y = 400; // Move to upper area newStreakText.rotation = -0.2; // Slight diagonal angle newStreakText.alpha = 0; newStreakText.scaleX = 0.5; newStreakText.scaleY = 0.5; game.addChild(newStreakText); streakText = newStreakText; // Animate streak text appearance with elastic bounce effect tween(newStreakText, { alpha: 1, scaleX: 1.3, scaleY: 1.3 }, { duration: 600, easing: tween.elasticOut, onFinish: function onFinish() { // Add a secondary bounce effect tween(newStreakText, { scaleX: 1.1, scaleY: 1.1 }, { duration: 200, easing: tween.bounceOut, onFinish: function onFinish() { // Animate text disappearance after showing tween(newStreakText, { alpha: 0, scaleX: 0.8, scaleY: 0.8, y: newStreakText.y - 100 }, { duration: 1500, easing: tween.elasticIn, onFinish: function onFinish() { if (newStreakText && newStreakText.parent) { newStreakText.destroy(); if (streakText === newStreakText) { streakText = null; } } } }); } }); } }); } }; var score = 0; var lastLinesClearedTime = 0; var streakLevel = 0; var streakTimeout = 5000; // 5 seconds in milliseconds var streakText = null; game.createBlocks(); var scoreTxt = new Text2('0', { size: 150, fill: 0xFFFFFF, font: 'Impact', stroke: '#2a636e', strokeThickness: 16 }); scoreTxt.anchor.set(1, 0); LK.gui.topRight.addChild(scoreTxt); game.isMovePossible = function () { // Cache blocks that exist for faster iteration var activeBlocks = []; for (var a = 0; a < blocks.length; a++) { if (blocks[a]) { activeBlocks.push(blocks[a]); } } for (var blockIndex = 0; blockIndex < activeBlocks.length; blockIndex++) { var block = activeBlocks[blockIndex]; // Check fewer positions by sampling every other position for performance for (var i = 0; i < 10; i += 1) { for (var j = 0; j < 10; j += 1) { if (board.grid[i][j].filled) { continue; } var canPlace = true; // Early bounds checking if (i + block.shape.length > 10 || j + block.shape[0].length > 10) { continue; } for (var k = 0; k < block.shape.length && canPlace; k++) { for (var l = 0; l < block.shape[k].length && canPlace; l++) { if (block.shape[k][l] === 1) { if (board.grid[i + k][j + l].filled) { canPlace = false; } } } } if (canPlace) { return true; } } } } return false; }; // Create frame-based animation sequence for assets var currentAssetIndex = 0; var assetDisplays = [asset1Display, asset2Display, asset3Display, asset4Display]; var animationTimer; function showNextFrame() { // Hide all frames first for stability for (var i = 0; i < assetDisplays.length; i++) { assetDisplays[i].alpha = 0; } // Move to next frame currentAssetIndex = (currentAssetIndex + 1) % assetDisplays.length; // Show next frame assetDisplays[currentAssetIndex].alpha = 1; } function startFrameAnimation() { // Hide all frames initially for stability for (var i = 0; i < assetDisplays.length; i++) { assetDisplays[i].alpha = 0; } // Show first frame assetDisplays[currentAssetIndex].alpha = 1; // Set up timer to cycle through frames every 100ms (10 FPS animation) for faster speed animationTimer = LK.setInterval(showNextFrame, 100); } // Start the frame animation startFrameAnimation(); // Play Fala music as background music with continuous looping LK.playMusic('Fala'); var isGameOver = false; LK.on('tick', function () { board.tick(); // Only check game over every 30 ticks (half second) to reduce performance impact if (LK.ticks % 30 === 0 && (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(); } } } });
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* 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 = [];
Board.prototype.spawnParticles = function (x, y, tint) {
for (var i = 0; i < 10; i++) {
var particle = new Particle(tint);
particle.x = x + (Math.random() - 0.5) * 50;
particle.y = y + (Math.random() - 0.5) * 50;
this.particles.push(particle);
this.addChild(particle);
// Add tween effect for particles with matching block color
tween(particle, {
scaleX: 0,
scaleY: 0,
alpha: 0,
x: particle.x + (Math.random() - 0.5) * 100,
y: particle.y + (Math.random() - 0.5) * 100
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
if (particle.parent) {
particle.destroy();
}
}
});
}
};
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);
// Play destruction sound when blocks are destroyed
LK.getSound('blockDestroy').play();
// Handle streak system
var currentTime = Date.now();
if (currentTime - lastLinesClearedTime <= streakTimeout && lastLinesClearedTime > 0) {
streakLevel = Math.min(streakLevel + 1, 6); // Cap at level 6
} else {
streakLevel = 1;
}
lastLinesClearedTime = currentTime;
// Show streak text
game.showStreakText(streakLevel);
for (var j = 0; j < 10; j++) {
if (rowFilled) {
var blockColor = self.grid[i][j].getBlockColor() || 0xffffff;
self.spawnParticles(self.grid[i][j].x, self.grid[i][j].y, blockColor);
self.grid[i][j].setFill(false);
}
if (colFilled) {
var blockColor = self.grid[j][i].getBlockColor() || 0xffffff;
self.spawnParticles(self.grid[j][i].x, self.grid[j][i].y, blockColor);
self.grid[j][i].setFill(false);
}
}
}
}
return rowsRemoved;
};
self.tick = function () {
// Process particles every other tick to reduce overhead
if (LK.ticks % 2 === 0) {
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);
}
}
}
}
// Optimize grid animation by processing fewer cells when not dragging
var processEveryNthCell = dragTarget ? 1 : 2;
for (var i = 0; i < 10; i += processEveryNthCell) {
for (var j = 0; j < 10; j += processEveryNthCell) {
self.grid[i][j].tick(i, j);
}
}
};
self.placeBlock = function () {};
});
var Cell = Container.expand(function () {
var self = Container.call(this);
self.filled = false;
var yOffsetArray = [-25, -10, -20, -25, -25, -20];
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, color) {
self.filled = isFilled;
empty.visible = !self.filled;
if (isFilled) {
if (asset) {
asset.x = 0;
asset.y = yOffsetArray[offset] || -15;
currentOffset = offset;
self.addChild(asset);
filled = asset;
if (color) {
self.currentTint = color;
self.blockColor = color; // Store the original block color
}
}
} else {
if (filled) {
filled.destroy();
filled = null;
}
}
};
self.tick = function (i, j) {
if (filled) {
// Reduce animation frequency to improve performance
var animationSpeed = LK.ticks / 4; // Slower animation
var offset = Math.cos(((i + j) * 3 + animationSpeed) / 6) / 20;
var ty = yOffsetArray[currentOffset] || -15;
filled.y = ty + Math.abs(offset * 200) - 5;
filled.rotation = offset;
}
};
self.getTint = function () {
return self.currentTint;
};
self.getBlockColor = function () {
return self.blockColor || 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: 0x000000
});
/****
* Game Code
****/
var gameBackground = game.attachAsset('gameBackground', {
anchorX: 0.5,
anchorY: 0.5
});
gameBackground.x = 2048 / 2;
gameBackground.y = 2732 / 2 + 65;
// Add asset1 to the front of the screen
var asset1Display = game.attachAsset('asset1', {
anchorX: 0.5,
anchorY: 0.5
});
asset1Display.x = 2048 / 2 + 30;
asset1Display.y = 2732 / 2 - 315;
// Add asset2 display with same positioning and properties as asset1
var asset2Display = game.attachAsset('asset2', {
anchorX: 0.5,
anchorY: 0.5
});
asset2Display.x = 2048 / 2 + 30;
asset2Display.y = 2732 / 2 - 315;
asset2Display.alpha = 0;
// Add asset3 display with same positioning and properties as asset1
var asset3Display = game.attachAsset('asset3', {
anchorX: 0.5,
anchorY: 0.5
});
asset3Display.x = 2048 / 2 + 30;
asset3Display.y = 2732 / 2 - 315;
asset3Display.alpha = 0;
// Add asset4 display with same positioning and properties as asset1
var asset4Display = game.attachAsset('asset4', {
anchorX: 0.5,
anchorY: 0.5
});
asset4Display.x = 2048 / 2 + 30;
asset4Display.y = 2732 / 2 - 315;
asset4Display.alpha = 0;
var blocks = [];
var dragTarget;
var board = game.addChild(new Board());
board.x = 2048 / 2;
board.y = 2732 / 2 - 250 + 30;
var targetOffset;
game.createBlock = function (index) {
var block = new Block(board);
block.x = 2048 / 2 + (index - 1) * (block.width + 50);
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) {
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, dragTarget.color);
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) {
score += Math.pow(pointsToAdd, 2) * 10;
LK.setScore(score);
scoreTxt.setText(score);
}
}
board.removeTint();
dragTarget = undefined;
}
});
game.createBlocks = function () {
for (var i = 0; i < 3; i++) {
game.createBlock(i);
}
};
game.showStreakText = function (level) {
// Remove existing streak text if any
if (streakText && streakText.parent) {
streakText.destroy();
}
var message = '';
var color = 0xFFFFFF;
if (level === 1) {
message = 'GOOD';
color = 0x00FF00; // Green
} else if (level === 2) {
message = 'SUPER';
color = 0x80FF00; // Green-Yellow
} else if (level === 3) {
message = 'WOW';
color = 0xFFFF00; // Yellow
} else if (level === 4) {
message = 'AMAZING';
color = 0xFF8000; // Yellow-Orange
} else if (level === 5) {
message = 'MANIAC';
color = 0xFF4000; // Orange-Red
} else if (level >= 6) {
message = 'CRAZYY!!!';
color = 0xFF0000; // Red
}
if (message) {
var newStreakText = new Text2(message, {
size: 200,
fill: color,
font: 'Impact',
stroke: '#000000',
strokeThickness: 8
});
// Position diagonally across screen (top-right diagonal style)
newStreakText.anchor.set(0.5, 0.5);
newStreakText.x = 2048 - 300; // Move to right side
newStreakText.y = 400; // Move to upper area
newStreakText.rotation = -0.2; // Slight diagonal angle
newStreakText.alpha = 0;
newStreakText.scaleX = 0.5;
newStreakText.scaleY = 0.5;
game.addChild(newStreakText);
streakText = newStreakText;
// Animate streak text appearance with elastic bounce effect
tween(newStreakText, {
alpha: 1,
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 600,
easing: tween.elasticOut,
onFinish: function onFinish() {
// Add a secondary bounce effect
tween(newStreakText, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 200,
easing: tween.bounceOut,
onFinish: function onFinish() {
// Animate text disappearance after showing
tween(newStreakText, {
alpha: 0,
scaleX: 0.8,
scaleY: 0.8,
y: newStreakText.y - 100
}, {
duration: 1500,
easing: tween.elasticIn,
onFinish: function onFinish() {
if (newStreakText && newStreakText.parent) {
newStreakText.destroy();
if (streakText === newStreakText) {
streakText = null;
}
}
}
});
}
});
}
});
}
};
var score = 0;
var lastLinesClearedTime = 0;
var streakLevel = 0;
var streakTimeout = 5000; // 5 seconds in milliseconds
var streakText = null;
game.createBlocks();
var scoreTxt = new Text2('0', {
size: 150,
fill: 0xFFFFFF,
font: 'Impact',
stroke: '#2a636e',
strokeThickness: 16
});
scoreTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(scoreTxt);
game.isMovePossible = function () {
// Cache blocks that exist for faster iteration
var activeBlocks = [];
for (var a = 0; a < blocks.length; a++) {
if (blocks[a]) {
activeBlocks.push(blocks[a]);
}
}
for (var blockIndex = 0; blockIndex < activeBlocks.length; blockIndex++) {
var block = activeBlocks[blockIndex];
// Check fewer positions by sampling every other position for performance
for (var i = 0; i < 10; i += 1) {
for (var j = 0; j < 10; j += 1) {
if (board.grid[i][j].filled) {
continue;
}
var canPlace = true;
// Early bounds checking
if (i + block.shape.length > 10 || j + block.shape[0].length > 10) {
continue;
}
for (var k = 0; k < block.shape.length && canPlace; k++) {
for (var l = 0; l < block.shape[k].length && canPlace; l++) {
if (block.shape[k][l] === 1) {
if (board.grid[i + k][j + l].filled) {
canPlace = false;
}
}
}
}
if (canPlace) {
return true;
}
}
}
}
return false;
};
// Create frame-based animation sequence for assets
var currentAssetIndex = 0;
var assetDisplays = [asset1Display, asset2Display, asset3Display, asset4Display];
var animationTimer;
function showNextFrame() {
// Hide all frames first for stability
for (var i = 0; i < assetDisplays.length; i++) {
assetDisplays[i].alpha = 0;
}
// Move to next frame
currentAssetIndex = (currentAssetIndex + 1) % assetDisplays.length;
// Show next frame
assetDisplays[currentAssetIndex].alpha = 1;
}
function startFrameAnimation() {
// Hide all frames initially for stability
for (var i = 0; i < assetDisplays.length; i++) {
assetDisplays[i].alpha = 0;
}
// Show first frame
assetDisplays[currentAssetIndex].alpha = 1;
// Set up timer to cycle through frames every 100ms (10 FPS animation) for faster speed
animationTimer = LK.setInterval(showNextFrame, 100);
}
// Start the frame animation
startFrameAnimation();
// Play Fala music as background music with continuous looping
LK.playMusic('Fala');
var isGameOver = false;
LK.on('tick', function () {
board.tick();
// Only check game over every 30 ticks (half second) to reduce performance impact
if (LK.ticks % 30 === 0 && (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 particle cloud. Cartoon. Bright outline. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Perfectly square bright purple Christmas decoration with cute happyy face. Cartoon style. Cute art style. Simple vector style.
Bunun herşeyini aynı yap sadece rengini koyu siyah ve mor yap surat ifadesi de kızgın ve yuĢzuĢnde kuĢçuĢk sıyrık ve kesikler olsun
Bunun hiç birşey ni degĢiştirme sadece rengini koyu yeşil ve açık yeşil nuĢkleer işareti koy ve arkaplanı olmasın
Bunun hiç birşey ni degĢiştirme sadece rengini koyu mavi ve açık gri ve alnına ters haç koy ve arkaplanı olmasın
Bunun hiç birşey ni degĢiştirme sadece rengini koyu kırmızı ve açık kırmızı.goĢzlerinin bebeklerini buĢyuĢlt ve kafasına şeytan boynuzlari koy ve arkaplanı olmasın
Bunun hiç birşey ni degĢiştirme sadece rengini koyu hayalet beyazı ve açık mor hayalet etekleri olsun alt kısmında ve arkaplanı olmasın
DuĢz arkaplan ama rengi koyu siyah ve açık kırmızı çizikler sıyrıklar olsun. In-Game asset. 2d. High contrast. No shadows
Bunun aynısı olsun yanlızca stili korku temalı olsun iç kısımdaki beyaz kısmı siyah ve kırmızı çizikler ve kesikler ekle
Rengini koyu yap mat olsun
Hiç birseyi degĢiştirme aynısını yap