背景音乐的速度和音调

This commit is contained in:
ckcz123 2021-07-24 19:54:36 +08:00
parent 37bde1701f
commit ead6e596f7
9 changed files with 122 additions and 33 deletions

View File

@ -478,8 +478,12 @@ playBgm: fn(bgm: string, startTime?: number)
bgm: 背景音乐的文件名,支持全塔属性中映射前的中文名 bgm: 背景音乐的文件名,支持全塔属性中映射前的中文名
startTime: 跳过前多少秒,不填则不跳过 startTime: 跳过前多少秒,不填则不跳过
playSound: fn(sound: string) playSound: fn(sound: string, pitch?: number, callback?: fn()) -> number
播放一个音效 播放一个音效
sound: 音效名;可以使用文件别名。
pitch: 播放的音调可选如果设置则为30-300之间的数值100为正常音调。
callback: 可选,播放完毕后执行的回调函数。
返回一个数字可用于core.stopSound的参数来只停止该音效。
registerAnimationFrame: fn(name: string, needPlaying: bool, func?: fn(timestamp: number)) registerAnimationFrame: fn(name: string, needPlaying: bool, func?: fn(timestamp: number))
注册一个 animationFrame 注册一个 animationFrame
@ -550,6 +554,11 @@ destX: 鼠标或手指的起拖点横坐标
destY: 鼠标或手指的起拖点纵坐标 destY: 鼠标或手指的起拖点纵坐标
stepPostfix: 拖动轨迹的数组表示,每项为一步的方向和目标点。 stepPostfix: 拖动轨迹的数组表示,每项为一步的方向和目标点。
setBgmSpeed: fn(speed: number, usePitch?: bool)
设置背景音乐的播放速度和音调
speed: 播放速度必须为30-300中间的值。100为正常速度。
usePitch: 是否同时改变音调(部分设备可能不支持)
setBuff: fn(name: string, value: number) setBuff: fn(name: string, value: number)
设置主角某个属性的百分比修正倍率初始值为1 设置主角某个属性的百分比修正倍率初始值为1
倍率存放在flag: '__'+name+'_buff__' 中 倍率存放在flag: '__'+name+'_buff__' 中
@ -640,8 +649,8 @@ stopAutomaticRoute: fn()
stopReplay: fn(force?: bool) stopReplay: fn(force?: bool)
停止播放 停止播放
stopSound: fn() stopSound: fn(id?: number)
停止所有SE 停止播放音效。如果未指定id则停止所有音效否则只停止指定的音效。
syncLoad: fn() syncLoad: fn()
从服务器加载存档 从服务器加载存档

View File

@ -2189,12 +2189,12 @@ var terndefs_f6783a0a_522d_417e_8407_94c67b692e50 = [
"!type": "fn(name: string, value: ?)" "!type": "fn(name: string, value: ?)"
}, },
"playSound": { "playSound": {
"!doc": "播放一个音效", "!doc": "播放一个音效<br/>sound: 音效名;可以使用文件别名。<br/>pitch: 播放的音调可选如果设置则为30-300之间的数值。<br/>callback: 可选,播放完毕后执行的回调函数。<br/>返回一个数字可用于core.stopSound的参数来只停止该音效。",
"!type": "fn(sound: string)" "!type": "fn(sound: string, pitch?: number, callback?: fn()) -> number"
}, },
"stopSound": { "stopSound": {
"!doc": "停止所有SE", "!doc": "停止播放音效。如果未指定id则停止所有音效否则只停止指定的音效。",
"!type": "fn()" "!type": "fn(id?: number)"
}, },
"addGameCanvasTranslate": { "addGameCanvasTranslate": {
"!doc": "加减画布偏移", "!doc": "加减画布偏移",

View File

@ -823,6 +823,7 @@ action
| playSound_1_s | playSound_1_s
| stopSound_s | stopSound_s
| setVolume_s | setVolume_s
| setBgmSpeed_s
| win_s | win_s
| lose_s | lose_s
| restart_s | restart_s
@ -2462,32 +2463,42 @@ return code;
*/; */;
playSound_s playSound_s
: '播放音效' EvalString '停止之前音效' Bool? Newline : '播放音效' EvalString '停止之前音效' Bool? '音调' IntString? '等待播放完毕' Bool? Newline
/* playSound_s /* playSound_s
tooltip : playSound: 播放音效 tooltip : playSound: 播放音效
helpUrl : /_docs/#/instruction helpUrl : /_docs/#/instruction
default : ["item.mp3",false] default : ["item.mp3",false,"",false]
colour : this.soundColor colour : this.soundColor
allSounds : ['EvalString_0'] allSounds : ['EvalString_0']
material : ["./project/sounds/", "EvalString_0"] material : ["./project/sounds/", "EvalString_0"]
if (IntString_0) {
if (parseInt(IntString_0) < 30 || parseInt(IntString_0) > 300) throw '音调设置只能在30-300之间100为正常音调。';
IntString_0 = ', "pitch": ' + IntString_0;
} else IntString_0 = '';
Bool_0 = Bool_0 ? ', "stop": true' : ''; Bool_0 = Bool_0 ? ', "stop": true' : '';
var code = '{"type": "playSound", "name": "'+EvalString_0+'"'+Bool_0+'},\n'; Bool_1 = Bool_1 ? ', "sync": true' : '';
var code = '{"type": "playSound", "name": "'+EvalString_0+'"'+Bool_0+IntString_0+Bool_1+'},\n';
return code; return code;
*/; */;
playSound_1_s playSound_1_s
: '播放系统音效' NameMap_List '停止之前音效' Bool? Newline : '播放系统音效' NameMap_List '停止之前音效' Bool? '音调' IntString? '等待播放完毕' Bool? Newline
/* playSound_1_s /* playSound_1_s
tooltip : playSound: 播放系统音效 tooltip : playSound: 播放系统音效
helpUrl : /_docs/#/instruction helpUrl : /_docs/#/instruction
default : ["确认",false] default : ["确认",false,"",false]
colour : this.soundColor colour : this.soundColor
if (IntString_0) {
if (parseInt(IntString_0) < 30 || parseInt(IntString_0) > 300) throw '音调设置只能在30-300之间100为正常音调。';
IntString_0 = ', "pitch": ' + IntString_0;
} else IntString_0 = '';
Bool_0 = Bool_0 ? ', "stop": true' : ''; Bool_0 = Bool_0 ? ', "stop": true' : '';
var code = '{"type": "playSound", "name": "'+NameMap_List_0+'"'+Bool_0+'},\n'; Bool_1 = Bool_1 ? ', "sync": true' : '';
var code = '{"type": "playSound", "name": "'+NameMap_List_0+'"'+Bool_0+IntString_0+Bool_1+'},\n';
return code; return code;
*/; */;
@ -2518,6 +2529,21 @@ var code = '{"type": "setVolume", "value": '+Int_0+IntString_0+async+'},\n';
return code; return code;
*/; */;
setBgmSpeed_s
: '设置背景音乐播放速度' Int '同时改变音调' Bool Newline
/* setBgmSpeed_s
tooltip : setSpeed: 设置背景音乐播放速度
helpUrl : /_docs/#/instruction
default : [100, true]
colour : this.soundColor
if (Int_0 < 30 || Int_0 > 300) throw '速度只能设置只能在30-300之间100为正常速度。';
Bool_0 = Bool_0?', "pitch": true':'';
var code = '{"type": "setBgmSpeed", "value": '+Int_0+Bool_0+'},\n';
return code;
*/;
win_s win_s
: '游戏胜利,结局' ':' EvalString? '不计入榜单' Bool '不结束游戏' Bool Newline : '游戏胜利,结局' ':' EvalString? '不计入榜单' Bool '不结束游戏' Bool Newline

View File

@ -642,10 +642,10 @@ ActionParser.prototype.parseAction = function() {
var knownItems = MotaActionBlocks['NameMap_List'].options.map(function (one) {return one[1];}); var knownItems = MotaActionBlocks['NameMap_List'].options.map(function (one) {return one[1];});
if (knownItems.indexOf(data.name) >= 0) { if (knownItems.indexOf(data.name) >= 0) {
this.next = MotaActionBlocks['playSound_1_s'].xmlText([ this.next = MotaActionBlocks['playSound_1_s'].xmlText([
data.name,data.stop,this.next]); data.name,data.stop,data.pitch||"",data.sync,this.next]);
} else { } else {
this.next = MotaActionBlocks['playSound_s'].xmlText([ this.next = MotaActionBlocks['playSound_s'].xmlText([
data.name,data.stop,this.next]); data.name,data.stop,data.pitch||"",data.sync,this.next]);
} }
break; break;
case "playBgm": case "playBgm":
@ -676,6 +676,10 @@ ActionParser.prototype.parseAction = function() {
this.next = MotaActionBlocks['setVolume_s'].xmlText([ this.next = MotaActionBlocks['setVolume_s'].xmlText([
data.value, data.time, data.async||false, this.next]); data.value, data.time, data.async||false, this.next]);
break break
case "setBgmSpeed":
this.next = MotaActionBlocks['setBgmSpeed_s'].xmlText([
data.value, data.pitch||false, this.next]);
break;
case "setValue": case "setValue":
this.next = MotaActionBlocks['setValue_s'].xmlText([ this.next = MotaActionBlocks['setValue_s'].xmlText([
this.expandIdBlock([data.name]), data["operator"]||'=', this.expandIdBlock([data.name]), data["operator"]||'=',

View File

@ -213,6 +213,7 @@ editor_blocklyconfig=(function(){
MotaActionBlocks['playSound_1_s'].xmlText(), MotaActionBlocks['playSound_1_s'].xmlText(),
MotaActionBlocks['stopSound_s'].xmlText(), MotaActionBlocks['stopSound_s'].xmlText(),
MotaActionBlocks['setVolume_s'].xmlText(), MotaActionBlocks['setVolume_s'].xmlText(),
MotaActionBlocks['setBgmSpeed_s'].xmlText(),
MotaActionBlocks['callBook_s'].xmlText(), MotaActionBlocks['callBook_s'].xmlText(),
MotaActionBlocks['callSave_s'].xmlText(), MotaActionBlocks['callSave_s'].xmlText(),
MotaActionBlocks['autoSave_s'].xmlText(), MotaActionBlocks['autoSave_s'].xmlText(),

View File

@ -2695,6 +2695,25 @@ control.prototype._playBgm_play = function (bgm, startTime) {
core.material.bgms[bgm].play(); core.material.bgms[bgm].play();
core.musicStatus.playingBgm = bgm; core.musicStatus.playingBgm = bgm;
core.musicStatus.lastBgm = bgm; core.musicStatus.lastBgm = bgm;
core.setBgmSpeed(100);
}
///// 设置当前背景音乐的播放速度 //////
control.prototype.setBgmSpeed = function (speed, usePitch) {
var bgm = core.musicStatus.playingBgm;
if (main.mode!='play' || !core.material.bgms[bgm]) return;
bgm = core.material.bgms[bgm];
if (speed < 30 || speed > 300) return;
bgm.playbackRate = speed / 100;
core.musicStatus.bgmSpeed = speed;
if (bgm.preservesPitch != null) {
if (bgm.__preservesPitch == null) bgm.__preservesPitch = bgm.preservesPitch;
if (usePitch == null) bgm.preservesPitch = bgm.__preservesPitch;
else if (usePitch) bgm.preservesPitch = false;
else bgm.preservesPitch = true;
core.musicStatus.bgmUsePitch = usePitch;
}
} }
////// 暂停背景音乐的播放 ////// ////// 暂停背景音乐的播放 //////
@ -2718,8 +2737,13 @@ control.prototype.pauseBgm = function () {
control.prototype.resumeBgm = function (resumeTime) { control.prototype.resumeBgm = function (resumeTime) {
if (main.mode!='play')return; if (main.mode!='play')return;
try { try {
var speed = core.musicStatus.bgmSpeed;
var usePitch = core.musicStatus.bgmUsePitch;
core.playBgm(core.musicStatus.playingBgm || core.musicStatus.lastBgm || main.startBgm, core.playBgm(core.musicStatus.playingBgm || core.musicStatus.lastBgm || main.startBgm,
resumeTime ? core.musicStatus.pauseTime : 0); resumeTime ? core.musicStatus.pauseTime : 0);
if (resumeTime) {
core.setBgmSpeed(speed, usePitch);
}
} }
catch (e) { catch (e) {
console.log("无法恢复BGM"); console.log("无法恢复BGM");
@ -2748,7 +2772,7 @@ control.prototype.triggerBgm = function () {
} }
////// 播放音频 ////// ////// 播放音频 //////
control.prototype.playSound = function (sound) { control.prototype.playSound = function (sound, pitch, callback) {
sound = core.getMappedName(sound); sound = core.getMappedName(sound);
if (main.mode!='play' || !core.musicStatus.soundStatus || !core.material.sounds[sound]) return; if (main.mode!='play' || !core.musicStatus.soundStatus || !core.material.sounds[sound]) return;
try { try {
@ -2757,16 +2781,22 @@ control.prototype.playSound = function (sound) {
source.buffer = core.material.sounds[sound]; source.buffer = core.material.sounds[sound];
source.connect(core.musicStatus.gainNode); source.connect(core.musicStatus.gainNode);
var id = setTimeout(null); var id = setTimeout(null);
if (pitch && pitch >= 30 && pitch <= 300) {
source.playbackRate.setValueAtTime(pitch / 100, 0);
}
source.onended = function () { source.onended = function () {
delete core.musicStatus.playingSounds[id]; delete core.musicStatus.playingSounds[id];
if (callback) callback();
} }
core.musicStatus.playingSounds[id] = source;
if (source.start) source.start(0); if (source.start) source.start(0);
else if (source.noteOn) source.noteOn(0); else if (source.noteOn) source.noteOn(0);
core.musicStatus.playingSounds[id] = source; return id;
} }
else { else {
core.material.sounds[sound].volume = core.musicStatus.userVolume; core.material.sounds[sound].volume = core.musicStatus.userVolume;
core.material.sounds[sound].play(); core.material.sounds[sound].play();
if (callback) callback();
} }
} }
catch (e) { catch (e) {
@ -2776,18 +2806,23 @@ control.prototype.playSound = function (sound) {
} }
////// 停止所有音频 ////// ////// 停止所有音频 //////
control.prototype.stopSound = function () { control.prototype.stopSound = function (id) {
for (var i in core.musicStatus.playingSounds) { if (id == null) {
var source = core.musicStatus.playingSounds[i]; Object.keys(core.musicStatus.playingSounds).forEach(function (id) {
try { core.control.stopSound(id);
if (source.stop) source.stop(); });
else if (source.noteOff) source.noteOff(); return;
}
catch (e) {
main.log(e);
}
} }
core.musicStatus.playingSounds = {}; var source = core.musicStatus.playingSounds[id];
if (!source) return;
try {
if (source.stop) source.stop();
else if (source.noteOff) source.noteOff();
}
catch (e) {
main.log(e);
}
delete core.musicStatus.playingSounds[id];
} }
////// 检查bgm状态 ////// ////// 检查bgm状态 //////

View File

@ -64,6 +64,8 @@ function core() {
'playingSounds': {}, // 正在播放的SE 'playingSounds': {}, // 正在播放的SE
'userVolume': 1.0, // 用户音量 'userVolume': 1.0, // 用户音量
'designVolume': 1.0, //设计音量 'designVolume': 1.0, //设计音量
'bgmSpeed': 100, // 背景音乐速度
'bgmUsePitch': null, // 是否同时修改音调
'cachedBgms': [], // 缓存BGM内容 'cachedBgms': [], // 缓存BGM内容
'cachedBgmCount': 8, // 缓存的bgm数量 'cachedBgmCount': 8, // 缓存的bgm数量
} }

View File

@ -1722,8 +1722,12 @@ events.prototype._action_freeBgm = function (data, x, y, prefix) {
events.prototype._action_playSound = function (data, x, y, prefix) { events.prototype._action_playSound = function (data, x, y, prefix) {
if (data.stop) core.stopSound(); if (data.stop) core.stopSound();
core.playSound(data.name); if (data.sync) {
core.doAction(); core.playSound(data.name, data.pitch, core.doAction);
} else {
core.playSound(data.name, data.pitch);
core.doAction();
}
} }
events.prototype._action_stopSound = function (data, x, y, prefix) { events.prototype._action_stopSound = function (data, x, y, prefix) {
@ -1737,6 +1741,11 @@ events.prototype._action_setVolume = function (data, x, y, prefix) {
this.__action_doAsyncFunc(data.async, core.setVolume, data.value, data.time || 0); this.__action_doAsyncFunc(data.async, core.setVolume, data.value, data.time || 0);
} }
events.prototype._action_setBgmSpeed = function (data, x, y, prefix) {
core.setBgmSpeed(data.value, data.pitch || false);
core.doAction();
}
events.prototype._action_setValue = function (data, x, y, prefix) { events.prototype._action_setValue = function (data, x, y, prefix) {
this.setValue(data.name, data.operator, data.value, prefix); this.setValue(data.name, data.operator, data.value, prefix);
if (!data.norefresh) { if (!data.norefresh) {

9
runtime.d.ts vendored
View File

@ -774,6 +774,9 @@ declare class control {
/** 恢复背景音乐的播放 */ /** 恢复背景音乐的播放 */
resumeBgm(resumeTime?: number): void resumeBgm(resumeTime?: number): void
/** 设置背景音乐的播放速度和音调 */
setBgmSpeed(speed: number, usePitch?: bool): void
/** 设置音乐图标的显隐状态 */ /** 设置音乐图标的显隐状态 */
setMusicBtn(): void setMusicBtn(): void
@ -781,10 +784,10 @@ declare class control {
triggerBgm(): void triggerBgm(): void
/** 播放一个音效 */ /** 播放一个音效 */
playSound(sound: string): void playSound(sound: string, pitch?: number, callback?: () => any): number
/** 停止所有音频 */ /** 停止所有音频 */
stopSound(): void stopSound(id?: number): void
/** 检查bgm状态 */ /** 检查bgm状态 */
checkBgm(): void checkBgm(): void