User prompt
ponle cajas de colicion invicibles a cada texto , as que los textos desaparescan luego de 10 segundos ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
arregla lo de a tienda , as que la tienda sea con tiempo , 5 segundos para elegir lo que quieras comprar ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
arregla todos los bugs
User prompt
, no me entendiste , dejalo como estava antes de que te pidiera antes eso de eliminar el texto que estava en la parte superior en medio
User prompt
as que los textos que estan en la parte superior de la pantalla en medio desaparescan
User prompt
aumentale el tamaño a los carteles y ponlos a todos en color berde , mueve la barra de energia a la parte superior derecha , y as que el texto que te indica que tienes que seleccionar un nivel desaparesca al ingresar a uno , y crea un boton berde funcional que diga skip ,o que diga saltar , para saltar la eleccion de mejoras ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
# Sistema de Habilidades y Mejoras del Jugador --- ## 1. Barra de Energía y Habilidad de Velocidad X2 Implementa una **barra de energía azul** en la interfaz de usuario, ubicada directamente debajo del contador de vida del jugador. Esta barra gestiona la habilidad de **velocidad X2**. * El jugador puede activar la velocidad X2 en cualquier momento. Al hacerlo, su velocidad de movimiento se duplica. * Mientras la habilidad está activa, la barra de energía se vacía. * La barra se recarga al recolectar **esferas** que se encuentran en el juego. Cada esfera llena una porción de la barra de energía. --- ## 2. Tienda de Mejoras Permanentes Después de la selección del personaje, muestra una pantalla de tienda con tres opciones de compra. Cada una de estas mejoras es permanente y se adquiere usando las esferas recolectadas. ### Multiplicador de Esferas * Este es un multiplicador que aumenta la cantidad de esferas obtenidas. * Cada vez que compras esta mejora, el valor del multiplicador aumenta de forma incremental. * **Ejemplo:** La primera compra establece un multiplicador de **x2**. La segunda compra aumenta este multiplicador a **x2.2**, y así sucesivamente. ### Multiplicador de Velocidad * Esta mejora aumenta de forma permanente la velocidad base del personaje. * El aumento de velocidad es constante con cada compra, por ejemplo, un incremento del 5% en la velocidad base. * Esta mejora no consume energía de la barra azul, sino que aumenta tu velocidad predeterminada. ### Aumento de Vida * Esta mejora incrementa la vida máxima del personaje. * El jugador comienza con **5 puntos de vida**. * Cada vez que compras esta mejora, tu vida máxima aumenta en **5 puntos adicionales**. Este efecto es acumulativo. ↪💡 Consider importing and using the following plugins: @upit/storage.v1, @upit/tween.v1
User prompt
as que en el nivel 1 al precionar click izquierdo el juego balla mas rapido , un x2 de tiempo , pero que se gasten 1 esfera por segundo que se este utilizando , el click izquierdo se puede dejar precionado , gastando 1 esfera por segundo , y al aser un clik izquierdo una sola ves que te gaste 1 esfera
User prompt
as que al ganar en el nivel 1 te deje entrar en el nivel 2 y asi progresivamente hasta el nivel 10 , y que no se reinicien los niveles , que se queden guardados luego de poder aber alcansado / logrado y o pasado el nivel en el que te encontravas ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
cambia la musica para el nivel 2 y pon la musica llamada musica_de_nivel_2 , saca la musica que esta en el menu y mientras estoy eligiendo el nivel
User prompt
añade que a todos los niveles , lvls se reinicien todas sus esferas luego de 5 intentos , los 5 intentos tendran que ser dentro de cada nivel
User prompt
as que cada nivel este separado de el otro , para no entreverar , y quita eso de la vida y los textos al jugar , solo deja los esensiales segun el nivel en el que estes jugando , en el lvl 1 deja la vida , el contador de esferas y otras cosas esenciales
User prompt
cambia que al tocar una pared te mueras instantaneamente , cambia eso , que solo se muera al tocar el lado izquierdo de la pantalla y la parte inferrior de la pantalla , as que al colicionar con una pared , no te aga nada , solo que coliciones con ella , añade que el personaje aparesca en el medio de la pantalla y
User prompt
añadele que al colicionar con una pared , no pierda , sino que solo se choque / colicione contra las paredes
User prompt
cambia el nivel 2 , intenta aser que el nivel 2 sea como el juego flappy birds , añade sus reglas y caracteristicas
User prompt
intenta realizar lo que te pedi recientemente , lo que no puedas agregar intenta arreglarlo de otra forma , no hay problema
User prompt
al ingresar a cualquier lvl quita la palabra que dice SELECCIONA NIVEL , corrigela y pon que diga SELECCIONA EL NIVEL , pero tienes que aser que desaparesca al ingresar a cualquier lvl
User prompt
que no salte tanto y que la lava se quede abajo , y añade una colicion invicible en el techo para que el personaje no salte mas alla de el techo de el juego
User prompt
as que salte mas alto
User prompt
as que el personaje pueda saltar mas y mas segun los clics que se agan , y que aiga un contador de altura recorrida , y al empesar a saltar que se genere un lago de lava proveniente de el suelo , osea de la parte inferior de la pantalla , y que se balla generando lugares para mantenerse en el aire , como rocas bolantiles con coliciones para que el personaje no se caiga a la lava , y as que al final de la partida la altura que allas alcansado se divida en 10 y que el resultado sean esferas , las cuales seran como las monedas de el lvl 1 , que serviran para comprar los personajes , ect. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
as que al seleccionar un nivel no aparesca la palabra SELECCIONA NIVEL , y crea un juego distinto en el segundo nivel , osea lvl2 , el juego se trata de esquivar los pinchos que saldran de los costados de la pantalla , el jugador tendra que aser clic izquierdo para que el personaje salte , para intentar esquivar los pinchos , as lo mismo que con los personajes de el lvl 1 , pero modificalos para que salten sigiendo el raton de el mause , pero esta ves el personaje se quedara en la pate inferior de la pantalla
User prompt
al ingresar a un nivel se tiene que quitar el texto que dice selecciona nivel y tambien al ingresar a jugar en el juego / nivel1 ,lvl1 tamvien no se vea el texto que indica cuantas esferas tienes acumuladas , y as que las esferas y pinchos de el lvl1 sean el doble de rapidas
User prompt
crea 10 niveles , luego de apretar en el boton de jugar , que aparescan los 10 niveles , los cuales se llamaran lvl1,lvl2,lvl3,lvl4,lvl5,lvl6,lvl7,lvl8,lvl9 y lvl10 , el nivel 1 , osea lvl1 , sera el primer juego osea el nivel en donde se guardara el juego actual , luego creare mas juegos en los distintos niveles , as que cada nivel tenga una imagen segun su modalidad de juego , añadele cajas de colicion a cada nivel para poder ingresar a cada uno ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
quita el jumscare
User prompt
y que a los personajes tambien se reinicien al ganar o despues de las 5 partidas , al igual que las esferas obtenidas a lo largo de las 5 partidas ↪💡 Consider importing and using the following plugins: @upit/storage.v1
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var CorruptedMemory = Container.expand(function () {
var self = Container.call(this);
var memoryGraphics = self.attachAsset('corruptedMemory', {
anchorX: 0.5,
anchorY: 0.5
});
// Add spikes around the corrupted memory
var spike1 = self.attachAsset('spike', {
anchorX: 0.5,
anchorY: 0.5
});
spike1.x = -30;
spike1.y = -30;
spike1.rotation = Math.PI / 4;
var spike2 = self.attachAsset('spike', {
anchorX: 0.5,
anchorY: 0.5
});
spike2.x = 30;
spike2.y = -30;
spike2.rotation = -Math.PI / 4;
var spike3 = self.attachAsset('spike', {
anchorX: 0.5,
anchorY: 0.5
});
spike3.x = 30;
spike3.y = 30;
spike3.rotation = Math.PI / 4;
var spike4 = self.attachAsset('spike', {
anchorX: 0.5,
anchorY: 0.5
});
spike4.x = -30;
spike4.y = 30;
spike4.rotation = -Math.PI / 4;
self.speed = 4;
self.lastY = undefined;
self.update = function () {
self.y += self.speed;
};
return self;
});
var EmotionCharacter = Container.expand(function (emotionType) {
var self = Container.call(this);
var characterGraphics = self.attachAsset(emotionType, {
anchorX: 0.5,
anchorY: 0.5
});
self.emotionType = emotionType;
self.health = 100;
self.maxHealth = 100;
return self;
});
var GoldenMemory = Container.expand(function () {
var self = Container.call(this);
var memoryGraphics = self.attachAsset('goldenMemory', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3;
self.lastY = undefined;
self.update = function () {
self.y += self.speed;
};
return self;
});
var Pipe = Container.expand(function (isTop, gapY) {
var self = Container.call(this);
var pipeGraphics = self.attachAsset('spike', {
anchorX: 0.5,
anchorY: isTop ? 1 : 0
});
pipeGraphics.tint = 0x4CAF50;
pipeGraphics.width = pipeWidth;
pipeGraphics.height = isTop ? gapY - pipeGap / 2 : 2732 - (gapY + pipeGap / 2);
self.speed = 4;
self.isTop = isTop;
self.scored = false;
self.lastX = undefined;
self.update = function () {
self.x -= self.speed;
};
return self;
});
var SideSpike = Container.expand(function (fromLeft) {
var self = Container.call(this);
var spikeGraphics = self.attachAsset('espinas', {
anchorX: 0.5,
anchorY: 0.5
});
self.fromLeft = fromLeft;
self.speed = fromLeft ? 8 : -8;
self.lastX = undefined;
self.update = function () {
self.x += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// All previously requested features have been successfully implemented:
// - Invisible hitboxes for JUGAR button and character selection
// - Jumpscare with 22.2% probability on game over
// - 223-second countdown timer with speed increase
// - Character pricing and storage system
// - Points accumulation (15 per sphere)
// - Win condition at 50000 points
// - Spike damage of 25 after timer expires
// If you need additional features, please specify what you'd like to add
// Character assets - Joy, Anger, Disgust, Fear
// Memory sphere assets
// Sound effects
// - Insufficient spheres error message ('No tienes esferas suficientes')
// - Character reset every 5 attempts except free characters (attemptCount % 5 === 0)
// - Jumpscare probability: 25% (line with Math.random() < 0.25)
// All requested features are already properly implemented:
var selectedEmotion = storage.selectedEmotion || 'joy';
var gameStarted = false;
var countdownActive = false;
var countdownValue = 3;
var character = null;
var goldenMemories = [];
var corruptedMemories = [];
var spawnTimer = 0;
var difficultyLevel = 1;
var health = 100;
var maxHealth = 100;
// Game state management
var gameState = 'menu'; // 'menu', 'levelSelection', 'characterSelection', 'countdown', 'playing'
var currentLevel = storage.currentLevel || 1;
var levelBoxes = [];
var characterSelectionActive = false;
var selectionButtons = [];
// Timer variables
var gameTimer = 223; // 223 seconds
var timerActive = false;
var speedIncreased = false;
// Character pricing and spheres
var totalSpheres = storage.totalSpheres || 0;
var attemptCount = storage.attemptCount || 0;
var characterPrices = {
joy: 0,
// Free
anger: 60,
disgust: 120,
fear: 180,
tristesa: 240
};
var ownedCharacters = storage.ownedCharacters || ['joy']; // Joy is free by default
// Level-specific attempt tracking
var levelAttempts = storage.levelAttempts || {};
// Track which levels are unlocked (level 1 is always unlocked)
var unlockedLevels = storage.unlockedLevels || [1];
// Speed boost variables for level 1
var speedBoostActive = false;
var speedBoostTimer = 0;
var isLeftMouseDown = false;
// Energy system variables
var maxEnergy = 100;
var currentEnergy = storage.currentEnergy || maxEnergy;
var energyBar = null;
var energyBarBg = null;
// Upgrade system variables
var sphereMultiplier = storage.sphereMultiplier || 1;
var speedMultiplier = storage.speedMultiplier || 1;
var maxHealthBonus = storage.maxHealthBonus || 0;
var shopItems = [];
// Shop timer variables
var shopTimer = 5;
var shopTimerActive = false;
var shopTimerText = null;
var shopTimerInterval = null;
// Level 2 specific variables - Flappy Bird style
var sideSpikes = [];
var birdVelocity = 0;
var gravity = 0.8;
var flapStrength = -12;
var pipes = [];
var pipeGap = 400;
var pipeWidth = 100;
var distanceTraveled = 0;
var scoreCounter = 0;
var heightText = new Text2('Distancia: 0m', {
size: 50,
fill: 0xFFFFFF
});
heightText.anchor.set(0, 0);
LK.gui.bottomLeft.addChild(heightText);
heightText.y = 100;
// Add invisible collision box to heightText
var heightTextBox = LK.getAsset('level1', {
anchorX: 0,
anchorY: 0,
scaleX: 1.5,
scaleY: 0.5
});
heightTextBox.alpha = 0;
heightTextBox.x = 0;
heightTextBox.y = 100;
heightTextBox.textElement = heightText;
LK.gui.bottomLeft.addChild(heightTextBox);
// Auto-hide heightText after 10 seconds when visible
var heightTimeout = null;
heightText.showWithTimeout = function () {
if (heightTimeout) LK.clearTimeout(heightTimeout);
heightTimeout = LK.setTimeout(function () {
tween(heightText, {
alpha: 0
}, {
duration: 1000
});
tween(heightTextBox, {
alpha: 0
}, {
duration: 1000
});
}, 10000);
};
// UI Elements
var scoreText = new Text2('Puntos: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
scoreText.alpha = 0; // Hide initially
LK.gui.top.addChild(scoreText);
// Add invisible collision box to scoreText
var scoreTextBox = LK.getAsset('level1', {
anchorX: 0.5,
anchorY: 0,
scaleX: 1.5,
scaleY: 0.6
});
scoreTextBox.alpha = 0;
scoreTextBox.x = 0;
scoreTextBox.y = 0;
scoreTextBox.textElement = scoreText;
LK.gui.top.addChild(scoreTextBox);
// Auto-hide scoreText after 10 seconds when visible
var scoreTimeout = null;
scoreText.showWithTimeout = function () {
if (scoreTimeout) LK.clearTimeout(scoreTimeout);
scoreTimeout = LK.setTimeout(function () {
tween(scoreText, {
alpha: 0
}, {
duration: 1000
});
tween(scoreTextBox, {
alpha: 0
}, {
duration: 1000
});
}, 10000);
};
var healthText = new Text2('Vida: 100/100', {
size: 50,
fill: 0xFF0000
});
healthText.anchor.set(1, 0);
LK.gui.topRight.addChild(healthText);
// Add invisible collision box to healthText
var healthTextBox = LK.getAsset('level1', {
anchorX: 1,
anchorY: 0,
scaleX: 1.2,
scaleY: 0.5
});
healthTextBox.alpha = 0;
healthTextBox.x = 0;
healthTextBox.y = 0;
healthTextBox.textElement = healthText;
LK.gui.topRight.addChild(healthTextBox);
// Auto-hide healthText after 10 seconds when visible
var healthTimeout = null;
healthText.showWithTimeout = function () {
if (healthTimeout) LK.clearTimeout(healthTimeout);
healthTimeout = LK.setTimeout(function () {
tween(healthText, {
alpha: 0
}, {
duration: 1000
});
tween(healthTextBox, {
alpha: 0
}, {
duration: 1000
});
}, 10000);
};
// Timer display
var timerText = new Text2('Tiempo: 223', {
size: 50,
fill: 0xFFFFFF
});
timerText.anchor.set(0, 1);
LK.gui.bottomLeft.addChild(timerText);
// Add invisible collision box to timerText
var timerTextBox = LK.getAsset('level1', {
anchorX: 0,
anchorY: 1,
scaleX: 1.2,
scaleY: 0.5
});
timerTextBox.alpha = 0;
timerTextBox.x = 0;
timerTextBox.y = 0;
timerTextBox.textElement = timerText;
LK.gui.bottomLeft.addChild(timerTextBox);
// Auto-hide timerText after 10 seconds when visible
var timerTimeout = null;
timerText.showWithTimeout = function () {
if (timerTimeout) LK.clearTimeout(timerTimeout);
timerTimeout = LK.setTimeout(function () {
tween(timerText, {
alpha: 0
}, {
duration: 1000
});
tween(timerTextBox, {
alpha: 0
}, {
duration: 1000
});
}, 10000);
};
// Energy bar background (dark blue)
energyBarBg = LK.getAsset('spike', {
anchorX: 1,
anchorY: 0,
scaleX: 8,
scaleY: 1
});
energyBarBg.tint = 0x000080;
energyBarBg.x = -20;
energyBarBg.y = 120;
LK.gui.topRight.addChild(energyBarBg);
// Energy bar (blue)
energyBar = LK.getAsset('spike', {
anchorX: 1,
anchorY: 0,
scaleX: 8,
scaleY: 1
});
energyBar.tint = 0x0099ff;
energyBar.x = -20;
energyBar.y = 120;
LK.gui.topRight.addChild(energyBar);
// Energy text
var energyText = new Text2('Energía', {
size: 30,
fill: 0xFFFFFF
});
energyText.anchor.set(1, 0);
energyText.x = -20;
energyText.y = 80;
LK.gui.topRight.addChild(energyText);
// Add invisible collision box to energyText
var energyTextBox = LK.getAsset('level1', {
anchorX: 1,
anchorY: 0,
scaleX: 0.8,
scaleY: 0.3
});
energyTextBox.alpha = 0;
energyTextBox.x = -20;
energyTextBox.y = 80;
energyTextBox.textElement = energyText;
LK.gui.topRight.addChild(energyTextBox);
// Auto-hide energyText after 10 seconds when visible
var energyTimeout = null;
energyText.showWithTimeout = function () {
if (energyTimeout) LK.clearTimeout(energyTimeout);
energyTimeout = LK.setTimeout(function () {
tween(energyText, {
alpha: 0
}, {
duration: 1000
});
tween(energyTextBox, {
alpha: 0
}, {
duration: 1000
});
}, 10000);
};
// Main Menu UI
var titleText = new Text2('INTENSAMENTE', {
size: 120,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 800;
game.addChild(titleText);
// Add invisible collision box to titleText
var titleTextBox = LK.getAsset('level1', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.8
});
titleTextBox.alpha = 0;
titleTextBox.x = titleText.x;
titleTextBox.y = titleText.y;
titleTextBox.textElement = titleText;
game.addChild(titleTextBox);
// Auto-hide titleText after 10 seconds
LK.setTimeout(function () {
tween(titleText, {
alpha: 0
}, {
duration: 1000
});
tween(titleTextBox, {
alpha: 0
}, {
duration: 1000
});
}, 10000);
var playButton = new Text2('JUGAR', {
size: 80,
fill: 0x00FF00
});
playButton.anchor.set(0.5, 0.5);
playButton.x = 1024;
playButton.y = 1200;
game.addChild(playButton);
// Add invisible collision box to playButton
var playButtonBox = LK.getAsset('level1', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 0.8
});
playButtonBox.alpha = 0;
playButtonBox.x = playButton.x;
playButtonBox.y = playButton.y;
playButtonBox.textElement = playButton;
game.addChild(playButtonBox);
// Auto-hide playButton after 10 seconds
LK.setTimeout(function () {
tween(playButton, {
alpha: 0
}, {
duration: 1000
});
tween(playButtonBox, {
alpha: 0
}, {
duration: 1000
});
}, 10000);
var instructionText = new Text2('Selecciona tu personaje', {
size: 80,
fill: 0xFFFFFF
});
instructionText.anchor.set(0.5, 0.5);
instructionText.x = 1024;
instructionText.y = 600;
instructionText.alpha = 0;
instructionText.visible = false;
game.addChild(instructionText);
// Add invisible collision box to instructionText
var instructionTextBox = LK.getAsset('level1', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.5,
scaleY: 0.8
});
instructionTextBox.alpha = 0;
instructionTextBox.x = instructionText.x;
instructionTextBox.y = instructionText.y;
instructionTextBox.textElement = instructionText;
game.addChild(instructionTextBox);
// Auto-hide instructionText after 10 seconds when visible
var instructionTimeout = null;
var originalInstructionAlpha = instructionText.alpha;
instructionText.showWithTimeout = function () {
instructionText.alpha = 1;
instructionText.visible = true;
if (instructionTimeout) LK.clearTimeout(instructionTimeout);
instructionTimeout = LK.setTimeout(function () {
tween(instructionText, {
alpha: 0
}, {
duration: 1000
});
tween(instructionTextBox, {
alpha: 0
}, {
duration: 1000
});
}, 10000);
};
var countdownText = new Text2('3', {
size: 200,
fill: 0xFFFFFF
});
countdownText.anchor.set(0.5, 0.5);
countdownText.x = 1024;
countdownText.y = 1366;
countdownText.alpha = 0;
countdownText.visible = false;
game.addChild(countdownText);
// Add invisible collision box to countdownText
var countdownTextBox = LK.getAsset('level1', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.2
});
countdownTextBox.alpha = 0;
countdownTextBox.x = countdownText.x;
countdownTextBox.y = countdownText.y;
countdownTextBox.textElement = countdownText;
game.addChild(countdownTextBox);
// Auto-hide countdownText after 10 seconds when visible
var countdownTimeout = null;
countdownText.showWithTimeout = function () {
countdownText.alpha = 1;
countdownText.visible = true;
if (countdownTimeout) LK.clearTimeout(countdownTimeout);
countdownTimeout = LK.setTimeout(function () {
tween(countdownText, {
alpha: 0
}, {
duration: 1000
});
tween(countdownTextBox, {
alpha: 0
}, {
duration: 1000
});
}, 10000);
};
// Spawn static character selection spheres in center
function spawnCharacterSelectionSpheres() {
// Only spawn once
if (goldenMemories.length === 0) {
var emotions = [{
type: 'joy',
name: 'ALEGRÍA',
color: 0xffeb3b,
x: 524,
y: 800
}, {
type: 'anger',
name: 'ENOJO',
color: 0xf44336,
x: 1524,
y: 800
}, {
type: 'disgust',
name: 'DESAGRADO',
color: 0x4caf50,
x: 524,
y: 1200
}, {
type: 'fear',
name: 'MIEDO',
color: 0x9c27b0,
x: 1024,
y: 1200
}, {
type: 'tristesa',
name: 'TRISTEZA',
color: 0x2196f3,
x: 1524,
y: 1200
}];
// Hide score text in character selection
scoreText.alpha = 0;
// Add spheres counter display only if not lvl1
if (currentLevel !== 1) {
var spheresText = new Text2('Esferas: ' + totalSpheres, {
size: 60,
fill: 0xFFD700
});
spheresText.anchor.set(0.5, 0.5);
spheresText.x = 1024;
spheresText.y = 500;
game.addChild(spheresText);
}
for (var i = 0; i < emotions.length; i++) {
var emotionData = emotions[i];
// Create character image instead of sphere
var characterImage = LK.getAsset(emotionData.type, {
anchorX: 0.5,
anchorY: 0.5
});
characterImage.x = emotionData.x;
characterImage.y = emotionData.y;
characterImage.characterType = emotionData.type;
game.addChild(characterImage);
goldenMemories.push(characterImage);
// Check if character is owned or affordable
var isOwned = ownedCharacters.indexOf(emotionData.type) !== -1;
var canAfford = totalSpheres >= characterPrices[emotionData.type];
var price = characterPrices[emotionData.type];
// Dim character if not owned and can't afford
if (!isOwned && !canAfford) {
characterImage.alpha = 0.3;
}
// Add text label with price
var labelText = emotionData.name;
if (!isOwned) {
labelText += '\nPrecio: ' + price + ' esferas';
} else {
labelText += '\nDISPONIBLE';
}
var nameText = new Text2(labelText, {
size: 35,
fill: isOwned ? 0x00FF00 : canAfford ? 0xFFFFFF : 0xFF6666
});
nameText.anchor.set(0.5, 0.5);
nameText.x = emotionData.x;
nameText.y = emotionData.y + 150;
game.addChild(nameText);
characterImage.nameText = nameText;
characterImage.isOwned = isOwned;
characterImage.canAfford = canAfford;
}
}
}
// Handle sphere selection for character choice
function handleSphereSelection(sphere) {
if (sphere.characterType) {
var characterType = sphere.characterType;
var isOwned = ownedCharacters.indexOf(characterType) !== -1;
var canAfford = totalSpheres >= characterPrices[characterType];
var price = characterPrices[characterType];
// Check if character can be selected
if (!isOwned && !canAfford) {
// Flash red to indicate can't select
LK.effects.flashObject(sphere, 0xFF0000, 500);
// Play error sound
LK.getSound('error').play();
// Show insufficient spheres message
var errorText = new Text2('No tienes esferas suficientes', {
size: 60,
fill: 0xFF0000
});
errorText.anchor.set(0.5, 0.5);
errorText.x = 1024;
errorText.y = 2200;
game.addChild(errorText);
// Remove error message after 2 seconds
LK.setTimeout(function () {
errorText.destroy();
}, 2000);
return;
}
// If not owned but can afford, purchase the character
if (!isOwned && canAfford) {
totalSpheres -= price;
ownedCharacters.push(characterType);
storage.totalSpheres = totalSpheres;
storage.ownedCharacters = ownedCharacters;
// Update spheres display after purchase
var spheresTextElements = [];
for (var k = 0; k < game.children.length; k++) {
if (game.children[k].text && game.children[k].text.indexOf('Esferas:') === 0) {
game.children[k].setText('Esferas: ' + totalSpheres);
break;
}
}
} else if (isOwned) {
// Character is already owned, no need to purchase again
} else {
// Character not owned and can't afford - deduct price anyway and add to owned
totalSpheres -= price;
if (totalSpheres < 0) totalSpheres = 0; // Prevent negative spheres
ownedCharacters.push(characterType);
storage.totalSpheres = totalSpheres;
storage.ownedCharacters = ownedCharacters;
// Update spheres display after purchase
for (var k = 0; k < game.children.length; k++) {
if (game.children[k].text && game.children[k].text.indexOf('Esferas:') === 0) {
game.children[k].setText('Esferas: ' + totalSpheres);
break;
}
}
}
selectedEmotion = characterType;
storage.selectedEmotion = selectedEmotion;
// Flash selected sphere
LK.effects.flashObject(sphere, 0xFFFFFF, 500);
// Clear all spheres and their labels
for (var i = goldenMemories.length - 1; i >= 0; i--) {
if (goldenMemories[i].nameText) {
goldenMemories[i].nameText.destroy();
}
goldenMemories[i].destroy();
goldenMemories.splice(i, 1);
}
// Hide instruction text
instructionText.alpha = 0;
instructionText.visible = false;
// Go to shop before starting game
LK.setTimeout(function () {
createShop();
}, 600);
}
}
// Create level selection UI
function createLevelSelection() {
gameState = 'levelSelection';
// Hide menu elements
titleText.alpha = 0;
playButton.alpha = 0;
// Show level selection title
var levelTitle = new Text2('SELECCIONA EL NIVEL', {
size: 80,
fill: 0xFFFFFF
});
levelTitle.anchor.set(0.5, 0.5);
levelTitle.x = 1024;
levelTitle.y = 400;
game.addChild(levelTitle);
// Create level boxes in a grid (2 columns, 5 rows)
var levelNames = ['lvl1', 'lvl2', 'lvl3', 'lvl4', 'lvl5', 'lvl6', 'lvl7', 'lvl8', 'lvl9', 'lvl10'];
var levelAssets = ['level1', 'level2', 'level3', 'level4', 'level5', 'level6', 'level7', 'level8', 'level9', 'level10'];
for (var i = 0; i < 10; i++) {
var col = i % 2;
var row = Math.floor(i / 2);
var levelBox = LK.getAsset(levelAssets[i], {
anchorX: 0.5,
anchorY: 0.5
});
levelBox.x = 600 + col * 848; // 600 and 1448 for two columns
levelBox.y = 700 + row * 280; // Spacing between rows
levelBox.levelNumber = i + 1;
levelBox.levelName = levelNames[i];
game.addChild(levelBox);
levelBoxes.push(levelBox);
// Check if level is unlocked
var isUnlocked = unlockedLevels.indexOf(i + 1) !== -1;
// Dim locked levels
if (!isUnlocked) {
levelBox.alpha = 0.3;
}
// Add level text with lock status
var levelText = new Text2(levelNames[i].toUpperCase() + (isUnlocked ? '' : '\nBLOQUEADO'), {
size: isUnlocked ? 50 : 40,
fill: isUnlocked ? 0xFFFFFF : 0xFF6666
});
levelText.anchor.set(0.5, 0.5);
levelText.x = levelBox.x;
levelText.y = levelBox.y;
game.addChild(levelText);
levelBox.levelText = levelText;
levelBox.isUnlocked = isUnlocked;
}
}
// Create shop screen
function createShop() {
gameState = 'shop';
// Hide other UI elements
titleText.alpha = 0;
playButton.alpha = 0;
instructionText.alpha = 0;
// Shop title
var shopTitle = new Text2('TIENDA DE MEJORAS', {
size: 80,
fill: 0xFFD700
});
shopTitle.anchor.set(0.5, 0.5);
shopTitle.x = 1024;
shopTitle.y = 400;
game.addChild(shopTitle);
// Show current spheres
var spheresDisplay = new Text2('Esferas: ' + totalSpheres, {
size: 60,
fill: 0xFFFFFF
});
spheresDisplay.anchor.set(0.5, 0.5);
spheresDisplay.x = 1024;
spheresDisplay.y = 500;
game.addChild(spheresDisplay);
// Create shop items
var shopItemsData = [{
name: 'Multiplicador\nde Esferas',
description: 'x' + (sphereMultiplier + 0.2).toFixed(1),
price: Math.floor(50 * Math.pow(sphereMultiplier, 2)),
type: 'sphere_multiplier',
x: 524,
y: 800
}, {
name: 'Multiplicador\nde Velocidad',
description: '+5% Velocidad',
price: Math.floor(30 * Math.pow(speedMultiplier, 1.5)),
type: 'speed_multiplier',
x: 1024,
y: 800
}, {
name: 'Aumento\nde Vida',
description: '+5 Vida Max',
price: Math.floor(40 * Math.pow(maxHealthBonus / 5 + 1, 1.2)),
type: 'health_bonus',
x: 1524,
y: 800
}];
for (var i = 0; i < shopItemsData.length; i++) {
var itemData = shopItemsData[i];
// Create item box
var itemBox = LK.getAsset('level1', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2
});
itemBox.x = itemData.x;
itemBox.y = itemData.y;
itemBox.itemType = itemData.type;
itemBox.price = itemData.price;
itemBox.tint = 0x00FF00;
game.addChild(itemBox);
shopItems.push(itemBox);
// Item name
var nameText = new Text2(itemData.name, {
size: 35,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0.5);
nameText.x = itemData.x;
nameText.y = itemData.y - 40;
game.addChild(nameText);
itemBox.nameText = nameText;
// Item description
var descText = new Text2(itemData.description, {
size: 30,
fill: 0xFFD700
});
descText.anchor.set(0.5, 0.5);
descText.x = itemData.x;
descText.y = itemData.y;
game.addChild(descText);
itemBox.descText = descText;
// Item price
var priceText = new Text2('Precio: ' + itemData.price, {
size: 30,
fill: totalSpheres >= itemData.price ? 0x00FF00 : 0xFF0000
});
priceText.anchor.set(0.5, 0.5);
priceText.x = itemData.x;
priceText.y = itemData.y + 40;
game.addChild(priceText);
itemBox.priceText = priceText;
}
// Continue button
var continueBtn = new Text2('CONTINUAR', {
size: 60,
fill: 0x00FF00
});
continueBtn.anchor.set(0.5, 0.5);
continueBtn.x = 1024;
continueBtn.y = 1200;
game.addChild(continueBtn);
shopItems.push(continueBtn);
continueBtn.isContinueBtn = true;
// Skip button
var skipBtn = new Text2('SALTAR', {
size: 60,
fill: 0x00FF00
});
skipBtn.anchor.set(0.5, 0.5);
skipBtn.x = 1024;
skipBtn.y = 1300;
game.addChild(skipBtn);
shopItems.push(skipBtn);
skipBtn.isSkipBtn = true;
// Shop timer display
shopTimerText = new Text2('Tiempo: 5', {
size: 60,
fill: 0xFF0000
});
shopTimerText.anchor.set(0.5, 0.5);
shopTimerText.x = 1024;
shopTimerText.y = 1000;
game.addChild(shopTimerText);
shopItems.push(shopTimerText);
// Start shop timer
shopTimer = 5;
shopTimerActive = true;
shopTimerInterval = LK.setInterval(function () {
shopTimer--;
shopTimerText.setText('Tiempo: ' + shopTimer);
if (shopTimer <= 0) {
LK.clearInterval(shopTimerInterval);
shopTimerActive = false;
// Auto-proceed when timer expires
// Clear shop UI
for (var j = shopItems.length - 1; j >= 0; j--) {
if (shopItems[j].nameText) shopItems[j].nameText.destroy();
if (shopItems[j].descText) shopItems[j].descText.destroy();
if (shopItems[j].priceText) shopItems[j].priceText.destroy();
shopItems[j].destroy();
}
shopItems = [];
// Clear shop title and spheres display
for (var k = game.children.length - 1; k >= 0; k--) {
if (game.children[k].text && (game.children[k].text.indexOf('TIENDA') === 0 || game.children[k].text.indexOf('Esferas:') === 0)) {
game.children[k].destroy();
}
}
// Go to countdown
startCountdown();
}
}, 1000);
}
// Start character selection
function startCharacterSelection() {
gameState = 'characterSelection';
// Hide menu elements
titleText.alpha = 0;
playButton.alpha = 0;
// Show instruction text with timeout
instructionText.showWithTimeout();
// Spawn character selection spheres
spawnCharacterSelectionSpheres();
}
// Start countdown before game
function startCountdown() {
gameState = 'countdown';
countdownActive = true;
countdownValue = 3;
countdownText.showWithTimeout();
countdownText.setText('3');
var countdownInterval = LK.setInterval(function () {
countdownValue--;
if (countdownValue > 0) {
countdownText.setText(countdownValue.toString());
} else if (countdownValue === 0) {
countdownText.setText('¡Juega!');
} else {
LK.clearInterval(countdownInterval);
countdownText.alpha = 0;
countdownText.visible = false;
startActualGame();
}
}, 1000);
}
// Start the actual game
function startActualGame() {
gameState = 'playing';
countdownActive = false;
gameStarted = true;
// Initialize timer
gameTimer = 223;
timerActive = true;
speedIncreased = false;
// Show/hide UI elements based on level
if (currentLevel === 1) {
// Level 1: Show health, score, timer, energy
scoreText.alpha = 1;
scoreText.showWithTimeout();
healthText.alpha = 1;
healthText.showWithTimeout();
timerText.alpha = 1;
timerText.showWithTimeout();
heightText.alpha = 0;
energyBar.alpha = 1;
energyBarBg.alpha = 1;
energyText.alpha = 1;
energyText.showWithTimeout();
} else if (currentLevel === 2) {
// Level 2: Show only distance and score
scoreText.alpha = 1;
scoreText.showWithTimeout();
healthText.alpha = 0;
timerText.alpha = 0;
heightText.alpha = 1;
heightText.showWithTimeout();
energyBar.alpha = 0;
energyBarBg.alpha = 0;
energyText.alpha = 0;
} else {
// Other levels: Show score only
scoreText.alpha = 1;
scoreText.showWithTimeout();
healthText.alpha = 0;
timerText.alpha = 0;
heightText.alpha = 0;
energyBar.alpha = 1;
energyBarBg.alpha = 1;
energyText.alpha = 1;
energyText.showWithTimeout();
}
// Create player character
character = new EmotionCharacter(selectedEmotion);
if (currentLevel === 2) {
// Spawn in middle of screen for Flappy Bird level
character.x = 1024;
character.y = 1366; // Middle of screen vertically
// Reset level 2 specific variables
birdVelocity = 0;
distanceTraveled = 0;
scoreCounter = 0;
// Clear any existing pipes
for (var p = pipes.length - 1; p >= 0; p--) {
pipes[p].destroy();
}
pipes = [];
} else {
character.x = 1024;
character.y = 2400;
// Reset level 1 specific variables with upgrades
health = 100 + maxHealthBonus;
maxHealth = 100 + maxHealthBonus;
healthText.setText('Vida: ' + health + '/' + maxHealth);
// Clear any existing memories
for (var g = goldenMemories.length - 1; g >= 0; g--) {
goldenMemories[g].destroy();
}
goldenMemories = [];
for (var c = corruptedMemories.length - 1; c >= 0; c--) {
corruptedMemories[c].destroy();
}
corruptedMemories = [];
}
game.addChild(character);
// Start level-specific background music
if (currentLevel === 2) {
LK.playMusic('musica_de_nivel_2');
} else {
LK.playMusic('gameMusic');
}
}
// Spawn memory function
function spawnMemory() {
if (gameState === 'characterSelection') {
// Character selection phase - spawn static character spheres in center
spawnCharacterSelectionSpheres();
} else if (gameState === 'playing') {
// Game phase - spawn colored spheres and corrupted ones
var spawnX = Math.random() * (2048 - 160) + 80;
var randomType = Math.random();
// Define sphere colors for optimization
var sphereColors = [0xffeb3b, 0x4caf50, 0x2196f3, 0xf44336];
var colorThresholds = [0.15, 0.3, 0.45, 0.6];
// Calculate time-based spine multiplier - more spines as time progresses
var initialTimer = 223;
var timeElapsed = initialTimer - gameTimer;
var timeProgressRatio = Math.min(timeElapsed / initialTimer, 1); // 0 to 1 progression
// Base spine spawn probability increases with time (starts at 0.33, goes up to 0.85)
var baseSpineProbability = 0.33 + timeProgressRatio * 0.52;
// Check for golden memory creation - probability decreases over time to allow for more spines
var goldenProbability = 0.67 * (1 - timeProgressRatio * 0.6); // Decreases from 0.67 to ~0.27
var createGolden = false;
var tintColor = 0xffeb3b;
for (var i = 0; i < colorThresholds.length; i++) {
if (randomType < colorThresholds[i] * goldenProbability) {
createGolden = true;
tintColor = sphereColors[i];
break;
}
}
if (createGolden) {
var memory = new GoldenMemory();
memory.x = spawnX;
memory.y = -100;
memory.lastY = memory.y;
memory.children[0].tint = tintColor;
goldenMemories.push(memory);
game.addChild(memory);
} else {
// Corrupted memory with spikes - spawn rate increases dramatically over time
var corrupted = new CorruptedMemory();
corrupted.x = spawnX;
corrupted.y = -100;
corrupted.lastY = corrupted.y;
corruptedMemories.push(corrupted);
game.addChild(corrupted);
}
}
}
// Game event handlers
game.down = function (x, y, obj) {
if (gameState === 'menu') {
// Check if JUGAR button was clicked with invisible hitbox
var playButtonX = playButton.x - playButton.width / 2;
var playButtonY = playButton.y - playButton.height / 2;
var playButtonWidth = playButton.width;
var playButtonHeight = playButton.height;
if (x >= playButtonX && x <= playButtonX + playButtonWidth && y >= playButtonY && y <= playButtonY + playButtonHeight) {
createLevelSelection();
}
} else if (gameState === 'levelSelection') {
// Check if any level box was clicked
for (var i = 0; i < levelBoxes.length; i++) {
var levelBox = levelBoxes[i];
var boxX = levelBox.x - 150; // Half of width (300/2)
var boxY = levelBox.y - 100; // Half of height (200/2)
var boxWidth = 300;
var boxHeight = 200;
if (x >= boxX && x <= boxX + boxWidth && y >= boxY && y <= boxY + boxHeight) {
// Check if level is unlocked
if (!levelBox.isUnlocked) {
// Flash red to indicate locked
LK.effects.flashObject(levelBox, 0xFF0000, 500);
LK.getSound('error').play();
return;
}
// Flash selected level
LK.effects.flashObject(levelBox, 0xFFFFFF, 500);
// Set current level
currentLevel = levelBox.levelNumber;
storage.currentLevel = currentLevel;
// Clear level selection UI
for (var j = levelBoxes.length - 1; j >= 0; j--) {
if (levelBoxes[j].levelText) {
levelBoxes[j].levelText.destroy();
}
levelBoxes[j].destroy();
}
levelBoxes = [];
// Remove level title immediately
for (var k = game.children.length - 1; k >= 0; k--) {
if (game.children[k].text && game.children[k].text === 'SELECCIONA EL NIVEL') {
game.children[k].destroy();
break;
}
}
// Start character selection after short delay
LK.setTimeout(function () {
startCharacterSelection();
}, 600);
break;
}
}
} else if (gameState === 'shop') {
// Handle shop item clicks
for (var i = 0; i < shopItems.length; i++) {
var item = shopItems[i];
var itemX = item.x - 150;
var itemY = item.y - 100;
var itemWidth = 300;
var itemHeight = 200;
if (x >= itemX && x <= itemX + itemWidth && y >= itemY && y <= itemY + itemHeight) {
if (item.isContinueBtn || item.isSkipBtn) {
// Clear shop timer
if (shopTimerInterval) {
LK.clearInterval(shopTimerInterval);
shopTimerActive = false;
}
// Clear shop UI
for (var j = shopItems.length - 1; j >= 0; j--) {
if (shopItems[j].nameText) shopItems[j].nameText.destroy();
if (shopItems[j].descText) shopItems[j].descText.destroy();
if (shopItems[j].priceText) shopItems[j].priceText.destroy();
shopItems[j].destroy();
}
shopItems = [];
// Clear shop title and spheres display
for (var k = game.children.length - 1; k >= 0; k--) {
if (game.children[k].text && (game.children[k].text.indexOf('TIENDA') === 0 || game.children[k].text.indexOf('Esferas:') === 0)) {
game.children[k].destroy();
}
}
if (item.isSkipBtn) {
// Skip shop, go directly to countdown
startCountdown();
} else {
startCharacterSelection();
}
break;
} else if (totalSpheres >= item.price) {
// Purchase item
totalSpheres -= item.price;
storage.totalSpheres = totalSpheres;
if (item.itemType === 'sphere_multiplier') {
sphereMultiplier += 0.2;
storage.sphereMultiplier = sphereMultiplier;
} else if (item.itemType === 'speed_multiplier') {
speedMultiplier += 0.05;
storage.speedMultiplier = speedMultiplier;
} else if (item.itemType === 'health_bonus') {
maxHealthBonus += 5;
storage.maxHealthBonus = maxHealthBonus;
}
LK.effects.flashObject(item, 0x00FF00, 300);
LK.getSound('collect').play();
// Clear shop timer before recreating
if (shopTimerInterval) {
LK.clearInterval(shopTimerInterval);
shopTimerActive = false;
}
// Recreate shop to update prices
for (var j = shopItems.length - 1; j >= 0; j--) {
if (shopItems[j].nameText) shopItems[j].nameText.destroy();
if (shopItems[j].descText) shopItems[j].descText.destroy();
if (shopItems[j].priceText) shopItems[j].priceText.destroy();
shopItems[j].destroy();
}
shopItems = [];
for (var k = game.children.length - 1; k >= 0; k--) {
if (game.children[k].text && (game.children[k].text.indexOf('TIENDA') === 0 || game.children[k].text.indexOf('Esferas:') === 0)) {
game.children[k].destroy();
}
}
createShop();
break;
} else {
LK.effects.flashObject(item, 0xFF0000, 300);
LK.getSound('error').play();
}
}
}
} else if (gameState === 'characterSelection') {
// Check if any character sphere was clicked with invisible hitboxes
for (var i = 0; i < goldenMemories.length; i++) {
var sphere = goldenMemories[i];
var sphereX = sphere.x - 60; // Sphere width is 120, so half is 60
var sphereY = sphere.y - 60; // Sphere height is 120, so half is 60
var sphereWidth = 120;
var sphereHeight = 120;
if (x >= sphereX && x <= sphereX + sphereWidth && y >= sphereY && y <= sphereY + sphereHeight) {
handleSphereSelection(sphere);
break;
}
}
} else if (gameState === 'playing' && currentLevel === 2) {
// Handle flapping in lvl2 - Flappy Bird style
if (character) {
birdVelocity = flapStrength;
}
} else if (gameState === 'playing' && currentLevel === 1) {
// Handle speed boost for level 1
isLeftMouseDown = true;
// Activate speed boost if player has energy
if (currentEnergy > 0 && !speedBoostActive) {
speedBoostActive = true;
speedBoostTimer = 0;
// Flash screen to indicate speed boost activation
LK.effects.flashScreen(0x00FF00, 200);
}
}
};
game.up = function (x, y, obj) {
if (gameState === 'playing' && currentLevel === 1) {
// Stop speed boost when left click is released
isLeftMouseDown = false;
if (speedBoostActive) {
speedBoostActive = false;
speedBoostTimer = 0;
// Flash screen to indicate speed boost deactivation
LK.effects.flashScreen(0xFF0000, 200);
}
}
};
game.move = function (x, y, obj) {
if (gameStarted && character) {
if (currentLevel === 2) {
// In lvl2, character stays in middle horizontal position for Flappy Bird
character.x = 1024;
// Y position is handled by gravity and flapping in update
} else {
// Original behavior for lvl1
var targetX = Math.max(60, Math.min(1988, x));
var targetY = Math.max(60, Math.min(2672, y));
character.x = targetX;
character.y = targetY;
}
}
};
// Start spawning spheres for character selection
// Main game update loop
game.update = function () {
// Handle different game states
if (gameState === 'menu') {
// Stop any playing music in menu
LK.stopMusic();
return; // No updates needed in menu
}
if (gameState === 'levelSelection') {
// Static level boxes, no updates needed
return;
}
if (gameState === 'characterSelection') {
// Static spheres, no updates needed
return;
}
if (gameState === 'countdown') {
return; // Countdown handles itself
}
if (gameState !== 'playing') {
return;
}
// Handle energy system for level 1
if (currentLevel === 1) {
if (speedBoostActive && isLeftMouseDown && currentEnergy > 0) {
// Consume energy while speed boost is active
currentEnergy -= 2; // 2 energy per frame
if (currentEnergy <= 0) {
currentEnergy = 0;
speedBoostActive = false;
isLeftMouseDown = false;
LK.effects.flashScreen(0xFF0000, 200);
}
} else if (!speedBoostActive || !isLeftMouseDown) {
speedBoostActive = false;
}
// Update energy bar visual
var energyPercent = currentEnergy / maxEnergy;
energyBar.scaleX = 8 * energyPercent;
// Keep energy bar anchored to the right
energyBar.x = -20;
storage.currentEnergy = currentEnergy;
}
// Update timer
if (timerActive && LK.ticks % 60 === 0) {
// Update every second (60 ticks = 1 second at 60 FPS)
gameTimer--;
timerText.setText('Tiempo: ' + gameTimer);
// When timer reaches 0, increase speed
if (gameTimer <= 0 && !speedIncreased) {
speedIncreased = true;
timerActive = false;
// Speed increase will be handled in the speed calculation section below
}
}
// Game playing state - spawn spheres or spikes based on level
spawnTimer++;
if (currentLevel === 2) {
// Level 2: Flappy Bird mechanics - completely separate from other levels
// Spawn pipes
var pipeSpawnRate = 120; // Spawn pipe every 2 seconds
if (spawnTimer >= pipeSpawnRate) {
var gapY = Math.random() * (2000 - 700) + 700; // Random gap position between y 700-2000
// Create top pipe
var topPipe = new Pipe(true, gapY);
topPipe.x = 2100;
topPipe.y = gapY - pipeGap / 2;
topPipe.lastX = topPipe.x;
pipes.push(topPipe);
game.addChild(topPipe);
// Create bottom pipe
var bottomPipe = new Pipe(false, gapY);
bottomPipe.x = 2100;
bottomPipe.y = gapY + pipeGap / 2;
bottomPipe.lastX = bottomPipe.x;
pipes.push(bottomPipe);
game.addChild(bottomPipe);
spawnTimer = 0;
}
// Handle Flappy Bird physics
if (character) {
// Apply gravity
birdVelocity += gravity;
character.y += birdVelocity;
// Check boundaries - only bounce off top, die on bottom and left
if (character.y < 50) {
character.y = 50;
birdVelocity = 0;
}
// Check win condition for level 2 - complete at 1000m distance
if (distanceTraveled >= 1000) {
// Unlock next level if current level is completed
var nextLevel = currentLevel + 1;
if (nextLevel <= 10 && unlockedLevels.indexOf(nextLevel) === -1) {
unlockedLevels.push(nextLevel);
storage.unlockedLevels = unlockedLevels;
}
// Convert distance to spheres and add to total
var spheresEarned = Math.floor(distanceTraveled / 10);
totalSpheres += spheresEarned;
storage.totalSpheres = totalSpheres;
// Show level completed
LK.showYouWin();
return;
}
// Check death conditions: left edge or bottom
if (character.x <= 0 || character.y > 2680) {
// Hit left edge or ground - game over
attemptCount++;
storage.attemptCount = attemptCount;
// Track level-specific attempts
if (!levelAttempts[currentLevel]) {
levelAttempts[currentLevel] = 0;
}
levelAttempts[currentLevel]++;
storage.levelAttempts = levelAttempts;
// Reset spheres after 5 attempts in this level
if (levelAttempts[currentLevel] % 5 === 0) {
totalSpheres = 0;
storage.totalSpheres = 0;
// Reset owned characters except free ones
ownedCharacters = ['joy'];
storage.ownedCharacters = ownedCharacters;
} else {
// Convert distance to spheres (divide by 10)
var spheresEarned = Math.floor(distanceTraveled / 10);
totalSpheres += spheresEarned;
storage.totalSpheres = totalSpheres;
}
LK.showGameOver();
return;
}
// Update distance
distanceTraveled += 4; // Distance increases as pipes move
heightText.setText('Distancia: ' + Math.floor(distanceTraveled) + 'm');
}
// Update pipes and check collisions
for (var p = pipes.length - 1; p >= 0; p--) {
var pipe = pipes[p];
if (pipe.lastX === undefined) pipe.lastX = pipe.x;
var shouldRemovePipe = false;
// Check if off screen
if (pipe.lastX >= -pipeWidth && pipe.x < -pipeWidth) {
shouldRemovePipe = true;
}
// Check collision with character - bounce instead of game over
if (character && pipe.intersects(character)) {
// Bounce character away from pipe
if (pipe.isTop) {
// Hit top pipe - bounce down
character.y = pipe.y + pipe.height + 20;
birdVelocity = 5; // Push down
} else {
// Hit bottom pipe - bounce up
character.y = pipe.y - 20;
birdVelocity = -5; // Push up
}
// Flash character red to indicate collision
LK.effects.flashObject(character, 0xFF0000, 300);
}
// Check if passed pipe for scoring (only check bottom pipes to avoid double scoring)
if (!pipe.isTop && !pipe.scored && pipe.lastX >= character.x && pipe.x < character.x) {
pipe.scored = true;
scoreCounter++;
LK.setScore(scoreCounter);
scoreText.setText('Puntos: ' + LK.getScore());
LK.getSound('collect').play();
}
if (shouldRemovePipe) {
pipe.destroy();
pipes.splice(p, 1);
} else {
pipe.lastX = pipe.x;
}
}
// Level 2 specific updates only
return; // Skip level 1 logic for level 2
} else if (currentLevel === 1) {
// Level 1 logic - completely separate from other levels
var spawnRate = Math.max(30, 90 - difficultyLevel * 5);
if (spawnTimer >= spawnRate) {
spawnMemory();
spawnTimer = 0;
}
}
// Increase difficulty over time
if (LK.getScore() > 0 && LK.getScore() % 10 === 0) {
difficultyLevel = Math.floor(LK.getScore() / 10) + 1;
}
// Spawn rate already handled at top of update function
// Only update memories for level 1
if (currentLevel === 1) {
// Update golden memories
for (var i = goldenMemories.length - 1; i >= 0; i--) {
var golden = goldenMemories[i];
// Initialize lastY if needed
if (golden.lastY === undefined) golden.lastY = golden.y;
var shouldRemove = false;
// Check if off screen
if (golden.lastY <= 2732 && golden.y > 2732) {
shouldRemove = true;
} else if (character && gameStarted && golden.intersects(character)) {
// Check collision with character for game phase
var spherePoints = Math.floor(3 * sphereMultiplier);
// Disgust character gets 2x spheres
if (selectedEmotion === 'disgust') {
spherePoints = Math.floor(6 * sphereMultiplier);
}
LK.setScore(LK.getScore() + spherePoints);
scoreText.setText('Puntos: ' + LK.getScore());
LK.getSound('collect').play();
// Flash character gold
LK.effects.flashObject(character, 0xFFD700, 300);
// Recharge energy
currentEnergy = Math.min(maxEnergy, currentEnergy + 15);
shouldRemove = true;
} else if (!gameStarted && !countdownActive && golden.characterType && golden.y > 500 && golden.y < 2000) {
// Check collision for character selection phase
handleSphereSelection(golden);
shouldRemove = true;
}
if (shouldRemove) {
golden.destroy();
goldenMemories.splice(i, 1);
} else {
golden.lastY = golden.y;
}
}
// Update corrupted memories
for (var j = corruptedMemories.length - 1; j >= 0; j--) {
var corrupted = corruptedMemories[j];
// Initialize lastY if needed
if (corrupted.lastY === undefined) corrupted.lastY = corrupted.y;
var shouldRemove = false;
// Check if off screen
if (corrupted.lastY <= 2732 && corrupted.y > 2732) {
shouldRemove = true;
} else if (character && corrupted.intersects(character)) {
// Check collision with character
var damage = speedIncreased ? 25 : 20;
health -= damage;
healthText.setText('Vida: ' + health + '/' + maxHealth);
LK.getSound('damage').play();
// Flash character red
LK.effects.flashObject(character, 0xFF0000, 500);
shouldRemove = true;
// Check game over
if (health <= 0) {
// Stop character from following cursor
if (character) {
tween.stop(character);
}
// Increment attempt counter
attemptCount++;
storage.attemptCount = attemptCount;
// Track level-specific attempts
if (!levelAttempts[currentLevel]) {
levelAttempts[currentLevel] = 0;
}
levelAttempts[currentLevel]++;
storage.levelAttempts = levelAttempts;
// Reset accumulated points every 5 attempts in this level
if (levelAttempts[currentLevel] % 5 === 0) {
totalSpheres = 0;
storage.totalSpheres = 0;
// Reset owned characters except free ones
ownedCharacters = ['joy'];
storage.ownedCharacters = ownedCharacters;
} else {
// Add accumulated points to total spheres
totalSpheres += LK.getScore();
storage.totalSpheres = totalSpheres;
}
// Show game over immediately
LK.showGameOver();
return;
}
}
if (shouldRemove) {
corrupted.destroy();
corruptedMemories.splice(j, 1);
} else {
corrupted.lastY = corrupted.y;
}
}
}
// Calculate speed only for level 1
if (currentLevel === 1) {
var goldenBaseSpeed = (3 + difficultyLevel * 0.5) * speedMultiplier;
var corruptedBaseSpeed = (4 + difficultyLevel * 0.5) * speedMultiplier;
if (speedIncreased) {
goldenBaseSpeed += goldenBaseSpeed * 0.5;
corruptedBaseSpeed += corruptedBaseSpeed * 0.5;
}
// Double speed for lvl1
goldenBaseSpeed *= 2;
corruptedBaseSpeed *= 2;
// Apply speed boost multiplier if active
if (speedBoostActive) {
goldenBaseSpeed *= 2;
corruptedBaseSpeed *= 2;
}
// Apply calculated speeds
for (var k = 0; k < goldenMemories.length; k++) {
goldenMemories[k].speed = goldenBaseSpeed;
}
for (var l = 0; l < corruptedMemories.length; l++) {
corruptedMemories[l].speed = corruptedBaseSpeed;
}
}
// Check win condition (500 spheres)
if (totalSpheres >= 500) {
// Create large green "GANASTE" text
var winText = new Text2('GANASTE', {
size: 200,
fill: 0x00FF00
});
winText.anchor.set(0.5, 0.5);
winText.x = 1024;
winText.y = 1366;
game.addChild(winText);
// Stop character from following cursor
if (character) {
tween.stop(character);
}
// Unlock next level if current level is completed
var nextLevel = currentLevel + 1;
if (nextLevel <= 10 && unlockedLevels.indexOf(nextLevel) === -1) {
unlockedLevels.push(nextLevel);
storage.unlockedLevels = unlockedLevels;
}
// Reset accumulated spheres to 0 when winning
totalSpheres = 0;
storage.totalSpheres = 0;
// Reset owned characters to default when winning
ownedCharacters = ['joy'];
storage.ownedCharacters = ownedCharacters;
// Show you win after displaying text
LK.setTimeout(function () {
LK.showYouWin();
}, 3000);
}
// Check win condition (score of 50000)
if (LK.getScore() >= 50000) {
// Stop character from following cursor
if (character) {
tween.stop(character);
}
// Unlock next level if current level is completed
var nextLevel = currentLevel + 1;
if (nextLevel <= 10 && unlockedLevels.indexOf(nextLevel) === -1) {
unlockedLevels.push(nextLevel);
storage.unlockedLevels = unlockedLevels;
}
// Increment attempt counter
attemptCount++;
storage.attemptCount = attemptCount;
// Track level-specific attempts
if (!levelAttempts[currentLevel]) {
levelAttempts[currentLevel] = 0;
}
levelAttempts[currentLevel]++;
storage.levelAttempts = levelAttempts;
// Reset accumulated points every 5 attempts in this level
if (levelAttempts[currentLevel] % 5 === 0) {
totalSpheres = 0;
storage.totalSpheres = 0;
// Reset owned characters except free ones
ownedCharacters = ['joy'];
storage.ownedCharacters = ownedCharacters;
} else {
// Add accumulated points to total spheres
totalSpheres += LK.getScore();
storage.totalSpheres = totalSpheres;
}
// Also reset owned characters when winning with high score
ownedCharacters = ['joy'];
storage.ownedCharacters = ownedCharacters;
LK.showYouWin();
}
}; ===================================================================
--- original.js
+++ change.js
@@ -204,29 +204,145 @@
});
heightText.anchor.set(0, 0);
LK.gui.bottomLeft.addChild(heightText);
heightText.y = 100;
+// Add invisible collision box to heightText
+var heightTextBox = LK.getAsset('level1', {
+ anchorX: 0,
+ anchorY: 0,
+ scaleX: 1.5,
+ scaleY: 0.5
+});
+heightTextBox.alpha = 0;
+heightTextBox.x = 0;
+heightTextBox.y = 100;
+heightTextBox.textElement = heightText;
+LK.gui.bottomLeft.addChild(heightTextBox);
+// Auto-hide heightText after 10 seconds when visible
+var heightTimeout = null;
+heightText.showWithTimeout = function () {
+ if (heightTimeout) LK.clearTimeout(heightTimeout);
+ heightTimeout = LK.setTimeout(function () {
+ tween(heightText, {
+ alpha: 0
+ }, {
+ duration: 1000
+ });
+ tween(heightTextBox, {
+ alpha: 0
+ }, {
+ duration: 1000
+ });
+ }, 10000);
+};
// UI Elements
var scoreText = new Text2('Puntos: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
scoreText.alpha = 0; // Hide initially
LK.gui.top.addChild(scoreText);
+// Add invisible collision box to scoreText
+var scoreTextBox = LK.getAsset('level1', {
+ anchorX: 0.5,
+ anchorY: 0,
+ scaleX: 1.5,
+ scaleY: 0.6
+});
+scoreTextBox.alpha = 0;
+scoreTextBox.x = 0;
+scoreTextBox.y = 0;
+scoreTextBox.textElement = scoreText;
+LK.gui.top.addChild(scoreTextBox);
+// Auto-hide scoreText after 10 seconds when visible
+var scoreTimeout = null;
+scoreText.showWithTimeout = function () {
+ if (scoreTimeout) LK.clearTimeout(scoreTimeout);
+ scoreTimeout = LK.setTimeout(function () {
+ tween(scoreText, {
+ alpha: 0
+ }, {
+ duration: 1000
+ });
+ tween(scoreTextBox, {
+ alpha: 0
+ }, {
+ duration: 1000
+ });
+ }, 10000);
+};
var healthText = new Text2('Vida: 100/100', {
size: 50,
fill: 0xFF0000
});
healthText.anchor.set(1, 0);
LK.gui.topRight.addChild(healthText);
+// Add invisible collision box to healthText
+var healthTextBox = LK.getAsset('level1', {
+ anchorX: 1,
+ anchorY: 0,
+ scaleX: 1.2,
+ scaleY: 0.5
+});
+healthTextBox.alpha = 0;
+healthTextBox.x = 0;
+healthTextBox.y = 0;
+healthTextBox.textElement = healthText;
+LK.gui.topRight.addChild(healthTextBox);
+// Auto-hide healthText after 10 seconds when visible
+var healthTimeout = null;
+healthText.showWithTimeout = function () {
+ if (healthTimeout) LK.clearTimeout(healthTimeout);
+ healthTimeout = LK.setTimeout(function () {
+ tween(healthText, {
+ alpha: 0
+ }, {
+ duration: 1000
+ });
+ tween(healthTextBox, {
+ alpha: 0
+ }, {
+ duration: 1000
+ });
+ }, 10000);
+};
// Timer display
var timerText = new Text2('Tiempo: 223', {
size: 50,
fill: 0xFFFFFF
});
timerText.anchor.set(0, 1);
LK.gui.bottomLeft.addChild(timerText);
+// Add invisible collision box to timerText
+var timerTextBox = LK.getAsset('level1', {
+ anchorX: 0,
+ anchorY: 1,
+ scaleX: 1.2,
+ scaleY: 0.5
+});
+timerTextBox.alpha = 0;
+timerTextBox.x = 0;
+timerTextBox.y = 0;
+timerTextBox.textElement = timerText;
+LK.gui.bottomLeft.addChild(timerTextBox);
+// Auto-hide timerText after 10 seconds when visible
+var timerTimeout = null;
+timerText.showWithTimeout = function () {
+ if (timerTimeout) LK.clearTimeout(timerTimeout);
+ timerTimeout = LK.setTimeout(function () {
+ tween(timerText, {
+ alpha: 0
+ }, {
+ duration: 1000
+ });
+ tween(timerTextBox, {
+ alpha: 0
+ }, {
+ duration: 1000
+ });
+ }, 10000);
+};
// Energy bar background (dark blue)
energyBarBg = LK.getAsset('spike', {
anchorX: 1,
anchorY: 0,
@@ -256,8 +372,37 @@
energyText.anchor.set(1, 0);
energyText.x = -20;
energyText.y = 80;
LK.gui.topRight.addChild(energyText);
+// Add invisible collision box to energyText
+var energyTextBox = LK.getAsset('level1', {
+ anchorX: 1,
+ anchorY: 0,
+ scaleX: 0.8,
+ scaleY: 0.3
+});
+energyTextBox.alpha = 0;
+energyTextBox.x = -20;
+energyTextBox.y = 80;
+energyTextBox.textElement = energyText;
+LK.gui.topRight.addChild(energyTextBox);
+// Auto-hide energyText after 10 seconds when visible
+var energyTimeout = null;
+energyText.showWithTimeout = function () {
+ if (energyTimeout) LK.clearTimeout(energyTimeout);
+ energyTimeout = LK.setTimeout(function () {
+ tween(energyText, {
+ alpha: 0
+ }, {
+ duration: 1000
+ });
+ tween(energyTextBox, {
+ alpha: 0
+ }, {
+ duration: 1000
+ });
+ }, 10000);
+};
// Main Menu UI
var titleText = new Text2('INTENSAMENTE', {
size: 120,
fill: 0xFFFFFF
@@ -265,16 +410,66 @@
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 800;
game.addChild(titleText);
+// Add invisible collision box to titleText
+var titleTextBox = LK.getAsset('level1', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 2,
+ scaleY: 0.8
+});
+titleTextBox.alpha = 0;
+titleTextBox.x = titleText.x;
+titleTextBox.y = titleText.y;
+titleTextBox.textElement = titleText;
+game.addChild(titleTextBox);
+// Auto-hide titleText after 10 seconds
+LK.setTimeout(function () {
+ tween(titleText, {
+ alpha: 0
+ }, {
+ duration: 1000
+ });
+ tween(titleTextBox, {
+ alpha: 0
+ }, {
+ duration: 1000
+ });
+}, 10000);
var playButton = new Text2('JUGAR', {
size: 80,
fill: 0x00FF00
});
playButton.anchor.set(0.5, 0.5);
playButton.x = 1024;
playButton.y = 1200;
game.addChild(playButton);
+// Add invisible collision box to playButton
+var playButtonBox = LK.getAsset('level1', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 1.5,
+ scaleY: 0.8
+});
+playButtonBox.alpha = 0;
+playButtonBox.x = playButton.x;
+playButtonBox.y = playButton.y;
+playButtonBox.textElement = playButton;
+game.addChild(playButtonBox);
+// Auto-hide playButton after 10 seconds
+LK.setTimeout(function () {
+ tween(playButton, {
+ alpha: 0
+ }, {
+ duration: 1000
+ });
+ tween(playButtonBox, {
+ alpha: 0
+ }, {
+ duration: 1000
+ });
+}, 10000);
var instructionText = new Text2('Selecciona tu personaje', {
size: 80,
fill: 0xFFFFFF
});
@@ -283,8 +478,40 @@
instructionText.y = 600;
instructionText.alpha = 0;
instructionText.visible = false;
game.addChild(instructionText);
+// Add invisible collision box to instructionText
+var instructionTextBox = LK.getAsset('level1', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 2.5,
+ scaleY: 0.8
+});
+instructionTextBox.alpha = 0;
+instructionTextBox.x = instructionText.x;
+instructionTextBox.y = instructionText.y;
+instructionTextBox.textElement = instructionText;
+game.addChild(instructionTextBox);
+// Auto-hide instructionText after 10 seconds when visible
+var instructionTimeout = null;
+var originalInstructionAlpha = instructionText.alpha;
+instructionText.showWithTimeout = function () {
+ instructionText.alpha = 1;
+ instructionText.visible = true;
+ if (instructionTimeout) LK.clearTimeout(instructionTimeout);
+ instructionTimeout = LK.setTimeout(function () {
+ tween(instructionText, {
+ alpha: 0
+ }, {
+ duration: 1000
+ });
+ tween(instructionTextBox, {
+ alpha: 0
+ }, {
+ duration: 1000
+ });
+ }, 10000);
+};
var countdownText = new Text2('3', {
size: 200,
fill: 0xFFFFFF
});
@@ -293,8 +520,39 @@
countdownText.y = 1366;
countdownText.alpha = 0;
countdownText.visible = false;
game.addChild(countdownText);
+// Add invisible collision box to countdownText
+var countdownTextBox = LK.getAsset('level1', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 1.5,
+ scaleY: 1.2
+});
+countdownTextBox.alpha = 0;
+countdownTextBox.x = countdownText.x;
+countdownTextBox.y = countdownText.y;
+countdownTextBox.textElement = countdownText;
+game.addChild(countdownTextBox);
+// Auto-hide countdownText after 10 seconds when visible
+var countdownTimeout = null;
+countdownText.showWithTimeout = function () {
+ countdownText.alpha = 1;
+ countdownText.visible = true;
+ if (countdownTimeout) LK.clearTimeout(countdownTimeout);
+ countdownTimeout = LK.setTimeout(function () {
+ tween(countdownText, {
+ alpha: 0
+ }, {
+ duration: 1000
+ });
+ tween(countdownTextBox, {
+ alpha: 0
+ }, {
+ duration: 1000
+ });
+ }, 10000);
+};
// Spawn static character selection spheres in center
function spawnCharacterSelectionSpheres() {
// Only spawn once
if (goldenMemories.length === 0) {
@@ -674,21 +932,19 @@
gameState = 'characterSelection';
// Hide menu elements
titleText.alpha = 0;
playButton.alpha = 0;
- // Show instruction text
- instructionText.alpha = 1;
- instructionText.visible = true;
+ // Show instruction text with timeout
+ instructionText.showWithTimeout();
// Spawn character selection spheres
spawnCharacterSelectionSpheres();
}
// Start countdown before game
function startCountdown() {
gameState = 'countdown';
countdownActive = true;
countdownValue = 3;
- countdownText.alpha = 1;
- countdownText.visible = true;
+ countdownText.showWithTimeout();
countdownText.setText('3');
var countdownInterval = LK.setInterval(function () {
countdownValue--;
if (countdownValue > 0) {
@@ -715,32 +971,40 @@
// Show/hide UI elements based on level
if (currentLevel === 1) {
// Level 1: Show health, score, timer, energy
scoreText.alpha = 1;
+ scoreText.showWithTimeout();
healthText.alpha = 1;
+ healthText.showWithTimeout();
timerText.alpha = 1;
+ timerText.showWithTimeout();
heightText.alpha = 0;
energyBar.alpha = 1;
energyBarBg.alpha = 1;
energyText.alpha = 1;
+ energyText.showWithTimeout();
} else if (currentLevel === 2) {
// Level 2: Show only distance and score
scoreText.alpha = 1;
+ scoreText.showWithTimeout();
healthText.alpha = 0;
timerText.alpha = 0;
heightText.alpha = 1;
+ heightText.showWithTimeout();
energyBar.alpha = 0;
energyBarBg.alpha = 0;
energyText.alpha = 0;
} else {
// Other levels: Show score only
scoreText.alpha = 1;
+ scoreText.showWithTimeout();
healthText.alpha = 0;
timerText.alpha = 0;
heightText.alpha = 0;
energyBar.alpha = 1;
energyBarBg.alpha = 1;
energyText.alpha = 1;
+ energyText.showWithTimeout();
}
// Create player character
character = new EmotionCharacter(selectedEmotion);
if (currentLevel === 2) {