User prompt
increase the padding between the grid
User prompt
make the grid little bit brighter
User prompt
generate the description for Light Echo: Pattern Memory Challenge
User prompt
add a celebration popup on the screen when a level completed without getting losing lives
User prompt
assign background asset as a game background
User prompt
make the background more dynamic
User prompt
adjust the entire grid position to the center of the screen
User prompt
increase the padding between the grid
Code edit (1 edits merged)
Please save this source code
User prompt
increase the grid space between them
User prompt
make the hint feature if the player completed the previous level without getting lost any of the lives
Code edit (1 edits merged)
Please save this source code
User prompt
Light Echo: Pattern Memory Challenge
Initial prompt
create a game which has a n x n led board which will highlight colors in a random pattern in a order player has to choose the orderly whatever order the light was blinked in a pattern by the AI , The player should click the same pattern and complete the color set , this will progress the game starting from 2 colors to n colors , increase the difficulty based on the each level progressing and give the player 3 chances to guess the color choosing if the player out of 3 chances game will be over , on each successful level progressing set a hint icon and if the player chooses the hint icon and give the order of colors as a hint
/**** * 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();