Skip to content

Instantly share code, notes, and snippets.

@yangfch3 yangfch3/SoundManager.ts
Last active Nov 8, 2018

Embed
What would you like to do?
[白鹭声音管理器] 白鹭音频接口的封装 #白鹭 #游戏开发
class SoundManager {
private static instance: SoundManager
private static IS_MUTE_SYMBOL = 'isMute'
private static BGM_VOLUME = 'bgmVolume'
private static EFFECT_VOLUME = 'effectVolume'
static getInstance() {
if (!SoundManager.instance) {
new SoundManager()
}
return SoundManager.instance
}
private isMute: number
private bgmVolume: number
private effectVolume: number
private curEffectTs: number // 记录最新音效的时间戳,开启音效不重叠时用到
private effectChannel: egret.SoundChannel
private bgmSound: egret.Sound
private bgmChannel: egret.SoundChannel
private bgmPausePosition: number
private soundCache = {
effect: {},
bgm: {}
}
constructor() {
if (!SoundManager.instance) {
SoundManager.instance = this
this.init()
}
return SoundManager.instance
}
init() {
this.isMute = +egret.localStorage.getItem(SoundManager.IS_MUTE_SYMBOL) || 0
this.bgmVolume = +egret.localStorage.getItem(SoundManager.BGM_VOLUME) || 1
this.effectVolume = +egret.localStorage.getItem(SoundManager.BGM_VOLUME) || 1
}
getIsMute() {
return this.isMute === 1
}
getBgmVolume() {
return this.bgmVolume
}
getEffectVolume() {
return this.effectVolume
}
setMute() {
this.isMute = 1
egret.localStorage.setItem(SoundManager.IS_MUTE_SYMBOL, '1')
this.bgmChannel && (this.bgmChannel.volume = 0)
this.effectChannel && (this.effectChannel.volume = 0)
}
cancleMute() {
this.isMute = 0
egret.localStorage.setItem(SoundManager.IS_MUTE_SYMBOL, '0')
this.bgmChannel && (this.bgmChannel.volume = this.bgmVolume)
this.effectChannel && (this.effectChannel.volume = this.effectVolume)
}
setBgmVolume(volume: number) {
this.bgmVolume = volume
this.bgmChannel && !this.isMute && (this.bgmChannel.volume = volume)
}
setEffectVolume(volume: number) {
this.effectVolume = volume
this.effectChannel && !this.isMute && (this.effectChannel.volume = volume)
}
// 默认不允许音效叠加
effectStart(resUrl: string, enableOverlap: boolean = false, cb?: () => void) {
if (!enableOverlap && this.effectChannel) {
this.effectChannel.stop()
}
let ts = Date.now() // 每次播放音效更新一次时间戳
this.curEffectTs = ts
let self = this
let effectSound
if (this.soundCache.effect[resUrl]) {
effectSound = this.soundCache.effect[resUrl]
if (!enableOverlap && ts < self.curEffectTs) {
return
}
self.effectChannel = effectSound.play(0, 1)
self.effectChannel.volume = self.isMute ? 0 : self.effectVolume
effectSound = null
} else {
effectSound = new egret.Sound()
effectSound.addEventListener(egret.Event.COMPLETE, function () {
console.log(`${resUrl} 加载成功`)
/**
* 可能在加载期间,又调用了 bgmStart
* 应用闭包来判断时效性
*/
if (!enableOverlap && ts < self.curEffectTs) {
return
}
self.soundCache.effect[resUrl] = effectSound
self.effectChannel = effectSound.play(0, 1)
self.effectChannel.volume = self.isMute ? 0 : self.effectVolume
self.effectChannel.addEventListener(egret.Event.SOUND_COMPLETE, function () {
if (ts === self.curEffectTs) {
self.effectChannel = null
effectSound = null
}
}, this)
}, this)
effectSound.addEventListener(egret.IOErrorEvent.IO_ERROR, function () {
console.error(`${resUrl} 加载出错`)
effectSound = null
self.effectChannel = null
}, this)
effectSound.load(resUrl)
}
}
bgmStart(resUrl: string, loop: number = 0) {
// 停掉旧的
this.bgmStop()
// 开始新的
let self = this
let bgmSound
if (this.soundCache.bgm[resUrl]) {
bgmSound = this.soundCache.bgm[resUrl]
this.bgmSound = bgmSound
self.bgmChannel = self.bgmSound.play(0, loop)
self.bgmChannel.volume = self.isMute ? 0 : self.bgmVolume
bgmSound = null
} else {
bgmSound = new egret.Sound()
this.bgmSound = bgmSound
this.bgmSound.addEventListener(egret.Event.COMPLETE, function () {
console.log(`${resUrl} 加载成功`)
// 可能在加载期间,又调用了 bgmStart
if (self.bgmSound !== bgmSound) {
return
}
self.soundCache.bgm[resUrl] = bgmSound
bgmSound = null
self.bgmChannel = self.bgmSound.play(0, loop)
self.bgmChannel.volume = self.isMute ? 0 : self.bgmVolume
}, this)
this.bgmSound.addEventListener(egret.IOErrorEvent.IO_ERROR, function () {
console.error(`${resUrl} 加载失败`)
// 可能在加载期间,又调用了 bgmStart
if (self.bgmSound !== bgmSound) {
return
}
self.bgmSound = null
}, this)
this.bgmSound.load(resUrl)
}
}
bgmPause() {
if (!this.bgmChannel) {
return
}
// 已暂停,直接退出
if (this.bgmPausePosition) {
return
}
this.bgmPausePosition = this.bgmChannel.position
this.bgmChannel.stop()
}
bgmResume(loop: number = 0) {
if (!this.bgmChannel) {
return
}
if (!this.bgmPausePosition) {
return
}
let bgmSound = this.bgmSound
this.bgmChannel = this.bgmSound.play(this.bgmPausePosition, 1)
this.bgmPausePosition = 0
let self = this
this.bgmChannel.addEventListener(egret.Event.SOUND_COMPLETE, function () {
if (self.bgmSound && bgmSound === self.bgmSound) {
self.bgmChannel = self.bgmSound.play(0, loop)
}
bgmSound = null
}, this)
}
bgmStop() {
if (!this.bgmChannel) {
return
}
this.bgmSound = null
this.bgmChannel.stop()
this.bgmChannel = null
this.bgmPausePosition = 0
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.