请查看这个太空射击游戏演示。
在Chrome 18和Firefox 10上,HTML5音频效果非常好。播放声音没有延迟,每个样本都能完美播放。上一次我使用HTML5音频和JavaScript尝试播放声音时,我无法使声音重复播放。
Scirra使用了什么方法来实现这样的完美效果呢?
请查看这个太空射击游戏演示。
在Chrome 18和Firefox 10上,HTML5音频效果非常好。播放声音没有延迟,每个样本都能完美播放。上一次我使用HTML5音频和JavaScript尝试播放声音时,我无法使声音重复播放。
Scirra使用了什么方法来实现这样的完美效果呢?
我是Construct 2的开发人员,所以希望我有足够的资格回答你的问题 :)
HTML5音频确实很混乱,所以我在Construct 2中做了很多努力,尝试让它变得更加可靠。以下是我所做的概述:
使用Web Audio API
HTML5音频似乎是为流媒体音乐设计的,因此HTML5音频对象是一种相当重量级的对象。像Space Blaster这样每秒播放10个声音就可以轻松地卡住浏览器。另一方面,Web Audio API是一款高性能的音频引擎,具有路由、效果和轻量级声音播放。它非常适合游戏。音频缓冲区和音频播放被分开,所以你可以有一个数据缓冲区并同时有效地播放多次,而某些浏览器非常有缺陷,如果你播放一个HTML5声音几次,它每次都会重新下载它!由于它实际上是为游戏等设计的,所以你可以愉快地播放吨的声音很长时间,它仍然会正常运行。它也可以使用HTML5音频作为声源,但我仅在用户指定为音乐曲目的东西中使用HTML5音频(因为那是你希望进行流媒体的地方 - 通常Web Audio API中的其他所有内容都在播放之前完全下载)。
Web Audio API受Chrome支持,并已经进入了iOS 6+(虽然在触摸事件中尝试播放一些音频之前它会静音),Firefox正在开发支持,它应该很快就会到来Chrome for Android上。因此,在这些平台上,音频将更加可靠。
有关更多信息,请访问HTML5Rocks和提议的规范 - 目前你必须使用规范作为文档,没有其他太多资源。
其他浏览器:实现音频回收系统
Web Audio API并不是所有浏览器都支持的,IE尤其不支持,这意味着你仍然需要为向后兼容而将HTML5音频引入游戏中。实现这一点的方法是回收音频对象。
例如,在《Space Blaster》游戏中,玩家的激光每秒发射10次 - 这还不包括其他任何声音效果!如我之前所提到的,Audio是一个比较笨重的对象,因此如果你每秒进行10次以上的new Audio()
操作,那么浏览器最终会崩溃并且声音会开始出故障。但是,通过回收音频对象,你可以大大减少创建Audio对象的数量。
基本上,对于每个声音效果,保留使用该声音作为源创建的每个Audio对象的缓存。然后,在播放新声音时,搜索已播放完毕的任何声音效果的缓存(ended
属性值为true)。如果找到,则将其倒回到开头(currentTime = 0
),然后再次进行播放(play()
)。否则,在缓存中创建一个new Audio()
对象。
由于玩家激光声效很短,所以不必每分钟创建600个Audio对象,只需保留3或4个对象并不断循环即可。不幸的是,某些浏览器仍然会下载它4次(我上次检查时Safari就是这样!),或者在播放每个声音缓冲区的第一次时延迟较高,但由于总是重复使用相同的缓冲区,浏览器最终会赶上来,所以声音可能会有点奇怪,然后就清晰了。我们还使用HTML5应用程序缓存,这样下次玩游戏时,所有内容都从磁盘加载,因此后续的游戏体验应该会非常流畅。
基本上就是这样。使用HTML5音频进行第一次播放仍然有点不稳定,但之后每次播放应该都很稳定,只要浏览器具备合理的音频实现即可。虽然有许多尝试克隆Audio对象的方法,但我发现将现有的Audios倒回工作效果最好。
我们没有SoundManager或任何Flash/插件回退,因为我们强调纯HTML5。
我们还支持PhoneGap和appMobi提供的音频API,用于移动设备,因为在移动设备上使用HTML5音频几乎没有意义。这样我们的音频引擎就包装了四个音频API,看起来像弗兰肯斯坦怪物一样混乱,但它能工作。