【问题标题】:Delay between loop's first execution and the next one循环的第一次执行和下一次执行之间的延迟
【发布时间】:2017-11-16 17:40:57
【问题描述】:

我正在尝试制作一个 simon 游戏,我几乎完成了,但我遇到了一个问题。 在 simon 游戏中,当 simon 给您命令(由闪烁的灯和每个灯的音频表示)您需要记住并在之后重复时,每次闪烁(带有音频)到下一个闪烁之间会有短暂的延迟。

所以现在,我的 simon 正在发出声音,但它会同时发出声音,没有任何延迟。我尝试使用setIntarvelsetTimeout,但它仍然一次播放所有音频。

由于添加闪烁不应该那么难,所以我一直坚持到最后。

然后我建立了一个定时器功能:

function timer(delayInMS) {
    var time = new Date();
    var currentTime = time.getTime();
    var nextTime = time.getTime() + delayInMS;
    while (currentTime != nextTime) {
        time = new Date();
        currentTime = time.getTime();
        }
}

并在播放音频的函数中使用它,但它仍然在做同样的事情 - 一次播放。

这是负责音频的函数:

function playAudio(btnSound) {
    if (btnSound == "c") {
        c.play();
    }
    if (btnSound == "g") {
        g.play();
    }
    if (btnSound == "a") {
        a.play();
    }
    if (btnSound == "d") {
        d.play();
    }
}

而这个函数负责游戏的逻辑:

var btns = ["c", "g", "a", "d"];
var randomOrder = "";

var playerInputOrder = "";

var timer = 1000;    //For timer()

function randomSimon() {
var randomBtn = btns[Math.floor(Math.random() * 4)];
randomOrder += randomBtn;
for  (i = 0; i <= randomOrder.length - 1; i++) {
    for (s = 0; s <= i; s++) {
        var someText = "";
        someText += randomOrder.charAt(s);
        playAudio(randomOrder.charAt(s));
        document.getElementById('debug').innerHTML = someText; //this is for debugin, should be ignored.
        timer(500);
    }
}

}

这是整个脚本以便更好地阅读:

var isGameStarted = false;

var d = new Audio("dSharpNote.wav");
var a = new Audio("aSharpNote.wav");
var g = new Audio("gSharpNote.wav");
var c = new Audio("cNote.wav");

var btns = ["c", "g", "a", "d"];
var randomOrder = "";

var playerInputOrder = "";

var timer = 1000;

function startGame() {
    isGameStarted = true;         //So players won't be able to just press the simon's buttons.
    randomOrder = "";             //A variable to keep the random order given by the simon.
    playerInputOrder = "";        //A variable to keep the random order the player inputs.
    randomSimon();                //Called to give the first button in the order.
}

function randomSimon() {                                       //Adds one random button to the order and saves the order.
    var randomBtn = btns[Math.floor(Math.random() * 4)];       //Adds the random button.
    randomOrder += randomBtn;                                  //Saves the random order.
    for  (i = 0; i <= randomOrder.length - 1; i++) {           //this should play all the audios one by one according the saved order
        for (s = 0; s <= i; s++) {
            var someText = "";
            someText += randomOrder.charAt(s);
            playAudio(randomOrder.charAt(s));
            document.getElementById('debug').innerHTML = someText;         //this is for debugin, should be ignored.
            timer(500);
        }
    }
}

function timer(delayInMS) {
    var time = new Date();
    var currentTime = time.getTime();
    var nextTime = time.getTime() + delayInMS;
    while (currentTime != nextTime) {
        time = new Date();
        currentTime = time.getTime();
    }
}

function playerProgress(btn) {                        //Getting the player's input and checks if it's in the right order.
    if (isGameStarted == true) {
        var btnClicked = btn.id;                      //Gets the id of the button the player clicked.
        playAudio(btnClicked);                        //So this could play it's audio.
        playerInputOrder += btnClicked;
        if (playerInputOrder.length == randomOrder.length) {
            if (playerInputOrder == randomOrder) {
                playerInputOrder = "";
                setTimeout(randomSimon, 1000);
            } else {
                document.getElementById('scoreText').innerHTML = randomOrder + " Game Over!";
                isGameStarted = false;               //Makes the player unable to play the simon's button's audios.
            }
        }
        document.getElementById('debug').innerHTML = playerInputOrder;
    }
}

function playAudio(btnSound) {
    if (btnSound == "c") {
        c.play();
    }
    if (btnSound == "g") {
        g.play();
    }
    if (btnSound == "a") {
        a.play();
    }
    if (btnSound == "d") {
        d.play();
    }
}

function someInterval() {
    var i = 0;
    var anInterval = setInterval(function() {
        i++;
        if (i > 11) {
            clearInterval(anInterval);
            timer *= 2;
        }
    }, timer);
}

【问题讨论】:

  • 可能相关,I answered this other question 前一阵子,是关于为这样的游戏排序动画。
  • eek...不要在您的游戏循环中自旋锁定...有一个每隔 5 毫秒运行的时间间隔,而是跟踪增量时间。或者只是使用大量的超时来推进游戏状态。除非您进行嵌入式编程,否则自旋锁定永远不会有用。
  • 我在google上看了一点关于spin-lock的内容,如果我理解正确的话,这里的spin-lock就是timer()函数?

标签: javascript for-loop delay


【解决方案1】:

所以您想在每次 playAudio 通话后暂停一下?

我还是会去超时

var sounds = {};
sounds.a = ...;
sounds.b = ...;

function playAudio(sound, callback) {
    if (typeof sounds[sound] === "undefined") {
        throw "sound not available";
    }
    sounds[sound].play();
    if (typeof callback !== "undefined") {
        window.setTimeout(callback, 500);
    }
}

// play a - pause - b - pause c
playAudio("a", function(){
    playAudio("b", function() {
        playAudio("c");
    });
});

如果你先构建序列,你也可以做这个动态

var sequence = ["a", "b", "c"];
var pointer = 0;

playAudio(sequene[pointer], function() {
    pointer += 1;
    if (typeof sequence[pointer] !== "undefined") {
        playAudio(sequence[pointer], this); // this will be bound to the function itself
    } else {
        alert("sequence finished");    
    }
});

这没有经过测试,但它应该可以工作,如果没有,请告诉我。

【讨论】:

  • 我会检查它并提供更新是否有效。我可以请您解释一下“序列”代码吗?我想我明白了,但不确定
  • 序列只是一个字符串数组(键码)。指针提供了关于我们使用的当前索引的信息(来自这个数组)。只要指针存在(在函数体的第 1 行增加),playAudio 数组就会再次调用自身。一旦指针到达数组的末尾(我们的序列),它就会简单地提醒“序列完成”。除了将其用作回调参数之外,您还可以创建一个命名函数并将该函数作为回调传递。在示例中使用“this”,否则我无法引用匿名函数。
【解决方案2】:

您可以使用setTimeout 并在浏览颜色时增加它:

function randomSimon() {                                       //Adds one random button to the order and saves the order.
    var randomBtn = btns[Math.floor(Math.random() * 4)];       //Adds the random button.
    randomOrder += randomBtn;                                  //Saves the random order.
    for  (i = 0; i <= randomOrder.length - 1; i++) {           //this should play all the audios one by one according the saved order
        for (s = 0; s <= i; s++) {
            var someText = "";
            someText += randomOrder.charAt(s);
  >>>>>>>   setTimeout(function() { playAudio(randomOrder.charAt(s)); },2000*s);
            document.getElementById('debug').innerHTML = someText;         //this is for debugin, should be ignored.

        }
    }
}

这将立即播放第一个声音,2s 后播放第二个声音,4s 后播放第三个声音,依此类推。希望对您有所帮助!


编辑

您有一个带有for 循环和setTimeout 的示例:

for (s = 0; s <= 2; s++) {
  setTimeout(function() { console.log('hello world'); },2000*s);
}

编辑 2

OK 看来这里的内存访问有点混乱。尝试这样做。

先创建一个函数,等待后做你想做的事情:

var delayedPlay = function(c,delay) {
  setTimeout(
    function() { playAudio(c); },
    delay);
}

然后在for循环中调用它:

function randomSimon() {                                       //Adds one random button to the order and saves the order.
    var randomBtn = btns[Math.floor(Math.random() * 4)];       //Adds the random button.
    randomOrder += randomBtn;                                  //Saves the random order.
    for  (i = 0; i <= randomOrder.length - 1; i++) {           //this should play all the audios one by one according the saved order
        for (s = 0; s <= i; s++) {
            var someText = "";
            someText += randomOrder.charAt(s);
  >>>>>>>   delayedPlay(randomOrder.charAt(s),2000*s);
            document.getElementById('debug').innerHTML = someText;         //this is for debugin, should be ignored.

        }
    }
}

【讨论】:

  • 已经试过了,做同样的事情,一次播放所有声音
  • @Omer 您是否完全按照我写的方式复制了车道?你是在乘以2000*s吗?我编辑了for 循环和setTimeout 的小提琴示例。
  • 我按照你说的做了,但没有达到我想要的效果。现在我只是用文本而不是声音来尝试它,因为它更舒服。我会尽力解释自己:我正在尝试做的类似于从 1 到 10 的普通“For”循环。但我希望它在打印每个数字之前等待一秒钟,所以之后它打印“1”,它应该等待一秒钟,然后打印“2”,依此类推,直到它到达 10。
  • #Omer 请告诉我你用来尝试的代码。
  • 试过你说的,现在根本不播放声音
猜你喜欢
  • 1970-01-01
  • 2023-01-26
  • 2019-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-18
  • 2013-08-12
相关资源
最近更新 更多