diff --git a/_server/blockly/MotaAction.g4 b/_server/blockly/MotaAction.g4 index 89175f71..6a488c98 100644 --- a/_server/blockly/MotaAction.g4 +++ b/_server/blockly/MotaAction.g4 @@ -5,22 +5,23 @@ grammar MotaAction; //事件 事件编辑器入口之一 event_m - : '事件' BGNL? Newline '覆盖触发器' Bool '启用' Bool '通行状态' B_0_List '显伤' Bool BGNL? Newline action+ BEND + : '事件' BGNL? Newline '覆盖触发器' Bool '启用' Bool '通行状态' B_0_List '动画' Bool '显伤' Bool BGNL? Newline action+ BEND /* event_m tooltip : 编辑魔塔的事件 helpUrl : https://h5mota.com/games/template/docs/#/event -default : [false,null,null,null] +default : [false,null,null,null,null] B_0_List_0=eval(B_0_List_0); var code = { 'trigger': Bool_0?'action':null, 'enable': Bool_1, 'noPass': B_0_List_0, - 'displayDamage': Bool_2, + 'animate': Bool_2, + 'displayDamage': Bool_3, 'data': 'data_asdfefw' } -if (!Bool_0 && Bool_1 && (B_0_List_0===null) && Bool_2) code = 'data_asdfefw'; +if (!Bool_0 && Bool_1 && (B_0_List_0===null) && Bool_2 && Bool_3) code = 'data_asdfefw'; code=JSON.stringify(code,null,2).split('"data_asdfefw"').join('[\n'+action_0+']\n'); return code; */; @@ -50,15 +51,16 @@ return code; */; levelCase - : '需求' expression '称号' EvalString? BGNL? Newline action+ + : '需求' expression '称号' EvalString? '是否扣除经验' Bool BGNL? Newline action+ /* levelCase tooltip : 升级设定 helpUrl : https://h5mota.com/games/template/docs/#/event?id=%e7%bb%8f%e9%aa%8c%e5%8d%87%e7%ba%a7%ef%bc%88%e8%bf%9b%e9%98%b6%2f%e5%a2%83%e7%95%8c%e5%a1%94%ef%bc%89 -default : [0,"",null] +default : [0,"",false,null] colour : this.subColor -var code = '{"need": "'+expression_0+'", "title": "'+EvalString_0+'", "action": [\n'+action_0+']},\n'; +Bool_0 = Bool_0?', "clear": true':''; +var code = '{"need": "'+expression_0+'", "title": "'+EvalString_0+'"'+Bool_0+', "action": [\n'+action_0+']},\n'; return code; */; @@ -522,7 +524,7 @@ if (EvalString_0 && EvalString_1) { floorstr = ', "loc": ['+EvalString_0.join(',')+']'; } IdString_0 = IdString_0 && (', "floorId": "'+IdString_0+'"'); -Int_0 = Int_0 ?(', "time": '+Int_0):''; +Int_0 = Int_0!=='' ?(', "time": '+Int_0):''; Bool_0 = Bool_0 ?', "async": true':''; var code = '{"type": "show"'+floorstr+IdString_0+''+Int_0+Bool_0+'},\n'; return code; @@ -555,7 +557,7 @@ if (EvalString_0 && EvalString_1) { floorstr = ', "loc": ['+EvalString_0.join(',')+']'; } IdString_0 = IdString_0 && (', "floorId": "'+IdString_0+'"'); -Int_0 = Int_0 ?(', "time": '+Int_0):''; +Int_0 = Int_0!=='' ?(', "time": '+Int_0):''; Bool_0 = Bool_0 ?', "async": true':''; var code = '{"type": "hide"'+floorstr+IdString_0+''+Int_0+Bool_0+'},\n'; return code; @@ -1126,7 +1128,7 @@ Number_0 = limit(Number_0,0,255); Number_1 = limit(Number_1,0,255); Number_2 = limit(Number_2,0,255); Number_3 = limit(Number_3,0,1); -Int_0 = Int_0 ?(', "time": '+Int_0):''; +Int_0 = Int_0!=='' ?(', "time": '+Int_0):''; var async = Bool_0?', "async": true':''; var code = '{"type": "setFg", "color": ['+Number_0+','+Number_1+','+Number_2+','+Number_3+']'+Int_0 +async+'},\n'; return code; @@ -1141,7 +1143,7 @@ tooltip : setFg: 恢复画面色调,动画时间可不填 helpUrl : https://h5mota.com/games/template/docs/#/event?id=setfg%EF%BC%9A%E6%9B%B4%E6%94%B9%E7%94%BB%E9%9D%A2%E8%89%B2%E8%B0%83 default : [500,false] colour : this.soundColor -Int_0 = Int_0 ?(', "time": '+Int_0):''; +Int_0 = Int_0!=='' ?(', "time": '+Int_0):''; var async = Bool_0?', "async": true':''; var code = '{"type": "setFg"'+Int_0 +async+'},\n'; return code; @@ -1175,7 +1177,7 @@ var floorstr = ''; if (PosString_0 && PosString_1) { floorstr = ', "loc": ['+PosString_0+','+PosString_1+']'; } -Int_0 = Int_0 ?(', "time": '+Int_0):''; +Int_0 = Int_0!=='' ?(', "time": '+Int_0):''; Bool_0 = Bool_0?', "keep": true':''; Bool_1 = Bool_1?', "async": true':''; var code = '{"type": "move"'+floorstr+Int_0+Bool_0+Bool_1+', "steps": '+JSON.stringify(StepString_0)+'},\n'; @@ -1191,7 +1193,7 @@ tooltip : moveHero:移动勇士,用这种方式移动勇士的过程中将无 helpUrl : https://h5mota.com/games/template/docs/#/event?id=movehero%EF%BC%9A%E7%A7%BB%E5%8A%A8%E5%8B%87%E5%A3%AB default : [500,false,"上右3下2左上左2"] colour : this.dataColor -Int_0 = Int_0 ?(', "time": '+Int_0):''; +Int_0 = Int_0!=='' ?(', "time": '+Int_0):''; Bool_0 = Bool_0?', "async": true':''; var code = '{"type": "moveHero"'+Int_0+Bool_0+', "steps": '+JSON.stringify(StepString_0)+'},\n'; return code; @@ -1213,7 +1215,7 @@ if (PosString_0 && PosString_1) { if (PosString_2 && PosString_3) { floorstr += ', "to": ['+PosString_2+','+PosString_3+']'; } -Int_0 = Int_0 ?(', "time": '+Int_0):''; +Int_0 = Int_0!=='' ?(', "time": '+Int_0):''; Bool_0 = Bool_0?', "keep": true':''; Bool_1 = Bool_1?', "async": true':''; var code = '{"type": "jump"'+floorstr+''+Int_0+Bool_0+Bool_1+'},\n'; @@ -1233,7 +1235,7 @@ var floorstr = ''; if (PosString_0 && PosString_1) { floorstr = ', "loc": ['+PosString_0+','+PosString_1+']'; } -Int_0 = Int_0 ?(', "time": '+Int_0):''; +Int_0 = Int_0!=='' ?(', "time": '+Int_0):''; Bool_0 = Bool_0?', "async": true':''; var code = '{"type": "jumpHero"'+floorstr+Int_0+Bool_0+'},\n'; return code; @@ -1298,7 +1300,7 @@ tooltip : setVolume: 设置音量 helpUrl : https://h5mota.com/games/template/docs/#/event?id=setvolume%EF%BC%9A%E8%AE%BE%E7%BD%AE%E9%9F%B3%E9%87%8F default : [90, 500, false] colour : this.soundColor -Int_1 = Int_1?(', "time": '+Int_1):"" +Int_1 = Int_1!==''?(', "time": '+Int_1):"" var async = Bool_0?', "async": true':''; var code = '{"type": "setVolume", "value": '+Int_0+Int_1+async+'},\n'; return code; @@ -1795,7 +1797,7 @@ ActionParser.prototype.parse = function (obj,type) { if(typeof(obj)===typeof('')) obj={'data':[obj]}; if(obj instanceof Array) obj={'data':obj}; return MotaActionBlocks['event_m'].xmlText([ - obj.trigger==='action',obj.enable,obj.noPass,obj.displayDamage,this.parseList(obj.data) + obj.trigger==='action',obj.enable,obj.noPass,obj.animate,obj.displayDamage,this.parseList(obj.data) ]); case 'changeFloor': @@ -1825,7 +1827,7 @@ ActionParser.prototype.parse = function (obj,type) { var text_choices = null; for(var ii=obj.length-1,choice;choice=obj[ii];ii--) { text_choices=MotaActionBlocks['levelCase'].xmlText([ - MotaActionBlocks['evalString_e'].xmlText([choice.need]),choice.title,this.parseList(choice.action),text_choices]); + MotaActionBlocks['evalString_e'].xmlText([choice.need]),choice.title,choice.clear||false,this.parseList(choice.action),text_choices]); } return MotaActionBlocks['level_m'].xmlText([text_choices]); @@ -1909,9 +1911,8 @@ ActionParser.prototype.parseAction = function() { this.EvalString(data.text),this.next]); break; case "autoText": // 自动剧情文本 - data.time=this.isset(data.time)?data.time:MotaActionBlocks['autoText_s'].fieldDefault[3]; this.next = MotaActionBlocks['autoText_s'].xmlText([ - '','','',data.time||0,this.EvalString(data.text),this.next]); + '','','',data.time,this.EvalString(data.text),this.next]); break; case "scrollText": this.next = MotaActionBlocks['scrollText_s'].xmlText([ diff --git a/_server/comment.js b/_server/comment.js index 9577712f..41aa00ef 100644 --- a/_server/comment.js +++ b/_server/comment.js @@ -261,7 +261,7 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "_leaf": true, "_type": "textarea", "_range": "thiseval==null||(thiseval instanceof Array)", - "_data": "该图块的不可入方向\n可以在这里定义不能从哪个方向访问该图块,可以达到悬崖之类的效果\n例如 [\"down\", \"right\"] 代表不能从下或右访问此图块\n此值对背景层、事件层、前景层上的图块均有效" + "_data": "该图块的不可入方向\n可以在这里定义不能朝哪个方向进入该图块,可以达到悬崖之类的效果\n例如 [\"down\"] 代表不能从该图块的上方点朝向下进入此图块\n此值对背景层、事件层、前景层上的图块均有效" }, "faceIds": { "_leaf": true, @@ -334,7 +334,7 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "_leaf": true, "_type": "event", "_event": "eachArrive", - "_data": "每次到该楼层触发的事件,可以双击进入事件编辑器;该事件会比firstArrive先执行。" + "_data": "每次到该楼层触发的事件,可以双击进入事件编辑器;该事件会在firstArrive执行后再执行。" }, "parallelDo": { "_leaf": true, diff --git a/_server/css/editor.css b/_server/css/editor.css index 928a0964..ebd4b009 100644 --- a/_server/css/editor.css +++ b/_server/css/editor.css @@ -392,3 +392,21 @@ table.row td { [v-cloak] { display: none !important; } + +#searchBlock { + width: 100px; + background-color: #E9EBF2; + border-radius: 10px; + outline: none; + padding-left: 20px; + height: 14px; +} + +.searchLogo { + width: 15px; + height: 15px; + position: absolute; + left: 6px; + top: 6px; + background-image:url('data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIGJhc2VQcm9maWxlPSJmdWxsIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWxuczpldj0iaHR0cDovL3d3dy53My5vcmcvMjAwMS94bWwtZXZlbnRzIj4KPGc%2BCgk8cG9seWdvbiBmaWxsPSIjNjY2IiBwb2ludHM9IjkuMjA3LDYuMTI2IDcuNzkzLDcuNTQxIDExLjc5MywxMS41NDEgMTMuMjA3LDEwLjEyNiIgLz4KCTxwYXRoIGZpbGw9IiM2NjYiIGQ9Ik01LjkxNywyYzEuNjA4LDAsMi45MTcsMS4zMDgsMi45MTcsMi45MTdTNy41MjUsNy44MzMsNS45MTcsNy44MzNTMyw2LjUyNSwzLDQuOTE3UzQuMzA4LDIsNS45MTcsMgoJCSBNNS45MTcsMEMzLjIwMSwwLDEsMi4yMDEsMSw0LjkxN3MyLjIwMSw0LjkxNyw0LjkxNyw0LjkxN3M0LjkxNy0yLjIwMSw0LjkxNy00LjkxN0MxMC44MzMsMi4yMDEsOC42MzIsMCw1LjkxNywwTDUuOTE3LDB6IiAvPgo8L2c%2BCjwvc3ZnPgo%3D'); +} \ No newline at end of file diff --git a/_server/editor.js b/_server/editor.js index f83e68b4..f90a9b6f 100644 --- a/_server/editor.js +++ b/_server/editor.js @@ -235,6 +235,7 @@ editor.prototype.changeFloor = function (floorId, callback) { }); editor.currentFloorData[name]=mapArray; } + editor.preMapData = null; core.changeFloor(floorId, null, {"x": 0, "y": 0, "direction": "up"}, null, function () { core.bigmap.offsetX=0; core.bigmap.offsetY=0; @@ -294,11 +295,18 @@ editor.prototype.drawPosSelection = function () { } editor.prototype.updateMap = function () { + var evs = {}; + if (editor.currentFloorData && editor.currentFloorData.events) { + for (var loc in editor.currentFloorData.events) { + if (editor.currentFloorData.events[loc].animate == false) + evs[loc] = {"animate": false}; + } + } var blocks = main.editor.mapIntoBlocks(editor.map.map(function (v) { return v.map(function (v) { return v.idnum || v || 0 }) - }), {'events': {}, 'changeFloor': {}}, editor.currentFloorId); + }), {'events': evs, 'changeFloor': {}}, editor.currentFloorId); core.status.thisMap.blocks = blocks; main.editor.updateMap(); @@ -728,7 +736,7 @@ editor.prototype.listen = function () { holdingPath = 0; e.stopPropagation(); if (stepPostfix && stepPostfix.length) { - preMapData = JSON.parse(JSON.stringify({map:editor.map,fgmap:editor.fgmap,bgmap:editor.bgmap})); + editor.preMapData = JSON.parse(JSON.stringify({map:editor.map,fgmap:editor.fgmap,bgmap:editor.bgmap})); if(editor.brushMod!=='line'){ var x0=stepPostfix[0].x; var y0=stepPostfix[0].y; @@ -822,7 +830,7 @@ editor.prototype.listen = function () { } } - var preMapData = {}; + editor.preMapData = null; var currDrawData = { pos: [], info: {} @@ -836,18 +844,18 @@ editor.prototype.listen = function () { if (e.altKey && [48, 49, 50, 51, 52, 53, 54, 55, 56, 57].indexOf(e.keyCode) !== -1) e.preventDefault(); //Ctrl+z 撤销上一步undo - if (e.keyCode == 90 && e.ctrlKey && preMapData && currDrawData.pos.length && selectBox.isSelected) { - editor.map = JSON.parse(JSON.stringify(preMapData.map)); - editor.fgmap = JSON.parse(JSON.stringify(preMapData.fgmap)); - editor.bgmap = JSON.parse(JSON.stringify(preMapData.bgmap)); + if (e.keyCode == 90 && e.ctrlKey && editor.preMapData && currDrawData.pos.length && selectBox.isSelected) { + editor.map = JSON.parse(JSON.stringify(editor.preMapData.map)); + editor.fgmap = JSON.parse(JSON.stringify(editor.preMapData.fgmap)); + editor.bgmap = JSON.parse(JSON.stringify(editor.preMapData.bgmap)); editor.updateMap(); reDo = JSON.parse(JSON.stringify(currDrawData)); currDrawData = {pos: [], info: {}}; - preMapData = null; + editor.preMapData = null; } //Ctrl+y 重做一步redo if (e.keyCode == 89 && e.ctrlKey && reDo && reDo.pos.length && selectBox.isSelected) { - preMapData = JSON.parse(JSON.stringify({map:editor.map,fgmap:editor.fgmap,bgmap:editor.bgmap})); + editor.preMapData = JSON.parse(JSON.stringify({map:editor.map,fgmap:editor.fgmap,bgmap:editor.bgmap})); for (var j = 0; j < reDo.pos.length; j++) editor.map[reDo.pos[j].y][reDo.pos[j].x] = JSON.parse(JSON.stringify(reDo.info)); @@ -1027,7 +1035,7 @@ editor.prototype.listen = function () { copyLoc.onmousedown = function(e){ editor.hideMidMenu(); e.stopPropagation(); - preMapData = null; + editor.preMapData = null; reDo = null; editor_mode.onmode(''); var now = editor.pos; @@ -1060,7 +1068,7 @@ editor.prototype.listen = function () { moveLoc.onmousedown = function(e){ editor.hideMidMenu(); e.stopPropagation(); - preMapData = null; + editor.preMapData = null; reDo = null; var thisevent = editor.map[editor.pos.y][editor.pos.x]; if(thisevent==0){ @@ -1106,7 +1114,7 @@ editor.prototype.listen = function () { clearLoc.onmousedown = function(e){ editor.hideMidMenu(); e.stopPropagation(); - preMapData = null; + editor.preMapData = null; reDo = null; editor.info = 0; editor_mode.onmode(''); diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index dcabfcf4..981a2746 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -4,12 +4,13 @@ editor_blockly = function () { initscript = String.raw` (function(){ - var getCategory = function(name){ + var getCategory = function(name,custom){ for(var node of document.getElementById('toolbox').children) { if(node.getAttribute('name')==name) return node; } var node = document.createElement('category'); node.setAttribute('name',name); + if(custom)node.setAttribute('custom',custom); document.getElementById('toolbox').appendChild(node); return node; } @@ -242,15 +243,19 @@ editor_blockly = function () { } ] },'event'), - ], + '最近使用事件':[ + '', + ] } var toolboxgap = '' //xml_text = MotaActionFunctions.actionParser.parse(obj,type||'event') //MotaActionBlocks['idString_e'].xmlText() for (var name in toolboxObj){ - getCategory(name).innerHTML = toolboxObj[name].join(toolboxgap); + var custom = null; + if(name=='最近使用事件')custom='searchBlockCategory'; + getCategory(name,custom).innerHTML = toolboxObj[name].join(toolboxgap); } var blocklyArea = document.getElementById('blocklyArea'); @@ -268,6 +273,23 @@ var workspace = Blockly.inject(blocklyDiv,{ }, trashcan: false, }); + +editor_blockly.searchBlockCategoryCallback = function(workspace) { + var xmlList = []; + var labels = editor_blockly.searchBlock(); + for (var i = 0; i < labels.length; i++) { + var blockText = '' + + MotaActionBlocks[labels[i]].xmlText() + + ''; + var block = Blockly.Xml.textToDom(blockText).firstChild; + block.setAttribute("gap", 5); + xmlList.push(block); + } + return xmlList; +}; + +workspace.registerToolboxCategoryCallback( + 'searchBlockCategory', editor_blockly.searchBlockCategoryCallback); var onresize = function(e) { blocklyDiv.style.width = blocklyArea.offsetWidth + 'px'; @@ -288,8 +310,11 @@ document.getElementById('blocklyDiv').onmousewheel = function(e){ workspace.setScale(workspace.scale); } - var doubleClickCheck=[[0,'abc']]; - function omitedcheckUpdateFunction(event) { +var doubleClickCheck=[[0,'abc']]; +function omitedcheckUpdateFunction(event) { + if(event.type==='create'){ + editor_blockly.addIntoLastUsedType(event.blockId); + } if(event.type==='ui'){ var newClick = [new Date().getTime(),event.blockId]; var lastClick = doubleClickCheck.shift(); @@ -510,6 +535,97 @@ document.getElementById('blocklyDiv').onmousewheel = function(e){ } } + editor_blockly.lastUsedType=[ + 'text_0_s', + 'comment_s', + 'show_s', + 'hide_s', + 'setValue_s', + 'if_s', + 'battle_s', + 'openDoor_s', + 'choices_s', + 'setText_s', + 'exit_s', + 'revisit_s', + 'sleep_s', + 'setBlock_s' + ]; // 最常用的15个图块 + editor_blockly.lastUsedTypeNum=15; + + editor_blockly.addIntoLastUsedType=function(blockId) { + var b = editor_blockly.workspace.getBlockById(blockId); + if(!b)return; + var blockType = b.type; + if(!blockType || blockType.indexOf("_s")!==blockType.length-2 || blockType==='pass_s')return; + editor_blockly.lastUsedType = editor_blockly.lastUsedType.filter(function (v) {return v!==blockType;}); + if (editor_blockly.lastUsedType.length >= editor_blockly.lastUsedTypeNum) + editor_blockly.lastUsedType.pop(); + editor_blockly.lastUsedType.unshift(blockType); + + document.getElementById("searchBlock").value=''; + } + + // Index from 1 - 9 + editor_blockly.openToolbox = function(index) { + // var element = document.getElementById(':'+index); + // if (element == null || element.getAttribute("aria-selected")=="true") return; + // element.click(); + editor_blockly.workspace.toolbox_.tree_.setSelectedItem(editor_blockly.workspace.toolbox_.tree_.children_[index-1]); + } + editor_blockly.reopenToolbox = function(index) { + // var element = document.getElementById(':'+index); + // if (element == null) return; + // if (element.getAttribute("aria-selected")=="true") element.click(); + // element.click(); + editor_blockly.workspace.toolbox_.tree_.setSelectedItem(editor_blockly.workspace.toolbox_.tree_.children_[index-1]); + editor_blockly.workspace.getFlyout_().show(editor_blockly.workspace.toolbox_.tree_.children_[index-1].blocks); + } + + editor_blockly.closeToolbox = function() { + /* + for (var i=1; i<=10; i++) { + var element = document.getElementById(':'+i); + if (element && element.getAttribute("aria-selected")=="true") { + element.click(); + return; + } + } + */ + editor_blockly.workspace.toolbox_.clearSelection(); + } + + var searchInput = document.getElementById("searchBlock"); + searchInput.onfocus = function () { + editor_blockly.reopenToolbox(9); + } + + searchInput.oninput = function () { + editor_blockly.reopenToolbox(9); + } + + editor_blockly.searchBlock = function (value) { + if (value == null) value = searchInput.value; + value = value.toLowerCase(); + if (value == '') return editor_blockly.lastUsedType; + var results = []; + for (var name in MotaActionBlocks) { + if (typeof name !== 'string' || name.indexOf("_s") !== name.length-2) continue; + var block = MotaActionBlocks[name]; + if(block && block.json) { + if ((block.json.type||"").toLowerCase().indexOf(value)>=0 + || (block.json.message0||"").toLowerCase().indexOf(value)>=0 + || (block.json.tooltip||"").toLowerCase().indexOf(value)>=0) { + results.push(name); + if (results.length>=editor_blockly.lastUsedTypeNum) + break; + } + } + } + + return results.length == 0 ? editor_blockly.lastUsedType : results; + } + return editor_blockly; } //editor_blockly=editor_blockly(); \ No newline at end of file diff --git a/docs/V2.0.md b/docs/V2.0.md index 908ca193..9c44dfa1 100644 --- a/docs/V2.0.md +++ b/docs/V2.0.md @@ -1,6 +1,6 @@ # V2.0版本介绍 -?> 目前版本**v2.5.2**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.5.3**,上次更新时间:* {docsify-updated} * 目前样板已经更新到V2.0版本以上,本章将对V2.0的一些内容进行介绍。 diff --git a/docs/api.md b/docs/api.md index c1f9bc74..bba4bba2 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1,6 +1,6 @@ # 附录: API列表 -?> 目前版本**v2.5.2**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.5.3**,上次更新时间:* {docsify-updated} * **这里只列出所有可能会被造塔者用到的常用API,更多的有关内容请在代码内进行查询。** @@ -135,11 +135,15 @@ core.changeFloor('MT5', null, {'x': 3, 'y': 6}, 0) 无动画切换到MT5层的(3 core.resetMap() -重置当前楼层地图。 +重置当前楼层地图和楼层属性。 当我们修改某一层地图后,进游戏读档,会发现修改的内容并没有被更新上去。 这是因为,H5的存档是会存下来每一个楼层的地图的,读档会从档里面获得地图信息。 此时,如果我们在某一层地图执行 core.resetMap() ,则可以立刻从剧本中读取并重置当前楼层地图。 已经被修改过的内容也会相应出现。 +此函数参数有三种形式: + - 不加任何参数,表示重置当前层:core.resetMap() + - 加上一个floorId,表示重置某一层:core.resetMap("MT1") + - 使用一个数组,表示重置若干层:core.resetMap(["MT1", "MT2", "MT3"]) R @@ -500,7 +504,7 @@ core.utils.decodeBase64(str) Base64解密字符串 -core.utils.formatBigNumber(x) +core.utils.formatBigNumber(x, onMap) 大数据的格式化 diff --git a/docs/element.md b/docs/element.md index 7ef586d3..807cacf4 100644 --- a/docs/element.md +++ b/docs/element.md @@ -1,6 +1,6 @@ # 元件说明 -?> 目前版本**v2.5.2**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.5.3**,上次更新时间:* {docsify-updated} * 在本章中,将对样板里的各个元件进行说明。各个元件主要包括道具、门、怪物、楼梯等等。 diff --git a/docs/event.md b/docs/event.md index 9f09a82e..e0cad317 100644 --- a/docs/event.md +++ b/docs/event.md @@ -1,6 +1,6 @@ # 事件 -?> 目前版本**v2.5.2**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.5.3**,上次更新时间:* {docsify-updated} * 本章内将对样板所支持的事件进行介绍。 diff --git a/docs/index.md b/docs/index.md index f46c24e5..1689ac40 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,6 +1,6 @@ # HTML5 魔塔样板说明文档 -?> 目前版本**v2.5.2**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.5.3**,上次更新时间:* {docsify-updated} * 众所周知,魔塔的趋势是向移动端发展,贴吧中也常常能见到“求手机魔塔”的帖子。然而现有的工具中,NekoRPG有着比较大的局限性,游戏感较差,更是完全没法在iOS上运行。而一些APP的魔塔虽然可用,但是必须要下载安装,对于Android和iOS还必须开发不同的版本,非常麻烦。 diff --git a/docs/personalization.md b/docs/personalization.md index 153ee029..a3816fc6 100644 --- a/docs/personalization.md +++ b/docs/personalization.md @@ -1,6 +1,6 @@ # 个性化 -?> 目前版本**v2.5.2**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.5.3**,上次更新时间:* {docsify-updated} * 有时候只靠样板本身可能是不够的。我们需要一些个性化、自定义的素材,道具效果,怪物属性,等等。 @@ -8,17 +8,17 @@ HTML5魔塔是使用画布(canvas)来绘制,存在若干个图层,它们之间有一个覆盖关系,后面的图层将覆盖前面的图层。 -所有图层从低往高依次如下: +所有图层从低往高依次如下:(加[B]的代表该层是大地图) -- bg:背景层;绘制背景图层素材bgmap,和背景贴图 -- event:事件层;所有事件(道具、墙壁、NPC、怪物等)都绘制在这一层进行处理 +- bg**[B]**:背景层;绘制背景图层素材bgmap,和背景贴图 +- event**[B]**:事件层;所有事件(道具、墙壁、NPC、怪物等)都绘制在这一层进行处理 - hero:勇士层;主要用来绘制勇士 -- event2:事件2层;本层主要用来绘制48x32的图片素材的上半部分(避免和勇士错位) -- fg:前景层;绘制前景图层素材fgmap,和前景贴图 -- damage:显伤层;主要用来绘制怪物显伤和领域显伤 -- animate:动画层;主要用来绘制动画。showImage事件绘制的图片也是在这一层。 -- weather:天气层;主要用来绘制天气(雨/雪) -- route:路线层;主要用来绘制勇士的行走路线图,也用来绘制图块的淡入/淡出效果,图块的移动等。 +- event2**[B]**:事件2层;本层主要用来绘制48x32的图片素材的上半部分(避免和勇士错位) +- fg**[B]**:前景层;绘制前景图层素材fgmap,和前景贴图 +- damage**[B]**:显伤层;主要用来绘制怪物显伤和领域显伤 +- animate:动画层;主要用来绘制动画。 +- weather:天气层;主要用来绘制天气(雨/雪/雾) +- route**[B]**:路线层;主要用来绘制勇士的行走路线图,也用来绘制图块的淡入/淡出效果,图块的移动等。 - curtain:色调层;用来控制当前楼层的画面色调 - image:图片层;主要用来绘制显示图片;该层之所以在curtain层上是为了可以在全黑时贴大头像图 - ui:UI层;用来绘制一切UI窗口,如剧情文本、怪物手册、楼传器、系统菜单等等 @@ -351,10 +351,11 @@ function (enemy, hero_hp, hero_atk, hero_def, hero_mdef, x, y, floorId) { ``` js // 写在获得道具后事件 [ - {"type": "setValue", "name": "no_zone", "value": "true"}, // 免疫领域 - {"type": "setValue", "name": "no_snipe", "value": "true"}, // 免疫阻击 - {"type": "setValue", "name": "no_laser", "value": "true"}, // 免疫激光 - {"type": "setValue", "name": "no_betweenAttack", "value": "true"}, // 免疫夹击 + // 设置不同的flag可以分别无视对应的阻激夹域效果 + {"type": "setValue", "name": "flag:no_zone", "value": "true"}, // 免疫领域 + {"type": "setValue", "name": "flag:no_snipe", "value": "true"}, // 免疫阻击 + {"type": "setValue", "name": "flag:no_laser", "value": "true"}, // 免疫激光 + {"type": "setValue", "name": "flag:no_betweenAttack", "value": "true"}, // 免疫夹击 ] ``` 4. 如果有更高的需求,例如想让吸血效果变成一半,则还是在上面这些地方进行对应的修改即可。 @@ -620,7 +621,7 @@ this.statusBar = { }, 'icons': { // ...其他略 - 'speed': 24, // 图标的定义,这里对应的是icons.png中的索引 + 'speed': 37, // 图标的定义,这里对应的是icons.png中的索引 }, // ...其他略 'speed': document.getElementById('speed'), // 显示内容(数据)的定义 diff --git a/docs/start.md b/docs/start.md index 27a6b3c8..1b4bcd71 100644 --- a/docs/start.md +++ b/docs/start.md @@ -1,6 +1,6 @@ # 快速上手 -?> 目前版本**v2.5.2**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.5.3**,上次更新时间:* {docsify-updated} * 在这一节中,将详细介绍做一部塔的流程。现在,让我们来做一部单层塔! diff --git a/editor-mobile.html b/editor-mobile.html index c3396905..fedd1cb1 100644 --- a/editor-mobile.html +++ b/editor-mobile.html @@ -179,6 +179,11 @@ + +
+ + +
diff --git a/editor.html b/editor.html index 54cdb46e..df51ae2e 100644 --- a/editor.html +++ b/editor.html @@ -178,6 +178,10 @@ +
+ + +
diff --git a/libs/actions.js b/libs/actions.js index 499e551f..917774c5 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -192,8 +192,8 @@ actions.prototype.keyDown = function(keyCode) { } ////// 根据放开键的code来执行一系列操作 ////// -actions.prototype.keyUp = function(keyCode, altKey) { - if (core.isset(core.status.replay)&&core.status.replay.replaying +actions.prototype.keyUp = function(keyCode, altKey, fromReplay) { + if (!fromReplay && core.isset(core.status.replay)&&core.status.replay.replaying &&core.status.event.id!='save'&&(core.status.event.id||"").indexOf('book')!=0&&core.status.event.id!='viewMaps') return; if (core.status.lockControl) { @@ -1821,19 +1821,6 @@ actions.prototype.clickSwitchs = function (x,y) { core.ui.drawSwitchs(); break; case 8: - if (core.platform.isPC) - window.open("editor.html", "_blank"); - else if (confirm("即将离开本塔,跳转至本塔工程页面,确认?")) { - window.location.href = "editor-mobile.html"; - } - break; - case 9: - if (core.platform.isPC) - window.open(core.firstData.name+".zip"); - else - window.location.href = core.firstData.name+".zip"; - break; - case 10: core.status.event.selection=0; core.ui.drawSettings(); break; @@ -2416,6 +2403,13 @@ actions.prototype.clickGameInfo = function (x, y) { core.ui.drawStatistics(); break; case 1: + if (core.platform.isPC) + window.open("editor.html", "_blank"); + else if (confirm("即将离开本塔,跳转至本塔工程页面,确认?")) { + window.location.href = "editor-mobile.html"; + } + break; + case 2: if (core.platform.isPC) { window.open("/score.php?name="+core.firstData.name+"&num=10", "_blank"); } @@ -2425,13 +2419,19 @@ actions.prototype.clickGameInfo = function (x, y) { } } break; - case 2: + case 3: core.ui.drawHelp(); break; - case 3: + case 4: core.ui.drawAbout(); break; - case 4: + case 5: + if (core.platform.isPC) + window.open(core.firstData.name+".zip"); + else + window.location.href = core.firstData.name+".zip"; + break; + case 6: core.status.event.selection=5; core.ui.drawSettings(); break; diff --git a/libs/control.js b/libs/control.js index 9edbda74..7f786c75 100644 --- a/libs/control.js +++ b/libs/control.js @@ -368,9 +368,6 @@ control.prototype.resetStatus = function(hero, hard, floorId, route, maps, value // 清除游戏数据 core.clearStatus(); - // 显示状态栏 - core.control.triggerStatusBar("show"); - // 初始化status core.status = core.clone(core.initStatus); // 初始化maps @@ -411,6 +408,8 @@ control.prototype.resetStatus = function(hero, hard, floorId, route, maps, value else core.values = core.clone(core.data.values); core.events.initGame(); + this.updateGlobalAttribute(Object.keys(core.status.globalAttribute)); + this.triggerStatusBar(core.getFlag('hideStatusBar', false)?'hide':'show'); core.status.played = true; } @@ -1387,7 +1386,7 @@ control.prototype.snipe = function (snipes) { else if (damage < core.status.hero.hp) color = '#FF7F00'; else color = '#FF0000'; - damage = core.formatBigNumber(damage); + damage = core.formatBigNumber(damage, true); if (core.enemys.hasSpecial(core.material.enemys[block.event.id], 19)) damage += "+"; if (core.enemys.hasSpecial(core.material.enemys[block.event.id], 21)) @@ -1569,26 +1568,26 @@ control.prototype.setFg = function(color, time, callback) { return; } - var step=0; - // core.status.replay.animate=true; + var per_time = 10, step=0, steps = parseInt(time / per_time); + var changeAnimate = setInterval(function() { step++; - var nowA = fromColor[3]+(color[3]-fromColor[3])*step/25; - var nowR = parseInt(fromColor[0]+(color[0]-fromColor[0])*step/25); - var nowG = parseInt(fromColor[1]+(color[1]-fromColor[1])*step/25); - var nowB = parseInt(fromColor[2]+(color[2]-fromColor[2])*step/25); + var nowA = fromColor[3]+(color[3]-fromColor[3])*step/steps; + var nowR = parseInt(fromColor[0]+(color[0]-fromColor[0])*step/steps); + var nowG = parseInt(fromColor[1]+(color[1]-fromColor[1])*step/steps); + var nowB = parseInt(fromColor[2]+(color[2]-fromColor[2])*step/steps); core.clearMap('curtain'); core.fillRect('curtain', 0, 0, 416, 416, core.arrayToRGBA([nowR,nowG,nowB,nowA])); - if (step>=25) { + if (step>=steps) { delete core.animateFrame.asyncId[changeAnimate]; clearInterval(changeAnimate); core.status.curtainColor = color; // core.status.replay.animate=false; if (core.isset(callback)) callback(); } - }, time/25/core.status.replay.speed); + }, per_time); core.animateFrame.asyncId[changeAnimate] = true; } @@ -1636,7 +1635,7 @@ control.prototype.updateDamage = function (floorId, canvas) { else if (damage < hero_hp * 2 / 3) color = '#FFFF00'; else if (damage < hero_hp) color = '#FF7F00'; else color = '#FF0000'; - damage = core.formatBigNumber(damage); + damage = core.formatBigNumber(damage, true); if (core.enemys.hasSpecial(core.material.enemys[id], 19)) damage += "+"; if (core.enemys.hasSpecial(core.material.enemys[id], 21)) @@ -1659,7 +1658,7 @@ control.prototype.updateDamage = function (floorId, canvas) { if (core.flags.displayCritical) { var critical = core.enemys.nextCriticals(id); if (critical.length>0) critical=critical[0]; - critical = core.formatBigNumber(critical[0]); + critical = core.formatBigNumber(critical[0], true); if (critical == '???') critical = '?'; canvas.fillStyle = '#000000'; canvas.fillText(critical, 32 * x + 2, 32 * (y + 1) - 2 - 10); @@ -1691,7 +1690,7 @@ control.prototype.updateDamage = function (floorId, canvas) { for (var y=0;y0) { - damage = core.formatBigNumber(damage); + damage = core.formatBigNumber(damage, true); canvas.fillStyle = '#000000'; canvas.fillText(damage, 32 * x + 17, 32 * (y + 1) - 13); canvas.fillText(damage, 32 * x + 15, 32 * (y + 1) - 15); @@ -2144,7 +2143,7 @@ control.prototype.replay = function () { } } else if (action.indexOf('key:')==0) { - core.actions.keyUp(parseInt(action.substring(4)), true); + core.actions.keyUp(parseInt(action.substring(4)), false, true); core.replay(); return; } @@ -2845,6 +2844,7 @@ control.prototype.triggerStatusBar = function (name) { var statusItems = core.dom.status; var toolItems = core.dom.tools; core.domStyle.showStatusBar = name == 'show'; + core.setFlag('hideStatusBar', core.domStyle.showStatusBar?null:true); if (!core.domStyle.showStatusBar) { for (var i = 0; i < statusItems.length; ++i) statusItems[i].style.opacity = 0; @@ -2910,11 +2910,11 @@ control.prototype.updateGlobalAttribute = function (name) { var border = '3px ' + attribute[name] + ' solid'; core.dom.statusBar.style.borderTop = border; core.dom.statusBar.style.borderLeft = border; - core.dom.statusBar.style.borderRight = core.domStyle.isVertical?'':border; + core.dom.statusBar.style.borderRight = core.domStyle.isVertical?border:''; core.dom.gameDraw.style.border = border; core.dom.toolBar.style.borderBottom = border; core.dom.toolBar.style.borderLeft = border; - core.dom.toolBar.style.borderRight = core.domStyle.isVertical?'':border; + core.dom.toolBar.style.borderRight = core.domStyle.isVertical?border:''; break; } case 'statusBarColor': diff --git a/libs/core.js b/libs/core.js index 3c332ee8..6b5f1a8a 100644 --- a/libs/core.js +++ b/libs/core.js @@ -431,8 +431,8 @@ core.prototype.keyDown = function(keyCode) { } ////// 根据放开键的code来执行一系列操作 ////// -core.prototype.keyUp = function(keyCode, altKey) { - return core.actions.keyUp(keyCode, altKey); +core.prototype.keyUp = function(keyCode, altKey, fromReplay) { + return core.actions.keyUp(keyCode, altKey, fromReplay); } ////// 点击(触摸)事件按下时 ////// @@ -1065,8 +1065,8 @@ core.prototype.formatDate2 = function (date) { } ////// 格式化大数 ////// -core.prototype.formatBigNumber = function (x) { - return core.utils.formatBigNumber(x); +core.prototype.formatBigNumber = function (x, onMap) { + return core.utils.formatBigNumber(x, onMap); } ////// 两位数显示 ////// diff --git a/libs/enemys.js b/libs/enemys.js index a3097af3..bc1563b5 100644 --- a/libs/enemys.js +++ b/libs/enemys.js @@ -179,7 +179,9 @@ enemys.prototype.nextCriticals = function (enemy, number, x, y, floorId) { } else { // 暴力for循环法 pre = info.damage; - for (var atk=hero_atk+1;atk<=mon_hp+mon_def;atk++) { + var per_add = Math.ceil(hero_atk / 5000); + if (per_add<0) per_add = 1; + for (var atk=hero_atk+per_add;atk<=mon_hp+mon_def;atk+=per_add) { var nextInfo = this.getDamageInfo(enemy, core.status.hero.hp, atk, core.status.hero.def, core.status.hero.mdef, x, y, floorId); if (nextInfo==null) break; if (pre>nextInfo.damage) { diff --git a/libs/events.js b/libs/events.js index 0548fe7c..922a8e27 100644 --- a/libs/events.js +++ b/libs/events.js @@ -117,7 +117,7 @@ events.prototype.startGame = function (hard, seed, route, callback) { core.changeFloor(core.firstData.floorId, null, nowLoc, null, function() { if (core.isset(callback)) callback(); - }, true); + }); setTimeout(function () { // Upload @@ -1723,21 +1723,20 @@ events.prototype.setVolume = function (value, time, callback) { if (core.isset(callback)) callback(); return; } - // core.status.replay.animate=true; + var currVolume = core.musicStatus.volume; - var step = 0; + var per_time = 10, step = 0, steps = parseInt(time / per_time); var fade = setInterval(function () { step++; - var nowVolume = currVolume+(value-currVolume)*step/32; + var nowVolume = currVolume+(value-currVolume)*step/steps; set(nowVolume); - if (step>=32) { + if (step>=steps) { delete core.animateFrame.asyncId[fade]; clearInterval(fade); - // core.status.replay.animate=false; if (core.isset(callback)) callback(); } - }, time / 32); + }, per_time); core.animateFrame.asyncId[fade] = true; } @@ -1892,12 +1891,14 @@ events.prototype.checkLvUp = function () { if (!core.flags.enableLevelUp || !core.isset(core.firstData.levelUp) || core.status.hero.lv>=core.firstData.levelUp.length) return; // 计算下一个所需要的数值 - var need=core.calValue((core.firstData.levelUp[core.status.hero.lv]||{}).need); + var next = (core.firstData.levelUp[core.status.hero.lv]||{}); + var need = core.calValue(next.need); if (!core.isset(need)) return; if (core.status.hero.experience>=need) { // 升级 core.status.hero.lv++; - core.insertAction(core.firstData.levelUp[core.status.hero.lv-1].action); + if (next.clear) core.status.hero.experience -= need; + core.insertAction(next.action); this.checkLvUp(); } } diff --git a/libs/items.js b/libs/items.js index fcba3daa..f8a7bfc1 100644 --- a/libs/items.js +++ b/libs/items.js @@ -91,6 +91,7 @@ items.prototype.useItem = function (itemId, callback) { delete core.status.hero.items[itemCls][itemId]; core.updateStatusBar(); + core.status.event.data = null; if (core.isset(callback)) callback(); } @@ -100,16 +101,18 @@ items.prototype.canUseItem = function (itemId) { // 没有道具 if (!core.hasItem(itemId)) return false; + var able = false; if (itemId in this.canUseItemEffect) { try { - return eval(this.canUseItemEffect[itemId]); + able = eval(this.canUseItemEffect[itemId]); } catch (e) { console.log(e); } } + if (!able) core.status.event.data = null; - return false; + return able; } ////// 获得某个物品的个数 ////// diff --git a/libs/maps.js b/libs/maps.js index 87977043..d823c6cc 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -146,9 +146,13 @@ maps.prototype.addEvent = function (block, x, y, event) { if (!core.isset(block.disable) && core.isset(event.enable)) { block.disable=!event.enable; } + // 覆盖animate + if (event.animate === false) { + block.event.animate = 1; + } // 覆盖所有属性 for (var key in event) { - if (key!="enable" && core.isset(event[key])) { + if (key!="enable" && key!="animate" && core.isset(event[key])) { block.event[key]=core.clone(event[key]); } } @@ -476,7 +480,7 @@ maps.prototype.drawBgFgMap = function (floorId, canvas, name, animate) { } } } - core.status.autotileAnimateObjs[name+"map"] = core.clone(arr); + if (animate) core.status.autotileAnimateObjs[name+"map"] = core.clone(arr); } ////// 绘制某张地图 ////// @@ -1129,9 +1133,10 @@ maps.prototype.animateBlock = function (loc,type,time,callback) { core.setAlpha('route', alpha); draw(); - var animate = window.setInterval(function () { - if (type=='show') alpha += 0.1; - else alpha -= 0.1; + var per_time = 10, steps = parseInt(time / per_time), delta = 1 / steps; + var animate = setInterval(function () { + if (type=='show') alpha += delta; + else alpha -= delta; clear(); if (alpha >=1 || alpha<=0) { delete core.animateFrame.asyncId[animate]; @@ -1153,7 +1158,7 @@ maps.prototype.animateBlock = function (loc,type,time,callback) { core.setAlpha('route', alpha); draw(); } - }, time / 10 / core.status.replay.speed); + }, per_time); core.animateFrame.asyncId[animate] = true; } @@ -1487,13 +1492,12 @@ maps.prototype.setBgFgMap = function (type, name, loc, floorId, callback) { maps.prototype.resetMap = function(floorId) { floorId = floorId || core.status.floorId; if (!core.isset(floorId)) return; - core.status.maps[floorId] = this.loadFloor(floorId); - if (floorId==core.status.floorId) { - this.drawMap(floorId, function () { - core.drawTip("地图重置成功"); - }) - } - else { - core.drawTip(floorId+"地图重置成功"); - } + if (typeof floorId == 'string') floorId = [floorId]; + var needRefresh = false; + floorId.forEach(function (t) { + core.status.maps[t] = core.maps.loadFloor(t); + if (t == core.status.floorId) needRefresh = true; + }); + if (needRefresh) this.drawMap(core.status.floorId); + core.drawTip("地图重置成功"); } \ No newline at end of file diff --git a/libs/ui.js b/libs/ui.js index 3a08b4e7..0ca964c4 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -955,6 +955,18 @@ ui.prototype.drawConfirmBox = function (text, yesCallback, noCallback) { core.clearLastEvent(); core.setFillStyle('ui', core.material.groundPattern); + + var background = core.status.textAttribute.background; + var isWindowSkin = false; + if (typeof background == 'string') { + background = core.material.images.images[background]; + if (core.isset(background) && background.width==192 && background.height==128) isWindowSkin = true; + else background = core.initStatus.textAttribute.background; + } + if (!isWindowSkin) background = core.arrayToRGBA(background); + var borderColor = core.status.globalAttribute.borderColor; + var textColor = core.arrayToRGBA(core.status.textAttribute.text); + var globalFont = core.status.globalAttribute.font; core.setFont('ui', "bold 19px "+globalFont); @@ -967,29 +979,35 @@ ui.prototype.drawConfirmBox = function (text, yesCallback, noCallback) { var left = Math.min(208 - 40 - parseInt(max_length / 2), 100); var top = 140 - (lines-1)*30; - var right = 416 - 2 * left, bottom = 416 - 140 - top; + var right = 416 - left, bottom = 416 - 140, width = right - left, height = bottom - top; - var borderColor = core.status.globalAttribute.borderColor; + core.clearMap('ui'); + if (isWindowSkin) { + core.setAlpha('ui', 0.85); + this.drawWindowSkin(background,'ui',left,top,width,height); + } + else { + core.fillRect('ui', left, top, width, height, background); + core.strokeRect('ui', left - 1, top - 1, width + 1, height + 1, borderColor, 2); + } + core.setAlpha('ui', 1); - if (core.isPlaying()) - core.fillRect('ui', left, top, right, bottom, core.material.groundPattern); - if (core.isPlaying()) - core.strokeRect('ui', left - 1, top - 1, right + 1, bottom + 1, borderColor, 2); core.canvas.ui.textAlign = "center"; for (var i in contents) { - core.fillText('ui', contents[i], 208, top + 50 + i*30, "#FFFFFF"); + core.fillText('ui', contents[i], 208, top + 50 + i*30, textColor); } - core.fillText('ui', "确定", 208 - 38, top + bottom - 35, "#FFFFFF", "bold 17px "+globalFont); - core.fillText('ui', "取消", 208 + 38, top + bottom - 35); + core.fillText('ui', "确定", 208 - 38, bottom - 35, null, "bold 17px "+globalFont); + core.fillText('ui', "取消", 208 + 38, bottom - 35); var len=core.canvas.ui.measureText("确定").width; - if (core.status.event.selection==0) { - core.strokeRect('ui', 208-38-parseInt(len/2)-5, top+bottom-35-20, len+10, 28, "#FFD700", 2); - } - if (core.status.event.selection==1) { - core.strokeRect('ui', 208+38-parseInt(len/2)-5, top+bottom-35-20, len+10, 28, "#FFD700", 2); - } + + var strokeLeft = 208 + (76*core.status.event.selection-38) - parseInt(len/2) - 5; + + if (isWindowSkin) + this.drawWindowSelector(background, 'ui', strokeLeft, bottom-35-20, len+10, 28); + else + core.strokeRect('ui', strokeLeft, bottom-35-20, len+10, 28, "#FFD700", 2); } @@ -1006,8 +1024,6 @@ ui.prototype.drawSwitchs = function() { "领域显伤: "+(core.flags.displayExtraDamage ? "[ON]" : "[OFF]"), "新版存档: "+(core.platform.useLocalForage ? "[ON]":"[OFF]"), "单击瞬移: "+(core.getFlag('clickMove', true) ? "[ON]":"[OFF]"), - "查看工程", - "下载离线版本", "返回主菜单" ]; this.drawChoices(null, choices); @@ -1411,7 +1427,7 @@ ui.prototype.drawReplay = function () { ui.prototype.drawGameInfo = function () { core.status.event.id = 'gameInfo'; this.drawChoices(null, [ - "数据统计", "查看评论", "操作帮助", "关于本塔", "返回上级菜单" + "数据统计", "查看工程", "查看评论", "操作帮助", "关于本塔","下载离线版本", "返回主菜单" ]); } @@ -1656,7 +1672,7 @@ ui.prototype.drawBookDetail = function (index) { u.push(t); } }); - hints.push(JSON.stringify(u.map(function (v) {return v[0]+":"+v[1];}))); + hints.push(JSON.stringify(u.map(function (v) {return core.formatBigNumber(v[0])+":"+core.formatBigNumber(v[1]);}))); } } @@ -1690,7 +1706,7 @@ ui.prototype.drawBookDetail = function (index) { hints.push(""); var criticals = core.enemys.nextCriticals(enemyId, 10).map(function (v) { - return v[0]+":"+v[1]; + return core.formatBigNumber(v[0])+":"+core.formatBigNumber(v[1]); }); while (criticals[0]=='0:0') criticals.shift(); hints.push("临界表:"+JSON.stringify(criticals)) @@ -2247,8 +2263,8 @@ ui.prototype.drawSLPanel = function(index, refresh) { core.strokeRect('ui', (2*i+1)*u-size/2, 45, size, size, i==offset?strokeColor:'#FFFFFF', i==offset?6:2); if (core.isset(data) && core.isset(data.floorId)) { core.ui.drawThumbnail(data.floorId, 'ui', core.maps.load(data.maps, data.floorId).blocks, (2*i+1)*u-size/2, 45, size, data.hero.loc.x, data.hero.loc.y, data.hero.loc, data.hero.flags.heroIcon||"hero.png"); - var v = core.formatBigNumber(data.hero.hp)+"/"+core.formatBigNumber(data.hero.atk)+"/"+core.formatBigNumber(data.hero.def); - var v2 = "/"+core.formatBigNumber(data.hero.mdef); + var v = core.formatBigNumber(data.hero.hp,true)+"/"+core.formatBigNumber(data.hero.atk,true)+"/"+core.formatBigNumber(data.hero.def,true); + var v2 = "/"+core.formatBigNumber(data.hero.mdef,true); if (v.length+v2.length<=21) v+=v2; core.fillText('ui', v, (2*i+1)*u, 60+size, '#FFD700', '10px '+globalFont); core.fillText('ui', core.formatDate(new Date(data.time)), (2*i+1)*u, 73+size, data.hero.flags.consoleOpened?'#FF6A6A':'#FFFFFF'); @@ -2263,8 +2279,8 @@ ui.prototype.drawSLPanel = function(index, refresh) { core.strokeRect('ui', (2*i-5)*u-size/2, 233, size, size, i==offset?strokeColor:'#FFFFFF', i==offset?6:2); if (core.isset(data) && core.isset(data.floorId)) { core.ui.drawThumbnail(data.floorId, 'ui', core.maps.load(data.maps, data.floorId).blocks, (2*i-5)*u-size/2, 233, size, data.hero.loc.x, data.hero.loc.y, data.hero.loc, data.hero.flags.heroIcon||"hero.png"); - var v = core.formatBigNumber(data.hero.hp)+"/"+core.formatBigNumber(data.hero.atk)+"/"+core.formatBigNumber(data.hero.def); - var v2 = "/"+core.formatBigNumber(data.hero.mdef); + var v = core.formatBigNumber(data.hero.hp,true)+"/"+core.formatBigNumber(data.hero.atk,true)+"/"+core.formatBigNumber(data.hero.def,true); + var v2 = "/"+core.formatBigNumber(data.hero.mdef,true); if (v.length+v2.length<=21) v+=v2; core.fillText('ui', v, (2*i-5)*u, 248+size, '#FFD700', '10px '+globalFont); core.fillText('ui', core.formatDate(new Date(data.time)), (2*i-5)*u, 261+size, data.hero.flags.consoleOpened?'#FF6A6A':'#FFFFFF', '10px '+globalFont); diff --git a/libs/utils.js b/libs/utils.js index b5dcdd2e..45313e71 100644 --- a/libs/utils.js +++ b/libs/utils.js @@ -297,14 +297,14 @@ utils.prototype.setTwoDigits = function (x) { return parseInt(x)<10?"0"+x:x; } -utils.prototype.formatBigNumber = function (x) { +utils.prototype.formatBigNumber = function (x, onMap) { x = Math.floor(parseFloat(x)); if (!core.isset(x)) return '???'; var c = x<0?"-":""; x = Math.abs(x); - if (x<=999999) return c + x; + if (x<=99999 || (!onMap && x<=999999)) return c + x; var all = [ {"val": 1e20, "c": "g"}, @@ -316,9 +316,17 @@ utils.prototype.formatBigNumber = function (x) { for (var i=0;i=10*one.val) { - var v = x/one.val; - return c + v.toFixed(Math.max(0, Math.floor(4-Math.log10(v+1)))) + one.c; + if (onMap) { + if (x>=one.val) { + var v = x/one.val; + return c + v.toFixed(Math.max(0, Math.floor(3-Math.log10(v+1)))) + one.c; + } + } + else { + if (x>=10*one.val) { + var v = x/one.val; + return c + v.toFixed(Math.max(0, Math.floor(4-Math.log10(v+1)))) + one.c; + } } } @@ -805,6 +813,12 @@ utils.prototype.encodeCanvas = function (ctx) { ////// 解析arr数组,并绘制到tempCanvas上 ////// utils.prototype.decodeCanvas = function (arr, width, height) { + // 清空tempCanvas + var tempCanvas = core.bigmap.tempCanvas; + tempCanvas.canvas.width=width; + tempCanvas.canvas.height=height; + tempCanvas.clearRect(0, 0, width, height); + if (!core.isset(arr)) return null; // to byte array var curr = 0, list = []; @@ -812,11 +826,6 @@ utils.prototype.decodeCanvas = function (arr, width, height) { for (var i=0;i threshold diff --git a/main.js b/main.js index 80ea5f7d..a697bccd 100644 --- a/main.js +++ b/main.js @@ -2,7 +2,7 @@ function main() { //------------------------ 用户修改内容 ------------------------// - this.version = "2.5.2"; // 游戏版本号;如果更改了游戏内容建议修改此version以免造成缓存问题。 + this.version = "2.5.3"; // 游戏版本号;如果更改了游戏内容建议修改此version以免造成缓存问题。 this.useCompress = false; // 是否使用压缩文件 // 当你即将发布你的塔时,请使用“JS代码压缩工具”将所有js代码进行压缩,然后将这里的useCompress改为true。 diff --git a/project/data.js b/project/data.js index e65bf7bd..75900628 100644 --- a/project/data.js +++ b/project/data.js @@ -70,7 +70,7 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "firstData": { "title": "魔塔样板", "name": "template", - "version": "Ver 2.5.2", + "version": "Ver 2.5.3", "floorId": "sample0", "hero": { "name": "阳光", diff --git a/project/functions.js b/project/functions.js index d2ffbc3e..9e06e527 100644 --- a/project/functions.js +++ b/project/functions.js @@ -87,16 +87,19 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = "afterChangeFloor": function (floorId, fromLoad) { // 转换楼层结束的事件 // floorId是切换到的楼层;fromLoad若为true则代表是从读档行为造成的楼层切换 + + // 每次抵达楼层时执行的事件 + if (!fromLoad) { + core.insertAction(core.floors[floorId].eachArrive); + } + + // 首次抵达楼层时执行的事件(后插入,先执行) var visited = core.getFlag("__visited__", []); if (visited.indexOf(floorId)===-1) { core.insertAction(core.floors[floorId].firstArrive); visited.push(floorId); core.setFlag("__visited__", visited); } - // 每次抵达楼层时执行的事件 - if (!fromLoad) { - core.insertAction(core.floors[floorId].eachArrive); - } }, "addPoint": function (enemy) { // 加点事件 @@ -523,9 +526,6 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = init_damage += vampire_damage; } - // 检查是否破防;否则直接返回不可战斗 - if (hero_atk <= mon_def) return null; - // 每回合怪物对勇士造成的战斗伤害 var per_damage = mon_atk - hero_def; // 魔攻:战斗伤害就是怪物攻击力 @@ -554,7 +554,11 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = init_damage += Math.floor(core.values.purify * hero_mdef); // 勇士每回合对怪物造成的伤害 - var hero_per_damage = hero_atk - mon_def; + var hero_per_damage = Math.max(hero_atk - mon_def, 0); + + // 如果没有破防,则不可战斗 + if (hero_per_damage <= 0) return null; + // 勇士的攻击回合数;为怪物生命除以每回合伤害向上取整 var turn = Math.ceil(mon_hp / hero_per_damage); // 最终伤害:初始伤害 + 怪物对勇士造成的伤害 + 反击伤害 @@ -1037,8 +1041,8 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = ctx.drawImage(core.statusBar.icons[name], leftOffset, topOffset, 25, 25); // 文字内容 var text = (core.statusBar[name]||{}).innerText || " "; - // 斜体判定:如果不是纯数字,斜体会非常难看,需要取消 - if (!/^\d*$/.test(text)) ctx.font = 'bold 18px Verdana'; + // 斜体判定:如果不是纯数字和字母,斜体会非常难看,需要取消 + if (!/^[-+_.a-zA-Z0-9]*$/.test(text)) ctx.font = 'bold 18px Verdana'; // 绘制文字 ctx.fillText(text, leftOffset + 36, topOffset + 20); ctx.font = 'italic bold 18px Verdana'; diff --git a/project/images/icons.png b/project/images/icons.png index c5a383c6..ec1e2d45 100644 Binary files a/project/images/icons.png and b/project/images/icons.png differ