diff --git a/README.md b/README.md index 2a60c151..54f5ff23 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,25 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏! ## 更新说明 +### 2018.5.6 V2.2 + +* [x] 事件坐标可用变量指定("loc": ["flag:x", "flag:y"]) +* [x] 全局商店也可以使用图块编辑 +* [x] 高亮显示有事件的格子 +* [x] 对于道具和怪物自动注册该列所有未注册的素材 +* [x] 便捷PS工具对于白底图片可自动调整为透明背景 +* [x] 事件:等待用户点击(type:wait) +* [x] 事件:图片移动事件(type:moveImage) +* [x] 事件:设置BGM音量(type:setVolume) +* [x] 提供core.rand()和core.rand2()两个随机数函数 +* [x] 作弊处理(最大有效生命值、匿名则最低成绩上传) +* [x] 自定义状态栏绘制 +* [x] 最高六倍速播放 +* [x] 播放录像时可以C键查看怪物手册 +* [x] 修复标题文字太长导致无法开始游戏的问题 +* [x] 新增纯新手简易造塔流程 +* [x] 部分效果和性能的优化 + ### 2018.4.25 V2.1.1 * [x] 新增事件:改变勇士行走图 diff --git a/V2.0版本简易造塔流程(For新人).txt b/V2.0版本简易造塔流程(For新人).txt new file mode 100644 index 00000000..042e6517 --- /dev/null +++ b/V2.0版本简易造塔流程(For新人).txt @@ -0,0 +1,78 @@ +这只是一个最简单的造塔流程,更为详细的还是请参见视频或教程文档。 + +1. 打开启动服务,地图编辑器。 + +2. 切换到MT0层,然后开始绘制地图。可以在上面放置墙、门、道具或怪物等。 +如果提示“该素材未被定义”,请参见第7点。 +如果要从RMXP中复刻已有的塔的地图,请参见第11点。 + +3. 切换到楼层属性,一项一项仔细进行楼层属性的编辑,如楼层名,firstArrive等等。 +将鼠标移动到表格的中间可以查看详细信息。 +firstArrive为初次到达楼层的事件,可以双击进行事件的编辑。有关事件请详见文档。 + +3. 输入怪物数据:点击右边怪物,然后左边写怪物的攻防血等数值。 +将鼠标移动到表格的中间可以查看详细信息。 +如果是特殊属性怪物直接写特殊编号,多个特殊属性可以用 [1,2] 来表示。 + +4. 在中间的下拉框切换全塔属性,一项一项仔细进行根据需求编辑。 +请注意"name"一项必须修改为“字母、数字、下划线组成的字符串”,否则会出现串档问题。 +startText(初始剧情)、shops(全局商店)、levelUp(升级)等都是可以双击方框进行编辑的。 +有关全局商店和升级等信息详见 教程文档 - 事件 + +5. 给地图添加事件;可以给地图上的NPC增加事件,或者战斗/开门事件等。 +点击地图上的某个点,在左边进行编辑。 +event -- 该点的自定义事件(例如NPC,商店,等等) +changeFloor -- 该点的楼层传送事件(楼梯/传送门) +afterBattle -- 该点战斗后触发的战后事件 +afterOpenDoor -- 该点开门后触发的事件 +afterGetItem -- 该点获得道具后触发的事件 +等等。 +有关事件详细内容请参见 文档 - 事件。 + +6. 新建楼层:切换到地图编辑,然后在框内输入新楼层的floorId,点击新建地图即可保存。 +创建的floorId必须是字母、数字和下划线组成,且不能以数字开头。 +不能为空白,不能和任何已有楼层的floorId重复。 +保存成功后刷新页面。 + +删除楼层同理,不过请注意删除的会是当前的楼层而不是框中的内容。 + +7. 关于素材未被定义的问题:如果点击某个怪物或NPC提示该素材未被定义,请在左边进行素材的注册。 +输入该素材的唯一ID(不能和其他素材的ID重复),和素材的唯一数字(1000以内,不能和其他的数字重复), +保存并刷新,即注册成功。 + +8. 添加新素材:请打开启动服务的便捷PS工具,然后左边读取你要添加到的图片(比如怪物是enemys.png,道具是items.png), +右边读取你要导入的怪物素材,通过复制粘贴进行导入,再保存,刷新页面后按照第7点来进行素材的注册。 + +9. 道具的自定义效果:如果需要自定义道具效果,请仿照其他的几个道具来写,更多信息详见文档。 + +10. 报错处理:有时候刷新后可能页面变成空白,即无法正确加载。 +出现这种问题的原因往往是手动错误编辑了文件、新建楼层使用了不合法的floorId(比如中文或数字)、楼层floorId定义重复,等等。 + +出现这种问题,(在Chrome浏览器中)请按Ctrl+Shift+I打开控制台,找到Console查看报错。 +一般都会具体到哪个楼层文件出错。 + +解决方式:哪个楼层文件出错,请使用VSCode等打开project目录下的data.js文件,并将出错的那个楼层定义删除。 + +举例,比如我在新建地图中写了 “水潭边” 这样一个楼层名(中文),然后新建并保存,刷新会出错。 +此时,打开控制台(Ctrl+Shift+I的Console),并查看报错,发现是该楼层错误。 +那么打开data.js文件,并将 "floorIds": [..., "水潭边"] 这里对它的楼层定义删除,再刷新即可。 + +11. 从RMXP中导入已有的塔的地图。 +如果你想复刻老塔,则需使用启动服务的地图生成器。 +请确保老地图中的所有使用素材(地面/墙壁/门/道具/怪物等等)都已经被注册过(参见第7点)。 + +打开windows自带的截图工具,并对地图进行截图。 +截图时请注意:必须截刚好13x13范围大小的地图,尽量对其边缘进行截取。 +如果不是13x13的范围大小,可能会导致地图生成器无响应。 +截图完毕后,请复制到剪切板,然后在地图生成器中点加载图片。等1-2秒,就可以看到截图被识别。 +点“复制地图”,然后在地图编辑器中切换到“地图编辑”,并粘贴到左边的框内,即可。 +如果存在个别识别问题,可以对这个别素材再进行重新绘制。 + +如果出现大量识别问题,比如基本全是错的,则代表你的截图方式有问题。 +由于地图生成器的识别以左上角的图块为基准来找寻截图偏移量,请确保左上角一定要是一个能被很好识别的图块。 +建议:在RM的图层第三层,左上角放一个岩浆,再进行截图(保证截图的13x13的左上角是岩浆,从而可以确保定位), +识别后再复制到地图编辑器中进行绘制。 + +-------------------------------- + +HTML5魔塔交流群:539113091,如果有问题请加群提问。 diff --git a/_server/blockly/MotaAction.g4 b/_server/blockly/MotaAction.g4 index 4ebc8d92..9b0d5068 100644 --- a/_server/blockly/MotaAction.g4 +++ b/_server/blockly/MotaAction.g4 @@ -192,6 +192,7 @@ action | setHeroIcon_s | update_s | sleep_s + | wait_s | battle_s | openDoor_s | changeFloor_s @@ -206,6 +207,7 @@ action | animateImage_1_s | showGif_0_s | showGif_1_s + | moveImage_0_s | setFg_0_s | setFg_1_s | setWeather_s @@ -215,6 +217,7 @@ action | pauseBgm_s | resumeBgm_s | playSound_s + | setVolume_s | win_s | lose_s | if_s @@ -406,7 +409,7 @@ trigger_s /* trigger_s tooltip : trigger: 立即触发另一个地点的事件 helpUrl : https://ckcz123.github.io/mota-js/#/event?id=trigger-%e7%ab%8b%e5%8d%b3%e8%a7%a6%e5%8f%91%e5%8f%a6%e4%b8%80%e4%b8%aa%e5%9c%b0%e7%82%b9%e7%9a%84%e4%ba%8b%e4%bb%b6 -default : [0,0] +default : ["0","0"] colour : this.eventColor var code = '{"type": "trigger", "loc": ['+PosString_0+','+PosString_1+']},\n'; return code; @@ -493,6 +496,18 @@ var code = '{"type": "sleep", "time": '+Int_0+'},\n'; return code; */ +wait_s + : '等待用户操作' + ; + +/* wait_s +tooltip : wait: 等待用户操作 +helpUrl : https://ckcz123.github.io/mota-js/#/event?id=wait-%e7%ad%89%e5%be%85%e7%94%a8%e6%88%b7%e6%93%8d%e4%bd%9c +colour : this.soundColor +var code = '{"type": "wait"},\n'; +return code; +*/ + battle_s : '强制战斗' IdString Newline ; @@ -513,7 +528,7 @@ openDoor_s /* openDoor_s tooltip : openDoor: 开门,楼层可不填表示当前层 helpUrl : https://ckcz123.github.io/mota-js/#/event?id=opendoor-%e5%bc%80%e9%97%a8 -default : [0,0,""] +default : ["","",""] colour : this.dataColor IdString_0 = IdString_0 && (', "floorId": "'+IdString_0+'"'); var code = '{"type": "openDoor", "loc": ['+PosString_0+','+PosString_1+']'+IdString_0+'},\n'; @@ -527,7 +542,7 @@ changeFloor_s /* changeFloor_s tooltip : changeFloor: 楼层切换,动画时间可不填 helpUrl : https://ckcz123.github.io/mota-js/#/event?id=changefloor-%e6%a5%bc%e5%b1%82%e5%88%87%e6%8d%a2 -default : ["MT1",0,0,null,500] +default : ["MT1","0","0",null,500] colour : this.dataColor DirectionEx_List_0 = DirectionEx_List_0 && (', "direction": "'+DirectionEx_List_0+'"'); Int_0 = Int_0 ?(', "time": '+Int_0):''; @@ -542,7 +557,7 @@ changePos_0_s /* changePos_0_s tooltip : changePos: 当前位置切换 helpUrl : https://ckcz123.github.io/mota-js/#/event?id=changepos-%e5%bd%93%e5%89%8d%e4%bd%8d%e7%bd%ae%e5%88%87%e6%8d%a2%e5%8b%87%e5%a3%ab%e8%bd%ac%e5%90%91 -default : [0,0,null] +default : ["","",null] colour : this.dataColor DirectionEx_List_0 = DirectionEx_List_0 && (', "direction": "'+DirectionEx_List_0+'"'); var code = '{"type": "changePos", "loc": ['+PosString_0+','+PosString_1+']'+DirectionEx_List_0+'},\n'; @@ -618,7 +633,7 @@ showImage_0_s /* showImage_0_s tooltip : showImage:显示图片 helpUrl : https://ckcz123.github.io/mota-js/#/event?id=showimage%ef%bc%9a%e6%98%be%e7%a4%ba%e5%9b%be%e7%89%87 -default : ["bg.jpg",0,0] +default : ["bg.jpg","0","0"] colour : this.printColor var code = '{"type": "showImage", "name": "'+EvalString_0+'", "loc": ['+PosString_0+','+PosString_1+']},\n'; return code; @@ -637,41 +652,41 @@ return code; */ animateImage_0_s - : '图片淡入' EvalString '起点像素位置' 'x' Number 'y' Number '动画时间' Int Newline + : '图片淡入' EvalString '起点像素位置' 'x' PosString 'y' PosString '动画时间' Int Newline ; /* animateImage_0_s tooltip : animageImage:图片淡入 helpUrl : https://ckcz123.github.io/mota-js/#/event?id=animateimage%ef%bc%9a%e5%9b%be%e7%89%87%e6%b7%a1%e5%85%a5%e6%b7%a1%e5%87%b -default : ["bg.jpg",0,0,500] +default : ["bg.jpg","0","0",500] colour : this.printColor -var code = '{"type": "animateImage", "action": "show", "name": "'+EvalString_0+'", "loc": ['+Number_0+','+Number_1+'], "time": '+Int_0+'},\n'; +var code = '{"type": "animateImage", "action": "show", "name": "'+EvalString_0+'", "loc": ['+PosString_0+','+PosString_1+'], "time": '+Int_0+'},\n'; return code; */ animateImage_1_s - : '图片淡出' EvalString '起点像素位置' 'x' Number 'y' Number '动画时间' Int Newline + : '图片淡出' EvalString '起点像素位置' 'x' PosString 'y' PosString '动画时间' Int Newline ; /* animateImage_1_s tooltip : animageImage:图片淡出 helpUrl : https://ckcz123.github.io/mota-js/#/event?id=animateimage%ef%bc%9a%e5%9b%be%e7%89%87%e6%b7%a1%e5%85%a5%e6%b7%a1%e5%87%b -default : ["bg.jpg",0,0,500] +default : ["bg.jpg","0","0",500] colour : this.printColor -var code = '{"type": "animateImage", "action": "hide", "name": "'+EvalString_0+'", "loc": ['+Number_0+','+Number_1+'], "time": '+Int_0+'},\n'; +var code = '{"type": "animateImage", "action": "hide", "name": "'+EvalString_0+'", "loc": ['+PosString_0+','+PosString_1+'], "time": '+Int_0+'},\n'; return code; */ showGif_0_s - : '显示动图' EvalString '起点像素位置' 'x' Number 'y' Number Newline + : '显示动图' EvalString '起点像素位置' 'x' PosString 'y' PosString Newline ; /* showGif_0_s tooltip : showGif:显示动图 helpUrl : https://ckcz123.github.io/mota-js/#/event?id=showgif%ef%bc%9a%e6%98%be%e7%a4%ba%e5%8a%a8%e5%9b%be -default : ["bg.gif",0,0] +default : ["bg.gif","0","0"] colour : this.printColor -var code = '{"type": "showGif", "name": "'+EvalString_0+'", "loc": ['+Number_0+','+Number_1+']},\n'; +var code = '{"type": "showGif", "name": "'+EvalString_0+'", "loc": ['+PosString_0+','+PosString_1+']},\n'; return code; */ @@ -687,6 +702,20 @@ var code = '{"type": "showGif"},\n'; return code; */ +moveImage_0_s + : '图片移动' EvalString '起点像素位置' 'x' PosString 'y' PosString BGNL + '终点像素位置' 'x' PosString 'y' PosString '移动时间' Int Newline + ; + +/* moveImage_0_s +tooltip : moveImage:图片移动 +helpUrl : https://ckcz123.github.io/mota-js/#/event?id=moveImage%ef%bc%9a%e6%98%be%e7%a4%ba%e5%8a%a8%e5%9b%be +default : ["bg.jpg","0","0","0","0",500] +colour : this.printColor +var code = '{"type": "moveImage", "name": "'+EvalString_0+'", "from": ['+PosString_0+','+PosString_1+'], "to": ['+PosString_2+','+PosString_3+'], "time": '+Int_0+'},\n'; +return code; +*/ + setFg_0_s : '更改画面色调' Number ',' Number ',' Number ',' Number '动画时间' Int? Newline ; @@ -821,6 +850,19 @@ var code = '{"type": "playSound", "name": "'+EvalString_0+'"},\n'; return code; */ +setVolume_s + : '设置音量' Int Newline + ; + +/* setVolume_s +tooltip : setVolume: 设置音量 +helpUrl : https://ckcz123.github.io/mota-js/#/event?id=setVolume-%e8%ae%be%e7%bd%ae%e9%9f%b3%e9%87%8f +default : [90] +colour : this.soundColor +var code = '{"type": "setVolume", "value": '+Int_0+'},\n'; +return code; +*/ + win_s : '游戏胜利,结局' ':' EvalString? Newline ; @@ -1390,6 +1432,11 @@ ActionParser.prototype.parseAction = function() { this.next]); } break; + case "moveImage": // 移动图片 + this.next = MotaActionBlocks['moveImage_0_s'].xmlText([ + data.name, data.from[0], data.from[1], data.to[0], data.to[1], data.time, this.next + ]); + break; case "setFg": // 颜色渐变 if(this.isset(data.color)){ this.next = MotaActionBlocks['setFg_0_s'].xmlText([ @@ -1439,6 +1486,10 @@ ActionParser.prototype.parseAction = function() { this.next = MotaActionBlocks['resumeBgm_s'].xmlText([ this.next]); break + case "setVolume": + this.next = MotaActionBlocks['setVolume_s'].xmlText([ + data.value, this.next]); + break case "setValue": this.next = MotaActionBlocks['setValue_s'].xmlText([ MotaActionBlocks['idString_e'].xmlText([data.name]), @@ -1487,6 +1538,10 @@ ActionParser.prototype.parseAction = function() { this.next = MotaActionBlocks['sleep_s'].xmlText([ data.time,this.next]); break; + case "wait": // 等待用户操作 + this.next = MotaActionBlocks['wait_s'].xmlText([ + this.next]); + break; case "revisit": // 立刻重新执行该事件 this.next = MotaActionBlocks['revisit_s'].xmlText([ this.next]); diff --git a/_server/comment.js b/_server/comment.js index 0a138152..92db9457 100644 --- a/_server/comment.js +++ b/_server/comment.js @@ -33,12 +33,6 @@ comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "_leaf": true, "_type": "textarea", "_data": "道具在道具栏中显示的描述" - }, - "isEquipment": { - "_leaf": true, - "_type": "checkbox", - "_bool": "bool", - "_data": "物品是否属于装备(仅在全塔属性的equipment为true时有效)" } } }, diff --git a/_server/data.comment.js b/_server/data.comment.js index 66260dbc..99f824e1 100644 --- a/_server/data.comment.js +++ b/_server/data.comment.js @@ -46,7 +46,22 @@ data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "_leaf": true, "_type": "textarea", "_data": "难度选择:每个数组的第一个是其在标题界面显示的难度,第二个是在游戏内部传输的字符串,会显示在状态栏,修改此处后需要在project/functions中作相应更改" - } + }, + "statusLeftBackground": { + "_leaf": true, + "_type": "textarea", + "_data": "横屏时左侧状态栏的背景样式,可以定义背景图、平铺方式等。\n具体请网上搜索\"css background\"了解写法。\n如果弄一张图片作为背景图,推荐写法:\n\"url(project/images/XXX.png) 0 0/100% 100% no-repeat\"\n图片最好进行一些压缩等操作节省流量。" + }, + "statusTopBackground": { + "_leaf": true, + "_type": "textarea", + "_data": "竖屏时上方状态栏的背景样式,可以定义背景图、平铺方式等。\n具体请网上搜索\"css background\"了解写法。\n如果弄一张图片作为背景图,推荐写法:\n\"url(project/images/XXX.png) 0 0/100% 100% no-repeat\"\n图片最好进行一些压缩等操作节省流量。" + }, + "toolsBackground": { + "_leaf": true, + "_type": "textarea", + "_data": "竖屏时下方道具栏的背景样式,可以定义背景图、平铺方式等。\n具体请网上搜索\"css background\"了解写法。\n如果弄一张图片作为背景图,推荐写法:\n\"url(project/images/XXX.png) 0 0/100% 100% no-repeat\"\n图片最好进行一些压缩等操作节省流量。" + }, } }, "firstData": { @@ -218,7 +233,7 @@ data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "weakValue": { "_leaf": true, "_type": "textarea", - "_data": "衰弱状态下攻防减少的数值" + "_data": "衰弱状态下攻防减少的数值\n如果此项不小于1,则作为实际下降的数值(比如10就是攻防各下降10)\n如果在0到1之间则为下降的比例(比如0.3就是下降30%的攻防)" }, "redJewel": { "_leaf": true, @@ -340,6 +355,12 @@ data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "_type": "textarea", "_data": "仇恨属性中,每杀死一个怪物获得的仇恨值" }, + "maxValidHp": { + "_leaf": true, + "_type": "textarea", + "_range": "thiseval==null||thiseval>0", + "_data": "最大合法生命值;如果此项不为null且用户通关血量超过本值,则视为作弊,不上传成绩" + }, "animateSpeed": { "_leaf": true, "_type": "textarea", diff --git a/_server/editor.js b/_server/editor.js index 7abc4d7e..75f6bbbd 100644 --- a/_server/editor.js +++ b/_server/editor.js @@ -20,7 +20,7 @@ editor.prototype.init = function (callback) { editor.updateMap(); editor.currentFloorId = core.status.floorId; editor.currentFloorData = core.floors[core.status.floorId]; - + editor.drawEventBlock(); if (Boolean(callback)) callback(); }); } @@ -193,6 +193,34 @@ editor.prototype.drawMapBg = function (img) { } } +editor.prototype.drawEventBlock = function () { + var fg=document.getElementById('efg').getContext('2d'); + + fg.clearRect(0, 0, 416, 416); + for (var i=0;i<13;i++) { + for (var j=0;j<13;j++) { + var color=null; + var loc=i+","+j; + if (core.isset(editor.currentFloorData.events[loc])) + color = '#FF0000'; + else if (core.isset(editor.currentFloorData.changeFloor[loc])) + color = '#00FF00'; + else if (core.isset(editor.currentFloorData.afterBattle[loc])) + color = '#FFFF00'; + else if (core.isset(editor.currentFloorData.afterGetItem[loc])) + color = '#00FFFF'; + else if (core.isset(editor.currentFloorData.afterOpenDoor[loc])) + color = '#FF00FF'; + else if (core.isset(editor.currentFloorData.cannotMove[loc])) + color = '#0000FF'; + if (color!=null) { + fg.fillStyle = color; + fg.fillRect(32*i, 32*j+32-8, 8, 8); + } + } + } +} + editor.prototype.updateMap = function () { var blocks = main.editor.mapIntoBlocks(editor.map.map(function (v) { return v.map(function (v) { @@ -340,6 +368,7 @@ editor.prototype.changeFloor = function (floorId, callback) { editor.currentFloorId = core.status.floorId; editor.currentFloorData = core.floors[core.status.floorId]; editor_mode.floor(); + editor.drawEventBlock(); if (core.isset(callback)) callback(); }); } diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index 9ec571c3..ba9850e6 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -67,6 +67,7 @@ editor_blockly = function () { MotaActionBlocks['showImage_1_s'].xmlText(), MotaActionBlocks['showGif_0_s'].xmlText(), MotaActionBlocks['showGif_1_s'].xmlText(), + MotaActionBlocks['moveImage_0_s'].xmlText(), MotaActionBlocks['tip_s'].xmlText(), MotaActionBlocks['openShop_s'].xmlText(), MotaActionBlocks['win_s'].xmlText(), @@ -102,6 +103,7 @@ editor_blockly = function () { MotaActionBlocks['disableShop_s'].xmlText(), '', MotaActionBlocks['sleep_s'].xmlText(), + MotaActionBlocks['wait_s'].xmlText(), MotaActionBlocks['animate_s'].xmlText(), MotaActionBlocks['setFg_0_s'].xmlText(), MotaActionBlocks['setFg_1_s'].xmlText(), @@ -110,6 +112,7 @@ editor_blockly = function () { MotaActionBlocks['pauseBgm_s'].xmlText(), MotaActionBlocks['resumeBgm_s'].xmlText(), MotaActionBlocks['playSound_s'].xmlText(), + MotaActionBlocks['setVolume_s'].xmlText(), '', MotaActionBlocks['function_s'].xmlText(), ], @@ -267,7 +270,7 @@ document.getElementById('blocklyDiv').onmousewheel = function(e){ var varName = error.varName; var block = error.block; } - console.log(error); + // console.log(error); } } diff --git a/_server/editor_file.js b/_server/editor_file.js index cc80ed8e..ce105848 100644 --- a/_server/editor_file.js +++ b/_server/editor_file.js @@ -144,6 +144,67 @@ editor_file = function (editor, callback) { //////////////////////////////////////////////////////////////////// + editor_file.autoRegister = function (info, callback) { + + var iconActions = []; + var mapActions = []; + var templateActions = []; + + var image = info.images; + + if (image!='items' && image.indexOf('enemy')!=0) { + callback('只有怪物和道具才能自动注册!'); + return; + } + var c=image=='items'?'I':'M'; + + var allIds = []; + editor.ids.forEach(function (v) { + if (v.images==image) { + allIds[v.y]=true; + } + }) + + var per_height = image.indexOf('48')>=0?48:32; + + var idnum=300; + for (var y=0; y 目前版本**v2.1**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.2**,上次更新时间:* {docsify-updated} * 目前样板已经更新到V2.0版本以上,本章将对V2.0的一些内容进行介绍。 diff --git a/docs/api.md b/docs/api.md index e78e8d9a..b65f4808 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1,6 +1,6 @@ # 附录:API列表 -?> 目前版本**v2.1**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.2**,上次更新时间:* {docsify-updated} * 所有系统支持的API都列在了这里。所有可能被用到的API都在前面用\*标记。 diff --git a/docs/element.md b/docs/element.md index 83ee5d5c..d4025cf8 100644 --- a/docs/element.md +++ b/docs/element.md @@ -1,6 +1,6 @@ # 元件说明 -?> 目前版本**v2.1**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.2**,上次更新时间:* {docsify-updated} * 在本章中,将对样板里的各个元件进行说明。各个元件主要包括道具、门、怪物、楼梯等等。 diff --git a/docs/event.md b/docs/event.md index 1d60fad1..8b63ae48 100644 --- a/docs/event.md +++ b/docs/event.md @@ -1,6 +1,6 @@ # 事件 -?> 目前版本**v2.1**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.2**,上次更新时间:* {docsify-updated} * 本章内将对样板所支持的事件进行介绍。 @@ -373,6 +373,8 @@ value是一个表达式,将通过这个表达式计算出的结果赋值给nam show事件需要用loc指定目标点的坐标,可以简单的写[x,y]代表一个点,也可以写个二维数组[[x1,y1],[x2,y2],...]来同时显示多个点。 +从V2.2开始,loc也可以用变量来代替,例如 `"loc": ["flag:x", "flag:y"]`。下同。 + floorId为目标点的楼层,如果不是该楼层的事件(比如4楼小偷开2楼的门)则是必须的,如果是当前楼层可以忽略不写。 time为动画效果时间,如果指定了某个大于0的数,则会以动画效果慢慢从无到有显示,动画时间为该数值;如果不指定该选项则无动画直接立刻显示。 @@ -519,6 +521,10 @@ name是可选的,代表目标行走图的文件名。 ] ``` +### wait:等待用户操作 + +使用 `{"type": "wait"}` 可以等待用户进行操作(如点击、回车等)。 + ### battle: 强制战斗 调用battle可强制与某怪物进行战斗(而无需去触碰到它)。 @@ -700,6 +706,26 @@ loc为动图左上角坐标,以像素为单位进行计算。 如果不指定name则清除所有显示的动图。 +### moveImage:图片移动 + +我们可以使用 `{"type": "moveImage"}` 来造成图片移动效果。 + +``` js +"x,y": [ // 实际执行的事件列表 + {"type": "moveImage", "name": "bg.jpg", "from": [231,297], "to": [22,333], "time": 500}, +] +``` + +name为图片名。**请确保图片在data.js中的images中被定义过。** + +from为起点图片左上角坐标,以像素为单位进行计算。 + +to为终点图片左上角坐标,以像素为单位进行计算。 + +time为总移动的时间。 + +!> 移动图片只是会在顶层绘制“移动”效果,动画结束即消失,并不会实际对图片的显示造成影响。请与showImage事件合用。 + ### setFg: 更改画面色调 我们可以使用 `{"type": "setFg"}` 来更改画面色调。 @@ -838,6 +864,14 @@ move完毕后移动的NPC/怪物一定会消失,只不过可以通过immediate 值得注意的是,如果是额外添加进文件的音效,则需在main.js中this.sounds里加载它。 +### setVolume:设置音量 + +使用setVolume可以设置音量大小。 + +使用方法: `{"type": "setVolume", "value": 90}` + +value为音量大小,在0到100之间,默认为100。设置后,BGM和SE都将使用该音量进行播放。 + ### win: 获得胜利 `{"type": "win", "reason": "xxx"}` 将会直接调用events.js中的win函数,并将reason作为结局传入。 @@ -1017,6 +1051,91 @@ choices为一个数组,其中每一项都是一个选项列表。 ], ``` +### while:循环处理 + +从2.2.1样板开始,我们提供了循环处理(while事件)。 + +其大致写法如下: + +``` js +"x,y": [ // 实际执行的事件列表 + {"type": "while", "condition": "...", // 循环测试某个条件 + "data": [ // 条件成立则执行data里面的事件 + + ] + }, +] +``` + +我们可以在condition中给出一个表达式(能将`status:xxx, item:xxx, flag:xxx`来作为参数),并进行判断是否成立。 + +如果条件成立,则将执行`"data"`中的列表事件内容。 + +该事件列表执行完毕后,将继续测试`"condition"`,如果还为true则重新进行执行data内容。 + +下面是一个输出1到10之间的数字,每隔1秒显示一个的例子。 + +``` js +"x,y": [ // 实际执行的事件列表 + {"type":"while", "condition": "flag:i<=10", // 循环处理;注意flag未设置则默认为0 + "data":[ + {"type": "setValue", "name": "flag:i", "value": "flag:i+1"}, // 递增i + "${flag:i}", // 输出i + {"type": "sleep","time":1000}, // 等待1秒 + ] + }, +] +``` + +### break:跳出循环 + +使用 `{"type": "break"}` 可以跳出当前循环。 + +上面的输出例子也可以这么写: + +``` js +"x,y": [ // 实际执行的事件列表 + {"type":"while", "condition": "true", // 循环处理;永远为真 + "data":[ + {"type": "setValue", "name": "flag:i", "value": "flag:i+1"}, // 递增i + {"type": "if", "condition": "flag:i>10", // 测试i是否超过了10 + "true": [{"type": "break"}], // 是的,则直接break调出循环 + "false": [] + }, + "${flag:i}", // 输出i + {"type": "sleep","time":1000}, // 等待1秒 + ] + }, +] +``` + +!> 如果break事件不在任何循环中被执行,则和exit等价,即会立刻结束当前事件! + +### continue:继续执行当前循环 + +使用 `{"type": "continue"}` 可以继续执行当前循环。 + +上面的输出例子也可以这么写: + +``` js +"x,y": [ // 实际执行的事件列表 + {"type":"while", "condition": "true", // 循环处理;永远为真 + "data":[ + {"type": "setValue", "name": "flag:i", "value": "flag:i+1"}, // 递增i + "${flag:i}", // 输出i + {"type": "sleep","time":1000}, // 等待1秒 + {"type": "if", "condition": "flag:i<10", // 测试i是否小于10 + "true": [{"type": "continue"}], // 是的,则继续循环 + "false": [] + }, + {"type": "break"}, // 跳出循环 + ] + }, +] +``` + +!> 如果continue事件不在任何循环中被执行,则和exit等价,即会立刻结束当前事件! + ### function: 自定义JS脚本 上述给出了这么多事件,但有时候往往不能满足需求,这时候就需要执行自定义脚本了。 diff --git a/docs/index.md b/docs/index.md index 068f0907..ad0b16ef 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,6 +1,6 @@ # HTML5 魔塔样板说明文档 -?> 目前版本**v2.1**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.2**,上次更新时间:* {docsify-updated} * 众所周知,魔塔的趋势是向移动端发展,贴吧中也常常能见到“求手机魔塔”的帖子。然而现有的工具中,NekoRPG有着比较大的局限性,游戏感较差,更是完全没法在iOS上运行。而一些APP的魔塔虽然可用,但是必须要下载安装,对于Android和iOS还必须开发不同的版本,非常麻烦。 diff --git a/docs/personalization.md b/docs/personalization.md index 6fa837b5..f11e2e12 100644 --- a/docs/personalization.md +++ b/docs/personalization.md @@ -1,6 +1,6 @@ # 个性化 -?> 目前版本**v2.1**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.2**,上次更新时间:* {docsify-updated} * 有时候只靠样板本身可能是不够的。我们需要一些个性化、自定义的素材,道具效果,怪物属性,等等。 diff --git a/docs/start.md b/docs/start.md index 078f587d..0bf5a6d3 100644 --- a/docs/start.md +++ b/docs/start.md @@ -1,6 +1,6 @@ # 快速上手 -?> 目前版本**v2.1**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.2**,上次更新时间:* {docsify-updated} * 在这一节中,将详细介绍做一部塔的流程。现在,让我们来做一部单层塔! diff --git a/editor.html b/editor.html index 2a0bf05c..696c7dbf 100644 --- a/editor.html +++ b/editor.html @@ -86,8 +86,10 @@ +
+ -
+
@@ -203,6 +205,7 @@ +
diff --git a/libs/actions.js b/libs/actions.js index eb98a683..0bf91aa6 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -13,7 +13,7 @@ actions.prototype.init = function () { ////// 按下某个键时 ////// actions.prototype.onkeyDown = function (e) { - if (core.isset(core.status.replay)&&core.status.replay.replaying&&core.status.event.id!='save') return; + if (core.isset(core.status.replay)&&core.status.replay.replaying&&core.status.event.id!='save'&&(core.status.event.id||"").indexOf('book')!=0) return; if (!core.isset(core.status.holdingKeys))core.status.holdingKeys=[]; var isArrow={37:true,38:true,39:true,40:true}[e.keyCode] if(isArrow && !core.status.lockControl){ @@ -31,7 +31,7 @@ actions.prototype.onkeyDown = function (e) { ////// 放开某个键时 ////// actions.prototype.onkeyUp = function(e) { - if (core.isset(core.status.replay)&&core.status.replay.replaying&&core.status.event.id!='save') { + if (core.isset(core.status.replay)&&core.status.replay.replaying&&core.status.event.id!='save'&&(core.status.event.id||"").indexOf('book')!=0) { if (e.keyCode==27) // ESCAPE core.stopReplay(); else if (e.keyCode==90) // Z @@ -44,6 +44,8 @@ actions.prototype.onkeyUp = function(e) { core.rewindReplay(); else if (e.keyCode==83) core.saveReplay(); + else if (e.keyCode==67) + core.bookReplay(); return; } @@ -64,7 +66,7 @@ actions.prototype.onkeyUp = function(e) { ////// 按住某个键时 ////// actions.prototype.pressKey = function (keyCode) { - if (core.isset(core.status.replay)&&core.status.replay.replaying&&core.status.event.id!='save') return; + if (core.isset(core.status.replay)&&core.status.replay.replaying&&core.status.event.id!='save'&&(core.status.event.id||"").indexOf('book')!=0) return; if (keyCode === core.status.holdingKeys.slice(-1)[0]) { this.keyDown(keyCode); window.setTimeout(function(){core.pressKey(keyCode);},30); @@ -73,7 +75,7 @@ actions.prototype.pressKey = function (keyCode) { ////// 根据按下键的code来执行一系列操作 ////// actions.prototype.keyDown = function(keyCode) { - if (core.isset(core.status.replay)&&core.status.replay.replaying&&core.status.event.id!='save') return; + if (core.isset(core.status.replay)&&core.status.replay.replaying&&core.status.event.id!='save'&&(core.status.event.id||"").indexOf('book')!=0) return; if (core.status.lockControl) { // Ctrl跳过对话 if (keyCode==17) { @@ -193,7 +195,8 @@ actions.prototype.keyDown = function(keyCode) { ////// 根据放开键的code来执行一系列操作 ////// actions.prototype.keyUp = function(keyCode, fromReplay) { - if (!fromReplay&&core.isset(core.status.replay)&&core.status.replay.replaying&&core.status.event.id!='save') return; + if (!fromReplay&&core.isset(core.status.replay)&&core.status.replay.replaying&&core.status.event.id!='save'&&(core.status.event.id||"").indexOf('book')!=0) + return; if (core.status.lockControl) { core.status.holdingKeys = []; @@ -399,7 +402,7 @@ actions.prototype.keyUp = function(keyCode, fromReplay) { ////// 点击(触摸)事件按下时 ////// actions.prototype.ondown = function (x ,y) { - if (core.isset(core.status.replay)&&core.status.replay.replaying&&core.status.event.id!='save') return; + if (core.isset(core.status.replay)&&core.status.replay.replaying&&core.status.event.id!='save'&&(core.status.event.id||"").indexOf('book')!=0) return; if (!core.status.played || core.status.lockControl) { this.onclick(x, y, []); if (core.timeout.onDownTimeout==null) { @@ -427,7 +430,7 @@ actions.prototype.ondown = function (x ,y) { ////// 当在触摸屏上滑动时 ////// actions.prototype.onmove = function (x ,y) { - if (core.isset(core.status.replay)&&core.status.replay.replaying&&core.status.event.id!='save') return; + if (core.isset(core.status.replay)&&core.status.replay.replaying&&core.status.event.id!='save'&&(core.status.event.id||"").indexOf('book')!=0) return; // if (core.status.holdingPath==0){return;} //core.status.mouseOutCheck =1; var pos={'x':x,'y':y}; @@ -451,7 +454,7 @@ actions.prototype.onmove = function (x ,y) { ////// 当点击(触摸)事件放开时 ////// actions.prototype.onup = function () { - if (core.isset(core.status.replay)&&core.status.replay.replaying&&core.status.event.id!='save') return; + if (core.isset(core.status.replay)&&core.status.replay.replaying&&core.status.event.id!='save'&&(core.status.event.id||"").indexOf('book')!=0) return; clearTimeout(core.timeout.onDownTimeout); core.timeout.onDownTimeout = null; @@ -517,7 +520,7 @@ actions.prototype.getClickLoc = function (x, y) { ////// 具体点击屏幕上(x,y)点时,执行的操作 ////// actions.prototype.onclick = function (x, y, stepPostfix) { - if (core.isset(core.status.replay)&&core.status.replay.replaying&&core.status.event.id!='save') return; + if (core.isset(core.status.replay)&&core.status.replay.replaying&&core.status.event.id!='save'&&(core.status.event.id||"").indexOf('book')!=0) return; // console.log("Click: (" + x + "," + y + ")"); stepPostfix=stepPostfix||[]; @@ -671,7 +674,7 @@ actions.prototype.onclick = function (x, y, stepPostfix) { ////// 滑动鼠标滚轮时的操作 ////// actions.prototype.onmousewheel = function (direct) { - if (core.isset(core.status.replay)&&core.status.replay.replaying&&core.status.event.id!='save') return; + if (core.isset(core.status.replay)&&core.status.replay.replaying&&core.status.event.id!='save'&&(core.status.event.id||"").indexOf('book')!=0) return; // 向下滚动是 -1 ,向上是 1 // 楼层飞行器 @@ -712,7 +715,7 @@ actions.prototype.longClick = function () { core.drawText(); return true; } - if (core.status.event.id=='action' && core.status.event.data.type=='text') { + if (core.status.event.id=='action' && (core.status.event.data.type=='text' || core.status.event.data.type=='wait')) { core.doAction(); return true; } @@ -725,7 +728,7 @@ actions.prototype.keyDownCtrl = function () { core.drawText(); return; } - if (core.status.event.id=='action' && core.status.event.data.type=='text') { + if (core.status.event.id=='action' && (core.status.event.data.type=='text' || core.status.event.data.type=='wait')) { core.doAction(); return; } @@ -766,7 +769,7 @@ actions.prototype.keyUpConfirmBox = function (keycode) { ////// 自定义事件时的点击操作 ////// actions.prototype.clickAction = function (x,y) { - if (core.status.event.data.type=='text') { + if (core.status.event.data.type=='text' || core.status.event.data.type=='wait') { // 文字 core.doAction(); return; @@ -808,7 +811,7 @@ 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.data.type=='text' || core.status.event.data.type=='wait') && (keycode==13 || keycode==32 || keycode==67)) { core.doAction(); return; } @@ -1655,7 +1658,7 @@ actions.prototype.clickSyncSave = function (x,y) { if (data instanceof Array) { core.ui.drawConfirmBox("所有本地存档都将被覆盖,确认?", function () { - for (var i=1;i<=150;i++) { + for (var i=1;i<=5*(main.savePages||30);i++) { if (i<=data.length) { core.setLocalStorage("save"+i, data[i-1]); } @@ -1670,8 +1673,8 @@ actions.prototype.clickSyncSave = function (x,y) { }) } else { - var index=150; - for (var i=150;i>=1;i--) { + var index=5*(main.savePages||30); + for (var i=5*(main.savePages||30);i>=1;i--) { if (core.getLocalStorage("save"+i, null)==null) index=i; else break; @@ -1687,6 +1690,7 @@ actions.prototype.clickSyncSave = function (x,y) { core.download(core.firstData.name+"_"+core.formatDate2(new Date())+".h5route", JSON.stringify({ 'name': core.firstData.name, 'hard': core.status.hard, + 'seed': core.getFlag('seed'), 'route': core.encodeRoute(core.status.route) })); break; @@ -1793,7 +1797,7 @@ actions.prototype.clickLocalSaveSelect = function (x,y) { switch (selection) { case 0: saves=[]; - for (var i=1;i<=150;i++) { + for (var i=1;i<=5*(main.savePages||30);i++) { var data = core.getLocalStorage("save"+i, null); if (core.isset(data)) { saves.push(data); @@ -1801,7 +1805,7 @@ actions.prototype.clickLocalSaveSelect = function (x,y) { } break; case 1: - for (var i=150;i>=1;i--) { + for (var i=5*(main.savePages||30);i>=1;i--) { saves=core.getLocalStorage("save"+i, null); if (core.isset(saves)) { break; @@ -1865,7 +1869,7 @@ actions.prototype.clickStorageRemove = function (x, y) { core.drawText("\t[操作成功]你的所有存档已被清空。"); break; case 1: - for (var i=1;i<=150;i++) { + for (var i=1;i<=5*(main.savePages||30);i++) { core.removeLocalStorage("save"+i); } core.drawText("\t[操作成功]当前塔的存档已被清空。"); @@ -1919,8 +1923,11 @@ actions.prototype.clickReplay = function (x, y) { { core.ui.closePanel(); var hard=core.status.hard, route=core.clone(core.status.route); + var seed = core.getFlag('seed'); core.resetStatus(core.firstData.hero, hard, core.firstData.floorId, null, core.initStatus.maps); core.events.setInitData(hard); + core.setFlag('seed', seed); + core.setFlag('rand', seed); core.changeFloor(core.status.floorId, null, core.firstData.hero.loc, null, function() { core.startReplay(route); }, true); diff --git a/libs/control.js b/libs/control.js index 900441ad..a7047e7a 100644 --- a/libs/control.js +++ b/libs/control.js @@ -583,9 +583,14 @@ control.prototype.setHeroMoveInterval = function (direction, x, y, callback) { 'down': {'x': 0, 'y': 1}, 'right': {'x': 1, 'y': 0} }; + + var toAdd = 1; + if (core.status.replay.speed>3) + toAdd = 2; + core.interval.heroMoveInterval = window.setInterval(function () { - core.status.heroMoving++; - if (core.status.heroMoving==8) { + core.status.heroMoving+=toAdd; + if (core.status.heroMoving>=8) { core.setHeroLoc('x', x+scan[direction].x); core.setHeroLoc('y', y+scan[direction].y); core.moveOneStep(); @@ -595,7 +600,7 @@ control.prototype.setHeroMoveInterval = function (direction, x, y, callback) { core.status.heroMoving = 0; if (core.isset(callback)) callback(); } - }, 12.5 / core.status.replay.speed); + }, 12.5 * toAdd / core.status.replay.speed); } ////// 实际每一步的行走过程 ////// @@ -1428,8 +1433,9 @@ control.prototype.resumeReplay = function () { control.prototype.speedUpReplay = function () { if (core.status.event.id=='save') return; if (!core.status.replay.replaying) return; - core.status.replay.speed = parseInt(10*core.status.replay.speed + 1)/10; - if (core.status.replay.speed>3.0) core.status.replay.speed=3.0; + var toAdd = core.status.replay.speed>=3?3:core.status.replay.speed>=2?2:1; + core.status.replay.speed = parseInt(10*core.status.replay.speed + toAdd)/10; + if (core.status.replay.speed>6.0) core.status.replay.speed=6.0; core.drawTip("x"+core.status.replay.speed+"倍"); } @@ -1437,7 +1443,8 @@ control.prototype.speedUpReplay = function () { control.prototype.speedDownReplay = function () { if (core.status.event.id=='save') return; if (!core.status.replay.replaying) return; - core.status.replay.speed = parseInt(10*core.status.replay.speed - 1)/10; + var toAdd = core.status.replay.speed>3?3:core.status.replay.speed>2?2:1; + core.status.replay.speed = parseInt(10*core.status.replay.speed - toAdd)/10; if (core.status.replay.speed<0.3) core.status.replay.speed=0.3; core.drawTip("x"+core.status.replay.speed+"倍"); } @@ -1512,6 +1519,23 @@ control.prototype.saveReplay = function () { core.ui.drawSLPanel(10*page+offset); } +////// 回放时查看怪物手册 ////// +control.prototype.bookReplay = function () { + if (!core.status.replay.replaying) return; + if (!core.status.replay.pausing) { + core.drawTip("请先暂停录像"); + return; + } + if (core.status.replay.animate || core.isset(core.status.event.id)) { + core.drawTip("请等待当前事件的处理结束"); + return; + } + + core.lockControl(); + core.status.event.id='book'; + core.useItem('book'); +} + ////// 回放 ////// control.prototype.replay = function () { @@ -1526,9 +1550,9 @@ control.prototype.replay = function () { } core.status.replay.steps++; - if (core.status.replay.steps%20==0) { - if (core.status.replay.save.length == 30) - core.status.replay.save.shift(); + if (core.status.replay.steps%50==0) { + //if (core.status.replay.save.length == 30) + // core.status.replay.save.shift(); core.status.replay.save.push({"data": core.saveData(), "replay": { "totalList": core.clone(core.status.replay.totalList), "toReplay": core.clone(core.status.replay.toReplay), @@ -1541,7 +1565,9 @@ control.prototype.replay = function () { if (action=='up' || action=='down' || action=='left' || action=='right') { core.moveHero(action, function () { - core.replay(); + setTimeout(function() { + core.replay(); + }); }); return; } @@ -1558,7 +1584,7 @@ control.prototype.replay = function () { core.useItem(itemId, function () { core.replay(); }); - }, 750 / Math.sqrt(core.status.replay.speed)); + }, 750 / core.status.replay.speed); } return; } @@ -1576,7 +1602,7 @@ control.prototype.replay = function () { core.changeFloor(floorId, stair, null, null, function () { core.replay(); }); - }, 750 / Math.sqrt(core.status.replay.speed)); + }, 750 / core.status.replay.speed); return; } } @@ -1609,7 +1635,7 @@ control.prototype.replay = function () { core.status.event.selection = parseInt(selections.shift()); core.events.openShop(shopId, false); - }, 750 / Math.sqrt(core.status.replay.speed)); + }, 750 / core.status.replay.speed); return; } } @@ -1819,8 +1845,11 @@ control.prototype.doSL = function (id, type) { // core.drawTip("存档版本不匹配"); if (confirm("存档版本不匹配!\n你想回放此存档的录像吗?")) { core.dom.startPanel.style.display = 'none'; + var seed = data.hero.flags.seed; core.resetStatus(core.firstData.hero, data.hard, core.firstData.floorId, null, core.initStatus.maps); core.events.setInitData(data.hard); + core.setFlag('seed', seed); + core.setFlag('rand', seed); core.changeFloor(core.status.floorId, null, core.firstData.hero.loc, null, function() { core.startReplay(core.decodeRoute(data.route)); }, true); @@ -1852,7 +1881,7 @@ control.prototype.doSL = function (id, type) { return; } var route = core.subarray(core.status.route, core.decodeRoute(data.route)); - if (!core.isset(route)) { + if (!core.isset(route) || data.hero.flags.seed!=core.getFlag('seed')) { core.drawTip("无法从此存档回放录像"); return; } @@ -1869,7 +1898,7 @@ control.prototype.syncSave = function (type) { // data if (type=='all') { saves=[]; - for (var i=1;i<=150;i++) { + for (var i=1;i<=5*(main.savePages||30);i++) { var data = core.getLocalStorage("save"+i, null); if (core.isset(data)) { saves.push(data); @@ -1877,7 +1906,7 @@ control.prototype.syncSave = function (type) { } } else { - for (var i=150;i>=1;i--) { + for (var i=5*(main.savePages||30);i>=1;i--) { saves=core.getLocalStorage("save"+i, null); if (core.isset(saves)) { break; @@ -1938,7 +1967,7 @@ control.prototype.syncLoad = function () { if (data instanceof Array) { core.status.event.selection=1; core.ui.drawConfirmBox("所有本地存档都将被覆盖,确认?", function () { - for (var i=1;i<=150;i++) { + for (var i=1;i<=5*(main.savePages||30);i++) { if (i<=data.length) { core.setLocalStorage("save"+i, data[i-1]); } @@ -1954,8 +1983,8 @@ control.prototype.syncLoad = function () { } else { // 只覆盖单存档 - var index=150; - for (var i=150;i>=1;i--) { + var index=5*(main.savePages||30); + for (var i=5*(main.savePages||30);i>=1;i--) { if (core.getLocalStorage("save"+i, null)==null) index=i; else break; @@ -2101,6 +2130,7 @@ control.prototype.playBgm = function (bgm) { } // 播放当前BGM core.musicStatus.playingBgm = bgm; + core.material.bgms[bgm].volume = core.musicStatus.volume; core.material.bgms[bgm].play(); core.musicStatus.isPlaying = true; @@ -2168,7 +2198,7 @@ control.prototype.playSound = function (sound) { if (core.musicStatus.audioContext != null) { var source = core.musicStatus.audioContext.createBufferSource(); source.buffer = core.material.sounds[sound]; - source.connect(core.musicStatus.audioContext.destination); + source.connect(core.musicStatus.gainNode); try { source.start(0); } @@ -2181,11 +2211,12 @@ control.prototype.playSound = function (sound) { } } else { + core.material.sounds[sound].volume = core.musicStatus.volume; core.material.sounds[sound].play(); } } catch (eee) { - console.log("无法播放SE "+bgm); + console.log("无法播放SE "+sound); console.log(eee); } } @@ -2253,18 +2284,14 @@ control.prototype.updateStatusBar = function () { core.statusBar.image.fly.style.opacity = 1; core.statusBar.image.toolbox.src = core.statusBar.icons.rewind.src; - core.statusBar.image.toolbox.style.opacity = 1; - core.statusBar.image.shop.style.opacity = 0; + core.statusBar.image.shop.src = core.statusBar.icons.book.src; core.statusBar.image.save.src = core.statusBar.icons.speedDown.src; - core.statusBar.image.save.style.opacity = 1; core.statusBar.image.load.src = core.statusBar.icons.speedUp.src; - core.statusBar.image.load.style.opacity = 1; core.statusBar.image.settings.src = core.statusBar.icons.save.src; - core.statusBar.image.settings.style.opacity = 1; } else { @@ -2275,18 +2302,14 @@ control.prototype.updateStatusBar = function () { core.statusBar.image.fly.style.opacity = core.hasItem('fly')?1:0.3; core.statusBar.image.toolbox.src = core.statusBar.icons.toolbox.src; - core.statusBar.image.toolbox.style.opacity = 1; - core.statusBar.image.shop.style.opacity = 1; + core.statusBar.image.shop.src = core.statusBar.icons.shop.src; core.statusBar.image.save.src = core.statusBar.icons.save.src; - core.statusBar.image.save.style.opacity = 1; core.statusBar.image.load.src = core.statusBar.icons.load.src; - core.statusBar.image.load.style.opacity = 1; core.statusBar.image.settings.src = core.statusBar.icons.settings.src; - core.statusBar.image.settings.style.opacity = 1; } core.updateFg(); @@ -2321,7 +2344,7 @@ control.prototype.resize = function(clientWidth, clientHeight) { statusWidth, statusHeight, statusMaxWidth,statusLabelsLH, toolBarWidth, toolBarHeight, toolBarTop, toolBarBorder, toolsWidth, toolsHeight,toolsMargin,toolsPMaxwidth, - fontSize, toolbarFontSize, margin; + fontSize, toolbarFontSize, margin, statusBackground, toolsBackground; var count = core.dom.statusBar.children.length; if (!core.flags.enableFloor) count--; @@ -2380,12 +2403,14 @@ control.prototype.resize = function(clientWidth, clientHeight) { statusHeight = scale*BASE_LINEHEIGHT * .8; statusLabelsLH = .8 * BASE_LINEHEIGHT *scale; statusMaxWidth = scale * DEFAULT_BAR_WIDTH * .95; + statusBackground = main.statusTopBackground; toolBarHeight = tempBotBarH; toolBarTop = statusBarHeight + canvasWidth; toolBarBorder = '3px #fff solid'; toolsHeight = scale * BASE_LINEHEIGHT; toolsPMaxwidth = scale * DEFAULT_BAR_WIDTH * .4; + toolsBackground = main.toolsBackground; borderRight = '3px #fff solid'; margin = scale * SPACE * 2; @@ -2400,15 +2425,17 @@ control.prototype.resize = function(clientWidth, clientHeight) { canvasTop = 0; // canvasLeft = DEFAULT_BAR_WIDTH * scale; toolBarWidth = statusBarWidth = DEFAULT_BAR_WIDTH * scale; - statusBarHeight = scale * statusLineHeight * count + SPACE * 2; //一共有9行加上两个padding空隙 + statusBarHeight = gameGroupHeight - SPACE; statusBarBorder = '3px #fff solid'; + statusBackground = main.statusLeftBackground; statusHeight = scale*statusLineHeight * .8; statusLabelsLH = .8 * statusLineHeight *scale; - toolBarHeight = canvasWidth - statusBarHeight; toolBarTop = scale*statusLineHeight * count + SPACE * 2; + toolBarHeight = canvasWidth - toolBarTop; toolBarBorder = '3px #fff solid'; toolsHeight = scale * BASE_LINEHEIGHT; + toolsBackground = 'transparent'; fontSize = statusLineFontSize * scale; toolbarFontSize = DEFAULT_FONT_SIZE * scale; borderRight = ''; @@ -2431,12 +2458,15 @@ control.prototype.resize = function(clientWidth, clientHeight) { // canvasLeft = DEFAULT_BAR_WIDTH; toolBarWidth = statusBarWidth = DEFAULT_BAR_WIDTH; - statusBarHeight = statusLineHeight * count + SPACE * 2; //一共有9行 + // statusBarHeight = statusLineHeight * count + SPACE * 2; //一共有9行 + statusBackground = main.statusLeftBackground; + statusBarHeight = gameGroupHeight - SPACE; statusHeight = statusLineHeight * .8; statusLabelsLH = .8 * statusLineHeight; - toolBarHeight = DEFAULT_CANVAS_WIDTH - statusBarHeight; toolBarTop = statusLineHeight * count + SPACE * 2; + toolBarHeight = DEFAULT_CANVAS_WIDTH - toolBarTop; + toolsBackground = 'transparent'; toolsHeight = BASE_LINEHEIGHT; borderRight = ''; @@ -2517,7 +2547,8 @@ control.prototype.resize = function(clientWidth, clientHeight) { borderTop: statusBarBorder, borderLeft: statusBarBorder, borderRight: borderRight, - fontSize: fontSize + unit + fontSize: fontSize + unit, + background: statusBackground, } }, { @@ -2547,7 +2578,8 @@ control.prototype.resize = function(clientWidth, clientHeight) { borderBottom: toolBarBorder, borderLeft: toolBarBorder, borderRight: borderRight, - fontSize: toolbarFontSize + unit + fontSize: toolbarFontSize + unit, + background: toolsBackground, } }, { diff --git a/libs/core.js b/libs/core.js index a1fe38db..525d3685 100644 --- a/libs/core.js +++ b/libs/core.js @@ -48,6 +48,8 @@ function core() { 'soundStatus': true, // 是否播放SE 'playingBgm': null, // 正在播放的BGM 'isPlaying': false, + 'gainNode': null, + 'volume': 1.0, // 音量 } this.platform = { 'isOnline': true, // 是否http @@ -187,6 +189,8 @@ core.prototype.init = function (coreData, callback) { window.AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.msAudioContext; try { core.musicStatus.audioContext = new window.AudioContext(); + core.musicStatus.gainNode = core.musicStatus.audioContext.createGain(); + core.musicStatus.gainNode.connect(core.musicStatus.audioContext.destination); } catch (e) { console.log("该浏览器不支持AudioContext"); core.musicStatus.audioContext = null; @@ -261,7 +265,8 @@ core.prototype.init = function (coreData, callback) { core.setRequestAnimationFrame(); core.showStartAnimate(); - core.events.initGame(); + if (main.mode=='play') + core.events.initGame(); if (core.isset(functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a.plugins)) core.plugin = new functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a.plugins.plugin(); @@ -928,6 +933,10 @@ core.prototype.saveReplay = function () { core.control.saveReplay(); } +core.prototype.bookReplay = function () { + core.control.bookReplay(); +} + ////// 回放 ////// core.prototype.replay = function () { core.control.replay(); @@ -1077,6 +1086,16 @@ core.prototype.subarray = function (a, b) { return core.utils.subarray(a, b); } +////// 生成随机数(seed方法) ////// +core.prototype.rand = function (num) { + return core.utils.rand(num); +} + +////// 生成随机数(录像方法) ////// +core.prototype.rand2 = function (num) { + return core.utils.rand2(num); +} + ////// 读取一个本地文件内容 ////// core.prototype.readFile = function (success, error, readType) { core.utils.readFile(success, error, readType); diff --git a/libs/enemys.js b/libs/enemys.js index e72ea82f..1b4158ff 100644 --- a/libs/enemys.js +++ b/libs/enemys.js @@ -33,8 +33,8 @@ enemys.prototype.hasSpecial = function (special, test) { ////// 获得所有特殊属性的名称 ////// enemys.prototype.getSpecialText = function (enemyId) { - if (enemyId == undefined) return ""; - var enemy = this.enemys[enemyId]; + var enemy = core.material.enemys[enemyId]; + if (!core.isset(enemy)) return []; var special = enemy.special; var text = []; if (this.hasSpecial(special, 1)) text.push("先攻"); diff --git a/libs/events.js b/libs/events.js index 43fdfd49..bf0866fe 100644 --- a/libs/events.js +++ b/libs/events.js @@ -57,8 +57,7 @@ events.prototype.init = function () { callback(); }, 'action': function (data, core, callback) { - core.events.doEvents(data.event.data, data.x, data.y); - if (core.isset(callback)) callback(); + core.events.insertAction(data.event.data, data.x, data.y, callback); } } } @@ -89,16 +88,19 @@ events.prototype.startGame = function (hard) { core.flags.battleAnimate = true; core.setLocalStorage('battleAnimate', true); core.startGame(hard); + core.utils.__init_seed(); core.events.setInitData(hard); }, function () { core.flags.battleAnimate = false; core.setLocalStorage('battleAnimate', false); core.startGame(hard); + core.utils.__init_seed(); core.events.setInitData(hard); }); } else { core.startGame(hard); + core.utils.__init_seed(); core.events.setInitData(hard); } }); @@ -142,6 +144,7 @@ events.prototype.gameOver = function (ending, fromReplay) { 'name': core.firstData.name, 'version': core.firstData.version, 'hard': core.status.hard, + 'seed': core.getFlag('seed'), 'route': core.encodeRoute(core.status.route) } core.download(core.firstData.name+"_"+core.formatDate2(new Date())+".h5route", JSON.stringify(obj)); @@ -163,7 +166,8 @@ events.prototype.gameOver = function (ending, fromReplay) { } var doUpload = function(username) { - if (username==null) username=""; + var hp = core.status.hero.hp; + if (username==undefined) hp = 1; // upload var formData = new FormData(); @@ -172,19 +176,23 @@ events.prototype.gameOver = function (ending, fromReplay) { formData.append('version', core.firstData.version); formData.append('platform', core.platform.isPC?"PC":core.platform.isAndroid?"Android":core.platform.isIOS?"iOS":""); formData.append('hard', core.status.hard); - formData.append('username', username); + formData.append('username', username||""); formData.append('ending', ending); formData.append('lv', core.status.hero.lv); - formData.append('hp', core.status.hero.hp); + formData.append('hp', hp); formData.append('atk', core.status.hero.atk); formData.append('def', core.status.hero.def); formData.append('mdef', core.status.hero.mdef); formData.append('money', core.status.hero.money); formData.append('experience', core.status.hero.experience); formData.append('steps', core.status.hero.steps); + formData.append('seed', core.getFlag('seed')); formData.append('route', core.encodeRoute(core.status.route)); - core.http("POST", "/games/upload.php", formData); + if (main.isCompetition) + core.http("POST", "/games/competition/upload.php", formData); + else + core.http("POST", "/games/upload.php", formData); setTimeout(function() { confirmDownload(); @@ -192,9 +200,17 @@ events.prototype.gameOver = function (ending, fromReplay) { } core.ui.drawConfirmBox("你想记录你的ID和成绩吗?", function () { - doUpload(prompt("请输入你的ID:")); + if (main.isCompetition) { + doUpload(""); + } + else { + doUpload(prompt("请输入你的ID:")); + } }, function () { - doUpload(""); + if (main.isCompetition) + confirmDownload(); + else + doUpload(undefined); }) return; @@ -206,7 +222,16 @@ events.prototype.gameOver = function (ending, fromReplay) { }); } else { - confirmUpload(); + + if (core.isset(core.values.maxValidHp) && core.status.hero.hp>core.values.maxValidHp) { + core.drawText("作弊可耻!", function () { + core.restart(); + }); + } + else { + confirmUpload(); + } + } } @@ -228,7 +253,9 @@ events.prototype.doEvents = function (list, x, y, callback) { core.waitHeroToStop(function() { core.lockControl(); core.status.event = {'id': 'action', 'data': { - 'list': core.clone(list), 'x': x, 'y': y, 'callback': callback + 'list': [ + {"todo": core.clone(list), "total": core.clone(list), "condition": "false"} + ], 'x': x, 'y': y, 'callback': callback }} core.events.doAction(); }); @@ -253,7 +280,18 @@ events.prototype.doAction = function() { return; } - var data = core.status.event.data.list.shift(); + var current = core.status.event.data.list[0]; + if (current.todo.length == 0) { // current list is empty + if (core.calValue(current.condition)) { // check condition + current.todo = core.clone(current.total); + } + else { + core.status.event.data.list.shift(); // remove stackc + } + this.doAction(); + return; + } + var data = current.todo.shift(); core.status.event.data.current = data; var x=core.status.event.data.x, y=core.status.event.data.y; @@ -311,8 +349,9 @@ events.prototype.doAction = function() { core.events.doAction(); break; case "show": // 显示 - if (typeof data.loc[0] == 'number' && typeof data.loc[1] == 'number') - data.loc = [data.loc]; + if ((typeof data.loc[0] == 'number' || typeof data.loc[0] == 'string') + && (typeof data.loc[1] == 'number' || typeof data.loc[1] == 'string')) + data.loc = [[core.calValue(data.loc[0]), core.calValue(data.loc[1])]]; if (core.isset(data.time) && data.time>0 && (!core.isset(data.floorId) || data.floorId==core.status.floorId)) { core.animateBlock(data.loc,'show', data.time, function () { data.loc.forEach(function (t) { @@ -331,8 +370,9 @@ events.prototype.doAction = function() { case "hide": // 消失 if (!core.isset(data.loc)) data.loc = [x,y]; - if (typeof data.loc[0] == 'number' && typeof data.loc[1] == 'number') - data.loc = [data.loc]; + if ((typeof data.loc[0] == 'number' || typeof data.loc[0] == 'string') + && (typeof data.loc[1] == 'number' || typeof data.loc[1] == 'string')) + data.loc = [[core.calValue(data.loc[0]), core.calValue(data.loc[1])]]; data.loc.forEach(function (t) { core.removeBlock(t[0],t[1],data.floorId); }) @@ -346,8 +386,8 @@ events.prototype.doAction = function() { case "setBlock": // 设置某图块 { if (core.isset(data.loc)) { - x=data.loc[0]; - y=data.loc[1]; + x=core.calValue(data.loc[0]); + y=core.calValue(data.loc[1]); } var floorId = data.floorId||core.status.floorId; var originBlock=core.getBlock(x,y,floorId,false); @@ -379,8 +419,8 @@ events.prototype.doAction = function() { y=core.getHeroLoc('y'); } else if (data.loc instanceof Array) { - x=data.loc[0]; - y=data.loc[1]; + x=core.calValue(data.loc[0]); + y=core.calValue(data.loc[1]); } } core.drawAnimate(data.name, x, y, function () { @@ -389,8 +429,8 @@ events.prototype.doAction = function() { break; case "move": // 移动事件 if (core.isset(data.loc)) { - x=data.loc[0]; - y=data.loc[1]; + x=core.calValue(data.loc[0]); + y=core.calValue(data.loc[1]); } core.moveBlock(x,y,data.steps,data.time,data.immediateHide,function() { core.events.doAction(); @@ -403,7 +443,7 @@ events.prototype.doAction = function() { break; case "changeFloor": // 楼层转换 { - var heroLoc = {"x": data.loc[0], "y": data.loc[1]}; + var heroLoc = {"x": core.calValue(data.loc[0]), "y": core.calValue(data.loc[1])}; if (core.isset(data.direction)) heroLoc.direction=data.direction; core.changeFloor(data.floorId||core.status.floorId, null, heroLoc, data.time, function() { core.lockControl(); @@ -414,8 +454,8 @@ events.prototype.doAction = function() { case "changePos": // 直接更换勇士位置,不切换楼层 core.clearMap('hero', 0, 0, 416, 416); if (core.isset(data.loc)) { - core.setHeroLoc('x', data.loc[0]); - core.setHeroLoc('y', data.loc[1]); + core.setHeroLoc('x', core.calValue(data.loc[0])); + core.setHeroLoc('y', core.calValue(data.loc[1])); } if (core.isset(data.direction)) core.setHeroLoc('direction', data.direction); core.drawHero(); @@ -423,7 +463,8 @@ events.prototype.doAction = function() { break; case "showImage": // 显示图片 if (core.isset(data.loc) && core.isset(core.material.images.images[data.name])) { - core.canvas.animate.drawImage(core.material.images.images[data.name], data.loc[0], data.loc[1]); + core.canvas.animate.drawImage(core.material.images.images[data.name], + core.calValue(data.loc[0]), core.calValue(data.loc[1])); } else core.clearMap('animate', 0, 0, 416, 416); this.doAction(); @@ -448,8 +489,8 @@ events.prototype.doAction = function() { var gif = new Image(); gif.src = core.material.images.images[data.name].src; gif.style.position = 'absolute'; - gif.style.left = (data.loc[0]*core.domStyle.scale)+"px"; - gif.style.top = (data.loc[1]*core.domStyle.scale)+"px"; + gif.style.left = (core.calValue(data.loc[0])*core.domStyle.scale)+"px"; + gif.style.top = (core.calValue(data.loc[1])*core.domStyle.scale)+"px"; core.dom.gif2.appendChild(gif); } else { @@ -457,6 +498,21 @@ events.prototype.doAction = function() { } this.doAction(); break; + case "moveImage": // 图片移动 + if (core.status.replay.replaying) { // 正在播放录像 + this.doAction(); + } + else { + if (core.isset(data.from) && core.isset(data.to) && core.isset(core.material.images.images[data.name])) { + core.events.moveImage(core.material.images.images[data.name], data.from, data.to, data.time, function() { + core.events.doAction(); + }); + } + else { + this.doAction(); + } + } + break; case "setFg": // 颜色渐变 core.setFg(data.color, data.time, function() { core.events.doAction(); @@ -469,7 +525,7 @@ events.prototype.doAction = function() { case "openDoor": // 开一个门,包括暗墙 { var floorId=data.floorId || core.status.floorId; - var block=core.getBlock(data.loc[0], data.loc[1], floorId); + var block=core.getBlock(core.calValue(data.loc[0]), core.calValue(data.loc[1]), floorId); if (block!=null) { if (floorId==core.status.floorId) core.openDoor(block.block.event.id, block.block.x, block.block.y, false, function() { @@ -504,13 +560,15 @@ events.prototype.doAction = function() { break; case "trigger": // 触发另一个事件;当前事件会被立刻结束。需要另一个地点的事件是有效的 { - var toX=data.loc[0], toY=data.loc[1]; + var toX=core.calValue(data.loc[0]), toY=core.calValue(data.loc[1]); var block=core.getBlock(toX, toY); if (block!=null) { block = block.block; if (core.isset(block.event) && block.event.trigger=='action') { // 触发 - core.status.event.data.list = core.clone(block.event.data); + core.status.event.data.list = [ + {"todo": core.clone(block.event.data), "total": core.clone(block.event.data), "condition": "false"} + ]; core.status.event.data.x=block.x; core.status.event.data.y=block.y; } @@ -535,6 +593,17 @@ events.prototype.doAction = function() { core.resumeBgm(); this.doAction(); break + case "setVolume": + data.value = parseInt(data.value||0); + if (data.value>100) data.value=100; + data.value = data.value / 100; + core.musicStatus.volume = data.value; + if (core.isset(core.musicStatus.playingBgm)) { + core.material.bgms[core.musicStatus.playingBgm].volume = data.value; + } + core.musicStatus.gainNode.gain.value = data.value; + this.doAction(); + break; case "setValue": try { var value=core.calValue(data.value); @@ -592,9 +661,9 @@ events.prototype.doAction = function() { core.drawTip("录像文件出错"); return; } - } else { + core.interval.onDownInterval = 'tmp'; value = prompt(core.replaceText(data.text)); } value = Math.abs(parseInt(value)||0); @@ -624,7 +693,7 @@ events.prototype.doAction = function() { core.status.route.push("choices:"+index); core.events.insertAction(data.choices[index].action); core.events.doAction(); - }, 750 / Math.sqrt(core.status.replay.speed)) + }, 750 / core.status.replay.speed) } else { core.stopReplay(); @@ -634,6 +703,27 @@ events.prototype.doAction = function() { } core.ui.drawChoices(data.text, data.choices); break; + case "while": + if (core.calValue(data.condition)) { + core.unshift(core.status.event.data.list, + {"todo": core.clone(data.data), "total": core.clone(data.data), "condition": data.condition} + ); + } + this.doAction(); + break; + case "break": + core.status.event.data.list.shift(); + this.doAction(); + break; + case "continue": + if (core.calValue(core.status.event.data.list[0].condition)) { + core.status.event.data.list[0].todo = core.clone(core.status.event.data.list[0].total); + } + else { + core.status.event.data.list.shift(); + } + this.doAction(); + break; case "win": core.events.win(data.reason, function () { core.events.doAction(); @@ -670,13 +760,19 @@ events.prototype.doAction = function() { }, data.time); } break; + case "wait": + if (core.status.replay.replaying) + core.events.doAction(); + break; case "revisit": // 立刻重新执行该事件 { var block=core.getBlock(x,y); // 重新获得事件 if (block!=null) { block = block.block; if (core.isset(block.event) && block.event.trigger=='action') { - core.status.event.data.list = core.clone(block.event.data); + core.status.event.data.list = [ + {"todo": core.clone(block.event.data), "total": core.clone(block.event.data), "condition": "false"} + ]; } } this.doAction(); @@ -699,7 +795,7 @@ events.prototype.insertAction = function (action, x, y, callback) { this.doEvents(action, x, y, callback); } else { - core.unshift(core.status.event.data.list, action) + core.unshift(core.status.event.data.list[0].todo, action) if (core.isset(x)) core.status.event.data.x=x; if (core.isset(y)) core.status.event.data.y=y; if (core.isset(callback)) core.status.event.data.callback=callback; @@ -1028,7 +1124,7 @@ events.prototype.animateImage = function (type, image, loc, time, callback) { if (type == 'hide') opacityVal = 1; core.setOpacity('data', opacityVal); - core.canvas.data.drawImage(image, loc[0], loc[1]); + core.canvas.data.drawImage(image, core.calValue(loc[0]), core.calValue(loc[1])); core.status.replay.animate=true; var animate = setInterval(function () { if (type=='show') opacityVal += 0.1; @@ -1041,7 +1137,38 @@ events.prototype.animateImage = function (type, image, loc, time, callback) { core.status.replay.animate=false; if (core.isset(callback)) callback(); } - }, time / 10 / core.status.replay.speed); + }, time / 10); +} + +////// 移动图片 ////// +events.prototype.moveImage = function (image, from, to, time, callback) { + time = time || 1000; + clearInterval(core.interval.tipAnimate); + core.setAlpha('data', 1); + core.setOpacity('data', 1); + + core.status.replay.animate=true; + var fromX = core.calValue(from[0]), fromY = core.calValue(from[1]), + toX = core.calValue(to[0]), toY = core.calValue(to[1]); + var step = 0; + var drawImage = function () { + core.clearMap('data', 0, 0, 416, 416); + var nowX = parseInt(fromX + (toX-fromX)*step/64); + var nowY = parseInt(fromY + (toY-fromY)*step/64); + core.canvas.data.drawImage(image, nowX, nowY); + } + + drawImage(); + var animate = setInterval(function () { + step++; + drawImage(); + if (step>=64) { + clearInterval(animate); + core.clearMap('data', 0, 0, 416, 416); + core.status.replay.animate=false; + if (core.isset(callback)) callback(); + } + }, time / 64); } ////// 打开一个全局商店 ////// @@ -1197,8 +1324,13 @@ events.prototype.passNet = function (data) { if (data.event.id=='weakNet') { // 衰网 if (core.hasFlag('weak')) return; core.setFlag('weak', true); - core.status.hero.atk-=core.values.weakValue; - core.status.hero.def-=core.values.weakValue; + var weakValue = core.status.weakValue; + var weakAtk = weakValue>=1?weakValue:Math.floor(weakValue*core.status.hero.atk); + var weakDef = weakValue>=1?weakValue:Math.floor(weakValue*core.status.hero.def); + core.setFlag('weakAtk', weakAtk); + core.setFlag('weakDef', weakDef); + core.status.hero.atk-=weakAtk; + core.status.hero.def-=weakDef; } if (data.event.id=='curseNet') { // 咒网 if (core.hasFlag('curse')) return; diff --git a/libs/items.js b/libs/items.js index 9f6d05b5..437c7ff4 100644 --- a/libs/items.js +++ b/libs/items.js @@ -32,9 +32,11 @@ items.prototype.getItemEffect = function(itemId, itemNum) { ////// “即捡即用类”道具的文字提示 ////// items.prototype.getItemEffectTip = function(itemId) { - var ratio = parseInt(core.floors[core.status.floorId].item_ratio) || 1; - if (itemId in this.itemEffectTip && (!this.items[itemId].isEquipment || !core.flags.equipment)) { - return eval(this.itemEffectTip[itemId]); + var itemCls = core.material.items[itemId].cls; + // 消耗品 + if (itemCls === 'items') { + var ratio = parseInt(core.floors[core.status.floorId].item_ratio) || 1; + if (itemId in this.itemEffectTip) return eval(this.itemEffectTip[itemId])||""; } return ""; } diff --git a/libs/ui.js b/libs/ui.js index 84ea2d28..b539d278 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -1513,7 +1513,7 @@ ui.prototype.drawToolbox = function(index) { if (core.isset(selectId)) { var item=core.material.items[selectId]; core.fillText('ui', item.name, 10, 32, '#FFD700', "bold 20px Verdana") - core.fillText('ui', item.text, 10, 62, '#FFFFFF', '17px Verdana'); + core.fillText('ui', item.text||"该道具暂无描述。", 10, 62, '#FFFFFF', '17px Verdana'); core.fillText('ui', '<继续点击该道具即可进行使用>', 10, 89, '#CCCCCC', '14px Verdana'); } @@ -1571,7 +1571,8 @@ ui.prototype.drawSLPanel = function(index) { if (index<0) index=0; var page = parseInt(index/10), offset=index%10; - if (page>=30) page=29; + var max_page = main.savePages || 30; + if (page>=max_page) page=max_page - 1; if (offset>5) offset=5; index=10*page+offset; @@ -1617,7 +1618,7 @@ ui.prototype.drawSLPanel = function(index) { } } } - this.drawPagination(page+1, 30); + this.drawPagination(page+1, max_page); if (core.status.event.selection) core.setFillStyle('ui', '#FF6A6A'); diff --git a/libs/utils.js b/libs/utils.js index 9d11609b..8ad8e03b 100644 --- a/libs/utils.js +++ b/libs/utils.js @@ -20,6 +20,12 @@ utils.prototype.replaceText = function (text) { ////// 计算表达式的值 ////// utils.prototype.calValue = function (value) { + if (typeof value == 'number') { + return value; + } + if (value instanceof Function) { + return value(); + } value=value.replace(/status:([\w\d_]+)/g, "core.getStatus('$1')"); value=value.replace(/item:([\w\d_]+)/g, "core.itemCount('$1')"); value=value.replace(/flag:([\w\d_]+)/g, "core.getFlag('$1', 0)"); @@ -164,9 +170,14 @@ utils.prototype.setTwoDigits = function (x) { } utils.prototype.formatBigNumber = function (x) { - x = parseFloat(x); + x = Math.floor(parseFloat(x)); if (!core.isset(x)) return '???'; + var c = x<0?"-":""; + x = Math.abs(x); + + if (x<=999999) return c + x; + var all = [ {"val": 1e20, "c": "g"}, {"val": 1e16, "c": "j"}, @@ -177,13 +188,13 @@ utils.prototype.formatBigNumber = function (x) { for (var i=0;i=100*one.val) { + if (x>=10*one.val) { var v = x/one.val; - return v.toFixed(Math.max(0, Math.floor(4-Math.log10(v+1)))) + one.c; + return c + v.toFixed(Math.max(0, Math.floor(4-Math.log10(v+1)))) + one.c; } } - return x; + return c+x; } ////// 数组转RGB ////// @@ -233,8 +244,10 @@ utils.prototype.encodeRoute = function (route) { ans+='N'; else if (t.indexOf('move:')==0) ans+="M"+t.substring(5); - else if (t=='key:') + else if (t.indexOf('key:')==0) ans+='K'+t.substring(4); + else if (t.indexOf('random:')==0) + ans+='X'+t.substring(7); } }); if (cnt>0) { @@ -287,6 +300,7 @@ utils.prototype.decodeRoute = function (route) { case "N": ans.push("no"); break; case "M": ++index; ans.push("move:"+nxt+":"+getNumber()); break; case "K": ans.push("key:"+nxt); break; + case "X": ans.push("random:"+nxt); break; } } return ans; @@ -311,6 +325,54 @@ utils.prototype.subarray = function (a, b) { return na; } +utils.prototype.__init_seed = function () { + var rand = new Date().getTime()%34834795 + 3534; + rand = this.__next_rand(rand); + rand = this.__next_rand(rand); + rand = this.__next_rand(rand); + core.setFlag('seed', rand); + core.setFlag('rand', rand); +} + +utils.prototype.__next_rand = function (_rand) { + _rand=(_rand%127773)*16807-~~(_rand/127773)*2836; + _rand+=_rand<0?2147483647:0; + return _rand; +} + +utils.prototype.rand = function (num) { + var rand = core.getFlag('rand'); + rand = this.__next_rand(rand); + core.setFlag('rand', rand); + var ans = rand/2147483647; + if (core.isset(num) && num>0) + return Math.floor(ans*num); + return ans; +} + +////// 生成随机数(录像方法) ////// +utils.prototype.rand2 = function (num) { + num = num||2147483648; + + var value; + if (core.status.replay.replaying) { + var action = core.status.replay.toReplay.shift(); + if (action.indexOf("random:")==0 ) { + value=parseInt(action.substring(7)); + } + else { + core.stopReplay(); + core.drawTip("录像文件出错"); + return; + } + } + else { + value = Math.floor(Math.random()*num); + } + core.status.route.push("random:"+value); + return value; +} + ////// 读取一个本地文件内容 ////// utils.prototype.readFile = function (success, error, readType) { diff --git a/main.js b/main.js index 6cd095c0..3dddfd0d 100644 --- a/main.js +++ b/main.js @@ -2,7 +2,7 @@ function main() { //------------------------ 用户修改内容 ------------------------// - this.version = "2.1.1"; // 游戏版本号;如果更改了游戏内容建议修改此version以免造成缓存问题。 + this.version = "2.2"; // 游戏版本号;如果更改了游戏内容建议修改此version以免造成缓存问题。 this.useCompress = false; // 是否使用压缩文件 // 当你即将发布你的塔时,请使用“JS代码压缩工具”将所有js代码进行压缩,然后将这里的useCompress改为true。 @@ -12,6 +12,10 @@ function main() { this.bgmRemote = false; // 是否采用远程BGM this.bgmRemoteRoot = "https://gitee.com/ckcz123/h5music/raw/master/"; // 远程BGM的根目录 + this.isCompetition = false; // 是否是比赛模式 + + this.savePages = 30; // 存档页数,每页可存5个;默认为30页150个存档 + //------------------------ 用户修改内容 END ------------------------// this.dom = { @@ -403,6 +407,12 @@ main.statusBar.image.toolbox.onclick = function () { ////// 点击状态栏中的快捷商店时 ////// main.statusBar.image.shop.onclick = function () { + + if (core.isset(core.status.replay) && core.status.replay.replaying) { + core.bookReplay(); + return; + } + if (main.core.isPlaying()) main.core.openQuickShop(true); } @@ -481,6 +491,8 @@ main.dom.replayGame.onclick = function () { core.dom.startPanel.style.display = 'none'; core.resetStatus(core.firstData.hero, obj.hard, core.firstData.floorId, null, core.initStatus.maps); core.events.setInitData(obj.hard); + core.setFlag('seed', obj.seed); + core.setFlag('rand', obj.seed); core.changeFloor(core.status.floorId, null, core.firstData.hero.loc, null, function() { core.startReplay(core.decodeRoute(obj.route)); }, true); diff --git a/project/data.js b/project/data.js index ac0361db..257d7b4f 100644 --- a/project/data.js +++ b/project/data.js @@ -19,11 +19,14 @@ data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "startBackground" : "bg.jpg", "startLogoStyle" : "color: black", "levelChoose" : [["简单","Easy"],["普通","Normal"],["困难","Hard"],["噩梦","Hell"]], + "statusLeftBackground": "url(project/images/ground.png) repeat", + "statusTopBackground": "url(project/images/ground.png) repeat", + "toolsBackground": "url(project/images/ground.png) repeat" }, "firstData" : { "title": "魔塔样板", "name": "template", - "version": "Ver 2.1.1", + "version": "Ver 2.2", "floorId": "sample0", "hero": { "name": "阳光", @@ -129,6 +132,7 @@ data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = 'counterAttack': 0.1, 'purify': 3, 'hatred': 2, + 'maxValidHp': null, 'animateSpeed': 300, }, diff --git a/project/functions.js b/project/functions.js index 0f33a232..975d9aab 100644 --- a/project/functions.js +++ b/project/functions.js @@ -14,19 +14,17 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = if (core.flags.bombFourDirections) core.material.items.bomb.text = "可以炸掉勇士四周的怪物"; if (core.flags.equipment) { - core.material.items.sword1 = {'cls': 'constants', 'name': '铁剑', 'text': '一把很普通的铁剑'}; - core.material.items.sword2 = {'cls': 'constants', 'name': '银剑', 'text': '一把很普通的银剑'}; - core.material.items.sword3 = {'cls': 'constants', 'name': '骑士剑', 'text': '一把很普通的骑士剑'}; - core.material.items.sword4 = {'cls': 'constants', 'name': '圣剑', 'text': '一把很普通的圣剑'}; - core.material.items.sword5 = {'cls': 'constants', 'name': '神圣剑', 'text': '一把很普通的神圣剑'}; - core.material.items.shield1 = {'cls': 'constants', 'name': '铁盾', 'text': '一个很普通的铁盾'}; - core.material.items.shield2 = {'cls': 'constants', 'name': '银盾', 'text': '一个很普通的银盾'}; - core.material.items.shield3 = {'cls': 'constants', 'name': '骑士盾', 'text': '一个很普通的骑士盾'}; - core.material.items.shield4 = {'cls': 'constants', 'name': '圣盾', 'text': '一个很普通的圣盾'}; - core.material.items.shield5 = {'cls': 'constants', 'name': '神圣盾', 'text': '一个很普通的神圣盾'}; + core.material.items.sword1.cls = 'constants'; + core.material.items.sword2.cls = 'constants'; + core.material.items.sword3.cls = 'constants'; + core.material.items.sword4.cls = 'constants'; + core.material.items.sword5.cls = 'constants'; + core.material.items.shield1.cls = 'constants'; + core.material.items.shield2.cls = 'constants'; + core.material.items.shield3.cls = 'constants'; + core.material.items.shield4.cls = 'constants'; + core.material.items.shield5.cls = 'constants'; } - - }, ////// 不同难度分别设置初始属性 ////// "setInitData":function (hard) { @@ -157,8 +155,13 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = // 衰弱 if (core.enemys.hasSpecial(special, 13) && !core.hasFlag('weak')) { core.setFlag('weak', true); - core.status.hero.atk-=core.values.weakValue; - core.status.hero.def-=core.values.weakValue; + var weakValue = core.status.weakValue; + var weakAtk = weakValue>=1?weakValue:Math.floor(weakValue*core.status.hero.atk); + var weakDef = weakValue>=1?weakValue:Math.floor(weakValue*core.status.hero.def); + core.setFlag('weakAtk', weakAtk); + core.setFlag('weakDef', weakDef); + core.status.hero.atk-=weakAtk; + core.status.hero.def-=weakDef; } // 诅咒 if (core.enemys.hasSpecial(special, 14) && !core.hasFlag('curse')) { @@ -343,59 +346,38 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = console.log("插件函数执行测试"); } + var _useEquipment = function (itemId, name, type) { + if (itemId.indexOf(name)==0) { + var now=core.getFlag(name, name+"0"); + + if (typeof core.values[now] == 'number') { + core.status.hero[type] -= core.values[now]; + } + else { + core.status.hero.atk -= core.values[now].atk || 0; + core.status.hero.def -= core.values[now].def || 0; + core.status.hero.mdef -= core.values[now].mdef || 0; + } + + if (typeof core.values[itemId] == 'number') { + core.status.hero[type] += core.values[itemId]; + } + else { + core.status.hero.atk += core.values[itemId].atk || 0; + core.status.hero.def += core.values[itemId].def || 0; + core.status.hero.mdef += core.values[itemId].mdef || 0; + } + + core.setItem(now, 1); + core.setItem(itemId, 0); + core.setFlag(name, itemId); + core.drawTip("已装备"+core.material.items[itemId].name); + } + } + this.useEquipment = function (itemId) { // 使用装备 - if (itemId.indexOf("sword")==0) { - var now=core.getFlag('sword', 'sword0'); // 当前装备剑的ID - - if (typeof core.values[now] == 'number') { - core.status.hero.atk -= core.values[now]; - } - else { - core.status.hero.atk -= core.values[now].atk || 0; - core.status.hero.def -= core.values[now].def || 0; - core.status.hero.mdef -= core.values[now].mdef || 0; - } - - if (typeof core.values[itemId] == 'number') { - core.status.hero.atk += core.values[itemId]; - } - else { - core.status.hero.atk += core.values[itemId].atk || 0; - core.status.hero.def += core.values[itemId].def || 0; - core.status.hero.mdef += core.values[itemId].mdef || 0; - } - - core.setItem(now, 1); - core.setItem(itemId, 0); - core.setFlag('sword', itemId); - core.drawTip("已装备"+core.material.items[itemId].name); - } - if (itemId.indexOf("shield")==0) { - var now=core.getFlag('shield', 'shield0'); - - if (typeof core.values[now] == 'number') { - core.status.hero.def -= core.values[now]; - } - else { - core.status.hero.atk -= core.values[now].atk || 0; - core.status.hero.def -= core.values[now].def || 0; - core.status.hero.mdef -= core.values[now].mdef || 0; - } - - if (typeof core.values[itemId] == 'number') { - core.status.hero.def += core.values[itemId]; - } - else { - core.status.hero.atk += core.values[itemId].atk || 0; - core.status.hero.def += core.values[itemId].def || 0; - core.status.hero.mdef += core.values[itemId].mdef || 0; - } - - core.setItem(now, 1); - core.setItem(itemId, 0); - core.setFlag('shield', itemId); - core.drawTip("已装备"+core.material.items[itemId].name); - } + _useEquipment(itemId, "sword", "atk"); + _useEquipment(itemId, "shield", "def"); } // 可以在任何地方(如afterXXX或自定义脚本事件)调用函数,方法为 core.plugin.xxx(); diff --git a/project/icons.js b/project/icons.js index cfc26a35..1d36e5e0 100644 --- a/project/icons.js +++ b/project/icons.js @@ -207,6 +207,7 @@ icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1 = 'bluePotion': 21, 'greenPotion': 22, 'yellowPotion': 23, + 'lifeWand': 33, 'sword0': 60, 'sword1': 50, 'sword2': 51, diff --git a/project/items.js b/project/items.js index 3a7660ce..5a2788fe 100644 --- a/project/items.js +++ b/project/items.js @@ -1,180 +1,341 @@ items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a = { - -"items" : { - // 钥匙 - 'yellowKey': {'cls': 'keys', 'name': '黄钥匙'}, - 'blueKey': {'cls': 'keys', 'name': '蓝钥匙'}, - 'redKey': {'cls': 'keys', 'name': '红钥匙'}, - - // 宝石、血瓶 - 'redJewel': {'cls': 'items', 'name': '红宝石'}, - 'blueJewel': {'cls': 'items', 'name': '蓝宝石'}, - 'greenJewel': {'cls': 'items', 'name': '绿宝石'}, - 'yellowJewel': {'cls': 'items', 'name': '黄宝石'}, - 'redPotion': {'cls': 'items', 'name': '红血瓶'}, - 'bluePotion': {'cls': 'items', 'name': '蓝血瓶'}, - 'yellowPotion': {'cls': 'items', 'name': '黄血瓶'}, - 'greenPotion': {'cls': 'items', 'name': '绿血瓶'}, - 'sword1': {'cls': 'items', 'name': '铁剑', 'isEquipment': true}, - 'sword2': {'cls': 'items', 'name': '银剑', 'isEquipment': true}, - 'sword3': {'cls': 'items', 'name': '骑士剑', 'isEquipment': true}, - 'sword4': {'cls': 'items', 'name': '圣剑', 'isEquipment': true}, - 'sword5': {'cls': 'items', 'name': '神圣剑', 'isEquipment': true}, - 'shield1': {'cls': 'items', 'name': '铁盾', 'isEquipment': true}, - 'shield2': {'cls': 'items', 'name': '银盾', 'isEquipment': true}, - 'shield3': {'cls': 'items', 'name': '骑士盾', 'isEquipment': true}, - 'shield4': {'cls': 'items', 'name': '圣盾', 'isEquipment': true}, - 'shield5': {'cls': 'items', 'name': '神圣盾', 'isEquipment': true}, - 'superPotion': {'cls': 'items', 'name': '圣水'}, - 'moneyPocket': {'cls': 'items', 'name': '金钱袋'}, - - // 物品 - 'sword0': {'cls': 'constants', 'name': '折断的剑', 'text': '没有任何作用的剑,相当于脱掉装备。'}, - 'shield0': {'cls': 'constants', 'name': '残破的盾', 'text': '没有任何作用的盾,相当于脱掉装备。'}, - 'book': {'cls': 'constants', 'name': '怪物手册', 'text': '可以查看当前楼层各怪物属性'}, - 'fly': {'cls': 'constants', 'name': '楼层传送器', 'text': '可以自由往来去过的楼层'}, - 'coin': {'cls': 'constants', 'name': '幸运金币', 'text': '持有时打败怪物可得双倍金币'}, - 'snow': {'cls': 'constants', 'name': '冰冻徽章', 'text': '可以将四周的熔岩变成平地'}, - 'cross': {'cls': 'constants', 'name': '十字架', 'text': '持有后无视怪物的无敌属性'}, - 'knife': {'cls': 'constants', 'name': '屠龙匕首', 'text': '该道具尚未被定义'}, - 'shoes': {'cls': 'constants', 'name': '绿鞋', 'text': '持有时无视负面地形'}, - - // 道具 - 'bigKey': {'cls': 'tools', 'name': '大黄门钥匙', 'text': '可以开启当前层所有黄门'}, - 'greenKey': {'cls': 'tools', 'name': '绿钥匙', 'text': '可以打开一扇绿门'}, - 'steelKey': {'cls': 'tools', 'name': '铁门钥匙', 'text': '可以打开一扇铁门'}, - 'pickaxe': {'cls': 'tools', 'name': '破墙镐', 'text': '可以破坏勇士面前的墙'}, - 'icePickaxe': {'cls': 'tools', 'name': '破冰镐', 'text': '可以破坏勇士面前的一堵冰墙'}, - 'bomb': {'cls': 'tools', 'name': '炸弹', 'text': '可以炸掉勇士面前的怪物'}, - 'centerFly': {'cls': 'tools', 'name': '中心对称飞行器', 'text': '可以飞向当前楼层中心对称的位置'}, - 'upFly': {'cls': 'tools', 'name': '上楼器', 'text': '可以飞往楼上的相同位置'}, - 'downFly': {'cls': 'tools', 'name': '下楼器', 'text': '可以飞往楼下的相同位置'}, - 'earthquake': {'cls': 'tools', 'name': '地震卷轴', 'text': '可以破坏当前层的所有墙'}, - 'poisonWine': {'cls': 'tools', 'name': '解毒药水', 'text': '可以解除中毒状态'}, - 'weakWine': {'cls': 'tools', 'name': '解衰药水', 'text': '可以解除衰弱状态'}, - 'curseWine': {'cls': 'tools', 'name': '解咒药水', 'text': '可以解除诅咒状态'}, - 'superWine': {'cls': 'tools', 'name': '万能药水', 'text': '可以解除所有不良状态'}, - 'hammer': {'cls': 'tools', 'name': '圣锤', 'text': '可以炸掉勇士面前的怪物'} -}, - - - - -"itemEffect" : { - "redJewel":"core.status.hero.atk += core.values.redJewel * ratio", - "blueJewel":"core.status.hero.def += core.values.blueJewel * ratio", - "greenJewel":"core.status.hero.mdef += core.values.greenJewel * ratio", - - "yellowJewel":"core.status.hero.hp+=1000;core.status.hero.atk+=6;core.status.hero.def+=6;core.status.hero.mdef+=10;", - // 黄宝石属性:需自己定义 - "redPotion":"core.status.hero.hp += core.values.redPotion * ratio", - "bluePotion":"core.status.hero.hp += core.values.bluePotion * ratio", - "yellowPotion":"core.status.hero.hp += core.values.yellowPotion * ratio", - "greenPotion":"core.status.hero.hp += core.values.greenPotion * ratio", - "sword1":"core.status.hero.atk += core.values.sword1", - "sword2":"core.status.hero.atk += core.values.sword2", - "sword3":"core.status.hero.atk += core.values.sword3", - "sword4":"core.status.hero.atk += core.values.sword4", - "sword5":"core.status.hero.atk += core.values.sword5", - "shield1":"core.status.hero.def += core.values.shield1", - "shield2":"core.status.hero.def += core.values.shield2", - "shield3":"core.status.hero.def += core.values.shield3", - "shield4":"core.status.hero.def += core.values.shield4", - "shield5":"core.status.hero.def += core.values.shield5", - - "bigKey":"core.status.hero.items.keys.yellowKey++;core.status.hero.items.keys.blueKey++;core.status.hero.items.keys.redKey++;", - // 只有是钥匙盒才会执行这一步 - "superPotion":"core.status.hero.hp *= 2", - "moneyPocket":"core.status.hero.money += core.values.moneyPocket", -}, - - -"itemEffectTip" : { - "redJewel":"',攻击+'+core.values.redJewel * ratio", - "blueJewel":"',防御+'+core.values.blueJewel * ratio", - "greenJewel":"',魔防+'+core.values.greenJewel * ratio", - "yellowJewel":"',全属性提升'", - "redPotion":"',生命+'+core.values.redPotion * ratio", - "bluePotion":"',生命+'+core.values.bluePotion * ratio", - "yellowPotion":"',生命+'+core.values.yellowPotion * ratio", - "greenPotion":"',生命+'+core.values.greenPotion * ratio", - "sword1":"',攻击+'+core.values.sword1", - "sword2":"',攻击+'+core.values.sword2", - "sword3":"',攻击+'+core.values.sword3", - "sword4":"',攻击+'+core.values.sword4", - "sword5":"',攻击+'+core.values.sword5", - "shield1":"',防御+'+core.values.shield1", - "shield2":"',防御+'+core.values.shield2", - "shield3":"',防御+'+core.values.shield3", - "shield4":"',防御+'+core.values.shield4", - "shield5":"',防御+'+core.values.shield5", - "bigKey":"',全钥匙+1'", - "superPotion":"',生命值翻倍'", - "moneyPocket":"',金币+'+core.values.moneyPocket", -}, - -"useItemEffect": { - "book": "core.ui.drawBook(0);", - "fly": "core.ui.drawFly(core.status.hero.flyRange.indexOf(core.status.floorId));", - "earthquake": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero();\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n});", - "pickaxe": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero();\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n});", - "icePickaxe": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero(), 'stop');\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n});", - "snow": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero();\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n});", - "bigKey": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero();\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n});", - "bomb": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero();\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n core.events.afterUseBomb();\n});", - "hammer": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero();\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n core.events.afterUseBomb();\n});", - "centerFly": "core.clearMap('hero', 0, 0, 416, 416);\ncore.setHeroLoc('x', core.status.event.data.x);\ncore.setHeroLoc('y', core.status.event.data.y);\ncore.drawHero();\ncore.drawTip(core.material.items[itemId].name + '使用成功');", - "upFly": "var loc = {'direction': core.status.hero.loc.direction, 'x': core.status.event.data.x, 'y': core.status.event.data.y};\ncore.changeFloor(core.status.event.data.id, null, loc, null, function (){\n core.drawTip(core.material.items[itemId].name + '使用成功');\n core.replay();\n});", - "downFly": "var loc = {'direction': core.status.hero.loc.direction, 'x': core.status.event.data.x, 'y': core.status.event.data.y};\ncore.changeFloor(core.status.event.data.id, null, loc, null, function (){\n core.drawTip(core.material.items[itemId].name + '使用成功');\n core.replay();\n});", - "poisonWine": "core.setFlag('poison', false);", - "weakWine": "core.setFlag('weak', false);\ncore.status.hero.atk += core.values.weakValue;\ncore.status.hero.def += core.values.weakValue;", - "curseWine": "core.setFlag('curse', false);", - "superWine": "core.setFlag('poison', false);\nif (core.hasFlag('weak')) {\n core.setFlag('weak', false);\n core.status.hero.atk += core.values.weakValue;\n core.status.hero.def += core.values.weakValue;\n}\ncore.setFlag('curse', false);", - "sword0": "core.plugin.useEquipment(itemId)", - "sword1": "core.plugin.useEquipment(itemId)", - "sword2": "core.plugin.useEquipment(itemId)", - "sword3": "core.plugin.useEquipment(itemId)", - "sword4": "core.plugin.useEquipment(itemId)", - "sword5": "core.plugin.useEquipment(itemId)", - "shield0": "core.plugin.useEquipment(itemId)", - "shield1": "core.plugin.useEquipment(itemId)", - "shield2": "core.plugin.useEquipment(itemId)", - "shield3": "core.plugin.useEquipment(itemId)", - "shield4": "core.plugin.useEquipment(itemId)", - "shield5": "core.plugin.useEquipment(itemId)", -}, - -"canUseItemEffect": { - "book": "true", - "fly": "core.status.hero.flyRange.indexOf(core.status.floorId)>=0", - "pickaxe": "var able=false;\nvar ids = [];\nfor (var i in core.status.thisMap.blocks) {\n var block = core.status.thisMap.blocks[i];\n if (core.isset(block.event) && !(core.isset(block.enable) && !block.enable) &&\n (block.event.id == 'yellowWall' || block.event.id=='whiteWall' || block.event.id=='blueWall')) // 能破哪些墙\n {\n // 四个方向\n if (core.flags.pickaxeFourDirections) {\n if (Math.abs(block.x-core.status.hero.loc.x)+Math.abs(block.y-core.status.hero.loc.y)<=1) {\n ids.push(i);\n }\n }\n else {\n if (block.x == core.nextX() && block.y == core.nextY()) {\n ids.push(i);\n }\n }\n }\n}\nif (ids.length>0) {\n core.status.event.data = ids;\n able=true;\n}\nable", - "icePickaxe": "var able=false;\nfor (var i in core.status.thisMap.blocks) {\n var block = core.status.thisMap.blocks[i];\n if (core.isset(block.event) && !(core.isset(block.enable) && !block.enable) && block.x==core.nextX() && block.y==core.nextY() && block.event.id=='ice') {\n core.status.event.data = [i];\n able=true;\n }\n}\nable", - "bomb": "var able=false;\nvar ids = [];\nfor (var i in core.status.thisMap.blocks) {\n var block = core.status.thisMap.blocks[i];\n if (core.isset(block.event) && !(core.isset(block.enable) && !block.enable) && block.event.cls.indexOf('enemy')==0 && Math.abs(block.x-core.status.hero.loc.x)+Math.abs(block.y-core.status.hero.loc.y)<=1) {\n var enemy = core.material.enemys[block.event.id];\n if ((core.isset(enemy.bomb) && !enemy.bomb) || (core.isset(enemy.notBomb) && enemy.notBomb)) continue;\n if (core.flags.bombFourDirections || (block.x==core.nextX() && block.y==core.nextY()))\n ids.push(i);\n }\n}\nif (ids.length>0) {\n core.status.event.data = ids;\n able=true;\n}\nable", - "hammer": "var able=false;\nfor (var i in core.status.thisMap.blocks) {\n var block = core.status.thisMap.blocks[i];\n if (core.isset(block.event) && !(core.isset(block.enable) && !block.enable) && block.event.cls.indexOf('enemy')==0 && block.x==core.nextX() && block.y==core.nextY()) {\n var enemy = core.material.enemys[block.event.id];\n ((core.isset(enemy.bomb) && !enemy.bomb) || (core.isset(enemy.notBomb) && enemy.notBomb)) continue;\n core.status.event.data = [i];\n able=true;\n }\n}\nable", - "earthquake": "var able=false;\nvar ids = [];\nfor (var i in core.status.thisMap.blocks) {\n var block = core.status.thisMap.blocks[i];\n if (core.isset(block.event) && !(core.isset(block.enable) && !block.enable) && (block.event.id == 'yellowWall' || block.event.id == 'blueWall' || block.event.id == 'whiteWall')) // 能炸的墙壁\n ids.push(i);\n}\nif (ids.length>0) {\n core.status.event.data = ids;\n able=true;\n}\nable", - "centerFly": "var able=false;\nvar toX = 12 - core.getHeroLoc('x'), toY = 12-core.getHeroLoc('y');\nvar block = core.getBlock(toX, toY);\nif (block==null) {\n core.status.event.data = {'x': toX, 'y': toY};\n able = true;\n}\nable", - "upFly": "var able=false;\nvar floorId = core.status.floorId, index = core.floorIds.indexOf(floorId);\nif (index0) {\n\tvar toId = core.floorIds[index-1], toX = core.getHeroLoc('x'), toY = core.getHeroLoc('y');\n\tif (core.getBlock(toX, toY, toId)==null) {\n\t\tcore.status.event.data = {'id': toId, 'x': toX, 'y': toY};\n\t\table=true;\n\t}\n}\nable", - "snow": "var able=false;\nvar ids = [];\nfor (var i in core.status.thisMap.blocks) {\n var block = core.status.thisMap.blocks[i];\n if (core.isset(block.event) && !(core.isset(block.enable) && !block.enable) && block.event.id == 'lava' && Math.abs(block.x-core.status.hero.loc.x)+Math.abs(block.y-core.status.hero.loc.y)<=1) {\n ids.push(i);\n }\n}\nif (ids.length>0) {\n core.status.event.data = ids;\n able=true;\n}\nable", - "bigKey": "var able=false;\nvar ids = [];\nfor (var i in core.status.thisMap.blocks) {\n var block = core.status.thisMap.blocks[i];\n if (core.isset(block.event) && !(core.isset(block.enable) && !block.enable) && block.event.id == 'yellowDoor') {\n ids.push(i);\n }\n}\nif (ids.length>0) {\n core.status.event.data = ids;\n able=true;\n}\nable", - "poisonWine": "core.hasFlag('poison')", - "weakWine": "core.hasFlag('weak')", - "curseWine": "core.hasFlag('curse')", - "superWine": "core.hasFlag('poison') || core.hasFlag('weak') || core.hasFlag('curse')", - "sword0": "true", - "sword1": "true", - "sword2": "true", - "sword3": "true", - "sword4": "true", - "sword5": "true", - "shield0": "true", - "shield1": "true", - "shield2": "true", - "shield3": "true", - "shield4": "true", - "shiled5": "true", - -} - + "items": { + "yellowKey": { + "cls": "keys", + "name": "黄钥匙" + }, + "blueKey": { + "cls": "keys", + "name": "蓝钥匙" + }, + "redKey": { + "cls": "keys", + "name": "红钥匙" + }, + "redJewel": { + "cls": "items", + "name": "红宝石" + }, + "blueJewel": { + "cls": "items", + "name": "蓝宝石" + }, + "greenJewel": { + "cls": "items", + "name": "绿宝石" + }, + "yellowJewel": { + "cls": "items", + "name": "黄宝石" + }, + "redPotion": { + "cls": "items", + "name": "红血瓶" + }, + "bluePotion": { + "cls": "items", + "name": "蓝血瓶" + }, + "yellowPotion": { + "cls": "items", + "name": "黄血瓶" + }, + "greenPotion": { + "cls": "items", + "name": "绿血瓶" + }, + "sword1": { + "cls": "items", + "name": "铁剑", + "text": "一把很普通的铁剑" + }, + "sword2": { + "cls": "items", + "name": "银剑", + "text": "一把很普通的银剑" + }, + "sword3": { + "cls": "items", + "name": "骑士剑", + "text": "一把很普通的骑士剑" + }, + "sword4": { + "cls": "items", + "name": "圣剑", + "text": "一把很普通的圣剑" + }, + "sword5": { + "cls": "items", + "name": "神圣剑", + "text": "一把很普通的神圣剑" + }, + "shield1": { + "cls": "items", + "name": "铁盾", + "text": "一个很普通的铁盾" + }, + "shield2": { + "cls": "items", + "name": "银盾", + "text": "一个很普通的银盾" + }, + "shield3": { + "cls": "items", + "name": "骑士盾", + "text": "一个很普通的骑士盾" + }, + "shield4": { + "cls": "items", + "name": "圣盾", + "text": "一个很普通的圣盾" + }, + "shield5": { + "cls": "items", + "name": "神圣盾", + "text": "一个很普通的神圣盾" + }, + "superPotion": { + "cls": "items", + "name": "圣水" + }, + "moneyPocket": { + "cls": "items", + "name": "金钱袋" + }, + "sword0": { + "cls": "constants", + "name": "折断的剑", + "text": "没有任何作用的剑,相当于脱掉装备。" + }, + "shield0": { + "cls": "constants", + "name": "残破的盾", + "text": "没有任何作用的盾,相当于脱掉装备。" + }, + "book": { + "cls": "constants", + "name": "怪物手册", + "text": "可以查看当前楼层各怪物属性" + }, + "fly": { + "cls": "constants", + "name": "楼层传送器", + "text": "可以自由往来去过的楼层" + }, + "coin": { + "cls": "constants", + "name": "幸运金币", + "text": "持有时打败怪物可得双倍金币" + }, + "snow": { + "cls": "constants", + "name": "冰冻徽章", + "text": "可以将四周的熔岩变成平地" + }, + "cross": { + "cls": "constants", + "name": "十字架", + "text": "持有后无视怪物的无敌属性" + }, + "knife": { + "cls": "constants", + "name": "屠龙匕首", + "text": "该道具尚未被定义" + }, + "shoes": { + "cls": "constants", + "name": "绿鞋", + "text": "持有时无视负面地形" + }, + "bigKey": { + "cls": "tools", + "name": "大黄门钥匙", + "text": "可以开启当前层所有黄门" + }, + "greenKey": { + "cls": "tools", + "name": "绿钥匙", + "text": "可以打开一扇绿门" + }, + "steelKey": { + "cls": "tools", + "name": "铁门钥匙", + "text": "可以打开一扇铁门" + }, + "pickaxe": { + "cls": "tools", + "name": "破墙镐", + "text": "可以破坏勇士面前的墙" + }, + "icePickaxe": { + "cls": "tools", + "name": "破冰镐", + "text": "可以破坏勇士面前的一堵冰墙" + }, + "bomb": { + "cls": "tools", + "name": "炸弹", + "text": "可以炸掉勇士面前的怪物" + }, + "centerFly": { + "cls": "tools", + "name": "中心对称飞行器", + "text": "可以飞向当前楼层中心对称的位置" + }, + "upFly": { + "cls": "tools", + "name": "上楼器", + "text": "可以飞往楼上的相同位置" + }, + "downFly": { + "cls": "tools", + "name": "下楼器", + "text": "可以飞往楼下的相同位置" + }, + "earthquake": { + "cls": "tools", + "name": "地震卷轴", + "text": "可以破坏当前层的所有墙" + }, + "poisonWine": { + "cls": "tools", + "name": "解毒药水", + "text": "可以解除中毒状态" + }, + "weakWine": { + "cls": "tools", + "name": "解衰药水", + "text": "可以解除衰弱状态" + }, + "curseWine": { + "cls": "tools", + "name": "解咒药水", + "text": "可以解除诅咒状态" + }, + "superWine": { + "cls": "tools", + "name": "万能药水", + "text": "可以解除所有不良状态" + }, + "hammer": { + "cls": "tools", + "name": "圣锤", + "text": "可以炸掉勇士面前的怪物" + }, + "lifeWand": { + "cls": "tools", + "name": "生命魔杖", + "text": "可以恢复100点生命值" + } + }, + "itemEffect": { + "redJewel": "core.status.hero.atk += core.values.redJewel * ratio", + "blueJewel": "core.status.hero.def += core.values.blueJewel * ratio", + "greenJewel": "core.status.hero.mdef += core.values.greenJewel * ratio", + "yellowJewel": "core.status.hero.hp+=1000;core.status.hero.atk+=6;core.status.hero.def+=6;core.status.hero.mdef+=10;", + "redPotion": "core.status.hero.hp += core.values.redPotion * ratio", + "bluePotion": "core.status.hero.hp += core.values.bluePotion * ratio", + "yellowPotion": "core.status.hero.hp += core.values.yellowPotion * ratio", + "greenPotion": "core.status.hero.hp += core.values.greenPotion * ratio", + "sword1": "core.status.hero.atk += core.values.sword1", + "sword2": "core.status.hero.atk += core.values.sword2", + "sword3": "core.status.hero.atk += core.values.sword3", + "sword4": "core.status.hero.atk += core.values.sword4", + "sword5": "core.status.hero.atk += core.values.sword5", + "shield1": "core.status.hero.def += core.values.shield1", + "shield2": "core.status.hero.def += core.values.shield2", + "shield3": "core.status.hero.def += core.values.shield3", + "shield4": "core.status.hero.def += core.values.shield4", + "shield5": "core.status.hero.def += core.values.shield5", + "bigKey": "core.status.hero.items.keys.yellowKey++;core.status.hero.items.keys.blueKey++;core.status.hero.items.keys.redKey++;", + "superPotion": "core.status.hero.hp *= 2", + "moneyPocket": "core.status.hero.money += core.values.moneyPocket" + }, + "itemEffectTip": { + "redJewel": "',攻击+'+core.values.redJewel * ratio", + "blueJewel": "',防御+'+core.values.blueJewel * ratio", + "greenJewel": "',魔防+'+core.values.greenJewel * ratio", + "yellowJewel": "',全属性提升'", + "redPotion": "',生命+'+core.values.redPotion * ratio", + "bluePotion": "',生命+'+core.values.bluePotion * ratio", + "yellowPotion": "',生命+'+core.values.yellowPotion * ratio", + "greenPotion": "',生命+'+core.values.greenPotion * ratio", + "sword1": "',攻击+'+core.values.sword1", + "sword2": "',攻击+'+core.values.sword2", + "sword3": "',攻击+'+core.values.sword3", + "sword4": "',攻击+'+core.values.sword4", + "sword5": "',攻击+'+core.values.sword5", + "shield1": "',防御+'+core.values.shield1", + "shield2": "',防御+'+core.values.shield2", + "shield3": "',防御+'+core.values.shield3", + "shield4": "',防御+'+core.values.shield4", + "shield5": "',防御+'+core.values.shield5", + "bigKey": "',全钥匙+1'", + "superPotion": "',生命值翻倍'", + "moneyPocket": "',金币+'+core.values.moneyPocket" + }, + "useItemEffect": { + "book": "core.ui.drawBook(0);", + "fly": "core.ui.drawFly(core.status.hero.flyRange.indexOf(core.status.floorId));", + "earthquake": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero();\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n});", + "pickaxe": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero();\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n});", + "icePickaxe": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero(), 'stop');\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n});", + "snow": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero();\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n});", + "bigKey": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero();\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n});", + "bomb": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero();\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n core.events.afterUseBomb();\n});", + "hammer": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero();\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n core.events.afterUseBomb();\n});", + "centerFly": "core.clearMap('hero', 0, 0, 416, 416);\ncore.setHeroLoc('x', core.status.event.data.x);\ncore.setHeroLoc('y', core.status.event.data.y);\ncore.drawHero();\ncore.drawTip(core.material.items[itemId].name + '使用成功');", + "upFly": "var loc = {'direction': core.status.hero.loc.direction, 'x': core.status.event.data.x, 'y': core.status.event.data.y};\ncore.changeFloor(core.status.event.data.id, null, loc, null, function (){\n core.drawTip(core.material.items[itemId].name + '使用成功');\n core.replay();\n});", + "downFly": "var loc = {'direction': core.status.hero.loc.direction, 'x': core.status.event.data.x, 'y': core.status.event.data.y};\ncore.changeFloor(core.status.event.data.id, null, loc, null, function (){\n core.drawTip(core.material.items[itemId].name + '使用成功');\n core.replay();\n});", + "poisonWine": "core.setFlag('poison', false);", + "weakWine": "core.setFlag('weak', false);\ncore.status.hero.atk += core.getFlag('weakAtk', core.values.weakValue);\ncore.status.hero.def += core.getFlag('weakDef', core.values.weakValue);", + "curseWine": "core.setFlag('curse', false);", + "superWine": "core.setFlag('poison', false);\nif (core.hasFlag('weak')) {\n core.setFlag('weak', false);\n core.status.hero.atk += core.getFlag('weakAtk', core.values.weakValue);\n core.status.hero.def += core.getFlag('weakDef', core.values.weakValue);\n}\ncore.setFlag('curse', false);", + "sword0": "core.plugin.useEquipment(itemId)", + "sword1": "core.plugin.useEquipment(itemId)", + "sword2": "core.plugin.useEquipment(itemId)", + "sword3": "core.plugin.useEquipment(itemId)", + "sword4": "core.plugin.useEquipment(itemId)", + "sword5": "core.plugin.useEquipment(itemId)", + "shield0": "core.plugin.useEquipment(itemId)", + "shield1": "core.plugin.useEquipment(itemId)", + "shield2": "core.plugin.useEquipment(itemId)", + "shield3": "core.plugin.useEquipment(itemId)", + "shield4": "core.plugin.useEquipment(itemId)", + "shield5": "core.plugin.useEquipment(itemId)", + "lifeWand": "core.insertAction([\n\t{\"type\": \"input\", \"text\": \"请输入生命魔杖使用次数:(0-${item:lifeWand})\"},\n\t{\"type\": \"if\", \"condition\": \"flag:input<=item:lifeWand\",\n\t\t\"true\": [\n\t\t\t{\"type\": \"setValue\", \"name\": \"item:lifeWand\", \"value\": \"item:lifeWand-flag:input\"},\n\t\t\t{\"type\": \"setValue\", \"name\": \"status:hp\", \"value\": \"status:hp+flag:input*100\"},\n\t\t\t\"成功使用${flag:input}次生命魔杖,恢复${flag:input*100}点生命。\"\n\t\t],\n\t\t\"false\": [\"输入不合法!\"]\n\t},\n]);\ncore.setItem('lifeWand', core.itemCount('lifeWand')+1);" + }, + "canUseItemEffect": { + "book": "true", + "fly": "core.status.hero.flyRange.indexOf(core.status.floorId)>=0", + "pickaxe": "var able=false;\nvar ids = [];\nfor (var i in core.status.thisMap.blocks) {\n var block = core.status.thisMap.blocks[i];\n if (core.isset(block.event) && !(core.isset(block.enable) && !block.enable) &&\n (block.event.id == 'yellowWall' || block.event.id=='whiteWall' || block.event.id=='blueWall')) // 能破哪些墙\n {\n // 四个方向\n if (core.flags.pickaxeFourDirections) {\n if (Math.abs(block.x-core.status.hero.loc.x)+Math.abs(block.y-core.status.hero.loc.y)<=1) {\n ids.push(i);\n }\n }\n else {\n if (block.x == core.nextX() && block.y == core.nextY()) {\n ids.push(i);\n }\n }\n }\n}\nif (ids.length>0) {\n core.status.event.data = ids;\n able=true;\n}\nable", + "icePickaxe": "var able=false;\nfor (var i in core.status.thisMap.blocks) {\n var block = core.status.thisMap.blocks[i];\n if (core.isset(block.event) && !(core.isset(block.enable) && !block.enable) && block.x==core.nextX() && block.y==core.nextY() && block.event.id=='ice') {\n core.status.event.data = [i];\n able=true;\n }\n}\nable", + "bomb": "var able=false;\nvar ids = [];\nfor (var i in core.status.thisMap.blocks) {\n var block = core.status.thisMap.blocks[i];\n if (core.isset(block.event) && !(core.isset(block.enable) && !block.enable) && block.event.cls.indexOf('enemy')==0 && Math.abs(block.x-core.status.hero.loc.x)+Math.abs(block.y-core.status.hero.loc.y)<=1) {\n var enemy = core.material.enemys[block.event.id];\n if ((core.isset(enemy.bomb) && !enemy.bomb) || (core.isset(enemy.notBomb) && enemy.notBomb)) continue;\n if (core.flags.bombFourDirections || (block.x==core.nextX() && block.y==core.nextY()))\n ids.push(i);\n }\n}\nif (ids.length>0) {\n core.status.event.data = ids;\n able=true;\n}\nable", + "hammer": "var able=false;\nfor (var i in core.status.thisMap.blocks) {\n var block = core.status.thisMap.blocks[i];\n if (core.isset(block.event) && !(core.isset(block.enable) && !block.enable) && block.event.cls.indexOf('enemy')==0 && block.x==core.nextX() && block.y==core.nextY()) {\n var enemy = core.material.enemys[block.event.id];\n ((core.isset(enemy.bomb) && !enemy.bomb) || (core.isset(enemy.notBomb) && enemy.notBomb)) continue;\n core.status.event.data = [i];\n able=true;\n }\n}\nable", + "earthquake": "var able=false;\nvar ids = [];\nfor (var i in core.status.thisMap.blocks) {\n var block = core.status.thisMap.blocks[i];\n if (core.isset(block.event) && !(core.isset(block.enable) && !block.enable) && (block.event.id == 'yellowWall' || block.event.id == 'blueWall' || block.event.id == 'whiteWall')) // 能炸的墙壁\n ids.push(i);\n}\nif (ids.length>0) {\n core.status.event.data = ids;\n able=true;\n}\nable", + "centerFly": "var able=false;\nvar toX = 12 - core.getHeroLoc('x'), toY = 12-core.getHeroLoc('y');\nvar block = core.getBlock(toX, toY);\nif (block==null) {\n core.status.event.data = {'x': toX, 'y': toY};\n able = true;\n}\nable", + "upFly": "var able=false;\nvar floorId = core.status.floorId, index = core.floorIds.indexOf(floorId);\nif (index0) {\n\tvar toId = core.floorIds[index-1], toX = core.getHeroLoc('x'), toY = core.getHeroLoc('y');\n\tif (core.getBlock(toX, toY, toId)==null) {\n\t\tcore.status.event.data = {'id': toId, 'x': toX, 'y': toY};\n\t\table=true;\n\t}\n}\nable", + "snow": "var able=false;\nvar ids = [];\nfor (var i in core.status.thisMap.blocks) {\n var block = core.status.thisMap.blocks[i];\n if (core.isset(block.event) && !(core.isset(block.enable) && !block.enable) && block.event.id == 'lava' && Math.abs(block.x-core.status.hero.loc.x)+Math.abs(block.y-core.status.hero.loc.y)<=1) {\n ids.push(i);\n }\n}\nif (ids.length>0) {\n core.status.event.data = ids;\n able=true;\n}\nable", + "bigKey": "var able=false;\nvar ids = [];\nfor (var i in core.status.thisMap.blocks) {\n var block = core.status.thisMap.blocks[i];\n if (core.isset(block.event) && !(core.isset(block.enable) && !block.enable) && block.event.id == 'yellowDoor') {\n ids.push(i);\n }\n}\nif (ids.length>0) {\n core.status.event.data = ids;\n able=true;\n}\nable", + "poisonWine": "core.hasFlag('poison')", + "weakWine": "core.hasFlag('weak')", + "curseWine": "core.hasFlag('curse')", + "superWine": "core.hasFlag('poison') || core.hasFlag('weak') || core.hasFlag('curse')", + "sword0": "true", + "sword1": "true", + "sword2": "true", + "sword3": "true", + "sword4": "true", + "sword5": "true", + "shield0": "true", + "shield1": "true", + "shield2": "true", + "shield3": "true", + "shield4": "true", + "shiled5": "true", + "shield5": "true", + "lifeWand": "true" + } } \ No newline at end of file diff --git a/project/maps.js b/project/maps.js index 07484df7..815c0ca9 100644 --- a/project/maps.js +++ b/project/maps.js @@ -76,6 +76,7 @@ maps_90f36752_8815_4be8_b32b_d7fad1d0542e = '63':{'cls': 'items', 'id': 'moneyPocket'}, // 金钱袋 '64':{'cls': 'items', 'id': 'shoes'}, // 绿鞋 '65':{'cls': 'items', 'id': 'hammer'}, // 圣锤 + '66':{'cls': 'items', 'id': 'lifeWand'}, // 生命魔杖 ////////////////////////// 门、楼梯、传送点部分 ////////////////////////// diff --git a/styles.css b/styles.css index 511f28c1..2021c874 100644 --- a/styles.css +++ b/styles.css @@ -106,7 +106,7 @@ background-color: #000; opacity: 0.85; display: none; - z-index: 220; + z-index: 260; bottom: 0; margin-bottom: 7%; } @@ -170,7 +170,7 @@ -moz-box-sizing: border-box; -webkit-box-sizing: border-box; background: url(project/images/ground.png) repeat; - z-index: 160; + z-index: 150; display: none; } #statusBar .status{ @@ -199,7 +199,7 @@ #toolBar { position: absolute; background: url(project/images/ground.png) repeat; - z-index: 150; + z-index: 160; box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; diff --git a/常用工具/便捷PS工具.exe b/常用工具/便捷PS工具.exe index 605b18a2..78a9c25e 100644 Binary files a/常用工具/便捷PS工具.exe and b/常用工具/便捷PS工具.exe differ diff --git a/更新说明.txt b/更新说明.txt index a2ed95eb..ee9e4b6b 100644 --- a/更新说明.txt +++ b/更新说明.txt @@ -1,4 +1,25 @@ -HTML5魔塔样板V2.1.1 +HTML5魔塔样板V2.2 + +事件坐标可用变量指定("loc": ["flag:x", "flag:y"]) +全局商店也可以使用图块编辑 +高亮显示有事件的格子 +对于道具和怪物自动注册该列所有未注册的素材 +便捷PS工具对于白底图片可自动调整为透明背景 +事件:等待用户点击(type:wait) +事件:图片移动事件(type:moveImage) +事件:设置BGM音量(type:setVolume) +提供core.rand()和core.rand2()两个随机数函数 +作弊处理(最大有效生命值、匿名则最低成绩上传) +自定义状态栏绘制 +最高六倍速播放 +播放录像时可以C键查看怪物手册 +修复标题文字太长导致无法开始游戏的问题 +新增纯新手简易造塔流程 +部分效果和性能的优化 + +----------------------------------------------------------------------- + +HTML5魔塔样板V2.1.1 新增事件:改变勇士行走图 楼传器落点设置