User prompt
Temas olmasa bile blok havada duruyor çarpışma algılama kötü
User prompt
Eger temas alanı alt blogun 4 te birinden az ise blok düşer ve kaybolur
User prompt
Çarpışma algılama temas bölgesi 4/1 ise blok düşmeye devam eder
User prompt
Oyında bulunan 2 farklı çarpışma algılamadan birini kaldır
User prompt
Blok düşme hızını 25 yap
User prompt
Düşme hızını biraz arttır
User prompt
Blok düşme hızını sabitle böylece çarpışma sekronizasyonu düzelir
User prompt
Çeyrek kapsama kontrolünü düzelt ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Çarpışma ve fizik kuralları ekle ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Carpışma fizigi ekle
User prompt
Eger temas noktasında 4/1 den azsa düşme fizigi ekke ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Carpışmaya fizik kuralları ekle ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Gerekli ayarları yap ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Eger üstteki blok düşüşte alttaki blogun 4/1 alanına temas ediyorsa dönerek dogal olarak düşsün oyuncu can kaybeder ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Olmuyor oyun bozuldu
User prompt
Hedef kaynagı yarat ve düzenle
User prompt
Üstteki kırmızı blok dülerken bazen alttaki blogu görmezden geliyor
User prompt
Asagı yukarı sallanmayıda aktif et ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Düşen blok bazen düşmesi gereken bölgeyi aşıyor ve tekrar birden blogun üzerinde beliriyor
User prompt
Saga sola sallantıyı genişlet ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Düşme sırasında carpması gereken blogu aşarak asagı gidip birdan blogun üzerinde beliriyor
User prompt
Kırmızı blok düşmeye başladıgında dogal davransın ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Sallantı dogal ve ve hiç durmasın ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
İp başlangıcı ekran üste degmeli
User prompt
İpi ve blogu biraz asagı dogru uzat
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ 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: 0x87ceeb }); /**** * Game Code ****/ // Game state var stackedBlocks = []; var gameHeight = 2732; var gameWidth = 2048; var groundLevel = gameHeight - 120; var stackHeight = 0; var gameActive = true; // 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 = LK.getAsset('swingingBlock', { anchorX: 0.5, anchorY: 0.5 }); 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.03; // Controls swing speed var swingAmplitude = 0.6; // Controls swing range (max rotation) // 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) 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 = 0; swingingBlock.gravity = 0.8; swingingBlock.falling = true; }; // Update function for falling blocks game.update = function () { // Update rope swing with natural pendulum motion if (rope && !swingingBlock.falling) { swingTime += swingSpeed; rope.rotation = Math.sin(swingTime) * swingAmplitude; // Add vertical swinging motion to the swinging block var verticalOffset = Math.cos(swingTime * 2) * 30; // Vertical swing with smaller amplitude swingingBlock.y = rope.height + 100 + verticalOffset; } if (swingingBlock.falling) { swingingBlock.velocityY += swingingBlock.gravity; swingingBlock.y += swingingBlock.velocityY; // Apply horizontal physics if velocity exists if (swingingBlock.velocityX) { swingingBlock.x += swingingBlock.velocityX; // Apply air resistance to horizontal movement swingingBlock.velocityX *= 0.98; // Stop very small horizontal movements if (Math.abs(swingingBlock.velocityX) < 0.1) { swingingBlock.velocityX = 0; } } // Check collision with any stacked block using Y position bounds var hasCollision = false; var nextY = swingingBlock.y + swingingBlock.velocityY + swingingBlock.gravity; for (var i = 0; i < stackedBlocks.length; i++) { var block = stackedBlocks[i]; var blockTop = block.y - block.height / 2; var blockBottom = block.y + block.height / 2; var swingingTop = swingingBlock.y - swingingBlock.height / 2; var swingingBottom = nextY + swingingBlock.height / 2; // Check if falling block will intersect or has passed through this block if (swingingTop <= blockBottom && swingingBottom >= blockTop) { // Also check X overlap for more accurate collision var swingingLeft = swingingBlock.x - swingingBlock.width / 2; var swingingRight = swingingBlock.x + swingingBlock.width / 2; var blockLeft = block.x - block.width / 2; var blockRight = block.x + block.width / 2; if (swingingLeft < blockRight && swingingRight > blockLeft) { 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) { // Calculate impact force based on velocity and angle var impactForce = Math.abs(swingingBlock.velocityY) + Math.abs(rope.rotation) * 10; var impactThreshold = 8; // Minimum force needed for stable landing // Physics-based collision response var collisionY = targetBlock.y - targetBlock.height / 2 - swingingBlock.height / 2; swingingBlock.y = collisionY; // Calculate bounce based on impact force and surface contact var swingingLeft = swingingBlock.x - swingingBlock.width / 2; var swingingRight = swingingBlock.x + swingingBlock.width / 2; var targetLeft = targetBlock.x - targetBlock.width / 2; var targetRight = targetBlock.x + targetBlock.width / 2; // Calculate overlap and contact physics var overlapLeft = Math.max(swingingLeft, targetLeft); var overlapRight = Math.min(swingingRight, targetRight); var overlapWidth = Math.max(0, overlapRight - overlapLeft); var contactRatio = overlapWidth / targetBlock.width; // Physics-based bounce calculation var bounceCoefficient = 0.3; // Natural bounce dampening var horizontalOffset = (swingingBlock.x - targetBlock.x) / (targetBlock.width / 2); var bounceVelocityY = -swingingBlock.velocityY * bounceCoefficient * (1 - contactRatio); var bounceVelocityX = horizontalOffset * impactForce * 0.5; // Apply physics effects based on contact ratio var requiredCoverage = targetBlock.width / 2; var quarterCoverage = targetBlock.width / 4; if (contactRatio <= 0.25 && overlapWidth > 0) { // Minimal contact - physics-based tumbling fall swingingBlock.falling = true; swingingBlock.velocityY = Math.max(bounceVelocityY, 2); swingingBlock.velocityX = bounceVelocityX; // Natural tumbling rotation with physics var rotationDirection = swingingBlock.x < targetBlock.x ? -1 : 1; var tumbleSpeed = impactForce * 100 + 800; // Faster tumble for higher impact tween(swingingBlock, { rotation: swingingBlock.rotation + rotationDirection * Math.PI * (1 + impactForce * 0.2) }, { duration: tumbleSpeed, easing: tween.easeOut }); // Add horizontal drift during fall if (!swingingBlock.velocityX) swingingBlock.velocityX = 0; swingingBlock.velocityX += bounceVelocityX; // Shake effect on impact LK.effects.flashScreen(0xff4444, 200); // Game over - player loses gameActive = false; LK.setTimeout(function () { LK.showGameOver(); }, Math.min(tumbleSpeed + 300, 1100)); // Delay based on tumble duration } else if (contactRatio >= 0.5 && impactForce < impactThreshold * 2) { // Good contact and reasonable impact - successful stack // Apply settling physics with small bounce var settleHeight = collisionY - Math.abs(bounceVelocityY); tween(swingingBlock, { y: settleHeight, rotation: swingingBlock.rotation * 0.9 // Slight rotation dampening }, { duration: 200, easing: tween.bounceOut, onFinish: function onFinish() { // Final settle to exact position tween(swingingBlock, { y: collisionY, rotation: 0 }, { duration: 100, easing: tween.easeOut }); } }); // Award 1 point LK.setScore(LK.getScore() + 1); scoreTxt.setText('Blocks: ' + LK.getScore()); // Place block on stack swingingBlock.falling = false; swingingBlock.velocityY = 0; swingingBlock.velocityX = 0; stackHeight -= 240; // Move stack up by block height stackedBlocks.push(swingingBlock); // Physics-based stack settling - slight wobble effect for (var m = 0; m < stackedBlocks.length - 1; m++) { var wobbleAmount = (stackedBlocks.length - m) * 2; // Higher blocks wobble more tween(stackedBlocks[m], { rotation: stackedBlocks[m].rotation + (Math.random() - 0.5) * 0.1 }, { duration: 300, easing: tween.easeInOut, onFinish: function () { tween(this, { rotation: 0 }, { duration: 200, easing: tween.easeOut }); }.bind(stackedBlocks[m]) }); } // If this is the second red block (score 2), start sliding foundation down if (LK.getScore() >= 2) { // Move foundation and all stacked blocks down by one block height for (var j = 0; j < stackedBlocks.length; j++) { tween(stackedBlocks[j], { y: stackedBlocks[j].y + 240 }, { duration: 500, easing: tween.easeInOut }); } // Update stack height stackHeight += 240; } // Create new swinging block swingingBlock = LK.getAsset('swingingBlock', { anchorX: 0.5, anchorY: 0.5 }); swingingBlock.x = 0; swingingBlock.y = rope.height + 100; rope.addChild(swingingBlock); } else { // Insufficient contact or too much impact - physics-based bounce and fall swingingBlock.falling = true; swingingBlock.velocityY = bounceVelocityY; if (!swingingBlock.velocityX) swingingBlock.velocityX = 0; swingingBlock.velocityX += bounceVelocityX; // Add spin based on impact angle and force var spinDirection = horizontalOffset > 0 ? 1 : -1; tween(swingingBlock, { rotation: swingingBlock.rotation + spinDirection * impactForce * 0.3 }, { duration: 1000, easing: tween.easeOut }); // Impact flash effect LK.effects.flashScreen(0xffaa44, 150); } } } // 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
@@ -95,8 +95,18 @@
}
if (swingingBlock.falling) {
swingingBlock.velocityY += swingingBlock.gravity;
swingingBlock.y += swingingBlock.velocityY;
+ // Apply horizontal physics if velocity exists
+ if (swingingBlock.velocityX) {
+ swingingBlock.x += swingingBlock.velocityX;
+ // Apply air resistance to horizontal movement
+ swingingBlock.velocityX *= 0.98;
+ // Stop very small horizontal movements
+ if (Math.abs(swingingBlock.velocityX) < 0.1) {
+ swingingBlock.velocityX = 0;
+ }
+ }
// Check collision with any stacked block using Y position bounds
var hasCollision = false;
var nextY = swingingBlock.y + swingingBlock.velocityY + swingingBlock.gravity;
for (var i = 0; i < stackedBlocks.length; i++) {
@@ -128,60 +138,116 @@
highestY = stackedBlocks[k].y;
}
}
if (targetBlock) {
- // Check if the swinging block covers at least half of the target block
+ // Calculate impact force based on velocity and angle
+ var impactForce = Math.abs(swingingBlock.velocityY) + Math.abs(rope.rotation) * 10;
+ var impactThreshold = 8; // Minimum force needed for stable landing
+ // Physics-based collision response
+ var collisionY = targetBlock.y - targetBlock.height / 2 - swingingBlock.height / 2;
+ swingingBlock.y = collisionY;
+ // Calculate bounce based on impact force and surface contact
var swingingLeft = swingingBlock.x - swingingBlock.width / 2;
var swingingRight = swingingBlock.x + swingingBlock.width / 2;
var targetLeft = targetBlock.x - targetBlock.width / 2;
var targetRight = targetBlock.x + targetBlock.width / 2;
- // Calculate overlap
+ // Calculate overlap and contact physics
var overlapLeft = Math.max(swingingLeft, targetLeft);
var overlapRight = Math.min(swingingRight, targetRight);
var overlapWidth = Math.max(0, overlapRight - overlapLeft);
- // Check if overlap is at least half of the target block width
+ var contactRatio = overlapWidth / targetBlock.width;
+ // Physics-based bounce calculation
+ var bounceCoefficient = 0.3; // Natural bounce dampening
+ var horizontalOffset = (swingingBlock.x - targetBlock.x) / (targetBlock.width / 2);
+ var bounceVelocityY = -swingingBlock.velocityY * bounceCoefficient * (1 - contactRatio);
+ var bounceVelocityX = horizontalOffset * impactForce * 0.5;
+ // Apply physics effects based on contact ratio
var requiredCoverage = targetBlock.width / 2;
- // Check for quarter coverage (1/4) to trigger natural fall with rotation
var quarterCoverage = targetBlock.width / 4;
- if (overlapWidth <= quarterCoverage && overlapWidth > 0) {
- // Block is barely touching - make it fall naturally with rotation
+ if (contactRatio <= 0.25 && overlapWidth > 0) {
+ // Minimal contact - physics-based tumbling fall
swingingBlock.falling = true;
- swingingBlock.velocityY = Math.max(swingingBlock.velocityY, 2); // Ensure some downward velocity
- // Add natural rotation based on which side is touching
+ swingingBlock.velocityY = Math.max(bounceVelocityY, 2);
+ swingingBlock.velocityX = bounceVelocityX;
+ // Natural tumbling rotation with physics
var rotationDirection = swingingBlock.x < targetBlock.x ? -1 : 1;
+ var tumbleSpeed = impactForce * 100 + 800; // Faster tumble for higher impact
tween(swingingBlock, {
- rotation: swingingBlock.rotation + rotationDirection * Math.PI * 2
+ rotation: swingingBlock.rotation + rotationDirection * Math.PI * (1 + impactForce * 0.2)
}, {
- duration: 1500,
+ duration: tumbleSpeed,
easing: tween.easeOut
});
+ // Add horizontal drift during fall
+ if (!swingingBlock.velocityX) swingingBlock.velocityX = 0;
+ swingingBlock.velocityX += bounceVelocityX;
+ // Shake effect on impact
+ LK.effects.flashScreen(0xff4444, 200);
// Game over - player loses
gameActive = false;
LK.setTimeout(function () {
LK.showGameOver();
- }, 800); // Delay to show the rotation effect
- } else if (overlapWidth >= requiredCoverage) {
+ }, Math.min(tumbleSpeed + 300, 1100)); // Delay based on tumble duration
+ } else if (contactRatio >= 0.5 && impactForce < impactThreshold * 2) {
+ // Good contact and reasonable impact - successful stack
+ // Apply settling physics with small bounce
+ var settleHeight = collisionY - Math.abs(bounceVelocityY);
+ tween(swingingBlock, {
+ y: settleHeight,
+ rotation: swingingBlock.rotation * 0.9 // Slight rotation dampening
+ }, {
+ duration: 200,
+ easing: tween.bounceOut,
+ onFinish: function onFinish() {
+ // Final settle to exact position
+ tween(swingingBlock, {
+ y: collisionY,
+ rotation: 0
+ }, {
+ duration: 100,
+ easing: tween.easeOut
+ });
+ }
+ });
// Award 1 point
LK.setScore(LK.getScore() + 1);
scoreTxt.setText('Blocks: ' + LK.getScore());
// Place block on stack
swingingBlock.falling = false;
swingingBlock.velocityY = 0;
+ swingingBlock.velocityX = 0;
stackHeight -= 240; // Move stack up by block height
- swingingBlock.y = stackHeight;
stackedBlocks.push(swingingBlock);
- // Camera adjustment: move all blocks down except the one just placed
+ // Physics-based stack settling - slight wobble effect
+ for (var m = 0; m < stackedBlocks.length - 1; m++) {
+ var wobbleAmount = (stackedBlocks.length - m) * 2; // Higher blocks wobble more
+ tween(stackedBlocks[m], {
+ rotation: stackedBlocks[m].rotation + (Math.random() - 0.5) * 0.1
+ }, {
+ duration: 300,
+ easing: tween.easeInOut,
+ onFinish: function () {
+ tween(this, {
+ rotation: 0
+ }, {
+ duration: 200,
+ easing: tween.easeOut
+ });
+ }.bind(stackedBlocks[m])
+ });
+ }
+ // If this is the second red block (score 2), start sliding foundation down
if (LK.getScore() >= 2) {
- // Move only the previously stacked blocks down (not the new one)
- for (var j = 0; j < stackedBlocks.length - 1; j++) {
+ // Move foundation and all stacked blocks down by one block height
+ for (var j = 0; j < stackedBlocks.length; j++) {
tween(stackedBlocks[j], {
y: stackedBlocks[j].y + 240
}, {
duration: 500,
easing: tween.easeInOut
});
}
- // Update stack height reference
+ // Update stack height
stackHeight += 240;
}
// Create new swinging block
swingingBlock = LK.getAsset('swingingBlock', {
@@ -191,10 +257,23 @@
swingingBlock.x = 0;
swingingBlock.y = rope.height + 100;
rope.addChild(swingingBlock);
} else {
- // Not enough coverage - continue falling
+ // Insufficient contact or too much impact - physics-based bounce and fall
swingingBlock.falling = true;
+ swingingBlock.velocityY = bounceVelocityY;
+ if (!swingingBlock.velocityX) swingingBlock.velocityX = 0;
+ swingingBlock.velocityX += bounceVelocityX;
+ // Add spin based on impact angle and force
+ var spinDirection = horizontalOffset > 0 ? 1 : -1;
+ tween(swingingBlock, {
+ rotation: swingingBlock.rotation + spinDirection * impactForce * 0.3
+ }, {
+ duration: 1000,
+ easing: tween.easeOut
+ });
+ // Impact flash effect
+ LK.effects.flashScreen(0xffaa44, 150);
}
}
}
// Check if block has fallen below the screen