User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'costo')' in or related to this line: 'if (playerNutripoints >= item.costo && ownedItems.indexOf(item.id) === -1) {' Line Number: 1748
User prompt
el boton de volver de cada sección que se encuentre en la parte inferior de cada sub página
User prompt
Elimina el texto amarillo que dice: Nutripoints y agranda el que dice Nutripoints pero de color verde ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
ELimina el texto que dice: Nutripoints y donde dice: TOTAL, cambialo por Nutripoints:
User prompt
HABILITAR LA OPCIÓN DE DAR CLICK AL BOTON DE ''PLAY'' PARA QUE COMIENZE UNA NUEVA PARTIDA ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
habilitar la opción de dar click al boton PLAY, cuando se le de click, comenzar el juego ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Comenzar el juego cuando se le da click al boton de PLAY ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Mientras este en la pantalla de inicio, la comida aún no debe caer, y el temporizador para el modo experto aún no debe comenzar. Interactividad del botón PLAY: Habilita detección de clic / toque táctil. Al presionarlo: Cambiar momentáneamente al estado presionado (animación escala o tint). Luego de 300‐500 ms, cambiar de escena a la del juego (llámala GameScene). Mientras MainMenu esté activo, la variable global gameStarted (o equivalente) debe permanecer false. Cámbiala a true solo dentro del callback del botón PLAY. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
El menu de inicio Debe cargarse como primer estado cuando la app se abre. No se debe crear ni actualizar ninguna lógica del juego principal mientras esta escena esté activa.
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'moveTo')' in or related to this line: 'player.moveTo(gamePos.x);' Line Number: 703
User prompt
Crea una pantalla de inicio para el juego “Caza‐ingredientes: Elige bien, vive mejor”. Debe contener tres botones grandes y táctiles: PLAY – inicia inmediatamente la partida. MISIONES – abre un panel con tres misiones aleatorias diarias: Lógica de MISIONES Crea un array de 10 misiones; cada día (o al primer inicio) el juego elige 3 sin repetir y las guarda en localStorage para 24 h. Ejemplo de misiones (puedes añadir más): “Alcanza 20 de Energía en una sola partida.” “Atrapa 10 frutas o verduras sanas en una partida.” “Evita TODAS las gaseosas durante 60 segundos.” “Consigue 6 Nutripoints en total.” “Recoge 5 botellas de agua (power‐ups) en una sesión.” “Juega 3 partidas seguidas sin perder una vida.” “Completa una partida con al menos 3 vidas restantes.” “Atrapa 3 alimentos ‘falsos sanos’ y aún así gana.” “Gana 2 partidas consecutivas con Energía ≥25.” “Juega durante 5 min. continuos sin colapsar.” Cada misión cumplida otorga +2 Nutripoints y se marca con un ✔️ y un sonido de victoria. TIENDA – permite canjear “Nutripoints” por skins y fondos: [ {"id":"skin_rojo","nombre":"Skin Roja","costo":5,"tipo":"skin"}, {"id":"skin_verde","nombre":"Skin Verde","costo":5,"tipo":"skin"}, {"id":"fondo_parque","nombre":"Fondo Parque","costo":8,"tipo":"fondo"}, {"id":"fondo_playa","nombre":"Fondo Playa","costo":10,"tipo":"fondo"} ] Muestra íconos, costo y botón COMPRAR; si el jugador no tiene Nutripoints suficientes, botón deshabilitado y mensaje “Necesitas más Nutripoints”. Al comprar, resta puntos, guarda en localStorage y muestra un pequeño popup: “¡Nuevo artículo desbloqueado!” con un shine SFX. Permitir seleccionar la skin/fondo adquirido y aplicar al empezar la partida. PREGUNTAS - abra un menú de preguntas y respuestas dinámico. Función: Al presionarlo abre un panel/escena “faqScene”. 2. Estructura de la escena faqScene Requisito Detalle a implementar Diseño Fondo claro, scroll vertical si es necesario. Formato de preguntas Lista tipo “accordion” (desplegable): al tocar una pregunta, se expande para mostrar la respuesta; al tocar otra, se cierra la anterior. Interactividad Animación de flecha rotando 90°, sonido click suave. Botón SALIR Icono “←” en esquina para volver a menú principal. 3. Contenido inicial de preguntas (puedes ampliarlo) Pregunta (label del acordeón) Respuesta sugerida (texto simple) ¿Cómo se juega “Caza‐ingredientes”:Mueve tu avatar a izquierda y derecha y atrapa solo los alimentos saludables para sumar Energía. Evita los ultraprocesados y trampas. ¿Para qué sirve la barra de Energía?: Representa tu nivel de salud en el juego. Si llega a 0, pierdes. Si llegas a 30, ganas Nutripoints extra. ¿Qué son los Nutripoints y cómo se consiguen?: Son puntos que obtienes al ganar con Energía completa o cumpliendo misiones. Sirven para comprar skins y fondos en la Tienda. ¿Cómo funciona la Tienda?: En la Tienda puedes cambiar Nutripoints por apariencias nuevas para tu avatar o fondos temáticos para el juego. ¿Cómo se completan las misiones? Ve a MISIONES, revisa las tareas diarias y juega hasta lograr cada objetivo. Al cumplirlas, recibes Nutripoints automáticamente. Valor nutricional de cada alimento Pulsa cada alimento en el menú desplegable para ver calorías, fibra, vitaminas y por qué es bueno o malo. (Implementar sublista o popup con datos que ya definiste). ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
baja un poco el boton de jgar de nuevo y agrandalo
User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'setText')' in or related to this line: 'nutripointsText.setText('Nutripoints: ' + gameNutripoints);' Line Number: 227
User prompt
los nutripoints solo se ganan cuando la barra de energía llega a 30 en una partida y se acumulan según las partidas jugadas seguidamente ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
que se muentren los nutripoins ganados en un lado y que se acumulen según las partidas que se juegan seguidamente ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
que se muestren los nutripoints ganados en una partida y se vayan acumulando según juegan ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Crea un sistema de puntaje llamado “Nutripoints” en un videojuego educativo. Quiero que se otorguen 2 Nutripoints cada vez que el jugador termine una partida con la barra de energía al máximo (30/30). 📌 Condiciones clave: El puntaje debe sumarse automáticamente al terminar la partida solo si la barra está completamente llena. El total de Nutripoints acumulados debe guardarse de forma persistente (ej: en una variable global, base de datos local o archivo json, según el motor del juego). Al final de cada partida, debe aparecer un mensaje como: “🎉 ¡Ganaste 2 Nutripoints por llegar al máximo de energía! Total acumulado: [X]” Si la barra no está completa, no se otorgan puntos y al final de la partida debe aparecer un mensaje como: “¡Sigue eligiendo bien para ganar Nutripoints!” ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Crea un sistema de puntaje llamado “Nutripoints” en un videojuego educativo. Quiero que se otorguen 2 Nutripoints cada vez que el jugador termine una partida con la barra de energía al máximo (30/30). 📌 Condiciones clave: El puntaje debe sumarse automáticamente al terminar la partida solo si la barra está completamente llena. El total de Nutripoints acumulados debe guardarse de forma persistente (ej: en una variable global, base de datos local o archivo json, según el motor del juego). Al final de cada partida, debe aparecer un mensaje como: “🎉 ¡Ganaste 2 Nutripoints por llegar al máximo de energía! Total acumulado: [X]” Si la barra no está completa, no se otorgan puntos y debe aparecer un mensaje como: “¡Sigue eligiendo bien para ganar Nutripoints!” ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
elimina la puntuación
User prompt
que el nivel experto comienze 20 segundos despues del comienzo de cada nueva partida y que cuando esta acabe se reinicie el contador
User prompt
pon más abajo el texto del alimento que más consumió en la partida
User prompt
en la pantalla de game over cuando termine una partida que diga: Alimento que más consumiste en esta partida. Y que debajo este el texto del alimento que más consiguio el jugador
User prompt
cuando se termine la partida que la sombra no sea el icono del jugador, simplemente un rectangulo oscuro donde este todo el texto y el boton de jugar de nuevo
User prompt
cuando se acabe la energía y se termine juego, en vez de pantalla final que diga: FATIGA, FALTA DE ENERGÍA. Y aumenta el tamaño de las letras de los textos que aparecen según el alimento que más consiguio el jugador
User prompt
Podrías hacer que aparezca más comida a la vez
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var FAQScreen = Container.expand(function () { var self = Container.call(this); // Create background var bg = LK.getAsset('energyBarBg', { width: 2048, height: 2732, anchorX: 0, anchorY: 0 }); bg.tint = 0xF8F9FA; self.addChild(bg); // Title var titleText = new Text2('PREGUNTAS FRECUENTES', { size: 80, fill: 0x2C3E50, font: "Impact" }); titleText.anchor.set(0.5, 0.5); titleText.x = 2048 / 2; titleText.y = 250; self.addChild(titleText); // Back button var backButton = LK.getAsset('restartButton', { width: 200, height: 80, anchorX: 0.5, anchorY: 0.5 }); backButton.tint = 0xFF6B35; backButton.x = 150; backButton.y = 150; self.addChild(backButton); var backText = new Text2('← VOLVER', { size: 50, fill: 0xFFFFFF, font: "Impact" }); backText.anchor.set(0.5, 0.5); backText.x = 150; backText.y = 150; self.addChild(backText); backButton.down = function () { showStartScreen(); }; backText.down = function () { showStartScreen(); }; self.faqContainer = new Container(); self.addChild(self.faqContainer); // Bottom back button var bottomBackButton = LK.getAsset('restartButton', { width: 400, height: 100, anchorX: 0.5, anchorY: 0.5 }); bottomBackButton.tint = 0xFF6B35; bottomBackButton.x = 2048 / 2; bottomBackButton.y = 2600; self.addChild(bottomBackButton); var bottomBackText = new Text2('← VOLVER', { size: 60, fill: 0xFFFFFF, font: "Impact" }); bottomBackText.anchor.set(0.5, 0.5); bottomBackText.x = 2048 / 2; bottomBackText.y = 2600; self.addChild(bottomBackText); bottomBackButton.down = function () { showStartScreen(); }; bottomBackText.down = function () { showStartScreen(); }; return self; }); var FallingItem = Container.expand(function (type, specificFood) { var self = Container.call(this); self.type = type; self.specificFood = specificFood; // Set different speeds based on type and add randomness if (type === 'anxiety') { self.speed = fallSpeed * 1.5; // Anxiety bombs fall faster } else if (type === 'water') { self.speed = fallSpeed * 0.8; // Water bottles fall slower } else { // Food items have variable speeds between 1.2x and 2.0x base speed (much faster) var speedMultiplier = 1.2 + Math.random() * 0.8; // Increase speed significantly during expert mode if (anxietyBombsActive) { speedMultiplier *= 2.2; // Make items fall 120% faster in expert mode } self.speed = fallSpeed * speedMultiplier; } var assetName = specificFood || 'waterBottle'; if (type === 'water') assetName = 'waterBottle';else if (type === 'anxiety') assetName = 'anxietyBomb'; var graphic = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { self.y += self.speed; }; return self; }); var MissionsScreen = Container.expand(function () { var self = Container.call(this); // Create background var bg = LK.getAsset('energyBarBg', { width: 2048, height: 2732, anchorX: 0, anchorY: 0 }); bg.tint = 0x2C3E50; bg.alpha = 0.95; self.addChild(bg); // Title var titleText = new Text2('MISIONES DIARIAS', { size: 100, fill: 0xFFD700, font: "Impact" }); titleText.anchor.set(0.5, 0.5); titleText.x = 2048 / 2; titleText.y = 300; self.addChild(titleText); // Back button var backButton = LK.getAsset('restartButton', { width: 200, height: 80, anchorX: 0.5, anchorY: 0.5 }); backButton.tint = 0xFF6B35; backButton.x = 150; backButton.y = 150; self.addChild(backButton); var backText = new Text2('← VOLVER', { size: 50, fill: 0xFFFFFF, font: "Impact" }); backText.anchor.set(0.5, 0.5); backText.x = 150; backText.y = 150; self.addChild(backText); backButton.down = function () { showStartScreen(); }; backText.down = function () { showStartScreen(); }; self.missionsContainer = new Container(); self.addChild(self.missionsContainer); // Bottom back button var bottomBackButton = LK.getAsset('restartButton', { width: 400, height: 100, anchorX: 0.5, anchorY: 0.5 }); bottomBackButton.tint = 0xFF6B35; bottomBackButton.x = 2048 / 2; bottomBackButton.y = 2600; self.addChild(bottomBackButton); var bottomBackText = new Text2('← VOLVER', { size: 60, fill: 0xFFFFFF, font: "Impact" }); bottomBackText.anchor.set(0.5, 0.5); bottomBackText.x = 2048 / 2; bottomBackText.y = 2600; self.addChild(bottomBackText); bottomBackButton.down = function () { showStartScreen(); }; bottomBackText.down = function () { showStartScreen(); }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerBody = self.attachAsset('player', { anchorX: 0.5, anchorY: 1.0 }); var basket = self.attachAsset('basket', { anchorX: 0.5, anchorY: 0.5, y: -110 }); self.speed = 8; self.targetX = self.x; self.update = function () { var dx = self.targetX - self.x; if (Math.abs(dx) > 5) { self.x += dx * 0.15; } else { self.x = self.targetX; } // Keep player within bounds if (self.x < 150) self.x = 150; if (self.x > 2048 - 150) self.x = 2048 - 150; }; self.moveTo = function (targetX) { self.targetX = targetX; }; return self; }); var StartScreen = Container.expand(function () { var self = Container.call(this); // Create background var bg = LK.getAsset('energyBarBg', { width: 2048, height: 2732, anchorX: 0, anchorY: 0 }); bg.tint = 0x5d6c16; self.addChild(bg); // Game title var titleText = new Text2('Caza-ingredientes', { size: 120, fill: 0xFFD700, font: "Impact" }); titleText.anchor.set(0.5, 0.5); titleText.x = 2048 / 2; titleText.y = 400; self.addChild(titleText); var subtitleText = new Text2('Elige bien, vive mejor', { size: 80, fill: 0x32CD32, font: "Impact" }); subtitleText.anchor.set(0.5, 0.5); subtitleText.x = 2048 / 2; subtitleText.y = 520; self.addChild(subtitleText); // Create buttons var buttonProps = [{ text: 'PLAY', y: 800, color: 0x32CD32 }, { text: 'MISIONES', y: 1000, color: 0xFF6B35 }, { text: 'TIENDA', y: 1200, color: 0x4ECDC4 }, { text: 'PREGUNTAS', y: 1400, color: 0x9B59B6 }]; self.buttons = []; for (var i = 0; i < buttonProps.length; i++) { var buttonBg = LK.getAsset('restartButton', { width: 600, height: 120, anchorX: 0.5, anchorY: 0.5 }); buttonBg.tint = buttonProps[i].color; buttonBg.x = 2048 / 2; buttonBg.y = buttonProps[i].y; self.addChild(buttonBg); var buttonText = new Text2(buttonProps[i].text, { size: 70, fill: 0xFFFFFF, font: "Impact" }); buttonText.anchor.set(0.5, 0.5); buttonText.x = 2048 / 2; buttonText.y = buttonProps[i].y; self.addChild(buttonText); buttonBg.buttonType = buttonProps[i].text; buttonText.buttonType = buttonProps[i].text; self.buttons.push({ bg: buttonBg, text: buttonText, type: buttonProps[i].text }); } // Button click handlers for (var j = 0; j < self.buttons.length; j++) { (function (button) { button.bg.down = function (x, y, obj) { handleStartScreenButton(button.type); }; button.text.down = function (x, y, obj) { handleStartScreenButton(button.type); }; })(self.buttons[j]); } return self; }); var StoreScreen = Container.expand(function () { var self = Container.call(this); // Create background var bg = LK.getAsset('energyBarBg', { width: 2048, height: 2732, anchorX: 0, anchorY: 0 }); bg.tint = 0x2C3E50; bg.alpha = 0.95; self.addChild(bg); // Title var titleText = new Text2('TIENDA', { size: 100, fill: 0xFFD700, font: "Impact" }); titleText.anchor.set(0.5, 0.5); titleText.x = 2048 / 2; titleText.y = 250; self.addChild(titleText); // Nutripoints display var nutripointsDisplay = new Text2('Nutripoints: ' + (storage.totalNutripoints || 0), { size: 60, fill: 0x32CD32, font: "Impact" }); nutripointsDisplay.anchor.set(0.5, 0.5); nutripointsDisplay.x = 2048 / 2; nutripointsDisplay.y = 350; self.addChild(nutripointsDisplay); // Back button var backButton = LK.getAsset('restartButton', { width: 200, height: 80, anchorX: 0.5, anchorY: 0.5 }); backButton.tint = 0xFF6B35; backButton.x = 150; backButton.y = 150; self.addChild(backButton); var backText = new Text2('← VOLVER', { size: 50, fill: 0xFFFFFF, font: "Impact" }); backText.anchor.set(0.5, 0.5); backText.x = 150; backText.y = 150; self.addChild(backText); backButton.down = function () { showStartScreen(); }; backText.down = function () { showStartScreen(); }; self.storeContainer = new Container(); self.addChild(self.storeContainer); // Bottom back button var bottomBackButton = LK.getAsset('restartButton', { width: 400, height: 100, anchorX: 0.5, anchorY: 0.5 }); bottomBackButton.tint = 0xFF6B35; bottomBackButton.x = 2048 / 2; bottomBackButton.y = 2600; self.addChild(bottomBackButton); var bottomBackText = new Text2('← VOLVER', { size: 60, fill: 0xFFFFFF, font: "Impact" }); bottomBackText.anchor.set(0.5, 0.5); bottomBackText.x = 2048 / 2; bottomBackText.y = 2600; self.addChild(bottomBackText); bottomBackButton.down = function () { showStartScreen(); }; bottomBackText.down = function () { showStartScreen(); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ // Game state management var currentScreen = 'start'; // 'start', 'game', 'missions', 'store', 'faq' var gameStarted = false; // Track if game has been started via PLAY button var startScreen; var missionsScreen; var storeScreen; var faqScreen; // Mission system var allMissions = ["Alcanza 20 de Energía en una sola partida.", "Atrapa 10 frutas o verduras sanas en una partida.", "Evita TODAS las gaseosas durante 60 segundos.", "Consigue 6 Nutripoints en total.", "Recoge 5 botellas de agua (power-ups) en una sesión.", "Juega 3 partidas seguidas sin perder una vida.", "Completa una partida con al menos 3 vidas restantes.", "Atrapa 3 alimentos 'falsos sanos' y aún así gana.", "Gana 2 partidas consecutivas con Energía ≥25.", "Juega durante 5 min. continuos sin colapsar."]; // Store items var storeItems = [{ id: "skin_rojo", nombre: "Skin Roja", costo: 5, tipo: "skin" }, { id: "skin_verde", nombre: "Skin Verde", costo: 5, tipo: "skin" }, { id: "fondo_parque", nombre: "Fondo Parque", costo: 8, tipo: "fondo" }, { id: "fondo_playa", nombre: "Fondo Playa", costo: 10, tipo: "fondo" }]; // FAQ data var faqData = [{ question: "¿Cómo se juega \"Caza-ingredientes\"?", answer: "Mueve tu avatar a izquierda y derecha y atrapa solo los alimentos saludables para sumar Energía. Evita los ultraprocesados y trampas." }, { question: "¿Para qué sirve la barra de Energía?", answer: "Representa tu nivel de salud en el juego. Si llega a 0, pierdes. Si llegas a 30, ganas Nutripoints extra." }, { question: "¿Qué son los Nutripoints y cómo se consiguen?", answer: "Son puntos que obtienes al ganar con Energía completa o cumpliendo misiones. Sirven para comprar skins y fondos en la Tienda." }, { question: "¿Cómo funciona la Tienda?", answer: "En la Tienda puedes cambiar Nutripoints por apariencias nuevas para tu avatar o fondos temáticos para el juego." }, { question: "¿Cómo se completan las misiones?", answer: "Ve a MISIONES, revisa las tareas diarias y juega hasta lograr cada objetivo. Al cumplirlas, recibes Nutripoints automáticamente." }]; // Game elements // Fake healthy foods // Junk foods // Healthy foods // Game variables // Healthy Foods - Fruits // Healthy Foods - Vegetables // Healthy Foods - Proteins & Grains // Junk Foods // Fake Healthy Foods var player; var fallingItems = []; var energy = 15; var lives = 3; var fallSpeed = 350 / 60; // 350px/s converted to pixels per frame (much faster) var lastSpeedIncrease = 0; var lastWaterSpawn = 0; var gameStartTime = 0; var foodsCaught = 0; var anxietyBombsActive = false; var lastSpawnTime = 0; var lastAnxietySpawnTime = 0; var expertMessageShown = false; var gameActive = true; // Track if game is active var expertModeTimer = 0; // Timer to track when expert mode should activate (20 seconds) var expertModeStartTime = 1200; // 20 seconds * 60 fps = 1200 frames // Nutripoints system variables var totalNutripoints = storage.totalNutripoints || 0; var gameNutripoints = 0; // Points earned in current game // Food tracking variables var foodCounts = { 'apple': 0, 'banana': 0, 'hardEgg': 0, 'broccoli': 0, 'carrot': 0, 'wholeBread': 0, 'waterBottle': 0 }; // UI elements var livesText; var scoreText; var energyText; var energyBarBg; var energyBarFill; var nutripointsText; var totalNutripointsText; // Initialize UI function initializeUI() { // Energy text with larger size energyText = new Text2('Energía: 15/30', { size: 72, fill: 0xFFFFFF, font: "Impact" }); energyText.anchor.set(0, 0); LK.gui.topLeft.addChild(energyText); energyText.x = 150; energyText.y = 20; // Energy bar background energyBarBg = LK.getAsset('energyBarBg', { anchorX: 0, anchorY: 0 }); LK.gui.topLeft.addChild(energyBarBg); energyBarBg.x = 150; energyBarBg.y = 100; // Energy bar fill energyBarFill = LK.getAsset('energyBarFill', { anchorX: 0, anchorY: 0 }); LK.gui.topLeft.addChild(energyBarFill); energyBarFill.x = 150; energyBarFill.y = 100; // Lives text with larger size livesText = new Text2('Vidas: 3', { size: 84, fill: 0xFF0000, font: "Impact" }); livesText.anchor.set(1, 0); LK.gui.topRight.addChild(livesText); livesText.x = -20; livesText.y = 20; // Total Nutripoints display (made larger) totalNutripointsText = new Text2('Nutripoints: ' + totalNutripoints, { size: 72, fill: 0x32CD32, font: "Impact" }); totalNutripointsText.anchor.set(1, 0); LK.gui.topRight.addChild(totalNutripointsText); totalNutripointsText.x = -20; totalNutripointsText.y = 120; // Score text removed } // Update UI function updateUI() { if (energyText) energyText.setText('Energía: ' + energy + '/30'); if (livesText) livesText.setText('Vidas: ' + lives); if (totalNutripointsText) totalNutripointsText.setText('Nutripoints: ' + totalNutripoints); // Score text update removed // Update energy bar fill based on current energy (0-30 range) if (energyBarFill) { var energyPercentage = energy / 30; energyBarFill.width = 400 * energyPercentage; // Change energy bar color based on energy level if (energy >= 20) { energyBarFill.tint = 0x00ff00; // Green for high energy } else if (energy >= 10) { energyBarFill.tint = 0xffff00; // Yellow for medium energy } else { energyBarFill.tint = 0xff0000; // Red for low energy } } } // Flash effect function flashScreen(color) { LK.effects.flashScreen(color, 300); } // Food arrays for variety - exactly 10 sprite types + 2 fake healthy var healthyFoods = ['banana', 'apple', 'carrot', 'broccoli', 'wholeBread', 'hardEgg']; var junkFoods = ['soda', 'chips', 'candy', 'burger']; var fakeFoods = ['cerealBar', 'flavoredYogurt']; // Spawn falling item function spawnFallingItem() { var type = 'healthy'; var specificFood = null; var rand = Math.random(); if (foodsCaught > 0 && foodsCaught % 20 === 0 && lastWaterSpawn !== foodsCaught) { type = 'water'; lastWaterSpawn = foodsCaught; } else if (rand < 0.3) { type = 'junk'; specificFood = junkFoods[Math.floor(Math.random() * junkFoods.length)]; } else if (rand < 0.5) { type = 'fake'; specificFood = fakeFoods[Math.floor(Math.random() * fakeFoods.length)]; } else { type = 'healthy'; specificFood = healthyFoods[Math.floor(Math.random() * healthyFoods.length)]; } var item = new FallingItem(type, specificFood); item.x = Math.random() * (2048 - 350) + 175; item.y = -175; fallingItems.push(item); game.addChild(item); } // Spawn anxiety bomb function spawnAnxietyBomb() { var item = new FallingItem('anxiety', null); item.x = Math.random() * (2048 - 350) + 175; item.y = -175; fallingItems.push(item); game.addChild(item); } // Helper function for player visual feedback function playerFeedback(color, duration, scaleEffect) { if (scaleEffect) { tween(player, { scaleX: 1.2, scaleY: 1.2 }, { duration: duration, onFinish: function onFinish() { tween(player, { scaleX: 1.0, scaleY: 1.0 }, { duration: duration }); } }); } else { tween(player, { tint: color }, { duration: duration, onFinish: function onFinish() { tween(player, { tint: 0xFFFFFF }, { duration: duration }); } }); } } // Helper function for vibration feedback function vibrateDevice() { if (navigator && navigator.vibrate) { navigator.vibrate(100); } } // Handle item collision function handleItemCollision(item) { switch (item.type) { case 'healthy': energy = Math.min(30, energy + 1); // Score increment removed LK.getSound('ping').play(); flashScreen(0x32CD32); playerFeedback(0x32CD32, 100, false); foodsCaught++; // Track healthy food counts if (item.specificFood && foodCounts.hasOwnProperty(item.specificFood)) { foodCounts[item.specificFood]++; } break; case 'junk': lives--; energy = Math.max(0, energy - 2); LK.getSound('buzz').play(); vibrateDevice(); flashScreen(0xFF4500); playerFeedback(0xFF4500, 100, false); break; case 'fake': energy = Math.max(0, energy - 2); LK.getSound('buzz').play(); vibrateDevice(); flashScreen(0xFFD700); playerFeedback(0xFFD700, 100, false); break; case 'water': energy = Math.min(30, energy + 3); // Score increment removed LK.getSound('powerup').play(); flashScreen(0x00BFFF); playerFeedback(0x00BFFF, 150, true); // Track water bottle counts foodCounts['waterBottle']++; break; case 'anxiety': energy = Math.max(0, energy - 5); LK.getSound('explosion').play(); vibrateDevice(); flashScreen(0x8B008B); playerFeedback(0x8B008B, 300, false); break; } } // Initialize game function initializeGame() { gameStartTime = LK.ticks; // Create player player = new Player(); player.x = 2048 / 2; player.y = 2732 - 100; game.addChild(player); // Initialize UI initializeUI(); updateUI(); } // Game input handling game.down = function (x, y, obj) { if (!player) return; // Check if player exists var gamePos = game.toLocal({ x: x, y: y }); player.moveTo(gamePos.x); }; game.move = function (x, y, obj) { if (!player) return; // Check if player exists var gamePos = game.toLocal({ x: x, y: y }); player.moveTo(gamePos.x); }; // Main game update loop game.update = function () { // Don't update game logic if game hasn't started or is not active if (!gameStarted || !gameActive) { return; } var currentTime = LK.ticks; var gameTime = (currentTime - gameStartTime) / 60; // Convert to seconds // Increase speed every 15 seconds if (gameTime - lastSpeedIncrease >= 15) { fallSpeed += 20 / 60; // Increase by 20px/s (double the previous increment) lastSpeedIncrease = gameTime; } // Increment expert mode timer expertModeTimer++; // Activate anxiety bombs after 20 seconds (1200 frames) if (expertModeTimer >= expertModeStartTime && !anxietyBombsActive) { anxietyBombsActive = true; lastAnxietySpawnTime = currentTime; // Only show expert message when expert mode activates if (expertModeTimer >= expertModeStartTime && !expertMessageShown) { expertMessageShown = true; // Create full screen overlay for expert message var expertOverlay = LK.getAsset('basket', { width: 2048, height: 2732, anchorX: 0, anchorY: 0 }); expertOverlay.tint = 0x000000; expertOverlay.alpha = 0.9; game.addChild(expertOverlay); // Show expert challenge message with attractive styling var expertText = new Text2('¡RETO EXPERTO!', { size: 150, fill: 0xFFD700, font: "Impact" }); expertText.anchor.set(0.5, 0.5); expertText.x = 2048 / 2; expertText.y = 2732 / 2 - 100; game.addChild(expertText); // Add subtitle text var subtitleText = new Text2('¡Los alimentos caen más rápido!', { size: 75, fill: 0xFF4500, font: "Impact" }); subtitleText.anchor.set(0.5, 0.5); subtitleText.x = 2048 / 2; subtitleText.y = 2732 / 2 + 50; game.addChild(subtitleText); // Animate expert message with pulsing effect tween(expertText, { scaleX: 1.2, scaleY: 1.2 }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { tween(expertText, { scaleX: 1.0, scaleY: 1.0 }, { duration: 500, easing: tween.easeInOut }); } }); // Animate and remove message after 4 seconds tween(expertOverlay, { alpha: 0 }, { duration: 4000, onFinish: function onFinish() { expertOverlay.destroy(); } }); tween(expertText, { alpha: 0 }, { duration: 4000, onFinish: function onFinish() { expertText.destroy(); } }); tween(subtitleText, { alpha: 0 }, { duration: 4000, onFinish: function onFinish() { subtitleText.destroy(); } }); } } // Spawn items every 1.5 seconds if (currentTime - lastSpawnTime >= 90) { // 1.5 * 60 = 90 frames // Spawn 2-3 items at once for more food variety var itemsToSpawn = 2 + Math.floor(Math.random() * 2); // 2 or 3 items for (var s = 0; s < itemsToSpawn; s++) { spawnFallingItem(); } lastSpawnTime = currentTime; } // Spawn anxiety bombs every 40 seconds after activation if (anxietyBombsActive && currentTime - lastAnxietySpawnTime >= 2400) { // 40 * 60 = 2400 frames spawnAnxietyBomb(); lastAnxietySpawnTime = currentTime; } // Update falling items for (var i = fallingItems.length - 1; i >= 0; i--) { var item = fallingItems[i]; // Check collision with player if (item.intersects(player)) { handleItemCollision(item); item.destroy(); fallingItems.splice(i, 1); continue; } // Remove items that fall off screen if (item.y > 2732 + 350) { item.destroy(); fallingItems.splice(i, 1); } } // Update UI updateUI(); // Check game over conditions if (energy >= 30) { // Store final stats for victory storage.finalEnergy = energy; storage.finalTime = Math.floor(gameTime); storage.gameEndReason = 'victoria'; gameActive = false; // Stop game updates showVictoryMessage(); } else if (lives <= 0) { // Store final stats when lives reach 0 storage.finalEnergy = energy; storage.finalTime = Math.floor(gameTime); storage.gameEndReason = 'colapso'; gameActive = false; // Stop game updates showGameOver(); } else if (energy <= 0) { // Store final stats storage.finalEnergy = energy; storage.finalTime = Math.floor(gameTime); storage.gameEndReason = 'fatiga'; gameActive = false; // Stop game updates showCustomGameOver(); } }; // Get nutritional information for the most caught food function getNutritionalInfo() { var maxCount = 0; var mostCaughtFood = null; // Find the food with highest count for (var food in foodCounts) { if (foodCounts[food] > maxCount) { maxCount = foodCounts[food]; mostCaughtFood = food; } } if (!mostCaughtFood || maxCount === 0) { return { title: "¡Sigue practicando!", info: "Intenta atrapar más alimentos saludables la próxima vez." }; } var nutritionalData = { 'apple': { title: "Manzana (1 unidad mediana)", info: "✅ Rica en fibra (4g), mejora la digestión.\n✅ Aporta vitamina C (8% de la recomendación diaria).\n✅ Tiene antioxidantes que protegen las células.\n⚖️ Solo 95 kcal y 0 grasa." }, 'banana': { title: "Plátano (1 unidad mediana)", info: "✅ Rico en potasio (400–450 mg), ideal para los músculos.\n✅ Contiene vitamina B6, que ayuda al sistema nervioso.\n✅ Da energía rápida gracias a sus azúcares naturales." }, 'hardEgg': { title: "Huevo duro (1 unidad)", info: "✅ Aporta proteínas completas (6g por huevo).\n✅ Rico en colina, esencial para la memoria y el cerebro.\n✅ Contiene vitamina D y hierro.\n⚠️ Contiene algo de colesterol, pero no es dañino en jóvenes sanos." }, 'broccoli': { title: "Brócoli (1 taza cocida)", info: "✅ Altísimo en vitamina C y vitamina K.\n✅ Fuente de fibra y antioxidantes.\n✅ Tiene compuestos que ayudan a prevenir el cáncer." }, 'carrot': { title: "Zanahoria (1 mediana cruda)", info: "✅ Altísima en betacaroteno (vitamina A), buena para la vista.\n✅ Solo 25 kcal y con fibra.\n✅ Rica en antioxidantes, fortalece el sistema inmune." }, 'wholeBread': { title: "Pan integral (1 rebanada)", info: "✅ Buena fuente de fibra (2–3 g por porción).\n✅ Aporta carbohidratos complejos que dan energía duradera.\n✅ Tiene hierro y vitaminas del grupo B." }, 'waterBottle': { title: "Agua (1 vaso / 240ml)", info: "✅ Hidratación esencial para todo el cuerpo.\n✅ Regula la temperatura, transporta nutrientes y limpia toxinas.\n✅ 0 calorías, 0 azúcar, 100% necesaria." } }; return nutritionalData[mostCaughtFood] || { title: "¡Sigue practicando!", info: "Intenta atrapar más alimentos saludables la próxima vez." }; } // Show victory message when energy reaches 30 function showVictoryMessage() { var finalTime = storage.finalTime || Math.floor((LK.ticks - gameStartTime) / 60); // Award Nutripoints only for reaching maximum energy if (energy >= 30) { gameNutripoints = 2; // Award 2 Nutripoints for completing with max energy totalNutripoints += gameNutripoints; storage.totalNutripoints = totalNutripoints; } // Create full screen overlay var overlay = LK.getAsset('energyBarBg', { width: 2048, height: 2732, anchorX: 0, anchorY: 0 }); overlay.tint = 0x000000; overlay.alpha = 0.9; game.addChild(overlay); // Victory title var titleText = new Text2('¡FELICITACIONES!', { size: 120, fill: 0xFFD700, font: "Impact" }); titleText.anchor.set(0.5, 0.5); titleText.x = 2048 / 2; titleText.y = 400; game.addChild(titleText); // Victory message var messageText = new Text2('¡Alcanzaste el nivel máximo de energía saludable!', { size: 70, fill: 0x32CD32, font: "Impact" }); messageText.anchor.set(0.5, 0.5); messageText.x = 2048 / 2; messageText.y = 600; game.addChild(messageText); // Additional message lines var message2Text = new Text2('Tu cuerpo y tu mente están listas para todo.', { size: 60, fill: 0x00BFFF, font: "Impact" }); message2Text.anchor.set(0.5, 0.5); message2Text.x = 2048 / 2; message2Text.y = 750; game.addChild(message2Text); var message3Text = new Text2('Elegiste bien, vivís mejor.', { size: 60, fill: 0xFF69B4, font: "Impact" }); message3Text.anchor.set(0.5, 0.5); message3Text.x = 2048 / 2; message3Text.y = 900; game.addChild(message3Text); // Score section removed // Time played section var timeText = new Text2('Tiempo jugado: ' + finalTime + ' segundos', { size: 60, fill: 0xFFFFFF, font: "Impact" }); timeText.anchor.set(0.5, 0.5); timeText.x = 2048 / 2; timeText.y = 1100; game.addChild(timeText); // Nutripoints message var gameNutripointsText = new Text2('¡Ganaste 2 Nutripoints por llegar al máximo de energía!', { size: 65, fill: 0x32CD32, font: "Impact" }); gameNutripointsText.anchor.set(0.5, 0.5); gameNutripointsText.x = 2048 / 2; gameNutripointsText.y = 1200; game.addChild(gameNutripointsText); var totalNutripointsText = new Text2('Total acumulado: ' + totalNutripoints + ' Nutripoints', { size: 55, fill: 0xFFD700, font: "Impact" }); totalNutripointsText.anchor.set(0.5, 0.5); totalNutripointsText.x = 2048 / 2; totalNutripointsText.y = 1300; game.addChild(totalNutripointsText); // Create animated restart button var restartButton = LK.getAsset('restartButton', { width: 700, height: 140, color: 0x32CD32, shape: 'box', anchorX: 0.5, anchorY: 0.5 }); restartButton.x = 2048 / 2; restartButton.y = 1600; game.addChild(restartButton); var restartText = new Text2('Jugar de nuevo', { size: 80, fill: 0xFFFFFF, font: "Impact" }); restartText.anchor.set(0.5, 0.5); restartText.x = 2048 / 2; restartText.y = 1600; game.addChild(restartText); // Animate button with pulsing effect function animateVictoryRestartButton() { tween(restartButton, { scaleX: 1.1, scaleY: 1.1 }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { tween(restartButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 800, easing: tween.easeInOut, onFinish: animateVictoryRestartButton }); } }); tween(restartText, { scaleX: 1.1, scaleY: 1.1 }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { tween(restartText, { scaleX: 1.0, scaleY: 1.0 }, { duration: 800, easing: tween.easeInOut }); } }); } animateVictoryRestartButton(); // Add click handler for restart restartButton.down = function () { showStartScreen(); }; restartText.down = function () { showStartScreen(); }; } // Show game over message when lives reach 0 function showGameOver() { var finalTime = storage.finalTime || Math.floor((LK.ticks - gameStartTime) / 60); // No Nutripoints awarded when not reaching maximum energy // Create full screen overlay var overlay = LK.getAsset('energyBarBg', { width: 2048, height: 2732, anchorX: 0, anchorY: 0 }); overlay.tint = 0x000000; overlay.alpha = 0.9; game.addChild(overlay); // Game Over title var gameOverText = new Text2('GAME OVER', { size: 150, fill: 0xFF0000, font: "Impact" }); gameOverText.anchor.set(0.5, 0.5); gameOverText.x = 2048 / 2; gameOverText.y = 600; game.addChild(gameOverText); // Score section removed // Time played section var timeText = new Text2('Tiempo jugado: ' + finalTime + ' segundos', { size: 60, fill: 0xFFFFFF, font: "Impact" }); timeText.anchor.set(0.5, 0.5); timeText.x = 2048 / 2; timeText.y = 800; game.addChild(timeText); // Nutripoints encouragement message var nutripointsEncourageText = new Text2('¡Sigue eligiendo bien para ganar Nutripoints!', { size: 65, fill: 0xFFD700, font: "Impact" }); nutripointsEncourageText.anchor.set(0.5, 0.5); nutripointsEncourageText.x = 2048 / 2; nutripointsEncourageText.y = 900; game.addChild(nutripointsEncourageText); // Add nutritional information section var mostConsumedText = new Text2('Alimento que más consumiste en esta partida', { size: 70, fill: 0x32CD32, font: "Impact" }); mostConsumedText.anchor.set(0.5, 0.5); mostConsumedText.x = 2048 / 2; mostConsumedText.y = 1050; game.addChild(mostConsumedText); var nutritionalInfo = getNutritionalInfo(); var nutritionTitleText = new Text2(nutritionalInfo.title, { size: 80, fill: 0xFFD700, font: "Impact" }); nutritionTitleText.anchor.set(0.5, 0.5); nutritionTitleText.x = 2048 / 2; nutritionTitleText.y = 1200; game.addChild(nutritionTitleText); var nutritionInfoText = new Text2(nutritionalInfo.info, { size: 55, fill: 0xFFFFFF, font: "Impact" }); nutritionInfoText.anchor.set(0.5, 0); nutritionInfoText.x = 2048 / 2; nutritionInfoText.y = 1250; game.addChild(nutritionInfoText); // Create animated restart button var restartButton = LK.getAsset('restartButton', { width: 700, height: 140, color: 0x32CD32, shape: 'box', anchorX: 0.5, anchorY: 0.5 }); restartButton.x = 2048 / 2; restartButton.y = 1650; game.addChild(restartButton); var restartText = new Text2('Jugar de nuevo', { size: 80, fill: 0xFFFFFF, font: "Impact" }); restartText.anchor.set(0.5, 0.5); restartText.x = 2048 / 2; restartText.y = 1650; game.addChild(restartText); // Animate button with pulsing effect function animateGameOverRestartButton() { tween(restartButton, { scaleX: 1.1, scaleY: 1.1 }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { tween(restartButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 800, easing: tween.easeInOut, onFinish: animateGameOverRestartButton }); } }); tween(restartText, { scaleX: 1.1, scaleY: 1.1 }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { tween(restartText, { scaleX: 1.0, scaleY: 1.0 }, { duration: 800, easing: tween.easeInOut }); } }); } animateGameOverRestartButton(); // Add click handler for restart restartButton.down = function () { showStartScreen(); }; restartText.down = function () { showStartScreen(); }; } // Show custom game over message for energy depletion function showCustomGameOver() { var finalEnergy = storage.finalEnergy || energy; var finalTime = storage.finalTime || Math.floor((LK.ticks - gameStartTime) / 60); var reason = storage.gameEndReason || 'fatiga'; var message = ''; if (finalEnergy >= 25) { message = '¡NutriMáster!'; } else if (finalEnergy >= 15) { message = '¡Buen cazador de nutrientes!'; } else { message = 'Sigue practicando, revisa tus elecciones'; } // No Nutripoints awarded when not reaching maximum energy // Create full screen overlay var overlay = LK.getAsset('energyBarBg', { width: 2048, height: 2732, anchorX: 0, anchorY: 0 }); overlay.tint = 0x000000; overlay.alpha = 0.9; game.addChild(overlay); // Title var titleText = new Text2('FATIGA, FALTA DE ENERGÍA', { size: 100, fill: 0xFFD700, font: "Impact" }); titleText.anchor.set(0.5, 0.5); titleText.x = 2048 / 2; titleText.y = 400; game.addChild(titleText); // Score section removed // Time played section var timeText = new Text2('Tiempo jugado: ' + finalTime + ' segundos', { size: 70, fill: 0x00BFFF, font: "Impact" }); timeText.anchor.set(0.5, 0.5); timeText.x = 2048 / 2; timeText.y = 700; game.addChild(timeText); // Nutripoints encouragement message var nutripointsEncourageText = new Text2('¡Sigue eligiendo bien para ganar Nutripoints!', { size: 65, fill: 0xFFD700, font: "Impact" }); nutripointsEncourageText.anchor.set(0.5, 0.5); nutripointsEncourageText.x = 2048 / 2; nutripointsEncourageText.y = 800; game.addChild(nutripointsEncourageText); // Message section with color based on performance var messageColor = 0xFFFFFF; if (finalEnergy >= 25) { messageColor = 0xFFD700; // Gold for NutriMaster } else if (finalEnergy >= 15) { messageColor = 0x32CD32; // Green for good hunter } else { messageColor = 0xFF4500; // Orange for keep practicing } var messageText = new Text2(message, { size: 80, fill: messageColor, font: "Impact" }); messageText.anchor.set(0.5, 0.5); messageText.x = 2048 / 2; messageText.y = 900; game.addChild(messageText); // Add nutritional information section var mostConsumedText = new Text2('Alimento que más consumiste en esta partida', { size: 70, fill: 0x32CD32, font: "Impact" }); mostConsumedText.anchor.set(0.5, 0.5); mostConsumedText.x = 2048 / 2; mostConsumedText.y = 1000; game.addChild(mostConsumedText); var nutritionalInfo = getNutritionalInfo(); var nutritionTitleText = new Text2(nutritionalInfo.title, { size: 80, fill: 0xFFD700, font: "Impact" }); nutritionTitleText.anchor.set(0.5, 0.5); nutritionTitleText.x = 2048 / 2; nutritionTitleText.y = 1150; game.addChild(nutritionTitleText); var nutritionInfoText = new Text2(nutritionalInfo.info, { size: 55, fill: 0xFFFFFF, font: "Impact" }); nutritionInfoText.anchor.set(0.5, 0); nutritionInfoText.x = 2048 / 2; nutritionInfoText.y = 1200; game.addChild(nutritionInfoText); // Create animated restart button var restartButton = LK.getAsset('restartButton', { width: 700, height: 140, color: 0x32CD32, shape: 'box', anchorX: 0.5, anchorY: 0.5 }); restartButton.x = 2048 / 2; restartButton.y = 1600; game.addChild(restartButton); var restartText = new Text2('Jugar de nuevo', { size: 80, fill: 0xFFFFFF, font: "Impact" }); restartText.anchor.set(0.5, 0.5); restartText.x = 2048 / 2; restartText.y = 1600; game.addChild(restartText); // Animate button with pulsing effect function animateRestartButton() { tween(restartButton, { scaleX: 1.1, scaleY: 1.1 }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { tween(restartButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 800, easing: tween.easeInOut, onFinish: animateRestartButton }); } }); tween(restartText, { scaleX: 1.1, scaleY: 1.1 }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { tween(restartText, { scaleX: 1.0, scaleY: 1.0 }, { duration: 800, easing: tween.easeInOut }); } }); } animateRestartButton(); // Add click handler for restart restartButton.down = function () { showStartScreen(); }; restartText.down = function () { showStartScreen(); }; } // Start countdown and restart game function startCountdown() { // Clear all game objects for (var i = fallingItems.length - 1; i >= 0; i--) { fallingItems[i].destroy(); } fallingItems = []; game.removeChildren(); // Reset all game variables energy = 15; lives = 3; fallSpeed = 350 / 60; lastSpeedIncrease = 0; lastWaterSpawn = 0; gameStartTime = 0; foodsCaught = 0; anxietyBombsActive = false; lastSpawnTime = 0; lastAnxietySpawnTime = 0; expertMessageShown = false; gameActive = true; // Reactivate game gameStarted = true; // Ensure game logic runs during countdown and game expertModeTimer = 0; // Reset expert mode timer gameNutripoints = 0; // Reset current game Nutripoints // Score reset removed // Clear GUI elements to reset them properly LK.gui.topLeft.removeChildren(); LK.gui.topRight.removeChildren(); LK.gui.top.removeChildren(); // Reset UI variable references totalNutripointsText = null; // Reset food counts foodCounts = { 'apple': 0, 'banana': 0, 'hardEgg': 0, 'broccoli': 0, 'carrot': 0, 'wholeBread': 0, 'waterBottle': 0 }; // Show countdown var countdownNumbers = [3, 2, 1]; var currentCount = 0; function showCountdownNumber() { if (currentCount < countdownNumbers.length) { var countText = new Text2(countdownNumbers[currentCount].toString(), { size: 250, fill: 0xFFFF00, font: "Impact" }); countText.anchor.set(0.5, 0.5); countText.x = 2048 / 2; countText.y = 2732 / 2; game.addChild(countText); // Animate countdown number tween(countText, { scaleX: 1.5, scaleY: 1.5, alpha: 0 }, { duration: 1000, onFinish: function onFinish() { countText.destroy(); currentCount++; if (currentCount < countdownNumbers.length) { showCountdownNumber(); } else { // Start new game initializeGame(); // Force UI update after initialization to show correct values updateUI(); } } }); } } showCountdownNumber(); } // Screen management functions function showStartScreen() { currentScreen = 'start'; gameStarted = false; // Reset game started state game.removeChildren(); LK.gui.topLeft.removeChildren(); LK.gui.topRight.removeChildren(); if (!startScreen) { startScreen = new StartScreen(); } game.addChild(startScreen); } function handleStartScreenButton(buttonType) { switch (buttonType) { case 'PLAY': // Find the PLAY button and animate it for (var i = 0; i < startScreen.buttons.length; i++) { if (startScreen.buttons[i].type === 'PLAY') { var playButton = startScreen.buttons[i]; // Set gameStarted immediately to enable game logic gameStarted = true; // Animate button press tween(playButton.bg, { scaleX: 0.95, scaleY: 0.95, tint: 0x228B22 }, { duration: 150, onFinish: function onFinish() { tween(playButton.bg, { scaleX: 1.0, scaleY: 1.0, tint: 0x32CD32 }, { duration: 150, onFinish: function onFinish() { // Start game immediately after animation startGame(); } }); } }); tween(playButton.text, { scaleX: 0.95, scaleY: 0.95 }, { duration: 150, onFinish: function onFinish() { tween(playButton.text, { scaleX: 1.0, scaleY: 1.0 }, { duration: 150 }); } }); break; } } break; case 'MISIONES': showMissionsScreen(); break; case 'TIENDA': showStoreScreen(); break; case 'PREGUNTAS': showFAQScreen(); break; } } function startGame() { currentScreen = 'game'; game.removeChildren(); startCountdown(); } function showMissionsScreen() { currentScreen = 'missions'; game.removeChildren(); LK.gui.topLeft.removeChildren(); LK.gui.topRight.removeChildren(); if (!missionsScreen) { missionsScreen = new MissionsScreen(); } game.addChild(missionsScreen); updateMissionsDisplay(); } function showStoreScreen() { currentScreen = 'store'; game.removeChildren(); LK.gui.topLeft.removeChildren(); LK.gui.topRight.removeChildren(); if (!storeScreen) { storeScreen = new StoreScreen(); } game.addChild(storeScreen); updateStoreDisplay(); } function showFAQScreen() { currentScreen = 'faq'; game.removeChildren(); LK.gui.topLeft.removeChildren(); LK.gui.topRight.removeChildren(); if (!faqScreen) { faqScreen = new FAQScreen(); } game.addChild(faqScreen); updateFAQDisplay(); } // Mission system functions function getDailyMissions() { var today = new Date().toDateString(); var savedMissions = storage.dailyMissions; var savedDate = storage.missionsDate; if (!savedMissions || savedDate !== today) { // Generate new daily missions var shuffled = allMissions.slice(); for (var i = shuffled.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var temp = shuffled[i]; shuffled[i] = shuffled[j]; shuffled[j] = temp; } var dailyMissions = shuffled.slice(0, 3); storage.dailyMissions = dailyMissions; storage.missionsDate = today; storage.missionsCompleted = [false, false, false]; return dailyMissions; } return savedMissions; } function updateMissionsDisplay() { if (!missionsScreen) return; missionsScreen.missionsContainer.removeChildren(); var dailyMissions = getDailyMissions(); var completed = storage.missionsCompleted || [false, false, false]; for (var i = 0; i < dailyMissions.length; i++) { var missionBg = LK.getAsset('restartButton', { width: 1600, height: 200, anchorX: 0.5, anchorY: 0.5 }); missionBg.tint = completed[i] ? 0x27AE60 : 0x34495E; missionBg.x = 2048 / 2; missionBg.y = 500 + i * 250; missionsScreen.missionsContainer.addChild(missionBg); var missionText = new Text2((completed[i] ? '✔️ ' : '') + dailyMissions[i], { size: 50, fill: 0xFFFFFF, font: "Impact" }); missionText.anchor.set(0.5, 0.5); missionText.x = 2048 / 2; missionText.y = 500 + i * 250; missionsScreen.missionsContainer.addChild(missionText); if (completed[i]) { var rewardText = new Text2('+2 Nutripoints', { size: 40, fill: 0xFFD700, font: "Impact" }); rewardText.anchor.set(0.5, 0.5); rewardText.x = 2048 / 2; rewardText.y = 530 + i * 250; missionsScreen.missionsContainer.addChild(rewardText); } } } // Store system functions function updateStoreDisplay() { if (!storeScreen) return; storeScreen.storeContainer.removeChildren(); var playerNutripoints = storage.totalNutripoints || 0; var ownedItems = storage.ownedItems || []; for (var i = 0; i < storeItems.length; i++) { var item = storeItems[i]; var owned = ownedItems.indexOf(item.id) !== -1; var canAfford = playerNutripoints >= item.costo; var itemBg = LK.getAsset('restartButton', { width: 700, height: 150, anchorX: 0.5, anchorY: 0.5 }); itemBg.tint = owned ? 0x27AE60 : canAfford ? 0x3498DB : 0x95A5A6; itemBg.x = i % 2 * 800 + 500; itemBg.y = 500 + Math.floor(i / 2) * 200; storeScreen.storeContainer.addChild(itemBg); var nameText = new Text2(item.nombre, { size: 45, fill: 0xFFFFFF, font: "Impact" }); nameText.anchor.set(0.5, 0.5); nameText.x = itemBg.x; nameText.y = itemBg.y - 20; storeScreen.storeContainer.addChild(nameText); var costText = new Text2(owned ? 'COMPRADO' : item.costo + ' Nutripoints', { size: 35, fill: owned ? 0x2ECC71 : canAfford ? 0xFFD700 : 0xE74C3C, font: "Impact" }); costText.anchor.set(0.5, 0.5); costText.x = itemBg.x; costText.y = itemBg.y + 20; storeScreen.storeContainer.addChild(costText); if (!owned && canAfford) { itemBg.itemData = item; (function (itemData) { itemBg.down = function (x, y, obj) { purchaseItem(itemData); }; })(item); } } } function purchaseItem(item) { if (!item || typeof item.costo === 'undefined') { console.error('Invalid item data in purchaseItem'); return; } var playerNutripoints = storage.totalNutripoints || 0; var ownedItems = storage.ownedItems || []; if (playerNutripoints >= item.costo && ownedItems.indexOf(item.id) === -1) { storage.totalNutripoints = playerNutripoints - item.costo; ownedItems.push(item.id); storage.ownedItems = ownedItems; // Show purchase popup var popup = LK.getAsset('restartButton', { width: 800, height: 200, anchorX: 0.5, anchorY: 0.5 }); popup.tint = 0x27AE60; popup.x = 2048 / 2; popup.y = 2732 / 2; game.addChild(popup); var popupText = new Text2('¡Nuevo artículo desbloqueado!', { size: 60, fill: 0xFFFFFF, font: "Impact" }); popupText.anchor.set(0.5, 0.5); popupText.x = 2048 / 2; popupText.y = 2732 / 2; game.addChild(popupText); LK.getSound('powerup').play(); // Remove popup after 2 seconds LK.setTimeout(function () { popup.destroy(); popupText.destroy(); updateStoreDisplay(); }, 2000); } } // FAQ system functions function updateFAQDisplay() { if (!faqScreen) return; faqScreen.faqContainer.removeChildren(); for (var i = 0; i < faqData.length; i++) { var faq = faqData[i]; var questionBg = LK.getAsset('restartButton', { width: 1800, height: 100, anchorX: 0.5, anchorY: 0.5 }); questionBg.tint = 0x3498DB; questionBg.x = 2048 / 2; questionBg.y = 350 + i * 300; faqScreen.faqContainer.addChild(questionBg); var questionText = new Text2(faq.question, { size: 45, fill: 0xFFFFFF, font: "Impact" }); questionText.anchor.set(0.5, 0.5); questionText.x = 2048 / 2; questionText.y = 350 + i * 300; faqScreen.faqContainer.addChild(questionText); var answerBg = LK.getAsset('restartButton', { width: 1800, height: 150, anchorX: 0.5, anchorY: 0.5 }); answerBg.tint = 0xECF0F1; answerBg.x = 2048 / 2; answerBg.y = 425 + i * 300; faqScreen.faqContainer.addChild(answerBg); var answerText = new Text2(faq.answer, { size: 35, fill: 0x2C3E50, font: "Impact" }); answerText.anchor.set(0.5, 0.5); answerText.x = 2048 / 2; answerText.y = 425 + i * 300; faqScreen.faqContainer.addChild(answerText); } } // Initialize storage for persistent data totalNutripoints = storage.totalNutripoints || 0; // Initialize the start screen as the first state showStartScreen(); ;
===================================================================
--- original.js
+++ change.js
@@ -1684,15 +1684,21 @@
costText.y = itemBg.y + 20;
storeScreen.storeContainer.addChild(costText);
if (!owned && canAfford) {
itemBg.itemData = item;
- itemBg.down = function (x, y, obj) {
- purchaseItem(obj.itemData);
- };
+ (function (itemData) {
+ itemBg.down = function (x, y, obj) {
+ purchaseItem(itemData);
+ };
+ })(item);
}
}
}
function purchaseItem(item) {
+ if (!item || typeof item.costo === 'undefined') {
+ console.error('Invalid item data in purchaseItem');
+ return;
+ }
var playerNutripoints = storage.totalNutripoints || 0;
var ownedItems = storage.ownedItems || [];
if (playerNutripoints >= item.costo && ownedItems.indexOf(item.id) === -1) {
storage.totalNutripoints = playerNutripoints - item.costo;