/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var ActionButton = Container.expand(function (text, color) { var self = Container.call(this); var buttonBg = self.attachAsset('button', { anchorX: 0.5, anchorY: 0.5, tint: color, scaleX: 1.4, scaleY: 1.4 }); var buttonText = new Text2(text, { size: 40, fill: 0xFFFFFF }); buttonText.anchor.set(0.5, 0.5); self.addChild(buttonText); self.down = function (x, y, obj) { tween(self, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); }; self.up = function (x, y, obj) { tween(self, { scaleX: 1.4, scaleY: 1.4 }, { duration: 100 }); if (self.onPress) { self.onPress(); } }; return self; }); var DigiEgg = Container.expand(function (eggType, isLocked) { var self = Container.call(this); // Use specific egg assets for each type var eggAssetName = 'digiEgg' + eggType; var eggGraphics = self.attachAsset(eggAssetName, { anchorX: 0.5, anchorY: 0.5, scaleX: 1.0, scaleY: 1.0 }); // Add pattern overlay for visual distinction var patternShapes = ['ellipse', 'box', 'ellipse', 'box', 'ellipse', 'box']; var patternColors = [0x66BB6A, 0x42A5F5, 0xFFB74D, 0xBA68C8, 0xEF5350, 0xFF7043]; var pattern = self.attachAsset('petEye', { anchorX: 0.5, anchorY: 0.5, tint: patternColors[eggType], scaleX: 0.6, scaleY: 0.6, alpha: 0.7 }); // Add small decorative spots for (var i = 0; i < 3; i++) { var spot = self.attachAsset('petEye', { anchorX: 0.5, anchorY: 0.5, x: (Math.random() - 0.5) * 80, y: (Math.random() - 0.5) * 100, tint: patternColors[eggType], scaleX: 0.2 + Math.random() * 0.2, scaleY: 0.2 + Math.random() * 0.2, alpha: 0.5 }); } if (isLocked) { var lockOverlay = self.attachAsset('button', { anchorX: 0.5, anchorY: 0.5, tint: 0x666666, alpha: 0.7, scaleX: 0.3, scaleY: 0.3 }); var lockText = new Text2(getText('locked'), { size: 20, fill: 0xFFFFFF }); lockText.anchor.set(0.5, 0.5); lockText.y = 50; self.addChild(lockText); } self.eggType = eggType; self.isLocked = isLocked; self.down = function (x, y, obj) { if (!self.isLocked && self.onSelect) { tween(self, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); self.onSelect(self.eggType); } }; self.up = function (x, y, obj) { if (!self.isLocked) { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }; return self; }); var DigitalPet = Container.expand(function () { var self = Container.call(this); // Pet graphics - will be updated based on evolution var body = null; // Pet stats self.hunger = storage.hunger || 100; self.happiness = storage.happiness || 100; self.fatigue = storage.fatigue || 0; // Changed from energy to fatigue, starts at 0 self.poopNeed = storage.poopNeed || 0; // New waste stat that increases over time self.hygiene = storage.hygiene || 100; // New hygiene stat that decreases when dirty self.friendship = storage.friendship || 0; // New friendship stat with percentage, starts at 0 self.evolutionLevel = storage.evolutionLevel || 0; self.attack = storage.attack || 0; self.health = storage.health || 0; self.speed = storage.speed || 0; self.weight = storage.weight || 5; self.name = storage.petName || 'Digimon'; self.eggType = storage.eggType || 0; self.wins = storage.wins || 0; self.battles = storage.battles || 0; self.lastUpdateTime = Date.now(); self.lastPetTime = storage.lastPetTime || 0; // Track when pet was last petted // Time-based evolution tracking self.birthTime = storage.birthTime || Date.now(); // Health system self.injured = storage.injured || false; self.sick = storage.sick || false; self.injuryTime = storage.injuryTime || 0; self.sickTime = storage.sickTime || 0; self.hungerDeathTimer = storage.hungerDeathTimer || 0; // Stats display self.statsDisplay = null; self.showingStats = false; // Health status icon self.statusIcon = null; // Evolution colors self.evolutionColors = [0x4CAF50, 0x2196F3, 0xFF9800, 0x9C27B0, 0xF44336]; self.updateStatusIcon = function () { // Remove existing status icon if (self.statusIcon) { self.removeChild(self.statusIcon); self.statusIcon = null; } // Add status icon if injured or sick if (self.injured || self.sick) { self.statusIcon = new Container(); var iconBg = self.statusIcon.attachAsset('petEye', { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 2, tint: self.sick ? 0x800080 : 0xFF0000 // Purple for sick, red for injured }); var iconText = new Text2(self.sick ? '!' : '?', { size: 40, fill: 0xFFFFFF }); iconText.anchor.set(0.5, 0.5); self.statusIcon.addChild(iconText); self.statusIcon.x = 0; self.statusIcon.y = -150; // Position above Digimon self.addChild(self.statusIcon); // Pulsing animation if (self.statusIcon) { tween(self.statusIcon, { alpha: 0.3 }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { if (self.statusIcon) { tween(self.statusIcon, { alpha: 1 }, { duration: 800, easing: tween.easeInOut }); } } }); } } }; self.updateAppearance = function () { // Remove old body if exists if (body) { self.removeChild(body); body = null; } // Choose asset based on evolution line and level - only use specific Digimon assets var evolutionAssets = [ // Line 0: Botamon → WarGreymon (Dragon and Fire) ['botamon', 'koromon', 'agumon', 'greymon', 'metalgreymon', 'wargreymon'], // Line 1: Punimon → MetalGarurumon (Beast and Ice) ['punimon', 'tsunomon', 'gabumon', 'garurumon', 'weregarurumon', 'metalgarurumon'], // Line 2: Poyomon → Seraphimon (Light - Angemon path) ['poyomon', 'tokomon', 'patamon', 'angemon', 'magnaangemon', 'seraphimon'], // Line 3: Poyomon → Ophanimon (Light - Angewomon path) ['poyomon', 'tokomon', 'patamon', 'angewomon', 'magnadramon', 'ophanimon'], // Line 4: Use Line 0 as fallback ['botamon', 'koromon', 'agumon', 'greymon', 'metalgreymon', 'wargreymon'], // Line 5: Use Line 1 as fallback ['punimon', 'tsunomon', 'gabumon', 'garurumon', 'weregarurumon', 'metalgarurumon']]; // Special logic for Poyomon evolution path determination var actualEggType = self.eggType; if (self.eggType === 2 || self.eggType === 3) { // Both egg types 2 and 3 start as Poyomon but evolve differently based on stats if (self.evolutionLevel >= 3) { // At Patamon level and beyond, check stats if (self.speed > self.attack && self.weight < 30) { // More speed than attack and low weight → Angewomon path actualEggType = 3; } else if (self.attack >= self.speed && self.weight >= 30) { // More attack than speed and higher weight → Angemon path actualEggType = 2; } // If neither condition is met, keep current path } } var lineAssets = evolutionAssets[actualEggType] || evolutionAssets[0]; var assetName = lineAssets[self.evolutionLevel] || lineAssets[0]; // Debug logging console.log('CREATING DIGIMON - Asset:', assetName, 'EggType:', self.eggType, 'Evolution:', self.evolutionLevel); // Create main body with specific Digimon asset (no shadow) body = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5, x: 0, y: 0, visible: true, alpha: 1, scaleX: 3.0, scaleY: 3.0 }); console.log('DIGIMON SPRITE - Successfully created with asset:', assetName); // Enhanced visibility and scaling if (body) { body.visible = true; body.alpha = 1; // Update the pet's display name based on evolution self.currentDigimonName = getCurrentDigimonName(self.eggType, self.evolutionLevel); // Larger scale for better visibility var evolutionScale = 3.0 + self.evolutionLevel * 0.3; var eggTypeScale = 1.0 + self.eggType * 0.1; var finalScale = evolutionScale * eggTypeScale; body.scaleX = finalScale; body.scaleY = finalScale; console.log('DIGIMON SPRITE FINAL - Scale:', finalScale, 'Visible:', body.visible, 'Alpha:', body.alpha); console.log('DIGIMON SPRITE POSITION - X:', body.x, 'Y:', body.y); console.log('DIGIMON SPRITE DIMENSIONS - Width:', body.width, 'Height:', body.height); } else { console.log('ERROR: DIGIMON SPRITE is null after creation!'); } // Force a refresh of the container self.visible = true; self.alpha = 1; console.log('PET CONTAINER - Visible:', self.visible, 'Alpha:', self.alpha, 'Children:', self.children.length); }; // Initialize appearance with debugging console.log('Initializing Digimon appearance'); self.updateAppearance(); // Single delayed update to ensure asset is loaded LK.setTimeout(function () { console.log('Delayed update at 200ms to ensure asset loading'); self.updateAppearance(); if (body) { console.log('200ms: Body confirmed - visible:', body.visible, 'alpha:', body.alpha, 'scale:', body.scaleX); } }, 200); self.evolveCheck = function () { // Time-based evolution with different times for each stage var evolutionTimes = [5 * 60 * 1000, // Baby 1 to Baby 2: 5 minutes 15 * 60 * 1000, // Baby 2 to Novato: 15 minutes 60 * 60 * 1000, // Novato to Campeón: 1 hour 5 * 60 * 60 * 1000, // Campeón to Perfecto: 5 hours 24 * 60 * 60 * 1000 // Perfecto to Mega: 1 day ]; var currentTime = Date.now(); // Initialize birth time if not set if (!self.birthTime) { self.birthTime = storage.birthTime || currentTime; storage.birthTime = self.birthTime; } var ageInMilliseconds = currentTime - self.birthTime; var targetLevel = 0; var accumulatedTime = 0; // Calculate target level based on accumulated evolution times for (var i = 0; i < evolutionTimes.length && i < self.evolutionColors.length - 1; i++) { accumulatedTime += evolutionTimes[i]; if (ageInMilliseconds >= accumulatedTime) { targetLevel = i + 1; } else { break; } } // Cap evolution level to maximum available var maxLevel = self.evolutionColors.length - 1; targetLevel = Math.min(targetLevel, maxLevel); if (targetLevel > self.evolutionLevel) { self.evolutionLevel = targetLevel; LK.getSound('evolve').play(); // Evolution animation tween(self, { scaleX: 1.5, scaleY: 1.5 }, { duration: 500, easing: tween.bounceOut, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 300, easing: tween.easeOut }); } }); self.updateAppearance(); // Update the centered Digimon image in the main game view if (typeof updateCenteredDigimonImage === 'function') { updateCenteredDigimonImage(); } LK.effects.flashScreen(0xFFD700, 1000); } }; self.update = function () { var currentTime = Date.now(); var deltaTime = (currentTime - self.lastUpdateTime) / 1000; self.lastUpdateTime = currentTime; // Decay stats over time - hunger no longer decreases automatically // self.hunger = Math.max(0, self.hunger - deltaTime * 2); // Removed automatic hunger decrease self.happiness = Math.max(0, self.happiness - deltaTime * 0.1); // Much slower happiness decrease (fun bar) // Energy is now fatigue - it doesn't decrease automatically, only increases during training // Increase poop need over time self.poopNeed = Math.min(100, self.poopNeed + deltaTime * 0.8); // Hygiene decreases slowly over time self.hygiene = Math.max(0, self.hygiene - deltaTime * 0.05); // When poop need reaches 100, create poop and reset if (self.poopNeed >= 100) { self.createPoop(); self.poopNeed = 0; self.hygiene = Math.max(0, self.hygiene - 20); // Reduce hygiene when pooping } // Check for old poop and degrade hygiene and friendship if not cleaned for (var i = 0; i < poopInstances.length; i++) { var poopObj = poopInstances[i]; if (poopObj.ageTime === undefined) poopObj.ageTime = 0; poopObj.ageTime += deltaTime; // After 60 seconds, start degrading hygiene and friendship if (poopObj.ageTime > 60) { self.hygiene = Math.max(0, self.hygiene - deltaTime * 0.2); self.friendship = Math.max(0, self.friendship - deltaTime * 0.1); } } // Health system timers if (self.injured) { self.injuryTime += deltaTime; // After 30 minutes (1800 seconds) injury becomes sickness if (self.injuryTime >= 1800) { self.injured = false; self.sick = true; self.injuryTime = 0; self.sickTime = 0; LK.effects.flashObject(self, 0x800080, 1000); } } if (self.sick) { self.sickTime += deltaTime; // Sick Digimon dies after some time without medicine if (self.sickTime >= 300) { // 5 minutes self.die(); return; } } // Hunger death timer if (self.hunger <= 0) { self.hungerDeathTimer += deltaTime; if (self.hungerDeathTimer >= 300) { // 5 minutes self.die(); return; } } else { self.hungerDeathTimer = 0; } // Simple visibility check every 5 seconds if (LK.ticks % 300 === 0) { console.log('VISIBILITY CHECK - Tick:', LK.ticks); if (body) { console.log('DIGIMON SPRITE - Visible:', body.visible, 'Alpha:', body.alpha, 'Scale:', body.scaleX); } console.log('PET CONTAINER - Visible:', self.visible, 'Alpha:', self.alpha, 'Children:', self.children.length); } // Enhanced idle animation with multiple effects if (LK.ticks % 120 === 0) { // Bouncing animation tween(self, { y: self.y - 20 }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { tween(self, { y: self.y + 20 }, { duration: 500, easing: tween.easeInOut }); } }); } // Additional breathing animation every 180 ticks - only on the body if (LK.ticks % 180 === 0 && body) { tween(body, { scaleX: body.scaleX * 1.05, scaleY: body.scaleY * 1.05 }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { if (body) { tween(body, { scaleX: body.scaleX / 1.05, scaleY: body.scaleY / 1.05 }, { duration: 800, easing: tween.easeInOut }); } } }); } // Subtle rotation animation every 240 ticks if (LK.ticks % 240 === 0) { var randomRotation = (Math.random() - 0.5) * 0.2; // Small random rotation tween(self, { rotation: randomRotation }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(self, { rotation: 0 }, { duration: 1000, easing: tween.easeInOut }); } }); } self.updateAppearance(); self.updateStatusIcon(); // Update health status icon self.evolveCheck(); // Calculate defense based on weight self.defense = Math.floor(self.weight / 2); // Save stats storage.hunger = self.hunger; storage.happiness = self.happiness; storage.fatigue = self.fatigue; // Changed from energy to fatigue storage.poopNeed = self.poopNeed; storage.hygiene = self.hygiene; storage.evolutionLevel = self.evolutionLevel; storage.attack = self.attack; storage.health = self.health; storage.speed = self.speed; storage.weight = self.weight; storage.petName = self.name; storage.eggType = self.eggType; storage.wins = self.wins; storage.battles = self.battles; storage.injured = self.injured; storage.sick = self.sick; storage.injuryTime = self.injuryTime; storage.sickTime = self.sickTime; storage.hungerDeathTimer = self.hungerDeathTimer; storage.birthTime = self.birthTime; storage.friendship = self.friendship; storage.lastPetTime = self.lastPetTime; }; self.down = function (x, y, obj) { // Petting functionality - once per day var currentTime = Date.now(); var dayInMs = 24 * 60 * 60 * 1000; // 24 hours in milliseconds if (currentTime - self.lastPetTime >= dayInMs) { // Can pet the digimon var friendshipGain = 4 + Math.floor(Math.random() * 2); // 4-5 points self.friendship = Math.min(100, self.friendship + friendshipGain); self.lastPetTime = currentTime; storage.lastPetTime = self.lastPetTime; storage.friendship = self.friendship; // Visual feedback for petting LK.effects.flashObject(self, 0xFF69B4, 1000); // Pink flash for petting tween(self, { scaleX: 1.2, scaleY: 1.2 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 200, easing: tween.easeOut }); } }); } else { // Show time remaining until next pet var timeRemaining = dayInMs - (currentTime - self.lastPetTime); var hoursRemaining = Math.ceil(timeRemaining / (60 * 60 * 1000)); // Could show a message here, but keeping it simple for now LK.effects.flashObject(self, 0x888888, 300); // Gray flash when can't pet } }; self.showStats = function () { if (self.statsDisplay) return; self.showingStats = true; var winRate = self.battles > 0 ? Math.round(self.wins / self.battles * 100) : 0; self.statsDisplay = new Container(); var statsBg = self.statsDisplay.attachAsset('gameArea', { anchorX: 0.5, anchorY: 0.5, scaleX: 4, scaleY: 3.5, tint: 0x263238, alpha: 0.9 }); // Get current Digimon asset name var evolutionAssets = [['botamon', 'koromon', 'agumon', 'greymon', 'metalgreymon', 'wargreymon'], ['punimon', 'tsunomon', 'gabumon', 'garurumon', 'weregarurumon', 'metalgarurumon'], ['poyomon', 'tokomon', 'patamon', 'angemon', 'magnaangemon', 'seraphimon'], ['poyomon', 'tokomon', 'patamon', 'angewomon', 'magnadramon', 'ophanimon'], ['botamon', 'koromon', 'agumon', 'greymon', 'metalgreymon', 'wargreymon'], ['punimon', 'tsunomon', 'gabumon', 'garurumon', 'weregarurumon', 'metalgarurumon']]; var actualEggType = self.eggType; if (self.eggType === 2 || self.eggType === 3) { if (self.evolutionLevel >= 3) { if (self.speed > self.attack && self.weight < 30) { actualEggType = 3; } else if (self.attack >= self.speed && self.weight >= 30) { actualEggType = 2; } } } var lineAssets = evolutionAssets[actualEggType] || evolutionAssets[0]; var assetName = lineAssets[self.evolutionLevel] || lineAssets[0]; var currentDigimonName = getCurrentDigimonName(self.eggType, self.evolutionLevel); // Calculate evolution timer var evolutionTimes = [5 * 60 * 1000, // Baby 1 to Baby 2: 5 minutes 15 * 60 * 1000, // Baby 2 to Novato: 15 minutes 60 * 60 * 1000, // Novato to Campeón: 1 hour 5 * 60 * 60 * 1000, // Campeón to Perfecto: 5 hours 24 * 60 * 60 * 1000 // Perfecto to Mega: 1 day ]; var currentTime = Date.now(); var ageInMilliseconds = currentTime - (self.birthTime || currentTime); var accumulatedTime = 0; var timeToNextEvolution = 0; var evolutionTimerText = ""; if (self.evolutionLevel < evolutionTimes.length) { // Calculate accumulated time for current level for (var i = 0; i < self.evolutionLevel && i < evolutionTimes.length; i++) { accumulatedTime += evolutionTimes[i]; } // Calculate time remaining for next evolution var nextEvolutionTime = accumulatedTime + evolutionTimes[self.evolutionLevel]; timeToNextEvolution = Math.max(0, nextEvolutionTime - ageInMilliseconds); if (timeToNextEvolution > 0) { var hours = Math.floor(timeToNextEvolution / (60 * 60 * 1000)); var minutes = Math.floor(timeToNextEvolution % (60 * 60 * 1000) / (60 * 1000)); var seconds = Math.floor(timeToNextEvolution % (60 * 1000) / 1000); if (hours > 0) { evolutionTimerText = 'Next Evolution: ' + hours + 'h ' + minutes + 'm ' + seconds + 's'; } else if (minutes > 0) { evolutionTimerText = 'Next Evolution: ' + minutes + 'm ' + seconds + 's'; } else { evolutionTimerText = 'Next Evolution: ' + seconds + 's'; } } else { evolutionTimerText = 'Evolution Ready!'; } } else { evolutionTimerText = 'Max Evolution Reached'; } var friendshipLevel = Math.floor(self.friendship / 20); // 0-5 friendship levels var criticalChance = Math.min(25, Math.floor(self.friendship / 4)); // Max 25% critical chance at 100% friendship var statsText = new Text2(self.name + ' (' + currentDigimonName + ')' + '\n\n' + getText('evolutionLevel') + ': ' + self.evolutionLevel + '\n' + evolutionTimerText + '\n\n' + getText('attack') + ': ' + Math.floor(self.attack) + '\n' + getText('health') + ': ' + Math.floor(self.health) + '\n' + getText('speed') + ': ' + Math.floor(self.speed) + '\n' + getText('defense') + ': ' + Math.floor(self.defense) + '\n' + getText('weight') + ': ' + Math.floor(self.weight) + '\n' + getText('friendship') + ': ' + Math.floor(self.friendship) + '%\n' + 'Critical Chance: ' + criticalChance + '%\n' + 'Win Rate: ' + winRate + '%', { size: 45, fill: 0xFFFFFF }); statsText.anchor.set(0.5, 0.5); statsText.y = 50; self.statsDisplay.addChild(statsText); self.statsDisplay.x = 0; self.statsDisplay.y = -200; self.addChild(self.statsDisplay); // Auto hide after 3 seconds LK.setTimeout(function () { if (self.showingStats) { self.hideStats(); } }, 3000); }; self.hideStats = function () { if (self.statsDisplay) { self.removeChild(self.statsDisplay); self.statsDisplay = null; self.showingStats = false; } }; self.die = function () { LK.effects.flashScreen(0x000000, 2000); LK.setTimeout(function () { // Clear all storage and restart storage.hunger = 100; storage.happiness = 100; storage.fatigue = 0; storage.evolutionLevel = 0; storage.attack = 10; storage.health = 50; storage.speed = 30; storage.weight = 50; storage.injured = false; storage.sick = false; storage.injuryTime = 0; storage.sickTime = 0; storage.hungerDeathTimer = 0; storage.birthTime = Date.now(); // Reset birth time for new pet // Give new starter items storage.smallMeat = 10; storage.blessing = 5; storage.medicine = 3; showMainMenu(); }, 2000); }; self.createPoop = function () { // Create poop near the digimon using new poop asset var poop = game.attachAsset('poop', { anchorX: 0.5, anchorY: 0.5, x: self.x + (Math.random() - 0.5) * 300, y: self.y + (Math.random() - 0.5) * 200, scaleX: 1.5, scaleY: 1.5 }); // Add click handler to clean poop poop.down = function (x, y, obj) { // Clean poop and restore hygiene var hygieneRestore = 20; // Amount of hygiene lost when pooping self.hygiene = Math.min(100, self.hygiene + hygieneRestore); // Remove poop from game and tracking array game.removeChild(poop); for (var j = 0; j < poopInstances.length; j++) { if (poopInstances[j] === poop) { poopInstances.splice(j, 1); break; } } LK.effects.flashObject(self, 0x00BCD4, 500); // Blue flash for cleaning }; // Add to tracking array poop.ageTime = 0; poopInstances.push(poop); // Auto cleanup after 5 minutes if not cleaned manually LK.setTimeout(function () { if (poop && poop.parent) { game.removeChild(poop); // Remove from tracking array for (var j = 0; j < poopInstances.length; j++) { if (poopInstances[j] === poop) { poopInstances.splice(j, 1); break; } } } }, 300000); // 5 minutes // Flash effect when poop is created LK.effects.flashObject(self, 0x8B4513, 500); // Play poop sound effect LK.getSound('poop').play(); }; self.train = function () { // Increase fatigue during training self.fatigue = Math.min(100, self.fatigue + 15); if (self.fatigue > 80) { // Training while tired causes injury if (!self.injured && !self.sick) { self.injured = true; self.injuryTime = 0; LK.effects.flashObject(self, 0xFF0000, 1000); } } // Reduce hunger slightly during training self.hunger = Math.max(0, self.hunger - 3); }; return self; }); var Inventory = Container.expand(function () { var self = Container.call(this); // Initialize inventory items self.items = { smallMeat: storage.smallMeat || 0, mediumMeat: storage.mediumMeat || 0, largeMeat: storage.largeMeat || 0, sirloin: storage.sirloin || 0, blessing: storage.blessing || 0, medicine: storage.medicine || 0, soap: storage.soap || 0 }; self.slots = []; // Create inventory slots var itemTypes = ['smallMeat', 'mediumMeat', 'largeMeat', 'sirloin', 'blessing', 'medicine', 'soap']; for (var i = 0; i < itemTypes.length; i++) { var slot = new Container(); var slotBg = slot.attachAsset('inventorySlot', { anchorX: 0.5, anchorY: 0.5 }); var itemIcon = slot.attachAsset(itemTypes[i], { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.2 }); var countText = new Text2('0', { size: 18, fill: 0xFFFFFF }); countText.anchor.set(0.5, 1); countText.y = 35; slot.addChild(countText); slot.itemType = itemTypes[i]; slot.x = i * 120; slot.y = 0; slot.down = function (x, y, obj) { if (self.items[this.itemType] > 0) { self.useItem(this.itemType); } }; self.addChild(slot); self.slots.push(slot); } self.useItem = function (itemType) { if (self.items[itemType] <= 0) return; self.items[itemType]--; switch (itemType) { case 'smallMeat': pet.hunger = Math.min(100, pet.hunger + 15); pet.friendship = Math.min(100, pet.friendship + 1); break; case 'mediumMeat': pet.hunger = Math.min(100, pet.hunger + 30); pet.friendship = Math.min(100, pet.friendship + 1); break; case 'largeMeat': pet.hunger = Math.min(100, pet.hunger + 50); pet.friendship = Math.min(100, pet.friendship + 1); break; case 'sirloin': pet.hunger = Math.min(100, pet.hunger + 75); pet.friendship = Math.min(100, pet.friendship + 1); break; case 'blessing': if (pet.injured) { pet.injured = false; pet.injuryTime = 0; LK.effects.flashObject(pet, 0xFFD700, 1000); } break; case 'medicine': if (pet.sick) { pet.sick = false; pet.sickTime = 0; LK.effects.flashObject(pet, 0x4CAF50, 1000); } break; case 'soap': pet.hygiene = Math.min(100, pet.hygiene + 50); pet.friendship = Math.min(100, pet.friendship + 10); // Soap also increases friendship LK.effects.flashObject(pet, 0x00BCD4, 1000); break; } self.updateDisplay(); self.saveItems(); LK.getSound('feed').play(); }; self.updateDisplay = function () { for (var i = 0; i < self.slots.length; i++) { var slot = self.slots[i]; var count = self.items[slot.itemType]; slot.children[2].setText(count.toString()); } }; self.saveItems = function () { storage.smallMeat = self.items.smallMeat; storage.mediumMeat = self.items.mediumMeat; storage.largeMeat = self.items.largeMeat; storage.sirloin = self.items.sirloin; storage.blessing = self.items.blessing; storage.medicine = self.items.medicine; storage.soap = self.items.soap; }; self.updateDisplay(); return self; }); var LanguageButton = Container.expand(function () { var self = Container.call(this); var buttonBg = self.attachAsset('languageButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.5, scaleY: 2.5 }); var flagEN = self.attachAsset('flagEN', { anchorX: 0.5, anchorY: 0.5, x: -25, scaleX: 1.0, scaleY: 1.0 }); var flagES = self.attachAsset('flagES', { anchorX: 0.5, anchorY: 0.5, x: 25, scaleX: 1.0, scaleY: 1.0 }); // Add EN/ES text overlay var textEN = new Text2('EN', { size: 24, fill: 0xFFFFFF }); textEN.anchor.set(0.5, 0.5); textEN.x = -25; flagEN.addChild(textEN); var textES = new Text2('ES', { size: 24, fill: 0xFFFFFF }); textES.anchor.set(0.5, 0.5); textES.x = 25; flagES.addChild(textES); self.updateDisplay = function () { if (currentLanguage === 'en') { flagEN.alpha = 1; flagES.alpha = 0.5; } else { flagEN.alpha = 0.5; flagES.alpha = 1; } }; self.down = function (x, y, obj) { tween(self, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); }; self.up = function (x, y, obj) { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 100 }); // Toggle language currentLanguage = currentLanguage === 'en' ? 'es' : 'en'; storage.currentLanguage = currentLanguage; self.updateDisplay(); updateAllTexts(); }; self.updateDisplay(); return self; }); var MainMenu = Container.expand(function () { var self = Container.call(this); // Add colorful background that properly fills the screen var menuBg = self.attachAsset('gameBackground', { anchorX: 0, anchorY: 0, x: 0, y: 0, scaleX: 1.0, scaleY: 1.0, tint: 0x4A90E2, alpha: 0.8 }); // Add decorative circles for visual appeal for (var i = 0; i < 8; i++) { var decorCircle = self.attachAsset('petEye', { anchorX: 0.5, anchorY: 0.5, x: (Math.random() - 0.5) * 2000, y: (Math.random() - 0.5) * 2500, scaleX: 2 + Math.random() * 3, scaleY: 2 + Math.random() * 3, tint: [0xFF6B6B, 0x4ECDC4, 0x45B7D1, 0x96CEB4, 0xFEA6A2, 0xDDA0DD, 0xF7DC6F, 0xBB8FCE][i], alpha: 0.3 }); } var titleText = new Text2('Digital Pet', { size: 120, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 400; self.addChild(titleText); // Add subtitle var subtitleText = new Text2('Monster Tamagotchi Simulator', { size: 50, fill: 0xE8F4FD }); subtitleText.anchor.set(0.5, 0.5); subtitleText.x = 1024; subtitleText.y = 500; self.addChild(subtitleText); // Add version number var versionText = new Text2('v0.0.1', { size: 40, fill: 0xBBBBBB }); versionText.anchor.set(0.5, 0.5); versionText.x = 1024; versionText.y = 560; self.addChild(versionText); var newGameButton = new ActionButton(getText('newGame'), 0x4CAF50); newGameButton.x = 1024; newGameButton.y = 800; newGameButton.scaleX = 1.8; newGameButton.scaleY = 1.8; newGameButton.onPress = function () { showEggSelection(); }; self.addChild(newGameButton); var savedGamesButton = new ActionButton(getText('savedGames'), 0x2196F3); savedGamesButton.x = 1024; savedGamesButton.y = 1000; savedGamesButton.scaleX = 1.8; savedGamesButton.scaleY = 1.8; savedGamesButton.onPress = function () { showSavedGames(); }; self.addChild(savedGamesButton); return self; }); var MiniGame = Container.expand(function () { var self = Container.call(this); var gameArea = self.attachAsset('gameArea', { anchorX: 0.5, anchorY: 0.5 }); var target = self.attachAsset('target', { anchorX: 0.5, anchorY: 0.5 }); self.score = 0; self.timeLeft = 10; self.gameActive = false; var scoreText = new Text2('Score: 0', { size: 30, fill: 0x333333 }); scoreText.anchor.set(0.5, 0); scoreText.y = -180; self.addChild(scoreText); var timerText = new Text2('Time: 10', { size: 30, fill: 0x333333 }); timerText.anchor.set(0.5, 0); timerText.y = -140; self.addChild(timerText); self.startGame = function () { self.gameActive = true; self.score = 0; self.timeLeft = 10; scoreText.setText(getText('score') + ': 0'); timerText.setText(getText('time') + ': 10'); self.moveTarget(); var gameTimer = LK.setInterval(function () { self.timeLeft -= 0.1; timerText.setText(getText('time') + ': ' + Math.ceil(self.timeLeft)); if (self.timeLeft <= 0) { LK.clearInterval(gameTimer); self.endGame(); } }, 100); }; self.moveTarget = function () { if (!self.gameActive) return; var newX = (Math.random() - 0.5) * 300; var newY = (Math.random() - 0.5) * 300; tween(target, { x: newX, y: newY }, { duration: 200, easing: tween.easeOut }); }; self.endGame = function () { self.gameActive = false; var happiness = Math.min(20, self.score * 2); pet.happiness = Math.min(100, pet.happiness + happiness); pet.fatigue = Math.min(100, pet.fatigue + 10); // Increase fatigue instead of decreasing energy pet.hunger = Math.max(0, pet.hunger - 5); if (self.onGameEnd) { self.onGameEnd(self.score); } }; target.down = function (x, y, obj) { if (!self.gameActive) return; self.score++; scoreText.setText(getText('score') + ': ' + self.score); LK.getSound('play').play(); tween(target, { scaleX: 1.3, scaleY: 1.3 }, { duration: 100, onFinish: function onFinish() { tween(target, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); self.moveTarget(); }; return self; }); var Shop = Container.expand(function () { var self = Container.call(this); // Full screen background var shopBg = self.attachAsset('gameBackground', { anchorX: 0, anchorY: 0, x: -1024, y: -1366, scaleX: 1.0, scaleY: 1.0, tint: 0x2E7D32, alpha: 0.95 }); // Prevent shop background from triggering external events shopBg.down = function (x, y, obj) { // Stop event propagation to prevent triggering other menus if (obj && obj.data && obj.data.originalEvent) { obj.data.originalEvent.stopPropagation(); } }; shopBg.up = function (x, y, obj) { // Stop event propagation to prevent triggering other menus if (obj && obj.data && obj.data.originalEvent) { obj.data.originalEvent.stopPropagation(); } }; // Table/desk positioned at bottom right corner var table = self.attachAsset('table', { anchorX: 0.5, anchorY: 1.0, x: 600, y: 1300, scaleX: 2.2, scaleY: 1.8, tint: 0x8B4513 }); // Shopkeeper character positioned behind table, higher priority than everything except table var shopkeeper = self.attachAsset('shopkeeper', { anchorX: 0.5, anchorY: 0.8, x: 700, y: 500, scaleX: 2.2, scaleY: 2.2 }); // Hide the VI (stats button) when in shop to show only when viewing Digimon if (game.children.length > 0) { for (var i = 0; i < game.children.length; i++) { var child = game.children[i]; if (child.children && child.children.length > 0) { // Look for stats button (question mark button) for (var j = 0; j < child.children.length; j++) { var grandchild = child.children[j]; if (grandchild.children && grandchild.children.length > 0) { for (var k = 0; k < grandchild.children.length; k++) { var text = grandchild.children[k]; if (text.text && text.text === '?') { child.visible = false; break; } } } } } } } // Add floating animation to shopkeeper tween(shopkeeper, { y: shopkeeper.y - 12 }, { duration: 1800, easing: tween.easeInOut, onFinish: function onFinish() { tween(shopkeeper, { y: shopkeeper.y + 12 }, { duration: 1800, easing: tween.easeInOut }); } }); // Speech bubble positioned above shopkeeper, not overlapping with items var speechBubble = self.attachAsset('gameArea', { anchorX: 0.5, anchorY: 0.5, x: 200, y: -200, scaleX: 2.8, scaleY: 1.3, tint: 0xFFFFFF, alpha: 0.92 }); var shopkeeperText = new Text2(getText('shopWelcome'), { size: 42, fill: 0x333333 }); shopkeeperText.anchor.set(0.5, 0.5); shopkeeperText.x = 200; shopkeeperText.y = -200; self.addChild(shopkeeperText); // Shop title positioned clearly at top center var titleText = new Text2(getText('shop'), { size: 120, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.x = 0; titleText.y = -750; self.addChild(titleText); var moneyText = new Text2(getText('money') + ': ' + (storage.money || 0), { size: 48, fill: 0xFFD700 }); moneyText.anchor.set(0.5, 0.5); moneyText.x = 0; moneyText.y = -650; self.addChild(moneyText); // Shop items - using actual inventory items var shopItems = [{ nameKey: 'smallMeat', asset: 'smallMeat', price: 10, storageKey: 'smallMeat' }, { nameKey: 'mediumMeat', asset: 'mediumMeat', price: 25, storageKey: 'mediumMeat' }, { nameKey: 'largeMeat', asset: 'largeMeat', price: 40, storageKey: 'largeMeat' }, { nameKey: 'sirloin', asset: 'sirloin', price: 60, storageKey: 'sirloin' }, { nameKey: 'blessing', asset: 'blessing', price: 50, storageKey: 'blessing' }, { nameKey: 'medicine', asset: 'medicine', price: 75, storageKey: 'medicine' }, { nameKey: 'soap', asset: 'soap', price: 400, storageKey: 'soap' }]; var itemButtons = []; // Arrange items in 2 columns of 3 rows - positioned in left area to avoid shopkeeper for (var i = 0; i < shopItems.length; i++) { var item = shopItems[i]; var itemContainer = new Container(); // Item icon background var itemBg = itemContainer.attachAsset('inventorySlot', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.6, scaleY: 1.6, tint: 0x795548 }); // Item icon var itemIcon = itemContainer.attachAsset(item.asset, { anchorX: 0.5, anchorY: 0.5, scaleX: 1.4, scaleY: 1.4 }); // Item name and price var itemText = new Text2(getText(item.nameKey) + '\n$' + item.price, { size: 32, fill: 0xFFFFFF }); itemText.anchor.set(0.5, 0); itemText.y = 75; itemContainer.addChild(itemText); // Position in grid (2 columns, 3 rows) - left side to avoid overlapping shopkeeper with more spacing var col = i % 2; var row = Math.floor(i / 2); itemContainer.x = -700 + col * 280; itemContainer.y = -500 + row * 250; itemContainer.itemData = item; itemContainer.down = function (x, y, obj) { tween(this, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); }; itemContainer.up = function (x, y, obj) { tween(this, { scaleX: 1, scaleY: 1 }, { duration: 100 }); // Stop event from bubbling up to prevent triggering other menus if (obj && obj.data && obj.data.originalEvent) { obj.data.originalEvent.stopPropagation(); } if ((storage.money || 0) >= this.itemData.price) { storage.money = (storage.money || 0) - this.itemData.price; storage[this.itemData.storageKey] = (storage[this.itemData.storageKey] || 0) + 1; moneyText.setText(getText('money') + ': ' + storage.money); // Immediately update main money display in GUI if (LK.gui.bottomLeft.children[0] && LK.gui.bottomLeft.children[0].children) { var moneyContainer = LK.gui.bottomLeft.children[0]; for (var i = 0; i < moneyContainer.children.length; i++) { var child = moneyContainer.children[i]; if (child.setText && typeof child.setText === 'function') { child.setText(getText('money') + ': ' + storage.money); break; } } } // Update global inventory reference if (typeof inventoryGlobal !== 'undefined' && inventoryGlobal && inventoryGlobal.updateDisplay) { inventoryGlobal.items[this.itemData.storageKey] = storage[this.itemData.storageKey] || 0; inventoryGlobal.updateDisplay(); } // Also check window reference as backup if (typeof window !== 'undefined' && window.inventoryRef && window.inventoryRef.updateDisplay) { window.inventoryRef.items[this.itemData.storageKey] = storage[this.itemData.storageKey] || 0; window.inventoryRef.updateDisplay(); } // Update shopkeeper text shopkeeperText.setText(getText('shopThanks')); LK.getSound('feed').play(); // Reset shopkeeper text after 2 seconds LK.setTimeout(function () { shopkeeperText.setText(getText('shopWelcome')); }, 2000); } else { // Not enough money shopkeeperText.setText(getText('shopNoMoney')); LK.setTimeout(function () { shopkeeperText.setText(getText('shopWelcome')); }, 2000); } }; self.addChild(itemContainer); itemButtons.push(itemContainer); } var closeButton = new ActionButton('Leave Shop', 0xF44336); closeButton.x = -600; closeButton.y = 600; closeButton.scaleX = 1.6; closeButton.scaleY = 1.6; closeButton.onPress = function () { LK.stopMusic(); LK.playMusic('Luna'); game.removeChild(shop); // Show the VI (stats button) again when leaving shop if (game.children.length > 0) { for (var i = 0; i < game.children.length; i++) { var child = game.children[i]; if (child.children && child.children.length > 0) { // Look for stats button (question mark button) for (var j = 0; j < child.children.length; j++) { var grandchild = child.children[j]; if (grandchild.children && grandchild.children.length > 0) { for (var k = 0; k < grandchild.children.length; k++) { var text = grandchild.children[k]; if (text.text && text.text === '?') { child.visible = true; break; } } } } } } } }; self.addChild(closeButton); // Ensure proper layering - bring shopkeeper and table to front self.removeChild(table); self.removeChild(shopkeeper); self.addChild(shopkeeper); // Shopkeeper has priority over items and dialogue self.addChild(table); // Table has highest priority return self; }); var StatBar = Container.expand(function (label, color, iconAsset) { var self = Container.call(this); var background = self.attachAsset('statBar', { anchorX: 0, anchorY: 0.5 }); var fill = self.attachAsset('statFill', { anchorX: 0, anchorY: 0.5, tint: color, scaleX: 1 }); // Add icon if provided if (iconAsset) { var icon = self.attachAsset(iconAsset, { anchorX: 0.5, anchorY: 0.5, x: -120, scaleX: 2.0, scaleY: 2.0 }); } var labelText = new Text2(label, { size: 25, fill: 0x333333 }); labelText.anchor.set(0, 0.5); labelText.x = -80; self.addChild(labelText); self.updateValue = function (value) { var percentage = Math.max(0, Math.min(100, value)) / 100; tween(fill, { scaleX: percentage }, { duration: 300, easing: tween.easeOut }); }; self.updateLabel = function (newLabel) { labelText.setText(newLabel); }; return self; }); var Training = Container.expand(function () { var self = Container.call(this); var trainingBg = self.attachAsset('gameArea', { anchorX: 0.5, anchorY: 0.5, scaleX: 6, scaleY: 6.5, tint: 0xFFF3E0 }); // Prevent training background from triggering external events trainingBg.down = function (x, y, obj) { // Stop event propagation to prevent triggering other menus if (obj && obj.data && obj.data.originalEvent) { obj.data.originalEvent.stopPropagation(); } }; trainingBg.up = function (x, y, obj) { // Stop event propagation to prevent triggering other menus if (obj && obj.data && obj.data.originalEvent) { obj.data.originalEvent.stopPropagation(); } }; var titleText = new Text2(getText('training'), { size: 100, fill: 0xE65100 }); titleText.anchor.set(0.5, 0.5); titleText.y = -850; self.addChild(titleText); // Training stats var attackBar = new TrainingBar(getText('attack'), 0xF44336, 100); attackBar.x = -200; attackBar.y = -600; attackBar.scaleX = 1.8; attackBar.scaleY = 1.8; self.addChild(attackBar); var healthBar = new TrainingBar(getText('health'), 0x4CAF50, 100); healthBar.x = -200; healthBar.y = -450; healthBar.scaleX = 1.8; healthBar.scaleY = 1.8; self.addChild(healthBar); var speedBar = new TrainingBar(getText('speed'), 0x2196F3, 100); speedBar.x = -200; speedBar.y = -300; speedBar.scaleX = 1.8; speedBar.scaleY = 1.8; self.addChild(speedBar); var weightText = new Text2(getText('weight') + ': ' + (pet.weight || 50), { size: 50, fill: 0x795548 }); weightText.anchor.set(0.5, 0.5); weightText.y = -120; self.addChild(weightText); // Training buttons with icons instead of text var trainAttackButton = new Container(); var attackIcon = trainAttackButton.attachAsset('target', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0, tint: 0xF44336 }); trainAttackButton.x = -300; trainAttackButton.y = 150; trainAttackButton.down = function (x, y, obj) { tween(this, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); }; trainAttackButton.up = function (x, y, obj) { tween(this, { scaleX: 1, scaleY: 1 }, { duration: 100 }); if (pet.fatigue < 90) { // Check fatigue instead of energy var maxStat = pet.evolutionLevel >= 6 ? 700 : 500; // Ultra level = 700, others = 500 pet.attack = Math.min(maxStat, (pet.attack || 0) + Math.floor(Math.random() * 2) + 1); pet.weight = Math.max(5, (pet.weight || 5) - 1); pet.train(); attackBar.updateValue(pet.attack); attackBar.maxValue = maxStat; weightText.setText(getText('weight') + ': ' + pet.weight); LK.getSound('play').play(); } }; self.addChild(trainAttackButton); var trainHealthButton = new Container(); var healthIcon = trainHealthButton.attachAsset('medicine', { anchorX: 0.5, anchorY: 0.5, scaleX: 3.0, scaleY: 3.0, tint: 0x4CAF50 }); trainHealthButton.x = 0; trainHealthButton.y = 150; trainHealthButton.down = function (x, y, obj) { tween(this, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); }; trainHealthButton.up = function (x, y, obj) { tween(this, { scaleX: 1, scaleY: 1 }, { duration: 100 }); if (pet.fatigue < 90) { // Check fatigue instead of energy var maxStat = pet.evolutionLevel >= 6 ? 700 : 500; // Ultra level = 700, others = 500 pet.health = Math.min(maxStat, (pet.health || 0) + Math.floor(Math.random() * 2) + 1); pet.weight = Math.max(5, (pet.weight || 5) - 1); pet.train(); healthBar.updateValue(pet.health); healthBar.maxValue = maxStat; weightText.setText(getText('weight') + ': ' + pet.weight); LK.getSound('play').play(); } }; self.addChild(trainHealthButton); var trainSpeedButton = new Container(); var speedIcon = trainSpeedButton.attachAsset('petEye', { anchorX: 0.5, anchorY: 0.5, scaleX: 4.0, scaleY: 4.0, tint: 0x2196F3 }); trainSpeedButton.x = 300; trainSpeedButton.y = 150; trainSpeedButton.down = function (x, y, obj) { tween(this, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); }; trainSpeedButton.up = function (x, y, obj) { tween(this, { scaleX: 1, scaleY: 1 }, { duration: 100 }); if (pet.fatigue < 90) { // Check fatigue instead of energy var maxStat = pet.evolutionLevel >= 6 ? 700 : 500; // Ultra level = 700, others = 500 pet.speed = Math.min(maxStat, (pet.speed || 0) + Math.floor(Math.random() * 2) + 1); pet.weight = Math.max(5, (pet.weight || 5) - 1); pet.train(); speedBar.updateValue(pet.speed); speedBar.maxValue = maxStat; weightText.setText(getText('weight') + ': ' + pet.weight); LK.getSound('play').play(); } }; self.addChild(trainSpeedButton); var closeButton = new ActionButton('X', 0xF44336); closeButton.x = 850; closeButton.y = -850; closeButton.scaleX = 1.5; closeButton.scaleY = 1.5; closeButton.onPress = function () { LK.stopMusic(); LK.playMusic('Luna'); game.removeChild(training); }; self.addChild(closeButton); self.updateBars = function () { attackBar.updateValue(pet.attack || 0); healthBar.updateValue(pet.health || 0); speedBar.updateValue(pet.speed || 0); weightText.setText(getText('weight') + ': ' + (pet.weight || 50)); }; return self; }); var TrainingBar = Container.expand(function (label, color, maxValue) { var self = Container.call(this); self.maxValue = maxValue; // Store maxValue as property var background = self.attachAsset('statBar', { anchorX: 0, anchorY: 0.5 }); var fill = self.attachAsset('statFill', { anchorX: 0, anchorY: 0.5, tint: color, scaleX: 0 }); var labelText = new Text2(label, { size: 35, fill: 0x333333 }); labelText.anchor.set(0, 0.5); labelText.x = -120; self.addChild(labelText); var valueText = new Text2('0/' + self.maxValue, { size: 30, fill: 0x333333 }); valueText.anchor.set(1, 0.5); valueText.x = 320; self.addChild(valueText); self.updateValue = function (value) { var percentage = Math.max(0, Math.min(self.maxValue, value)) / self.maxValue; tween(fill, { scaleX: percentage }, { duration: 300, easing: tween.easeOut }); valueText.setText(Math.floor(value) + '/' + self.maxValue); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xE8F5E8 }); /**** * Game Code ****/ // Game state management var gameState = 'menu'; // 'menu', 'game', 'pause' var gameData = storage.gameData || {}; // Language system var languages = { en: { feed: "Feed", play: "Play", sleep: "Sleep", hunger: "Hunger", happy: "Fun", energy: "Fatigue", evolutionLevel: "Evolution Level", score: "Score", time: "Time", newGame: "New Game", savedGames: "Saved Games", mainMenu: "Main Menu", digimonName: "Digimon Name", chooseEgg: "Choose Your Digi-Egg", money: "Money", shop: "Shop", training: "Training", attack: "Attack", health: "Health", speed: "Speed", defense: "Defense", weight: "Weight", locked: "Locked", buy: "Buy", train: "Train", shopWelcome: "Welcome to my shop!\nWhat would you like to buy?", shopThanks: "Thank you for your purchase!\nCome back anytime!", shopNoMoney: "Sorry, you don't have\nenough money for that!", smallMeat: "Small Meat", mediumMeat: "Medium Meat", largeMeat: "Large Meat", sirloin: "Sirloin", blessing: "Blessing", medicine: "Medicine", poopNeed: "Waste", hygiene: "Hygiene", soap: "Soap", friendship: "Friendship", namingTitle: "Name Your Digimon" }, es: { feed: "Alimentar", play: "Jugar", sleep: "Dormir", hunger: "Hambre", happy: "Diversión", energy: "Fatiga", evolutionLevel: "Nivel de Evolución", score: "Puntuación", time: "Tiempo", newGame: "Nuevo Juego", savedGames: "Partidas Guardadas", mainMenu: "Menú Principal", digimonName: "Nombre del Digimon", chooseEgg: "Elige tu Digi-Huevo", money: "Dinero", shop: "Tienda", training: "Entrenamiento", attack: "Ataque", health: "Vida", speed: "Velocidad", defense: "Defensa", weight: "Peso", locked: "Bloqueado", buy: "Comprar", train: "Entrenar", shopWelcome: "¡Bienvenido a mi tienda!\n¿Qué te gustaría comprar?", shopThanks: "¡Gracias por tu compra!\n¡Vuelve cuando quieras!", shopNoMoney: "¡Lo siento, no tienes\nsuficiente dinero para eso!", smallMeat: "Carne Pequeña", mediumMeat: "Carne Mediana", largeMeat: "Carne Grande", sirloin: "Solomillo", blessing: "Bendición", medicine: "Medicina", poopNeed: "Desechos", hygiene: "Higiene", soap: "Jabón", friendship: "Amistad", namingTitle: "Nombra a tu Digimon" } }; var currentLanguage = storage.currentLanguage || 'en'; function getText(key) { return languages[currentLanguage][key] || key; } function getCurrentDigimonName(eggType, evolutionLevel) { if (evolutionLines[eggType] && evolutionLines[eggType][evolutionLevel]) { return evolutionLines[eggType][evolutionLevel]; } return 'Digimon'; } // Game variables var mainMenu, pet, hungerBar, happinessBar, energyBar, poopNeedBar, hygieneBar, friendshipBar, evolutionText; var poopInstances = []; // Track all poop instances for cleanup timing var feedButton, playButton, sleepButton, shopButton, trainingButton; var shop, training; var centeredDigimonImage; // Reference to the centered Digimon image for updates // Evolution lines data var evolutionLines = [ // Line 0: Botamon → WarGreymon (Dragon and Fire line) ['Botamon', 'Koromon', 'Agumon', 'Greymon', 'MetalGreymon', 'WarGreymon'], // Line 1: Punimon → MetalGarurumon (Beast and Ice line) ['Punimon', 'Tsunomon', 'Gabumon', 'Garurumon', 'WereGarurumon', 'MetalGarurumon'], // Line 2: Poyomon → Seraphimon (Light line - Angemon path: more attack than speed, weight > 30) ['Poyomon', 'Tokomon', 'Patamon', 'Angemon', 'MagnaAngemon', 'Seraphimon'], // Line 3: Poyomon → Ophanimon (Light line - Angewomon path: more speed than attack, low weight) ['Poyomon', 'Tokomon', 'Patamon', 'Angewomon', 'Magnadramon', 'Ophanimon'], // Line 4: Reserved for future (Lightning/Electric line) ['DigiEgg', 'Fresh', 'InTraining', 'Rookie', 'Champion', 'Ultimate'], // Line 5: Reserved for future (Earth/Metal line) ['DigiEgg', 'Fresh', 'InTraining', 'Rookie', 'Champion', 'Ultimate']]; // Initialize money if not exists if (!storage.money) storage.money = 100; function updateCenteredDigimonImage() { if (!pet || !centeredDigimonImage || gameState !== 'game') return; // Get the correct asset for current evolution var evolutionAssets = [['botamon', 'koromon', 'agumon', 'greymon', 'metalgreymon', 'wargreymon'], ['punimon', 'tsunomon', 'gabumon', 'garurumon', 'weregarurumon', 'metalgarurumon'], ['poyomon', 'tokomon', 'patamon', 'angemon', 'magnaangemon', 'seraphimon'], ['poyomon', 'tokomon', 'patamon', 'angewomon', 'magnadramon', 'ophanimon'], ['botamon', 'koromon', 'agumon', 'greymon', 'metalgreymon', 'wargreymon'], ['punimon', 'tsunomon', 'gabumon', 'garurumon', 'weregarurumon', 'metalgarurumon']]; var actualEggType = pet.eggType; if ((pet.eggType === 2 || pet.eggType === 3) && pet.evolutionLevel >= 3) { if (pet.speed > pet.attack && pet.weight < 30) { actualEggType = 3; } else if (pet.attack >= pet.speed && pet.weight >= 30) { actualEggType = 2; } } var lineAssets = evolutionAssets[actualEggType] || evolutionAssets[0]; var newAssetName = lineAssets[pet.evolutionLevel] || lineAssets[0]; // Evolution animation: flash and scale effect tween(centeredDigimonImage, { alpha: 0, scaleX: centeredDigimonImage.scaleX * 1.5, scaleY: centeredDigimonImage.scaleY * 1.5 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { // Remove old image and create new one var oldX = centeredDigimonImage.x; var oldY = centeredDigimonImage.y; var oldScaleX = centeredDigimonImage.scaleX / 1.5; // Reset to original scale var oldScaleY = centeredDigimonImage.scaleY / 1.5; game.removeChild(centeredDigimonImage); // Create new centered Digimon image with correct asset centeredDigimonImage = game.attachAsset(newAssetName, { anchorX: 0.5, anchorY: 0.5, x: oldX, y: oldY, scaleX: oldScaleX, scaleY: oldScaleY, alpha: 0 }); // Animate the new image appearing tween(centeredDigimonImage, { alpha: 1, scaleX: oldScaleX * 1.2, scaleY: oldScaleY * 1.2 }, { duration: 400, easing: tween.bounceOut, onFinish: function onFinish() { tween(centeredDigimonImage, { scaleX: oldScaleX, scaleY: oldScaleY }, { duration: 200, easing: tween.easeOut }); } }); } }); } function updateAllTexts() { if (gameState === 'game') { // Update action buttons if (playButton) playButton.children[1].setText(getText('play')); if (sleepButton) sleepButton.children[1].setText(getText('sleep')); if (shopButton) shopButton.children[1].setText(getText('shop')); if (trainingButton) trainingButton.children[1].setText(getText('training')); // Update stat bar labels if (hungerBar) hungerBar.updateLabel(getText('hunger')); if (happinessBar) happinessBar.updateLabel(getText('happy')); if (energyBar) energyBar.updateLabel(getText('energy')); // Update evolution text if (evolutionText && pet) evolutionText.setText(getText('evolutionLevel') + ': ' + pet.evolutionLevel); } } function showMainMenu() { gameState = 'menu'; LK.playMusic('menuMusic'); game.removeChildren(); mainMenu = game.addChild(new MainMenu()); } function showEggSelection() { game.removeChildren(); // Add background for better contrast var eggSelectionBg = game.attachAsset('gameBackground', { anchorX: 0, anchorY: 0, x: 0, y: 0, scaleX: 1.0, scaleY: 1.0, tint: 0x1A237E, alpha: 0.9 }); var titleText = new Text2(getText('chooseEgg'), { size: 120, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 200; game.addChild(titleText); // Evolution line descriptions var eggDescriptions = ['Botamon Line\nBotamon → WarGreymon\nDragon • Fire', 'Punimon Line\nPunimon → MetalGarurumon\nBeast • Ice', 'Poyomon Line\nPoyomon → Seraphimon\nLight • Angemon Path', 'Poyomon Line\nPoyomon → Ophanimon\nLight • Angewomon Path', 'Lightning Line\nElectric • Speed • Energy', 'Earth Line\nRock • Metal • Defense']; // Create 6 eggs (3 unlocked, 3 locked) - larger layout var eggs = []; for (var i = 0; i < 6; i++) { var isLocked = i >= 3 && (storage.money || 0) < 500 && (storage.completedMissions || 0) < 1; var egg = new DigiEgg(i, isLocked); egg.x = 350 + i % 3 * 500; egg.y = 550 + Math.floor(i / 3) * 600; egg.scaleX = 1.8; egg.scaleY = 1.8; egg.onSelect = function (eggType) { showDigimonNaming(eggType); }; game.addChild(egg); eggs.push(egg); // Add evolution line description below each egg - larger text var lineText = new Text2(eggDescriptions[i], { size: 36, fill: 0xFFFFFF }); lineText.anchor.set(0.5, 0.5); lineText.x = egg.x; lineText.y = egg.y + 220; game.addChild(lineText); } var backButton = new ActionButton(getText('mainMenu'), 0x9E9E9E); backButton.x = 1024; backButton.y = 1600; backButton.scaleX = 1.8; backButton.scaleY = 1.8; backButton.onPress = function () { showMainMenu(); }; game.addChild(backButton); } function showSavedGames() { game.removeChildren(); // Add background to saved games screen var savedGamesBg = game.attachAsset('gameBackground', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366, scaleX: 1.2, scaleY: 1.2, tint: 0x4A90E2, alpha: 0.8 }); // Add decorative circles for visual appeal for (var i = 0; i < 6; i++) { var decorCircle = game.attachAsset('petEye', { anchorX: 0.5, anchorY: 0.5, x: (Math.random() - 0.5) * 2000 + 1024, y: (Math.random() - 0.5) * 2500 + 1366, scaleX: 1.5 + Math.random() * 2, scaleY: 1.5 + Math.random() * 2, tint: [0xFF6B6B, 0x4ECDC4, 0x45B7D1, 0x96CEB4, 0xFEA6A2, 0xDDA0DD][i], alpha: 0.3 }); } var titleText = new Text2(getText('savedGames'), { size: 60, fill: 0x2196F3 }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 400; game.addChild(titleText); // Check for saved games var saveCount = storage.saveCount || 0; var savedGames = []; for (var i = 0; i < saveCount; i++) { var petName = storage['save_' + i + '_petName']; if (petName) { var saveData = { petName: petName, evolutionLevel: storage['save_' + i + '_evolutionLevel'] || 0, saveIndex: i }; savedGames.push(saveData); } } if (savedGames.length === 0) { var noSavesText = new Text2('No saved games yet', { size: 40, fill: 0x666666 }); noSavesText.anchor.set(0.5, 0.5); noSavesText.x = 1024; noSavesText.y = 600; game.addChild(noSavesText); } else { // Display saved games with load and delete buttons for (var i = 0; i < savedGames.length && i < 5; i++) { var saveData = savedGames[i]; var loadButton = new ActionButton('Load: ' + saveData.petName + ' (Lv.' + saveData.evolutionLevel + ')', 0x4CAF50); loadButton.x = 800; loadButton.y = 500 + i * 120; loadButton.saveIndex = saveData.saveIndex; loadButton.onPress = function () { loadGame(this.saveIndex); }; game.addChild(loadButton); var deleteButton = new ActionButton('Delete', 0xF44336); deleteButton.x = 1300; deleteButton.y = 500 + i * 120; deleteButton.saveIndex = saveData.saveIndex; deleteButton.onPress = function () { deleteSave(this.saveIndex); showSavedGames(); // Refresh the saved games display }; game.addChild(deleteButton); } } // Add clear all saves button var clearAllButton = new ActionButton('Clear All Saves', 0x9E9E9E); clearAllButton.x = 1024; clearAllButton.y = 950; clearAllButton.onPress = function () { clearAllSaves(); showSavedGames(); // Refresh the display }; game.addChild(clearAllButton); var backButton = new ActionButton(getText('mainMenu'), 0x9E9E9E); backButton.x = 1024; backButton.y = 1050; backButton.onPress = function () { showMainMenu(); }; game.addChild(backButton); } function saveGame() { // Get current save count var saveCount = storage.saveCount || 0; // Store save data as individual properties instead of nested object var savePrefix = 'save_' + saveCount + '_'; // Check if save with same name exists and replace it var existingSaveIndex = -1; for (var i = 0; i < saveCount; i++) { var existingName = storage['save_' + i + '_petName']; if (existingName && existingName === pet.name) { existingSaveIndex = i; break; } } if (existingSaveIndex >= 0) { // Replace existing save savePrefix = 'save_' + existingSaveIndex + '_'; } else { // Add new save if (saveCount >= 5) { // Remove oldest save and shift all saves down for (var j = 0; j < 4; j++) { var oldPrefix = 'save_' + (j + 1) + '_'; var newPrefix = 'save_' + j + '_'; storage[newPrefix + 'petName'] = storage[oldPrefix + 'petName']; storage[newPrefix + 'evolutionLevel'] = storage[oldPrefix + 'evolutionLevel']; storage[newPrefix + 'hunger'] = storage[oldPrefix + 'hunger']; storage[newPrefix + 'happiness'] = storage[oldPrefix + 'happiness']; storage[newPrefix + 'fatigue'] = storage[oldPrefix + 'fatigue']; // Changed from energy to fatigue storage[newPrefix + 'attack'] = storage[oldPrefix + 'attack']; storage[newPrefix + 'health'] = storage[oldPrefix + 'health']; storage[newPrefix + 'speed'] = storage[oldPrefix + 'speed']; storage[newPrefix + 'weight'] = storage[oldPrefix + 'weight']; storage[newPrefix + 'eggType'] = storage[oldPrefix + 'eggType']; storage[newPrefix + 'money'] = storage[oldPrefix + 'money']; storage[newPrefix + 'timestamp'] = storage[oldPrefix + 'timestamp']; storage[newPrefix + 'birthTime'] = storage[oldPrefix + 'birthTime']; storage[newPrefix + 'poopNeed'] = storage[oldPrefix + 'poopNeed']; storage[newPrefix + 'hygiene'] = storage[oldPrefix + 'hygiene']; storage[newPrefix + 'friendship'] = storage[oldPrefix + 'friendship']; storage[newPrefix + 'wins'] = storage[oldPrefix + 'wins']; storage[newPrefix + 'battles'] = storage[oldPrefix + 'battles']; storage[newPrefix + 'injured'] = storage[oldPrefix + 'injured']; storage[newPrefix + 'sick'] = storage[oldPrefix + 'sick']; storage[newPrefix + 'injuryTime'] = storage[oldPrefix + 'injuryTime']; storage[newPrefix + 'sickTime'] = storage[oldPrefix + 'sickTime']; storage[newPrefix + 'hungerDeathTimer'] = storage[oldPrefix + 'hungerDeathTimer']; storage[newPrefix + 'lastPetTime'] = storage[oldPrefix + 'lastPetTime']; storage[newPrefix + 'smallMeat'] = storage[oldPrefix + 'smallMeat']; storage[newPrefix + 'mediumMeat'] = storage[oldPrefix + 'mediumMeat']; storage[newPrefix + 'largeMeat'] = storage[oldPrefix + 'largeMeat']; storage[newPrefix + 'sirloin'] = storage[oldPrefix + 'sirloin']; storage[newPrefix + 'blessing'] = storage[oldPrefix + 'blessing']; storage[newPrefix + 'medicine'] = storage[oldPrefix + 'medicine']; storage[newPrefix + 'soap'] = storage[oldPrefix + 'soap']; } savePrefix = 'save_4_'; } else { storage.saveCount = saveCount + 1; } } // Store individual properties - save ALL game data storage[savePrefix + 'petName'] = pet.name; storage[savePrefix + 'evolutionLevel'] = pet.evolutionLevel; storage[savePrefix + 'hunger'] = pet.hunger; storage[savePrefix + 'happiness'] = pet.happiness; storage[savePrefix + 'fatigue'] = pet.fatigue; // Changed from energy to fatigue storage[savePrefix + 'attack'] = pet.attack; storage[savePrefix + 'health'] = pet.health; storage[savePrefix + 'speed'] = pet.speed; storage[savePrefix + 'weight'] = pet.weight; storage[savePrefix + 'eggType'] = pet.eggType; storage[savePrefix + 'money'] = storage.money || 0; storage[savePrefix + 'timestamp'] = Date.now(); storage[savePrefix + 'birthTime'] = pet.birthTime || Date.now(); storage[savePrefix + 'poopNeed'] = pet.poopNeed || 0; storage[savePrefix + 'hygiene'] = pet.hygiene || 100; storage[savePrefix + 'friendship'] = pet.friendship || 0; storage[savePrefix + 'wins'] = pet.wins || 0; storage[savePrefix + 'battles'] = pet.battles || 0; storage[savePrefix + 'injured'] = pet.injured || false; storage[savePrefix + 'sick'] = pet.sick || false; storage[savePrefix + 'injuryTime'] = pet.injuryTime || 0; storage[savePrefix + 'sickTime'] = pet.sickTime || 0; storage[savePrefix + 'hungerDeathTimer'] = pet.hungerDeathTimer || 0; storage[savePrefix + 'lastPetTime'] = pet.lastPetTime || 0; storage[savePrefix + 'smallMeat'] = storage.smallMeat || 0; storage[savePrefix + 'mediumMeat'] = storage.mediumMeat || 0; storage[savePrefix + 'largeMeat'] = storage.largeMeat || 0; storage[savePrefix + 'sirloin'] = storage.sirloin || 0; storage[savePrefix + 'blessing'] = storage.blessing || 0; storage[savePrefix + 'medicine'] = storage.medicine || 0; storage[savePrefix + 'soap'] = storage.soap || 0; } function loadGame(saveIndex) { var savePrefix = 'save_' + saveIndex + '_'; var petName = storage[savePrefix + 'petName']; if (petName) { // First completely clear ALL current storage data to prevent conflicts var currentLanguage = storage.currentLanguage; // Preserve language setting var currentSaveCount = storage.saveCount; // Preserve save count var savedGames = {}; // Preserve all saved game data for (var i = 0; i < (currentSaveCount || 0); i++) { var tempPrefix = 'save_' + i + '_'; savedGames[tempPrefix + 'petName'] = storage[tempPrefix + 'petName']; savedGames[tempPrefix + 'evolutionLevel'] = storage[tempPrefix + 'evolutionLevel']; savedGames[tempPrefix + 'hunger'] = storage[tempPrefix + 'hunger']; savedGames[tempPrefix + 'happiness'] = storage[tempPrefix + 'happiness']; savedGames[tempPrefix + 'fatigue'] = storage[tempPrefix + 'fatigue']; savedGames[tempPrefix + 'attack'] = storage[tempPrefix + 'attack']; savedGames[tempPrefix + 'health'] = storage[tempPrefix + 'health']; savedGames[tempPrefix + 'speed'] = storage[tempPrefix + 'speed']; savedGames[tempPrefix + 'weight'] = storage[tempPrefix + 'weight']; savedGames[tempPrefix + 'eggType'] = storage[tempPrefix + 'eggType']; savedGames[tempPrefix + 'money'] = storage[tempPrefix + 'money']; savedGames[tempPrefix + 'timestamp'] = storage[tempPrefix + 'timestamp']; savedGames[tempPrefix + 'birthTime'] = storage[tempPrefix + 'birthTime']; savedGames[tempPrefix + 'poopNeed'] = storage[tempPrefix + 'poopNeed']; savedGames[tempPrefix + 'hygiene'] = storage[tempPrefix + 'hygiene']; savedGames[tempPrefix + 'friendship'] = storage[tempPrefix + 'friendship']; savedGames[tempPrefix + 'wins'] = storage[tempPrefix + 'wins']; savedGames[tempPrefix + 'battles'] = storage[tempPrefix + 'battles']; savedGames[tempPrefix + 'injured'] = storage[tempPrefix + 'injured']; savedGames[tempPrefix + 'sick'] = storage[tempPrefix + 'sick']; savedGames[tempPrefix + 'injuryTime'] = storage[tempPrefix + 'injuryTime']; savedGames[tempPrefix + 'sickTime'] = storage[tempPrefix + 'sickTime']; savedGames[tempPrefix + 'hungerDeathTimer'] = storage[tempPrefix + 'hungerDeathTimer']; savedGames[tempPrefix + 'lastPetTime'] = storage[tempPrefix + 'lastPetTime']; savedGames[tempPrefix + 'smallMeat'] = storage[tempPrefix + 'smallMeat']; savedGames[tempPrefix + 'mediumMeat'] = storage[tempPrefix + 'mediumMeat']; savedGames[tempPrefix + 'largeMeat'] = storage[tempPrefix + 'largeMeat']; savedGames[tempPrefix + 'sirloin'] = storage[tempPrefix + 'sirloin']; savedGames[tempPrefix + 'blessing'] = storage[tempPrefix + 'blessing']; savedGames[tempPrefix + 'medicine'] = storage[tempPrefix + 'medicine']; savedGames[tempPrefix + 'soap'] = storage[tempPrefix + 'soap']; } // Clear all current game data delete storage.petName; delete storage.evolutionLevel; delete storage.hunger; delete storage.happiness; delete storage.fatigue; delete storage.energy; // Remove old energy property delete storage.attack; delete storage.health; delete storage.speed; delete storage.weight; delete storage.eggType; delete storage.money; delete storage.birthTime; delete storage.poopNeed; delete storage.hygiene; delete storage.friendship; delete storage.wins; delete storage.battles; delete storage.injured; delete storage.sick; delete storage.injuryTime; delete storage.sickTime; delete storage.hungerDeathTimer; delete storage.lastPetTime; delete storage.smallMeat; delete storage.mediumMeat; delete storage.largeMeat; delete storage.sirloin; delete storage.blessing; delete storage.medicine; delete storage.soap; // Restore saved game data and language settings storage.currentLanguage = currentLanguage; storage.saveCount = currentSaveCount; // Restore saved games data using individual property assignments for (var i = 0; i < (currentSaveCount || 0); i++) { var tempPrefix = 'save_' + i + '_'; if (savedGames[tempPrefix + 'petName']) { // Use Object.defineProperty to properly set storage values for (var key in savedGames) { if (key.indexOf(tempPrefix) === 0 && savedGames[key] !== undefined) { Object.defineProperty(storage, key, { value: savedGames[key], writable: true, enumerable: true, configurable: true }); } } } } // Load the specific save data storage.petName = storage[savePrefix + 'petName']; storage.evolutionLevel = storage[savePrefix + 'evolutionLevel'] || 0; storage.hunger = storage[savePrefix + 'hunger'] || 100; storage.happiness = storage[savePrefix + 'happiness'] || 100; storage.fatigue = storage[savePrefix + 'fatigue'] || 0; storage.attack = storage[savePrefix + 'attack'] || 0; storage.health = storage[savePrefix + 'health'] || 0; storage.speed = storage[savePrefix + 'speed'] || 0; storage.weight = storage[savePrefix + 'weight'] || 5; storage.eggType = storage[savePrefix + 'eggType'] || 0; storage.money = storage[savePrefix + 'money'] || 100; storage.birthTime = storage[savePrefix + 'birthTime'] || Date.now(); storage.poopNeed = storage[savePrefix + 'poopNeed'] || 0; storage.hygiene = storage[savePrefix + 'hygiene'] || 100; storage.friendship = storage[savePrefix + 'friendship'] || 0; storage.wins = storage[savePrefix + 'wins'] || 0; storage.battles = storage[savePrefix + 'battles'] || 0; storage.injured = storage[savePrefix + 'injured'] || false; storage.sick = storage[savePrefix + 'sick'] || false; storage.injuryTime = storage[savePrefix + 'injuryTime'] || 0; storage.sickTime = storage[savePrefix + 'sickTime'] || 0; storage.hungerDeathTimer = storage[savePrefix + 'hungerDeathTimer'] || 0; storage.lastPetTime = storage[savePrefix + 'lastPetTime'] || 0; storage.smallMeat = storage[savePrefix + 'smallMeat'] || 0; storage.mediumMeat = storage[savePrefix + 'mediumMeat'] || 0; storage.largeMeat = storage[savePrefix + 'largeMeat'] || 0; storage.sirloin = storage[savePrefix + 'sirloin'] || 0; storage.blessing = storage[savePrefix + 'blessing'] || 0; storage.medicine = storage[savePrefix + 'medicine'] || 0; storage.soap = storage[savePrefix + 'soap'] || 0; // Load the game with the restored data gameState = 'game'; game.removeChildren(); initializeGameplay(); } } function deleteSave(saveIndex) { var savePrefix = 'save_' + saveIndex + '_'; // Delete all properties for this save delete storage[savePrefix + 'petName']; delete storage[savePrefix + 'evolutionLevel']; delete storage[savePrefix + 'hunger']; delete storage[savePrefix + 'happiness']; delete storage[savePrefix + 'fatigue']; delete storage[savePrefix + 'attack']; delete storage[savePrefix + 'health']; delete storage[savePrefix + 'speed']; delete storage[savePrefix + 'weight']; delete storage[savePrefix + 'eggType']; delete storage[savePrefix + 'money']; delete storage[savePrefix + 'timestamp']; delete storage[savePrefix + 'birthTime']; delete storage[savePrefix + 'poopNeed']; delete storage[savePrefix + 'hygiene']; delete storage[savePrefix + 'friendship']; delete storage[savePrefix + 'wins']; delete storage[savePrefix + 'battles']; delete storage[savePrefix + 'injured']; delete storage[savePrefix + 'sick']; delete storage[savePrefix + 'injuryTime']; delete storage[savePrefix + 'sickTime']; delete storage[savePrefix + 'hungerDeathTimer']; delete storage[savePrefix + 'lastPetTime']; delete storage[savePrefix + 'smallMeat']; delete storage[savePrefix + 'mediumMeat']; delete storage[savePrefix + 'largeMeat']; delete storage[savePrefix + 'sirloin']; delete storage[savePrefix + 'blessing']; delete storage[savePrefix + 'medicine']; delete storage[savePrefix + 'soap']; // Compact saves by moving all remaining saves down var saveCount = storage.saveCount || 0; for (var i = saveIndex; i < saveCount - 1; i++) { var currentPrefix = 'save_' + i + '_'; var nextPrefix = 'save_' + (i + 1) + '_'; storage[currentPrefix + 'petName'] = storage[nextPrefix + 'petName']; storage[currentPrefix + 'evolutionLevel'] = storage[nextPrefix + 'evolutionLevel']; storage[currentPrefix + 'hunger'] = storage[nextPrefix + 'hunger']; storage[currentPrefix + 'happiness'] = storage[nextPrefix + 'happiness']; storage[currentPrefix + 'fatigue'] = storage[nextPrefix + 'fatigue']; storage[currentPrefix + 'attack'] = storage[nextPrefix + 'attack']; storage[currentPrefix + 'health'] = storage[nextPrefix + 'health']; storage[currentPrefix + 'speed'] = storage[nextPrefix + 'speed']; storage[currentPrefix + 'weight'] = storage[nextPrefix + 'weight']; storage[currentPrefix + 'eggType'] = storage[nextPrefix + 'eggType']; storage[currentPrefix + 'money'] = storage[nextPrefix + 'money']; storage[currentPrefix + 'timestamp'] = storage[nextPrefix + 'timestamp']; storage[currentPrefix + 'birthTime'] = storage[nextPrefix + 'birthTime']; storage[currentPrefix + 'poopNeed'] = storage[nextPrefix + 'poopNeed']; storage[currentPrefix + 'hygiene'] = storage[nextPrefix + 'hygiene']; storage[currentPrefix + 'friendship'] = storage[nextPrefix + 'friendship']; storage[currentPrefix + 'wins'] = storage[nextPrefix + 'wins']; storage[currentPrefix + 'battles'] = storage[nextPrefix + 'battles']; storage[currentPrefix + 'injured'] = storage[nextPrefix + 'injured']; storage[currentPrefix + 'sick'] = storage[nextPrefix + 'sick']; storage[currentPrefix + 'injuryTime'] = storage[nextPrefix + 'injuryTime']; storage[currentPrefix + 'sickTime'] = storage[nextPrefix + 'sickTime']; storage[currentPrefix + 'hungerDeathTimer'] = storage[nextPrefix + 'hungerDeathTimer']; storage[currentPrefix + 'lastPetTime'] = storage[nextPrefix + 'lastPetTime']; storage[currentPrefix + 'smallMeat'] = storage[nextPrefix + 'smallMeat']; storage[currentPrefix + 'mediumMeat'] = storage[nextPrefix + 'mediumMeat']; storage[currentPrefix + 'largeMeat'] = storage[nextPrefix + 'largeMeat']; storage[currentPrefix + 'sirloin'] = storage[nextPrefix + 'sirloin']; storage[currentPrefix + 'blessing'] = storage[nextPrefix + 'blessing']; storage[currentPrefix + 'medicine'] = storage[nextPrefix + 'medicine']; storage[currentPrefix + 'soap'] = storage[nextPrefix + 'soap']; } // Clear the last save slot var lastPrefix = 'save_' + (saveCount - 1) + '_'; delete storage[lastPrefix + 'petName']; delete storage[lastPrefix + 'evolutionLevel']; delete storage[lastPrefix + 'hunger']; delete storage[lastPrefix + 'happiness']; delete storage[lastPrefix + 'fatigue']; delete storage[lastPrefix + 'attack']; delete storage[lastPrefix + 'health']; delete storage[lastPrefix + 'speed']; delete storage[lastPrefix + 'weight']; delete storage[lastPrefix + 'eggType']; delete storage[lastPrefix + 'money']; delete storage[lastPrefix + 'timestamp']; delete storage[lastPrefix + 'birthTime']; delete storage[lastPrefix + 'poopNeed']; delete storage[lastPrefix + 'hygiene']; delete storage[lastPrefix + 'friendship']; delete storage[lastPrefix + 'wins']; delete storage[lastPrefix + 'battles']; delete storage[lastPrefix + 'injured']; delete storage[lastPrefix + 'sick']; delete storage[lastPrefix + 'injuryTime']; delete storage[lastPrefix + 'sickTime']; delete storage[lastPrefix + 'hungerDeathTimer']; delete storage[lastPrefix + 'lastPetTime']; delete storage[lastPrefix + 'smallMeat']; delete storage[lastPrefix + 'mediumMeat']; delete storage[lastPrefix + 'largeMeat']; delete storage[lastPrefix + 'sirloin']; delete storage[lastPrefix + 'blessing']; delete storage[lastPrefix + 'medicine']; delete storage[lastPrefix + 'soap']; // Decrease save count storage.saveCount = Math.max(0, saveCount - 1); } function clearAllSaves() { var saveCount = storage.saveCount || 0; for (var i = 0; i < saveCount; i++) { var savePrefix = 'save_' + i + '_'; delete storage[savePrefix + 'petName']; delete storage[savePrefix + 'evolutionLevel']; delete storage[savePrefix + 'hunger']; delete storage[savePrefix + 'happiness']; delete storage[savePrefix + 'fatigue']; delete storage[savePrefix + 'attack']; delete storage[savePrefix + 'health']; delete storage[savePrefix + 'speed']; delete storage[savePrefix + 'weight']; delete storage[savePrefix + 'eggType']; delete storage[savePrefix + 'money']; delete storage[savePrefix + 'timestamp']; delete storage[savePrefix + 'birthTime']; delete storage[savePrefix + 'poopNeed']; delete storage[savePrefix + 'hygiene']; delete storage[savePrefix + 'friendship']; delete storage[savePrefix + 'wins']; delete storage[savePrefix + 'battles']; delete storage[savePrefix + 'injured']; delete storage[savePrefix + 'sick']; delete storage[savePrefix + 'injuryTime']; delete storage[savePrefix + 'sickTime']; delete storage[savePrefix + 'hungerDeathTimer']; delete storage[savePrefix + 'lastPetTime']; delete storage[savePrefix + 'smallMeat']; delete storage[savePrefix + 'mediumMeat']; delete storage[savePrefix + 'largeMeat']; delete storage[savePrefix + 'sirloin']; delete storage[savePrefix + 'blessing']; delete storage[savePrefix + 'medicine']; delete storage[savePrefix + 'soap']; } storage.saveCount = 0; } function showDigimonNaming(eggType) { game.removeChildren(); // Add full screen gradient background with better contrast var namingBg = game.attachAsset('gameBackground', { anchorX: 0, anchorY: 0, x: 0, y: 0, scaleX: 1.0, scaleY: 1.0, tint: 0x2A2A2A, alpha: 0.98 }); var titleText = new Text2(getText('digimonName') + ' (Max 7 chars)', { size: 90, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 350; game.addChild(titleText); var nameInputBg = game.attachAsset('gameArea', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 550, scaleX: 4.5, scaleY: 1.2, tint: 0xFFFFFF, alpha: 0.95 }); // Custom name input system var customName = ''; var nameText = new Text2(customName || 'Enter name...', { size: 85, fill: customName ? 0x333333 : 0x777777 }); nameText.anchor.set(0.5, 0.5); nameText.x = 1024; nameText.y = 550; // Add keyboard background panel for better organization var keyboardPanel = game.attachAsset('gameArea', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1100, scaleX: 7.5, scaleY: 4.2, tint: 0x424242, alpha: 0.9 }); // Add nameText after all background elements to ensure it appears on top game.addChild(nameText); // Add title text for the naming screen var namingTitleText = new Text2(getText('namingTitle'), { size: 70, fill: 0xFFFFFF }); namingTitleText.anchor.set(0.5, 0.5); namingTitleText.x = 1024; namingTitleText.y = 200; game.addChild(namingTitleText); // Character input keyboard - organized in 3 rows of 9 letters each var keyboard = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; var keyboardButtons = []; var startX = 180; var startY = 850; var keyWidth = 170; var keyHeight = 120; var keySpacing = 18; for (var i = 0; i < keyboard.length; i++) { var letter = keyboard[i]; var keyButton = new Container(); // Create key background with better contrast var keyBg = keyButton.attachAsset('keyboardBg', { anchorX: 0.5, anchorY: 0.5, scaleX: keyWidth / 120, scaleY: keyHeight / 80 }); // Add letter text with larger size var keyText = new Text2(letter, { size: 42, fill: 0xFFFFFF }); keyText.anchor.set(0.5, 0.5); keyButton.addChild(keyText); // Position in 3 rows of 9 var row = Math.floor(i / 9); var col = i % 9; keyButton.x = startX + col * (keyWidth + keySpacing); keyButton.y = startY + row * (keyHeight + keySpacing); keyButton.letter = letter; keyButton.down = function (x, y, obj) { tween(this, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); }; keyButton.up = function (x, y, obj) { tween(this, { scaleX: 1, scaleY: 1 }, { duration: 100 }); if (customName.length < 7) { customName += this.letter; nameText.setText(customName); nameText.fill = 0x333333; } }; game.addChild(keyButton); keyboardButtons.push(keyButton); } // Add space and delete buttons with better sizing for mobile var spaceButton = new Container(); var spaceBg = spaceButton.attachAsset('keyboardBg', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.5, scaleY: keyHeight / 80, tint: 0x6A1B9A }); var spaceText = new Text2('SPACE', { size: 36, fill: 0xFFFFFF }); spaceText.anchor.set(0.5, 0.5); spaceButton.addChild(spaceText); spaceButton.x = 700; spaceButton.y = startY + 3 * (keyHeight + keySpacing); spaceButton.down = function (x, y, obj) { tween(this, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); }; spaceButton.up = function (x, y, obj) { tween(this, { scaleX: 1, scaleY: 1 }, { duration: 100 }); if (customName.length < 7 && customName.length > 0) { customName += ' '; nameText.setText(customName); } }; game.addChild(spaceButton); var deleteButton = new Container(); var deleteBg = deleteButton.attachAsset('keyboardBg', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.8, scaleY: keyHeight / 80, tint: 0xF44336 }); var deleteText = new Text2('DELETE', { size: 34, fill: 0xFFFFFF }); deleteText.anchor.set(0.5, 0.5); deleteButton.addChild(deleteText); deleteButton.x = 1350; deleteButton.y = startY + 3 * (keyHeight + keySpacing); deleteButton.down = function (x, y, obj) { tween(this, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); }; deleteButton.up = function (x, y, obj) { tween(this, { scaleX: 1, scaleY: 1 }, { duration: 100 }); if (customName.length > 0) { customName = customName.slice(0, -1); nameText.setText(customName || 'Enter name...'); nameText.fill = customName ? 0x333333 : 0x999999; } }; game.addChild(deleteButton); var confirmButton = new ActionButton('OK', 0x4CAF50); confirmButton.x = 1024; confirmButton.y = 1450; confirmButton.onPress = function () { if (customName.length > 0) { storage.petName = customName; storage.eggType = eggType; startNewGame(); } }; game.addChild(confirmButton); var backButton = new ActionButton(getText('mainMenu'), 0x9E9E9E); backButton.x = 1024; backButton.y = 1550; backButton.onPress = function () { showEggSelection(); }; game.addChild(backButton); } function startNewGame() { gameState = 'game'; game.removeChildren(); // Clear ALL storage data for a completely fresh start // Core pet stats - all reset to starting values storage.hunger = 100; storage.happiness = 100; storage.fatigue = 0; storage.poopNeed = 0; storage.hygiene = 100; storage.friendship = 0; storage.evolutionLevel = 0; storage.attack = 0; storage.health = 0; storage.speed = 0; storage.weight = 5; storage.wins = 0; storage.battles = 0; storage.birthTime = Date.now(); // Set birth time for new pet // Health system storage.injured = false; storage.sick = false; storage.injuryTime = 0; storage.sickTime = 0; storage.hungerDeathTimer = 0; storage.lastPetTime = 0; // Reset petting timer for new game // Economy storage.money = 100; // Initialize starter inventory for new games storage.smallMeat = 10; storage.mediumMeat = 0; storage.largeMeat = 0; storage.sirloin = 0; storage.blessing = 5; storage.medicine = 3; storage.soap = 1; // Clear any other potential leftover data delete storage.energy; // Remove old energy property if it exists // Reset global game variables to prevent carryover if (pet) { pet = null; } hungerBar = null; happinessBar = null; energyBar = null; friendshipBar = null; poopInstances = []; // Clear poop tracking evolutionText = null; feedButton = null; playButton = null; sleepButton = null; shopButton = null; trainingButton = null; shop = null; training = null; initializeGameplay(); } function initializeGameplay() { // Add background image var background = game.attachAsset('gameBackground', { anchorX: 0, anchorY: 0, x: 0, y: 0 }); // Start game music LK.playMusic('Luna'); // Create pet with debugging console.log('Creating new DigitalPet'); pet = game.addChild(new DigitalPet()); pet.x = 1024; pet.y = 900; // Don't override scale here - let the pet manage its own scaling // Force pet visibility pet.visible = true; pet.alpha = 1; console.log('Pet created at position:', pet.x, pet.y, 'visible:', pet.visible); console.log('Pet children count:', pet.children.length); // Add debugging info about pet state LK.setTimeout(function () { console.log('Pet debug after 1 second:'); console.log('- Position:', pet.x, pet.y); console.log('- Scale:', pet.scaleX, pet.scaleY); console.log('- Alpha:', pet.alpha); console.log('- Visible:', pet.visible); console.log('- Children count:', pet.children.length); if (pet.children.length > 0) { for (var i = 0; i < pet.children.length; i++) { var child = pet.children[i]; console.log('-- Child', i, ':', 'visible:', child.visible, 'alpha:', child.alpha, 'scale:', child.scaleX); } } }, 1000); // UI Elements - scaled up for mobile hungerBar = new StatBar(getText('hunger'), 0xFF5722, 'hungerIcon'); hungerBar.x = 200; hungerBar.y = 300; hungerBar.scaleX = 1.5; hungerBar.scaleY = 1.5; game.addChild(hungerBar); happinessBar = new StatBar(getText('happy'), 0xFFEB3B, 'funIcon'); happinessBar.x = 200; happinessBar.y = 420; happinessBar.scaleX = 1.5; happinessBar.scaleY = 1.5; game.addChild(happinessBar); energyBar = new StatBar(getText('energy'), 0x2196F3, 'fatigueIcon'); // This will now show "Fatigue" energyBar.x = 200; energyBar.y = 540; energyBar.scaleX = 1.5; energyBar.scaleY = 1.5; game.addChild(energyBar); poopNeedBar = new StatBar(getText('poopNeed'), 0x8B4513, 'wasteIcon'); poopNeedBar.x = 200; poopNeedBar.y = 660; poopNeedBar.scaleX = 1.5; poopNeedBar.scaleY = 1.5; game.addChild(poopNeedBar); hygieneBar = new StatBar(getText('hygiene'), 0x00BCD4, 'hygieneIcon'); hygieneBar.x = 200; hygieneBar.y = 780; hygieneBar.scaleX = 1.5; hygieneBar.scaleY = 1.5; game.addChild(hygieneBar); friendshipBar = new StatBar(getText('friendship'), 0xE91E63, 'funIcon'); friendshipBar.x = 200; friendshipBar.y = 900; friendshipBar.scaleX = 1.5; friendshipBar.scaleY = 1.5; game.addChild(friendshipBar); // Inventory - scaled up and repositioned var inventory = new Inventory(); inventory.x = 200; inventory.y = 1800; inventory.scaleX = 1.8; inventory.scaleY = 1.8; game.addChild(inventory); // Store inventory reference globally for shop access var inventoryGlobal = inventory; if (typeof window !== 'undefined') { window.inventoryRef = inventory; } playButton = new ActionButton(getText('play'), 0xFF9800); playButton.x = 200; playButton.y = 1600; playButton.scaleX = 1.4; playButton.scaleY = 1.4; playButton.onPress = function () { if (pet.fatigue > 80) { // Check if too tired to play LK.effects.flashObject(pet, 0xFF0000, 500); return; } var miniGame = new MiniGame(); miniGame.x = 1024; miniGame.y = 1200; game.addChild(miniGame); miniGame.onGameEnd = function (score) { game.removeChild(miniGame); storage.money = (storage.money || 0) + score; }; miniGame.startGame(); }; game.addChild(playButton); sleepButton = new ActionButton(getText('sleep'), 0x9C27B0); sleepButton.x = 520; sleepButton.y = 1600; sleepButton.scaleX = 1.4; sleepButton.scaleY = 1.4; sleepButton.onPress = function () { pet.fatigue = Math.max(0, pet.fatigue - 30); // Reduce fatigue instead of increasing energy pet.hunger = Math.max(0, pet.hunger - 5); LK.getSound('sleep').play(); tween(pet, { alpha: 0.5 }, { duration: 500, onFinish: function onFinish() { tween(pet, { alpha: 1 }, { duration: 500 }); } }); }; game.addChild(sleepButton); shopButton = new ActionButton(getText('shop'), 0x795548); shopButton.x = 840; shopButton.y = 1600; shopButton.scaleX = 1.4; shopButton.scaleY = 1.4; shopButton.onPress = function () { LK.stopMusic(); LK.playMusic('shopMusic'); shop = game.addChild(new Shop()); shop.x = 1024; shop.y = 1366; // Don't pause game state so stats continue to update // Add floating animation to shopkeeper LK.setTimeout(function () { if (shop && shop.children[1]) { // shopkeeper is second child var shopkeeper = shop.children[1]; tween(shopkeeper, { y: shopkeeper.y - 30 }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { tween(shopkeeper, { y: shopkeeper.y + 30 }, { duration: 2000, easing: tween.easeInOut }); } }); } }, 500); }; game.addChild(shopButton); trainingButton = new ActionButton(getText('training'), 0xE65100); trainingButton.x = 1160; trainingButton.y = 1600; trainingButton.scaleX = 1.4; trainingButton.scaleY = 1.4; trainingButton.onPress = function () { LK.stopMusic(); LK.playMusic('trainingMusic'); training = game.addChild(new Training()); training.x = 1024; training.y = 1366; training.updateBars(); // Don't pause game state so stats continue to update }; game.addChild(trainingButton); // Add save game button var saveButton = new ActionButton('Save', 0x607D8B); saveButton.x = 1480; saveButton.y = 1600; saveButton.scaleX = 1.4; saveButton.scaleY = 1.4; saveButton.onPress = function () { if (pet) { saveGame(); LK.effects.flashScreen(0x4CAF50, 500); } }; game.addChild(saveButton); // Evolution display evolutionText = new Text2(getText('evolutionLevel') + ': 0', { size: 60, fill: 0x333333 }); evolutionText.anchor.set(0.5, 0); evolutionText.x = 1024; evolutionText.y = 680; game.addChild(evolutionText); // Current Digimon name display var digimonNameText = new Text2('', { size: 80, fill: 0x2196F3 }); digimonNameText.anchor.set(0.5, 0); digimonNameText.x = 1024; digimonNameText.y = 600; game.addChild(digimonNameText); // Add centered Digimon image with animation separate from pet stats var evolutionAssets = [['botamon', 'koromon', 'agumon', 'greymon', 'metalgreymon', 'wargreymon'], ['punimon', 'tsunomon', 'gabumon', 'garurumon', 'weregarurumon', 'metalgarurumon'], ['poyomon', 'tokomon', 'patamon', 'angemon', 'magnaangemon', 'seraphimon'], ['poyomon', 'tokomon', 'patamon', 'angewomon', 'magnadramon', 'ophanimon'], ['botamon', 'koromon', 'agumon', 'greymon', 'metalgreymon', 'wargreymon'], ['punimon', 'tsunomon', 'gabumon', 'garurumon', 'weregarurumon', 'metalgarurumon']]; var actualEggType = storage.eggType || 0; if ((storage.eggType === 2 || storage.eggType === 3) && (storage.evolutionLevel || 0) >= 3) { if ((storage.speed || 0) > (storage.attack || 0) && (storage.weight || 5) < 30) { actualEggType = 3; } else if ((storage.attack || 0) >= (storage.speed || 0) && (storage.weight || 5) >= 30) { actualEggType = 2; } } var lineAssets = evolutionAssets[actualEggType] || evolutionAssets[0]; var assetName = lineAssets[storage.evolutionLevel || 0] || lineAssets[0]; centeredDigimonImage = game.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1200, scaleX: 3.5, scaleY: 3.5 }); // Add breathing animation to centered Digimon image if (centeredDigimonImage) { tween(centeredDigimonImage, { scaleX: centeredDigimonImage.scaleX * 1.08, scaleY: centeredDigimonImage.scaleY * 1.08 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { if (centeredDigimonImage) { tween(centeredDigimonImage, { scaleX: centeredDigimonImage.scaleX / 1.08, scaleY: centeredDigimonImage.scaleY / 1.08 }, { duration: 1000, easing: tween.easeInOut }); } } }); } // Money display with background and coin icon - positioned in bottom left corner var moneyContainer = new Container(); var moneyBg = moneyContainer.attachAsset('inventorySlot', { anchorX: 0, anchorY: 0, scaleX: 3.5, scaleY: 1.2, tint: 0x4CAF50, alpha: 0.8 }); var moneyIcon = moneyContainer.attachAsset('petEye', { anchorX: 0.5, anchorY: 0.5, x: 50, y: 40, scaleX: 1.2, scaleY: 1.2, tint: 0xFFD700 }); var moneyText = new Text2(getText('money') + ': ' + (storage.money || 0), { size: 45, fill: 0xFFFFFF }); moneyText.anchor.set(0, 0.5); moneyText.x = 100; moneyText.y = 40; moneyContainer.addChild(moneyText); moneyContainer.x = 50; moneyContainer.y = -120; LK.gui.bottomLeft.addChild(moneyContainer); // Add question mark button for stats display var statsButton = new Container(); var statsBg = statsButton.attachAsset('questionIcon', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.2, tint: 0x2196F3 }); var statsText = new Text2('?', { size: 60, fill: 0xFFFFFF }); statsText.anchor.set(0.5, 0.5); statsButton.addChild(statsText); statsButton.x = 1800; statsButton.y = 400; statsButton.down = function (x, y, obj) { tween(this, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); }; statsButton.up = function (x, y, obj) { tween(this, { scaleX: 1, scaleY: 1 }, { duration: 100 }); if (pet) { pet.showStats(); } }; game.addChild(statsButton); updateAllTexts(); } // Language button var languageButton = new LanguageButton(); LK.gui.topRight.addChild(languageButton); languageButton.x = -120; languageButton.y = 80; // Start with main menu showMainMenu(); game.update = function () { if (gameState === 'game' && pet) { // Update stat bars hungerBar.updateValue(pet.hunger); happinessBar.updateValue(pet.happiness); energyBar.updateValue(pet.fatigue); // Use fatigue instead of energy poopNeedBar.updateValue(pet.poopNeed); hygieneBar.updateValue(pet.hygiene); friendshipBar.updateValue(pet.friendship); // Update evolution display evolutionText.setText(getText('evolutionLevel') + ': ' + pet.evolutionLevel); // Update current Digimon name display if (game.children[7] && game.children[7].setText) { // digimonNameText is now the 8th child (index 7) due to scaling changes var currentDigimonName = getCurrentDigimonName(pet.eggType, pet.evolutionLevel); game.children[7].setText(currentDigimonName); } // Digimon display is now handled by the pet itself with animations // Update money display immediately if (LK.gui.bottomLeft.children[0] && LK.gui.bottomLeft.children[0].children && LK.gui.bottomLeft.children[0].children.length > 0) { // Find the text element in the money container var moneyContainer = LK.gui.bottomLeft.children[0]; for (var i = 0; i < moneyContainer.children.length; i++) { var child = moneyContainer.children[i]; if (child.setText && typeof child.setText === 'function') { child.setText(getText('money') + ': ' + (storage.money || 0)); break; } } } // Warning effects for low stats if (pet.hunger < 20 && LK.ticks % 60 === 0) { LK.effects.flashObject(hungerBar, 0xFF0000, 300); } if (pet.happiness < 20 && LK.ticks % 60 === 0) { LK.effects.flashObject(happinessBar, 0xFF0000, 300); } if (pet.fatigue > 80 && LK.ticks % 60 === 0) { // Warning when fatigue is high LK.effects.flashObject(energyBar, 0xFF0000, 300); } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var ActionButton = Container.expand(function (text, color) {
var self = Container.call(this);
var buttonBg = self.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
tint: color,
scaleX: 1.4,
scaleY: 1.4
});
var buttonText = new Text2(text, {
size: 40,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
self.addChild(buttonText);
self.down = function (x, y, obj) {
tween(self, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100
});
};
self.up = function (x, y, obj) {
tween(self, {
scaleX: 1.4,
scaleY: 1.4
}, {
duration: 100
});
if (self.onPress) {
self.onPress();
}
};
return self;
});
var DigiEgg = Container.expand(function (eggType, isLocked) {
var self = Container.call(this);
// Use specific egg assets for each type
var eggAssetName = 'digiEgg' + eggType;
var eggGraphics = self.attachAsset(eggAssetName, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.0,
scaleY: 1.0
});
// Add pattern overlay for visual distinction
var patternShapes = ['ellipse', 'box', 'ellipse', 'box', 'ellipse', 'box'];
var patternColors = [0x66BB6A, 0x42A5F5, 0xFFB74D, 0xBA68C8, 0xEF5350, 0xFF7043];
var pattern = self.attachAsset('petEye', {
anchorX: 0.5,
anchorY: 0.5,
tint: patternColors[eggType],
scaleX: 0.6,
scaleY: 0.6,
alpha: 0.7
});
// Add small decorative spots
for (var i = 0; i < 3; i++) {
var spot = self.attachAsset('petEye', {
anchorX: 0.5,
anchorY: 0.5,
x: (Math.random() - 0.5) * 80,
y: (Math.random() - 0.5) * 100,
tint: patternColors[eggType],
scaleX: 0.2 + Math.random() * 0.2,
scaleY: 0.2 + Math.random() * 0.2,
alpha: 0.5
});
}
if (isLocked) {
var lockOverlay = self.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0x666666,
alpha: 0.7,
scaleX: 0.3,
scaleY: 0.3
});
var lockText = new Text2(getText('locked'), {
size: 20,
fill: 0xFFFFFF
});
lockText.anchor.set(0.5, 0.5);
lockText.y = 50;
self.addChild(lockText);
}
self.eggType = eggType;
self.isLocked = isLocked;
self.down = function (x, y, obj) {
if (!self.isLocked && self.onSelect) {
tween(self, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100
});
self.onSelect(self.eggType);
}
};
self.up = function (x, y, obj) {
if (!self.isLocked) {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
}
};
return self;
});
var DigitalPet = Container.expand(function () {
var self = Container.call(this);
// Pet graphics - will be updated based on evolution
var body = null;
// Pet stats
self.hunger = storage.hunger || 100;
self.happiness = storage.happiness || 100;
self.fatigue = storage.fatigue || 0; // Changed from energy to fatigue, starts at 0
self.poopNeed = storage.poopNeed || 0; // New waste stat that increases over time
self.hygiene = storage.hygiene || 100; // New hygiene stat that decreases when dirty
self.friendship = storage.friendship || 0; // New friendship stat with percentage, starts at 0
self.evolutionLevel = storage.evolutionLevel || 0;
self.attack = storage.attack || 0;
self.health = storage.health || 0;
self.speed = storage.speed || 0;
self.weight = storage.weight || 5;
self.name = storage.petName || 'Digimon';
self.eggType = storage.eggType || 0;
self.wins = storage.wins || 0;
self.battles = storage.battles || 0;
self.lastUpdateTime = Date.now();
self.lastPetTime = storage.lastPetTime || 0; // Track when pet was last petted
// Time-based evolution tracking
self.birthTime = storage.birthTime || Date.now();
// Health system
self.injured = storage.injured || false;
self.sick = storage.sick || false;
self.injuryTime = storage.injuryTime || 0;
self.sickTime = storage.sickTime || 0;
self.hungerDeathTimer = storage.hungerDeathTimer || 0;
// Stats display
self.statsDisplay = null;
self.showingStats = false;
// Health status icon
self.statusIcon = null;
// Evolution colors
self.evolutionColors = [0x4CAF50, 0x2196F3, 0xFF9800, 0x9C27B0, 0xF44336];
self.updateStatusIcon = function () {
// Remove existing status icon
if (self.statusIcon) {
self.removeChild(self.statusIcon);
self.statusIcon = null;
}
// Add status icon if injured or sick
if (self.injured || self.sick) {
self.statusIcon = new Container();
var iconBg = self.statusIcon.attachAsset('petEye', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2,
tint: self.sick ? 0x800080 : 0xFF0000 // Purple for sick, red for injured
});
var iconText = new Text2(self.sick ? '!' : '?', {
size: 40,
fill: 0xFFFFFF
});
iconText.anchor.set(0.5, 0.5);
self.statusIcon.addChild(iconText);
self.statusIcon.x = 0;
self.statusIcon.y = -150; // Position above Digimon
self.addChild(self.statusIcon);
// Pulsing animation
if (self.statusIcon) {
tween(self.statusIcon, {
alpha: 0.3
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (self.statusIcon) {
tween(self.statusIcon, {
alpha: 1
}, {
duration: 800,
easing: tween.easeInOut
});
}
}
});
}
}
};
self.updateAppearance = function () {
// Remove old body if exists
if (body) {
self.removeChild(body);
body = null;
}
// Choose asset based on evolution line and level - only use specific Digimon assets
var evolutionAssets = [
// Line 0: Botamon → WarGreymon (Dragon and Fire)
['botamon', 'koromon', 'agumon', 'greymon', 'metalgreymon', 'wargreymon'],
// Line 1: Punimon → MetalGarurumon (Beast and Ice)
['punimon', 'tsunomon', 'gabumon', 'garurumon', 'weregarurumon', 'metalgarurumon'],
// Line 2: Poyomon → Seraphimon (Light - Angemon path)
['poyomon', 'tokomon', 'patamon', 'angemon', 'magnaangemon', 'seraphimon'],
// Line 3: Poyomon → Ophanimon (Light - Angewomon path)
['poyomon', 'tokomon', 'patamon', 'angewomon', 'magnadramon', 'ophanimon'],
// Line 4: Use Line 0 as fallback
['botamon', 'koromon', 'agumon', 'greymon', 'metalgreymon', 'wargreymon'],
// Line 5: Use Line 1 as fallback
['punimon', 'tsunomon', 'gabumon', 'garurumon', 'weregarurumon', 'metalgarurumon']];
// Special logic for Poyomon evolution path determination
var actualEggType = self.eggType;
if (self.eggType === 2 || self.eggType === 3) {
// Both egg types 2 and 3 start as Poyomon but evolve differently based on stats
if (self.evolutionLevel >= 3) {
// At Patamon level and beyond, check stats
if (self.speed > self.attack && self.weight < 30) {
// More speed than attack and low weight → Angewomon path
actualEggType = 3;
} else if (self.attack >= self.speed && self.weight >= 30) {
// More attack than speed and higher weight → Angemon path
actualEggType = 2;
}
// If neither condition is met, keep current path
}
}
var lineAssets = evolutionAssets[actualEggType] || evolutionAssets[0];
var assetName = lineAssets[self.evolutionLevel] || lineAssets[0];
// Debug logging
console.log('CREATING DIGIMON - Asset:', assetName, 'EggType:', self.eggType, 'Evolution:', self.evolutionLevel);
// Create main body with specific Digimon asset (no shadow)
body = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 0,
visible: true,
alpha: 1,
scaleX: 3.0,
scaleY: 3.0
});
console.log('DIGIMON SPRITE - Successfully created with asset:', assetName);
// Enhanced visibility and scaling
if (body) {
body.visible = true;
body.alpha = 1;
// Update the pet's display name based on evolution
self.currentDigimonName = getCurrentDigimonName(self.eggType, self.evolutionLevel);
// Larger scale for better visibility
var evolutionScale = 3.0 + self.evolutionLevel * 0.3;
var eggTypeScale = 1.0 + self.eggType * 0.1;
var finalScale = evolutionScale * eggTypeScale;
body.scaleX = finalScale;
body.scaleY = finalScale;
console.log('DIGIMON SPRITE FINAL - Scale:', finalScale, 'Visible:', body.visible, 'Alpha:', body.alpha);
console.log('DIGIMON SPRITE POSITION - X:', body.x, 'Y:', body.y);
console.log('DIGIMON SPRITE DIMENSIONS - Width:', body.width, 'Height:', body.height);
} else {
console.log('ERROR: DIGIMON SPRITE is null after creation!');
}
// Force a refresh of the container
self.visible = true;
self.alpha = 1;
console.log('PET CONTAINER - Visible:', self.visible, 'Alpha:', self.alpha, 'Children:', self.children.length);
};
// Initialize appearance with debugging
console.log('Initializing Digimon appearance');
self.updateAppearance();
// Single delayed update to ensure asset is loaded
LK.setTimeout(function () {
console.log('Delayed update at 200ms to ensure asset loading');
self.updateAppearance();
if (body) {
console.log('200ms: Body confirmed - visible:', body.visible, 'alpha:', body.alpha, 'scale:', body.scaleX);
}
}, 200);
self.evolveCheck = function () {
// Time-based evolution with different times for each stage
var evolutionTimes = [5 * 60 * 1000,
// Baby 1 to Baby 2: 5 minutes
15 * 60 * 1000,
// Baby 2 to Novato: 15 minutes
60 * 60 * 1000,
// Novato to Campeón: 1 hour
5 * 60 * 60 * 1000,
// Campeón to Perfecto: 5 hours
24 * 60 * 60 * 1000 // Perfecto to Mega: 1 day
];
var currentTime = Date.now();
// Initialize birth time if not set
if (!self.birthTime) {
self.birthTime = storage.birthTime || currentTime;
storage.birthTime = self.birthTime;
}
var ageInMilliseconds = currentTime - self.birthTime;
var targetLevel = 0;
var accumulatedTime = 0;
// Calculate target level based on accumulated evolution times
for (var i = 0; i < evolutionTimes.length && i < self.evolutionColors.length - 1; i++) {
accumulatedTime += evolutionTimes[i];
if (ageInMilliseconds >= accumulatedTime) {
targetLevel = i + 1;
} else {
break;
}
}
// Cap evolution level to maximum available
var maxLevel = self.evolutionColors.length - 1;
targetLevel = Math.min(targetLevel, maxLevel);
if (targetLevel > self.evolutionLevel) {
self.evolutionLevel = targetLevel;
LK.getSound('evolve').play();
// Evolution animation
tween(self, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 500,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.easeOut
});
}
});
self.updateAppearance();
// Update the centered Digimon image in the main game view
if (typeof updateCenteredDigimonImage === 'function') {
updateCenteredDigimonImage();
}
LK.effects.flashScreen(0xFFD700, 1000);
}
};
self.update = function () {
var currentTime = Date.now();
var deltaTime = (currentTime - self.lastUpdateTime) / 1000;
self.lastUpdateTime = currentTime;
// Decay stats over time - hunger no longer decreases automatically
// self.hunger = Math.max(0, self.hunger - deltaTime * 2); // Removed automatic hunger decrease
self.happiness = Math.max(0, self.happiness - deltaTime * 0.1); // Much slower happiness decrease (fun bar)
// Energy is now fatigue - it doesn't decrease automatically, only increases during training
// Increase poop need over time
self.poopNeed = Math.min(100, self.poopNeed + deltaTime * 0.8);
// Hygiene decreases slowly over time
self.hygiene = Math.max(0, self.hygiene - deltaTime * 0.05);
// When poop need reaches 100, create poop and reset
if (self.poopNeed >= 100) {
self.createPoop();
self.poopNeed = 0;
self.hygiene = Math.max(0, self.hygiene - 20); // Reduce hygiene when pooping
}
// Check for old poop and degrade hygiene and friendship if not cleaned
for (var i = 0; i < poopInstances.length; i++) {
var poopObj = poopInstances[i];
if (poopObj.ageTime === undefined) poopObj.ageTime = 0;
poopObj.ageTime += deltaTime;
// After 60 seconds, start degrading hygiene and friendship
if (poopObj.ageTime > 60) {
self.hygiene = Math.max(0, self.hygiene - deltaTime * 0.2);
self.friendship = Math.max(0, self.friendship - deltaTime * 0.1);
}
}
// Health system timers
if (self.injured) {
self.injuryTime += deltaTime;
// After 30 minutes (1800 seconds) injury becomes sickness
if (self.injuryTime >= 1800) {
self.injured = false;
self.sick = true;
self.injuryTime = 0;
self.sickTime = 0;
LK.effects.flashObject(self, 0x800080, 1000);
}
}
if (self.sick) {
self.sickTime += deltaTime;
// Sick Digimon dies after some time without medicine
if (self.sickTime >= 300) {
// 5 minutes
self.die();
return;
}
}
// Hunger death timer
if (self.hunger <= 0) {
self.hungerDeathTimer += deltaTime;
if (self.hungerDeathTimer >= 300) {
// 5 minutes
self.die();
return;
}
} else {
self.hungerDeathTimer = 0;
}
// Simple visibility check every 5 seconds
if (LK.ticks % 300 === 0) {
console.log('VISIBILITY CHECK - Tick:', LK.ticks);
if (body) {
console.log('DIGIMON SPRITE - Visible:', body.visible, 'Alpha:', body.alpha, 'Scale:', body.scaleX);
}
console.log('PET CONTAINER - Visible:', self.visible, 'Alpha:', self.alpha, 'Children:', self.children.length);
}
// Enhanced idle animation with multiple effects
if (LK.ticks % 120 === 0) {
// Bouncing animation
tween(self, {
y: self.y - 20
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self, {
y: self.y + 20
}, {
duration: 500,
easing: tween.easeInOut
});
}
});
}
// Additional breathing animation every 180 ticks - only on the body
if (LK.ticks % 180 === 0 && body) {
tween(body, {
scaleX: body.scaleX * 1.05,
scaleY: body.scaleY * 1.05
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (body) {
tween(body, {
scaleX: body.scaleX / 1.05,
scaleY: body.scaleY / 1.05
}, {
duration: 800,
easing: tween.easeInOut
});
}
}
});
}
// Subtle rotation animation every 240 ticks
if (LK.ticks % 240 === 0) {
var randomRotation = (Math.random() - 0.5) * 0.2; // Small random rotation
tween(self, {
rotation: randomRotation
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self, {
rotation: 0
}, {
duration: 1000,
easing: tween.easeInOut
});
}
});
}
self.updateAppearance();
self.updateStatusIcon(); // Update health status icon
self.evolveCheck();
// Calculate defense based on weight
self.defense = Math.floor(self.weight / 2);
// Save stats
storage.hunger = self.hunger;
storage.happiness = self.happiness;
storage.fatigue = self.fatigue; // Changed from energy to fatigue
storage.poopNeed = self.poopNeed;
storage.hygiene = self.hygiene;
storage.evolutionLevel = self.evolutionLevel;
storage.attack = self.attack;
storage.health = self.health;
storage.speed = self.speed;
storage.weight = self.weight;
storage.petName = self.name;
storage.eggType = self.eggType;
storage.wins = self.wins;
storage.battles = self.battles;
storage.injured = self.injured;
storage.sick = self.sick;
storage.injuryTime = self.injuryTime;
storage.sickTime = self.sickTime;
storage.hungerDeathTimer = self.hungerDeathTimer;
storage.birthTime = self.birthTime;
storage.friendship = self.friendship;
storage.lastPetTime = self.lastPetTime;
};
self.down = function (x, y, obj) {
// Petting functionality - once per day
var currentTime = Date.now();
var dayInMs = 24 * 60 * 60 * 1000; // 24 hours in milliseconds
if (currentTime - self.lastPetTime >= dayInMs) {
// Can pet the digimon
var friendshipGain = 4 + Math.floor(Math.random() * 2); // 4-5 points
self.friendship = Math.min(100, self.friendship + friendshipGain);
self.lastPetTime = currentTime;
storage.lastPetTime = self.lastPetTime;
storage.friendship = self.friendship;
// Visual feedback for petting
LK.effects.flashObject(self, 0xFF69B4, 1000); // Pink flash for petting
tween(self, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeOut
});
}
});
} else {
// Show time remaining until next pet
var timeRemaining = dayInMs - (currentTime - self.lastPetTime);
var hoursRemaining = Math.ceil(timeRemaining / (60 * 60 * 1000));
// Could show a message here, but keeping it simple for now
LK.effects.flashObject(self, 0x888888, 300); // Gray flash when can't pet
}
};
self.showStats = function () {
if (self.statsDisplay) return;
self.showingStats = true;
var winRate = self.battles > 0 ? Math.round(self.wins / self.battles * 100) : 0;
self.statsDisplay = new Container();
var statsBg = self.statsDisplay.attachAsset('gameArea', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 3.5,
tint: 0x263238,
alpha: 0.9
});
// Get current Digimon asset name
var evolutionAssets = [['botamon', 'koromon', 'agumon', 'greymon', 'metalgreymon', 'wargreymon'], ['punimon', 'tsunomon', 'gabumon', 'garurumon', 'weregarurumon', 'metalgarurumon'], ['poyomon', 'tokomon', 'patamon', 'angemon', 'magnaangemon', 'seraphimon'], ['poyomon', 'tokomon', 'patamon', 'angewomon', 'magnadramon', 'ophanimon'], ['botamon', 'koromon', 'agumon', 'greymon', 'metalgreymon', 'wargreymon'], ['punimon', 'tsunomon', 'gabumon', 'garurumon', 'weregarurumon', 'metalgarurumon']];
var actualEggType = self.eggType;
if (self.eggType === 2 || self.eggType === 3) {
if (self.evolutionLevel >= 3) {
if (self.speed > self.attack && self.weight < 30) {
actualEggType = 3;
} else if (self.attack >= self.speed && self.weight >= 30) {
actualEggType = 2;
}
}
}
var lineAssets = evolutionAssets[actualEggType] || evolutionAssets[0];
var assetName = lineAssets[self.evolutionLevel] || lineAssets[0];
var currentDigimonName = getCurrentDigimonName(self.eggType, self.evolutionLevel);
// Calculate evolution timer
var evolutionTimes = [5 * 60 * 1000,
// Baby 1 to Baby 2: 5 minutes
15 * 60 * 1000,
// Baby 2 to Novato: 15 minutes
60 * 60 * 1000,
// Novato to Campeón: 1 hour
5 * 60 * 60 * 1000,
// Campeón to Perfecto: 5 hours
24 * 60 * 60 * 1000 // Perfecto to Mega: 1 day
];
var currentTime = Date.now();
var ageInMilliseconds = currentTime - (self.birthTime || currentTime);
var accumulatedTime = 0;
var timeToNextEvolution = 0;
var evolutionTimerText = "";
if (self.evolutionLevel < evolutionTimes.length) {
// Calculate accumulated time for current level
for (var i = 0; i < self.evolutionLevel && i < evolutionTimes.length; i++) {
accumulatedTime += evolutionTimes[i];
}
// Calculate time remaining for next evolution
var nextEvolutionTime = accumulatedTime + evolutionTimes[self.evolutionLevel];
timeToNextEvolution = Math.max(0, nextEvolutionTime - ageInMilliseconds);
if (timeToNextEvolution > 0) {
var hours = Math.floor(timeToNextEvolution / (60 * 60 * 1000));
var minutes = Math.floor(timeToNextEvolution % (60 * 60 * 1000) / (60 * 1000));
var seconds = Math.floor(timeToNextEvolution % (60 * 1000) / 1000);
if (hours > 0) {
evolutionTimerText = 'Next Evolution: ' + hours + 'h ' + minutes + 'm ' + seconds + 's';
} else if (minutes > 0) {
evolutionTimerText = 'Next Evolution: ' + minutes + 'm ' + seconds + 's';
} else {
evolutionTimerText = 'Next Evolution: ' + seconds + 's';
}
} else {
evolutionTimerText = 'Evolution Ready!';
}
} else {
evolutionTimerText = 'Max Evolution Reached';
}
var friendshipLevel = Math.floor(self.friendship / 20); // 0-5 friendship levels
var criticalChance = Math.min(25, Math.floor(self.friendship / 4)); // Max 25% critical chance at 100% friendship
var statsText = new Text2(self.name + ' (' + currentDigimonName + ')' + '\n\n' + getText('evolutionLevel') + ': ' + self.evolutionLevel + '\n' + evolutionTimerText + '\n\n' + getText('attack') + ': ' + Math.floor(self.attack) + '\n' + getText('health') + ': ' + Math.floor(self.health) + '\n' + getText('speed') + ': ' + Math.floor(self.speed) + '\n' + getText('defense') + ': ' + Math.floor(self.defense) + '\n' + getText('weight') + ': ' + Math.floor(self.weight) + '\n' + getText('friendship') + ': ' + Math.floor(self.friendship) + '%\n' + 'Critical Chance: ' + criticalChance + '%\n' + 'Win Rate: ' + winRate + '%', {
size: 45,
fill: 0xFFFFFF
});
statsText.anchor.set(0.5, 0.5);
statsText.y = 50;
self.statsDisplay.addChild(statsText);
self.statsDisplay.x = 0;
self.statsDisplay.y = -200;
self.addChild(self.statsDisplay);
// Auto hide after 3 seconds
LK.setTimeout(function () {
if (self.showingStats) {
self.hideStats();
}
}, 3000);
};
self.hideStats = function () {
if (self.statsDisplay) {
self.removeChild(self.statsDisplay);
self.statsDisplay = null;
self.showingStats = false;
}
};
self.die = function () {
LK.effects.flashScreen(0x000000, 2000);
LK.setTimeout(function () {
// Clear all storage and restart
storage.hunger = 100;
storage.happiness = 100;
storage.fatigue = 0;
storage.evolutionLevel = 0;
storage.attack = 10;
storage.health = 50;
storage.speed = 30;
storage.weight = 50;
storage.injured = false;
storage.sick = false;
storage.injuryTime = 0;
storage.sickTime = 0;
storage.hungerDeathTimer = 0;
storage.birthTime = Date.now(); // Reset birth time for new pet
// Give new starter items
storage.smallMeat = 10;
storage.blessing = 5;
storage.medicine = 3;
showMainMenu();
}, 2000);
};
self.createPoop = function () {
// Create poop near the digimon using new poop asset
var poop = game.attachAsset('poop', {
anchorX: 0.5,
anchorY: 0.5,
x: self.x + (Math.random() - 0.5) * 300,
y: self.y + (Math.random() - 0.5) * 200,
scaleX: 1.5,
scaleY: 1.5
});
// Add click handler to clean poop
poop.down = function (x, y, obj) {
// Clean poop and restore hygiene
var hygieneRestore = 20; // Amount of hygiene lost when pooping
self.hygiene = Math.min(100, self.hygiene + hygieneRestore);
// Remove poop from game and tracking array
game.removeChild(poop);
for (var j = 0; j < poopInstances.length; j++) {
if (poopInstances[j] === poop) {
poopInstances.splice(j, 1);
break;
}
}
LK.effects.flashObject(self, 0x00BCD4, 500); // Blue flash for cleaning
};
// Add to tracking array
poop.ageTime = 0;
poopInstances.push(poop);
// Auto cleanup after 5 minutes if not cleaned manually
LK.setTimeout(function () {
if (poop && poop.parent) {
game.removeChild(poop);
// Remove from tracking array
for (var j = 0; j < poopInstances.length; j++) {
if (poopInstances[j] === poop) {
poopInstances.splice(j, 1);
break;
}
}
}
}, 300000); // 5 minutes
// Flash effect when poop is created
LK.effects.flashObject(self, 0x8B4513, 500);
// Play poop sound effect
LK.getSound('poop').play();
};
self.train = function () {
// Increase fatigue during training
self.fatigue = Math.min(100, self.fatigue + 15);
if (self.fatigue > 80) {
// Training while tired causes injury
if (!self.injured && !self.sick) {
self.injured = true;
self.injuryTime = 0;
LK.effects.flashObject(self, 0xFF0000, 1000);
}
}
// Reduce hunger slightly during training
self.hunger = Math.max(0, self.hunger - 3);
};
return self;
});
var Inventory = Container.expand(function () {
var self = Container.call(this);
// Initialize inventory items
self.items = {
smallMeat: storage.smallMeat || 0,
mediumMeat: storage.mediumMeat || 0,
largeMeat: storage.largeMeat || 0,
sirloin: storage.sirloin || 0,
blessing: storage.blessing || 0,
medicine: storage.medicine || 0,
soap: storage.soap || 0
};
self.slots = [];
// Create inventory slots
var itemTypes = ['smallMeat', 'mediumMeat', 'largeMeat', 'sirloin', 'blessing', 'medicine', 'soap'];
for (var i = 0; i < itemTypes.length; i++) {
var slot = new Container();
var slotBg = slot.attachAsset('inventorySlot', {
anchorX: 0.5,
anchorY: 0.5
});
var itemIcon = slot.attachAsset(itemTypes[i], {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2
});
var countText = new Text2('0', {
size: 18,
fill: 0xFFFFFF
});
countText.anchor.set(0.5, 1);
countText.y = 35;
slot.addChild(countText);
slot.itemType = itemTypes[i];
slot.x = i * 120;
slot.y = 0;
slot.down = function (x, y, obj) {
if (self.items[this.itemType] > 0) {
self.useItem(this.itemType);
}
};
self.addChild(slot);
self.slots.push(slot);
}
self.useItem = function (itemType) {
if (self.items[itemType] <= 0) return;
self.items[itemType]--;
switch (itemType) {
case 'smallMeat':
pet.hunger = Math.min(100, pet.hunger + 15);
pet.friendship = Math.min(100, pet.friendship + 1);
break;
case 'mediumMeat':
pet.hunger = Math.min(100, pet.hunger + 30);
pet.friendship = Math.min(100, pet.friendship + 1);
break;
case 'largeMeat':
pet.hunger = Math.min(100, pet.hunger + 50);
pet.friendship = Math.min(100, pet.friendship + 1);
break;
case 'sirloin':
pet.hunger = Math.min(100, pet.hunger + 75);
pet.friendship = Math.min(100, pet.friendship + 1);
break;
case 'blessing':
if (pet.injured) {
pet.injured = false;
pet.injuryTime = 0;
LK.effects.flashObject(pet, 0xFFD700, 1000);
}
break;
case 'medicine':
if (pet.sick) {
pet.sick = false;
pet.sickTime = 0;
LK.effects.flashObject(pet, 0x4CAF50, 1000);
}
break;
case 'soap':
pet.hygiene = Math.min(100, pet.hygiene + 50);
pet.friendship = Math.min(100, pet.friendship + 10); // Soap also increases friendship
LK.effects.flashObject(pet, 0x00BCD4, 1000);
break;
}
self.updateDisplay();
self.saveItems();
LK.getSound('feed').play();
};
self.updateDisplay = function () {
for (var i = 0; i < self.slots.length; i++) {
var slot = self.slots[i];
var count = self.items[slot.itemType];
slot.children[2].setText(count.toString());
}
};
self.saveItems = function () {
storage.smallMeat = self.items.smallMeat;
storage.mediumMeat = self.items.mediumMeat;
storage.largeMeat = self.items.largeMeat;
storage.sirloin = self.items.sirloin;
storage.blessing = self.items.blessing;
storage.medicine = self.items.medicine;
storage.soap = self.items.soap;
};
self.updateDisplay();
return self;
});
var LanguageButton = Container.expand(function () {
var self = Container.call(this);
var buttonBg = self.attachAsset('languageButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.5,
scaleY: 2.5
});
var flagEN = self.attachAsset('flagEN', {
anchorX: 0.5,
anchorY: 0.5,
x: -25,
scaleX: 1.0,
scaleY: 1.0
});
var flagES = self.attachAsset('flagES', {
anchorX: 0.5,
anchorY: 0.5,
x: 25,
scaleX: 1.0,
scaleY: 1.0
});
// Add EN/ES text overlay
var textEN = new Text2('EN', {
size: 24,
fill: 0xFFFFFF
});
textEN.anchor.set(0.5, 0.5);
textEN.x = -25;
flagEN.addChild(textEN);
var textES = new Text2('ES', {
size: 24,
fill: 0xFFFFFF
});
textES.anchor.set(0.5, 0.5);
textES.x = 25;
flagES.addChild(textES);
self.updateDisplay = function () {
if (currentLanguage === 'en') {
flagEN.alpha = 1;
flagES.alpha = 0.5;
} else {
flagEN.alpha = 0.5;
flagES.alpha = 1;
}
};
self.down = function (x, y, obj) {
tween(self, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100
});
};
self.up = function (x, y, obj) {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
// Toggle language
currentLanguage = currentLanguage === 'en' ? 'es' : 'en';
storage.currentLanguage = currentLanguage;
self.updateDisplay();
updateAllTexts();
};
self.updateDisplay();
return self;
});
var MainMenu = Container.expand(function () {
var self = Container.call(this);
// Add colorful background that properly fills the screen
var menuBg = self.attachAsset('gameBackground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
scaleX: 1.0,
scaleY: 1.0,
tint: 0x4A90E2,
alpha: 0.8
});
// Add decorative circles for visual appeal
for (var i = 0; i < 8; i++) {
var decorCircle = self.attachAsset('petEye', {
anchorX: 0.5,
anchorY: 0.5,
x: (Math.random() - 0.5) * 2000,
y: (Math.random() - 0.5) * 2500,
scaleX: 2 + Math.random() * 3,
scaleY: 2 + Math.random() * 3,
tint: [0xFF6B6B, 0x4ECDC4, 0x45B7D1, 0x96CEB4, 0xFEA6A2, 0xDDA0DD, 0xF7DC6F, 0xBB8FCE][i],
alpha: 0.3
});
}
var titleText = new Text2('Digital Pet', {
size: 120,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 400;
self.addChild(titleText);
// Add subtitle
var subtitleText = new Text2('Monster Tamagotchi Simulator', {
size: 50,
fill: 0xE8F4FD
});
subtitleText.anchor.set(0.5, 0.5);
subtitleText.x = 1024;
subtitleText.y = 500;
self.addChild(subtitleText);
// Add version number
var versionText = new Text2('v0.0.1', {
size: 40,
fill: 0xBBBBBB
});
versionText.anchor.set(0.5, 0.5);
versionText.x = 1024;
versionText.y = 560;
self.addChild(versionText);
var newGameButton = new ActionButton(getText('newGame'), 0x4CAF50);
newGameButton.x = 1024;
newGameButton.y = 800;
newGameButton.scaleX = 1.8;
newGameButton.scaleY = 1.8;
newGameButton.onPress = function () {
showEggSelection();
};
self.addChild(newGameButton);
var savedGamesButton = new ActionButton(getText('savedGames'), 0x2196F3);
savedGamesButton.x = 1024;
savedGamesButton.y = 1000;
savedGamesButton.scaleX = 1.8;
savedGamesButton.scaleY = 1.8;
savedGamesButton.onPress = function () {
showSavedGames();
};
self.addChild(savedGamesButton);
return self;
});
var MiniGame = Container.expand(function () {
var self = Container.call(this);
var gameArea = self.attachAsset('gameArea', {
anchorX: 0.5,
anchorY: 0.5
});
var target = self.attachAsset('target', {
anchorX: 0.5,
anchorY: 0.5
});
self.score = 0;
self.timeLeft = 10;
self.gameActive = false;
var scoreText = new Text2('Score: 0', {
size: 30,
fill: 0x333333
});
scoreText.anchor.set(0.5, 0);
scoreText.y = -180;
self.addChild(scoreText);
var timerText = new Text2('Time: 10', {
size: 30,
fill: 0x333333
});
timerText.anchor.set(0.5, 0);
timerText.y = -140;
self.addChild(timerText);
self.startGame = function () {
self.gameActive = true;
self.score = 0;
self.timeLeft = 10;
scoreText.setText(getText('score') + ': 0');
timerText.setText(getText('time') + ': 10');
self.moveTarget();
var gameTimer = LK.setInterval(function () {
self.timeLeft -= 0.1;
timerText.setText(getText('time') + ': ' + Math.ceil(self.timeLeft));
if (self.timeLeft <= 0) {
LK.clearInterval(gameTimer);
self.endGame();
}
}, 100);
};
self.moveTarget = function () {
if (!self.gameActive) return;
var newX = (Math.random() - 0.5) * 300;
var newY = (Math.random() - 0.5) * 300;
tween(target, {
x: newX,
y: newY
}, {
duration: 200,
easing: tween.easeOut
});
};
self.endGame = function () {
self.gameActive = false;
var happiness = Math.min(20, self.score * 2);
pet.happiness = Math.min(100, pet.happiness + happiness);
pet.fatigue = Math.min(100, pet.fatigue + 10); // Increase fatigue instead of decreasing energy
pet.hunger = Math.max(0, pet.hunger - 5);
if (self.onGameEnd) {
self.onGameEnd(self.score);
}
};
target.down = function (x, y, obj) {
if (!self.gameActive) return;
self.score++;
scoreText.setText(getText('score') + ': ' + self.score);
LK.getSound('play').play();
tween(target, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 100,
onFinish: function onFinish() {
tween(target, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
}
});
self.moveTarget();
};
return self;
});
var Shop = Container.expand(function () {
var self = Container.call(this);
// Full screen background
var shopBg = self.attachAsset('gameBackground', {
anchorX: 0,
anchorY: 0,
x: -1024,
y: -1366,
scaleX: 1.0,
scaleY: 1.0,
tint: 0x2E7D32,
alpha: 0.95
});
// Prevent shop background from triggering external events
shopBg.down = function (x, y, obj) {
// Stop event propagation to prevent triggering other menus
if (obj && obj.data && obj.data.originalEvent) {
obj.data.originalEvent.stopPropagation();
}
};
shopBg.up = function (x, y, obj) {
// Stop event propagation to prevent triggering other menus
if (obj && obj.data && obj.data.originalEvent) {
obj.data.originalEvent.stopPropagation();
}
};
// Table/desk positioned at bottom right corner
var table = self.attachAsset('table', {
anchorX: 0.5,
anchorY: 1.0,
x: 600,
y: 1300,
scaleX: 2.2,
scaleY: 1.8,
tint: 0x8B4513
});
// Shopkeeper character positioned behind table, higher priority than everything except table
var shopkeeper = self.attachAsset('shopkeeper', {
anchorX: 0.5,
anchorY: 0.8,
x: 700,
y: 500,
scaleX: 2.2,
scaleY: 2.2
});
// Hide the VI (stats button) when in shop to show only when viewing Digimon
if (game.children.length > 0) {
for (var i = 0; i < game.children.length; i++) {
var child = game.children[i];
if (child.children && child.children.length > 0) {
// Look for stats button (question mark button)
for (var j = 0; j < child.children.length; j++) {
var grandchild = child.children[j];
if (grandchild.children && grandchild.children.length > 0) {
for (var k = 0; k < grandchild.children.length; k++) {
var text = grandchild.children[k];
if (text.text && text.text === '?') {
child.visible = false;
break;
}
}
}
}
}
}
}
// Add floating animation to shopkeeper
tween(shopkeeper, {
y: shopkeeper.y - 12
}, {
duration: 1800,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(shopkeeper, {
y: shopkeeper.y + 12
}, {
duration: 1800,
easing: tween.easeInOut
});
}
});
// Speech bubble positioned above shopkeeper, not overlapping with items
var speechBubble = self.attachAsset('gameArea', {
anchorX: 0.5,
anchorY: 0.5,
x: 200,
y: -200,
scaleX: 2.8,
scaleY: 1.3,
tint: 0xFFFFFF,
alpha: 0.92
});
var shopkeeperText = new Text2(getText('shopWelcome'), {
size: 42,
fill: 0x333333
});
shopkeeperText.anchor.set(0.5, 0.5);
shopkeeperText.x = 200;
shopkeeperText.y = -200;
self.addChild(shopkeeperText);
// Shop title positioned clearly at top center
var titleText = new Text2(getText('shop'), {
size: 120,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 0;
titleText.y = -750;
self.addChild(titleText);
var moneyText = new Text2(getText('money') + ': ' + (storage.money || 0), {
size: 48,
fill: 0xFFD700
});
moneyText.anchor.set(0.5, 0.5);
moneyText.x = 0;
moneyText.y = -650;
self.addChild(moneyText);
// Shop items - using actual inventory items
var shopItems = [{
nameKey: 'smallMeat',
asset: 'smallMeat',
price: 10,
storageKey: 'smallMeat'
}, {
nameKey: 'mediumMeat',
asset: 'mediumMeat',
price: 25,
storageKey: 'mediumMeat'
}, {
nameKey: 'largeMeat',
asset: 'largeMeat',
price: 40,
storageKey: 'largeMeat'
}, {
nameKey: 'sirloin',
asset: 'sirloin',
price: 60,
storageKey: 'sirloin'
}, {
nameKey: 'blessing',
asset: 'blessing',
price: 50,
storageKey: 'blessing'
}, {
nameKey: 'medicine',
asset: 'medicine',
price: 75,
storageKey: 'medicine'
}, {
nameKey: 'soap',
asset: 'soap',
price: 400,
storageKey: 'soap'
}];
var itemButtons = [];
// Arrange items in 2 columns of 3 rows - positioned in left area to avoid shopkeeper
for (var i = 0; i < shopItems.length; i++) {
var item = shopItems[i];
var itemContainer = new Container();
// Item icon background
var itemBg = itemContainer.attachAsset('inventorySlot', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.6,
scaleY: 1.6,
tint: 0x795548
});
// Item icon
var itemIcon = itemContainer.attachAsset(item.asset, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.4,
scaleY: 1.4
});
// Item name and price
var itemText = new Text2(getText(item.nameKey) + '\n$' + item.price, {
size: 32,
fill: 0xFFFFFF
});
itemText.anchor.set(0.5, 0);
itemText.y = 75;
itemContainer.addChild(itemText);
// Position in grid (2 columns, 3 rows) - left side to avoid overlapping shopkeeper with more spacing
var col = i % 2;
var row = Math.floor(i / 2);
itemContainer.x = -700 + col * 280;
itemContainer.y = -500 + row * 250;
itemContainer.itemData = item;
itemContainer.down = function (x, y, obj) {
tween(this, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100
});
};
itemContainer.up = function (x, y, obj) {
tween(this, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
// Stop event from bubbling up to prevent triggering other menus
if (obj && obj.data && obj.data.originalEvent) {
obj.data.originalEvent.stopPropagation();
}
if ((storage.money || 0) >= this.itemData.price) {
storage.money = (storage.money || 0) - this.itemData.price;
storage[this.itemData.storageKey] = (storage[this.itemData.storageKey] || 0) + 1;
moneyText.setText(getText('money') + ': ' + storage.money);
// Immediately update main money display in GUI
if (LK.gui.bottomLeft.children[0] && LK.gui.bottomLeft.children[0].children) {
var moneyContainer = LK.gui.bottomLeft.children[0];
for (var i = 0; i < moneyContainer.children.length; i++) {
var child = moneyContainer.children[i];
if (child.setText && typeof child.setText === 'function') {
child.setText(getText('money') + ': ' + storage.money);
break;
}
}
}
// Update global inventory reference
if (typeof inventoryGlobal !== 'undefined' && inventoryGlobal && inventoryGlobal.updateDisplay) {
inventoryGlobal.items[this.itemData.storageKey] = storage[this.itemData.storageKey] || 0;
inventoryGlobal.updateDisplay();
}
// Also check window reference as backup
if (typeof window !== 'undefined' && window.inventoryRef && window.inventoryRef.updateDisplay) {
window.inventoryRef.items[this.itemData.storageKey] = storage[this.itemData.storageKey] || 0;
window.inventoryRef.updateDisplay();
}
// Update shopkeeper text
shopkeeperText.setText(getText('shopThanks'));
LK.getSound('feed').play();
// Reset shopkeeper text after 2 seconds
LK.setTimeout(function () {
shopkeeperText.setText(getText('shopWelcome'));
}, 2000);
} else {
// Not enough money
shopkeeperText.setText(getText('shopNoMoney'));
LK.setTimeout(function () {
shopkeeperText.setText(getText('shopWelcome'));
}, 2000);
}
};
self.addChild(itemContainer);
itemButtons.push(itemContainer);
}
var closeButton = new ActionButton('Leave Shop', 0xF44336);
closeButton.x = -600;
closeButton.y = 600;
closeButton.scaleX = 1.6;
closeButton.scaleY = 1.6;
closeButton.onPress = function () {
LK.stopMusic();
LK.playMusic('Luna');
game.removeChild(shop);
// Show the VI (stats button) again when leaving shop
if (game.children.length > 0) {
for (var i = 0; i < game.children.length; i++) {
var child = game.children[i];
if (child.children && child.children.length > 0) {
// Look for stats button (question mark button)
for (var j = 0; j < child.children.length; j++) {
var grandchild = child.children[j];
if (grandchild.children && grandchild.children.length > 0) {
for (var k = 0; k < grandchild.children.length; k++) {
var text = grandchild.children[k];
if (text.text && text.text === '?') {
child.visible = true;
break;
}
}
}
}
}
}
}
};
self.addChild(closeButton);
// Ensure proper layering - bring shopkeeper and table to front
self.removeChild(table);
self.removeChild(shopkeeper);
self.addChild(shopkeeper); // Shopkeeper has priority over items and dialogue
self.addChild(table); // Table has highest priority
return self;
});
var StatBar = Container.expand(function (label, color, iconAsset) {
var self = Container.call(this);
var background = self.attachAsset('statBar', {
anchorX: 0,
anchorY: 0.5
});
var fill = self.attachAsset('statFill', {
anchorX: 0,
anchorY: 0.5,
tint: color,
scaleX: 1
});
// Add icon if provided
if (iconAsset) {
var icon = self.attachAsset(iconAsset, {
anchorX: 0.5,
anchorY: 0.5,
x: -120,
scaleX: 2.0,
scaleY: 2.0
});
}
var labelText = new Text2(label, {
size: 25,
fill: 0x333333
});
labelText.anchor.set(0, 0.5);
labelText.x = -80;
self.addChild(labelText);
self.updateValue = function (value) {
var percentage = Math.max(0, Math.min(100, value)) / 100;
tween(fill, {
scaleX: percentage
}, {
duration: 300,
easing: tween.easeOut
});
};
self.updateLabel = function (newLabel) {
labelText.setText(newLabel);
};
return self;
});
var Training = Container.expand(function () {
var self = Container.call(this);
var trainingBg = self.attachAsset('gameArea', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 6,
scaleY: 6.5,
tint: 0xFFF3E0
});
// Prevent training background from triggering external events
trainingBg.down = function (x, y, obj) {
// Stop event propagation to prevent triggering other menus
if (obj && obj.data && obj.data.originalEvent) {
obj.data.originalEvent.stopPropagation();
}
};
trainingBg.up = function (x, y, obj) {
// Stop event propagation to prevent triggering other menus
if (obj && obj.data && obj.data.originalEvent) {
obj.data.originalEvent.stopPropagation();
}
};
var titleText = new Text2(getText('training'), {
size: 100,
fill: 0xE65100
});
titleText.anchor.set(0.5, 0.5);
titleText.y = -850;
self.addChild(titleText);
// Training stats
var attackBar = new TrainingBar(getText('attack'), 0xF44336, 100);
attackBar.x = -200;
attackBar.y = -600;
attackBar.scaleX = 1.8;
attackBar.scaleY = 1.8;
self.addChild(attackBar);
var healthBar = new TrainingBar(getText('health'), 0x4CAF50, 100);
healthBar.x = -200;
healthBar.y = -450;
healthBar.scaleX = 1.8;
healthBar.scaleY = 1.8;
self.addChild(healthBar);
var speedBar = new TrainingBar(getText('speed'), 0x2196F3, 100);
speedBar.x = -200;
speedBar.y = -300;
speedBar.scaleX = 1.8;
speedBar.scaleY = 1.8;
self.addChild(speedBar);
var weightText = new Text2(getText('weight') + ': ' + (pet.weight || 50), {
size: 50,
fill: 0x795548
});
weightText.anchor.set(0.5, 0.5);
weightText.y = -120;
self.addChild(weightText);
// Training buttons with icons instead of text
var trainAttackButton = new Container();
var attackIcon = trainAttackButton.attachAsset('target', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0,
tint: 0xF44336
});
trainAttackButton.x = -300;
trainAttackButton.y = 150;
trainAttackButton.down = function (x, y, obj) {
tween(this, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100
});
};
trainAttackButton.up = function (x, y, obj) {
tween(this, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
if (pet.fatigue < 90) {
// Check fatigue instead of energy
var maxStat = pet.evolutionLevel >= 6 ? 700 : 500; // Ultra level = 700, others = 500
pet.attack = Math.min(maxStat, (pet.attack || 0) + Math.floor(Math.random() * 2) + 1);
pet.weight = Math.max(5, (pet.weight || 5) - 1);
pet.train();
attackBar.updateValue(pet.attack);
attackBar.maxValue = maxStat;
weightText.setText(getText('weight') + ': ' + pet.weight);
LK.getSound('play').play();
}
};
self.addChild(trainAttackButton);
var trainHealthButton = new Container();
var healthIcon = trainHealthButton.attachAsset('medicine', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3.0,
scaleY: 3.0,
tint: 0x4CAF50
});
trainHealthButton.x = 0;
trainHealthButton.y = 150;
trainHealthButton.down = function (x, y, obj) {
tween(this, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100
});
};
trainHealthButton.up = function (x, y, obj) {
tween(this, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
if (pet.fatigue < 90) {
// Check fatigue instead of energy
var maxStat = pet.evolutionLevel >= 6 ? 700 : 500; // Ultra level = 700, others = 500
pet.health = Math.min(maxStat, (pet.health || 0) + Math.floor(Math.random() * 2) + 1);
pet.weight = Math.max(5, (pet.weight || 5) - 1);
pet.train();
healthBar.updateValue(pet.health);
healthBar.maxValue = maxStat;
weightText.setText(getText('weight') + ': ' + pet.weight);
LK.getSound('play').play();
}
};
self.addChild(trainHealthButton);
var trainSpeedButton = new Container();
var speedIcon = trainSpeedButton.attachAsset('petEye', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4.0,
scaleY: 4.0,
tint: 0x2196F3
});
trainSpeedButton.x = 300;
trainSpeedButton.y = 150;
trainSpeedButton.down = function (x, y, obj) {
tween(this, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100
});
};
trainSpeedButton.up = function (x, y, obj) {
tween(this, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
if (pet.fatigue < 90) {
// Check fatigue instead of energy
var maxStat = pet.evolutionLevel >= 6 ? 700 : 500; // Ultra level = 700, others = 500
pet.speed = Math.min(maxStat, (pet.speed || 0) + Math.floor(Math.random() * 2) + 1);
pet.weight = Math.max(5, (pet.weight || 5) - 1);
pet.train();
speedBar.updateValue(pet.speed);
speedBar.maxValue = maxStat;
weightText.setText(getText('weight') + ': ' + pet.weight);
LK.getSound('play').play();
}
};
self.addChild(trainSpeedButton);
var closeButton = new ActionButton('X', 0xF44336);
closeButton.x = 850;
closeButton.y = -850;
closeButton.scaleX = 1.5;
closeButton.scaleY = 1.5;
closeButton.onPress = function () {
LK.stopMusic();
LK.playMusic('Luna');
game.removeChild(training);
};
self.addChild(closeButton);
self.updateBars = function () {
attackBar.updateValue(pet.attack || 0);
healthBar.updateValue(pet.health || 0);
speedBar.updateValue(pet.speed || 0);
weightText.setText(getText('weight') + ': ' + (pet.weight || 50));
};
return self;
});
var TrainingBar = Container.expand(function (label, color, maxValue) {
var self = Container.call(this);
self.maxValue = maxValue; // Store maxValue as property
var background = self.attachAsset('statBar', {
anchorX: 0,
anchorY: 0.5
});
var fill = self.attachAsset('statFill', {
anchorX: 0,
anchorY: 0.5,
tint: color,
scaleX: 0
});
var labelText = new Text2(label, {
size: 35,
fill: 0x333333
});
labelText.anchor.set(0, 0.5);
labelText.x = -120;
self.addChild(labelText);
var valueText = new Text2('0/' + self.maxValue, {
size: 30,
fill: 0x333333
});
valueText.anchor.set(1, 0.5);
valueText.x = 320;
self.addChild(valueText);
self.updateValue = function (value) {
var percentage = Math.max(0, Math.min(self.maxValue, value)) / self.maxValue;
tween(fill, {
scaleX: percentage
}, {
duration: 300,
easing: tween.easeOut
});
valueText.setText(Math.floor(value) + '/' + self.maxValue);
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xE8F5E8
});
/****
* Game Code
****/
// Game state management
var gameState = 'menu'; // 'menu', 'game', 'pause'
var gameData = storage.gameData || {};
// Language system
var languages = {
en: {
feed: "Feed",
play: "Play",
sleep: "Sleep",
hunger: "Hunger",
happy: "Fun",
energy: "Fatigue",
evolutionLevel: "Evolution Level",
score: "Score",
time: "Time",
newGame: "New Game",
savedGames: "Saved Games",
mainMenu: "Main Menu",
digimonName: "Digimon Name",
chooseEgg: "Choose Your Digi-Egg",
money: "Money",
shop: "Shop",
training: "Training",
attack: "Attack",
health: "Health",
speed: "Speed",
defense: "Defense",
weight: "Weight",
locked: "Locked",
buy: "Buy",
train: "Train",
shopWelcome: "Welcome to my shop!\nWhat would you like to buy?",
shopThanks: "Thank you for your purchase!\nCome back anytime!",
shopNoMoney: "Sorry, you don't have\nenough money for that!",
smallMeat: "Small Meat",
mediumMeat: "Medium Meat",
largeMeat: "Large Meat",
sirloin: "Sirloin",
blessing: "Blessing",
medicine: "Medicine",
poopNeed: "Waste",
hygiene: "Hygiene",
soap: "Soap",
friendship: "Friendship",
namingTitle: "Name Your Digimon"
},
es: {
feed: "Alimentar",
play: "Jugar",
sleep: "Dormir",
hunger: "Hambre",
happy: "Diversión",
energy: "Fatiga",
evolutionLevel: "Nivel de Evolución",
score: "Puntuación",
time: "Tiempo",
newGame: "Nuevo Juego",
savedGames: "Partidas Guardadas",
mainMenu: "Menú Principal",
digimonName: "Nombre del Digimon",
chooseEgg: "Elige tu Digi-Huevo",
money: "Dinero",
shop: "Tienda",
training: "Entrenamiento",
attack: "Ataque",
health: "Vida",
speed: "Velocidad",
defense: "Defensa",
weight: "Peso",
locked: "Bloqueado",
buy: "Comprar",
train: "Entrenar",
shopWelcome: "¡Bienvenido a mi tienda!\n¿Qué te gustaría comprar?",
shopThanks: "¡Gracias por tu compra!\n¡Vuelve cuando quieras!",
shopNoMoney: "¡Lo siento, no tienes\nsuficiente dinero para eso!",
smallMeat: "Carne Pequeña",
mediumMeat: "Carne Mediana",
largeMeat: "Carne Grande",
sirloin: "Solomillo",
blessing: "Bendición",
medicine: "Medicina",
poopNeed: "Desechos",
hygiene: "Higiene",
soap: "Jabón",
friendship: "Amistad",
namingTitle: "Nombra a tu Digimon"
}
};
var currentLanguage = storage.currentLanguage || 'en';
function getText(key) {
return languages[currentLanguage][key] || key;
}
function getCurrentDigimonName(eggType, evolutionLevel) {
if (evolutionLines[eggType] && evolutionLines[eggType][evolutionLevel]) {
return evolutionLines[eggType][evolutionLevel];
}
return 'Digimon';
}
// Game variables
var mainMenu, pet, hungerBar, happinessBar, energyBar, poopNeedBar, hygieneBar, friendshipBar, evolutionText;
var poopInstances = []; // Track all poop instances for cleanup timing
var feedButton, playButton, sleepButton, shopButton, trainingButton;
var shop, training;
var centeredDigimonImage; // Reference to the centered Digimon image for updates
// Evolution lines data
var evolutionLines = [
// Line 0: Botamon → WarGreymon (Dragon and Fire line)
['Botamon', 'Koromon', 'Agumon', 'Greymon', 'MetalGreymon', 'WarGreymon'],
// Line 1: Punimon → MetalGarurumon (Beast and Ice line)
['Punimon', 'Tsunomon', 'Gabumon', 'Garurumon', 'WereGarurumon', 'MetalGarurumon'],
// Line 2: Poyomon → Seraphimon (Light line - Angemon path: more attack than speed, weight > 30)
['Poyomon', 'Tokomon', 'Patamon', 'Angemon', 'MagnaAngemon', 'Seraphimon'],
// Line 3: Poyomon → Ophanimon (Light line - Angewomon path: more speed than attack, low weight)
['Poyomon', 'Tokomon', 'Patamon', 'Angewomon', 'Magnadramon', 'Ophanimon'],
// Line 4: Reserved for future (Lightning/Electric line)
['DigiEgg', 'Fresh', 'InTraining', 'Rookie', 'Champion', 'Ultimate'],
// Line 5: Reserved for future (Earth/Metal line)
['DigiEgg', 'Fresh', 'InTraining', 'Rookie', 'Champion', 'Ultimate']];
// Initialize money if not exists
if (!storage.money) storage.money = 100;
function updateCenteredDigimonImage() {
if (!pet || !centeredDigimonImage || gameState !== 'game') return;
// Get the correct asset for current evolution
var evolutionAssets = [['botamon', 'koromon', 'agumon', 'greymon', 'metalgreymon', 'wargreymon'], ['punimon', 'tsunomon', 'gabumon', 'garurumon', 'weregarurumon', 'metalgarurumon'], ['poyomon', 'tokomon', 'patamon', 'angemon', 'magnaangemon', 'seraphimon'], ['poyomon', 'tokomon', 'patamon', 'angewomon', 'magnadramon', 'ophanimon'], ['botamon', 'koromon', 'agumon', 'greymon', 'metalgreymon', 'wargreymon'], ['punimon', 'tsunomon', 'gabumon', 'garurumon', 'weregarurumon', 'metalgarurumon']];
var actualEggType = pet.eggType;
if ((pet.eggType === 2 || pet.eggType === 3) && pet.evolutionLevel >= 3) {
if (pet.speed > pet.attack && pet.weight < 30) {
actualEggType = 3;
} else if (pet.attack >= pet.speed && pet.weight >= 30) {
actualEggType = 2;
}
}
var lineAssets = evolutionAssets[actualEggType] || evolutionAssets[0];
var newAssetName = lineAssets[pet.evolutionLevel] || lineAssets[0];
// Evolution animation: flash and scale effect
tween(centeredDigimonImage, {
alpha: 0,
scaleX: centeredDigimonImage.scaleX * 1.5,
scaleY: centeredDigimonImage.scaleY * 1.5
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
// Remove old image and create new one
var oldX = centeredDigimonImage.x;
var oldY = centeredDigimonImage.y;
var oldScaleX = centeredDigimonImage.scaleX / 1.5; // Reset to original scale
var oldScaleY = centeredDigimonImage.scaleY / 1.5;
game.removeChild(centeredDigimonImage);
// Create new centered Digimon image with correct asset
centeredDigimonImage = game.attachAsset(newAssetName, {
anchorX: 0.5,
anchorY: 0.5,
x: oldX,
y: oldY,
scaleX: oldScaleX,
scaleY: oldScaleY,
alpha: 0
});
// Animate the new image appearing
tween(centeredDigimonImage, {
alpha: 1,
scaleX: oldScaleX * 1.2,
scaleY: oldScaleY * 1.2
}, {
duration: 400,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(centeredDigimonImage, {
scaleX: oldScaleX,
scaleY: oldScaleY
}, {
duration: 200,
easing: tween.easeOut
});
}
});
}
});
}
function updateAllTexts() {
if (gameState === 'game') {
// Update action buttons
if (playButton) playButton.children[1].setText(getText('play'));
if (sleepButton) sleepButton.children[1].setText(getText('sleep'));
if (shopButton) shopButton.children[1].setText(getText('shop'));
if (trainingButton) trainingButton.children[1].setText(getText('training'));
// Update stat bar labels
if (hungerBar) hungerBar.updateLabel(getText('hunger'));
if (happinessBar) happinessBar.updateLabel(getText('happy'));
if (energyBar) energyBar.updateLabel(getText('energy'));
// Update evolution text
if (evolutionText && pet) evolutionText.setText(getText('evolutionLevel') + ': ' + pet.evolutionLevel);
}
}
function showMainMenu() {
gameState = 'menu';
LK.playMusic('menuMusic');
game.removeChildren();
mainMenu = game.addChild(new MainMenu());
}
function showEggSelection() {
game.removeChildren();
// Add background for better contrast
var eggSelectionBg = game.attachAsset('gameBackground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
scaleX: 1.0,
scaleY: 1.0,
tint: 0x1A237E,
alpha: 0.9
});
var titleText = new Text2(getText('chooseEgg'), {
size: 120,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 200;
game.addChild(titleText);
// Evolution line descriptions
var eggDescriptions = ['Botamon Line\nBotamon → WarGreymon\nDragon • Fire', 'Punimon Line\nPunimon → MetalGarurumon\nBeast • Ice', 'Poyomon Line\nPoyomon → Seraphimon\nLight • Angemon Path', 'Poyomon Line\nPoyomon → Ophanimon\nLight • Angewomon Path', 'Lightning Line\nElectric • Speed • Energy', 'Earth Line\nRock • Metal • Defense'];
// Create 6 eggs (3 unlocked, 3 locked) - larger layout
var eggs = [];
for (var i = 0; i < 6; i++) {
var isLocked = i >= 3 && (storage.money || 0) < 500 && (storage.completedMissions || 0) < 1;
var egg = new DigiEgg(i, isLocked);
egg.x = 350 + i % 3 * 500;
egg.y = 550 + Math.floor(i / 3) * 600;
egg.scaleX = 1.8;
egg.scaleY = 1.8;
egg.onSelect = function (eggType) {
showDigimonNaming(eggType);
};
game.addChild(egg);
eggs.push(egg);
// Add evolution line description below each egg - larger text
var lineText = new Text2(eggDescriptions[i], {
size: 36,
fill: 0xFFFFFF
});
lineText.anchor.set(0.5, 0.5);
lineText.x = egg.x;
lineText.y = egg.y + 220;
game.addChild(lineText);
}
var backButton = new ActionButton(getText('mainMenu'), 0x9E9E9E);
backButton.x = 1024;
backButton.y = 1600;
backButton.scaleX = 1.8;
backButton.scaleY = 1.8;
backButton.onPress = function () {
showMainMenu();
};
game.addChild(backButton);
}
function showSavedGames() {
game.removeChildren();
// Add background to saved games screen
var savedGamesBg = game.attachAsset('gameBackground', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366,
scaleX: 1.2,
scaleY: 1.2,
tint: 0x4A90E2,
alpha: 0.8
});
// Add decorative circles for visual appeal
for (var i = 0; i < 6; i++) {
var decorCircle = game.attachAsset('petEye', {
anchorX: 0.5,
anchorY: 0.5,
x: (Math.random() - 0.5) * 2000 + 1024,
y: (Math.random() - 0.5) * 2500 + 1366,
scaleX: 1.5 + Math.random() * 2,
scaleY: 1.5 + Math.random() * 2,
tint: [0xFF6B6B, 0x4ECDC4, 0x45B7D1, 0x96CEB4, 0xFEA6A2, 0xDDA0DD][i],
alpha: 0.3
});
}
var titleText = new Text2(getText('savedGames'), {
size: 60,
fill: 0x2196F3
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 400;
game.addChild(titleText);
// Check for saved games
var saveCount = storage.saveCount || 0;
var savedGames = [];
for (var i = 0; i < saveCount; i++) {
var petName = storage['save_' + i + '_petName'];
if (petName) {
var saveData = {
petName: petName,
evolutionLevel: storage['save_' + i + '_evolutionLevel'] || 0,
saveIndex: i
};
savedGames.push(saveData);
}
}
if (savedGames.length === 0) {
var noSavesText = new Text2('No saved games yet', {
size: 40,
fill: 0x666666
});
noSavesText.anchor.set(0.5, 0.5);
noSavesText.x = 1024;
noSavesText.y = 600;
game.addChild(noSavesText);
} else {
// Display saved games with load and delete buttons
for (var i = 0; i < savedGames.length && i < 5; i++) {
var saveData = savedGames[i];
var loadButton = new ActionButton('Load: ' + saveData.petName + ' (Lv.' + saveData.evolutionLevel + ')', 0x4CAF50);
loadButton.x = 800;
loadButton.y = 500 + i * 120;
loadButton.saveIndex = saveData.saveIndex;
loadButton.onPress = function () {
loadGame(this.saveIndex);
};
game.addChild(loadButton);
var deleteButton = new ActionButton('Delete', 0xF44336);
deleteButton.x = 1300;
deleteButton.y = 500 + i * 120;
deleteButton.saveIndex = saveData.saveIndex;
deleteButton.onPress = function () {
deleteSave(this.saveIndex);
showSavedGames(); // Refresh the saved games display
};
game.addChild(deleteButton);
}
}
// Add clear all saves button
var clearAllButton = new ActionButton('Clear All Saves', 0x9E9E9E);
clearAllButton.x = 1024;
clearAllButton.y = 950;
clearAllButton.onPress = function () {
clearAllSaves();
showSavedGames(); // Refresh the display
};
game.addChild(clearAllButton);
var backButton = new ActionButton(getText('mainMenu'), 0x9E9E9E);
backButton.x = 1024;
backButton.y = 1050;
backButton.onPress = function () {
showMainMenu();
};
game.addChild(backButton);
}
function saveGame() {
// Get current save count
var saveCount = storage.saveCount || 0;
// Store save data as individual properties instead of nested object
var savePrefix = 'save_' + saveCount + '_';
// Check if save with same name exists and replace it
var existingSaveIndex = -1;
for (var i = 0; i < saveCount; i++) {
var existingName = storage['save_' + i + '_petName'];
if (existingName && existingName === pet.name) {
existingSaveIndex = i;
break;
}
}
if (existingSaveIndex >= 0) {
// Replace existing save
savePrefix = 'save_' + existingSaveIndex + '_';
} else {
// Add new save
if (saveCount >= 5) {
// Remove oldest save and shift all saves down
for (var j = 0; j < 4; j++) {
var oldPrefix = 'save_' + (j + 1) + '_';
var newPrefix = 'save_' + j + '_';
storage[newPrefix + 'petName'] = storage[oldPrefix + 'petName'];
storage[newPrefix + 'evolutionLevel'] = storage[oldPrefix + 'evolutionLevel'];
storage[newPrefix + 'hunger'] = storage[oldPrefix + 'hunger'];
storage[newPrefix + 'happiness'] = storage[oldPrefix + 'happiness'];
storage[newPrefix + 'fatigue'] = storage[oldPrefix + 'fatigue']; // Changed from energy to fatigue
storage[newPrefix + 'attack'] = storage[oldPrefix + 'attack'];
storage[newPrefix + 'health'] = storage[oldPrefix + 'health'];
storage[newPrefix + 'speed'] = storage[oldPrefix + 'speed'];
storage[newPrefix + 'weight'] = storage[oldPrefix + 'weight'];
storage[newPrefix + 'eggType'] = storage[oldPrefix + 'eggType'];
storage[newPrefix + 'money'] = storage[oldPrefix + 'money'];
storage[newPrefix + 'timestamp'] = storage[oldPrefix + 'timestamp'];
storage[newPrefix + 'birthTime'] = storage[oldPrefix + 'birthTime'];
storage[newPrefix + 'poopNeed'] = storage[oldPrefix + 'poopNeed'];
storage[newPrefix + 'hygiene'] = storage[oldPrefix + 'hygiene'];
storage[newPrefix + 'friendship'] = storage[oldPrefix + 'friendship'];
storage[newPrefix + 'wins'] = storage[oldPrefix + 'wins'];
storage[newPrefix + 'battles'] = storage[oldPrefix + 'battles'];
storage[newPrefix + 'injured'] = storage[oldPrefix + 'injured'];
storage[newPrefix + 'sick'] = storage[oldPrefix + 'sick'];
storage[newPrefix + 'injuryTime'] = storage[oldPrefix + 'injuryTime'];
storage[newPrefix + 'sickTime'] = storage[oldPrefix + 'sickTime'];
storage[newPrefix + 'hungerDeathTimer'] = storage[oldPrefix + 'hungerDeathTimer'];
storage[newPrefix + 'lastPetTime'] = storage[oldPrefix + 'lastPetTime'];
storage[newPrefix + 'smallMeat'] = storage[oldPrefix + 'smallMeat'];
storage[newPrefix + 'mediumMeat'] = storage[oldPrefix + 'mediumMeat'];
storage[newPrefix + 'largeMeat'] = storage[oldPrefix + 'largeMeat'];
storage[newPrefix + 'sirloin'] = storage[oldPrefix + 'sirloin'];
storage[newPrefix + 'blessing'] = storage[oldPrefix + 'blessing'];
storage[newPrefix + 'medicine'] = storage[oldPrefix + 'medicine'];
storage[newPrefix + 'soap'] = storage[oldPrefix + 'soap'];
}
savePrefix = 'save_4_';
} else {
storage.saveCount = saveCount + 1;
}
}
// Store individual properties - save ALL game data
storage[savePrefix + 'petName'] = pet.name;
storage[savePrefix + 'evolutionLevel'] = pet.evolutionLevel;
storage[savePrefix + 'hunger'] = pet.hunger;
storage[savePrefix + 'happiness'] = pet.happiness;
storage[savePrefix + 'fatigue'] = pet.fatigue; // Changed from energy to fatigue
storage[savePrefix + 'attack'] = pet.attack;
storage[savePrefix + 'health'] = pet.health;
storage[savePrefix + 'speed'] = pet.speed;
storage[savePrefix + 'weight'] = pet.weight;
storage[savePrefix + 'eggType'] = pet.eggType;
storage[savePrefix + 'money'] = storage.money || 0;
storage[savePrefix + 'timestamp'] = Date.now();
storage[savePrefix + 'birthTime'] = pet.birthTime || Date.now();
storage[savePrefix + 'poopNeed'] = pet.poopNeed || 0;
storage[savePrefix + 'hygiene'] = pet.hygiene || 100;
storage[savePrefix + 'friendship'] = pet.friendship || 0;
storage[savePrefix + 'wins'] = pet.wins || 0;
storage[savePrefix + 'battles'] = pet.battles || 0;
storage[savePrefix + 'injured'] = pet.injured || false;
storage[savePrefix + 'sick'] = pet.sick || false;
storage[savePrefix + 'injuryTime'] = pet.injuryTime || 0;
storage[savePrefix + 'sickTime'] = pet.sickTime || 0;
storage[savePrefix + 'hungerDeathTimer'] = pet.hungerDeathTimer || 0;
storage[savePrefix + 'lastPetTime'] = pet.lastPetTime || 0;
storage[savePrefix + 'smallMeat'] = storage.smallMeat || 0;
storage[savePrefix + 'mediumMeat'] = storage.mediumMeat || 0;
storage[savePrefix + 'largeMeat'] = storage.largeMeat || 0;
storage[savePrefix + 'sirloin'] = storage.sirloin || 0;
storage[savePrefix + 'blessing'] = storage.blessing || 0;
storage[savePrefix + 'medicine'] = storage.medicine || 0;
storage[savePrefix + 'soap'] = storage.soap || 0;
}
function loadGame(saveIndex) {
var savePrefix = 'save_' + saveIndex + '_';
var petName = storage[savePrefix + 'petName'];
if (petName) {
// First completely clear ALL current storage data to prevent conflicts
var currentLanguage = storage.currentLanguage; // Preserve language setting
var currentSaveCount = storage.saveCount; // Preserve save count
var savedGames = {}; // Preserve all saved game data
for (var i = 0; i < (currentSaveCount || 0); i++) {
var tempPrefix = 'save_' + i + '_';
savedGames[tempPrefix + 'petName'] = storage[tempPrefix + 'petName'];
savedGames[tempPrefix + 'evolutionLevel'] = storage[tempPrefix + 'evolutionLevel'];
savedGames[tempPrefix + 'hunger'] = storage[tempPrefix + 'hunger'];
savedGames[tempPrefix + 'happiness'] = storage[tempPrefix + 'happiness'];
savedGames[tempPrefix + 'fatigue'] = storage[tempPrefix + 'fatigue'];
savedGames[tempPrefix + 'attack'] = storage[tempPrefix + 'attack'];
savedGames[tempPrefix + 'health'] = storage[tempPrefix + 'health'];
savedGames[tempPrefix + 'speed'] = storage[tempPrefix + 'speed'];
savedGames[tempPrefix + 'weight'] = storage[tempPrefix + 'weight'];
savedGames[tempPrefix + 'eggType'] = storage[tempPrefix + 'eggType'];
savedGames[tempPrefix + 'money'] = storage[tempPrefix + 'money'];
savedGames[tempPrefix + 'timestamp'] = storage[tempPrefix + 'timestamp'];
savedGames[tempPrefix + 'birthTime'] = storage[tempPrefix + 'birthTime'];
savedGames[tempPrefix + 'poopNeed'] = storage[tempPrefix + 'poopNeed'];
savedGames[tempPrefix + 'hygiene'] = storage[tempPrefix + 'hygiene'];
savedGames[tempPrefix + 'friendship'] = storage[tempPrefix + 'friendship'];
savedGames[tempPrefix + 'wins'] = storage[tempPrefix + 'wins'];
savedGames[tempPrefix + 'battles'] = storage[tempPrefix + 'battles'];
savedGames[tempPrefix + 'injured'] = storage[tempPrefix + 'injured'];
savedGames[tempPrefix + 'sick'] = storage[tempPrefix + 'sick'];
savedGames[tempPrefix + 'injuryTime'] = storage[tempPrefix + 'injuryTime'];
savedGames[tempPrefix + 'sickTime'] = storage[tempPrefix + 'sickTime'];
savedGames[tempPrefix + 'hungerDeathTimer'] = storage[tempPrefix + 'hungerDeathTimer'];
savedGames[tempPrefix + 'lastPetTime'] = storage[tempPrefix + 'lastPetTime'];
savedGames[tempPrefix + 'smallMeat'] = storage[tempPrefix + 'smallMeat'];
savedGames[tempPrefix + 'mediumMeat'] = storage[tempPrefix + 'mediumMeat'];
savedGames[tempPrefix + 'largeMeat'] = storage[tempPrefix + 'largeMeat'];
savedGames[tempPrefix + 'sirloin'] = storage[tempPrefix + 'sirloin'];
savedGames[tempPrefix + 'blessing'] = storage[tempPrefix + 'blessing'];
savedGames[tempPrefix + 'medicine'] = storage[tempPrefix + 'medicine'];
savedGames[tempPrefix + 'soap'] = storage[tempPrefix + 'soap'];
}
// Clear all current game data
delete storage.petName;
delete storage.evolutionLevel;
delete storage.hunger;
delete storage.happiness;
delete storage.fatigue;
delete storage.energy; // Remove old energy property
delete storage.attack;
delete storage.health;
delete storage.speed;
delete storage.weight;
delete storage.eggType;
delete storage.money;
delete storage.birthTime;
delete storage.poopNeed;
delete storage.hygiene;
delete storage.friendship;
delete storage.wins;
delete storage.battles;
delete storage.injured;
delete storage.sick;
delete storage.injuryTime;
delete storage.sickTime;
delete storage.hungerDeathTimer;
delete storage.lastPetTime;
delete storage.smallMeat;
delete storage.mediumMeat;
delete storage.largeMeat;
delete storage.sirloin;
delete storage.blessing;
delete storage.medicine;
delete storage.soap;
// Restore saved game data and language settings
storage.currentLanguage = currentLanguage;
storage.saveCount = currentSaveCount;
// Restore saved games data using individual property assignments
for (var i = 0; i < (currentSaveCount || 0); i++) {
var tempPrefix = 'save_' + i + '_';
if (savedGames[tempPrefix + 'petName']) {
// Use Object.defineProperty to properly set storage values
for (var key in savedGames) {
if (key.indexOf(tempPrefix) === 0 && savedGames[key] !== undefined) {
Object.defineProperty(storage, key, {
value: savedGames[key],
writable: true,
enumerable: true,
configurable: true
});
}
}
}
}
// Load the specific save data
storage.petName = storage[savePrefix + 'petName'];
storage.evolutionLevel = storage[savePrefix + 'evolutionLevel'] || 0;
storage.hunger = storage[savePrefix + 'hunger'] || 100;
storage.happiness = storage[savePrefix + 'happiness'] || 100;
storage.fatigue = storage[savePrefix + 'fatigue'] || 0;
storage.attack = storage[savePrefix + 'attack'] || 0;
storage.health = storage[savePrefix + 'health'] || 0;
storage.speed = storage[savePrefix + 'speed'] || 0;
storage.weight = storage[savePrefix + 'weight'] || 5;
storage.eggType = storage[savePrefix + 'eggType'] || 0;
storage.money = storage[savePrefix + 'money'] || 100;
storage.birthTime = storage[savePrefix + 'birthTime'] || Date.now();
storage.poopNeed = storage[savePrefix + 'poopNeed'] || 0;
storage.hygiene = storage[savePrefix + 'hygiene'] || 100;
storage.friendship = storage[savePrefix + 'friendship'] || 0;
storage.wins = storage[savePrefix + 'wins'] || 0;
storage.battles = storage[savePrefix + 'battles'] || 0;
storage.injured = storage[savePrefix + 'injured'] || false;
storage.sick = storage[savePrefix + 'sick'] || false;
storage.injuryTime = storage[savePrefix + 'injuryTime'] || 0;
storage.sickTime = storage[savePrefix + 'sickTime'] || 0;
storage.hungerDeathTimer = storage[savePrefix + 'hungerDeathTimer'] || 0;
storage.lastPetTime = storage[savePrefix + 'lastPetTime'] || 0;
storage.smallMeat = storage[savePrefix + 'smallMeat'] || 0;
storage.mediumMeat = storage[savePrefix + 'mediumMeat'] || 0;
storage.largeMeat = storage[savePrefix + 'largeMeat'] || 0;
storage.sirloin = storage[savePrefix + 'sirloin'] || 0;
storage.blessing = storage[savePrefix + 'blessing'] || 0;
storage.medicine = storage[savePrefix + 'medicine'] || 0;
storage.soap = storage[savePrefix + 'soap'] || 0;
// Load the game with the restored data
gameState = 'game';
game.removeChildren();
initializeGameplay();
}
}
function deleteSave(saveIndex) {
var savePrefix = 'save_' + saveIndex + '_';
// Delete all properties for this save
delete storage[savePrefix + 'petName'];
delete storage[savePrefix + 'evolutionLevel'];
delete storage[savePrefix + 'hunger'];
delete storage[savePrefix + 'happiness'];
delete storage[savePrefix + 'fatigue'];
delete storage[savePrefix + 'attack'];
delete storage[savePrefix + 'health'];
delete storage[savePrefix + 'speed'];
delete storage[savePrefix + 'weight'];
delete storage[savePrefix + 'eggType'];
delete storage[savePrefix + 'money'];
delete storage[savePrefix + 'timestamp'];
delete storage[savePrefix + 'birthTime'];
delete storage[savePrefix + 'poopNeed'];
delete storage[savePrefix + 'hygiene'];
delete storage[savePrefix + 'friendship'];
delete storage[savePrefix + 'wins'];
delete storage[savePrefix + 'battles'];
delete storage[savePrefix + 'injured'];
delete storage[savePrefix + 'sick'];
delete storage[savePrefix + 'injuryTime'];
delete storage[savePrefix + 'sickTime'];
delete storage[savePrefix + 'hungerDeathTimer'];
delete storage[savePrefix + 'lastPetTime'];
delete storage[savePrefix + 'smallMeat'];
delete storage[savePrefix + 'mediumMeat'];
delete storage[savePrefix + 'largeMeat'];
delete storage[savePrefix + 'sirloin'];
delete storage[savePrefix + 'blessing'];
delete storage[savePrefix + 'medicine'];
delete storage[savePrefix + 'soap'];
// Compact saves by moving all remaining saves down
var saveCount = storage.saveCount || 0;
for (var i = saveIndex; i < saveCount - 1; i++) {
var currentPrefix = 'save_' + i + '_';
var nextPrefix = 'save_' + (i + 1) + '_';
storage[currentPrefix + 'petName'] = storage[nextPrefix + 'petName'];
storage[currentPrefix + 'evolutionLevel'] = storage[nextPrefix + 'evolutionLevel'];
storage[currentPrefix + 'hunger'] = storage[nextPrefix + 'hunger'];
storage[currentPrefix + 'happiness'] = storage[nextPrefix + 'happiness'];
storage[currentPrefix + 'fatigue'] = storage[nextPrefix + 'fatigue'];
storage[currentPrefix + 'attack'] = storage[nextPrefix + 'attack'];
storage[currentPrefix + 'health'] = storage[nextPrefix + 'health'];
storage[currentPrefix + 'speed'] = storage[nextPrefix + 'speed'];
storage[currentPrefix + 'weight'] = storage[nextPrefix + 'weight'];
storage[currentPrefix + 'eggType'] = storage[nextPrefix + 'eggType'];
storage[currentPrefix + 'money'] = storage[nextPrefix + 'money'];
storage[currentPrefix + 'timestamp'] = storage[nextPrefix + 'timestamp'];
storage[currentPrefix + 'birthTime'] = storage[nextPrefix + 'birthTime'];
storage[currentPrefix + 'poopNeed'] = storage[nextPrefix + 'poopNeed'];
storage[currentPrefix + 'hygiene'] = storage[nextPrefix + 'hygiene'];
storage[currentPrefix + 'friendship'] = storage[nextPrefix + 'friendship'];
storage[currentPrefix + 'wins'] = storage[nextPrefix + 'wins'];
storage[currentPrefix + 'battles'] = storage[nextPrefix + 'battles'];
storage[currentPrefix + 'injured'] = storage[nextPrefix + 'injured'];
storage[currentPrefix + 'sick'] = storage[nextPrefix + 'sick'];
storage[currentPrefix + 'injuryTime'] = storage[nextPrefix + 'injuryTime'];
storage[currentPrefix + 'sickTime'] = storage[nextPrefix + 'sickTime'];
storage[currentPrefix + 'hungerDeathTimer'] = storage[nextPrefix + 'hungerDeathTimer'];
storage[currentPrefix + 'lastPetTime'] = storage[nextPrefix + 'lastPetTime'];
storage[currentPrefix + 'smallMeat'] = storage[nextPrefix + 'smallMeat'];
storage[currentPrefix + 'mediumMeat'] = storage[nextPrefix + 'mediumMeat'];
storage[currentPrefix + 'largeMeat'] = storage[nextPrefix + 'largeMeat'];
storage[currentPrefix + 'sirloin'] = storage[nextPrefix + 'sirloin'];
storage[currentPrefix + 'blessing'] = storage[nextPrefix + 'blessing'];
storage[currentPrefix + 'medicine'] = storage[nextPrefix + 'medicine'];
storage[currentPrefix + 'soap'] = storage[nextPrefix + 'soap'];
}
// Clear the last save slot
var lastPrefix = 'save_' + (saveCount - 1) + '_';
delete storage[lastPrefix + 'petName'];
delete storage[lastPrefix + 'evolutionLevel'];
delete storage[lastPrefix + 'hunger'];
delete storage[lastPrefix + 'happiness'];
delete storage[lastPrefix + 'fatigue'];
delete storage[lastPrefix + 'attack'];
delete storage[lastPrefix + 'health'];
delete storage[lastPrefix + 'speed'];
delete storage[lastPrefix + 'weight'];
delete storage[lastPrefix + 'eggType'];
delete storage[lastPrefix + 'money'];
delete storage[lastPrefix + 'timestamp'];
delete storage[lastPrefix + 'birthTime'];
delete storage[lastPrefix + 'poopNeed'];
delete storage[lastPrefix + 'hygiene'];
delete storage[lastPrefix + 'friendship'];
delete storage[lastPrefix + 'wins'];
delete storage[lastPrefix + 'battles'];
delete storage[lastPrefix + 'injured'];
delete storage[lastPrefix + 'sick'];
delete storage[lastPrefix + 'injuryTime'];
delete storage[lastPrefix + 'sickTime'];
delete storage[lastPrefix + 'hungerDeathTimer'];
delete storage[lastPrefix + 'lastPetTime'];
delete storage[lastPrefix + 'smallMeat'];
delete storage[lastPrefix + 'mediumMeat'];
delete storage[lastPrefix + 'largeMeat'];
delete storage[lastPrefix + 'sirloin'];
delete storage[lastPrefix + 'blessing'];
delete storage[lastPrefix + 'medicine'];
delete storage[lastPrefix + 'soap'];
// Decrease save count
storage.saveCount = Math.max(0, saveCount - 1);
}
function clearAllSaves() {
var saveCount = storage.saveCount || 0;
for (var i = 0; i < saveCount; i++) {
var savePrefix = 'save_' + i + '_';
delete storage[savePrefix + 'petName'];
delete storage[savePrefix + 'evolutionLevel'];
delete storage[savePrefix + 'hunger'];
delete storage[savePrefix + 'happiness'];
delete storage[savePrefix + 'fatigue'];
delete storage[savePrefix + 'attack'];
delete storage[savePrefix + 'health'];
delete storage[savePrefix + 'speed'];
delete storage[savePrefix + 'weight'];
delete storage[savePrefix + 'eggType'];
delete storage[savePrefix + 'money'];
delete storage[savePrefix + 'timestamp'];
delete storage[savePrefix + 'birthTime'];
delete storage[savePrefix + 'poopNeed'];
delete storage[savePrefix + 'hygiene'];
delete storage[savePrefix + 'friendship'];
delete storage[savePrefix + 'wins'];
delete storage[savePrefix + 'battles'];
delete storage[savePrefix + 'injured'];
delete storage[savePrefix + 'sick'];
delete storage[savePrefix + 'injuryTime'];
delete storage[savePrefix + 'sickTime'];
delete storage[savePrefix + 'hungerDeathTimer'];
delete storage[savePrefix + 'lastPetTime'];
delete storage[savePrefix + 'smallMeat'];
delete storage[savePrefix + 'mediumMeat'];
delete storage[savePrefix + 'largeMeat'];
delete storage[savePrefix + 'sirloin'];
delete storage[savePrefix + 'blessing'];
delete storage[savePrefix + 'medicine'];
delete storage[savePrefix + 'soap'];
}
storage.saveCount = 0;
}
function showDigimonNaming(eggType) {
game.removeChildren();
// Add full screen gradient background with better contrast
var namingBg = game.attachAsset('gameBackground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
scaleX: 1.0,
scaleY: 1.0,
tint: 0x2A2A2A,
alpha: 0.98
});
var titleText = new Text2(getText('digimonName') + ' (Max 7 chars)', {
size: 90,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 350;
game.addChild(titleText);
var nameInputBg = game.attachAsset('gameArea', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 550,
scaleX: 4.5,
scaleY: 1.2,
tint: 0xFFFFFF,
alpha: 0.95
});
// Custom name input system
var customName = '';
var nameText = new Text2(customName || 'Enter name...', {
size: 85,
fill: customName ? 0x333333 : 0x777777
});
nameText.anchor.set(0.5, 0.5);
nameText.x = 1024;
nameText.y = 550;
// Add keyboard background panel for better organization
var keyboardPanel = game.attachAsset('gameArea', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1100,
scaleX: 7.5,
scaleY: 4.2,
tint: 0x424242,
alpha: 0.9
});
// Add nameText after all background elements to ensure it appears on top
game.addChild(nameText);
// Add title text for the naming screen
var namingTitleText = new Text2(getText('namingTitle'), {
size: 70,
fill: 0xFFFFFF
});
namingTitleText.anchor.set(0.5, 0.5);
namingTitleText.x = 1024;
namingTitleText.y = 200;
game.addChild(namingTitleText);
// Character input keyboard - organized in 3 rows of 9 letters each
var keyboard = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var keyboardButtons = [];
var startX = 180;
var startY = 850;
var keyWidth = 170;
var keyHeight = 120;
var keySpacing = 18;
for (var i = 0; i < keyboard.length; i++) {
var letter = keyboard[i];
var keyButton = new Container();
// Create key background with better contrast
var keyBg = keyButton.attachAsset('keyboardBg', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: keyWidth / 120,
scaleY: keyHeight / 80
});
// Add letter text with larger size
var keyText = new Text2(letter, {
size: 42,
fill: 0xFFFFFF
});
keyText.anchor.set(0.5, 0.5);
keyButton.addChild(keyText);
// Position in 3 rows of 9
var row = Math.floor(i / 9);
var col = i % 9;
keyButton.x = startX + col * (keyWidth + keySpacing);
keyButton.y = startY + row * (keyHeight + keySpacing);
keyButton.letter = letter;
keyButton.down = function (x, y, obj) {
tween(this, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100
});
};
keyButton.up = function (x, y, obj) {
tween(this, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
if (customName.length < 7) {
customName += this.letter;
nameText.setText(customName);
nameText.fill = 0x333333;
}
};
game.addChild(keyButton);
keyboardButtons.push(keyButton);
}
// Add space and delete buttons with better sizing for mobile
var spaceButton = new Container();
var spaceBg = spaceButton.attachAsset('keyboardBg', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.5,
scaleY: keyHeight / 80,
tint: 0x6A1B9A
});
var spaceText = new Text2('SPACE', {
size: 36,
fill: 0xFFFFFF
});
spaceText.anchor.set(0.5, 0.5);
spaceButton.addChild(spaceText);
spaceButton.x = 700;
spaceButton.y = startY + 3 * (keyHeight + keySpacing);
spaceButton.down = function (x, y, obj) {
tween(this, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100
});
};
spaceButton.up = function (x, y, obj) {
tween(this, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
if (customName.length < 7 && customName.length > 0) {
customName += ' ';
nameText.setText(customName);
}
};
game.addChild(spaceButton);
var deleteButton = new Container();
var deleteBg = deleteButton.attachAsset('keyboardBg', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.8,
scaleY: keyHeight / 80,
tint: 0xF44336
});
var deleteText = new Text2('DELETE', {
size: 34,
fill: 0xFFFFFF
});
deleteText.anchor.set(0.5, 0.5);
deleteButton.addChild(deleteText);
deleteButton.x = 1350;
deleteButton.y = startY + 3 * (keyHeight + keySpacing);
deleteButton.down = function (x, y, obj) {
tween(this, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100
});
};
deleteButton.up = function (x, y, obj) {
tween(this, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
if (customName.length > 0) {
customName = customName.slice(0, -1);
nameText.setText(customName || 'Enter name...');
nameText.fill = customName ? 0x333333 : 0x999999;
}
};
game.addChild(deleteButton);
var confirmButton = new ActionButton('OK', 0x4CAF50);
confirmButton.x = 1024;
confirmButton.y = 1450;
confirmButton.onPress = function () {
if (customName.length > 0) {
storage.petName = customName;
storage.eggType = eggType;
startNewGame();
}
};
game.addChild(confirmButton);
var backButton = new ActionButton(getText('mainMenu'), 0x9E9E9E);
backButton.x = 1024;
backButton.y = 1550;
backButton.onPress = function () {
showEggSelection();
};
game.addChild(backButton);
}
function startNewGame() {
gameState = 'game';
game.removeChildren();
// Clear ALL storage data for a completely fresh start
// Core pet stats - all reset to starting values
storage.hunger = 100;
storage.happiness = 100;
storage.fatigue = 0;
storage.poopNeed = 0;
storage.hygiene = 100;
storage.friendship = 0;
storage.evolutionLevel = 0;
storage.attack = 0;
storage.health = 0;
storage.speed = 0;
storage.weight = 5;
storage.wins = 0;
storage.battles = 0;
storage.birthTime = Date.now(); // Set birth time for new pet
// Health system
storage.injured = false;
storage.sick = false;
storage.injuryTime = 0;
storage.sickTime = 0;
storage.hungerDeathTimer = 0;
storage.lastPetTime = 0; // Reset petting timer for new game
// Economy
storage.money = 100;
// Initialize starter inventory for new games
storage.smallMeat = 10;
storage.mediumMeat = 0;
storage.largeMeat = 0;
storage.sirloin = 0;
storage.blessing = 5;
storage.medicine = 3;
storage.soap = 1;
// Clear any other potential leftover data
delete storage.energy; // Remove old energy property if it exists
// Reset global game variables to prevent carryover
if (pet) {
pet = null;
}
hungerBar = null;
happinessBar = null;
energyBar = null;
friendshipBar = null;
poopInstances = []; // Clear poop tracking
evolutionText = null;
feedButton = null;
playButton = null;
sleepButton = null;
shopButton = null;
trainingButton = null;
shop = null;
training = null;
initializeGameplay();
}
function initializeGameplay() {
// Add background image
var background = game.attachAsset('gameBackground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
// Start game music
LK.playMusic('Luna');
// Create pet with debugging
console.log('Creating new DigitalPet');
pet = game.addChild(new DigitalPet());
pet.x = 1024;
pet.y = 900;
// Don't override scale here - let the pet manage its own scaling
// Force pet visibility
pet.visible = true;
pet.alpha = 1;
console.log('Pet created at position:', pet.x, pet.y, 'visible:', pet.visible);
console.log('Pet children count:', pet.children.length);
// Add debugging info about pet state
LK.setTimeout(function () {
console.log('Pet debug after 1 second:');
console.log('- Position:', pet.x, pet.y);
console.log('- Scale:', pet.scaleX, pet.scaleY);
console.log('- Alpha:', pet.alpha);
console.log('- Visible:', pet.visible);
console.log('- Children count:', pet.children.length);
if (pet.children.length > 0) {
for (var i = 0; i < pet.children.length; i++) {
var child = pet.children[i];
console.log('-- Child', i, ':', 'visible:', child.visible, 'alpha:', child.alpha, 'scale:', child.scaleX);
}
}
}, 1000);
// UI Elements - scaled up for mobile
hungerBar = new StatBar(getText('hunger'), 0xFF5722, 'hungerIcon');
hungerBar.x = 200;
hungerBar.y = 300;
hungerBar.scaleX = 1.5;
hungerBar.scaleY = 1.5;
game.addChild(hungerBar);
happinessBar = new StatBar(getText('happy'), 0xFFEB3B, 'funIcon');
happinessBar.x = 200;
happinessBar.y = 420;
happinessBar.scaleX = 1.5;
happinessBar.scaleY = 1.5;
game.addChild(happinessBar);
energyBar = new StatBar(getText('energy'), 0x2196F3, 'fatigueIcon'); // This will now show "Fatigue"
energyBar.x = 200;
energyBar.y = 540;
energyBar.scaleX = 1.5;
energyBar.scaleY = 1.5;
game.addChild(energyBar);
poopNeedBar = new StatBar(getText('poopNeed'), 0x8B4513, 'wasteIcon');
poopNeedBar.x = 200;
poopNeedBar.y = 660;
poopNeedBar.scaleX = 1.5;
poopNeedBar.scaleY = 1.5;
game.addChild(poopNeedBar);
hygieneBar = new StatBar(getText('hygiene'), 0x00BCD4, 'hygieneIcon');
hygieneBar.x = 200;
hygieneBar.y = 780;
hygieneBar.scaleX = 1.5;
hygieneBar.scaleY = 1.5;
game.addChild(hygieneBar);
friendshipBar = new StatBar(getText('friendship'), 0xE91E63, 'funIcon');
friendshipBar.x = 200;
friendshipBar.y = 900;
friendshipBar.scaleX = 1.5;
friendshipBar.scaleY = 1.5;
game.addChild(friendshipBar);
// Inventory - scaled up and repositioned
var inventory = new Inventory();
inventory.x = 200;
inventory.y = 1800;
inventory.scaleX = 1.8;
inventory.scaleY = 1.8;
game.addChild(inventory);
// Store inventory reference globally for shop access
var inventoryGlobal = inventory;
if (typeof window !== 'undefined') {
window.inventoryRef = inventory;
}
playButton = new ActionButton(getText('play'), 0xFF9800);
playButton.x = 200;
playButton.y = 1600;
playButton.scaleX = 1.4;
playButton.scaleY = 1.4;
playButton.onPress = function () {
if (pet.fatigue > 80) {
// Check if too tired to play
LK.effects.flashObject(pet, 0xFF0000, 500);
return;
}
var miniGame = new MiniGame();
miniGame.x = 1024;
miniGame.y = 1200;
game.addChild(miniGame);
miniGame.onGameEnd = function (score) {
game.removeChild(miniGame);
storage.money = (storage.money || 0) + score;
};
miniGame.startGame();
};
game.addChild(playButton);
sleepButton = new ActionButton(getText('sleep'), 0x9C27B0);
sleepButton.x = 520;
sleepButton.y = 1600;
sleepButton.scaleX = 1.4;
sleepButton.scaleY = 1.4;
sleepButton.onPress = function () {
pet.fatigue = Math.max(0, pet.fatigue - 30); // Reduce fatigue instead of increasing energy
pet.hunger = Math.max(0, pet.hunger - 5);
LK.getSound('sleep').play();
tween(pet, {
alpha: 0.5
}, {
duration: 500,
onFinish: function onFinish() {
tween(pet, {
alpha: 1
}, {
duration: 500
});
}
});
};
game.addChild(sleepButton);
shopButton = new ActionButton(getText('shop'), 0x795548);
shopButton.x = 840;
shopButton.y = 1600;
shopButton.scaleX = 1.4;
shopButton.scaleY = 1.4;
shopButton.onPress = function () {
LK.stopMusic();
LK.playMusic('shopMusic');
shop = game.addChild(new Shop());
shop.x = 1024;
shop.y = 1366;
// Don't pause game state so stats continue to update
// Add floating animation to shopkeeper
LK.setTimeout(function () {
if (shop && shop.children[1]) {
// shopkeeper is second child
var shopkeeper = shop.children[1];
tween(shopkeeper, {
y: shopkeeper.y - 30
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(shopkeeper, {
y: shopkeeper.y + 30
}, {
duration: 2000,
easing: tween.easeInOut
});
}
});
}
}, 500);
};
game.addChild(shopButton);
trainingButton = new ActionButton(getText('training'), 0xE65100);
trainingButton.x = 1160;
trainingButton.y = 1600;
trainingButton.scaleX = 1.4;
trainingButton.scaleY = 1.4;
trainingButton.onPress = function () {
LK.stopMusic();
LK.playMusic('trainingMusic');
training = game.addChild(new Training());
training.x = 1024;
training.y = 1366;
training.updateBars();
// Don't pause game state so stats continue to update
};
game.addChild(trainingButton);
// Add save game button
var saveButton = new ActionButton('Save', 0x607D8B);
saveButton.x = 1480;
saveButton.y = 1600;
saveButton.scaleX = 1.4;
saveButton.scaleY = 1.4;
saveButton.onPress = function () {
if (pet) {
saveGame();
LK.effects.flashScreen(0x4CAF50, 500);
}
};
game.addChild(saveButton);
// Evolution display
evolutionText = new Text2(getText('evolutionLevel') + ': 0', {
size: 60,
fill: 0x333333
});
evolutionText.anchor.set(0.5, 0);
evolutionText.x = 1024;
evolutionText.y = 680;
game.addChild(evolutionText);
// Current Digimon name display
var digimonNameText = new Text2('', {
size: 80,
fill: 0x2196F3
});
digimonNameText.anchor.set(0.5, 0);
digimonNameText.x = 1024;
digimonNameText.y = 600;
game.addChild(digimonNameText);
// Add centered Digimon image with animation separate from pet stats
var evolutionAssets = [['botamon', 'koromon', 'agumon', 'greymon', 'metalgreymon', 'wargreymon'], ['punimon', 'tsunomon', 'gabumon', 'garurumon', 'weregarurumon', 'metalgarurumon'], ['poyomon', 'tokomon', 'patamon', 'angemon', 'magnaangemon', 'seraphimon'], ['poyomon', 'tokomon', 'patamon', 'angewomon', 'magnadramon', 'ophanimon'], ['botamon', 'koromon', 'agumon', 'greymon', 'metalgreymon', 'wargreymon'], ['punimon', 'tsunomon', 'gabumon', 'garurumon', 'weregarurumon', 'metalgarurumon']];
var actualEggType = storage.eggType || 0;
if ((storage.eggType === 2 || storage.eggType === 3) && (storage.evolutionLevel || 0) >= 3) {
if ((storage.speed || 0) > (storage.attack || 0) && (storage.weight || 5) < 30) {
actualEggType = 3;
} else if ((storage.attack || 0) >= (storage.speed || 0) && (storage.weight || 5) >= 30) {
actualEggType = 2;
}
}
var lineAssets = evolutionAssets[actualEggType] || evolutionAssets[0];
var assetName = lineAssets[storage.evolutionLevel || 0] || lineAssets[0];
centeredDigimonImage = game.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1200,
scaleX: 3.5,
scaleY: 3.5
});
// Add breathing animation to centered Digimon image
if (centeredDigimonImage) {
tween(centeredDigimonImage, {
scaleX: centeredDigimonImage.scaleX * 1.08,
scaleY: centeredDigimonImage.scaleY * 1.08
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (centeredDigimonImage) {
tween(centeredDigimonImage, {
scaleX: centeredDigimonImage.scaleX / 1.08,
scaleY: centeredDigimonImage.scaleY / 1.08
}, {
duration: 1000,
easing: tween.easeInOut
});
}
}
});
}
// Money display with background and coin icon - positioned in bottom left corner
var moneyContainer = new Container();
var moneyBg = moneyContainer.attachAsset('inventorySlot', {
anchorX: 0,
anchorY: 0,
scaleX: 3.5,
scaleY: 1.2,
tint: 0x4CAF50,
alpha: 0.8
});
var moneyIcon = moneyContainer.attachAsset('petEye', {
anchorX: 0.5,
anchorY: 0.5,
x: 50,
y: 40,
scaleX: 1.2,
scaleY: 1.2,
tint: 0xFFD700
});
var moneyText = new Text2(getText('money') + ': ' + (storage.money || 0), {
size: 45,
fill: 0xFFFFFF
});
moneyText.anchor.set(0, 0.5);
moneyText.x = 100;
moneyText.y = 40;
moneyContainer.addChild(moneyText);
moneyContainer.x = 50;
moneyContainer.y = -120;
LK.gui.bottomLeft.addChild(moneyContainer);
// Add question mark button for stats display
var statsButton = new Container();
var statsBg = statsButton.attachAsset('questionIcon', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2,
tint: 0x2196F3
});
var statsText = new Text2('?', {
size: 60,
fill: 0xFFFFFF
});
statsText.anchor.set(0.5, 0.5);
statsButton.addChild(statsText);
statsButton.x = 1800;
statsButton.y = 400;
statsButton.down = function (x, y, obj) {
tween(this, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100
});
};
statsButton.up = function (x, y, obj) {
tween(this, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
if (pet) {
pet.showStats();
}
};
game.addChild(statsButton);
updateAllTexts();
}
// Language button
var languageButton = new LanguageButton();
LK.gui.topRight.addChild(languageButton);
languageButton.x = -120;
languageButton.y = 80;
// Start with main menu
showMainMenu();
game.update = function () {
if (gameState === 'game' && pet) {
// Update stat bars
hungerBar.updateValue(pet.hunger);
happinessBar.updateValue(pet.happiness);
energyBar.updateValue(pet.fatigue); // Use fatigue instead of energy
poopNeedBar.updateValue(pet.poopNeed);
hygieneBar.updateValue(pet.hygiene);
friendshipBar.updateValue(pet.friendship);
// Update evolution display
evolutionText.setText(getText('evolutionLevel') + ': ' + pet.evolutionLevel);
// Update current Digimon name display
if (game.children[7] && game.children[7].setText) {
// digimonNameText is now the 8th child (index 7) due to scaling changes
var currentDigimonName = getCurrentDigimonName(pet.eggType, pet.evolutionLevel);
game.children[7].setText(currentDigimonName);
}
// Digimon display is now handled by the pet itself with animations
// Update money display immediately
if (LK.gui.bottomLeft.children[0] && LK.gui.bottomLeft.children[0].children && LK.gui.bottomLeft.children[0].children.length > 0) {
// Find the text element in the money container
var moneyContainer = LK.gui.bottomLeft.children[0];
for (var i = 0; i < moneyContainer.children.length; i++) {
var child = moneyContainer.children[i];
if (child.setText && typeof child.setText === 'function') {
child.setText(getText('money') + ': ' + (storage.money || 0));
break;
}
}
}
// Warning effects for low stats
if (pet.hunger < 20 && LK.ticks % 60 === 0) {
LK.effects.flashObject(hungerBar, 0xFF0000, 300);
}
if (pet.happiness < 20 && LK.ticks % 60 === 0) {
LK.effects.flashObject(happinessBar, 0xFF0000, 300);
}
if (pet.fatigue > 80 && LK.ticks % 60 === 0) {
// Warning when fatigue is high
LK.effects.flashObject(energyBar, 0xFF0000, 300);
}
}
};
Bandera de idioma español. In-Game asset. 2d. High contrast. No shadows
Bandera de Idioma inglés curvada con sus primeras letras EN. In-Game asset. 2d. High contrast. No shadows
Planeta tierra con un libro. In-Game asset. 2d. High contrast. No shadows
Pelusa roja de ojos amarillos tierno. In-Game asset. 2d. High contrast. No shadows
Marco de menu con relleno sin ningun texto. In-Game asset. 2d. High contrast. No shadows
Fondo de ambiente digital con azul y verde. In-Game asset. 2d. High contrast. No shadows
Carne pequeña. In-Game asset. 2d. High contrast. No shadows
Carne Grande. In-Game asset. 2d. High contrast. No shadows
Sirloin. In-Game asset. 2d. High contrast. No shadows
Medicina. In-Game asset. 2d. High contrast. No shadows
Benda. In-Game asset. 2d. High contrast. No shadows
Agumon. In-Game asset. 2d. High contrast. No shadows
barra llena. In-Game asset. 2d. High contrast. No shadows
boton sin texto. In-Game asset. 2d. High contrast. No shadows
zzZZZ. In-Game asset. 2d. High contrast. No shadows
Greymon. In-Game asset. 2d. High contrast. No shadows
Wargreymon. In-Game asset. 2d. High contrast. No shadows
Metalgreymon. In-Game asset. 2d. High contrast. No shadows
Omegamon. In-Game asset. 2d. High contrast. No shadows
Cara Koromon feliz. In-Game asset. 2d. High contrast. No shadows
Botamon. In-Game asset. 2d. High contrast. No shadows
Angemon. In-Game asset. 2d. High contrast. No shadows
Angewomon. In-Game asset. 2d. High contrast. No shadows
Gabumon. In-Game asset. 2d. High contrast. No shadows
Garurumon. In-Game asset. 2d. High contrast. No shadows
Magnaangemon. In-Game asset. 2d. High contrast. No shadows
magnadramon. In-Game asset. 2d. High contrast. No shadows
Metalgarurumon. In-Game asset. 2d. High contrast. No shadows
Ophanimon blue armor complete body sensual. In-Game asset. 2d. High contrast. No shadows
Poyomon. In-Game asset. 2d. High contrast. No shadows
Patamon. In-Game asset. 2d. High contrast. No shadows
Punimon. In-Game asset. 2d. High contrast. No shadows
Seraphimon. In-Game asset. 2d. High contrast. No shadows
Tokomon. In-Game asset. 2d. High contrast. No shadows
Tsunomon. In-Game asset. 2d. High contrast. No shadows
Weregarurumon. In-Game asset. 2d. High contrast. No shadows
Digi huevo de botamon. In-Game asset. 2d. High contrast. No shadows
Digi huevo con el patron clasico de Punimon. In-Game asset. 2d. High contrast. No shadows
Digi huevo con el patron clasico de Puyomon. In-Game asset. 2d. High contrast. No shadows
Moneda ojo monstruo. In-Game asset. 2d. High contrast. No shadows
Labrys personaje de Persona 4 Arena con ropa de tendera.. In-Game asset. 2d. High contrast. No shadows
Mesa de tienda para poner un personaje detras. In-Game asset. 2d. High contrast. No shadows
Tecla gris. In-Game asset. 2d. High contrast. No shadows
Caca rosada. In-Game asset. 2d. High contrast. No shadows
Jabón. In-Game asset. 2d. High contrast. No shadows