JavaScript井字棋问题:如何显示当前玩家及获胜者昵称
解决本地多人井字棋游戏的玩家昵称显示问题
我是JavaScript初学者,开发了一款本地多人Tic Tac Toe(井字棋)游戏,需求为从两个输入框获取玩家昵称,并在游戏中显示当前回合玩家昵称及获胜者昵称。目前能在控制台访问存储在p1和p2对象中的值(p1.name、p1.val、p2.name、p2.val),但不清楚如何在setTurnIndicator函数中调用这些值,也不知道如何在判断获胜时展示获胜者昵称。尝试使用localStorage存储并读取这些昵称,但未成功。
原有代码
// Multiplayer Options let ps = document.getElementById('btn'); let c1 = document.getElementsByName('characP1'); let c2 = document.getElementsByName('characP2'); let msg = document.getElementById('message'); let char1; let char2; function Player(name, val) { this.name = name; this.val = val; } for (i = 0; i < c1.length; i++) { c1[i].addEventListener('change', function () { if (this.checked) { this.value == 'X' ? c2[1].checked = true : c2[0].checked = true; char1 = this.value; char2 = this.value == 'X' ? 'O' : 'X'; } }); } for (i = 0; i < c2.length; i++) { c2[i].addEventListener('change', function () { if (this.checked) { this.value == 'X' ? c1[1].checked = true : c1[0].checked = true; char2 = this.value char1 = this.value == 'X' ? 'O' : 'X'; } }); } ps.addEventListener('click', function () { let player1 = document.getElementById('p1').value; let player2 = document.getElementById('p2').value; p1 = new Player(player1, char1); p2 = new Player(player2, char2); if (p1.name && p1.val && p2.name && p2.val) { msg.innerHTML = p1.name + ' : ' + p1.val + '<br />' + p2.name + ' : ' + p2.val; } else { msg.innerHTML = 'Please fill all input fields'; } // return playerOne, playerTwo; // window.localStorage.setItem('nume1', p1.name); // window.localStorage.setItem('nume2', p2.name); }); // Hide Players Options function hidePlayersOptions() { let x = document.getElementById("mpOptions"); if (x.style.display === "none") { x.style.display = "block"; } else { x.style.display = "none"; } let y = document.getElementById("game"); if (y.style.display === "none") { y.style.display = "block"; } else { y.style.display = "block"; } } // Multiplayer Game Logic /* Tic-Tac-Toe functions */ let TicTacToe = { /* initialize the Tic-Tac-Toe variables */ init: function() { this.symbols = [`X`, `O`]; this.name = [window.localStorage.getItem('nume1'), window.localStorage.getItem('nume2')]; this.squares = Array.from(document.querySelectorAll(".square")); this.turnIndicator = document.querySelector(".turnIndicator"); this.button = document.querySelector(".newGame"); this.board = document.querySelector(".board"); // square positions in which you can get 3-in-a-row this.winningSets = [ // horizontal sets [0,1,2], [3,4,5], [6,7,8], // vertical sets [0,3,6], [1,4,7], [2,5,8], // diagonal sets [0,4,8], [2,4,6] ]; // add click event listeners to squares and button this.addEventListeners(); // reset the game this.newGame(); }, // add click event listeners to squares and button addEventListeners: function() { let ttt = this; // for each square, add a click listener which will call "play()" this.squares.forEach(function(x) { x.addEventListener("click",function() { ttt.play(this); }, false) }) // when the new game button is clicked, call "newGame()" this.button.addEventListener("click", function() { ttt.newGame(); }, false); }, // reset the game newGame: function() { // set player to first player (X) this.activePlayer = 0; // reset the game over variable this.gameOver = false; // remove all X and O classes from every square this.squares.forEach(function (x) { x.classList.remove(TicTacToe.symbols[0]); x.classList.remove(TicTacToe.symbols[1]); }) // remove gameOver class from board if it exists this.board.classList.remove("gameOver"); // set the turn indicator (X's turn) this.setTurnIndicator(); }, // set the turn indicator to indicate whose turn it is setTurnIndicator: function() { this.turnIndicator.innerText = this.symbols[this.name[this.activePlayer]] + "'s turn." // this.turnIndicator.innerText = this.symbols["window.localStorage.getItem('nume1')"] + "'s turn." // this.turnIndicator.innerText = this.symbols[window.localStorage.getItem('nume1')[this.activePlayer]]; }, play: function(el) { // make sure that the square is not filled if (!this.gameOver && el.classList.length == 1) { // set the contents to your player's symbol el.classList.add(this.symbols[this.activePlayer]); // check if you won if (this.checkWin()) { // set the game text to display the winner this.turnIndicator.innerText = this.symbols[this.activePlayer] + " wins!"; // call the game over function this.endGame(); } // check if there is a draw else if (this.checkDraw()) { // set the game text to say it is a draw this.turnIndicator.innerText = "It's a draw!"; // call the game over function this.endGame(); } // go to the next player's turn else { // change the turn (0 -> 1 or 1 -> 0) this.activePlayer = 1 - this.activePlayer; // set the turn indicator text this.setTurnIndicator(); } } }, // check if current player won checkWin: function() { let ttt = this; // if for any of the winning sets, // every square in the set is filled with // the current player's symbol, return true // otherwise, return false return this.winningSets.some(function (x) { return x.every(function(i) { return Array.from(ttt.squares[i].classList).indexOf(ttt.symbols[ttt.activePlayer]) > -1; }) }) }, // check if there is a draw checkDraw: function() { // return true if every square // has more than 1 class (is filled) // otherwise, return false return this.squares.every(function (x) { return x.classList.length > 1; }) }, // set the game over variable and board class when the game ends endGame: function() { this.gameOver = true; this.board.classList.add("gameOver"); } } // call the init() function of TicTacToe when the page loads TicTacToe.init();
解决方案
1. 核心问题
TicTacToe对象无法直接访问全局作用域的p1、p2变量,且页面初始化时localStorage还未存储玩家昵称,导致读取失败。
2. 具体修改步骤
(1)让TicTacToe持有玩家信息
在按钮点击事件中,创建玩家对象后,直接将玩家数据传递给TicTacToe:
ps.addEventListener('click', function () { let player1 = document.getElementById('p1').value; let player2 = document.getElementById('p2').value; p1 = new Player(player1, char1); p2 = new Player(player2, char2); if (p1.name && p1.val && p2.name && p2.val) { msg.innerHTML = p1.name + ' : ' + p1.val + '<br />' + p2.name + ' : ' + p2.val; // 将玩家数组传入TicTacToe TicTacToe.players = [p1, p2]; // 实时更新回合提示 TicTacToe.setTurnIndicator(); } else { msg.innerHTML = 'Please fill all input fields'; } });
同时修改TicTacToe的init方法,初始化players属性:
init: function() { this.symbols = [`X`, `O`]; this.players = []; // 初始化玩家数组 this.squares = Array.from(document.querySelectorAll(".square")); // ... 保留原有其他代码 }
(2)修改回合提示函数
更新setTurnIndicator,优先显示玩家昵称,无昵称时用符号兜底:
setTurnIndicator: function() { const currentPlayer = this.players[this.activePlayer]; const displayText = currentPlayer ? `${currentPlayer.name}'s turn.` : `${this.symbols[this.activePlayer]}'s turn.`; this.turnIndicator.innerText = displayText; }
(3)修改获胜提示
在play函数的获胜判断部分,替换为显示玩家昵称:
if (this.checkWin()) { const currentPlayer = this.players[this.activePlayer]; const displayText = currentPlayer ? `${currentPlayer.name} wins!` : `${this.symbols[this.activePlayer]} wins!`; this.turnIndicator.innerText = displayText; this.endGame(); }
内容的提问来源于stack exchange,提问作者Ciuca Sebastian
相关产品推荐
相关产品推荐

