User prompt
Nesne boyutları biraz kücült
User prompt
Parcacıl ve blok gibi sıklıkla olusturulan yok edilen nesneler için nesne pirleştirme uygula
User prompt
Nesneleri biraz büyült
User prompt
Oyun müzigi
User prompt
Parçacık dagılımı için resim ekle
User prompt
İp boştayken sallanmaya devam etsin ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
İp boşta kaldıgında gitar teli gibi sallansın ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Arkplan rengini gri yap
User prompt
Taş dönme animasyonu kaldır
User prompt
30 yap
User prompt
Taş dönme animasyonu kaldor
User prompt
Bşraz yukarı
User prompt
Biraz daha
User prompt
İp ve üst blogu aşagı uzat
User prompt
İp ve baglı blogu biraz aşagı uzat
User prompt
25 yap
User prompt
20 yap
User prompt
15 yap
User prompt
Kesişme yüzey alanı 100 de 10 veya daha az ise oyun niter
User prompt
Başlangıcta ip sallantısı cok hızlı ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Oyun varlık boyutlarını biraz büyüt
User prompt
Blok düşme sesi ekle
User prompt
Parçacık dagılma efektini arttır ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Çarpışma sesi ekle
User prompt
Çarpışma animasyonuna dagılan parçacıklar ekle ↪💡 Consider importing and using the following plugins: @upit/tween.v1
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var CutPiece = Container.expand(function () {
var self = Container.call(this);
var piece = self.attachAsset('cutPiece', {
anchorX: 0.5,
anchorY: 0.5
});
self.animate = function (direction, blockWidth) {
// Set initial appearance
piece.alpha = 1;
piece.width = blockWidth;
// Animate piece falling and rotating
var fallDirection = direction === 'left' ? -1 : 1;
tween(self, {
x: self.x + fallDirection * 400,
y: self.y + 600,
rotation: fallDirection * Math.PI * 2
}, {
duration: 1200,
easing: tween.easeIn
});
tween(piece, {
alpha: 0
}, {
duration: 1200,
easing: tween.linear,
onFinish: function onFinish() {
self.destroyed = true;
returnCutPieceToPool(self);
}
});
};
return self;
});
var Particle = Container.expand(function () {
var self = Container.call(this);
var particle = self.attachAsset('particle', {
anchorX: 0.5,
anchorY: 0.5
});
particle.width = 28;
particle.height = 28;
self.animate = function (velocityX, velocityY, color) {
// Set particle color with slight brightness variation
particle.tint = color || 0xFFFFFF;
// Randomize particle size for more variety
var sizeVariation = 0.5 + Math.random() * 1.0; // Size between 0.5x and 1.5x
particle.width = 28 * sizeVariation;
particle.height = 28 * sizeVariation;
// Set initial velocity with slight randomness
self.velocityX = velocityX + (Math.random() - 0.5) * 2;
self.velocityY = velocityY + (Math.random() - 0.5) * 2;
// Vary gravity for different particle behavior
self.gravity = 0.3 + Math.random() * 0.4; // Gravity between 0.3 and 0.7
// Vary particle lifetime for more dynamic effect
self.life = 45 + Math.random() * 30; // Lifetime between 45-75 frames
self.maxLife = self.life;
// Add initial scale animation for spawn effect
particle.scaleX = 0.1;
particle.scaleY = 0.1;
tween(particle, {
scaleX: sizeVariation,
scaleY: sizeVariation
}, {
duration: 200,
easing: tween.easeOut
});
};
self.update = function () {
if (self.life <= 0) {
self.destroyed = true;
returnParticleToPool(self);
return;
}
// Update position with velocity
self.x += self.velocityX;
self.y += self.velocityY;
// Apply gravity with slight randomness
self.velocityY += self.gravity + (Math.random() - 0.5) * 0.1;
// Apply air resistance to create more realistic movement
self.velocityX *= 0.98;
self.velocityY *= 0.99;
// Add slight rotation for visual interest
particle.rotation += self.velocityX * 0.02;
// Enhanced fade out with scale reduction
var alpha = self.life / self.maxLife;
particle.alpha = alpha;
particle.scaleX = alpha * 0.8 + 0.2; // Scale down as it fades
particle.scaleY = alpha * 0.8 + 0.2;
// Reduce life
self.life--;
};
return self;
});
var StackedBlock = Container.expand(function () {
var self = Container.call(this);
var block = self.attachAsset('block', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x808080
});
/****
* Game Code
****/
// Game state
var stackedBlocks = [];
var particles = [];
var gameHeight = 2732;
var gameWidth = 2048;
var groundLevel = gameHeight - 120;
var stackHeight = 0;
var gameActive = true;
// Object pools for memory optimization
var particlePool = [];
var cutPiecePool = [];
var swingingBlockPool = [];
// Pool management functions
function getParticleFromPool() {
if (particlePool.length > 0) {
var particle = particlePool.pop();
particle.visible = true;
particle.destroyed = false;
return particle;
}
return new Particle();
}
function returnParticleToPool(particle) {
if (particle && !particle.pooled) {
particle.visible = false;
particle.pooled = true;
particlePool.push(particle);
}
}
function getCutPieceFromPool() {
if (cutPiecePool.length > 0) {
var cutPiece = cutPiecePool.pop();
cutPiece.visible = true;
cutPiece.destroyed = false;
return cutPiece;
}
return new CutPiece();
}
function returnCutPieceToPool(cutPiece) {
if (cutPiece && !cutPiece.pooled) {
cutPiece.visible = false;
cutPiece.pooled = true;
cutPiecePool.push(cutPiece);
}
}
function getSwingingBlockFromPool() {
if (swingingBlockPool.length > 0) {
var block = swingingBlockPool.pop();
block.visible = true;
block.destroyed = false;
block.falling = false;
block.rotationStarted = false;
block.velocityY = 0;
block.rotation = 0;
block.scaleX = 1;
block.scaleY = 1;
block.width = 350;
block.pooled = false;
return block;
}
return LK.getAsset('swingingBlock', {
anchorX: 0.5,
anchorY: 0.5
});
}
function returnSwingingBlockToPool(block) {
if (block && !block.pooled) {
block.visible = false;
block.pooled = true;
swingingBlockPool.push(block);
}
}
// Create foundation block
var foundation = new StackedBlock();
foundation.x = gameWidth / 2;
foundation.y = gameHeight - 120; // Move to bottom of screen
game.addChild(foundation);
stackedBlocks.push(foundation);
stackHeight = foundation.y;
// Create rope hanging from top center
var rope = LK.getAsset('rope', {
anchorX: 0.5,
anchorY: 0
});
rope.x = gameWidth / 2;
rope.y = 0; // Rope starts at top of screen
game.addChild(rope);
// Create swinging block at the end of rope
var swingingBlock = getSwingingBlockFromPool();
swingingBlock.x = 0;
swingingBlock.y = rope.height + 100; // Extend the rope length by moving block further down
rope.addChild(swingingBlock);
// Natural pendulum swing variables
var swingTime = 0;
var swingSpeed = 0.015; // Controls swing speed - reduced for slower initial swing
var swingAmplitude = 1.2; // Controls swing range (max rotation) - increased for wider swing
// Score display
var scoreTxt = new Text2('Blocks: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Touch handler to drop the block
game.down = function (x, y, obj) {
if (!gameActive || !swingingBlock.parent || swingingBlock.falling) return;
// Get the current world position of the swinging block
var worldPos = rope.toGlobal(swingingBlock.position);
var gamePos = game.toLocal(worldPos);
// Detach from rope and add to game
rope.removeChild(swingingBlock);
game.addChild(swingingBlock);
// Set position in game coordinates
swingingBlock.x = gamePos.x;
swingingBlock.y = gamePos.y;
// Add falling velocity
swingingBlock.velocityY = 25; // Start with constant speed
swingingBlock.falling = true;
// Play falling sound
LK.getSound('fall').play();
};
// Update function for falling blocks
game.update = function () {
// Update particles
for (var i = particles.length - 1; i >= 0; i--) {
var particle = particles[i];
if (particle.destroyed) {
particles.splice(i, 1);
}
}
// Update rope swing with natural pendulum motion
if (rope) {
// Gradually increase swing speed based on score - every 5 blocks
var currentSwingSpeed = swingSpeed + Math.floor(LK.getScore() / 5) * 0.005; // Increase speed by 0.005 every 5 blocks
swingTime += currentSwingSpeed;
rope.rotation = Math.sin(swingTime) * swingAmplitude;
// Add vertical swinging motion to the swinging block only if it exists and is not falling
if (swingingBlock && swingingBlock.parent === rope && !swingingBlock.falling) {
var verticalOffset = Math.cos(swingTime * 2) * 30; // Vertical swing with smaller amplitude
swingingBlock.y = rope.height + 100 + verticalOffset;
}
}
if (swingingBlock.falling) {
// Use constant falling speed instead of accelerating gravity
swingingBlock.velocityY = 25; // Fixed falling speed
swingingBlock.y += swingingBlock.velocityY;
// Rotation animation removed - blocks fall straight down
if (!swingingBlock.rotationStarted) {
swingingBlock.rotationStarted = true;
}
// Check collision with any stacked block using built-in intersects method
var hasCollision = false;
for (var i = 0; i < stackedBlocks.length; i++) {
var block = stackedBlocks[i];
if (swingingBlock.intersects(block)) {
hasCollision = true;
break;
}
}
if (hasCollision) {
// Find the topmost block that the swinging block collided with
var targetBlock = null;
var highestY = gameHeight;
for (var k = 0; k < stackedBlocks.length; k++) {
if (swingingBlock.intersects(stackedBlocks[k]) && stackedBlocks[k].y < highestY) {
targetBlock = stackedBlocks[k];
highestY = stackedBlocks[k].y;
}
}
if (targetBlock) {
// Check if block is close enough to the top of the target block to land
var blockBottom = swingingBlock.y + swingingBlock.height / 2;
var targetTop = targetBlock.y - targetBlock.height / 2;
var landingDistance = Math.abs(blockBottom - targetTop);
// Only land if we're within reasonable landing distance (less than falling speed)
if (landingDistance <= 30) {
// Award 1 point
LK.setScore(LK.getScore() + 1);
scoreTxt.setText('Blocks: ' + LK.getScore());
// Calculate collision overlap and trim the block
var targetLeft = targetBlock.x - targetBlock.width / 2;
var targetRight = targetBlock.x + targetBlock.width / 2;
var swingingLeft = swingingBlock.x - swingingBlock.width / 2;
var swingingRight = swingingBlock.x + swingingBlock.width / 2;
// Find the overlapping area
var overlapLeft = Math.max(targetLeft, swingingLeft);
var overlapRight = Math.min(targetRight, swingingRight);
var overlapWidth = overlapRight - overlapLeft;
// Only proceed if there's actual overlap
if (overlapWidth > 0) {
// Place block exactly on top of target block
swingingBlock.falling = false;
swingingBlock.velocityY = 0;
swingingBlock.y = targetBlock.y - 300; // Place exactly one block height above
// Stop rotation animation and reset to straight position
tween.stop(swingingBlock, {
rotation: true
});
swingingBlock.rotation = 0;
// Add collision impact animation
// Scale the landing block and target block for impact effect
var originalScale = swingingBlock.scaleX;
swingingBlock.scaleX = originalScale * 1.2;
swingingBlock.scaleY = originalScale * 1.2;
targetBlock.scaleX = originalScale * 1.1;
targetBlock.scaleY = originalScale * 1.1;
// Animate back to normal size
tween(swingingBlock, {
scaleX: originalScale,
scaleY: originalScale
}, {
duration: 300,
easing: tween.easeOut
});
tween(targetBlock, {
scaleX: originalScale,
scaleY: originalScale
}, {
duration: 300,
easing: tween.easeOut
});
// Create enhanced particle explosion effect
var particleCount = 20; // Increased from 8 to 20
var collisionCenterX = swingingBlock.x;
var collisionCenterY = swingingBlock.y;
for (var p = 0; p < particleCount; p++) {
var particle = getParticleFromPool();
// Larger spawn area for more spread
particle.x = collisionCenterX + (Math.random() - 0.5) * 80;
particle.y = collisionCenterY + (Math.random() - 0.5) * 50;
// Create more varied velocity directions with bursts
var angle = Math.PI * 2 * p / particleCount + (Math.random() - 0.5) * 0.8;
var speed = 12 + Math.random() * 12; // Increased speed range
var velocityX = Math.cos(angle) * speed;
var velocityY = Math.sin(angle) * speed - Math.random() * 8; // More upward bias
// Random particle colors (yellows, oranges, whites)
var colors = [0xFFD700, 0xFFA500, 0xFFFFFF, 0xFFE4B5, 0xFFF8DC];
var color = colors[Math.floor(Math.random() * colors.length)];
particle.animate(velocityX, velocityY, color);
particles.push(particle);
game.addChild(particle);
}
// Add secondary burst of smaller, faster particles
var secondaryParticleCount = 15;
for (var s = 0; s < secondaryParticleCount; s++) {
var secondaryParticle = getParticleFromPool();
// Tighter spawn area for secondary burst
secondaryParticle.x = collisionCenterX + (Math.random() - 0.5) * 30;
secondaryParticle.y = collisionCenterY + (Math.random() - 0.5) * 20;
// Faster, more chaotic movement
var secondaryAngle = Math.random() * Math.PI * 2;
var secondarySpeed = 15 + Math.random() * 15;
var secondaryVelocityX = Math.cos(secondaryAngle) * secondarySpeed;
var secondaryVelocityY = Math.sin(secondaryAngle) * secondarySpeed - Math.random() * 10;
// Brighter colors for secondary particles
var secondaryColors = [0xFFFFFF, 0xFFFF00, 0xFF6600, 0xFF3300];
var secondaryColor = secondaryColors[Math.floor(Math.random() * secondaryColors.length)];
secondaryParticle.animate(secondaryVelocityX, secondaryVelocityY, secondaryColor);
particles.push(secondaryParticle);
game.addChild(secondaryParticle);
}
// Play collision sound
LK.getSound('collision').play();
// Add screen shake effect by moving the game container
var originalGameX = game.x;
var originalGameY = game.y;
var shakeIntensity = 15;
// Quick shake animation
tween(game, {
x: originalGameX + shakeIntensity,
y: originalGameY + shakeIntensity * 0.5
}, {
duration: 50,
easing: tween.linear,
onFinish: function onFinish() {
tween(game, {
x: originalGameX - shakeIntensity * 0.8,
y: originalGameY - shakeIntensity * 0.3
}, {
duration: 50,
easing: tween.linear,
onFinish: function onFinish() {
tween(game, {
x: originalGameX,
y: originalGameY
}, {
duration: 100,
easing: tween.easeOut
});
}
});
}
});
// Create cut pieces for trimmed parts
var leftTrimmed = swingingLeft < overlapLeft;
var rightTrimmed = swingingRight > overlapRight;
if (leftTrimmed) {
// Create cut piece for left trimmed part
var leftCutPiece = getCutPieceFromPool();
game.addChild(leftCutPiece);
var leftTrimWidth = overlapLeft - swingingLeft;
leftCutPiece.x = swingingLeft + leftTrimWidth / 2;
leftCutPiece.y = swingingBlock.y;
leftCutPiece.animate('left', leftTrimWidth);
}
if (rightTrimmed) {
// Create cut piece for right trimmed part
var rightCutPiece = getCutPieceFromPool();
game.addChild(rightCutPiece);
var rightTrimWidth = swingingRight - overlapRight;
rightCutPiece.x = overlapRight + rightTrimWidth / 2;
rightCutPiece.y = swingingBlock.y;
rightCutPiece.animate('right', rightTrimWidth);
}
// Calculate how much of the original block remains
var originalWidth = 350; // Original block width
var remainingPercentage = overlapWidth / originalWidth * 100;
// Check if 70% or more was trimmed (only 30% or less remains)
if (remainingPercentage <= 30) {
// Game over - too much of the block was cut off
gameActive = false;
LK.showGameOver();
return;
}
// Trim the block to only show the overlapping area
var newCenterX = overlapLeft + overlapWidth / 2;
swingingBlock.x = newCenterX;
swingingBlock.width = overlapWidth;
stackedBlocks.push(swingingBlock);
} else {
// No overlap, block falls off
swingingBlock.falling = true;
}
// Update stack height to the new top
stackHeight = swingingBlock.y;
// After 2 blocks are placed (3rd block landing), start sliding all blocks down
if (LK.getScore() > 2) {
// Animate all blocks sliding down by one block height (300px)
for (var b = 0; b < stackedBlocks.length; b++) {
var block = stackedBlocks[b];
tween(block, {
y: block.y + 300
}, {
duration: 800,
easing: tween.easeInOut
});
}
// Get the bottom block for destruction after animation
var bottomBlock = stackedBlocks[0];
// Set a timeout to destroy the bottom block after animation completes
LK.setTimeout(function () {
bottomBlock.destroy();
stackedBlocks.splice(0, 1);
}, 800);
}
// Create new swinging block
swingingBlock = getSwingingBlockFromPool();
swingingBlock.x = 0;
swingingBlock.y = rope.height + 100;
swingingBlock.rotationStarted = false; // Reset rotation flag
rope.addChild(swingingBlock);
// Start background music
LK.playMusic('bgmusic');
} else {
// Not close enough to land - continue falling
swingingBlock.falling = true;
}
}
}
// Check if block has fallen below the screen
else if (swingingBlock.y > gameHeight + 200) {
// Game over - player missed the target
gameActive = false;
LK.showGameOver();
}
}
};
; ===================================================================
--- original.js
+++ change.js
@@ -173,9 +173,9 @@
block.velocityY = 0;
block.rotation = 0;
block.scaleX = 1;
block.scaleY = 1;
- block.width = 500;
+ block.width = 350;
block.pooled = false;
return block;
}
return LK.getAsset('swingingBlock', {
@@ -310,9 +310,9 @@
if (overlapWidth > 0) {
// Place block exactly on top of target block
swingingBlock.falling = false;
swingingBlock.velocityY = 0;
- swingingBlock.y = targetBlock.y - 450; // Place exactly one block height above
+ swingingBlock.y = targetBlock.y - 300; // Place exactly one block height above
// Stop rotation animation and reset to straight position
tween.stop(swingingBlock, {
rotation: true
});
@@ -432,9 +432,9 @@
rightCutPiece.y = swingingBlock.y;
rightCutPiece.animate('right', rightTrimWidth);
}
// Calculate how much of the original block remains
- var originalWidth = 500; // Original block width
+ var originalWidth = 350; // Original block width
var remainingPercentage = overlapWidth / originalWidth * 100;
// Check if 70% or more was trimmed (only 30% or less remains)
if (remainingPercentage <= 30) {
// Game over - too much of the block was cut off
@@ -454,13 +454,13 @@
// Update stack height to the new top
stackHeight = swingingBlock.y;
// After 2 blocks are placed (3rd block landing), start sliding all blocks down
if (LK.getScore() > 2) {
- // Animate all blocks sliding down by one block height (450px)
+ // Animate all blocks sliding down by one block height (300px)
for (var b = 0; b < stackedBlocks.length; b++) {
var block = stackedBlocks[b];
tween(block, {
- y: block.y + 450
+ y: block.y + 300
}, {
duration: 800,
easing: tween.easeInOut
});