JavaScript开发Simon游戏遭遇异常问题,请求技术支持
解决Simon游戏的两个关键问题
我来帮你分析并修复这两个困扰你的问题:
问题1:userClickedPattern数组重复添加元素
你遇到的每次点击按钮后数组里会重复三次添加颜色值的问题,核心原因是事件冒泡:你把点击事件绑定在了所有<div>元素上($("div").on("click", ...)),但游戏按钮本身嵌套在.container、.row这些父级div里。当你点击按钮时,点击事件会向上冒泡到所有父级div,导致同一个userClickedPattern.push()被执行多次。
修复方案:
把点击事件的绑定目标改成按钮专属的类.btn,这样只有点击按钮本身时才会触发事件:
$(".btn").on("click", function() { // 原逻辑保留,只修改选择器即可 })
问题2:条件判断逻辑错误
你的checkAnswer函数存在两处核心逻辑错误:
- 传递的
currentLevel参数完全不合理:userClickedPattern.length -3没有任何依据,正确的做法是传递当前用户点击的最后一个元素的索引,也就是userClickedPattern.length - 1 - 判断用户序列是否完成的条件逻辑混乱:
(userClickedPattern.length-2) === gamePattern.length完全不符合游戏逻辑,正确的判断应该是当用户点击的序列长度和游戏生成的序列长度一致时,说明当前回合完成,进入下一轮。
修复后的点击事件和checkAnswer函数:
$(".btn").on ("click", function() { const userChosenColour = $(this).attr("id"); $("#" + userChosenColour).addClass("pressed"); setTimeout(function () { $("#" + userChosenColour).removeClass("pressed"); }, 100); // 把延迟改成100ms更贴合原版游戏的反馈速度,可选调整 userClickedPattern.push(userChosenColour); flashandsound(userChosenColour); // 传递正确的当前点击元素索引 checkAnser(userClickedPattern.length - 1); }) function checkAnser(currentLevel){ // 检查当前点击的元素是否和游戏序列对应位置匹配 if (gamePattern[currentLevel] === userClickedPattern[currentLevel]) { // 检查用户是否完成了当前回合的所有序列 if (userClickedPattern.length === gamePattern.length) { setTimeout(function () { nextSequence(); }, 1000); } } else { $("#level-title").html('Game over, Press any key to start again'); var audio = new Audio("sounds/wrong.mp3"); audio.play(); $("body").addClass("game-over"); setTimeout(function () { $("body").removeClass("game-over"); }, 1000); restart(); } }
另外还有个小细节需要调整:nextSequence函数里的标题更新顺序,原来先更新标题再升级level会导致第一次显示Level 0,不符合预期,调整顺序即可:
function nextSequence() { userClickedPattern = []; level++; // 先升级,再更新标题 $("#level-title").html("Level " + level ); var num1 = Math.floor(Math.random() * 4); var randomChosenColor = buttonColor[num1]; gamePattern.push(randomChosenColor); flashandsound(randomChosenColor); }
完整修复后的JavaScript代码
var buttonColor = ["red", "blue", "green", "yellow"]; var userClickedPattern = []; var gamePattern = []; var totalKey = []; var level = 0; $("*").on("keydown", function(m) { var key = m.key; totalKey.push(key); var keyLength = totalKey.length; if (keyLength == 1) { nextSequence(); } }); function nextSequence() { userClickedPattern = []; level++; $("#level-title").html("Level " + level ); var num1 = Math.floor(Math.random() * 4); var randomChosenColor = buttonColor[num1]; gamePattern.push(randomChosenColor); flashandsound(randomChosenColor); } function flashandsound(n) { $("#" + n ).fadeOut(100).fadeIn(100).fadeOut(100).fadeIn(100); var audio = new Audio("sounds/" + n + ".mp3"); audio.play(); } $(".btn").on ("click", function() { const userChosenColour = $(this).attr("id"); $("#" + userChosenColour).addClass("pressed"); setTimeout(function () { $("#" + userChosenColour).removeClass("pressed"); }, 100); userClickedPattern.push(userChosenColour); flashandsound(userChosenColour); checkAnser(userClickedPattern.length - 1); }) function checkAnser(currentLevel){ if (gamePattern[currentLevel] === userClickedPattern[currentLevel]) { if (userClickedPattern.length === gamePattern.length) { setTimeout(function () { nextSequence(); }, 1000); } } else { $("#level-title").html('Game over, Press any key to start again'); var audio = new Audio("sounds/wrong.mp3"); audio.play(); $("body").addClass("game-over"); setTimeout(function () { $("body").removeClass("game-over"); }, 1000); restart(); } } function restart() { totalKey = []; level = 0; gamePattern = []; userClickedPattern = []; }
修改完成后,两个问题都能解决:点击按钮只会向数组添加一次元素,游戏的序列匹配逻辑也能正常工作,每完成一轮会自动进入下一关,错误时也能正确触发游戏结束流程。
内容的提问来源于stack exchange,提问作者user16521364
相关产品推荐
相关产品推荐

