User prompt
can the texts colour to white
User prompt
Set a pixel-art style background that looks like an old arcade game screen. Use dark tones with neon grid lines to create a retro gaming atmosphere.
Code edit (1 edits merged)
Please save this source code
Initial prompt
Tic Tac Toe: Human vs Computer
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// BoardCell: Represents a single cell in the Tic Tac Toe grid
var BoardCell = Container.expand(function () {
var self = Container.call(this);
// Cell state: 0 = empty, 1 = player (X), 2 = AI (O)
self.state = 0;
self.row = 0;
self.col = 0;
// Draw cell background (box)
var cellBg = self.attachAsset('cellBg', {
anchorX: 0.5,
anchorY: 0.5
});
self.cellBg = cellBg;
// X and O graphics (hidden by default)
var xMark = self.attachAsset('xMark', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
self.xMark = xMark;
var oMark = self.attachAsset('oMark', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
self.oMark = oMark;
// Highlight overlay (for winning line)
var highlight = self.attachAsset('highlight', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
self.highlight = highlight;
// Set cell state and update graphics
self.setState = function (state) {
self.state = state;
if (state === 1) {
self.xMark.alpha = 1;
self.oMark.alpha = 0;
} else if (state === 2) {
self.xMark.alpha = 0;
self.oMark.alpha = 1;
} else {
self.xMark.alpha = 0;
self.oMark.alpha = 0;
}
};
// Show highlight overlay
self.showHighlight = function () {
self.highlight.alpha = 0.5;
};
// Hide highlight overlay
self.hideHighlight = function () {
self.highlight.alpha = 0;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xffffff
});
/****
* Game Code
****/
// --- Game Variables ---
// --- Asset Initialization ---
// Cell background (light gray box)
// X mark (red)
// O mark (blue ellipse)
// Highlight overlay (yellow, semi-transparent)
var boardSize = 3;
var cellSize = 480; // px (for 3x3 grid, fits well in 2048x2732)
var board = []; // 2D array of BoardCell
var boardState = []; // 2D array of 0 (empty), 1 (player), 2 (AI)
var currentPlayer = 1; // 1 = player, 2 = AI
var gameActive = true;
var winningLine = null; // Array of [row, col] for winning cells
// UI elements
var statusText = null;
var playAgainBtn = null;
// --- Board Setup ---
// Center the board
var boardOriginX = Math.floor((2048 - cellSize * boardSize) / 2);
var boardOriginY = Math.floor((2732 - cellSize * boardSize) / 2);
// Create board cells
for (var row = 0; row < boardSize; row++) {
board[row] = [];
boardState[row] = [];
for (var col = 0; col < boardSize; col++) {
var cell = new BoardCell();
cell.x = boardOriginX + col * cellSize + cellSize / 2;
cell.y = boardOriginY + row * cellSize + cellSize / 2;
cell.row = row;
cell.col = col;
cell.setState(0);
cell.hideHighlight();
board[row][col] = cell;
boardState[row][col] = 0;
game.addChild(cell);
// Cell tap handler
cell.down = function (cellRef) {
return function (x, y, obj) {
if (!gameActive) return;
if (currentPlayer !== 1) return;
if (boardState[cellRef.row][cellRef.col] !== 0) return;
playerMove(cellRef.row, cellRef.col);
};
}(cell);
}
}
// --- Status Text ---
statusText = new Text2('Your turn', {
size: 120,
fill: 0x222222
});
statusText.anchor.set(0.5, 0);
LK.gui.top.addChild(statusText);
// --- Play Again Button ---
playAgainBtn = new Text2('Play Again', {
size: 100,
fill: 0xFFFFFF
});
playAgainBtn.anchor.set(0.5, 0.5);
playAgainBtn.x = 2048 / 2;
playAgainBtn.y = 2732 - 350;
playAgainBtn.visible = false;
playAgainBtn.bg = LK.getAsset('playAgainBg', {
width: 600,
height: 180,
color: 0x2a6edb,
anchorX: 0.5,
anchorY: 0.5
});
playAgainBtn.bg.y = 0;
playAgainBtn.bg.x = 0;
playAgainBtn.addChild(playAgainBtn.bg);
playAgainBtn.setChildIndex(playAgainBtn.bg, 0);
game.addChild(playAgainBtn);
// Play Again tap handler
playAgainBtn.down = function (x, y, obj) {
if (!gameActive) {
resetGame();
}
};
// --- Game Logic ---
function playerMove(row, col) {
if (!gameActive) return;
if (boardState[row][col] !== 0) return;
boardState[row][col] = 1;
board[row][col].setState(1);
currentPlayer = 2;
updateStatus();
checkGameEnd();
if (gameActive) {
LK.setTimeout(aiMove, 400);
}
}
function aiMove() {
if (!gameActive) return;
// Find best move for AI (O)
var move = findBestAIMove();
if (move) {
boardState[move.row][move.col] = 2;
board[move.row][move.col].setState(2);
currentPlayer = 1;
updateStatus();
checkGameEnd();
}
}
function updateStatus() {
if (!gameActive) return;
if (currentPlayer === 1) {
statusText.setText('Your turn');
} else {
statusText.setText('AI\'s turn');
}
}
function checkGameEnd() {
var result = checkWinner();
if (result.winner) {
gameActive = false;
highlightWinningLine(result.line);
if (result.winner === 1) {
statusText.setText('You win!');
} else if (result.winner === 2) {
statusText.setText('AI wins!');
}
showPlayAgain();
} else if (isBoardFull()) {
gameActive = false;
statusText.setText('Draw!');
showPlayAgain();
}
}
function showPlayAgain() {
playAgainBtn.visible = true;
}
function hidePlayAgain() {
playAgainBtn.visible = false;
}
function resetGame() {
// Reset board state
for (var row = 0; row < boardSize; row++) {
for (var col = 0; col < boardSize; col++) {
boardState[row][col] = 0;
board[row][col].setState(0);
board[row][col].hideHighlight();
}
}
currentPlayer = 1;
gameActive = true;
winningLine = null;
statusText.setText('Your turn');
hidePlayAgain();
}
// --- AI Logic ---
function findBestAIMove() {
// 1. Win if possible
for (var row = 0; row < boardSize; row++) {
for (var col = 0; col < boardSize; col++) {
if (boardState[row][col] === 0) {
boardState[row][col] = 2;
if (checkWinner().winner === 2) {
boardState[row][col] = 0;
return {
row: row,
col: col
};
}
boardState[row][col] = 0;
}
}
}
// 2. Block player win
for (var row = 0; row < boardSize; row++) {
for (var col = 0; col < boardSize; col++) {
if (boardState[row][col] === 0) {
boardState[row][col] = 1;
if (checkWinner().winner === 1) {
boardState[row][col] = 0;
return {
row: row,
col: col
};
}
boardState[row][col] = 0;
}
}
}
// 3. Take center if available
if (boardState[1][1] === 0) {
return {
row: 1,
col: 1
};
}
// 4. Take a corner if available
var corners = [{
row: 0,
col: 0
}, {
row: 0,
col: 2
}, {
row: 2,
col: 0
}, {
row: 2,
col: 2
}];
for (var i = 0; i < corners.length; i++) {
var c = corners[i];
if (boardState[c.row][c.col] === 0) {
return {
row: c.row,
col: c.col
};
}
}
// 5. Take any side
var sides = [{
row: 0,
col: 1
}, {
row: 1,
col: 0
}, {
row: 1,
col: 2
}, {
row: 2,
col: 1
}];
for (var i = 0; i < sides.length; i++) {
var s = sides[i];
if (boardState[s.row][s.col] === 0) {
return {
row: s.row,
col: s.col
};
}
}
// 6. No moves left
return null;
}
// --- Win/Draw Detection ---
function checkWinner() {
// Rows, columns, diagonals
for (var i = 0; i < boardSize; i++) {
// Row
if (boardState[i][0] !== 0 && boardState[i][0] === boardState[i][1] && boardState[i][1] === boardState[i][2]) {
return {
winner: boardState[i][0],
line: [[i, 0], [i, 1], [i, 2]]
};
}
// Column
if (boardState[0][i] !== 0 && boardState[0][i] === boardState[1][i] && boardState[1][i] === boardState[2][i]) {
return {
winner: boardState[0][i],
line: [[0, i], [1, i], [2, i]]
};
}
}
// Diagonal \
if (boardState[0][0] !== 0 && boardState[0][0] === boardState[1][1] && boardState[1][1] === boardState[2][2]) {
return {
winner: boardState[0][0],
line: [[0, 0], [1, 1], [2, 2]]
};
}
// Diagonal /
if (boardState[0][2] !== 0 && boardState[0][2] === boardState[1][1] && boardState[1][1] === boardState[2][0]) {
return {
winner: boardState[0][2],
line: [[0, 2], [1, 1], [2, 0]]
};
}
return {
winner: 0,
line: null
};
}
function isBoardFull() {
for (var row = 0; row < boardSize; row++) {
for (var col = 0; col < boardSize; col++) {
if (boardState[row][col] === 0) return false;
}
}
return true;
}
function highlightWinningLine(line) {
if (!line) return;
for (var i = 0; i < line.length; i++) {
var rc = line[i];
board[rc[0]][rc[1]].showHighlight();
}
}
// --- Prevent interaction in top-left 100x100 px (no cells are placed there) ---
// --- No need for dragging or move handlers ---
// --- No music, sound, or pause ---
// --- No background beyond white ---
// --- No keyboard controls ---
// --- No dynamic resizing/orientation code ---
// --- No leaderboard, game over, or win popups (handled by LK) ---
// --- End of game code --- ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,378 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+// BoardCell: Represents a single cell in the Tic Tac Toe grid
+var BoardCell = Container.expand(function () {
+ var self = Container.call(this);
+ // Cell state: 0 = empty, 1 = player (X), 2 = AI (O)
+ self.state = 0;
+ self.row = 0;
+ self.col = 0;
+ // Draw cell background (box)
+ var cellBg = self.attachAsset('cellBg', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.cellBg = cellBg;
+ // X and O graphics (hidden by default)
+ var xMark = self.attachAsset('xMark', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ alpha: 0
+ });
+ self.xMark = xMark;
+ var oMark = self.attachAsset('oMark', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ alpha: 0
+ });
+ self.oMark = oMark;
+ // Highlight overlay (for winning line)
+ var highlight = self.attachAsset('highlight', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ alpha: 0
+ });
+ self.highlight = highlight;
+ // Set cell state and update graphics
+ self.setState = function (state) {
+ self.state = state;
+ if (state === 1) {
+ self.xMark.alpha = 1;
+ self.oMark.alpha = 0;
+ } else if (state === 2) {
+ self.xMark.alpha = 0;
+ self.oMark.alpha = 1;
+ } else {
+ self.xMark.alpha = 0;
+ self.oMark.alpha = 0;
+ }
+ };
+ // Show highlight overlay
+ self.showHighlight = function () {
+ self.highlight.alpha = 0.5;
+ };
+ // Hide highlight overlay
+ self.hideHighlight = function () {
+ self.highlight.alpha = 0;
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0xffffff
+});
+
+/****
+* Game Code
+****/
+// --- Game Variables ---
+// --- Asset Initialization ---
+// Cell background (light gray box)
+// X mark (red)
+// O mark (blue ellipse)
+// Highlight overlay (yellow, semi-transparent)
+var boardSize = 3;
+var cellSize = 480; // px (for 3x3 grid, fits well in 2048x2732)
+var board = []; // 2D array of BoardCell
+var boardState = []; // 2D array of 0 (empty), 1 (player), 2 (AI)
+var currentPlayer = 1; // 1 = player, 2 = AI
+var gameActive = true;
+var winningLine = null; // Array of [row, col] for winning cells
+// UI elements
+var statusText = null;
+var playAgainBtn = null;
+// --- Board Setup ---
+// Center the board
+var boardOriginX = Math.floor((2048 - cellSize * boardSize) / 2);
+var boardOriginY = Math.floor((2732 - cellSize * boardSize) / 2);
+// Create board cells
+for (var row = 0; row < boardSize; row++) {
+ board[row] = [];
+ boardState[row] = [];
+ for (var col = 0; col < boardSize; col++) {
+ var cell = new BoardCell();
+ cell.x = boardOriginX + col * cellSize + cellSize / 2;
+ cell.y = boardOriginY + row * cellSize + cellSize / 2;
+ cell.row = row;
+ cell.col = col;
+ cell.setState(0);
+ cell.hideHighlight();
+ board[row][col] = cell;
+ boardState[row][col] = 0;
+ game.addChild(cell);
+ // Cell tap handler
+ cell.down = function (cellRef) {
+ return function (x, y, obj) {
+ if (!gameActive) return;
+ if (currentPlayer !== 1) return;
+ if (boardState[cellRef.row][cellRef.col] !== 0) return;
+ playerMove(cellRef.row, cellRef.col);
+ };
+ }(cell);
+ }
+}
+// --- Status Text ---
+statusText = new Text2('Your turn', {
+ size: 120,
+ fill: 0x222222
+});
+statusText.anchor.set(0.5, 0);
+LK.gui.top.addChild(statusText);
+// --- Play Again Button ---
+playAgainBtn = new Text2('Play Again', {
+ size: 100,
+ fill: 0xFFFFFF
+});
+playAgainBtn.anchor.set(0.5, 0.5);
+playAgainBtn.x = 2048 / 2;
+playAgainBtn.y = 2732 - 350;
+playAgainBtn.visible = false;
+playAgainBtn.bg = LK.getAsset('playAgainBg', {
+ width: 600,
+ height: 180,
+ color: 0x2a6edb,
+ anchorX: 0.5,
+ anchorY: 0.5
+});
+playAgainBtn.bg.y = 0;
+playAgainBtn.bg.x = 0;
+playAgainBtn.addChild(playAgainBtn.bg);
+playAgainBtn.setChildIndex(playAgainBtn.bg, 0);
+game.addChild(playAgainBtn);
+// Play Again tap handler
+playAgainBtn.down = function (x, y, obj) {
+ if (!gameActive) {
+ resetGame();
+ }
+};
+// --- Game Logic ---
+function playerMove(row, col) {
+ if (!gameActive) return;
+ if (boardState[row][col] !== 0) return;
+ boardState[row][col] = 1;
+ board[row][col].setState(1);
+ currentPlayer = 2;
+ updateStatus();
+ checkGameEnd();
+ if (gameActive) {
+ LK.setTimeout(aiMove, 400);
+ }
+}
+function aiMove() {
+ if (!gameActive) return;
+ // Find best move for AI (O)
+ var move = findBestAIMove();
+ if (move) {
+ boardState[move.row][move.col] = 2;
+ board[move.row][move.col].setState(2);
+ currentPlayer = 1;
+ updateStatus();
+ checkGameEnd();
+ }
+}
+function updateStatus() {
+ if (!gameActive) return;
+ if (currentPlayer === 1) {
+ statusText.setText('Your turn');
+ } else {
+ statusText.setText('AI\'s turn');
+ }
+}
+function checkGameEnd() {
+ var result = checkWinner();
+ if (result.winner) {
+ gameActive = false;
+ highlightWinningLine(result.line);
+ if (result.winner === 1) {
+ statusText.setText('You win!');
+ } else if (result.winner === 2) {
+ statusText.setText('AI wins!');
+ }
+ showPlayAgain();
+ } else if (isBoardFull()) {
+ gameActive = false;
+ statusText.setText('Draw!');
+ showPlayAgain();
+ }
+}
+function showPlayAgain() {
+ playAgainBtn.visible = true;
+}
+function hidePlayAgain() {
+ playAgainBtn.visible = false;
+}
+function resetGame() {
+ // Reset board state
+ for (var row = 0; row < boardSize; row++) {
+ for (var col = 0; col < boardSize; col++) {
+ boardState[row][col] = 0;
+ board[row][col].setState(0);
+ board[row][col].hideHighlight();
+ }
+ }
+ currentPlayer = 1;
+ gameActive = true;
+ winningLine = null;
+ statusText.setText('Your turn');
+ hidePlayAgain();
+}
+// --- AI Logic ---
+function findBestAIMove() {
+ // 1. Win if possible
+ for (var row = 0; row < boardSize; row++) {
+ for (var col = 0; col < boardSize; col++) {
+ if (boardState[row][col] === 0) {
+ boardState[row][col] = 2;
+ if (checkWinner().winner === 2) {
+ boardState[row][col] = 0;
+ return {
+ row: row,
+ col: col
+ };
+ }
+ boardState[row][col] = 0;
+ }
+ }
+ }
+ // 2. Block player win
+ for (var row = 0; row < boardSize; row++) {
+ for (var col = 0; col < boardSize; col++) {
+ if (boardState[row][col] === 0) {
+ boardState[row][col] = 1;
+ if (checkWinner().winner === 1) {
+ boardState[row][col] = 0;
+ return {
+ row: row,
+ col: col
+ };
+ }
+ boardState[row][col] = 0;
+ }
+ }
+ }
+ // 3. Take center if available
+ if (boardState[1][1] === 0) {
+ return {
+ row: 1,
+ col: 1
+ };
+ }
+ // 4. Take a corner if available
+ var corners = [{
+ row: 0,
+ col: 0
+ }, {
+ row: 0,
+ col: 2
+ }, {
+ row: 2,
+ col: 0
+ }, {
+ row: 2,
+ col: 2
+ }];
+ for (var i = 0; i < corners.length; i++) {
+ var c = corners[i];
+ if (boardState[c.row][c.col] === 0) {
+ return {
+ row: c.row,
+ col: c.col
+ };
+ }
+ }
+ // 5. Take any side
+ var sides = [{
+ row: 0,
+ col: 1
+ }, {
+ row: 1,
+ col: 0
+ }, {
+ row: 1,
+ col: 2
+ }, {
+ row: 2,
+ col: 1
+ }];
+ for (var i = 0; i < sides.length; i++) {
+ var s = sides[i];
+ if (boardState[s.row][s.col] === 0) {
+ return {
+ row: s.row,
+ col: s.col
+ };
+ }
+ }
+ // 6. No moves left
+ return null;
+}
+// --- Win/Draw Detection ---
+function checkWinner() {
+ // Rows, columns, diagonals
+ for (var i = 0; i < boardSize; i++) {
+ // Row
+ if (boardState[i][0] !== 0 && boardState[i][0] === boardState[i][1] && boardState[i][1] === boardState[i][2]) {
+ return {
+ winner: boardState[i][0],
+ line: [[i, 0], [i, 1], [i, 2]]
+ };
+ }
+ // Column
+ if (boardState[0][i] !== 0 && boardState[0][i] === boardState[1][i] && boardState[1][i] === boardState[2][i]) {
+ return {
+ winner: boardState[0][i],
+ line: [[0, i], [1, i], [2, i]]
+ };
+ }
+ }
+ // Diagonal \
+ if (boardState[0][0] !== 0 && boardState[0][0] === boardState[1][1] && boardState[1][1] === boardState[2][2]) {
+ return {
+ winner: boardState[0][0],
+ line: [[0, 0], [1, 1], [2, 2]]
+ };
+ }
+ // Diagonal /
+ if (boardState[0][2] !== 0 && boardState[0][2] === boardState[1][1] && boardState[1][1] === boardState[2][0]) {
+ return {
+ winner: boardState[0][2],
+ line: [[0, 2], [1, 1], [2, 0]]
+ };
+ }
+ return {
+ winner: 0,
+ line: null
+ };
+}
+function isBoardFull() {
+ for (var row = 0; row < boardSize; row++) {
+ for (var col = 0; col < boardSize; col++) {
+ if (boardState[row][col] === 0) return false;
+ }
+ }
+ return true;
+}
+function highlightWinningLine(line) {
+ if (!line) return;
+ for (var i = 0; i < line.length; i++) {
+ var rc = line[i];
+ board[rc[0]][rc[1]].showHighlight();
+ }
+}
+// --- Prevent interaction in top-left 100x100 px (no cells are placed there) ---
+// --- No need for dragging or move handlers ---
+// --- No music, sound, or pause ---
+// --- No background beyond white ---
+// --- No keyboard controls ---
+// --- No dynamic resizing/orientation code ---
+// --- No leaderboard, game over, or win popups (handled by LK) ---
+// --- End of game code ---
\ No newline at end of file