From 77e29f603978b8a9154359da06553c95df285cb9 Mon Sep 17 00:00:00 2001 From: ckcz123 Date: Tue, 5 May 2020 16:26:55 +0800 Subject: [PATCH] =?UTF-8?q?=E6=98=BE=E7=A4=BA=E9=80=89=E6=8B=A9=E9=A1=B9/?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E7=A1=AE=E8=AE=A4=E6=A1=86=E5=8F=AF=E4=BB=A5?= =?UTF-8?q?=E6=8C=87=E5=AE=9A=E8=B6=85=E6=97=B6=E6=97=B6=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _server/MotaAction.g4 | 18 ++++++----- _server/editor_blockly.js | 2 +- libs/actions.js | 3 ++ libs/events.js | 63 +++++++++++++++++++++++++-------------- libs/ui.js | 21 ++++++------- v2.x-final更新.txt | 2 +- 6 files changed, 66 insertions(+), 43 deletions(-) diff --git a/_server/MotaAction.g4 b/_server/MotaAction.g4 index 658d50ba..5079a58e 100644 --- a/_server/MotaAction.g4 +++ b/_server/MotaAction.g4 @@ -1895,13 +1895,13 @@ return code; */; choices_s - : '选项' ':' EvalString? BGNL? '标题' EvalString? '图像' IdString? BGNL? Newline choicesContext+ BEND Newline + : '选项' ':' EvalString? BGNL? '标题' EvalString? '图像' IdString? '超时毫秒数' Int BGNL? Newline choicesContext+ BEND Newline /* choices_s tooltip : choices: 给用户提供选项 helpUrl : https://h5mota.com/games/template/_docs/#/event?id=choices%EF%BC%9A%E7%BB%99%E7%94%A8%E6%88%B7%E6%8F%90%E4%BE%9B%E9%80%89%E9%A1%B9 -default : ["","流浪者","woman"] +default : ["","流浪者","woman",0] var title=''; if (EvalString_1==''){ if (IdString_0=='')title=''; @@ -1912,7 +1912,8 @@ if (EvalString_1==''){ } EvalString_0 = title+EvalString_0; EvalString_0 = EvalString_0 ?(', "text": "'+EvalString_0+'"'):''; -var code = ['{"type": "choices"',EvalString_0,', "choices": [\n', +Int_0 = Int_0 ? (', "timeout": '+Int_0) : ''; +var code = ['{"type": "choices"',EvalString_0,Int_0,', "choices": [\n', choicesContext_0, ']},\n'].join(''); return code; @@ -1941,14 +1942,15 @@ return code; */; confirm_s - : '显示确认框' ':' EvalString BGNL? '确定的场合' ':' '(默认选中' Bool ')' BGNL? Newline action+ '取消的场合' ':' BGNL? Newline action+ BEND Newline + : '显示确认框' ':' EvalString '超时毫秒数' Int BGNL? '确定的场合' ':' '(默认选中' Bool ')' BGNL? Newline action+ '取消的场合' ':' BGNL? Newline action+ BEND Newline /* confirm_s tooltip : 弹出确认框 helpUrl : https://h5mota.com/games/template/_docs/#/ -default : ["确认要xxx吗?",false] +default : ["确认要xxx吗?",0,false] Bool_0 = Bool_0?', "default": true':'' -var code = ['{"type": "confirm"'+Bool_0+', "text": "',EvalString_0,'",\n', +Int_0 = Int_0 ? (', "timeout": '+Int_0) : ''; +var code = ['{"type": "confirm"'+Int_0+Bool_0+', "text": "',EvalString_0,'",\n', '"yes": [\n',action_0,'],\n', '"no": [\n',action_1,']\n', '},\n'].join(''); @@ -3508,7 +3510,7 @@ ActionParser.prototype.parseAction = function() { break; case "confirm": // 显示确认框 this.next = MotaActionBlocks['confirm_s'].xmlText([ - this.EvalString(data.text), data["default"], + this.EvalString(data.text), data.timeout||0, data["default"], this.insertActionList(data["yes"]), this.insertActionList(data["no"]), this.next]); @@ -3534,7 +3536,7 @@ ActionParser.prototype.parseAction = function() { if (!this.isset(data.text)) data.text = ''; var info = this.getTitleAndPosition(data.text); this.next = MotaActionBlocks['choices_s'].xmlText([ - info[3],info[0],info[1],text_choices,this.next]); + info[3],info[0],info[1],data.timeout||0,text_choices,this.next]); break; case "while": // 前置条件循环处理 this.next = MotaActionBlocks['while_s'].xmlText([ diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index aa221608..bcc1836e 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -91,7 +91,7 @@ editor_blockly = function () { MotaActionBlocks['restart_s'].xmlText(), MotaActionBlocks['confirm_s'].xmlText(), MotaActionBlocks['choices_s'].xmlText([ - '选择剑或者盾','流浪者','man',MotaActionBlocks['choicesContext'].xmlText([ + '选择剑或者盾','流浪者','man',0,MotaActionBlocks['choicesContext'].xmlText([ '剑','','',null,'',MotaActionFunctions.actionParser.parseList([{"type": "openDoor", "loc": [3,3]}]), MotaActionBlocks['choicesContext'].xmlText([ '盾','','',null,'',MotaActionFunctions.actionParser.parseList([{"type": "openDoor", "loc": [9,3]}]), diff --git a/libs/actions.js b/libs/actions.js index 2db1c534..ec1f84c7 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -995,6 +995,7 @@ actions.prototype._clickAction = function (x, y) { if (x >= this.CHOICES_LEFT && x <= this.CHOICES_RIGHT) { var topIndex = this.HSIZE - parseInt((choices.length - 1) / 2) + (core.status.event.ui.offset || 0); if (y >= topIndex && y < topIndex + choices.length) { + clearTimeout(core.status.event.interval); // 选择 core.status.route.push("choices:" + (y - topIndex)); core.insertAction(choices[y - topIndex].action); @@ -1006,11 +1007,13 @@ actions.prototype._clickAction = function (x, y) { if (core.status.event.data.type == 'confirm') { if ((x == this.HSIZE-2 || x == this.HSIZE-1) && y == this.HSIZE+1) { + clearTimeout(core.status.event.interval); core.status.route.push("choices:0"); core.insertAction(core.status.event.ui.yes); core.doAction(); } else if ((x == this.HSIZE+2 || x == this.HSIZE+1) && y == this.HSIZE+1) { + clearTimeout(core.status.event.interval); core.status.route.push("choices:1"); core.insertAction(core.status.event.ui.no); core.doAction(); diff --git a/libs/events.js b/libs/events.js index b8d7a4ec..f395421f 100644 --- a/libs/events.js +++ b/libs/events.js @@ -895,6 +895,7 @@ events.prototype.doAction = function (keepUI) { // 清空boxAnimate和UI层 core.clearUI(); clearInterval(core.status.event.interval); + clearTimeout(core.status.event.interval); core.status.event.interval = null; } // 判定是否执行完毕 @@ -1763,21 +1764,27 @@ events.prototype._action_choices = function (data, x, y, prefix) { }) if (data.choices.length == 0) return this.doAction(); if (core.isReplaying()) { - var action = core.status.replay.toReplay.shift(), index; + var action = core.status.replay.toReplay.shift(); // --- 忽略可能的turn事件 if (action == 'turn') action = core.status.replay.toReplay.shift(); - if (action.indexOf("choices:") == 0 && ((index = parseInt(action.substring(8))) >= 0) && index < data.choices.length) { - core.status.event.selection = index; - setTimeout(function () { - core.status.route.push("choices:" + index); - core.insertAction(data.choices[index].action); - core.doAction(); - }, core.status.replay.speed == 24 ? 1 : 750 / Math.max(1, core.status.replay.speed)) - } - else { - core.control._replay_error(action); - return; + if (action.indexOf('choices:') == 0) { + var index = action.substring(8); + if (index == 'none' || ((index = parseInt(index)) >= 0) && index < data.choices.length) { + core.status.event.selection = index; + setTimeout(function () { + core.status.route.push("choices:"+index); + if (index != 'none') { + core.insertAction(data.choices[index].action); + } + core.doAction(); + }, core.status.replay.speed == 24 ? 1 : 750 / Math.max(1, core.status.replay.speed)); + } } + } else if (data.timeout) { + core.status.event.interval = setTimeout(function () { + core.status.route.push("choices:none"); + core.doAction(); + }, data.timeout); } core.ui.drawChoices(data.text, data.choices); } @@ -1795,25 +1802,35 @@ events.prototype._precompile_choices = function (data) { events.prototype._action_confirm = function (data, x, y, prefix) { core.status.event.ui = {"text": data.text, "yes": data.yes, "no": data.no}; if (core.isReplaying()) { - var action = core.status.replay.toReplay.shift(), index; + var action = core.status.replay.toReplay.shift(); // --- 忽略可能的turn事件 if (action == 'turn') action = core.status.replay.toReplay.shift(); - if (action.indexOf("choices:") == 0 && ((index = parseInt(action.substring(8))) >= 0) && index < 2) { - core.status.event.selection = index; - setTimeout(function () { - core.status.route.push("choices:" + index); - if (index == 0) core.insertAction(data.yes); - else core.insertAction(data.no); - core.doAction(); - }, core.status.replay.speed == 24 ? 1 : 750 / Math.max(1, core.status.replay.speed)) - } - else { + if (action.indexOf('choices:') == 0) { + var index = action.substring(8); + if (index == 'none' || ((index = parseInt(index)) >= 0) && index < 2) { + core.status.event.selection = index; + setTimeout(function () { + core.status.route.push("choices:"+index); + if (index != 'none') { + if (index == 0) core.insertAction(data.yes); + else core.insertAction(data.no); + } + core.doAction(); + }, core.status.replay.speed == 24 ? 1 : 750 / Math.max(1, core.status.replay.speed)); + } + } else { core.control._replay_error(action); return; } } else { core.status.event.selection = data["default"] ? 0 : 1; + if (data.timeout) { + core.status.event.interval = setTimeout(function () { + core.status.route.push("choices:none"); + core.doAction(); + }, data.timeout); + } } core.ui.drawConfirmBox(data.text); } diff --git a/libs/ui.js b/libs/ui.js index ad1075d1..9012be56 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -1409,7 +1409,7 @@ ui.prototype._drawChoices_drawChoices = function (choices, isWindowSkin, hPos, v core.fillText('ui', choices[i].text, offset, vPos.choice_top + 32 * i, color); } - if (choices.length>0) { + if (choices.length>0 && core.status.event.selection != 'none') { core.status.event.selection = core.status.event.selection || 0; while (core.status.event.selection < 0) core.status.event.selection += choices.length; while (core.status.event.selection >= choices.length) core.status.event.selection -= choices.length; @@ -1435,7 +1435,7 @@ ui.prototype.drawConfirmBox = function (text, yesCallback, noCallback) { core.status.event.data = {'yes': yesCallback, 'no': noCallback}; } - if (core.status.event.selection != 0) core.status.event.selection = 1; + if (core.status.event.selection != 0 && core.status.event.selection != 'none') core.status.event.selection = 1; this.clearUI(); core.setFont('ui', this._buildFont(19, true)); @@ -1451,14 +1451,15 @@ ui.prototype.drawConfirmBox = function (text, yesCallback, noCallback) { core.fillText('ui', "确定", this.HPIXEL - 38, rect.bottom - 35, null, this._buildFont(17, true)); core.fillText('ui', "取消", this.HPIXEL + 38, rect.bottom - 35); - var len=core.calWidth('ui', "确定"); - var strokeLeft = this.HPIXEL + (76*core.status.event.selection-38) - parseInt(len/2) - 5; - - if (isWindowSkin) - this.drawWindowSelector(core.status.textAttribute.background, strokeLeft, rect.bottom-35-20, len+10, 28); - else - core.strokeRect('ui', strokeLeft, rect.bottom-35-20, len+10, 28, "#FFD700", 2); - + if (core.status.event.selection != 'none') { + var len=core.calWidth('ui', "确定"); + var strokeLeft = this.HPIXEL + (76*core.status.event.selection-38) - parseInt(len/2) - 5; + + if (isWindowSkin) + this.drawWindowSelector(core.status.textAttribute.background, strokeLeft, rect.bottom-35-20, len+10, 28); + else + core.strokeRect('ui', strokeLeft, rect.bottom-35-20, len+10, 28, "#FFD700", 2); + } } ui.prototype._drawConfirmBox_getRect = function (contents) { diff --git a/v2.x-final更新.txt b/v2.x-final更新.txt index e380d237..66f6a14a 100644 --- a/v2.x-final更新.txt +++ b/v2.x-final更新.txt @@ -6,7 +6,7 @@ 5. 建议优化core.splitLines()来避免把单词打断和触犯标点禁则,如点号和右标号禁止用于行首,左标号禁止用于行尾 (已完成!) 6. core.drawAnimate()和对应的事件,建议增加一个boolean型参数来表示坐标是绝对坐标(即当前的实现)还是在视野中的相对坐标(以13*13为例相对坐标总是在0~12之间),以实现形如“在视野正中心播放某某动画”的需求(小地图可以写6,6,大地图怎么办) (已完成!) 7. 建议把core.playBgm(bgm, startTime)的startTime参数在事件中也提供出来,以用于一些演出(比如适当的剧情处直接从高潮开始)。同理可以让“暂停背景音乐”记录下当前播放到了第几秒,并在“恢复背景音乐”中自动从这个秒数恢复。作者还可以手动配合音量渐变效果 -8. 系统设置菜单中“音量”和“步时”的点击区并不是根据文本长度自动适配的,这导致作者修改文本(包括但不限于翻译)后玩家难以找到准确的点击区,建议优化 +(已完成!) 8. 系统设置菜单中“音量”和“步时”的点击区并不是根据文本长度自动适配的,这导致作者修改文本(包括但不限于翻译)后玩家难以找到准确的点击区,建议优化 9. 建议给“显示选择项”、“显示确认框”、“等待用户操作”这三个事件添加一个“若多少毫秒内不响应则触发的分支”,用来实现一些如新新2的QTE,录像中可以记录“choice: timeout”、“confirm: timeout”和“wait: timeout”来表示触发了超时分支 10. 建议给“转变图块”事件增加一个淡入时间参数,用于原本是空地或空气墙的情况,目前这种效果必须借助存在安全隐患的红点 11. 建议修复勇士后退时跟随者的鬼畜行为,并推出一套能够对跟随者位置和朝向进行读写的API甚至事件,且允许这些信息被计入存档,以实现一些演出效果甚至游戏要素,如新新2用公主占位防冰块