diff --git a/_server/blockly/MotaAction.g4 b/_server/blockly/MotaAction.g4 index 61bbe2a0..db191884 100644 --- a/_server/blockly/MotaAction.g4 +++ b/_server/blockly/MotaAction.g4 @@ -235,6 +235,7 @@ action | break_s | continue_s | input_s + | input2_s | choices_s | function_s | pass_s @@ -1057,18 +1058,31 @@ return code; */; input_s - : '接受用户输入,提示' ':' EvalString Newline + : '接受用户输入数字,提示' ':' EvalString Newline /* input_s -tooltip : input:接受用户输入, 事件只能接受非负整数输入, 所有非法的输入将全部变成0 -helpUrl : https://ckcz123.github.io/mota-js/#/event?id=input%EF%BC%9A%E6%8E%A5%E5%8F%97%E7%94%A8%E6%88%B7%E8%BE%93%E5%85%A5 +tooltip : input:接受用户输入数字, 事件只能接受非负整数输入, 所有非法的输入将全部变成0 +helpUrl : https://ckcz123.github.io/mota-js/#/event?id=input%ef%bc%9a%e6%8e%a5%e5%8f%97%e7%94%a8%e6%88%b7%e8%be%93%e5%85%a5%e6%95%b0%e5%ad%97 default : ["请输入一个数"] colour : this.dataColor var code = '{"type": "input", "text": "'+EvalString_0+'"},\n'; return code; */; +input2_s + : '接受用户输入文本,提示' ':' EvalString Newline + + +/* input2_s +tooltip : input2:接受用户输入文本, 允许用户输入任何形式的文本 +helpUrl : https://ckcz123.github.io/mota-js/#/event?id=input2%ef%bc%9a%e6%8e%a5%e5%8f%97%e7%94%a8%e6%88%b7%e8%be%93%e5%85%a5%e6%96%87%e6%9c%ac +default : ["请输入文本"] +colour : this.dataColor +var code = '{"type": "input2", "text": "'+EvalString_0+'"},\n'; +return code; +*/; + if_s : '如果' ':' expression BGNL? Newline action+ '否则' ':' BGNL? Newline action+ BEND Newline @@ -1773,6 +1787,10 @@ ActionParser.prototype.parseAction = function() { this.next = MotaActionBlocks['input_s'].xmlText([ data.text,this.next]); break; + case "input2": + this.next = MotaActionBlocks['input2_s'].xmlText([ + data.text,this.next]); + break; case "if": // 条件判断 this.next = MotaActionBlocks['if_s'].xmlText([ MotaActionBlocks['evalString_e'].xmlText([data.condition]), diff --git a/_server/data.comment.js b/_server/data.comment.js index acfae9fc..3cd98103 100644 --- a/_server/data.comment.js +++ b/_server/data.comment.js @@ -589,6 +589,12 @@ data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "_type": "checkbox", "_bool": "bool", "_data": "是否允许瞬间移动" + }, + "clickMoveDirectly": { + "_leaf": true, + "_type": "checkbox", + "_bool": "bool", + "_data": "是否默认开启单击瞬移,用户可在菜单栏手动开关" } } } diff --git a/_server/editor.js b/_server/editor.js index 0e8a53c4..9c9603cc 100644 --- a/_server/editor.js +++ b/_server/editor.js @@ -333,6 +333,10 @@ editor.prototype.changeFloor = function (floorId, callback) { }) }); core.changeFloor(floorId, null, {"x": 0, "y": 0, "direction": "up"}, null, function () { + core.bigmap.offsetX=0; + core.bigmap.offsetY=0; + editor.moveViewport(0,0); + editor.drawMapBg(); var mapArray = core.maps.save(core.status.maps, core.status.floorId); editor.map = mapArray.map(function (v) { diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index d9017a64..7be006de 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -88,6 +88,7 @@ editor_blockly = function () { MotaActionBlocks['idString_1_e'].xmlText(['status','hp']) ]), MotaActionBlocks['input_s'].xmlText(), + MotaActionBlocks['input2_s'].xmlText(), MotaActionBlocks['update_s'].xmlText(), MotaActionBlocks['updateEnemys_s'].xmlText(), MotaActionBlocks['moveHero_s'].xmlText(), diff --git a/_server/editor_mode.js b/_server/editor_mode.js index 9c5c2b4e..47ddbd94 100644 --- a/_server/editor_mode.js +++ b/_server/editor_mode.js @@ -441,10 +441,7 @@ editor_mode = function (editor) { selectFloor.onchange = function () { editor_mode.onmode('nextChange'); editor_mode.onmode('floor'); - core.bigmap.offsetX=0; - core.bigmap.offsetY=0; editor.changeFloor(selectFloor.value); - editor.moveViewport(0,0); } }); diff --git a/docs/event.md b/docs/event.md index 29b55dfa..b36539bc 100644 --- a/docs/event.md +++ b/docs/event.md @@ -995,13 +995,13 @@ value为音量大小,在0到100之间,默认为100。设置后,BGM和SE都 该事件会显示失败页面,并重新开始游戏。 -### input:接受用户输入 +### input:接受用户输入数字 -使用`{"type": "input"}`可以接受用户的输入。 +使用`{"type": "input"}`可以接受用户的输入的数字。 ``` js "x,y": [ // 实际执行的事件列表 - {"type": "input", "text": "请输入一个数"}, // 显示一个弹窗让用户输入内容 + {"type": "input", "text": "请输入一个数"}, // 显示一个弹窗让用户输入数字 "你刚刚输入的数是${flag:input}" // 输入结果将被赋值为flag:input ] ``` @@ -1014,6 +1014,25 @@ text为提示文字,可以在这里给输入提示文字。这里同样可以 输入得到的结果将被赋值给flag:input,可以供后续if来进行判断。 +### input2:接受用户输入文本 + +类似于input事件,使用`{"type": "input2"}`可以接受用户的输入的文本。 + +``` js +"x,y": [ // 实际执行的事件列表 + {"type": "input2", "text": "请输入你的ID"}, // 显示一个弹窗让用户输入文本 + "你好,${flag:input},欢迎来到本塔" // 输入结果将被赋值为flag:input +] +``` + +text为提示文字,可以在这里给输入提示文字。这里同样可以使用${ }来计算表达式的值。 + +当执行input2事件时,将显示一个弹窗,并提示用户输入一个内容。 + +该事件可以接收任何形式的文本输入,包括中文,空格,标点符号等等。如果用户点击取消按钮,则视为空字符串。 + +输入得到的结果也将被赋值给flag:input,可以供后续使用。 + ### if:条件判断 使用`{"type": "if"}`可以对条件进行判断,根据判断结果将会选择不同的分支执行。 @@ -1585,9 +1604,9 @@ core.insertAction([ 当角色走上冰面时,将触发ski事件,并会一直向前滑行,直到撞上不可通行的块会触发事件(比如撞上怪物会触发battle,撞上门会触发openDoor等等),或者离开冰面为止。 -!> 由于H5魔塔只有事件一层,因此滑冰的冰面上将无法摆放任何东西(如道具)。 +!> 由于H5魔塔只有事件一层,因此滑冰的冰面上将无法摆放任何东西(如怪物,门或道具等);不过可以在战后/开门后/道具后的事件写转变图块成167,从而继续滑冰。 -!> 撞上怪物将触发battle进行战斗,此战斗的触发和直接撞上怪物相同(战斗前自动存档,打不过则无法战斗);如需不自动存档的强制战斗请使用自定义事件覆盖。开门同理。 +!> 撞上怪物将触发battle进行战斗,该战斗是强制战斗,打不过将直接死亡。 关于推箱子,存在三种状态:花(168),箱子(169)和已经推到花的箱子(170)。 diff --git a/libs/actions.js b/libs/actions.js index 8e47e24b..01619092 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -1591,17 +1591,22 @@ actions.prototype.clickSwitchs = function (x,y) { core.ui.drawSwitchs(); break; case 6: - core.status.automaticRoute.clickMoveDirectly=!core.status.automaticRoute.clickMoveDirectly; - core.setLocalStorage('clickMoveDirectly', core.status.automaticRoute.clickMoveDirectly); + core.flags.clickMoveDirectly=!core.flags.clickMoveDirectly; + core.setLocalStorage('clickMoveDirectly', core.flags.clickMoveDirectly); core.ui.drawSwitchs(); break; case 7: - window.open(core.platform.isPC?"editor.html":"editor-mobile.html", "_blank"); + core.platform.useLocalForage=!core.platform.useLocalForage; + core.setLocalStorage('useLocalForage', core.platform.useLocalForage); + core.ui.drawSwitchs(); break; case 8: - window.open(core.firstData.name+".zip", "_blank"); + window.open(core.platform.isPC?"editor.html":"editor-mobile.html", "_blank"); break; case 9: + window.open(core.firstData.name+".zip", "_blank"); + break; + case 10: core.status.event.selection=0; core.ui.drawSettings(); break; @@ -2020,9 +2025,15 @@ actions.prototype.clickStorageRemove = function (x, y) { var selection = y - topIndex; switch (selection) { case 0: - localforage.clear(function () { + if (core.platform.useLocalForage) { + localforage.clear(function () { + core.drawText("\t[操作成功]你的所有存档已被清空。"); + }); + } + else { + localStorage.clear(); core.drawText("\t[操作成功]你的所有存档已被清空。"); - }); + } break; case 1: for (var i=1;i<=5*(main.savePages||30);i++) { diff --git a/libs/control.js b/libs/control.js index ec9d6928..a59adf5a 100644 --- a/libs/control.js +++ b/libs/control.js @@ -295,8 +295,6 @@ control.prototype.resetStatus = function(hero, hard, floorId, route, maps, value // 保存的Index core.status.saveIndex = core.getLocalStorage('saveIndex2', 1); - core.status.automaticRoute.clickMoveDirectly = core.getLocalStorage('clickMoveDirectly', true); - if (core.isset(values)) core.values = core.clone(values); else core.values = core.clone(core.data.values); @@ -457,7 +455,7 @@ control.prototype.setAutomaticRoute = function (destX, destY, stepPostfix) { if (core.timeout.turnHeroTimeout!=null) return; // 单击瞬间移动 - if (core.status.automaticRoute.clickMoveDirectly && core.status.heroStop) { + if (core.flags.clickMoveDirectly && core.status.heroStop) { if (core.control.tryMoveDirectly(destX, destY)) return; } @@ -754,7 +752,14 @@ control.prototype.moveAction = function (callback) { } ////// 转向 ////// -control.prototype.turnHero = function() { +control.prototype.turnHero = function(direction) { + if (core.isset(direction)) { + core.setHeroLoc('direction', direction); + core.drawHero(); + core.clearMap('route'); + core.status.route.push("turn:"+direction); + return; + } if (core.status.hero.loc.direction == 'up') core.status.hero.loc.direction = 'right'; else if (core.status.hero.loc.direction == 'right') core.status.hero.loc.direction = 'down'; else if (core.status.hero.loc.direction == 'down') core.status.hero.loc.direction = 'left'; @@ -2010,6 +2015,11 @@ control.prototype.replay = function () { core.replay(); return; } + else if (action.indexOf("turn:")==0) { + core.turnHero(action.substring(5)); + core.replay(); + return; + } else if (action=='getNext') { if (core.flags.enableGentleClick && core.getBlock(core.nextX(), core.nextY())!=null) { var nextX = core.nextX(), nextY = core.nextY(); @@ -2182,7 +2192,10 @@ control.prototype.autosave = function (removeLast) { var x=null; if (removeLast) x=core.status.route.pop(); + // 加入当前方向 + core.status.route.push("turn:"+core.getHeroLoc('direction')); core.setLocalForage("autoSave", core.saveData()) + core.status.route.pop(); if (removeLast && core.isset(x)) core.status.route.push(x); } diff --git a/libs/core.js b/libs/core.js index 585e3924..ee47c077 100644 --- a/libs/core.js +++ b/libs/core.js @@ -60,6 +60,7 @@ function core() { 'isQQ': false, // 是否是QQ 'isChrome': false, // 是否是Chrome 'supportCopy': false, // 是否支持复制到剪切板 + 'useLocalForage': true, 'fileInput': null, // FileInput 'fileReader': null, // 是否支持FileReader @@ -112,7 +113,6 @@ function core() { 'cursorX': null, 'cursorY': null, "moveDirectly": false, - 'clickMoveDirectly': true, }, // 按下键的时间:为了判定双击 @@ -230,6 +230,27 @@ core.prototype.init = function (coreData, callback) { core.platform.isSafari = /Safari/i.test(navigator.userAgent) && !/Chrome/i.test(navigator.userAgent); core.platform.isQQ = /QQ/i.test(navigator.userAgent); core.platform.isWeChat = /MicroMessenger/i.test(navigator.userAgent); + core.platform.useLocalForage = core.getLocalStorage('useLocalForage', true); + if (core.platform.useLocalForage) { + try { + core.setLocalForage("__test__", "__test__", function() { + try { + core.getLocalForage("__test__", null, function(data) { + if (data!="__test__") { + console.log("localForage unsupported!"); + core.platform.useLocalForage=false; + } + else { + console.log("localForage supported!") + core.removeLocalForage("__test__"); + } + }, function(e) {console.log(e); core.platform.useLocalForage=false;}) + } + catch (e) {console.log(e); core.platform.useLocalForage=false;} + }, function(e) {console.log(e); core.platform.useLocalForage=false;}) + } + catch (e) {console.log(e); core.platform.useLocalForage=false;} + } if (window.FileReader) { core.platform.fileReader = new FileReader(); @@ -266,12 +287,13 @@ core.prototype.init = function (coreData, callback) { core.flags.displayEnemyDamage = core.getLocalStorage('enemyDamage', core.flags.displayEnemyDamage); core.flags.displayCritical = core.getLocalStorage('critical', core.flags.displayCritical); core.flags.displayExtraDamage = core.getLocalStorage('extraDamage', core.flags.displayExtraDamage); + core.flags.clickMoveDirectly = core.getLocalStorage('clickMoveDirectly', + !(core.isset(core.flags.clickMoveDirectly) && !core.flags.clickMoveDirectly)); core.material.ground = new Image(); core.material.ground.src = "project/images/ground.png"; core.bigmap.tempCanvas = document.createElement('canvas').getContext('2d'); - core.getLocalForage("test"); core.loader.load(function () { console.log(core.material); @@ -452,8 +474,8 @@ core.prototype.moveAction = function (callback) { } ////// 转向 ////// -core.prototype.turnHero = function() { - core.control.turnHero(); +core.prototype.turnHero = function(direction) { + core.control.turnHero(direction); } ////// 勇士能否前往某方向 ////// diff --git a/libs/events.js b/libs/events.js index 1318c8d9..73497b87 100644 --- a/libs/events.js +++ b/libs/events.js @@ -750,6 +750,32 @@ events.prototype.doAction = function() { this.doAction(); } break; + case "input2": + { + var value; + if (core.status.replay.replaying) { + var action = core.status.replay.toReplay.shift(); + try { + if (action.indexOf("input2:")!=0) throw new Error("Input2 Error. Current action: "+action); + value = core.decodeBase64(action.substring(7)); + } + catch (e) { + console.log(e); + core.stopReplay(); + core.drawTip("录像文件出错"); + return; + } + } + else { + core.interval.onDownInterval = 'tmp'; + value = prompt(core.replaceText(data.text)); + if (!core.isset(value)) value=""; + } + core.status.route.push("input2:"+core.encodeBase64(value)); + core.setFlag("input", value); + this.doAction(); + } + break; case "if": // 条件判断 if (core.calValue(data.condition)) core.events.insertAction(data["true"]) @@ -1013,7 +1039,7 @@ events.prototype.battle = function (id, x, y, force, callback) { core.stopAutomaticRoute(); // 非强制战斗 - if (!core.enemys.canBattle(id) && !force) { + if (!core.enemys.canBattle(id) && !force && !core.isset(core.status.event.id)) { core.drawTip("你打不过此怪物!"); core.clearContinueAutomaticRoute(); return; diff --git a/libs/maps.js b/libs/maps.js index c9c42891..ba9653c8 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -214,6 +214,9 @@ maps.prototype.load = function (data, floorId) { ////// 将当前地图重新变成二维数组形式 ////// maps.prototype.getMapArray = function (blockArray,width,height){ + width=width||13; + height=height||13; + var blocks = []; for (var x=0;x