/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var EscapedAnimal = Container.expand(function (animalType, habitatRef) {
var self = Container.call(this);
self.animalType = animalType;
self.habitat = habitatRef;
self.isDragging = false;
self.isEscaped = true;
var animalGraphics;
if (animalType === 'lion') {
animalGraphics = self.attachAsset('LionEscaped', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (animalType === 'elephant') {
animalGraphics = self.attachAsset('ElephantEscaped', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (animalType === 'zebra') {
animalGraphics = self.attachAsset('ZebraEscaped', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (animalType === 'penguin') {
animalGraphics = self.attachAsset('PenguinEscaped', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (animalType === 'monkey') {
animalGraphics = self.attachAsset('MonkeyEscaped', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (animalType === 'crocodile') {
animalGraphics = self.attachAsset('CrocodileEscaped', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (animalType === 'giraffe') {
animalGraphics = self.attachAsset('GiraffeEscaped', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (animalType === 'panda') {
animalGraphics = self.attachAsset('PandaEscaped', {
anchorX: 0.5,
anchorY: 0.5
});
}
// Random wandering movement
self.wanderDirection = Math.random() * Math.PI * 2;
self.wanderSpeed = 2;
self.wanderTimer = 0;
self.changeDirectionTime = 120; // Change direction every 2 seconds at 60fps
self.down = function (x, y, obj) {
self.isDragging = true;
tween.stop(self); // Stop any wandering animation
};
self.update = function () {
if (!self.isDragging && self.isEscaped) {
// Wandering behavior
self.wanderTimer++;
if (self.wanderTimer >= self.changeDirectionTime) {
self.wanderDirection = Math.random() * Math.PI * 2;
self.wanderTimer = 0;
}
var newX = self.x + Math.cos(self.wanderDirection) * self.wanderSpeed;
var newY = self.y + Math.sin(self.wanderDirection) * self.wanderSpeed;
// Keep within game bounds
if (newX > 50 && newX < 2048 - 50) {
self.x = newX;
}
if (newY > 50 && newY < 2732 - 50) {
self.y = newY;
}
}
};
return self;
});
var GridSystem = Container.expand(function () {
var self = Container.call(this);
self.gridWidth = 8;
self.gridHeight = 10;
self.cellSize = 200;
self.grid = [];
for (var y = 0; y < self.gridHeight; y++) {
self.grid[y] = [];
for (var x = 0; x < self.gridWidth; x++) {
self.grid[y][x] = null;
var gridSquare = self.addChild(LK.getAsset('gridSquare', {
anchorX: 0,
anchorY: 0
}));
gridSquare.x = x * self.cellSize + 200;
gridSquare.y = y * self.cellSize + 400;
gridSquare.alpha = 0.3;
}
}
// Add water features
var waterFeature1 = self.addChild(LK.getAsset('waterFeature', {
anchorX: 0,
anchorY: 0
}));
waterFeature1.x = 2 * self.cellSize + 200;
waterFeature1.y = 8 * self.cellSize + 400;
var waterFeature2 = self.addChild(LK.getAsset('waterFeature', {
anchorX: 0,
anchorY: 0
}));
waterFeature2.x = 5 * self.cellSize + 200;
waterFeature2.y = 8 * self.cellSize + 400;
self.canPlaceHabitat = function (habitat, gridX, gridY) {
if (gridX < 0 || gridY < 0 || gridX + habitat.gridSize > self.gridWidth || gridY + habitat.gridSize > self.gridHeight) {
return false;
}
for (var y = gridY; y < gridY + habitat.gridSize; y++) {
for (var x = gridX; x < gridX + habitat.gridSize; x++) {
if (self.grid[y][x] !== null) {
return false;
}
}
}
return true;
};
self.placeHabitat = function (habitat, gridX, gridY) {
if (!self.canPlaceHabitat(habitat, gridX, gridY)) {
return false;
}
for (var y = gridY; y < gridY + habitat.gridSize; y++) {
for (var x = gridX; x < gridX + habitat.gridSize; x++) {
self.grid[y][x] = habitat;
}
}
habitat.gridX = gridX;
habitat.gridY = gridY;
habitat.x = gridX * self.cellSize + 200;
habitat.y = gridY * self.cellSize + 400;
habitat.placed = true;
// Check for penguin water bonus
if (habitat.animalType === 'penguin') {
var nearWater = false;
if ((gridX === 1 || gridX === 2 || gridX === 3) && gridY === 7) nearWater = true;
if ((gridX === 4 || gridX === 5 || gridX === 6) && gridY === 7) nearWater = true;
if (nearWater) {
habitat.visitorPoints *= 1.5;
habitat.revenue *= 1.5;
LK.effects.flashObject(habitat, 0x00ff00, 1000);
}
}
visitorSatisfaction += habitat.visitorPoints;
updateUI();
LK.getSound('placeHabitat').play();
return true;
};
self.removeHabitat = function (habitat) {
if (!habitat.placed) return;
for (var y = habitat.gridY; y < habitat.gridY + habitat.gridSize; y++) {
for (var x = habitat.gridX; x < habitat.gridX + habitat.gridSize; x++) {
self.grid[y][x] = null;
}
}
visitorSatisfaction -= habitat.visitorPoints;
habitat.placed = false;
habitat.gridX = -1;
habitat.gridY = -1;
updateUI();
};
self.getGridPosition = function (worldX, worldY) {
var gridX = Math.floor((worldX - 200) / self.cellSize);
var gridY = Math.floor((worldY - 400) / self.cellSize);
return {
x: gridX,
y: gridY
};
};
return self;
});
var Habitat = Container.expand(function (animalType, size) {
var self = Container.call(this);
self.animalType = animalType;
self.gridSize = size;
self.visitorPoints = 0;
self.revenue = 0;
self.placed = false;
self.gridX = -1;
self.gridY = -1;
var habitatGraphics;
if (animalType === 'lion') {
habitatGraphics = self.attachAsset('lionHabitat', {
anchorX: 0,
anchorY: 0
});
self.visitorPoints = 10;
self.revenue = 5;
} else if (animalType === 'elephant') {
habitatGraphics = self.attachAsset('elephantHabitat', {
anchorX: 0,
anchorY: 0
});
self.visitorPoints = 25;
self.revenue = 15;
} else if (animalType === 'zebra') {
habitatGraphics = self.attachAsset('zebraHabitat', {
anchorX: 0,
anchorY: 0
});
self.visitorPoints = 8;
self.revenue = 4;
} else if (animalType === 'penguin') {
habitatGraphics = self.attachAsset('penguinHabitat', {
anchorX: 0,
anchorY: 0
});
self.visitorPoints = 12;
self.revenue = 7;
} else if (animalType === 'monkey') {
habitatGraphics = self.attachAsset('monkeyHabitat', {
anchorX: 0,
anchorY: 0
});
self.visitorPoints = 15;
self.revenue = 8;
} else if (animalType === 'crocodile') {
habitatGraphics = self.attachAsset('crocodileHabitat', {
anchorX: 0,
anchorY: 0
});
self.visitorPoints = 20;
self.revenue = 12;
} else if (animalType === 'giraffe') {
habitatGraphics = self.attachAsset('giraffeHabitat', {
anchorX: 0,
anchorY: 0
});
self.visitorPoints = 18;
self.revenue = 10;
} else if (animalType === 'panda') {
habitatGraphics = self.attachAsset('pandaHabitat', {
anchorX: 0,
anchorY: 0
});
self.visitorPoints = 30;
self.revenue = 18;
}
self.animalLabel = new Text2(animalType.toUpperCase(), {
size: 24,
fill: 0x000000
});
self.animalLabel.anchor.set(0.5, 0.5);
self.animalLabel.x = habitatGraphics.width / 2;
self.animalLabel.y = habitatGraphics.height / 2;
self.addChild(self.animalLabel);
self.lastRevenueTime = Date.now();
self.update = function () {
if (self.placed && Date.now() - self.lastRevenueTime > 3000) {
self.lastRevenueTime = Date.now();
var coinEffect = game.addChild(LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
}));
coinEffect.x = self.x + self.width / 2;
coinEffect.y = self.y + self.height / 2;
tween(coinEffect, {
y: coinEffect.y - 100,
alpha: 0
}, {
duration: 1000,
onFinish: function onFinish() {
coinEffect.destroy();
}
});
coins += self.revenue;
updateUI();
LK.getSound('collectCoin').play();
// Random chance for animal to escape (1% chance per revenue collection)
if (Math.random() < 0.01) {
var escapedAnimal = new EscapedAnimal(self.animalType, self);
// Position escaped animal near the habitat
escapedAnimal.x = self.x + self.width / 2 + (Math.random() - 0.5) * 200;
escapedAnimal.y = self.y + self.height / 2 + (Math.random() - 0.5) * 200;
game.addChild(escapedAnimal);
escapedAnimals.push(escapedAnimal);
// Flash habitat red to indicate escape
LK.effects.flashObject(self, 0xff0000, 1000);
// Play animal sound
if (self.animalType === 'lion') {
LK.getSound('lioncall').play();
} else if (self.animalType === 'elephant') {
LK.getSound('elephantcall').play();
} else if (self.animalType === 'zebra') {
LK.getSound('zebracall').play();
} else if (self.animalType === 'penguin') {
LK.getSound('penguincall').play();
} else if (self.animalType === 'monkey') {
LK.getSound('monkeycall').play();
} else if (self.animalType === 'crocodile') {
LK.getSound('crocodilecall').play();
} else if (self.animalType === 'giraffe') {
LK.getSound('giraffecall').play();
} else if (self.animalType === 'panda') {
LK.getSound('pandacall').play();
}
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb
});
/****
* Game Code
****/
var coins = 100;
var visitorSatisfaction = 0;
var targetSatisfaction = 200;
var selectedAnimalType = null;
var draggedHabitat = null;
var habitats = [];
var escapedAnimals = [];
var draggedEscapedAnimal = null;
var gridSystem = game.addChild(new GridSystem());
// UI Elements
var coinsText = new Text2('Coins: ' + coins, {
size: 40,
fill: 0xFFFFFF
});
coinsText.anchor.set(0, 0);
LK.gui.topRight.addChild(coinsText);
var satisfactionText = new Text2('Satisfaction: ' + visitorSatisfaction + '/' + targetSatisfaction, {
size: 40,
fill: 0xFFFFFF
});
satisfactionText.anchor.set(0.5, 0);
LK.gui.top.addChild(satisfactionText);
// Animal selection buttons
var buttonY = 150;
var buttonSpacing = 300;
var lionButton = LK.gui.bottomLeft.addChild(LK.getAsset('lionHabitat', {
anchorX: 0,
anchorY: 1,
scaleX: 0.8,
scaleY: 0.8
}));
lionButton.x = 100;
lionButton.y = -buttonY;
var elephantButton = LK.gui.bottomLeft.addChild(LK.getAsset('elephantHabitat', {
anchorX: 0,
anchorY: 1,
scaleX: 0.4,
scaleY: 0.4
}));
elephantButton.x = 100 + buttonSpacing;
elephantButton.y = -buttonY;
var zebraButton = LK.gui.bottomLeft.addChild(LK.getAsset('zebraHabitat', {
anchorX: 0,
anchorY: 1,
scaleX: 0.8,
scaleY: 0.8
}));
zebraButton.x = 100 + buttonSpacing * 2;
zebraButton.y = -buttonY;
var penguinButton = LK.gui.bottomLeft.addChild(LK.getAsset('penguinHabitat', {
anchorX: 0,
anchorY: 1,
scaleX: 0.8,
scaleY: 0.8
}));
penguinButton.x = 100 + buttonSpacing * 3;
penguinButton.y = -buttonY;
var monkeyButton = LK.gui.bottomLeft.addChild(LK.getAsset('monkeyHabitat', {
anchorX: 0,
anchorY: 1,
scaleX: 0.8,
scaleY: 0.8
}));
monkeyButton.x = 100;
monkeyButton.y = -buttonY - 200;
var crocodileButton = LK.gui.bottomLeft.addChild(LK.getAsset('crocodileHabitat', {
anchorX: 0,
anchorY: 1,
scaleX: 0.5,
scaleY: 0.8
}));
crocodileButton.x = 100 + buttonSpacing;
crocodileButton.y = -buttonY - 200;
var giraffeButton = LK.gui.bottomLeft.addChild(LK.getAsset('giraffeHabitat', {
anchorX: 0,
anchorY: 1,
scaleX: 0.8,
scaleY: 0.5
}));
giraffeButton.x = 100 + buttonSpacing * 2;
giraffeButton.y = -buttonY - 200;
var pandaButton = LK.gui.bottomLeft.addChild(LK.getAsset('pandaHabitat', {
anchorX: 0,
anchorY: 1,
scaleX: 0.7,
scaleY: 0.7
}));
pandaButton.x = 100 + buttonSpacing * 3;
pandaButton.y = -buttonY - 200;
// Button labels
var lionLabel = new Text2('LION\n$20', {
size: 20,
fill: 0x000000
});
lionLabel.anchor.set(0.5, 0.5);
lionLabel.x = lionButton.x + 75;
lionLabel.y = lionButton.y - 75;
LK.gui.bottomLeft.addChild(lionLabel);
var elephantLabel = new Text2('ELEPHANT\n$50', {
size: 20,
fill: 0x000000
});
elephantLabel.anchor.set(0.5, 0.5);
elephantLabel.x = elephantButton.x + 75;
elephantLabel.y = elephantButton.y - 75;
LK.gui.bottomLeft.addChild(elephantLabel);
var zebraLabel = new Text2('ZEBRA\n$15', {
size: 20,
fill: 0x000000
});
zebraLabel.anchor.set(0.5, 0.5);
zebraLabel.x = zebraButton.x + 75;
zebraLabel.y = zebraButton.y - 75;
LK.gui.bottomLeft.addChild(zebraLabel);
var penguinLabel = new Text2('PENGUIN\n$25', {
size: 20,
fill: 0x000000
});
penguinLabel.anchor.set(0.5, 0.5);
penguinLabel.x = penguinButton.x + 75;
penguinLabel.y = penguinButton.y - 75;
LK.gui.bottomLeft.addChild(penguinLabel);
var monkeyLabel = new Text2('MONKEY\n$30', {
size: 20,
fill: 0x000000
});
monkeyLabel.anchor.set(0.5, 0.5);
monkeyLabel.x = monkeyButton.x + 75;
monkeyLabel.y = monkeyButton.y - 75;
LK.gui.bottomLeft.addChild(monkeyLabel);
var crocodileLabel = new Text2('CROCODILE\n$40', {
size: 20,
fill: 0x000000
});
crocodileLabel.anchor.set(0.5, 0.5);
crocodileLabel.x = crocodileButton.x + 75;
crocodileLabel.y = crocodileButton.y - 75;
LK.gui.bottomLeft.addChild(crocodileLabel);
var giraffeLabel = new Text2('GIRAFFE\n$35', {
size: 20,
fill: 0x000000
});
giraffeLabel.anchor.set(0.5, 0.5);
giraffeLabel.x = giraffeButton.x + 75;
giraffeLabel.y = giraffeButton.y - 75;
LK.gui.bottomLeft.addChild(giraffeLabel);
var pandaLabel = new Text2('PANDA\n$60', {
size: 20,
fill: 0x000000
});
pandaLabel.anchor.set(0.5, 0.5);
pandaLabel.x = pandaButton.x + 75;
pandaLabel.y = pandaButton.y - 75;
LK.gui.bottomLeft.addChild(pandaLabel);
function updateUI() {
coinsText.setText('Coins: ' + coins);
satisfactionText.setText('Satisfaction: ' + visitorSatisfaction + '/' + targetSatisfaction);
if (visitorSatisfaction >= targetSatisfaction) {
LK.showYouWin();
}
}
function getAnimalCost(animalType) {
switch (animalType) {
case 'lion':
return 20;
case 'elephant':
return 50;
case 'zebra':
return 15;
case 'penguin':
return 25;
case 'monkey':
return 30;
case 'crocodile':
return 40;
case 'giraffe':
return 35;
case 'panda':
return 60;
default:
return 0;
}
}
function getAnimalSize(animalType) {
if (animalType === 'elephant') return 2;
if (animalType === 'crocodile') return {
width: 2,
height: 1
};
if (animalType === 'giraffe') return {
width: 1,
height: 2
};
if (animalType === 'panda') return {
width: 1.5,
height: 1.5
};
return 1;
}
function createHabitat(animalType) {
var cost = getAnimalCost(animalType);
if (coins < cost) return null;
coins -= cost;
updateUI();
var size = getAnimalSize(animalType);
var habitat = new Habitat(animalType, size);
habitats.push(habitat);
return habitat;
}
// Button event handlers
lionButton.down = function (x, y, obj) {
var habitat = createHabitat('lion');
if (habitat) {
draggedHabitat = habitat;
game.addChild(habitat);
var gamePos = game.toLocal({
x: lionButton.x + x,
y: lionButton.y + y
});
habitat.x = gamePos.x;
habitat.y = gamePos.y;
}
};
elephantButton.down = function (x, y, obj) {
var habitat = createHabitat('elephant');
if (habitat) {
draggedHabitat = habitat;
game.addChild(habitat);
var gamePos = game.toLocal({
x: elephantButton.x + x,
y: elephantButton.y + y
});
habitat.x = gamePos.x;
habitat.y = gamePos.y;
}
};
zebraButton.down = function (x, y, obj) {
var habitat = createHabitat('zebra');
if (habitat) {
draggedHabitat = habitat;
game.addChild(habitat);
var gamePos = game.toLocal({
x: zebraButton.x + x,
y: zebraButton.y + y
});
habitat.x = gamePos.x;
habitat.y = gamePos.y;
}
};
penguinButton.down = function (x, y, obj) {
var habitat = createHabitat('penguin');
if (habitat) {
draggedHabitat = habitat;
game.addChild(habitat);
var gamePos = game.toLocal({
x: penguinButton.x + x,
y: penguinButton.y + y
});
habitat.x = gamePos.x;
habitat.y = gamePos.y;
}
};
monkeyButton.down = function (x, y, obj) {
var habitat = createHabitat('monkey');
if (habitat) {
draggedHabitat = habitat;
game.addChild(habitat);
var gamePos = game.toLocal({
x: monkeyButton.x + x,
y: monkeyButton.y + y
});
habitat.x = gamePos.x;
habitat.y = gamePos.y;
}
};
crocodileButton.down = function (x, y, obj) {
var habitat = createHabitat('crocodile');
if (habitat) {
draggedHabitat = habitat;
game.addChild(habitat);
var gamePos = game.toLocal({
x: crocodileButton.x + x,
y: crocodileButton.y + y
});
habitat.x = gamePos.x;
habitat.y = gamePos.y;
}
};
giraffeButton.down = function (x, y, obj) {
var habitat = createHabitat('giraffe');
if (habitat) {
draggedHabitat = habitat;
game.addChild(habitat);
var gamePos = game.toLocal({
x: giraffeButton.x + x,
y: giraffeButton.y + y
});
habitat.x = gamePos.x;
habitat.y = gamePos.y;
}
};
pandaButton.down = function (x, y, obj) {
var habitat = createHabitat('panda');
if (habitat) {
draggedHabitat = habitat;
game.addChild(habitat);
var gamePos = game.toLocal({
x: pandaButton.x + x,
y: pandaButton.y + y
});
habitat.x = gamePos.x;
habitat.y = gamePos.y;
}
};
game.move = function (x, y, obj) {
if (draggedHabitat) {
draggedHabitat.x = x - draggedHabitat.width / 2;
draggedHabitat.y = y - draggedHabitat.height / 2;
}
if (draggedEscapedAnimal) {
draggedEscapedAnimal.x = x;
draggedEscapedAnimal.y = y;
}
};
game.up = function (x, y, obj) {
if (draggedHabitat) {
var gridPos = gridSystem.getGridPosition(x, y);
if (gridSystem.placeHabitat(draggedHabitat, gridPos.x, gridPos.y)) {
// Successfully placed
} else {
// Failed to place, remove habitat and refund
var cost = getAnimalCost(draggedHabitat.animalType);
coins += cost;
updateUI();
var habitatIndex = habitats.indexOf(draggedHabitat);
if (habitatIndex > -1) {
habitats.splice(habitatIndex, 1);
}
draggedHabitat.destroy();
}
draggedHabitat = null;
}
if (draggedEscapedAnimal) {
// Check if animal is returned to its habitat
var habitat = draggedEscapedAnimal.habitat;
var dx = x - (habitat.x + habitat.width / 2);
var dy = y - (habitat.y + habitat.height / 2);
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 100) {
// Within habitat range
// Successfully returned animal
LK.effects.flashObject(habitat, 0x00ff00, 1000);
coins += 10; // Reward for returning animal
updateUI();
LK.getSound('collectCoin').play();
// Remove escaped animal
var animalIndex = escapedAnimals.indexOf(draggedEscapedAnimal);
if (animalIndex > -1) {
escapedAnimals.splice(animalIndex, 1);
}
draggedEscapedAnimal.destroy();
} else {
// Animal not returned, continue wandering
draggedEscapedAnimal.isDragging = false;
}
draggedEscapedAnimal = null;
}
};
// Play ambient zoo music
LK.playMusic('ZooAmbient');
game.update = function () {
for (var i = 0; i < habitats.length; i++) {
habitats[i].update();
}
for (var j = 0; j < escapedAnimals.length; j++) {
escapedAnimals[j].update();
}
};
game.down = function (x, y, obj) {
// Check if we clicked on an escaped animal
for (var i = 0; i < escapedAnimals.length; i++) {
var animal = escapedAnimals[i];
var dx = x - animal.x;
var dy = y - animal.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 50) {
// Within touch range
draggedEscapedAnimal = animal;
animal.isDragging = true;
break;
}
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var EscapedAnimal = Container.expand(function (animalType, habitatRef) {
var self = Container.call(this);
self.animalType = animalType;
self.habitat = habitatRef;
self.isDragging = false;
self.isEscaped = true;
var animalGraphics;
if (animalType === 'lion') {
animalGraphics = self.attachAsset('LionEscaped', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (animalType === 'elephant') {
animalGraphics = self.attachAsset('ElephantEscaped', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (animalType === 'zebra') {
animalGraphics = self.attachAsset('ZebraEscaped', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (animalType === 'penguin') {
animalGraphics = self.attachAsset('PenguinEscaped', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (animalType === 'monkey') {
animalGraphics = self.attachAsset('MonkeyEscaped', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (animalType === 'crocodile') {
animalGraphics = self.attachAsset('CrocodileEscaped', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (animalType === 'giraffe') {
animalGraphics = self.attachAsset('GiraffeEscaped', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (animalType === 'panda') {
animalGraphics = self.attachAsset('PandaEscaped', {
anchorX: 0.5,
anchorY: 0.5
});
}
// Random wandering movement
self.wanderDirection = Math.random() * Math.PI * 2;
self.wanderSpeed = 2;
self.wanderTimer = 0;
self.changeDirectionTime = 120; // Change direction every 2 seconds at 60fps
self.down = function (x, y, obj) {
self.isDragging = true;
tween.stop(self); // Stop any wandering animation
};
self.update = function () {
if (!self.isDragging && self.isEscaped) {
// Wandering behavior
self.wanderTimer++;
if (self.wanderTimer >= self.changeDirectionTime) {
self.wanderDirection = Math.random() * Math.PI * 2;
self.wanderTimer = 0;
}
var newX = self.x + Math.cos(self.wanderDirection) * self.wanderSpeed;
var newY = self.y + Math.sin(self.wanderDirection) * self.wanderSpeed;
// Keep within game bounds
if (newX > 50 && newX < 2048 - 50) {
self.x = newX;
}
if (newY > 50 && newY < 2732 - 50) {
self.y = newY;
}
}
};
return self;
});
var GridSystem = Container.expand(function () {
var self = Container.call(this);
self.gridWidth = 8;
self.gridHeight = 10;
self.cellSize = 200;
self.grid = [];
for (var y = 0; y < self.gridHeight; y++) {
self.grid[y] = [];
for (var x = 0; x < self.gridWidth; x++) {
self.grid[y][x] = null;
var gridSquare = self.addChild(LK.getAsset('gridSquare', {
anchorX: 0,
anchorY: 0
}));
gridSquare.x = x * self.cellSize + 200;
gridSquare.y = y * self.cellSize + 400;
gridSquare.alpha = 0.3;
}
}
// Add water features
var waterFeature1 = self.addChild(LK.getAsset('waterFeature', {
anchorX: 0,
anchorY: 0
}));
waterFeature1.x = 2 * self.cellSize + 200;
waterFeature1.y = 8 * self.cellSize + 400;
var waterFeature2 = self.addChild(LK.getAsset('waterFeature', {
anchorX: 0,
anchorY: 0
}));
waterFeature2.x = 5 * self.cellSize + 200;
waterFeature2.y = 8 * self.cellSize + 400;
self.canPlaceHabitat = function (habitat, gridX, gridY) {
if (gridX < 0 || gridY < 0 || gridX + habitat.gridSize > self.gridWidth || gridY + habitat.gridSize > self.gridHeight) {
return false;
}
for (var y = gridY; y < gridY + habitat.gridSize; y++) {
for (var x = gridX; x < gridX + habitat.gridSize; x++) {
if (self.grid[y][x] !== null) {
return false;
}
}
}
return true;
};
self.placeHabitat = function (habitat, gridX, gridY) {
if (!self.canPlaceHabitat(habitat, gridX, gridY)) {
return false;
}
for (var y = gridY; y < gridY + habitat.gridSize; y++) {
for (var x = gridX; x < gridX + habitat.gridSize; x++) {
self.grid[y][x] = habitat;
}
}
habitat.gridX = gridX;
habitat.gridY = gridY;
habitat.x = gridX * self.cellSize + 200;
habitat.y = gridY * self.cellSize + 400;
habitat.placed = true;
// Check for penguin water bonus
if (habitat.animalType === 'penguin') {
var nearWater = false;
if ((gridX === 1 || gridX === 2 || gridX === 3) && gridY === 7) nearWater = true;
if ((gridX === 4 || gridX === 5 || gridX === 6) && gridY === 7) nearWater = true;
if (nearWater) {
habitat.visitorPoints *= 1.5;
habitat.revenue *= 1.5;
LK.effects.flashObject(habitat, 0x00ff00, 1000);
}
}
visitorSatisfaction += habitat.visitorPoints;
updateUI();
LK.getSound('placeHabitat').play();
return true;
};
self.removeHabitat = function (habitat) {
if (!habitat.placed) return;
for (var y = habitat.gridY; y < habitat.gridY + habitat.gridSize; y++) {
for (var x = habitat.gridX; x < habitat.gridX + habitat.gridSize; x++) {
self.grid[y][x] = null;
}
}
visitorSatisfaction -= habitat.visitorPoints;
habitat.placed = false;
habitat.gridX = -1;
habitat.gridY = -1;
updateUI();
};
self.getGridPosition = function (worldX, worldY) {
var gridX = Math.floor((worldX - 200) / self.cellSize);
var gridY = Math.floor((worldY - 400) / self.cellSize);
return {
x: gridX,
y: gridY
};
};
return self;
});
var Habitat = Container.expand(function (animalType, size) {
var self = Container.call(this);
self.animalType = animalType;
self.gridSize = size;
self.visitorPoints = 0;
self.revenue = 0;
self.placed = false;
self.gridX = -1;
self.gridY = -1;
var habitatGraphics;
if (animalType === 'lion') {
habitatGraphics = self.attachAsset('lionHabitat', {
anchorX: 0,
anchorY: 0
});
self.visitorPoints = 10;
self.revenue = 5;
} else if (animalType === 'elephant') {
habitatGraphics = self.attachAsset('elephantHabitat', {
anchorX: 0,
anchorY: 0
});
self.visitorPoints = 25;
self.revenue = 15;
} else if (animalType === 'zebra') {
habitatGraphics = self.attachAsset('zebraHabitat', {
anchorX: 0,
anchorY: 0
});
self.visitorPoints = 8;
self.revenue = 4;
} else if (animalType === 'penguin') {
habitatGraphics = self.attachAsset('penguinHabitat', {
anchorX: 0,
anchorY: 0
});
self.visitorPoints = 12;
self.revenue = 7;
} else if (animalType === 'monkey') {
habitatGraphics = self.attachAsset('monkeyHabitat', {
anchorX: 0,
anchorY: 0
});
self.visitorPoints = 15;
self.revenue = 8;
} else if (animalType === 'crocodile') {
habitatGraphics = self.attachAsset('crocodileHabitat', {
anchorX: 0,
anchorY: 0
});
self.visitorPoints = 20;
self.revenue = 12;
} else if (animalType === 'giraffe') {
habitatGraphics = self.attachAsset('giraffeHabitat', {
anchorX: 0,
anchorY: 0
});
self.visitorPoints = 18;
self.revenue = 10;
} else if (animalType === 'panda') {
habitatGraphics = self.attachAsset('pandaHabitat', {
anchorX: 0,
anchorY: 0
});
self.visitorPoints = 30;
self.revenue = 18;
}
self.animalLabel = new Text2(animalType.toUpperCase(), {
size: 24,
fill: 0x000000
});
self.animalLabel.anchor.set(0.5, 0.5);
self.animalLabel.x = habitatGraphics.width / 2;
self.animalLabel.y = habitatGraphics.height / 2;
self.addChild(self.animalLabel);
self.lastRevenueTime = Date.now();
self.update = function () {
if (self.placed && Date.now() - self.lastRevenueTime > 3000) {
self.lastRevenueTime = Date.now();
var coinEffect = game.addChild(LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
}));
coinEffect.x = self.x + self.width / 2;
coinEffect.y = self.y + self.height / 2;
tween(coinEffect, {
y: coinEffect.y - 100,
alpha: 0
}, {
duration: 1000,
onFinish: function onFinish() {
coinEffect.destroy();
}
});
coins += self.revenue;
updateUI();
LK.getSound('collectCoin').play();
// Random chance for animal to escape (1% chance per revenue collection)
if (Math.random() < 0.01) {
var escapedAnimal = new EscapedAnimal(self.animalType, self);
// Position escaped animal near the habitat
escapedAnimal.x = self.x + self.width / 2 + (Math.random() - 0.5) * 200;
escapedAnimal.y = self.y + self.height / 2 + (Math.random() - 0.5) * 200;
game.addChild(escapedAnimal);
escapedAnimals.push(escapedAnimal);
// Flash habitat red to indicate escape
LK.effects.flashObject(self, 0xff0000, 1000);
// Play animal sound
if (self.animalType === 'lion') {
LK.getSound('lioncall').play();
} else if (self.animalType === 'elephant') {
LK.getSound('elephantcall').play();
} else if (self.animalType === 'zebra') {
LK.getSound('zebracall').play();
} else if (self.animalType === 'penguin') {
LK.getSound('penguincall').play();
} else if (self.animalType === 'monkey') {
LK.getSound('monkeycall').play();
} else if (self.animalType === 'crocodile') {
LK.getSound('crocodilecall').play();
} else if (self.animalType === 'giraffe') {
LK.getSound('giraffecall').play();
} else if (self.animalType === 'panda') {
LK.getSound('pandacall').play();
}
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb
});
/****
* Game Code
****/
var coins = 100;
var visitorSatisfaction = 0;
var targetSatisfaction = 200;
var selectedAnimalType = null;
var draggedHabitat = null;
var habitats = [];
var escapedAnimals = [];
var draggedEscapedAnimal = null;
var gridSystem = game.addChild(new GridSystem());
// UI Elements
var coinsText = new Text2('Coins: ' + coins, {
size: 40,
fill: 0xFFFFFF
});
coinsText.anchor.set(0, 0);
LK.gui.topRight.addChild(coinsText);
var satisfactionText = new Text2('Satisfaction: ' + visitorSatisfaction + '/' + targetSatisfaction, {
size: 40,
fill: 0xFFFFFF
});
satisfactionText.anchor.set(0.5, 0);
LK.gui.top.addChild(satisfactionText);
// Animal selection buttons
var buttonY = 150;
var buttonSpacing = 300;
var lionButton = LK.gui.bottomLeft.addChild(LK.getAsset('lionHabitat', {
anchorX: 0,
anchorY: 1,
scaleX: 0.8,
scaleY: 0.8
}));
lionButton.x = 100;
lionButton.y = -buttonY;
var elephantButton = LK.gui.bottomLeft.addChild(LK.getAsset('elephantHabitat', {
anchorX: 0,
anchorY: 1,
scaleX: 0.4,
scaleY: 0.4
}));
elephantButton.x = 100 + buttonSpacing;
elephantButton.y = -buttonY;
var zebraButton = LK.gui.bottomLeft.addChild(LK.getAsset('zebraHabitat', {
anchorX: 0,
anchorY: 1,
scaleX: 0.8,
scaleY: 0.8
}));
zebraButton.x = 100 + buttonSpacing * 2;
zebraButton.y = -buttonY;
var penguinButton = LK.gui.bottomLeft.addChild(LK.getAsset('penguinHabitat', {
anchorX: 0,
anchorY: 1,
scaleX: 0.8,
scaleY: 0.8
}));
penguinButton.x = 100 + buttonSpacing * 3;
penguinButton.y = -buttonY;
var monkeyButton = LK.gui.bottomLeft.addChild(LK.getAsset('monkeyHabitat', {
anchorX: 0,
anchorY: 1,
scaleX: 0.8,
scaleY: 0.8
}));
monkeyButton.x = 100;
monkeyButton.y = -buttonY - 200;
var crocodileButton = LK.gui.bottomLeft.addChild(LK.getAsset('crocodileHabitat', {
anchorX: 0,
anchorY: 1,
scaleX: 0.5,
scaleY: 0.8
}));
crocodileButton.x = 100 + buttonSpacing;
crocodileButton.y = -buttonY - 200;
var giraffeButton = LK.gui.bottomLeft.addChild(LK.getAsset('giraffeHabitat', {
anchorX: 0,
anchorY: 1,
scaleX: 0.8,
scaleY: 0.5
}));
giraffeButton.x = 100 + buttonSpacing * 2;
giraffeButton.y = -buttonY - 200;
var pandaButton = LK.gui.bottomLeft.addChild(LK.getAsset('pandaHabitat', {
anchorX: 0,
anchorY: 1,
scaleX: 0.7,
scaleY: 0.7
}));
pandaButton.x = 100 + buttonSpacing * 3;
pandaButton.y = -buttonY - 200;
// Button labels
var lionLabel = new Text2('LION\n$20', {
size: 20,
fill: 0x000000
});
lionLabel.anchor.set(0.5, 0.5);
lionLabel.x = lionButton.x + 75;
lionLabel.y = lionButton.y - 75;
LK.gui.bottomLeft.addChild(lionLabel);
var elephantLabel = new Text2('ELEPHANT\n$50', {
size: 20,
fill: 0x000000
});
elephantLabel.anchor.set(0.5, 0.5);
elephantLabel.x = elephantButton.x + 75;
elephantLabel.y = elephantButton.y - 75;
LK.gui.bottomLeft.addChild(elephantLabel);
var zebraLabel = new Text2('ZEBRA\n$15', {
size: 20,
fill: 0x000000
});
zebraLabel.anchor.set(0.5, 0.5);
zebraLabel.x = zebraButton.x + 75;
zebraLabel.y = zebraButton.y - 75;
LK.gui.bottomLeft.addChild(zebraLabel);
var penguinLabel = new Text2('PENGUIN\n$25', {
size: 20,
fill: 0x000000
});
penguinLabel.anchor.set(0.5, 0.5);
penguinLabel.x = penguinButton.x + 75;
penguinLabel.y = penguinButton.y - 75;
LK.gui.bottomLeft.addChild(penguinLabel);
var monkeyLabel = new Text2('MONKEY\n$30', {
size: 20,
fill: 0x000000
});
monkeyLabel.anchor.set(0.5, 0.5);
monkeyLabel.x = monkeyButton.x + 75;
monkeyLabel.y = monkeyButton.y - 75;
LK.gui.bottomLeft.addChild(monkeyLabel);
var crocodileLabel = new Text2('CROCODILE\n$40', {
size: 20,
fill: 0x000000
});
crocodileLabel.anchor.set(0.5, 0.5);
crocodileLabel.x = crocodileButton.x + 75;
crocodileLabel.y = crocodileButton.y - 75;
LK.gui.bottomLeft.addChild(crocodileLabel);
var giraffeLabel = new Text2('GIRAFFE\n$35', {
size: 20,
fill: 0x000000
});
giraffeLabel.anchor.set(0.5, 0.5);
giraffeLabel.x = giraffeButton.x + 75;
giraffeLabel.y = giraffeButton.y - 75;
LK.gui.bottomLeft.addChild(giraffeLabel);
var pandaLabel = new Text2('PANDA\n$60', {
size: 20,
fill: 0x000000
});
pandaLabel.anchor.set(0.5, 0.5);
pandaLabel.x = pandaButton.x + 75;
pandaLabel.y = pandaButton.y - 75;
LK.gui.bottomLeft.addChild(pandaLabel);
function updateUI() {
coinsText.setText('Coins: ' + coins);
satisfactionText.setText('Satisfaction: ' + visitorSatisfaction + '/' + targetSatisfaction);
if (visitorSatisfaction >= targetSatisfaction) {
LK.showYouWin();
}
}
function getAnimalCost(animalType) {
switch (animalType) {
case 'lion':
return 20;
case 'elephant':
return 50;
case 'zebra':
return 15;
case 'penguin':
return 25;
case 'monkey':
return 30;
case 'crocodile':
return 40;
case 'giraffe':
return 35;
case 'panda':
return 60;
default:
return 0;
}
}
function getAnimalSize(animalType) {
if (animalType === 'elephant') return 2;
if (animalType === 'crocodile') return {
width: 2,
height: 1
};
if (animalType === 'giraffe') return {
width: 1,
height: 2
};
if (animalType === 'panda') return {
width: 1.5,
height: 1.5
};
return 1;
}
function createHabitat(animalType) {
var cost = getAnimalCost(animalType);
if (coins < cost) return null;
coins -= cost;
updateUI();
var size = getAnimalSize(animalType);
var habitat = new Habitat(animalType, size);
habitats.push(habitat);
return habitat;
}
// Button event handlers
lionButton.down = function (x, y, obj) {
var habitat = createHabitat('lion');
if (habitat) {
draggedHabitat = habitat;
game.addChild(habitat);
var gamePos = game.toLocal({
x: lionButton.x + x,
y: lionButton.y + y
});
habitat.x = gamePos.x;
habitat.y = gamePos.y;
}
};
elephantButton.down = function (x, y, obj) {
var habitat = createHabitat('elephant');
if (habitat) {
draggedHabitat = habitat;
game.addChild(habitat);
var gamePos = game.toLocal({
x: elephantButton.x + x,
y: elephantButton.y + y
});
habitat.x = gamePos.x;
habitat.y = gamePos.y;
}
};
zebraButton.down = function (x, y, obj) {
var habitat = createHabitat('zebra');
if (habitat) {
draggedHabitat = habitat;
game.addChild(habitat);
var gamePos = game.toLocal({
x: zebraButton.x + x,
y: zebraButton.y + y
});
habitat.x = gamePos.x;
habitat.y = gamePos.y;
}
};
penguinButton.down = function (x, y, obj) {
var habitat = createHabitat('penguin');
if (habitat) {
draggedHabitat = habitat;
game.addChild(habitat);
var gamePos = game.toLocal({
x: penguinButton.x + x,
y: penguinButton.y + y
});
habitat.x = gamePos.x;
habitat.y = gamePos.y;
}
};
monkeyButton.down = function (x, y, obj) {
var habitat = createHabitat('monkey');
if (habitat) {
draggedHabitat = habitat;
game.addChild(habitat);
var gamePos = game.toLocal({
x: monkeyButton.x + x,
y: monkeyButton.y + y
});
habitat.x = gamePos.x;
habitat.y = gamePos.y;
}
};
crocodileButton.down = function (x, y, obj) {
var habitat = createHabitat('crocodile');
if (habitat) {
draggedHabitat = habitat;
game.addChild(habitat);
var gamePos = game.toLocal({
x: crocodileButton.x + x,
y: crocodileButton.y + y
});
habitat.x = gamePos.x;
habitat.y = gamePos.y;
}
};
giraffeButton.down = function (x, y, obj) {
var habitat = createHabitat('giraffe');
if (habitat) {
draggedHabitat = habitat;
game.addChild(habitat);
var gamePos = game.toLocal({
x: giraffeButton.x + x,
y: giraffeButton.y + y
});
habitat.x = gamePos.x;
habitat.y = gamePos.y;
}
};
pandaButton.down = function (x, y, obj) {
var habitat = createHabitat('panda');
if (habitat) {
draggedHabitat = habitat;
game.addChild(habitat);
var gamePos = game.toLocal({
x: pandaButton.x + x,
y: pandaButton.y + y
});
habitat.x = gamePos.x;
habitat.y = gamePos.y;
}
};
game.move = function (x, y, obj) {
if (draggedHabitat) {
draggedHabitat.x = x - draggedHabitat.width / 2;
draggedHabitat.y = y - draggedHabitat.height / 2;
}
if (draggedEscapedAnimal) {
draggedEscapedAnimal.x = x;
draggedEscapedAnimal.y = y;
}
};
game.up = function (x, y, obj) {
if (draggedHabitat) {
var gridPos = gridSystem.getGridPosition(x, y);
if (gridSystem.placeHabitat(draggedHabitat, gridPos.x, gridPos.y)) {
// Successfully placed
} else {
// Failed to place, remove habitat and refund
var cost = getAnimalCost(draggedHabitat.animalType);
coins += cost;
updateUI();
var habitatIndex = habitats.indexOf(draggedHabitat);
if (habitatIndex > -1) {
habitats.splice(habitatIndex, 1);
}
draggedHabitat.destroy();
}
draggedHabitat = null;
}
if (draggedEscapedAnimal) {
// Check if animal is returned to its habitat
var habitat = draggedEscapedAnimal.habitat;
var dx = x - (habitat.x + habitat.width / 2);
var dy = y - (habitat.y + habitat.height / 2);
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 100) {
// Within habitat range
// Successfully returned animal
LK.effects.flashObject(habitat, 0x00ff00, 1000);
coins += 10; // Reward for returning animal
updateUI();
LK.getSound('collectCoin').play();
// Remove escaped animal
var animalIndex = escapedAnimals.indexOf(draggedEscapedAnimal);
if (animalIndex > -1) {
escapedAnimals.splice(animalIndex, 1);
}
draggedEscapedAnimal.destroy();
} else {
// Animal not returned, continue wandering
draggedEscapedAnimal.isDragging = false;
}
draggedEscapedAnimal = null;
}
};
// Play ambient zoo music
LK.playMusic('ZooAmbient');
game.update = function () {
for (var i = 0; i < habitats.length; i++) {
habitats[i].update();
}
for (var j = 0; j < escapedAnimals.length; j++) {
escapedAnimals[j].update();
}
};
game.down = function (x, y, obj) {
// Check if we clicked on an escaped animal
for (var i = 0; i < escapedAnimals.length; i++) {
var animal = escapedAnimals[i];
var dx = x - animal.x;
var dy = y - animal.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 50) {
// Within touch range
draggedEscapedAnimal = animal;
animal.isDragging = true;
break;
}
}
};
elephants in elephant enclosure. In-Game asset. 2d. High contrast. No shadows
sleeping lion in a lion enclosure, jungle styled. In-Game asset. 2d. High contrast. No shadows
snowy penguins in penguin exhibit. In-Game asset. 2d. High contrast. No shadows
plains zebra feeding wheat in zebra exhibit. In-Game asset. 2d. High contrast. No shadows
Elephant full body. In-Game asset. 2d. High contrast. No shadows
A masai Lion angry. In-Game asset. 2d. High contrast. No shadows
Bored Penguin holding ice cream. In-Game asset. 2d. High contrast. No shadows
A grey zebra eating a leaf. In-Game asset. 2d. High contrast. No shadows
A zoo exhibit of silly monkeys eating bananas on the bag. In-Game asset. 2d. High contrast. No shadows
A brown monkey eating a berry. In-Game asset. 2d. High contrast. No shadows
A giraffe exhibit. In-Game asset. 2d. High contrast. No shadows
A giraffe. In-Game asset. 2d. High contrast. No shadows
A swamp like zoo exhibit with a crocodile on top of a lily pad with a fish. In-Game asset. 2d. High contrast. No shadows
Bamboo zoo enclosure with two panda. In-Game asset. 2d. High contrast. No shadows
Angry crocodile holding a carp. In-Game asset. 2d. High contrast. No shadows
A panda. In-Game asset. 2d. High contrast. No shadows