/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Cell = Container.expand(function () { var self = Container.call(this); var cellBg = self.attachAsset('cell', { anchorX: 0.5, anchorY: 0.5, alpha: 0.8 }); self.row = 0; self.col = 0; self.value = 0; // 0 = empty, 1 = X, 2 = O self.marker = null; self.highlight = function () { tween(cellBg, { alpha: 1 }, { duration: 200 }); }; self.unhighlight = function () { tween(cellBg, { alpha: 0.8 }, { duration: 200 }); }; self.setMarker = function (playerValue) { if (self.value !== 0) { return false; } self.value = playerValue; if (playerValue === 1) { self.marker = self.attachAsset('x_marker', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); } else { self.marker = self.attachAsset('o_marker', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); } tween(self.marker, { alpha: 1, scaleX: 1, scaleY: 1 }, { duration: 300, easing: tween.easeOut }); return true; }; self.reset = function () { self.value = 0; if (self.marker) { tween(self.marker, { alpha: 0 }, { duration: 200, onFinish: function onFinish() { if (self.marker) { self.marker.destroy(); self.marker = null; } } }); } }; self.down = function (x, y, obj) { if (gameState === STATE_PLAYER_TURN && self.value === 0 && (isTwoPlayerMode || currentPlayer === 1)) { if (self.setMarker(currentPlayer)) { LK.getSound('place').play(); checkGameState(); if (gameState === STATE_PLAYER_TURN) { // Game continues, switch player currentPlayer = currentPlayer === 1 ? 2 : 1; updateTurnIndicator(); } } } }; return self; }); var WinLine = Container.expand(function () { var self = Container.call(this); var line = self.attachAsset('board_bg', { anchorX: 0.5, anchorY: 0.5, alpha: 0, tint: 0x00ff00 }); line.width = 800; line.height = 20; self.showLine = function (startX, startY, endX, endY) { self.x = (startX + endX) / 2; self.y = (startY + endY) / 2; // Calculate rotation and length var dx = endX - startX; var dy = endY - startY; var distance = Math.sqrt(dx * dx + dy * dy); var angle = Math.atan2(dy, dx); line.width = distance; line.rotation = angle; tween(line, { alpha: 0.7 }, { duration: 500 }); }; self.hide = function () { tween(line, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { self.destroy(); } }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x004488 }); /**** * Game Code ****/ // Game constants var AIPlayer = function AIPlayer() { this.makeMove = function () { if (gameState !== STATE_PLAYER_TURN) { return; } // Simple AI: choose the first available cell for (var row = 0; row < GRID_SIZE; row++) { for (var col = 0; col < GRID_SIZE; col++) { if (gameBoard[row][col].value === 0) { gameBoard[row][col].setMarker(currentPlayer); LK.getSound('place').play(); checkGameState(); if (gameState === STATE_PLAYER_TURN) { currentPlayer = currentPlayer === 1 ? 2 : 1; updateTurnIndicator(); } return; } } } }; }; var GRID_SIZE = 4; var CELL_SIZE = 180; var CELL_SPACING = 10; var BOARD_SIZE = CELL_SIZE * GRID_SIZE + CELL_SPACING * (GRID_SIZE - 1); // Game states var STATE_PLAYER_TURN = 0; var STATE_GAME_OVER = 1; // AI player var aiPlayer = new AIPlayer(); var gameBoard = []; var gameState = STATE_PLAYER_TURN; var currentPlayer = 1; // 1 = X, 2 = O var isTwoPlayerMode = true; // Toggle for two player mode var winningCombos = []; // GUI elements var turnIndicator; var gameOverText; // Create board background var boardBg = LK.getAsset('board_bg', { anchorX: 0.5, anchorY: 0.5, width: BOARD_SIZE + 40, height: BOARD_SIZE + 40 }); boardBg.x = 2048 / 2; boardBg.y = 2732 / 2; game.addChild(boardBg); // Initialize turn indicator turnIndicator = new Text2('X\'s Turn', { size: 80, fill: 0xFFFFFF }); turnIndicator.anchor.set(0.5, 0); LK.gui.top.addChild(turnIndicator); turnIndicator.y = 100; // Initialize game over text (hidden initially) gameOverText = new Text2('', { size: 100, fill: 0xFFFFFF }); gameOverText.anchor.set(0.5, 0.5); gameOverText.visible = false; LK.gui.center.addChild(gameOverText); function initializeBoard() { // Clear any existing board if (gameBoard.length > 0) { for (var i = 0; i < gameBoard.length; i++) { for (var j = 0; j < gameBoard[i].length; j++) { if (gameBoard[i][j]) { gameBoard[i][j].destroy(); } } } } // Create new board gameBoard = []; var startX = 2048 / 2 - BOARD_SIZE / 2 + CELL_SIZE / 2; var startY = 2732 / 2 - BOARD_SIZE / 2 + CELL_SIZE / 2; for (var row = 0; row < GRID_SIZE; row++) { gameBoard[row] = []; for (var col = 0; col < GRID_SIZE; col++) { var cell = new Cell(); cell.row = row; cell.col = col; cell.x = startX + col * (CELL_SIZE + CELL_SPACING); cell.y = startY + row * (CELL_SIZE + CELL_SPACING); gameBoard[row][col] = cell; game.addChild(cell); } } // Define winning combinations defineWinningCombinations(); } function defineWinningCombinations() { winningCombos = []; // Rows for (var row = 0; row < GRID_SIZE; row++) { winningCombos.push([{ row: row, col: 0 }, { row: row, col: 1 }, { row: row, col: 2 }, { row: row, col: 3 }]); } // Columns for (var col = 0; col < GRID_SIZE; col++) { winningCombos.push([{ row: 0, col: col }, { row: 1, col: col }, { row: 2, col: col }, { row: 3, col: col }]); } // Diagonals winningCombos.push([{ row: 0, col: 0 }, { row: 1, col: 1 }, { row: 2, col: 2 }, { row: 3, col: 3 }]); winningCombos.push([{ row: 0, col: 3 }, { row: 1, col: 2 }, { row: 2, col: 1 }, { row: 3, col: 0 }]); } function checkGameState() { // Check for win var winResult = checkForWin(); if (winResult) { gameState = STATE_GAME_OVER; showWinLine(winResult.combo); updateGameOverText(currentPlayer === 1 ? "X Wins!" : "O Wins!"); LK.getSound('win').play(); LK.setScore(LK.getScore() + 1); return; } // Check for draw if (checkForDraw()) { gameState = STATE_GAME_OVER; updateGameOverText("Draw!"); LK.getSound('draw').play(); return; } } function checkForWin() { for (var i = 0; i < winningCombos.length; i++) { var combo = winningCombos[i]; var first = gameBoard[combo[0].row][combo[0].col].value; if (first !== 0) { var isWin = true; for (var j = 1; j < combo.length; j++) { if (gameBoard[combo[j].row][combo[j].col].value !== first) { isWin = false; break; } } if (isWin) { return { player: first, combo: combo }; } } } return null; } function checkForDraw() { for (var row = 0; row < GRID_SIZE; row++) { for (var col = 0; col < GRID_SIZE; col++) { if (gameBoard[row][col].value === 0) { return false; // Still empty cells } } } return true; } function showWinLine(combo) { var startCell = gameBoard[combo[0].row][combo[0].col]; var endCell = gameBoard[combo[combo.length - 1].row][combo[combo.length - 1].col]; var winLine = new WinLine(); game.addChild(winLine); winLine.showLine(startCell.x, startCell.y, endCell.x, endCell.y); } function updateTurnIndicator() { turnIndicator.setText(currentPlayer === 1 ? "X's Turn" : "O's Turn"); } function updateGameOverText(text) { gameOverText.setText(text); gameOverText.visible = true; // Show restart button after a delay LK.setTimeout(function () { LK.showGameOver(); }, 2000); } function restartGame() { // Reset game state gameState = STATE_PLAYER_TURN; currentPlayer = 1; // Reset board for (var row = 0; row < GRID_SIZE; row++) { for (var col = 0; col < GRID_SIZE; col++) { gameBoard[row][col].reset(); } } // Update UI updateTurnIndicator(); gameOverText.visible = false; } // Game setup initializeBoard(); updateTurnIndicator(); // Play background music LK.playMusic('bgmusic', { loop: true, fade: { start: 0, end: 0.3, duration: 1000 } }); // Game main loop game.update = function () { // This is called every frame if (!isTwoPlayerMode && currentPlayer === 2 && gameState === STATE_PLAYER_TURN) { aiPlayer.makeMove(); } };
===================================================================
--- original.js
+++ change.js
@@ -76,9 +76,9 @@
});
}
};
self.down = function (x, y, obj) {
- if (gameState === STATE_PLAYER_TURN && self.value === 0) {
+ if (gameState === STATE_PLAYER_TURN && self.value === 0 && (isTwoPlayerMode || currentPlayer === 1)) {
if (self.setMarker(currentPlayer)) {
LK.getSound('place').play();
checkGameState();
if (gameState === STATE_PLAYER_TURN) {
@@ -174,8 +174,9 @@
var aiPlayer = new AIPlayer();
var gameBoard = [];
var gameState = STATE_PLAYER_TURN;
var currentPlayer = 1; // 1 = X, 2 = O
+var isTwoPlayerMode = true; // Toggle for two player mode
var winningCombos = [];
// GUI elements
var turnIndicator;
var gameOverText;
@@ -394,8 +395,8 @@
});
// Game main loop
game.update = function () {
// This is called every frame
- if (currentPlayer === 2 && gameState === STATE_PLAYER_TURN) {
+ if (!isTwoPlayerMode && currentPlayer === 2 && gameState === STATE_PLAYER_TURN) {
aiPlayer.makeMove();
}
};
\ No newline at end of file