我正在用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;
然后又回来了!现在我确信播放声音会导致问题。我对么?为什么会这样?我该如何解决?
答案 0 :(得分:7)
当玩家发射武器时,我遇到了同样的延迟问题。我的解决方案有两个方面:
在加载时播放每个声音,然后立即暂停。这将允许它快速恢复播放,而不是从头开始播放。每次播放声音后都要进行播放暂停技术。
为每个声音使用<audio>
个对象池,而不是为每种声音类型使用单个音频对象。不要只使用sounds[id]
,而是使用sound[id][count]
访问的2D数组。这里,sound[id]
是所有声音相同的音频对象列表,count
是该声音id使用的当前对象的索引。每次调用playSound(id)
时,递增与该id相关的计数,以便下一个调用调用不同的音频对象。
我不得不一起使用这些,因为播放暂停技术可以很好地将的缓冲延迟移动到需要播放的声音之前,但是如果你需要快速的声音,那么你我还会得到延迟。这样,最近使用的音频对象可以在另一个对象播放时“充电”。
答案 1 :(得分:0)
可能对您有用的两件事就是使用Web workers或提前预先计算几个响度级别,您也可以在后台使用工作线程进行计算。我是这样说的,没有考虑Web音频API的特性或者你如何计算声音输出,但是如果你已经用尽所有其他方法,这可能是你应该关注的下一个方向。