/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Block = Container.expand(function () {
var self = Container.call(this);
self.blockWidth = 200;
self.isMoving = true;
self.direction = 1;
self.speed = 2;
self.baseY = 0;
// Create the main block
var blockGraphics = self.attachAsset('block', {
anchorX: 0.5,
anchorY: 0.5
});
// Create shadow for 3D effect
var shadowGraphics = self.attachAsset('shadow', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3,
scaleX: 1.1,
scaleY: 0.3
});
shadowGraphics.y = 35; // Offset shadow below block
self.setWidth = function (newWidth) {
self.blockWidth = newWidth;
blockGraphics.width = newWidth;
shadowGraphics.width = newWidth * 1.1;
};
self.setColor = function (color) {
blockGraphics.tint = color;
};
self.stopMoving = function () {
self.isMoving = false;
};
self.getOverlap = function (targetX, targetWidth) {
var leftEdge = self.x - self.blockWidth / 2;
var rightEdge = self.x + self.blockWidth / 2;
var targetLeft = targetX - targetWidth / 2;
var targetRight = targetX + targetWidth / 2;
var overlapLeft = Math.max(leftEdge, targetLeft);
var overlapRight = Math.min(rightEdge, targetRight);
if (overlapLeft >= overlapRight) {
return {
width: 0,
centerX: 0
};
}
return {
width: overlapRight - overlapLeft,
centerX: (overlapLeft + overlapRight) / 2
};
};
self.update = function () {
if (self.isMoving) {
self.x += self.speed * self.direction;
// Bounce off screen edges
if (self.x <= self.blockWidth / 2) {
self.direction = 1;
self.x = self.blockWidth / 2;
} else if (self.x >= 2048 - self.blockWidth / 2) {
self.direction = -1;
self.x = 2048 - self.blockWidth / 2;
}
}
};
return self;
});
var Particle = Container.expand(function () {
var self = Container.call(this);
var particle = self.attachAsset('block', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.1,
scaleY: 0.1
});
particle.tint = 0xFFD700; // Gold color
self.velocityX = (Math.random() - 0.5) * 10;
self.velocityY = -Math.random() * 8 - 2;
self.gravity = 0.3;
self.life = 60; // 1 second at 60fps
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
self.velocityY += self.gravity;
self.life--;
self.alpha = self.life / 60;
if (self.life <= 0) {
self.destroy();
particles.splice(particles.indexOf(self), 1);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB // Sky blue
});
/****
* Game Code
****/
// Game state variables
var tower = [];
var currentBlock = null;
var gameRunning = true;
var level = 1;
var baseBlockWidth = 200;
var currentBlockWidth = baseBlockWidth;
var particles = [];
var perfectCount = 0;
var cameraY = 2732 / 2;
// Create gradient sky background
game.setBackgroundColor(0x87CEEB);
// UI Elements
var scoreText = new Text2('Level: 1', {
size: 80,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
var perfectText = new Text2('', {
size: 60,
fill: 0xFFD700
});
perfectText.anchor.set(0.5, 0);
perfectText.y = 100;
LK.gui.top.addChild(perfectText);
// Create base block
function createBaseBlock() {
var baseBlock = new Block();
baseBlock.x = 2048 / 2;
baseBlock.y = 2400;
baseBlock.stopMoving();
baseBlock.setColor(0x2E7D32); // Darker green for base
tower.push({
x: baseBlock.x,
y: baseBlock.y,
width: baseBlock.blockWidth,
block: baseBlock
});
game.addChild(baseBlock);
}
// Create new moving block
function createNewBlock() {
if (!gameRunning) return;
currentBlock = new Block();
currentBlock.setWidth(currentBlockWidth);
// Position above the last block
var lastBlock = tower[tower.length - 1];
currentBlock.x = 100; // Start from left side
currentBlock.y = lastBlock.y - 80;
// Increase speed every 10 levels
var speedMultiplier = 1 + Math.floor(level / 10) * 0.5;
currentBlock.speed = 2 * speedMultiplier;
// Color gradient based on level
var greenShade = 0x4CAF50 + level % 10 * 0x001100;
currentBlock.setColor(greenShade);
game.addChild(currentBlock);
}
// Handle block placement
function placeBlock() {
if (!currentBlock || !gameRunning) return;
currentBlock.stopMoving();
var lastBlock = tower[tower.length - 1];
var overlap = currentBlock.getOverlap(lastBlock.x, lastBlock.width);
if (overlap.width <= 0) {
// No overlap - game over
gameOver();
return;
}
// Check if placement is perfect (within 10 pixels of center)
var isPerfect = Math.abs(currentBlock.x - lastBlock.x) < 10;
if (isPerfect) {
// Perfect placement
perfectCount++;
LK.getSound('perfect').play();
// Create particles
for (var i = 0; i < 8; i++) {
var particle = new Particle();
particle.x = currentBlock.x;
particle.y = currentBlock.y;
particles.push(particle);
game.addChild(particle);
}
// Show perfect text
perfectText.setText('PERFECT!');
tween(perfectText, {
alpha: 0
}, {
duration: 1000
});
// Keep same width for perfect placement
currentBlockWidth = lastBlock.width;
} else {
// Cut the block
currentBlockWidth = overlap.width;
currentBlock.setWidth(currentBlockWidth);
currentBlock.x = overlap.centerX;
LK.getSound('cut').play();
// Reset perfect text
perfectText.alpha = 1;
perfectText.setText('');
}
LK.getSound('place').play();
// Add to tower
tower.push({
x: currentBlock.x,
y: currentBlock.y,
width: currentBlockWidth,
block: currentBlock
});
// Update score
level++;
LK.setScore(level - 1);
scoreText.setText('Level: ' + level);
// Update camera position
updateCamera();
// Check for minimum width
if (currentBlockWidth < 20) {
gameOver();
return;
}
// Create next block after short delay
LK.setTimeout(function () {
createNewBlock();
}, 300);
}
// Update camera to follow tower
function updateCamera() {
if (tower.length > 0) {
var targetY = tower[tower.length - 1].y + 400;
tween(game, {
y: -targetY + 2732 / 2
}, {
duration: 500,
easing: tween.easeOut
});
}
}
// Game over
function gameOver() {
gameRunning = false;
// Flash screen red
LK.effects.flashScreen(0xff0000, 1000);
LK.setTimeout(function () {
LK.showGameOver();
}, 1000);
}
// Touch controls
game.down = function (x, y, obj) {
if (gameRunning && currentBlock) {
placeBlock();
}
};
// Initialize game
createBaseBlock();
createNewBlock();
// Main game loop
game.update = function () {
// Update particles
for (var i = particles.length - 1; i >= 0; i--) {
// Particles update themselves and remove from array when done
}
// Check if block fell too far (safety check)
if (currentBlock && currentBlock.y > 3000) {
gameOver();
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Block = Container.expand(function () {
var self = Container.call(this);
self.blockWidth = 200;
self.isMoving = true;
self.direction = 1;
self.speed = 2;
self.baseY = 0;
// Create the main block
var blockGraphics = self.attachAsset('block', {
anchorX: 0.5,
anchorY: 0.5
});
// Create shadow for 3D effect
var shadowGraphics = self.attachAsset('shadow', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3,
scaleX: 1.1,
scaleY: 0.3
});
shadowGraphics.y = 35; // Offset shadow below block
self.setWidth = function (newWidth) {
self.blockWidth = newWidth;
blockGraphics.width = newWidth;
shadowGraphics.width = newWidth * 1.1;
};
self.setColor = function (color) {
blockGraphics.tint = color;
};
self.stopMoving = function () {
self.isMoving = false;
};
self.getOverlap = function (targetX, targetWidth) {
var leftEdge = self.x - self.blockWidth / 2;
var rightEdge = self.x + self.blockWidth / 2;
var targetLeft = targetX - targetWidth / 2;
var targetRight = targetX + targetWidth / 2;
var overlapLeft = Math.max(leftEdge, targetLeft);
var overlapRight = Math.min(rightEdge, targetRight);
if (overlapLeft >= overlapRight) {
return {
width: 0,
centerX: 0
};
}
return {
width: overlapRight - overlapLeft,
centerX: (overlapLeft + overlapRight) / 2
};
};
self.update = function () {
if (self.isMoving) {
self.x += self.speed * self.direction;
// Bounce off screen edges
if (self.x <= self.blockWidth / 2) {
self.direction = 1;
self.x = self.blockWidth / 2;
} else if (self.x >= 2048 - self.blockWidth / 2) {
self.direction = -1;
self.x = 2048 - self.blockWidth / 2;
}
}
};
return self;
});
var Particle = Container.expand(function () {
var self = Container.call(this);
var particle = self.attachAsset('block', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.1,
scaleY: 0.1
});
particle.tint = 0xFFD700; // Gold color
self.velocityX = (Math.random() - 0.5) * 10;
self.velocityY = -Math.random() * 8 - 2;
self.gravity = 0.3;
self.life = 60; // 1 second at 60fps
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
self.velocityY += self.gravity;
self.life--;
self.alpha = self.life / 60;
if (self.life <= 0) {
self.destroy();
particles.splice(particles.indexOf(self), 1);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB // Sky blue
});
/****
* Game Code
****/
// Game state variables
var tower = [];
var currentBlock = null;
var gameRunning = true;
var level = 1;
var baseBlockWidth = 200;
var currentBlockWidth = baseBlockWidth;
var particles = [];
var perfectCount = 0;
var cameraY = 2732 / 2;
// Create gradient sky background
game.setBackgroundColor(0x87CEEB);
// UI Elements
var scoreText = new Text2('Level: 1', {
size: 80,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
var perfectText = new Text2('', {
size: 60,
fill: 0xFFD700
});
perfectText.anchor.set(0.5, 0);
perfectText.y = 100;
LK.gui.top.addChild(perfectText);
// Create base block
function createBaseBlock() {
var baseBlock = new Block();
baseBlock.x = 2048 / 2;
baseBlock.y = 2400;
baseBlock.stopMoving();
baseBlock.setColor(0x2E7D32); // Darker green for base
tower.push({
x: baseBlock.x,
y: baseBlock.y,
width: baseBlock.blockWidth,
block: baseBlock
});
game.addChild(baseBlock);
}
// Create new moving block
function createNewBlock() {
if (!gameRunning) return;
currentBlock = new Block();
currentBlock.setWidth(currentBlockWidth);
// Position above the last block
var lastBlock = tower[tower.length - 1];
currentBlock.x = 100; // Start from left side
currentBlock.y = lastBlock.y - 80;
// Increase speed every 10 levels
var speedMultiplier = 1 + Math.floor(level / 10) * 0.5;
currentBlock.speed = 2 * speedMultiplier;
// Color gradient based on level
var greenShade = 0x4CAF50 + level % 10 * 0x001100;
currentBlock.setColor(greenShade);
game.addChild(currentBlock);
}
// Handle block placement
function placeBlock() {
if (!currentBlock || !gameRunning) return;
currentBlock.stopMoving();
var lastBlock = tower[tower.length - 1];
var overlap = currentBlock.getOverlap(lastBlock.x, lastBlock.width);
if (overlap.width <= 0) {
// No overlap - game over
gameOver();
return;
}
// Check if placement is perfect (within 10 pixels of center)
var isPerfect = Math.abs(currentBlock.x - lastBlock.x) < 10;
if (isPerfect) {
// Perfect placement
perfectCount++;
LK.getSound('perfect').play();
// Create particles
for (var i = 0; i < 8; i++) {
var particle = new Particle();
particle.x = currentBlock.x;
particle.y = currentBlock.y;
particles.push(particle);
game.addChild(particle);
}
// Show perfect text
perfectText.setText('PERFECT!');
tween(perfectText, {
alpha: 0
}, {
duration: 1000
});
// Keep same width for perfect placement
currentBlockWidth = lastBlock.width;
} else {
// Cut the block
currentBlockWidth = overlap.width;
currentBlock.setWidth(currentBlockWidth);
currentBlock.x = overlap.centerX;
LK.getSound('cut').play();
// Reset perfect text
perfectText.alpha = 1;
perfectText.setText('');
}
LK.getSound('place').play();
// Add to tower
tower.push({
x: currentBlock.x,
y: currentBlock.y,
width: currentBlockWidth,
block: currentBlock
});
// Update score
level++;
LK.setScore(level - 1);
scoreText.setText('Level: ' + level);
// Update camera position
updateCamera();
// Check for minimum width
if (currentBlockWidth < 20) {
gameOver();
return;
}
// Create next block after short delay
LK.setTimeout(function () {
createNewBlock();
}, 300);
}
// Update camera to follow tower
function updateCamera() {
if (tower.length > 0) {
var targetY = tower[tower.length - 1].y + 400;
tween(game, {
y: -targetY + 2732 / 2
}, {
duration: 500,
easing: tween.easeOut
});
}
}
// Game over
function gameOver() {
gameRunning = false;
// Flash screen red
LK.effects.flashScreen(0xff0000, 1000);
LK.setTimeout(function () {
LK.showGameOver();
}, 1000);
}
// Touch controls
game.down = function (x, y, obj) {
if (gameRunning && currentBlock) {
placeBlock();
}
};
// Initialize game
createBaseBlock();
createNewBlock();
// Main game loop
game.update = function () {
// Update particles
for (var i = particles.length - 1; i >= 0; i--) {
// Particles update themselves and remove from array when done
}
// Check if block fell too far (safety check)
if (currentBlock && currentBlock.y > 3000) {
gameOver();
}
};