在 javascript 中逐个播放随机生成的音频文件数组

问题描述 投票:0回答:1

我正在尝试使用 vanilla javascript 创建 simon 游戏的第一步。

我能够生成一个随机的颜色数组,然后我希望将其传递给 playSequentially 函数,该函数将逐个播放与每种颜色相关的音频文件。

但是,我的 playSequentially 功能没有按预期工作。如果声音已经播放过,它通常不会播放该声音。然而,这种行为似乎不可预测。例如,给定这个数组 ['purple', 'red', 'blue', 'red', 'purple', 'red'],紫色将播放两次,但红色只会播放一次。我一直在阅读 MDN 上的文档 - 查看 currentTime,或重置结束属性。我问过chatGPT。但无济于事。有没有办法修复此代码,或者我只是完全以错误的方式处理此问题?谢谢你

let greenBtn = document.getElementById("green-button");
let redBtn = document.getElementById("red-button");
let blueBtn = document.getElementById("blue-button");
let purpleBtn = document.getElementById("purple-button");
let greenAudio = document.getElementById("green-audio");
let redAudio = document.getElementById("red-audio");
let blueAudio = document.getElementById("blue-audio");
let purpleAudio = document.getElementById("purple-audio");
let playback = document.getElementById("play");
greenBtn.addEventListener("click", () => {
  greenAudio.play();
})
redBtn.addEventListener("click", () => {
  redAudio.play();
})
blueBtn.addEventListener("click", () => {
  blueAudio.play();
})
purpleBtn.addEventListener("click", () => {
  purpleAudio.play();
})
let audioArray = [greenAudio, blueAudio, redAudio, purpleAudio];
function playAudio(audio) {
  audio.play();
}
function getAudioFromColor(color) {
  switch (color) {
    case "green":
      return greenAudio;
    case "blue":
      return blueAudio;
    case "red":
      return redAudio;
    case "purple":
      return purpleAudio;
  }
}
//create random array of colors of length n
function getRandomColorArray(n) {
  let randomColorArray = []
  let colors = ["green", "blue", "red", "purple"];
  let i = 0;
  while (i < n) {
    let index = Math.floor(Math.random() * 4);
    console.log(index)
    randomColorArray.push(colors[index]);
    i++;
  }
  return randomColorArray;
}
function playSequentially(audioColorArray) {
  let delay = 500;
  let currentAudio = getAudioFromColor(audioColorArray[0]);
  currentAudio.play();
  for (let i = 0; i < audioColorArray.length - 1; i++) {
    delay += 500;
    currentAudio = getAudioFromColor(audioColorArray[i]);
    currentAudio.onended = setTimeout(() => {
      getAudioFromColor(audioColorArray[i + 1]).play();
    }, delay);
  }
}
playback.addEventListener("click", () => {
  // let randomColorArray = getRandomColorArray(5);
  let randomColorArray = ['purple', 'red', 'blue', 'red', 'purple', 'red']
  console.log(randomColorArray)
  playSequentially(randomColorArray);
});
div {
  margin: 10px;
  /* padding: 10px; */
}
.game-btn {
  border: 1px solid black;
  border-radius: 20%;
  width: 200px;
  height: 200px;
}
.green {
  background-color: green;
}
.blue {
  background-color: blue;
}
.red {
  background-color: red
}
.purple {
  background-color: purple;
}
.green:hover {
  background-color: lightgreen;
}
.blue:hover {
  background-color: lightblue;
}
.red:hover {
  background-color: lightcoral
}
.purple:hover {
  background-color: plum;
}
#play {
  width: 100px;
  background-color: pink;
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<title>Document</title>
<div class="container" style="max-width: 75%;">
  <div class="row justify-content-center">
    <div class=" btn" id="play"> Playback</div>
  </div>
  <div class="row justify-content-center">
    <div class="game-btn green btn" id="green-button"></div>
    <audio id="green-audio" src="./sounds/539252-Kalimba-INTIMATE-D5-01.wav"></audio>
    <div class="game-btn blue btn" id="blue-button"></div>
    <audio id="blue-audio" src="./sounds/539256-Kalimba-INTIMATE-E6-01.wav"></audio>
  </div>
  <div class="row justify-content-center">
    <div class="game-btn red btn" id="red-button"></div>
    <audio id="red-audio" src="./sounds/539257-Kalimba-INTIMATE-F4-01.wav"></audio>
    <div class="game-btn purple btn" id="purple-button"></div>
    <audio id="purple-audio" src="./sounds/539258-Kalimba-INTIMATE-F5-01.wav"></audio>
  </div>
</div>
<script src="./assignment22.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>

javascript html
1个回答
0
投票

当你已经结束时,setTimeout 并不是一个好方法。

您还有关闭问题。

这是一种方法

const playSequentially = (audioColorArray) => {
  let index = 0; // Start from the first color
  const playNextAudio = () => {
    if (index < audioColorArray.length) {
      const audioElement = getAudioFromColor(audioColorArray[index]);
      audioElement.currentTime = 0; // Reset the audio time
      audioElement.play(); 
      audioElement.onended = () => {
        index++; // Move to the next index
        playNextAudio(); // Recursively call to play the next audio
      };
    }
  }
  playNextAudio(); // Start 
};
const colorArray = ['purple', 'red', 'blue', 'red', 'purple', 'red'];

playback.addEventListener("click", () => {
  colorArray.sort((a, b) => 0.5 - Math.random());
  console.log(colorArray)
  playSequentially(colorArray);
});
© www.soinside.com 2019 - 2024. All rights reserved.