我使用HTML5来编写游戏;我现在遇到的障碍是如何播放音效。

具体要求不多:

播放和混合多种声音, 多次播放相同的样本,可能会重复播放, 在任何时候中断样本的回放, 最好播放WAV文件包含(低质量)原始PCM,但我可以转换这些,当然。

我的第一个方法是使用HTML5 <audio>元素并在我的页面中定义所有音效。Firefox播放WAV文件的效果很好,但是多次调用#play并不能真正地多次播放示例。根据我对HTML5规范的理解,<audio>元素还跟踪播放状态,这就解释了为什么。

我的第一个想法是克隆音频元素,所以我创建了以下小型JavaScript库来为我做这件事(依赖于jQuery):

var Snd = {
  init: function() {
    $("audio").each(function() {
      var src = this.getAttribute('src');
      if (src.substring(0, 4) !== "snd/") { return; }
      // Cut out the basename (strip directory and extension)
      var name = src.substring(4, src.length - 4);
      // Create the helper function, which clones the audio object and plays it
      var Constructor = function() {};
      Constructor.prototype = this;
      Snd[name] = function() {
        var clone = new Constructor();
        clone.play();
        // Return the cloned element, so the caller can interrupt the sound effect
        return clone;
      };
    });
  }
};

现在我可以写snd。boom();从Firebug控制台并播放snd/boom.wav,但我仍然不能多次播放相同的样本。<audio>元素似乎更像是一个流媒体功能,而不是用来播放声音效果的。

有什么聪明的方法可以做到这一点,最好只使用HTML5和JavaScript?

我还应该提一下,我的测试环境是Ubuntu 9.10上的Firefox 3.5。我尝试过的其他浏览器——Opera、Midori、Chromium、Epiphany——产生了不同的结果。有些不播放任何内容,有些则抛出异常。


当前回答

所选答案将在除IE之外的所有程序中工作。我写了一个关于如何使它跨浏览器工作的教程。下面是我写的函数:

function playSomeSounds(soundPath) {
    var trident = !!navigator.userAgent.match(/Trident\/7.0/);
    var net = !!navigator.userAgent.match(/.NET4.0E/);
    var IE11 = trident && net
    var IEold = (navigator.userAgent.match(/MSIE/i) ? true : false);
    if (IE11 || IEold) {
        document.all.sound.src = soundPath;
    } else {
        var snd = new Audio(soundPath); // buffers automatically when created
        snd.play();
    }
}

你还需要添加以下标签到html页面:

<bgsound id="sound">

最后,你可以调用这个函数,并简单地通过这里的路径:

playSomeSounds("sounds/welcome.wav");

其他回答

http://robert.ocallahan.org/2011/11/latency-of-html5-sounds.html

http://people.mozilla.org/~roc/audio-latency-repeating.html

对我来说,在Firefox和Chrome中工作正常。

想要停止由你引起的声音,就这么做 var sound = document.getElementById("shot").cloneNode(true); sound.play (); 后来 sound.pause ();

howler.js

对于游戏创作,最好的解决方案之一就是使用一个能够解决我们在编写网页代码时所面临的许多问题的库,如嚎叫.js。js将强大(但低级)的Web Audio API抽象为一个易于使用的框架。如果Web音频API不可用,它将尝试退回到HTML5音频元素。

var sound = new Howl({
  urls: ['sound.mp3', 'sound.ogg']
}).play();
// it also provides calls for spatial/3d audio effects (most browsers)
sound.pos3d(0.1,0.3,0.5);

wad.js

另一个很棒的库是wad.js,它在生成合成音频(如音乐和效果)时特别有用。例如:

var saw = new Wad({source : 'sawtooth'})
saw.play({
    volume  : 0.8,
    wait    : 0,     // Time in seconds between calling play() and actually triggering the note.
    loop    : false, // This overrides the value for loop on the constructor, if it was set. 
    pitch   : 'A4',  // A4 is 440 hertz.
    label   : 'A',   // A label that identifies this note.
    env     : {hold : 9001},
    panning : [1, -1, 10],
    filter  : {frequency : 900},
    delay   : {delayTime : .8}
})

游戏音效

另一个与Wad.js类似的库是“Sound for Games”,它更专注于效果制作,同时通过一个相对独特(可能更简洁)的API提供了一组类似的功能:

function shootSound() {
  soundEffect(
    1046.5,           //frequency
    0,                //attack
    0.3,              //decay
    "sawtooth",       //waveform
    1,                //Volume
    -0.8,             //pan
    0,                //wait before playing
    1200,             //pitch bend amount
    false,            //reverse bend
    0,                //random pitch range
    25,               //dissonance
    [0.2, 0.2, 2000], //echo array: [delay, feedback, filter]
    undefined         //reverb array: [duration, decay, reverse?]
  );
}

总结

无论您是需要播放单个声音文件,还是创建自己的基于html的音乐编辑器、效果生成器或视频游戏,这些库都值得一看。

在某些情况下,你可能也想用它来检测HTML 5音频:

http://diveintohtml5.ep.io/everything.html

HTML 5 JS检测功能

function supportsAudio()
{
    var a = document.createElement('audio'); 
    return !!(a.canPlayType && a.canPlayType('audio/mpeg;').replace(/no/, ''));
}

我在编程一个音乐盒卡片生成器时遇到了这个问题。从不同的库开始,但每次都有某种程度的故障。正常音频执行的延迟很糟糕,没有多次播放……最终使用低延迟库+ soundmanager:

http://lowlag.alienbill.com/ 而且 http://www.schillmania.com/projects/soundmanager2/

你可以在这里查看实现: http://musicbox.grit.it/

我生成了wav + ogg文件,用于多种浏览器播放。这个音乐盒播放器工作响应ipad, iphone, Nexus, mac, pc,…对我有用。

这里有一种方法可以同时播放相同的声音。结合预加载器,你就万事俱备了。这至少适用于Firefox 17.0.1,还没有在其他任何东西上测试过。

// collection of sounds that are playing
var playing={};
// collection of sounds
var sounds={step:"knock.ogg",throw:"swing.ogg"};

// function that is used to play sounds
function player(x)
{
    var a,b;
    b=new Date();
    a=x+b.getTime();
    playing[a]=new Audio(sounds[x]);
    // with this we prevent playing-object from becoming a memory-monster:
    playing[a].onended=function(){delete playing[a]};
    playing[a].play();
}

将此绑定到键盘键,并享受:

player("step");