3

我正在用 Javascript 制作一个简单的游戏,其中当一个物体与墙壁碰撞时,它会发出“砰”的一声。该声音的响度取决于物体的速度(更高的速度=>更大的声音)。

播放功能:

playSound = function(id, vol) //ID of the sound in the sounds array, volume/loudness of the sound
{
    if (vol) //sometimes, I just want to play the sound without worrying about volume
        sounds[id].volume = vol;
    else
        sounds[id].volume = 1;

    sounds[id].play();
}

我怎么称呼它:

playSound(2, Math.sqrt(p.vx*p.vx + p.vy*p.vy)/self.TV); //self.TV stands for terminal velocity. This calculates the actual speed using the basic Pythagora's theorem and then divides it by self.TV, which results in a number from 0 to self.TV. 2 is the id of the sound I want to play.

在 Chrome 中,一切都很好。然而,在 Firefox 中,每次发生与墙壁的碰撞(=>playSound被调用)时,都会有一个持续近半秒的暂停!起初,我以为问题出在Math.sqrt,但我错了。这就是我测试它的方式:

//playSound(2, 1); //2 Is the id of the sound I want to play, and 1 is max loudness
Math.sqrt(p.vx*p.vx + p.vy*p.vy)/self.TV;
Math.sqrt(p.vx*p.vx + p.vy*p.vy)/self.TV;
Math.sqrt(p.vx*p.vx + p.vy*p.vy)/self.TV;

这完全消除了碰撞延迟,让我相信这Math.sqrt根本不会引起任何问题。不过,可以肯定的是,我这样做了:

playSound(2, 1); //2 Is the id of the sound I want to play, and 1 is max loudness
//Math.sqrt(p.vx*p.vx + p.vy*p.vy)/self.TV;
//Math.sqrt(p.vx*p.vx + p.vy*p.vy)/self.TV;
//Math.sqrt(p.vx*p.vx + p.vy*p.vy)/self.TV;

滞后又回来了!现在我确定播放声音会导致问题。我对么?为什么会这样?我如何解决它?

4

2 回答 2

7

当玩家发射武器时,我遇到了同样的延迟问题。我的解决方案有两个:

  1. 在加载时播放每个声音,然后立即暂停。这将允许它快速恢复播放,而不是从头开始播放。在每次播放声音后执行此播放暂停技巧。

  2. 为每种声音使用一个对象池<audio>,而不是为每种声音类型使用一个音频对象。不只是使用sounds[id],而是使用二维数组,使用sound[id][count]. 这里,sound[id]是所有具有相同声音的音频对象的列表,并且count是用于该声音 id 的当前对象的索引。每次调用 时playSound(id),增加与该 id 关联的计数,以便下一次调用调用不同的音频对象。

我不得不一起使用这些,因为播放暂停技术可以很好地将缓冲延迟移动到需要播放声音之前,但如果你需要快速播放声音,你仍然会得到延迟。这样,最近使用的音频对象可以在另一个对象播放时“充电”。

于 2012-04-09T19:36:59.180 回答
0

可能对您有所帮助的两件事是利用Web 工作者或预先预先计算多个响度级别,您也可以在后台使用工作者线程执行此操作。我这样说并没有涉及 Web 音频 API 的特性或您如何计算声音输出,但如果您已经用尽了所有其他方法,这可能是您应该关注的下一个方向。

于 2012-04-09T19:42:46.733 回答