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

如何实现动画按数组顺序播放?Simon Says游戏开发问题

解决Simon Says序列动画播放问题

先拆解两种方法的问题,再给你修正后的完整代码:

方法1的问题

for循环里用var i的话,i属于函数级作用域,所有setTimeout的回调共享同一个i变量。等回调执行时,循环已经跑完,i的值变成了4(pattern.length为4),pattern[4]是undefined,找不到对应DOM元素,自然没有动画效果。

方法2的问题

setTimeout的第一个参数必须是函数,你直接写$("." + pattern[0]).fadeOut(200).fadeIn(200),会立刻执行动画,然后把jQuery对象传给setTimeout,这不符合语法要求所以报错,而且所有动画会同时触发,完全起不到延迟作用。

修正后的完整代码

var pattern       = []
var userPattern   = [];
var buttonColours = ["red", "blue", "green", "yellow"];
var started       = false
var level         = 0;

function nextSequence() {
  // 清除旧序列
  pattern     = [];
  userPattern = [];
  
  // 生成新的4位随机序列
  while (pattern.length < 4) {
    var randomNumber = Math.floor(Math.random() * 4);
    var randomColour = buttonColours[randomNumber];
    pattern.push(randomColour);
  }

  // 按顺序播放按钮动画:用let声明i,形成块级作用域保存每个循环的索引
  for (let i = 0; i < pattern.length; i++) {
    setTimeout(function() {
      const $button = $("." + pattern[i]);
      // 确保元素存在再执行动画,避免控制台报错
      if ($button.length) {
        $button.fadeOut(200).fadeIn(200);
      }
    }, 700 * (i + 1)); // 调大间隔,让动画衔接更清晰
  }

  // 更新关卡标题
  $("h1").text("Level " + level);
  level++;
  console.log(pattern);
}

关键修正点

  1. 循环变量改用let i:let会在每个循环迭代中创建独立的变量绑定,确保每个setTimeout回调拿到的是当前循环的索引值,不会出现索引越界的问题。
  2. 增加元素存在判断:避免因DOM元素找不到导致控制台报错,提升代码健壮性。
  3. 调大超时间隔:把原500ms改成700ms,避免fadeIn/fadeOut的时长(共400ms)和间隔太接近,让每个按钮的动画更清晰区分。

如果你觉得for循环的写法不够直观,也可以用forEach遍历序列:

// 替代for循环的写法
pattern.forEach((colour, index) => {
  setTimeout(() => {
    const $button = $("." + colour);
    if ($button.length) {
      $button.fadeOut(200).fadeIn(200);
    }
  }, 700 * (index + 1));
});

这样就能实现清除旧序列、生成新序列,然后按数组顺序依次播放按钮动画的效果了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 11:37:33