/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Pill = Container.expand(function () { var self = Container.call(this); var pillGraphics = self.attachAsset('pill', { anchorX: 0.5, anchorY: 0.5 }); self.collected = false; self.collect = function () { if (self.collected) return; self.collected = true; self.visible = false; LK.getSound('collect').play(); }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.targetX = 0; self.targetY = 0; self.isMoving = false; self.moveToTarget = function (targetX, targetY) { if (self.isMoving) return; self.targetX = targetX; self.targetY = targetY; self.isMoving = true; tween(self, { x: targetX, y: targetY }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { self.isMoving = false; } }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Language system var currentLanguage = storage.language || 'spanish'; var texts = { spanish: { play: 'JUGAR', playDay2: 'JUGAR DÍA 2', language: 'LENGUAJE', spanish: 'ESPAÑOL', english: 'INGLES', pills: 'PASTILLAS', "continue": 'Haz CLICK en cualquier lugar para continuar', yes: 'SI', givePills: 'DAR PASTILLAS' }, english: { play: 'PLAY', playDay2: 'PLAY DAY 2', language: 'LANGUAGE', spanish: 'SPANISH', english: 'ENGLISH', pills: 'PILLS', "continue": 'Click anywhere to continue', yes: 'YES', givePills: 'GIVE PILLS' } }; // Game state management var gameState = "menu"; // "menu", "dialogue", "game", "ending", "language" var currentDialogue = 0; var dialogueTexts = { spanish: ["Ahhh… qué sorpresa… un pequeño perdido en este lugar sin alma.\nMmm… qué olor más extraño tienes… ya sé de dónde vienes.", "¿Quieres salir, verdad? ¿Quieres encontrar la puerta que te lleve lejos de aquí? Je, je, je… Yo sé dónde está.\nSí… yo siempre lo sé.", "Pero nada es gratis, pequeño. Yo también necesito algo… unas píldoras. Mis dulces, mis tesoros…\nLas perdí, y sin ellas me siento… vacía. ¿Me ayudarás?", "Eso está mejor… sabía que no me dirías que no, pequeño.\nMis píldoras… están dentro de la mansión que se levanta allá… la de cinco pisos que araña el cielo.", "No tengas miedo… no necesitas recorrerla toda.\nMis píldoras están en el primer piso, todas escondidas como pequeños ratones traviesos.", "Son diez en total. Diez. Ni una menos… ni una más.\nCuando las tengas todas… busca la puerta roja. Solo por ahí podrás salir… si es que todavía quieres hacerlo.", "Ve, pequeño… la mansión te espera. Y yo… yo estaré observando."], english: ["Ahhh... what a surprise... a little one lost in this soulless place.\nMmm... what a strange smell you have... I know where you come from.", "You want to leave, right? You want to find the door that takes you away from here? Heh, heh, heh... I know where it is.\nYes... I always know.", "But nothing is free, little one. I also need something... some pills. My sweets, my treasures...\nI lost them, and without them I feel... empty. Will you help me?", "That's better... I knew you wouldn't say no to me, little one.\nMy pills... are inside the mansion that rises there... the five-story one that scrapes the sky.", "Don't be afraid... you don't need to go through it all.\nMy pills are on the first floor, all hidden like little mischievous mice.", "There are ten in total. Ten. Not one less... not one more.\nWhen you have them all... look for the red door. Only through there can you leave... if you still want to.", "Go, little one... the mansion awaits you. And I... I will be watching."] }; var endingDialogueTexts = { spanish: ["Ahhh… has vuelto, pequeño. Y veo que... sí... sí... puedo sentirlas.\n Mis dulces tesoros están contigo, ¿verdad?", "Dámelas... por favor... necesito sentir su dulzura en mis manos otra vez.", "Sí... sí... aquí están todas. Una... dos... tres... ¡Diez! Mis preciosas... cómo las extrañé...", "Gracias, pequeño... gracias por devolverme lo que más amo.\n Me siento... completa otra vez. El vacío se llena, la oscuridad se calma...", "Pero... pero hay algo que debo decirte. Algo que me duele confesar...", "Yo... yo te mentí, pequeño. La puerta roja... no te llevará a casa.\n No puedo decirte cómo salir de aquí porque... porque Ella nos observa.", "La Vigía del Umbral... siempre está mirando, siempre está escuchando. Si te dijera la verdad sobre la salida... \nsi te mostrara el camino real... Ella lo sabría. Y entonces... entonces nos castigaría a ambos.", "Perdóname, pequeño... perdóname por engañarte. Pero necesitaba mis píldoras... \ny tú... tú necesitabas una razón para seguir adelante, para no rendirte en este lugar maldito.", "La puerta roja... solo es el comienzo de otro laberinto. Pero tal vez...\n tal vez si eres lo suficientemente astuto... encontrarás tu propio camino.", "Ve ahora... antes de que Ella se dé cuenta de que hemos hablado demasiado.\n Y recuerda... en este lugar, la verdad es un lujo que pocos pueden permitirse.", "Adiós, pequeño valiente... que la suerte te acompañe en la oscuridad que te espera."], english: ["Ahhh... you've returned, little one. And I see that... yes... yes... I can feel them.\n My sweet treasures are with you, aren't they?", "Give them to me... please... I need to feel their sweetness in my hands again.", "Yes... yes... here they all are. One... two... three... Ten! My precious ones... how I missed them...", "Thank you, little one... thank you for returning what I love most.\n I feel... complete again. The void is filled, the darkness calms...", "But... but there's something I must tell you. Something that hurts me to confess...", "I... I lied to you, little one. The red door... won't take you home.\n I can't tell you how to get out of here because... because She watches us.", "The Watcher of the Threshold... always looking, always listening. If I told you the truth about the exit... \nif I showed you the real way... She would know. And then... then she would punish us both.", "Forgive me, little one... forgive me for deceiving you. But I needed my pills... \nand you... you needed a reason to keep going, to not give up in this cursed place.", "The red door... is only the beginning of another labyrinth. But maybe...\n maybe if you're clever enough... you'll find your own way.", "Go now... before She realizes we've talked too much.\n And remember... in this place, truth is a luxury few can afford.", "Goodbye, brave little one... may luck accompany you in the darkness that awaits."] }; var currentEndingDialogue = 0; var showYesButton = false; var showGivePillsButton = false; var pillAssetShown = false; var day2Unlocked = false; var abriendoSoundPlayed = false; var CELL_SIZE = 64; // Menu UI Elements var titleText = LK.getAsset('TITULO', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 600, scaleX: 8, scaleY: 8 }); game.addChild(titleText); var playButton = new Text2(texts[currentLanguage].play, { size: 80, fill: 0x4a90e2 }); playButton.anchor.set(0.5, 0.5); playButton.x = 1024; playButton.y = 1000; game.addChild(playButton); var languageButton = new Text2(texts[currentLanguage].language, { size: 60, fill: 0x4a90e2 }); languageButton.anchor.set(0.5, 0.5); languageButton.x = 1024; languageButton.y = 1150; game.addChild(languageButton); // Language selection buttons (initially hidden) var spanishButton = new Text2(texts[currentLanguage].spanish, { size: 60, fill: 0x4a90e2 }); spanishButton.anchor.set(0.5, 0.5); spanishButton.x = 1024; spanishButton.y = 1250; spanishButton.visible = false; game.addChild(spanishButton); var englishButton = new Text2(texts[currentLanguage].english, { size: 60, fill: 0x4a90e2 }); englishButton.anchor.set(0.5, 0.5); englishButton.x = 1024; englishButton.y = 1350; englishButton.visible = false; game.addChild(englishButton); // Character sprite (initially hidden) var pinkcraiyon = LK.getAsset('Pinkcraiyon', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 800, scaleX: 2, scaleY: 2 }); pinkcraiyon.alpha = 0; game.addChild(pinkcraiyon); // Dialogue UI var dialogueBox = new Text2('', { size: 35, fill: 0xffffff }); dialogueBox.anchor.set(0.5, 0.5); dialogueBox.x = 1024; dialogueBox.y = 1800; dialogueBox.visible = false; game.addChild(dialogueBox); var continueText = new Text2(texts[currentLanguage]["continue"], { size: 28, fill: 0xcccccc }); continueText.anchor.set(0.5, 0.5); continueText.x = 1024; continueText.y = 2200; continueText.visible = false; game.addChild(continueText); var yesButton = new Text2(texts[currentLanguage].yes, { size: 60, fill: 0x4a90e2 }); yesButton.anchor.set(0.5, 0.5); yesButton.x = 1024; yesButton.y = 2000; yesButton.visible = false; game.addChild(yesButton); var givePillsButton = new Text2(texts[currentLanguage].givePills, { size: 60, fill: 0x4a90e2 }); givePillsButton.anchor.set(0.5, 0.5); givePillsButton.x = 1024; givePillsButton.y = 2000; givePillsButton.visible = false; game.addChild(givePillsButton); // Pill asset for ending sequence var pillAsset = LK.getAsset('pill', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 800, scaleX: 15, scaleY: 15 }); pillAsset.alpha = 0; game.addChild(pillAsset); // Red door asset for final sequence var puertaRoja = LK.getAsset('puertaroja', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366, scaleX: 0.5, scaleY: 0.5 }); puertaRoja.alpha = 0; game.addChild(puertaRoja); // Game variables (will be initialized when starting game) var MAZE_WIDTH, MAZE_HEIGHT, maze, mazeContainer, player, pills, pillsCollected, totalPills, counterText, door; // Function to update all UI texts with current language function updateLanguageTexts() { playButton.setText(day2Unlocked ? texts[currentLanguage].playDay2 : texts[currentLanguage].play); languageButton.setText(texts[currentLanguage].language); spanishButton.setText(texts[currentLanguage].spanish); englishButton.setText(texts[currentLanguage].english); continueText.setText(texts[currentLanguage]["continue"]); yesButton.setText(texts[currentLanguage].yes); givePillsButton.setText(texts[currentLanguage].givePills); if (counterText) { counterText.setText(texts[currentLanguage].pills + ' ' + pillsCollected + '/' + totalPills); } } // Function to check if a position is walkable function isWalkable(x, y) { var gridX = Math.floor(x / CELL_SIZE); var gridY = Math.floor(y / CELL_SIZE); if (gridX < 0 || gridX >= MAZE_WIDTH || gridY < 0 || gridY >= MAZE_HEIGHT) { return false; } return maze[gridY][gridX] === 0; } // Function to check if path between two points is clear function hasPathTo(fromX, fromY, toX, toY) { var fromGridX = Math.floor(fromX / CELL_SIZE); var fromGridY = Math.floor(fromY / CELL_SIZE); var toGridX = Math.floor(toX / CELL_SIZE); var toGridY = Math.floor(toY / CELL_SIZE); // Simple line-of-sight check var dx = Math.abs(toGridX - fromGridX); var dy = Math.abs(toGridY - fromGridY); var stepX = fromGridX < toGridX ? 1 : -1; var stepY = fromGridY < toGridY ? 1 : -1; var err = dx - dy; var currentX = fromGridX; var currentY = fromGridY; while (true) { if (currentX < 0 || currentX >= MAZE_WIDTH || currentY < 0 || currentY >= MAZE_HEIGHT) { return false; } if (maze[currentY][currentX] === 1) { return false; } if (currentX === toGridX && currentY === toGridY) { return true; } var e2 = 2 * err; if (e2 > -dy) { err -= dy; currentX += stepX; } if (e2 < dx) { err += dx; currentY += stepY; } } } // Function to get random walkable position function getRandomWalkablePosition() { var attempts = 0; while (attempts < 100) { var x = Math.floor(Math.random() * MAZE_WIDTH); var y = Math.floor(Math.random() * MAZE_HEIGHT); if (maze[y][x] === 0) { return { x: x * CELL_SIZE + CELL_SIZE / 2, y: y * CELL_SIZE + CELL_SIZE / 2 }; } attempts++; } // Fallback to player starting position return { x: CELL_SIZE / 2, y: CELL_SIZE / 2 }; } // Spawn initial pills for (var i = 0; i < totalPills; i++) { var pillPos = getRandomWalkablePosition(); // Make sure pill is not too close to player start while (Math.abs(pillPos.x - CELL_SIZE / 2) < 128 && Math.abs(pillPos.y - CELL_SIZE / 2) < 128) { pillPos = getRandomWalkablePosition(); } var pill = game.addChild(new Pill()); pill.x = pillPos.x; pill.y = pillPos.y + 150; // Adjust for maze container offset pills.push(pill); } // Game click handler game.down = function (x, y, obj) { if (gameState === "menu") { // Check if play button was clicked if (x >= playButton.x - 100 && x <= playButton.x + 100 && y >= playButton.y - 50 && y <= playButton.y + 50) { startDialogue(); } // Check if language button was clicked else if (x >= languageButton.x - 120 && x <= languageButton.x + 120 && y >= languageButton.y - 50 && y <= languageButton.y + 50) { gameState = "language"; spanishButton.visible = true; englishButton.visible = true; } } else if (gameState === "language") { // Check if Spanish button was clicked if (x >= spanishButton.x - 100 && x <= spanishButton.x + 100 && y >= spanishButton.y - 50 && y <= spanishButton.y + 50) { currentLanguage = 'spanish'; storage.language = currentLanguage; gameState = "menu"; spanishButton.visible = false; englishButton.visible = false; updateLanguageTexts(); } // Check if English button was clicked else if (x >= englishButton.x - 100 && x <= englishButton.x + 100 && y >= englishButton.y - 50 && y <= englishButton.y + 50) { currentLanguage = 'english'; storage.language = currentLanguage; gameState = "menu"; spanishButton.visible = false; englishButton.visible = false; updateLanguageTexts(); } } else if (gameState === "dialogue") { if (showYesButton && yesButton.visible) { // Check if yes button was clicked if (x >= yesButton.x - 50 && x <= yesButton.x + 50 && y >= yesButton.y - 30 && y <= yesButton.y + 30) { showYesButton = false; yesButton.visible = false; continueText.visible = true; currentDialogue++; if (currentDialogue < dialogueTexts[currentLanguage].length) { dialogueBox.setText(dialogueTexts[currentLanguage][currentDialogue]); } } } else { // Continue dialogue currentDialogue++; if (currentDialogue === 3) { // Show YES button after third dialogue showYesButton = true; yesButton.visible = true; continueText.visible = false; } else if (currentDialogue >= dialogueTexts[currentLanguage].length) { // Start the game startGame(); } else { dialogueBox.setText(dialogueTexts[currentLanguage][currentDialogue]); } } } else if (gameState === "ending") { if (showGivePillsButton && givePillsButton.visible) { // Check if give pills button was clicked if (x >= givePillsButton.x - 120 && x <= givePillsButton.x + 120 && y >= givePillsButton.y - 30 && y <= givePillsButton.y + 30) { showGivePillsButton = false; givePillsButton.visible = false; continueText.visible = true; currentEndingDialogue++; dialogueBox.setText(endingDialogueTexts[currentLanguage][currentEndingDialogue]); } } else { // Continue ending dialogue currentEndingDialogue++; if (currentEndingDialogue === 2) { // Show give pills button after second dialogue showGivePillsButton = true; givePillsButton.visible = true; continueText.visible = false; } else if (currentEndingDialogue === 3) { dialogueBox.setText(endingDialogueTexts[currentLanguage][currentEndingDialogue]); } else if (currentEndingDialogue >= endingDialogueTexts[currentLanguage].length) { // End sequence with door animation startEndingSequence(); } else { dialogueBox.setText(endingDialogueTexts[currentLanguage][currentEndingDialogue]); } } } else if (gameState === "game") { if (player.isMoving) return; // Adjust for maze container offset var adjustedY = y - 150; var adjustedPlayerY = player.y - 150; // Check if target position is walkable and path is clear if (isWalkable(x, adjustedY) && hasPathTo(player.x, adjustedPlayerY, x, adjustedY)) { // Snap to grid center var gridX = Math.floor(x / CELL_SIZE); var gridY = Math.floor(adjustedY / CELL_SIZE); var targetX = gridX * CELL_SIZE + CELL_SIZE / 2; var targetY = gridY * CELL_SIZE + CELL_SIZE / 2 + 150; // Add offset back player.moveToTarget(targetX, targetY); } } }; function startDialogue() { gameState = "dialogue"; titleText.visible = false; playButton.visible = false; languageButton.visible = false; // Fade in Pinkcraiyon tween(pinkcraiyon, { alpha: 1 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { // Show first dialogue dialogueBox.visible = true; continueText.visible = true; dialogueBox.setText(dialogueTexts[currentLanguage][currentDialogue]); } }); } function startGame() { gameState = "game"; // Hide dialogue elements pinkcraiyon.visible = false; dialogueBox.visible = false; continueText.visible = false; initializeGame(); } function startEndingDialogue() { gameState = "ending"; currentEndingDialogue = 0; // Hide game elements if (mazeContainer) mazeContainer.visible = false; if (player) player.visible = false; if (counterText) counterText.visible = false; // Hide all pills for (var i = 0; i < pills.length; i++) { pills[i].visible = false; } // Show dialogue elements game.setBackgroundColor(0x000000); dialogueBox.visible = true; continueText.visible = true; // Fade in Pinkcraiyon tween(pinkcraiyon, { alpha: 1 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { pinkcraiyon.visible = true; dialogueBox.setText(endingDialogueTexts[currentLanguage][currentEndingDialogue]); } }); } function startEndingSequence() { // Hide dialogue elements first dialogueBox.visible = false; continueText.visible = false; // Fade out Pinkcraiyon tween(pinkcraiyon, { alpha: 0 }, { duration: 1000, onFinish: function onFinish() { // After Pinkcraiyon fades out, show and animate puerta roja puertaRoja.visible = true; puertaRoja.scaleX = 0.5; puertaRoja.scaleY = 0.5; tween(puertaRoja, { alpha: 1, scaleX: 8, scaleY: 8 }, { duration: 12000, easing: tween.easeOut, onFinish: function onFinish() { // Play opening sound only once if (!abriendoSoundPlayed) { LK.getSound('abriendo').play(); abriendoSoundPlayed = true; } // Wait for sound to finish, then fade out door and show black background LK.setTimeout(function () { tween(puertaRoja, { alpha: 0 }, { duration: 1000, onFinish: function onFinish() { // After door fades out and black background is shown, return to menu returnToMenu(); } }); }, 3000); // Wait 3 seconds for sound to finish } }); } }); } function returnToMenu() { gameState = "menu"; day2Unlocked = true; // Reset all variables currentDialogue = 0; currentEndingDialogue = 0; showYesButton = false; showGivePillsButton = false; pillAssetShown = false; abriendoSoundPlayed = false; // Show menu elements titleText.visible = true; playButton.visible = true; languageButton.visible = true; spanishButton.visible = false; englishButton.visible = false; updateLanguageTexts(); // Hide all other elements pinkcraiyon.visible = false; pinkcraiyon.alpha = 0; pillAsset.visible = false; pillAsset.alpha = 0; puertaRoja.visible = false; puertaRoja.alpha = 0; if (mazeContainer) mazeContainer.visible = false; if (player) player.visible = false; if (counterText) counterText.visible = false; } function initializeGame() { MAZE_WIDTH = Math.floor(1800 / CELL_SIZE); // Make maze smaller MAZE_HEIGHT = Math.floor(2582 / CELL_SIZE); // Reach bottom of screen (2732 - 150 offset) // Simple maze generation that ensures connectivity with longer walls maze = []; for (var y = 0; y < MAZE_HEIGHT; y++) { maze[y] = []; for (var x = 0; x < MAZE_WIDTH; x++) { // Create outer walls if (x === 0 || y === 0 || x === MAZE_WIDTH - 1 || y === MAZE_HEIGHT - 1) { maze[y][x] = 1; // wall } // Create longer L-shaped wall patterns (extended from 2-3 to 2-5 for longer walls) else if (x % 8 >= 2 && x % 8 <= 5 && y % 8 >= 2 && y % 8 <= 5 && Math.random() < 0.6) { maze[y][x] = 1; // Extended L-shaped walls } // Create longer horizontal wall segments else if (y % 6 === 2 && x % 8 >= 1 && x % 8 <= 6 && Math.random() < 0.5) { maze[y][x] = 1; // longer horizontal walls } // Create longer vertical wall segments else if (x % 6 === 2 && y % 8 >= 1 && y % 8 <= 6 && Math.random() < 0.5) { maze[y][x] = 1; // longer vertical walls } // Add some random walls but keep paths open else if (x % 4 === 0 && y % 4 === 0 && Math.random() < 0.3) { maze[y][x] = 1; // sparse additional walls } else { maze[y][x] = 0; // floor } } } // Ensure starting position and surrounding area is clear (larger area) for (var sy = 1; sy <= 4; sy++) { for (var sx = 1; sx <= 4; sx++) { maze[sy][sx] = 0; } } // Ensure exit area is clear (larger area) for (var ey = MAZE_HEIGHT - 5; ey < MAZE_HEIGHT - 1; ey++) { for (var ex = MAZE_WIDTH - 5; ex < MAZE_WIDTH - 1; ex++) { maze[ey][ex] = 0; } } // Create guaranteed horizontal paths every 6 rows for (var py = 3; py < MAZE_HEIGHT - 1; py += 6) { for (var px = 1; px < MAZE_WIDTH - 1; px++) { maze[py][px] = 0; } } // Create guaranteed vertical paths every 6 columns for (var px = 3; px < MAZE_WIDTH - 1; px += 6) { for (var py = 1; py < MAZE_HEIGHT - 1; py++) { maze[py][px] = 0; } } // Create maze visuals mazeContainer = game.addChild(new Container()); mazeContainer.y = 150; // Move maze down to avoid pause button for (var y = 0; y < MAZE_HEIGHT; y++) { for (var x = 0; x < MAZE_WIDTH; x++) { var cellX = x * CELL_SIZE; var cellY = y * CELL_SIZE; if (maze[y][x] === 1) { // Wall var wall = LK.getAsset('wall', { x: cellX, y: cellY }); mazeContainer.addChild(wall); } else { // Floor var floor = LK.getAsset('floor', { x: cellX, y: cellY }); mazeContainer.addChild(floor); } } } // Create door inside maze at bottom-right walkable area door = LK.getAsset('door', { x: (MAZE_WIDTH - 3) * CELL_SIZE, y: (MAZE_HEIGHT - 3) * CELL_SIZE, anchorX: 0, anchorY: 0 }); mazeContainer.addChild(door); // Create player at guaranteed walkable position player = game.addChild(new Player()); // Find first walkable position starting from top-left var playerStartX = CELL_SIZE + CELL_SIZE / 2; // Grid position 1,1 center var playerStartY = CELL_SIZE + CELL_SIZE / 2; // Grid position 1,1 center player.x = playerStartX; player.y = playerStartY + 150; // Adjust for maze container offset // Pills array and counter pills = []; pillsCollected = 0; totalPills = 10; // UI Counter counterText = new Text2(texts[currentLanguage].pills + ' 0/10', { size: 80, fill: 0xFFFFFF }); counterText.anchor.set(0.5, 0); LK.gui.top.addChild(counterText); // Spawn initial pills for (var i = 0; i < totalPills; i++) { var pillPos = getRandomWalkablePosition(); // Make sure pill is not too close to player start while (Math.abs(pillPos.x - CELL_SIZE / 2) < 128 && Math.abs(pillPos.y - CELL_SIZE / 2) < 128) { pillPos = getRandomWalkablePosition(); } var pill = game.addChild(new Pill()); pill.x = pillPos.x; pill.y = pillPos.y + 150; // Adjust for maze container offset pills.push(pill); } } // Game update loop game.update = function () { if (gameState !== "game" || !player || !pills) return; // Check pill collection for (var i = pills.length - 1; i >= 0; i--) { var pill = pills[i]; if (!pill.collected && player.intersects(pill)) { pill.collect(); pillsCollected++; // Update counter counterText.setText(texts[currentLanguage].pills + ' ' + pillsCollected + '/' + totalPills); // Remove from array pills.splice(i, 1); } } // Check door collision only after collecting all pills if (pillsCollected >= totalPills) { var doorBounds = { x: (MAZE_WIDTH - 3) * CELL_SIZE, y: (MAZE_HEIGHT - 3) * CELL_SIZE + 150, width: CELL_SIZE, height: CELL_SIZE }; if (player.x >= doorBounds.x && player.x <= doorBounds.x + doorBounds.width && player.y >= doorBounds.y && player.y <= doorBounds.y + doorBounds.height) { startEndingDialogue(); return; } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Pill = Container.expand(function () {
var self = Container.call(this);
var pillGraphics = self.attachAsset('pill', {
anchorX: 0.5,
anchorY: 0.5
});
self.collected = false;
self.collect = function () {
if (self.collected) return;
self.collected = true;
self.visible = false;
LK.getSound('collect').play();
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.targetX = 0;
self.targetY = 0;
self.isMoving = false;
self.moveToTarget = function (targetX, targetY) {
if (self.isMoving) return;
self.targetX = targetX;
self.targetY = targetY;
self.isMoving = true;
tween(self, {
x: targetX,
y: targetY
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
self.isMoving = false;
}
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Language system
var currentLanguage = storage.language || 'spanish';
var texts = {
spanish: {
play: 'JUGAR',
playDay2: 'JUGAR DÍA 2',
language: 'LENGUAJE',
spanish: 'ESPAÑOL',
english: 'INGLES',
pills: 'PASTILLAS',
"continue": 'Haz CLICK en cualquier lugar para continuar',
yes: 'SI',
givePills: 'DAR PASTILLAS'
},
english: {
play: 'PLAY',
playDay2: 'PLAY DAY 2',
language: 'LANGUAGE',
spanish: 'SPANISH',
english: 'ENGLISH',
pills: 'PILLS',
"continue": 'Click anywhere to continue',
yes: 'YES',
givePills: 'GIVE PILLS'
}
};
// Game state management
var gameState = "menu"; // "menu", "dialogue", "game", "ending", "language"
var currentDialogue = 0;
var dialogueTexts = {
spanish: ["Ahhh… qué sorpresa… un pequeño perdido en este lugar sin alma.\nMmm… qué olor más extraño tienes… ya sé de dónde vienes.", "¿Quieres salir, verdad? ¿Quieres encontrar la puerta que te lleve lejos de aquí? Je, je, je… Yo sé dónde está.\nSí… yo siempre lo sé.", "Pero nada es gratis, pequeño. Yo también necesito algo… unas píldoras. Mis dulces, mis tesoros…\nLas perdí, y sin ellas me siento… vacía. ¿Me ayudarás?", "Eso está mejor… sabía que no me dirías que no, pequeño.\nMis píldoras… están dentro de la mansión que se levanta allá… la de cinco pisos que araña el cielo.", "No tengas miedo… no necesitas recorrerla toda.\nMis píldoras están en el primer piso, todas escondidas como pequeños ratones traviesos.", "Son diez en total. Diez. Ni una menos… ni una más.\nCuando las tengas todas… busca la puerta roja. Solo por ahí podrás salir… si es que todavía quieres hacerlo.", "Ve, pequeño… la mansión te espera. Y yo… yo estaré observando."],
english: ["Ahhh... what a surprise... a little one lost in this soulless place.\nMmm... what a strange smell you have... I know where you come from.", "You want to leave, right? You want to find the door that takes you away from here? Heh, heh, heh... I know where it is.\nYes... I always know.", "But nothing is free, little one. I also need something... some pills. My sweets, my treasures...\nI lost them, and without them I feel... empty. Will you help me?", "That's better... I knew you wouldn't say no to me, little one.\nMy pills... are inside the mansion that rises there... the five-story one that scrapes the sky.", "Don't be afraid... you don't need to go through it all.\nMy pills are on the first floor, all hidden like little mischievous mice.", "There are ten in total. Ten. Not one less... not one more.\nWhen you have them all... look for the red door. Only through there can you leave... if you still want to.", "Go, little one... the mansion awaits you. And I... I will be watching."]
};
var endingDialogueTexts = {
spanish: ["Ahhh… has vuelto, pequeño. Y veo que... sí... sí... puedo sentirlas.\n Mis dulces tesoros están contigo, ¿verdad?", "Dámelas... por favor... necesito sentir su dulzura en mis manos otra vez.", "Sí... sí... aquí están todas. Una... dos... tres... ¡Diez! Mis preciosas... cómo las extrañé...", "Gracias, pequeño... gracias por devolverme lo que más amo.\n Me siento... completa otra vez. El vacío se llena, la oscuridad se calma...", "Pero... pero hay algo que debo decirte. Algo que me duele confesar...", "Yo... yo te mentí, pequeño. La puerta roja... no te llevará a casa.\n No puedo decirte cómo salir de aquí porque... porque Ella nos observa.", "La Vigía del Umbral... siempre está mirando, siempre está escuchando. Si te dijera la verdad sobre la salida... \nsi te mostrara el camino real... Ella lo sabría. Y entonces... entonces nos castigaría a ambos.", "Perdóname, pequeño... perdóname por engañarte. Pero necesitaba mis píldoras... \ny tú... tú necesitabas una razón para seguir adelante, para no rendirte en este lugar maldito.", "La puerta roja... solo es el comienzo de otro laberinto. Pero tal vez...\n tal vez si eres lo suficientemente astuto... encontrarás tu propio camino.", "Ve ahora... antes de que Ella se dé cuenta de que hemos hablado demasiado.\n Y recuerda... en este lugar, la verdad es un lujo que pocos pueden permitirse.", "Adiós, pequeño valiente... que la suerte te acompañe en la oscuridad que te espera."],
english: ["Ahhh... you've returned, little one. And I see that... yes... yes... I can feel them.\n My sweet treasures are with you, aren't they?", "Give them to me... please... I need to feel their sweetness in my hands again.", "Yes... yes... here they all are. One... two... three... Ten! My precious ones... how I missed them...", "Thank you, little one... thank you for returning what I love most.\n I feel... complete again. The void is filled, the darkness calms...", "But... but there's something I must tell you. Something that hurts me to confess...", "I... I lied to you, little one. The red door... won't take you home.\n I can't tell you how to get out of here because... because She watches us.", "The Watcher of the Threshold... always looking, always listening. If I told you the truth about the exit... \nif I showed you the real way... She would know. And then... then she would punish us both.", "Forgive me, little one... forgive me for deceiving you. But I needed my pills... \nand you... you needed a reason to keep going, to not give up in this cursed place.", "The red door... is only the beginning of another labyrinth. But maybe...\n maybe if you're clever enough... you'll find your own way.", "Go now... before She realizes we've talked too much.\n And remember... in this place, truth is a luxury few can afford.", "Goodbye, brave little one... may luck accompany you in the darkness that awaits."]
};
var currentEndingDialogue = 0;
var showYesButton = false;
var showGivePillsButton = false;
var pillAssetShown = false;
var day2Unlocked = false;
var abriendoSoundPlayed = false;
var CELL_SIZE = 64;
// Menu UI Elements
var titleText = LK.getAsset('TITULO', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 600,
scaleX: 8,
scaleY: 8
});
game.addChild(titleText);
var playButton = new Text2(texts[currentLanguage].play, {
size: 80,
fill: 0x4a90e2
});
playButton.anchor.set(0.5, 0.5);
playButton.x = 1024;
playButton.y = 1000;
game.addChild(playButton);
var languageButton = new Text2(texts[currentLanguage].language, {
size: 60,
fill: 0x4a90e2
});
languageButton.anchor.set(0.5, 0.5);
languageButton.x = 1024;
languageButton.y = 1150;
game.addChild(languageButton);
// Language selection buttons (initially hidden)
var spanishButton = new Text2(texts[currentLanguage].spanish, {
size: 60,
fill: 0x4a90e2
});
spanishButton.anchor.set(0.5, 0.5);
spanishButton.x = 1024;
spanishButton.y = 1250;
spanishButton.visible = false;
game.addChild(spanishButton);
var englishButton = new Text2(texts[currentLanguage].english, {
size: 60,
fill: 0x4a90e2
});
englishButton.anchor.set(0.5, 0.5);
englishButton.x = 1024;
englishButton.y = 1350;
englishButton.visible = false;
game.addChild(englishButton);
// Character sprite (initially hidden)
var pinkcraiyon = LK.getAsset('Pinkcraiyon', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 800,
scaleX: 2,
scaleY: 2
});
pinkcraiyon.alpha = 0;
game.addChild(pinkcraiyon);
// Dialogue UI
var dialogueBox = new Text2('', {
size: 35,
fill: 0xffffff
});
dialogueBox.anchor.set(0.5, 0.5);
dialogueBox.x = 1024;
dialogueBox.y = 1800;
dialogueBox.visible = false;
game.addChild(dialogueBox);
var continueText = new Text2(texts[currentLanguage]["continue"], {
size: 28,
fill: 0xcccccc
});
continueText.anchor.set(0.5, 0.5);
continueText.x = 1024;
continueText.y = 2200;
continueText.visible = false;
game.addChild(continueText);
var yesButton = new Text2(texts[currentLanguage].yes, {
size: 60,
fill: 0x4a90e2
});
yesButton.anchor.set(0.5, 0.5);
yesButton.x = 1024;
yesButton.y = 2000;
yesButton.visible = false;
game.addChild(yesButton);
var givePillsButton = new Text2(texts[currentLanguage].givePills, {
size: 60,
fill: 0x4a90e2
});
givePillsButton.anchor.set(0.5, 0.5);
givePillsButton.x = 1024;
givePillsButton.y = 2000;
givePillsButton.visible = false;
game.addChild(givePillsButton);
// Pill asset for ending sequence
var pillAsset = LK.getAsset('pill', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 800,
scaleX: 15,
scaleY: 15
});
pillAsset.alpha = 0;
game.addChild(pillAsset);
// Red door asset for final sequence
var puertaRoja = LK.getAsset('puertaroja', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366,
scaleX: 0.5,
scaleY: 0.5
});
puertaRoja.alpha = 0;
game.addChild(puertaRoja);
// Game variables (will be initialized when starting game)
var MAZE_WIDTH, MAZE_HEIGHT, maze, mazeContainer, player, pills, pillsCollected, totalPills, counterText, door;
// Function to update all UI texts with current language
function updateLanguageTexts() {
playButton.setText(day2Unlocked ? texts[currentLanguage].playDay2 : texts[currentLanguage].play);
languageButton.setText(texts[currentLanguage].language);
spanishButton.setText(texts[currentLanguage].spanish);
englishButton.setText(texts[currentLanguage].english);
continueText.setText(texts[currentLanguage]["continue"]);
yesButton.setText(texts[currentLanguage].yes);
givePillsButton.setText(texts[currentLanguage].givePills);
if (counterText) {
counterText.setText(texts[currentLanguage].pills + ' ' + pillsCollected + '/' + totalPills);
}
}
// Function to check if a position is walkable
function isWalkable(x, y) {
var gridX = Math.floor(x / CELL_SIZE);
var gridY = Math.floor(y / CELL_SIZE);
if (gridX < 0 || gridX >= MAZE_WIDTH || gridY < 0 || gridY >= MAZE_HEIGHT) {
return false;
}
return maze[gridY][gridX] === 0;
}
// Function to check if path between two points is clear
function hasPathTo(fromX, fromY, toX, toY) {
var fromGridX = Math.floor(fromX / CELL_SIZE);
var fromGridY = Math.floor(fromY / CELL_SIZE);
var toGridX = Math.floor(toX / CELL_SIZE);
var toGridY = Math.floor(toY / CELL_SIZE);
// Simple line-of-sight check
var dx = Math.abs(toGridX - fromGridX);
var dy = Math.abs(toGridY - fromGridY);
var stepX = fromGridX < toGridX ? 1 : -1;
var stepY = fromGridY < toGridY ? 1 : -1;
var err = dx - dy;
var currentX = fromGridX;
var currentY = fromGridY;
while (true) {
if (currentX < 0 || currentX >= MAZE_WIDTH || currentY < 0 || currentY >= MAZE_HEIGHT) {
return false;
}
if (maze[currentY][currentX] === 1) {
return false;
}
if (currentX === toGridX && currentY === toGridY) {
return true;
}
var e2 = 2 * err;
if (e2 > -dy) {
err -= dy;
currentX += stepX;
}
if (e2 < dx) {
err += dx;
currentY += stepY;
}
}
}
// Function to get random walkable position
function getRandomWalkablePosition() {
var attempts = 0;
while (attempts < 100) {
var x = Math.floor(Math.random() * MAZE_WIDTH);
var y = Math.floor(Math.random() * MAZE_HEIGHT);
if (maze[y][x] === 0) {
return {
x: x * CELL_SIZE + CELL_SIZE / 2,
y: y * CELL_SIZE + CELL_SIZE / 2
};
}
attempts++;
}
// Fallback to player starting position
return {
x: CELL_SIZE / 2,
y: CELL_SIZE / 2
};
}
// Spawn initial pills
for (var i = 0; i < totalPills; i++) {
var pillPos = getRandomWalkablePosition();
// Make sure pill is not too close to player start
while (Math.abs(pillPos.x - CELL_SIZE / 2) < 128 && Math.abs(pillPos.y - CELL_SIZE / 2) < 128) {
pillPos = getRandomWalkablePosition();
}
var pill = game.addChild(new Pill());
pill.x = pillPos.x;
pill.y = pillPos.y + 150; // Adjust for maze container offset
pills.push(pill);
}
// Game click handler
game.down = function (x, y, obj) {
if (gameState === "menu") {
// Check if play button was clicked
if (x >= playButton.x - 100 && x <= playButton.x + 100 && y >= playButton.y - 50 && y <= playButton.y + 50) {
startDialogue();
}
// Check if language button was clicked
else if (x >= languageButton.x - 120 && x <= languageButton.x + 120 && y >= languageButton.y - 50 && y <= languageButton.y + 50) {
gameState = "language";
spanishButton.visible = true;
englishButton.visible = true;
}
} else if (gameState === "language") {
// Check if Spanish button was clicked
if (x >= spanishButton.x - 100 && x <= spanishButton.x + 100 && y >= spanishButton.y - 50 && y <= spanishButton.y + 50) {
currentLanguage = 'spanish';
storage.language = currentLanguage;
gameState = "menu";
spanishButton.visible = false;
englishButton.visible = false;
updateLanguageTexts();
}
// Check if English button was clicked
else if (x >= englishButton.x - 100 && x <= englishButton.x + 100 && y >= englishButton.y - 50 && y <= englishButton.y + 50) {
currentLanguage = 'english';
storage.language = currentLanguage;
gameState = "menu";
spanishButton.visible = false;
englishButton.visible = false;
updateLanguageTexts();
}
} else if (gameState === "dialogue") {
if (showYesButton && yesButton.visible) {
// Check if yes button was clicked
if (x >= yesButton.x - 50 && x <= yesButton.x + 50 && y >= yesButton.y - 30 && y <= yesButton.y + 30) {
showYesButton = false;
yesButton.visible = false;
continueText.visible = true;
currentDialogue++;
if (currentDialogue < dialogueTexts[currentLanguage].length) {
dialogueBox.setText(dialogueTexts[currentLanguage][currentDialogue]);
}
}
} else {
// Continue dialogue
currentDialogue++;
if (currentDialogue === 3) {
// Show YES button after third dialogue
showYesButton = true;
yesButton.visible = true;
continueText.visible = false;
} else if (currentDialogue >= dialogueTexts[currentLanguage].length) {
// Start the game
startGame();
} else {
dialogueBox.setText(dialogueTexts[currentLanguage][currentDialogue]);
}
}
} else if (gameState === "ending") {
if (showGivePillsButton && givePillsButton.visible) {
// Check if give pills button was clicked
if (x >= givePillsButton.x - 120 && x <= givePillsButton.x + 120 && y >= givePillsButton.y - 30 && y <= givePillsButton.y + 30) {
showGivePillsButton = false;
givePillsButton.visible = false;
continueText.visible = true;
currentEndingDialogue++;
dialogueBox.setText(endingDialogueTexts[currentLanguage][currentEndingDialogue]);
}
} else {
// Continue ending dialogue
currentEndingDialogue++;
if (currentEndingDialogue === 2) {
// Show give pills button after second dialogue
showGivePillsButton = true;
givePillsButton.visible = true;
continueText.visible = false;
} else if (currentEndingDialogue === 3) {
dialogueBox.setText(endingDialogueTexts[currentLanguage][currentEndingDialogue]);
} else if (currentEndingDialogue >= endingDialogueTexts[currentLanguage].length) {
// End sequence with door animation
startEndingSequence();
} else {
dialogueBox.setText(endingDialogueTexts[currentLanguage][currentEndingDialogue]);
}
}
} else if (gameState === "game") {
if (player.isMoving) return;
// Adjust for maze container offset
var adjustedY = y - 150;
var adjustedPlayerY = player.y - 150;
// Check if target position is walkable and path is clear
if (isWalkable(x, adjustedY) && hasPathTo(player.x, adjustedPlayerY, x, adjustedY)) {
// Snap to grid center
var gridX = Math.floor(x / CELL_SIZE);
var gridY = Math.floor(adjustedY / CELL_SIZE);
var targetX = gridX * CELL_SIZE + CELL_SIZE / 2;
var targetY = gridY * CELL_SIZE + CELL_SIZE / 2 + 150; // Add offset back
player.moveToTarget(targetX, targetY);
}
}
};
function startDialogue() {
gameState = "dialogue";
titleText.visible = false;
playButton.visible = false;
languageButton.visible = false;
// Fade in Pinkcraiyon
tween(pinkcraiyon, {
alpha: 1
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
// Show first dialogue
dialogueBox.visible = true;
continueText.visible = true;
dialogueBox.setText(dialogueTexts[currentLanguage][currentDialogue]);
}
});
}
function startGame() {
gameState = "game";
// Hide dialogue elements
pinkcraiyon.visible = false;
dialogueBox.visible = false;
continueText.visible = false;
initializeGame();
}
function startEndingDialogue() {
gameState = "ending";
currentEndingDialogue = 0;
// Hide game elements
if (mazeContainer) mazeContainer.visible = false;
if (player) player.visible = false;
if (counterText) counterText.visible = false;
// Hide all pills
for (var i = 0; i < pills.length; i++) {
pills[i].visible = false;
}
// Show dialogue elements
game.setBackgroundColor(0x000000);
dialogueBox.visible = true;
continueText.visible = true;
// Fade in Pinkcraiyon
tween(pinkcraiyon, {
alpha: 1
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
pinkcraiyon.visible = true;
dialogueBox.setText(endingDialogueTexts[currentLanguage][currentEndingDialogue]);
}
});
}
function startEndingSequence() {
// Hide dialogue elements first
dialogueBox.visible = false;
continueText.visible = false;
// Fade out Pinkcraiyon
tween(pinkcraiyon, {
alpha: 0
}, {
duration: 1000,
onFinish: function onFinish() {
// After Pinkcraiyon fades out, show and animate puerta roja
puertaRoja.visible = true;
puertaRoja.scaleX = 0.5;
puertaRoja.scaleY = 0.5;
tween(puertaRoja, {
alpha: 1,
scaleX: 8,
scaleY: 8
}, {
duration: 12000,
easing: tween.easeOut,
onFinish: function onFinish() {
// Play opening sound only once
if (!abriendoSoundPlayed) {
LK.getSound('abriendo').play();
abriendoSoundPlayed = true;
}
// Wait for sound to finish, then fade out door and show black background
LK.setTimeout(function () {
tween(puertaRoja, {
alpha: 0
}, {
duration: 1000,
onFinish: function onFinish() {
// After door fades out and black background is shown, return to menu
returnToMenu();
}
});
}, 3000); // Wait 3 seconds for sound to finish
}
});
}
});
}
function returnToMenu() {
gameState = "menu";
day2Unlocked = true;
// Reset all variables
currentDialogue = 0;
currentEndingDialogue = 0;
showYesButton = false;
showGivePillsButton = false;
pillAssetShown = false;
abriendoSoundPlayed = false;
// Show menu elements
titleText.visible = true;
playButton.visible = true;
languageButton.visible = true;
spanishButton.visible = false;
englishButton.visible = false;
updateLanguageTexts();
// Hide all other elements
pinkcraiyon.visible = false;
pinkcraiyon.alpha = 0;
pillAsset.visible = false;
pillAsset.alpha = 0;
puertaRoja.visible = false;
puertaRoja.alpha = 0;
if (mazeContainer) mazeContainer.visible = false;
if (player) player.visible = false;
if (counterText) counterText.visible = false;
}
function initializeGame() {
MAZE_WIDTH = Math.floor(1800 / CELL_SIZE); // Make maze smaller
MAZE_HEIGHT = Math.floor(2582 / CELL_SIZE); // Reach bottom of screen (2732 - 150 offset)
// Simple maze generation that ensures connectivity with longer walls
maze = [];
for (var y = 0; y < MAZE_HEIGHT; y++) {
maze[y] = [];
for (var x = 0; x < MAZE_WIDTH; x++) {
// Create outer walls
if (x === 0 || y === 0 || x === MAZE_WIDTH - 1 || y === MAZE_HEIGHT - 1) {
maze[y][x] = 1; // wall
}
// Create longer L-shaped wall patterns (extended from 2-3 to 2-5 for longer walls)
else if (x % 8 >= 2 && x % 8 <= 5 && y % 8 >= 2 && y % 8 <= 5 && Math.random() < 0.6) {
maze[y][x] = 1; // Extended L-shaped walls
}
// Create longer horizontal wall segments
else if (y % 6 === 2 && x % 8 >= 1 && x % 8 <= 6 && Math.random() < 0.5) {
maze[y][x] = 1; // longer horizontal walls
}
// Create longer vertical wall segments
else if (x % 6 === 2 && y % 8 >= 1 && y % 8 <= 6 && Math.random() < 0.5) {
maze[y][x] = 1; // longer vertical walls
}
// Add some random walls but keep paths open
else if (x % 4 === 0 && y % 4 === 0 && Math.random() < 0.3) {
maze[y][x] = 1; // sparse additional walls
} else {
maze[y][x] = 0; // floor
}
}
}
// Ensure starting position and surrounding area is clear (larger area)
for (var sy = 1; sy <= 4; sy++) {
for (var sx = 1; sx <= 4; sx++) {
maze[sy][sx] = 0;
}
}
// Ensure exit area is clear (larger area)
for (var ey = MAZE_HEIGHT - 5; ey < MAZE_HEIGHT - 1; ey++) {
for (var ex = MAZE_WIDTH - 5; ex < MAZE_WIDTH - 1; ex++) {
maze[ey][ex] = 0;
}
}
// Create guaranteed horizontal paths every 6 rows
for (var py = 3; py < MAZE_HEIGHT - 1; py += 6) {
for (var px = 1; px < MAZE_WIDTH - 1; px++) {
maze[py][px] = 0;
}
}
// Create guaranteed vertical paths every 6 columns
for (var px = 3; px < MAZE_WIDTH - 1; px += 6) {
for (var py = 1; py < MAZE_HEIGHT - 1; py++) {
maze[py][px] = 0;
}
}
// Create maze visuals
mazeContainer = game.addChild(new Container());
mazeContainer.y = 150; // Move maze down to avoid pause button
for (var y = 0; y < MAZE_HEIGHT; y++) {
for (var x = 0; x < MAZE_WIDTH; x++) {
var cellX = x * CELL_SIZE;
var cellY = y * CELL_SIZE;
if (maze[y][x] === 1) {
// Wall
var wall = LK.getAsset('wall', {
x: cellX,
y: cellY
});
mazeContainer.addChild(wall);
} else {
// Floor
var floor = LK.getAsset('floor', {
x: cellX,
y: cellY
});
mazeContainer.addChild(floor);
}
}
}
// Create door inside maze at bottom-right walkable area
door = LK.getAsset('door', {
x: (MAZE_WIDTH - 3) * CELL_SIZE,
y: (MAZE_HEIGHT - 3) * CELL_SIZE,
anchorX: 0,
anchorY: 0
});
mazeContainer.addChild(door);
// Create player at guaranteed walkable position
player = game.addChild(new Player());
// Find first walkable position starting from top-left
var playerStartX = CELL_SIZE + CELL_SIZE / 2; // Grid position 1,1 center
var playerStartY = CELL_SIZE + CELL_SIZE / 2; // Grid position 1,1 center
player.x = playerStartX;
player.y = playerStartY + 150; // Adjust for maze container offset
// Pills array and counter
pills = [];
pillsCollected = 0;
totalPills = 10;
// UI Counter
counterText = new Text2(texts[currentLanguage].pills + ' 0/10', {
size: 80,
fill: 0xFFFFFF
});
counterText.anchor.set(0.5, 0);
LK.gui.top.addChild(counterText);
// Spawn initial pills
for (var i = 0; i < totalPills; i++) {
var pillPos = getRandomWalkablePosition();
// Make sure pill is not too close to player start
while (Math.abs(pillPos.x - CELL_SIZE / 2) < 128 && Math.abs(pillPos.y - CELL_SIZE / 2) < 128) {
pillPos = getRandomWalkablePosition();
}
var pill = game.addChild(new Pill());
pill.x = pillPos.x;
pill.y = pillPos.y + 150; // Adjust for maze container offset
pills.push(pill);
}
}
// Game update loop
game.update = function () {
if (gameState !== "game" || !player || !pills) return;
// Check pill collection
for (var i = pills.length - 1; i >= 0; i--) {
var pill = pills[i];
if (!pill.collected && player.intersects(pill)) {
pill.collect();
pillsCollected++;
// Update counter
counterText.setText(texts[currentLanguage].pills + ' ' + pillsCollected + '/' + totalPills);
// Remove from array
pills.splice(i, 1);
}
}
// Check door collision only after collecting all pills
if (pillsCollected >= totalPills) {
var doorBounds = {
x: (MAZE_WIDTH - 3) * CELL_SIZE,
y: (MAZE_HEIGHT - 3) * CELL_SIZE + 150,
width: CELL_SIZE,
height: CELL_SIZE
};
if (player.x >= doorBounds.x && player.x <= doorBounds.x + doorBounds.width && player.y >= doorBounds.y && player.y <= doorBounds.y + doorBounds.height) {
startEndingDialogue();
return;
}
}
};