17 lines
2.1 KiB
JavaScript
17 lines
2.1 KiB
JavaScript
// 微信原生短音频播放:资源随包提供,不依赖浏览器振荡器。
|
|
const instances=new Set();
|
|
export const audioDiagnostics={backend:'InnerAudioContext',lastError:null,plays:0};
|
|
export function stopAudio(){for(const instance of instances)instance.stop();}
|
|
export class CasualAudio{
|
|
constructor(host,storage,key){this.storage=storage;this.key=key;this.channels=[];this.cursor=0;this.timers=new Set();this.lastEvent=null;this.lastAt={};this.warned=false;try{this.enabled=storage.getItem(key)!=='off';}catch{this.enabled=true;}instances.add(this);}
|
|
unlock(){if(!this.enabled||!wx.createInnerAudioContext)return false;
|
|
try{wx.setInnerAudioOption?.({obeyMuteSwitch:false,mixWithOther:true});if(!this.channels.length)for(let i=0;i<4;i++){const a=wx.createInnerAudioContext();a.obeyMuteSwitch=false;a.volume=.85;a.onError?.(error=>this.error(error));this.channels.push(a);}return true;}catch(error){this.error(error);return false;}}
|
|
error(error){audioDiagnostics.lastError={errCode:error?.errCode||0,errMsg:error?.errMsg||String(error)};if(!this.warned){this.warned=true;wx.showToast?.({title:'音效加载失败,请重新进入游戏',icon:'none'});}}
|
|
stop(){for(const timer of this.timers)clearTimeout(timer);this.timers.clear();for(const a of this.channels){try{a.stop();}catch{}}}
|
|
toggle(){this.enabled=!this.enabled;try{this.storage.setItem(this.key,this.enabled?'on':'off');}catch{}if(this.enabled)this.play('correct');else this.stop();return this.enabled;}
|
|
play(kind,delay=0,step=1){if(!this.unlock())return;const now=Date.now();if(kind==='error'&&now-(this.lastAt.error||0)<180)return;this.lastAt[kind]=now;
|
|
if(kind==='restart')this.stop();const file=kind==='move'?'move-'+Math.max(1,Math.min(36,Math.floor(step))):kind;
|
|
const run=()=>{if(!this.enabled)return;const a=this.channels[this.cursor++%this.channels.length];try{a.stop();a.src='audio/'+file+'.wav';a.play();this.lastEvent=kind;audioDiagnostics.plays++;}catch(error){this.error(error);}};
|
|
if(delay>0){const timer=setTimeout(()=>{this.timers.delete(timer);run();},delay*1000);this.timers.add(timer);}else run();}
|
|
}
|