如何用JavaScript结合DOM实现石头剪刀布多轮对局推进?
石头剪刀布游戏5轮循环与分数更新问题修复
问题说明
开发石头剪刀布游戏时,无法实现5轮对局循环,回合计数器和分数更新异常,无法正常展示最终胜负结果。
修复后的完整代码
JavaScript 代码
let humanScore = 0 let computerScore = 0 let rounds = 0; const getComputerChoice = () => { const items = ["rock", "paper", "scissors"]; const randomItems = items[Math.floor(Math.random() * items.length)]; return randomItems; } const getHumanChoice = () => { return new Promise((resolve) => { const rockSelection = document.querySelector("#rock"); const paperSelection = document.querySelector("#paper"); const scissorsSelection = document.querySelector("#scissors"); // 清除之前的选中动画 rockSelection.classList.remove("animation"); paperSelection.classList.remove("animation"); scissorsSelection.classList.remove("animation"); const handleChoice = (choice) => { document.querySelector(`#${choice}`).classList.add("animation"); resolve(choice); }; // 绑定一次性点击事件 rockSelection.addEventListener("click", () => handleChoice("rock"), { once: true }); paperSelection.addEventListener("click", () => handleChoice("paper"), { once: true }); scissorsSelection.addEventListener("click", () => handleChoice("scissors"), { once: true }); }); } const playRound = (humanChoice, computerChoice) => { const textResponse = document.querySelector("#display"); // 清空上一轮的结果显示 textResponse.innerHTML = ""; const para = document.createElement("p"); para.classList.add("para"); if (humanChoice === "rock" && computerChoice === "scissors") { para.textContent = `You win! ${humanChoice} 🗿 beats ${computerChoice} ✂️`; humanScore++; } else if (humanChoice === "scissors" && computerChoice === "paper") { para.textContent = `You win! ${humanChoice} ✂️ beats ${computerChoice} 🧻`; humanScore++; } else if (humanChoice === "paper" && computerChoice === "rock") { para.textContent = `You win! ${humanChoice} 🧻 beats ${computerChoice} 🗿`; humanScore++; } else if (humanChoice === computerChoice) { para.textContent = `Draw! 😐 Computer also chose ${computerChoice}`; } else { para.textContent = `You lose! 😩 Computer chose ${computerChoice}`; computerScore++; } textResponse.appendChild(para); } const playGame = async () => { const humanChoice = await getHumanChoice(); const computerChoice = getComputerChoice(); playRound(humanChoice, computerChoice); const scoreContainer = document.querySelector("#score"); const scorePara = document.createElement("p"); scorePara.classList.add("Score"); scorePara.textContent = `ROUND ${rounds}: You ${humanScore}, Computer: ${computerScore}`; scoreContainer.appendChild(scorePara); if (rounds < 5) { const nextDiv = document.createElement("div"); const nextBtn = document.createElement("button"); nextDiv.classList.add("nextDiv"); nextBtn.classList.add("button"); nextBtn.textContent = "Next Round"; nextDiv.appendChild(nextBtn); scoreContainer.appendChild(nextDiv); return new Promise((resolve) => { nextBtn.addEventListener("click", () => { resolve(); }, { once: true }); }); } }; const loopRounds = async () => { while (rounds < 5) { rounds++; await playGame(); } const finalMsg = document.createElement("p"); finalMsg.classList.add("final-msg"); if (humanScore > computerScore) { finalMsg.textContent = "🎉 You won the game!"; } else if (humanScore < computerScore) { finalMsg.textContent = "💥 You lost the game!"; } else { finalMsg.textContent = "🤝 Game ended in a draw!"; } document.querySelector("#score").appendChild(finalMsg); } loopRounds();
HTML 代码(含样式调整)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Rock, Paper, Scissors</title> <style> body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; } #botones { display: flex; gap: 15px; justify-content: center; align-items: center; margin: 30px 0; } .animation { background-color: #5240F5 !important; transform: scale(1.05); transition: all 0.2s ease; } #title, #subTitle { text-align: center; } button { font-size: 20px; font-weight: bold; border-radius: 8px; border: none; padding: 12px 24px; background-color: #3FA2F6; color: white; cursor: pointer; transition: background-color 0.2s ease; } button:hover { background-color: #2c8bd8; } #display, #score { text-align: center; margin: 20px 0; } .Score { font-weight: bold; font-size: 22px; margin: 10px 0; } .para { font-weight: bold; font-size: 24px; margin: 15px 0; } .nextDiv { margin: 20px 0; } .final-msg { font-size: 28px; font-weight: bold; margin-top: 30px; color: #2c3e50; } </style> </head> <body> <div id="title"> <h1>🗿🧻✂️ Rock, Paper, Scissors 🗿🧻✂️</h1> </div> <div id="subTitle"> <h2>Pick your option 👇</h2> </div> <div id="botones"> <button id="rock">Rock</button> <button id="paper">Paper</button> <button id="scissors">Scissors</button> </div> <div id="display"></div> <div id="score"></div> <script src="codigo.js"></script> </body> </html>
关键修复点
- 事件绑定修正:将
{once: true}正确传递给addEventListener,确保每个按钮点击事件只触发一次,避免重复绑定导致的逻辑混乱。 - 动画状态重置:每次获取用户选择前,清除所有按钮的
animation类,保证选中状态仅对应当前选择。 - 结果显示优化:清空上一轮的结果显示区域,避免内容堆积;调整分数和结果的排版,提升可读性。
- 逻辑流程理顺:确保回合计数器
rounds在每次循环前自增,分数更新实时同步到页面显示。 - 最终结果强化:给最终胜负消息添加独立样式,突出显示游戏结论。
内容的提问来源于stack exchange,提问作者user24210059
相关产品推荐
相关产品推荐

