From c00ae6e0171841ef976aec17fa04d4fcd88826bd Mon Sep 17 00:00:00 2001 From: ckcz123 Date: Mon, 17 Sep 2018 16:18:33 +0800 Subject: [PATCH 1/9] Equipment --- README.md | 2 + _server/README.md | 4 +- _server/comment.js | 35 +------- _server/editor.js | 6 +- _server/editor_mode.js | 6 +- editor-mobile.html | 6 +- editor.html | 6 +- libs/actions.js | 176 ++++++++++++++++++++++------------------- libs/control.js | 21 ++--- libs/items.js | 4 +- libs/ui.js | 121 +++++++++++++--------------- libs/utils.js | 4 +- 更新说明.txt | 15 +++- 13 files changed, 198 insertions(+), 208 deletions(-) diff --git a/README.md b/README.md index cfc384fe..d2498933 100644 --- a/README.md +++ b/README.md @@ -321,4 +321,6 @@ HTML5魔塔交流群群号: `539113091` [@fux4](https://github.com/fux4) 打通了RM和H5之间的障壁(从而使RM动画导出器和怪物数据导出器成为可能),同时也是部分新功能(如跳跃、跟随、画面震动)等的编写者。 +[@tocque](https://github.com/tocque) 装备栏的编写者。 + 以及[百度贴吧魔塔吧](https://tieba.baidu.com/f?kw=%E9%AD%94%E5%A1%94)和H5魔塔交流群`539113091`内的诸位魔塔爱好者们对本样板的大力支持! diff --git a/_server/README.md b/_server/README.md index 2d6a8d08..374db923 100644 --- a/_server/README.md +++ b/_server/README.md @@ -70,7 +70,7 @@ editor.file.editFunctions(["change","['events']['afterChangeLight']","function(x 生成表格并绑定事件的函数 ```javascript editor.mode.loc(); -editor.mode.emenyitem(); +editor.mode.enemyitem(); editor.mode.floor(); editor.mode.tower(); editor.mode.functions(); @@ -83,7 +83,7 @@ editor.mode.onmode('save');//保存 editor.mode.onmode('nextChange');//下次onmode时前端进行切换 editor.mode.onmode('loc'); -editor.mode.onmode('emenyitem'); +editor.mode.onmode('enemyitem'); editor.mode.onmode('floor'); editor.mode.onmode('tower'); editor.mode.onmode('functions'); diff --git a/_server/comment.js b/_server/comment.js index 9f7bb124..0621926b 100644 --- a/_server/comment.js +++ b/_server/comment.js @@ -23,7 +23,7 @@ comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "equips" ] }, - "_data": "只能取keys(钥匙) items(宝石、血瓶) constants(永久物品) tools(消耗道具) equip(装备)" + "_data": "只能取keys(钥匙) items(宝石、血瓶) constants(永久物品) tools(消耗道具) equips(装备)" }, "name": { "_leaf": true, @@ -38,36 +38,9 @@ comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "_data": "道具在道具栏中显示的描述" }, "equip": { - "_leaf": false, - "_type": "object", - "_data": { - "type": { - "_leaf": true, - "_type": "textarea", - "_data": "如果是装备,其类别,与equipName按顺序对应(从0开始)" - }, - "atk": { - "_leaf": true, - "_type": "textarea", - "_data": "如果是装备,其增加的攻击数值" - }, - "def": { - "_leaf": true, - "_type": "textarea", - "_data": "如果是装备,其增加的防御数值" - }, - "mdef": { - "_leaf": true, - "_type": "textarea", - "_data": "如果是装备,其增加的魔防数值" - }, - "animate": { - "_leaf": true, - "_type": "textarea", - "_string": true, - "_data": "如果是装备,其攻击动画,仅对type为0的装备有效" - } - } + "_leaf": true, + "_type": "textarea", + "_data": "装备属性设置,仅对cls为equips有效。\n如果此项不为null,需要是一个对象,里面可含\"type\",\"atk\",\"def\",\"mdef\",\"animate\"五项,分别对应装备部位、攻防魔防和动画。\n具体详见文档和已有的几个装备的写法。" }, } }, diff --git a/_server/editor.js b/_server/editor.js index 07741e42..6b53043a 100644 --- a/_server/editor.js +++ b/_server/editor.js @@ -709,8 +709,8 @@ editor.prototype.listen = function () { } tip.infos = JSON.parse(JSON.stringify(editor.info)); editor_mode.onmode('nextChange'); - editor_mode.onmode('emenyitem'); - //editor_mode.emenyitem(); + editor_mode.onmode('enemyitem'); + //editor_mode.enemyitem(); } } } @@ -779,7 +779,7 @@ editor.prototype.listen = function () { dataSelection.style.height = ysize - 6 + 'px'; tip.infos = JSON.parse(JSON.stringify(editor.info)); editor_mode.onmode('nextChange'); - editor_mode.onmode('emenyitem'); + editor_mode.onmode('enemyitem'); } var fields = Object.keys(editor.file.comment._data.floors._data.loc._data); diff --git a/_server/editor_mode.js b/_server/editor_mode.js index 47ddbd94..3fe44261 100644 --- a/_server/editor_mode.js +++ b/_server/editor_mode.js @@ -4,7 +4,7 @@ editor_mode = function (editor) { function editor_mode() { this.ids = { 'loc': 'left2', - 'emenyitem': 'left3', + 'enemyitem': 'left3', 'floor': 'left4', 'tower': 'left5', 'functions': 'left8', @@ -208,7 +208,7 @@ editor_mode = function (editor) { editor.drawEventBlock(); }); break; - case 'emenyitem': + case 'enemyitem': if (editor_mode.info.images == 'enemys' || editor_mode.info.images == 'enemy48') { editor.file.editEnemy(editor_mode.info.id, actionList, function (objs_) {/*console.log(objs_);*/ @@ -310,7 +310,7 @@ editor_mode = function (editor) { if (Boolean(callback)) callback(); } - editor_mode.prototype.emenyitem = function (callback) { + editor_mode.prototype.enemyitem = function (callback) { //editor.info=editor.ids[editor.indexs[201]]; if (!core.isset(editor.info)) return; diff --git a/editor-mobile.html b/editor-mobile.html index 5d5a7d8b..9a2b55ea 100644 --- a/editor-mobile.html +++ b/editor-mobile.html @@ -88,7 +88,7 @@ -
+

图块属性  

@@ -264,7 +264,7 @@ - + @@ -449,7 +449,7 @@ if (location.protocol.indexOf("http")!=0) { editor.pos = {x: 0, y: 0}; editor.mode.loc(); editor.info = editor.ids[editor.indexs[201]]; - editor.mode.emenyitem(); + editor.mode.enemyitem(); editor.mode.floor(); editor.mode.tower(); editor.mode.functions(); diff --git a/libs/actions.js b/libs/actions.js index 53fb05ae..d060d672 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -1245,24 +1245,28 @@ actions.prototype.clickToolbox = function(x,y) { } */ var toolsPage = core.status.event.data.toolsPage; - var constantsPage = core.status.event.data.constantsPage + var constantsPage = core.status.event.data.constantsPage; // 上一页 if (x == 3 || x == 4) { - if ( y == 7 && toolsPage>1) + if (y == 7 && toolsPage>1) { core.status.event.data.toolsPage--; - if ( y == 12 && constantsPage>1) - core.status.event.data.constantsPage--; - core.ui.drawToolbox(core.status.event.selection) - return; + core.ui.drawToolbox(core.status.event.selection); + } + if (y == 12 && constantsPage>1) { + core.status.event.data.toolsPage--; + core.ui.drawToolbox(core.status.event.selection); + } } // 下一页 - if ((x == 8 || x == 9)) { - if (( y == 7 && toolsPage1) { + if (index==0) { // 处理向前翻页 + if (toolsPage > 1) { core.status.event.data.toolsPage--; index = 11; } else return; // 第一页不向前翻 - else if (index==12) - if (constantsPage>1) { + } + else if (index==12) { + if (constantsPage == 1) { + if (toolsTotalPage==0) return; + core.status.event.data.toolsPage = toolsTotalPage; + index = (tools.length+11)%12; + } + else { core.status.event.data.constantsPage--; index = 23; } - else return; + } else index -= 1 ; this.clickToolboxIndex(index); return; } if (keycode==38) { // up - if (toolsPage==toolsTotalPage&&index<18&&index>11) { // 进入tools + if (index>=12&&index<=17) { // 进入tools if (toolsTotalPage==0) return; - if (tools.length%12<=6 && tools.length%12>index%12) index -= 12; - else if (tools.length%12>6 && tools.length%6>index%12) index -= 6; - else index = tools.length%12-1; + if (toolsLastIndex>=6) index = Math.min(toolsLastIndex, index-6); + else index = Math.min(toolsLastIndex, index-12); } else if (index<6) return; // 第一行没有向上 else index -= 6; @@ -1349,28 +1360,33 @@ actions.prototype.keyDownToolbox = function (keycode) { core.status.event.data.constantsPage++; index = 12; } - else if((toolsPage==toolsTotalPage && index==tools.length%12-1) || - (constantsPage==constantsTotalPage && index==constants.length%12+11)) // 一个物品无操作 + else if (index == toolsLastIndex) { + if (constantsTotalPage==0) return; + core.status.event.data.constantsPage = 1; + index = 12; + } + else if(index==constantsLastIndex) // 一个物品无操作 return; - else index +=1; + else index++; this.clickToolboxIndex(index); return; } if (keycode==40) { // down - if ((index>5 || (toolsPage==toolsTotalPage && tools.length%12<=6)) && index<12) {// 进入constant - if (constantsTotalPage == 0) return; - if (constantsTotalPage == constantsPage && constants.length%12<(index%6+1)) - index = constants.length%12+11; - else if (index<6) index += 12; - else index += 6; + var nextIndex = null; + if (index<=5) { + if (toolsLastIndex > 5) nextIndex = Math.min(toolsLastIndex, index + 6); + else index+=6; + } + if (nextIndex==null && index<=11) { + if (constantsTotalPage == 0) return; + nextIndex = Math.min(index+6, constantsLastIndex); + } + if (nextIndex==null && index<=17) { + if (constantsLastIndex > 17) nextIndex = Math.min(constantsLastIndex, index+6); + } + if (nextIndex!=null) { + this.clickToolboxIndex(nextIndex); } - else if (toolsPage==toolsTotalPage && tools.length%12>6 && index > tools.length%6 &&index<6) - index = tools.length%12-1; - else if (constantsPage==constantsTotalPage && constants.length%12>6 && index>constants.length%6+11 && index<18) - index = constants.length%12+11; - else if (index>17 || (constantsPage==constantsTotalPage && constants.length%12<=6 && index>11)) return;//最后一行无操作 - else index += 6; - this.clickToolboxIndex(index); return; } } @@ -1438,43 +1454,39 @@ actions.prototype.clickEquipbox = function(x,y) { // 下一页 if ((x == 8 || x == 9) && y == 12) { var lastPage = Math.ceil(Object.keys(core.status.hero.items.equips).length/12); - if (page=0) + if (index>=0) { + if (index<12) index = parseInt(index/2); this.clickEquipboxIndex(index); + } } ////// 选择装备栏界面中某个Index后的操作 ////// actions.prototype.clickEquipboxIndex = function(index) { - if (index<12) { - if (index>=core.status.hero.equipment.length) return; - if (index==core.status.event.selection && core.status.hero.equipment[index] != "blank") { + if (index<6) { + if (index>=(main.equipName||[]).length) return; + if (index==core.status.event.selection && core.isset(core.status.hero.equipment[index])) { core.unloadEquip(index); } } - else { - var equips = null; - equips = Object.keys(core.status.hero.items.equips).sort(); - if (equips==null) return; - if (index>=equips.length+12) return; + else if (index>=12) { + var equips = Object.keys(core.status.hero.items.equips||{}).sort(); if (index==core.status.event.selection) { - var equipId = equips[index-12]; + var equipId = equips[index-12 + (core.status.event.data.page-1)*12]; core.loadEquip(equipId); - equips = Object.keys(core.status.hero.items.equips).sort(); - if ( equips.length == 0) - index = core.status.hero.equipment.length-1; } } core.ui.drawEquipbox(index); @@ -1484,35 +1496,36 @@ actions.prototype.clickEquipboxIndex = function(index) { actions.prototype.keyDownEquipbox = function (keycode) { if (!core.isset(core.status.event.data)) return; - var equipCapacity = core.status.hero.equipment.length; + var equipCapacity = (main.equipName||[]).length; var ownEquipment = Object.keys(core.status.hero.items.equips).sort(); var index = core.status.event.selection; var page = core.status.event.data.page; var totalPage = Math.ceil(ownEquipment.length/12); + var totalLastIndex = 12+(page1) { + if (index==12) { + if (page > 1) { core.status.event.data.page--; index = 23; } - else if (page==1) - index = equipCapacity-1; + else if (page == 1) + index = equipCapacity - 1; else return; + } else index -= 1; this.clickEquipboxIndex(index); return; } if (keycode==38) { // up - if (index<18 && index>11) { // 进入当前装备 - index = Math.ceil((index-12)/2); - if (equipCapacity<=3 && equipCapacity>index) index += 0; - else if (equipCapacity>3 && equipCapacity>index) index += 3; - else index = equipCapacity-1; + if (index<3) return; + else if (index<6) index -= 3; + else if (index < 18) { + index = parseInt((index-12)/2); + if (equipCapacity>3) index = Math.min(equipCapacity-1, index + 3); + else index = Math.min(equipCapacity-1, index); } - else if (index<3) return; // 第一行没有向上 - else if (index<12) index -= 3; else index -= 6; this.clickEquipboxIndex(index); return; @@ -1522,28 +1535,31 @@ actions.prototype.keyDownEquipbox = function (keycode) { core.status.event.data.page++; index = 12; } - else if (index==equipCapacity-1 && totalPage>0) + else if (index==equipCapacity-1) { + if (totalPage==0) return; index = 12; - else if (page==totalPage && index==ownEquipment.length%12+11) + } + else if (index==totalLastIndex) return; - else index += 1; + else index++; this.clickEquipboxIndex(index); return; } if (keycode==40) { // down - if ((index>2 || equipCapacity<=3) && index<12) {// 进入拥有装备 - index = (index%3)*2+13; - if (totalPage == 0) return; - if (totalPage == page && ownEquipment.length%12<(index%6+1)) - index = ownEquipment.length%12+11; + if (index<3) { + if (equipCapacity>3) index = Math.min(index+3, equipCapacity-1); + else { + if (totalPage == 0) return; + index = Math.min(2*index+1+12, totalLastIndex); + } } - else if (equipCapacity>3 && equipCapacity%36 && index>ownEquipment.length%6+11 && index<18) - index = ownEquipment.length%12+11; - else if (index>17 || (totalPage==page && ownEquipment.length%12<=6 && index>11)) return;//最后一行无操作 - else if (index<12) index += 3; - else index += 6; + else if (index < 6) { + if (totalPage == 0) return; + index = Math.min(2*(index-3)+1+12, totalLastIndex); + } + else if (index < 18) + index = Math.min(index+6, totalLastIndex); + else return; this.clickEquipboxIndex(index); return; } diff --git a/libs/control.js b/libs/control.js index 8b9bc67b..ff4c53d2 100644 --- a/libs/control.js +++ b/libs/control.js @@ -1857,16 +1857,17 @@ control.prototype.replay = function () { } } else if (action.indexOf("unEquip:")==0) { - var unloadEquipId = action.substring(8); - var equipType = core.material.items[unloadEquipId].equip.type; - core.ui.drawEquipbox(equipType); - setTimeout(function () { - core.ui.closePanel(); - core.unloadEquip(equipType, function () { - core.replay(); - }); - }, 750 / Math.max(1, core.status.replay.speed)); - return; + var equipType = parseInt(action.substring(8)); + if (core.isset(equipType)) { + core.ui.drawEquipbox(equipType); + setTimeout(function () { + core.ui.closePanel(); + core.unloadEquip(equipType, function () { + core.replay(); + }); + }, 750 / Math.max(1, core.status.replay.speed)); + return; + } } else if (action.indexOf("equip:")==0) { var equipId = action.substring(6); diff --git a/libs/items.js b/libs/items.js index fe052929..7203efde 100644 --- a/libs/items.js +++ b/libs/items.js @@ -187,7 +187,7 @@ items.prototype.loadEquip = function (equipId, callback) { if (core.isset(unloadEquipId)) core.addItem(unloadEquipId, 1); - core.log("已装备上"+loadEquip.name, core.material.icons.items[equipId]); + core.drawTip("已装备上"+loadEquip.name, core.material.icons.items[equipId]); if (core.isset(callback)) callback(); } @@ -217,7 +217,7 @@ items.prototype.unloadEquip = function (equipType, callback) { core.updateStatusBar(); // 记录路线 - core.status.route.push("unEquip:"+unloadEquipId); + core.status.route.push("unEquip:"+equipType); // 装备更换完毕:增加卸下的装备 core.addItem(unloadEquipId, 1); diff --git a/libs/ui.js b/libs/ui.js index 68d7c2d7..9ba566f4 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -1206,7 +1206,9 @@ ui.prototype.drawReplay = function () { ////// 绘制分页 ////// ui.prototype.drawPagination = function (page, totalPage, top) { - if (totalPage <= 1) return; + // if (totalPage0) index=0; + if (equipLength>0 && core.isset(equipEquipment[0])) index=0; else if (ownEquipment.length>0) index=12; else index=0; } - core.status.event.selection=index; - - var selectId; + if (index>=12 && ownEquipment.length==0) index = 0; + var selectId=null; if (index<12) { - if (index>=equipEquipment.length) index=Math.max(0, equipEquipment.length-1); - selectId = equipEquipment[index]; + if (index >= equipLength) index=Math.max(0, equipLength - 1); + selectId = equipEquipment[index]||null; } else { - if (index+12*(page-2)>=ownEquipment.length) index=12+Math.max(0, ownEquipment.length%12-1); - selectId = ownEquipment[index-12]; + if (page == totalPage) index = Math.min(index, (ownEquipment.length+11)%12+12); + selectId = ownEquipment[index-12 + (page-1)*12]; if (!core.hasItem(selectId)) selectId=null; } + core.status.event.selection=index; core.status.event.data.selectId=selectId; core.clearMap('ui', 0, 0, 416, 416); @@ -1792,16 +1801,16 @@ ui.prototype.drawEquipbox = function(index) { core.canvas.ui.textAlign = 'left'; - console.log(equipEquipment[0]); // 描述 if (core.isset(selectId)) { var equip=core.material.items[selectId]; - core.fillText('ui', equip.name, 10, 32, '#FFD700', "bold 20px Verdana") + var equipType = (equip.equip||{}).type || 0; + core.fillText('ui', equip.name + "(" + (allEquips[equipType]||"未知部位") + ")", 10, 32, '#FFD700', "bold 20px Verdana") var text = equip.text||"该装备暂无描述。"; var lines = core.splitLines('ui', text, 406, '17px Verdana'); - core.fillText('ui', lines[0], 10, 62, '#FFFFFF', '17px Verdana'); + core.fillText('ui', lines[0], 10, 62, '#FFFFFF', '17px Verdana'); // 比较属性 if (lines.length==1) { @@ -1810,43 +1819,20 @@ ui.prototype.drawEquipbox = function(index) { else { compare = core.compareEquipment(selectId, equipEquipment[equip.equip.type]); } - // 绘制 - var drawList; //= [['攻击',atk],['防御',def],['魔防',mdef]]; - var drawPointer = 0; - var color; - if (compare.atk!=0) { - if (compare.atk>0) color = '#00FF00'; - else color = '#FF0000'; - drawList = '攻击 '+core.status.hero.atk+'->'; - core.fillText('ui', drawList, 10+drawPointer, 89, '#CCCCCC', 'bold 14px Verdana'); - drawPointer += core.canvas.ui.measureText(drawList).width; + var drawOffset = 10; - drawList = (core.status.hero.atk+compare.atk)+' '; - core.fillText('ui', drawList, 10+drawPointer, 89, color, 'bold 14px Verdana'); - drawPointer += core.canvas.ui.measureText(drawList).width; - } - if (compare.def!=0) { - if (compare.def>0) color = '#00FF00'; - else color = '#FF0000'; - drawList = '防御 '+core.status.hero.atk+'->'; - core.fillText('ui', drawList, 10+drawPointer, 89, '#CCCCCC', 'bold 14px Verdana'); - drawPointer += core.canvas.ui.measureText(drawList).width; - - drawList = (core.status.hero.atk+compare.def)+' '; - core.fillText('ui', drawList, 10+drawPointer, 89, color, 'bold 14px Verdana'); - drawPointer += core.canvas.ui.measureText(drawList).width; - } - if (compare.mdef!=0) { - if (compare.mdef>0) color = '#00FF00'; - else color = '#FF0000'; - drawList = '魔防 '+core.status.hero.atk+'->'; - core.fillText('ui', drawList, 10+drawPointer, 89, '#CCCCCC', 'bold 14px Verdana'); - drawPointer += core.canvas.ui.measureText(drawList).width; - - drawList = (core.status.hero.atk+compare.mdef)+' '; - core.fillText('ui', drawList, 10+drawPointer, 89, color, 'bold 14px Verdana'); - drawPointer += core.canvas.ui.measureText(drawList).width; - } + [['攻击','atk'], ['防御','def'], ['魔防','mdef']].forEach(function (t) { + var title = t[0], name = t[1]; + if (!core.isset(compare[name]) || compare[name]==0) return; + var color = '#00FF00'; + if (compare[name]<0) color = '#FF0000'; + var content = title + ' ' + core.getStatus(name) + '->'; + core.fillText('ui', content, drawOffset, 89, '#CCCCCC', 'bold 14px Verdana'); + drawOffset += core.canvas.ui.measureText(content).width; + var newValue = core.getStatus(name) + compare[name] + ""; + core.fillText('ui', newValue, drawOffset, 89, color); + drawOffset += core.canvas.ui.measureText(newValue).width + 15; + }) } else { var leftText = text.substring(lines[0].length); @@ -1858,34 +1844,33 @@ ui.prototype.drawEquipbox = function(index) { var images = core.material.images.items; // 当前装备 - for (var i = 0 ; i < core.status.hero.equipment.length ; i++) { - var equipId = core.status.hero.equipment[i]; + for (var i = 0 ; i < equipLength ; i++) { + var equipId = equipEquipment[i] || null; if (core.isset(equipId)) { var icon = core.material.icons.items[equipId]; - core.canvas.ui.drawImage(images, 0, icon*32, 32, 32, 16*(8*(i%3)+5)+5, 144+Math.floor(i/3)*64+5-ydelta, 32, 32); + core.canvas.ui.drawImage(images, 0, icon*32, 32, 32, 16*(8*(i%3)+5)+5, 144+Math.floor(i/3)*54+5-ydelta, 32, 32); } - core.fillText('ui', main.equipName[i], 16*(8*(i%3)+1)+40, 144+Math.floor(i/3)*64+32-ydelta, '#FFFFFF', "bold 16px Verdana"); - if (index == i) - core.strokeRect('ui', 16*(8*(i%3)+5)+1, 144+Math.floor(i/3)*64+1-ydelta, 40, 40, '#FFD700'); + core.fillText('ui', allEquips[i]||"未知", 16*(8*(i%3)+1)+40, 144+Math.floor(i/3)*54+32-ydelta, '#FFFFFF', "bold 16px Verdana"); + core.strokeRect('ui', 16*(8*(i%3)+5)+1, 144+Math.floor(i/3)*54+1-ydelta, 40, 40, index==i?'#FFD700':"#FFFFFF"); } // 现有装备 for (var i=0;i<12;i++) { var ownEquip=ownEquipment[12*(page-1)+i]; - if (!core.isset(ownEquip)) break; + if (!core.isset(ownEquip)) continue; var icon=core.material.icons.items[ownEquip]; - core.canvas.ui.drawImage(images, 0, icon*32, 32, 32, 16*(4*(i%6)+1)+5, 304+Math.floor(i/6)*64+5-ydelta, 32, 32) + core.canvas.ui.drawImage(images, 0, icon*32, 32, 32, 16*(4*(i%6)+1)+5, 304+Math.floor(i/6)*54+5-ydelta, 32, 32) // 个数 if (core.itemCount(ownEquip)>1) - core.fillText('ui', core.itemCount(ownEquip), 16*(4*(i%6)+1)+40, 304+Math.floor(i/6)*64+38-ydelta, '#FFFFFF', "bold 14px Verdana"); + core.fillText('ui', core.itemCount(ownEquip), 16*(4*(i%6)+1)+40, 304+Math.floor(i/6)*54+38-ydelta, '#FFFFFF', "bold 14px Verdana"); if (selectId == ownEquip) - core.strokeRect('ui', 16*(4*(i%6)+1)+1, 304+Math.floor(i/6)*64+1-ydelta, 40, 40, '#FFD700'); + core.strokeRect('ui', 16*(4*(i%6)+1)+1, 304+Math.floor(i/6)*54+1-ydelta, 40, 40, '#FFD700'); } this.drawPagination(page, totalPage, 12); // 道具栏 core.canvas.ui.textAlign = 'center'; - core.fillText('ui', '道具栏', 370, 19,'#DDDDDD', 'bold 15px Verdana'); + core.fillText('ui', '[道具栏]', 370, 25,'#DDDDDD', 'bold 15px Verdana'); // 退出按钮 core.fillText('ui', '返回游戏', 370, 403,'#DDDDDD', 'bold 15px Verdana'); } diff --git a/libs/utils.js b/libs/utils.js index 3551cea1..9a05a0a1 100644 --- a/libs/utils.js +++ b/libs/utils.js @@ -325,7 +325,7 @@ utils.prototype.encodeRoute = function (route) { if (t.indexOf('item:')==0) ans+="I"+t.substring(5)+":"; else if (t.indexOf('unEquip:')==0) - ans+="u"+t.substring(8)+":"; + ans+="u"+t.substring(8); else if (t.indexOf('equip:')==0) ans+="e"+t.substring(6)+":"; else if (t.indexOf('fly:')==0) @@ -387,7 +387,7 @@ utils.prototype.decodeRoute = function (route) { while (index Date: Mon, 17 Sep 2018 18:19:34 +0800 Subject: [PATCH 2/9] Equipment Docs --- _server/comment.js | 2 +- docs/api.md | 37 +++++++++++++++++++--- docs/element.md | 65 ++++++++++++++++++++++++++++++++++++++- docs/personalization.md | 27 ++++++---------- docs/start.md | 3 +- libs/actions.js | 2 ++ libs/control.js | 4 +-- libs/core.js | 13 +++++--- libs/items.js | 26 ++++++++++------ libs/ui.js | 3 +- project/floors/sample0.js | 3 +- project/functions.js | 37 +++++++++++++++++++--- 12 files changed, 172 insertions(+), 50 deletions(-) diff --git a/_server/comment.js b/_server/comment.js index 0621926b..dd31f1ab 100644 --- a/_server/comment.js +++ b/_server/comment.js @@ -40,7 +40,7 @@ comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "equip": { "_leaf": true, "_type": "textarea", - "_data": "装备属性设置,仅对cls为equips有效。\n如果此项不为null,需要是一个对象,里面可含\"type\",\"atk\",\"def\",\"mdef\",\"animate\"五项,分别对应装备部位、攻防魔防和动画。\n具体详见文档和已有的几个装备的写法。" + "_data": "装备属性设置,仅对cls为equips有效。\n如果此项不为null,需要是一个对象,里面可含\"type\",\"atk\",\"def\",\"mdef\",\"animate\"五项,分别对应装备部位、攻防魔防和动画。\n具体详见文档(元件说明-装备)和已有的几个装备的写法。" }, } }, diff --git a/docs/api.md b/docs/api.md index c7ced584..e18f44cf 100644 --- a/docs/api.md +++ b/docs/api.md @@ -72,8 +72,17 @@ core.setItem('pickaxe', 10) 将破墙镐个数设置为10个。这里可以写任何道具的ID。 +core.addItem('pickaxe', 2) +将破墙镐的个数增加2个,无任何特效。这里可以写任何道具的ID。 + + core.getItem('pickaxe', 4) -另勇士获得四个破墙镐。这里可以写任何道具的ID。 +令勇士获得4个破墙镐。这里可以写任何道具的ID。 +和addItem相比,使用getItem会播放获得道具的音效,也会在左上角绘制获得提示。 + + +core.removeItem('pickaxe', 3) +删除3个破墙镐。第二项可忽略,默认值为1。 core.itemCount('pickaxe') @@ -84,6 +93,15 @@ core.hasItem('pickaxe') 返回当前是否存在某个道具。等价于 core.itemCount('pickaxe')>0 。 +core.getEquip(0) +获得0号装备类型(武器)的当前装备的itemId。如果不存在则返回null。 +这里可以写任意装备类型,从0开始和全塔属性中的equipName一一对应。 + + +core.hasEquip('sword1') +获得当前某个具体的装备是否处于正在被装备状态。 + + core.setFlag('xyz', 2) 设置某个flag/变量的值为2。这里可以写任何的flag变量名。 @@ -229,12 +247,12 @@ core.canUseItem(itemId) 返回当前能否使用某个道具。 -core.addItem(itemId, number) -将某个道具增加number个。 +core.loadEquip(itemId, callback) +装备上某个装备。itemId为装备的ID,callback为成功或失败后的回调。 -core.removeItem(itemId) -将某个道具个数-1;如果道具个数归0则从道具列表删除。 +core.unloadEquip(equipType, callback) +卸下某个部位的装备。equipType为装备类型,从0开始;callback为成功或失败后的回调。 core.getNextItem() @@ -266,6 +284,11 @@ core.getLocalStorage(key, defaultValue) 从localStorage中获得某个数据(已被parse);如果对应的key不存在则返回defaultValue。 +core.getLocalForage(key, defaultValue, successCallback, errorCallback) +从localForage中获得某个数据(已被parse),如果对应的key不存在则返回defaultValue。 +如果成功则通过successCallback回调,失败则通过errorCallback回调。 + + core.clone(data) 深拷贝某个对象。 @@ -399,6 +422,10 @@ core.events.setHeroIcon(name) items.js将处理和道具相关的内容,比如道具的使用,获取和删除等等。 +core.items.compareEquipment(equipId1, equipId2) +比较两个装备的属性变化值 + + ========== core.loader.XXX 和游戏加载相关的函数 ========== loader.js将主要用来进行资源的加载,比如加载音乐、图片、动画等等。 diff --git a/docs/element.md b/docs/element.md index 882f54f5..fbc5304b 100644 --- a/docs/element.md +++ b/docs/element.md @@ -24,7 +24,58 @@ 如果需要让剑盾等变成装备,可以直接在`data.js`中设置`'equipment': true`即可。 -有关装备更为详细的资料可参见[自定义装备](personalization#自定义装备)的说明。 +从V2.4.1开始,HTML5魔塔样板终于拥有了属于自己的装备页面。 + +### 装备栏的设置,装备类型 + +在全塔属性中,有一个`equipName`项,其定义了本塔的所有可装备的装备栏。 + +其需要是一个不小于1且不大于6的数组,其中每一项为装备栏的名称,**建议是两个汉字**。 + +例如下面这种写法就是定义了四个装备孔,名称分别为武器、防御、首饰和魔杖。 + +``` js +"equipName": ["武器","防具","首饰","魔杖"] +``` + +这么定义好后,装备类型即为每个装备孔的索引(从0开始)。 + +即,武器的装备类型是0,防御的装备类型是1,首饰的装备类型是2,魔杖的装备类型是3。 + +### 设置每个装备的属性 + +如果要将一个道具设置为装备,首先需要将其`cls`设为`equips`。 + +然后在图块属性的`equip`一项中设置装备的具体属性。该项写法如下: +``` js +{"type": 0, "atk": 0, "def": 0, "mdef":0, "animate": "hand"} +``` + +type为该装备的类型,必填,和上面装备栏一一对应。例如,0就是武器,2就是首饰等等。 + +atk/def/mdef为该装备分别增加的攻防魔防数值(支持负数);如果不加也可省略不写。 + +animate为该装备的攻击动画,仅对type为0时有效。具体可参见[动画和天气系统](#动画和天气系统)。 + +下面是几个写法例子。 + +``` js +{"type": 0, "atk": 10} // 装备类型是武器,效果是攻击+10,使用默认的攻击动画 +{"type": 0, "atk": 40, "animate": "sword"} // 装备类型为武器,效果是攻击+10,攻击动画是sword +{"type": 1, "def": 40} // 装备类型是防具,效果是防御+40 +{"type": 1, "def": 100, "mdef": 100} // 装备类型是防具,效果是防御和魔防各+100 +{"type": 3, "atk": -20, "def": 50, "mdef": 50} // 装备类型是魔杖,效果是攻击-20,防御和魔防各+50 +``` + +### 检测是否存在装备 + +可以使用`core.hasEquip(itemId)`来检测是否装上某个装备。 + +使用`core.hasItem(itemId)`来检测是否存在一个未装上的装备。 + +使用`core.getEquip(equipType)`来获得某个装备类型的当前装备。 + +更多相关API详见[附录:API列表](api)。 ## 门 @@ -32,6 +83,8 @@ 开门后可触发该层的`afterOpenDoor`事件,有关事件的详细介绍请参见第四章。 +如果要新增自己的门,请参见[新增门和对应的钥匙](personalization#新增门和对应的钥匙)。 + ## 暗墙 本塔支持暗墙。 @@ -139,16 +192,26 @@ N连击怪物的special是6,且我们可以为它定义n代表实际连击数 领域怪还可以设置`range`选项代表该领域怪的范围,不写则默认为1。 +**将`flag:no_zone`设置为true可以取消领域效果。** + 阻击怪同样需要设置value,代表阻击伤害的数值。如果勇士生命值扣减到0,则直接死亡触发lose事件。 +**将`flag:no_snipe`设置为true可以取消阻击效果。** + !> 阻击怪后退的地点不能有任何事件存在,即使是已经被禁用的自定义事件! 激光怪同样需要设置value,代表激光伤害的数值。 请注意如果吸血、领域、阻击中任何两个同时存在,则value会冲突。**因此请勿将吸血、领域、阻击或激光放置在同一个怪物身上。** +**将`flag:no_laser`设置为true可以免疫激光效果。** + 退化怪需要设置'atkValue'和'defValue'表示退化的数值;也可以不设置默认为0。 +夹击可以通过全塔属性中的`betweenAttackCeil`设为true可以将伤害向上取整。 + +**将`flag:no_betweenAttack`设置为true可以免疫夹击效果。** + 固伤怪则需要设置`damage`选项,代表战前扣血数值。 如有额外需求,可参见[自定义怪物属性](personalization#自定义自定义怪物属性),里面讲了如何设置一个新的怪物属性。 diff --git a/docs/personalization.md b/docs/personalization.md index be460129..d454eb90 100644 --- a/docs/personalization.md +++ b/docs/personalization.md @@ -308,25 +308,13 @@ function (enemy, hero_hp, hero_atk, hero_def, hero_mdef) { } // ... 下略 ``` -3. 免疫领域、夹击、阻击效果:在`control.js`中,找到checkBlock函数,并编辑成如果有神圣盾标记,则将伤害变成0。 +3. 免疫领域、夹击、阻击效果:在2.4.1之后,可以直接将flag:no_zone设为true来免疫领域效果,其他几个同理。 ``` js -// 检查领域、夹击、阻击事件 -control.prototype.checkBlock = function () { - var x=core.getHeroLoc('x'), y=core.getHeroLoc('y'); - var damage = core.status.checkBlock.damage[x+core.bigmap.width*y]; - if (damage>0) { - if (core.hasFlag("shield5")) damage = 0; // 如果存在神圣盾,则将伤害变成0 - core.status.hero.hp -= damage; - - // 检查阻击事件 - var snipe = []; - var scan = { - 'up': {'x': 0, 'y': -1}, - 'left': {'x': -1, 'y': 0}, - 'down': {'x': 0, 'y': 1}, - 'right': {'x': 1, 'y': 0} - } -// ... 下略 +// 同样写在道具的itemEffect中 +core.setFlag("no_zone", true); // 免疫领域 +core.setFlag("no_snipe", true); // 免疫阻击 +core.setFlag("no_laser", true); // 免疫激光 +core.setFlag("no_betweenAttack", true); // 免疫夹击 ``` 4. 如果有更高的需求,例如想让吸血效果变成一半,则还是在上面这些地方进行对应的修改即可。 @@ -375,6 +363,7 @@ control.prototype.useFly = function (need) { ``` 修改时,请先把`null`改成空字符串`""`,然后再双击进行编辑。 + + ## 自定义怪物属性 如果你对现有的怪物不满意,想自行添加怪物属性也是可以的。具体参见脚本编辑-getSpecials。 diff --git a/docs/start.md b/docs/start.md index 46d5346d..6bbceee0 100644 --- a/docs/start.md +++ b/docs/start.md @@ -201,6 +201,8 @@ HTML5的塔都是可以进行控制台调试的。 - `core.getItem('pickaxe', 2)` 令勇士获得两个破墙镐。 - `core.itemCount('pickaxe')` 返回勇士某个道具的个数。 - `core.hasItem('pickaxe')` 返回勇士是否拥有某个道具。等价于`core.itemCount('pickaxe')!=0`。 +- `core.getEquip(0)` 返回0号装备类型(武器)的当前装备的itemId,不存在则返回null +- `core.hasEquip('sword1')` 返回某个装备当前是否处于被装备状态 - `core.setFlag('xxx', 1)` 设置某个flag/自定义变量的值。 - `core.getFlag('xxx', 10)` 获得某个flag/自定义变量的值;如果该项不存在(未被定义),则返回第二个参数的值。 - `core.hasFlag('xxx')` 返回是否存在某个变量且不为0。等价于`core.getFlag('xxx', 0)!=0`。 @@ -210,7 +212,6 @@ HTML5的塔都是可以进行控制台调试的。 - `core.getBlock(3, 5, 'MT1')` 获得当前地图上某一个块的信息。第三个参数为floorId,可省略表示当前楼层。 - `core.getBlockId(3, 5, 'MT1')` 获得当前地图上某一个点的图块ID。第三个参数为floorId,可省略表示当前楼层。 - `core.resetMap()` 重置当前层地图。**当修改地图后再读档,修改的地图不会立刻生效,此时可以使用resetMap来重置当前楼层的地图。** -- `localStorage` 获得所有的存档数据。可以用 `core.getLocalStorage('save1')` 来具体获得某个存档。 - …… 更多API和详细参数介绍可参见[API列表](api)。 diff --git a/libs/actions.js b/libs/actions.js index d060d672..7b259cad 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -1480,6 +1480,7 @@ actions.prototype.clickEquipboxIndex = function(index) { if (index>=(main.equipName||[]).length) return; if (index==core.status.event.selection && core.isset(core.status.hero.equipment[index])) { core.unloadEquip(index); + core.status.route.push("unEquip:"+index); } } else if (index>=12) { @@ -1487,6 +1488,7 @@ actions.prototype.clickEquipboxIndex = function(index) { if (index==core.status.event.selection) { var equipId = equips[index-12 + (core.status.event.data.page-1)*12]; core.loadEquip(equipId); + core.status.route.push("equip:"+equipId); } } core.ui.drawEquipbox(index); diff --git a/libs/control.js b/libs/control.js index ff4c53d2..2596e872 100644 --- a/libs/control.js +++ b/libs/control.js @@ -1860,6 +1860,7 @@ control.prototype.replay = function () { var equipType = parseInt(action.substring(8)); if (core.isset(equipType)) { core.ui.drawEquipbox(equipType); + core.status.route.push(action); setTimeout(function () { core.ui.closePanel(); core.unloadEquip(equipType, function () { @@ -1874,6 +1875,7 @@ control.prototype.replay = function () { var ownEquipment = Object.keys(core.status.hero.items.equips).sort(); var index = ownEquipment.indexOf(equipId); if (index>=0) { + core.status.route.push(action); core.status.event.data = {"page":Math.floor(index/12)+1, "selectId":null}; index = index%12+12; core.ui.drawEquipbox(index); @@ -2639,8 +2641,6 @@ control.prototype.updateStatusBar = function () { core.statusBar.image.settings.src = core.statusBar.icons.settings.src; } - - core.updateDamage(); } ////// 屏幕分辨率改变后重新自适应 ////// diff --git a/libs/core.js b/libs/core.js index 1c6a8625..f3155dd9 100644 --- a/libs/core.js +++ b/libs/core.js @@ -834,8 +834,13 @@ core.prototype.hasItem = function (itemId) { } ////// 是否装备某件装备 ////// -core.prototype.hasEquip = function (equipId) { - return core.items.hasEquip(equipId); +core.prototype.hasEquip = function (itemId) { + return core.items.hasEquip(itemId); +} + +////// 获得某个装备类型的当前装备 ///// +core.prototype.getEquip = function (equipType) { + return core.items.getEquip(equipType); } ////// 设置某个物品的个数 ////// @@ -844,8 +849,8 @@ core.prototype.setItem = function (itemId, itemNum) { } ////// 删除某个物品 ////// -core.prototype.removeItem = function (itemId) { - return core.items.removeItem(itemId); +core.prototype.removeItem = function (itemId, itemNum) { + return core.items.removeItem(itemId, itemNum); } ////// 使用某个物品 ////// diff --git a/libs/items.js b/libs/items.js index 7203efde..f6bfd29b 100644 --- a/libs/items.js +++ b/libs/items.js @@ -97,17 +97,22 @@ items.prototype.hasItem = function (itemId) { } ////// 是否装备某件装备 ////// -items.prototype.hasEquip = function (equipId) { +items.prototype.hasEquip = function (itemId) { - if (!core.isset(equipId)) return null; - if (!core.isset((core.material.items[equipId]||{}).equip)) return null; + if (!core.isset(itemId)) return null; + if (!core.isset((core.material.items[itemId]||{}).equip)) return null; - var equiptype = core.material.items[equipId].equip.type; - return equipId == (core.status.hero.equipment||[])[equiptype]; + return itemId == this.getEquip(core.material.items[itemId].equip.type); +} + +////// 获得某个装备类型的当前装备 ////// +items.prototype.getEquip = function (equipType) { + return (core.status.hero.equipment||[])[equipType]||null; } ////// 设置某个物品的个数 ////// items.prototype.setItem = function (itemId, itemNum) { + itemNum = itemNum || 1; var itemCls = core.material.items[itemId].cls; if (itemCls == 'items') return; if (!core.isset(core.status.hero.items[itemCls])) { @@ -120,11 +125,12 @@ items.prototype.setItem = function (itemId, itemNum) { } ////// 删除某个物品 ////// -items.prototype.removeItem = function (itemId) { +items.prototype.removeItem = function (itemId, itemNum) { + itemNum = itemNum || 1; if (!core.hasItem(itemId)) return false; var itemCls = core.material.items[itemId].cls; - core.status.hero.items[itemCls][itemId]--; - if (itemCls!='keys' && core.status.hero.items[itemCls][itemId]==0) { + core.status.hero.items[itemCls][itemId]-=itemNum; + if (itemCls!='keys' && core.status.hero.items[itemCls][itemId]<=0) { delete core.status.hero.items[itemCls][itemId]; } core.updateStatusBar(); @@ -178,7 +184,7 @@ items.prototype.loadEquip = function (equipId, callback) { core.updateStatusBar(); // 记录路线 - core.status.route.push("equip:"+equipId); + // core.status.route.push("equip:"+equipId); // 装备更换完毕:删除换上的装备 core.removeItem(equipId); @@ -217,7 +223,7 @@ items.prototype.unloadEquip = function (equipType, callback) { core.updateStatusBar(); // 记录路线 - core.status.route.push("unEquip:"+equipType); + // core.status.route.push("unEquip:"+equipType); // 装备更换完毕:增加卸下的装备 core.addItem(unloadEquipId, 1); diff --git a/libs/ui.js b/libs/ui.js index 9ba566f4..78bf7692 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -1804,7 +1804,8 @@ ui.prototype.drawEquipbox = function(index) { // 描述 if (core.isset(selectId)) { var equip=core.material.items[selectId]; - var equipType = (equip.equip||{}).type || 0; + if (!core.isset(equip.equip)) equip.equip = {"type": 0}; + var equipType = equip.equip.type; core.fillText('ui', equip.name + "(" + (allEquips[equipType]||"未知部位") + ")", 10, 32, '#FFD700', "bold 20px Verdana") var text = equip.text||"该装备暂无描述。"; diff --git a/project/floors/sample0.js b/project/floors/sample0.js index a442ab3f..51810f8a 100644 --- a/project/floors/sample0.js +++ b/project/floors/sample0.js @@ -32,9 +32,8 @@ main.floors.sample0= ], "events": { "10,9": [ - "\t[老人,man]这些是本样板支持的所有的道具。\n\n道具分为三类:items, constants, tools。\nitems 为即捡即用类道具,例如宝石、血瓶、剑盾等。\nconstants 为永久道具,例如怪物手册、楼层传送器、幸运金币等。\ntools 为消耗类道具,例如破墙镐、炸弹、中心对称飞行器等。\n\n后两类道具在工具栏中可以看到并使用。", + "\t[老人,man]这些是本样板支持的所有的道具。\n\n道具分为四类:items, constants, tools,equips。\nitems 为即捡即用类道具,例如宝石、血瓶、剑盾等。\nconstants 为永久道具,例如怪物手册、楼层传送器、幸运金币等。\ntools 为消耗类道具,例如破墙镐、炸弹、中心对称飞行器等。\nequips 为装备,例如剑盾等。", "\t[老人,man]\b[up]有关道具效果,定义在items.js中。\n目前大多数道具已有默认行为,如有自定义的需求则需在items.js中修改代码。", - "\t[老人,man]constants 和 tools 各最多只允许12种,多了会导致图标溢出。", "\t[老人,man]\b[up]拾取道具结束后可触发 afterGetItem 事件。\n\n有关事件的各种信息在下一层会有更为详细的说明。", { "type": "hide", diff --git a/project/functions.js b/project/functions.js index e397cb30..6f80e240 100644 --- a/project/functions.js +++ b/project/functions.js @@ -477,44 +477,60 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = core.setStatus('hp', Math.min(core.getStatus('hpmax'), core.getStatus('hp'))); } - // 更新领域、阻击、显伤 - core.updateCheckBlock(); - + // 设置等级奴名称 var lvName = core.getLvName(); core.statusBar.lv.innerHTML = lvName; + // 检测是不是纯数字;如果带中文等需要取消斜体(不然很难看的!) if (/^[+-]?\d+$/.test(lvName)) core.statusBar.lv.style.fontStyle = 'italic'; else core.statusBar.lv.style.fontStyle = 'normal'; + // 设置生命上限、生命值、攻防魔防金币和经验值 var statusList = ['hpmax', 'hp', 'atk', 'def', 'mdef', 'money', 'experience']; statusList.forEach(function (item) { + // 向下取整 if (core.isset(core.status.hero[item])) core.status.hero[item] = Math.floor(core.status.hero[item]); + // 大数据格式化 core.statusBar[item].innerHTML = core.formatBigNumber(core.getStatus(item)); }); + // 可以在这里添加自己额外的状态栏信息,比如想攻击显示 +0.5 可以这么写: + // if (core.hasFlag('halfAtk')) core.statusBar.atk.innerHTML += "+0.5"; + + // 如果是自定义添加的状态栏,也需要在这里进行设置显示的数值 + // 进阶 if (core.flags.enableLevelUp && core.status.hero.lv=core.bigmap.width || ny<0 || ny>=core.bigmap.height) continue; + // 如果是十字领域,则还需要满足 |dx|+|dy|<=range if (!zoneSquare && Math.abs(dx)+Math.abs(dy)>range) continue; core.status.checkBlock.damage[nx+ny*core.bigmap.width]+=enemy.value||0; } @@ -574,6 +595,7 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = // 存在激光 // 如果要防止激光伤害,可以直接简单的将 flag:no_laser 设为true if (core.enemys.hasSpecial(enemy.special, 24) && !core.hasFlag("no_laser")) { + // 检查同行和同列,增加激光伤害值 for (var nx=0;nx0 && x0 && y1) core.status.checkBlock.damage[x+core.bigmap.width*y] += Math.floor((leftHp+(core.flags.betweenAttackCeil?0:1))/2); } @@ -677,7 +704,7 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = // 在这里写所有需要自定义的函数 // 写法必须是 this.xxx = function (args) { ... // 如果不写this的话,函数将无法被外部所访问 - this.test = function () { + this.test = function () { console.log("插件函数执行测试"); } From 6956a2754419b8eace0f85b4b87b3b0a888e40d3 Mon Sep 17 00:00:00 2001 From: ckcz123 Date: Mon, 17 Sep 2018 18:20:18 +0800 Subject: [PATCH 3/9] Equipment Docs --- libs/items.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/items.js b/libs/items.js index f6bfd29b..e5a4118b 100644 --- a/libs/items.js +++ b/libs/items.js @@ -112,7 +112,7 @@ items.prototype.getEquip = function (equipType) { ////// 设置某个物品的个数 ////// items.prototype.setItem = function (itemId, itemNum) { - itemNum = itemNum || 1; + itemNum = itemNum || 0; var itemCls = core.material.items[itemId].cls; if (itemCls == 'items') return; if (!core.isset(core.status.hero.items[itemCls])) { From 3a50fb93302ab6b6fc1a41b981307524b8d514f8 Mon Sep 17 00:00:00 2001 From: ckcz123 Date: Mon, 17 Sep 2018 18:39:53 +0800 Subject: [PATCH 4/9] Fix textAttribute in save --- libs/control.js | 2 ++ libs/events.js | 1 + libs/items.js | 1 + 3 files changed, 4 insertions(+) diff --git a/libs/control.js b/libs/control.js index 2596e872..20d4d0bf 100644 --- a/libs/control.js +++ b/libs/control.js @@ -2368,6 +2368,8 @@ control.prototype.loadData = function (data, callback) { } } + core.status.textAttribute = core.getFlag('textAttribute') || core.status.textAttribute || core.initStatus.textAttribute; + // load icons var icon = core.getFlag("heroIcon", "hero.png"); if (core.isset(core.material.images.images[icon])) { diff --git a/libs/events.js b/libs/events.js index f1a585a0..60f4b03c 100644 --- a/libs/events.js +++ b/libs/events.js @@ -356,6 +356,7 @@ events.prototype.doAction = function() { if (core.isset(data.time)) { core.status.textAttribute.time=data.time; } + core.setFlag('textAttribute', core.status.textAttribute); core.events.doAction(); break; case "tip": diff --git a/libs/items.js b/libs/items.js index e5a4118b..3d0fdef6 100644 --- a/libs/items.js +++ b/libs/items.js @@ -113,6 +113,7 @@ items.prototype.getEquip = function (equipType) { ////// 设置某个物品的个数 ////// items.prototype.setItem = function (itemId, itemNum) { itemNum = itemNum || 0; + if (itemNum<=0) itemNum = 0; var itemCls = core.material.items[itemId].cls; if (itemCls == 'items') return; if (!core.isset(core.status.hero.items[itemCls])) { From bc5d4efcf7efb2f07ce04c6b611c6ca23dc143f3 Mon Sep 17 00:00:00 2001 From: ckcz123 Date: Mon, 17 Sep 2018 18:42:15 +0800 Subject: [PATCH 5/9] Fix textAttribute in save --- libs/control.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/control.js b/libs/control.js index 20d4d0bf..2ebad530 100644 --- a/libs/control.js +++ b/libs/control.js @@ -2368,7 +2368,7 @@ control.prototype.loadData = function (data, callback) { } } - core.status.textAttribute = core.getFlag('textAttribute') || core.status.textAttribute || core.initStatus.textAttribute; + core.status.textAttribute = core.getFlag('textAttribute', core.status.textAttribute); // load icons var icon = core.getFlag("heroIcon", "hero.png"); From c57e734b97b8feec5654e36583073a04901a2017 Mon Sep 17 00:00:00 2001 From: ckcz123 Date: Mon, 17 Sep 2018 19:35:34 +0800 Subject: [PATCH 6/9] Typing effect: display all on click --- _server/comment.js | 4 ++-- libs/actions.js | 10 ++++++++++ libs/events.js | 3 ++- libs/maps.js | 2 +- libs/ui.js | 10 ++++++++-- 5 files changed, 23 insertions(+), 6 deletions(-) diff --git a/_server/comment.js b/_server/comment.js index dd31f1ab..cceaf71f 100644 --- a/_server/comment.js +++ b/_server/comment.js @@ -211,7 +211,7 @@ comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "pushBox" ] }, - "_data": "图块的默认触发器" + "_data": "该图块的默认触发器" }, "noPass": { "_leaf": true, @@ -223,7 +223,7 @@ comment_c456ea59_6018_45ef_8bcc_211a24c627dc = false ] }, - "_data": "图块默认可通行状态" + "_data": "该图块是否不可通行;true代表不可通行,false代表可通行,null代表使用系统缺省值" } } }, diff --git a/libs/actions.js b/libs/actions.js index 7b259cad..706eac89 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -808,6 +808,12 @@ actions.prototype.keyUpConfirmBox = function (keycode) { actions.prototype.clickAction = function (x,y) { if (core.status.event.data.type=='text') { + + // 打字机效果显示全部文字 + if (core.status.event.interval!=null) { + core.insertAction({"type": "text", "text": core.status.event.ui, "showAll": true}); + } + // 文字 core.doAction(); return; @@ -859,6 +865,10 @@ actions.prototype.keyDownAction = function (keycode) { ////// 自定义事件时,放开某个键的操作 ////// actions.prototype.keyUpAction = function (keycode) { if (core.status.event.data.type=='text' && (keycode==13 || keycode==32 || keycode==67)) { + // 打字机效果显示全部文字 + if (core.status.event.interval!=null) { + core.insertAction({"type": "text", "text": core.status.event.ui, "showAll": true}); + } core.doAction(); return; } diff --git a/libs/events.js b/libs/events.js index 60f4b03c..b4c7919a 100644 --- a/libs/events.js +++ b/libs/events.js @@ -280,6 +280,7 @@ events.prototype.doAction = function() { // 清空boxAnimate和UI层 core.status.boxAnimateObjs = []; clearInterval(core.status.event.interval); + core.status.event.interval = null; core.clearMap('ui'); core.setAlpha('ui', 1.0); @@ -328,7 +329,7 @@ events.prototype.doAction = function() { if (core.status.replay.replaying) core.events.doAction(); else - core.ui.drawTextBox(data.text); + core.ui.drawTextBox(data.text, data.showAll); break; case "autoText": if (core.status.replay.replaying) diff --git a/libs/maps.js b/libs/maps.js index 6ad50ff5..69c138d7 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -74,7 +74,7 @@ maps.prototype.addInfo = function (block) { block.event.trigger = 'getItem'; } if (!core.isset(block.event.noPass)) { - if (block.event.cls.indexOf("enemy")==0 || block.event.cls.indexOf("npc")==0 || block.event.cls=='terrains') { + if (block.event.cls.indexOf("enemy")==0 || block.event.cls.indexOf("npc")==0 || block.event.cls=='terrains' || block.event.cls=='autotile') { block.event.noPass = true; } } diff --git a/libs/ui.js b/libs/ui.js index 78bf7692..4fe93ed2 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -282,9 +282,14 @@ ui.prototype.drawText = function (contents, callback) { } ////// 绘制一个对话框 ////// -ui.prototype.drawTextBox = function(content) { +ui.prototype.drawTextBox = function(content, showAll) { + + if (core.isset(core.status.event) && core.status.event.id=='action') { + core.status.event.ui = content; + } clearInterval(core.status.event.interval); + core.status.event.interval = null; // 获得name, image, icon var id=null, name=null, image=null, icon=null, iconHeight=32, animate=null; @@ -541,7 +546,7 @@ ui.prototype.drawTextBox = function(content) { } - if (textAttribute.time<=0 || core.status.event.id!='action') { + if (showAll || textAttribute.time<=0 || core.status.event.id!='action') { drawContent(content); } else { @@ -550,6 +555,7 @@ ui.prototype.drawTextBox = function(content) { drawContent(content.substring(0, ++index)); if (index==content.length) { clearInterval(core.status.event.interval); + core.status.event.interval = null; } }, textAttribute.time); } From 1eca3614e726ca77bb21fd5746721c04ab285aba Mon Sep 17 00:00:00 2001 From: oc Date: Tue, 18 Sep 2018 11:33:06 +0800 Subject: [PATCH 7/9] Reformat enemys --- project/enemys.js | 128 +++++++++++++++++++++++----------------------- 1 file changed, 64 insertions(+), 64 deletions(-) diff --git a/project/enemys.js b/project/enemys.js index dc389a6d..8c4c08b2 100644 --- a/project/enemys.js +++ b/project/enemys.js @@ -1,67 +1,67 @@ enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80 = { - 'greenSlime': {'name': '绿头怪', 'hp': 100, 'atk': 120, 'def': 0, 'money': 1, 'experience': 1, 'point': 0, 'special': [1,5,7,8]}, - 'redSlime': {'name': '红头怪', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': [16,18], 'value': 10}, - 'blackSlime': {'name': '青头怪', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'slimelord': {'name': '怪王', 'hp': 100, 'atk': 120, 'def': 0, 'money': 10, 'experience': 0, 'point': 0, 'special': [1,9]}, - 'bat': {'name': '小蝙蝠', 'hp': 100, 'atk': 120, 'def': 0, 'money': 2, 'experience': 0, 'point': 0, 'special': 1}, - 'bigBat': {'name': '大蝙蝠', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'redBat': {'name': '红蝙蝠', 'hp': 100, 'atk': 120, 'def': 0, 'money': 5, 'experience': 0, 'point': 0, 'special': 4}, - 'vampire': {'name': '冥灵魔王', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'skeleton': {'name': '骷髅人', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'skeletonSoilder': {'name': '骷髅士兵', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'skeletonCaptain': {'name': '骷髅队长', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'ghostSkeleton': {'name': '冥队长', 'hp': 100, 'atk': 120, 'def': 0, 'money': 8, 'experience': 0, 'point': 0, 'special': 7}, - 'zombie': {'name': '兽人', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'zombieKnight': {'name': '兽人武士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'rock': {'name': '石头人', 'hp': 100, 'atk': 120, 'def': 0, 'money': 4, 'experience': 0, 'point': 0, 'special': 3}, - 'slimeMan': {'name': '影子战士', 'hp': 100, 'atk': 0, 'def': 0, 'money': 11, 'experience': 0, 'point': 0, 'special': [10,21], 'atkValue': 2, 'defValue': 3}, // 退化怪可以在后面写atkValue和defValue表示退化的数值 - 'bluePriest': {'name': '初级法师', 'hp': 100, 'atk': 120, 'def': 0, 'money': 3, 'experience': 0, 'point': 1, 'special': 2}, - 'redPriest': {'name': '高级法师', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'brownWizard': {'name': '初级巫师', 'hp': 100, 'atk': 120, 'def': 0, 'money': 16, 'experience': 0, 'point': 0, 'special': 15, 'value': 100, 'range': 2}, // 领域怪需要加value表示领域伤害的数值;range可选,代表领域伤害的范围;不加默认为1 - 'redWizard': {'name': '高级巫师', 'hp': 1000, 'atk': 1200, 'def': 0, 'money': 160, 'experience': 0, 'point': 0, 'special': 15, 'value': 200, 'zoneSquare': true}, // zoneSquare可选,代表是否九宫格伤害,true为是九宫格伤害,false或不设置为十字伤害 - 'yellowGuard': {'name': '初级卫兵', 'hp': 100, 'atk': 120, 'def': 0, 'money': 10, 'experience': 0, 'point': 0, 'special': 0}, - 'blueGuard': {'name': '中级卫兵', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'redGuard': {'name': '高级卫兵', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'swordsman': {'name': '双手剑士', 'hp': 100, 'atk': 120, 'def': 0, 'money': 6, 'experience': 0, 'point': 0, 'special': [5,23]}, - 'soldier': {'name': '冥战士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'yellowKnight': {'name': '金骑士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'redKnight': {'name': '红骑士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'darkKnight': {'name': '黑骑士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'blackKing': {'name': '黑衣魔王', 'hp': 1000, 'atk': 500, 'def': 0, 'money': 1000, 'experience': 1000, 'point': 0, 'special': 0, 'notBomb': true}, // 加入 'notBomb': true 代表该怪物不可被炸弹或圣锤炸掉 - 'yellowKing': {'name': '黄衣魔王', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'greenKing': {'name': '青衣武士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'blueKnight': {'name': '蓝骑士', 'hp': 100, 'atk': 120, 'def': 0, 'money': 9, 'experience': 0, 'point': 0, 'special': 8}, - 'goldSlime': {'name': '黄头怪', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'poisonSkeleton': {'name': '紫骷髅', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'poisonBat': {'name': '紫蝙蝠', 'hp': 100, 'atk': 120, 'def': 0, 'money': 14, 'experience': 0, 'point': 0, 'special': 13}, - 'steelRock': {'name': '铁面人', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'skeletonPriest': {'name': '骷髅法师', 'hp': 100, 'atk': 100, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 18, 'value': 20}, - 'skeletonKing': {'name': '骷髅王', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'skeletonWizard': {'name': '骷髅巫师', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'redSkeletonCaption': {'name': '骷髅武士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'badHero': {'name': '迷失勇者', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'demon': {'name': '魔神武士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'demonPriest': {'name': '魔神法师', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'goldHornSlime': {'name': '金角怪', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'redKing': {'name': '红衣魔王', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'whiteKing': {'name': '白衣武士', 'hp': 100, 'atk': 120, 'def': 0, 'money': 17, 'experience': 0, 'point': 0, 'special': 16}, - 'blackMagician': {'name': '黑暗大法师', 'hp': 100, 'atk': 120, 'def': 0, 'money': 12, 'experience': 0, 'point': 0, 'special': 11, 'value': 1/3, 'add': true, 'notBomb': true}, // 吸血怪需要在后面添加value代表吸血比例;添加add: true可以将吸血的伤害加到自身 - 'silverSlime': {'name': '银头怪', 'hp': 100, 'atk': 120, 'def': 0, 'money': 15, 'experience': 0, 'point': 0, 'special': 14}, - 'swordEmperor': {'name': '剑圣', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'whiteHornSlime': {'name': '尖角怪', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'badPrincess': {'name': '痛苦魔女', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'badFairy': {'name': '黑暗仙子', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'grayPriest': {'name': '中级法师', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'redSwordsman': {'name': '剑王', 'hp': 100, 'atk': 120, 'def': 0, 'money': 7, 'experience': 0, 'point': 0, 'special': 6, 'n': 8}, // 多连击需要在后面指定n代表是几连击 - 'whiteGhost': {'name': '水银战士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'poisonZombie': {'name': '绿兽人', 'hp': 100, 'atk': 120, 'def': 0, 'money': 13, 'experience': 0, 'point': 0, 'special': 12}, - 'magicDragon': {'name': '魔龙', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'octopus': {'name': '血影', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'darkFairy': {'name': '仙子', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'greenKnight': {'name': '强盾骑士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'angel': {'name': '天使', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'elemental': {'name': '元素生物', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0}, - 'steelGuard': {'name': '铁守卫', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 18, 'value': 20}, - 'evilBat': {'name': '邪恶蝙蝠', 'hp': 1000, 'atk': 1, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': [2,3]}, + "greenSlime": {"name":"绿头怪","hp":100,"atk":120,"def":0,"money":1,"experience":1,"point":0,"special":[1,5,7,8]}, + "redSlime": {"name":"红头怪","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":[16,18],"value":10}, + "blackSlime": {"name":"青头怪","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "slimelord": {"name":"怪王","hp":100,"atk":120,"def":0,"money":10,"experience":0,"point":0,"special":[1,9]}, + "bat": {"name":"小蝙蝠","hp":100,"atk":120,"def":0,"money":2,"experience":0,"point":0,"special":1}, + "bigBat": {"name":"大蝙蝠","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "redBat": {"name":"红蝙蝠","hp":100,"atk":120,"def":0,"money":5,"experience":0,"point":0,"special":4}, + "vampire": {"name":"冥灵魔王","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "skeleton": {"name":"骷髅人","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "skeletonSoilder": {"name":"骷髅士兵","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "skeletonCaptain": {"name":"骷髅队长","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "ghostSkeleton": {"name":"冥队长","hp":100,"atk":120,"def":0,"money":8,"experience":0,"point":0,"special":7}, + "zombie": {"name":"兽人","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "zombieKnight": {"name":"兽人武士","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "rock": {"name":"石头人","hp":100,"atk":120,"def":0,"money":4,"experience":0,"point":0,"special":3}, + "slimeMan": {"name":"影子战士","hp":100,"atk":0,"def":0,"money":11,"experience":0,"point":0,"special":[10,21],"atkValue":2,"defValue":3}, + "bluePriest": {"name":"初级法师","hp":100,"atk":120,"def":0,"money":3,"experience":0,"point":1,"special":2}, + "redPriest": {"name":"高级法师","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "brownWizard": {"name":"初级巫师","hp":100,"atk":120,"def":0,"money":16,"experience":0,"point":0,"special":15,"value":100,"range":2}, + "redWizard": {"name":"高级巫师","hp":1000,"atk":1200,"def":0,"money":160,"experience":0,"point":0,"special":15,"value":200,"zoneSquare":true}, + "yellowGuard": {"name":"初级卫兵","hp":100,"atk":120,"def":0,"money":10,"experience":0,"point":0,"special":0}, + "blueGuard": {"name":"中级卫兵","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "redGuard": {"name":"高级卫兵","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "swordsman": {"name":"双手剑士","hp":100,"atk":120,"def":0,"money":6,"experience":0,"point":0,"special":[5,23]}, + "soldier": {"name":"冥战士","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "yellowKnight": {"name":"金骑士","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "redKnight": {"name":"红骑士","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "darkKnight": {"name":"黑骑士","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "blackKing": {"name":"黑衣魔王","hp":1000,"atk":500,"def":0,"money":1000,"experience":1000,"point":0,"special":0,"notBomb":true}, + "yellowKing": {"name":"黄衣魔王","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "greenKing": {"name":"青衣武士","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "blueKnight": {"name":"蓝骑士","hp":100,"atk":120,"def":0,"money":9,"experience":0,"point":0,"special":8}, + "goldSlime": {"name":"黄头怪","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "poisonSkeleton": {"name":"紫骷髅","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "poisonBat": {"name":"紫蝙蝠","hp":100,"atk":120,"def":0,"money":14,"experience":0,"point":0,"special":13}, + "steelRock": {"name":"铁面人","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "skeletonPriest": {"name":"骷髅法师","hp":100,"atk":100,"def":0,"money":0,"experience":0,"point":0,"special":18,"value":20}, + "skeletonKing": {"name":"骷髅王","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "skeletonWizard": {"name":"骷髅巫师","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "redSkeletonCaption": {"name":"骷髅武士","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "badHero": {"name":"迷失勇者","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "demon": {"name":"魔神武士","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "demonPriest": {"name":"魔神法师","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "goldHornSlime": {"name":"金角怪","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "redKing": {"name":"红衣魔王","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "whiteKing": {"name":"白衣武士","hp":100,"atk":120,"def":0,"money":17,"experience":0,"point":0,"special":16}, + "blackMagician": {"name":"黑暗大法师","hp":100,"atk":120,"def":0,"money":12,"experience":0,"point":0,"special":11,"value":0.3333333333333333,"add":true,"notBomb":true}, + "silverSlime": {"name":"银头怪","hp":100,"atk":120,"def":0,"money":15,"experience":0,"point":0,"special":14}, + "swordEmperor": {"name":"剑圣","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "whiteHornSlime": {"name":"尖角怪","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "badPrincess": {"name":"痛苦魔女","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "badFairy": {"name":"黑暗仙子","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "grayPriest": {"name":"中级法师","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "redSwordsman": {"name":"剑王","hp":100,"atk":120,"def":0,"money":7,"experience":0,"point":0,"special":6,"n":8}, + "whiteGhost": {"name":"水银战士","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "poisonZombie": {"name":"绿兽人","hp":100,"atk":120,"def":0,"money":13,"experience":0,"point":0,"special":12}, + "magicDragon": {"name":"魔龙","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "octopus": {"name":"血影","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "darkFairy": {"name":"仙子","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "greenKnight": {"name":"强盾骑士","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "angel": {"name":"天使","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "elemental": {"name":"元素生物","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":0}, + "steelGuard": {"name":"铁守卫","hp":0,"atk":0,"def":0,"money":0,"experience":0,"point":0,"special":18,"value":20}, + "evilBat": {"name":"邪恶蝙蝠","hp":1000,"atk":1,"def":0,"money":0,"experience":0,"point":0,"special":[2,3]} } \ No newline at end of file From 64e39b8da610a9882e8563caf24f13a1d6490095 Mon Sep 17 00:00:00 2001 From: oc Date: Tue, 18 Sep 2018 11:51:55 +0800 Subject: [PATCH 8/9] curtain -> canvas --- editor-mobile.html | 2 +- editor.html | 2 +- index.html | 2 +- libs/control.js | 14 ++++++++------ libs/events.js | 12 +++++++----- libs/ui.js | 2 ++ main.js | 1 - styles.css | 11 ++++------- 更新说明.txt | 6 ++++-- 9 files changed, 28 insertions(+), 24 deletions(-) diff --git a/editor-mobile.html b/editor-mobile.html index 9a2b55ea..90b4810f 100644 --- a/editor-mobile.html +++ b/editor-mobile.html @@ -408,7 +408,6 @@
-
@@ -418,6 +417,7 @@ + 此浏览器不支持HTML5
diff --git a/editor.html b/editor.html index 04f3c6be..42eed365 100644 --- a/editor.html +++ b/editor.html @@ -393,7 +393,6 @@
-
@@ -403,6 +402,7 @@ + 此浏览器不支持HTML5
diff --git a/index.html b/index.html index c97c9a8e..56128d9d 100644 --- a/index.html +++ b/index.html @@ -111,7 +111,6 @@
-
@@ -121,6 +120,7 @@ + 此浏览器不支持HTML5
diff --git a/libs/control.js b/libs/control.js index 2ebad530..962c6c09 100644 --- a/libs/control.js +++ b/libs/control.js @@ -187,8 +187,6 @@ control.prototype.showStartAnimate = function (callback) { core.dom.startButtonGroup.style.display = 'none'; core.dom.startButtons.style.display = 'block'; core.dom.levelChooseButtons.style.display = 'none'; - core.dom.curtain.style.background = "#000000"; - core.dom.curtain.style.opacity = 0; core.status.played = false; core.clearStatus(); core.clearMap('all'); @@ -1451,8 +1449,9 @@ control.prototype.setFg = function(color, time, callback) { if (time==0) { // 直接变色 - core.dom.curtain.style.background = core.arrayToRGB(color); - core.dom.curtain.style.opacity = color[3]; + core.clearMap('curtain'); + core.setAlpha('curtain', color[3]); + core.fillRect('curtain', 0, 0, 416, 416, core.arrayToRGB(color)); core.status.curtainColor = color; if (core.isset(callback)) callback(); return; @@ -1467,8 +1466,9 @@ control.prototype.setFg = function(color, time, callback) { 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); - core.dom.curtain.style.background = core.arrayToRGB([nowR,nowG,nowB]); - core.dom.curtain.style.opacity = nowAlpha; + core.clearMap('curtain'); + core.setAlpha('curtain', nowAlpha); + core.fillRect('curtain', 0, 0, 416, 416, core.arrayToRGB([nowR,nowG,nowB])); if (step>=25) { clearInterval(changeAnimate); @@ -2844,6 +2844,7 @@ control.prototype.resize = function(clientWidth, clientHeight) { height:(canvasWidth - SPACE*2) + unit, } }, + /* { id: 'curtain', rules: { @@ -2851,6 +2852,7 @@ control.prototype.resize = function(clientWidth, clientHeight) { height:(canvasWidth - SPACE*2) + unit, } }, + */ { id: 'gameDraw', rules: { diff --git a/libs/events.js b/libs/events.js index b4c7919a..e55bcee9 100644 --- a/libs/events.js +++ b/libs/events.js @@ -1236,15 +1236,17 @@ events.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback var color = core.floors[floorId].color; // 直接变色 - core.dom.curtain.style.background = core.arrayToRGB(color); + core.clearMap('curtain'); if (core.isset(color[3])) - core.dom.curtain.style.opacity = color[3]; - else core.dom.curtain.style.opacity=1; + core.setAlpha('curtain', color[3]); + else + core.setAlpha('curtain', 1); + core.fillRect('curtain', 0, 0, 416, 416, core.arrayToRGB(color)); core.status.curtainColor = color; } else { - core.dom.curtain.style.background = "#000000"; - core.dom.curtain.style.opacity = 0; + core.clearMap('curtain'); + core.setAlpha('curtain', 0); } } diff --git a/libs/ui.js b/libs/ui.js index 4fe93ed2..ac0bfedc 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -18,6 +18,8 @@ ui.prototype.init = function () { ui.prototype.clearMap = function (map, x, y, width, height) { if (map == 'all') { for (var m in core.canvas) { + // 不擦除curtain层 + if (m=='curtain') continue; core.canvas[m].clearRect(0, 0, core.bigmap.width*32, core.bigmap.height*32); } core.dom.gif.innerHTML = ""; diff --git a/main.js b/main.js index 7a31642e..f93f1f33 100644 --- a/main.js +++ b/main.js @@ -42,7 +42,6 @@ function main() { 'gameCanvas': document.getElementsByClassName('gameCanvas'), 'gif': document.getElementById('gif'), 'gif2': document.getElementById('gif2'), - 'curtain': document.getElementById('curtain'), 'gameDraw': document.getElementById('gameDraw'), 'startButtons': document.getElementById('startButtons'), 'playGame': document.getElementById('playGame'), diff --git a/styles.css b/styles.css index bae823ee..6b45773f 100644 --- a/styles.css +++ b/styles.css @@ -246,13 +246,6 @@ span#poison, span#weak, span#curse, span#pickaxe, span#bomb, span#fly { overflow: hidden; } -#curtain { - z-index: 100; - position: absolute; - opacity: 0; - background: #000000; -} - #gameDraw { position: absolute; background: #000000; @@ -296,6 +289,10 @@ span#poison, span#weak, span#curse, span#pickaxe, span#bomb, span#fly { z-index: 95; } +#curtain { + z-index: 100; +} + #ui { z-index: 110; } diff --git a/更新说明.txt b/更新说明.txt index a9f467ad..db3a2a5a 100644 --- a/更新说明.txt +++ b/更新说明.txt @@ -1,7 +1,9 @@ HTML5魔塔样板V2.4.1 -可叠加的三图层绘制图块 -专门的装备页面;装备系统大改造 +增加背景层和前景层的图块绘制,多层图块可叠加 +背景层/前景层图块的显示、隐藏、修改等事件 +专门的装备页面(Q键开启);装备系统大改造 +仿RM的灯光效果,通过插件函数方式给出 将状态栏更新和阻激夹域的计算移动到脚本编辑中 增加控制免疫阻激夹域的flag:no_zone等 打字机效果时点击显示全部文字 From 99697ddbbfb709100449ea413d7dc140c8618359 Mon Sep 17 00:00:00 2001 From: ckcz123 Date: Tue, 18 Sep 2018 18:03:42 +0800 Subject: [PATCH 9/9] Light Effect & V2.4.1 --- README.md | 18 +++++- docs/V2.0.md | 2 +- docs/api.md | 2 +- docs/element.md | 2 +- docs/event.md | 2 +- docs/index.md | 6 +- docs/personalization.md | 2 +- docs/start.md | 2 +- libs/ui.js | 17 +++++- main.js | 2 +- project/data.js | 6 +- project/functions.js | 130 ++++++++++++++++++++++++++++++---------- 更新说明.txt | 2 +- 13 files changed, 141 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index d2498933..1006b2c4 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,9 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏! * [List / HTML5魔塔游戏列表](https://h5mota.com/) * [Demo / 样板效果](https://ckcz123.com/games/template/) * [Docs / 使用文档说明](https://ckcz123.github.io/mota-js/) + ![样板](./docs/img/sample0.png) ## 目录结构 @@ -53,6 +54,19 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏! ## 更新说明 +### 2018.9.18 V2.4.1 + +* [x] 增加背景层和前景层的图块绘制,多层图块可叠加 +* [x] 背景层/前景层图块的显示、隐藏、修改等事件 +* [x] 专门的装备页面(Q键开启);装备系统大改造 +* [x] 灯光和漆黑层效果,通过插件函数方式给出 +* [x] 将状态栏更新和阻激夹域的计算移动到脚本编辑中 +* [x] 增加控制免疫阻激夹域的flag:no_zone等 +* [x] 打字机效果时点击显示全部文字 +* [x] 修复更改画面色调的Bug +* [x] 修复更改剧情文本属性后读档恢复原样的问题 +* [x] 部分细节优化 + ### 2018.8.28 V2.4 * [x] 大地图的支持 @@ -293,7 +307,7 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏! - [JS代码压缩工具](http://github.com/ckcz123/JSCompressor/):能对Javascript代码进行压缩和整合,从而减少IO请求量。 - [便捷PS工具](http://github.com/ckcz123/ps/):能只用复制和粘贴来快速对素材进行PS操作。 - [地图生成器](http://github.com/ckcz123/map_generator/):能从一张截图识别出来具体的数字数组,方便复刻已有的塔。 -- [怪物数据导出器](http://github.com/ckcz123/enemy_export/):能从RMXP中带出怪物数据,以供H5使用。 +- [怪物数据导出器](http://github.com/ckcz123/enemy_export/):能从RMXP中导出怪物数据,以供H5使用。 - [伤害和临界值计算器](http://github.com/ckcz123/magic-tower-calculator/):一个能帮助计算怪物的伤害和临界值的小工具。 ## 联系我们 diff --git a/docs/V2.0.md b/docs/V2.0.md index 2c87474d..0df0686a 100644 --- a/docs/V2.0.md +++ b/docs/V2.0.md @@ -1,6 +1,6 @@ # V2.0版本介绍 -?> 目前版本**v2.4**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.4.1**,上次更新时间:* {docsify-updated} * 目前样板已经更新到V2.0版本以上,本章将对V2.0的一些内容进行介绍。 diff --git a/docs/api.md b/docs/api.md index e18f44cf..e411229f 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1,6 +1,6 @@ # 附录: API列表 -?> 目前版本**v2.4**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.4.1**,上次更新时间:* {docsify-updated} * **这里只列出所有可能会被造塔者用到的常用API,更多的有关内容请在代码内进行查询。** diff --git a/docs/element.md b/docs/element.md index fbc5304b..0fd64fc8 100644 --- a/docs/element.md +++ b/docs/element.md @@ -1,6 +1,6 @@ # 元件说明 -?> 目前版本**v2.4**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.4.1**,上次更新时间:* {docsify-updated} * 在本章中,将对样板里的各个元件进行说明。各个元件主要包括道具、门、怪物、楼梯等等。 diff --git a/docs/event.md b/docs/event.md index 4786774d..bc1a9561 100644 --- a/docs/event.md +++ b/docs/event.md @@ -1,6 +1,6 @@ # 事件 -?> 目前版本**v2.4**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.4.1**,上次更新时间:* {docsify-updated} * 本章内将对样板所支持的事件进行介绍。 diff --git a/docs/index.md b/docs/index.md index 4bfabadd..b4ca28de 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,6 +1,6 @@ # HTML5 魔塔样板说明文档 -?> 目前版本**v2.4**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.4.1**,上次更新时间:* {docsify-updated} * 众所周知,魔塔的趋势是向移动端发展,贴吧中也常常能见到“求手机魔塔”的帖子。然而现有的工具中,NekoRPG有着比较大的局限性,游戏感较差,更是完全没法在iOS上运行。而一些APP的魔塔虽然可用,但是必须要下载安装,对于Android和iOS还必须开发不同的版本,非常麻烦。 @@ -12,9 +12,9 @@ > 这个魔塔样板,可以让你在完全不懂任何编程的情况下,做出自己的H5魔塔。不会代码?没关系!只要你想做,就能做出来! 继续查看文档的详细介绍,让你学会如何使用这一个样板来制作属于自己的HTML5魔塔。 - + ========================================================================================== [继续阅读下一章:现在就做出自己的第一部H5魔塔!](start) diff --git a/docs/personalization.md b/docs/personalization.md index d454eb90..87280538 100644 --- a/docs/personalization.md +++ b/docs/personalization.md @@ -1,6 +1,6 @@ # 个性化 -?> 目前版本**v2.4**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.4.1**,上次更新时间:* {docsify-updated} * 有时候只靠样板本身可能是不够的。我们需要一些个性化、自定义的素材,道具效果,怪物属性,等等。 diff --git a/docs/start.md b/docs/start.md index 6bbceee0..6e330a4a 100644 --- a/docs/start.md +++ b/docs/start.md @@ -1,6 +1,6 @@ # 快速上手 -?> 目前版本**v2.4**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.4.1**,上次更新时间:* {docsify-updated} * 在这一节中,将详细介绍做一部塔的流程。现在,让我们来做一部单层塔! diff --git a/libs/ui.js b/libs/ui.js index ac0bfedc..eb94dcdf 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -567,6 +567,8 @@ ui.prototype.drawTextBox = function(content, showAll) { ////// 绘制一个选项界面 ////// ui.prototype.drawChoices = function(content, choices) { + choices = choices || []; + var background = core.canvas.ui.createPattern(core.material.ground, "repeat"); core.clearMap('ui'); @@ -577,7 +579,15 @@ ui.prototype.drawChoices = function(content, choices) { // Step 1: 计算长宽高 var length = choices.length; - var left=85, width = 416-2*left; // 宽度 + + // 宽度计算:考虑选项的长度 + var width = 416 - 2*85; + core.setFont('ui', "bold 17px Verdana"); + for (var i = 0; i < choices.length; i++) { + width = Math.max(width, core.canvas.ui.measureText(core.replaceText(choices[i].text || choices[i])).width + 30); + } + + var left=parseInt((416 - width) / 2); // 左边界 // 高度 var height = 32*(length+2), bottom = 208+height/2; if (length%2==0) bottom+=16; @@ -693,8 +703,9 @@ ui.prototype.drawChoices = function(content, choices) { content_top = top+55; var title_offset = left+width/2; // 动画 + if (id=='hero' || core.isset(icon)) - title_offset += 22; + title_offset += 12; if (id == 'hero') { var heroHeight = core.material.icons.hero.height; @@ -1872,7 +1883,7 @@ ui.prototype.drawEquipbox = function(index) { // 个数 if (core.itemCount(ownEquip)>1) core.fillText('ui', core.itemCount(ownEquip), 16*(4*(i%6)+1)+40, 304+Math.floor(i/6)*54+38-ydelta, '#FFFFFF', "bold 14px Verdana"); - if (selectId == ownEquip) + if (index>=12 && selectId == ownEquip) core.strokeRect('ui', 16*(4*(i%6)+1)+1, 304+Math.floor(i/6)*54+1-ydelta, 40, 40, '#FFD700'); } diff --git a/main.js b/main.js index f93f1f33..b5720c43 100644 --- a/main.js +++ b/main.js @@ -2,7 +2,7 @@ function main() { //------------------------ 用户修改内容 ------------------------// - this.version = "2.4"; // 游戏版本号;如果更改了游戏内容建议修改此version以免造成缓存问题。 + this.version = "2.4.1"; // 游戏版本号;如果更改了游戏内容建议修改此version以免造成缓存问题。 this.useCompress = false; // 是否使用压缩文件 // 当你即将发布你的塔时,请使用“JS代码压缩工具”将所有js代码进行压缩,然后将这里的useCompress改为true。 diff --git a/project/data.js b/project/data.js index 3d95092b..8ddfa7b1 100644 --- a/project/data.js +++ b/project/data.js @@ -60,7 +60,7 @@ data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "firstData": { "title": "魔塔样板", "name": "template", - "version": "Ver 2.4", + "version": "Ver 2.4.1", "floorId": "sample0", "hero": { "name": "阳光", @@ -200,8 +200,8 @@ data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "bombFourDirections": false, "snowFourDirections": false, "bigKeyIsBox": false, - "equipment": true, - "equipboxButton": true, + "equipment": false, + "equipboxButton": false, "enableAddPoint": false, "enableNegativeDamage": false, "hatredDecrease": true, diff --git a/project/functions.js b/project/functions.js index 6f80e240..6ea42f21 100644 --- a/project/functions.js +++ b/project/functions.js @@ -1,7 +1,7 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = { - "events": { - "initGame": function() { + "events": { + "initGame": function() { // 游戏开始前的一些初始化操作 // 根据flag来对道具进行修改 @@ -32,7 +32,7 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = core.material.items.shield5.cls = 'equips'; } }, - "setInitData": function (hard) { + "setInitData": function (hard) { // 不同难度分别设置初始属性 if (hard=='Easy') { // 简单难度 core.setFlag('hard', 1); // 可以用flag:hard来获得当前难度 @@ -52,7 +52,7 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = } core.events.afterLoadData(); }, - "win": function(reason, norank) { + "win": function(reason, norank) { // 游戏获胜事件 core.ui.closePanel(); var replaying = core.status.replay.replaying; @@ -71,7 +71,7 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = }) }); }, - "lose": function(reason) { + "lose": function(reason) { // 游戏失败事件 core.ui.closePanel(); var replaying = core.status.replay.replaying; @@ -84,7 +84,7 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = }); }) }, - "afterChangeFloor": function (floorId, fromLoad) { + "afterChangeFloor": function (floorId, fromLoad) { // 转换楼层结束的事件 // floorId是切换到的楼层;fromLoad若为true则代表是从读档行为造成的楼层切换 if (!core.hasFlag("visited_"+floorId)) { @@ -92,7 +92,7 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = core.setFlag("visited_"+floorId, true); } }, - "addPoint": function (enemy) { + "addPoint": function (enemy) { // 加点事件 var point = enemy.point; if (!core.flags.enableAddPoint || !core.isset(point) || point<=0) return []; @@ -114,7 +114,7 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = } ]; }, - "afterBattle": function(enemyId,x,y,callback) { + "afterBattle": function(enemyId,x,y,callback) { // 战斗结束后触发的事件 var enemy = core.material.enemys[enemyId]; @@ -235,7 +235,7 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = if (core.isset(callback)) callback(); }, - "afterOpenDoor": function(doorId,x,y,callback) { + "afterOpenDoor": function(doorId,x,y,callback) { // 开一个门后触发的事件 var todo = []; @@ -258,7 +258,7 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = } if (core.isset(callback)) callback(); }, - "afterGetItem": function(itemId,x,y,callback) { + "afterGetItem": function(itemId,x,y,callback) { // 获得一个道具后触发的事件 var todo = []; @@ -275,11 +275,11 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = if (core.isset(callback)) callback(); }, - "afterChangeLight": function(x,y) { + "afterChangeLight": function(x,y) { // 改变亮灯之后,可以触发的事件 }, - "afterPushBox": function () { + "afterPushBox": function () { // 推箱子后的事件 var noBoxLeft = function () { @@ -302,7 +302,7 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = */ } }, - "afterUseBomb": function () { + "afterUseBomb": function () { // 使用炸弹/圣锤后的事件 // 这是一个使用炸弹也能开门的例子 @@ -317,19 +317,19 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = */ }, - "beforeSaveData": function(data) { + "beforeSaveData": function(data) { // 即将存档前可以执行的操作 }, - "afterLoadData": function(data) { + "afterLoadData": function(data) { // 读档事件后,载入事件前,可以执行的操作 // 怪物数据的动态修改迁移到了“脚本编辑 - updateEnemys”中,详见文档说明 core.enemys.updateEnemys(); } - }, - "enemys": { - "getSpecials": function() { + }, + "enemys": { + "getSpecials": function() { // 获得怪物的特殊属性,每一行定义一个特殊属性。 // 分为三项,第一项为该特殊属性的数字,第二项为特殊属性的名字,第三项为特殊属性的描述 // 可以直接写字符串,也可以写个function将怪物传进去 @@ -360,7 +360,7 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = [24, "激光", function (enemy) {return "经过怪物同行或同列时自动减生命"+(enemy.value||0)+"点";}] ]; }, - "getDamageInfo": function (enemy, hero_hp, hero_atk, hero_def, hero_mdef) { + "getDamageInfo": function (enemy, hero_hp, hero_atk, hero_def, hero_mdef) { // 获得战斗伤害信息(实际伤害计算函数) // 怪物生命,怪物攻击、防御、特殊属性 @@ -453,7 +453,7 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = "damage": damage }; }, - "updateEnemys": function () { + "updateEnemys": function () { // 更新怪物数据,可以在这里对怪物属性和数据进行动态更新,详见文档——事件——怪物数据的动态修改 // 比如下面这个例子,如果flag:xxx为真,则将绿头怪的攻击设为100,金币设为20 /* @@ -464,9 +464,9 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = */ // 别忘了在事件中调用“更新怪物数据”事件! } - }, - "control": { - "updateStatusBar": function () { + }, + "control": { + "updateStatusBar": function () { // 更新状态栏 // 检查等级 @@ -532,7 +532,7 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = // 更新全地图显伤 core.updateDamage(); }, - "updateCheckBlock": function () { + "updateCheckBlock": function () { // 领域、夹击、阻击等的伤害值计算 core.status.checkBlock = {}; @@ -652,7 +652,7 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = // 计算夹击伤害 if (has) { core.status.checkBlock.betweenAttack[x+core.bigmap.width*y]=true; - // 先扣除该点领域/阻击/激光造成的伤害,再算夹击 + // 先扣除该点领域/阻击/激光造成的伤害,再算夹击 var leftHp = core.status.hero.hp - core.status.checkBlock.damage[x+core.bigmap.width*y]; // 1血不夹;core.flags.betweenAttackCeil控制向上还是向下 if (leftHp>1) @@ -662,9 +662,9 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = } } } - }, - "ui": { - "drawAbout": function() { + }, + "ui": { + "drawAbout": function() { // 绘制“关于”界面 if (!core.isPlaying()) { core.status.event = {'id': null, 'data': null}; @@ -691,9 +691,9 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = core.fillText('ui', 'HTML5魔塔交流群:539113091', text_start, top+112+32); // TODO: 写自己的“关于”页面,每次增加32像素即可 } - }, - "plugins": { - "plugin": function () { + }, + "plugins": { + "plugin": function () { ////// 插件编写,可以在这里写自己额外需要执行的脚本 ////// // 在这里写的代码,在所有模块加载完毕后,游戏开始前会被执行 @@ -706,10 +706,74 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = // 如果不写this的话,函数将无法被外部所访问 this.test = function () { console.log("插件函数执行测试"); + }; + + + // 绘制灯光/漆黑层效果。调用方式 core.plugin.drawLight(...) + // 【参数说明】 + // color:可选,灯光以外部分的颜色,可以是一个四元数组,或者简单的一个0到1之间的数。忽略则默认为0.9。 + // 如果是四元数组,则代表RGBA值,如 [255,255,0,0.2] 就代表 #FFFF00 且不透明度0.2 + // 如果是一个数,则只是不透明度的值,RGB均为0,如 0.9 就代表 [0,0,0,0.9] + // lights:可选,一个数组,定义了每个独立的灯光。 + // 其中每一项是三元组 [x,y,r] 或者四元组 [x,y,r,o] + // x和y分别为该灯光的横纵坐标,r为该灯光的半径,o为该灯光中心的不透明度,可忽略默认为0。 + // lightDec:可选,0到1之间,光从多少百分比才开始衰减(在此范围内保持全亮),不设置默认为0。 + // 比如lightDec为0.5代表,每个灯光部分内圈50%的范围全亮,50%以后才开始快速衰减。 + // 【调用样例】 + // core.plugin.drawLight(); // 绘制一个0.9的全图不透明度,等价于更改画面色调为[0,0,0,0.9]。 + // core.plugin.drawLight(0.95, [[25,11,46]]); // 全图不透明度0.95,其中在(25,11)点存在一个半径为46的灯光效果。 + // core.plugin.drawLight([255,255,0,0.2], [[25,11,46,0.1]]); // 全图为不透明度0.2的黄色,其中在(25,11)点存在一个半径为46的灯光效果,灯光中心不透明度0.1。 + // core.plugin.drawLight(0.9, [[25,11,46],[105,121,88],[301,221,106]]); // 存在三个灯光效果,分别是中心(25,11)半径46,中心(105,121)半径88,中心(301,221)半径106。 + // core.plugin.drawLight([0,0,255,0.3], [[25,11,46],[105,121,88,0.2]], 0.4); // 存在两个灯光效果,它们在内圈40%范围内保持全亮,且40%后才开始衰减。 + // 【注意事项】 + // 此函数会和更改画面色调发生冲突,请只选择一个使用。 + this.drawLight = function (color, lights, lightDec) { + // 清空色调层 + var ctx = core.canvas.curtain; + ctx.mozImageSmoothingEnabled = false; + ctx.webkitImageSmoothingEnabled = false; + ctx.msImageSmoothingEnabled = false; + ctx.imageSmoothingEnabled = false; + core.clearMap('curtain'); + core.setOpacity('curtain', 1); + core.setAlpha('curtain', 1); + + // 绘制色调层,默认不透明度 + if (!core.isset(color)) color = 0.9; + if (typeof color == "number") color = [0,0,0,color]; + core.fillRect('curtain', 0, 0, 416, 416, + 'rgba('+color[0]+','+color[1]+','+color[2]+','+core.clamp(color[3],0,1)+')'); + + // 绘制每个灯光效果 + if (!core.isset(lights) || lights.length==0) return; + lightDec = core.clamp(lightDec, 0, 1); + lights.forEach(function (light) { + // 坐标,半径,中心不透明度 + var x = light[0], y = light[1], r = light[2], o = 255 * (1 - core.clamp(light[3], 0, 1)); + // 计算衰减距离 + var decDistance = parseInt(r * lightDec), leftDistance = r - decDistance; + // 正方形区域的直径和左上角坐标 + var d = r * 2, sx = x - r, sy = y - r; + // 获得正方形区域的颜色信息 + var imageData = ctx.getImageData(sx, sy, d, d); + // 对每个像素点进行遍历 + for (var i = 0; i < imageData.data.length; i+=4) { + // 当前点的坐标 + var index = i / 4, cx = parseInt(index/d), cy = index%d; + // 当前点距离中心点的距离 + var dx = r - cx, dy = r - cy, distance = Math.sqrt(dx*dx+dy*dy); + if (distance >= r) continue; + // 计算当前点的alpha值 + var alpha = imageData.data[i+3] - (distance