You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Simon游戏重启后点击事件异常:调用函数时重复触发逻辑

Simon游戏重启后异常问题解决

问题现象

Simon游戏复刻项目,首次运行完全正常,但首次失败重启后,第二次游戏出现异常:

  • 按下正确按钮时,嵌套if条件均满足,但setTimeout(nextRandomSequence,1500)未执行目标函数
  • 按钮点击逻辑被重复触发,gamePattern变量被重复添加元素,最终userClickedPattern与gamePattern数组无法匹配,游戏误判失败

问题根源

  1. 重复绑定点击事件:每次通过按键启动游戏时,都会给按钮元素添加新的click事件监听器,重启游戏后旧的监听器并未被移除,导致按钮被点击时多个监听器同时执行,重复向gamePattern添加元素。
  2. 启动逻辑无状态控制:没有标记游戏是否处于运行状态,按键事件可被多次触发,叠加启动流程。

修复步骤

1. 分离事件绑定,避免重复绑定

将按钮的click事件监听器移到按键启动事件外部,确保页面加载后只绑定一次,同时通过状态变量控制监听器内的逻辑是否执行。

2. 添加游戏状态标记

新增gameStarted变量,标记游戏是否正在运行,防止重复启动和无效的点击逻辑触发。

3. 修正层级更新逻辑

原nextRandomSequence中level++的位置导致标题显示的层级与实际进度不符,调整为更新标题后再递增层级。

修复后的完整JavaScript代码

let userClickedPattern = [];
let gamePattern = [];
let buttonColors = ["green", "red", "yellow", "blue"];
let level = 1;
let gameStarted = false; // 新增游戏状态标记

// 页面加载后只绑定一次点击事件
$("div[type='button']").click(function(e) {
  if (!gameStarted) return; // 游戏未启动时不响应点击

  let userChosenColor = e.target.id;
  console.log("user chosen color: " + userChosenColor);
  pressButtonAnimation(userChosenColor);
  playSound(userChosenColor);
  userClickedPattern.push(userChosenColor);

  console.log("compare arrays userClicked/gamePattern " + userClickedPattern + " " + gamePattern);

  if (userClickedPattern[userClickedPattern.length - 1] === gamePattern[userClickedPattern.length - 1]) {
    if (userClickedPattern.length === gamePattern.length) {
      $("#level-title").text("Level " + level);
      console.log(level);
      console.log("----- continue ---------");
      setTimeout(nextRandomSequence, 1500);
    }
  } else {
    console.log("----- game over ---------");
    playSound("wrong");
    gameOverAnimation(userChosenColor);
    $("#level-title").text("GAME OVER, your arrived to level " + level + " press any key to start");
    restartGame();
    console.log(level);
  }
});

// 按键启动游戏逻辑
$(document).keypress(function() {
  if (gameStarted) return; // 游戏已启动时不重复触发
  gameStarted = true;
  $("#level-title").text("Level " + level);
  nextRandomSequence();
});

function nextRandomSequence() {
  console.log("--------- inside nextRandomSequence -------------")
  userClickedPattern = [];
  const randomNumber = Math.floor(Math.random() * 4);
  const randomChosenColor = buttonColors[randomNumber];
  gamePattern.push(randomChosenColor);

  $("#" + randomChosenColor).fadeIn(300).fadeOut(300).fadeIn(300);
  playSound(randomChosenColor);
  $("#level-title").text("Level " + level); // 先更新标题
  level++; // 再递增层级

  console.log("random chosen color " + randomChosenColor);
}

function playSound(name) {
  var audio = new Audio("sounds/" + name + ".mp3");
  audio.play();
}

function pressButtonAnimation(colorPressed) {
  $("#" + colorPressed).addClass("pressed");
  setTimeout(function() {
    $("#" + colorPressed).removeClass("pressed");
  }, 100);
}

function gameOverAnimation(colorPressed) {
  $("body").addClass("game-over");
  setTimeout(function() {
    $("body").removeClass("game-over");
  }, 200);
}

function restartGame() {
  level = 1;
  gamePattern = [];
  gameStarted = false; // 重置游戏状态
}

说明

  • 原CSS和HTML代码无需修改,仅调整JavaScript部分即可解决问题
  • 新增的gameStarted变量有效控制了游戏启动状态和点击逻辑的有效性
  • 点击事件只绑定一次,彻底解决了重复触发逻辑的问题

内容的提问来源于stack exchange,提问作者adrian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 18:57:17