User prompt
for one block make 10 points
Code edit (1 edits merged)
Please save this source code
User prompt
Stack the Blocks
Initial prompt
"Stack the Blocks" is a simple yet addictive casual game where players aim to build the tallest tower by stacking moving blocks on top of each other. Each block moves horizontally across the screen, and the player must tap at the right moment to drop it onto the previous one. If the block is not perfectly aligned, the overhanging part gets trimmed off, making the next block smaller and increasing the challenge. The game continues until a block completely misses the stack. With smooth animations, responsive tap controls, and progressively increasing speed, this game tests the player's timing and precision. Ideal for FRVR, it offers an endless gameplay loop perfect for mobile and web platforms.
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Block = Container.expand(function () {
var self = Container.call(this);
// Properties
self.blockWidth = 400;
self.blockHeight = 100;
self.movingDirection = 1; // 1 for right, -1 for left
self.speed = 10;
self.moving = true;
self.trimmedAmount = 0;
// Create block visual
var blockGraphics = self.attachAsset('block', {
anchorX: 0.5,
anchorY: 0.5,
width: self.blockWidth,
height: self.blockHeight
});
// Method to update block position
self.update = function () {
if (self.moving) {
self.x += self.speed * self.movingDirection;
// Bounce off the edges of the screen
if (self.x + self.blockWidth / 2 > 2048) {
self.x = 2048 - self.blockWidth / 2;
self.movingDirection = -1;
} else if (self.x - self.blockWidth / 2 < 0) {
self.x = self.blockWidth / 2;
self.movingDirection = 1;
}
}
};
// Method to stop the block from moving
self.stopMoving = function () {
self.moving = false;
};
// Method to trim the block based on the block below
self.trimToFit = function (prevBlockX, prevBlockWidth) {
// Calculate the trim amount
var leftEdge = self.x - self.blockWidth / 2;
var rightEdge = self.x + self.blockWidth / 2;
var prevLeftEdge = prevBlockX - prevBlockWidth / 2;
var prevRightEdge = prevBlockX + prevBlockWidth / 2;
// The block is completely off the stack
if (rightEdge < prevLeftEdge || leftEdge > prevRightEdge) {
self.blockWidth = 0;
self.trimmedAmount = self.blockWidth;
return false;
}
// Calculate new dimensions after trimming
var newLeftEdge = Math.max(leftEdge, prevLeftEdge);
var newRightEdge = Math.min(rightEdge, prevRightEdge);
var newWidth = newRightEdge - newLeftEdge;
// Store the trimmed amount
self.trimmedAmount = self.blockWidth - newWidth;
// Update the block width
self.blockWidth = newWidth;
// Update the visual representation
blockGraphics.width = self.blockWidth;
// Center the block on its visible portion
self.x = newLeftEdge + newWidth / 2;
return true;
};
// Method to highlight block when it's a miss
self.highlightMiss = function () {
// Replace current graphics with red block
blockGraphics.destroy();
blockGraphics = self.attachAsset('gameOverBlock', {
anchorX: 0.5,
anchorY: 0.5,
width: self.blockWidth,
height: self.blockHeight
});
};
return self;
});
var StackedBlock = Container.expand(function () {
var self = Container.call(this);
// Properties
self.blockWidth = 400;
self.blockHeight = 100;
// Create block visual
var blockGraphics = self.attachAsset('stackBlock', {
anchorX: 0.5,
anchorY: 0.5,
width: self.blockWidth,
height: self.blockHeight
});
// Method to set the width
self.setWidth = function (width) {
self.blockWidth = width;
blockGraphics.width = width;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Game state variables
var currentBlock;
var stackedBlocks = [];
var baseY = 2400;
var score = 0;
var gameActive = false;
var difficultyLevel = 1;
var lastBlockWidth = 400;
var lastBlockX = 2048 / 2;
// Create base platform
var base = game.addChild(LK.getAsset('base', {
anchorX: 0.5,
anchorY: 0.5
}));
base.x = 2048 / 2;
base.y = baseY;
base.width = 480;
// UI Elements
var scoreTxt = new Text2('0', {
size: 100,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var instructionTxt = new Text2('Tap to drop blocks and build your tower!', {
size: 60,
fill: 0xFFFFFF
});
instructionTxt.anchor.set(0.5, 0.5);
instructionTxt.x = 0;
instructionTxt.y = 300;
LK.gui.center.addChild(instructionTxt);
// Game logic methods
function startGame() {
// Reset game state
for (var i = 0; i < stackedBlocks.length; i++) {
stackedBlocks[i].destroy();
}
stackedBlocks = [];
score = 0;
difficultyLevel = 1;
baseY = 2400;
lastBlockWidth = 400;
lastBlockX = 2048 / 2;
gameActive = true;
// Update score display
scoreTxt.setText('0');
// Hide instruction text
instructionTxt.visible = false;
// Create first block
spawnNewBlock();
// Start background music
LK.playMusic('bgMusic');
}
function spawnNewBlock() {
currentBlock = new Block();
currentBlock.blockWidth = lastBlockWidth;
var blockGraphics = currentBlock.getChildAt(0);
blockGraphics.width = currentBlock.blockWidth;
// Randomly start from left or right
currentBlock.x = Math.random() > 0.5 ? 0 + currentBlock.blockWidth / 2 : 2048 - currentBlock.blockWidth / 2;
currentBlock.y = baseY - (stackedBlocks.length + 1) * 110;
currentBlock.movingDirection = currentBlock.x < 1024 ? 1 : -1;
// Increase speed based on difficulty level
currentBlock.speed = 5 + difficultyLevel;
game.addChild(currentBlock);
}
function dropBlock() {
if (!currentBlock || !gameActive) {
return;
}
// Stop the block from moving
currentBlock.stopMoving();
// Check if the block fits on the previous block
var successfulPlacement = true;
if (stackedBlocks.length > 0) {
successfulPlacement = currentBlock.trimToFit(lastBlockX, lastBlockWidth);
}
if (successfulPlacement && currentBlock.blockWidth > 0) {
// Play placement sound
LK.getSound('place').play();
// Update variables for next block
lastBlockWidth = currentBlock.blockWidth;
lastBlockX = currentBlock.x;
// Create a stacked version of the block
var stackedBlock = new StackedBlock();
stackedBlock.setWidth(lastBlockWidth);
stackedBlock.x = lastBlockX;
stackedBlock.y = currentBlock.y;
game.addChild(stackedBlock);
stackedBlocks.push(stackedBlock);
// Remove the moving block
currentBlock.destroy();
currentBlock = null;
// Update score
score += 10;
scoreTxt.setText(score.toString());
// Increase difficulty every 5 points
if (score % 5 === 0) {
difficultyLevel++;
}
// After a short delay, spawn a new block
LK.setTimeout(function () {
spawnNewBlock();
}, 300);
} else {
// Game over
gameActive = false;
// Play miss sound
LK.getSound('miss').play();
// Highlight the missed block in red
currentBlock.highlightMiss();
// Make the block fall off screen
tween(currentBlock, {
y: 3000,
rotation: Math.PI * 2
}, {
duration: 1500,
easing: tween.easeIn,
onFinish: function onFinish() {
// Check if this is a new high score
var highScore = storage.highScore || 0;
if (score > highScore) {
storage.highScore = score;
}
// Show game over screen after a short delay
LK.setTimeout(function () {
LK.showGameOver();
}, 500);
}
});
}
}
function moveCamera() {
// Only move camera if we have enough stacked blocks
if (stackedBlocks.length > 8) {
// Target Y for the topmost block
var targetY = 2732 / 2;
// Calculate how much to move everything down
var moveAmount = baseY - (stackedBlocks.length + 1) * 110 - targetY;
// Move everything down
base.y -= moveAmount;
for (var i = 0; i < stackedBlocks.length; i++) {
stackedBlocks[i].y -= moveAmount;
}
if (currentBlock) {
currentBlock.y -= moveAmount;
}
baseY -= moveAmount;
}
}
// Input handlers
game.down = function (x, y, obj) {
if (!gameActive) {
startGame();
} else {
dropBlock();
}
};
// Update method
game.update = function () {
if (currentBlock && gameActive) {
currentBlock.update();
}
// Move camera to follow the tower
moveCamera();
};
// Show instruction text at start
instructionTxt.visible = true; ===================================================================
--- original.js
+++ change.js
@@ -205,9 +205,9 @@
// Remove the moving block
currentBlock.destroy();
currentBlock = null;
// Update score
- score++;
+ score += 10;
scoreTxt.setText(score.toString());
// Increase difficulty every 5 points
if (score % 5 === 0) {
difficultyLevel++;