User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'length')' in or related to this line: 'var animalSprite = self.attachAsset(self.assetId, {' Line Number: 73
Code edit (1 edits merged)
Please save this source code
User prompt
Animal Escape: Snake Tummy Struggle
Initial prompt
(Pig) (Cat) (Bee) (Frog) (Polar Bear) (Elephant) (Bird) (Snail) (Axolotl) (Pink Fox) (Boy Bat) (Wolf) (Chinchilla) (Moth) (Goat) (Bunny) (Bear) And (Deer) Is Struggle In The Snake Tummy With Outside Of Snake Tummy
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Acid Bubble (obstacle)
var AcidBubble = Container.expand(function () {
var self = Container.call(this);
var bubble = self.attachAsset('acidBubble', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = bubble.width / 2;
self.vx = (Math.random() - 0.5) * 6;
self.vy = (Math.random() - 0.5) * 6;
self.update = function () {
self.x += self.vx;
self.y += self.vy;
// Bounce off belly walls
if (self.x < snakeBelly.x - snakeBelly.width / 2 + self.radius) {
self.x = snakeBelly.x - snakeBelly.width / 2 + self.radius;
self.vx *= -1;
}
if (self.x > snakeBelly.x + snakeBelly.width / 2 - self.radius) {
self.x = snakeBelly.x + snakeBelly.width / 2 - self.radius;
self.vx *= -1;
}
if (self.y < snakeBelly.y - snakeBelly.height / 2 + self.radius) {
self.y = snakeBelly.y - snakeBelly.height / 2 + self.radius;
self.vy *= -1;
}
if (self.y > snakeBelly.y + snakeBelly.height / 2 - self.radius) {
self.y = snakeBelly.y + snakeBelly.height / 2 - self.radius;
self.vy *= -1;
}
};
return self;
});
// Animal class
var Animal = Container.expand(function () {
var self = Container.call(this);
// Defensive: set a default assetId if not set
if (!self.assetId) self.assetId = 'pig';
// Asset id is passed in as self.assetId
var animalSprite = self.attachAsset(self.assetId, {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = animalSprite.width / 2;
// Used for movement
self.vx = 0;
self.vy = 0;
self.isSelected = false;
// Called every tick
self.update = function () {
// Gravity inside snake
self.vy += 0.5;
self.x += self.vx;
self.y += self.vy;
// Friction
self.vx *= 0.95;
self.vy *= 0.95;
// Keep inside belly bounds
if (self.x < snakeBelly.x - snakeBelly.width / 2 + self.radius) {
self.x = snakeBelly.x - snakeBelly.width / 2 + self.radius;
self.vx *= -0.5;
}
if (self.x > snakeBelly.x + snakeBelly.width / 2 - self.radius) {
self.x = snakeBelly.x + snakeBelly.width / 2 - self.radius;
self.vx *= -0.5;
}
if (self.y < snakeBelly.y - snakeBelly.height / 2 + self.radius) {
self.y = snakeBelly.y - snakeBelly.height / 2 + self.radius;
self.vy *= -0.5;
}
if (self.y > snakeBelly.y + snakeBelly.height / 2 - self.radius) {
self.y = snakeBelly.y + snakeBelly.height / 2 - self.radius;
self.vy *= -0.5;
}
};
// Touch down on animal
self.down = function (x, y, obj) {
self.isSelected = true;
selectedAnimal = self;
dragOffsetX = self.x - x;
dragOffsetY = self.y - y;
};
// Touch up
self.up = function (x, y, obj) {
self.isSelected = false;
selectedAnimal = null;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222222
});
/****
* Game Code
****/
// Sound for animal jump
// Exit (esophagus opening)
// Obstacle (stomach acid bubble)
// Snake exterior (for outside interaction)
// Snake belly (background)
// Animal shapes (simple colored ellipses for each animal)
// --- Global variables ---
var animalIds = ['pig', 'cat', 'bee', 'frog', 'polarBear', 'elephant', 'bird', 'snail', 'axolotl', 'pinkFox', 'boyBat', 'wolf', 'chinchilla', 'moth', 'goat', 'bunny', 'bear', 'deer'];
var animals = [];
var acidBubbles = [];
var selectedAnimal = null;
var dragOffsetX = 0;
var dragOffsetY = 0;
var insideMode = true; // true: inside snake, false: outside
var snakeBelly, snakeSkin, exitNode;
var scoreTxt;
var rescuedCount = 0;
var totalToRescue = 5; // MVP: rescue 5 animals to win
// --- Setup snake belly (inside) ---
snakeBelly = LK.getAsset('snakeBelly', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 1200
});
game.addChild(snakeBelly);
// --- Setup exit (esophagus opening) ---
exitNode = LK.getAsset('exit', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 800
});
game.addChild(exitNode);
// --- Setup animals ---
function spawnAnimals() {
animals = [];
var startX = 2048 / 2 - 400;
var startY = 1200;
for (var i = 0; i < totalToRescue; i++) {
var id = animalIds[i];
var animal = new Animal();
animal.assetId = id;
animal.x = startX + i * 200;
animal.y = startY + Math.random() * 100 - 50;
animal.vx = (Math.random() - 0.5) * 6;
animal.vy = (Math.random() - 0.5) * 6;
animals.push(animal);
game.addChild(animal);
}
}
spawnAnimals();
// --- Setup acid bubbles (obstacles) ---
function spawnAcidBubbles() {
acidBubbles = [];
for (var i = 0; i < 3; i++) {
var bubble = new AcidBubble();
bubble.x = 2048 / 2 + (Math.random() - 0.5) * 600;
bubble.y = 1200 + (Math.random() - 0.5) * 300;
acidBubbles.push(bubble);
game.addChild(bubble);
}
}
spawnAcidBubbles();
// --- Setup score text ---
scoreTxt = new Text2('0', {
size: 120,
fill: "#fff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// --- Setup snake skin (outside) ---
snakeSkin = LK.getAsset('snakeSkin', {
anchorX: 0.5,
anchorY: 0,
x: 2048 / 2,
y: 0
});
// Not added yet; only shown in outside mode
// --- Helper: reset game state ---
function resetGame() {
// Remove all animals and bubbles
for (var i = 0; i < animals.length; i++) animals[i].destroy();
for (var i = 0; i < acidBubbles.length; i++) acidBubbles[i].destroy();
animals = [];
acidBubbles = [];
rescuedCount = 0;
scoreTxt.setText('0');
insideMode = true;
if (snakeSkin.parent) snakeSkin.parent.removeChild(snakeSkin);
if (!snakeBelly.parent) game.addChild(snakeBelly);
if (!exitNode.parent) game.addChild(exitNode);
spawnAnimals();
spawnAcidBubbles();
}
// --- Touch/drag logic ---
game.move = function (x, y, obj) {
if (!insideMode) return;
if (selectedAnimal) {
// Move animal with finger
selectedAnimal.x = x + dragOffsetX;
selectedAnimal.y = y + dragOffsetY;
}
};
game.down = function (x, y, obj) {
if (!insideMode) return;
// Check if any animal is touched
for (var i = 0; i < animals.length; i++) {
var a = animals[i];
var dx = x - a.x;
var dy = y - a.y;
if (dx * dx + dy * dy < a.radius * a.radius) {
a.down(x, y, obj);
return;
}
}
};
game.up = function (x, y, obj) {
if (!insideMode) return;
if (selectedAnimal) {
// Give a jump impulse upwards
selectedAnimal.vy = -18;
selectedAnimal.vx = (Math.random() - 0.5) * 8;
LK.getSound('jump').play();
selectedAnimal.up(x, y, obj);
}
};
// --- Outside mode: tap snake skin to help animals escape ---
snakeSkin.down = function (x, y, obj) {
if (!insideMode) {
// "Massage" the snake: all animals get a little upward boost
for (var i = 0; i < animals.length; i++) {
animals[i].vy -= 10 + Math.random() * 6;
}
// Animate snake skin
tween(snakeSkin, {
y: 20
}, {
duration: 120,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(snakeSkin, {
y: 0
}, {
duration: 180,
easing: tween.easeIn
});
}
});
}
};
// --- Game update loop ---
game.update = function () {
// Switch between inside/outside every 10 seconds
if (LK.ticks % 600 === 0) {
insideMode = !insideMode;
if (insideMode) {
// Show inside
if (!snakeBelly.parent) game.addChild(snakeBelly);
if (!exitNode.parent) game.addChild(exitNode);
if (snakeSkin.parent) snakeSkin.parent.removeChild(snakeSkin);
} else {
// Show outside
if (!snakeSkin.parent) game.addChild(snakeSkin);
if (snakeBelly.parent) snakeBelly.parent.removeChild(snakeBelly);
if (exitNode.parent) exitNode.parent.removeChild(exitNode);
}
}
// Update animals
for (var i = animals.length - 1; i >= 0; i--) {
var a = animals[i];
a.update();
// If animal touches exit, rescue it!
if (insideMode && a.intersects(exitNode)) {
// Animate out
tween(a, {
y: exitNode.y - 200
}, {
duration: 400,
easing: tween.easeIn,
onFinish: function onFinish() {
a.destroy();
}
});
animals.splice(i, 1);
rescuedCount++;
scoreTxt.setText(rescuedCount);
// Win condition
if (rescuedCount >= totalToRescue) {
LK.showYouWin();
return;
}
}
}
// Update acid bubbles
for (var i = acidBubbles.length - 1; i >= 0; i--) {
var b = acidBubbles[i];
b.update();
// If any animal hits a bubble, game over
for (var j = 0; j < animals.length; j++) {
var a = animals[j];
var dx = a.x - b.x;
var dy = a.y - b.y;
var dist = a.radius + b.radius - 10;
if (dx * dx + dy * dy < dist * dist) {
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
return;
}
}
}
};
// --- Reset game on game over or win ---
LK.on('gameover', function () {
resetGame();
});
LK.on('youwin', function () {
resetGame();
});
// --- Instructions text ---
var instructions = new Text2("Drag animals to help them jump to the exit!\nAvoid acid bubbles.\nSometimes tap the snake's back to help!", {
size: 60,
fill: "#fff"
});
instructions.anchor.set(0.5, 0);
LK.gui.top.addChild(instructions);
instructions.y = 180;
instructions.x = 2048 / 2; ===================================================================
--- original.js
+++ change.js
@@ -41,8 +41,10 @@
});
// Animal class
var Animal = Container.expand(function () {
var self = Container.call(this);
+ // Defensive: set a default assetId if not set
+ if (!self.assetId) self.assetId = 'pig';
// Asset id is passed in as self.assetId
var animalSprite = self.attachAsset(self.assetId, {
anchorX: 0.5,
anchorY: 0.5