User prompt
Please fix the bug: 'Script error.' in or related to this line: 'storage.savedGame = gameData;' Line Number: 1042 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Cuando juegas, abajo en el medio abra un botón de "guardar" qué hace que no pierdas tu partida. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Donde los botones " 2 jugadores" y "vs la IA". aparecerá nuevo botón que es "modo historia" qué cuando tocas no te lleva a ningún lado pero te dice un texto que dice próximamente.
User prompt
En el menú agrega el botón "skins" dónde puedes cambiar las fichas del juego. Y sin errores.
User prompt
Corrige todos los errores que haya.
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'addChild')' in or related to this line: 'settingsContainer.addChild(spanishButton);' Line Number: 640
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'removeChild')' in or related to this line: 'settingsContainer.removeChild(spanishButton);' Line Number: 623
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'fill')' in or related to this line: 'spanishButton.fill = '#2ecc71';' Line Number: 622
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'style')' in or related to this line: 'spanishButton.style.fill = '#2ecc71';' Line Number: 622
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'fill')' in or related to this line: 'spanishButton.fill = '#2ecc71';' Line Number: 622
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'tint')' in or related to this line: 'spanishButton.tint = 0x2ecc71;' Line Number: 622
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'fill')' in or related to this line: 'spanishButton.fill = '#2ecc71';' Line Number: 622
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'tint')' in or related to this line: 'spanishButton.tint = 0x2ecc71;' Line Number: 622
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'fill')' in or related to this line: 'spanishButton.fill = '#2ecc71';' Line Number: 622
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'setText')' in or related to this line: 'gameModeTitle.setText('SELECCIONA MODO DE JUEGO');' Line Number: 654
User prompt
Ahora en el menú, coloca el botón ajustes donde te lleva a cambiar idioma que son "inglés" o "español" ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Que la linea amarilla brille. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Cuando toca el botón "jugar" te llevara a 2 modos que son "el de 2 jugadores" y "vs la Inteligencia artificial".
User prompt
Pero que se coloque bien la línea amarilla y encima de la ficha de tres en raya y no en otro lado ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Pero la línea amarilla solo aparece cuando alguien hace 3 en rayas
User prompt
Haz una Animación de línea ganadora (un trazo que se dibuja sobre la línea de 3 fichas). ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Pero que no se juegue una ronda por partida. Las rondas son infinitas y el botón de "Nueva ronda" solo funciona para vaciar el tablero sin perder el marcador acumulado
User prompt
Haz Un botón que diga "Nueva ronda" para vaciar el tablero sin perder el marcador acumulado.
User prompt
¿Pero no aparece?. Te dije que al inicio tienes un menú que diga "jugar" donde te lleva al juego.
User prompt
Puedes colocar un menú que diga "jugar" y "instrucciones"
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Cell = Container.expand(function (row, col) {
var self = Container.call(this);
self.row = row;
self.col = col;
self.state = 'empty'; // 'empty', 'X', 'O'
// Cell background
var background = self.attachAsset('cellBackground', {
anchorX: 0.5,
anchorY: 0.5
});
self.mark = null;
self.placeMark = function (markType) {
if (self.state !== 'empty') return false;
self.state = markType;
if (markType === 'X') {
var xAssetName = 'xMark';
if (currentSkin === 'blue') xAssetName = 'xMark_blue';else if (currentSkin === 'purple') xAssetName = 'xMark_purple';else if (currentSkin === 'orange') xAssetName = 'xMark_orange';
self.mark = self.attachAsset(xAssetName, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0,
scaleY: 0
});
tween(self.mark, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeOut
});
LK.getSound('placeX').play();
} else if (markType === 'O') {
var oAssetName = 'oMark';
if (currentSkin === 'blue') oAssetName = 'oMark_blue';else if (currentSkin === 'purple') oAssetName = 'oMark_purple';else if (currentSkin === 'orange') oAssetName = 'oMark_orange';
self.mark = self.attachAsset(oAssetName, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0,
scaleY: 0
});
tween(self.mark, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeOut
});
LK.getSound('placeO').play();
}
return true;
};
self.highlight = function () {
tween(background, {
tint: 0xf39c12
}, {
duration: 300,
easing: tween.easeInOut
});
};
self.down = function (x, y, obj) {
if (gameState === 'playing') {
handleCellClick(self);
}
};
return self;
});
var GameBoard = Container.expand(function () {
var self = Container.call(this);
// Grid background
var gridBg = self.attachAsset('gridBackground', {
anchorX: 0.5,
anchorY: 0.5
});
// Grid lines - vertical
var vLine1 = self.attachAsset('gridLine', {
anchorX: 0.5,
anchorY: 0.5,
x: -100,
rotation: Math.PI / 2
});
var vLine2 = self.attachAsset('gridLine', {
anchorX: 0.5,
anchorY: 0.5,
x: 100,
rotation: Math.PI / 2
});
// Grid lines - horizontal
var hLine1 = self.attachAsset('gridLine', {
anchorX: 0.5,
anchorY: 0.5,
y: -100
});
var hLine2 = self.attachAsset('gridLine', {
anchorX: 0.5,
anchorY: 0.5,
y: 100
});
self.cells = [];
// Create 3x3 grid of cells
for (var row = 0; row < 3; row++) {
self.cells[row] = [];
for (var col = 0; col < 3; col++) {
var cell = new Cell(row, col);
cell.x = (col - 1) * 200;
cell.y = (row - 1) * 200;
self.cells[row][col] = cell;
self.addChild(cell);
}
}
self.drawWinningLine = function (winningCells) {
// Calculate start and end positions
var startCell = winningCells[0];
var endCell = winningCells[2];
var startX = startCell.x;
var startY = startCell.y;
var endX = endCell.x;
var endY = endCell.y;
// Calculate line properties
var deltaX = endX - startX;
var deltaY = endY - startY;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
var angle = Math.atan2(deltaY, deltaX);
// Calculate center position for the line
var centerX = (startX + endX) / 2;
var centerY = (startY + endY) / 2;
// Create winning line with proper dimensions and positioning
var winningLine = self.attachAsset('winningLine', {
anchorX: 0.5,
anchorY: 0.5,
x: centerX,
y: centerY,
rotation: angle,
scaleX: 0,
width: distance + 40,
height: 8
});
// Animate the line drawing
tween(winningLine, {
scaleX: 1
}, {
duration: 800,
easing: tween.easeOut
});
// Add glowing effect by tweening alpha repeatedly
function glowEffect() {
tween(winningLine, {
alpha: 0.3
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(winningLine, {
alpha: 1
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: glowEffect
});
}
});
}
glowEffect();
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a252f
});
/****
* Game Code
****/
var gameBoard;
var currentPlayer = 'X';
var gameState = 'menu'; // 'menu', 'modeSelection', 'settings', 'playing', 'gameOver'
var gameMode = 'twoPlayer'; // 'twoPlayer', 'ai'
var playerXScore = 0;
var playerOScore = 0;
var drawScore = 0;
var currentLanguage = storage.language || 'spanish';
var currentSkin = storage.currentSkin || 'default';
// UI Elements
var currentPlayerText;
var scoreText;
var resultText;
// Menu UI
var menuContainer = new Container();
var menuTitle = new Text2('TIC TAC TOE', {
size: 160,
fill: 0xffffff
});
menuTitle.anchor.set(0.5, 0.5);
menuTitle.x = 2048 / 2;
menuTitle.y = 700;
menuContainer.addChild(menuTitle);
var playButton = new Text2('JUGAR', {
size: 120,
fill: 0x2ecc71
});
playButton.anchor.set(0.5, 0.5);
playButton.x = 2048 / 2;
playButton.y = 1100;
menuContainer.addChild(playButton);
var instructionsButton = new Text2('INSTRUCCIONES', {
size: 90,
fill: 0x3498db
});
instructionsButton.anchor.set(0.5, 0.5);
instructionsButton.x = 2048 / 2;
instructionsButton.y = 1300;
menuContainer.addChild(instructionsButton);
var settingsButton = new Text2('AJUSTES', {
size: 90,
fill: 0x9b59b6
});
settingsButton.anchor.set(0.5, 0.5);
settingsButton.x = 2048 / 2;
settingsButton.y = 1500;
menuContainer.addChild(settingsButton);
var skinsButton = new Text2('SKINS', {
size: 90,
fill: 0xf39c12
});
skinsButton.anchor.set(0.5, 0.5);
skinsButton.x = 2048 / 2;
skinsButton.y = 1700;
menuContainer.addChild(skinsButton);
var loadGameButton = new Text2('CARGAR JUEGO', {
size: 80,
fill: 0x27ae60
});
loadGameButton.anchor.set(0.5, 0.5);
loadGameButton.x = 2048 / 2;
loadGameButton.y = 1900;
menuContainer.addChild(loadGameButton);
var instructionsText = new Text2('Toca una celda vacía para colocar tu marca.\nConsigue tres en línea para ganar.\n¡Alterna turnos con tu oponente!', {
size: 70,
fill: 0xffffff,
align: 'center'
});
instructionsText.anchor.set(0.5, 0.5);
instructionsText.x = 2048 / 2;
instructionsText.y = 2100;
instructionsText.visible = false;
menuContainer.addChild(instructionsText);
game.addChild(menuContainer);
// Initialize language
updateAllTexts();
// Game Mode Selection UI
var gameModeContainer = new Container();
var gameModeTitle = new Text2('SELECCIONA MODO DE JUEGO', {
size: 120,
fill: 0xffffff
});
gameModeTitle.anchor.set(0.5, 0.5);
gameModeTitle.x = 2048 / 2;
gameModeTitle.y = 700;
gameModeContainer.addChild(gameModeTitle);
var twoPlayerButton = new Text2('2 JUGADORES', {
size: 100,
fill: 0x2ecc71
});
twoPlayerButton.anchor.set(0.5, 0.5);
twoPlayerButton.x = 2048 / 2;
twoPlayerButton.y = 1100;
gameModeContainer.addChild(twoPlayerButton);
var aiButton = new Text2('VS INTELIGENCIA ARTIFICIAL', {
size: 90,
fill: 0xe74c3c
});
aiButton.anchor.set(0.5, 0.5);
aiButton.x = 2048 / 2;
aiButton.y = 1300;
gameModeContainer.addChild(aiButton);
var storyModeButton = new Text2('MODO HISTORIA', {
size: 90,
fill: 0xf39c12
});
storyModeButton.anchor.set(0.5, 0.5);
storyModeButton.x = 2048 / 2;
storyModeButton.y = 1500;
gameModeContainer.addChild(storyModeButton);
var backButton = new Text2('VOLVER', {
size: 80,
fill: 0x95a5a6
});
backButton.anchor.set(0.5, 0.5);
backButton.x = 2048 / 2;
backButton.y = 1700;
gameModeContainer.addChild(backButton);
gameModeContainer.visible = false;
game.addChild(gameModeContainer);
// Settings UI
var settingsContainer = new Container();
var settingsTitle = new Text2('AJUSTES', {
size: 120,
fill: 0xffffff
});
settingsTitle.anchor.set(0.5, 0.5);
settingsTitle.x = 2048 / 2;
settingsTitle.y = 700;
settingsContainer.addChild(settingsTitle);
var languageLabel = new Text2('IDIOMA:', {
size: 90,
fill: 0xffffff
});
languageLabel.anchor.set(0.5, 0.5);
languageLabel.x = 2048 / 2;
languageLabel.y = 1000;
settingsContainer.addChild(languageLabel);
var spanishButton = new Text2('ESPAÑOL', {
size: 80,
fill: 0x2ecc71
});
spanishButton.anchor.set(0.5, 0.5);
spanishButton.x = 2048 / 2;
spanishButton.y = 1200;
settingsContainer.addChild(spanishButton);
var englishButton = new Text2('ENGLISH', {
size: 80,
fill: 0x3498db
});
englishButton.anchor.set(0.5, 0.5);
englishButton.x = 2048 / 2;
englishButton.y = 1400;
settingsContainer.addChild(englishButton);
var settingsBackButton = new Text2('VOLVER', {
size: 80,
fill: 0x95a5a6
});
settingsBackButton.anchor.set(0.5, 0.5);
settingsBackButton.x = 2048 / 2;
settingsBackButton.y = 1600;
settingsContainer.addChild(settingsBackButton);
settingsContainer.visible = false;
game.addChild(settingsContainer);
// Skins UI
var skinsContainer = new Container();
var skinsTitle = new Text2('SKINS', {
size: 120,
fill: 0xffffff
});
skinsTitle.anchor.set(0.5, 0.5);
skinsTitle.x = 2048 / 2;
skinsTitle.y = 600;
skinsContainer.addChild(skinsTitle);
var skinLabel = new Text2('SELECCIONA ESTILO:', {
size: 80,
fill: 0xffffff
});
skinLabel.anchor.set(0.5, 0.5);
skinLabel.x = 2048 / 2;
skinLabel.y = 800;
skinsContainer.addChild(skinLabel);
// Default skin button
var defaultSkinButton = new Text2('CLÁSICO', {
size: 70,
fill: 0x2ecc71
});
defaultSkinButton.anchor.set(0.5, 0.5);
defaultSkinButton.x = 2048 / 2;
defaultSkinButton.y = 1000;
skinsContainer.addChild(defaultSkinButton);
// Blue skin button
var blueSkinButton = new Text2('AZUL', {
size: 70,
fill: 0x3498db
});
blueSkinButton.anchor.set(0.5, 0.5);
blueSkinButton.x = 2048 / 2;
blueSkinButton.y = 1200;
skinsContainer.addChild(blueSkinButton);
// Purple skin button
var purpleSkinButton = new Text2('MORADO', {
size: 70,
fill: 0x9b59b6
});
purpleSkinButton.anchor.set(0.5, 0.5);
purpleSkinButton.x = 2048 / 2;
purpleSkinButton.y = 1400;
skinsContainer.addChild(purpleSkinButton);
// Orange skin button
var orangeSkinButton = new Text2('NARANJA', {
size: 70,
fill: 0xf39c12
});
orangeSkinButton.anchor.set(0.5, 0.5);
orangeSkinButton.x = 2048 / 2;
orangeSkinButton.y = 1600;
skinsContainer.addChild(orangeSkinButton);
var skinsBackButton = new Text2('VOLVER', {
size: 80,
fill: 0x95a5a6
});
skinsBackButton.anchor.set(0.5, 0.5);
skinsBackButton.x = 2048 / 2;
skinsBackButton.y = 1800;
skinsContainer.addChild(skinsBackButton);
skinsContainer.visible = false;
game.addChild(skinsContainer);
// Play button event
playButton.down = function (x, y, obj) {
showGameModeSelection();
};
// Instructions button event
instructionsButton.down = function (x, y, obj) {
instructionsText.visible = !instructionsText.visible;
};
// Settings button event
settingsButton.down = function (x, y, obj) {
showSettings();
};
// Skins button event
skinsButton.down = function (x, y, obj) {
showSkins();
};
// Load game button event
loadGameButton.down = function (x, y, obj) {
if (storage.savedGame) {
menuContainer.visible = false;
gameState = 'playing';
// Create UI elements
currentPlayerText = new Text2('Player X\'s Turn', {
size: 80,
fill: 0xFFFFFF
});
currentPlayerText.anchor.set(0.5, 0.5);
currentPlayerText.x = 2048 / 2;
currentPlayerText.y = 400;
game.addChild(currentPlayerText);
scoreText = new Text2('X: 0 | O: 0 | Draws: 0', {
size: 60,
fill: 0xBDC3C7
});
scoreText.anchor.set(0.5, 0.5);
scoreText.x = 2048 / 2;
scoreText.y = 300;
game.addChild(scoreText);
resultText = new Text2('', {
size: 100,
fill: 0xF39C12
});
resultText.anchor.set(0.5, 0.5);
resultText.x = 2048 / 2;
resultText.y = 2000;
resultText.alpha = 0;
game.addChild(resultText);
// Add save button
var saveButton = new Text2('GUARDAR', {
size: 60,
fill: 0x27ae60
});
saveButton.anchor.set(0.5, 0.5);
saveButton.x = 2048 / 2;
saveButton.y = 2100;
game.addChild(saveButton);
saveButton.down = function (x, y, obj) {
if (gameState === 'playing') {
saveGame();
}
};
// Add new round button
var newRoundButton = new Text2('NUEVA RONDA', {
size: 70,
fill: 0x9b59b6
});
newRoundButton.anchor.set(0.5, 0.5);
newRoundButton.x = 2048 / 2;
newRoundButton.y = 2200;
game.addChild(newRoundButton);
newRoundButton.down = function (x, y, obj) {
if (gameState === 'playing') {
startNewRound();
}
};
loadGame();
}
};
// Game mode button events
twoPlayerButton.down = function (x, y, obj) {
gameMode = 'twoPlayer';
startGame();
};
aiButton.down = function (x, y, obj) {
gameMode = 'ai';
startGame();
};
storyModeButton.down = function (x, y, obj) {
showComingSoonMessage();
};
backButton.down = function (x, y, obj) {
showMainMenu();
};
// Language selection events
spanishButton.down = function (x, y, obj) {
setLanguage('spanish');
};
englishButton.down = function (x, y, obj) {
setLanguage('english');
};
settingsBackButton.down = function (x, y, obj) {
showMainMenu();
};
// Skin selection events
defaultSkinButton.down = function (x, y, obj) {
setSkin('default');
};
blueSkinButton.down = function (x, y, obj) {
setSkin('blue');
};
purpleSkinButton.down = function (x, y, obj) {
setSkin('purple');
};
orangeSkinButton.down = function (x, y, obj) {
setSkin('orange');
};
skinsBackButton.down = function (x, y, obj) {
showMainMenu();
};
// Start game function
function startGame() {
menuContainer.visible = false;
gameModeContainer.visible = false;
gameState = 'playing';
// Initialize game board
gameBoard = new GameBoard();
gameBoard.x = 2048 / 2;
gameBoard.y = 2732 / 2 - 100;
game.addChild(gameBoard);
// Current player indicator
currentPlayerText = new Text2('Player X\'s Turn', {
size: 80,
fill: 0xFFFFFF
});
currentPlayerText.anchor.set(0.5, 0.5);
currentPlayerText.x = 2048 / 2;
currentPlayerText.y = 400;
game.addChild(currentPlayerText);
// Score display
scoreText = new Text2('X: 0 | O: 0 | Draws: 0', {
size: 60,
fill: 0xBDC3C7
});
scoreText.anchor.set(0.5, 0.5);
scoreText.x = 2048 / 2;
scoreText.y = 300;
game.addChild(scoreText);
// Result text (initially hidden)
resultText = new Text2('', {
size: 100,
fill: 0xF39C12
});
resultText.anchor.set(0.5, 0.5);
resultText.x = 2048 / 2;
resultText.y = 2000;
resultText.alpha = 0;
game.addChild(resultText);
// Save button
var saveButton = new Text2('GUARDAR', {
size: 60,
fill: 0x27ae60
});
saveButton.anchor.set(0.5, 0.5);
saveButton.x = 2048 / 2;
saveButton.y = 2100;
game.addChild(saveButton);
// Save button event
saveButton.down = function (x, y, obj) {
if (gameState === 'playing') {
saveGame();
}
};
// Nueva Ronda button
var newRoundButton = new Text2('NUEVA RONDA', {
size: 70,
fill: 0x9b59b6
});
newRoundButton.anchor.set(0.5, 0.5);
newRoundButton.x = 2048 / 2;
newRoundButton.y = 2200;
game.addChild(newRoundButton);
// Nueva Ronda button event
newRoundButton.down = function (x, y, obj) {
if (gameState === 'playing') {
startNewRound();
}
};
}
function handleCellClick(cell) {
if (cell.placeMark(currentPlayer)) {
var winner = checkWinner();
if (winner) {
handleGameEnd(winner);
} else if (isBoardFull()) {
handleGameEnd('draw');
} else {
// Switch players
currentPlayer = currentPlayer === 'X' ? 'O' : 'X';
updateCurrentPlayerText();
// If AI mode and now it's O's turn (AI), make AI move after a short delay
if (gameMode === 'ai' && currentPlayer === 'O') {
LK.setTimeout(function () {
makeAIMove();
}, 500);
}
}
}
}
function checkWinner() {
var cells = gameBoard.cells;
// Check rows
for (var row = 0; row < 3; row++) {
if (cells[row][0].state === cells[row][1].state && cells[row][1].state === cells[row][2].state && cells[row][0].state !== 'empty') {
highlightWinningCells([cells[row][0], cells[row][1], cells[row][2]]);
return cells[row][0].state;
}
}
// Check columns
for (var col = 0; col < 3; col++) {
if (cells[0][col].state === cells[1][col].state && cells[1][col].state === cells[2][col].state && cells[0][col].state !== 'empty') {
highlightWinningCells([cells[0][col], cells[1][col], cells[2][col]]);
return cells[0][col].state;
}
}
// Check diagonals
if (cells[0][0].state === cells[1][1].state && cells[1][1].state === cells[2][2].state && cells[0][0].state !== 'empty') {
highlightWinningCells([cells[0][0], cells[1][1], cells[2][2]]);
return cells[0][0].state;
}
if (cells[0][2].state === cells[1][1].state && cells[1][1].state === cells[2][0].state && cells[0][2].state !== 'empty') {
highlightWinningCells([cells[0][2], cells[1][1], cells[2][0]]);
return cells[0][2].state;
}
return null;
}
function isBoardFull() {
var cells = gameBoard.cells;
for (var row = 0; row < 3; row++) {
for (var col = 0; col < 3; col++) {
if (cells[row][col].state === 'empty') {
return false;
}
}
}
return true;
}
function highlightWinningCells(winningCells) {
for (var i = 0; i < winningCells.length; i++) {
winningCells[i].highlight();
}
// Draw winning line animation immediately
gameBoard.drawWinningLine(winningCells);
}
function handleGameEnd(result) {
if (result === 'X') {
playerXScore++;
if (gameMode === 'ai') {
resultText.setText('You Win!');
} else {
resultText.setText('Player X Wins!');
}
resultText.tint = 0xe74c3c;
LK.getSound('win').play();
LK.setScore(LK.getScore() + 10);
} else if (result === 'O') {
playerOScore++;
if (gameMode === 'ai') {
resultText.setText('AI Wins!');
} else {
resultText.setText('Player O Wins!');
}
resultText.tint = 0x2ecc71;
LK.getSound('win').play();
LK.setScore(LK.getScore() + 10);
} else if (result === 'draw') {
drawScore++;
resultText.setText('It\'s a Draw!');
resultText.tint = 0xf39c12;
LK.getSound('draw').play();
LK.setScore(LK.getScore() + 5);
}
updateScoreText();
showResult();
// Auto start new round after 2 seconds
LK.setTimeout(function () {
startNewRound();
}, 2000);
}
function showResult() {
resultText.alpha = 1;
resultText.y = 1800;
tween(resultText, {
y: 1600
}, {
duration: 500,
easing: tween.easeOut
});
}
function updateCurrentPlayerText() {
if (gameMode === 'ai') {
if (currentPlayer === 'X') {
currentPlayerText.setText('Your Turn');
currentPlayerText.tint = 0xe74c3c;
} else {
currentPlayerText.setText('AI\'s Turn');
currentPlayerText.tint = 0x2ecc71;
}
} else {
if (currentPlayer === 'X') {
currentPlayerText.setText('Player X\'s Turn');
currentPlayerText.tint = 0xe74c3c;
} else {
currentPlayerText.setText('Player O\'s Turn');
currentPlayerText.tint = 0x2ecc71;
}
}
}
function updateScoreText() {
scoreText.setText('X: ' + playerXScore + ' | O: ' + playerOScore + ' | Draws: ' + drawScore);
}
function makeAIMove() {
if (gameState !== 'playing') return;
var cells = gameBoard.cells;
var emptyCells = [];
// Find all empty cells
for (var row = 0; row < 3; row++) {
for (var col = 0; col < 3; col++) {
if (cells[row][col].state === 'empty') {
emptyCells.push(cells[row][col]);
}
}
}
// Simple AI: choose random empty cell
if (emptyCells.length > 0) {
var randomIndex = Math.floor(Math.random() * emptyCells.length);
var selectedCell = emptyCells[randomIndex];
handleCellClick(selectedCell);
}
}
function startNewRound() {
// Remove current game board
if (gameBoard) {
game.removeChild(gameBoard);
gameBoard = null;
}
// Reset game state but keep scores
currentPlayer = 'X';
gameState = 'playing';
// Create new game board
gameBoard = new GameBoard();
gameBoard.x = 2048 / 2;
gameBoard.y = 2732 / 2 - 100;
game.addChild(gameBoard);
// Update UI
updateCurrentPlayerText();
resultText.alpha = 0;
}
function showGameModeSelection() {
menuContainer.visible = false;
gameModeContainer.visible = true;
gameState = 'modeSelection';
}
function showMainMenu() {
gameModeContainer.visible = false;
settingsContainer.visible = false;
skinsContainer.visible = false;
menuContainer.visible = true;
gameState = 'menu';
}
function showSettings() {
menuContainer.visible = false;
settingsContainer.visible = true;
gameState = 'settings';
updateLanguageButtons();
}
function showSkins() {
menuContainer.visible = false;
skinsContainer.visible = true;
gameState = 'skins';
updateSkinButtons();
}
function showComingSoonMessage() {
var comingSoonText = new Text2('PRÓXIMAMENTE', {
size: 100,
fill: 0xf39c12
});
comingSoonText.anchor.set(0.5, 0.5);
comingSoonText.x = 2048 / 2;
comingSoonText.y = 2732 / 2;
comingSoonText.alpha = 0;
game.addChild(comingSoonText);
tween(comingSoonText, {
alpha: 1
}, {
duration: 500,
easing: tween.easeOut
});
LK.setTimeout(function () {
tween(comingSoonText, {
alpha: 0
}, {
duration: 500,
easing: tween.easeIn,
onFinish: function onFinish() {
game.removeChild(comingSoonText);
}
});
}, 2000);
}
function setSkin(skin) {
currentSkin = skin;
storage.currentSkin = skin;
updateSkinButtons();
}
function updateSkinButtons() {
if (!skinsContainer || !defaultSkinButton || !blueSkinButton || !purpleSkinButton || !orangeSkinButton) return;
// Reset all button colors
defaultSkinButton.tint = 0x95a5a6;
blueSkinButton.tint = 0x95a5a6;
purpleSkinButton.tint = 0x95a5a6;
orangeSkinButton.tint = 0x95a5a6;
// Highlight selected skin
if (currentSkin === 'default') {
defaultSkinButton.tint = 0x2ecc71;
} else if (currentSkin === 'blue') {
blueSkinButton.tint = 0x3498db;
} else if (currentSkin === 'purple') {
purpleSkinButton.tint = 0x9b59b6;
} else if (currentSkin === 'orange') {
orangeSkinButton.tint = 0xf39c12;
}
}
function setLanguage(language) {
currentLanguage = language;
storage.language = language;
updateAllTexts();
updateLanguageButtons();
}
function updateLanguageButtons() {
if (!settingsContainer || !spanishButton || !englishButton) return; // Safety check to prevent errors
if (currentLanguage === 'spanish') {
spanishButton.tint = 0x2ecc71;
englishButton.tint = 0x95a5a6;
} else {
spanishButton.tint = 0x95a5a6;
englishButton.tint = 0x3498db;
}
}
function updateAllTexts() {
if (currentLanguage === 'english') {
// Update menu texts
menuTitle.setText('TIC TAC TOE');
playButton.setText('PLAY');
instructionsButton.setText('INSTRUCTIONS');
settingsButton.setText('SETTINGS');
skinsButton.setText('SKINS');
if (loadGameButton) loadGameButton.setText('LOAD GAME');
instructionsText.setText('Touch an empty cell to place your mark.\nGet three in a line to win.\nAlternate turns with your opponent!');
// Update game mode texts
if (gameModeTitle) gameModeTitle.setText('SELECT GAME MODE');
if (twoPlayerButton) twoPlayerButton.setText('2 PLAYERS');
if (aiButton) aiButton.setText('VS ARTIFICIAL INTELLIGENCE');
if (storyModeButton) storyModeButton.setText('STORY MODE');
if (backButton) backButton.setText('BACK');
// Update settings texts
if (settingsTitle) settingsTitle.setText('SETTINGS');
if (languageLabel) languageLabel.setText('LANGUAGE:');
if (settingsBackButton) settingsBackButton.setText('BACK');
// Update skins texts
if (skinsTitle) skinsTitle.setText('SKINS');
if (skinLabel) skinLabel.setText('SELECT STYLE:');
if (defaultSkinButton) defaultSkinButton.setText('CLASSIC');
if (blueSkinButton) blueSkinButton.setText('BLUE');
if (purpleSkinButton) purpleSkinButton.setText('PURPLE');
if (orangeSkinButton) orangeSkinButton.setText('ORANGE');
if (skinsBackButton) skinsBackButton.setText('BACK');
} else {
// Spanish texts (default)
menuTitle.setText('TIC TAC TOE');
playButton.setText('JUGAR');
instructionsButton.setText('INSTRUCCIONES');
settingsButton.setText('AJUSTES');
skinsButton.setText('SKINS');
if (loadGameButton) loadGameButton.setText('CARGAR JUEGO');
instructionsText.setText('Toca una celda vacía para colocar tu marca.\nConsigue tres en línea para ganar.\n¡Alterna turnos con tu oponente!');
// Update game mode texts
if (gameModeTitle) gameModeTitle.setText('SELECCIONA MODO DE JUEGO');
if (twoPlayerButton) twoPlayerButton.setText('2 JUGADORES');
if (aiButton) aiButton.setText('VS INTELIGENCIA ARTIFICIAL');
if (storyModeButton) storyModeButton.setText('MODO HISTORIA');
if (backButton) backButton.setText('VOLVER');
// Update settings texts
if (settingsTitle) settingsTitle.setText('AJUSTES');
if (languageLabel) languageLabel.setText('IDIOMA:');
if (settingsBackButton) settingsBackButton.setText('VOLVER');
// Update skins texts
if (skinsTitle) skinsTitle.setText('SKINS');
if (skinLabel) skinLabel.setText('SELECCIONA ESTILO:');
if (defaultSkinButton) defaultSkinButton.setText('CLÁSICO');
if (blueSkinButton) blueSkinButton.setText('AZUL');
if (purpleSkinButton) purpleSkinButton.setText('MORADO');
if (orangeSkinButton) orangeSkinButton.setText('NARANJA');
if (skinsBackButton) skinsBackButton.setText('VOLVER');
}
}
function saveGame() {
if (!gameBoard) return;
var gameData = {
currentPlayer: currentPlayer,
playerXScore: playerXScore,
playerOScore: playerOScore,
drawScore: drawScore,
gameMode: gameMode,
boardState: []
};
// Save board state
for (var row = 0; row < 3; row++) {
gameData.boardState[row] = [];
for (var col = 0; col < 3; col++) {
gameData.boardState[row][col] = gameBoard.cells[row][col].state;
}
}
storage.savedGame = gameData;
// Show save confirmation
var saveText = new Text2('JUEGO GUARDADO', {
size: 80,
fill: 0x27ae60
});
saveText.anchor.set(0.5, 0.5);
saveText.x = 2048 / 2;
saveText.y = 2732 / 2;
saveText.alpha = 0;
game.addChild(saveText);
tween(saveText, {
alpha: 1
}, {
duration: 300,
easing: tween.easeOut
});
LK.setTimeout(function () {
tween(saveText, {
alpha: 0
}, {
duration: 300,
easing: tween.easeIn,
onFinish: function onFinish() {
game.removeChild(saveText);
}
});
}, 1500);
}
function loadGame() {
var gameData = storage.savedGame;
if (!gameData) return false;
// Restore game state
currentPlayer = gameData.currentPlayer;
playerXScore = gameData.playerXScore;
playerOScore = gameData.playerOScore;
drawScore = gameData.drawScore;
gameMode = gameData.gameMode;
// Create new game board
gameBoard = new GameBoard();
gameBoard.x = 2048 / 2;
gameBoard.y = 2732 / 2 - 100;
game.addChild(gameBoard);
// Restore board state
for (var row = 0; row < 3; row++) {
for (var col = 0; col < 3; col++) {
var cellState = gameData.boardState[row][col];
if (cellState !== 'empty') {
gameBoard.cells[row][col].placeMark(cellState);
}
}
}
// Update UI
updateCurrentPlayerText();
updateScoreText();
return true;
}
function resetGame() {
// Remove game board and UI, show menu again
if (gameBoard) {
game.removeChild(gameBoard);
gameBoard = null;
}
if (currentPlayerText) {
game.removeChild(currentPlayerText);
currentPlayerText = null;
}
if (scoreText) {
game.removeChild(scoreText);
scoreText = null;
}
if (resultText) {
game.removeChild(resultText);
resultText = null;
}
menuContainer.visible = true;
gameState = 'menu';
currentPlayer = 'X';
}
// Touch anywhere to restart when game is over
game.down = function (x, y, obj) {
// Prevent board interaction in menu
if (gameState === 'menu') {
return;
}
};
game.update = function () {
// Game logic is handled through events
}; ===================================================================
--- original.js
+++ change.js
@@ -237,16 +237,24 @@
skinsButton.anchor.set(0.5, 0.5);
skinsButton.x = 2048 / 2;
skinsButton.y = 1700;
menuContainer.addChild(skinsButton);
+var loadGameButton = new Text2('CARGAR JUEGO', {
+ size: 80,
+ fill: 0x27ae60
+});
+loadGameButton.anchor.set(0.5, 0.5);
+loadGameButton.x = 2048 / 2;
+loadGameButton.y = 1900;
+menuContainer.addChild(loadGameButton);
var instructionsText = new Text2('Toca una celda vacía para colocar tu marca.\nConsigue tres en línea para ganar.\n¡Alterna turnos con tu oponente!', {
size: 70,
fill: 0xffffff,
align: 'center'
});
instructionsText.anchor.set(0.5, 0.5);
instructionsText.x = 2048 / 2;
-instructionsText.y = 1900;
+instructionsText.y = 2100;
instructionsText.visible = false;
menuContainer.addChild(instructionsText);
game.addChild(menuContainer);
// Initialize language
@@ -418,8 +426,70 @@
// Skins button event
skinsButton.down = function (x, y, obj) {
showSkins();
};
+// Load game button event
+loadGameButton.down = function (x, y, obj) {
+ if (storage.savedGame) {
+ menuContainer.visible = false;
+ gameState = 'playing';
+ // Create UI elements
+ currentPlayerText = new Text2('Player X\'s Turn', {
+ size: 80,
+ fill: 0xFFFFFF
+ });
+ currentPlayerText.anchor.set(0.5, 0.5);
+ currentPlayerText.x = 2048 / 2;
+ currentPlayerText.y = 400;
+ game.addChild(currentPlayerText);
+ scoreText = new Text2('X: 0 | O: 0 | Draws: 0', {
+ size: 60,
+ fill: 0xBDC3C7
+ });
+ scoreText.anchor.set(0.5, 0.5);
+ scoreText.x = 2048 / 2;
+ scoreText.y = 300;
+ game.addChild(scoreText);
+ resultText = new Text2('', {
+ size: 100,
+ fill: 0xF39C12
+ });
+ resultText.anchor.set(0.5, 0.5);
+ resultText.x = 2048 / 2;
+ resultText.y = 2000;
+ resultText.alpha = 0;
+ game.addChild(resultText);
+ // Add save button
+ var saveButton = new Text2('GUARDAR', {
+ size: 60,
+ fill: 0x27ae60
+ });
+ saveButton.anchor.set(0.5, 0.5);
+ saveButton.x = 2048 / 2;
+ saveButton.y = 2100;
+ game.addChild(saveButton);
+ saveButton.down = function (x, y, obj) {
+ if (gameState === 'playing') {
+ saveGame();
+ }
+ };
+ // Add new round button
+ var newRoundButton = new Text2('NUEVA RONDA', {
+ size: 70,
+ fill: 0x9b59b6
+ });
+ newRoundButton.anchor.set(0.5, 0.5);
+ newRoundButton.x = 2048 / 2;
+ newRoundButton.y = 2200;
+ game.addChild(newRoundButton);
+ newRoundButton.down = function (x, y, obj) {
+ if (gameState === 'playing') {
+ startNewRound();
+ }
+ };
+ loadGame();
+ }
+};
// Game mode button events
twoPlayerButton.down = function (x, y, obj) {
gameMode = 'twoPlayer';
startGame();
@@ -497,8 +567,23 @@
resultText.x = 2048 / 2;
resultText.y = 2000;
resultText.alpha = 0;
game.addChild(resultText);
+ // Save button
+ var saveButton = new Text2('GUARDAR', {
+ size: 60,
+ fill: 0x27ae60
+ });
+ saveButton.anchor.set(0.5, 0.5);
+ saveButton.x = 2048 / 2;
+ saveButton.y = 2100;
+ game.addChild(saveButton);
+ // Save button event
+ saveButton.down = function (x, y, obj) {
+ if (gameState === 'playing') {
+ saveGame();
+ }
+ };
// Nueva Ronda button
var newRoundButton = new Text2('NUEVA RONDA', {
size: 70,
fill: 0x9b59b6
@@ -781,8 +866,9 @@
playButton.setText('PLAY');
instructionsButton.setText('INSTRUCTIONS');
settingsButton.setText('SETTINGS');
skinsButton.setText('SKINS');
+ if (loadGameButton) loadGameButton.setText('LOAD GAME');
instructionsText.setText('Touch an empty cell to place your mark.\nGet three in a line to win.\nAlternate turns with your opponent!');
// Update game mode texts
if (gameModeTitle) gameModeTitle.setText('SELECT GAME MODE');
if (twoPlayerButton) twoPlayerButton.setText('2 PLAYERS');
@@ -807,8 +893,9 @@
playButton.setText('JUGAR');
instructionsButton.setText('INSTRUCCIONES');
settingsButton.setText('AJUSTES');
skinsButton.setText('SKINS');
+ if (loadGameButton) loadGameButton.setText('CARGAR JUEGO');
instructionsText.setText('Toca una celda vacía para colocar tu marca.\nConsigue tres en línea para ganar.\n¡Alterna turnos con tu oponente!');
// Update game mode texts
if (gameModeTitle) gameModeTitle.setText('SELECCIONA MODO DE JUEGO');
if (twoPlayerButton) twoPlayerButton.setText('2 JUGADORES');
@@ -828,8 +915,82 @@
if (orangeSkinButton) orangeSkinButton.setText('NARANJA');
if (skinsBackButton) skinsBackButton.setText('VOLVER');
}
}
+function saveGame() {
+ if (!gameBoard) return;
+ var gameData = {
+ currentPlayer: currentPlayer,
+ playerXScore: playerXScore,
+ playerOScore: playerOScore,
+ drawScore: drawScore,
+ gameMode: gameMode,
+ boardState: []
+ };
+ // Save board state
+ for (var row = 0; row < 3; row++) {
+ gameData.boardState[row] = [];
+ for (var col = 0; col < 3; col++) {
+ gameData.boardState[row][col] = gameBoard.cells[row][col].state;
+ }
+ }
+ storage.savedGame = gameData;
+ // Show save confirmation
+ var saveText = new Text2('JUEGO GUARDADO', {
+ size: 80,
+ fill: 0x27ae60
+ });
+ saveText.anchor.set(0.5, 0.5);
+ saveText.x = 2048 / 2;
+ saveText.y = 2732 / 2;
+ saveText.alpha = 0;
+ game.addChild(saveText);
+ tween(saveText, {
+ alpha: 1
+ }, {
+ duration: 300,
+ easing: tween.easeOut
+ });
+ LK.setTimeout(function () {
+ tween(saveText, {
+ alpha: 0
+ }, {
+ duration: 300,
+ easing: tween.easeIn,
+ onFinish: function onFinish() {
+ game.removeChild(saveText);
+ }
+ });
+ }, 1500);
+}
+function loadGame() {
+ var gameData = storage.savedGame;
+ if (!gameData) return false;
+ // Restore game state
+ currentPlayer = gameData.currentPlayer;
+ playerXScore = gameData.playerXScore;
+ playerOScore = gameData.playerOScore;
+ drawScore = gameData.drawScore;
+ gameMode = gameData.gameMode;
+ // Create new game board
+ gameBoard = new GameBoard();
+ gameBoard.x = 2048 / 2;
+ gameBoard.y = 2732 / 2 - 100;
+ game.addChild(gameBoard);
+ // Restore board state
+ for (var row = 0; row < 3; row++) {
+ for (var col = 0; col < 3; col++) {
+ var cellState = gameData.boardState[row][col];
+ if (cellState !== 'empty') {
+ gameBoard.cells[row][col].placeMark(cellState);
+ }
+ }
+ }
+ // Update UI
+ updateCurrentPlayerText();
+ updateScoreText();
+ return true;
+}
function resetGame() {
// Remove game board and UI, show menu again
if (gameBoard) {
game.removeChild(gameBoard);