在具有 if/else 语句的 for 循环中延迟迭代

Delaying iterations in a for loop which has if/else statements

我正在尝试制作西蒙说的游戏。我有一个循环遍历数字数组的函数。每个数字都与一个动作相关联(因此相应的按钮动画)。当序列只有 1 个值长时,这很好用,但它们都只是一次播放。我已经查找了在迭代之间放置延迟的方法,但没有找到包含 if/else 语句的 for 循环。

我尝试了一个我找到的解决方案 here:

function show_sequence() {
    var k = right_seq.length;

    //assign each button a number
    //when the loop goes over it that button's animation plays
    (function animation(i) {
            setTimeout(function() {
            if (i == 1) { 
                setTimeout(function() {
                    TweenMax.from("#pink", 0.6, {opacity:0.3, scale:0.8, ease:Elastic.easeOut});
                    one.play();
                }, 1000);
            } else if (i == 2) {
                setTimeout(function() {
                    TweenMax.from("#blue", 0.6, {opacity:0.3, scale:0.8, ease:Elastic.easeOut});
                    two.play();
                }, 1000);
            } else if (i == 3) {
                setTimeout(function() {
                    TweenMax.from("#yellow", 0.6, {opacity:0.3, scale:0.8, ease:Elastic.easeOut});
                    three.play();
                }, 1000);
            } else {
                setTimeout(function() {
                    TweenMax.from("#green", 0.6, {opacity:0.3, scale:0.8, ease:Elastic.easeOut});
                    four.play();
                }, 1000);
            }; //end for loop
            if (--i) {
                animation(i);
            }
        }, 200);
})(k);
}

它的工作原理是它在动画和声音之间增加了延迟,但没有按正确的顺序播放它们。例如,如果数组是 [3, 4, 1, 2] 它不会将动画放在这些按钮上,而是按 [4, 3, 2, 1] 的顺序,并且它不会工作超过 4 轮.

这是 fiddle 但游戏尚未完成,所以我不知道它是否有帮助。按绿色小圆圈start/keep添加回合。

这是一个快速修复。您可以做很多事情来改善它,但这应该能让您克服当前的障碍。

问题是您根本没有使用序列。您传递给 show_sequence 的数字只是数组的长度 - 您正在递减(这是 4、3、2、1 的来源)。你从来没有真正从你的序列数组中得到按钮索引

function show_sequence() {
  var k = right_seq.length;

  //assign each button a number
  //when the loop goes over it that button's animation plays
  (function animation(i) {
    if (i >= right_seq.length) {
      return;
    }
    setTimeout(function() {
      if (right_seq[i] == 1) {
        setTimeout(function() {
          TweenMax.from("#pink", 0.6, {
            opacity: 0.3,
            scale: 0.8,
            ease: Elastic.easeOut
          });
          one.play();
        }, 1000);
      } else if (right_seq[i] == 2) {
        setTimeout(function() {
          TweenMax.from("#blue", 0.6, {
            opacity: 0.3,
            scale: 0.8,
            ease: Elastic.easeOut
          });
          two.play();
        }, 1000);
      } else if (right_seq[i] == 3) {
        setTimeout(function() {
          TweenMax.from("#yellow", 0.6, {
            opacity: 0.3,
            scale: 0.8,
            ease: Elastic.easeOut
          });
          three.play();
        }, 1000);
      } else {
        setTimeout(function() {
          TweenMax.from("#green", 0.6, {
            opacity: 0.3,
            scale: 0.8,
            ease: Elastic.easeOut
          });
          four.play();
        }, 1000);
      }; //end for loop
      animation(++i);
    }, 200);
  })(0);
}

不要使用所有这些计时器,而是使用方法 staggerFrom,它会为您延迟。要从 right_seq 数组生成系列,请将该数组转换为元素名称列表:

function show_sequence() {
    var k = right_seq.length;
    var circles = right_seq.map(function (num) {
        return ['#pink','#blue','#yellow','#green'][num-1];
    });
    // this will apply the animation in sequence
    TweenMax.staggerFrom(circles, 0.6, {opacity:0.3, scale:0.8, ease:Elastic.easeOut}, 0.6);
}

既然你已经有了这个,你可能需要检查动画本身,因为这个方法会立即将所有受影响的元素设置为它们的初始样式,但在 "staggered" 延迟时执行动画。

如果这不起作用,请使用 onComplete 属性:

实现循环
function show_sequence() {
    var circles = right_seq.map(function (num) {
        return ['#pink','#blue','#yellow','#green'][num-1];
    });
    (function loop(i) {
        if (i>=circles.length) return;
        TweenMax.from(circles[i], 0.6, {
            opacity:0.3, scale:0.8, ease:Elastic.easeOut, 
            onComplete: loop.bind(this,i+1)
        });
    })(0);
}