如何为Tic Tac Toe网页添加计分板与音效功能?
井字棋游戏计分板与音效功能修复方案
问题概述
开发JavaScript井字棋游戏时,无法实现两个核心功能:
- 计分板无法累计玩家获胜次数与平局次数
- 玩家获胜/平局时对应音效无法正常播放,尝试将
win.play()移入isWin函数仍无效
具体修复步骤
1. 计分板功能实现
关键修改点:
- 新增全局平局计分变量
tieScore,和已有的p1Score、p2Score共同维护累计数据 - 在游戏结束的分支(获胜/平局)中更新对应计分,并同步到页面的计分DOM元素
- 确保
startGame函数仅重置单局游戏状态,不重置累计计分
2. 音效功能修复
原代码问题:
playSound函数中使用赋值运算符=而非比较运算符==,逻辑判断失效- 函数内部递归调用
playSound()会导致死循环 - 音效未在正确的时机(游戏结束时)被触发
- HTML中音频文件路径为
win.mp3/fail.mp3,但JS中写的是success.mp3/fail.mp3,路径不统一
修复方案:
- 统一音频文件路径,确保HTML和JS中的路径一致
- 移除无用的
playSound函数,直接在游戏结束的分支中调用音效播放 - 确保音频对象正确初始化
修改后的完整代码
HTML代码(调整音频标签位置+统一路径)
<!DOCTYPE html> <html lang="en"> <head> <title>Tic Tac Toe</title> <link href="css/style.css" rel="stylesheet" type="text/css"> <script src="js/script.js"></script> </head> <body onload="startGame();"> <audio src="../sounds/win.mp3" id="win"></audio> <audio src="../sounds/fail.mp3" id="tie"></audio> <h2 id="game-message">Tic Tac Toe</h2> <div id="game-board"></div> <table id="scoreboard"> <tr> <th>Player 1</th> <th>Player 2</th> <th>Ties</th> </tr> <tr id="scores"> <td class="score" id="p1score">0</td> <td class="score" id="p2score">0</td> <td class="score" id="tiescore">0</td> </tr> </table> <div id="button"><button id="playAgain" onclick="startGame();">Play Again?</button></div> </body> </html>
JavaScript代码(修复计分+音效)
var markers = ["X", "O"]; var players = []; players[0] = prompt("Enter player one:"); players[1] = prompt("Enter player two:"); var totals = []; var winCodes = [7,56,73,84,146,273,292,448]; var gameOver = false; var whoseTurn = 0; // 维护累计计分 var p1Score = 0; var p2Score = 0; var tieScore = 0; // 统一音频路径,和HTML保持一致 var winSound = new Audio('../sounds/win.mp3'); var tieSound = new Audio('../sounds/fail.mp3'); function startGame() { var counter = 1; var innerDivs = ""; for (i = 1; i <=3; i++) { innerDivs += '<div id="row-' + i + '">'; for (j = 1; j <=3; j++) { innerDivs += '<div onclick="playGame(this,' + counter + ');"></div>'; counter *=2; } innerDivs += '</div>'; } document.getElementById("game-board").innerHTML = innerDivs; totals = [0, 0]; gameOver = false; // 保持当前玩家回合(如需重置回合可改为whoseTurn=0) document.getElementById("game-message").innerText = "It's " + players[whoseTurn] + "'s Turn"; } function playGame(clickedDiv, divValue) { if (!gameOver) { clickedDiv.innerText = markers[whoseTurn]; totals[whoseTurn] += divValue; if (isWin()) { // 玩家获胜,更新计分 if (whoseTurn === 0) { p1Score++; document.getElementById("p1score").textContent = p1Score; } else { p2Score++; document.getElementById("p2score").textContent = p2Score; } document.getElementById("game-message").innerText = players[whoseTurn] + " Wins!"; // 播放获胜音效 winSound.play(); } else if (gameOver) { // 平局,更新计分 tieScore++; document.getElementById("tiescore").textContent = tieScore; document.getElementById("game-message").innerText = "Game Over, Man! (Tie)"; // 播放平局音效 tieSound.play(); } else { whoseTurn = whoseTurn === 0 ? 1 : 0; clickedDiv.onclick = ""; document.getElementById("game-message").innerText = "It's " + players[whoseTurn] + "'s turn"; } } } function isWin() { for (i = 0; i < winCodes.length; i++) { if ((totals[whoseTurn] & winCodes[i]) == winCodes[i]) { gameOver = true; return true; } } if (totals[0] + totals[1] == 511) { gameOver = true; } return false; }
内容的提问来源于stack exchange,提问作者WastelandSniper
相关产品推荐
相关产品推荐

