/**** * 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
placeHabitat
Sound effect
collectCoin
Sound effect
ZooAmbient
Music
elephantcall
Sound effect
lioncall
Sound effect
penguincall
Sound effect
zebracall
Sound effect
EscapeWarning
Music
monkeycall
Sound effect
crocodilecall
Sound effect
giraffecall
Sound effect
pandacall
Sound effect