User prompt
Los botones principales siguen estando muy pegados separa los más y los iconos del inventario más grandes aun también vamos añadir iconos a la barra hambre, Diversión y fatiga.
User prompt
También has los iconos del inventario más grandes además algunos botones estan muy pegados como el de entranamiento y se sobre ponen con otros
User prompt
Deberíamos hacer los botones un poco más grandes y el texto también sobra mucho espacio y además la barra de diversión y hambre deben bajar más lento por si solas
User prompt
La barra de hambre no baja por si sola y la barra de diversión baja lentamente, la barra de dormir se cambia a fatiga y esta sube solo cuando entrena, falta añadir un icono encima del Digimon que indique si esta lesionado o enfermo. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
La barra de hambre solo bajara un poco cuando entrenes y juegues con el Digimon además el botón de alimentar lo vamos a quitar y en su lugar añadiremos un inventario abajo de los botones principales en ese inventario en cada nueva partida y solo en estas, el jugador recibirá 10 carnes pequeñas 5 benditas y 3 medicinas, el digimon puede lastimarse si lo entrenas con cansancio y si no le das una bendita esto empeora y se enferma si no le das la medicina se muere y comienzas de nuevo también el digimon muere si la barra de hambre llega a cero y no lo alimentas en 5 minutos, el tiempo de lesión a enfermedad es de 30 minutos, las carnes que existen son, Carne Pequeña, Carne Mediana, Carne Grande, Solomillo. ↪💡 Consider importing and using the following plugins: @upit/storage.v1, @upit/tween.v1
User prompt
Hay que añadir un fondo
User prompt
Please fix the bug: 'Uncaught TypeError: self.updateAppearance is not a function' in or related to this line: 'self.updateAppearance();' Line Number: 159
User prompt
Puedes añadir los assets que faltan de todo eso y por favor arregla bien el teclado digital el espacio y borrar se sobre ponen en otras letras
User prompt
Muy bien falta que los Digimon tengan diferentes apariencia y cada uno evolucione según los parámetros de nivel, ataque, vida, velocidad, peso y ratio de victorias, todas esas estadísticas deberían ser visibles al pulsar el Digimon y por cierto quiero que el jugar es el que ponga el nombre del Digimon con un límite de 7 Caracteres. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'storage.savedGames = savedGames;' Line Number: 893 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'Uncaught TypeError: storage.get is not a function' in or related to this line: 'var savedGames = storage.get('savedGames') || [];' Line Number: 833 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'storage.savedGames = savedGames;' Line Number: 893
User prompt
Faltaron varias cosas de las que te pedi por favor ↪💡 Consider importing and using the following plugins: @upit/storage.v1, @upit/tween.v1
User prompt
Muy bien pero deberíamos añadir un menu principal donde diga nuevo juego y también ver las partidas guardadas, cuando iniciemos un juego nuevo nos pedirá el nombre del Digimon y escogeremos uno de los 3 digi huevos coloca otros 3 con un candado que se desbloquearan cuando los hayamos comprado dentro del juego o completado una misión tendremos que añadir dinero y una tienda, el dinero se conseguirá jugando con el Digimon o en combates, será necesario implementar un sistema de entrenamiento de ataque, vida y velocidad la defensa se calculará según el peso del Digimon y este se sabrá por la cantidad de comida digerida el entrenamiento bajara un poquito el peso cada vez y la comida lo subirá, añadiremos diferentes comidas con efectos únicos también debemos tener música en la tienda, en el menú principal y en el menú de entrenamiento, el entrenamiento y jugar nos dará experiencia la cual aumentará el nivel de evolución cada Digimon tendrá 5 evoluciones. Más adelante profundizaremos la mecánica de combate rítmica junto con sus tipos y elementos. ↪💡 Consider importing and using the following plugins: @upit/storage.v1, @upit/tween.v1
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'setText')' in or related to this line: 'evolutionText.setText(getText('evolutionLevel') + ': ' + pet.evolutionLevel);' Line Number: 412
User prompt
Please fix the bug: 'hungerBar.children[1].setText is not a function' in or related to this line: 'return languages[currentLanguage][key] || key;' Line Number: 400
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'setText')' in or related to this line: 'evolutionText.setText(getText('evolutionLevel') + ': ' + pet.evolutionLevel);' Line Number: 415
User prompt
Please fix the bug: 'hungerBar.children[1].setText is not a function' in or related to this line: 'return languages[currentLanguage][key] || key;' Line Number: 400
User prompt
Si y le pones un icono de bandera según el idioma ↪💡 Consider importing and using the following plugins: @upit/storage.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Digi Pet Evolution
Initial prompt
Hola Ava mucho gusto quisiera crear un juego inspirado en los tamagoshi de Digimon
/**** * 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