石头剪刀布游戏:Enter重置分数失效及分数达3后禁用选择需求
解决石头剪刀布游戏的分数重置与结束逻辑问题
问题分析
当前代码存在以下核心问题:
- 重复定义函数:代码中重复编写了
reset()和endGame()函数,后定义的函数会覆盖前一个,导致部分逻辑失效 - 分数重置错误:
endGame()里试图用userPoints.textContent = 0重置分数,但userPoints是数值变量而非DOM元素,正确方式是直接赋值数值并同步更新DOM显示 - 重复绑定事件:每次调用
endGame()都会给document.body绑定新的keydown事件,多次触发后会重复执行重置逻辑 - 缺少禁用选择项逻辑:当任意一方分数达到3分时,未禁用选择项,用户仍可继续点击操作
修复后的完整代码
JavaScript 代码
const choices = ['Rock', 'Paper', 'Scissors'] let userScore = document.querySelector('.result-score-user') let computerScore = document.querySelector('.result-score-computer') const computerOutput = document.querySelector('.computer-output') const outcome = document.querySelector('.outcome') const rockPaperScissors = document.querySelectorAll('li') let userPoints = 0 let computerPoints = 0 let gameActive = true // 标记游戏是否处于可进行状态 // 初始化分数显示 updateScoreDisplay() // 绑定选择项点击事件 rockPaperScissors.forEach(choice => { choice.addEventListener('click', () => { if (!gameActive) return // 游戏结束时不响应点击 const userChoice = choice.innerHTML const randomChoice = choices[Math.floor(Math.random() * choices.length)] computerOutput.innerHTML = randomChoice isWinner(userChoice, randomChoice) updateScoreDisplay() checkGameEnd() }) }) // 判断胜负逻辑 function isWinner(userChoice, computerChoice) { const combination = computerChoice + userChoice switch (combination) { case 'RockScissors': case 'ScissorsPaper': case 'PaperRock': outcome.innerHTML = 'You Lose' computerPoints++ break case 'ScissorsRock': case 'PaperScissors': case 'RockPaper': outcome.innerHTML = 'You Win!' userPoints++ break default: outcome.innerHTML = 'Draw' break } } // 更新分数到DOM function updateScoreDisplay() { userScore.innerHTML = userPoints computerScore.innerHTML = computerPoints } // 检查游戏是否结束 function checkGameEnd() { if (userPoints === 3) { outcome.innerHTML = 'You Win the game! <br> Press Enter to reset' endGame() } else if (computerPoints === 3) { outcome.innerHTML = 'You Lost the game. <br> Press Enter to reset' endGame() } } // 游戏结束与重置逻辑 function endGame() { gameActive = false // 禁用选择项,添加视觉反馈 rockPaperScissors.forEach(choice => { choice.style.pointerEvents = 'none' choice.style.opacity = '0.5' }) // 绑定单次Enter重置事件,避免重复绑定 const handleReset = (e) => { if (e.key === 'Enter') { // 重置游戏状态 gameActive = true userPoints = 0 computerPoints = 0 computerOutput.innerHTML = 'Computer chose...' outcome.innerHTML = '' updateScoreDisplay() // 恢复选择项可用状态 rockPaperScissors.forEach(choice => { choice.style.pointerEvents = 'auto' choice.style.opacity = '1' }) // 移除事件监听,防止重复触发 document.body.removeEventListener('keydown', handleReset) } } document.body.addEventListener('keydown', handleReset) }
HTML 代码(无需修改)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="styles.css"> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Lato&family=Roboto&family=Staatliches&display=swap" rel="stylesheet"> <title>Rock Paper Scissors</title> </head> <body> <main class="container"> <div class="scoreboard"> <div class="score-heading">Score</div> <div class="scores"> <div class="user-score score">You: <span class="result-score-user"></span></div> <div class="computer-score score">Computer: <span class="result-score-computer"></span></div> </div> </div> <div class="user-choice"> <ul class="choices"> <li>Rock</li> <li>Paper</li> <li>Scissors</li> </ul> </div> <div class="computer-choice"> <div class="computer-output">Computer chose...</div> </div> <div class="outcome"></div> </main> <script src="script.js"></script> <script src="https://kit.fontawesome.com/f439b384ed.js" crossorigin="anonymous"></script> </body> </html>
关键修复说明
- 移除重复函数:删除重复的
reset()和endGame(),整合逻辑为checkGameEnd(),避免函数覆盖 - 正确重置分数:直接修改
userPoints和computerPoints数值,调用updateScoreDisplay()同步更新DOM显示 - 避免重复绑定事件:重置后移除keydown事件监听,防止多次触发重置逻辑
- 实现选择项禁用:通过
pointerEvents: 'none'和透明度变化,在游戏结束时禁用点击,重置后恢复 - 添加游戏状态控制:用
gameActive变量控制点击事件是否响应,彻底阻断游戏结束后的无效操作
内容的提问来源于stack exchange,提问作者Joe.sexton
相关产品推荐
相关产品推荐

