User prompt
woods can fall
User prompt
birds can push down the blocks
User prompt
add gravity for all blocsk
User prompt
side boxes have gravty too
User prompt
add ragdoll for boxes
User prompt
birds can touch boxes
User prompt
boxes can fall
User prompt
add box gravity
User prompt
make boxes can touch other boxes
User prompt
add gravity for boxes
User prompt
another box top
User prompt
add two big boxes top top
User prompt
bigger box.
User prompt
make them a box
User prompt
put the woods shaped two box
User prompt
add on the game two box made of wood
User prompt
create two box mode of wood
User prompt
Add a Block class named wood
User prompt
remove bird nosses
User prompt
Please fix the bug: 'TypeError: birds[i].update is not a function' in or related to this line: 'birds[i].update();' Line Number: 378
User prompt
deletele bird dteails
User prompt
detele block
User prompt
Please fix the bug: 's.apply(...).then is not a function' in or related to this line: 'self.lastY = self.y;' Line Number: 433
User prompt
deletele the wood blocks from save and game
User prompt
deletele sun
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Bird class var Bird = Container.expand(function () { var self = Container.call(this); // Attach a red ellipse as the main bird body var birdBody = self.attachAsset('bird', { anchorX: 0.5, anchorY: 0.5 }); birdBody.width = 90; birdBody.height = 90; // Add a white ellipse for the belly var belly = self.attachAsset('bird', { anchorX: 0.5, anchorY: 0.5 }); belly.width = birdBody.width * 0.7; belly.height = birdBody.height * 0.5; belly.x = 0; belly.y = birdBody.height * 0.18; belly.tint = 0xffffff; // Add a black ellipse for the left eye var leftEye = self.attachAsset('bird', { anchorX: 0.5, anchorY: 0.5 }); leftEye.width = birdBody.width * 0.18; leftEye.height = birdBody.height * 0.18; leftEye.x = -birdBody.width * 0.18; leftEye.y = -birdBody.height * 0.18; leftEye.tint = 0x000000; // Add a black ellipse for the right eye var rightEye = self.attachAsset('bird', { anchorX: 0.5, anchorY: 0.5 }); rightEye.width = birdBody.width * 0.18; rightEye.height = birdBody.height * 0.18; rightEye.x = birdBody.width * 0.08; rightEye.y = -birdBody.height * 0.18; rightEye.tint = 0x000000; // Add a yellow triangle for the beak var beak = self.attachAsset('beakTriangle', { anchorX: 0.1, anchorY: 0.5 }); beak.width = birdBody.width * 0.48; beak.height = birdBody.height * 0.36; beak.x = birdBody.width * 0.56; beak.y = 0; beak.rotation = Math.PI / 8; // Physics properties self.vx = 0; self.vy = 0; self.launched = false; self.radius = birdBody.width / 2; self.gravity = 0.35; self.friction = 0.998; self.bounce = 0.5; self.stopped = false; // Called every tick self.update = function () { // Track lastX and lastY for physics events if (typeof self.lastX === "undefined") self.lastX = self.x; if (typeof self.lastY === "undefined") self.lastY = self.y; if (self.launched && !self.stopped) { // Standard projectile physics, no tracking or homing self.vy += self.gravity; self.x += self.vx; self.y += self.vy; // Friction self.vx *= self.friction; self.vy *= self.friction; // Floor collision if (self.y + self.radius > groundY) { self.y = groundY - self.radius; if (Math.abs(self.vy) > 2) { self.vy = -self.vy * self.bounce; self.vx *= 0.8; self.stopped = false; // Don't stop if still bouncing } else { self.vy = 0; self.vx *= 0.8; // Only stop if both vx and vy are very small and bird is on ground if (Math.abs(self.vx) < 1 && Math.abs(self.vy) < 0.5) { self.stopped = true; } else { self.stopped = false; } } } // Wall collision if (self.x - self.radius < 0) { self.x = self.radius; self.vx = -self.vx * self.bounce; } if (self.x + self.radius > 2048) { self.x = 2048 - self.radius; self.vx = -self.vx * self.bounce; } } // Update lastX and lastY after movement if (typeof self.x === "number" && !isNaN(self.x)) { self.lastX = self.x; } else if (typeof self.x === "string" && !isNaN(parseFloat(self.x))) { self.lastX = parseFloat(self.x); } else if (typeof self.lastX === "number" && !isNaN(self.lastX)) { // keep previous } else { self.lastX = 0; } if (typeof self.y === "number" && !isNaN(self.y)) { self.lastY = self.y; } else if (typeof self.y === "string" && !isNaN(parseFloat(self.y))) { self.lastY = parseFloat(self.y); } else if (typeof self.lastY === "number" && !isNaN(self.lastY)) { // keep previous } else { self.lastY = 0; } // Defensive: always ensure lastY is a number if (typeof self.lastY !== "number" || isNaN(self.lastY)) { self.lastY = 0; } }; // Simple circle collision self.intersectsCircle = function (other) { var dx = self.x - other.x; var dy = self.y - other.y; var dist = Math.sqrt(dx * dx + dy * dy); return dist < self.radius + other.radius; }; return self; }); // Pig class var Pig = Container.expand(function () { var self = Container.call(this); // Attach a green ellipse as the pig var pigAsset = self.attachAsset('pig', { anchorX: 0.5, anchorY: 0.5 }); self.radius = pigAsset.width / 2; self.alive = true; // Physics properties for pigs self.vx = 0; self.vy = 0; self.gravity = 0.7; self.friction = 0.98; self.bounce = 0.3; self.stopped = false; // Called every tick self.update = function () { if (!self.alive) return; // Track lastX and lastY for physics events if (typeof self.lastX === "undefined") self.lastX = self.x; if (typeof self.lastY === "undefined") self.lastY = self.y; if (!self.stopped) { self.vy += self.gravity; self.x += self.vx; self.y += self.vy; self.vx *= self.friction; self.vy *= self.friction; // Pig-on-block collision: prevent pig from going inside the wood blocks for (var i = 0; i < blocks.length; i++) { var block = blocks[i]; // Axis-aligned bounding box for block var blockLeft = block.x - block.width / 2; var blockRight = block.x + block.width / 2; var blockTop = block.y - block.height / 2; var blockBottom = block.y + block.height / 2; // Only check if pig is above block and falling if (self.y < block.y && self.vy > 0) { // Check horizontal overlap if (self.x + self.radius > blockLeft && self.x - self.radius < blockRight) { // Check if pig's bottom is entering block's top if (self.y + self.radius > blockTop && self.y - self.radius < blockBottom) { // Place pig on top of block self.y = blockTop - self.radius; if (Math.abs(self.vy) > 2) { self.vy = -self.vy * self.bounce; self.vx *= 0.8; // Transfer some force to the block below (crash effect) block.vx += self.vx * 0.2; block.vy += self.vy * 0.2; } else { self.vy = 0; self.vx *= 0.8; if (Math.abs(self.vx) < 1) { self.stopped = true; } } } } } } // Floor collision if (self.y + self.radius > groundY) { self.y = groundY - self.radius; if (Math.abs(self.vy) > 2) { self.vy = -self.vy * self.bounce; self.vx *= 0.8; } else { self.vy = 0; self.vx *= 0.8; if (Math.abs(self.vx) < 1) { self.stopped = true; } } } // Wall collision if (self.x - self.radius < 0) { self.x = self.radius; self.vx = -self.vx * self.bounce; } if (self.x + self.radius > 2048) { self.x = 2048 - self.radius; self.vx = -self.vx * self.bounce; } } // Update lastX and lastY after movement self.lastX = self.x; self.lastY = self.y; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87ceeb // Sky blue }); /**** * Game Code ****/ // --- Asset Initialization (shapes) --- // --- Add Background Image --- var background = LK.getAsset('block', { anchorX: 0, anchorY: 0 }); background.width = 2048; background.height = 2732; background.tint = 0x87ceeb; // Sky blue tint for now background.x = 0; background.y = 0; game.addChild(background); // (Sun removed) // --- Add Trees for Scenery --- var treeTrunkColor = 0x8b5a2b; var treeLeafColor = 0x228b22; var treeCount = 4; var treeSpacing = 2048 / (treeCount + 1); for (var i = 0; i < treeCount; i++) { // Trunk var trunk = LK.getAsset('block', { anchorX: 0.5, anchorY: 1 }); trunk.width = 40; trunk.height = 220; trunk.tint = treeTrunkColor; trunk.x = treeSpacing * (i + 1); trunk.y = groundY + 10; game.addChild(trunk); // Leaves (ellipse) var leaves = LK.getAsset('bird', { anchorX: 0.5, anchorY: 1 }); leaves.width = 180; leaves.height = 160; leaves.tint = treeLeafColor; leaves.x = trunk.x; leaves.y = trunk.y - trunk.height + 10; game.addChild(leaves); } // --- Game Variables --- var birds = []; var pigs = []; var blocks = []; var currentBird = null; var birdIndex = 0; var isDragging = false; var dragStart = { x: 0, y: 0 }; var dragEnd = { x: 0, y: 0 }; var slingshotX = 260; // Moved more right from 60 var slingshotY = 2000; // Raised slingshot higher (was 2450) var slingshotBandLength = 180; var maxBirds = 5; var groundY = 2650; var level = 1; var launching = false; var score = 0; // --- GUI --- var scoreTxt = new Text2('0', { size: 120, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); var birdsLeftTxt = new Text2('', { size: 80, fill: 0xFFFFFF }); birdsLeftTxt.anchor.set(0.5, 0); LK.gui.topRight.addChild(birdsLeftTxt); // --- Draw Ground --- var ground = LK.getAsset('ground', { anchorX: 0, anchorY: 0 }); ground.x = 0; ground.y = groundY; game.addChild(ground); // --- Draw Little Mountain below the slingshot --- var mountainWidth = 400; var mountainHeight = 120; var mountain = LK.getAsset('block', { anchorX: 0.5, anchorY: 1 }); mountain.width = mountainWidth; mountain.height = mountainHeight; mountain.x = slingshotX; mountain.y = groundY + 10; // Slightly below ground for overlap mountain.tint = 0x8b7765; // Optional: make it look more like a mountain game.addChild(mountain); // --- Draw Slingshot --- var slingshot = LK.getAsset('slingshot', { anchorX: 0.5, anchorY: 1 }); slingshot.x = slingshotX; slingshot.y = slingshotY + 90; game.addChild(slingshot); // --- Level Setup --- function setupLevel() { // Add a golden star collectible above the house for bonus points if (typeof star === "undefined") { star = LK.getAsset('block', { anchorX: 0.5, anchorY: 0.5 }); star.width = 80; star.height = 80; star.tint = 0xffd700; // gold color star.isStar = true; } star.x = 1500; star.y = groundY - 600; star.collected = false; star.visible = true; game.addChild(star); // Clear previous for (var i = 0; i < birds.length; i++) birds[i].destroy(); for (var i = 0; i < pigs.length; i++) pigs[i].destroy(); for (var i = 0; i < blocks.length; i++) blocks[i].destroy(); birds = []; pigs = []; blocks = []; birdIndex = 0; score = 0; LK.setScore(0); scoreTxt.setText('0'); launching = false; for (var i = 0; i < maxBirds; i++) { var bird = new Bird(); bird.x = slingshotX - 120 - i * 80; bird.y = slingshotY + 40; birds.push(bird); game.addChild(bird); } currentBird = birds[birdIndex]; var pig1 = new Pig(); pig1.x = 1500; pig1.y = groundY - 400; pigs.push(pig1); game.addChild(pig1); // (Second pig inside the house removed) // --- Ensure blocks and pigs are not hanging in the air --- for (var i = 0; i < pigs.length; i++) { var pig = pigs[i]; // Check if pig is supported by ground var supported = false; // Supported by ground if (Math.abs(pig.y + pig.radius - groundY) < 2) { supported = true; } pig.stopped = !supported ? false : pig.stopped; } updateBirdsLeft(); // Reset star collectible if it exists if (typeof star !== "undefined") { star.collected = false; star.visible = true; } } // --- Update birds left text --- function updateBirdsLeft() { birdsLeftTxt.setText('Birds: ' + (maxBirds - birdIndex)); } // --- Drag and Launch Logic --- function getDistance(x1, y1, x2, y2) { var dx = x2 - x1; var dy = y2 - y1; return Math.sqrt(dx * dx + dy * dy); } function getAngle(x1, y1, x2, y2) { return Math.atan2(y2 - y1, x2 - x1); } // Only allow drag if not launched game.down = function (x, y, obj) { if (launching) return; if (!currentBird || currentBird.launched) return; // Only allow drag if touch is near the bird var dist = getDistance(x, y, currentBird.x, currentBird.y); if (dist < currentBird.radius * 1.5) { isDragging = true; dragStart.x = x; dragStart.y = y; } }; game.move = function (x, y, obj) { if (isDragging && currentBird && !currentBird.launched) { // Limit drag distance var dx = x - slingshotX; var dy = y - slingshotY; var dist = getDistance(x, y, slingshotX, slingshotY); if (dist > slingshotBandLength) { var angle = getAngle(slingshotX, slingshotY, x, y); dx = Math.cos(angle) * slingshotBandLength; dy = Math.sin(angle) * slingshotBandLength; } currentBird.x = slingshotX + dx; currentBird.y = slingshotY + dy; dragEnd.x = currentBird.x; dragEnd.y = currentBird.y; } }; game.up = function (x, y, obj) { if (isDragging && currentBird && !currentBird.launched) { isDragging = false; // Calculate launch velocity var dx = slingshotX - currentBird.x; var dy = slingshotY - currentBird.y; currentBird.vx = dx * 0.18; currentBird.vy = dy * 0.18; currentBird.launched = true; launching = true; // Animate slingshot back tween(currentBird, { x: currentBird.x, y: currentBird.y }, { duration: 80 }); } }; // --- Main Game Loop --- game.update = function () { // Update all birds for (var i = 0; i < birds.length; i++) { birds[i].update(); } // Update all pigs for (var i = 0; i < pigs.length; i++) { pigs[i].update(); } // Bird-pig collision for (var i = 0; i < birds.length; i++) { var bird = birds[i]; if (!bird.launched) continue; if (bird.stopped) continue; // Bird-star collision if (typeof star !== "undefined" && star.visible && !star.collected && bird.intersectsCircle({ x: star.x, y: star.y, radius: star.width / 2 })) { star.collected = true; star.visible = false; LK.setScore(LK.getScore() + 5000); scoreTxt.setText(LK.getScore()); } for (var j = 0; j < pigs.length; j++) { var pig = pigs[j]; if (!pig.alive) continue; if (bird.intersectsCircle(pig)) { pig.alive = false; pig.visible = false; LK.setScore(LK.getScore() + 1000); scoreTxt.setText(LK.getScore()); } } } // --- Check support for each pig: if not supported, set stopped = false so it falls --- for (var i = 0; i < pigs.length; i++) { var pig = pigs[i]; if (!pig.alive) continue; var supported = false; // Supported by ground if (Math.abs(pig.y + pig.radius - groundY) < 2) { supported = true; } if (!supported) { pig.stopped = false; } } // Remove dead pigs var allPigsDead = true; for (var i = 0; i < pigs.length; i++) { if (pigs[i].alive) { allPigsDead = false; break; } } // If all pigs dead, win (only if there was at least one pig) if (pigs.length > 0 && allPigsDead) { LK.showYouWin(); return; } // If current bird stopped, move to next bird if (currentBird && currentBird.launched && currentBird.stopped && !isDragging && launching) { birdIndex++; updateBirdsLeft(); if (birdIndex < birds.length) { currentBird = birds[birdIndex]; // Move next bird to slingshot tween(currentBird, { x: slingshotX, y: slingshotY }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { launching = false; } }); } else { // Out of birds, game over LK.showGameOver(); return; } launching = false; } }; // --- Start Game --- setupLevel();
===================================================================
--- original.js
+++ change.js
@@ -138,173 +138,8 @@
return dist < self.radius + other.radius;
};
return self;
});
-// Block class (rectangular, can be horizontal or vertical)
-var Block = Container.expand(function () {
- var self = Container.call(this);
- // Attach a brown box as the block
- var blockAsset = self.attachAsset('block', {
- anchorX: 0.5,
- anchorY: 0.5
- });
- self.width = blockAsset.width;
- self.height = blockAsset.height;
- self.vx = 0;
- self.vy = 0;
- self.gravity = 0.7;
- self.friction = 0.98;
- self.bounce = 0.3;
- self.stopped = false;
- // Add health property for wood blocks
- self.health = 100;
- // Called every tick
- self.update = function () {
- // Track lastX and lastY for physics events
- if (typeof self.lastX === "undefined") self.lastX = self.x;
- if (typeof self.lastY === "undefined") self.lastY = self.y;
- if (!self.stopped) {
- // Apply gravity to wood blocks
- self.vy += self.gravity;
- self.x += self.vx;
- self.y += self.vy;
- self.vx *= self.friction;
- self.vy *= self.friction;
- // --- Ragdoll effect: angular physics ---
- if (typeof self.angularVelocity === "undefined") self.angularVelocity = 0;
- if (typeof self.angle === "undefined") self.angle = self.rotation || 0;
- // Apply angular velocity to rotation
- self.angle += self.angularVelocity;
- self.rotation = self.angle;
- // Dampen angular velocity (simulate friction)
- self.angularVelocity *= 0.97;
- // Block-on-block collision (stand or crash)
- for (var i = 0; i < blocks.length; i++) {
- var other = blocks[i];
- if (other === self) continue;
- // Axis-aligned bounding box collision
- var selfLeft = self.x - self.width / 2;
- var selfRight = self.x + self.width / 2;
- var selfBottom = self.y + self.height / 2;
- var selfTop = self.y - self.height / 2;
- var otherLeft = other.x - other.width / 2;
- var otherRight = other.x + other.width / 2;
- var otherTop = other.y - other.height / 2;
- var otherBottom = other.y + other.height / 2;
- // Check if horizontally overlapping and self is falling onto other
- if (selfRight > otherLeft && selfLeft < otherRight && selfBottom > otherTop && selfTop < otherTop && self.vy > 0 && self.y < other.y) {
- // Land on top of the other block
- self.y = otherTop - self.height / 2;
- // If falling fast, bounce/crash
- if (Math.abs(self.vy) > 2) {
- self.vy = -self.vy * self.bounce;
- self.vx *= 0.8;
- // Transfer some force to the block below (crash effect)
- other.vx += self.vx * 0.2;
- other.vy += self.vy * 0.2;
- // --- Ragdoll: add angular velocity based on impact ---
- var impact = self.vx * 0.1 + self.vy * 0.1;
- if (typeof self.angularVelocity === "undefined") self.angularVelocity = 0;
- self.angularVelocity += impact * (Math.random() - 0.5) * 0.2;
- if (typeof other.angularVelocity === "undefined") other.angularVelocity = 0;
- other.angularVelocity += impact * (Math.random() - 0.5) * 0.2;
- // Reduce health for both blocks based on impact
- var damage = Math.min(30, Math.max(5, Math.floor(Math.abs(self.vy) * 2)));
- self.health -= damage;
- other.health -= Math.floor(damage / 2);
- // Destroy self if health <= 0
- if (self.health <= 0) {
- self.destroy();
- return;
- }
- // Destroy other if health <= 0
- if (other.health <= 0) {
- other.destroy();
- }
- // Bird-block collision damage is handled in game.update
- } else {
- self.vy = 0;
- self.vx *= 0.8;
- if (Math.abs(self.vx) < 1) {
- self.stopped = true;
- }
- }
- }
- // Also allow side-to-side collision (prevent overlap horizontally)
- if (selfBottom > otherTop && selfTop < otherBottom) {
- // Check if self is moving right into other's left side
- if (selfRight > otherLeft && selfLeft < otherLeft && self.vx > 0) {
- self.x = otherLeft - self.width / 2;
- self.vx = -self.vx * self.bounce;
- // Transfer some force to the other block (right hit)
- other.vx += self.vx * 0.2;
- // --- Ragdoll: add angular velocity based on side impact ---
- var impact = self.vx * 0.1;
- if (typeof self.angularVelocity === "undefined") self.angularVelocity = 0;
- self.angularVelocity += impact * 0.1;
- if (typeof other.angularVelocity === "undefined") other.angularVelocity = 0;
- other.angularVelocity -= impact * 0.1;
- }
- // Check if self is moving left into other's right side
- if (selfLeft < otherRight && selfRight > otherRight && self.vx < 0) {
- self.x = otherRight + self.width / 2;
- self.vx = -self.vx * self.bounce;
- // Transfer some force to the other block (left hit)
- other.vx += self.vx * 0.2;
- // --- Ragdoll: add angular velocity based on side impact ---
- var impact = self.vx * 0.1;
- if (typeof self.angularVelocity === "undefined") self.angularVelocity = 0;
- self.angularVelocity -= impact * 0.1;
- if (typeof other.angularVelocity === "undefined") other.angularVelocity = 0;
- other.angularVelocity += impact * 0.1;
- }
- }
- }
- // Floor collision
- if (self.y + self.height / 2 > groundY) {
- self.y = groundY - self.height / 2;
- if (Math.abs(self.vy) > 2) {
- self.vy = -self.vy * self.bounce;
- self.vx *= 0.8;
- } else {
- self.vy = 0;
- self.vx *= 0.8;
- if (Math.abs(self.vx) < 1) {
- self.stopped = true;
- }
- }
- }
- // Wall collision
- if (self.x - self.width / 2 < 0) {
- self.x = self.width / 2;
- self.vx = -self.vx * self.bounce;
- }
- if (self.x + self.width / 2 > 2048) {
- self.x = 2048 - self.width / 2;
- self.vx = -self.vx * self.bounce;
- }
- }
- // Update lastX and lastY after movement
- self.lastX = self.x;
- self.lastY = self.y;
- };
- // Simple rectangle collision with circle (bird)
- self.intersectsCircle = function (circle) {
- var cx = circle.x;
- var cy = circle.y;
- var rx = self.x;
- var ry = self.y;
- var hw = self.width / 2;
- var hh = self.height / 2;
- // Closest point on rectangle to circle center
- var closestX = Math.max(rx - hw, Math.min(cx, rx + hw));
- var closestY = Math.max(ry - hh, Math.min(cy, ry + hh));
- var dx = cx - closestX;
- var dy = cy - closestY;
- return dx * dx + dy * dy < circle.radius * circle.radius;
- };
- return self;
-});
// Pig class
var Pig = Container.expand(function () {
var self = Container.call(this);
// Attach a green ellipse as the pig
@@ -543,66 +378,31 @@
score = 0;
LK.setScore(0);
scoreTxt.setText('0');
launching = false;
- // Place birds
for (var i = 0; i < maxBirds; i++) {
var bird = new Bird();
bird.x = slingshotX - 120 - i * 80;
bird.y = slingshotY + 40;
birds.push(bird);
game.addChild(bird);
}
currentBird = birds[birdIndex];
- // Place pig in the level (no blocks)
var pig1 = new Pig();
pig1.x = 1500;
pig1.y = groundY - 400;
pigs.push(pig1);
game.addChild(pig1);
// (Second pig inside the house removed)
// --- Ensure blocks and pigs are not hanging in the air ---
- for (var i = 0; i < blocks.length; i++) {
- var block = blocks[i];
- // Check if block is supported by ground or another block
- var supported = false;
- // Supported by ground
- if (Math.abs(block.y + block.height / 2 - groundY) < 2) {
- supported = true;
- }
- // Supported by another block below
- for (var j = 0; j < blocks.length; j++) {
- if (i === j) continue;
- var other = blocks[j];
- var blockBottom = block.y + block.height / 2;
- var otherTop = other.y - other.height / 2;
- var horizontalOverlap = block.x + block.width / 2 > other.x - other.width / 2 && block.x - block.width / 2 < other.x + other.width / 2;
- if (horizontalOverlap && Math.abs(blockBottom - otherTop) < 2) {
- supported = true;
- break;
- }
- }
- block.stopped = !supported ? false : block.stopped;
- }
for (var i = 0; i < pigs.length; i++) {
var pig = pigs[i];
- // Check if pig is supported by ground or a block
+ // Check if pig is supported by ground
var supported = false;
// Supported by ground
if (Math.abs(pig.y + pig.radius - groundY) < 2) {
supported = true;
}
- // Supported by a block below
- for (var j = 0; j < blocks.length; j++) {
- var block = blocks[j];
- var pigBottom = pig.y + pig.radius;
- var blockTop = block.y - block.height / 2;
- var horizontalOverlap = pig.x + pig.radius > block.x - block.width / 2 && pig.x - pig.radius < block.x + block.width / 2;
- if (horizontalOverlap && Math.abs(pigBottom - blockTop) < 2) {
- supported = true;
- break;
- }
- }
pig.stopped = !supported ? false : pig.stopped;
}
updateBirdsLeft();
// Reset star collectible if it exists
@@ -681,81 +481,8 @@
// Update all pigs
for (var i = 0; i < pigs.length; i++) {
pigs[i].update();
}
- // Update all blocks
- for (var i = 0; i < blocks.length; i++) {
- blocks[i].update();
- }
- // --- Check support for each block: if not supported, set stopped = false so it falls ---
- for (var i = 0; i < blocks.length; i++) {
- var block = blocks[i];
- // Check if block is supported by ground or another block
- var supported = false;
- // Supported by ground
- if (Math.abs(block.y + block.height / 2 - groundY) < 2) {
- supported = true;
- }
- // Supported by another block below
- for (var j = 0; j < blocks.length; j++) {
- if (i === j) continue;
- var other = blocks[j];
- var blockBottom = block.y + block.height / 2;
- var otherTop = other.y - other.height / 2;
- var horizontalOverlap = block.x + block.width / 2 > other.x - other.width / 2 && block.x - block.width / 2 < other.x + other.width / 2;
- if (horizontalOverlap && Math.abs(blockBottom - otherTop) < 2) {
- supported = true;
- break;
- }
- }
- // If not supported, set stopped = false so it will fall
- if (!supported) {
- block.stopped = false;
- }
- }
- // Bird-block collision
- for (var i = 0; i < birds.length; i++) {
- var bird = birds[i];
- if (!bird.launched) continue;
- if (bird.stopped) continue;
- // Collide with blocks
- for (var j = 0; j < blocks.length; j++) {
- var block = blocks[j];
- // Remove block.stopped check so birds can always touch wood
- if (block.intersectsCircle(bird)) {
- // Calculate collision angle and force
- var angle = getAngle(bird.x, bird.y, block.x, block.y);
- var force = Math.sqrt(bird.vx * bird.vx + bird.vy * bird.vy) * 0.5;
- // Apply force to block
- block.vx += Math.cos(angle) * force * 0.7;
- block.vy += Math.sin(angle) * force * 0.7;
- // --- Ragdoll: add angular velocity to block based on bird impact ---
- var impact = force * 0.2;
- if (typeof block.angularVelocity === "undefined") block.angularVelocity = 0;
- block.angularVelocity += impact * (Math.random() - 0.5);
- // Apply bounce to bird
- bird.vx = -bird.vx * 0.4;
- bird.vy = -bird.vy * 0.4;
- // Move bird out of block to prevent sticking
- var overlap = bird.radius + Math.max(block.width, block.height) / 2 - getDistance(bird.x, bird.y, block.x, block.y);
- if (overlap > 0) {
- bird.x += Math.cos(angle) * overlap * 0.5;
- bird.y += Math.sin(angle) * overlap * 0.5;
- }
- // Optionally, mark block as not stopped to allow it to move if hit hard
- block.stopped = false;
- // Birds deal damage to woods on collision
- var birdDamage = Math.min(40, Math.max(5, Math.floor(force * 2)));
- block.health -= birdDamage;
- if (block.health <= 0) {
- block.destroy();
- blocks.splice(j, 1);
- j--; // Adjust index since we removed a block
- continue;
- }
- }
- }
- }
// Bird-pig collision
for (var i = 0; i < birds.length; i++) {
var bird = birds[i];
if (!bird.launched) continue;
@@ -781,28 +508,8 @@
scoreTxt.setText(LK.getScore());
}
}
}
- // Block-pig collision (falling blocks can kill pigs)
- for (var i = 0; i < blocks.length; i++) {
- var block = blocks[i];
- if (block.stopped) continue;
- for (var j = 0; j < pigs.length; j++) {
- var pig = pigs[j];
- if (!pig.alive) continue;
- // Treat pig as circle, block as rectangle
- if (block.intersectsCircle(pig)) {
- // Only kill pig if block is moving fast enough (e.g. falling hard)
- var blockSpeed = Math.sqrt(block.vx * block.vx + block.vy * block.vy);
- if (blockSpeed > 8) {
- pig.alive = false;
- pig.visible = false;
- LK.setScore(LK.getScore() + 1000);
- scoreTxt.setText(LK.getScore());
- }
- }
- }
- }
// --- Check support for each pig: if not supported, set stopped = false so it falls ---
for (var i = 0; i < pigs.length; i++) {
var pig = pigs[i];
if (!pig.alive) continue;
@@ -810,19 +517,8 @@
// Supported by ground
if (Math.abs(pig.y + pig.radius - groundY) < 2) {
supported = true;
}
- // Supported by a block below
- for (var j = 0; j < blocks.length; j++) {
- var block = blocks[j];
- var pigBottom = pig.y + pig.radius;
- var blockTop = block.y - block.height / 2;
- var horizontalOverlap = pig.x + pig.radius > block.x - block.width / 2 && pig.x - pig.radius < block.x + block.width / 2;
- if (horizontalOverlap && Math.abs(pigBottom - blockTop) < 2) {
- supported = true;
- break;
- }
- }
if (!supported) {
pig.stopped = false;
}
}