User prompt
Please fix the bug: 'Timeout.tick error: timeLeftText is not defined' in or related to this line: 'if (timeLeftText.parent) {' Line Number: 380 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
cuando jugamos el primer nivel y terminamos de derrotar a las panteras abajo de la pantalla aparecen unas letras rojas, elimínalas, no te lo pedí.
User prompt
cuando pausemos el nivel que el tiempo se detenga, basicamente que no siga contando, y que cuando saquemos la pausa que el tiempo marque justo el minuto y segundo que se mostro cuando pausamos el nivel, okey?. por otro lado, que cuando estemos jugando en cualquier nivel que detras de el laberinto y de las letras se muestre el asset: "fondonegro" y que deje de verse cuando ganemos o perdamos el nivel.
User prompt
cuando comienze el nivel 1 elimina el asset "FONDOMENU" y que el fondo que se vea mientras jugamos sea una imagen negra.
User prompt
cuando comience el nivel 1 que el asset "FONDOMENU" sea solo color negro como te lo pedí. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
cuando recolectamos una pastafrola se suma un solo punto, pero hay otro bug este es que si recolectamos (por ejemplo) en un solo movimiento 2 pastafrolas se suman 4 puntos, esto esta mal, solo se deben suman en los puntos la cantidad real de pastafrolas que recolectamos. por otro lado, quiero que el fondo de el menu principal sea el asset: "FONDOMENU" y que la intensidad de su brillo sea solo de un 20% osea que es bastante oscuro, eso si, cuando comencemos a jugar un nivel que este asset fije su brillo a 0% (osea que sea negro) y que solo recupere su 20% de brillo cuando se muestre el menu. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
cuando seleccionamos el idioma español hay palabras que no aparecen en este idioma, corrige esto pues quiero que cuando elijamos el idioma español que TODAS las palabras aparezcan en este idioma, ademas en este idioma se bugueo el texto que sale cuando precionamos tutorial, arregla TODOS estos bugs porfavor. y la implementacion de los sonidos de victoria y derrota esta mal hecha pues n o se escuchan, ARREGLA ESTO.
User prompt
cuando seleccionamos el idioma ingles no todos los textos aparecen en ingles, quiero que cuando seleccionemos esa opcion que TODOS los textos aparezcan en ese idioma. por otro lado, cuando ganemos el primer nivel y se nos muestre la pantalla de victoria que suene el sonido: "victoria" pero en cambio si perdemos cuando se nos muestre la pantalla de derrota que sueñe el sonido: "derrota"
User prompt
Viste los botones en el menu? bueno, conserva el de jugar, y elimina los otros(el de lenguaje y el de tutorial) , que en su lugar haya uno llamado: "opciones" y que al presionarlo nos muestre las siguientes opciones: la de lenguaje llamada: "lenguaje" y otra opcion llamada niveles, y al presionar esta misma nos muestre los assets: "level1" y "level2" y que al presionar level1 volvamos al menu (el level1 es el nivel que estuvimos creando, por lo que ahora al darle a jugar comience ese nivel) y que al lado del asset "level 2" que este el asset: "candado" (este ultimo asset es para indicar que el level2 esta bloqueado por lo que aun no se puede jugar) que abajo del asset "level1" diga tutorial, al presionarlo que nos muestre un apartado con el siguiente texto: "Para moverte presiona el lugar donde quieras ir, para ganar derrota a los enemigos lanzándoles pastafrolas, recoléctalas pasando sobre ellas, y lánzaselas presionando al enemigo que quieras atacar! Tienes un contador que te indica cuantas pastafrolas tienes recolectadas. y un limite de tiempo de 2 minutos para completar el nivel!" y que abajo de "level2" este tambien un boton de tutorial, pero que al presionarlo salga el mensaje: "ups, este nivel esta bloqueado!" cuando comience el juego si no elegimos un nivel... pues cuando le demos a jugar que nos salga el siguiente mensaje: "primero selecciona el nivel que quieras jugar"
User prompt
hay un bug que a veces cuando tratamos de golpear a la pantera y esta no recibe daño, por favor arregla este bug, gracias., lo correcto sería que deberíamos podemos atacar a las pateras siempre y cuando no haya una barrera del laberinto entre nosotros y la pantera. (recuerda que su colisión es del tamaño de un bloque)
User prompt
HAS QUE LAS colisiones DE CADA PANTERA SEA EQUIVALENTE A UN BLOQUE
User prompt
arregla el codigo, ahora no podemos atacar a las panteras... quiero que podamos atacarlas pero estando como maximo a 3 bloques de distancia, pero que no podamos atacarla si entre la pantera y el raton hay un wall de por medio.
User prompt
has que tengas que estar muy cerca de las panteras para poder atacarlas, no puedes estar con una pared del laberinto separado de la pantera a la hora de atacar, para poder atacarla no puede haber ningun obstaculo entre nosotros (con obstaculo me refiero a las paredes del laberinto)
User prompt
elimina el sonido de menu del juego
User prompt
cuando golpeemos a las panteras que suene el sonido: "panterasgolpe"
User prompt
esta sonando como repetido... que solo suene una pista de audio a la vez
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
language: "spanish"
});
/****
* Classes
****/
var Door = Container.expand(function () {
var self = Container.call(this);
var doorGraphics = self.attachAsset('door', {
anchorX: 0.5,
anchorY: 0.5
});
self.locked = true;
self.update = function () {
if (self.locked && panterasDefeated >= 2 && mouse.pastafrolas >= 10) {
self.locked = false;
doorGraphics.tint = 0x90EE90; // Light green when unlocked
}
if (!self.locked && self.intersects(mouse)) {
// Show congratulations screen
showCongratulationsScreen();
}
};
return self;
});
// Game constants
var Mouse = Container.expand(function () {
var self = Container.call(this);
var mouseGraphics = self.attachAsset('mouse', {
anchorX: 0.5,
anchorY: 0.5
});
self.isMoving = false;
self.targetX = 0;
self.targetY = 0;
self.speed = 8;
self.pastafrolas = 0;
self.moveTo = function (x, y) {
var adjustedY = y - MAZE_OFFSET_Y;
var gridX = Math.floor(x / CELL_SIZE);
var gridY = Math.floor(adjustedY / CELL_SIZE);
if (isWalkable(gridX, gridY)) {
self.targetX = x;
self.targetY = y;
self.isMoving = true;
}
};
self.update = function () {
if (self.isMoving) {
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Calculate rotation angle based on movement direction
var targetRotation = Math.atan2(dy, dx) + Math.PI / 2 + Math.PI; // Add PI/2 because mouse starts pointing down, plus PI to correct direction
tween(mouseGraphics, {
rotation: targetRotation
}, {
duration: 150,
easing: tween.easeOut
});
if (distance < self.speed) {
self.x = self.targetX;
self.y = self.targetY;
self.isMoving = false;
} else {
var newX = self.x + dx / distance * self.speed;
var newY = self.y + dy / distance * self.speed;
var adjustedY = newY - MAZE_OFFSET_Y;
var gridX = Math.floor(newX / CELL_SIZE);
var gridY = Math.floor(adjustedY / CELL_SIZE);
// Check collision during movement
if (isWalkable(gridX, gridY)) {
self.x = newX;
self.y = newY;
} else {
// Stop movement if hitting wall
self.isMoving = false;
}
}
}
};
return self;
});
var Pantera = Container.expand(function () {
var self = Container.call(this);
var panteraGraphics = self.attachAsset('pantera', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 100;
self.maxHealth = 100;
self.defeated = false;
// Override the width and height for collision detection to match block size
self.width = 102; // CELL_SIZE
self.height = 102; // CELL_SIZE
self.takeDamage = function (damage) {
if (!self.defeated) {
self.health -= damage;
LK.getSound('hit').play();
LK.getSound('panterasgolpe').play();
if (self.health <= 0) {
self.health = 0;
self.defeated = true;
self.visible = false;
panterasDefeated++;
// Spawn new pastafrola when pantera is defeated
spawnPastafrola();
}
// Visual feedback
LK.effects.flashObject(self, 0xFF0000, 300);
}
};
self.down = function (x, y, obj) {
if (!self.defeated && mouse.pastafrolas > 0) {
// Calculate distance between mouse and pantera centers
var dx = mouse.x - self.x;
var dy = mouse.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var maxAttackDistance = CELL_SIZE * 3; // Must be within 3 cells
// Convert positions to grid coordinates for more reliable line of sight check
var mouseGridX = Math.floor(mouse.x / CELL_SIZE);
var mouseGridY = Math.floor((mouse.y - MAZE_OFFSET_Y) / CELL_SIZE);
var panteraGridX = Math.floor(self.x / CELL_SIZE);
var panteraGridY = Math.floor((self.y - MAZE_OFFSET_Y) / CELL_SIZE);
// Calculate grid distance (Manhattan distance for more lenient attack range)
var gridDistance = Math.abs(mouseGridX - panteraGridX) + Math.abs(panteraGridY - mouseGridY);
// Check if mouse is close enough (within 3 grid cells) and has line of sight
if (gridDistance <= 3 && hasLineOfSight(mouse.x, mouse.y, self.x, self.y)) {
mouse.pastafrolas--;
self.takeDamage(20);
LK.getSound('attack').play();
updateUI();
} else {
// Show notification if attack failed due to distance or obstacles
if (gridDistance > 3) {
showNotification(currentLanguage === 'spanish' ? '¡Muy lejos para atacar!' : 'Too far to attack!');
} else {
showNotification(currentLanguage === 'spanish' ? '¡Hay obstáculos en el camino!' : 'Obstacles are blocking the way!');
}
}
}
};
return self;
});
var Pastafrola = Container.expand(function () {
var self = Container.call(this);
var pastaGraphics = self.attachAsset('pastafrola', {
anchorX: 0.5,
anchorY: 0.5
});
self.collected = false;
self.update = function () {
// Initialize lastIntersecting state if not set
if (self.lastIntersecting === undefined) {
self.lastIntersecting = false;
}
// Check current intersection state
var currentIntersecting = self.intersects(mouse);
// Only collect if we just started intersecting (transition from false to true)
if (!self.collected && !self.lastIntersecting && currentIntersecting) {
self.collected = true;
mouse.pastafrolas++;
pastafrolarCollas++;
LK.getSound('pastafrolasound').play();
self.visible = false;
updateUI();
}
// Update last intersecting state
self.lastIntersecting = currentIntersecting;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x8B4513
});
/****
* Game Code
****/
// Game state management
var gameStarted = false;
var startButton;
var selectedLevel = null;
var showingLanguageMenu = false;
var currentLanguage = storage.language || 'spanish';
// Timer variables
var gameTimer = 120000; // 2 minutes in milliseconds
var gameStartTime = 0;
var timeRemainingText;
// Translations object
var translations = {
spanish: {
play: 'JUGAR',
language: 'LENGUAJE',
tutorial: 'TUTORIAL',
selectLanguage: 'SELECCIONA IDIOMA',
spanish: 'ESPAÑOL',
english: 'INGLÉS',
congratulations: 'FELICIDADES',
youWon: '¡GANASTE!',
pastafrolas: 'Pastafrolas',
panteras: 'Panteras',
instructionCollect: 'Haz clic para moverte. ¡Recoge pastafrolas y derrota panteras!',
instructionDefeat: '¡Derrota todas las panteras primero!',
instructionNeed10: '¡Necesitas 10 pastafrolas en tu inventario!',
instructionComplete: '¡Todos los objetivos completados! ¡Ve a la puerta verde!',
allDefeated: '¡Todas las panteras derrotadas! Necesitas tener 10 pastafrolas en tu inventario para abrir la puerta',
defeatEnemy: 'Derrota al enemigo de esta zona para continuar',
tutorialText: 'Para moverte presiona el lugar donde quieras ir, para ganar derrota a los enemigos lanzándoles pastafrolas, recoléctalas pasando sobre ellas, y lánzaselas presionando al enemigo que quieras atacar! Tienes un contador que te indica cuantas pastafrolas tienes recolectadas.',
defeat: '¡PERDISTE!',
betterNextTime: 'mejor la próxima vez',
timeRemaining: 'Tiempo restante',
opciones: 'OPCIONES',
lenguaje: 'LENGUAJE',
niveles: 'NIVELES',
volver: 'VOLVER',
cerrar: 'CERRAR',
firstSelectLevel: 'primero selecciona el nivel que quieras jugar',
levelBlocked: 'ups, este nivel está bloqueado!',
tutorialLevel1: 'Para moverte presiona el lugar donde quieras ir, para ganar derrota a los enemigos lanzándoles pastafrolas, recoléctalas pasando sobre ellas, y lánzaselas presionando al enemigo que quieras atacar! Tienes un contador que te indica cuantas pastafrolas tienes recolectadas. ¡y un límite de tiempo de 2 minutos para completar el nivel!'
},
english: {
play: 'PLAY',
language: 'LANGUAGE',
tutorial: 'TUTORIAL',
selectLanguage: 'SELECT LANGUAGE',
spanish: 'SPANISH',
english: 'ENGLISH',
congratulations: 'CONGRATULATIONS',
youWon: 'YOU WON!',
pastafrolas: 'Pastafrolas',
panteras: 'Panthers',
instructionCollect: 'Click to move. Collect pastafrolas and defeat panthers!',
instructionDefeat: 'Defeat all panthers first!',
instructionNeed10: 'You need 10 pastafrolas in your inventory!',
instructionComplete: 'All objectives complete! Head to the green door!',
allDefeated: 'All panthers defeated! You need to have 10 pastafrolas in your inventory to open the door',
defeatEnemy: 'Defeat the enemy in this area to continue',
tutorialText: 'To move press the place where you want to go, to win defeat the enemies by throwing pastafrolas at them, collect them by passing over them, and throw them by pressing the enemy you want to attack! You have a counter that indicates how many pastafrolas you have collected.',
defeat: 'YOU LOST!',
betterNextTime: 'better luck next time',
timeRemaining: 'Time remaining',
opciones: 'OPTIONS',
lenguaje: 'LANGUAGE',
niveles: 'LEVELS',
volver: 'BACK',
cerrar: 'CLOSE',
firstSelectLevel: 'first select the level you want to play',
levelBlocked: 'oops, this level is blocked!',
tutorialLevel1: 'To move press the place where you want to go, to win defeat the enemies by throwing pastafrolas at them, collect them by passing over them, and throw them by pressing the enemy you want to attack! You have a counter that indicates how many pastafrolas you have collected. and a time limit of 2 minutes to complete the level!'
}
};
function getText(key) {
return translations[currentLanguage][key] || key;
}
// Game constants
var CELL_SIZE = 102;
var MAZE_WIDTH = 20;
var MAZE_HEIGHT = 22;
var MAZE_OFFSET_Y = 300; // Vertical offset to move maze down
// Game variables
var mouse;
var door;
var pastafrolas = [];
var panteras = [];
var pastafrolarCollas = 0;
var panterasDefeated = 0;
var lastPanterasDefeated = 0; // Track last pantera count to detect changes
// UI elements
var pastafrolarText;
var panteraText;
var instructionText;
var notificationText;
// Simple maze layout (1 = wall, 0 = walkable)
var mazeData = [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], [1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1], [1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1], [1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1], [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1], [1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1], [1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1], [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1], [1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1], [1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1], [1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1], [1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1], [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1], [1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1], [1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], [1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]];
function showCongratulationsScreen() {
// Play victory sound
LK.getSound('victoria').play();
// Stop the game timer by setting gameStarted to false
gameStarted = false;
// Hide UI counters immediately
if (pastafrolarText && pastafrolarText.parent) {
pastafrolarText.visible = false;
}
if (panteraText && panteraText.parent) {
panteraText.visible = false;
}
if (instructionText && instructionText.parent) {
instructionText.visible = false;
}
if (notificationText && notificationText.parent) {
notificationText.visible = false;
}
if (timeRemainingText && timeRemainingText.parent) {
timeRemainingText.visible = false;
}
// Create congratulations background
var congratsBackground = LK.getAsset('wall', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366,
scaleX: 25,
scaleY: 35,
tint: 0x000000,
alpha: 0.8
});
game.addChild(congratsBackground);
// Create congratulations title
var congratsTitle = new Text2(getText('congratulations'), {
size: 120,
fill: 0xFFD700
});
congratsTitle.anchor.set(0.5, 0.5);
congratsTitle.x = 1024;
congratsTitle.y = 1200;
game.addChild(congratsTitle);
// Create you won text
var youWonText = new Text2(getText('youWon'), {
size: 100,
fill: 0x00FF00
});
youWonText.anchor.set(0.5, 0.5);
youWonText.x = 1024;
youWonText.y = 1400;
game.addChild(youWonText);
// Calculate and display remaining time
var currentTime = Date.now();
var elapsedTime = currentTime - gameStartTime;
var timeLeft = Math.max(0, gameTimer - elapsedTime);
var secondsLeft = Math.ceil(timeLeft / 1000);
var minutes = Math.floor(secondsLeft / 60);
var seconds = secondsLeft % 60;
var timeLeftStr = minutes + ':' + (seconds < 10 ? '0' : '') + seconds;
// Create time remaining text
var timeLeftText = new Text2(getText('timeRemaining') + ': ' + timeLeftStr, {
size: 80,
fill: 0xFFD700
});
timeLeftText.anchor.set(0.5, 0.5);
timeLeftText.x = 1024;
timeLeftText.y = 1550;
game.addChild(timeLeftText);
// Automatically return to menu after 3 seconds
LK.setTimeout(function () {
// Remove congratulations screen elements
if (congratsBackground.parent) game.removeChild(congratsBackground);
if (congratsTitle.parent) game.removeChild(congratsTitle);
if (youWonText.parent) game.removeChild(youWonText);
if (timeLeftText.parent) game.removeChild(timeLeftText);
// Reset game state and return to main menu
resetGameState();
showStartScreen();
}, 3000);
}
function showDefeatScreen() {
// Play defeat sound
LK.getSound('derrota').play();
// Hide UI counters immediately
if (pastafrolarText && pastafrolarText.parent) {
pastafrolarText.visible = false;
}
if (panteraText && panteraText.parent) {
panteraText.visible = false;
}
if (instructionText && instructionText.parent) {
instructionText.visible = false;
}
if (notificationText && notificationText.parent) {
notificationText.visible = false;
}
if (timeRemainingText && timeRemainingText.parent) {
timeRemainingText.visible = false;
}
// Create defeat background
var defeatBackground = LK.getAsset('wall', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366,
scaleX: 25,
scaleY: 35,
tint: 0x000000,
alpha: 0.8
});
game.addChild(defeatBackground);
// Create defeat title
var defeatTitle = new Text2(getText('defeat'), {
size: 120,
fill: 0xFF4444
});
defeatTitle.anchor.set(0.5, 0.5);
defeatTitle.x = 1024;
defeatTitle.y = 1200;
game.addChild(defeatTitle);
// Create better next time text
var betterNextTimeText = new Text2(getText('betterNextTime'), {
size: 80,
fill: 0xFFFFFF
});
betterNextTimeText.anchor.set(0.5, 0.5);
betterNextTimeText.x = 1024;
betterNextTimeText.y = 1400;
game.addChild(betterNextTimeText);
// Automatically return to menu after 3 seconds
LK.setTimeout(function () {
// Remove defeat screen elements
if (defeatBackground.parent) game.removeChild(defeatBackground);
if (defeatTitle.parent) game.removeChild(defeatTitle);
if (betterNextTimeText.parent) game.removeChild(betterNextTimeText);
// Reset game state and return to main menu
resetGameState();
showStartScreen();
}, 3000);
}
function showStartScreen() {
// Set background to FONDOMENU with 20% brightness (tint to make it darker)
game.setBackgroundColor(0x000000); // Set to black first
var menuBackground = LK.getAsset('FONDOMENU', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366,
scaleX: 20.48,
// Scale to fill width (2048/100)
scaleY: 19.54,
// Scale to fill height (2732/139.89)
alpha: 0.2 // 20% brightness
});
game.addChild(menuBackground);
// Create start screen title using titulo asset
var titleText = LK.getAsset('titulo', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 800,
scaleX: 1.3,
scaleY: 1.3
});
game.addChild(titleText);
// Add pulsing animation to title
function animateTitle() {
tween(titleText, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(titleText, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: animateTitle
});
}
});
}
animateTitle();
// Create JUGAR button
startButton = LK.getAsset('wall', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1200,
scaleX: 4.5,
scaleY: 1.5,
tint: 0x4CAF50
});
game.addChild(startButton);
// Create button text
var buttonText = new Text2(getText('play'), {
size: 80,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
buttonText.x = 1024;
buttonText.y = 1200;
game.addChild(buttonText);
// Create OPCIONES button
var opcionesButton = LK.getAsset('wall', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1400,
scaleX: 5,
scaleY: 1.5,
tint: 0x2196F3
});
game.addChild(opcionesButton);
// Create opciones button text
var opcionesButtonText = new Text2(getText('opciones'), {
size: 80,
fill: 0xFFFFFF
});
opcionesButtonText.anchor.set(0.5, 0.5);
opcionesButtonText.x = 1024;
opcionesButtonText.y = 1400;
game.addChild(opcionesButtonText);
// Add click handler to start button
startButton.down = function (x, y, obj) {
if (!selectedLevel) {
showNotificationMessage(getText('firstSelectLevel'));
return;
}
gameStarted = true;
// Set background to black (0% brightness) when game starts
game.setBackgroundColor(0x000000);
// gameStarted flag will stop menumusical sound from looping
// Remove start screen elements
game.removeChild(titleText);
game.removeChild(startButton);
game.removeChild(buttonText);
game.removeChild(opcionesButton);
game.removeChild(opcionesButtonText);
// Initialize the actual game
initializeGame();
};
// Add click handler to opciones button
opcionesButton.down = function (x, y, obj) {
// Remove start screen elements
if (game.children[0] && game.children[0].texture && game.children[0].texture.textureCacheIds && game.children[0].texture.textureCacheIds.indexOf('FONDOMENU') !== -1) {
game.removeChild(game.children[0]); // Remove menuBackground
}
game.removeChild(titleText);
game.removeChild(startButton);
game.removeChild(buttonText);
game.removeChild(opcionesButton);
game.removeChild(opcionesButtonText);
// Show options screen
showOptionsScreen();
};
}
function showLanguageScreen() {
showingLanguageMenu = true;
// Create title
var languageTitle = new Text2(getText('selectLanguage'), {
size: 100,
fill: 0xFFFFFF
});
languageTitle.anchor.set(0.5, 0.5);
languageTitle.x = 1024;
languageTitle.y = 800;
game.addChild(languageTitle);
// Create Spanish button
var spanishButton = LK.getAsset('wall', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1100,
scaleX: 3,
scaleY: 1.5,
tint: currentLanguage === 'spanish' ? 0x4CAF50 : 0x757575
});
game.addChild(spanishButton);
var spanishButtonText = new Text2(getText('spanish'), {
size: 70,
fill: 0xFFFFFF
});
spanishButtonText.anchor.set(0.5, 0.5);
spanishButtonText.x = 1024;
spanishButtonText.y = 1100;
game.addChild(spanishButtonText);
// Create English button
var englishButton = LK.getAsset('wall', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1300,
scaleX: 3,
scaleY: 1.5,
tint: currentLanguage === 'english' ? 0x4CAF50 : 0x757575
});
game.addChild(englishButton);
var englishButtonText = new Text2(getText('english'), {
size: 70,
fill: 0xFFFFFF
});
englishButtonText.anchor.set(0.5, 0.5);
englishButtonText.x = 1024;
englishButtonText.y = 1300;
game.addChild(englishButtonText);
// Spanish button click handler
spanishButton.down = function (x, y, obj) {
currentLanguage = 'spanish';
storage.language = 'spanish';
// Remove language screen elements
game.removeChild(languageTitle);
game.removeChild(spanishButton);
game.removeChild(spanishButtonText);
game.removeChild(englishButton);
game.removeChild(englishButtonText);
showingLanguageMenu = false;
// Return to options screen
showOptionsScreen();
};
// English button click handler
englishButton.down = function (x, y, obj) {
currentLanguage = 'english';
storage.language = 'english';
// Remove language screen elements
game.removeChild(languageTitle);
game.removeChild(spanishButton);
game.removeChild(spanishButtonText);
game.removeChild(englishButton);
game.removeChild(englishButtonText);
showingLanguageMenu = false;
// Return to options screen
showOptionsScreen();
};
}
function showTutorialScreen() {
// Create tutorial background
var tutorialBackground = LK.getAsset('wall', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366,
scaleX: 24,
scaleY: 32,
tint: 0x1A1A1A,
alpha: 0.9
});
game.addChild(tutorialBackground);
// Create tutorial title
var tutorialTitle = new Text2(getText('tutorial'), {
size: 100,
fill: 0xFFD700
});
tutorialTitle.anchor.set(0.5, 0.5);
tutorialTitle.x = 1024;
tutorialTitle.y = 400;
game.addChild(tutorialTitle);
// Create tutorial text - break into multiple lines for better readability
var tutorialText = new Text2(getText('tutorialText'), {
size: 50,
fill: 0xFFFFFF,
wordWrap: true,
wordWrapWidth: 1800
});
tutorialText.anchor.set(0.5, 0.5);
tutorialText.x = 1024;
tutorialText.y = 1000;
game.addChild(tutorialText);
// Create back button
var backButton = LK.getAsset('wall', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1700,
scaleX: 2.5,
scaleY: 1.2,
tint: 0x4CAF50
});
game.addChild(backButton);
// Create back button text
var backButtonText = new Text2(getText('volver'), {
size: 60,
fill: 0xFFFFFF
});
backButtonText.anchor.set(0.5, 0.5);
backButtonText.x = 1024;
backButtonText.y = 1700;
game.addChild(backButtonText);
// Add click handler to back button
backButton.down = function (x, y, obj) {
// Remove tutorial screen elements
game.removeChild(tutorialBackground);
game.removeChild(tutorialTitle);
game.removeChild(tutorialText);
game.removeChild(backButton);
game.removeChild(backButtonText);
// Return to start screen
showStartScreen();
};
}
function showOptionsScreen() {
// Create options title
var optionsTitle = new Text2(getText('opciones'), {
size: 100,
fill: 0xFFFFFF
});
optionsTitle.anchor.set(0.5, 0.5);
optionsTitle.x = 1024;
optionsTitle.y = 600;
game.addChild(optionsTitle);
// Create language button
var languageButton = LK.getAsset('wall', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1000,
scaleX: 4,
scaleY: 1.5,
tint: 0x2196F3
});
game.addChild(languageButton);
var languageButtonText = new Text2(getText('lenguaje'), {
size: 70,
fill: 0xFFFFFF
});
languageButtonText.anchor.set(0.5, 0.5);
languageButtonText.x = 1024;
languageButtonText.y = 1000;
game.addChild(languageButtonText);
// Create niveles button
var nivelesButton = LK.getAsset('wall', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1200,
scaleX: 4,
scaleY: 1.5,
tint: 0xFF9800
});
game.addChild(nivelesButton);
var nivelesButtonText = new Text2(getText('niveles'), {
size: 70,
fill: 0xFFFFFF
});
nivelesButtonText.anchor.set(0.5, 0.5);
nivelesButtonText.x = 1024;
nivelesButtonText.y = 1200;
game.addChild(nivelesButtonText);
// Create back button
var backButton = LK.getAsset('wall', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1500,
scaleX: 2.5,
scaleY: 1.2,
tint: 0x4CAF50
});
game.addChild(backButton);
var backButtonText = new Text2(getText('volver'), {
size: 60,
fill: 0xFFFFFF
});
backButtonText.anchor.set(0.5, 0.5);
backButtonText.x = 1024;
backButtonText.y = 1500;
game.addChild(backButtonText);
// Language button click handler
languageButton.down = function (x, y, obj) {
// Remove options screen elements
game.removeChild(optionsTitle);
game.removeChild(languageButton);
game.removeChild(languageButtonText);
game.removeChild(nivelesButton);
game.removeChild(nivelesButtonText);
game.removeChild(backButton);
game.removeChild(backButtonText);
// Show language selection screen
showLanguageScreen();
};
// Niveles button click handler
nivelesButton.down = function (x, y, obj) {
// Remove options screen elements
game.removeChild(optionsTitle);
game.removeChild(languageButton);
game.removeChild(languageButtonText);
game.removeChild(nivelesButton);
game.removeChild(nivelesButtonText);
game.removeChild(backButton);
game.removeChild(backButtonText);
// Show levels screen
showLevelsScreen();
};
// Back button click handler
backButton.down = function (x, y, obj) {
// Remove options screen elements
game.removeChild(optionsTitle);
game.removeChild(languageButton);
game.removeChild(languageButtonText);
game.removeChild(nivelesButton);
game.removeChild(nivelesButtonText);
game.removeChild(backButton);
game.removeChild(backButtonText);
// Return to start screen
showStartScreen();
};
}
function showLevelsScreen() {
// Create levels title
var levelsTitle = new Text2(getText('niveles'), {
size: 100,
fill: 0xFFFFFF
});
levelsTitle.anchor.set(0.5, 0.5);
levelsTitle.x = 1024;
levelsTitle.y = 600;
game.addChild(levelsTitle);
// Create level1 button
var level1Button = LK.getAsset('level1', {
anchorX: 0.5,
anchorY: 0.5,
x: 512,
y: 900,
scaleX: 3,
scaleY: 3
});
game.addChild(level1Button);
// Create level2 button
var level2Button = LK.getAsset('level2', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 900,
scaleX: 3,
scaleY: 3
});
game.addChild(level2Button);
// Create candado (lock) for level2
var candadoButton = LK.getAsset('candado', {
anchorX: 0.5,
anchorY: 0.5,
x: 1200,
y: 900,
scaleX: 1,
scaleY: 1
});
game.addChild(candadoButton);
// Create tutorial button for level1
var tutorialLevel1Button = LK.getAsset('wall', {
anchorX: 0.5,
anchorY: 0.5,
x: 512,
y: 1100,
scaleX: 2,
scaleY: 1,
tint: 0x4CAF50
});
game.addChild(tutorialLevel1Button);
var tutorialLevel1Text = new Text2(getText('tutorial'), {
size: 40,
fill: 0xFFFFFF
});
tutorialLevel1Text.anchor.set(0.5, 0.5);
tutorialLevel1Text.x = 512;
tutorialLevel1Text.y = 1100;
game.addChild(tutorialLevel1Text);
// Create tutorial button for level2
var tutorialLevel2Button = LK.getAsset('wall', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1100,
scaleX: 2,
scaleY: 1,
tint: 0x757575
});
game.addChild(tutorialLevel2Button);
var tutorialLevel2Text = new Text2(getText('tutorial'), {
size: 40,
fill: 0xFFFFFF
});
tutorialLevel2Text.anchor.set(0.5, 0.5);
tutorialLevel2Text.x = 1024;
tutorialLevel2Text.y = 1100;
game.addChild(tutorialLevel2Text);
// Create back button
var backButton = LK.getAsset('wall', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1400,
scaleX: 2.5,
scaleY: 1.2,
tint: 0x4CAF50
});
game.addChild(backButton);
var backButtonText = new Text2(getText('volver'), {
size: 60,
fill: 0xFFFFFF
});
backButtonText.anchor.set(0.5, 0.5);
backButtonText.x = 1024;
backButtonText.y = 1400;
game.addChild(backButtonText);
// Level1 button click handler
level1Button.down = function (x, y, obj) {
selectedLevel = 1;
// Remove levels screen elements
game.removeChild(levelsTitle);
game.removeChild(level1Button);
game.removeChild(level2Button);
game.removeChild(candadoButton);
game.removeChild(tutorialLevel1Button);
game.removeChild(tutorialLevel1Text);
game.removeChild(tutorialLevel2Button);
game.removeChild(tutorialLevel2Text);
game.removeChild(backButton);
game.removeChild(backButtonText);
// Return to main menu
showStartScreen();
};
// Tutorial Level1 button click handler
tutorialLevel1Button.down = function (x, y, obj) {
showTutorialMessage(getText('tutorialLevel1'));
};
// Tutorial Level2 button click handler
tutorialLevel2Button.down = function (x, y, obj) {
showTutorialMessage(getText('levelBlocked'));
};
// Back button click handler
backButton.down = function (x, y, obj) {
// Remove levels screen elements
game.removeChild(levelsTitle);
game.removeChild(level1Button);
game.removeChild(level2Button);
game.removeChild(candadoButton);
game.removeChild(tutorialLevel1Button);
game.removeChild(tutorialLevel1Text);
game.removeChild(tutorialLevel2Button);
game.removeChild(tutorialLevel2Text);
game.removeChild(backButton);
game.removeChild(backButtonText);
// Return to options screen
showOptionsScreen();
};
}
function showTutorialMessage(message) {
// Create tutorial background
var tutorialBackground = LK.getAsset('wall', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366,
scaleX: 24,
scaleY: 32,
tint: 0x1A1A1A,
alpha: 0.9
});
game.addChild(tutorialBackground);
// Create tutorial text
var tutorialText = new Text2(message, {
size: 50,
fill: 0xFFFFFF,
wordWrap: true,
wordWrapWidth: 1800
});
tutorialText.anchor.set(0.5, 0.5);
tutorialText.x = 1024;
tutorialText.y = 1200;
game.addChild(tutorialText);
// Create close button
var closeButton = LK.getAsset('wall', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1600,
scaleX: 2.5,
scaleY: 1.2,
tint: 0x4CAF50
});
game.addChild(closeButton);
var closeButtonText = new Text2(getText('cerrar'), {
size: 60,
fill: 0xFFFFFF
});
closeButtonText.anchor.set(0.5, 0.5);
closeButtonText.x = 1024;
closeButtonText.y = 1600;
game.addChild(closeButtonText);
// Close button click handler
closeButton.down = function (x, y, obj) {
// Remove tutorial message elements
game.removeChild(tutorialBackground);
game.removeChild(tutorialText);
game.removeChild(closeButton);
game.removeChild(closeButtonText);
};
}
function showNotificationMessage(message) {
// Create notification background
var notificationBackground = LK.getAsset('wall', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366,
scaleX: 20,
scaleY: 8,
tint: 0x1A1A1A,
alpha: 0.9
});
game.addChild(notificationBackground);
// Create notification text
var notificationText = new Text2(message, {
size: 60,
fill: 0xFFFFFF,
wordWrap: true,
wordWrapWidth: 1600
});
notificationText.anchor.set(0.5, 0.5);
notificationText.x = 1024;
notificationText.y = 1300;
game.addChild(notificationText);
// Create close button
var closeButton = LK.getAsset('wall', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1500,
scaleX: 2,
scaleY: 1,
tint: 0x4CAF50
});
game.addChild(closeButton);
var closeButtonText = new Text2('OK', {
size: 50,
fill: 0xFFFFFF
});
closeButtonText.anchor.set(0.5, 0.5);
closeButtonText.x = 1024;
closeButtonText.y = 1500;
game.addChild(closeButtonText);
// Close button click handler
closeButton.down = function (x, y, obj) {
// Remove notification message elements
game.removeChild(notificationBackground);
game.removeChild(notificationText);
game.removeChild(closeButton);
game.removeChild(closeButtonText);
};
}
function initializeGame() {
// Build the maze
for (var y = 0; y < MAZE_HEIGHT; y++) {
for (var x = 0; x < MAZE_WIDTH; x++) {
if (y < mazeData.length && mazeData[y][x] === 1) {
var wall = LK.getAsset('wall', {
anchorX: 0.5,
anchorY: 0.5,
x: x * CELL_SIZE + CELL_SIZE / 2,
y: y * CELL_SIZE + CELL_SIZE / 2 + MAZE_OFFSET_Y
});
game.addChild(wall);
} else if (y < mazeData.length) {
var floor = LK.getAsset('floor', {
anchorX: 0.5,
anchorY: 0.5,
x: x * CELL_SIZE + CELL_SIZE / 2,
y: y * CELL_SIZE + CELL_SIZE / 2 + MAZE_OFFSET_Y
});
game.addChild(floor);
}
}
}
// Create mouse
mouse = new Mouse();
mouse.x = 1.5 * CELL_SIZE;
mouse.y = 1.5 * CELL_SIZE + MAZE_OFFSET_Y;
game.addChild(mouse);
// Create door at the bottom right
door = new Door();
door.x = 18 * CELL_SIZE + CELL_SIZE / 2;
door.y = (MAZE_HEIGHT - 2) * CELL_SIZE + CELL_SIZE / 2 + MAZE_OFFSET_Y;
game.addChild(door);
// Spawn initial pastafrolas
for (var i = 0; i < 20; i++) {
spawnPastafrola();
}
// Spawn 2 panteras in strategic positions
var panteraPositions = [{
x: 5,
y: 5
}, {
x: 15,
y: 8
}];
for (var i = 0; i < panteraPositions.length; i++) {
var pos = panteraPositions[i];
if (isWalkable(pos.x, pos.y)) {
var pantera = new Pantera();
pantera.x = pos.x * CELL_SIZE + CELL_SIZE / 2;
pantera.y = pos.y * CELL_SIZE + CELL_SIZE / 2 + MAZE_OFFSET_Y;
panteras.push(pantera);
game.addChild(pantera);
}
}
// Setup UI - all elements in top area to avoid click interference
pastafrolarText = new Text2(getText('pastafrolas') + ': 0', {
size: 60,
fill: 0xFFFFFF
});
pastafrolarText.anchor.set(0.5, 0);
pastafrolarText.y = 0; // At very top
LK.gui.top.addChild(pastafrolarText);
// Add panteras defeated text below pastafrolas text
panteraText = new Text2(getText('panteras') + ': 0/2', {
size: 50,
fill: 0xFFFFFF
});
panteraText.anchor.set(0.5, 0);
panteraText.y = 70; // Below pastafrola text
LK.gui.top.addChild(panteraText);
instructionText = new Text2(getText('instructionCollect'), {
size: 40,
fill: 0xFFFFFF
});
instructionText.anchor.set(0.5, 0);
instructionText.y = 130; // Below pantera text
LK.gui.top.addChild(instructionText);
notificationText = new Text2('', {
size: 45,
fill: 0xFF4444
});
notificationText.anchor.set(0.5, 1);
notificationText.visible = false;
LK.gui.bottom.addChild(notificationText);
// Initialize game timer
gameStartTime = Date.now();
// Create time remaining display
timeRemainingText = new Text2(getText('timeRemaining') + ': 2:00', {
size: 50,
fill: 0xFFFFFF
});
timeRemainingText.anchor.set(0.5, 0);
timeRemainingText.y = 180; // Below instruction text
LK.gui.top.addChild(timeRemainingText);
// Update UI
updateUI();
}
// Show start screen initially
showStartScreen();
function isWalkable(gridX, gridY) {
if (gridX < 0 || gridX >= MAZE_WIDTH || gridY < 0 || gridY >= MAZE_HEIGHT) {
return false;
}
return mazeData[gridY][gridX] === 0;
}
function hasLineOfSight(x1, y1, x2, y2) {
// Convert world coordinates to grid coordinates more accurately
var gridX1 = Math.floor(x1 / CELL_SIZE);
var gridY1 = Math.floor((y1 - MAZE_OFFSET_Y) / CELL_SIZE);
var gridX2 = Math.floor(x2 / CELL_SIZE);
var gridY2 = Math.floor((y2 - MAZE_OFFSET_Y) / CELL_SIZE);
// Ensure coordinates are within bounds
if (gridX1 < 0 || gridX1 >= MAZE_WIDTH || gridY1 < 0 || gridY1 >= MAZE_HEIGHT || gridX2 < 0 || gridX2 >= MAZE_WIDTH || gridY2 < 0 || gridY2 >= MAZE_HEIGHT) {
return false;
}
// Use Bresenham's line algorithm to check each grid cell between the two points
var dx = Math.abs(gridX2 - gridX1);
var dy = Math.abs(gridY2 - gridY1);
var x = gridX1;
var y = gridY1;
var xInc = gridX1 < gridX2 ? 1 : -1;
var yInc = gridY1 < gridY2 ? 1 : -1;
var error = dx - dy;
// Don't check the starting position (mouse position) as it's always walkable
var stepCount = 0;
while (true) {
// If we reached the target, we have clear line of sight
if (x === gridX2 && y === gridY2) {
break;
}
var error2 = 2 * error;
if (error2 > -dy) {
error -= dy;
x += xInc;
}
if (error2 < dx) {
error += dx;
y += yInc;
}
stepCount++;
// Check if current position is a wall (not walkable), but skip first and last positions
if (stepCount > 0 && (x !== gridX2 || y !== gridY2) && !isWalkable(x, y)) {
return false; // Wall blocks line of sight
}
// Prevent infinite loops
if (stepCount > 50) {
return false;
}
}
return true; // Clear line of sight
}
var barriers = []; // Global array to track barriers
function canAccessArea(gridX, gridY) {
// Define restricted areas that unlock as panteras are defeated
var restrictedAreas = [{
minX: 0,
maxX: 6,
minY: 0,
maxY: 8,
requiredDefeats: 0
},
// Starting area
{
minX: 7,
maxX: 13,
minY: 0,
maxY: 8,
requiredDefeats: 1
},
// Second area
{
minX: 14,
maxX: 19,
minY: 0,
maxY: 8,
requiredDefeats: 2
},
// Third area
{
minX: 0,
maxX: 6,
minY: 9,
maxY: 17,
requiredDefeats: 2
},
// Fourth area
{
minX: 7,
maxX: 13,
minY: 9,
maxY: 17,
requiredDefeats: 3
},
// Fifth area
{
minX: 14,
maxX: 19,
minY: 9,
maxY: 17,
requiredDefeats: 4
},
// Sixth area
{
minX: 0,
maxX: 19,
minY: 18,
maxY: 26,
requiredDefeats: 5
} // Final area
];
for (var i = 0; i < restrictedAreas.length; i++) {
var area = restrictedAreas[i];
if (gridX >= area.minX && gridX <= area.maxX && gridY >= area.minY && gridY <= area.maxY) {
if (panterasDefeated < area.requiredDefeats) {
showNotification(getText('defeatEnemy'));
return false;
}
return true;
}
}
return true; // Default allow access
}
function createBarriers() {
// Create barriers at area boundaries
var barrierPositions = [
// Vertical barrier between areas 1 and 2
{
x: 6,
y: 1
}, {
x: 6,
y: 2
}, {
x: 6,
y: 3
}, {
x: 6,
y: 4
}, {
x: 6,
y: 5
}, {
x: 6,
y: 6
}, {
x: 6,
y: 7
},
// Vertical barrier between areas 2 and 3
{
x: 13,
y: 1
}, {
x: 13,
y: 2
}, {
x: 13,
y: 3
}, {
x: 13,
y: 4
}, {
x: 13,
y: 5
}, {
x: 13,
y: 6
}, {
x: 13,
y: 7
},
// Horizontal barrier between upper and middle sections
{
x: 1,
y: 8
}, {
x: 2,
y: 8
}, {
x: 3,
y: 8
}, {
x: 4,
y: 8
}, {
x: 5,
y: 8
}, {
x: 7,
y: 8
}, {
x: 8,
y: 8
}, {
x: 9,
y: 8
}, {
x: 10,
y: 8
}, {
x: 11,
y: 8
}, {
x: 12,
y: 8
}, {
x: 14,
y: 8
}, {
x: 15,
y: 8
}, {
x: 16,
y: 8
}, {
x: 17,
y: 8
}, {
x: 18,
y: 8
},
// Vertical barriers in middle section
{
x: 6,
y: 10
}, {
x: 6,
y: 11
}, {
x: 6,
y: 13
}, {
x: 6,
y: 14
}, {
x: 6,
y: 15
}, {
x: 6,
y: 16
}, {
x: 13,
y: 10
}, {
x: 13,
y: 11
}, {
x: 13,
y: 13
}, {
x: 13,
y: 14
}, {
x: 13,
y: 15
}, {
x: 13,
y: 16
},
// Horizontal barrier between middle and bottom sections
{
x: 1,
y: 17
}, {
x: 2,
y: 17
}, {
x: 3,
y: 17
}, {
x: 4,
y: 17
}, {
x: 5,
y: 17
}, {
x: 6,
y: 17
}, {
x: 7,
y: 17
}, {
x: 8,
y: 17
}, {
x: 9,
y: 17
}, {
x: 10,
y: 17
}, {
x: 11,
y: 17
}, {
x: 12,
y: 17
}, {
x: 13,
y: 17
}, {
x: 14,
y: 17
}, {
x: 15,
y: 17
}, {
x: 16,
y: 17
}, {
x: 17,
y: 17
}, {
x: 18,
y: 17
}];
for (var i = 0; i < barrierPositions.length; i++) {
var pos = barrierPositions[i];
if (isWalkable(pos.x, pos.y)) {
var barrier = LK.getAsset('barrier', {
anchorX: 0.5,
anchorY: 0.5,
x: pos.x * CELL_SIZE + CELL_SIZE / 2,
y: pos.y * CELL_SIZE + CELL_SIZE / 2 + MAZE_OFFSET_Y,
alpha: 0.7
});
barriers.push(barrier);
game.addChild(barrier);
}
}
}
function updateBarrierVisibility() {
// Hide barriers in unlocked areas
for (var i = 0; i < barriers.length; i++) {
var barrier = barriers[i];
var gridX = Math.floor((barrier.x - CELL_SIZE / 2) / CELL_SIZE);
var gridY = Math.floor((barrier.y - CELL_SIZE / 2 - MAZE_OFFSET_Y) / CELL_SIZE);
// Check if this barrier should be visible based on area access
var shouldShow = !canAccessAreaSilent(gridX, gridY);
barrier.visible = shouldShow;
}
}
function canAccessAreaSilent(gridX, gridY) {
// Same as canAccessArea but without showing notification
var restrictedAreas = [{
minX: 0,
maxX: 6,
minY: 0,
maxY: 8,
requiredDefeats: 0
}, {
minX: 7,
maxX: 13,
minY: 0,
maxY: 8,
requiredDefeats: 1
}, {
minX: 14,
maxX: 19,
minY: 0,
maxY: 8,
requiredDefeats: 2
}, {
minX: 0,
maxX: 6,
minY: 9,
maxY: 17,
requiredDefeats: 2
}, {
minX: 7,
maxX: 13,
minY: 9,
maxY: 17,
requiredDefeats: 3
}, {
minX: 14,
maxX: 19,
minY: 9,
maxY: 17,
requiredDefeats: 4
}, {
minX: 0,
maxX: 19,
minY: 18,
maxY: 26,
requiredDefeats: 5
}];
for (var i = 0; i < restrictedAreas.length; i++) {
var area = restrictedAreas[i];
if (gridX >= area.minX && gridX <= area.maxX && gridY >= area.minY && gridY <= area.maxY) {
return panterasDefeated >= area.requiredDefeats;
}
}
return true;
}
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 (isWalkable(x, y)) {
return {
x: x * CELL_SIZE + CELL_SIZE / 2,
y: y * CELL_SIZE + CELL_SIZE / 2 + MAZE_OFFSET_Y
};
}
attempts++;
}
return {
x: 1.5 * CELL_SIZE,
y: 1.5 * CELL_SIZE + MAZE_OFFSET_Y
}; // Fallback position
}
function getRandomWalkablePositionIncludingRestricted() {
var attempts = 0;
while (attempts < 100) {
var x = Math.floor(Math.random() * MAZE_WIDTH);
var y = Math.floor(Math.random() * MAZE_HEIGHT);
// Allow spawning in any walkable area, including restricted ones
if (isWalkable(x, y)) {
return {
x: x * CELL_SIZE + CELL_SIZE / 2,
y: y * CELL_SIZE + CELL_SIZE / 2 + MAZE_OFFSET_Y
};
}
attempts++;
}
return {
x: 1.5 * CELL_SIZE,
y: 1.5 * CELL_SIZE + MAZE_OFFSET_Y
}; // Fallback position
}
function spawnPastafrola() {
var position = getRandomWalkablePositionIncludingRestricted();
var pastafrola = new Pastafrola();
pastafrola.x = position.x;
pastafrola.y = position.y;
pastafrolas.push(pastafrola);
game.addChild(pastafrola);
}
function resetGameState() {
// Reset game state
gameStarted = false;
pastafrolarCollas = 0;
panterasDefeated = 0;
lastPanterasDefeated = 0;
gameTimer = 120000;
gameStartTime = 0;
// Clear all game objects
if (mouse) {
game.removeChild(mouse);
mouse = null;
}
if (door) {
game.removeChild(door);
door = null;
}
// Clear arrays and remove objects
for (var i = 0; i < pastafrolas.length; i++) {
if (pastafrolas[i].parent) {
game.removeChild(pastafrolas[i]);
}
}
pastafrolas = [];
for (var i = 0; i < panteras.length; i++) {
if (panteras[i].parent) {
game.removeChild(panteras[i]);
}
}
panteras = [];
for (var i = 0; i < barriers.length; i++) {
if (barriers[i].parent) {
game.removeChild(barriers[i]);
}
}
barriers = [];
// Clear UI elements
if (pastafrolarText && pastafrolarText.parent) {
LK.gui.top.removeChild(pastafrolarText);
pastafrolarText = null;
}
if (panteraText && panteraText.parent) {
LK.gui.top.removeChild(panteraText);
panteraText = null;
}
if (instructionText && instructionText.parent) {
LK.gui.top.removeChild(instructionText);
instructionText = null;
}
if (notificationText && notificationText.parent) {
LK.gui.bottom.removeChild(notificationText);
notificationText = null;
}
if (timeRemainingText && timeRemainingText.parent) {
LK.gui.top.removeChild(timeRemainingText);
timeRemainingText = null;
}
// Clear all remaining children from game - create a copy of the array to avoid modification during iteration
var childrenToRemove = [];
for (var i = 0; i < game.children.length; i++) {
childrenToRemove.push(game.children[i]);
}
for (var i = 0; i < childrenToRemove.length; i++) {
if (childrenToRemove[i].parent === game) {
game.removeChild(childrenToRemove[i]);
}
}
}
function showNotification(message) {
if (notificationText) {
notificationText.setText(message);
notificationText.visible = true;
LK.setTimeout(function () {
if (notificationText) {
notificationText.visible = false;
}
}, 2000);
}
}
function updateUI() {
pastafrolarText.setText(getText('pastafrolas') + ': ' + mouse.pastafrolas);
panteraText.setText(getText('panteras') + ': ' + panterasDefeated + '/2');
if (panterasDefeated < 2) {
instructionText.setText(getText('instructionDefeat') + ' (' + panterasDefeated + '/2)');
} else if (mouse.pastafrolas < 10) {
instructionText.setText(getText('instructionNeed10') + ' (' + mouse.pastafrolas + '/10)');
} else {
instructionText.setText(getText('instructionComplete'));
}
}
// Game initialization now handled by start screen
// Game controls
game.down = function (x, y, obj) {
if (gameStarted && mouse) {
mouse.moveTo(x, y);
}
};
// Main game loop
game.update = function () {
if (!gameStarted) return;
// Update timer
var currentTime = Date.now();
var elapsedTime = currentTime - gameStartTime;
var timeLeft = Math.max(0, gameTimer - elapsedTime);
// Update timer display
if (timeRemainingText) {
var secondsLeft = Math.ceil(timeLeft / 1000);
var minutes = Math.floor(secondsLeft / 60);
var seconds = secondsLeft % 60;
var timeStr = minutes + ':' + (seconds < 10 ? '0' : '') + seconds;
timeRemainingText.setText(getText('timeRemaining') + ': ' + timeStr);
// Change color when time is running out
if (timeLeft <= 30000) {
// Last 30 seconds
timeRemainingText.tint = 0xFF4444;
} else if (timeLeft <= 60000) {
// Last minute
timeRemainingText.tint = 0xFFAA00;
} else {
timeRemainingText.tint = 0xFFFFFF;
}
}
// Check if time is up
if (timeLeft <= 0) {
showDefeatScreen();
return;
}
// Check if we just defeated all panteras (transition from not all defeated to all defeated)
if (lastPanterasDefeated < 2 && panterasDefeated >= 2) {
showNotification(getText('allDefeated'));
}
lastPanterasDefeated = panterasDefeated;
// Update mouse
if (mouse) {
mouse.update();
}
// Update pastafrolas
for (var i = 0; i < pastafrolas.length; i++) {
pastafrolas[i].update();
}
// Update panteras
for (var i = 0; i < panteras.length; i++) {
if (!panteras[i].defeated) {
// Simple AI: panteras don't move but can be clicked for combat
}
}
// Update door
if (door) {
door.update();
}
// Barrier visibility removed - no restrictions
// Spawn more pastafrolas if needed and not all collected
if (pastafrolarCollas < 10 && pastafrolas.filter(function (p) {
return !p.collected;
}).length < 15) {
if (Math.random() < 0.05) {
// 5% chance per frame
spawnPastafrola();
}
}
}; ===================================================================
--- original.js
+++ change.js
@@ -154,16 +154,25 @@
anchorY: 0.5
});
self.collected = false;
self.update = function () {
- if (!self.collected && self.intersects(mouse)) {
+ // Initialize lastIntersecting state if not set
+ if (self.lastIntersecting === undefined) {
+ self.lastIntersecting = false;
+ }
+ // Check current intersection state
+ var currentIntersecting = self.intersects(mouse);
+ // Only collect if we just started intersecting (transition from false to true)
+ if (!self.collected && !self.lastIntersecting && currentIntersecting) {
self.collected = true;
mouse.pastafrolas++;
pastafrolarCollas++;
LK.getSound('pastafrolasound').play();
self.visible = false;
updateUI();
}
+ // Update last intersecting state
+ self.lastIntersecting = currentIntersecting;
};
return self;
});
@@ -413,8 +422,22 @@
showStartScreen();
}, 3000);
}
function showStartScreen() {
+ // Set background to FONDOMENU with 20% brightness (tint to make it darker)
+ game.setBackgroundColor(0x000000); // Set to black first
+ var menuBackground = LK.getAsset('FONDOMENU', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 1024,
+ y: 1366,
+ scaleX: 20.48,
+ // Scale to fill width (2048/100)
+ scaleY: 19.54,
+ // Scale to fill height (2732/139.89)
+ alpha: 0.2 // 20% brightness
+ });
+ game.addChild(menuBackground);
// Create start screen title using titulo asset
var titleText = LK.getAsset('titulo', {
anchorX: 0.5,
anchorY: 0.5,
@@ -491,8 +514,10 @@
showNotificationMessage(getText('firstSelectLevel'));
return;
}
gameStarted = true;
+ // Set background to black (0% brightness) when game starts
+ game.setBackgroundColor(0x000000);
// gameStarted flag will stop menumusical sound from looping
// Remove start screen elements
game.removeChild(titleText);
game.removeChild(startButton);
@@ -504,8 +529,11 @@
};
// Add click handler to opciones button
opcionesButton.down = function (x, y, obj) {
// Remove start screen elements
+ if (game.children[0] && game.children[0].texture && game.children[0].texture.textureCacheIds && game.children[0].texture.textureCacheIds.indexOf('FONDOMENU') !== -1) {
+ game.removeChild(game.children[0]); // Remove menuBackground
+ }
game.removeChild(titleText);
game.removeChild(startButton);
game.removeChild(buttonText);
game.removeChild(opcionesButton);