From 82490f352be392b93ca0e1fe52131ddfcae59adb Mon Sep 17 00:00:00 2001 From: oc Date: Mon, 17 Dec 2018 00:31:43 +0800 Subject: [PATCH] Cache bgms --- _server/blockly/MotaAction.g4 | 36 ++++++++++++++++++++++++++++++ _server/editor_blockly.js | 2 ++ docs/element.md | 8 +++++++ docs/event.md | 14 ++++++++++++ libs/control.js | 2 ++ libs/core.js | 12 ++++++++++ libs/events.js | 8 +++++++ libs/loader.js | 42 ++++++++++++++++++++++++++++++----- 8 files changed, 118 insertions(+), 6 deletions(-) diff --git a/_server/blockly/MotaAction.g4 b/_server/blockly/MotaAction.g4 index 3fb29c71..c99e1695 100644 --- a/_server/blockly/MotaAction.g4 +++ b/_server/blockly/MotaAction.g4 @@ -278,6 +278,8 @@ action | playBgm_s | pauseBgm_s | resumeBgm_s + | loadBgm_s + | freeBgm_s | playSound_s | setVolume_s | win_s @@ -1282,6 +1284,32 @@ var code = '{"type": "resumeBgm"},\n'; return code; */; +loadBgm_s + : '预加载背景音乐' EvalString Newline + + +/* loadBgm_s +tooltip : loadBgm: 预加载某个背景音乐,之后可以直接播放 +helpUrl : https://h5mota.com/games/template/docs/#/event?id=playbgm%EF%BC%9A%E6%92%AD%E6%94%BE%E8%83%8C%E6%99%AF%E9%9F%B3%E4%B9%90 +default : ["bgm.mp3"] +colour : this.soundColor +var code = '{"type": "loadBgm", "name": "'+EvalString_0+'"},\n'; +return code; +*/; + +freeBgm_s + : '释放背景音乐的缓存' EvalString Newline + + +/* freeBgm_s +tooltip : freeBgm: 释放背景音乐的缓存 +helpUrl : https://h5mota.com/games/template/docs/#/event?id=playbgm%EF%BC%9A%E6%92%AD%E6%94%BE%E8%83%8C%E6%99%AF%E9%9F%B3%E4%B9%90 +default : ["bgm.mp3"] +colour : this.soundColor +var code = '{"type": "freeBgm", "name": "'+EvalString_0+'"},\n'; +return code; +*/; + playSound_s : '播放音效' EvalString Newline @@ -2157,6 +2185,14 @@ ActionParser.prototype.parseAction = function() { this.next = MotaActionBlocks['resumeBgm_s'].xmlText([ this.next]); break + case "loadBgm": + this.next = MotaActionBlocks['loadBgm_s'].xmlText([ + data.name,this.next]); + break + case "freeBgm": + this.next = MotaActionBlocks['freeBgm_s'].xmlText([ + data.name,this.next]); + break case "setVolume": this.next = MotaActionBlocks['setVolume_s'].xmlText([ data.value, data.time||0, data.async||false, this.next]); diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index 15c48840..34e90829 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -144,6 +144,8 @@ editor_blockly = function () { MotaActionBlocks['playBgm_s'].xmlText(), MotaActionBlocks['pauseBgm_s'].xmlText(), MotaActionBlocks['resumeBgm_s'].xmlText(), + MotaActionBlocks['loadBgm_s'].xmlText(), + MotaActionBlocks['freeBgm_s'].xmlText(), MotaActionBlocks['playSound_s'].xmlText(), MotaActionBlocks['setVolume_s'].xmlText(), ], diff --git a/docs/element.md b/docs/element.md index 807cacf4..ebec42ad 100644 --- a/docs/element.md +++ b/docs/element.md @@ -402,6 +402,14 @@ floorId指定的是目标楼层的唯一标识符(ID)。 !> iOS平台以及部分浏览器不支持获得当前网络状态,此时即使在使用Wifi也必须要用户点击“音乐开关”才能播放音乐。 +从V2.5.3开始,可以使用`loadBgm`事件来预加载一个bgm,这样到播放时无需等待,直接播放。 + +同时BGM将使用LRU算法增加缓存机制。默认最多缓存4个BGM(在core.js的musicStatus.cachedBgmCount控制)。 + +系统会自动释放最久未使用的BGM。 + +也可以使用`freeBgm`事件来手动释放一个无需再用的bgm。 + ## 录像 HTML5魔塔一大亮点就是存在录像系统,可以很方便进行录像回放。 diff --git a/docs/event.md b/docs/event.md index 061b97e6..a16a6737 100644 --- a/docs/event.md +++ b/docs/event.md @@ -1217,6 +1217,20 @@ async可选,如果为true则会异步执行(即不等待当前事件执行 使用`{"type": "resumeBgm"}`可以恢复背景音乐的播放。 +### loadBgm:预加载一个背景音乐 + +使用loadBgm可以预加载一个背景音乐。 + +使用方法:`{"type": "loadBgm", "name": "bgm.mp3"}` + +有关BGM播放的详细说明参见[背景音乐](element#背景音乐) + +### freeBgm:释放一个背景音乐的缓存 + +使用freeBgm可以预加载一个背景音乐。 + +使用方法:`{"type": "freeBgm", "name": "bgm.mp3"}` + ### playSound:播放音效 使用playSound可以立刻播放一个音效。 diff --git a/libs/control.js b/libs/control.js index 25bcd17b..f82a8112 100644 --- a/libs/control.js +++ b/libs/control.js @@ -2606,6 +2606,8 @@ control.prototype.playBgm = function (bgm) { } try { + // 缓存BGM + core.loader.loadBgm(bgm); // 如果当前正在播放,且和本BGM相同,直接忽略 if (core.musicStatus.playingBgm == bgm && core.musicStatus.isPlaying) { return; diff --git a/libs/core.js b/libs/core.js index 5c9871d1..86cc2836 100644 --- a/libs/core.js +++ b/libs/core.js @@ -58,6 +58,8 @@ function core() { 'isPlaying': false, 'gainNode': null, 'volume': 1.0, // 音量 + 'cachedBgms': [], // 缓存BGM内容 + 'cachedBgmCount': 4, // 缓存的bgm数量 } this.platform = { 'isOnline': true, // 是否http @@ -1405,6 +1407,16 @@ core.prototype.resumeBgm = function () { core.control.resumeBgm(); } +////// 预加载一个背景音乐 ////// +core.prototype.loadBgm = function (bgm) { + core.loader.loadBgm(bgm); +} + +////// 手动释放一个背景音乐的缓存 ////// +core.prototype.freeBgm = function (bgm) { + core.loader.freeBgm(bgm); +} + ////// 播放音频 ////// core.prototype.playSound = function (sound) { core.control.playSound(sound); diff --git a/libs/events.js b/libs/events.js index 518a5c25..e15818d0 100644 --- a/libs/events.js +++ b/libs/events.js @@ -901,6 +901,14 @@ events.prototype.doAction = function() { core.resumeBgm(); this.doAction(); break + case "loadBgm": + core.loadBgm(data.name); + this.doAction(); + break; + case "freeBgm": + core.freeBgm(data.name); + this.doAction(); + break; case "setVolume": data.value = core.clamp(parseInt(data.value)/100, 0, 1); core.setFlag("__volume__", data.value); diff --git a/libs/loader.js b/libs/loader.js index ff24e929..03b97e4b 100644 --- a/libs/loader.js +++ b/libs/loader.js @@ -208,12 +208,7 @@ loader.prototype.loadMusic = function () { } } else { - var music = new Audio(); - music.preload = 'none'; - if (main.bgmRemote) music.src = main.bgmRemoteRoot+core.firstData.name+'/'+t; - else music.src = 'project/sounds/'+t; - music.loop = 'loop'; - core.material.bgms[t] = music; + core.loader.loadOneMusic(t); } }); @@ -251,3 +246,38 @@ loader.prototype.loadMusic = function () { if (core.musicStatus.startDirectly && core.bgms.length>0) core.playBgm(core.bgms[0]); } + +loader.prototype.loadOneMusic = function (name) { + var music = new Audio(); + music.preload = 'none'; + if (main.bgmRemote) music.src = main.bgmRemoteRoot+core.firstData.name+'/'+t; + else music.src = 'project/sounds/'+name; + music.loop = 'loop'; + core.material.bgms[name] = music; +} + +loader.prototype.freeBgm = function (name) { + if (!core.isset(core.material.bgms[name])) return; + // 从cachedBgms中删除 + core.musicStatus.cachedBgms = core.musicStatus.cachedBgms.filter(function (t) {return t!=name; }); + // 清掉缓存 + core.material.bgms[name].removeAttribute("src"); + core.material.bgms[name].load(); + core.material.bgms[name] = null; + // 三秒后重新加载 + setTimeout(function () { + core.loader.loadOneMusic(name); + }, 3000); +} + +loader.prototype.loadBgm = function (name) { + if (!core.isset(core.material.bgms[name])) return; + // 预加载BGM + core.material.bgms[name].load(); + // 移动到缓存最前方 + core.musicStatus.cachedBgms = core.musicStatus.cachedBgms.filter(function (t) {return t!=name; }); + core.musicStatus.cachedBgms.unshift(name); + if (core.musicStatus.cachedBgms.length > core.musicStatus.cachedBgmCount) { + this.freeBgm(core.musicStatus.cachedBgms.pop()); + } +} \ No newline at end of file