User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'length')' in or related to this line: 'for (var i = 0; i < animalButtons.length; i++) {' Line Number: 385
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'length')' in or related to this line: 'for (var i = 0; i < animalButtons.length; i++) {' Line Number: 385
Code edit (1 edits merged)
Please save this source code
User prompt
Pig Cat Bee Frog: Snake Tummy Struggle
Initial prompt
Pig Cat Bee And Frog Is Struggle In The Snake Tummy With Keyboard
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Digestive hazard (acid pool) var Acid = Container.expand(function () { var self = Container.call(this); self.asset = self.attachAsset('acid', { anchorX: 0.5, anchorY: 0.5 }); self.type = 'hazard'; return self; }); // Animal base class var Animal = Container.expand(function () { var self = Container.call(this); self.speed = 0; self.jumpPower = 0; self.gravity = 0.7; self.vx = 0; self.vy = 0; self.isOnGround = false; self.isActive = false; self.asset = null; self.type = 'animal'; self.name = ''; self.moveDir = 0; // -1 left, 1 right, 0 none // Called every tick self.update = function () { // Only update if active if (!self.isActive) return; // Movement self.x += self.vx; self.y += self.vy; // Gravity self.vy += self.gravity; // Clamp to game area if (self.x < 90) self.x = 90; if (self.x > 2048 - 90) self.x = 2048 - 90; if (self.y > 2732 - 90) { self.y = 2732 - 90; self.vy = 0; self.isOnGround = true; } // If moving left/right if (self.moveDir !== 0) { self.vx = self.moveDir * self.speed; } else { self.vx = 0; } }; // Called when jump button pressed self.jump = function () { if (self.isOnGround) { self.vy = -self.jumpPower; self.isOnGround = false; } }; // Called when switching to this animal self.activate = function () { self.isActive = true; if (self.asset) self.asset.alpha = 1; }; // Called when switching away self.deactivate = function () { self.isActive = false; if (self.asset) self.asset.alpha = 0.5; self.moveDir = 0; self.vx = 0; }; return self; }); // Pig: slow, can push blocks var Pig = Animal.expand(function () { var self = Animal.call(this); self.asset = self.attachAsset('pig', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 10; self.jumpPower = 32; self.name = 'Pig'; return self; }); // Frog: can double jump var Frog = Animal.expand(function () { var self = Animal.call(this); self.asset = self.attachAsset('frog', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 13; self.jumpPower = 38; self.name = 'Frog'; self.jumpsLeft = 2; // Override update for double jump self.update = function () { if (!self.isActive) return; self.x += self.vx; self.y += self.vy; self.vy += self.gravity; if (self.x < 90) self.x = 90; if (self.x > 2048 - 90) self.x = 2048 - 90; if (self.y > 2732 - 90) { self.y = 2732 - 90; self.vy = 0; self.isOnGround = true; self.jumpsLeft = 2; } if (self.isOnGround && self.vy !== 0) { self.isOnGround = false; } }; self.jump = function () { if (self.jumpsLeft > 0) { self.vy = -self.jumpPower; self.jumpsLeft--; self.isOnGround = false; } }; // Reset jumps on ground self.activate = function () { self.isActive = true; if (self.asset) self.asset.alpha = 1; if (self.y >= 2732 - 90) self.jumpsLeft = 2; }; return self; }); // Cat: fast, high jump var Cat = Animal.expand(function () { var self = Animal.call(this); self.asset = self.attachAsset('cat', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 18; self.jumpPower = 48; self.name = 'Cat'; return self; }); // Bee: can fly (no gravity) var Bee = Animal.expand(function () { var self = Animal.call(this); self.asset = self.attachAsset('bee', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 14; self.jumpPower = 0; self.name = 'Bee'; self.gravity = 0; // No gravity // Override update for flying self.update = function () { if (!self.isActive) return; self.x += self.vx; self.y += self.vy; // Clamp if (self.x < 90) self.x = 90; if (self.x > 2048 - 90) self.x = 2048 - 90; if (self.y < 90) self.y = 90; if (self.y > 2732 - 90) self.y = 2732 - 90; }; // Bee "jump" is fly up self.jump = function () { self.vy = -16; }; return self; }); // Puzzle block (static) var Block = Container.expand(function () { var self = Container.call(this); self.asset = self.attachAsset('block', { anchorX: 0.5, anchorY: 0.5 }); self.type = 'block'; return self; }); // Button UI var UIButton = Container.expand(function () { var self = Container.call(this); self.bg = self.attachAsset('button', { anchorX: 0.5, anchorY: 0.5 }); self.txt = new Text2('', { size: 60, fill: "#fff" }); self.txt.anchor.set(0.5, 0.5); self.addChild(self.txt); self.action = null; self.isActive = false; self.setText = function (str) { self.txt.setText(str); }; self.setActive = function (active) { self.isActive = active; self.bg.tint = active ? 0x77cc77 : 0x333333; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2e1e1e }); /**** * Game Code ****/ // Button shapes // Puzzle block // Digestive hazard // Snake belly background // Animal shapes (distinct color for each) // Add snake belly background var bg = LK.getAsset('snakeBelly', { anchorX: 0, anchorY: 0, x: 0, y: 0 }); game.addChild(bg); // Level layout (minimal MVP: platforms, hazards, exit) var blocks = []; var acids = []; var exitZone = { x: 2048 - 200, y: 200, w: 200, h: 200 }; // Top right corner // Create platforms function createBlock(x, y) { var b = new Block(); b.x = x; b.y = y; blocks.push(b); game.addChild(b); } createBlock(400, 2200); createBlock(800, 1800); createBlock(1200, 1400); createBlock(1600, 1000); createBlock(1800, 600); // Create acid hazards function createAcid(x, y) { var a = new Acid(); a.x = x; a.y = y; acids.push(a); game.addChild(a); } createAcid(600, 2300); createAcid(1400, 1600); createAcid(1700, 800); // Create exit zone (invisible, just a rectangle) var exitRect = new Rectangle(exitZone.x, exitZone.y, exitZone.w, exitZone.h); // Animals var animals = []; var pig = new Pig(); pig.x = 400; pig.y = 2100; animals.push(pig); game.addChild(pig); var cat = new Cat(); cat.x = 800; cat.y = 1700; animals.push(cat); game.addChild(cat); var bee = new Bee(); bee.x = 1200; bee.y = 1300; animals.push(bee); game.addChild(bee); var frog = new Frog(); frog.x = 1600; frog.y = 900; animals.push(frog); game.addChild(frog); // Set initial active animal var activeAnimalIndex = 0; function setActiveAnimal(idx) { for (var i = 0; i < animals.length; i++) { if (i === idx) animals[i].activate();else animals[i].deactivate(); } activeAnimalIndex = idx; updateAnimalButtons(); } setActiveAnimal(0); // UI: On-screen controls var btnLeft = new UIButton(); btnLeft.setText('←'); btnLeft.x = 300; btnLeft.y = 2732 - 200; LK.gui.bottomLeft.addChild(btnLeft); var btnRight = new UIButton(); btnRight.setText('→'); btnRight.x = 600; btnRight.y = 2732 - 200; LK.gui.bottomLeft.addChild(btnRight); var btnJump = new UIButton(); btnJump.setText('⤒'); btnJump.x = 2048 - 600; btnJump.y = 2732 - 200; LK.gui.bottomRight.addChild(btnJump); // Animal switch buttons var btnPig = new UIButton(); btnPig.setText('Pig'); btnPig.x = 400; btnPig.y = 200; LK.gui.top.addChild(btnPig); var btnCat = new UIButton(); btnCat.setText('Cat'); btnCat.x = 800; btnCat.y = 200; LK.gui.top.addChild(btnCat); var btnBee = new UIButton(); btnBee.setText('Bee'); btnBee.x = 1200; btnBee.y = 200; LK.gui.top.addChild(btnBee); var btnFrog = new UIButton(); btnFrog.setText('Frog'); btnFrog.x = 1600; btnFrog.y = 200; LK.gui.top.addChild(btnFrog); var animalButtons = [btnPig, btnCat, btnBee, btnFrog]; function updateAnimalButtons() { for (var i = 0; i < animalButtons.length; i++) { animalButtons[i].setActive(i === activeAnimalIndex); } } // Score: animals escaped var scoreTxt = new Text2('Escaped: 0/4', { size: 90, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Touch handling for buttons var leftPressed = false, rightPressed = false, jumpPressed = false; // Button event helpers function isInsideBtn(btn, x, y) { var bx = btn.x, by = btn.y; var w = btn.bg.width, h = btn.bg.height; return x >= bx - w / 2 && x <= bx + w / 2 && y >= by - h / 2 && y <= by + h / 2; } // GUI event: move LK.gui.move = function (x, y, obj) { // Only handle move for button press/release // (No drag for MVP) }; // GUI event: down LK.gui.down = function (x, y, obj) { // Convert to GUI coordinates for each button // Left if (isInsideBtn(btnLeft, x, y)) { leftPressed = true; btnLeft.setActive(true); animals[activeAnimalIndex].moveDir = -1; } // Right if (isInsideBtn(btnRight, x, y)) { rightPressed = true; btnRight.setActive(true); animals[activeAnimalIndex].moveDir = 1; } // Jump if (isInsideBtn(btnJump, x, y)) { jumpPressed = true; btnJump.setActive(true); animals[activeAnimalIndex].jump(); } // Animal switch for (var i = 0; i < animalButtons.length; i++) { if (isInsideBtn(animalButtons[i], x, y)) { setActiveAnimal(i); } } }; // GUI event: up LK.gui.up = function (x, y, obj) { // Left if (leftPressed) { leftPressed = false; btnLeft.setActive(false); if (animals[activeAnimalIndex].moveDir === -1) animals[activeAnimalIndex].moveDir = 0; } // Right if (rightPressed) { rightPressed = false; btnRight.setActive(false); if (animals[activeAnimalIndex].moveDir === 1) animals[activeAnimalIndex].moveDir = 0; } // Jump if (jumpPressed) { jumpPressed = false; btnJump.setActive(false); } }; // Collision helpers function rectsIntersect(ax, ay, aw, ah, bx, by, bw, bh) { return !(bx > ax + aw || bx + bw < ax || by > ay + ah || by + bh < ay); } // Check collision with blocks function animalBlockCollision(animal) { for (var i = 0; i < blocks.length; i++) { var b = blocks[i]; var aw = animal.asset.width, ah = animal.asset.height; var bw = b.asset.width, bh = b.asset.height; // Simple AABB if (rectsIntersect(animal.x - aw / 2, animal.y - ah / 2, aw, ah, b.x - bw / 2, b.y - bh / 2, bw, bh)) { // Land on top if (animal.y < b.y && animal.vy > 0) { animal.y = b.y - bh / 2 - ah / 2; animal.vy = 0; animal.isOnGround = true; if (animal.name === 'Frog') animal.jumpsLeft = 2; } // Push block (only Pig) if (animal.name === 'Pig' && Math.abs(animal.x - b.x) < (aw + bw) / 2 && Math.abs(animal.y - b.y) < (ah + bh) / 2) { b.x += animal.vx * 0.5; // Clamp block if (b.x < bw / 2) b.x = bw / 2; if (b.x > 2048 - bw / 2) b.x = 2048 - bw / 2; } } } } // Check collision with acid function animalAcidCollision(animal) { for (var i = 0; i < acids.length; i++) { var a = acids[i]; var aw = animal.asset.width, ah = animal.asset.height; var aw2 = aw / 2, ah2 = ah / 2; var ax = animal.x - aw2, ay = animal.y - ah2; var bw = a.asset.width, bh = a.asset.height; var bx = a.x - bw / 2, by = a.y - bh / 2; if (rectsIntersect(ax, ay, aw, ah, bx, by, bw, bh)) { // Flash and game over LK.effects.flashScreen(0x00ffff, 800); LK.showGameOver(); return true; } } return false; } // Check if animal reached exit function animalAtExit(animal) { var aw = animal.asset.width, ah = animal.asset.height; var ax = animal.x - aw / 2, ay = animal.y - ah / 2; return rectsIntersect(ax, ay, aw, ah, exitRect.x, exitRect.y, exitRect.width, exitRect.height); } // Track which animals have escaped var escaped = [false, false, false, false]; // Main game update game.update = function () { // Update all animals for (var i = 0; i < animals.length; i++) { animals[i].update(); animalBlockCollision(animals[i]); if (animalAcidCollision(animals[i])) return; // Check exit if (!escaped[i] && animalAtExit(animals[i])) { escaped[i] = true; animals[i].visible = false; // Flash green LK.effects.flashScreen(0x00ff00, 400); // Update score var count = 0; for (var j = 0; j < escaped.length; j++) if (escaped[j]) count++; scoreTxt.setText('Escaped: ' + count + '/4'); // If all escaped, win! if (count === 4) { LK.showYouWin(); } else { // Switch to next available animal for (var k = 0; k < animals.length; k++) { if (!escaped[k]) { setActiveAnimal(k); break; } } } } } // If active animal is escaped, switch if (escaped[activeAnimalIndex]) { for (var k = 0; k < animals.length; k++) { if (!escaped[k]) { setActiveAnimal(k); break; } } } }; // Draw exit zone (for MVP, invisible, but could add a visual hint if desired) // var exitHint = LK.getAsset('centerCircle', {anchorX:0.5, anchorY:0.5, x:exitZone.x+exitZone.w/2, y:exitZone.y+exitZone.h/2, scaleX:1.2, scaleY:1.2, tint:0x00ff00, alpha:0.2}); // game.addChild(exitHint);
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,521 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+// Digestive hazard (acid pool)
+var Acid = Container.expand(function () {
+ var self = Container.call(this);
+ self.asset = self.attachAsset('acid', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.type = 'hazard';
+ return self;
+});
+// Animal base class
+var Animal = Container.expand(function () {
+ var self = Container.call(this);
+ self.speed = 0;
+ self.jumpPower = 0;
+ self.gravity = 0.7;
+ self.vx = 0;
+ self.vy = 0;
+ self.isOnGround = false;
+ self.isActive = false;
+ self.asset = null;
+ self.type = 'animal';
+ self.name = '';
+ self.moveDir = 0; // -1 left, 1 right, 0 none
+ // Called every tick
+ self.update = function () {
+ // Only update if active
+ if (!self.isActive) return;
+ // Movement
+ self.x += self.vx;
+ self.y += self.vy;
+ // Gravity
+ self.vy += self.gravity;
+ // Clamp to game area
+ if (self.x < 90) self.x = 90;
+ if (self.x > 2048 - 90) self.x = 2048 - 90;
+ if (self.y > 2732 - 90) {
+ self.y = 2732 - 90;
+ self.vy = 0;
+ self.isOnGround = true;
+ }
+ // If moving left/right
+ if (self.moveDir !== 0) {
+ self.vx = self.moveDir * self.speed;
+ } else {
+ self.vx = 0;
+ }
+ };
+ // Called when jump button pressed
+ self.jump = function () {
+ if (self.isOnGround) {
+ self.vy = -self.jumpPower;
+ self.isOnGround = false;
+ }
+ };
+ // Called when switching to this animal
+ self.activate = function () {
+ self.isActive = true;
+ if (self.asset) self.asset.alpha = 1;
+ };
+ // Called when switching away
+ self.deactivate = function () {
+ self.isActive = false;
+ if (self.asset) self.asset.alpha = 0.5;
+ self.moveDir = 0;
+ self.vx = 0;
+ };
+ return self;
+});
+// Pig: slow, can push blocks
+var Pig = Animal.expand(function () {
+ var self = Animal.call(this);
+ self.asset = self.attachAsset('pig', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 10;
+ self.jumpPower = 32;
+ self.name = 'Pig';
+ return self;
+});
+// Frog: can double jump
+var Frog = Animal.expand(function () {
+ var self = Animal.call(this);
+ self.asset = self.attachAsset('frog', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 13;
+ self.jumpPower = 38;
+ self.name = 'Frog';
+ self.jumpsLeft = 2;
+ // Override update for double jump
+ self.update = function () {
+ if (!self.isActive) return;
+ self.x += self.vx;
+ self.y += self.vy;
+ self.vy += self.gravity;
+ if (self.x < 90) self.x = 90;
+ if (self.x > 2048 - 90) self.x = 2048 - 90;
+ if (self.y > 2732 - 90) {
+ self.y = 2732 - 90;
+ self.vy = 0;
+ self.isOnGround = true;
+ self.jumpsLeft = 2;
+ }
+ if (self.isOnGround && self.vy !== 0) {
+ self.isOnGround = false;
+ }
+ };
+ self.jump = function () {
+ if (self.jumpsLeft > 0) {
+ self.vy = -self.jumpPower;
+ self.jumpsLeft--;
+ self.isOnGround = false;
+ }
+ };
+ // Reset jumps on ground
+ self.activate = function () {
+ self.isActive = true;
+ if (self.asset) self.asset.alpha = 1;
+ if (self.y >= 2732 - 90) self.jumpsLeft = 2;
+ };
+ return self;
+});
+// Cat: fast, high jump
+var Cat = Animal.expand(function () {
+ var self = Animal.call(this);
+ self.asset = self.attachAsset('cat', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 18;
+ self.jumpPower = 48;
+ self.name = 'Cat';
+ return self;
+});
+// Bee: can fly (no gravity)
+var Bee = Animal.expand(function () {
+ var self = Animal.call(this);
+ self.asset = self.attachAsset('bee', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 14;
+ self.jumpPower = 0;
+ self.name = 'Bee';
+ self.gravity = 0; // No gravity
+ // Override update for flying
+ self.update = function () {
+ if (!self.isActive) return;
+ self.x += self.vx;
+ self.y += self.vy;
+ // Clamp
+ if (self.x < 90) self.x = 90;
+ if (self.x > 2048 - 90) self.x = 2048 - 90;
+ if (self.y < 90) self.y = 90;
+ if (self.y > 2732 - 90) self.y = 2732 - 90;
+ };
+ // Bee "jump" is fly up
+ self.jump = function () {
+ self.vy = -16;
+ };
+ return self;
+});
+// Puzzle block (static)
+var Block = Container.expand(function () {
+ var self = Container.call(this);
+ self.asset = self.attachAsset('block', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.type = 'block';
+ return self;
+});
+// Button UI
+var UIButton = Container.expand(function () {
+ var self = Container.call(this);
+ self.bg = self.attachAsset('button', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.txt = new Text2('', {
+ size: 60,
+ fill: "#fff"
+ });
+ self.txt.anchor.set(0.5, 0.5);
+ self.addChild(self.txt);
+ self.action = null;
+ self.isActive = false;
+ self.setText = function (str) {
+ self.txt.setText(str);
+ };
+ self.setActive = function (active) {
+ self.isActive = active;
+ self.bg.tint = active ? 0x77cc77 : 0x333333;
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x2e1e1e
+});
+
+/****
+* Game Code
+****/
+// Button shapes
+// Puzzle block
+// Digestive hazard
+// Snake belly background
+// Animal shapes (distinct color for each)
+// Add snake belly background
+var bg = LK.getAsset('snakeBelly', {
+ anchorX: 0,
+ anchorY: 0,
+ x: 0,
+ y: 0
+});
+game.addChild(bg);
+// Level layout (minimal MVP: platforms, hazards, exit)
+var blocks = [];
+var acids = [];
+var exitZone = {
+ x: 2048 - 200,
+ y: 200,
+ w: 200,
+ h: 200
+}; // Top right corner
+// Create platforms
+function createBlock(x, y) {
+ var b = new Block();
+ b.x = x;
+ b.y = y;
+ blocks.push(b);
+ game.addChild(b);
+}
+createBlock(400, 2200);
+createBlock(800, 1800);
+createBlock(1200, 1400);
+createBlock(1600, 1000);
+createBlock(1800, 600);
+// Create acid hazards
+function createAcid(x, y) {
+ var a = new Acid();
+ a.x = x;
+ a.y = y;
+ acids.push(a);
+ game.addChild(a);
+}
+createAcid(600, 2300);
+createAcid(1400, 1600);
+createAcid(1700, 800);
+// Create exit zone (invisible, just a rectangle)
+var exitRect = new Rectangle(exitZone.x, exitZone.y, exitZone.w, exitZone.h);
+// Animals
+var animals = [];
+var pig = new Pig();
+pig.x = 400;
+pig.y = 2100;
+animals.push(pig);
+game.addChild(pig);
+var cat = new Cat();
+cat.x = 800;
+cat.y = 1700;
+animals.push(cat);
+game.addChild(cat);
+var bee = new Bee();
+bee.x = 1200;
+bee.y = 1300;
+animals.push(bee);
+game.addChild(bee);
+var frog = new Frog();
+frog.x = 1600;
+frog.y = 900;
+animals.push(frog);
+game.addChild(frog);
+// Set initial active animal
+var activeAnimalIndex = 0;
+function setActiveAnimal(idx) {
+ for (var i = 0; i < animals.length; i++) {
+ if (i === idx) animals[i].activate();else animals[i].deactivate();
+ }
+ activeAnimalIndex = idx;
+ updateAnimalButtons();
+}
+setActiveAnimal(0);
+// UI: On-screen controls
+var btnLeft = new UIButton();
+btnLeft.setText('←');
+btnLeft.x = 300;
+btnLeft.y = 2732 - 200;
+LK.gui.bottomLeft.addChild(btnLeft);
+var btnRight = new UIButton();
+btnRight.setText('→');
+btnRight.x = 600;
+btnRight.y = 2732 - 200;
+LK.gui.bottomLeft.addChild(btnRight);
+var btnJump = new UIButton();
+btnJump.setText('⤒');
+btnJump.x = 2048 - 600;
+btnJump.y = 2732 - 200;
+LK.gui.bottomRight.addChild(btnJump);
+// Animal switch buttons
+var btnPig = new UIButton();
+btnPig.setText('Pig');
+btnPig.x = 400;
+btnPig.y = 200;
+LK.gui.top.addChild(btnPig);
+var btnCat = new UIButton();
+btnCat.setText('Cat');
+btnCat.x = 800;
+btnCat.y = 200;
+LK.gui.top.addChild(btnCat);
+var btnBee = new UIButton();
+btnBee.setText('Bee');
+btnBee.x = 1200;
+btnBee.y = 200;
+LK.gui.top.addChild(btnBee);
+var btnFrog = new UIButton();
+btnFrog.setText('Frog');
+btnFrog.x = 1600;
+btnFrog.y = 200;
+LK.gui.top.addChild(btnFrog);
+var animalButtons = [btnPig, btnCat, btnBee, btnFrog];
+function updateAnimalButtons() {
+ for (var i = 0; i < animalButtons.length; i++) {
+ animalButtons[i].setActive(i === activeAnimalIndex);
+ }
+}
+// Score: animals escaped
+var scoreTxt = new Text2('Escaped: 0/4', {
+ size: 90,
+ fill: "#fff"
+});
+scoreTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(scoreTxt);
+// Touch handling for buttons
+var leftPressed = false,
+ rightPressed = false,
+ jumpPressed = false;
+// Button event helpers
+function isInsideBtn(btn, x, y) {
+ var bx = btn.x,
+ by = btn.y;
+ var w = btn.bg.width,
+ h = btn.bg.height;
+ return x >= bx - w / 2 && x <= bx + w / 2 && y >= by - h / 2 && y <= by + h / 2;
+}
+// GUI event: move
+LK.gui.move = function (x, y, obj) {
+ // Only handle move for button press/release
+ // (No drag for MVP)
+};
+// GUI event: down
+LK.gui.down = function (x, y, obj) {
+ // Convert to GUI coordinates for each button
+ // Left
+ if (isInsideBtn(btnLeft, x, y)) {
+ leftPressed = true;
+ btnLeft.setActive(true);
+ animals[activeAnimalIndex].moveDir = -1;
+ }
+ // Right
+ if (isInsideBtn(btnRight, x, y)) {
+ rightPressed = true;
+ btnRight.setActive(true);
+ animals[activeAnimalIndex].moveDir = 1;
+ }
+ // Jump
+ if (isInsideBtn(btnJump, x, y)) {
+ jumpPressed = true;
+ btnJump.setActive(true);
+ animals[activeAnimalIndex].jump();
+ }
+ // Animal switch
+ for (var i = 0; i < animalButtons.length; i++) {
+ if (isInsideBtn(animalButtons[i], x, y)) {
+ setActiveAnimal(i);
+ }
+ }
+};
+// GUI event: up
+LK.gui.up = function (x, y, obj) {
+ // Left
+ if (leftPressed) {
+ leftPressed = false;
+ btnLeft.setActive(false);
+ if (animals[activeAnimalIndex].moveDir === -1) animals[activeAnimalIndex].moveDir = 0;
+ }
+ // Right
+ if (rightPressed) {
+ rightPressed = false;
+ btnRight.setActive(false);
+ if (animals[activeAnimalIndex].moveDir === 1) animals[activeAnimalIndex].moveDir = 0;
+ }
+ // Jump
+ if (jumpPressed) {
+ jumpPressed = false;
+ btnJump.setActive(false);
+ }
+};
+// Collision helpers
+function rectsIntersect(ax, ay, aw, ah, bx, by, bw, bh) {
+ return !(bx > ax + aw || bx + bw < ax || by > ay + ah || by + bh < ay);
+}
+// Check collision with blocks
+function animalBlockCollision(animal) {
+ for (var i = 0; i < blocks.length; i++) {
+ var b = blocks[i];
+ var aw = animal.asset.width,
+ ah = animal.asset.height;
+ var bw = b.asset.width,
+ bh = b.asset.height;
+ // Simple AABB
+ if (rectsIntersect(animal.x - aw / 2, animal.y - ah / 2, aw, ah, b.x - bw / 2, b.y - bh / 2, bw, bh)) {
+ // Land on top
+ if (animal.y < b.y && animal.vy > 0) {
+ animal.y = b.y - bh / 2 - ah / 2;
+ animal.vy = 0;
+ animal.isOnGround = true;
+ if (animal.name === 'Frog') animal.jumpsLeft = 2;
+ }
+ // Push block (only Pig)
+ if (animal.name === 'Pig' && Math.abs(animal.x - b.x) < (aw + bw) / 2 && Math.abs(animal.y - b.y) < (ah + bh) / 2) {
+ b.x += animal.vx * 0.5;
+ // Clamp block
+ if (b.x < bw / 2) b.x = bw / 2;
+ if (b.x > 2048 - bw / 2) b.x = 2048 - bw / 2;
+ }
+ }
+ }
+}
+// Check collision with acid
+function animalAcidCollision(animal) {
+ for (var i = 0; i < acids.length; i++) {
+ var a = acids[i];
+ var aw = animal.asset.width,
+ ah = animal.asset.height;
+ var aw2 = aw / 2,
+ ah2 = ah / 2;
+ var ax = animal.x - aw2,
+ ay = animal.y - ah2;
+ var bw = a.asset.width,
+ bh = a.asset.height;
+ var bx = a.x - bw / 2,
+ by = a.y - bh / 2;
+ if (rectsIntersect(ax, ay, aw, ah, bx, by, bw, bh)) {
+ // Flash and game over
+ LK.effects.flashScreen(0x00ffff, 800);
+ LK.showGameOver();
+ return true;
+ }
+ }
+ return false;
+}
+// Check if animal reached exit
+function animalAtExit(animal) {
+ var aw = animal.asset.width,
+ ah = animal.asset.height;
+ var ax = animal.x - aw / 2,
+ ay = animal.y - ah / 2;
+ return rectsIntersect(ax, ay, aw, ah, exitRect.x, exitRect.y, exitRect.width, exitRect.height);
+}
+// Track which animals have escaped
+var escaped = [false, false, false, false];
+// Main game update
+game.update = function () {
+ // Update all animals
+ for (var i = 0; i < animals.length; i++) {
+ animals[i].update();
+ animalBlockCollision(animals[i]);
+ if (animalAcidCollision(animals[i])) return;
+ // Check exit
+ if (!escaped[i] && animalAtExit(animals[i])) {
+ escaped[i] = true;
+ animals[i].visible = false;
+ // Flash green
+ LK.effects.flashScreen(0x00ff00, 400);
+ // Update score
+ var count = 0;
+ for (var j = 0; j < escaped.length; j++) if (escaped[j]) count++;
+ scoreTxt.setText('Escaped: ' + count + '/4');
+ // If all escaped, win!
+ if (count === 4) {
+ LK.showYouWin();
+ } else {
+ // Switch to next available animal
+ for (var k = 0; k < animals.length; k++) {
+ if (!escaped[k]) {
+ setActiveAnimal(k);
+ break;
+ }
+ }
+ }
+ }
+ }
+ // If active animal is escaped, switch
+ if (escaped[activeAnimalIndex]) {
+ for (var k = 0; k < animals.length; k++) {
+ if (!escaped[k]) {
+ setActiveAnimal(k);
+ break;
+ }
+ }
+ }
+};
+// Draw exit zone (for MVP, invisible, but could add a visual hint if desired)
+// var exitHint = LK.getAsset('centerCircle', {anchorX:0.5, anchorY:0.5, x:exitZone.x+exitZone.w/2, y:exitZone.y+exitZone.h/2, scaleX:1.2, scaleY:1.2, tint:0x00ff00, alpha:0.2});
+// game.addChild(exitHint);
\ No newline at end of file