From f0420fc75eb90edd6bc95ce4ca015f218b591cab Mon Sep 17 00:00:00 2001 From: oc Date: Wed, 24 Apr 2019 00:47:19 +0800 Subject: [PATCH 01/25] \t without title --- _docs/event.md | 6 +++++- libs/ui.js | 34 ++++++++++++++++++---------------- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/_docs/event.md b/_docs/event.md index bb586464..309e6a7e 100644 --- a/_docs/event.md +++ b/_docs/event.md @@ -188,6 +188,8 @@ 从V2.5.2以后,新增了绘制大头像的功能。绘制大头像图的基本写法是`\t[1.png]`或者`\t[标题,1.png]`。 +从V2.6开始,所有图块都允许只写ID,对于非怪物则没有标题。 + ``` js [ "一段普通文字", @@ -198,7 +200,9 @@ "\t[小妖精,fairy]这是一段小妖精说的话,使用仙子(fairy)的图标", "\t[你赢了]直接显示标题为【你赢了】", "\t[1.png]绘制1.png这个头像图", - "\t[标题,1.png]同时绘制标题和1.png这个头像图" + "\t[标题,1.png]同时绘制标题和1.png这个头像图", + "\t[sword1]获得铁剑,没有标题", + "\t[man]没有标题的npc动画" ] ``` diff --git a/libs/ui.js b/libs/ui.js index ec4652fc..9ec62374 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -383,7 +383,6 @@ ui.prototype._getTitleAndIcon = function (content) { var blockInfo = core.getBlockInfo(s4); if (blockInfo != null) { if (core.material.enemys[s4]) title = core.material.enemys[s4].name; - else title = s4; image = blockInfo.image; icon = blockInfo.posY; height = blockInfo.height; @@ -874,8 +873,10 @@ ui.prototype._drawTextBox_getVerticalPosition = function (content, titleInfo, po var realContent = this._getRealContent(content); var height = 30 + lineHeight * core.splitLines("ui", realContent, validWidth, this._buildFont()).length; if (titleInfo.title) height += textAttribute.titlefont + 5; - if (titleInfo.icon != null) - height = Math.max(height, titleInfo.height+50); + if (titleInfo.icon != null) { + if (titleInfo.title) height = Math.max(height, titleInfo.height+50); + else height = Math.max(height, titleInfo.height + 30); + } else if (titleInfo.image) height = Math.max(height, 90); @@ -904,9 +905,11 @@ ui.prototype._drawTextBox_drawTitleAndIcon = function (titleInfo, hPos, vPos, al core.setTextAlign('ui', 'left'); var textAttribute = core.status.textAttribute; var content_top = vPos.top + 15; + var image_top = vPos.top + 15; if (titleInfo.title != null) { var titlefont = textAttribute.titlefont; content_top += titlefont + 5; + image_top = vPos.top + 40; core.setFillStyle('ui', core.arrayToRGB(textAttribute.title)); core.setStrokeStyle('ui', core.arrayToRGB(textAttribute.title)); @@ -919,19 +922,18 @@ ui.prototype._drawTextBox_drawTitleAndIcon = function (titleInfo, hPos, vPos, al title_left = hPos.right - title_width - 12; core.fillText('ui', titleInfo.title, title_left, vPos.top + 8 + titlefont); - - if (titleInfo.icon != null) { - core.setAlpha('ui', alpha); - core.strokeRect('ui', hPos.left + 15 - 1, vPos.top + 40-1, 34, titleInfo.height + 2, null, 2); - core.setAlpha('ui', 1); - core.status.boxAnimateObjs = []; - core.status.boxAnimateObjs.push({ - 'bgx': hPos.left + 15, 'bgy': vPos.top + 40, 'bgWidth': 32, 'bgHeight': titleInfo.height, - 'x': hPos.left + 15, 'y': vPos.top + 40, 'height': titleInfo.height, 'animate': titleInfo.animate, - 'image': titleInfo.image, 'pos': titleInfo.icon * titleInfo.height - }); - core.drawBoxAnimate(); - } + } + if (titleInfo.icon != null) { + core.setAlpha('ui', alpha); + core.strokeRect('ui', hPos.left + 15 - 1, image_top-1, 34, titleInfo.height + 2, null, 2); + core.setAlpha('ui', 1); + core.status.boxAnimateObjs = []; + core.status.boxAnimateObjs.push({ + 'bgx': hPos.left + 15, 'bgy': image_top, 'bgWidth': 32, 'bgHeight': titleInfo.height, + 'x': hPos.left + 15, 'y': image_top, 'height': titleInfo.height, 'animate': titleInfo.animate, + 'image': titleInfo.image, 'pos': titleInfo.icon * titleInfo.height + }); + core.drawBoxAnimate(); } if (titleInfo.image != null && titleInfo.icon == null) { // 头像图 core.drawImage('ui', titleInfo.image, 0, 0, titleInfo.image.width, titleInfo.image.height, From 4e102eba6c2e01dbaa9fe8dfaa70831721600c61 Mon Sep 17 00:00:00 2001 From: YouWei Zhao Date: Tue, 23 Apr 2019 14:39:19 -0400 Subject: [PATCH 02/25] editor_file --- _server/README.md | 2 -- _server/editor.js | 1 + _server/editor_file_unsorted.js | 17 ----------------- _server/editor_game.js | 25 +++++++++++++++++++++---- _server/editor_unsorted_2.js | 2 +- _server/editor_util.js | 11 +++++++++++ _server/refactoring.md | 6 +++--- 7 files changed, 37 insertions(+), 27 deletions(-) diff --git a/_server/README.md b/_server/README.md index d23bfb43..e6a12c67 100644 --- a/_server/README.md +++ b/_server/README.md @@ -42,8 +42,6 @@ editor.util.guid()//产生一个可以作为id的长随机字符串 提供了以下函数进行楼层`map`数组相关的操作 ```javascript -editor.file.getFloorFileList -editor.file.loadFloorFile editor.file.saveFloorFile editor.file.saveFloorFileAs ``` diff --git a/_server/editor.js b/_server/editor.js index 1e277681..aa5a21ec 100644 --- a/_server/editor.js +++ b/_server/editor.js @@ -53,6 +53,7 @@ editor.prototype.init = function (callback) { editor_file_wrapper(editor); editor_table_wrapper(editor); editor_unsorted_1_wrapper(editor); + editor.printe=printe; afterMainInit(); }); diff --git a/_server/editor_file_unsorted.js b/_server/editor_file_unsorted.js index 92ba8c81..27d4e7aa 100644 --- a/_server/editor_file_unsorted.js +++ b/_server/editor_file_unsorted.js @@ -7,23 +7,6 @@ editor_file = function (editor, callback) { /////////////////////////////////////////////////////////////////////////// - editor.file.getFloorFileList = function (callback) { - checkCallback(callback); - /* var fs = editor.fs; - fs.readdir('project/floors',function(err, data){ - callback([data,err]); - }); */ - callback([editor.core.floorIds, null]); - } - //callback([Array,err:String]) - editor.file.loadFloorFile = function (filename, callback) { - //filename不含'/'不含'.js' - checkCallback(callback); - - editor.currentFloorId = editor.core.status.floorId; - editor.currentFloorData = editor.core.floors[editor.currentFloorId]; - } - //callback(err:String) editor.file.saveFloorFile = function (callback) { checkCallback(callback); /* if (!isset(editor.currentFloorId) || !isset(editor.currentFloorData)) { diff --git a/_server/editor_game.js b/_server/editor_game.js index 13b4d402..278dd67e 100644 --- a/_server/editor_game.js +++ b/_server/editor_game.js @@ -5,7 +5,10 @@ editor_game_wrapper = function (editor, main, core) { this.replacerRecord = {} } + + //////////////////// 修改数据相关 //////////////////// // 三个 replacer 和 replacerRecord 暂时放在此处 + editor_game.prototype.replacerForLoading = function (_key, value) { var rmap = editor.game.replacerRecord; if (value instanceof Function) { @@ -29,7 +32,7 @@ editor_game_wrapper = function (editor, main, core) { return value } - editor_game.prototype.getValue = function(field){ + editor_game.prototype.getValue = function (field) { var rmap = editor.game.replacerRecord; var value = eval(field) if (rmap.hasOwnProperty(oldval)) { @@ -39,13 +42,13 @@ editor_game_wrapper = function (editor, main, core) { } } - editor_game.prototype.setValue = function(field,value){ + editor_game.prototype.setValue = function (field, value) { var rmap = editor.game.replacerRecord; var oldval = eval(field) if (rmap.hasOwnProperty(oldval)) { - rmap[value]=eval(value) + rmap[value] = eval(value) } else { - eval(field+'='+value) + eval(field + '=' + value) } } @@ -62,6 +65,9 @@ editor_game_wrapper = function (editor, main, core) { data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = JSON.parse(JSON.stringify(data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d, rf)); } + //////////////////// 加载游戏数据相关 //////////////////// + + // 初始化数字与地图图块的对应 editor_game.prototype.idsInit = function (maps, icons) { editor.ids = [0]; editor.indexs = []; @@ -125,6 +131,7 @@ editor_game_wrapper = function (editor, main, core) { } } + // 获取当前地图 editor_game.prototype.fetchMapFromCore = function () { var mapArray = core.maps.saveMap(core.status.floorId); editor.map = mapArray.map(function (v) { @@ -158,6 +165,16 @@ editor_game_wrapper = function (editor, main, core) { } } + // 获取地图列表 + editor_game.prototype.getFloorFileList = function (callback) { + // callback([Array,err:String]) + editor.util.checkCallback(callback); + /* editor.fs.readdir('project/floors',function(err, data){ + callback([data,err]); + }); */ + callback([editor.core.floorIds, null]); + } + editor.constructor.prototype.game = new editor_game(); } //editor_game_wrapper(editor); \ No newline at end of file diff --git a/_server/editor_unsorted_2.js b/_server/editor_unsorted_2.js index 82dfd7b8..fe7ecf58 100644 --- a/_server/editor_unsorted_2.js +++ b/_server/editor_unsorted_2.js @@ -37,7 +37,7 @@ editor_unsorted_2_wrapper=function(editor_mode){ } var selectFloor = document.getElementById('selectFloor'); - editor.file.getFloorFileList(function (floors) { + editor.game.getFloorFileList(function (floors) { var outstr = []; floors[0].forEach(function (floor) { outstr.push(["\n'].join('')); diff --git a/_server/editor_util.js b/_server/editor_util.js index 83b745a5..6f81a8c1 100644 --- a/_server/editor_util.js +++ b/_server/editor_util.js @@ -157,6 +157,17 @@ editor_util_wrapper = function (editor) { }).join('')) } + editor_util.prototype.isset = function (val) { + return val != null && !(typeof val == 'number' && isNaN(val)); + } + + editor_util.prototype.checkCallback=function(callback){ + if (!editor.util.isset(callback)) { + editor.printe('未设置callback'); + throw('未设置callback') + } + } + editor.constructor.prototype.util = new editor_util(); } //editor_util_wrapper(editor); \ No newline at end of file diff --git a/_server/refactoring.md b/_server/refactoring.md index ff45ab82..7c3380c2 100644 --- a/_server/refactoring.md +++ b/_server/refactoring.md @@ -10,9 +10,9 @@ + [ ] editor_blockly 图块化事件编辑器 + [ ] editor_multi 多行文本编辑器 + [x] editor_table 处理表格的生成, 及其响应的事件, 从原editor\_mode中分离 -+ [ ] editor_file 调用fs.js编辑文件, 把原editor\_file模块化 -+ [ ] editor_game 处理来自core的数据, 导入为editor的数据, 从原editor中分离. **只有此文件允许`\s(main|core)`形式的调用**(以及其初始化`editor_game_wrapper(editor, main, core);`) -+ [x] editor_util 生成guid等函数, 从editor分离 ++ [ ] editor_file 调用fs.js编辑文件, 把原editor\_file模块化, 并且只负责文件写入 ++ [ ] editor_game 处理游戏数据, 导入为editor的数据, 编辑数据, 从原editor和editor_file中抽离. **只有此文件允许`\s(main|core)`形式的调用**(以及其初始化`editor_game_wrapper(editor, main, core);`) ++ [x] editor_util 生成guid/处理颜色 等函数, 从editor分离 + [ ] editor 执行初始化流程加组合各组件 + [ ] 原editor_mode 移除 + [x] 原vm 移除 From 057861d82644cf65cdad6e187d11906de044cc13 Mon Sep 17 00:00:00 2001 From: YouWei Zhao Date: Tue, 23 Apr 2019 14:58:15 -0400 Subject: [PATCH 03/25] floors_template --- _server/editor_file_unsorted.js | 34 ++++++------------------------ _server/table/comment.js | 37 +++++++++++++++++++++++++++++---- 2 files changed, 39 insertions(+), 32 deletions(-) diff --git a/_server/editor_file_unsorted.js b/_server/editor_file_unsorted.js index 27d4e7aa..80c34c3a 100644 --- a/_server/editor_file_unsorted.js +++ b/_server/editor_file_unsorted.js @@ -70,7 +70,8 @@ editor_file = function (editor, callback) { name = saveFilename.substring(2); title = "主塔 "+name+" 层"; } - editor.currentFloorData = { + // editor.file.comment._data.floors_template + editor.currentFloorData = Object.assign(JSON.parse(JSON.stringify(editor.file.comment._data.floors_template)), { floorId: saveFilename, title: title, name: name, @@ -80,24 +81,13 @@ editor_file = function (editor, callback) { canUseQuickShop: saveStatus?currData.canUseQuickShop:true, cannotViewMap: saveStatus?currData.cannotViewMap:false, cannotMoveDirectly: saveStatus?currData.cannotMoveDirectly:false, - images: [], item_ratio: saveStatus?currData.item_ratio:1, defaultGround: saveStatus?currData.defaultGround:"ground", bgm: saveStatus?currData.bgm:null, - upFloor: null, - downFloor: null, color: saveStatus?currData.color:null, weather: saveStatus?currData.weather:null, - firstArrive: [], - eachArrive: [], - parallelDo: "", - events: {}, - changeFloor: {}, - afterBattle: {}, - afterGetItem: {}, - afterOpenDoor: {}, - cannotMove: {} - }; + }); + Object.keys(editor.currentFloorData).forEach(function (t) { if (editor.currentFloorData[t] == null) delete editor.currentFloorData[t]; @@ -128,7 +118,7 @@ editor_file = function (editor, callback) { var datas = []; for (var i=from;i<=to;i++) { var datastr = ['main.floors.', floorIdList[i-from], '=\n{']; - var data = { + var data = Object.assign(JSON.parse(JSON.stringify(editor.file.comment._data.floors_template)), { floorId: floorIdList[i-from], title: calValue(document.getElementById('newFloorTitles').value, i), name: calValue(document.getElementById('newFloorNames').value, i), @@ -139,24 +129,12 @@ editor_file = function (editor, callback) { canUseQuickShop: saveStatus?currData.canUseQuickShop:true, cannotViewMap: saveStatus?currData.cannotViewMap:false, cannotMoveDirectly: saveStatus?currData.cannotMoveDirectly:false, - images: [], item_ratio: saveStatus?currData.item_ratio:1, defaultGround: saveStatus?currData.defaultGround:"ground", bgm: saveStatus?currData.bgm:null, - upFloor: null, - downFloor: null, color: saveStatus?currData.color:null, weather: saveStatus?currData.weather:null, - firstArrive: [], - eachArrive: [], - parallelDo: "", - events: {}, - changeFloor: {}, - afterBattle: {}, - afterGetItem: {}, - afterOpenDoor: {}, - cannotMove: {} - }; + }); Object.keys(data).forEach(function (t) { if (data[t] == null) delete data[t]; diff --git a/_server/table/comment.js b/_server/table/comment.js index ff09aa48..d5d72cf8 100644 --- a/_server/table/comment.js +++ b/_server/table/comment.js @@ -230,7 +230,7 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc = { "_type": "select", "_select": { "values": [ - null, + "null", "openDoor", "passNet", "changeLight", @@ -245,9 +245,9 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc = { "_type": "select", "_select": { "values": [ - null, - true, - false + "null", + "true", + "false" ] }, "_data": "该图块是否不可通行;true代表不可通行,false代表可通行,null代表使用系统缺省值" @@ -462,6 +462,35 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc = { } } } + }, + + "floors_template": { + "floorId": "to be covered", + "title": "new floor", + "name": "new floor", + "width": 13, + "height": 13, + "canFlyTo": true, + "canUseQuickShop": true, + "cannotViewMap": false, + "cannotMoveDirectly": false, + "images": [], + "item_ratio": 1, + "defaultGround": "ground", + "bgm": null, + "upFloor": null, + "downFloor": null, + "color": null, + "weather": null, + "firstArrive": [], + "eachArrive": [], + "parallelDo": "", + "events": {}, + "changeFloor": {}, + "afterBattle": {}, + "afterGetItem": {}, + "afterOpenDoor": {}, + "cannotMove": {} } } } \ No newline at end of file From 59b1bee743aa212d8531861ca5f0a350f967f339 Mon Sep 17 00:00:00 2001 From: YouWei Zhao Date: Tue, 23 Apr 2019 16:46:03 -0400 Subject: [PATCH 04/25] editor_file floors_template --- _server/editor_file_unsorted.js | 42 +++++++++++++++++---------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/_server/editor_file_unsorted.js b/_server/editor_file_unsorted.js index 80c34c3a..471adb69 100644 --- a/_server/editor_file_unsorted.js +++ b/_server/editor_file_unsorted.js @@ -77,16 +77,17 @@ editor_file = function (editor, callback) { name: name, width: parseInt(document.getElementById('newMapWidth').value), height: parseInt(document.getElementById('newMapHeight').value), - canFlyTo: saveStatus?currData.canFlyTo:true, - canUseQuickShop: saveStatus?currData.canUseQuickShop:true, - cannotViewMap: saveStatus?currData.cannotViewMap:false, - cannotMoveDirectly: saveStatus?currData.cannotMoveDirectly:false, - item_ratio: saveStatus?currData.item_ratio:1, - defaultGround: saveStatus?currData.defaultGround:"ground", - bgm: saveStatus?currData.bgm:null, - color: saveStatus?currData.color:null, - weather: saveStatus?currData.weather:null, - }); + },saveStatus?{ + canFlyTo: currData.canFlyTo, + canUseQuickShop: currData.canUseQuickShop, + cannotViewMap: currData.cannotViewMap, + cannotMoveDirectly: currData.cannotMoveDirectly, + item_ratio: currData.item_ratio, + defaultGround: currData.defaultGround, + bgm: currData.bgm, + color: currData.color, + weather: currData.weather, + }:{}); Object.keys(editor.currentFloorData).forEach(function (t) { if (editor.currentFloorData[t] == null) @@ -125,16 +126,17 @@ editor_file = function (editor, callback) { width: width, height: height, map: map, - canFlyTo: saveStatus?currData.canFlyTo:true, - canUseQuickShop: saveStatus?currData.canUseQuickShop:true, - cannotViewMap: saveStatus?currData.cannotViewMap:false, - cannotMoveDirectly: saveStatus?currData.cannotMoveDirectly:false, - item_ratio: saveStatus?currData.item_ratio:1, - defaultGround: saveStatus?currData.defaultGround:"ground", - bgm: saveStatus?currData.bgm:null, - color: saveStatus?currData.color:null, - weather: saveStatus?currData.weather:null, - }); + },saveStatus?{ + canFlyTo: currData.canFlyTo, + canUseQuickShop: currData.canUseQuickShop, + cannotViewMap: currData.cannotViewMap, + cannotMoveDirectly: currData.cannotMoveDirectly, + item_ratio: currData.item_ratio, + defaultGround: currData.defaultGround, + bgm: currData.bgm, + color: currData.color, + weather: currData.weather, + }:{}); Object.keys(data).forEach(function (t) { if (data[t] == null) delete data[t]; From b49fbc6c22c692091a176236aa519e42d3e7f9f8 Mon Sep 17 00:00:00 2001 From: YouWei Zhao Date: Tue, 23 Apr 2019 17:08:31 -0400 Subject: [PATCH 05/25] editor_file --- _server/editor_file_unsorted.js | 42 +++++++++++++-------------------- 1 file changed, 16 insertions(+), 26 deletions(-) diff --git a/_server/editor_file_unsorted.js b/_server/editor_file_unsorted.js index 471adb69..72e204ae 100644 --- a/_server/editor_file_unsorted.js +++ b/_server/editor_file_unsorted.js @@ -14,31 +14,16 @@ editor_file = function (editor, callback) { } */ var filename = 'project/floors/' + editor.currentFloorId + '.js'; var datastr = ['main.floors.', editor.currentFloorId, '=\n']; - if (editor.currentFloorData.map == 'new') { - /* - editor.currentFloorData.map = editor.map.map(function (v) { - return v.map(function () { - return 0 + + for(var ii=0,name;name=['map','bgmap','fgmap'][ii];ii++){ + var mapArray=editor[name].map(function (v) { + return v.map(function (v) { + return v.idnum || v || 0 }) }); - */ - var width = parseInt(document.getElementById('newMapWidth').value); - var height = parseInt(document.getElementById('newMapHeight').value); - var row = []; - for (var i=0;i Date: Tue, 23 Apr 2019 17:49:49 -0400 Subject: [PATCH 06/25] =?UTF-8?q?update=20refactoring.md=20=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E7=9A=84=E9=87=8D=E6=9E=84=E6=80=9D=E8=B7=AF,?= =?UTF-8?q?=E5=85=B3=E4=BA=8Eedtior=5Ffile=E7=9A=84=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E6=80=9D=E8=80=83=E7=9A=84(=E5=8F=AF=E8=83=BD)=E6=AF=94?= =?UTF-8?q?=E8=BE=83=E6=B8=85=E6=99=B0=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _server/editor_file.js | 1 + _server/refactoring.md | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/_server/editor_file.js b/_server/editor_file.js index 84c6595f..9b9f0418 100644 --- a/_server/editor_file.js +++ b/_server/editor_file.js @@ -3,6 +3,7 @@ editor_file_wrapper = function (editor) { } + // 这个函数之后挪到editor.table? editor_file_proto.prototype.loadCommentjs=function(callback){ var commentjs = { 'comment': 'comment', diff --git a/_server/refactoring.md b/_server/refactoring.md index 7c3380c2..8ea8c365 100644 --- a/_server/refactoring.md +++ b/_server/refactoring.md @@ -1,9 +1,18 @@ # 重构 +总体思路 + 按功能拆分文件 + 左侧页面模块化, 方便添加 + 不同的模式的文件操作尽可能模块化 +目前主要在重构editor_file, 思路是editor.file负责把editor.game内的游戏数据格式化成字符串以及写入到文件, 由editor.game来修改数据 ++ editor.file维护一些标记, 描述哪些数据需要格式化并写入, 在save时写入文件(自动保存的话就是每次修改数据都触发save) ++ editor.game修改数据, 并修改editor.file中的标记 ++ 此思路下editor.file的大部分内容会挪到editor.game, editor.game和editor.table可能会再进一步合并拆分 + +editor_file之后是更改editor.map的储存方式, 现有的存对象的模式要在对象和数字间来回转换, 非常繁琐和奇怪 + +再之后是把editor_unsorted_*.js整理清晰 ## 文件结构 From ccee812af734c6e36d5544a41cdf1fd2a506c810 Mon Sep 17 00:00:00 2001 From: oc Date: Sun, 28 Apr 2019 19:23:27 +0800 Subject: [PATCH 07/25] replay animate speed & step replay --- libs/actions.js | 16 +++++++++------- libs/control.js | 46 +++++++++++++++++++++++++++------------------- libs/events.js | 9 ++++++--- libs/items.js | 2 +- libs/maps.js | 5 ++++- libs/ui.js | 1 + 6 files changed, 48 insertions(+), 31 deletions(-) diff --git a/libs/actions.js b/libs/actions.js index 1924144e..ffe68124 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -162,19 +162,21 @@ actions.prototype._sys_onkeyUp_replay = function (e) { core.triggerReplay(); else if (e.keyCode == 65) // A core.rewindReplay(); - else if (e.keyCode == 83) + else if (e.keyCode == 83) // S core.saveReplay(); - else if (e.keyCode == 67) + else if (e.keyCode == 67) // C core.bookReplay(); - else if (e.keyCode == 33 || e.keyCode == 34) + else if (e.keyCode == 33 || e.keyCode == 34) // PgUp/PgDn core.viewMapReplay(); - else if (e.keyCode >= 49 && e.keyCode <= 51) + else if (e.keyCode == 78) // N + core.stepReplay(); + else if (e.keyCode >= 49 && e.keyCode <= 51) // 1-3 core.setReplaySpeed(e.keyCode - 48); - else if (e.keyCode == 52) + else if (e.keyCode == 52) // 4 core.setReplaySpeed(6); - else if (e.keyCode == 53) + else if (e.keyCode == 53) // 5 core.setReplaySpeed(12); - else if (e.keyCode == 54) + else if (e.keyCode == 54) // 6 core.setReplaySpeed(24); return true; } diff --git a/libs/control.js b/libs/control.js index c5f23449..36bdf40c 100644 --- a/libs/control.js +++ b/libs/control.js @@ -1056,7 +1056,7 @@ control.prototype.chooseReplayFile = function () { control.prototype.startReplay = function (list) { if (!core.isPlaying()) return; core.status.replay.replaying=true; - core.status.replay.pausing=false; + core.status.replay.pausing=true; core.status.replay.speed=1.0; core.status.replay.toReplay = core.clone(list); core.status.replay.totalList = core.status.route.concat(list); @@ -1092,16 +1092,24 @@ control.prototype.resumeReplay = function () { core.replay(); } +////// 单步播放 ////// +control.prototype.stepReplay = function () { + if (!core.isPlaying() || !core.isReplaying()) return; + if (!core.status.replay.pausing) return core.drawTip("请先暂停录像"); + if (core.isMoving() || core.status.replay.animate || core.status.event.id) + return core.drawTip("请等待当前事件的处理结束"); + core.replay(true); +} + ////// 加速播放 ////// control.prototype.speedUpReplay = function () { if (!core.isPlaying() || !core.isReplaying()) return; - if (core.status.replay.speed==12) core.status.replay.speed=24; - else if (core.status.replay.speed==6) core.status.replay.speed=12; - else if (core.status.replay.speed==3) core.status.replay.speed=6; - else if (core.status.replay.speed==2.5) core.status.replay.speed=3; - else if (core.status.replay.speed==2) core.status.replay.speed=2.5; - else if (core.status.replay.speed<2) { - core.status.replay.speed = parseInt(10*core.status.replay.speed + 2)/10; + var speeds = [0.2, 0.5, 1, 2, 3, 6, 12, 24]; + for (var i = speeds.length - 2; i >= 0; i--) { + if (speeds[i] <= core.status.replay.speed) { + core.status.replay.speed = speeds[i+1]; + break; + } } core.drawTip("x"+core.status.replay.speed+"倍"); } @@ -1109,15 +1117,13 @@ control.prototype.speedUpReplay = function () { ////// 减速播放 ////// control.prototype.speedDownReplay = function () { if (!core.isPlaying() || !core.isReplaying()) return; - if (core.status.replay.speed==24) core.status.replay.speed=12; - else if (core.status.replay.speed==12) core.status.replay.speed=6; - else if (core.status.replay.speed==6) core.status.replay.speed=3; - else if (core.status.replay.speed==3) core.status.replay.speed=2.5; - else if (core.status.replay.speed==2.5) core.status.replay.speed=2; - else { - core.status.replay.speed = parseInt(10*core.status.replay.speed - 2)/10; + var speeds = [0.2, 0.5, 1, 2, 3, 6, 12, 24]; + for (var i = 1; i <= speeds.length; i++) { + if (speeds[i] >= core.status.replay.speed) { + core.status.replay.speed = speeds[i-1]; + break; + } } - if (core.status.replay.speed<0.2) core.status.replay.speed=0.2; core.drawTip("x"+core.status.replay.speed+"倍"); } @@ -1218,9 +1224,10 @@ control.prototype.isReplaying = function () { } ////// 回放 ////// -control.prototype.replay = function () { +control.prototype.replay = function (force) { if (!core.isPlaying() || !core.isReplaying() - || core.status.replay.pausing || core.status.replay.animate || core.status.event.id) return; + || core.status.replay.animate || core.status.event.id) return; + if (core.status.replay.pausing && !force) return; if (core.status.replay.toReplay.length==0) return this._replay_finished(); this._replay_save(); @@ -1412,9 +1419,9 @@ control.prototype._replayAction_shop = function (action) { return true; } var choices = shop.choices; - var topIndex = core.__HALF_SIZE__ - parseInt(choices.length / 2); core.status.event.selection = parseInt(selections.shift()); core.events.openShop(shopId, false); + var topIndex = core.__HALF_SIZE__ - parseInt(choices.length / 2) + (core.status.event.ui.offset || 0); var shopInterval = setInterval(function () { if (!core.actions._clickShop(core.__HALF_SIZE__, topIndex+core.status.event.selection)) { clearInterval(shopInterval); @@ -2065,6 +2072,7 @@ control.prototype.setCurtain = function(color, time, callback) { } control.prototype._setCurtain_animate = function (nowColor, color, time, callback) { + time /= Math.max(core.status.replay.speed, 1) var per_time = 10, step = parseInt(time / per_time); var animate = setInterval(function() { nowColor = [ diff --git a/libs/events.js b/libs/events.js index fc654e2c..1eb1ad15 100644 --- a/libs/events.js +++ b/libs/events.js @@ -432,7 +432,7 @@ events.prototype._openDoor_animate = function (id, x, y, callback) { } core.clearMap('event', 32 * x, 32 * y, 32, 32); core.drawImage('event', core.material.images.animates, 32 * state, 32 * door, 32, 32, 32 * x, 32 * y, 32, 32); - }, speed / core.status.replay.speed); + }, speed / Math.max(core.status.replay.speed, 1)); } ////// 开一个门后触发的事件 ////// @@ -1884,7 +1884,7 @@ events.prototype.closeDoor = function (x, y, id, callback) { } core.clearMap('event', 32 * x, 32 * y, 32, 32); core.drawImage('event', core.material.images.animates, 32 * (4-state), 32 * door, 32, 32, 32 * x, 32 * y, 32, 32); - }, speed / core.status.replay.speed); + }, speed / Math.max(core.status.replay.speed, 1)); core.animateFrame.asyncId[animate] = true; } @@ -1958,7 +1958,8 @@ events.prototype.moveImage = function (code, to, opacityVal, time, callback) { var opacity = parseFloat(canvas.style.opacity), toOpacity = getOrDefault(opacityVal, opacity); this._moveImage_moving(name, { - fromX: fromX, fromY: fromY, toX: toX, toY: toY, opacity: opacity, toOpacity: toOpacity, time: time + fromX: fromX, fromY: fromY, toX: toX, toY: toY, opacity: opacity, toOpacity: toOpacity, + time: time / Math.max(core.status.replay.speed, 1) }, callback) } @@ -2016,6 +2017,7 @@ events.prototype.setVolume = function (value, time, callback) { return; } var currVolume = core.musicStatus.volume; + time /= Math.max(core.status.replay.speed, 1); var per_time = 10, step = 0, steps = parseInt(time / per_time); var fade = setInterval(function () { step++; @@ -2037,6 +2039,7 @@ events.prototype.vibrate = function (time, callback) { } if (!time || time < 1000) time = 1000; // --- 将time调整为500的倍数(上整),不然会出错 + time /= Math.max(core.status.replay.speed, 1) time = Math.ceil(time / 500) * 500; var shakeInfo = {duration: time * 3 / 50, speed: 5, power: 5, direction: 1, shake: 0}; var animate = setInterval(function () { diff --git a/libs/items.js b/libs/items.js index 6c13e824..15ce13ac 100644 --- a/libs/items.js +++ b/libs/items.js @@ -35,7 +35,7 @@ items.prototype._resetItems = function () { if (core.flags.bombFourDirections) core.material.items.bomb.text = "可以炸掉勇士四周的怪物"; if (core.flags.snowFourDirections) - core.material.items.bomb.text = "可以将四周的熔岩变成平地"; + core.material.items.snow.text = "可以将四周的熔岩变成平地"; if (core.flags.equipment) { core.material.items.sword1.cls = 'equips'; core.material.items.sword2.cls = 'equips'; diff --git a/libs/maps.js b/libs/maps.js index 2e8c4c8f..b8aaf3a9 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -238,7 +238,8 @@ maps.prototype.saveMap = function (floorId) { if (!floorId) { var map = {}; for (var id in maps) { - map[id] = this.saveMap(id); + var obj = this.saveMap(id); + if (Object.keys(obj).length > 0) map[id] = obj; } return map; } @@ -1688,6 +1689,7 @@ maps.prototype.jumpBlock = function (sx, sy, ex, ey, time, keep, callback) { maps.prototype.__generateJumpInfo = function (sx, sy, ex, ey, time) { var dx = ex - sx, dy = ey - sy, distance = Math.round(Math.sqrt(dx * dx + dy * dy)); var jump_peak = 6 + distance, jump_count = jump_peak * 2; + time /= Math.max(core.status.replay.speed, 1) return { x: sx, y: sy, ex: ex, ey: ey, px: 32 * sx, py: 32 * sy, opacity: 1, jump_peak: jump_peak, jump_count: jump_count, @@ -1751,6 +1753,7 @@ maps.prototype.animateBlock = function (loc, type, time, callback) { return; } this._animateBlock_drawList(list, isHide ? 1 : 0); + time /= Math.max(core.status.replay.speed, 1) this._animateBlock_doAnimate(loc, list, isHide, 10 / time, callback); } diff --git a/libs/ui.js b/libs/ui.js index 9ec62374..67e5ad85 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -971,6 +971,7 @@ ui.prototype.drawScrollText = function (content, time, lineHeight, callback) { ui.prototype._drawScrollText_animate = function (ctx, time, callback) { // 开始绘制到UI上 + time /= Math.max(core.status.replay.speed, 1) var per_pixel = 1, height = ctx.canvas.height, per_time = time * per_pixel / (this.PIXEL+height); var currH = this.PIXEL; core.drawImage('ui', ctx.canvas, 0, currH); From 9e9025e08980e727214fd40161547ffe643daa55 Mon Sep 17 00:00:00 2001 From: oc Date: Sun, 28 Apr 2019 20:29:51 +0800 Subject: [PATCH 08/25] openDoor async & battle loc & trigger keep --- _docs/event.md | 51 +++++++++++++++++------------------ _server/MotaAction.g4 | 57 +++++++++++++++++++++++++++++---------- _server/editor_blockly.js | 1 + libs/events.js | 21 ++++++++++----- 4 files changed, 83 insertions(+), 47 deletions(-) diff --git a/_docs/event.md b/_docs/event.md index 309e6a7e..dd104f48 100644 --- a/_docs/event.md +++ b/_docs/event.md @@ -180,7 +180,7 @@ 我们可以给文字加上标题或图标,只要以`\t[...]`开头就可以。 -其一般写法是`\t[名字,ID]`,其中名字为你要显示的标题,ID为图块ID,只能为`hero`,或者NPC/怪物的图块ID。 +其一般写法是`\t[名字,ID]`,其中名字为你要显示的标题,ID为图块ID,只能为open`hero`,或者NPC/怪物的图块ID。 如果不需要可以不写ID,则只会显示标题。 @@ -574,24 +574,22 @@ NPC对话事件结束后如果需要NPC消失也需要调用 `{"type": "hide"}` `{"type":"trigger"}` 会立刻触发当层另一个地点的自定义事件。 -上面我们说到,show事件会让一个禁用事件启用且可被交互;但是如果我想立刻让它执行应该怎么办呢?使用trigger就行。 - 其基本写法如下: ``` js [ {"type": "trigger", "loc": [3,6]}, // 立即触发loc位置的事件,当前剩下的事件全部不再执行 - "执行trigger后,这段文字将不会再被显示" + {"type": "trigger", "loc": [3,6], "keep": true}, // 触发loc位置的事件,不结束当前事件 ] ``` 其后面带有loc选项,代表另一个地点的坐标。 -执行trigger事件后,当前事件将立刻被结束,剩下所有内容被忽略;然后重新启动另一个地点的action事件。 +keep可选,如果此项为true则不会结束当前的事件列表,否则会中断当前的事件流。 -例如上面这个例子,下面的文字将不会再被显示,而是直接跳转到`"3,6"`对应的事件列表从头执行。 +从V2.5.4开始允许执行另一个点的系统事件,如打怪开门拾取道具等等,对应点的战后等事件也会被插入执行。 -!> 从V2.5.4开始,允许执行另一个点的“系统事件”,如打怪、开门、拾取道具等等。对应点的战后事件等也会被执行。 +值得注意的是,此事件会**改变当前点坐标**为目标点。 ### insert:插入公共事件或另一个地点的事件并执行 @@ -619,11 +617,12 @@ NPC对话事件结束后如果需要NPC消失也需要调用 `{"type": "hide"}` - floorId可选,代表另一个地点所在的楼层;如果不写则默认为当前层。 - 从V2.6开始,还可以传可选的which,可以为`afterBattle`/`afterGetItem`/`afterOpenDoor`,代表插入该点的战后/获得道具后/开门后事件。 -和`type:trigger`不同的是,**`type:trigger`是立刻将当前事件结束(剩下所有内容都忽略),然后重新启动另一个地点的action事件。** +和`type:trigger`不同点如下: +- `type:trigger`只能指定当前楼层且会改变当前点坐标,`type:insert`可以跨楼层且不会改变当前点坐标。 +- `type:trigger`如果不设置`keep:true`则还会结束当前事件,`type:insert`而是将另一个点的事件插入到当前事件列表中执行。 +- `type:trigger`可以触发系统事件,`type:insert`只能触发该点的自定义事件或战后事件等。 -但是`type:insert`不会结束当前事件,而是直接将另一个地点的事件列表“插入”到当前事件列表中执行。 - -**这个过程中,当前事件不会被结束,当前的楼层和事件坐标不会发生改变。** 插入的事件执行完毕后,会继续执行接下来的内容。 +插入的事件执行完毕后,会继续执行接下来的内容。 从V2.6开始,插入事件允许传参。如果需要传参,则需要增加一个`args`数组。 @@ -840,28 +839,20 @@ name是可选的,代表目标行走图的文件名。 调用battle可强制与某怪物进行战斗(而无需去触碰到它)。 -其基本写法是: `{"type": "battle", "id": xxx}`,其中xxx为怪物ID。 - ``` js [ - "\t[blackKing]你终于还是来了。", - "\t[hero]放开我们的公主!", - "\t[blackKing]如果我不愿意呢?", - "\t[hero]无需多说,拔剑吧!", - {"type": "battle", "id": "blackKing"}, // 强制战斗 - // 如果战斗失败直接死亡,不会继续触发接下来的剧情。 - {"type": "hide", "loc": [10,2]}, // 战斗后需要手动使怪物消失;战斗后不会引发afterBattle事件。 - {"type": "openDoor", "loc": [8,7]}, // 开门口的机关门 - "\t[blackKing]没想到你已经变得这么强大了... 算你厉害。\n公主就交给你了,请好好对她。", - {"type": "hide"} // 隐藏本事件 + {"type": "battle", "id": "blackKing"}, // 强制战斗黑衣魔王 + {"type": "battle", "loc": [2,3]}, // 强制战斗(2,3)点的怪物 ], ``` -上面就是样板层中右上角的强制战斗例子。 +从V2.6开始,有两种写法: +- 写id,则视为和空降怪物进行强制战斗,不会执行一些战后事件,也不会隐藏任何点。 +- 写loc(可选,不填默认当前点),则视为和某点怪物进行强制战斗,会隐藏该点并且插入该点战后事件执行。 -如果强制战斗失败,则会立刻生命归0并死亡,调用lose函数,接下来的事件不会再被执行。 +强制战斗不会自动存档,如果战斗失败则立刻死亡。 -强制战斗没有指定loc的选项,因此战斗后需要调用hide使怪物消失(如果有必要)。 +值得注意的是,如果是和某个点的怪物强制战斗,并且该点存在战后事件,执行时会**修改当前点坐标**为目标点。 ### openDoor:开门 @@ -871,7 +862,7 @@ name是可选的,代表目标行走图的文件名。 [ {"type": "openDoor", "loc": [3,6], "floorId": "MT1"}, // 打开MT1层的[3,6]位置的门 {"type": "openDoor", "loc": [3,6]}, // 如果是本层则可省略floorId - {"type": "openDoor", "loc": [3,6], "needKey": true} // 打开此门需要钥匙 + {"type": "openDoor", "loc": [3,6], "needKey": true, "async": true} // 打开此门需要钥匙,异步执行 ] ``` @@ -883,8 +874,12 @@ loc指定门的坐标,floorId指定门所在的楼层ID。如果是当前层 needKey是可选的,如果设置为true则需要钥匙才能打开此门。如果没有钥匙则跳过此事件。 +async可选,如果为true则会异步执行(即不等待当前事件执行完毕,立刻执行下一个事件)。 + !> needKey仅对当前楼层开门有效!跨楼层的门仍然不需要钥匙即可打开,如有需求请自行判定。 +值得注意的是,如果该点存在开门事件,执行时会**修改当前点坐标**为目标点。 + ### closeDoor:关门 从V2.6开始提供了关门事件`{"type": "closeDoor"}`,拥有关门动画和对应的音效。 @@ -907,6 +902,8 @@ yellowWall, blueWall, whiteWall loc可选,为要关的位置,不填默认为当前点。 +async可选,如果为true则会异步执行(即不等待当前事件执行完毕,立刻执行下一个事件)。 + 关门事件需要保证该点是空地,否则将无视此事件。 ### changeFloor:楼层切换 diff --git a/_server/MotaAction.g4 b/_server/MotaAction.g4 index 2d8a580e..5165f962 100644 --- a/_server/MotaAction.g4 +++ b/_server/MotaAction.g4 @@ -287,6 +287,7 @@ action | wait_s | waitAsync_s | battle_s + | battle_1_s | openDoor_s | closeDoor_s | changeFloor_s @@ -643,15 +644,16 @@ return code; */; trigger_s - : '触发事件' 'x' PosString ',' 'y' PosString Newline + : '触发事件' 'x' PosString ',' 'y' PosString '不结束当前事件' Bool Newline /* trigger_s tooltip : trigger: 立即触发另一个地点的事件 helpUrl : https://h5mota.com/games/template/docs/#/event?id=trigger%EF%BC%9A%E7%AB%8B%E5%8D%B3%E8%A7%A6%E5%8F%91%E5%8F%A6%E4%B8%80%E4%B8%AA%E5%9C%B0%E7%82%B9%E7%9A%84%E4%BA%8B%E4%BB%B6 -default : ["0","0"] +default : ["0","0",false] colour : this.eventColor -var code = '{"type": "trigger", "loc": ['+PosString_0+','+PosString_1+']},\n'; +Bool_0 = Bool_0 ?', "keep": true':''; +var code = '{"type": "trigger", "loc": ['+PosString_0+','+PosString_1+']'+Bool_0+'},\n'; return code; */; @@ -984,14 +986,32 @@ var code = '{"type": "battle", "id": "'+IdString_0+'"},\n'; return code; */; + +battle_1_s + : '强制战斗' 'x' PosString? ',' 'y' PosString? Newline + + +/* battle_1_s +tooltip : battle: 强制战斗 +helpUrl : https://h5mota.com/games/template/docs/#/event?id=battle%EF%BC%9A%E5%BC%BA%E5%88%B6%E6%88%98%E6%96%97 +default : ["","",""] +colour : this.mapColor +var floorstr = ''; +if (PosString_0 && PosString_1) { + floorstr = ', "loc": ['+PosString_0+','+PosString_1+']'; +} +var code = '{"type": "battle"'+floorstr+'},\n'; +return code; +*/; + openDoor_s - : '开门' 'x' PosString? ',' 'y' PosString? '楼层' IdString? '需要钥匙' Bool? Newline + : '开门' 'x' PosString? ',' 'y' PosString? '楼层' IdString? '需要钥匙' Bool? '不等待执行完毕' Bool Newline /* openDoor_s tooltip : openDoor: 开门,楼层可不填表示当前层 helpUrl : https://h5mota.com/games/template/docs/#/event?id=opendoor%EF%BC%9A%E5%BC%80%E9%97%A8 -default : ["","","",false] +default : ["","","",false,false] colour : this.mapColor IdString_0 = IdString_0 && (', "floorId": "'+IdString_0+'"'); var floorstr = ''; @@ -999,24 +1019,26 @@ if (PosString_0 && PosString_1) { floorstr = ', "loc": ['+PosString_0+','+PosString_1+']'; } Bool_0 = Bool_0 ? ', "needKey": true' : ''; -var code = '{"type": "openDoor"'+floorstr+IdString_0+Bool_0+'},\n'; +Bool_1 = Bool_1 ? ', "async": true' : ''; +var code = '{"type": "openDoor"'+floorstr+IdString_0+Bool_0+Bool_1+'},\n'; return code; */; closeDoor_s - : '关门' 'x' PosString? ',' 'y' PosString? 'ID' IdString Newline + : '关门' 'x' PosString? ',' 'y' PosString? 'ID' IdString '不等待执行完毕' Bool Newline /* closeDoor_s tooltip : closeDoor: 关门事件,需要该点本身无事件 helpUrl : https://h5mota.com/games/template/docs/#/event?id=opendoor%EF%BC%9A%E5%BC%80%E9%97%A8 -default : ["","","yellowDoor"] +default : ["","","yellowDoor",false] colour : this.mapColor var floorstr = ''; if (PosString_0 && PosString_1) { floorstr = ', "loc": ['+PosString_0+','+PosString_1+']'; } -var code = '{"type": "closeDoor", "id": "'+IdString_0+'"'+floorstr+'},\n'; +Bool_0 = Bool_0 ? ', "async": true' : ''; +var code = '{"type": "closeDoor", "id": "'+IdString_0+'"'+floorstr+Bool_0+'},\n'; return code; */; @@ -2532,12 +2554,12 @@ ActionParser.prototype.parseAction = function() { case "openDoor": // 开一个门, 包括暗墙 data.loc=data.loc||['',''] this.next = MotaActionBlocks['openDoor_s'].xmlText([ - data.loc[0],data.loc[1],data.floorId||'',data.needKey||false,this.next]); + data.loc[0],data.loc[1],data.floorId||'',data.needKey||false,data.async||false,this.next]); break; case "closeDoor": // 关一个门,需要该点无事件 data.loc=data.loc||['',''] this.next = MotaActionBlocks['closeDoor_s'].xmlText([ - data.loc[0],data.loc[1],data.id,this.next]); + data.loc[0],data.loc[1],data.id,data.async||false,this.next]); break; case "useItem": // 使用道具 this.next = MotaActionBlocks['useItem_s'].xmlText([ @@ -2552,12 +2574,19 @@ ActionParser.prototype.parseAction = function() { data.id,this.next]); break; case "battle": // 强制战斗 - this.next = MotaActionBlocks['battle_s'].xmlText([ - data.id,this.next]); + if (data.id) { + this.next = MotaActionBlocks['battle_s'].xmlText([ + data.id,this.next]); + } + else { + data.loc = data.loc || []; + this.next = MotaActionBlocks['battle_1_s'].xmlText([ + data.loc[0],data.loc[1],this.next]); + } break; case "trigger": // 触发另一个事件;当前事件会被立刻结束。需要另一个地点的事件是有效的 this.next = MotaActionBlocks['trigger_s'].xmlText([ - data.loc[0],data.loc[1],this.next]); + data.loc[0],data.loc[1],data.keep,this.next]); break; case "insert": // 强制插入另一个点的事件在当前事件列表执行,当前坐标和楼层不会改变 if (data.args instanceof Array) { diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index 44b03be5..b81d675a 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -112,6 +112,7 @@ editor_blockly = function () { MotaActionBlocks['unfollow_s'].xmlText(), ], '地图处理':[ + MotaActionBlocks['battle_1_s'].xmlText(), MotaActionBlocks['openDoor_s'].xmlText(), MotaActionBlocks['closeDoor_s'].xmlText(), MotaActionBlocks['show_s'].xmlText(), diff --git a/libs/events.js b/libs/events.js index 1eb1ad15..cfa68e7d 100644 --- a/libs/events.js +++ b/libs/events.js @@ -419,20 +419,23 @@ events.prototype._openDoor_animate = function (id, x, y, callback) { var locked = core.status.lockControl; core.lockControl(); core.status.replay.animate = true; + core.removeBlock(x, y); + core.drawImage('event', core.material.images.animates, 0, 32 * door, 32, 32, 32 * x, 32 * y, 32, 32); var state = 0; var animate = window.setInterval(function () { + core.clearMap('event', 32 * x, 32 * y, 32, 32); state++; if (state == 4) { clearInterval(animate); - core.removeBlock(x, y); + delete core.animateFrame.asyncId[animate]; if (!locked) core.unLockControl(); core.status.replay.animate = false; core.events.afterOpenDoor(id, x, y, callback); return; } - core.clearMap('event', 32 * x, 32 * y, 32, 32); core.drawImage('event', core.material.images.animates, 32 * state, 32 * door, 32, 32, 32 * x, 32 * y, 32, 32); }, speed / Math.max(core.status.replay.speed, 1)); + core.animateFrame.asyncId[animate] = true; } ////// 开一个门后触发的事件 ////// @@ -1133,7 +1136,7 @@ events.prototype._action_openDoor = function (data, x, y, prefix) { var loc = this.__action_getLoc(data.loc, x, y, prefix); var floorId = data.floorId || core.status.floorId; if (floorId == core.status.floorId) { - core.openDoor(loc[0], loc[1], data.needKey, core.doAction); + this.__action_doAsyncFunc(data.async, core.openDoor, loc[0], loc[1], data.needKey); } else { core.removeBlock(loc[0], loc[1], floorId); @@ -1172,7 +1175,13 @@ events.prototype._action_disableShop = function (data, x, y, prefix) { } events.prototype._action_battle = function (data, x, y, prefix) { - this.battle(data.id, null, null, true, core.doAction); + if (data.id) { + this.battle(data.id, null, null, true, core.doAction); + } + else { + var loc = this.__action_getLoc(data.loc, x, y, prefix); + this.battle(null, loc[0], loc[1], true, core.doAction); + } } events.prototype._action_trigger = function (data, x, y, prefix) { @@ -1180,9 +1189,9 @@ events.prototype._action_trigger = function (data, x, y, prefix) { var block = core.getBlock(loc[0], loc[1]); if (block != null && block.block.event.trigger) { block = block.block; - this.setEvents([], block.x, block.y); + this.setEvents(data.keep ? null : [], block.x, block.y); if (block.event.trigger == 'action') - this.setEvents(block.event.data); + this.insertAction(block.event.data); else { core.doSystemEvent(block.event.trigger, block, core.doAction); return; From f6ac9610cc91b9f7bf1c015ad4f02036b608cf3b Mon Sep 17 00:00:00 2001 From: oc Date: Sun, 28 Apr 2019 21:14:14 +0800 Subject: [PATCH 09/25] hero any width --- _docs/event.md | 2 +- libs/control.js | 15 +++++++++------ libs/events.js | 13 +++++++------ libs/ui.js | 22 ++++++++++++++++------ project/functions.js | 1 + project/icons.js | 1 + 6 files changed, 35 insertions(+), 19 deletions(-) diff --git a/_docs/event.md b/_docs/event.md index dd104f48..1df664c1 100644 --- a/_docs/event.md +++ b/_docs/event.md @@ -180,7 +180,7 @@ 我们可以给文字加上标题或图标,只要以`\t[...]`开头就可以。 -其一般写法是`\t[名字,ID]`,其中名字为你要显示的标题,ID为图块ID,只能为open`hero`,或者NPC/怪物的图块ID。 +其一般写法是`\t[名字,ID]`,其中名字为你要显示的标题,ID为图块ID,只能为`hero`,或者NPC/怪物的图块ID。 如果不需要可以不写ID,则只会显示标题。 diff --git a/libs/control.js b/libs/control.js index 36bdf40c..4145e01e 100644 --- a/libs/control.js +++ b/libs/control.js @@ -777,9 +777,9 @@ control.prototype.drawHero = function (status, offset) { core.clearMap('hero'); this._drawHero_getDrawObjs(direction, x, y, status, offset).forEach(function (block) { - core.drawImage('hero', block.img, block.heroIcon[block.status]*32, - block.heroIcon.loc * block.height, 32, block.height, - block.posx, block.posy+32-block.height, 32, block.height); + core.drawImage('hero', block.img, block.heroIcon[block.status]*block.width, + block.heroIcon.loc * block.height, block.width, block.height, + block.posx+(32-block.width)/2, block.posy+32-block.height, block.width, block.height); }); core.control.updateViewport(); @@ -789,6 +789,7 @@ control.prototype._drawHero_getDrawObjs = function (direction, x, y, status, off var heroIconArr = core.material.icons.hero, drawObjs = [], index = 0; drawObjs.push({ "img": core.material.images.hero, + "width": core.material.icons.hero.width || 32, "height": core.material.icons.hero.height, "heroIcon": heroIconArr[direction], "posx": x * 32 - core.bigmap.offsetX + core.utils.scan[direction].x * offset, @@ -799,6 +800,7 @@ control.prototype._drawHero_getDrawObjs = function (direction, x, y, status, off (core.status.hero.followers||[]).forEach(function (t) { drawObjs.push({ "img": core.material.images.images[t.name], + "width": core.material.images.images[t.name].width/4, "height": core.material.images.images[t.name].height/4, "heroIcon": heroIconArr[t.direction], "posx": 32*t.x - core.bigmap.offsetX + (t.stop?0:core.utils.scan[t.direction].x*offset), @@ -2345,14 +2347,15 @@ control.prototype.updateHeroIcon = function (name) { var image = core.material.images.hero; // 全身图 - var height = core.material.icons.hero.height; - var ratio = 32 / height, width = 32 * ratio, left = 16-width/2; + var w = core.material.icons.hero.width || 32; + var h = core.material.icons.hero.height || 48; + var ratio = Math.max(w / h, 1), width = 32 * ratio, left = 16 - width/2; var canvas = document.createElement("canvas"); var context = canvas.getContext("2d"); canvas.width = 32; canvas.height = 32; - context.drawImage(image, 0, 0, 32, height, left, 0, width, 32); + context.drawImage(image, 0, 0, w, h, left, 0, width, 32); core.statusBar.image.name.src = canvas.toDataURL("image/png"); } diff --git a/libs/events.js b/libs/events.js index cfa68e7d..64bb9cb3 100644 --- a/libs/events.js +++ b/libs/events.js @@ -1758,8 +1758,7 @@ events.prototype.hasAsync = function () { events.prototype.follow = function (name) { core.status.hero.followers = core.status.hero.followers || []; name = core.getMappedName(name); - if (core.material.images.images[name] - && core.material.images.images[name].width == 128) { + if (core.material.images.images[name]) { core.status.hero.followers.push({"name": name}); core.gatherFollowers(); core.clearMap('hero'); @@ -2139,6 +2138,7 @@ events.prototype.jumpHero = function (ex, ey, time, callback) { core.playSound('jump.mp3'); var jumpInfo = core.maps.__generateJumpInfo(sx, sy, ex, ey, time || 500); jumpInfo.icon = core.material.icons.hero[core.getHeroLoc('direction')]; + jumpInfo.width = core.material.icons.hero.width || 32; jumpInfo.height = core.material.icons.hero.height; this._jumpHero_doJump(jumpInfo, callback); @@ -2158,12 +2158,12 @@ events.prototype._jumpHero_doJump = function (jumpInfo, callback) { events.prototype._jumpHero_jumping = function (jumpInfo) { core.clearMap('hero'); core.maps.__updateJumpInfo(jumpInfo); - var nowx = jumpInfo.px, nowy = jumpInfo.py, height = jumpInfo.height; + var nowx = jumpInfo.px, nowy = jumpInfo.py, width = jumpInfo.width || 32, height = jumpInfo.height; core.bigmap.offsetX = core.clamp(nowx - 32*core.__HALF_SIZE__, 0, 32*core.bigmap.width-core.__PIXELS__); core.bigmap.offsetY = core.clamp(nowy - 32*core.__HALF_SIZE__, 0, 32*core.bigmap.height-core.__PIXELS__); core.control.updateViewport(); - core.drawImage('hero', core.material.images.hero, jumpInfo.icon.stop, jumpInfo.icon.loc * height, 32, height, - nowx - core.bigmap.offsetX, nowy + 32-height - core.bigmap.offsetY, 32, height); + core.drawImage('hero', core.material.images.hero, jumpInfo.icon.stop, jumpInfo.icon.loc * height, width, height, + nowx + (32 - width) / 2 - core.bigmap.offsetX, nowy + 32-height - core.bigmap.offsetY, width, height); } events.prototype._jumpHero_finished = function (animate, ex, ey, callback) { @@ -2251,9 +2251,10 @@ events.prototype.canUseQuickShop = function (shopId) { events.prototype.setHeroIcon = function (name, noDraw) { name = core.getMappedName(name); var img = core.material.images.images[name]; - if (!img || img.width != 128) return; + if (!img) return; core.setFlag("heroIcon", name); core.material.images.hero.onload = function () { + core.material.icons.hero.width = img.width / 4; core.material.icons.hero.height = img.height / 4; core.control.updateHeroIcon(name); if (!noDraw) core.drawHero(); diff --git a/libs/ui.js b/libs/ui.js index 67e5ad85..aca20dd8 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -373,7 +373,8 @@ ui.prototype._getTitleAndIcon = function (content) { title = core.status.hero.name; image = core.material.images.hero; icon = 0; - height = core.material.icons.hero.height; + var w = core.material.icons.hero.width || 32; + height = 32 * core.material.icons.hero.height / w; } else if (s4.endsWith(".png")) { s4 = core.getMappedName(s4); @@ -928,11 +929,20 @@ ui.prototype._drawTextBox_drawTitleAndIcon = function (titleInfo, hPos, vPos, al core.strokeRect('ui', hPos.left + 15 - 1, image_top-1, 34, titleInfo.height + 2, null, 2); core.setAlpha('ui', 1); core.status.boxAnimateObjs = []; - core.status.boxAnimateObjs.push({ - 'bgx': hPos.left + 15, 'bgy': image_top, 'bgWidth': 32, 'bgHeight': titleInfo.height, - 'x': hPos.left + 15, 'y': image_top, 'height': titleInfo.height, 'animate': titleInfo.animate, - 'image': titleInfo.image, 'pos': titleInfo.icon * titleInfo.height - }); + // --- 勇士 + if (titleInfo.image == core.material.images.hero) { + core.clearMap('ui', hPos.left + 15, image_top, 32, titleInfo.height); + core.fillRect('ui', hPos.left + 15, image_top, 32, titleInfo.height, core.material.groundPattern); + core.drawImage('ui', titleInfo.image, 0, 0, core.material.icons.hero.width || 32, core.material.icons.hero.height, + hPos.left + 15, image_top, 32, titleInfo.height); + } + else { + core.status.boxAnimateObjs.push({ + 'bgx': hPos.left + 15, 'bgy': image_top, 'bgWidth': 32, 'bgHeight': titleInfo.height, + 'x': hPos.left + 15, 'y': image_top, 'height': titleInfo.height, 'animate': titleInfo.animate, + 'image': titleInfo.image, 'pos': titleInfo.icon * titleInfo.height + }); + } core.drawBoxAnimate(); } if (titleInfo.image != null && titleInfo.icon == null) { // 头像图 diff --git a/project/functions.js b/project/functions.js index 5b007f7a..e2497c87 100644 --- a/project/functions.js +++ b/project/functions.js @@ -973,6 +973,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = icon = core.getMappedName(icon); if (core.material.images.images[icon]) { core.material.images.hero.src = core.material.images.images[icon].src; + core.material.icons.hero.width = core.material.images.images[icon].width / 4; core.material.icons.hero.height = core.material.images.images[icon].height / 4; } // 刷新怪物数据 diff --git a/project/icons.js b/project/icons.js index 0fe339c2..e9d0ae7c 100644 --- a/project/icons.js +++ b/project/icons.js @@ -25,6 +25,7 @@ var icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1 = "leftFoot": 1, "rightFoot": 3 }, + "width": 32, "height": 48 }, "terrains": { From 6724234133b2f40833f221114752d0145844d17a Mon Sep 17 00:00:00 2001 From: oc Date: Sun, 28 Apr 2019 21:36:01 +0800 Subject: [PATCH 10/25] useShop space & longclick --- libs/actions.js | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/libs/actions.js b/libs/actions.js index ffe68124..75a43b8b 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -251,6 +251,8 @@ actions.prototype._sys_keyDown_lockControl = function (keyCode) { this._keyDownSL(keyCode); break; case 'shop': + this._keyDownShop(keyCode); + break; case 'selectShop': case 'switchs': case 'settings': @@ -760,13 +762,17 @@ actions.prototype._sys_longClick_lockControl = function (x, y) { return true; } } - // 长按SL快速翻页 + // 长按SL上下页快速翻页 if (["save","load","replayLoad","replayRemain"].indexOf(core.status.event.id) >= 0) { if ([this.HSIZE-2, this.HSIZE-3, this.HSIZE+2, this.HSIZE+3].indexOf(x) >= 0 && y == this.LAST) { this._clickSL(x, y); return true; } } + // 长按商店连续购买 + if (core.status.event.id == 'shop' && x >= this.CHOICES_LEFT && x <= this.CHOICES_RIGHT) { + return this._clickShop(x, y); + } // 长按可以跳过等待事件 if (core.status.event.id == 'action' && core.status.event.data.type == 'sleep' && !core.status.event.data.current.noSkip) { @@ -918,7 +924,7 @@ actions.prototype._clickAction = function (x, y) { core.insertAction(core.status.event.ui.yes); core.doAction(); } - if ((x == this.HSIZE+2 || x == this.HSIZE+1) && y == this.HSIZE+1) { + else if ((x == this.HSIZE+2 || x == this.HSIZE+1) && y == this.HSIZE+1) { core.status.route.push("choices:1"); core.insertAction(core.status.event.ui.no); core.doAction(); @@ -1245,13 +1251,25 @@ actions.prototype._clickShop = function (x, y) { return true; } +actions.prototype._keyDownShop = function (keycode) { + // 商店界面长按空格连续购买 + if (keycode == 32) { + this._selectChoices(core.status.event.data.shop.choices.length + 1, keycode, this._clickShop); + return; + } + this._keyDownChoices(keycode); +} + ////// 商店界面时,放开某个键的操作 ////// actions.prototype._keyUpShop = function (keycode) { if (keycode == 27 || keycode == 88) { core.events._exitShop(); return; } - this._selectChoices(core.status.event.data.shop.choices.length + 1, keycode, this._clickShop); + if (keycode != 32) { + this._selectChoices(core.status.event.data.shop.choices.length + 1, keycode, this._clickShop); + return; + } return; } From 9a993b13cab52cac15791dc7646906a685163d9a Mon Sep 17 00:00:00 2001 From: oc Date: Sun, 28 Apr 2019 21:50:14 +0800 Subject: [PATCH 11/25] global:xxx -> core.getLocalStorage --- _docs/event.md | 9 +++++++-- _server/MotaAction.g4 | 4 ++-- libs/events.js | 6 ++++++ libs/utils.js | 1 + 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/_docs/event.md b/_docs/event.md index 1df664c1..fb88e23e 100644 --- a/_docs/event.md +++ b/_docs/event.md @@ -287,18 +287,22 @@ 我们可以使用 `status:xxx` 代表勇士的一个属性值;`item:xxx` 代表某个道具的个数;`flag:xxx` 代表某个自定义的变量或flag值。 +从V2.6开始,也可以使用`global:xxx`代表全局存储(和存档无关的存储)。 + ``` js [ "你当前的攻击力是${status:atk}, 防御是${status:def},坐标是(${status:x},${status:y})", "你的攻防和的十倍是${10*(status:atk+status:def)}", "你的红黄蓝钥匙总数为${item:yellowKey+item:blueKey+item:redKey}", "你访问某个老人的次数为${flag:man_times}", + "当前的存档编号是${global:saveIndex}", ] ``` - `status:xxx` 获取勇士属性时只能使用如下几个:hp(生命值),atk(攻击力),def(防御力),mdef(魔防值),money(金币),experience(经验),x(勇士的横坐标),y(勇士的纵坐标),direction(勇士的方向)。 - `item:xxx` 中的xxx为道具ID。所有道具的ID定义在items.js中,请自行查看。例如,`item:centerFly` 代表中心对称飞行器的个数。 -- `flag:xxx` 中的xxx为一个自定义的变量/Flag;如果没有对其进行赋值则默认值为false。 +- `flag:xxx` 中的xxx为一个自定义的变量/Flag(支持中文);如果没有对其进行赋值则默认值为0。 +- `global:xxx` 中的xxx为一个全局存储的名称(支持中文);如果没有对其进行赋值则默认值为0。 ### autoText:自动剧情文本 @@ -417,7 +421,7 @@ icon是可选的,如果设置则会绘制图标,其可以是一个有效的I name为你要修改的属性/道具/Flag,每次只能修改一个值。写法和上面完全相同,`status:xxx` 表示勇士一个属性,`item:xxx` 表示某个道具个数,`flag:xxx` 表示某个变量或flag值。参见上面的介绍。 -value是一个表达式,将通过这个表达式计算出的结果赋值给name。该表达式同样可以使用`status:xxx`, `item:xxx`, `flag:xxx`的写法表示勇士当前属性,道具个数和某个变量/Flag值。 +value是一个表达式,将通过这个表达式计算出的结果赋值给name。该表达式同样可以使用`status:xxx`, `item:xxx`, `flag:xxx`, `global:xxx`的写法表示勇士当前属性,道具个数,某个变量/Flag值和某个全局存储值。 ``` js [ @@ -428,6 +432,7 @@ value是一个表达式,将通过这个表达式计算出的结果赋值给nam {"type": "setValue", "name": "item:bomb", "value": "item:bomb+10" } // 炸弹个数+10 {"type": "setValue", "name": "flag:man_times", "value": "0" } // 将变量man_times设为0 {"type": "setValue", "name": "flag:man_times", "value": "flag:man_times+2*status:atk" } // 将变量man_times的值加上勇士的攻击数值的两倍 + {"type": "setValue", "name": "global:123", "value": "4"} // 设置全局存储233为4(任何存档都可以读取它) ] ``` diff --git a/_server/MotaAction.g4 b/_server/MotaAction.g4 index 5165f962..0619d740 100644 --- a/_server/MotaAction.g4 +++ b/_server/MotaAction.g4 @@ -2135,8 +2135,8 @@ FixedId_List /*FixedId_List ['status:hp','status:atk','status:def','status:mdef','item:yellowKey','item:blueKey','item:redKey','status:money','status:experience']*/; Id_List - : '变量' | '状态' | '物品' | '独立开关' - /*Id_List ['flag','status','item', 'switch']*/; + : '变量' | '状态' | '物品' | '独立开关' | '全局存储' + /*Id_List ['flag','status','item', 'switch', 'global']*/; //转blockly后不保留需要加" EvalString diff --git a/libs/events.js b/libs/events.js index 64bb9cb3..949a7b00 100644 --- a/libs/events.js +++ b/libs/events.js @@ -1794,6 +1794,7 @@ events.prototype.setValue = function (name, value, prefix, add) { this._setValue_setItem(name, value); this._setValue_setFlag(name, value); this._setValue_setSwitch(name, value, prefix); + this._setValue_setGlobal(name, value); core.updateStatusBar(); } @@ -1824,6 +1825,11 @@ events.prototype._setValue_setSwitch = function (name, value, prefix) { core.setFlag((prefix || ":f@x@y") + "@" + name.substring(7), value); } +events.prototype._setValue_setGlobal = function (name, value) { + if (name.indexOf("global:") !== 0) return; + core.setLocalStorage(name.substring(7), value); +} + ////// 数值增减 ////// events.prototype.addValue = function (name, value, prefix) { this.setValue(name, value, prefix, true); diff --git a/libs/utils.js b/libs/utils.js index 76494f55..cf255416 100644 --- a/libs/utils.js +++ b/libs/utils.js @@ -67,6 +67,7 @@ utils.prototype.calValue = function (value, prefix, need, times) { value = value.replace(/item:([a-zA-Z0-9_]+)/g, "core.itemCount('$1')"); value = value.replace(/flag:([a-zA-Z0-9_\u4E00-\u9FCC]+)/g, "core.getFlag('$1', 0)"); value = value.replace(/switch:([a-zA-Z0-9_]+)/g, "core.getFlag('" + (prefix || ":f@x@y") + "@$1', 0)"); + value = value.replace(/global:([a-zA-Z0-9_\u4E00-\u9FCC]+)/g, "core.getLocalStorage('$1', 0)"); return eval(value); } if (value instanceof Function) { From 45101d43f6085e953470f64d55c6c7a18bd3d6ce Mon Sep 17 00:00:00 2001 From: YouWei Zhao Date: Sun, 28 Apr 2019 10:21:07 -0400 Subject: [PATCH 12/25] .g4-regex --- _server/MotaAction.g4 | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/_server/MotaAction.g4 b/_server/MotaAction.g4 index 0619d740..3c4b086a 100644 --- a/_server/MotaAction.g4 +++ b/_server/MotaAction.g4 @@ -442,7 +442,7 @@ helpUrl : https://h5mota.com/games/template/docs/#/event?id=settext%EF%BC%9A%E8% default : [null,"",null,"",'rgba(255,255,255,1)',"",'rgba(255,255,255,1)',"",'rgba(255,255,255,1)',null,"","",""] SetTextPosition_List_0 =SetTextPosition_List_0==='null'?'': ', "position": "'+SetTextPosition_List_0+'"'; SetTextAlign_List_0 =SetTextAlign_List_0==='null'?'': ', "align": "'+SetTextAlign_List_0+'"'; -var colorRe = /^(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(,0(\.\d+)?|,1)?$/; +var colorRe = MotaActionFunctions.pattern.colorRe; if (EvalString_0) { if (!/^\d+$/.test(EvalString_0))throw new Error('像素偏移量必须是整数或不填'); EvalString_0 = ', "offset": '+EvalString_0; @@ -588,7 +588,7 @@ default : ["","","",500,false] colour : this.mapColor var floorstr = ''; if (EvalString_0 && EvalString_1) { - var pattern1 = /^flag:([a-zA-Z0-9_\u4E00-\u9FCC]+)$/; + var pattern1 = MotaActionFunctions.pattern.id; if(pattern1.test(EvalString_0) || pattern1.test(EvalString_1)){ EvalString_0=MotaActionFunctions.PosString_pre(EvalString_0); EvalString_1=MotaActionFunctions.PosString_pre(EvalString_1); @@ -621,7 +621,7 @@ default : ["","","",500,false] colour : this.mapColor var floorstr = ''; if (EvalString_0 && EvalString_1) { - var pattern1 = /^flag:([a-zA-Z0-9_\u4E00-\u9FCC]+)$/; + var pattern1 = MotaActionFunctions.pattern.id; if(pattern1.test(EvalString_0) || pattern1.test(EvalString_1)){ EvalString_0=MotaActionFunctions.PosString_pre(EvalString_0); EvalString_1=MotaActionFunctions.PosString_pre(EvalString_1); @@ -763,7 +763,7 @@ default : ["","",""] colour : this.mapColor var floorstr = ''; if (EvalString_0 && EvalString_1) { - var pattern1 = /^flag:([a-zA-Z0-9_\u4E00-\u9FCC]+)$/; + var pattern1 = MotaActionFunctions.pattern.id; if(pattern1.test(EvalString_0) || pattern1.test(EvalString_1)){ EvalString_0=MotaActionFunctions.PosString_pre(EvalString_0); EvalString_1=MotaActionFunctions.PosString_pre(EvalString_1); @@ -794,7 +794,7 @@ default : ["","",""] colour : this.mapColor var floorstr = ''; if (EvalString_0 && EvalString_1) { - var pattern1 = /^flag:([a-zA-Z0-9_\u4E00-\u9FCC]+)$/; + var pattern1 = MotaActionFunctions.pattern.id; if(pattern1.test(EvalString_0) || pattern1.test(EvalString_1)){ EvalString_0=MotaActionFunctions.PosString_pre(EvalString_0); EvalString_1=MotaActionFunctions.PosString_pre(EvalString_1); @@ -825,7 +825,7 @@ default : ["bg","","",""] colour : this.mapColor var floorstr = ''; if (EvalString_0 && EvalString_1) { - var pattern1 = /^flag:([a-zA-Z0-9_\u4E00-\u9FCC]+)$/; + var pattern1 = MotaActionFunctions.pattern.id; if(pattern1.test(EvalString_0) || pattern1.test(EvalString_1)){ EvalString_0=MotaActionFunctions.PosString_pre(EvalString_0); EvalString_1=MotaActionFunctions.PosString_pre(EvalString_1); @@ -856,7 +856,7 @@ default : ["bg","","",""] colour : this.mapColor var floorstr = ''; if (EvalString_0 && EvalString_1) { - var pattern1 = /^flag:([a-zA-Z0-9_\u4E00-\u9FCC]+)$/; + var pattern1 = MotaActionFunctions.pattern.id; if(pattern1.test(EvalString_0) || pattern1.test(EvalString_1)){ EvalString_0=MotaActionFunctions.PosString_pre(EvalString_0); EvalString_1=MotaActionFunctions.PosString_pre(EvalString_1); @@ -1179,7 +1179,7 @@ helpUrl : https://h5mota.com/games/template/docs/#/event?id=animate%EF%BC%9A%E6% default : ["zone","hero",false] colour : this.soundColor if (EvalString_0) { - if(/^flag:([a-zA-Z0-9_\u4E00-\u9FCC]+),flag:([a-zA-Z0-9_\u4E00-\u9FCC]+)$/.test(EvalString_0)) { + if(MotaActionFunctions.pattern.id2.test(EvalString_0)) { EvalString_0=', "loc": ["'+EvalString_0.split(',').join('","')+'"]'; } else if (/hero|([+-]?\d+),([+-]?\d+)/.test(EvalString_0)) { if(EvalString_0.indexOf(',')!==-1)EvalString_0='['+EvalString_0+']'; @@ -1315,7 +1315,7 @@ tooltip : setCurtain: 更改画面色调,动画时间可不填 helpUrl : https://h5mota.com/games/template/docs/#/event?id=setcurtain%EF%BC%9A%E6%9B%B4%E6%94%B9%E7%94%BB%E9%9D%A2%E8%89%B2%E8%B0%83 default : ["255,255,255,1",'rgba(255,255,255,1)',500,false] colour : this.soundColor -var colorRe = /^(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(,0(\.\d+)?|,1)?$/; +var colorRe = MotaActionFunctions.pattern.colorRe; if (!colorRe.test(EvalString_0))throw new Error('颜色格式错误,形如:0~255,0~255,0~255,0~1'); Int_0 = Int_0!=='' ?(', "time": '+Int_0):''; var async = Bool_0?', "async": true':''; @@ -1346,7 +1346,7 @@ tooltip : screenFlash: 画面闪烁,动画时间可不填 helpUrl : https://h5mota.com/games/template/docs/#/event?id=screenFlash%EF%BC%9A%E7%94%BB%E9%9D%A2%E9%97%AA%E7%83%81 default : ["255,255,255,1",'rgba(255,255,255,1)',500,1,false] colour : this.soundColor -var colorRe = /^(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(,0(\.\d+)?|,1)?$/; +var colorRe = MotaActionFunctions.pattern.colorRe; if (!colorRe.test(EvalString_0))throw new Error('颜色格式错误,形如:0~255,0~255,0~255,0~1'); Int_1 = Int_1!=='' ?(', "times": '+Int_1):''; var async = Bool_0?', "async": true':''; @@ -1704,7 +1704,7 @@ helpUrl : https://h5mota.com/games/template/docs/#/event?id=choices%EF%BC%9A%E7% default : ["提示文字:红钥匙","",""] colour : this.subColor if (EvalString_1) { - var colorRe = /^(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(,0(\.\d+)?|,1)?$/; + var colorRe = MotaActionFunctions.pattern.colorRe; if (colorRe.test(EvalString_1)) EvalString_1 = ', "color": ['+EvalString_1+']'; else @@ -2886,14 +2886,14 @@ MotaActionFunctions.EvalString_pre = function(EvalString){ MotaActionFunctions.IdString_pre = function(IdString){ if (IdString.indexOf('__door__')!==-1) throw new Error('请修改开门变量__door__,如door1,door2,door3等依次向后。请勿存在两个门使用相同的开门变量。'); - if (IdString && !(/^flag:([a-zA-Z0-9_\u4E00-\u9FCC]+)$/.test(IdString)) && !(/^[0-9a-zA-Z_][0-9a-zA-Z_\-:]*$/.test(IdString))) + if (IdString && !(MotaActionFunctions.pattern.id.test(IdString)) && !(MotaActionFunctions.pattern.idWithoutFlag.test(IdString))) throw new Error('id: '+IdString+'中包含了0-9 a-z A-Z _ - :之外的字符'); return IdString; } MotaActionFunctions.PosString_pre = function(PosString){ if (!PosString || /^-?\d+$/.test(PosString)) return PosString; - if (!(/^flag:([a-zA-Z0-9_\u4E00-\u9FCC]+)$/.test(PosString)))throw new Error(PosString+'中包含了0-9 a-z A-Z _ 和中文之外的字符,或者是没有以flag: 开头'); + if (!(MotaActionFunctions.pattern.id.test(PosString)))throw new Error(PosString+'中包含了0-9 a-z A-Z _ 和中文之外的字符,或者是没有以flag: 开头'); return '"'+PosString+'"'; } @@ -2935,4 +2935,10 @@ MotaActionFunctions.StepString_pre = function(StepString){ return ans; } +MotaActionFunctions.pattern=MotaActionFunctions.pattern||{}; +MotaActionFunctions.pattern.id=/^flag:([a-zA-Z0-9_\u4E00-\u9FCC]+)$/; +MotaActionFunctions.pattern.id2=/^flag:([a-zA-Z0-9_\u4E00-\u9FCC]+),flag:([a-zA-Z0-9_\u4E00-\u9FCC]+)$/; +MotaActionFunctions.pattern.idWithoutFlag=/^[0-9a-zA-Z_][0-9a-zA-Z_\-:]*$/; +MotaActionFunctions.pattern.colorRe=/^(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(,0(\.\d+)?|,1)?$/; + */ \ No newline at end of file From 929bf1a11bb735e233e360c339d9c16fb9c929ff Mon Sep 17 00:00:00 2001 From: oc Date: Sun, 28 Apr 2019 22:35:58 +0800 Subject: [PATCH 13/25] moveBlock forward & backward --- libs/maps.js | 51 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/libs/maps.js b/libs/maps.js index b8aaf3a9..bdac2f51 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -1615,13 +1615,13 @@ maps.prototype.moveBlock = function (x, y, steps, time, keep, callback) { } var block = blockArr[0], blockInfo = blockArr[1]; var moveSteps = (steps||[]).filter(function (t) { - return ['up','down','left','right'].indexOf(t)>=0; + return ['up','down','left','right','forward','backward'].indexOf(t)>=0; }); var canvases = this._initDetachedBlock(blockInfo, x, y, block.event.animate !== false); this._moveDetachedBlock(blockInfo, 32 * x, 32 * y, 1, canvases); var moveInfo = { - x: x, y: y, px: 32 * x, py: 32 * y, opacity: 1, keep: keep, + x: x, y: y, px: 32 * x, py: 32 * y, opacity: 1, keep: keep, lastDirection: null, offset: 1, moveSteps: moveSteps, step: 0, per_time: time / 16 / core.status.replay.speed } this._moveBlock_doMove(blockInfo, canvases, moveInfo, callback); @@ -1646,21 +1646,46 @@ maps.prototype._moveBlock_doMove = function (blockInfo, canvases, moveInfo, call core.animateFrame.asyncId[animate] = true; } -maps.prototype._moveBlock_moving = function (blockInfo, canvases, moveInfo) { +maps.prototype._moveBlock_updateDirection = function (blockInfo, moveInfo) { + moveInfo.offset = 1; var direction = moveInfo.moveSteps[0]; - if (moveInfo.step == 0) { - moveInfo.x += core.utils.scan[direction].x; - moveInfo.y += core.utils.scan[direction].y; - // 根据faceIds修改朝向 - var currid = blockInfo.faceIds[direction]; - if (currid) { - var posY = core.material.icons[blockInfo.cls][currid]; - if (posY != null) blockInfo.posY = posY; + if (moveInfo.lastDirection == null) { + for (var d in blockInfo.faceIds) { + if (blockInfo.faceIds[d] == blockInfo.id) { + moveInfo.lastDirection = d; + break; + } } } + if (direction == 'forward' || direction == 'backward') { + if (moveInfo.lastDirection == null) { + moveInfo.moveSteps.shift(); + return false; + } + if (direction == 'backward') + moveInfo.offset = -1; + direction = moveInfo.lastDirection; + } + moveInfo.lastDirection = moveInfo.moveSteps[0] = direction; + moveInfo.x += core.utils.scan[direction].x * moveInfo.offset; + moveInfo.y += core.utils.scan[direction].y * moveInfo.offset; + // 根据faceIds修改朝向 + var currid = blockInfo.faceIds[direction]; + if (currid) { + var posY = core.material.icons[blockInfo.cls][currid]; + if (posY != null) blockInfo.posY = posY; + } + return true; +} + +maps.prototype._moveBlock_moving = function (blockInfo, canvases, moveInfo) { + if (moveInfo.step == 0) { + if (!this._moveBlock_updateDirection(blockInfo, moveInfo)) return; + } + var direction = moveInfo.moveSteps[0]; moveInfo.step++; - moveInfo.px += core.utils.scan[direction].x * 2; - moveInfo.py += core.utils.scan[direction].y * 2; + moveInfo.px += core.utils.scan[direction].x * 2 * moveInfo.offset; + moveInfo.py += core.utils.scan[direction].y * 2 * moveInfo.offset; this._moveDetachedBlock(blockInfo, moveInfo.px, moveInfo.py, moveInfo.opacity, canvases); if (moveInfo.step == 16) { moveInfo.step = 0; From c4a38f4f99de7e95c974b372cb7d96a2eb341559 Mon Sep 17 00:00:00 2001 From: oc Date: Sun, 28 Apr 2019 22:38:19 +0800 Subject: [PATCH 14/25] moveBlock forward & backward --- _server/MotaAction.g4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_server/MotaAction.g4 b/_server/MotaAction.g4 index 0619d740..6e87a1ff 100644 --- a/_server/MotaAction.g4 +++ b/_server/MotaAction.g4 @@ -1376,7 +1376,7 @@ move_s /* move_s tooltip : move: 让某个NPC/怪物移动,位置可不填代表当前事件 helpUrl : https://h5mota.com/games/template/docs/#/event?id=move%EF%BC%9A%E8%AE%A9%E6%9F%90%E4%B8%AAnpc%E6%80%AA%E7%89%A9%E7%A7%BB%E5%8A%A8 -default : ["","",500,false,false,"上右3下2左上左2"] +default : ["","",500,false,false,"上右3下2后4左前2"] colour : this.mapColor var floorstr = ''; if (PosString_0 && PosString_1) { From 87696682228f04f8b475afc671c48dcbac2554d9 Mon Sep 17 00:00:00 2001 From: oc Date: Mon, 29 Apr 2019 19:34:27 +0800 Subject: [PATCH 15/25] setGlobal & getGlobal --- libs/control.js | 4 ++-- libs/events.js | 18 +++++------------- libs/utils.js | 32 ++++++++++++++++++++++++++++---- 3 files changed, 35 insertions(+), 19 deletions(-) diff --git a/libs/control.js b/libs/control.js index 4145e01e..fb836179 100644 --- a/libs/control.js +++ b/libs/control.js @@ -1300,6 +1300,7 @@ control.prototype._replay_save = function () { } control.prototype._replay_error = function (action) { + core.ui.closePanel(); core.status.replay.replaying = false; var len = core.status.replay.toReplay.length; var prevList = core.status.replay.totalList.slice(-len - 11, -len - 1); @@ -1427,8 +1428,7 @@ control.prototype._replayAction_shop = function (action) { var shopInterval = setInterval(function () { if (!core.actions._clickShop(core.__HALF_SIZE__, topIndex+core.status.event.selection)) { clearInterval(shopInterval); - core.stopReplay(); - core.drawTip("录像文件出错"); + core.control._replay_error(action); return; } if (selections.length==0) { diff --git a/libs/events.js b/libs/events.js index 949a7b00..16ade8b0 100644 --- a/libs/events.js +++ b/libs/events.js @@ -1336,10 +1336,8 @@ events.prototype.__action_getInput = function (hint, isText, callback) { callback(value); } catch (e) { - main.log(e); - core.stopReplay(); - core.insertAction(["录像文件出错,请在控制台查看报错信息。", {"type": "exit"}]); - core.doAction(); + core.control._replay_error(action); + return; } } else { @@ -1384,10 +1382,7 @@ events.prototype._action_choices = function (data, x, y, prefix) { }, 750 / Math.max(1, core.status.replay.speed)) } else { - main.log("录像文件出错!当前需要一个 choices: 项,实际为 " + action); - core.stopReplay(); - core.insertAction(["录像文件出错,请在控制台查看报错信息。", {"type": "exit"}]); - core.doAction(); + core.control._replay_error(action); return; } } @@ -1410,10 +1405,7 @@ events.prototype._action_confirm = function (data, x, y, prefix) { }, 750 / Math.max(1, core.status.replay.speed)) } else { - main.log("录像文件出错!当前需要一个 choices: 项,实际为 " + action); - core.stopReplay(); - core.insertAction(["录像文件出错,请在控制台查看报错信息。", {"type": "exit"}]); - core.doAction(); + core.control._replay_error(action); return; } } @@ -1827,7 +1819,7 @@ events.prototype._setValue_setSwitch = function (name, value, prefix) { events.prototype._setValue_setGlobal = function (name, value) { if (name.indexOf("global:") !== 0) return; - core.setLocalStorage(name.substring(7), value); + core.setGlobal(name.substring(7), value); } ////// 数值增减 ////// diff --git a/libs/utils.js b/libs/utils.js index cf255416..afe6a241 100644 --- a/libs/utils.js +++ b/libs/utils.js @@ -67,7 +67,7 @@ utils.prototype.calValue = function (value, prefix, need, times) { value = value.replace(/item:([a-zA-Z0-9_]+)/g, "core.itemCount('$1')"); value = value.replace(/flag:([a-zA-Z0-9_\u4E00-\u9FCC]+)/g, "core.getFlag('$1', 0)"); value = value.replace(/switch:([a-zA-Z0-9_]+)/g, "core.getFlag('" + (prefix || ":f@x@y") + "@$1', 0)"); - value = value.replace(/global:([a-zA-Z0-9_\u4E00-\u9FCC]+)/g, "core.getLocalStorage('$1', 0)"); + value = value.replace(/global:([a-zA-Z0-9_\u4E00-\u9FCC]+)/g, "core.getGlobal('$1', 0)"); return eval(value); } if (value instanceof Function) { @@ -247,6 +247,31 @@ utils.prototype.removeLocalForage = function (key, successCallback, errorCallbac }) } +utils.prototype.setGlobal = function (key, value) { + if (core.status.replay.replaying) return; + core.setLocalStorage(key, value); +} + +utils.prototype.getGlobal = function (key, defaultValue) { + var value; + if (core.isReplaying()) { + // 不考虑key不一致的情况 + var action = core.status.replay.toReplay.shift(); + if (action.indexOf("input2:") == 0) { + value = JSON.parse(core.decodeBase64(action.substring(7))); + } + else { + core.control._replay_error(action); + return defaultValue; + } + } + else { + value = core.getLocalStorage(key, defaultValue); + } + core.status.route.push("input2:" + core.encodeBase64(JSON.stringify(value))); + return value; +} + ////// 深拷贝一个对象 ////// utils.prototype.clone = function (data, filter, recursion) { if (!core.isset(data)) return null; @@ -687,9 +712,8 @@ utils.prototype.rand2 = function (num) { value = parseInt(action.substring(7)); } else { - core.stopReplay(); - core.drawTip("录像文件出错"); - return; + core.control._replay_error(action); + return 0; } } else { From 9264e7dfe5d78b3368ab202594183c8cd2465304 Mon Sep 17 00:00:00 2001 From: oc Date: Mon, 29 Apr 2019 20:10:42 +0800 Subject: [PATCH 16/25] insertAction commonEvent do-while --- _server/MotaAction.g4 | 2 +- libs/events.js | 5 ++++- libs/utils.js | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/_server/MotaAction.g4 b/_server/MotaAction.g4 index 43d375fd..d8593e39 100644 --- a/_server/MotaAction.g4 +++ b/_server/MotaAction.g4 @@ -1757,7 +1757,7 @@ return code; */; break_s - : '跳出循环' Newline + : '跳出当前循环或公共事件' Newline /* break_s tooltip : break:跳出循环, 如果break事件不在任何循环中被执行,则和exit等价,即会立刻结束当前事件! diff --git a/libs/events.js b/libs/events.js index 16ade8b0..2befed36 100644 --- a/libs/events.js +++ b/libs/events.js @@ -843,7 +843,10 @@ events.prototype.insertAction = function (action, x, y, callback, addToLast) { // ------ 判定commonEvent var commonEvent = this.getCommonEvent(action); - if (commonEvent instanceof Array) action = commonEvent; + if (commonEvent instanceof Array) { + // 将公共事件视为一个do-while事件插入执行,可被break跳出 + action = [{"type": "dowhile", "condition": "false", "data": commonEvent}]; + } if (!action) return; if (core.status.event.id != 'action') { diff --git a/libs/utils.js b/libs/utils.js index afe6a241..b5107087 100644 --- a/libs/utils.js +++ b/libs/utils.js @@ -248,7 +248,7 @@ utils.prototype.removeLocalForage = function (key, successCallback, errorCallbac } utils.prototype.setGlobal = function (key, value) { - if (core.status.replay.replaying) return; + if (core.isReplaying()) return; core.setLocalStorage(key, value); } @@ -262,7 +262,7 @@ utils.prototype.getGlobal = function (key, defaultValue) { } else { core.control._replay_error(action); - return defaultValue; + return core.getLocalStorage(key, defaultValue); } } else { From 2426c8b0101e39818a7c20d4504d0d91e18d5c43 Mon Sep 17 00:00:00 2001 From: oc Date: Tue, 30 Apr 2019 20:22:06 +0800 Subject: [PATCH 17/25] canEquip -> equipCondition --- _docs/script.md | 32 +++++++++++++++++++++++++++++++- _server/table/comment.js | 4 ++-- libs/control.js | 1 - libs/items.js | 6 +++--- 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/_docs/script.md b/_docs/script.md index 96a48838..0e8c7206 100644 --- a/_docs/script.md +++ b/_docs/script.md @@ -224,7 +224,11 @@ function () { - 清晰明了。很容易方便知道自己修改过什么,尤其是可以和系统原有代码进行对比。 - 方便整理成新的插件,给其他的塔使用。 -如果我想对xxx文件中的yyy函数进行重写,其模式一般是:`core.xxx.yyy = function (参数列表) { ... }` +一般而言,复写规则如下: + +**对xxx文件中的yyy函数进行复写,规则是`core.xxx.yyy = function (参数列表) { ... }`。** + +但是,对于`registerXXX`所注册的函数是无效的,例如直接复写`core.control._animationFrame_globalAnimate`函数是没有效果的。对于这种情况引入的函数,需要注册同名函数,可参见最下面的样例。 下面是几个例子,从简单到复杂。 @@ -317,6 +321,32 @@ core.maps.drawMap = function (floorId, callback) { 详见[call和apply的用法](https://www.jianshu.com/p/80ea0d1c04f8)。 +### 复写全局动画绘制函数 + +全局动画绘制在`control.js`的`_animationFrame_globalAnimate`函数。 + +注意到此函数是由`registerAnimationFrame`注册的,因此直接复写是无效的。 + +其在control.js的注册的定义如下: + +```js +// 注册全局动画函数 +this.registerAnimationFrame("globalAnimate", true, this._animationFrame_globalAnimate); +``` + +因此,可以在插件中自行注册一个**同名**的函数来覆盖原始的内容。 + +```js +// 插件中复写全局动画绘制函数 +this.myGlobalAnimate = function (timestamp) { + // ...... 实际复写的函数内容 +} + +// 注册同名(globalAnimate)函数来覆盖系统原始内容 +core.registerAnimationFrame("globalAnimate", true, "myGlobalAnimate"); +``` + + ========================================================================================== [继续阅读下一章:API列表](api) diff --git a/_server/table/comment.js b/_server/table/comment.js index d5d72cf8..ef03953d 100644 --- a/_server/table/comment.js +++ b/_server/table/comment.js @@ -81,12 +81,12 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc = { "_lint": true, "_data": "当前能否使用该道具,仅对cls为tools或constants有效。" }, - "canEquip": { + "equipCondition": { "_leaf": true, "_type": "textarea", "_string": true, "_lint": true, - "_data": "当前能否装备某个装备,仅对cls为equips有效。\n与canUseItemEffect不同,这里null代表可以装备。" + "_data": "能装备某个装备的条件,仅对cls为equips有效。\n与canUseItemEffect不同,这里null代表可以装备。" } } }, diff --git a/libs/control.js b/libs/control.js index fb836179..d3289e37 100644 --- a/libs/control.js +++ b/libs/control.js @@ -189,7 +189,6 @@ control.prototype._animationFrame_animate = function (timestamp) { control.prototype._animationFrame_heroMoving = function (timestamp) { if (core.status.heroMoving <= 0) return; - var x=core.getHeroLoc('x'), y=core.getHeroLoc('y'), direction = core.getHeroLoc('direction'); // 换腿 if (timestamp - core.animateFrame.moveTime > (core.values.moveSpeed||100)) { core.animateFrame.leftLeg = !core.animateFrame.leftLeg; diff --git a/libs/items.js b/libs/items.js index 15ce13ac..13030de5 100644 --- a/libs/items.js +++ b/libs/items.js @@ -11,9 +11,9 @@ items.prototype._init = function () { this.itemEffectTip = items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a.itemEffectTip; this.useItemEffect = items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a.useItemEffect; this.canUseItemEffect = items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a.canUseItemEffect; - if (!items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a.canEquip) - items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a.canEquip = {}; - this.equipCondition = items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a.canEquip; + if (!items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a.equipCondition) + items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a.equipCondition = {}; + this.equipCondition = items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a.equipCondition; } ////// 获得所有道具 ////// From 77e66f849daf6b7725262d55efef4613dd12ca11 Mon Sep 17 00:00:00 2001 From: oc Date: Tue, 30 Apr 2019 20:36:39 +0800 Subject: [PATCH 18/25] force binarysearch on large turn --- libs/enemys.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libs/enemys.js b/libs/enemys.js index ad43a0f9..70e8263b 100644 --- a/libs/enemys.js +++ b/libs/enemys.js @@ -241,6 +241,11 @@ enemys.prototype._nextCriticals_useBinarySearch = function (enemy, info, number, enemys.prototype._nextCriticals_useTurn = function (enemy, info, number, x, y, floorId) { var mon_hp = info.mon_hp, hero_atk = core.status.hero.atk, mon_def = info.mon_def, turn = info.turn; + // ------ 超大回合数强制使用二分算临界 + // 以避免1攻10e回合,2攻5e回合导致下述循环卡死问题 + if (turn >= 1e6) { // 100w回合以上强制二分计算临界 + return this._nextCriticals_useBinarySearch(enemy, info, number, x, y, floorId); + } var list = [], pre = null; for (var t = turn - 1; t >= 1; t--) { var nextAtk = Math.ceil(mon_hp / t) + mon_def; From 570f03343d82e45dff2e400ed771e3c65fd43796 Mon Sep 17 00:00:00 2001 From: YouWei Zhao Date: Tue, 30 Apr 2019 20:35:11 -0400 Subject: [PATCH 19/25] change id idnum --- _server/editor_file_unsorted.js | 169 ++++++++++++++++++++------------ _server/editor_mode.js | 2 +- _server/editor_unsorted_2.js | 2 +- editor-mobile.html | 14 +-- editor.html | 26 ++--- 5 files changed, 130 insertions(+), 83 deletions(-) diff --git a/_server/editor_file_unsorted.js b/_server/editor_file_unsorted.js index 72e204ae..780f312e 100644 --- a/_server/editor_file_unsorted.js +++ b/_server/editor_file_unsorted.js @@ -261,70 +261,93 @@ editor_file = function (editor, callback) { editor.file.changeIdAndIdnum = function (id, idnum, info, callback) { checkCallback(callback); - //检查maps中是否有重复的idnum或id - var change = -1; - for (var ii in editor.core.maps.blocksInfo) { - if (ii == idnum) { - //暂时只允许创建新的不允许修改已有的 - //if (info.idnum==idnum){change=ii;break;}//修改id - callback('idnum重复了'); - return; - } - if (editor.core.maps.blocksInfo[ii].id == id) { - //if (info.id==id){change=ii;break;}//修改idnum - callback('id重复了'); - return; - } - } - /* - if (change!=-1 && change!=idnum){//修改idnum - editor.core.maps.blocksInfo[idnum] = editor.core.maps.blocksInfo[change]; - delete(editor.core.maps.blocksInfo[change]); - } else if (change==idnum) {//修改id - var oldid = editor.core.maps.blocksInfo[idnum].id; - editor.core.maps.blocksInfo[idnum].id = id; - for(var ii in editor.core.icons.icons){ - if (ii.hasOwnProperty(oldid)){ - ii[id]=ii[oldid]; - delete(ii[oldid]); - } - } - } else {//创建新的 - editor.core.maps.blocksInfo[idnum]={'cls': info.images, 'id':id}; - editor.core.icons.icons[info.images][id]=info.y; - } - */ - var templist = []; - var tempcallback = function (err) { - templist.push(err); - if (templist.length == 2) { - if (templist[0] != null || templist[1] != null) - callback((templist[0] || '') + '\n' + (templist[1] || '')); - //这里如果一个成功一个失败会出严重bug - else - callback(null); - } - } - saveSetting('maps', [["add", "['" + idnum + "']", {'cls': info.images, 'id': id}]], tempcallback); - saveSetting('icons', [["add", "['" + info.images + "']['" + id + "']", info.y]], tempcallback); - if (info.images === 'items') { - saveSetting('items', [["add", "['items']['" + id + "']", editor.file.comment._data.items_template]], function (err) { - if (err) { - printe(err); - throw(err) + + var changeOrNew=core.isset(editor_mode.info.id)?'change':'new' + if(changeOrNew=='new'){ + //检查maps中是否有重复的idnum或id + for (var ii in editor.core.maps.blocksInfo) { + if (ii == idnum) { + callback('idnum重复了'); + return; } - }); - } - if (info.images === 'enemys' || info.images === 'enemy48') { - saveSetting('enemys', [["add", "['" + id + "']", editor.file.comment._data.enemys_template]], function (err) { - if (err) { - printe(err); - throw(err) + if (editor.core.maps.blocksInfo[ii].id == id) { + callback('id重复了'); + return; } - }); - } + } + var templist = []; + var tempcallback = function (err) { + templist.push(err); + if (templist.length == 2) { + if (templist[0] != null || templist[1] != null) + callback((templist[0] || '') + '\n' + (templist[1] || '')); + //这里如果一个成功一个失败会出严重bug + else + callback(null); + } + } + saveSetting('maps', [["add", "['" + idnum + "']", {'cls': info.images, 'id': id}]], tempcallback); + saveSetting('icons', [["add", "['" + info.images + "']['" + id + "']", info.y]], tempcallback); + if (info.images === 'items') { + saveSetting('items', [["add", "['items']['" + id + "']", editor.file.comment._data.items_template]], function (err) { + if (err) { + printe(err); + throw(err) + } + }); + } + if (info.images === 'enemys' || info.images === 'enemy48') { + saveSetting('enemys', [["add", "['" + id + "']", editor.file.comment._data.enemys_template]], function (err) { + if (err) { + printe(err); + throw(err) + } + }); + } - callback(null); + callback(null); + + }else{ + //检查maps中是否有重复的idnum或id + for (var ii in editor.core.maps.blocksInfo) { + if (ii == idnum && idnum != info.idnum) { + callback('idnum重复了'); + return; + } + if (editor.core.maps.blocksInfo[ii].id == id && id != info.id) { + callback('id重复了'); + return; + } + } + if (idnum != info.idnum && id != info.id) { + callback('此版本idnum和id一次只允许修改一个, 请修改idnum刷新后再修改id'); + return; + } + if (idnum == info.idnum && id == info.id) { + callback('无改动'); + return; + } + + if (idnum != info.idnum){//修改idnum + maps_90f36752_8815_4be8_b32b_d7fad1d0542e[idnum] = maps_90f36752_8815_4be8_b32b_d7fad1d0542e[info.idnum]; + delete(maps_90f36752_8815_4be8_b32b_d7fad1d0542e[info.idnum]); + } else {//修改id + maps_90f36752_8815_4be8_b32b_d7fad1d0542e[idnum].id = id; + var obj=Object.assign({},icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1,items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a,{enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80:enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80}) + for(var jj in obj){ + var ii=obj[jj] + if (ii.hasOwnProperty(info.id)){ + ii[id]=ii[info.id]; + delete(ii[info.id]); + } + } + } + editor.file.save_icons_maps_items_enemys(callback) + + } + + + } //callback(err:String) editor.file.editItem = function (id, actionList, callback) { @@ -723,6 +746,30 @@ editor_file = function (editor, callback) { } } + editor.file.save_icons_maps_items_enemys=function(callback){ + var check=[] + saveSetting('icons',[],function(err){ + if(err){callback(err);return;} + check.push('icons') + if(check.length==4)callback(null); + }) + saveSetting('maps',[],function(err){ + if(err){callback(err);return;} + check.push('maps') + if(check.length==4)callback(null); + }) + saveSetting('items',[],function(err){ + if(err){callback(err);return;} + check.push('items') + if(check.length==4)callback(null); + }) + saveSetting('enemys',[],function(err){ + if(err){callback(err);return;} + check.push('enemys') + if(check.length==4)callback(null); + }) + } + var saveSetting = function (file, actionList, callback) { //console.log(file); //console.log(actionList); diff --git a/_server/editor_mode.js b/_server/editor_mode.js index 240baee0..0627e903 100644 --- a/_server/editor_mode.js +++ b/_server/editor_mode.js @@ -150,7 +150,7 @@ editor_mode = function (editor) { return; } - document.getElementById('newIdIdnum').style.display = 'none'; + document.getElementById('newIdIdnum').style.display = 'block'; document.getElementById('enemyItemTable').style.display = 'block'; var objs = []; diff --git a/_server/editor_unsorted_2.js b/_server/editor_unsorted_2.js index fe7ecf58..6ac8c1b2 100644 --- a/_server/editor_unsorted_2.js +++ b/_server/editor_unsorted_2.js @@ -19,7 +19,7 @@ editor_unsorted_2_wrapper=function(editor_mode){ printe(err); throw(err) } - printe('添加id的idnum成功,请F5刷新编辑器'); + printe(core.isset(editor_mode.info.id)?'修改id和idnum成功,请F5刷新编辑器':'添加id和idnum成功,请F5刷新编辑器'); }); } else { printe('请输入id和idnum'); diff --git a/editor-mobile.html b/editor-mobile.html index dcfd7dea..508d25f9 100644 --- a/editor-mobile.html +++ b/editor-mobile.html @@ -121,13 +121,6 @@

图块属性        

-
- - - -
- -
@@ -141,6 +134,13 @@
+
+ + + +
+ +
diff --git a/editor.html b/editor.html index 977e374d..adcc55e0 100644 --- a/editor.html +++ b/editor.html @@ -117,6 +117,19 @@

图块属性        

+
+
+ + + + + + + + +
条目注释
+
+
@@ -124,19 +137,6 @@
-
-
- - - - - - - - -
条目注释
-
-
From d9a4ee1aae2a5911e626e878a897d6ac7f069788 Mon Sep 17 00:00:00 2001 From: oc Date: Wed, 1 May 2019 15:18:52 +0800 Subject: [PATCH 20/25] fix bugs...... --- libs/events.js | 2 +- libs/maps.js | 10 +++++++++- libs/ui.js | 5 +++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/libs/events.js b/libs/events.js index 2befed36..546e3bb3 100644 --- a/libs/events.js +++ b/libs/events.js @@ -1149,7 +1149,7 @@ events.prototype._action_openDoor = function (data, x, y, prefix) { events.prototype._action_closeDoor = function (data, x, y, prefix) { var loc = this.__action_getLoc(data.loc, x, y, prefix); - core.closeDoor(loc[0], loc[1], data.id, core.doAction); + this.__action_doAsyncFunc(data.async, core.closeDoor, loc[0], loc[1], data.id); } events.prototype._action_useItem = function (data, x, y, prefix) { diff --git a/libs/maps.js b/libs/maps.js index bdac2f51..fe9fd6bf 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -91,6 +91,9 @@ maps.prototype.initBlock = function (x, y, id, addInfo, eventFloor) { else if (core.icons.getTilesetOffset(id)) block.event = {"cls": "tileset", "id": "X" + id, "noPass": true}; else block.event = {'cls': 'terrains', 'id': 'none', 'noPass': false}; + if (typeof block.event.noPass === 'string') + block.event.noPass = JSON.parse(block.event.noPass); + if (addInfo) this._addInfo(block); if (eventFloor) { this._addEvent(block, x, y, (eventFloor.events || {})[x + "," + y]); @@ -1447,8 +1450,13 @@ maps.prototype.setBlock = function (number, x, y, floorId) { else number = core.getNumberById(number); } - var originBlock = core.getBlock(x, y, floorId, true); var block = this.initBlock(x, y, number, true, core.floors[floorId]); + if (block.id == 0 && !block.event.trigger) { + // 转变图块为0且该点无事件,视为隐藏 + core.removeBlock(x, y, floorId); + return; + } + var originBlock = core.getBlock(x, y, floorId, true); if (floorId == core.status.floorId) { core.removeGlobalAnimate(x, y); core.clearMap('event', x * 32, y * 32, 32, 32); diff --git a/libs/ui.js b/libs/ui.js index aca20dd8..6f990152 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -467,6 +467,11 @@ ui.prototype.drawWindowSelector = function(background, x, y, w, h) { ////// 绘制 WindowSkin ui.prototype.drawWindowSkin = function(background, ctx, x, y, w, h, direction, px, py) { + background = background || core.status.textAttribute.background; + if (typeof background == 'string') { + background = core.getMappedName(background); + background = core.material.images.images[background]; + } // 仿RM窗口皮肤 ↓ var dstImage = core.getContextByName(ctx); if (!dstImage) return; From 053665d081dd3a513d8a27e2f8bc4c7029363c47 Mon Sep 17 00:00:00 2001 From: oc Date: Wed, 1 May 2019 16:24:25 +0800 Subject: [PATCH 21/25] changeId --- _server/editor_file_unsorted.js | 37 ++++++++++----------------------- _server/editor_mode.js | 6 ++++-- _server/editor_unsorted_2.js | 22 +++++++++++++++++++- editor-mobile.html | 4 ++++ editor.html | 4 ++++ project/items.js | 2 +- 6 files changed, 45 insertions(+), 30 deletions(-) diff --git a/_server/editor_file_unsorted.js b/_server/editor_file_unsorted.js index 780f312e..04c46d99 100644 --- a/_server/editor_file_unsorted.js +++ b/_server/editor_file_unsorted.js @@ -310,44 +310,29 @@ editor_file = function (editor, callback) { }else{ //检查maps中是否有重复的idnum或id for (var ii in editor.core.maps.blocksInfo) { - if (ii == idnum && idnum != info.idnum) { - callback('idnum重复了'); - return; - } - if (editor.core.maps.blocksInfo[ii].id == id && id != info.id) { + if (editor.core.maps.blocksInfo[ii].id == id) { callback('id重复了'); return; } } - if (idnum != info.idnum && id != info.id) { - callback('此版本idnum和id一次只允许修改一个, 请修改idnum刷新后再修改id'); - return; - } - if (idnum == info.idnum && id == info.id) { - callback('无改动'); - return; - } - - if (idnum != info.idnum){//修改idnum - maps_90f36752_8815_4be8_b32b_d7fad1d0542e[idnum] = maps_90f36752_8815_4be8_b32b_d7fad1d0542e[info.idnum]; - delete(maps_90f36752_8815_4be8_b32b_d7fad1d0542e[info.idnum]); - } else {//修改id - maps_90f36752_8815_4be8_b32b_d7fad1d0542e[idnum].id = id; - var obj=Object.assign({},icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1,items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a,{enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80:enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80}) + idnum = info.idnum; + + maps_90f36752_8815_4be8_b32b_d7fad1d0542e[idnum].id = id; + + var arr=[icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1,items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a,{enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80:enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80}] + arr.forEach(function (obj) { for(var jj in obj){ var ii=obj[jj] if (ii.hasOwnProperty(info.id)){ - ii[id]=ii[info.id]; - delete(ii[info.id]); + ii[id]=ii[info.id]; + delete(ii[info.id]); } } - } + }); + editor.file.save_icons_maps_items_enemys(callback) } - - - } //callback(err:String) editor.file.editItem = function (id, actionList, callback) { diff --git a/_server/editor_mode.js b/_server/editor_mode.js index 0627e903..8bf22dc9 100644 --- a/_server/editor_mode.js +++ b/_server/editor_mode.js @@ -145,13 +145,15 @@ editor_mode = function (editor) { if (!core.isset(editor_mode.info.id)) { // document.getElementById('table_a3f03d4c_55b8_4ef6_b362_b345783acd72').innerHTML = ''; - document.getElementById('enemyItemTable').style.display = 'none'; document.getElementById('newIdIdnum').style.display = 'block'; + document.getElementById('enemyItemTable').style.display = 'none'; + document.getElementById('changeId').style.display = 'none'; return; } - document.getElementById('newIdIdnum').style.display = 'block'; + document.getElementById('newIdIdnum').style.display = 'none'; document.getElementById('enemyItemTable').style.display = 'block'; + document.getElementById('changeId').style.display = 'block'; var objs = []; if (editor_mode.info.images == 'enemys' || editor_mode.info.images == 'enemy48') { diff --git a/_server/editor_unsorted_2.js b/_server/editor_unsorted_2.js index 6ac8c1b2..ceb3bf16 100644 --- a/_server/editor_unsorted_2.js +++ b/_server/editor_unsorted_2.js @@ -19,7 +19,7 @@ editor_unsorted_2_wrapper=function(editor_mode){ printe(err); throw(err) } - printe(core.isset(editor_mode.info.id)?'修改id和idnum成功,请F5刷新编辑器':'添加id和idnum成功,请F5刷新编辑器'); + printe('添加id和idnum成功,请F5刷新编辑器'); }); } else { printe('请输入id和idnum'); @@ -36,6 +36,26 @@ editor_unsorted_2_wrapper=function(editor_mode){ }) } + var changeId = document.getElementById('changeId'); + changeId.children[1].onclick = function () { + var id = changeId.children[0].value; + if (id) { + if (!/^[0-9a-zA-Z_]+$/.test(id)) { + printe('不合法的id,请使用字母、数字或下划线') + return; + } + editor.file.changeIdAndIdnum(id, null, editor_mode.info, function (err) { + if (err) { + printe(err); + throw(err); + } + printe('修改id成功,请F5刷新编辑器'); + }); + } else { + printe('请输入要修改到的ID'); + } + } + var selectFloor = document.getElementById('selectFloor'); editor.game.getFloorFileList(function (floors) { var outstr = []; diff --git a/editor-mobile.html b/editor-mobile.html index 508d25f9..563c0b7e 100644 --- a/editor-mobile.html +++ b/editor-mobile.html @@ -141,6 +141,10 @@
+
+ + +
diff --git a/editor.html b/editor.html index adcc55e0..7af5e35d 100644 --- a/editor.html +++ b/editor.html @@ -137,6 +137,10 @@
+
+ + +
diff --git a/project/items.js b/project/items.js index efda5b71..bc656898 100644 --- a/project/items.js +++ b/project/items.js @@ -416,5 +416,5 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a = "yellowJewel": "true", "skill1": "true" }, - "canEquip": {} + "equipCondition": {} } \ No newline at end of file From 432b5354df59b6057020fa2b2e6aa3a73c3686d7 Mon Sep 17 00:00:00 2001 From: oc Date: Thu, 2 May 2019 10:58:34 +0800 Subject: [PATCH 22/25] setHeroIcon onload --- libs/events.js | 12 +++++------- project/functions.js | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/libs/events.js b/libs/events.js index 546e3bb3..8c72173f 100644 --- a/libs/events.js +++ b/libs/events.js @@ -2254,13 +2254,11 @@ events.prototype.setHeroIcon = function (name, noDraw) { var img = core.material.images.images[name]; if (!img) return; core.setFlag("heroIcon", name); - core.material.images.hero.onload = function () { - core.material.icons.hero.width = img.width / 4; - core.material.icons.hero.height = img.height / 4; - core.control.updateHeroIcon(name); - if (!noDraw) core.drawHero(); - } - core.material.images.hero.src = img.src; + core.material.images.hero = img; + core.material.icons.hero.width = img.width / 4; + core.material.icons.hero.height = img.height / 4; + core.control.updateHeroIcon(name); + if (!noDraw) core.drawHero(); } ////// 检查升级事件 ////// diff --git a/project/functions.js b/project/functions.js index e2497c87..13cf4cfc 100644 --- a/project/functions.js +++ b/project/functions.js @@ -465,7 +465,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = [12, "中毒", "战斗后,勇士陷入中毒状态,每一步损失生命" + core.values.poisonDamage + "点"], [13, "衰弱", "战斗后,勇士陷入衰弱状态,攻防暂时下降" + (core.values.weakValue >= 1 ? core.values.weakValue + "点" : parseInt(core.values.weakValue * 100) + "%")], [14, "诅咒", "战斗后,勇士陷入诅咒状态,战斗无法获得金币和经验"], - [15, "领域", function (enemy) { return "经过怪物周围" + (enemy.range || 1) + "格时自动减生命" + (enemy.value || 0) + "点"; }], + [15, "领域", function (enemy) { return "经过怪物周围" + (enemy.zoneSquare ? "九宫格" : "十字") + "范围内" + (enemy.range || 1) + "格时自动减生命" + (enemy.value || 0) + "点"; }], [16, "夹击", "经过两只相同的怪物中间,勇士生命值变成一半"], [17, "仇恨", "战斗前,怪物附加之前积累的仇恨值作为伤害" + (core.flags.hatredDecrease ? ";战斗后,释放一半的仇恨值" : "") + "。(每杀死一个怪物获得" + (core.values.hatred || 0) + "点仇恨值)"], [18, "阻击", function (enemy) { return "经过怪物的十字领域时自动减生命" + (enemy.value || 0) + "点,同时怪物后退一格"; }], From 330e031bc799481aa2d214503fd1e30b82cdfa45 Mon Sep 17 00:00:00 2001 From: oc Date: Thu, 2 May 2019 21:05:05 +0800 Subject: [PATCH 23/25] changeFloorId --- _server/editor_unsorted_2.js | 35 +++++++++++++++++++++++++++++++++++ editor-mobile.html | 4 ++++ editor.html | 4 ++++ 3 files changed, 43 insertions(+) diff --git a/_server/editor_unsorted_2.js b/_server/editor_unsorted_2.js index ceb3bf16..c21864a3 100644 --- a/_server/editor_unsorted_2.js +++ b/_server/editor_unsorted_2.js @@ -185,6 +185,41 @@ editor_unsorted_2_wrapper=function(editor_mode){ }); } + var changeFloorId = document.getElementById('changeFloorId'); + changeFloorId.children[1].onclick = function () { + var floorId = changeFloorId.children[0].value; + if (floorId) { + if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(floorId)) { + printe("楼层名 "+floorId+" 不合法!请使用字母、数字、下划线,且不能以数字开头!"); + return; + } + if (main.floorIds.indexOf(floorId)>=0) { + printe("楼层名 "+floorId+" 已存在!"); + return; + } + var currentFloorId = editor.currentFloorId; + editor.currentFloorId = floorId; + editor.currentFloorData.floorId = floorId; + editor.file.saveFloorFile(floorId, function (err) { + if (err) { + printe(err); + throw(err); + } + core.floorIds[core.floorIds.indexOf(currentFloorId)] = floorId; + editor.file.editTower([['change', "['main']['floorIds']", core.floorIds]], function (objs_) {//console.log(objs_); + if (objs_.slice(-1)[0] != null) { + printe(objs_.slice(-1)[0]); + throw(objs_.slice(-1)[0]) + } + alert("修改floorId成功,需要刷新编辑器生效。\n请注意,原始的楼层文件没有删除,请根据需要手动删除。"); + window.location.reload(); + }); + }); + } else { + printe('请输入要修改到的floorId'); + } + } + var ratio = 1; var appendPicCanvas = document.getElementById('appendPicCanvas'); var bg = appendPicCanvas.children[0]; diff --git a/editor-mobile.html b/editor-mobile.html index 563c0b7e..67db31dd 100644 --- a/editor-mobile.html +++ b/editor-mobile.html @@ -162,6 +162,10 @@
+
+ + +
diff --git a/editor.html b/editor.html index 7af5e35d..4ea3654f 100644 --- a/editor.html +++ b/editor.html @@ -158,6 +158,10 @@
+
+ + +
From 2c0e0ba307a9a7a16c4bcf995f655daae625f37d Mon Sep 17 00:00:00 2001 From: oc Date: Thu, 2 May 2019 21:06:44 +0800 Subject: [PATCH 24/25] changeFloorId --- _server/editor_unsorted_2.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_server/editor_unsorted_2.js b/_server/editor_unsorted_2.js index c21864a3..17b8092e 100644 --- a/_server/editor_unsorted_2.js +++ b/_server/editor_unsorted_2.js @@ -200,7 +200,7 @@ editor_unsorted_2_wrapper=function(editor_mode){ var currentFloorId = editor.currentFloorId; editor.currentFloorId = floorId; editor.currentFloorData.floorId = floorId; - editor.file.saveFloorFile(floorId, function (err) { + editor.file.saveFloorFile(function (err) { if (err) { printe(err); throw(err); From f2212672eaa8a40db611f7bfb2014682d790bfeb Mon Sep 17 00:00:00 2001 From: oc Date: Thu, 2 May 2019 21:22:46 +0800 Subject: [PATCH 25/25] v2.6.1 --- API列表.txt | 11 +++++++++++ README.md | 19 +++++++++++++++++++ _docs/V2.0.md | 2 +- _docs/api.md | 13 ++++++++++++- _docs/element.md | 2 +- _docs/event.md | 2 +- _docs/index.md | 2 +- _docs/personalization.md | 2 +- _docs/script.md | 2 +- _docs/start.md | 2 +- main.js | 6 +++--- project/data.js | 2 +- 更新说明.txt | 23 ++++++++++++++++++++++- 13 files changed, 75 insertions(+), 13 deletions(-) diff --git a/API列表.txt b/API列表.txt index bc4da122..8233a735 100644 --- a/API列表.txt +++ b/API列表.txt @@ -1949,6 +1949,17 @@ errorCallback可选,如果失败,则会将错误信息传入errorCallback() 此函数是异步的,只能通过回调函数来获得读取的结果或错误信息。 +core.setGlobal(key, value) +设置一个全局存储,适用于global:xxx。 +录像播放时将忽略此函数,否则直接调用core.setLocalStorage。 + + +core.getGlobal(key, value) +获得一个全局存储,适用于global:xxx,支持录像。 +正常游戏时将使用core.getLocalStorage获得具体的数据,并将结果存放到录像中。 +录像播放时会直接从录像中获得对应的数据。 + + core.clone(data, filter, recursion) 深拷贝一个对象。有关浅拷贝,深拷贝,基本类型和引用类型等相关知识可参见: https://zhuanlan.zhihu.com/p/26282765 diff --git a/README.md b/README.md index da2183a4..7e331545 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,25 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏! ## 更新说明 +### 2019.5.2 V2.6.1 + +* [x] 区域优化的录像播放功能,R键使用 +* [x] 强制战斗可以指定怪物坐标,将自动隐藏并执行该点战后事件 +* [x] flag:xxx也支持中文,例如 flag:2楼机关门 +* [x] 增加文件名映射,可以用中文映射到某个图片或bgm文件并使用 +* [x] 勇士宽度可以超过32(例如48x48的勇士行走图) +* [x] 现在允许修改floorId和图块ID了(在表格下方) +* [x] 增加事件:自动存档,返回标题界面;部分事件优化 +* [x] 商店长按空格可以连续加点 +* [x] 增设global:xxx使用全局存储,可被录像支持 +* [x] 支持\b[hero]和\b[null,x,y]来自动调整上下方向 +* [x] 支持\t[yellowKey]等只显示图标而没有标题 +* [x] 编辑器中前景层对于有事件的点半透明显示 +* [x] 存档改成1000页,长按上下页可快速翻页 +* [x] 录像播放初始默认暂停,N键可以单步执行 +* [x] 增设本地API文档,部分API和事件的优化 +* [x] 所有已知的bug修复,大量细节优化 + ### 2019.4.13 V2.6 * [x] 拆分整个项目,大幅重构代码,新增大量API diff --git a/_docs/V2.0.md b/_docs/V2.0.md index f10852d8..0b8bd92a 100644 --- a/_docs/V2.0.md +++ b/_docs/V2.0.md @@ -1,6 +1,6 @@ # V2.0版本介绍 -?> 目前版本**v2.5.5**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.6.1**,上次更新时间:* {docsify-updated} * 目前样板已经更新到V2.0版本以上,本章将对V2.0的一些内容进行介绍。 diff --git a/_docs/api.md b/_docs/api.md index 8be9d072..c1c65a3d 100644 --- a/_docs/api.md +++ b/_docs/api.md @@ -1,6 +1,6 @@ # 附录:API列表 -?> 目前版本**v2.6**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.6.1**,上次更新时间:* {docsify-updated} * 这里将列出所有被转发到core的API,没有被转发的函数此处不会列出,请自行在代码中查看。 @@ -1915,6 +1915,17 @@ errorCallback可选,如果失败,则会将错误信息传入errorCallback() 此函数是异步的,只能通过回调函数来获得读取的结果或错误信息。 +core.setGlobal(key, value) +设置一个全局存储,适用于global:xxx。 +录像播放时将忽略此函数,否则直接调用core.setLocalStorage。 + + +core.getGlobal(key, value) +获得一个全局存储,适用于global:xxx,支持录像。 +正常游戏时将使用core.getLocalStorage获得具体的数据,并将结果存放到录像中。 +录像播放时会直接从录像中获得对应的数据。 + + core.clone(data, filter, recursion) 深拷贝一个对象。有关浅拷贝,深拷贝,基本类型和引用类型等相关知识可参见: https://zhuanlan.zhihu.com/p/26282765 diff --git a/_docs/element.md b/_docs/element.md index 4fed9b92..a6fbcc9f 100644 --- a/_docs/element.md +++ b/_docs/element.md @@ -1,6 +1,6 @@ # 元件说明 -?> 目前版本**v2.6**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.6.1**,上次更新时间:* {docsify-updated} * 在本章中,将对样板里的各个元件进行说明。各个元件主要包括道具、门、怪物、楼梯等等。 diff --git a/_docs/event.md b/_docs/event.md index fb88e23e..34fff45b 100644 --- a/_docs/event.md +++ b/_docs/event.md @@ -1,6 +1,6 @@ # 事件 -?> 目前版本**v2.6**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.6.1**,上次更新时间:* {docsify-updated} * 本章内将对样板所支持的事件进行介绍。 diff --git a/_docs/index.md b/_docs/index.md index d2f290e2..510bd14c 100644 --- a/_docs/index.md +++ b/_docs/index.md @@ -1,6 +1,6 @@ # HTML5 魔塔样板说明文档 -?> 目前版本**v2.6**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.6.1**,上次更新时间:* {docsify-updated} * 众所周知,魔塔的趋势是向移动端发展,贴吧中也常常能见到“求手机魔塔”的帖子。然而现有的工具中,NekoRPG有着比较大的局限性,游戏感较差,更是完全没法在iOS上运行。而一些APP的魔塔虽然可用,但是必须要下载安装,对于Android和iOS还必须开发不同的版本,非常麻烦。 diff --git a/_docs/personalization.md b/_docs/personalization.md index c8f517e6..72de08cd 100644 --- a/_docs/personalization.md +++ b/_docs/personalization.md @@ -1,6 +1,6 @@ # 个性化 -?> 目前版本**v2.6**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.6.1**,上次更新时间:* {docsify-updated} * 有时候只靠样板本身可能是不够的。我们需要一些个性化、自定义的素材,道具效果,怪物属性,等等。 diff --git a/_docs/script.md b/_docs/script.md index 0e8c7206..c6d0aeff 100644 --- a/_docs/script.md +++ b/_docs/script.md @@ -1,6 +1,6 @@ # 脚本 -?> 目前版本**v2.6**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.6.1**,上次更新时间:* {docsify-updated} * 在V2.6版本中,基本对整个项目代码进行了重写,更加方便造塔者的使用和复写函数。 diff --git a/_docs/start.md b/_docs/start.md index 004ea21f..87319f4c 100644 --- a/_docs/start.md +++ b/_docs/start.md @@ -1,6 +1,6 @@ # 快速上手 -?> 目前版本**v2.6**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.6.1**,上次更新时间:* {docsify-updated} * 在这一节中,将详细介绍做一部塔的流程。现在,让我们来做一部单层塔! diff --git a/main.js b/main.js index 4743655b..5ecac76f 100644 --- a/main.js +++ b/main.js @@ -2,7 +2,7 @@ function main() { //------------------------ 用户修改内容 ------------------------// - this.version = "2.6"; // 游戏版本号;如果更改了游戏内容建议修改此version以免造成缓存问题。 + this.version = "2.6.1"; // 游戏版本号;如果更改了游戏内容建议修改此version以免造成缓存问题。 this.useCompress = false; // 是否使用压缩文件 // 当你即将发布你的塔时,请使用“JS代码压缩工具”将所有js代码进行压缩,然后将这里的useCompress改为true。 @@ -188,8 +188,8 @@ function main() { this.floors = {} this.canvas = {}; - this.__VERSION__ = "2.6"; - this.__VERSION_CODE__ = 30; + this.__VERSION__ = "2.6.1"; + this.__VERSION_CODE__ = 36; } main.prototype.init = function (mode, callback) { diff --git a/project/data.js b/project/data.js index 6d732a08..aa989629 100644 --- a/project/data.js +++ b/project/data.js @@ -77,7 +77,7 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "firstData": { "title": "魔塔样板", "name": "template", - "version": "Ver 2.6", + "version": "Ver 2.6.1", "floorId": "sample0", "hero": { "name": "阳光", diff --git a/更新说明.txt b/更新说明.txt index ec9833e3..c66b427b 100644 --- a/更新说明.txt +++ b/更新说明.txt @@ -1,4 +1,25 @@ -HTML5魔塔样板V2.6 +HTML5魔塔样板V2.6.1 + +区域优化的录像播放功能,R键使用 +强制战斗可以指定怪物坐标,将自动隐藏并执行该点战后事件 +flag:xxx也支持中文,例如 flag:2楼机关门 +增加文件名映射,可以用中文映射到某个图片或bgm文件并使用 +勇士宽度可以超过32(例如48x48的勇士行走图) +现在允许修改floorId和图块ID了(在表格下方) +增加事件:自动存档,返回标题界面;部分事件优化 +商店长按空格可以连续加点 +增设global:xxx使用全局存储,可被录像支持 +支持\b[hero]和\b[null,x,y]来自动调整上下方向 +支持\t[yellowKey]等只显示图标而没有标题 +编辑器中前景层对于有事件的点半透明显示 +存档改成1000页,长按上下页可快速翻页 +录像播放初始默认暂停,N键可以单步执行 +增设本地API文档,部分API和事件的优化 +所有已知的bug修复,大量细节优化 + +----------------------------------------------------------------------- + +HTML5魔塔样板V2.6 拆分整个项目,大幅重构代码,新增大量API 重写文档,尤其是脚本和API列表