正常将游戏构建到微信小游戏,总体上一切正常,以为大功告成,但打开声音多测试一会儿,突然发现每次音效正常一段时间后,突然就消失了!时间大约几分钟,次数也不一定,但几分钟后肯定消失,如果一直测试下去,偶尔会听到一二次音效,但最终的结果连背景音乐一并消失!反复验证后,证实这个现象只反正在微信小游戏中,在浏览器、内置模拟器还是真机app都无次问题。
在网上查询了下,有多个说法,其中之一是要求每次播放都重新对audioSource进行stop和release操作,这个听起来有点不靠谱,但死马当活马医尝试了下,代码需要做很多调整,包括重新创建的设计,花了大半天,写出来代码,一运行还是出错!只不过错误形式变得更加奇怪,有时候能多坚持一会儿,但最终出各种问题,甚至死机!后来加了一大堆try catch代码,以为会好点,但结果依旧,程序逻辑感觉都不对,最后只有放弃,代码重新恢复,真是歪专家误事啊!
正确的思路是:这个问题应该是cocos creator的兼容性bug,估计在后面版本会修复!目前要解决,最简单方法就是绕过cocos creator自带的音频播放,用微信的方式播放;但是cocos creator的资源管理自成一体,直接使用连文件路径都找不到,需要一些技巧,下面就是完整的过程,经过测试完全可用:
定义微信小游戏播放控件
private _wxAudio:any = null;
放置在自定义audioManager类下面。
加载资源
resources.load(name, AudioClip, (err, clip)=> {
if (err) {
warn('load audioClip failed: ', err);
return;
}
其中name表示原来代码中资源名称(含路径,如sound/test,注意不能有扩展名)。
3. 找到真实路径,微信小游戏加载
if (this._wxAudio === null) {
this._wxAudio = wx.createInnerAudioContext();
}
this._wxAudio.src = clip.nativeUrl; // src 可以设置 http(s) 的路径,本地文件路径或者代码包文件路径
this._wxAudio.volume = this.soundVolume;
this._wxAudio.play();
核心就是nativeUrl参数,代表实际最终的资源路径。测试后工作正常。
完整加载代码如下:
const audioSource = audioManager._audioSource!;
assert(audioSource, 'AudioManager not inited!');
name = 'sound/' + name;
resources.load(name, AudioClip, (err, clip)=> {
if (err) {
warn('load audioClip failed: ', err);
return;
}
// NOTE: the second parameter is volume scale.
if (sys.platform === "WECHAT_GAME") {
if (this._wxAudio === null) {
this._wxAudio = wx.createInnerAudioContext();
}
this._wxAudio.src = clip.nativeUrl; // src 可以设置 http(s) 的路径,本地文件路径或者代码包文件路径
this._wxAudio.volume = this.soundVolume;
this._wxAudio.play();
return;
}
// 非微信小游戏环境的正常播放模式
if (audioSource.volume!=0){
audioSource.playOneShot(clip, volumeScale * this.soundVolume / audioSource.volume);
}
else{
audioSource.volume = this.soundVolume;
audioSource.playOneShot(clip, volumeScale * this.soundVolume);
audioSource.volume = 0;
}
});
下面是我的游戏示例,大家可以试试:
