User prompt
Please fix the bug: 'Timeout.tick error: Cannot read properties of null (reading 'setProgress')' in or related to this line: 'progressDisplay.setProgress(currentQuestion, questionsPerRound);' Line Number: 1318
User prompt
esta todo bug
User prompt
🎮 TÍTULO DEL MODO: Forja de Leyendas Un viaje interactivo por el universo de Destiny 2 donde los conocimientos se convierten en armas, y las decisiones marcan el destino de tu Guardián. 🧱 VISIÓN GENERAL "Forja de Leyendas" es una campaña por niveles dividida en sectores narrativos. Cada nivel es un enfrentamiento táctico que combina: Preguntas de trivia tematizadas (lore, armas, personajes, eventos) Mecánicas RPG ligeras (clase, vida, energía) Decisiones estratégicas (elegir ruta, gastar energía, usar habilidades) Tu progreso se guarda, y puedes repetir niveles para subir puntuación, mejorar tu Guardian, o desbloquear rutas alternativas. 🌌 ESTRUCTURA PRINCIPAL ➤ 5 SECTORES — CAMPAÑA PRINCIPAL Cada sector es una zona narrativa inspirada en el universo de Destiny, con ambientación, enemigos y trivia única. Sector Tema central Enemigos Trivia 1. ZME (Zona Muerta) Primer contacto Caídos Básicos de Destiny 2 2. Marte Rojo Dominio militar Cabal NPCs, armas, historia bélica 3. Mundo Trono Corrupción y engaño Hive Savathûn, colmena, lore oscuro 4. Red Vex Simulación y paradoja Vex Misiones, lógica, fractales 5. Apoteosis Luz vs Oscuridad final Combinados Filosofía, Unveiling, Final Shape Cada sector tiene 5 niveles, con progresión creciente. 🧠 ESTRUCTURA DE NIVEL ▶ Nivel tipo: Nombre del nivel Narración introductoria (puede ser texto o voz) Enemigo con mecánicas especiales 5 preguntas (de dificultad progresiva) Resultado basado en respuestas (ataque, defensa, energía, etc.) ▶ Mecánicas ✅ Aciertas → Atacas o activas habilidad ❌ Fallas → Recibes daño o efectos negativos ⚡ Energía: se acumula con respuestas buenas, se gasta en habilidades especiales ❤️ Vidas: pierdes una con cada error; a 0 = reinicio del nivel ⚔️ EJEMPLO DETALLADO DE UN NIVEL 🌑 Sector 3: Mundo Trono Nivel 2 - "El Eco de Savathûn" Historia breve: Te adentras en los secretos del trono de Savathûn. Las ilusiones son fuertes. Solo el conocimiento puede atravesarlas. Enemigo: Acolyte Fantasma HP: 3 Habilidad: si fallas dos preguntas, se regenera 1 vida Preguntas: ¿Qué le ofreció la Luz a Savathûn? ¿Quién es Immaru? ¿Qué arma exótica se relaciona con su historia? ¿Qué hizo Mara Sov para traerla de vuelta? ¿Qué dijo la colmena sobre la Verdad oculta? Resultados: Si aciertas 4+, pasas y desbloqueas la siguiente misión. Si aciertas todas, desbloqueas una entrada del grimorio secreto. Si fallas 3+, reinicias el nivel y pierdes un intento. 🧬 EVOLUCIÓN DEL GUARDIÁN El jugador tiene un perfil de Guardián con: ⭐ Nivel (sube con EXP por nivel) 💠 Clase (Titan, Hunter, Warlock — elige una al principio) ⚙️ Habilidades desbloqueables (ej: "Curarse al acertar 3 seguidas") 📚 Recompensas cosméticas (avatares, emblemas) 🔄 RUTAS RAMIFICADAS Al terminar ciertos niveles, puedes: Elegir entre dos caminos (difícil/fácil) Desbloquear un atajo si respondiste rápido Iniciar niveles de evento raro (preguntas trampa, narrativa oculta, lore profundo) 🧩 MODO DESAFÍO: “Realidad Fracturada” Se desbloquea tras completar los 5 sectores: Todos los enemigos combinados Preguntas sin opciones (escribes la respuesta) Límite de tiempo para cada turno Solo una vida Recompensa final: “Leyenda Eterna” 💡 VENTAJAS DE ESTE SISTEMA Mantiene el núcleo de trivia, pero lo hace emocionante y significativo. Introduce progresión, historia y conexión emocional con Destiny. Tiene espacio para rejugabilidad, desbloqueos, decisiones. Perfecto para contenido episódico o expansiones. es para el rpg esta idea ↪💡 Consider importing and using the following plugins: @upit/storage.v1, @upit/tween.v1
User prompt
cuando me hace daño no me baja la vida y cuando acierto tampoco le bajo la vida
User prompt
agregue un sonido llamado damage y quiero que este en el modo rpg que cuando de una incorrecta como recibe dano de oponentes cuando le baja vida que suene ese sonido
User prompt
IDEA NUEVA: “Forja de Leyendas” – Trivia con mecánicas de rol táctico Concepto general Un juego que mezcla preguntas de trivia con combate táctico por turnos, donde las respuestas correctas “atacan” o “defienden” a tu Guardián en batallas contra enemigos icónicos de Destiny 2. No es solo responder, sino usar la trivia para ganar ventaja en peleas estratégicas. Mecánicas centrales 1. Batallas por turnos basadas en trivia En cada turno, para atacar o defender debes responder una pregunta. Respuesta correcta = ataque exitoso o defensa reforzada. Respuesta incorrecta = enemigo ataca o tu defensa se debilita. 2. Clases y habilidades del Guardián Elige entre Titan, Hunter o Warlock. Cada clase tiene habilidades especiales que puedes activar respondiendo preguntas “de habilidad” (por ejemplo, preguntas de dificultad extra o retos). Habilidades: Titan: escudo extra que absorbe daño. Hunter: doble ataque si responde dos preguntas seguidas bien. Warlock: cura o daño en área. 3. Enemigos con patrones y debilidades Cada enemigo tiene un patrón de ataque y puntos débiles que se revelan parcialmente con las preguntas. Preguntas temáticas según enemigo (Ejemplo: Cabal, Hive, Vex). Responder preguntas correctas explota debilidades, aumentando el daño. 4. Sistema de energía y recursos Responder bien genera energía para activar habilidades especiales o combos. Responder mal consume energía o hace que pierdas vida. 5. Modo campaña progresivo Avanzas por diferentes misiones con enemigos y preguntas específicas. Cada misión con dificultad creciente y enemigos más fuertes. Dinámica de juego Inicias con tu Guardián y enfrentas un enemigo. Turno 1: te hacen una pregunta, respondes. Si aciertas, atacas y haces daño. Si fallas, el enemigo ataca y te quita vida. Al ganar, recibes puntos y mejoras (mejor equipo, habilidades). Puedes elegir mejorar estadísticas o habilidades según las respuestas que des. ¿Qué hace único a este juego? Combina trivia con estrategia y RPG táctico, no es solo preguntas y respuestas. La trivia afecta directamente la batalla y estrategia. Las clases ofrecen estilos de juego diferentes. Preguntas adaptadas a enemigos y situaciones, enriqueciendo la experiencia. Desafíos tácticos: decidir cuándo usar habilidades, cuándo arriesgarse con preguntas difíciles. Ejemplo de una ronda Entras a combate contra un Cabal Coloso. Pregunta: “¿Cuál es la principal fortaleza del Cabal?” Opciones. Respondes correctamente. Tu Titan activa escudo y ataca. El Coloso pierde vida. Enemigo contraataca. Turno siguiente, te preguntan sobre armas exóticas para Hunter. Si fallas, recibes daño extra. Si aciertas, tu Hunter lanza doble ataque. quiero que hagas una seccion que dice. que quieres jugar? trivia o Forja de Leyendas” – Trivia con mecánicas de rol táctico
User prompt
Nivel 1 (Rodri) ¿Qué vendedor maneja Trials of Osiris? Opciones: Lord Shaxx, Saint-14, Osiris, The Drifter Correcta marcada: Saint-14 Corrección: El vendedor correcto es Osiris. ¿Qué moneda reemplazó Legendary Shards? Opciones: Enhancement Cores, Glimmer only, Bright Dust, Strange Coins Correcta marcada: Bright Dust Corrección: Legendary Shards no fue reemplazado por Bright Dust; Legendary Shards sigue vigente para mejoras. Esta pregunta es confusa o incorrecta. Nivel 2 (Diego) ¿Cómo se llama el pollo de Cayde-6? Opciones: Ace, Colonel, General, Captain Correcta marcada: Colonel Corrección: El pollo se llama Ace. ¿Quién fue el dueño original de Whisper of the Worm? Opciones: Oryx, Xol, Nokris, Savathûn Correcta marcada: Xol Corrección: Mejor respuesta sería Oryx (el arma está relacionada con él en la historia). ¿Qué conecta el Jardín Negro con la red Vex? Opciones: The Black Heart, Sol Divisive, Quria, The Undying Mind Correcta marcada: Sol Divisive Corrección: "Sol Divisive" no es término canon; conexiones conocidas son Quria o The Undying Mind.
Code edit (1 edits merged)
Please save this source code
User prompt
quiero que pongas timer para responder cada pregunta de 60s y que pongas cuando falta
User prompt
pon 60s de time para responder cada pregunta quiero que pongas cuando tiempo falta
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'setOption')' in or related to this line: 'optionButtons[i].setOption(questionData.options[originalIndex], originalIndex, originalIndex === questionData.correct);' Line Number: 655
User prompt
podrias mejorar el codigo y mirar todo eso que te dije
User prompt
en dificultad diego 8/10 son abajo a la izquierda del cuadrado en todas las dificultades hazlo random
User prompt
porque muchas respuestas son de abajo a la izquierda de ese cuadrado quiero que sea random y no este fijo porque de 6/10 ahi esta
User prompt
quiero clickear una y hace otra y siempre es la correcta mira todos los bugs y analiza
User prompt
al aparecer de 8/10 la respuesta es la de abajo a la derecha quiero que sea al azar donde aparezca arriba derecha izquierda pero no donde mismo y es asi en todas las dificultsddes
User prompt
quiero que cambies los nombrs de las dificultades, el primero que se llame Javi segundo Rodri, tercero Diego y ultimo que se llame Nadie la sabe
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var MenuButton = Container.expand(function () {
var self = Container.call(this);
var bg = self.attachAsset('optionButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
self.buttonText = new Text2('', {
size: 48,
fill: 0xFFFFFF
});
self.buttonText.anchor.set(0.5, 0.5);
self.addChild(self.buttonText);
self.difficulty = 0;
self.setButton = function (text, difficulty) {
self.buttonText.setText(text);
self.difficulty = difficulty;
};
self.down = function (x, y, obj) {
if (inMenu) {
startGameWithDifficulty(self.difficulty);
}
};
return self;
});
var OptionButton = Container.expand(function () {
var self = Container.call(this);
var bg = self.attachAsset('optionButton', {
anchorX: 0.5,
anchorY: 0.5
});
self.optionText = new Text2('', {
size: 36,
fill: 0xFFFFFF
});
self.optionText.anchor.set(0.5, 0.5);
self.addChild(self.optionText);
self.correctIndicator = null;
self.wrongIndicator = null;
self.isCorrect = false;
self.index = 0;
self.buttonPosition = 0;
self.setOption = function (text, index, isCorrect) {
self.optionText.setText(text);
self.index = index;
self.isCorrect = isCorrect;
};
self.showResult = function (correct) {
if (correct) {
self.correctIndicator = self.attachAsset('correctIndicator', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.7
});
} else {
self.wrongIndicator = self.attachAsset('wrongIndicator', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.7
});
}
};
self.down = function (x, y, obj) {
if (!canAnswer) {
return;
}
checkAnswer(self.buttonPosition);
};
return self;
});
var ProgressDisplay = Container.expand(function () {
var self = Container.call(this);
var barBg = self.attachAsset('progressBar', {
anchorX: 0,
anchorY: 0.5
});
self.progressFill = self.attachAsset('progressFill', {
anchorX: 0,
anchorY: 0.5,
scaleX: 0
});
self.progressText = new Text2('Question 1/10', {
size: 32,
fill: 0xFFFFFF
});
self.progressText.anchor.set(0.5, 0.5);
self.progressText.x = 800;
self.progressText.y = -40;
self.addChild(self.progressText);
self.setProgress = function (current, total) {
self.progressText.setText('Question ' + current + '/' + total);
var progress = current / total;
tween(self.progressFill, {
scaleX: progress
}, {
duration: 500,
easing: tween.easeOut
});
};
return self;
});
var QuestionDisplay = Container.expand(function () {
var self = Container.call(this);
var bg = self.attachAsset('questionBg', {
anchorX: 0.5,
anchorY: 0.5
});
self.questionText = new Text2('', {
size: 48,
fill: 0xFFFFFF
});
self.questionText.anchor.set(0.5, 0.5);
self.addChild(self.questionText);
self.setQuestion = function (text) {
self.questionText.setText(text);
// Word wrap for long questions
self.questionText.wordWrap = true;
self.questionText.wordWrapWidth = 1600;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x0a0a0f
});
/****
* Game Code
****/
// Constants
var ANIMATION_DURATION = {
SHORT: 500,
MEDIUM: 1000,
LONG: 1500,
EXTRA_LONG: 2000,
GAME_OVER_DELAY: 3000
};
var SCORE_BASE = [5, 10, 20, 40];
var UNLOCK_THRESHOLDS = {
GUARDIAN: 30,
DARKNESS: 50,
TIMER: 70,
WIN: 100
};
var TIMER_BASE = 3600; // 60 seconds in frames (60 FPS)
var TIMER_REDUCTION_PER_DIFFICULTY = 0; // No reduction per difficulty for 60s timer
var DIFFICULTY_COLORS = [0x5EB3FF, 0xFFD700, 0xFF6B6B, 0x9B59B6];
var timerDisplay = null; // Timer display text for all modes
// Game state variables
var currentPhase = 0; // 0: Javi, 1: Rodri, 2: Diego, 3: Nadie la sabe
var currentQuestion = 0;
var score = 0;
var lives = 3;
var questionsPerRound = 10;
var canAnswer = true;
var guardianMode = false;
var darknessMode = false;
var timerMode = false;
var timerCount = 0;
var timerStartTime = 0; // For real-time timer sync
var usedQuestions = []; // Track used questions to avoid repetition
var availableQuestionsPool = []; // Pool of available questions for current difficulty
var inMenu = true; // Track if we're in the menu
var selectedDifficulty = 0; // Selected starting difficulty
var questionDifficulty = 0; // Current question difficulty within phase
// UI Elements
var questionDisplay = null;
var optionButtons = [];
var progressDisplay = null;
var scoreText = null;
var phaseText = null;
var livesText = null;
var modeIndicator = null;
// Question Database - Updated for 02/07/2025 with progressive difficulty
var questions = {
0: [
// Javi - Basic knowledge, commonly played content
// Easy questions (0-3)
{
q: "What is the primary currency in Destiny 2?",
options: ["Glimmer", "Bright Dust", "Legendary Shards", "Silver"],
correct: 0,
difficulty: 0
}, {
q: "How many character classes exist in the game?",
options: ["2", "3", "4", "5"],
correct: 1,
difficulty: 0
}, {
q: "What element type is Solar associated with?",
options: ["Ice", "Lightning", "Fire", "Void"],
correct: 2,
difficulty: 0
}, {
q: "Which NPC serves as the Titan Vanguard?",
options: ["Ikora Rey", "Commander Zavala", "Lord Shaxx", "Saint-14"],
correct: 1,
difficulty: 1
}, {
q: "Where do Guardians primarily operate from?",
options: ["The Farm", "The Tower", "The Reef", "Europa"],
correct: 1,
difficulty: 1
}, {
q: "What is the name of your Ghost?",
options: ["Sundance", "Sagira", "Ghost", "Pulled Pork"],
correct: 2,
difficulty: 1
},
// Medium questions (4-7)
{
q: "Which activity rewards Pinnacle gear?",
options: ["Public Events", "Patrols", "Nightfalls", "Lost Sectors"],
correct: 2,
difficulty: 2
}, {
q: "What currency is used in Eververse?",
options: ["Glimmer", "Silver", "Legendary Shards", "Enhancement Cores"],
correct: 1,
difficulty: 2
}, {
q: "How many subclasses can each class use?",
options: ["3", "4", "5", "6"],
correct: 2,
difficulty: 2
},
// Harder questions (8-10)
{
q: "What is the weekly reset day?",
options: ["Monday", "Tuesday", "Wednesday", "Thursday"],
correct: 1,
difficulty: 3
}, {
q: "What power level is the soft cap?",
options: ["1750", "1800", "1810", "1830"],
correct: 2,
difficulty: 3
}, {
q: "Which raid was the first in Destiny 2?",
options: ["Leviathan", "Last Wish", "Garden of Salvation", "Deep Stone Crypt"],
correct: 0,
difficulty: 3
}],
1: [
// Rodri - Requires playing multiple seasons
{
q: "Which exotic hand cannon returned in Episode: Revenant?",
options: ["Hawkmoon", "Thorn", "The Last Word", "Eriana's Vow"],
correct: 1,
difficulty: 0
}, {
q: "What is the name of the Witness's ship seen in The Final Shape?",
options: ["The Monolith", "The Pyramid", "The Veil", "The Radial Mast"],
correct: 0,
difficulty: 1
}, {
q: "Which character became the new Hunter Vanguard?",
options: ["Crow", "Ana Bray", "Shiro-4", "No one yet"],
correct: 3,
difficulty: 1
}, {
q: "What exotic was craftable in Season of the Wish?",
options: ["Wish-Ender", "Dragon's Breath", "Whisper of the Worm", "Outbreak Perfected"],
correct: 1,
difficulty: 2
}, {
q: "Which vendor handles Trials of Osiris?",
options: ["Lord Shaxx", "Saint-14", "Osiris", "The Drifter"],
correct: 2,
difficulty: 0
}, {
q: "What is the main currency for weapon upgrades?",
options: ["Enhancement Cores", "Legendary Shards", "Bright Dust", "Strange Coins"],
correct: 1,
difficulty: 2
}, {
q: "Which raid features Nezarec as the final boss?",
options: ["Root of Nightmares", "King's Fall", "Vow of the Disciple", "Deep Stone Crypt"],
correct: 0,
difficulty: 3
}, {
q: "What is the max stat tier for abilities?",
options: ["10", "100", "12", "120"],
correct: 1,
difficulty: 3
}, {
q: "Which season introduced the Lightfall expansion?",
options: ["Season of Defiance", "Season of the Deep", "Season of the Witch", "Season of the Wish"],
correct: 0,
difficulty: 2
}, {
q: "What is the name of Strand's Titan super?",
options: ["Bladefury", "Needlestorm", "Silkstrike", "Threadrunner"],
correct: 0,
difficulty: 3
}],
2: [
// Diego - Deep lore, connections between seasons
{
q: "According to lore, who gave Savathûn her memories back?",
options: ["The Witness", "Immaru", "The Traveler", "Mara Sov"],
correct: 2,
difficulty: 0
}, {
q: "What is the name of Cayde-6's chicken?",
options: ["Ace", "Colonel", "General", "Captain"],
correct: 0,
difficulty: 0
}, {
q: "Which Disciple of the Witness created the Hive?",
options: ["Nezarec", "Rhulk", "Calus", "The Witness itself"],
correct: 1,
difficulty: 1
}, {
q: "What are the three queens Mara Sov refers to in her throne world?",
options: ["Past Present Future", "Light Dark Gray", "Savathûn Xivu Mara", "Birth Life Death"],
correct: 2,
difficulty: 1
}, {
q: "Which Hive Worm God is connected to the Whisper of the Worm?",
options: ["Oryx", "Xol", "Nokris", "Savathûn"],
correct: 1,
difficulty: 2
}, {
q: "What did the Witness seek within the Traveler?",
options: ["Power", "The Final Shape", "Salvation", "The Light"],
correct: 1,
difficulty: 2
}, {
q: "Which character's real name is Uldren Sov?",
options: ["The Drifter", "Crow", "Spider", "Variks"],
correct: 1,
difficulty: 3
}, {
q: "What connects the Black Garden to the Vex network?",
options: ["The Black Heart", "Sol Divisive", "Quria", "The Undying Mind"],
correct: 1,
difficulty: 3
}],
3: [
// Nadie la sabe - Cryptic connections, unexplained details
{
q: "Complete the prophecy: 'The line between Light and Dark is so very...'",
options: ["Blurred", "Thin", "Fragile", "Clear"],
correct: 1,
difficulty: 0
}, {
q: "What pattern appears in the symbols of the Nine?",
options: ["Circles within circles", "Triangular fractals", "Spiral convergence", "Unknown geometry"],
correct: 0,
difficulty: 0
}, {
q: "In the Books of Sorrow, what is the Sword Logic's ultimate goal?",
options: ["Survival", "The Final Shape", "Perfect existence", "Eternal war"],
correct: 1,
difficulty: 1
}, {
q: "What whispered truth did Savathûn hide in her throne world?",
options: ["The Witness lied", "The Traveler chose her", "Light needs Dark", "All of the above"],
correct: 3,
difficulty: 1
}, {
q: "According to Unveiling, what existed before Light and Dark?",
options: ["The Garden", "Nothing", "The Pattern", "Potential"],
correct: 0,
difficulty: 2
}, {
q: "What is the significance of 'O champion mine'?",
options: ["Ahamkara wish magic", "Vex simulation", "Hive curse", "Awoken blessing"],
correct: 0,
difficulty: 2
}, {
q: "What truth about the Collapse did Rasputin hide?",
options: ["He attacked the Traveler", "He made a deal", "He knew it would happen", "All records were destroyed"],
correct: 0,
difficulty: 3
}, {
q: "In Cayde's final message, what does Ace represent?",
options: ["His gun", "His son", "A memory", "All meanings"],
correct: 3,
difficulty: 3
}]
};
var phaseNames = ["Javi", "Rodri", "Diego", "Nadie la sabe"];
var rankNames = ["Light Bearer", "Disciple of Osiris", "Wisdom Devourer", "Archive Legend"];
// Tactical mode variables
var tacticalMode = false;
var guardianClass = 0; // 0: Titan, 1: Hunter, 2: Warlock
var guardianHealth = 100;
var guardianMaxHealth = 100;
var guardianEnergy = 3;
var guardianMaxEnergy = 3;
var enemyHealth = 80;
var enemyMaxHealth = 80;
var currentEnemy = 0;
var battleTurn = 0; // 0: player turn, 1: enemy turn
var consecutiveCorrect = 0;
var shieldActive = false;
var hunterDoubleAttack = false;
var enemies = [{
name: "Cabal Legionary",
health: 60,
damage: 15,
pattern: ["attack", "attack", "defend"],
weakness: "Cabal"
}, {
name: "Hive Knight",
health: 80,
damage: 20,
pattern: ["attack", "special", "attack"],
weakness: "Hive"
}, {
name: "Vex Minotaur",
health: 100,
damage: 25,
pattern: ["defend", "attack", "special"],
weakness: "Vex"
}, {
name: "Fallen Captain",
health: 70,
damage: 18,
pattern: ["attack", "attack", "special"],
weakness: "Fallen"
}];
var classNames = ["Titan", "Hunter", "Warlock"];
var classColors = [0xFF6B6B, 0x5EB3FF, 0x9B59B6];
function initializeGame() {
// Show game mode selection first
showGameModeMenu();
LK.playMusic('ambient');
}
function showGameModeMenu() {
inMenu = true;
// Title
var titleText = new Text2('Destiny 2', {
size: 96,
fill: 0xFFD700
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 400;
game.addChild(titleText);
// Subtitle
var subtitleText = new Text2('¿Qué quieres jugar?', {
size: 56,
fill: 0xFFFFFF
});
subtitleText.anchor.set(0.5, 0.5);
subtitleText.x = 1024;
subtitleText.y = 600;
game.addChild(subtitleText);
// Trivia mode button
var triviaButton = game.addChild(new MenuButton());
triviaButton.x = 1024;
triviaButton.y = 900;
triviaButton.setButton('Trivia Clásico', 0);
triviaButton.buttonText.tint = 0x5EB3FF;
var triviaDesc = new Text2('El juego de trivia tradicional', {
size: 32,
fill: 0xAAAAAA
});
triviaDesc.anchor.set(0.5, 0.5);
triviaDesc.x = 1024;
triviaDesc.y = 950;
game.addChild(triviaDesc);
// Tactical RPG mode button
var rpgButton = game.addChild(new MenuButton());
rpgButton.x = 1024;
rpgButton.y = 1200;
rpgButton.setButton('Forja de Leyendas', 1);
rpgButton.buttonText.tint = 0xFF6B6B;
var rpgDesc = new Text2('Trivia con mecánicas de combate táctico', {
size: 32,
fill: 0xAAAAAA
});
rpgDesc.anchor.set(0.5, 0.5);
rpgDesc.x = 1024;
rpgDesc.y = 1250;
game.addChild(rpgDesc);
// Override button actions
triviaButton.down = function (x, y, obj) {
if (inMenu) {
// Clear menu
while (game.children.length > 0) {
game.children[0].destroy();
}
showDifficultyMenu();
}
};
rpgButton.down = function (x, y, obj) {
if (inMenu) {
// Clear menu
while (game.children.length > 0) {
game.children[0].destroy();
}
showClassSelectionMenu();
}
};
}
function showDifficultyMenu() {
inMenu = true;
// Title
var titleText = new Text2('Destiny 2', {
size: 96,
fill: 0xFFD700
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 400;
game.addChild(titleText);
// Subtitle
var subtitleText = new Text2('Selecciona tu nivel de dificultad', {
size: 48,
fill: 0xFFFFFF
});
subtitleText.anchor.set(0.5, 0.5);
subtitleText.x = 1024;
subtitleText.y = 600;
game.addChild(subtitleText);
// Difficulty buttons
var difficulties = [{
name: 'Javi',
color: 0x5EB3FF,
desc: 'Conocimiento básico'
}, {
name: 'Rodri',
color: 0xFFD700,
desc: 'Experiencia intermedia'
}, {
name: 'Diego',
color: 0xFF6B6B,
desc: 'Dominio del lore'
}, {
name: 'Nadie la sabe',
color: 0x9B59B6,
desc: 'Desafío extremo'
}];
for (var i = 0; i < 4; i++) {
var menuBtn = game.addChild(new MenuButton());
menuBtn.x = 1024;
menuBtn.y = 900 + i * 200;
menuBtn.setButton(difficulties[i].name, i);
menuBtn.buttonText.tint = difficulties[i].color;
var descText = new Text2(difficulties[i].desc, {
size: 32,
fill: 0xAAAAAA
});
descText.anchor.set(0.5, 0.5);
descText.x = 1024;
descText.y = 950 + i * 200;
game.addChild(descText);
}
// Show unlocked modes
if (guardianMode || darknessMode || timerMode) {
var modesText = new Text2('Modos desbloqueados:', {
size: 36,
fill: 0xFFD700
});
modesText.anchor.set(0.5, 0.5);
modesText.x = 1024;
modesText.y = 2000;
game.addChild(modesText);
var unlocked = [];
if (guardianMode) {
unlocked.push('Guardian');
}
if (darknessMode) {
unlocked.push('Oscuridad');
}
if (timerMode) {
unlocked.push('Cronómetro');
}
var unlockedText = new Text2(unlocked.join(' • '), {
size: 32,
fill: 0x5EB3FF
});
unlockedText.anchor.set(0.5, 0.5);
unlockedText.x = 1024;
unlockedText.y = 2050;
game.addChild(unlockedText);
}
}
function showClassSelectionMenu() {
inMenu = true;
// Title
var titleText = new Text2('Forja de Leyendas', {
size: 96,
fill: 0xFF6B6B
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 400;
game.addChild(titleText);
// Subtitle
var subtitleText = new Text2('Elige tu clase de Guardián', {
size: 48,
fill: 0xFFFFFF
});
subtitleText.anchor.set(0.5, 0.5);
subtitleText.x = 1024;
subtitleText.y = 600;
game.addChild(subtitleText);
var classes = [{
name: 'Titan',
color: 0xFF6B6B,
desc: 'Escudo extra que absorbe daño'
}, {
name: 'Hunter',
color: 0x5EB3FF,
desc: 'Doble ataque con respuestas consecutivas'
}, {
name: 'Warlock',
color: 0x9B59B6,
desc: 'Curación y daño en área'
}];
for (var i = 0; i < 3; i++) {
var classBtn = game.addChild(new MenuButton());
classBtn.x = 1024;
classBtn.y = 900 + i * 200;
classBtn.setButton(classes[i].name, i);
classBtn.buttonText.tint = classes[i].color;
var descText = new Text2(classes[i].desc, {
size: 32,
fill: 0xAAAAAA
});
descText.anchor.set(0.5, 0.5);
descText.x = 1024;
descText.y = 950 + i * 200;
game.addChild(descText);
}
// Override all class button actions to start tactical mode
for (var i = 0; i < game.children.length; i++) {
if (game.children[i].setButton) {
game.children[i].down = function (x, y, obj) {
if (inMenu) {
// Clear menu
while (game.children.length > 0) {
game.children[0].destroy();
}
startTacticalMode(this.difficulty);
}
};
}
}
}
function startGameWithDifficulty(difficulty) {
if (!inMenu) {
return;
}
inMenu = false;
selectedDifficulty = difficulty;
currentPhase = difficulty;
// Clear menu
while (game.children.length > 0) {
game.children[0].destroy();
}
// Initialize game elements
// Question display
questionDisplay = game.addChild(new QuestionDisplay());
questionDisplay.x = 1024;
questionDisplay.y = 600;
// Option buttons
optionButtons = []; // Reset the array before populating
for (var i = 0; i < 4; i++) {
var button = game.addChild(new OptionButton());
button.x = 520 + i % 2 * 1000;
button.y = 1200 + Math.floor(i / 2) * 200;
optionButtons.push(button);
}
// Progress display
progressDisplay = game.addChild(new ProgressDisplay());
progressDisplay.x = 224;
progressDisplay.y = 2400;
// Score text
scoreText = new Text2('Score: 0', {
size: 64,
fill: 0xFFFFFF
});
scoreText.anchor.set(1, 0);
LK.gui.topRight.addChild(scoreText);
// Phase text
phaseText = new Text2(phaseNames[currentPhase], {
size: 48,
fill: 0x5EB3FF
});
phaseText.anchor.set(0.5, 0);
phaseText.y = 100;
LK.gui.top.addChild(phaseText);
// Lives text
livesText = new Text2('Lives: ❤❤❤', {
size: 40,
fill: 0xFF6B6B
});
livesText.anchor.set(0, 0);
livesText.x = 120;
LK.gui.topLeft.addChild(livesText);
// Timer display for all modes
timerDisplay = new Text2('Time: 60s', {
size: 40,
fill: 0xFFD700
});
timerDisplay.anchor.set(0.5, 0);
timerDisplay.y = 180;
LK.gui.top.addChild(timerDisplay);
// Mode indicator for timer mode
if (timerMode) {
modeIndicator = new Text2('TIMER MODE ACTIVE', {
size: 36,
fill: 0xFF6B6B
});
modeIndicator.anchor.set(0.5, 0);
modeIndicator.y = 230;
LK.gui.top.addChild(modeIndicator);
}
// Load saved progress
guardianMode = storage.guardianUnlocked || false;
darknessMode = storage.darknessUnlocked || false;
timerMode = storage.timerUnlocked || false;
// Reset game state
score = 0;
lives = 3;
currentQuestion = 0;
questionDifficulty = 0;
usedQuestions = [];
availableQuestionsPool = [];
timerStartTime = 0;
// Start game
loadQuestion();
}
function startTacticalMode(selectedClass) {
if (!inMenu) return;
inMenu = false;
tacticalMode = true;
guardianClass = selectedClass;
// Reset tactical state
guardianHealth = guardianMaxHealth;
guardianEnergy = guardianMaxEnergy;
currentEnemy = 0;
battleTurn = 0;
consecutiveCorrect = 0;
shieldActive = false;
hunterDoubleAttack = false;
score = 0;
currentQuestion = 0;
// Setup enemy
var enemy = enemies[currentEnemy];
enemyHealth = enemy.health;
enemyMaxHealth = enemy.health;
// Initialize tactical UI
setupTacticalUI();
loadTacticalQuestion();
}
function setupTacticalUI() {
// Question display
questionDisplay = game.addChild(new QuestionDisplay());
questionDisplay.x = 1024;
questionDisplay.y = 800;
// Option buttons
optionButtons = [];
for (var i = 0; i < 4; i++) {
var button = game.addChild(new OptionButton());
button.x = 520 + i % 2 * 1000;
button.y = 1400 + Math.floor(i / 2) * 200;
optionButtons.push(button);
}
// Guardian info
var guardianInfo = new Text2(classNames[guardianClass] + ' Guardian', {
size: 48,
fill: classColors[guardianClass]
});
guardianInfo.anchor.set(0, 0);
guardianInfo.x = 50;
guardianInfo.y = 100;
game.addChild(guardianInfo);
// Health bars
var guardianHealthBar = new Text2('Health: ' + guardianHealth + '/' + guardianMaxHealth, {
size: 36,
fill: 0x00FF00
});
guardianHealthBar.anchor.set(0, 0);
guardianHealthBar.x = 50;
guardianHealthBar.y = 200;
game.addChild(guardianHealthBar);
var energyBar = new Text2('Energy: ' + guardianEnergy + '/' + guardianMaxEnergy, {
size: 36,
fill: 0x5EB3FF
});
energyBar.anchor.set(0, 0);
energyBar.x = 50;
energyBar.y = 250;
game.addChild(energyBar);
// Enemy info
var enemy = enemies[currentEnemy];
var enemyInfo = new Text2(enemy.name, {
size: 48,
fill: 0xFF6B6B
});
enemyInfo.anchor.set(1, 0);
enemyInfo.x = 1998;
enemyInfo.y = 100;
game.addChild(enemyInfo);
var enemyHealthBar = new Text2('Health: ' + enemyHealth + '/' + enemyMaxHealth, {
size: 36,
fill: 0xFF6B6B
});
enemyHealthBar.anchor.set(1, 0);
enemyHealthBar.x = 1998;
enemyHealthBar.y = 200;
game.addChild(enemyHealthBar);
// Battle status
var battleStatus = new Text2('Your Turn - Answer to Attack!', {
size: 40,
fill: 0xFFD700
});
battleStatus.anchor.set(0.5, 0);
battleStatus.x = 1024;
battleStatus.y = 400;
game.addChild(battleStatus);
}
function loadQuestion() {
canAnswer = true;
currentQuestion++;
// Calculate question difficulty based on progress
questionDifficulty = Math.floor((currentQuestion - 1) / 3);
if (questionDifficulty > 3) {
questionDifficulty = 3;
}
if (currentQuestion > questionsPerRound) {
// Phase complete - stay in selected difficulty
checkAchievements();
return;
}
progressDisplay.setProgress(currentQuestion, questionsPerRound);
// Update difficulty visual indicator
phaseText.tint = DIFFICULTY_COLORS[currentPhase];
// Add difficulty indicator
var difficultyText = ' - Nivel ' + (questionDifficulty + 1);
phaseText.setText(phaseNames[currentPhase] + difficultyText);
// Get questions from current phase
var phaseQuestions = questions[currentPhase];
// Initialize question pool if empty or at start
if (availableQuestionsPool.length === 0 || currentQuestion === 1) {
availableQuestionsPool = [];
for (var i = 0; i < phaseQuestions.length; i++) {
availableQuestionsPool.push({
question: phaseQuestions[i],
index: i
});
}
}
// Filter questions by difficulty from the pool
var availableQuestions = [];
for (var i = 0; i < availableQuestionsPool.length; i++) {
var qData = availableQuestionsPool[i];
var q = qData.question;
// Select questions matching current difficulty or close to it
if (Math.abs(q.difficulty - questionDifficulty) <= 1) {
availableQuestions.push(qData);
}
}
// If no questions available for this difficulty, expand search
if (availableQuestions.length === 0) {
// Use all remaining questions in pool
availableQuestions = availableQuestionsPool.slice();
}
// Select random question from available
var selectedIndex = Math.floor(Math.random() * availableQuestions.length);
var selected = availableQuestions[selectedIndex];
var questionData = selected.question;
// Remove selected question from pool
for (var i = 0; i < availableQuestionsPool.length; i++) {
if (availableQuestionsPool[i].index === selected.index) {
availableQuestionsPool.splice(i, 1);
break;
}
}
// Apply darkness mode with better visual feedback
if (darknessMode) {
questionDisplay.setQuestion("\n" + questionData.q + "\n");
questionDisplay.questionText.tint = 0x9B59B6;
} else {
questionDisplay.setQuestion(questionData.q);
questionDisplay.questionText.tint = 0xFFFFFF;
}
// Create a shuffled array of indices using only Fisher-Yates
var indices = [0, 1, 2, 3];
var shuffledIndices = [];
// Use proper Fisher-Yates shuffle
var tempIndices = indices.slice(); // Create a copy
while (tempIndices.length > 0) {
var randomIndex = Math.floor(Math.random() * tempIndices.length);
shuffledIndices.push(tempIndices[randomIndex]);
tempIndices.splice(randomIndex, 1);
}
// Set options with shuffled positions
for (var i = 0; i < 4; i++) {
var originalIndex = shuffledIndices[i];
optionButtons[i].setOption(questionData.options[originalIndex], originalIndex, originalIndex === questionData.correct);
// Store button position for click handling
optionButtons[i].buttonPosition = i;
}
// Initialize 60-second timer for all questions
timerCount = TIMER_BASE; // Always 60 seconds
timerStartTime = Date.now();
}
function loadTacticalQuestion() {
if (!tacticalMode) return;
canAnswer = true;
currentQuestion++;
// Select question based on enemy weakness or general knowledge
var enemy = enemies[currentEnemy];
var questionPool = [];
// Add questions from all phases for variety
for (var phase = 0; phase < 4; phase++) {
for (var i = 0; i < questions[phase].length; i++) {
questionPool.push(questions[phase][i]);
}
}
// Randomly select a question
var selectedQuestion = questionPool[Math.floor(Math.random() * questionPool.length)];
questionDisplay.setQuestion(selectedQuestion.q);
// Shuffle options
var indices = [0, 1, 2, 3];
var shuffledIndices = [];
var tempIndices = indices.slice();
while (tempIndices.length > 0) {
var randomIndex = Math.floor(Math.random() * tempIndices.length);
shuffledIndices.push(tempIndices[randomIndex]);
tempIndices.splice(randomIndex, 1);
}
// Set options
for (var i = 0; i < 4; i++) {
var originalIndex = shuffledIndices[i];
optionButtons[i].setOption(selectedQuestion.options[originalIndex], originalIndex, originalIndex === selectedQuestion.correct);
optionButtons[i].buttonPosition = i;
}
// Initialize timer
timerCount = TIMER_BASE;
timerStartTime = Date.now();
}
function checkAnswer(selectedIndex) {
if (!canAnswer) {
return;
}
canAnswer = false;
timerStartTime = 0; // Stop timer when answer is selected
if (tacticalMode) {
checkTacticalAnswer(selectedIndex);
return;
}
var correct = optionButtons[selectedIndex].isCorrect;
// Darkness mode inverts correct answers
if (darknessMode) {
correct = !correct;
}
if (correct) {
LK.getSound('correct').play();
optionButtons[selectedIndex].showResult(true);
// Progressive scoring based on phase and question difficulty
var difficultyMultiplier = 1 + questionDifficulty * 0.5; // 1x, 1.5x, 2x, 2.5x
var pointsEarned = Math.floor(SCORE_BASE[currentPhase] * difficultyMultiplier);
score += pointsEarned;
scoreText.setText('Score: ' + score);
LK.setScore(score);
// Show points earned
var pointsText = new Text2('+' + pointsEarned, {
size: 48,
fill: 0x00FF00
});
pointsText.anchor.set(0.5, 0.5);
pointsText.x = optionButtons[selectedIndex].x;
pointsText.y = optionButtons[selectedIndex].y - 100;
game.addChild(pointsText);
tween(pointsText, {
y: pointsText.y - 50,
alpha: 0
}, {
duration: ANIMATION_DURATION.MEDIUM,
onFinish: function onFinish() {
pointsText.destroy();
}
});
// Check for unlocks
if (score >= UNLOCK_THRESHOLDS.GUARDIAN && !guardianMode) {
guardianMode = true;
storage.guardianUnlocked = true;
LK.getSound('unlock').play();
showUnlockMessage("Guardian's Challenge Unlocked!");
}
if (score >= UNLOCK_THRESHOLDS.DARKNESS && !darknessMode) {
darknessMode = true;
storage.darknessUnlocked = true;
LK.getSound('unlock').play();
showUnlockMessage("Darkness Mode Unlocked!");
}
if (score >= UNLOCK_THRESHOLDS.TIMER && !timerMode) {
timerMode = true;
storage.timerUnlocked = true;
LK.getSound('unlock').play();
showUnlockMessage("Timer Mode Unlocked!");
}
} else {
LK.getSound('wrong').play();
optionButtons[selectedIndex].showResult(false);
lives--;
updateLives();
if (lives <= 0) {
LK.showGameOver();
return;
}
}
// Save high score
if (score > (storage.highScore || 0)) {
storage.highScore = score;
}
// Next question after delay
LK.setTimeout(function () {
// Clear indicators
for (var i = 0; i < 4; i++) {
if (optionButtons[i].correctIndicator) {
optionButtons[i].correctIndicator.destroy();
optionButtons[i].correctIndicator = null;
}
if (optionButtons[i].wrongIndicator) {
optionButtons[i].wrongIndicator.destroy();
optionButtons[i].wrongIndicator = null;
}
}
loadQuestion();
}, ANIMATION_DURATION.LONG);
}
function checkTacticalAnswer(selectedIndex) {
var correct = optionButtons[selectedIndex].isCorrect;
if (correct) {
LK.getSound('correct').play();
optionButtons[selectedIndex].showResult(true);
consecutiveCorrect++;
// Guardian attacks enemy
var damage = 25;
// Class-specific abilities
if (guardianClass === 0 && guardianEnergy >= 2) {
// Titan shield
shieldActive = true;
guardianEnergy -= 2;
showBattleMessage("Titan Shield Activated!");
} else if (guardianClass === 1 && consecutiveCorrect >= 2) {
// Hunter double attack
damage *= 2;
consecutiveCorrect = 0;
showBattleMessage("Hunter Double Strike!");
} else if (guardianClass === 2 && guardianEnergy >= 1) {
// Warlock heal
guardianHealth = Math.min(guardianMaxHealth, guardianHealth + 15);
guardianEnergy -= 1;
damage += 10; // Area damage bonus
showBattleMessage("Warlock Healing + Area Damage!");
}
enemyHealth -= damage;
guardianEnergy = Math.min(guardianMaxEnergy, guardianEnergy + 1);
score += 10;
if (enemyHealth <= 0) {
// Enemy defeated
currentEnemy++;
if (currentEnemy >= enemies.length) {
showBattleMessage("All enemies defeated! Victory!");
LK.setTimeout(function () {
LK.showYouWin();
}, 2000);
return;
} else {
// Next enemy
var nextEnemy = enemies[currentEnemy];
enemyHealth = nextEnemy.health;
enemyMaxHealth = nextEnemy.health;
showBattleMessage("Enemy defeated! Next: " + nextEnemy.name);
}
}
} else {
LK.getSound('wrong').play();
optionButtons[selectedIndex].showResult(false);
consecutiveCorrect = 0;
guardianEnergy = Math.max(0, guardianEnergy - 1);
}
updateTacticalUI();
// Enemy turn after delay
LK.setTimeout(function () {
if (enemyHealth > 0) {
enemyTurn();
}
LK.setTimeout(function () {
clearBattleIndicators();
loadTacticalQuestion();
}, ANIMATION_DURATION.MEDIUM);
}, ANIMATION_DURATION.LONG);
}
function enemyTurn() {
var enemy = enemies[currentEnemy];
var turnIndex = battleTurn % enemy.pattern.length;
var action = enemy.pattern[turnIndex];
battleTurn++;
if (action === "attack") {
var damage = enemy.damage;
if (shieldActive && guardianClass === 0) {
damage = Math.floor(damage * 0.5);
shieldActive = false;
showBattleMessage("Shield absorbed damage!");
} else {
showBattleMessage(enemy.name + " attacks for " + damage + " damage!");
}
guardianHealth -= damage;
} else if (action === "special") {
var damage = Math.floor(enemy.damage * 1.5);
showBattleMessage(enemy.name + " uses special attack!");
guardianHealth -= damage;
} else if (action === "defend") {
showBattleMessage(enemy.name + " defends and recovers!");
enemyHealth = Math.min(enemyMaxHealth, enemyHealth + 10);
}
if (guardianHealth <= 0) {
showBattleMessage("Guardian defeated!");
LK.setTimeout(function () {
LK.showGameOver();
}, 2000);
}
updateTacticalUI();
}
function updateTacticalUI() {
// Update all UI elements with current stats
// This is a simplified version - in a full implementation,
// you'd store references to UI elements and update them
}
function showBattleMessage(message) {
var battleText = new Text2(message, {
size: 36,
fill: 0xFFD700
});
battleText.anchor.set(0.5, 0.5);
battleText.x = 1024;
battleText.y = 500;
battleText.alpha = 0;
game.addChild(battleText);
tween(battleText, {
alpha: 1
}, {
duration: 300,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(battleText, {
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
battleText.destroy();
}
});
}, 1500);
}
});
}
function clearBattleIndicators() {
for (var i = 0; i < 4; i++) {
if (optionButtons[i].correctIndicator) {
optionButtons[i].correctIndicator.destroy();
optionButtons[i].correctIndicator = null;
}
if (optionButtons[i].wrongIndicator) {
optionButtons[i].wrongIndicator.destroy();
optionButtons[i].wrongIndicator = null;
}
}
}
function updateLives() {
var hearts = '';
for (var i = 0; i < lives; i++) {
hearts += '❤';
}
livesText.setText('Lives: ' + hearts);
}
function showUnlockMessage(message) {
var unlockText = new Text2(message, {
size: 72,
fill: 0xFFD700
});
unlockText.anchor.set(0.5, 0.5);
unlockText.x = 1024;
unlockText.y = 1366;
unlockText.alpha = 0;
game.addChild(unlockText);
tween(unlockText, {
alpha: 1,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: ANIMATION_DURATION.SHORT,
easing: tween.easeOut,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(unlockText, {
alpha: 0
}, {
duration: ANIMATION_DURATION.SHORT,
onFinish: function onFinish() {
unlockText.destroy();
}
});
}, ANIMATION_DURATION.EXTRA_LONG);
}
});
}
function checkAchievements() {
var rank = 0;
if (score >= 21) {
rank = 1;
}
if (score >= 51) {
rank = 2;
}
if (score >= 76) {
rank = 3;
}
var achievementText = new Text2('Rank: ' + rankNames[rank], {
size: 96,
fill: 0xFFD700
});
achievementText.anchor.set(0.5, 0.5);
achievementText.x = 1024;
achievementText.y = 1366;
game.addChild(achievementText);
if (score >= UNLOCK_THRESHOLDS.WIN) {
LK.showYouWin();
} else {
LK.setTimeout(function () {
LK.showGameOver();
}, ANIMATION_DURATION.GAME_OVER_DELAY);
}
}
game.update = function () {
// Update timer for all modes when answering is allowed
if (canAnswer && timerStartTime > 0) {
// Calculate elapsed time in milliseconds
var elapsedTime = Date.now() - timerStartTime;
var elapsedFrames = Math.floor(elapsedTime / (1000 / 60)); // Convert to frames (60 FPS)
var remainingFrames = timerCount - elapsedFrames;
// Update timer display
if (timerDisplay) {
var remainingSeconds = Math.max(0, Math.ceil(remainingFrames / 60));
timerDisplay.setText('Time: ' + remainingSeconds + 's');
// Change color when time is running low
if (remainingSeconds <= 10) {
timerDisplay.tint = 0xFF6B6B; // Red when low
} else if (remainingSeconds <= 20) {
timerDisplay.tint = 0xFFD700; // Yellow when moderate
} else {
timerDisplay.tint = 0x5EB3FF; // Blue when plenty
}
}
if (remainingFrames <= 0) {
// Time's up
canAnswer = false;
timerStartTime = 0;
// In timer mode, losing a life. In other modes, just move to next question
if (timerMode) {
lives--;
updateLives();
LK.getSound('wrong').play();
if (lives <= 0) {
LK.showGameOver();
return;
}
} else {
// In non-timer modes, just show a visual indication and move on
LK.getSound('wrong').play();
}
LK.setTimeout(function () {
loadQuestion();
}, ANIMATION_DURATION.MEDIUM);
}
}
};
// Initialize the game
initializeGame(); ===================================================================
--- original.js
+++ change.js
@@ -395,13 +395,122 @@
}]
};
var phaseNames = ["Javi", "Rodri", "Diego", "Nadie la sabe"];
var rankNames = ["Light Bearer", "Disciple of Osiris", "Wisdom Devourer", "Archive Legend"];
+// Tactical mode variables
+var tacticalMode = false;
+var guardianClass = 0; // 0: Titan, 1: Hunter, 2: Warlock
+var guardianHealth = 100;
+var guardianMaxHealth = 100;
+var guardianEnergy = 3;
+var guardianMaxEnergy = 3;
+var enemyHealth = 80;
+var enemyMaxHealth = 80;
+var currentEnemy = 0;
+var battleTurn = 0; // 0: player turn, 1: enemy turn
+var consecutiveCorrect = 0;
+var shieldActive = false;
+var hunterDoubleAttack = false;
+var enemies = [{
+ name: "Cabal Legionary",
+ health: 60,
+ damage: 15,
+ pattern: ["attack", "attack", "defend"],
+ weakness: "Cabal"
+}, {
+ name: "Hive Knight",
+ health: 80,
+ damage: 20,
+ pattern: ["attack", "special", "attack"],
+ weakness: "Hive"
+}, {
+ name: "Vex Minotaur",
+ health: 100,
+ damage: 25,
+ pattern: ["defend", "attack", "special"],
+ weakness: "Vex"
+}, {
+ name: "Fallen Captain",
+ health: 70,
+ damage: 18,
+ pattern: ["attack", "attack", "special"],
+ weakness: "Fallen"
+}];
+var classNames = ["Titan", "Hunter", "Warlock"];
+var classColors = [0xFF6B6B, 0x5EB3FF, 0x9B59B6];
function initializeGame() {
- // Show menu first
- showDifficultyMenu();
+ // Show game mode selection first
+ showGameModeMenu();
LK.playMusic('ambient');
}
+function showGameModeMenu() {
+ inMenu = true;
+ // Title
+ var titleText = new Text2('Destiny 2', {
+ size: 96,
+ fill: 0xFFD700
+ });
+ titleText.anchor.set(0.5, 0.5);
+ titleText.x = 1024;
+ titleText.y = 400;
+ game.addChild(titleText);
+ // Subtitle
+ var subtitleText = new Text2('¿Qué quieres jugar?', {
+ size: 56,
+ fill: 0xFFFFFF
+ });
+ subtitleText.anchor.set(0.5, 0.5);
+ subtitleText.x = 1024;
+ subtitleText.y = 600;
+ game.addChild(subtitleText);
+ // Trivia mode button
+ var triviaButton = game.addChild(new MenuButton());
+ triviaButton.x = 1024;
+ triviaButton.y = 900;
+ triviaButton.setButton('Trivia Clásico', 0);
+ triviaButton.buttonText.tint = 0x5EB3FF;
+ var triviaDesc = new Text2('El juego de trivia tradicional', {
+ size: 32,
+ fill: 0xAAAAAA
+ });
+ triviaDesc.anchor.set(0.5, 0.5);
+ triviaDesc.x = 1024;
+ triviaDesc.y = 950;
+ game.addChild(triviaDesc);
+ // Tactical RPG mode button
+ var rpgButton = game.addChild(new MenuButton());
+ rpgButton.x = 1024;
+ rpgButton.y = 1200;
+ rpgButton.setButton('Forja de Leyendas', 1);
+ rpgButton.buttonText.tint = 0xFF6B6B;
+ var rpgDesc = new Text2('Trivia con mecánicas de combate táctico', {
+ size: 32,
+ fill: 0xAAAAAA
+ });
+ rpgDesc.anchor.set(0.5, 0.5);
+ rpgDesc.x = 1024;
+ rpgDesc.y = 1250;
+ game.addChild(rpgDesc);
+ // Override button actions
+ triviaButton.down = function (x, y, obj) {
+ if (inMenu) {
+ // Clear menu
+ while (game.children.length > 0) {
+ game.children[0].destroy();
+ }
+ showDifficultyMenu();
+ }
+ };
+ rpgButton.down = function (x, y, obj) {
+ if (inMenu) {
+ // Clear menu
+ while (game.children.length > 0) {
+ game.children[0].destroy();
+ }
+ showClassSelectionMenu();
+ }
+ };
+}
function showDifficultyMenu() {
inMenu = true;
// Title
var titleText = new Text2('Destiny 2', {
@@ -483,8 +592,71 @@
unlockedText.y = 2050;
game.addChild(unlockedText);
}
}
+function showClassSelectionMenu() {
+ inMenu = true;
+ // Title
+ var titleText = new Text2('Forja de Leyendas', {
+ size: 96,
+ fill: 0xFF6B6B
+ });
+ titleText.anchor.set(0.5, 0.5);
+ titleText.x = 1024;
+ titleText.y = 400;
+ game.addChild(titleText);
+ // Subtitle
+ var subtitleText = new Text2('Elige tu clase de Guardián', {
+ size: 48,
+ fill: 0xFFFFFF
+ });
+ subtitleText.anchor.set(0.5, 0.5);
+ subtitleText.x = 1024;
+ subtitleText.y = 600;
+ game.addChild(subtitleText);
+ var classes = [{
+ name: 'Titan',
+ color: 0xFF6B6B,
+ desc: 'Escudo extra que absorbe daño'
+ }, {
+ name: 'Hunter',
+ color: 0x5EB3FF,
+ desc: 'Doble ataque con respuestas consecutivas'
+ }, {
+ name: 'Warlock',
+ color: 0x9B59B6,
+ desc: 'Curación y daño en área'
+ }];
+ for (var i = 0; i < 3; i++) {
+ var classBtn = game.addChild(new MenuButton());
+ classBtn.x = 1024;
+ classBtn.y = 900 + i * 200;
+ classBtn.setButton(classes[i].name, i);
+ classBtn.buttonText.tint = classes[i].color;
+ var descText = new Text2(classes[i].desc, {
+ size: 32,
+ fill: 0xAAAAAA
+ });
+ descText.anchor.set(0.5, 0.5);
+ descText.x = 1024;
+ descText.y = 950 + i * 200;
+ game.addChild(descText);
+ }
+ // Override all class button actions to start tactical mode
+ for (var i = 0; i < game.children.length; i++) {
+ if (game.children[i].setButton) {
+ game.children[i].down = function (x, y, obj) {
+ if (inMenu) {
+ // Clear menu
+ while (game.children.length > 0) {
+ game.children[0].destroy();
+ }
+ startTacticalMode(this.difficulty);
+ }
+ };
+ }
+ }
+}
function startGameWithDifficulty(difficulty) {
if (!inMenu) {
return;
}
@@ -567,8 +739,98 @@
timerStartTime = 0;
// Start game
loadQuestion();
}
+function startTacticalMode(selectedClass) {
+ if (!inMenu) return;
+ inMenu = false;
+ tacticalMode = true;
+ guardianClass = selectedClass;
+ // Reset tactical state
+ guardianHealth = guardianMaxHealth;
+ guardianEnergy = guardianMaxEnergy;
+ currentEnemy = 0;
+ battleTurn = 0;
+ consecutiveCorrect = 0;
+ shieldActive = false;
+ hunterDoubleAttack = false;
+ score = 0;
+ currentQuestion = 0;
+ // Setup enemy
+ var enemy = enemies[currentEnemy];
+ enemyHealth = enemy.health;
+ enemyMaxHealth = enemy.health;
+ // Initialize tactical UI
+ setupTacticalUI();
+ loadTacticalQuestion();
+}
+function setupTacticalUI() {
+ // Question display
+ questionDisplay = game.addChild(new QuestionDisplay());
+ questionDisplay.x = 1024;
+ questionDisplay.y = 800;
+ // Option buttons
+ optionButtons = [];
+ for (var i = 0; i < 4; i++) {
+ var button = game.addChild(new OptionButton());
+ button.x = 520 + i % 2 * 1000;
+ button.y = 1400 + Math.floor(i / 2) * 200;
+ optionButtons.push(button);
+ }
+ // Guardian info
+ var guardianInfo = new Text2(classNames[guardianClass] + ' Guardian', {
+ size: 48,
+ fill: classColors[guardianClass]
+ });
+ guardianInfo.anchor.set(0, 0);
+ guardianInfo.x = 50;
+ guardianInfo.y = 100;
+ game.addChild(guardianInfo);
+ // Health bars
+ var guardianHealthBar = new Text2('Health: ' + guardianHealth + '/' + guardianMaxHealth, {
+ size: 36,
+ fill: 0x00FF00
+ });
+ guardianHealthBar.anchor.set(0, 0);
+ guardianHealthBar.x = 50;
+ guardianHealthBar.y = 200;
+ game.addChild(guardianHealthBar);
+ var energyBar = new Text2('Energy: ' + guardianEnergy + '/' + guardianMaxEnergy, {
+ size: 36,
+ fill: 0x5EB3FF
+ });
+ energyBar.anchor.set(0, 0);
+ energyBar.x = 50;
+ energyBar.y = 250;
+ game.addChild(energyBar);
+ // Enemy info
+ var enemy = enemies[currentEnemy];
+ var enemyInfo = new Text2(enemy.name, {
+ size: 48,
+ fill: 0xFF6B6B
+ });
+ enemyInfo.anchor.set(1, 0);
+ enemyInfo.x = 1998;
+ enemyInfo.y = 100;
+ game.addChild(enemyInfo);
+ var enemyHealthBar = new Text2('Health: ' + enemyHealth + '/' + enemyMaxHealth, {
+ size: 36,
+ fill: 0xFF6B6B
+ });
+ enemyHealthBar.anchor.set(1, 0);
+ enemyHealthBar.x = 1998;
+ enemyHealthBar.y = 200;
+ game.addChild(enemyHealthBar);
+ // Battle status
+ var battleStatus = new Text2('Your Turn - Answer to Attack!', {
+ size: 40,
+ fill: 0xFFD700
+ });
+ battleStatus.anchor.set(0.5, 0);
+ battleStatus.x = 1024;
+ battleStatus.y = 400;
+ game.addChild(battleStatus);
+}
function loadQuestion() {
canAnswer = true;
currentQuestion++;
// Calculate question difficulty based on progress
@@ -653,14 +915,53 @@
// Initialize 60-second timer for all questions
timerCount = TIMER_BASE; // Always 60 seconds
timerStartTime = Date.now();
}
+function loadTacticalQuestion() {
+ if (!tacticalMode) return;
+ canAnswer = true;
+ currentQuestion++;
+ // Select question based on enemy weakness or general knowledge
+ var enemy = enemies[currentEnemy];
+ var questionPool = [];
+ // Add questions from all phases for variety
+ for (var phase = 0; phase < 4; phase++) {
+ for (var i = 0; i < questions[phase].length; i++) {
+ questionPool.push(questions[phase][i]);
+ }
+ }
+ // Randomly select a question
+ var selectedQuestion = questionPool[Math.floor(Math.random() * questionPool.length)];
+ questionDisplay.setQuestion(selectedQuestion.q);
+ // Shuffle options
+ var indices = [0, 1, 2, 3];
+ var shuffledIndices = [];
+ var tempIndices = indices.slice();
+ while (tempIndices.length > 0) {
+ var randomIndex = Math.floor(Math.random() * tempIndices.length);
+ shuffledIndices.push(tempIndices[randomIndex]);
+ tempIndices.splice(randomIndex, 1);
+ }
+ // Set options
+ for (var i = 0; i < 4; i++) {
+ var originalIndex = shuffledIndices[i];
+ optionButtons[i].setOption(selectedQuestion.options[originalIndex], originalIndex, originalIndex === selectedQuestion.correct);
+ optionButtons[i].buttonPosition = i;
+ }
+ // Initialize timer
+ timerCount = TIMER_BASE;
+ timerStartTime = Date.now();
+}
function checkAnswer(selectedIndex) {
if (!canAnswer) {
return;
}
canAnswer = false;
timerStartTime = 0; // Stop timer when answer is selected
+ if (tacticalMode) {
+ checkTacticalAnswer(selectedIndex);
+ return;
+ }
var correct = optionButtons[selectedIndex].isCorrect;
// Darkness mode inverts correct answers
if (darknessMode) {
correct = !correct;
@@ -740,8 +1041,148 @@
}
loadQuestion();
}, ANIMATION_DURATION.LONG);
}
+function checkTacticalAnswer(selectedIndex) {
+ var correct = optionButtons[selectedIndex].isCorrect;
+ if (correct) {
+ LK.getSound('correct').play();
+ optionButtons[selectedIndex].showResult(true);
+ consecutiveCorrect++;
+ // Guardian attacks enemy
+ var damage = 25;
+ // Class-specific abilities
+ if (guardianClass === 0 && guardianEnergy >= 2) {
+ // Titan shield
+ shieldActive = true;
+ guardianEnergy -= 2;
+ showBattleMessage("Titan Shield Activated!");
+ } else if (guardianClass === 1 && consecutiveCorrect >= 2) {
+ // Hunter double attack
+ damage *= 2;
+ consecutiveCorrect = 0;
+ showBattleMessage("Hunter Double Strike!");
+ } else if (guardianClass === 2 && guardianEnergy >= 1) {
+ // Warlock heal
+ guardianHealth = Math.min(guardianMaxHealth, guardianHealth + 15);
+ guardianEnergy -= 1;
+ damage += 10; // Area damage bonus
+ showBattleMessage("Warlock Healing + Area Damage!");
+ }
+ enemyHealth -= damage;
+ guardianEnergy = Math.min(guardianMaxEnergy, guardianEnergy + 1);
+ score += 10;
+ if (enemyHealth <= 0) {
+ // Enemy defeated
+ currentEnemy++;
+ if (currentEnemy >= enemies.length) {
+ showBattleMessage("All enemies defeated! Victory!");
+ LK.setTimeout(function () {
+ LK.showYouWin();
+ }, 2000);
+ return;
+ } else {
+ // Next enemy
+ var nextEnemy = enemies[currentEnemy];
+ enemyHealth = nextEnemy.health;
+ enemyMaxHealth = nextEnemy.health;
+ showBattleMessage("Enemy defeated! Next: " + nextEnemy.name);
+ }
+ }
+ } else {
+ LK.getSound('wrong').play();
+ optionButtons[selectedIndex].showResult(false);
+ consecutiveCorrect = 0;
+ guardianEnergy = Math.max(0, guardianEnergy - 1);
+ }
+ updateTacticalUI();
+ // Enemy turn after delay
+ LK.setTimeout(function () {
+ if (enemyHealth > 0) {
+ enemyTurn();
+ }
+ LK.setTimeout(function () {
+ clearBattleIndicators();
+ loadTacticalQuestion();
+ }, ANIMATION_DURATION.MEDIUM);
+ }, ANIMATION_DURATION.LONG);
+}
+function enemyTurn() {
+ var enemy = enemies[currentEnemy];
+ var turnIndex = battleTurn % enemy.pattern.length;
+ var action = enemy.pattern[turnIndex];
+ battleTurn++;
+ if (action === "attack") {
+ var damage = enemy.damage;
+ if (shieldActive && guardianClass === 0) {
+ damage = Math.floor(damage * 0.5);
+ shieldActive = false;
+ showBattleMessage("Shield absorbed damage!");
+ } else {
+ showBattleMessage(enemy.name + " attacks for " + damage + " damage!");
+ }
+ guardianHealth -= damage;
+ } else if (action === "special") {
+ var damage = Math.floor(enemy.damage * 1.5);
+ showBattleMessage(enemy.name + " uses special attack!");
+ guardianHealth -= damage;
+ } else if (action === "defend") {
+ showBattleMessage(enemy.name + " defends and recovers!");
+ enemyHealth = Math.min(enemyMaxHealth, enemyHealth + 10);
+ }
+ if (guardianHealth <= 0) {
+ showBattleMessage("Guardian defeated!");
+ LK.setTimeout(function () {
+ LK.showGameOver();
+ }, 2000);
+ }
+ updateTacticalUI();
+}
+function updateTacticalUI() {
+ // Update all UI elements with current stats
+ // This is a simplified version - in a full implementation,
+ // you'd store references to UI elements and update them
+}
+function showBattleMessage(message) {
+ var battleText = new Text2(message, {
+ size: 36,
+ fill: 0xFFD700
+ });
+ battleText.anchor.set(0.5, 0.5);
+ battleText.x = 1024;
+ battleText.y = 500;
+ battleText.alpha = 0;
+ game.addChild(battleText);
+ tween(battleText, {
+ alpha: 1
+ }, {
+ duration: 300,
+ onFinish: function onFinish() {
+ LK.setTimeout(function () {
+ tween(battleText, {
+ alpha: 0
+ }, {
+ duration: 300,
+ onFinish: function onFinish() {
+ battleText.destroy();
+ }
+ });
+ }, 1500);
+ }
+ });
+}
+function clearBattleIndicators() {
+ for (var i = 0; i < 4; i++) {
+ if (optionButtons[i].correctIndicator) {
+ optionButtons[i].correctIndicator.destroy();
+ optionButtons[i].correctIndicator = null;
+ }
+ if (optionButtons[i].wrongIndicator) {
+ optionButtons[i].wrongIndicator.destroy();
+ optionButtons[i].wrongIndicator = null;
+ }
+ }
+}
function updateLives() {
var hearts = '';
for (var i = 0; i < lives; i++) {
hearts += '❤';