User prompt
Play stackmaster music off all game
User prompt
Play blockkoyma sound when block is placed
User prompt
if camera moves move the background in the same way at the same time
User prompt
change background's location according camera
User prompt
change backgrounds texture with texture named background
User prompt
create background and set that texture named background
User prompt
cut out the areas left outside when the block is placed
User prompt
change cameras road just the opposite
User prompt
keep camera tracking block to 1000
User prompt
keep camera tracking to 1000 point
User prompt
keep camera tracking to 1000 point
User prompt
keep the camera tracking continuously
User prompt
if blocks goes out of camera, change the camera location accordingly
User prompt
set perfectly a little bit harder
User prompt
Set easier for perfect
User prompt
İncrease speed of block step by step
User prompt
İf the blocks stacks perfect write perfect at screen
Code edit (1 edits merged)
Please save this source code
User prompt
Stack Master: Block Tower
Initial prompt
A block move horizontally and we are trying stack blocks
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Block class for stackable blocks var Block = Container.expand(function () { var self = Container.call(this); // Attach block asset var blockAsset = self.attachAsset('block', { anchorX: 0.5, anchorY: 0.5 }); // Store reference for resizing self.blockAsset = blockAsset; // Set initial width/height self.setBlockSize = function (width, height) { blockAsset.width = width; blockAsset.height = height; self.width = width; self.height = height; }; // Animate block to a new position (used for dropping) self.animateDrop = function (targetY, onFinish) { tween(self, { y: targetY }, { duration: 180, easing: tween.cubicIn, onFinish: onFinish }); }; // Animate block to a new width (used for trimming) self.animateTrim = function (newWidth, newX, onFinish) { tween(self.blockAsset, { width: newWidth }, { duration: 120, easing: tween.linear }); tween(self, { x: newX }, { duration: 120, easing: tween.linear, onFinish: onFinish }); }; // Set color (for overhangs) self.setColor = function (color) { blockAsset.color = color; }; return self; }); // Overhang class for falling pieces var Overhang = Container.expand(function () { var self = Container.call(this); var overhangAsset = self.attachAsset('overhang', { anchorX: 0.5, anchorY: 0.5 }); self.setOverhangSize = function (width, height) { overhangAsset.width = width; overhangAsset.height = height; self.width = width; self.height = height; }; // Animate falling self.fall = function (onFinish) { tween(self, { y: self.y + 400 }, { duration: 400, easing: tween.cubicIn, onFinish: onFinish }); tween(self, { alpha: 0 }, { duration: 400, easing: tween.linear }); }; // Set color self.setColor = function (color) { overhangAsset.color = color; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222a36 }); /**** * Game Code ****/ // Overhang asset: red // Base block asset: darker blue // Block asset: blue rectangle // Game constants var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; var BLOCK_HEIGHT = 100; var BLOCK_START_WIDTH = 600; var BLOCK_MIN_WIDTH = 40; var BLOCK_SPEED_START = 12; var BLOCK_SPEED_INCREMENT = 0.7; var BLOCK_Y_START = GAME_HEIGHT - 400; var BLOCK_Y_GAP = 90; // vertical gap between blocks // State variables var stack = []; // Array of stacked blocks var currentBlock = null; // The moving block var currentLevel = 0; // How many blocks stacked var blockSpeed = BLOCK_SPEED_START; var blockDirection = 1; // 1 = right, -1 = left var isDropping = false; var isGameOver = false; var scoreTxt = null; var cameraY = 0; // Camera Y offset for following the stack // GUI: Score display scoreTxt = new Text2('0', { size: 120, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Center score, but not in top left 100x100 scoreTxt.x = LK.gui.top.width / 2; scoreTxt.y = 30; // Add base block var baseBlock = new Block(); baseBlock.setBlockSize(BLOCK_START_WIDTH, BLOCK_HEIGHT); baseBlock.x = GAME_WIDTH / 2; baseBlock.y = BLOCK_Y_START; baseBlock.blockAsset.color = 0x21618c; // darker game.addChild(baseBlock); stack.push(baseBlock); // Start first moving block function spawnBlock() { var prevBlock = stack[stack.length - 1]; var newBlock = new Block(); newBlock.setBlockSize(prevBlock.blockAsset.width, BLOCK_HEIGHT); // Start at left or right edge, alternate var startX = blockDirection === 1 ? GAME_WIDTH / 2 - 400 : GAME_WIDTH / 2 + 400; newBlock.x = startX; newBlock.y = prevBlock.y - BLOCK_Y_GAP; game.addChild(newBlock); currentBlock = newBlock; isDropping = false; } function updateScore() { scoreTxt.setText(currentLevel); } // Drop the current block function dropBlock() { if (isDropping || isGameOver) return; isDropping = true; var prevBlock = stack[stack.length - 1]; var overlap = getOverlap(currentBlock, prevBlock); if (overlap.width <= 0 || overlap.width < BLOCK_MIN_WIDTH) { // No overlap or too small: game over currentBlock.animateDrop(prevBlock.y - BLOCK_Y_GAP, function () { endGame(); }); return; } // Animate block drop currentBlock.animateDrop(prevBlock.y - BLOCK_Y_GAP, function () { // Trim block to overlap var trimmedX = overlap.center; var trimmedWidth = overlap.width; // Check for perfect stack (allowing 5px tolerance) var isPerfect = Math.abs(currentBlock.x - prevBlock.x) < 5; // Calculate overhang areas var leftOverhang = 0; var rightOverhang = 0; var currentLeft = currentBlock.x - currentBlock.blockAsset.width / 2; var currentRight = currentBlock.x + currentBlock.blockAsset.width / 2; var prevLeft = prevBlock.x - prevBlock.blockAsset.width / 2; var prevRight = prevBlock.x + prevBlock.blockAsset.width / 2; // Calculate left overhang if (currentLeft < prevLeft) { leftOverhang = prevLeft - currentLeft; } // Calculate right overhang if (currentRight > prevRight) { rightOverhang = currentRight - prevRight; } // Animate trim currentBlock.animateTrim(trimmedWidth, trimmedX, function () { // Add left overhang if any if (leftOverhang > 0.5) { var leftOverhangX = prevLeft - leftOverhang / 2; var leftOverhangObj = new Overhang(); leftOverhangObj.setOverhangSize(leftOverhang, BLOCK_HEIGHT); leftOverhangObj.x = leftOverhangX; leftOverhangObj.y = currentBlock.y; leftOverhangObj.setColor(0xe74c3c); game.addChild(leftOverhangObj); leftOverhangObj.fall(function () { leftOverhangObj.destroy(); }); } // Add right overhang if any if (rightOverhang > 0.5) { var rightOverhangX = prevRight + rightOverhang / 2; var rightOverhangObj = new Overhang(); rightOverhangObj.setOverhangSize(rightOverhang, BLOCK_HEIGHT); rightOverhangObj.x = rightOverhangX; rightOverhangObj.y = currentBlock.y; rightOverhangObj.setColor(0xe74c3c); game.addChild(rightOverhangObj); rightOverhangObj.fall(function () { rightOverhangObj.destroy(); }); } // Show "Perfect" text if perfectly stacked if (isPerfect) { var perfectTxt = new Text2('Perfect!', { size: 120, fill: 0xFFD700 }); perfectTxt.anchor.set(0.5, 0.5); perfectTxt.x = currentBlock.x; perfectTxt.y = currentBlock.y - BLOCK_HEIGHT; game.addChild(perfectTxt); tween(perfectTxt, { y: perfectTxt.y - 120, alpha: 0 }, { duration: 700, easing: tween.cubicOut, onFinish: function onFinish() { perfectTxt.destroy(); } }); } // Finalize block currentBlock.setBlockSize(trimmedWidth, BLOCK_HEIGHT); currentBlock.x = trimmedX; stack.push(currentBlock); // Next round currentLevel += 1; updateScore(); // Increase speed a bit, with a cap to prevent it from becoming unplayable blockSpeed += BLOCK_SPEED_INCREMENT; if (blockSpeed > 40) blockSpeed = 40; // Cap speed for playability blockDirection *= -1; // alternate direction spawnBlock(); }); }); } // Calculate overlap between two blocks function getOverlap(blockA, blockB) { var leftA = blockA.x - blockA.blockAsset.width / 2; var rightA = blockA.x + blockA.blockAsset.width / 2; var leftB = blockB.x - blockB.blockAsset.width / 2; var rightB = blockB.x + blockB.blockAsset.width / 2; var left = Math.max(leftA, leftB); var right = Math.min(rightA, rightB); var width = right - left; var center = left + width / 2; return { width: width, center: center }; } // End game function endGame() { isGameOver = true; // Flash screen red LK.effects.flashScreen(0xe74c3c, 800); // Show game over popup (handled by LK) LK.showGameOver(); } // Handle tap/click to drop block game.down = function (x, y, obj) { if (isGameOver) return; dropBlock(); }; // Main update loop game.update = function () { if (isGameOver) return; if (!currentBlock) { spawnBlock(); return; } if (isDropping) return; // Move block horizontally currentBlock.x += blockSpeed * blockDirection; // Bounce at screen edges (keep inside 200px from edge) var minX = 200 + currentBlock.blockAsset.width / 2; var maxX = GAME_WIDTH - 200 - currentBlock.blockAsset.width / 2; if (currentBlock.x > maxX) { currentBlock.x = maxX; blockDirection = -1; } if (currentBlock.x < minX) { currentBlock.x = minX; blockDirection = 1; } // Update camera to follow the stack continuously up to 1000 points if (stack.length > 0 && currentLevel <= 1000) { var topBlock = stack[stack.length - 1]; // Include current moving block in camera calculation if it exists var highestY = topBlock.y; if (currentBlock && !isDropping) { highestY = Math.min(topBlock.y, currentBlock.y); } // Calculate target camera position to move camera down as stack grows up var targetCameraY = Math.max(0, BLOCK_Y_START - highestY - GAME_HEIGHT / 2); // Smooth camera movement cameraY += (targetCameraY - cameraY) * 0.15; // Reverse camera direction - positive cameraY moves view down game.y = cameraY; } }; // Reset game state on restart game.on('reset', function () { // Remove all blocks except base for (var i = 1; i < stack.length; i++) { stack[i].destroy(); } stack = [baseBlock]; baseBlock.setBlockSize(BLOCK_START_WIDTH, BLOCK_HEIGHT); baseBlock.x = GAME_WIDTH / 2; baseBlock.y = BLOCK_Y_START; currentBlock = null; currentLevel = 0; blockSpeed = BLOCK_SPEED_START; blockDirection = 1; isDropping = false; isGameOver = false; cameraY = 0; game.y = 0; updateScore(); }); // Initial score updateScore();
===================================================================
--- original.js
+++ change.js
@@ -177,24 +177,51 @@
var trimmedX = overlap.center;
var trimmedWidth = overlap.width;
// Check for perfect stack (allowing 5px tolerance)
var isPerfect = Math.abs(currentBlock.x - prevBlock.x) < 5;
+ // Calculate overhang areas
+ var leftOverhang = 0;
+ var rightOverhang = 0;
+ var currentLeft = currentBlock.x - currentBlock.blockAsset.width / 2;
+ var currentRight = currentBlock.x + currentBlock.blockAsset.width / 2;
+ var prevLeft = prevBlock.x - prevBlock.blockAsset.width / 2;
+ var prevRight = prevBlock.x + prevBlock.blockAsset.width / 2;
+ // Calculate left overhang
+ if (currentLeft < prevLeft) {
+ leftOverhang = prevLeft - currentLeft;
+ }
+ // Calculate right overhang
+ if (currentRight > prevRight) {
+ rightOverhang = currentRight - prevRight;
+ }
// Animate trim
currentBlock.animateTrim(trimmedWidth, trimmedX, function () {
- // Add overhang if any
- var overhangWidth = currentBlock.blockAsset.width - trimmedWidth;
- if (overhangWidth > 0.5) {
- var overhangX = currentBlock.x < prevBlock.x ? trimmedX - trimmedWidth / 2 - overhangWidth / 2 : trimmedX + trimmedWidth / 2 + overhangWidth / 2;
- var overhang = new Overhang();
- overhang.setOverhangSize(overhangWidth, BLOCK_HEIGHT);
- overhang.x = overhangX;
- overhang.y = currentBlock.y;
- overhang.setColor(0xe74c3c);
- game.addChild(overhang);
- overhang.fall(function () {
- overhang.destroy();
+ // Add left overhang if any
+ if (leftOverhang > 0.5) {
+ var leftOverhangX = prevLeft - leftOverhang / 2;
+ var leftOverhangObj = new Overhang();
+ leftOverhangObj.setOverhangSize(leftOverhang, BLOCK_HEIGHT);
+ leftOverhangObj.x = leftOverhangX;
+ leftOverhangObj.y = currentBlock.y;
+ leftOverhangObj.setColor(0xe74c3c);
+ game.addChild(leftOverhangObj);
+ leftOverhangObj.fall(function () {
+ leftOverhangObj.destroy();
});
}
+ // Add right overhang if any
+ if (rightOverhang > 0.5) {
+ var rightOverhangX = prevRight + rightOverhang / 2;
+ var rightOverhangObj = new Overhang();
+ rightOverhangObj.setOverhangSize(rightOverhang, BLOCK_HEIGHT);
+ rightOverhangObj.x = rightOverhangX;
+ rightOverhangObj.y = currentBlock.y;
+ rightOverhangObj.setColor(0xe74c3c);
+ game.addChild(rightOverhangObj);
+ rightOverhangObj.fall(function () {
+ rightOverhangObj.destroy();
+ });
+ }
// Show "Perfect" text if perfectly stacked
if (isPerfect) {
var perfectTxt = new Text2('Perfect!', {
size: 120,