简体   繁体   English

如何在Javascript For循环中的每次迭代之间增加延迟

[英]How to add delay between each iteration in Javascript For loop

I'm creating a Simon game for FreeCodeCamp and I'm trying to use a for loop to play an audio sound for each piece of the pattern. 我正在为FreeCodeCamp创建一个Simon游戏,并且尝试使用for循环为每个模式片段播放音频。

The code I have now plays the audio all at once which won't work for the game. 我现在拥有的代码可以一次播放所有音频,而这不适用于游戏。 How can I change this code so that it will play each audio sound individually with a .5 second break in between? 如何更改此代码,以使其在间隔0.5秒的时间内分别播放每种音频?

Here's the function that plays the audio and adds visual effect 这是播放音频并增加视觉效果的功能

function playAudio() {
    if (colorColor === "red") {
      red.play();
      $('#red').effect("highlight", { color: colorColor }, 500);
    } else if (colorColor === "blue") {
      blue.play();
      $('#blue').effect("highlight", { color: colorColor }, 500);
    } else if (colorColor === "green") {
      green.play();
      $('#green').effect("highlight", { color: colorColor }, 500);
    } else if (colorColor === "yellow") {
      yellow.play();
      $('#yellow').effect("highlight", { color: colorColor }, 500);
    }
}

This is the function where I believe the issue is. 我认为这是问题所在。

function playPattern() {
    for (var i = 0; i < pattern.length; i++) {
      colorColor = pattern[i];
      setTimeout(playAudio, 500);
    }
  setTimeout(random, 750);
}

And here's the random() function only because it is called within playPattern() 这是random()函数,仅是因为它在playPattern()中被调用

function random() {
    randomColor = colors[Math.floor(Math.random() * colors.length)];
    colorColor = randomColor;
    colorColor = colorColor.slice(1);
    pattern.push(colorColor);

    count++;
    if (count < 10) {
      document.getElementById("count").innerHTML = "0" + count;
    } else {
      document.getElementById("count").innerHTML = count;
    }

    playAudio();

    pickCount = 0;
    userPick = [];
}

Thanks! 谢谢!

Assuming your audios are all the same length: 假设您的音频长度相同:

var audioLength = 3000; // length of audio in ms

for (var i = 0; i < pattern.length; i++) {
  colorColor = pattern[i];
  setTimeout(playAudio, (i * (audioLength + 500));
}

In your code where you are doing: 在您正在执行的代码中:

for (var i = 0; i < pattern.length; i++) {
  colorColor = pattern[i];
  setTimeout(playAudio, 500);
}

What happens is that you basically define to run playAudio in 500ms for all patterns. 发生的事情是,您基本上定义了对所有模式在500ms内运行playAudio the for loop is processed immediately and 500ms later all audios are being played together. 将立即处理for循环,然后在500毫秒后一起播放所有音频。

What you want is to call the next timeout only when the playAudio function ends. 您想要的是仅在playAudio函数结束时才调用下一个超时。

let i = 0;
function playAudio() {
    i++;
    colorColor = pattern[i];
    if (colorColor === "red") {
      red.play();
      $('#red').effect("highlight", { color: colorColor }, 500);
    } else if (colorColor === "blue") {
      blue.play();
      $('#blue').effect("highlight", { color: colorColor }, 500);
    } else if (colorColor === "green") {
      green.play();
      $('#green').effect("highlight", { color: colorColor }, 500);
    } else if (colorColor === "yellow") {
      yellow.play();
      $('#yellow').effect("highlight", { color: colorColor }, 500);
    }
    if (i < pattern.length) {
        setTimeout(playAudio, 500);
    }
}

function random() {
    randomColor = colors[Math.floor(Math.random() * colors.length)];
    colorColor = randomColor;
    colorColor = colorColor.slice(1);
    pattern.push(colorColor);

    count++;
    if (count < 10) {
      document.getElementById("count").innerHTML = "0" + count;
    } else {
      document.getElementById("count").innerHTML = count;
    }

    playAudio();

    pickCount = 0;
    userPick = [];
}

setTimeout(random, 750);

I based my answer on this answer . 我以这个答案为基础

What I did was to preload audio files by creating an object with the titles as keys and with an object value which contains the files' source and if it's loaded already: 我所做的是通过创建一个预加载音频文件object与标题密钥和与它包含文件的来源,如果它已经加载的对象值:

const notes = ['do', 're', 'mi', 'fa', 'sol', 'la', 'ti'];
const audioFiles = notes.reduce((obj, title) => {
  obj[title] = {
    src: `notes/${title}.wav`,
    loaded: false,
  };

  return obj;
}, {});

// Preload files.
Object.entries(audioFiles).forEach(([title, details]) => {
  const audio = new Audio();

  audio.addEventListener('canplaythrough', () => {
    details.loaded = true;
  });

  audio.src = details.src;
});

The playPlaylist function takes a playlist (array of titles) and an object containing the audio files: playPlaylist函数获取一个播放列表(标题数组)和一个包含音频文件的对象:

const playAudio = function playAudio(player, src) {
  player.src = src;
  player.play();
};

const playPlaylist = function playPlaylist(playlist, files) {
  // TODO: Check if files in playlist are already loaded.
  // while (!filesLoaded) { ... }

  const player = new Audio();
  let audioIndex = 0;

  player.addEventListener('ended', () => {
    audioIndex++;

    if (audioIndex >= playlist.length) {
      return;
    }

    setTimeout(() => {
      playAudio(player, files[playlist[audioIndex]].src);
    }, 500);
  });

  playAudio(player, files[playlist[audioIndex]].src);
};

Then just provide the playlist and pass the audioFiles object. 然后只需提供播放列表并传递audioFiles对象即可。

// Play sample playlist.
const playlist = 'do,mi,fa,sol,do,re,la,fa,mi'.split(',');
playPlaylist(playlist, audioFiles);

Just change the files and file paths to test. 只需更改文件和文件路径即可进行测试。

You need to consider how much the song lasts, and include that on your timeout, for example if red lasts 1 min, you need to set your next timeout to setTimeout(blue, 60*1000 + 500) , something like this : 您需要考虑歌曲的持续时间,并将其包括在超时中,例如,如果红色持续1分钟,则需要将下一个超时设置为setTimeout(blue, 60*1000 + 500) ,如下所示:

function playAudio(color) {
    if (colorColor === "red") {
      red.play();
      $('#red').effect("highlight", { color: colorColor }, 500);
      setTimeout(function () {
         playAudio("blue");
      },60*1000 + 500);
    } else if (colorColor === "blue") {
      blue.play();
      $('#blue').effect("highlight", { color: colorColor }, 500);
      setTimeout(function () {
         playAudio("green");
      },60*1000 + 500);
    } else if (colorColor === "green") {
    //.... ETC

You don't need a for, just some recursion 您不需要for,只需进行一些递归

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM