作者:郑谊099_448 | 2023-08-13 13:13
我正在使用HTML5来编写游戏; 我现在遇到的障碍是如何播放声音效果.
具体要求很少:
播放和混合多种声音,
多次播放相同的样本,可能重叠播放,
在任何点中断播放样本,
最好播放包含(低质量)原始PCM的WAV文件,但我当然可以转换它们.
我的第一种方法是使用HTML5
元素并在我的页面中定义所有声音效果.Firefox播放WAV文件只是很好,但#play
多次调用并不能真正多次播放样本.根据我对HTML5规范的理解,该
元素还可以跟踪播放状态,因此可以解释原因.
我的直接想法是克隆音频元素,所以我创建了以下微小的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
,但我仍然无法多次播放相同的样本.看起来这个
元素实际上更像是一个流媒体功能而不是播放音效的东西.
是否有一种聪明的方法可以实现这一点,我很想忘记,最好只使用HTML5和JavaScript?
我还要提一下,我的测试环境是Ubuntu 9.10上的Firefox 3.5.我尝试过的其他浏览器--Opera,Midori,Chromium,Epiphany--产生了不同的结果.有些人不玩任何东西,有些人抛出异常.
1> Kornel..: HTML5
Audio
对象
你不需要打扰
元素.HTML 5允许您直接访问Audio
对象:
var snd = new Audio("file.wav"); // buffers automatically when created
snd.play();
在当前版本的规范中不支持混合.
要多次播放相同的声音,请创建Audio
对象的多个实例.您也可以snd.currentTime=0
在完成播放后设置对象.
由于JS构造函数不支持回退
元素,因此您应该使用
(new Audio()).canPlayType("audio/ogg; codecs=vorbis")
测试浏览器是否支持Ogg Vorbis.
如果您正在编写游戏或音乐应用程序(不仅仅是一个播放器),您将需要使用更高级的Web Audio API,现在大多数浏览器都支持它.
`Audio`对象是自动缓冲的.它们的设计类似于`Image`对象,因此oldschool图像预加载技术也适用于音频.
这也适用于iOS.请注意,您*需要*使用某种用户操作(例如,单击按钮)来启动声音.你不能只在window.load()上做一个`snd.play()`.
如果不是因为
html5元素允许多个源,我更喜欢这种方法,所以如果浏览器不支持mp3,你可以回退到ogg/wav.在javascript中需要一些技巧才能完成相同的操作. 在iOS 6上支持自动播放:您可以在window.load()上使用简单的snd.play()启动声音. 2> Chris Jaynes..: W3C的WebAudio API
截至2012年7月,Chrome现在支持WebAudio API,并且至少部分支持Firefox,并且将从版本6开始添加到IOS.
虽然它足够强大,可以编程方式用于基本任务,但Audio元素从未打算为游戏等提供完整的音频支持.它旨在允许将单个媒体嵌入到页面中,类似于img标签.尝试将音频标记用于游戏时存在很多问题:
定时单对于Audio元素很常见
每个声音实例都需要一个Audio元素
负载事件尚不完全可靠
没有常见的音量控制,没有褪色,没有滤镜/效果
我使用WebAudio入门文章开始使用WebAudio API.该炮塔防御WebAudio案例也很好看.
3> d13..: howler.js
对于游戏创作,最好的解决方案之一是使用一个库来解决我们在为Web编写代码时遇到的许多问题,例如howler.js.howler.js将伟大的(但是低级的)Web Audio API抽象为易于使用的框架.如果Web Audio 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的音乐编辑器,效果生成器或视频游戏,这些库中的每一个都值得一看.
4> Rob..: 在某些情况下,您可能还希望使用它来检测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/, ''));
}
5> F-3000..: 这是一种可以同时播放相同声音的方法.结合预加载器,你就完成了.这至少适用于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");