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.