/****
* 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();