/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { bunnyAge: 0, bunnyStage: "baby", lastFed: 0, lastCleaned: 0, lastPlayed: 0, hunger: 100, happiness: 100, cleanliness: 100, health: 100 }); /**** * Classes ****/ var ActionButton = Container.expand(function (label, action) { var self = Container.call(this); self.action = action; // Create button background self.background = self.attachAsset('button', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 0 }); // Create button label self.label = new Text2(label, { size: 50, fill: 0xFFFFFF }); self.label.anchor.set(0.5, 0.5); self.addChild(self.label); // Make interactive self.down = function () { tween(self.background.scale, { x: 0.9, y: 0.9 }, { duration: 100, easing: tween.easeOut }); }; self.up = function () { tween(self.background.scale, { x: 1, y: 1 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { if (self.action && typeof self.action === 'function') { self.action(); } } }); }; return self; }); var BunnyPet = Container.expand(function () { var self = Container.call(this); // Create bunny body parts self.body = self.attachAsset('bunny', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 1 }); self.leftEar = self.attachAsset('ear', { anchorX: 0.5, anchorY: 1, x: -50, y: -40 }); self.rightEar = self.attachAsset('ear', { anchorX: 0.5, anchorY: 1, x: 50, y: -40 }); self.face = self.attachAsset('face', { anchorX: 0.5, anchorY: 0.5, y: 10 }); self.leftEye = self.attachAsset('eye', { anchorX: 0.5, anchorY: 0.5, x: -30, y: 0 }); self.rightEye = self.attachAsset('eye', { anchorX: 0.5, anchorY: 0.5, x: 30, y: 0 }); self.nose = self.attachAsset('nose', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 20 }); self.mouth = self.attachAsset('mouth', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 50 }); // Dirt spots (initially hidden) self.dirtSpots = []; for (var i = 0; i < 5; i++) { var dirt = self.attachAsset('dirty', { anchorX: 0.5, anchorY: 0.5, x: (Math.random() - 0.5) * 150, y: (Math.random() - 0.5) * 150, alpha: 0 }); self.dirtSpots.push(dirt); } // Growth stages self.setStage = function (stage) { var scale = 1; switch (stage) { case 'baby': scale = 0.7; self.leftEar.height = 80; self.rightEar.height = 80; self.leftEar.y = -30; self.rightEar.y = -30; break; case 'teen': scale = 0.85; self.leftEar.height = 100; self.rightEar.height = 100; self.leftEar.y = -35; self.rightEar.y = -35; break; case 'adult': scale = 1; self.leftEar.height = 120; self.rightEar.height = 120; self.leftEar.y = -40; self.rightEar.y = -40; break; } self.body.scale.set(scale); self.face.scale.set(scale); }; // Animate bunny idle self.animateIdle = function () { // Gentle breathing animation tween(self.body.scale, { x: 1.05, y: 0.95 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(self.body.scale, { x: 1, y: 1 }, { duration: 1000, easing: tween.easeInOut, onFinish: self.animateIdle }); } }); // Gentle ear movement tween(self.leftEar, { rotation: -0.1 }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { tween(self.leftEar, { rotation: 0 }, { duration: 2000, easing: tween.easeInOut }); } }); tween(self.rightEar, { rotation: 0.1 }, { duration: 2500, easing: tween.easeInOut, onFinish: function onFinish() { tween(self.rightEar, { rotation: 0 }, { duration: 2500, easing: tween.easeInOut }); } }); }; // Show happy expression self.showHappy = function () { tween.stop(self.mouth); tween(self.mouth.scale, { y: 1.5 }, { duration: 500, easing: tween.easeOut }); tween(self.leftEye.scale, { x: 1.2, y: 1.2 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { tween(self.leftEye.scale, { x: 1, y: 1 }, { duration: 300, easing: tween.easeIn }); } }); tween(self.rightEye.scale, { x: 1.2, y: 1.2 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { tween(self.rightEye.scale, { x: 1, y: 1 }, { duration: 300, easing: tween.easeIn, onFinish: function onFinish() { tween(self.mouth.scale, { y: 1 }, { duration: 500, easing: tween.easeOut }); } }); } }); }; // Show sad expression self.showSad = function () { tween.stop(self.mouth); tween(self.mouth.scale, { y: 0.5 }, { duration: 500, easing: tween.easeOut }); tween(self.leftEar, { rotation: -0.2 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { tween(self.leftEar, { rotation: 0 }, { duration: 1000, easing: tween.easeInOut }); } }); tween(self.rightEar, { rotation: 0.2 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { tween(self.rightEar, { rotation: 0 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(self.mouth.scale, { y: 1 }, { duration: 500, easing: tween.easeOut }); } }); } }); }; // Show dirty state self.showDirty = function (dirtLevel) { var visibleDirt = Math.floor((1 - dirtLevel / 100) * self.dirtSpots.length); for (var i = 0; i < self.dirtSpots.length; i++) { self.dirtSpots[i].alpha = i < visibleDirt ? 0.8 : 0; } }; // Animate eating self.animateEat = function () { tween(self.mouth.scale, { x: 1.5, y: 0.5 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { tween(self.mouth.scale, { x: 1, y: 1 }, { duration: 300, easing: tween.easeOut }); } }); }; // Animate play self.animatePlay = function () { tween(self, { rotation: 0.2 }, { duration: 300, easing: tween.bounceOut, onFinish: function onFinish() { tween(self, { rotation: -0.2 }, { duration: 300, easing: tween.bounceOut, onFinish: function onFinish() { tween(self, { rotation: 0 }, { duration: 300, easing: tween.easeOut }); } }); } }); }; // Initialize animation self.animateIdle(); return self; }); var Food = Container.expand(function () { var self = Container.call(this); self.graphic = self.attachAsset('food', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { self.y += 3; if (self.y > bunny.y + 50) { self.destroy(); var index = foods.indexOf(self); if (index !== -1) { foods.splice(index, 1); } } }; return self; }); var MiniGame = Container.expand(function () { var self = Container.call(this); self.isActive = false; self.score = 0; self.timeLeft = 30; self.carrots = []; // Create game background self.background = self.attachAsset('environment', { anchorX: 0.5, anchorY: 0.5, width: 1600, height: 1200, tint: 0xE8F7D6 }); // Create carrot catcher (player) self.player = new Container(); self.playerGraphic = self.player.attachAsset('bunny', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, scaleY: 0.6 }); self.player.x = 0; self.player.y = 400; self.addChild(self.player); // Timer text self.timerText = new Text2("Time: 30", { size: 60, fill: 0x333333 }); self.timerText.anchor.set(0.5, 0); self.timerText.x = 0; self.timerText.y = -500; self.addChild(self.timerText); // Score text self.scoreText = new Text2("Score: 0", { size: 60, fill: 0x333333 }); self.scoreText.anchor.set(0.5, 0); self.scoreText.x = 0; self.scoreText.y = -400; self.addChild(self.scoreText); // Create carrot asset self.createCarrot = function () { var carrot = new Container(); var carrotGraphic = carrot.attachAsset('food', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5 }); carrot.x = (Math.random() - 0.5) * 1400; carrot.y = -600; carrot.velocity = 3 + Math.random() * 5; carrot.update = function () { this.y += this.velocity; if (this.y > 600) { this.destroy(); var index = self.carrots.indexOf(this); if (index !== -1) { self.carrots.splice(index, 1); } } }; self.addChild(carrot); self.carrots.push(carrot); }; // Start game self.startGame = function () { self.isActive = true; self.score = 0; self.timeLeft = 30; self.updateUI(); // Clear any existing carrots for (var i = self.carrots.length - 1; i >= 0; i--) { self.carrots[i].destroy(); } self.carrots = []; // Hide main game elements toggleMainGameVisibility(false); // Position minigame self.x = 2048 / 2; self.y = 2732 / 2; }; // End game self.endGame = function () { self.isActive = false; // Calculate reward based on score var happinessBoost = Math.min(50, self.score); happiness = Math.min(100, happiness + happinessBoost); storage.happiness = happiness; // Award coins based on score var coinReward = Math.floor(self.score / 2); coins += coinReward; storage.coins = coins; coinsDisplay.setText("Coins: " + coins + " 🪙"); // Display coin reward var rewardText = new Text2("+" + coinReward + " 🪙", { size: 80, fill: 0xFFD700 }); rewardText.anchor.set(0.5, 0.5); rewardText.x = self.x; rewardText.y = self.y; game.addChild(rewardText); // Animate reward text tween(rewardText, { y: rewardText.y - 100, alpha: 0 }, { duration: 1500, easing: tween.easeOut, onFinish: function onFinish() { rewardText.destroy(); } }); // Clear any existing carrots for (var i = self.carrots.length - 1; i >= 0; i--) { self.carrots[i].destroy(); } self.carrots = []; // Show main game elements again toggleMainGameVisibility(true); }; // Update UI self.updateUI = function () { self.timerText.setText("Time: " + self.timeLeft); self.scoreText.setText("Score: " + self.score); }; // Player movement self.move = function (x, y, obj) { if (self.isActive) { var localX = x - self.x; self.player.x = Math.max(-700, Math.min(700, localX)); } }; // Check collisions self.checkCollisions = function () { for (var i = self.carrots.length - 1; i >= 0; i--) { var carrot = self.carrots[i]; if (self.player.x - 60 < carrot.x && self.player.x + 60 > carrot.x && self.player.y - 60 < carrot.y && self.player.y + 60 > carrot.y) { self.score++; carrot.destroy(); self.carrots.splice(i, 1); LK.getSound('eat').play(); self.updateUI(); } } }; // Game update self.update = function () { if (self.isActive) { // Spawn carrots if (LK.ticks % 30 === 0) { self.createCarrot(); } // Update carrots for (var i = 0; i < self.carrots.length; i++) { self.carrots[i].update(); } // Check collisions self.checkCollisions(); // Update timer if (LK.ticks % 60 === 0) { self.timeLeft--; self.updateUI(); if (self.timeLeft <= 0) { self.endGame(); } } } }; // Set initial visibility to false self.visible = false; return self; }); var ProgressBar = Container.expand(function (name, color) { var self = Container.call(this); self.name = name || "Progress"; self.barColor = color || 0x83de44; // Create label self.label = new Text2(self.name, { size: 40, fill: 0x333333 }); self.label.anchor.set(0, 0.5); self.addChild(self.label); // Create background bar self.background = self.attachAsset('progressBar', { anchorX: 0, anchorY: 0.5, x: 150, y: 0 }); // Create fill bar self.fill = self.attachAsset('progressFill', { anchorX: 0, anchorY: 0.5, x: 150, y: 0, tint: self.barColor }); // Set value between 0-100 self.setValue = function (value) { var clampedValue = Math.max(0, Math.min(100, value)); var fillWidth = clampedValue / 100 * self.background.width; self.fill.width = fillWidth; // Change color based on value if (clampedValue < 30) { self.fill.tint = 0xFF0000; // Red when low } else if (clampedValue < 60) { self.fill.tint = 0xFFCC00; // Yellow when medium } else { self.fill.tint = self.barColor; // Normal color when high } }; return self; }); var Shop = Container.expand(function () { var self = Container.call(this); self.isOpen = false; // Create shop background self.background = self.attachAsset('environment', { anchorX: 0.5, anchorY: 0.5, width: 1800, height: 2000, tint: 0xFFF8E1 }); // Shop title self.title = new Text2("Bunny Shop", { size: 80, fill: 0x333333 }); self.title.anchor.set(0.5, 0); self.title.x = 0; self.title.y = -800; self.addChild(self.title); // Create coins display self.coinsText = new Text2("Coins: 0", { size: 60, fill: 0x333333 }); self.coinsText.anchor.set(0.5, 0); self.coinsText.x = 0; self.coinsText.y = -700; self.addChild(self.coinsText); // Shop items (containers for each item) self.items = []; // Item types and data self.itemData = [{ name: "Premium Food", price: 20, description: "Increases hunger +40", type: "food", bonusValue: 40, color: 0xFF9900 }, { name: "Luxury Toy", price: 30, description: "Increases happiness +40", type: "toy", bonusValue: 40, color: 0x5555FF }, { name: "Premium Soap", price: 25, description: "Increases cleanliness +40", type: "soap", bonusValue: 40, color: 0x00FFFF }, { name: "Health Potion", price: 50, description: "Increases all stats +20", type: "health", bonusValue: 20, color: 0xFF5555 }]; // Create shop items self.createItems = function () { // Clear existing items first for (var i = 0; i < self.items.length; i++) { self.items[i].destroy(); } self.items = []; // Create new items for (var i = 0; i < self.itemData.length; i++) { var item = new Container(); var itemData = self.itemData[i]; // Item background var itemBg = item.attachAsset('button', { anchorX: 0.5, anchorY: 0.5, width: 1200, height: 220, tint: 0xFFFFFF }); // Item icon var icon = item.attachAsset(itemData.type === "health" ? "progressFill" : itemData.type, { anchorX: 0.5, anchorY: 0.5, x: -450, y: 0, tint: itemData.color, scaleX: 1.5, scaleY: 1.5 }); // Item name var nameText = new Text2(itemData.name, { size: 50, fill: 0x333333 }); nameText.anchor.set(0, 0.5); nameText.x = -350; nameText.y = -40; item.addChild(nameText); // Item description var descText = new Text2(itemData.description, { size: 40, fill: 0x666666 }); descText.anchor.set(0, 0.5); descText.x = -350; descText.y = 30; item.addChild(descText); // Price button var priceButton = item.attachAsset('button', { anchorX: 0.5, anchorY: 0.5, x: 400, y: 0, width: 200, height: 100, tint: 0x83de44 }); // Price text var priceText = new Text2(itemData.price + " 🪙", { size: 45, fill: 0xFFFFFF }); priceText.anchor.set(0.5, 0.5); priceText.x = 400; priceText.y = 0; item.addChild(priceText); // Position item item.y = -500 + i * 300; item.itemData = itemData; item.priceButton = priceButton; // Add interaction to buy button item.interactive = true; item.down = function (x, y, obj) { var localItem = this; var localX = x - localItem.x; var localY = y - localItem.y; // Check if click is on the price button if (Math.abs(localX - 400) < 100 && Math.abs(localY) < 50) { self.buyItem(localItem.itemData); } }; self.addChild(item); self.items.push(item); } }; // Buy item functionality self.buyItem = function (itemData) { if (coins >= itemData.price) { // Deduct coins coins -= itemData.price; storage.coins = coins; self.updateCoinsDisplay(); // Apply item effects switch (itemData.type) { case "food": hunger = Math.min(100, hunger + itemData.bonusValue); storage.hunger = hunger; // Create premium food effect var food = new Food(); food.x = bunny.x; food.y = bunny.y - 300; food.graphic.tint = itemData.color; food.graphic.scale.set(1.5); game.addChild(food); foods.push(food); LK.getSound('eat').play(); break; case "toy": happiness = Math.min(100, happiness + itemData.bonusValue); storage.happiness = happiness; // Create premium toy effect var toy = new Toy(); toy.x = bunny.x + (Math.random() - 0.5) * 200; toy.y = bunny.y - 100; toy.graphic.tint = itemData.color; toy.graphic.scale.set(1.5); game.addChild(toy); toys.push(toy); LK.getSound('play').play(); bunny.animatePlay(); break; case "soap": cleanliness = Math.min(100, cleanliness + itemData.bonusValue); storage.cleanliness = cleanliness; // Create premium soap effect for (var i = 0; i < 3; i++) { var soap = new Soap(); soap.x = bunny.x + (Math.random() - 0.5) * 150; soap.y = bunny.y + (Math.random() - 0.5) * 150; soap.graphic.tint = itemData.color; soap.graphic.scale.set(1.5); game.addChild(soap); soaps.push(soap); } LK.getSound('clean').play(); break; case "health": hunger = Math.min(100, hunger + itemData.bonusValue); happiness = Math.min(100, happiness + itemData.bonusValue); cleanliness = Math.min(100, cleanliness + itemData.bonusValue); health = Math.min(100, health + itemData.bonusValue); storage.hunger = hunger; storage.happiness = happiness; storage.cleanliness = cleanliness; storage.health = health; LK.effects.flashObject(bunny, 0xFF5555, 1000); break; } // Flash item button to indicate successful purchase tween(itemData.button, { tint: 0xFFFF00 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(itemData.button, { tint: 0x83de44 }, { duration: 200, easing: tween.easeOut }); } }); } else { // Not enough coins - flash the coins text tween(self.coinsText, { tint: 0xFF0000 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(self.coinsText, { tint: 0xFFFFFF }, { duration: 200, easing: tween.easeOut }); } }); } }; // Close button self.closeButton = new ActionButton("Close", function () { self.closeShop(); }); self.closeButton.x = 0; self.closeButton.y = 800; self.addChild(self.closeButton); // Update coins display self.updateCoinsDisplay = function () { self.coinsText.setText("Coins: " + coins + " 🪙"); }; // Open shop self.openShop = function () { self.isOpen = true; self.visible = true; self.createItems(); self.updateCoinsDisplay(); // Position shop self.x = 2048 / 2; self.y = 2732 / 2; // Hide main game elements toggleMainGameVisibility(false); }; // Close shop self.closeShop = function () { self.isOpen = false; self.visible = false; // Show main game elements again toggleMainGameVisibility(true); }; // Set initial visibility to false self.visible = false; return self; }); var Soap = Container.expand(function () { var self = Container.call(this); self.graphic = self.attachAsset('soap', { anchorX: 0.5, anchorY: 0.5 }); self.lifetime = 30; // Frames before disappearing self.update = function () { self.lifetime--; self.alpha = self.lifetime / 30; if (self.lifetime <= 0) { self.destroy(); var index = soaps.indexOf(self); if (index !== -1) { soaps.splice(index, 1); } } }; return self; }); var Toy = Container.expand(function () { var self = Container.call(this); self.graphic = self.attachAsset('toy', { anchorX: 0.5, anchorY: 0.5 }); self.velocity = { x: (Math.random() - 0.5) * 10, y: -10 }; self.rotation = Math.random() * Math.PI * 2; self.rotationSpeed = (Math.random() - 0.5) * 0.2; self.update = function () { self.velocity.y += 0.5; // Gravity self.x += self.velocity.x; self.y += self.velocity.y; self.rotation += self.rotationSpeed; // Bounce off walls if (self.x < 0 || self.x > 2048) { self.velocity.x *= -0.8; if (self.x < 0) { self.x = 0; } if (self.x > 2048) { self.x = 2048; } } // Remove when below screen if (self.y > 2732) { self.destroy(); var index = toys.indexOf(self); if (index !== -1) { toys.splice(index, 1); } } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xF0F9FF }); /**** * Game Code ****/ // Play background music LK.playMusic('bgmusic'); // Game state variables var bunnyAge = storage.bunnyAge; var bunnyStage = storage.bunnyStage; var lastFed = storage.lastFed; var lastCleaned = storage.lastCleaned; var lastPlayed = storage.lastPlayed; var hunger = storage.hunger; var happiness = storage.happiness; var cleanliness = storage.cleanliness; var health = storage.health; var coins = storage.coins || 50; // Initialize with 50 coins if not existing var foods = []; var toys = []; var soaps = []; var gameActive = true; // Get current timestamp function getCurrentTime() { return Date.now(); } // Create environment var environment = game.addChild(LK.getAsset('environment', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, width: 1800, height: 1500 })); // Create bunny var bunny = game.addChild(new BunnyPet()); bunny.x = 2048 / 2; bunny.y = 2732 / 2; bunny.setStage(bunnyStage); // Create status bars var statusContainer = new Container(); statusContainer.x = 150; statusContainer.y = 200; game.addChild(statusContainer); var hungerBar = new ProgressBar("Hunger", 0x83de44); hungerBar.y = 0; statusContainer.addChild(hungerBar); var happinessBar = new ProgressBar("Happiness", 0xFFD700); happinessBar.y = 80; statusContainer.addChild(happinessBar); var cleanlinessBar = new ProgressBar("Cleanliness", 0x00AAFF); cleanlinessBar.y = 160; statusContainer.addChild(cleanlinessBar); var healthBar = new ProgressBar("Health", 0xFF5555); healthBar.y = 240; statusContainer.addChild(healthBar); // Create minigame instance var minigame = new MiniGame(); game.addChild(minigame); minigame.visible = false; // Create shop instance var shop = new Shop(); game.addChild(shop); shop.visible = false; // Function to toggle main game elements visibility function toggleMainGameVisibility(visible) { environment.visible = visible; bunny.visible = visible; statusContainer.visible = visible; buttonContainer.visible = visible; ageText.visible = visible; stageText.visible = visible; coinsDisplay.visible = visible; minigame.visible = !visible && minigame.isActive; shop.visible = !visible && shop.isOpen; } // Create action buttons var buttonContainer = new Container(); buttonContainer.x = 2048 / 2; buttonContainer.y = 2732 - 300; game.addChild(buttonContainer); // Create coins display var coinsDisplay = new Text2("Coins: 0 🪙", { size: 50, fill: 0xFFD700 }); coinsDisplay.anchor.set(1, 0); coinsDisplay.x = 2048 - 50; coinsDisplay.y = 50; game.addChild(coinsDisplay); coinsDisplay.setText("Coins: " + coins + " 🪙"); var feedButton = new ActionButton("Feed", function () { // Create food var food = new Food(); food.x = bunny.x; food.y = bunny.y - 300; game.addChild(food); foods.push(food); // Play sound LK.getSound('eat').play(); // Update last fed time lastFed = getCurrentTime(); storage.lastFed = lastFed; // Increase hunger stat hunger = Math.min(100, hunger + 20); storage.hunger = hunger; }); feedButton.x = -350; buttonContainer.addChild(feedButton); var playButton = new ActionButton("Play", function () { // Create toy var toy = new Toy(); toy.x = bunny.x + (Math.random() - 0.5) * 200; toy.y = bunny.y - 100; game.addChild(toy); toys.push(toy); // Play sound LK.getSound('play').play(); // Update last played time lastPlayed = getCurrentTime(); storage.lastPlayed = lastPlayed; // Bunny play animation bunny.animatePlay(); // Increase happiness stat happiness = Math.min(100, happiness + 20); storage.happiness = happiness; }); playButton.x = 0; buttonContainer.addChild(playButton); var cleanButton = new ActionButton("Clean", function () { // Create cleaning effect var soap = new Soap(); soap.x = bunny.x + (Math.random() - 0.5) * 150; soap.y = bunny.y + (Math.random() - 0.5) * 150; game.addChild(soap); soaps.push(soap); // Play sound LK.getSound('clean').play(); // Update last cleaned time lastCleaned = getCurrentTime(); storage.lastCleaned = lastCleaned; // Increase cleanliness stat cleanliness = Math.min(100, cleanliness + 20); storage.cleanliness = cleanliness; }); cleanButton.x = 350; buttonContainer.addChild(cleanButton); var minigameButton = new ActionButton("Mini Game", function () { // Start the minigame minigame.startGame(); }); minigameButton.x = -175; minigameButton.y = 120; buttonContainer.addChild(minigameButton); var shopButton = new ActionButton("Shop", function () { // Open the shop shop.openShop(); }); shopButton.x = 175; shopButton.y = 120; buttonContainer.addChild(shopButton); // Create age display var ageText = new Text2("Age: 0 days", { size: 60, fill: 0x333333 }); ageText.anchor.set(0.5, 0); ageText.x = 2048 / 2; ageText.y = 80; game.addChild(ageText); // Create stage display var stageText = new Text2("Baby Bunny", { size: 70, fill: 0x83DE44 }); stageText.anchor.set(0.5, 0); stageText.x = 2048 / 2; stageText.y = 150; game.addChild(stageText); // Function to check for level up function checkLevelUp() { var newStage = bunnyStage; if (bunnyAge >= 10 && bunnyStage === 'baby') { newStage = 'teen'; LK.getSound('levelUp').play(); LK.effects.flashScreen(0x83de44, 1000); stageText.setText("Teen Bunny"); } else if (bunnyAge >= 20 && bunnyStage === 'teen') { newStage = 'adult'; LK.getSound('levelUp').play(); LK.effects.flashScreen(0x83de44, 1000); stageText.setText("Adult Bunny"); } if (newStage !== bunnyStage) { bunnyStage = newStage; storage.bunnyStage = bunnyStage; bunny.setStage(bunnyStage); // Show happy expression bunny.showHappy(); } } // Decay timer - decreases stats over time var lastDecayTime = getCurrentTime(); var dayCounter = getCurrentTime(); function updateStats() { var currentTime = getCurrentTime(); // Decay every 3 seconds if (currentTime - lastDecayTime > 3000) { // Decay stats hunger = Math.max(0, hunger - 2); happiness = Math.max(0, happiness - 1); cleanliness = Math.max(0, cleanliness - 1.5); // Update health based on other stats var avgStats = (hunger + happiness + cleanliness) / 3; health = avgStats; // Update storage storage.hunger = hunger; storage.happiness = happiness; storage.cleanliness = cleanliness; storage.health = health; lastDecayTime = currentTime; } // Age counter - increase age every "day" (30 seconds in this demo) if (currentTime - dayCounter > 30000) { bunnyAge++; storage.bunnyAge = bunnyAge; ageText.setText("Age: " + bunnyAge + " days"); dayCounter = currentTime; // Check for level up checkLevelUp(); } // Update UI hungerBar.setValue(hunger); happinessBar.setValue(happiness); cleanlinessBar.setValue(cleanliness); healthBar.setValue(health); // Show bunny's dirty state bunny.showDirty(cleanliness); // Update bunny mood if (health < 30) { bunny.showSad(); } else if (health > 70 && (happiness > 70 || hunger > 70)) { bunny.showHappy(); } } // Initial UI update ageText.setText("Age: " + bunnyAge + " days"); switch (bunnyStage) { case 'baby': stageText.setText("Baby Bunny"); break; case 'teen': stageText.setText("Teen Bunny"); break; case 'adult': stageText.setText("Adult Bunny"); break; } hungerBar.setValue(hunger); happinessBar.setValue(happiness); cleanlinessBar.setValue(cleanliness); healthBar.setValue(health); // Handle interaction var dragTarget = null; game.down = function (x, y, obj) { // Only allow dragging the bunny if (bunny.intersects({ x: x, y: y, width: 1, height: 1 })) { dragTarget = bunny; } }; game.move = function (x, y, obj) { // If minigame is active, pass movement to it if (minigame.isActive) { minigame.move(x, y, obj); return; } // If shop is open, handle shop interactions if (shop.isOpen) { return; } if (dragTarget) { dragTarget.x = x; dragTarget.y = y; // Keep bunny within environment boundaries var envBounds = { left: environment.x - environment.width / 2 + 100, right: environment.x + environment.width / 2 - 100, top: environment.y - environment.height / 2 + 100, bottom: environment.y + environment.height / 2 - 100 }; dragTarget.x = Math.max(envBounds.left, Math.min(envBounds.right, dragTarget.x)); dragTarget.y = Math.max(envBounds.top, Math.min(envBounds.bottom, dragTarget.y)); } }; game.up = function (x, y, obj) { dragTarget = null; }; // Handle collision between bunny and objects function checkCollisions() { // Check food collisions for (var i = foods.length - 1; i >= 0; i--) { if (bunny.intersects(foods[i])) { bunny.animateEat(); foods[i].destroy(); foods.splice(i, 1); } } // Check toy collisions for (var j = toys.length - 1; j >= 0; j--) { if (bunny.intersects(toys[j])) { bunny.animatePlay(); toys[j].destroy(); toys.splice(j, 1); } } } // Game update loop game.update = function () { // Update minigame if active if (minigame.isActive) { minigame.update(); return; } // Skip updates if shop is open if (shop.isOpen) { return; } // Update game objects for (var i = 0; i < foods.length; i++) { foods[i].update(); } for (var j = 0; j < toys.length; j++) { toys[j].update(); } for (var k = 0; k < soaps.length; k++) { soaps[k].update(); } // Check collisions checkCollisions(); // Update stats updateStats(); // Add coins periodically (every 5 seconds) if (LK.ticks % 300 === 0) { coins++; storage.coins = coins; coinsDisplay.setText("Coins: " + coins + " 🪙"); } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
bunnyAge: 0,
bunnyStage: "baby",
lastFed: 0,
lastCleaned: 0,
lastPlayed: 0,
hunger: 100,
happiness: 100,
cleanliness: 100,
health: 100
});
/****
* Classes
****/
var ActionButton = Container.expand(function (label, action) {
var self = Container.call(this);
self.action = action;
// Create button background
self.background = self.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 0
});
// Create button label
self.label = new Text2(label, {
size: 50,
fill: 0xFFFFFF
});
self.label.anchor.set(0.5, 0.5);
self.addChild(self.label);
// Make interactive
self.down = function () {
tween(self.background.scale, {
x: 0.9,
y: 0.9
}, {
duration: 100,
easing: tween.easeOut
});
};
self.up = function () {
tween(self.background.scale, {
x: 1,
y: 1
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
if (self.action && typeof self.action === 'function') {
self.action();
}
}
});
};
return self;
});
var BunnyPet = Container.expand(function () {
var self = Container.call(this);
// Create bunny body parts
self.body = self.attachAsset('bunny', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1,
scaleY: 1
});
self.leftEar = self.attachAsset('ear', {
anchorX: 0.5,
anchorY: 1,
x: -50,
y: -40
});
self.rightEar = self.attachAsset('ear', {
anchorX: 0.5,
anchorY: 1,
x: 50,
y: -40
});
self.face = self.attachAsset('face', {
anchorX: 0.5,
anchorY: 0.5,
y: 10
});
self.leftEye = self.attachAsset('eye', {
anchorX: 0.5,
anchorY: 0.5,
x: -30,
y: 0
});
self.rightEye = self.attachAsset('eye', {
anchorX: 0.5,
anchorY: 0.5,
x: 30,
y: 0
});
self.nose = self.attachAsset('nose', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 20
});
self.mouth = self.attachAsset('mouth', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 50
});
// Dirt spots (initially hidden)
self.dirtSpots = [];
for (var i = 0; i < 5; i++) {
var dirt = self.attachAsset('dirty', {
anchorX: 0.5,
anchorY: 0.5,
x: (Math.random() - 0.5) * 150,
y: (Math.random() - 0.5) * 150,
alpha: 0
});
self.dirtSpots.push(dirt);
}
// Growth stages
self.setStage = function (stage) {
var scale = 1;
switch (stage) {
case 'baby':
scale = 0.7;
self.leftEar.height = 80;
self.rightEar.height = 80;
self.leftEar.y = -30;
self.rightEar.y = -30;
break;
case 'teen':
scale = 0.85;
self.leftEar.height = 100;
self.rightEar.height = 100;
self.leftEar.y = -35;
self.rightEar.y = -35;
break;
case 'adult':
scale = 1;
self.leftEar.height = 120;
self.rightEar.height = 120;
self.leftEar.y = -40;
self.rightEar.y = -40;
break;
}
self.body.scale.set(scale);
self.face.scale.set(scale);
};
// Animate bunny idle
self.animateIdle = function () {
// Gentle breathing animation
tween(self.body.scale, {
x: 1.05,
y: 0.95
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self.body.scale, {
x: 1,
y: 1
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: self.animateIdle
});
}
});
// Gentle ear movement
tween(self.leftEar, {
rotation: -0.1
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self.leftEar, {
rotation: 0
}, {
duration: 2000,
easing: tween.easeInOut
});
}
});
tween(self.rightEar, {
rotation: 0.1
}, {
duration: 2500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self.rightEar, {
rotation: 0
}, {
duration: 2500,
easing: tween.easeInOut
});
}
});
};
// Show happy expression
self.showHappy = function () {
tween.stop(self.mouth);
tween(self.mouth.scale, {
y: 1.5
}, {
duration: 500,
easing: tween.easeOut
});
tween(self.leftEye.scale, {
x: 1.2,
y: 1.2
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self.leftEye.scale, {
x: 1,
y: 1
}, {
duration: 300,
easing: tween.easeIn
});
}
});
tween(self.rightEye.scale, {
x: 1.2,
y: 1.2
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self.rightEye.scale, {
x: 1,
y: 1
}, {
duration: 300,
easing: tween.easeIn,
onFinish: function onFinish() {
tween(self.mouth.scale, {
y: 1
}, {
duration: 500,
easing: tween.easeOut
});
}
});
}
});
};
// Show sad expression
self.showSad = function () {
tween.stop(self.mouth);
tween(self.mouth.scale, {
y: 0.5
}, {
duration: 500,
easing: tween.easeOut
});
tween(self.leftEar, {
rotation: -0.2
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self.leftEar, {
rotation: 0
}, {
duration: 1000,
easing: tween.easeInOut
});
}
});
tween(self.rightEar, {
rotation: 0.2
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self.rightEar, {
rotation: 0
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self.mouth.scale, {
y: 1
}, {
duration: 500,
easing: tween.easeOut
});
}
});
}
});
};
// Show dirty state
self.showDirty = function (dirtLevel) {
var visibleDirt = Math.floor((1 - dirtLevel / 100) * self.dirtSpots.length);
for (var i = 0; i < self.dirtSpots.length; i++) {
self.dirtSpots[i].alpha = i < visibleDirt ? 0.8 : 0;
}
};
// Animate eating
self.animateEat = function () {
tween(self.mouth.scale, {
x: 1.5,
y: 0.5
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self.mouth.scale, {
x: 1,
y: 1
}, {
duration: 300,
easing: tween.easeOut
});
}
});
};
// Animate play
self.animatePlay = function () {
tween(self, {
rotation: 0.2
}, {
duration: 300,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(self, {
rotation: -0.2
}, {
duration: 300,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(self, {
rotation: 0
}, {
duration: 300,
easing: tween.easeOut
});
}
});
}
});
};
// Initialize animation
self.animateIdle();
return self;
});
var Food = Container.expand(function () {
var self = Container.call(this);
self.graphic = self.attachAsset('food', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
self.y += 3;
if (self.y > bunny.y + 50) {
self.destroy();
var index = foods.indexOf(self);
if (index !== -1) {
foods.splice(index, 1);
}
}
};
return self;
});
var MiniGame = Container.expand(function () {
var self = Container.call(this);
self.isActive = false;
self.score = 0;
self.timeLeft = 30;
self.carrots = [];
// Create game background
self.background = self.attachAsset('environment', {
anchorX: 0.5,
anchorY: 0.5,
width: 1600,
height: 1200,
tint: 0xE8F7D6
});
// Create carrot catcher (player)
self.player = new Container();
self.playerGraphic = self.player.attachAsset('bunny', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.6
});
self.player.x = 0;
self.player.y = 400;
self.addChild(self.player);
// Timer text
self.timerText = new Text2("Time: 30", {
size: 60,
fill: 0x333333
});
self.timerText.anchor.set(0.5, 0);
self.timerText.x = 0;
self.timerText.y = -500;
self.addChild(self.timerText);
// Score text
self.scoreText = new Text2("Score: 0", {
size: 60,
fill: 0x333333
});
self.scoreText.anchor.set(0.5, 0);
self.scoreText.x = 0;
self.scoreText.y = -400;
self.addChild(self.scoreText);
// Create carrot asset
self.createCarrot = function () {
var carrot = new Container();
var carrotGraphic = carrot.attachAsset('food', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
carrot.x = (Math.random() - 0.5) * 1400;
carrot.y = -600;
carrot.velocity = 3 + Math.random() * 5;
carrot.update = function () {
this.y += this.velocity;
if (this.y > 600) {
this.destroy();
var index = self.carrots.indexOf(this);
if (index !== -1) {
self.carrots.splice(index, 1);
}
}
};
self.addChild(carrot);
self.carrots.push(carrot);
};
// Start game
self.startGame = function () {
self.isActive = true;
self.score = 0;
self.timeLeft = 30;
self.updateUI();
// Clear any existing carrots
for (var i = self.carrots.length - 1; i >= 0; i--) {
self.carrots[i].destroy();
}
self.carrots = [];
// Hide main game elements
toggleMainGameVisibility(false);
// Position minigame
self.x = 2048 / 2;
self.y = 2732 / 2;
};
// End game
self.endGame = function () {
self.isActive = false;
// Calculate reward based on score
var happinessBoost = Math.min(50, self.score);
happiness = Math.min(100, happiness + happinessBoost);
storage.happiness = happiness;
// Award coins based on score
var coinReward = Math.floor(self.score / 2);
coins += coinReward;
storage.coins = coins;
coinsDisplay.setText("Coins: " + coins + " 🪙");
// Display coin reward
var rewardText = new Text2("+" + coinReward + " 🪙", {
size: 80,
fill: 0xFFD700
});
rewardText.anchor.set(0.5, 0.5);
rewardText.x = self.x;
rewardText.y = self.y;
game.addChild(rewardText);
// Animate reward text
tween(rewardText, {
y: rewardText.y - 100,
alpha: 0
}, {
duration: 1500,
easing: tween.easeOut,
onFinish: function onFinish() {
rewardText.destroy();
}
});
// Clear any existing carrots
for (var i = self.carrots.length - 1; i >= 0; i--) {
self.carrots[i].destroy();
}
self.carrots = [];
// Show main game elements again
toggleMainGameVisibility(true);
};
// Update UI
self.updateUI = function () {
self.timerText.setText("Time: " + self.timeLeft);
self.scoreText.setText("Score: " + self.score);
};
// Player movement
self.move = function (x, y, obj) {
if (self.isActive) {
var localX = x - self.x;
self.player.x = Math.max(-700, Math.min(700, localX));
}
};
// Check collisions
self.checkCollisions = function () {
for (var i = self.carrots.length - 1; i >= 0; i--) {
var carrot = self.carrots[i];
if (self.player.x - 60 < carrot.x && self.player.x + 60 > carrot.x && self.player.y - 60 < carrot.y && self.player.y + 60 > carrot.y) {
self.score++;
carrot.destroy();
self.carrots.splice(i, 1);
LK.getSound('eat').play();
self.updateUI();
}
}
};
// Game update
self.update = function () {
if (self.isActive) {
// Spawn carrots
if (LK.ticks % 30 === 0) {
self.createCarrot();
}
// Update carrots
for (var i = 0; i < self.carrots.length; i++) {
self.carrots[i].update();
}
// Check collisions
self.checkCollisions();
// Update timer
if (LK.ticks % 60 === 0) {
self.timeLeft--;
self.updateUI();
if (self.timeLeft <= 0) {
self.endGame();
}
}
}
};
// Set initial visibility to false
self.visible = false;
return self;
});
var ProgressBar = Container.expand(function (name, color) {
var self = Container.call(this);
self.name = name || "Progress";
self.barColor = color || 0x83de44;
// Create label
self.label = new Text2(self.name, {
size: 40,
fill: 0x333333
});
self.label.anchor.set(0, 0.5);
self.addChild(self.label);
// Create background bar
self.background = self.attachAsset('progressBar', {
anchorX: 0,
anchorY: 0.5,
x: 150,
y: 0
});
// Create fill bar
self.fill = self.attachAsset('progressFill', {
anchorX: 0,
anchorY: 0.5,
x: 150,
y: 0,
tint: self.barColor
});
// Set value between 0-100
self.setValue = function (value) {
var clampedValue = Math.max(0, Math.min(100, value));
var fillWidth = clampedValue / 100 * self.background.width;
self.fill.width = fillWidth;
// Change color based on value
if (clampedValue < 30) {
self.fill.tint = 0xFF0000; // Red when low
} else if (clampedValue < 60) {
self.fill.tint = 0xFFCC00; // Yellow when medium
} else {
self.fill.tint = self.barColor; // Normal color when high
}
};
return self;
});
var Shop = Container.expand(function () {
var self = Container.call(this);
self.isOpen = false;
// Create shop background
self.background = self.attachAsset('environment', {
anchorX: 0.5,
anchorY: 0.5,
width: 1800,
height: 2000,
tint: 0xFFF8E1
});
// Shop title
self.title = new Text2("Bunny Shop", {
size: 80,
fill: 0x333333
});
self.title.anchor.set(0.5, 0);
self.title.x = 0;
self.title.y = -800;
self.addChild(self.title);
// Create coins display
self.coinsText = new Text2("Coins: 0", {
size: 60,
fill: 0x333333
});
self.coinsText.anchor.set(0.5, 0);
self.coinsText.x = 0;
self.coinsText.y = -700;
self.addChild(self.coinsText);
// Shop items (containers for each item)
self.items = [];
// Item types and data
self.itemData = [{
name: "Premium Food",
price: 20,
description: "Increases hunger +40",
type: "food",
bonusValue: 40,
color: 0xFF9900
}, {
name: "Luxury Toy",
price: 30,
description: "Increases happiness +40",
type: "toy",
bonusValue: 40,
color: 0x5555FF
}, {
name: "Premium Soap",
price: 25,
description: "Increases cleanliness +40",
type: "soap",
bonusValue: 40,
color: 0x00FFFF
}, {
name: "Health Potion",
price: 50,
description: "Increases all stats +20",
type: "health",
bonusValue: 20,
color: 0xFF5555
}];
// Create shop items
self.createItems = function () {
// Clear existing items first
for (var i = 0; i < self.items.length; i++) {
self.items[i].destroy();
}
self.items = [];
// Create new items
for (var i = 0; i < self.itemData.length; i++) {
var item = new Container();
var itemData = self.itemData[i];
// Item background
var itemBg = item.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
width: 1200,
height: 220,
tint: 0xFFFFFF
});
// Item icon
var icon = item.attachAsset(itemData.type === "health" ? "progressFill" : itemData.type, {
anchorX: 0.5,
anchorY: 0.5,
x: -450,
y: 0,
tint: itemData.color,
scaleX: 1.5,
scaleY: 1.5
});
// Item name
var nameText = new Text2(itemData.name, {
size: 50,
fill: 0x333333
});
nameText.anchor.set(0, 0.5);
nameText.x = -350;
nameText.y = -40;
item.addChild(nameText);
// Item description
var descText = new Text2(itemData.description, {
size: 40,
fill: 0x666666
});
descText.anchor.set(0, 0.5);
descText.x = -350;
descText.y = 30;
item.addChild(descText);
// Price button
var priceButton = item.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 400,
y: 0,
width: 200,
height: 100,
tint: 0x83de44
});
// Price text
var priceText = new Text2(itemData.price + " 🪙", {
size: 45,
fill: 0xFFFFFF
});
priceText.anchor.set(0.5, 0.5);
priceText.x = 400;
priceText.y = 0;
item.addChild(priceText);
// Position item
item.y = -500 + i * 300;
item.itemData = itemData;
item.priceButton = priceButton;
// Add interaction to buy button
item.interactive = true;
item.down = function (x, y, obj) {
var localItem = this;
var localX = x - localItem.x;
var localY = y - localItem.y;
// Check if click is on the price button
if (Math.abs(localX - 400) < 100 && Math.abs(localY) < 50) {
self.buyItem(localItem.itemData);
}
};
self.addChild(item);
self.items.push(item);
}
};
// Buy item functionality
self.buyItem = function (itemData) {
if (coins >= itemData.price) {
// Deduct coins
coins -= itemData.price;
storage.coins = coins;
self.updateCoinsDisplay();
// Apply item effects
switch (itemData.type) {
case "food":
hunger = Math.min(100, hunger + itemData.bonusValue);
storage.hunger = hunger;
// Create premium food effect
var food = new Food();
food.x = bunny.x;
food.y = bunny.y - 300;
food.graphic.tint = itemData.color;
food.graphic.scale.set(1.5);
game.addChild(food);
foods.push(food);
LK.getSound('eat').play();
break;
case "toy":
happiness = Math.min(100, happiness + itemData.bonusValue);
storage.happiness = happiness;
// Create premium toy effect
var toy = new Toy();
toy.x = bunny.x + (Math.random() - 0.5) * 200;
toy.y = bunny.y - 100;
toy.graphic.tint = itemData.color;
toy.graphic.scale.set(1.5);
game.addChild(toy);
toys.push(toy);
LK.getSound('play').play();
bunny.animatePlay();
break;
case "soap":
cleanliness = Math.min(100, cleanliness + itemData.bonusValue);
storage.cleanliness = cleanliness;
// Create premium soap effect
for (var i = 0; i < 3; i++) {
var soap = new Soap();
soap.x = bunny.x + (Math.random() - 0.5) * 150;
soap.y = bunny.y + (Math.random() - 0.5) * 150;
soap.graphic.tint = itemData.color;
soap.graphic.scale.set(1.5);
game.addChild(soap);
soaps.push(soap);
}
LK.getSound('clean').play();
break;
case "health":
hunger = Math.min(100, hunger + itemData.bonusValue);
happiness = Math.min(100, happiness + itemData.bonusValue);
cleanliness = Math.min(100, cleanliness + itemData.bonusValue);
health = Math.min(100, health + itemData.bonusValue);
storage.hunger = hunger;
storage.happiness = happiness;
storage.cleanliness = cleanliness;
storage.health = health;
LK.effects.flashObject(bunny, 0xFF5555, 1000);
break;
}
// Flash item button to indicate successful purchase
tween(itemData.button, {
tint: 0xFFFF00
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(itemData.button, {
tint: 0x83de44
}, {
duration: 200,
easing: tween.easeOut
});
}
});
} else {
// Not enough coins - flash the coins text
tween(self.coinsText, {
tint: 0xFF0000
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self.coinsText, {
tint: 0xFFFFFF
}, {
duration: 200,
easing: tween.easeOut
});
}
});
}
};
// Close button
self.closeButton = new ActionButton("Close", function () {
self.closeShop();
});
self.closeButton.x = 0;
self.closeButton.y = 800;
self.addChild(self.closeButton);
// Update coins display
self.updateCoinsDisplay = function () {
self.coinsText.setText("Coins: " + coins + " 🪙");
};
// Open shop
self.openShop = function () {
self.isOpen = true;
self.visible = true;
self.createItems();
self.updateCoinsDisplay();
// Position shop
self.x = 2048 / 2;
self.y = 2732 / 2;
// Hide main game elements
toggleMainGameVisibility(false);
};
// Close shop
self.closeShop = function () {
self.isOpen = false;
self.visible = false;
// Show main game elements again
toggleMainGameVisibility(true);
};
// Set initial visibility to false
self.visible = false;
return self;
});
var Soap = Container.expand(function () {
var self = Container.call(this);
self.graphic = self.attachAsset('soap', {
anchorX: 0.5,
anchorY: 0.5
});
self.lifetime = 30; // Frames before disappearing
self.update = function () {
self.lifetime--;
self.alpha = self.lifetime / 30;
if (self.lifetime <= 0) {
self.destroy();
var index = soaps.indexOf(self);
if (index !== -1) {
soaps.splice(index, 1);
}
}
};
return self;
});
var Toy = Container.expand(function () {
var self = Container.call(this);
self.graphic = self.attachAsset('toy', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocity = {
x: (Math.random() - 0.5) * 10,
y: -10
};
self.rotation = Math.random() * Math.PI * 2;
self.rotationSpeed = (Math.random() - 0.5) * 0.2;
self.update = function () {
self.velocity.y += 0.5; // Gravity
self.x += self.velocity.x;
self.y += self.velocity.y;
self.rotation += self.rotationSpeed;
// Bounce off walls
if (self.x < 0 || self.x > 2048) {
self.velocity.x *= -0.8;
if (self.x < 0) {
self.x = 0;
}
if (self.x > 2048) {
self.x = 2048;
}
}
// Remove when below screen
if (self.y > 2732) {
self.destroy();
var index = toys.indexOf(self);
if (index !== -1) {
toys.splice(index, 1);
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xF0F9FF
});
/****
* Game Code
****/
// Play background music
LK.playMusic('bgmusic');
// Game state variables
var bunnyAge = storage.bunnyAge;
var bunnyStage = storage.bunnyStage;
var lastFed = storage.lastFed;
var lastCleaned = storage.lastCleaned;
var lastPlayed = storage.lastPlayed;
var hunger = storage.hunger;
var happiness = storage.happiness;
var cleanliness = storage.cleanliness;
var health = storage.health;
var coins = storage.coins || 50; // Initialize with 50 coins if not existing
var foods = [];
var toys = [];
var soaps = [];
var gameActive = true;
// Get current timestamp
function getCurrentTime() {
return Date.now();
}
// Create environment
var environment = game.addChild(LK.getAsset('environment', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
width: 1800,
height: 1500
}));
// Create bunny
var bunny = game.addChild(new BunnyPet());
bunny.x = 2048 / 2;
bunny.y = 2732 / 2;
bunny.setStage(bunnyStage);
// Create status bars
var statusContainer = new Container();
statusContainer.x = 150;
statusContainer.y = 200;
game.addChild(statusContainer);
var hungerBar = new ProgressBar("Hunger", 0x83de44);
hungerBar.y = 0;
statusContainer.addChild(hungerBar);
var happinessBar = new ProgressBar("Happiness", 0xFFD700);
happinessBar.y = 80;
statusContainer.addChild(happinessBar);
var cleanlinessBar = new ProgressBar("Cleanliness", 0x00AAFF);
cleanlinessBar.y = 160;
statusContainer.addChild(cleanlinessBar);
var healthBar = new ProgressBar("Health", 0xFF5555);
healthBar.y = 240;
statusContainer.addChild(healthBar);
// Create minigame instance
var minigame = new MiniGame();
game.addChild(minigame);
minigame.visible = false;
// Create shop instance
var shop = new Shop();
game.addChild(shop);
shop.visible = false;
// Function to toggle main game elements visibility
function toggleMainGameVisibility(visible) {
environment.visible = visible;
bunny.visible = visible;
statusContainer.visible = visible;
buttonContainer.visible = visible;
ageText.visible = visible;
stageText.visible = visible;
coinsDisplay.visible = visible;
minigame.visible = !visible && minigame.isActive;
shop.visible = !visible && shop.isOpen;
}
// Create action buttons
var buttonContainer = new Container();
buttonContainer.x = 2048 / 2;
buttonContainer.y = 2732 - 300;
game.addChild(buttonContainer);
// Create coins display
var coinsDisplay = new Text2("Coins: 0 🪙", {
size: 50,
fill: 0xFFD700
});
coinsDisplay.anchor.set(1, 0);
coinsDisplay.x = 2048 - 50;
coinsDisplay.y = 50;
game.addChild(coinsDisplay);
coinsDisplay.setText("Coins: " + coins + " 🪙");
var feedButton = new ActionButton("Feed", function () {
// Create food
var food = new Food();
food.x = bunny.x;
food.y = bunny.y - 300;
game.addChild(food);
foods.push(food);
// Play sound
LK.getSound('eat').play();
// Update last fed time
lastFed = getCurrentTime();
storage.lastFed = lastFed;
// Increase hunger stat
hunger = Math.min(100, hunger + 20);
storage.hunger = hunger;
});
feedButton.x = -350;
buttonContainer.addChild(feedButton);
var playButton = new ActionButton("Play", function () {
// Create toy
var toy = new Toy();
toy.x = bunny.x + (Math.random() - 0.5) * 200;
toy.y = bunny.y - 100;
game.addChild(toy);
toys.push(toy);
// Play sound
LK.getSound('play').play();
// Update last played time
lastPlayed = getCurrentTime();
storage.lastPlayed = lastPlayed;
// Bunny play animation
bunny.animatePlay();
// Increase happiness stat
happiness = Math.min(100, happiness + 20);
storage.happiness = happiness;
});
playButton.x = 0;
buttonContainer.addChild(playButton);
var cleanButton = new ActionButton("Clean", function () {
// Create cleaning effect
var soap = new Soap();
soap.x = bunny.x + (Math.random() - 0.5) * 150;
soap.y = bunny.y + (Math.random() - 0.5) * 150;
game.addChild(soap);
soaps.push(soap);
// Play sound
LK.getSound('clean').play();
// Update last cleaned time
lastCleaned = getCurrentTime();
storage.lastCleaned = lastCleaned;
// Increase cleanliness stat
cleanliness = Math.min(100, cleanliness + 20);
storage.cleanliness = cleanliness;
});
cleanButton.x = 350;
buttonContainer.addChild(cleanButton);
var minigameButton = new ActionButton("Mini Game", function () {
// Start the minigame
minigame.startGame();
});
minigameButton.x = -175;
minigameButton.y = 120;
buttonContainer.addChild(minigameButton);
var shopButton = new ActionButton("Shop", function () {
// Open the shop
shop.openShop();
});
shopButton.x = 175;
shopButton.y = 120;
buttonContainer.addChild(shopButton);
// Create age display
var ageText = new Text2("Age: 0 days", {
size: 60,
fill: 0x333333
});
ageText.anchor.set(0.5, 0);
ageText.x = 2048 / 2;
ageText.y = 80;
game.addChild(ageText);
// Create stage display
var stageText = new Text2("Baby Bunny", {
size: 70,
fill: 0x83DE44
});
stageText.anchor.set(0.5, 0);
stageText.x = 2048 / 2;
stageText.y = 150;
game.addChild(stageText);
// Function to check for level up
function checkLevelUp() {
var newStage = bunnyStage;
if (bunnyAge >= 10 && bunnyStage === 'baby') {
newStage = 'teen';
LK.getSound('levelUp').play();
LK.effects.flashScreen(0x83de44, 1000);
stageText.setText("Teen Bunny");
} else if (bunnyAge >= 20 && bunnyStage === 'teen') {
newStage = 'adult';
LK.getSound('levelUp').play();
LK.effects.flashScreen(0x83de44, 1000);
stageText.setText("Adult Bunny");
}
if (newStage !== bunnyStage) {
bunnyStage = newStage;
storage.bunnyStage = bunnyStage;
bunny.setStage(bunnyStage);
// Show happy expression
bunny.showHappy();
}
}
// Decay timer - decreases stats over time
var lastDecayTime = getCurrentTime();
var dayCounter = getCurrentTime();
function updateStats() {
var currentTime = getCurrentTime();
// Decay every 3 seconds
if (currentTime - lastDecayTime > 3000) {
// Decay stats
hunger = Math.max(0, hunger - 2);
happiness = Math.max(0, happiness - 1);
cleanliness = Math.max(0, cleanliness - 1.5);
// Update health based on other stats
var avgStats = (hunger + happiness + cleanliness) / 3;
health = avgStats;
// Update storage
storage.hunger = hunger;
storage.happiness = happiness;
storage.cleanliness = cleanliness;
storage.health = health;
lastDecayTime = currentTime;
}
// Age counter - increase age every "day" (30 seconds in this demo)
if (currentTime - dayCounter > 30000) {
bunnyAge++;
storage.bunnyAge = bunnyAge;
ageText.setText("Age: " + bunnyAge + " days");
dayCounter = currentTime;
// Check for level up
checkLevelUp();
}
// Update UI
hungerBar.setValue(hunger);
happinessBar.setValue(happiness);
cleanlinessBar.setValue(cleanliness);
healthBar.setValue(health);
// Show bunny's dirty state
bunny.showDirty(cleanliness);
// Update bunny mood
if (health < 30) {
bunny.showSad();
} else if (health > 70 && (happiness > 70 || hunger > 70)) {
bunny.showHappy();
}
}
// Initial UI update
ageText.setText("Age: " + bunnyAge + " days");
switch (bunnyStage) {
case 'baby':
stageText.setText("Baby Bunny");
break;
case 'teen':
stageText.setText("Teen Bunny");
break;
case 'adult':
stageText.setText("Adult Bunny");
break;
}
hungerBar.setValue(hunger);
happinessBar.setValue(happiness);
cleanlinessBar.setValue(cleanliness);
healthBar.setValue(health);
// Handle interaction
var dragTarget = null;
game.down = function (x, y, obj) {
// Only allow dragging the bunny
if (bunny.intersects({
x: x,
y: y,
width: 1,
height: 1
})) {
dragTarget = bunny;
}
};
game.move = function (x, y, obj) {
// If minigame is active, pass movement to it
if (minigame.isActive) {
minigame.move(x, y, obj);
return;
}
// If shop is open, handle shop interactions
if (shop.isOpen) {
return;
}
if (dragTarget) {
dragTarget.x = x;
dragTarget.y = y;
// Keep bunny within environment boundaries
var envBounds = {
left: environment.x - environment.width / 2 + 100,
right: environment.x + environment.width / 2 - 100,
top: environment.y - environment.height / 2 + 100,
bottom: environment.y + environment.height / 2 - 100
};
dragTarget.x = Math.max(envBounds.left, Math.min(envBounds.right, dragTarget.x));
dragTarget.y = Math.max(envBounds.top, Math.min(envBounds.bottom, dragTarget.y));
}
};
game.up = function (x, y, obj) {
dragTarget = null;
};
// Handle collision between bunny and objects
function checkCollisions() {
// Check food collisions
for (var i = foods.length - 1; i >= 0; i--) {
if (bunny.intersects(foods[i])) {
bunny.animateEat();
foods[i].destroy();
foods.splice(i, 1);
}
}
// Check toy collisions
for (var j = toys.length - 1; j >= 0; j--) {
if (bunny.intersects(toys[j])) {
bunny.animatePlay();
toys[j].destroy();
toys.splice(j, 1);
}
}
}
// Game update loop
game.update = function () {
// Update minigame if active
if (minigame.isActive) {
minigame.update();
return;
}
// Skip updates if shop is open
if (shop.isOpen) {
return;
}
// Update game objects
for (var i = 0; i < foods.length; i++) {
foods[i].update();
}
for (var j = 0; j < toys.length; j++) {
toys[j].update();
}
for (var k = 0; k < soaps.length; k++) {
soaps[k].update();
}
// Check collisions
checkCollisions();
// Update stats
updateStats();
// Add coins periodically (every 5 seconds)
if (LK.ticks % 300 === 0) {
coins++;
storage.coins = coins;
coinsDisplay.setText("Coins: " + coins + " 🪙");
}
};