/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
player1Wins: 0,
player1Losses: 0,
player2Wins: 0,
player2Losses: 0,
selectedBoard: "original",
selectedLevel: "level1",
unlockedLevels: ["level1"]
});
/****
* Classes
****/
var Dice = Container.expand(function () {
var self = Container.call(this);
var diceGraphics = self.attachAsset('dice', {
anchorX: 0.5,
anchorY: 0.5
});
self.valueText = new Text2('1', {
size: 60,
fill: 0x000000
});
self.valueText.anchor.set(0.5, 0.5);
self.addChild(self.valueText);
self.currentValue = 1;
self.isRolling = false;
self.roll = function () {
if (self.isRolling) return;
self.isRolling = true;
LK.getSound('diceRoll').play();
var rollCount = 0;
var rollInterval = LK.setInterval(function () {
var tempValue = Math.floor(Math.random() * 6) + 1;
self.valueText.setText(tempValue.toString());
rollCount++;
if (rollCount >= 10) {
LK.clearInterval(rollInterval);
self.currentValue = tempValue;
self.isRolling = false;
onDiceRolled(self.currentValue);
}
}, 100);
};
self.down = function (x, y, obj) {
if (!self.isRolling && !isGameOver) {
self.roll();
}
};
return self;
});
var GameSquare = Container.expand(function (number, x, y) {
var self = Container.call(this);
// Get selected theme
var selectedTheme = boardThemes[storage.selectedBoard] || boardThemes.original;
// Alternate colors for checkerboard pattern
var isAlt = (Math.floor((number - 1) / 10) + (number - 1) % 10) % 2 === 1;
var squareGraphics = self.attachAsset(isAlt ? selectedTheme.squareAlt : selectedTheme.square, {
anchorX: 0.5,
anchorY: 0.5
});
var numberText = new Text2(number.toString(), {
size: 40,
fill: 0x000000
});
numberText.anchor.set(0.5, 0.5);
numberText.x = 0;
numberText.y = -60;
self.addChild(numberText);
self.squareNumber = number;
self.x = x;
self.y = y;
return self;
});
var MainMenu = Container.expand(function () {
var self = Container.call(this);
// Background for better visual appeal
var menuBackground = LK.getAsset('dice', {
anchorX: 0.5,
anchorY: 0.5
});
menuBackground.width = 1800;
menuBackground.height = 2200;
menuBackground.x = 2048 / 2;
menuBackground.y = 2732 / 2;
menuBackground.alpha = 0.1;
self.addChild(menuBackground);
// Game title
var gameTitle = new Text2('SERPIENTES Y ESCALERAS', {
size: 120,
fill: 0xFFD700
});
gameTitle.anchor.set(0.5, 0.5);
gameTitle.x = 2048 / 2;
gameTitle.y = 300;
self.addChild(gameTitle);
// Board selection section
var boardSelectionTitle = new Text2('SELECCIONAR TABLERO', {
size: 70,
fill: 0xFFFFFF
});
boardSelectionTitle.anchor.set(0.5, 0.5);
boardSelectionTitle.x = 2048 / 2;
boardSelectionTitle.y = 500;
self.addChild(boardSelectionTitle);
// Create board selection buttons
var boardButtons = [];
var boardKeys = Object.keys(boardThemes);
var buttonWidth = 300;
var buttonHeight = 100;
var buttonsPerRow = 3;
var startX = 2048 / 2 - (buttonsPerRow * buttonWidth + (buttonsPerRow - 1) * 20) / 2;
var startY = 600;
for (var i = 0; i < boardKeys.length; i++) {
var boardKey = boardKeys[i];
var theme = boardThemes[boardKey];
var row = Math.floor(i / buttonsPerRow);
var col = i % buttonsPerRow;
var buttonX = startX + col * (buttonWidth + 20);
var buttonY = startY + row * (buttonHeight + 20);
var boardButton = LK.getAsset('dice', {
anchorX: 0.5,
anchorY: 0.5
});
boardButton.width = buttonWidth;
boardButton.height = buttonHeight;
boardButton.x = buttonX;
boardButton.y = buttonY;
boardButton.boardKey = boardKey;
// Highlight selected board
if (storage.selectedBoard === boardKey) {
boardButton.alpha = 1.0;
boardButton.tint = 0x00FF00;
} else {
boardButton.alpha = 0.7;
boardButton.tint = 0xFFFFFF;
}
self.addChild(boardButton);
var buttonText = new Text2(theme.name, {
size: 45,
fill: 0x000000
});
buttonText.anchor.set(0.5, 0.5);
buttonText.x = buttonX;
buttonText.y = buttonY;
self.addChild(buttonText);
// Add click handler for board selection
boardButton.down = function (x, y, obj) {
storage.selectedBoard = this.boardKey;
// Update all button appearances
for (var j = 0; j < boardButtons.length; j++) {
var btn = boardButtons[j];
if (btn.boardKey === storage.selectedBoard) {
btn.alpha = 1.0;
btn.tint = 0x00FF00;
} else {
btn.alpha = 0.7;
btn.tint = 0xFFFFFF;
}
}
};
boardButtons.push(boardButton);
}
// Play button in center
var playButton = LK.getAsset('playButton', {
anchorX: 0.5,
anchorY: 0.5
});
playButton.x = 2048 / 2;
playButton.y = 1150;
self.addChild(playButton);
var playText = new Text2('JUGAR', {
size: 80,
fill: 0x000000
});
playText.anchor.set(0.5, 0.5);
playText.x = playButton.x;
playText.y = playButton.y;
self.addChild(playText);
// Player 1 stats section (left side)
var player1Section = LK.getAsset('dice', {
anchorX: 0.5,
anchorY: 0.5
});
player1Section.width = 500;
player1Section.height = 600;
player1Section.x = 400;
player1Section.y = 1800;
player1Section.alpha = 0.3;
self.addChild(player1Section);
var player1Title = new Text2('JUGADOR 1', {
size: 80,
fill: 0xff0000
});
player1Title.anchor.set(0.5, 0.5);
player1Title.x = 400;
player1Title.y = 1550;
self.addChild(player1Title);
var player1WinsText = new Text2('VICTORIAS: ' + (storage.player1Wins || 0), {
size: 65,
fill: 0x00FF00
});
player1WinsText.anchor.set(0.5, 0.5);
player1WinsText.x = 400;
player1WinsText.y = 1700;
self.addChild(player1WinsText);
var player1LossesText = new Text2('DERROTAS: ' + (storage.player1Losses || 0), {
size: 65,
fill: 0xFF4444
});
player1LossesText.anchor.set(0.5, 0.5);
player1LossesText.x = 400;
player1LossesText.y = 1850;
self.addChild(player1LossesText);
// Player 2 stats section (right side)
var player2Section = LK.getAsset('dice', {
anchorX: 0.5,
anchorY: 0.5
});
player2Section.width = 500;
player2Section.height = 600;
player2Section.x = 1648;
player2Section.y = 1800;
player2Section.alpha = 0.3;
self.addChild(player2Section);
var player2Title = new Text2('JUGADOR 2', {
size: 80,
fill: 0x0000ff
});
player2Title.anchor.set(0.5, 0.5);
player2Title.x = 1648;
player2Title.y = 1550;
self.addChild(player2Title);
var player2WinsText = new Text2('VICTORIAS: ' + (storage.player2Wins || 0), {
size: 65,
fill: 0x00FF00
});
player2WinsText.anchor.set(0.5, 0.5);
player2WinsText.x = 1648;
player2WinsText.y = 1700;
self.addChild(player2WinsText);
var player2LossesText = new Text2('DERROTAS: ' + (storage.player2Losses || 0), {
size: 65,
fill: 0xFF4444
});
player2LossesText.anchor.set(0.5, 0.5);
player2LossesText.x = 1648;
player2LossesText.y = 1850;
self.addChild(player2LossesText);
// Level selection section
var levelSelectionTitle = new Text2('SELECCIONAR NIVEL', {
size: 70,
fill: 0xFFFFFF
});
levelSelectionTitle.anchor.set(0.5, 0.5);
levelSelectionTitle.x = 2048 / 2;
levelSelectionTitle.y = 850;
self.addChild(levelSelectionTitle);
// Create level selection buttons
var levelButtons = [];
var levelKeys = Object.keys(levelConfigs);
var levelButtonWidth = 200;
var levelButtonHeight = 80;
var levelButtonsPerRow = 4;
var levelStartX = 2048 / 2 - (levelButtonsPerRow * levelButtonWidth + (levelButtonsPerRow - 1) * 20) / 2;
var levelStartY = 950;
for (var i = 0; i < levelKeys.length; i++) {
var levelKey = levelKeys[i];
var levelConfig = levelConfigs[levelKey];
var row = Math.floor(i / levelButtonsPerRow);
var col = i % levelButtonsPerRow;
var buttonX = levelStartX + col * (levelButtonWidth + 20);
var buttonY = levelStartY + row * (levelButtonHeight + 20);
var levelButton = LK.getAsset('dice', {
anchorX: 0.5,
anchorY: 0.5
});
levelButton.width = levelButtonWidth;
levelButton.height = levelButtonHeight;
levelButton.x = buttonX;
levelButton.y = buttonY;
levelButton.levelKey = levelKey;
var isUnlocked = storage.unlockedLevels.indexOf(levelKey) !== -1;
// Set button appearance based on locked/unlocked state
if (!isUnlocked) {
levelButton.alpha = 0.3;
levelButton.tint = 0x666666;
} else if (storage.selectedLevel === levelKey) {
levelButton.alpha = 1.0;
levelButton.tint = 0x00FF00;
} else {
levelButton.alpha = 0.7;
levelButton.tint = 0xFFFFFF;
}
self.addChild(levelButton);
var levelButtonText = new Text2(isUnlocked ? levelConfig.name : 'BLOQUEADO', {
size: isUnlocked ? 35 : 25,
fill: isUnlocked ? 0x000000 : 0x444444
});
levelButtonText.anchor.set(0.5, 0.5);
levelButtonText.x = buttonX;
levelButtonText.y = buttonY;
self.addChild(levelButtonText);
// Add click handler for level selection (only if unlocked)
if (isUnlocked) {
levelButton.down = function (x, y, obj) {
storage.selectedLevel = this.levelKey;
// Update all level button appearances
for (var j = 0; j < levelButtons.length; j++) {
var btn = levelButtons[j];
var btnIsUnlocked = storage.unlockedLevels.indexOf(btn.levelKey) !== -1;
if (!btnIsUnlocked) {
btn.alpha = 0.3;
btn.tint = 0x666666;
} else if (btn.levelKey === storage.selectedLevel) {
btn.alpha = 1.0;
btn.tint = 0x00FF00;
} else {
btn.alpha = 0.7;
btn.tint = 0xFFFFFF;
}
}
};
}
levelButtons.push(levelButton);
}
// Instructions
var instructionText = new Text2('¡Selecciona tablero, nivel y toca JUGAR!', {
size: 60,
fill: 0xFFFFFF
});
instructionText.anchor.set(0.5, 0.5);
instructionText.x = 2048 / 2;
instructionText.y = 2000;
self.addChild(instructionText);
// Play button click handler
playButton.down = function (x, y, obj) {
startGame();
};
return self;
});
var Player = Container.expand(function (playerNumber, color) {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player' + playerNumber, {
anchorX: 0.5,
anchorY: 0.5
});
self.playerNumber = playerNumber;
self.currentSquare = 1;
self.isMoving = false;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb
});
/****
* Game Code
****/
var boardSquares = [];
var players = [];
var currentPlayer = 0;
var gameStarted = false;
var isGameOver = false;
var dice;
var mainMenu;
var inMenu = true;
// Board themes configuration
var boardThemes = {
original: {
name: 'ORIGINAL',
square: 'boardSquare',
squareAlt: 'boardSquareAlt'
},
classic: {
name: 'CLÁSICO',
square: 'boardSquareClassic',
squareAlt: 'boardSquareClassicAlt'
},
ocean: {
name: 'OCÉANO',
square: 'boardSquareOcean',
squareAlt: 'boardSquareOceanAlt'
},
forest: {
name: 'BOSQUE',
square: 'boardSquareForest',
squareAlt: 'boardSquareForestAlt'
},
desert: {
name: 'DESIERTO',
square: 'boardSquareDesert',
squareAlt: 'boardSquareDesertAlt'
}
};
// Level configurations with different snake and ladder positions
var levelConfigs = {
level1: {
name: 'NIVEL 1',
ladders: [{
start: 4,
end: 14
}, {
start: 9,
end: 31
}, {
start: 21,
end: 42
}, {
start: 28,
end: 84
}, {
start: 36,
end: 44
}, {
start: 51,
end: 67
}, {
start: 71,
end: 91
}, {
start: 80,
end: 100
}],
snakes: [{
start: 99,
end: 78
}, {
start: 95,
end: 75
}, {
start: 92,
end: 88
}, {
start: 87,
end: 24
}, {
start: 64,
end: 60
}, {
start: 62,
end: 19
}, {
start: 56,
end: 53
}, {
start: 49,
end: 11
}, {
start: 47,
end: 26
}, {
start: 16,
end: 6
}]
},
level2: {
name: 'NIVEL 2',
ladders: [{
start: 2,
end: 38
}, {
start: 7,
end: 14
}, {
start: 15,
end: 26
}, {
start: 28,
end: 84
}, {
start: 40,
end: 59
}, {
start: 63,
end: 81
}, {
start: 70,
end: 89
}],
snakes: [{
start: 98,
end: 79
}, {
start: 96,
end: 42
}, {
start: 93,
end: 73
}, {
start: 85,
end: 17
}, {
start: 74,
end: 53
}, {
start: 68,
end: 46
}, {
start: 65,
end: 52
}, {
start: 54,
end: 34
}, {
start: 43,
end: 18
}]
},
level3: {
name: 'NIVEL 3',
ladders: [{
start: 1,
end: 19
}, {
start: 6,
end: 27
}, {
start: 22,
end: 58
}, {
start: 35,
end: 56
}, {
start: 45,
end: 67
}, {
start: 61,
end: 82
}, {
start: 75,
end: 95
}],
snakes: [{
start: 99,
end: 41
}, {
start: 97,
end: 76
}, {
start: 91,
end: 71
}, {
start: 88,
end: 69
}, {
start: 83,
end: 62
}, {
start: 79,
end: 39
}, {
start: 66,
end: 45
}, {
start: 57,
end: 37
}, {
start: 48,
end: 28
}, {
start: 32,
end: 12
}]
},
level4: {
name: 'NIVEL 4',
ladders: [{
start: 3,
end: 23
}, {
start: 8,
end: 34
}, {
start: 18,
end: 38
}, {
start: 25,
end: 46
}, {
start: 41,
end: 63
}, {
start: 55,
end: 76
}, {
start: 64,
end: 85
}, {
start: 77,
end: 98
}],
snakes: [{
start: 96,
end: 47
}, {
start: 94,
end: 74
}, {
start: 89,
end: 68
}, {
start: 84,
end: 43
}, {
start: 80,
end: 59
}, {
start: 73,
end: 52
}, {
start: 69,
end: 49
}, {
start: 58,
end: 16
}, {
start: 44,
end: 24
}, {
start: 29,
end: 9
}]
}
};
// Current level and snake/ladder references
var currentLevel = 'level1';
var ladders = levelConfigs[currentLevel].ladders;
var snakes = levelConfigs[currentLevel].snakes;
// Create board
function createBoard() {
var boardContainer = new Container();
game.addChild(boardContainer);
var startX = 200;
var startY = 300;
var squareSize = 180;
for (var i = 1; i <= 100; i++) {
var row = Math.floor((i - 1) / 10);
var col = (i - 1) % 10;
// Reverse direction for odd rows (snake-like pattern)
if (row % 2 === 1) {
col = 9 - col;
}
var x = startX + col * squareSize;
var y = startY + (9 - row) * squareSize;
var square = new GameSquare(i, x, y);
boardSquares[i] = square;
boardContainer.addChild(square);
}
// Add snakes and ladders visual indicators
for (var j = 0; j < ladders.length; j++) {
var ladder = ladders[j];
var startSquare = boardSquares[ladder.start];
var endSquare = boardSquares[ladder.end];
var ladderGraphic = LK.getAsset('ladder', {
anchorX: 0.5,
anchorY: 0.5
});
ladderGraphic.x = (startSquare.x + endSquare.x) / 2;
ladderGraphic.y = (startSquare.y + endSquare.y) / 2;
var angle = Math.atan2(endSquare.y - startSquare.y, endSquare.x - startSquare.x);
ladderGraphic.rotation = angle;
var distance = Math.sqrt(Math.pow(endSquare.x - startSquare.x, 2) + Math.pow(endSquare.y - startSquare.y, 2));
ladderGraphic.width = distance * 0.8;
ladderGraphic.height = 60;
boardContainer.addChild(ladderGraphic);
}
for (var k = 0; k < snakes.length; k++) {
var snake = snakes[k];
var startSquare = boardSquares[snake.start];
var endSquare = boardSquares[snake.end];
var snakeGraphic = LK.getAsset('snake', {
anchorX: 0.5,
anchorY: 0.5
});
snakeGraphic.x = (startSquare.x + endSquare.x) / 2;
snakeGraphic.y = (startSquare.y + endSquare.y) / 2;
var angle = Math.atan2(endSquare.y - startSquare.y, endSquare.x - startSquare.x);
snakeGraphic.rotation = angle;
var distance = Math.sqrt(Math.pow(endSquare.x - startSquare.x, 2) + Math.pow(endSquare.y - startSquare.y, 2));
snakeGraphic.width = distance * 0.9;
snakeGraphic.height = 50;
boardContainer.addChild(snakeGraphic);
}
}
// Create players
function createPlayers() {
for (var i = 1; i <= 2; i++) {
var player = new Player(i);
players.push(player);
game.addChild(player);
// Position players at starting square
var startSquare = boardSquares[1];
player.x = startSquare.x + (i === 1 ? -30 : 30);
player.y = startSquare.y;
}
}
// Create dice
function createDice() {
dice = new Dice();
dice.x = 2048 / 2; // Center horizontally
dice.y = 2732 - 200; // Bottom of screen with margin
game.addChild(dice);
}
// Create UI
function createUI() {
var titleText = new Text2('Snakes and Ladders', {
size: 80,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0);
LK.gui.top.addChild(titleText);
var instructionText = new Text2('Tap dice to roll', {
size: 40,
fill: 0xFFFFFF
});
instructionText.anchor.set(0.5, 0);
instructionText.y = 100;
LK.gui.top.addChild(instructionText);
// Add back to menu button
var backButton = LK.getAsset('dice', {
anchorX: 0.5,
anchorY: 0.5
});
backButton.width = 200;
backButton.height = 80;
backButton.x = 2048 - 150; // Position on right side
backButton.y = 150;
game.addChild(backButton);
var backText = new Text2('MENÚ', {
size: 40,
fill: 0x000000
});
backText.anchor.set(0.5, 0.5);
backText.x = backButton.x;
backText.y = backButton.y;
game.addChild(backText);
// Back button click handler
backButton.down = function (x, y, obj) {
returnToMenu();
};
}
// Handle dice roll result
function onDiceRolled(value) {
var player = players[currentPlayer];
var newSquare = Math.min(player.currentSquare + value, 100);
movePlayer(player, newSquare);
}
// Move player to new square
function movePlayer(player, targetSquare) {
if (player.isMoving) return;
player.isMoving = true;
LK.getSound('moveSound').play();
var currentSquare = player.currentSquare;
var steps = targetSquare - currentSquare;
var stepCount = 0;
var moveInterval = LK.setInterval(function () {
stepCount++;
var nextSquare = currentSquare + stepCount;
if (nextSquare <= targetSquare && nextSquare <= 100) {
var square = boardSquares[nextSquare];
tween(player, {
x: square.x + (player.playerNumber === 1 ? -30 : 30),
y: square.y
}, {
duration: 200,
easing: tween.easeOut
});
player.currentSquare = nextSquare;
if (stepCount >= steps || nextSquare >= 100) {
LK.clearInterval(moveInterval);
LK.setTimeout(function () {
checkSpecialSquares(player);
}, 300);
}
}
}, 250);
}
// Check for snakes and ladders
function checkSpecialSquares(player) {
var currentSquare = player.currentSquare;
// Check for ladders
for (var i = 0; i < ladders.length; i++) {
if (ladders[i].start === currentSquare) {
LK.getSound('ladderSound').play();
LK.setTimeout(function () {
movePlayerToSquare(player, ladders[i].end);
}, 500);
return;
}
}
// Check for snakes
for (var j = 0; j < snakes.length; j++) {
if (snakes[j].start === currentSquare) {
LK.getSound('snakeSound').play();
LK.setTimeout(function () {
movePlayerToSquare(player, snakes[j].end);
}, 500);
return;
}
}
// Check win condition
if (currentSquare >= 100) {
isGameOver = true;
showWinMessage(player.playerNumber);
return;
}
// End turn
endTurn();
}
// Move player directly to a square (for snakes/ladders)
function movePlayerToSquare(player, targetSquare) {
var square = boardSquares[targetSquare];
tween(player, {
x: square.x + (player.playerNumber === 1 ? -30 : 30),
y: square.y
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
player.currentSquare = targetSquare;
player.isMoving = false;
if (targetSquare >= 100) {
isGameOver = true;
showWinMessage(player.playerNumber);
} else {
endTurn();
}
}
});
}
// Start the game from menu
function startGame() {
if (mainMenu) {
game.removeChild(mainMenu);
mainMenu = null;
}
inMenu = false;
gameStarted = true;
isGameOver = false;
currentPlayer = 0;
// Load selected level configuration
currentLevel = storage.selectedLevel || 'level1';
ladders = levelConfigs[currentLevel].ladders;
snakes = levelConfigs[currentLevel].snakes;
// Reset players
for (var i = 0; i < players.length; i++) {
if (players[i].parent) {
game.removeChild(players[i]);
}
}
players = [];
createBoard();
createPlayers();
createDice();
createUI();
}
// Unlock next level when current level is completed
function unlockNextLevel() {
var levelKeys = Object.keys(levelConfigs);
var currentLevelIndex = levelKeys.indexOf(currentLevel);
if (currentLevelIndex !== -1 && currentLevelIndex < levelKeys.length - 1) {
var nextLevel = levelKeys[currentLevelIndex + 1];
if (storage.unlockedLevels.indexOf(nextLevel) === -1) {
storage.unlockedLevels.push(nextLevel);
}
}
}
// Show win message for specific player
function showWinMessage(playerNumber) {
// Update statistics
if (playerNumber === 1) {
storage.player1Wins = (storage.player1Wins || 0) + 1;
storage.player2Losses = (storage.player2Losses || 0) + 1;
} else {
storage.player2Wins = (storage.player2Wins || 0) + 1;
storage.player1Losses = (storage.player1Losses || 0) + 1;
}
// Unlock next level when completing current level
unlockNextLevel();
var winText = new Text2('Jugador ' + playerNumber + ' Ganaste!', {
size: 100,
fill: playerNumber === 1 ? 0xff0000 : 0x0000ff
});
winText.anchor.set(0.5, 0.5);
winText.x = 2048 / 2;
winText.y = 2732 / 2;
game.addChild(winText);
// Show level unlock message if a new level was unlocked
var levelKeys = Object.keys(levelConfigs);
var currentLevelIndex = levelKeys.indexOf(currentLevel);
if (currentLevelIndex !== -1 && currentLevelIndex < levelKeys.length - 1) {
var nextLevel = levelKeys[currentLevelIndex + 1];
var nextLevelConfig = levelConfigs[nextLevel];
var unlockText = new Text2('¡' + nextLevelConfig.name + ' DESBLOQUEADO!', {
size: 60,
fill: 0xFFD700
});
unlockText.anchor.set(0.5, 0.5);
unlockText.x = 2048 / 2;
unlockText.y = 2732 / 2 + 120;
game.addChild(unlockText);
}
LK.setTimeout(function () {
// Return to menu after win
while (game.children.length > 0) {
game.removeChild(game.children[0]);
}
inMenu = true;
mainMenu = new MainMenu();
game.addChild(mainMenu);
}, 2000);
}
// End current player's turn
function endTurn() {
players[currentPlayer].isMoving = false;
currentPlayer = (currentPlayer + 1) % 2;
}
// Return to main menu
function returnToMenu() {
while (game.children.length > 0) {
game.removeChild(game.children[0]);
}
inMenu = true;
gameStarted = false;
isGameOver = false;
mainMenu = new MainMenu();
game.addChild(mainMenu);
}
// Initialize main menu
mainMenu = new MainMenu();
game.addChild(mainMenu); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
player1Wins: 0,
player1Losses: 0,
player2Wins: 0,
player2Losses: 0,
selectedBoard: "original",
selectedLevel: "level1",
unlockedLevels: ["level1"]
});
/****
* Classes
****/
var Dice = Container.expand(function () {
var self = Container.call(this);
var diceGraphics = self.attachAsset('dice', {
anchorX: 0.5,
anchorY: 0.5
});
self.valueText = new Text2('1', {
size: 60,
fill: 0x000000
});
self.valueText.anchor.set(0.5, 0.5);
self.addChild(self.valueText);
self.currentValue = 1;
self.isRolling = false;
self.roll = function () {
if (self.isRolling) return;
self.isRolling = true;
LK.getSound('diceRoll').play();
var rollCount = 0;
var rollInterval = LK.setInterval(function () {
var tempValue = Math.floor(Math.random() * 6) + 1;
self.valueText.setText(tempValue.toString());
rollCount++;
if (rollCount >= 10) {
LK.clearInterval(rollInterval);
self.currentValue = tempValue;
self.isRolling = false;
onDiceRolled(self.currentValue);
}
}, 100);
};
self.down = function (x, y, obj) {
if (!self.isRolling && !isGameOver) {
self.roll();
}
};
return self;
});
var GameSquare = Container.expand(function (number, x, y) {
var self = Container.call(this);
// Get selected theme
var selectedTheme = boardThemes[storage.selectedBoard] || boardThemes.original;
// Alternate colors for checkerboard pattern
var isAlt = (Math.floor((number - 1) / 10) + (number - 1) % 10) % 2 === 1;
var squareGraphics = self.attachAsset(isAlt ? selectedTheme.squareAlt : selectedTheme.square, {
anchorX: 0.5,
anchorY: 0.5
});
var numberText = new Text2(number.toString(), {
size: 40,
fill: 0x000000
});
numberText.anchor.set(0.5, 0.5);
numberText.x = 0;
numberText.y = -60;
self.addChild(numberText);
self.squareNumber = number;
self.x = x;
self.y = y;
return self;
});
var MainMenu = Container.expand(function () {
var self = Container.call(this);
// Background for better visual appeal
var menuBackground = LK.getAsset('dice', {
anchorX: 0.5,
anchorY: 0.5
});
menuBackground.width = 1800;
menuBackground.height = 2200;
menuBackground.x = 2048 / 2;
menuBackground.y = 2732 / 2;
menuBackground.alpha = 0.1;
self.addChild(menuBackground);
// Game title
var gameTitle = new Text2('SERPIENTES Y ESCALERAS', {
size: 120,
fill: 0xFFD700
});
gameTitle.anchor.set(0.5, 0.5);
gameTitle.x = 2048 / 2;
gameTitle.y = 300;
self.addChild(gameTitle);
// Board selection section
var boardSelectionTitle = new Text2('SELECCIONAR TABLERO', {
size: 70,
fill: 0xFFFFFF
});
boardSelectionTitle.anchor.set(0.5, 0.5);
boardSelectionTitle.x = 2048 / 2;
boardSelectionTitle.y = 500;
self.addChild(boardSelectionTitle);
// Create board selection buttons
var boardButtons = [];
var boardKeys = Object.keys(boardThemes);
var buttonWidth = 300;
var buttonHeight = 100;
var buttonsPerRow = 3;
var startX = 2048 / 2 - (buttonsPerRow * buttonWidth + (buttonsPerRow - 1) * 20) / 2;
var startY = 600;
for (var i = 0; i < boardKeys.length; i++) {
var boardKey = boardKeys[i];
var theme = boardThemes[boardKey];
var row = Math.floor(i / buttonsPerRow);
var col = i % buttonsPerRow;
var buttonX = startX + col * (buttonWidth + 20);
var buttonY = startY + row * (buttonHeight + 20);
var boardButton = LK.getAsset('dice', {
anchorX: 0.5,
anchorY: 0.5
});
boardButton.width = buttonWidth;
boardButton.height = buttonHeight;
boardButton.x = buttonX;
boardButton.y = buttonY;
boardButton.boardKey = boardKey;
// Highlight selected board
if (storage.selectedBoard === boardKey) {
boardButton.alpha = 1.0;
boardButton.tint = 0x00FF00;
} else {
boardButton.alpha = 0.7;
boardButton.tint = 0xFFFFFF;
}
self.addChild(boardButton);
var buttonText = new Text2(theme.name, {
size: 45,
fill: 0x000000
});
buttonText.anchor.set(0.5, 0.5);
buttonText.x = buttonX;
buttonText.y = buttonY;
self.addChild(buttonText);
// Add click handler for board selection
boardButton.down = function (x, y, obj) {
storage.selectedBoard = this.boardKey;
// Update all button appearances
for (var j = 0; j < boardButtons.length; j++) {
var btn = boardButtons[j];
if (btn.boardKey === storage.selectedBoard) {
btn.alpha = 1.0;
btn.tint = 0x00FF00;
} else {
btn.alpha = 0.7;
btn.tint = 0xFFFFFF;
}
}
};
boardButtons.push(boardButton);
}
// Play button in center
var playButton = LK.getAsset('playButton', {
anchorX: 0.5,
anchorY: 0.5
});
playButton.x = 2048 / 2;
playButton.y = 1150;
self.addChild(playButton);
var playText = new Text2('JUGAR', {
size: 80,
fill: 0x000000
});
playText.anchor.set(0.5, 0.5);
playText.x = playButton.x;
playText.y = playButton.y;
self.addChild(playText);
// Player 1 stats section (left side)
var player1Section = LK.getAsset('dice', {
anchorX: 0.5,
anchorY: 0.5
});
player1Section.width = 500;
player1Section.height = 600;
player1Section.x = 400;
player1Section.y = 1800;
player1Section.alpha = 0.3;
self.addChild(player1Section);
var player1Title = new Text2('JUGADOR 1', {
size: 80,
fill: 0xff0000
});
player1Title.anchor.set(0.5, 0.5);
player1Title.x = 400;
player1Title.y = 1550;
self.addChild(player1Title);
var player1WinsText = new Text2('VICTORIAS: ' + (storage.player1Wins || 0), {
size: 65,
fill: 0x00FF00
});
player1WinsText.anchor.set(0.5, 0.5);
player1WinsText.x = 400;
player1WinsText.y = 1700;
self.addChild(player1WinsText);
var player1LossesText = new Text2('DERROTAS: ' + (storage.player1Losses || 0), {
size: 65,
fill: 0xFF4444
});
player1LossesText.anchor.set(0.5, 0.5);
player1LossesText.x = 400;
player1LossesText.y = 1850;
self.addChild(player1LossesText);
// Player 2 stats section (right side)
var player2Section = LK.getAsset('dice', {
anchorX: 0.5,
anchorY: 0.5
});
player2Section.width = 500;
player2Section.height = 600;
player2Section.x = 1648;
player2Section.y = 1800;
player2Section.alpha = 0.3;
self.addChild(player2Section);
var player2Title = new Text2('JUGADOR 2', {
size: 80,
fill: 0x0000ff
});
player2Title.anchor.set(0.5, 0.5);
player2Title.x = 1648;
player2Title.y = 1550;
self.addChild(player2Title);
var player2WinsText = new Text2('VICTORIAS: ' + (storage.player2Wins || 0), {
size: 65,
fill: 0x00FF00
});
player2WinsText.anchor.set(0.5, 0.5);
player2WinsText.x = 1648;
player2WinsText.y = 1700;
self.addChild(player2WinsText);
var player2LossesText = new Text2('DERROTAS: ' + (storage.player2Losses || 0), {
size: 65,
fill: 0xFF4444
});
player2LossesText.anchor.set(0.5, 0.5);
player2LossesText.x = 1648;
player2LossesText.y = 1850;
self.addChild(player2LossesText);
// Level selection section
var levelSelectionTitle = new Text2('SELECCIONAR NIVEL', {
size: 70,
fill: 0xFFFFFF
});
levelSelectionTitle.anchor.set(0.5, 0.5);
levelSelectionTitle.x = 2048 / 2;
levelSelectionTitle.y = 850;
self.addChild(levelSelectionTitle);
// Create level selection buttons
var levelButtons = [];
var levelKeys = Object.keys(levelConfigs);
var levelButtonWidth = 200;
var levelButtonHeight = 80;
var levelButtonsPerRow = 4;
var levelStartX = 2048 / 2 - (levelButtonsPerRow * levelButtonWidth + (levelButtonsPerRow - 1) * 20) / 2;
var levelStartY = 950;
for (var i = 0; i < levelKeys.length; i++) {
var levelKey = levelKeys[i];
var levelConfig = levelConfigs[levelKey];
var row = Math.floor(i / levelButtonsPerRow);
var col = i % levelButtonsPerRow;
var buttonX = levelStartX + col * (levelButtonWidth + 20);
var buttonY = levelStartY + row * (levelButtonHeight + 20);
var levelButton = LK.getAsset('dice', {
anchorX: 0.5,
anchorY: 0.5
});
levelButton.width = levelButtonWidth;
levelButton.height = levelButtonHeight;
levelButton.x = buttonX;
levelButton.y = buttonY;
levelButton.levelKey = levelKey;
var isUnlocked = storage.unlockedLevels.indexOf(levelKey) !== -1;
// Set button appearance based on locked/unlocked state
if (!isUnlocked) {
levelButton.alpha = 0.3;
levelButton.tint = 0x666666;
} else if (storage.selectedLevel === levelKey) {
levelButton.alpha = 1.0;
levelButton.tint = 0x00FF00;
} else {
levelButton.alpha = 0.7;
levelButton.tint = 0xFFFFFF;
}
self.addChild(levelButton);
var levelButtonText = new Text2(isUnlocked ? levelConfig.name : 'BLOQUEADO', {
size: isUnlocked ? 35 : 25,
fill: isUnlocked ? 0x000000 : 0x444444
});
levelButtonText.anchor.set(0.5, 0.5);
levelButtonText.x = buttonX;
levelButtonText.y = buttonY;
self.addChild(levelButtonText);
// Add click handler for level selection (only if unlocked)
if (isUnlocked) {
levelButton.down = function (x, y, obj) {
storage.selectedLevel = this.levelKey;
// Update all level button appearances
for (var j = 0; j < levelButtons.length; j++) {
var btn = levelButtons[j];
var btnIsUnlocked = storage.unlockedLevels.indexOf(btn.levelKey) !== -1;
if (!btnIsUnlocked) {
btn.alpha = 0.3;
btn.tint = 0x666666;
} else if (btn.levelKey === storage.selectedLevel) {
btn.alpha = 1.0;
btn.tint = 0x00FF00;
} else {
btn.alpha = 0.7;
btn.tint = 0xFFFFFF;
}
}
};
}
levelButtons.push(levelButton);
}
// Instructions
var instructionText = new Text2('¡Selecciona tablero, nivel y toca JUGAR!', {
size: 60,
fill: 0xFFFFFF
});
instructionText.anchor.set(0.5, 0.5);
instructionText.x = 2048 / 2;
instructionText.y = 2000;
self.addChild(instructionText);
// Play button click handler
playButton.down = function (x, y, obj) {
startGame();
};
return self;
});
var Player = Container.expand(function (playerNumber, color) {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player' + playerNumber, {
anchorX: 0.5,
anchorY: 0.5
});
self.playerNumber = playerNumber;
self.currentSquare = 1;
self.isMoving = false;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb
});
/****
* Game Code
****/
var boardSquares = [];
var players = [];
var currentPlayer = 0;
var gameStarted = false;
var isGameOver = false;
var dice;
var mainMenu;
var inMenu = true;
// Board themes configuration
var boardThemes = {
original: {
name: 'ORIGINAL',
square: 'boardSquare',
squareAlt: 'boardSquareAlt'
},
classic: {
name: 'CLÁSICO',
square: 'boardSquareClassic',
squareAlt: 'boardSquareClassicAlt'
},
ocean: {
name: 'OCÉANO',
square: 'boardSquareOcean',
squareAlt: 'boardSquareOceanAlt'
},
forest: {
name: 'BOSQUE',
square: 'boardSquareForest',
squareAlt: 'boardSquareForestAlt'
},
desert: {
name: 'DESIERTO',
square: 'boardSquareDesert',
squareAlt: 'boardSquareDesertAlt'
}
};
// Level configurations with different snake and ladder positions
var levelConfigs = {
level1: {
name: 'NIVEL 1',
ladders: [{
start: 4,
end: 14
}, {
start: 9,
end: 31
}, {
start: 21,
end: 42
}, {
start: 28,
end: 84
}, {
start: 36,
end: 44
}, {
start: 51,
end: 67
}, {
start: 71,
end: 91
}, {
start: 80,
end: 100
}],
snakes: [{
start: 99,
end: 78
}, {
start: 95,
end: 75
}, {
start: 92,
end: 88
}, {
start: 87,
end: 24
}, {
start: 64,
end: 60
}, {
start: 62,
end: 19
}, {
start: 56,
end: 53
}, {
start: 49,
end: 11
}, {
start: 47,
end: 26
}, {
start: 16,
end: 6
}]
},
level2: {
name: 'NIVEL 2',
ladders: [{
start: 2,
end: 38
}, {
start: 7,
end: 14
}, {
start: 15,
end: 26
}, {
start: 28,
end: 84
}, {
start: 40,
end: 59
}, {
start: 63,
end: 81
}, {
start: 70,
end: 89
}],
snakes: [{
start: 98,
end: 79
}, {
start: 96,
end: 42
}, {
start: 93,
end: 73
}, {
start: 85,
end: 17
}, {
start: 74,
end: 53
}, {
start: 68,
end: 46
}, {
start: 65,
end: 52
}, {
start: 54,
end: 34
}, {
start: 43,
end: 18
}]
},
level3: {
name: 'NIVEL 3',
ladders: [{
start: 1,
end: 19
}, {
start: 6,
end: 27
}, {
start: 22,
end: 58
}, {
start: 35,
end: 56
}, {
start: 45,
end: 67
}, {
start: 61,
end: 82
}, {
start: 75,
end: 95
}],
snakes: [{
start: 99,
end: 41
}, {
start: 97,
end: 76
}, {
start: 91,
end: 71
}, {
start: 88,
end: 69
}, {
start: 83,
end: 62
}, {
start: 79,
end: 39
}, {
start: 66,
end: 45
}, {
start: 57,
end: 37
}, {
start: 48,
end: 28
}, {
start: 32,
end: 12
}]
},
level4: {
name: 'NIVEL 4',
ladders: [{
start: 3,
end: 23
}, {
start: 8,
end: 34
}, {
start: 18,
end: 38
}, {
start: 25,
end: 46
}, {
start: 41,
end: 63
}, {
start: 55,
end: 76
}, {
start: 64,
end: 85
}, {
start: 77,
end: 98
}],
snakes: [{
start: 96,
end: 47
}, {
start: 94,
end: 74
}, {
start: 89,
end: 68
}, {
start: 84,
end: 43
}, {
start: 80,
end: 59
}, {
start: 73,
end: 52
}, {
start: 69,
end: 49
}, {
start: 58,
end: 16
}, {
start: 44,
end: 24
}, {
start: 29,
end: 9
}]
}
};
// Current level and snake/ladder references
var currentLevel = 'level1';
var ladders = levelConfigs[currentLevel].ladders;
var snakes = levelConfigs[currentLevel].snakes;
// Create board
function createBoard() {
var boardContainer = new Container();
game.addChild(boardContainer);
var startX = 200;
var startY = 300;
var squareSize = 180;
for (var i = 1; i <= 100; i++) {
var row = Math.floor((i - 1) / 10);
var col = (i - 1) % 10;
// Reverse direction for odd rows (snake-like pattern)
if (row % 2 === 1) {
col = 9 - col;
}
var x = startX + col * squareSize;
var y = startY + (9 - row) * squareSize;
var square = new GameSquare(i, x, y);
boardSquares[i] = square;
boardContainer.addChild(square);
}
// Add snakes and ladders visual indicators
for (var j = 0; j < ladders.length; j++) {
var ladder = ladders[j];
var startSquare = boardSquares[ladder.start];
var endSquare = boardSquares[ladder.end];
var ladderGraphic = LK.getAsset('ladder', {
anchorX: 0.5,
anchorY: 0.5
});
ladderGraphic.x = (startSquare.x + endSquare.x) / 2;
ladderGraphic.y = (startSquare.y + endSquare.y) / 2;
var angle = Math.atan2(endSquare.y - startSquare.y, endSquare.x - startSquare.x);
ladderGraphic.rotation = angle;
var distance = Math.sqrt(Math.pow(endSquare.x - startSquare.x, 2) + Math.pow(endSquare.y - startSquare.y, 2));
ladderGraphic.width = distance * 0.8;
ladderGraphic.height = 60;
boardContainer.addChild(ladderGraphic);
}
for (var k = 0; k < snakes.length; k++) {
var snake = snakes[k];
var startSquare = boardSquares[snake.start];
var endSquare = boardSquares[snake.end];
var snakeGraphic = LK.getAsset('snake', {
anchorX: 0.5,
anchorY: 0.5
});
snakeGraphic.x = (startSquare.x + endSquare.x) / 2;
snakeGraphic.y = (startSquare.y + endSquare.y) / 2;
var angle = Math.atan2(endSquare.y - startSquare.y, endSquare.x - startSquare.x);
snakeGraphic.rotation = angle;
var distance = Math.sqrt(Math.pow(endSquare.x - startSquare.x, 2) + Math.pow(endSquare.y - startSquare.y, 2));
snakeGraphic.width = distance * 0.9;
snakeGraphic.height = 50;
boardContainer.addChild(snakeGraphic);
}
}
// Create players
function createPlayers() {
for (var i = 1; i <= 2; i++) {
var player = new Player(i);
players.push(player);
game.addChild(player);
// Position players at starting square
var startSquare = boardSquares[1];
player.x = startSquare.x + (i === 1 ? -30 : 30);
player.y = startSquare.y;
}
}
// Create dice
function createDice() {
dice = new Dice();
dice.x = 2048 / 2; // Center horizontally
dice.y = 2732 - 200; // Bottom of screen with margin
game.addChild(dice);
}
// Create UI
function createUI() {
var titleText = new Text2('Snakes and Ladders', {
size: 80,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0);
LK.gui.top.addChild(titleText);
var instructionText = new Text2('Tap dice to roll', {
size: 40,
fill: 0xFFFFFF
});
instructionText.anchor.set(0.5, 0);
instructionText.y = 100;
LK.gui.top.addChild(instructionText);
// Add back to menu button
var backButton = LK.getAsset('dice', {
anchorX: 0.5,
anchorY: 0.5
});
backButton.width = 200;
backButton.height = 80;
backButton.x = 2048 - 150; // Position on right side
backButton.y = 150;
game.addChild(backButton);
var backText = new Text2('MENÚ', {
size: 40,
fill: 0x000000
});
backText.anchor.set(0.5, 0.5);
backText.x = backButton.x;
backText.y = backButton.y;
game.addChild(backText);
// Back button click handler
backButton.down = function (x, y, obj) {
returnToMenu();
};
}
// Handle dice roll result
function onDiceRolled(value) {
var player = players[currentPlayer];
var newSquare = Math.min(player.currentSquare + value, 100);
movePlayer(player, newSquare);
}
// Move player to new square
function movePlayer(player, targetSquare) {
if (player.isMoving) return;
player.isMoving = true;
LK.getSound('moveSound').play();
var currentSquare = player.currentSquare;
var steps = targetSquare - currentSquare;
var stepCount = 0;
var moveInterval = LK.setInterval(function () {
stepCount++;
var nextSquare = currentSquare + stepCount;
if (nextSquare <= targetSquare && nextSquare <= 100) {
var square = boardSquares[nextSquare];
tween(player, {
x: square.x + (player.playerNumber === 1 ? -30 : 30),
y: square.y
}, {
duration: 200,
easing: tween.easeOut
});
player.currentSquare = nextSquare;
if (stepCount >= steps || nextSquare >= 100) {
LK.clearInterval(moveInterval);
LK.setTimeout(function () {
checkSpecialSquares(player);
}, 300);
}
}
}, 250);
}
// Check for snakes and ladders
function checkSpecialSquares(player) {
var currentSquare = player.currentSquare;
// Check for ladders
for (var i = 0; i < ladders.length; i++) {
if (ladders[i].start === currentSquare) {
LK.getSound('ladderSound').play();
LK.setTimeout(function () {
movePlayerToSquare(player, ladders[i].end);
}, 500);
return;
}
}
// Check for snakes
for (var j = 0; j < snakes.length; j++) {
if (snakes[j].start === currentSquare) {
LK.getSound('snakeSound').play();
LK.setTimeout(function () {
movePlayerToSquare(player, snakes[j].end);
}, 500);
return;
}
}
// Check win condition
if (currentSquare >= 100) {
isGameOver = true;
showWinMessage(player.playerNumber);
return;
}
// End turn
endTurn();
}
// Move player directly to a square (for snakes/ladders)
function movePlayerToSquare(player, targetSquare) {
var square = boardSquares[targetSquare];
tween(player, {
x: square.x + (player.playerNumber === 1 ? -30 : 30),
y: square.y
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
player.currentSquare = targetSquare;
player.isMoving = false;
if (targetSquare >= 100) {
isGameOver = true;
showWinMessage(player.playerNumber);
} else {
endTurn();
}
}
});
}
// Start the game from menu
function startGame() {
if (mainMenu) {
game.removeChild(mainMenu);
mainMenu = null;
}
inMenu = false;
gameStarted = true;
isGameOver = false;
currentPlayer = 0;
// Load selected level configuration
currentLevel = storage.selectedLevel || 'level1';
ladders = levelConfigs[currentLevel].ladders;
snakes = levelConfigs[currentLevel].snakes;
// Reset players
for (var i = 0; i < players.length; i++) {
if (players[i].parent) {
game.removeChild(players[i]);
}
}
players = [];
createBoard();
createPlayers();
createDice();
createUI();
}
// Unlock next level when current level is completed
function unlockNextLevel() {
var levelKeys = Object.keys(levelConfigs);
var currentLevelIndex = levelKeys.indexOf(currentLevel);
if (currentLevelIndex !== -1 && currentLevelIndex < levelKeys.length - 1) {
var nextLevel = levelKeys[currentLevelIndex + 1];
if (storage.unlockedLevels.indexOf(nextLevel) === -1) {
storage.unlockedLevels.push(nextLevel);
}
}
}
// Show win message for specific player
function showWinMessage(playerNumber) {
// Update statistics
if (playerNumber === 1) {
storage.player1Wins = (storage.player1Wins || 0) + 1;
storage.player2Losses = (storage.player2Losses || 0) + 1;
} else {
storage.player2Wins = (storage.player2Wins || 0) + 1;
storage.player1Losses = (storage.player1Losses || 0) + 1;
}
// Unlock next level when completing current level
unlockNextLevel();
var winText = new Text2('Jugador ' + playerNumber + ' Ganaste!', {
size: 100,
fill: playerNumber === 1 ? 0xff0000 : 0x0000ff
});
winText.anchor.set(0.5, 0.5);
winText.x = 2048 / 2;
winText.y = 2732 / 2;
game.addChild(winText);
// Show level unlock message if a new level was unlocked
var levelKeys = Object.keys(levelConfigs);
var currentLevelIndex = levelKeys.indexOf(currentLevel);
if (currentLevelIndex !== -1 && currentLevelIndex < levelKeys.length - 1) {
var nextLevel = levelKeys[currentLevelIndex + 1];
var nextLevelConfig = levelConfigs[nextLevel];
var unlockText = new Text2('¡' + nextLevelConfig.name + ' DESBLOQUEADO!', {
size: 60,
fill: 0xFFD700
});
unlockText.anchor.set(0.5, 0.5);
unlockText.x = 2048 / 2;
unlockText.y = 2732 / 2 + 120;
game.addChild(unlockText);
}
LK.setTimeout(function () {
// Return to menu after win
while (game.children.length > 0) {
game.removeChild(game.children[0]);
}
inMenu = true;
mainMenu = new MainMenu();
game.addChild(mainMenu);
}, 2000);
}
// End current player's turn
function endTurn() {
players[currentPlayer].isMoving = false;
currentPlayer = (currentPlayer + 1) % 2;
}
// Return to main menu
function returnToMenu() {
while (game.children.length > 0) {
game.removeChild(game.children[0]);
}
inMenu = true;
gameStarted = false;
isGameOver = false;
mainMenu = new MainMenu();
game.addChild(mainMenu);
}
// Initialize main menu
mainMenu = new MainMenu();
game.addChild(mainMenu);