/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { level: 1, highScore: 0 }); /**** * Classes ****/ var HintButton = Container.expand(function () { var self = Container.call(this); var buttonBackground = self.attachAsset('light', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 0.6 }); buttonBackground.tint = 0x3498db; // Blue color var hintText = new Text2("HINT", { size: 50, fill: 0xFFFFFF }); hintText.anchor.set(0.5, 0.5); self.addChild(hintText); self.enabled = true; self.disable = function () { self.enabled = false; buttonBackground.alpha = 0.3; hintText.alpha = 0.3; }; self.enable = function () { self.enabled = true; buttonBackground.alpha = 1; hintText.alpha = 1; }; self.down = function (x, y, obj) { if (!self.enabled) { return; } // Provide visual feedback buttonBackground.alpha = 0.7; tween(buttonBackground, { alpha: 1 }, { duration: 200 }); // Call the onPressed callback if it exists if (typeof self.onPressed === 'function') { self.onPressed(); } }; return self; }); var Light = Container.expand(function () { var self = Container.call(this); var lightGraphics = self.attachAsset('light', { anchorX: 0.5, anchorY: 0.5, alpha: 0.6 // Brighter by default }); self.isActive = false; self.originalColor = 0xffffff; self.originalTint = lightGraphics.tint; self.setColor = function (colorHex) { self.originalColor = colorHex; lightGraphics.tint = colorHex; }; self.activate = function (duration) { self.isActive = true; // Stop any ongoing tweens tween.stop(lightGraphics, { alpha: true, tint: true }); // Flash the light lightGraphics.alpha = 1; // Play the light sound LK.getSound('lightOn').play(); // After duration, dim the light tween(lightGraphics, { alpha: 0.4 }, { duration: duration || 500, onFinish: function onFinish() { self.isActive = false; } }); }; self.highlight = function () { // Short highlight for user feedback when pressed lightGraphics.alpha = 1; tween(lightGraphics, { alpha: 0.4 }, { duration: 200 }); }; self.down = function (x, y, obj) { // Callback to handle when this light is pressed self.highlight(); // Delegate to game logic if (typeof self.onLightPressed === 'function') { self.onLightPressed(self); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1c2833 // Dark blue background }); /**** * Game Code ****/ // Game configuration var config = { gridSize: 3, // Starting grid size (3x3) maxGridSize: 5, // Maximum grid size (for harder levels) initialSequenceLength: 2, // Start with 2 light patterns maxLives: 3, // Player gets 3 chances hintAllowed: true, // Allow one hint per level colors: [0xff5252, // Red 0x4caf50, // Green 0x2196f3, // Blue 0xffeb3b, // Yellow 0xe040fb // Purple ], timeBetweenLights: 800, // Time between showing each light in the sequence (ms) timeBeforeStart: 1500 // Time before starting a new sequence (ms) }; // Game state var state = { level: 1, currentSequence: [], // The sequence to memorize playerSequence: [], // The player's input sequence sequenceIndex: 0, // Current position in playback/verification lives: config.maxLives, hintUsed: false, // Has the hint been used this level isShowingSequence: false, // Are we currently showing a sequence? isPlayerTurn: false, // Is it the player's turn to repeat the sequence? gridElements: [], // Store grid elements for easy access gameStarted: false // Has the game started yet? }; // UI Elements var grid = new Container(); var uiContainer = new Container(); var levelText; var livesText; var scoreText; var hintButton; // Initialize the game function initGame() { // Start background music LK.playMusic('bgMusic', { fade: { start: 0, end: 0.5, duration: 1000 } }); // Setup UI setupUI(); // Create the grid of lights createGrid(); // Position the grid in the center of the screen positionGrid(); // Add UI and grid to the game game.addChild(grid); game.addChild(uiContainer); // Show start screen showStartScreen(); } function setupUI() { // Level indicator levelText = new Text2("Level: 1", { size: 80, fill: 0xFFFFFF }); levelText.anchor.set(0.5, 0); LK.gui.top.addChild(levelText); levelText.y = 100; // Lives indicator livesText = new Text2("Lives: " + state.lives, { size: 70, fill: 0xFFFFFF }); livesText.anchor.set(0, 0); LK.gui.topLeft.addChild(livesText); livesText.x = 120; // Avoid the menu icon in top left livesText.y = 100; // Score (current level) scoreText = new Text2("Score: 0", { size: 70, fill: 0xFFFFFF }); scoreText.anchor.set(1, 0); LK.gui.topRight.addChild(scoreText); scoreText.x = -50; scoreText.y = 100; // Hint button hintButton = new HintButton(); uiContainer.addChild(hintButton); hintButton.x = 2048 / 2; hintButton.y = 2732 - 200; // Set up hint button callback hintButton.onPressed = function () { if (!state.hintUsed && state.isPlayerTurn) { showHint(); } }; } function createGrid() { var currentGridSize = Math.min(config.gridSize + Math.floor((state.level - 1) / 5), config.maxGridSize); var lightSize = 200; var padding = 80; // Further increased padding for even better spacing var totalWidth = (lightSize + padding) * currentGridSize - padding; // Clear existing grid if any while (grid.children.length > 0) { grid.removeChild(grid.children[0]); } state.gridElements = []; // Create the new grid for (var row = 0; row < currentGridSize; row++) { for (var col = 0; col < currentGridSize; col++) { var light = new Light(); light.x = col * (lightSize + padding); light.y = row * (lightSize + padding); light.gridRow = row; light.gridCol = col; // Assign a color to the light var colorIndex = (row * currentGridSize + col) % config.colors.length; light.setColor(config.colors[colorIndex]); // Add callback for when the light is pressed light.onLightPressed = onLightPressed; grid.addChild(light); state.gridElements.push(light); } } // Update grid container width and height for positioning grid.width = totalWidth; grid.height = totalWidth; } function positionGrid() { // Center the grid on the screen grid.x = (2048 - grid.width) / 2; grid.y = (2732 - grid.height) / 2; } function showStartScreen() { var startText = new Text2("Tap to Start", { size: 100, fill: 0xFFFFFF }); startText.anchor.set(0.5, 0.5); startText.x = 2048 / 2; startText.y = 2732 / 2; game.addChild(startText); // Make it pulse function pulse() { tween(startText, { alpha: 0.5 }, { duration: 800, onFinish: function onFinish() { tween(startText, { alpha: 1 }, { duration: 800, onFinish: pulse }); } }); } pulse(); // Start game on tap var _startHandler = function startHandler(x, y, obj) { game.removeChild(startText); game.off('down', _startHandler); startGame(); }; game.on('down', _startHandler); } function startGame() { state.gameStarted = true; resetGame(); startLevel(); } function resetGame() { state.level = 1; state.lives = config.maxLives; updateUI(); createGrid(); positionGrid(); } function startLevel() { state.currentSequence = []; state.playerSequence = []; state.sequenceIndex = 0; state.hintUsed = false; state.isShowingSequence = false; state.isPlayerTurn = false; // Update UI updateUI(); // Enable hint button for this level hintButton.enable(); // Generate a new sequence generateSequence(); // Wait a moment, then show the sequence LK.setTimeout(function () { showSequence(); }, config.timeBeforeStart); } function updateUI() { levelText.setText("Level: " + state.level); livesText.setText("Lives: " + state.lives); scoreText.setText("Score: " + (state.level - 1)); // Save high score if needed if (state.level - 1 > storage.highScore) { storage.highScore = state.level - 1; } } function generateSequence() { var sequenceLength = config.initialSequenceLength + state.level - 1; var gridSize = state.gridElements.length; // Generate random sequence for (var i = 0; i < sequenceLength; i++) { var randomIndex = Math.floor(Math.random() * gridSize); state.currentSequence.push(randomIndex); } } function showSequence() { state.isShowingSequence = true; state.sequenceIndex = 0; // Show the "Watch" text var watchText = new Text2("Watch!", { size: 100, fill: 0xFFFFFF }); watchText.anchor.set(0.5, 0.5); watchText.x = 2048 / 2; watchText.y = grid.y - 150; game.addChild(watchText); // Function to show each light in sequence function showNextLight() { if (state.sequenceIndex < state.currentSequence.length) { var lightIndex = state.currentSequence[state.sequenceIndex]; var light = state.gridElements[lightIndex]; light.activate(config.timeBetweenLights * 0.8); state.sequenceIndex++; // Schedule next light LK.setTimeout(showNextLight, config.timeBetweenLights); } else { // Sequence complete state.isShowingSequence = false; state.isPlayerTurn = true; state.sequenceIndex = 0; // Remove the watch text game.removeChild(watchText); // Show the "Your Turn" text var turnText = new Text2("Your Turn!", { size: 100, fill: 0xFFFFFF }); turnText.anchor.set(0.5, 0.5); turnText.x = 2048 / 2; turnText.y = grid.y - 150; game.addChild(turnText); // Fade out the text after a moment tween(turnText, { alpha: 0 }, { duration: 1500, onFinish: function onFinish() { game.removeChild(turnText); } }); } } // Start showing sequence showNextLight(); } function onLightPressed(light) { if (!state.isPlayerTurn) { return; } // Find the index of this light in our grid var lightIndex = state.gridElements.indexOf(light); if (lightIndex === -1) { return; } // Add to player sequence state.playerSequence.push(lightIndex); // Check if this press was correct var currentIndex = state.playerSequence.length - 1; if (state.playerSequence[currentIndex] === state.currentSequence[currentIndex]) { // Correct! // Check if sequence is complete if (state.playerSequence.length === state.currentSequence.length) { // Level completed! LK.getSound('success').play(); state.isPlayerTurn = false; // Show success message var successText = new Text2("Success!", { size: 120, fill: 0x2ECC71 // Green }); successText.anchor.set(0.5, 0.5); successText.x = 2048 / 2; successText.y = grid.y - 150; game.addChild(successText); // Blink the entire grid to show success for (var i = 0; i < state.gridElements.length; i++) { var currentLight = state.gridElements[i]; currentLight.activate(300); } // Show celebration popup if no lives were lost if (state.lives === config.maxLives) { var celebrationText = new Text2("Perfect Level!", { size: 120, fill: 0xFFD700 // Gold }); celebrationText.anchor.set(0.5, 0.5); celebrationText.x = 2048 / 2; celebrationText.y = grid.y - 300; game.addChild(celebrationText); tween(celebrationText, { alpha: 0 }, { duration: 2000, onFinish: function onFinish() { game.removeChild(celebrationText); } }); } // Move to next level LK.setTimeout(function () { game.removeChild(successText); state.level++; // Every 5 levels, sound a special effect and show a celebration if (state.level % 5 === 1) { LK.getSound('levelUp').play(); // Flash the screen LK.effects.flashScreen(0x2ecc71, 500); // Recreate grid with potentially new size createGrid(); positionGrid(); } startLevel(); }, 1500); } } else { // Incorrect! LK.getSound('failure').play(); state.isPlayerTurn = false; // Flash the screen red LK.effects.flashScreen(0xe74c3c, 300); // Show incorrect message var incorrectText = new Text2("Incorrect!", { size: 120, fill: 0xE74C3C // Red }); incorrectText.anchor.set(0.5, 0.5); incorrectText.x = 2048 / 2; incorrectText.y = grid.y - 150; game.addChild(incorrectText); // Lose a life state.lives--; updateUI(); LK.setTimeout(function () { game.removeChild(incorrectText); if (state.lives <= 0) { // Game over gameOver(); } else { // Try again startLevel(); } }, 1500); } } function showHint() { if (state.hintUsed) { return; } state.hintUsed = true; hintButton.disable(); // Temporarily disable player input var wasPlayerTurn = state.isPlayerTurn; state.isPlayerTurn = false; // Show the hint sequence but faster var fastTimeBetweenLights = config.timeBetweenLights * 0.6; var hintIndex = 0; // Show hint text var hintText = new Text2("Hint!", { size: 100, fill: 0xF39C12 // Orange }); hintText.anchor.set(0.5, 0.5); hintText.x = 2048 / 2; hintText.y = grid.y - 150; game.addChild(hintText); function showNextHintLight() { if (hintIndex < state.currentSequence.length) { var lightIndex = state.currentSequence[hintIndex]; var light = state.gridElements[lightIndex]; light.activate(fastTimeBetweenLights * 0.8); hintIndex++; // Schedule next light LK.setTimeout(showNextHintLight, fastTimeBetweenLights); } else { // Hint complete, restore player's turn state.isPlayerTurn = wasPlayerTurn; // Remove the hint text tween(hintText, { alpha: 0 }, { duration: 500, onFinish: function onFinish() { game.removeChild(hintText); } }); } } // Start showing hint showNextHintLight(); } function gameOver() { LK.showGameOver(); } // Initialize the game initGame();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
level: 1,
highScore: 0
});
/****
* Classes
****/
var HintButton = Container.expand(function () {
var self = Container.call(this);
var buttonBackground = self.attachAsset('light', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 0.6
});
buttonBackground.tint = 0x3498db; // Blue color
var hintText = new Text2("HINT", {
size: 50,
fill: 0xFFFFFF
});
hintText.anchor.set(0.5, 0.5);
self.addChild(hintText);
self.enabled = true;
self.disable = function () {
self.enabled = false;
buttonBackground.alpha = 0.3;
hintText.alpha = 0.3;
};
self.enable = function () {
self.enabled = true;
buttonBackground.alpha = 1;
hintText.alpha = 1;
};
self.down = function (x, y, obj) {
if (!self.enabled) {
return;
}
// Provide visual feedback
buttonBackground.alpha = 0.7;
tween(buttonBackground, {
alpha: 1
}, {
duration: 200
});
// Call the onPressed callback if it exists
if (typeof self.onPressed === 'function') {
self.onPressed();
}
};
return self;
});
var Light = Container.expand(function () {
var self = Container.call(this);
var lightGraphics = self.attachAsset('light', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.6 // Brighter by default
});
self.isActive = false;
self.originalColor = 0xffffff;
self.originalTint = lightGraphics.tint;
self.setColor = function (colorHex) {
self.originalColor = colorHex;
lightGraphics.tint = colorHex;
};
self.activate = function (duration) {
self.isActive = true;
// Stop any ongoing tweens
tween.stop(lightGraphics, {
alpha: true,
tint: true
});
// Flash the light
lightGraphics.alpha = 1;
// Play the light sound
LK.getSound('lightOn').play();
// After duration, dim the light
tween(lightGraphics, {
alpha: 0.4
}, {
duration: duration || 500,
onFinish: function onFinish() {
self.isActive = false;
}
});
};
self.highlight = function () {
// Short highlight for user feedback when pressed
lightGraphics.alpha = 1;
tween(lightGraphics, {
alpha: 0.4
}, {
duration: 200
});
};
self.down = function (x, y, obj) {
// Callback to handle when this light is pressed
self.highlight();
// Delegate to game logic
if (typeof self.onLightPressed === 'function') {
self.onLightPressed(self);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1c2833 // Dark blue background
});
/****
* Game Code
****/
// Game configuration
var config = {
gridSize: 3,
// Starting grid size (3x3)
maxGridSize: 5,
// Maximum grid size (for harder levels)
initialSequenceLength: 2,
// Start with 2 light patterns
maxLives: 3,
// Player gets 3 chances
hintAllowed: true,
// Allow one hint per level
colors: [0xff5252,
// Red
0x4caf50,
// Green
0x2196f3,
// Blue
0xffeb3b,
// Yellow
0xe040fb // Purple
],
timeBetweenLights: 800,
// Time between showing each light in the sequence (ms)
timeBeforeStart: 1500 // Time before starting a new sequence (ms)
};
// Game state
var state = {
level: 1,
currentSequence: [],
// The sequence to memorize
playerSequence: [],
// The player's input sequence
sequenceIndex: 0,
// Current position in playback/verification
lives: config.maxLives,
hintUsed: false,
// Has the hint been used this level
isShowingSequence: false,
// Are we currently showing a sequence?
isPlayerTurn: false,
// Is it the player's turn to repeat the sequence?
gridElements: [],
// Store grid elements for easy access
gameStarted: false // Has the game started yet?
};
// UI Elements
var grid = new Container();
var uiContainer = new Container();
var levelText;
var livesText;
var scoreText;
var hintButton;
// Initialize the game
function initGame() {
// Start background music
LK.playMusic('bgMusic', {
fade: {
start: 0,
end: 0.5,
duration: 1000
}
});
// Setup UI
setupUI();
// Create the grid of lights
createGrid();
// Position the grid in the center of the screen
positionGrid();
// Add UI and grid to the game
game.addChild(grid);
game.addChild(uiContainer);
// Show start screen
showStartScreen();
}
function setupUI() {
// Level indicator
levelText = new Text2("Level: 1", {
size: 80,
fill: 0xFFFFFF
});
levelText.anchor.set(0.5, 0);
LK.gui.top.addChild(levelText);
levelText.y = 100;
// Lives indicator
livesText = new Text2("Lives: " + state.lives, {
size: 70,
fill: 0xFFFFFF
});
livesText.anchor.set(0, 0);
LK.gui.topLeft.addChild(livesText);
livesText.x = 120; // Avoid the menu icon in top left
livesText.y = 100;
// Score (current level)
scoreText = new Text2("Score: 0", {
size: 70,
fill: 0xFFFFFF
});
scoreText.anchor.set(1, 0);
LK.gui.topRight.addChild(scoreText);
scoreText.x = -50;
scoreText.y = 100;
// Hint button
hintButton = new HintButton();
uiContainer.addChild(hintButton);
hintButton.x = 2048 / 2;
hintButton.y = 2732 - 200;
// Set up hint button callback
hintButton.onPressed = function () {
if (!state.hintUsed && state.isPlayerTurn) {
showHint();
}
};
}
function createGrid() {
var currentGridSize = Math.min(config.gridSize + Math.floor((state.level - 1) / 5), config.maxGridSize);
var lightSize = 200;
var padding = 80; // Further increased padding for even better spacing
var totalWidth = (lightSize + padding) * currentGridSize - padding;
// Clear existing grid if any
while (grid.children.length > 0) {
grid.removeChild(grid.children[0]);
}
state.gridElements = [];
// Create the new grid
for (var row = 0; row < currentGridSize; row++) {
for (var col = 0; col < currentGridSize; col++) {
var light = new Light();
light.x = col * (lightSize + padding);
light.y = row * (lightSize + padding);
light.gridRow = row;
light.gridCol = col;
// Assign a color to the light
var colorIndex = (row * currentGridSize + col) % config.colors.length;
light.setColor(config.colors[colorIndex]);
// Add callback for when the light is pressed
light.onLightPressed = onLightPressed;
grid.addChild(light);
state.gridElements.push(light);
}
}
// Update grid container width and height for positioning
grid.width = totalWidth;
grid.height = totalWidth;
}
function positionGrid() {
// Center the grid on the screen
grid.x = (2048 - grid.width) / 2;
grid.y = (2732 - grid.height) / 2;
}
function showStartScreen() {
var startText = new Text2("Tap to Start", {
size: 100,
fill: 0xFFFFFF
});
startText.anchor.set(0.5, 0.5);
startText.x = 2048 / 2;
startText.y = 2732 / 2;
game.addChild(startText);
// Make it pulse
function pulse() {
tween(startText, {
alpha: 0.5
}, {
duration: 800,
onFinish: function onFinish() {
tween(startText, {
alpha: 1
}, {
duration: 800,
onFinish: pulse
});
}
});
}
pulse();
// Start game on tap
var _startHandler = function startHandler(x, y, obj) {
game.removeChild(startText);
game.off('down', _startHandler);
startGame();
};
game.on('down', _startHandler);
}
function startGame() {
state.gameStarted = true;
resetGame();
startLevel();
}
function resetGame() {
state.level = 1;
state.lives = config.maxLives;
updateUI();
createGrid();
positionGrid();
}
function startLevel() {
state.currentSequence = [];
state.playerSequence = [];
state.sequenceIndex = 0;
state.hintUsed = false;
state.isShowingSequence = false;
state.isPlayerTurn = false;
// Update UI
updateUI();
// Enable hint button for this level
hintButton.enable();
// Generate a new sequence
generateSequence();
// Wait a moment, then show the sequence
LK.setTimeout(function () {
showSequence();
}, config.timeBeforeStart);
}
function updateUI() {
levelText.setText("Level: " + state.level);
livesText.setText("Lives: " + state.lives);
scoreText.setText("Score: " + (state.level - 1));
// Save high score if needed
if (state.level - 1 > storage.highScore) {
storage.highScore = state.level - 1;
}
}
function generateSequence() {
var sequenceLength = config.initialSequenceLength + state.level - 1;
var gridSize = state.gridElements.length;
// Generate random sequence
for (var i = 0; i < sequenceLength; i++) {
var randomIndex = Math.floor(Math.random() * gridSize);
state.currentSequence.push(randomIndex);
}
}
function showSequence() {
state.isShowingSequence = true;
state.sequenceIndex = 0;
// Show the "Watch" text
var watchText = new Text2("Watch!", {
size: 100,
fill: 0xFFFFFF
});
watchText.anchor.set(0.5, 0.5);
watchText.x = 2048 / 2;
watchText.y = grid.y - 150;
game.addChild(watchText);
// Function to show each light in sequence
function showNextLight() {
if (state.sequenceIndex < state.currentSequence.length) {
var lightIndex = state.currentSequence[state.sequenceIndex];
var light = state.gridElements[lightIndex];
light.activate(config.timeBetweenLights * 0.8);
state.sequenceIndex++;
// Schedule next light
LK.setTimeout(showNextLight, config.timeBetweenLights);
} else {
// Sequence complete
state.isShowingSequence = false;
state.isPlayerTurn = true;
state.sequenceIndex = 0;
// Remove the watch text
game.removeChild(watchText);
// Show the "Your Turn" text
var turnText = new Text2("Your Turn!", {
size: 100,
fill: 0xFFFFFF
});
turnText.anchor.set(0.5, 0.5);
turnText.x = 2048 / 2;
turnText.y = grid.y - 150;
game.addChild(turnText);
// Fade out the text after a moment
tween(turnText, {
alpha: 0
}, {
duration: 1500,
onFinish: function onFinish() {
game.removeChild(turnText);
}
});
}
}
// Start showing sequence
showNextLight();
}
function onLightPressed(light) {
if (!state.isPlayerTurn) {
return;
}
// Find the index of this light in our grid
var lightIndex = state.gridElements.indexOf(light);
if (lightIndex === -1) {
return;
}
// Add to player sequence
state.playerSequence.push(lightIndex);
// Check if this press was correct
var currentIndex = state.playerSequence.length - 1;
if (state.playerSequence[currentIndex] === state.currentSequence[currentIndex]) {
// Correct!
// Check if sequence is complete
if (state.playerSequence.length === state.currentSequence.length) {
// Level completed!
LK.getSound('success').play();
state.isPlayerTurn = false;
// Show success message
var successText = new Text2("Success!", {
size: 120,
fill: 0x2ECC71 // Green
});
successText.anchor.set(0.5, 0.5);
successText.x = 2048 / 2;
successText.y = grid.y - 150;
game.addChild(successText);
// Blink the entire grid to show success
for (var i = 0; i < state.gridElements.length; i++) {
var currentLight = state.gridElements[i];
currentLight.activate(300);
}
// Show celebration popup if no lives were lost
if (state.lives === config.maxLives) {
var celebrationText = new Text2("Perfect Level!", {
size: 120,
fill: 0xFFD700 // Gold
});
celebrationText.anchor.set(0.5, 0.5);
celebrationText.x = 2048 / 2;
celebrationText.y = grid.y - 300;
game.addChild(celebrationText);
tween(celebrationText, {
alpha: 0
}, {
duration: 2000,
onFinish: function onFinish() {
game.removeChild(celebrationText);
}
});
}
// Move to next level
LK.setTimeout(function () {
game.removeChild(successText);
state.level++;
// Every 5 levels, sound a special effect and show a celebration
if (state.level % 5 === 1) {
LK.getSound('levelUp').play();
// Flash the screen
LK.effects.flashScreen(0x2ecc71, 500);
// Recreate grid with potentially new size
createGrid();
positionGrid();
}
startLevel();
}, 1500);
}
} else {
// Incorrect!
LK.getSound('failure').play();
state.isPlayerTurn = false;
// Flash the screen red
LK.effects.flashScreen(0xe74c3c, 300);
// Show incorrect message
var incorrectText = new Text2("Incorrect!", {
size: 120,
fill: 0xE74C3C // Red
});
incorrectText.anchor.set(0.5, 0.5);
incorrectText.x = 2048 / 2;
incorrectText.y = grid.y - 150;
game.addChild(incorrectText);
// Lose a life
state.lives--;
updateUI();
LK.setTimeout(function () {
game.removeChild(incorrectText);
if (state.lives <= 0) {
// Game over
gameOver();
} else {
// Try again
startLevel();
}
}, 1500);
}
}
function showHint() {
if (state.hintUsed) {
return;
}
state.hintUsed = true;
hintButton.disable();
// Temporarily disable player input
var wasPlayerTurn = state.isPlayerTurn;
state.isPlayerTurn = false;
// Show the hint sequence but faster
var fastTimeBetweenLights = config.timeBetweenLights * 0.6;
var hintIndex = 0;
// Show hint text
var hintText = new Text2("Hint!", {
size: 100,
fill: 0xF39C12 // Orange
});
hintText.anchor.set(0.5, 0.5);
hintText.x = 2048 / 2;
hintText.y = grid.y - 150;
game.addChild(hintText);
function showNextHintLight() {
if (hintIndex < state.currentSequence.length) {
var lightIndex = state.currentSequence[hintIndex];
var light = state.gridElements[lightIndex];
light.activate(fastTimeBetweenLights * 0.8);
hintIndex++;
// Schedule next light
LK.setTimeout(showNextHintLight, fastTimeBetweenLights);
} else {
// Hint complete, restore player's turn
state.isPlayerTurn = wasPlayerTurn;
// Remove the hint text
tween(hintText, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
game.removeChild(hintText);
}
});
}
}
// Start showing hint
showNextHintLight();
}
function gameOver() {
LK.showGameOver();
}
// Initialize the game
initGame();