LuaSoundManager = LuaSoundManager or BaseClass() local LuaSoundManager = LuaSoundManager local soundMgr = soundMgr local math_random = math.random LuaSoundManager.SOUND_TYPE = { SKILL = 1, UI = 2, ROLE = 3, FUNC = 4, NPC = 5, SCENE = 6, DROP = 7, GOD = 8, STORY = 9, GUIDE = 10, } LuaSoundManager.SOUND_PRE = { [1] = "sound_skill", [2] = "sound_ui", [3] = "sound_role", [4] = "sound_func", [5] = "sound_npc_", [6] = "sound_scene_", [7] = "sound_drop", [8] = "sound_god", [9] = "sound_story_", [10] = "sound_guide", } LuaSoundManager.SOUND_UI = { NONE = 9000,--不需要声音 OPEN = 9001,--开界面 CLOSE = 9002,--关界面 CLICK = 9003,--点击 SWITCH = 9003,--暂时没有区分音效和点击 FAULT = 9004,--报错、无效操作、物品不足等 AWARD = 9005,--打开宝箱 DICE = 9006,--掷骰子 SUCCESS = 9007,--升阶、分解、合成等操作成功(获得物品或其他数值奖励) UPGRADE = 9008, --完成任务 LEVELUP = 9009, --升级 EXPBULLETSHOT1 = 9010, -- 经验副本 霰射音效1 EXPBULLETSHOT2 = 9011, -- 经验副本 霰射音效2 EXPBULLETLASER = 9012, -- 经验副本 激光音效 } function LuaSoundManager:__init() LuaSoundManager.Instance = self self.last_backgound_abName = nil self.current_scene_sound="" self.mute_request = {} self.sound_effect_time_list = {} --记录音效播放时间,cd控制用 GlobalEventSystem:Bind(EventName.CHANGE_ACCOUNT, function() self:Reset() end) GlobalEventSystem:Bind(EventName.CHANGE_ROLE, function() self:Reset() end) self:InitVolumeCache() self:InitEvent() end function LuaSoundManager:InitEvent( ) local function play_ui_effect( use_sound) self:PlayUIEffectSound(use_sound) end GlobalEventSystem:Bind(EventName.PLAY_UI_EFFECT_SOUND,play_ui_effect) end function LuaSoundManager:Reset() self.mute_request = {} end function LuaSoundManager:getInstance() if LuaSoundManager.Instance == nil then LuaSoundManager.New() end return LuaSoundManager.Instance end function LuaSoundManager:PlayLoginSound(sound_id, volume) if self.volume_cache_value and self.volume_cache_value <= 0 then return end local sound_type = LuaSoundManager.SOUND_TYPE.SCENE local ab_name = LuaSoundManager.SOUND_PRE[sound_type] .. tostring(sound_id) if self.last_backgound_abName and self.last_backgound_abName == ab_name then if volume then self:ChangeVolume(volume) end return end if self:StopBacksound() then self.last_backgound_abName = ab_name local back_ground_vol = volume or Config.ConfigSound.DefaultSceneVolume soundMgr:PlayBacksound(ab_name,tostring(sound_id),back_ground_vol) end end --播放场景音乐 function LuaSoundManager:PlayBackground(scene_id, need_random) if self.volume_cache_value and self.volume_cache_value <= 0 then return end local scene_sound = Config.ConfigSound.DefaultScene local sound_cfg = Config.ConfigSound.Scene[scene_id] if sound_cfg then if #sound_cfg > 1 and need_random then local index = math_random(1, #sound_cfg) scene_sound = sound_cfg[index] else scene_sound = sound_cfg[1] end elseif ConfigItemMgr.Instance:GetSceneItem(scene_id) then local scene_type = ConfigItemMgr.Instance:GetSceneItem(scene_id).type if Config.ConfigSound.DefaultSceneType[scene_type] then scene_sound = Config.ConfigSound.DefaultSceneType[scene_type] end end self.current_scene_sound = scene_sound local back_ground_vol =nil if Config.ConfigSound.DefaultSceneTypeVolume[self.current_scene_sound] then back_ground_vol = Config.ConfigSound.DefaultSceneTypeVolume[self.current_scene_sound] else back_ground_vol = Config.ConfigSound.DefaultSceneVolume end local sound_type = LuaSoundManager.SOUND_TYPE.SCENE local ab_name = LuaSoundManager.SOUND_PRE[sound_type] .. tostring(scene_sound) local setting_music_vol = self.cookieSetting.sound * 0.01 self.cur_backgound_abName = ab_name self.cur_backgound_vol = back_ground_vol and back_ground_vol * setting_music_vol or setting_music_vol self.cur_scene_sound = scene_sound --首次的话直接播放 if not self.last_backgound_abName then soundMgr:PlayBacksound(self.cur_backgound_abName,tostring(self.cur_scene_sound),back_ground_vol) return end --渐变过渡 if self.last_backgound_abName ~= ab_name then local cur_vol = soundMgr.volume local function fadeOut() cur_vol = cur_vol - 0.02 if cur_vol < 0.1 then cur_vol = 0.1 end -- print("fadeOut ",cur_vol) self:ChangeVolume(cur_vol) if cur_vol <= 0.1 then self.last_backgound_vol = 0 -- print("播放音乐 ",self.cur_backgound_abName,self.cur_scene_sound,self.cur_backgound_vol) self:StopBacksound() soundMgr:PlayBacksound(self.cur_backgound_abName,tostring(self.cur_scene_sound),back_ground_vol) local function fadeIn() self.last_backgound_vol = self.last_backgound_vol + 0.01 local targetVol = self.cur_backgound_vol if self.last_backgound_vol >= targetVol then self.last_backgound_vol = targetVol end self:ChangeVolume(self.last_backgound_vol) -- print("fadeIn ",self.last_backgound_vol) if self.last_backgound_vol >= targetVol then GlobalTimerQuest:CancelQuest(self.fade_in_id) self.fade_in_id = nil self.last_backgound_abName = self.cur_backgound_abName self.last_backgound_vol = targetVol end end local function delay() if not self.fade_in_id then self.fade_in_id = GlobalTimerQuest:AddPeriodQuest(fadeIn,0.02,-1) end end setTimeout(delay,0.5) --假装等待加载 GlobalTimerQuest:CancelQuest(self.fade_out_id) self.fade_out_id = nil end end if not self.fade_out_id then self.fade_out_id = GlobalTimerQuest:AddPeriodQuest(fadeOut,0.02,-1) end end end function LuaSoundManager:PlayBackgroundSound(sound_name, sound_type, force) if sound_name == self.current_scene_sound and not force then return end if self.volume_effect_cache_value and self.volume_effect_cache_value <= 0 then return end self.current_scene_sound = sound_name local back_ground_vol =nil if Config.ConfigSound.DefaultSceneTypeVolume[self.current_scene_sound] then back_ground_vol = Config.ConfigSound.DefaultSceneTypeVolume[self.current_scene_sound] else back_ground_vol = Config.ConfigSound.DefaultSceneVolume end local ab_name = LuaSoundManager.SOUND_PRE[sound_type]..tostring(sound_name) local setting_music_vol = self.cookieSetting.sound * 0.01 self.cur_backgound_abName = ab_name self.cur_backgound_vol = back_ground_vol and back_ground_vol * setting_music_vol or setting_music_vol --首次的话直接播放 if not self.last_backgound_abName then soundMgr:PlayBacksound(self.cur_backgound_abName,tostring(sound_name),back_ground_vol) return end --渐变过渡 if self.last_backgound_abName ~= ab_name or force then local cur_vol = soundMgr.volume local function fadeOut() cur_vol = cur_vol - 0.02 if cur_vol < 0.1 then cur_vol = 0.1 end self:ChangeVolume(cur_vol) if cur_vol <= 0.1 then self.last_backgound_vol = 0 self:StopBacksound() soundMgr:PlayBacksound(self.cur_backgound_abName,sound_name,back_ground_vol) local function fadeIn() self.last_backgound_vol = self.last_backgound_vol + 0.01 local targetVol = self.cur_backgound_vol if self.last_backgound_vol >= targetVol then self.last_backgound_vol = targetVol end self:ChangeVolume(self.last_backgound_vol) if self.last_backgound_vol >= targetVol then GlobalTimerQuest:CancelQuest(self.fade_in_id) self.fade_in_id = nil self.last_backgound_abName = self.cur_backgound_abName self.last_backgound_vol = targetVol end end local function delay() if not self.fade_in_id then self.fade_in_id = GlobalTimerQuest:AddPeriodQuest(fadeIn,0.02,-1) end end setTimeout(delay,0.5) --假装等待加载 GlobalTimerQuest:CancelQuest(self.fade_out_id) self.fade_out_id = nil end end if not self.fade_out_id then self.fade_out_id = GlobalTimerQuest:AddPeriodQuest(fadeOut,0.02,-1) end end end --继续播放背景音乐 function LuaSoundManager:ContinueBacksound() soundMgr:ContinueBacksound() end --暂停背景音乐 function LuaSoundManager:PauseBacksound() soundMgr:PauseBacksound() end --停止背景音乐 function LuaSoundManager:StopBacksound() if self.last_backgound_abName then soundMgr:StopBacksound() resMgr:UnloadAssetBundle(self.last_backgound_abName, true, 1) end return true end --播放指定音效 function LuaSoundManager:PlayEffect(ref_tar, path, is_loop, sound_type, vol_modulus, speed) if not path then return end --首次登陆还未进入游戏,协议返回的成功失败等消息不要有声音 if RoleController and RoleController.Instance then if not RoleController.Instance.is_load_and_enter_finished then if path == "award" or path == "success" or path == "upgrade" or path == "fault" then return end end end if self.volume_effect_cache_value and self.volume_effect_cache_value < 0.01 then return path end local res_name = path local ab_name = LuaSoundManager.SOUND_PRE[sound_type] if sound_type == LuaSoundManager.SOUND_TYPE.NPC or sound_type == LuaSoundManager.SOUND_TYPE.STORY then --NPC音效变成了单独打包 ab_name = LuaSoundManager.SOUND_PRE[sound_type]..tostring(res_name) end if not vol_modulus then if Config.ConfigSound.SoundEffect[sound_type] then if Config.ConfigSound.SoundEffect[sound_type][path] then vol_modulus = Config.ConfigSound.SoundEffect[sound_type][path] else vol_modulus = Config.ConfigSound.DefaultSoundEffectTypeVolume[sound_type] end else vol_modulus = Config.ConfigSound.DefaultSoundEffectVolume end end self.sound_effect_time_list[path] = Time.time local effect_id = lua_resM:loadSound(ref_tar, ab_name, tostring(res_name), is_loop,vol_modulus, speed) return effect_id or path end --停止指定音效 function LuaSoundManager:StopEffect(ref_tar, sound_type, effect_id) local ab_name = LuaSoundManager.SOUND_PRE[sound_type] lua_resM:stopSound(ref_tar, ab_name, effect_id) end --加载语音 function LuaSoundManager:LoadVoice(path, callback) soundMgr:LoadVoice(path, callback) end --初始化音量值 function LuaSoundManager:InitVolumeCache( ) self.volume_cache_value = soundMgr.volume self.volume_effect_cache_value = soundMgr.volumeEffect self.last_volume_cache_value = self.volume_cache_value end --改变声音音量大小 function LuaSoundManager:ChangeVolume(value) soundMgr.volume = value self.volume_cache_value = value if self.last_volume_cache_value and self.last_volume_cache_value <= 0 and value and value > 0 then --播放场景背景音乐 self.last_backgound_abName = false local cur_scene = SceneManager:getInstance():GetSceneId() self:PlayBackground(cur_scene) end self.last_volume_cache_value = value end --改变音效音量大小 function LuaSoundManager:ChangeVolumeEffect(value) self.volume_effect_cache_value = value soundMgr.volumeEffect = value end --是否音效静音 function LuaSoundManager:IsEffectMute( ) if self.volume_effect_cache_value and self.volume_effect_cache_value <= 0.1 then return true else return false end end --开关背景音乐 function LuaSoundManager:SwitchMusicState(open) soundMgr.musicSwitch = open end --开关音效 function LuaSoundManager:SwitchEffectState(open) soundMgr.effectSwitch = open end --添加静音请求 function LuaSoundManager:AddMuteQuest(obj) if not soundMgr.musicSwitch then soundMgr.musicSwitch = false end if not soundMgr.effectSwitch then soundMgr.effectSwitch = false end self.mute_request[obj] = true if RuntimePlatform and SystemRuntimePlatform.IsIphone() then self.ios_last_scene_sound = self.current_scene_sound self:PauseBacksound() end end --移除静音请求 function LuaSoundManager:CancelMuteQuest(obj) self.mute_request[obj] = nil if TableSize(self.mute_request) == 0 then if soundMgr.musicSwitch then soundMgr.musicSwitch = true end if soundMgr.effectSwitch then soundMgr.effectSwitch = true end end if self.ios_last_scene_sound then self:ContinueBacksound() self.ios_last_scene_sound = nil end end --恢复所有声音 function LuaSoundManager:StartAllVoice() -- soundMgr.volume = 1 self:LoadSetting() end function LuaSoundManager:PlayingSoundEffect(name, cd) -- return soundMgr:PlayingSoundEffect(name) --有gc的开销,先在lua层缓存时间做CD local cd_time = cd or 0.2 if self.sound_effect_time_list and self.sound_effect_time_list[name] then return self.sound_effect_time_list[name] + cd_time > Time.time end end function LuaSoundManager:LoadSetting() -- local cookieSetting = CookieWrapper.Instance:GetCookie(CookieLevelType.Common,CookieKey.SYSTEM_SETTING) -- if cookieSetting then -- soundMgr.musicSwitch = cookieSetting.musicSound -- soundMgr.effectSwitch = cookieSetting.effectSound -- end self.cookieSetting = CookieWrapper.Instance:GetCookie(CookieLevelType.Common,CookieKey.SOUND_SETTING) self.cookieSetting = self.cookieSetting or {sound = Config.ConfigSound.TotalVloume, effectSound = Config.ConfigSound.TotalSoundEffect} if self.cookieSetting then self:ChangeVolume(self.cookieSetting.sound / 100) self:ChangeVolumeEffect(self.cookieSetting.effectSound / 100) end end function LuaSoundManager:CreateAudioClip(voice_data, data_ver, callback) if data_ver <= 29 then return soundMgr:CreateAudioClip(voice_data) elseif data_ver <= 32 then return soundMgr:CreateAudioClipFromCompress(voice_data) else if Application.isMobilePlatform then return soundMgr:CreateAudioClip(voice_data, AppConst.CachedVoicePath.."/tmp.mp3", callback) else return soundMgr:CreateAudioClip(voice_data, AppConst.CachedVoicePath.."/tmp.wav", callback) end end end function LuaSoundManager:PlayUIEffectSound(use_sound) if not use_sound then return end if lua_soundM then if use_sound == LuaSoundManager.SOUND_UI.OPEN and not lua_soundM:PlayingSoundEffect("window_open", 0.7) then self:PlayEffect(self, "window_open",false,LuaSoundManager.SOUND_TYPE.UI) elseif use_sound == LuaSoundManager.SOUND_UI.CLOSE and not lua_soundM:PlayingSoundEffect("window_close", 0.2) then self:PlayEffect(self, "window_close",false,LuaSoundManager.SOUND_TYPE.UI) elseif use_sound == LuaSoundManager.SOUND_UI.SWITCH or use_sound == LuaSoundManager.SOUND_UI.CLICK then self:PlayEffect(self, "click",false,LuaSoundManager.SOUND_TYPE.UI) elseif use_sound == LuaSoundManager.SOUND_UI.FAULT and not lua_soundM:PlayingSoundEffect("fault", 1) then self:PlayEffect(self, "fault",false,LuaSoundManager.SOUND_TYPE.UI) elseif use_sound == LuaSoundManager.SOUND_UI.AWARD and not lua_soundM:PlayingSoundEffect("award", 1.3) then self:PlayEffect(self, "award",false,LuaSoundManager.SOUND_TYPE.UI) elseif use_sound == LuaSoundManager.SOUND_UI.DICE and not lua_soundM:PlayingSoundEffect("dice", 2.6) then self:PlayEffect(self, "dice",false,LuaSoundManager.SOUND_TYPE.UI) elseif use_sound == LuaSoundManager.SOUND_UI.SUCCESS and not lua_soundM:PlayingSoundEffect("success", 0.2) then self:PlayEffect(self, "success",false,LuaSoundManager.SOUND_TYPE.UI) elseif use_sound == LuaSoundManager.SOUND_UI.UPGRADE and not lua_soundM:PlayingSoundEffect("upgrade", 0.1) then self:PlayEffect(self, "upgrade",false,LuaSoundManager.SOUND_TYPE.ROLE, 1) elseif use_sound == LuaSoundManager.SOUND_UI.LEVELUP and not lua_soundM:PlayingSoundEffect("levelup", 0.2) then self:PlayEffect(self, "levelup",false,LuaSoundManager.SOUND_TYPE.ROLE, 1, 1, true) elseif use_sound == LuaSoundManager.SOUND_UI.EXPBULLETSHOT1 and not lua_soundM:PlayingSoundEffect("exp_bullet_shot1", 0.6) then self:PlayEffect(self, "exp_bullet_shot1",false,LuaSoundManager.SOUND_TYPE.UI, 1, 1, true) elseif use_sound == LuaSoundManager.SOUND_UI.EXPBULLETSHOT2 and not lua_soundM:PlayingSoundEffect("exp_bullet_shot2", 0.6) then self:PlayEffect(self, "exp_bullet_shot2",false,LuaSoundManager.SOUND_TYPE.UI, 1, 1, true) elseif use_sound == LuaSoundManager.SOUND_UI.EXPBULLETLASER and not lua_soundM:PlayingSoundEffect("exp_bullet_laser", 0.6) then self:PlayEffect(self, "exp_bullet_laser",false,LuaSoundManager.SOUND_TYPE.UI, 1, 1, true) end end end function LuaSoundManager:PlayDungeonResultSound( is_win ) local career = RoleManager.Instance.mainRoleInfo.career or 1 local prefix = is_win and "victor_" or "fail_" local suffix = is_win and math_random(1,2) or 1 local res_name = prefix .. career*1000 .. "_" .. suffix self:PlayEffect(self, res_name, false, LuaSoundManager.SOUND_TYPE.ROLE, 1) end