diff --git a/README.md b/README.md index 406abacc..45bf5d2f 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,22 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏! ## 更新说明 +### 2018.11.21 V2.5.1 + +* [x] 新增事件type:insert,可以插入另一个地点的事件执行(公共事件) +* [x] 可以使用\v来控制剧情文本部分文字的颜色 +* [x] 新增事件type:switch,多重分歧 +* [x] 绘制前景/背景层时淡化其他图层 +* [x] 追加素材的自动调整(如白底、不规范的素材) +* [x] 浏览地图时:左上角/V开启显伤;右上角/Z查看当前层大地图 +* [x] 允许在受到领域夹击等伤害后禁用快捷商店 +* [x] 升级的扣除模式,即不显示经验值,只显示升级的所需剩余值 +* [x] 装备增加可装备条件判定 +* [x] 选项界面可以使用1-9快速选择 +* [x] 未开启状态的快捷商店用灰色显示 +* [x] 修复不能在背景/前景层绘图的Bug +* [x] 部分其他细节优化 + ### 2018.10.31 V2.5 * [x] 添加绘图模式支持;可以用户手动绘图和保存 diff --git a/_server/blockly/MotaAction.g4 b/_server/blockly/MotaAction.g4 index 2a3d6ddd..92c52eb2 100644 --- a/_server/blockly/MotaAction.g4 +++ b/_server/blockly/MotaAction.g4 @@ -192,6 +192,7 @@ action | show_s | hide_s | trigger_s + | insert_s | revisit_s | exit_s | setBlock_s @@ -481,6 +482,20 @@ var code = '{"type": "trigger", "loc": ['+PosString_0+','+PosString_1+']},\n'; return code; */; +insert_s + : '插入事件' 'x' PosString ',' 'y' PosString '楼层' IdString? Newline + + +/* insert_s +tooltip : insert: 立即插入另一个地点的事件执行,当前事件不会中断,事件坐标不会改变 +helpUrl : https://ckcz123.github.io/mota-js/#/event?id=insert%ef%bc%9a%e6%8f%92%e5%85%a5%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",""] +colour : this.eventColor +IdString_0 = IdString_0 && (', "floorId": "'+IdString_0+'"'); +var code = '{"type": "insert", "loc": ['+PosString_0+','+PosString_1+']'+IdString_0+'},\n'; +return code; +*/; + revisit_s : '重启当前事件' Newline @@ -1966,6 +1981,10 @@ ActionParser.prototype.parseAction = function() { this.next = MotaActionBlocks['trigger_s'].xmlText([ data.loc[0],data.loc[1],this.next]); break; + case "insert": // 强制插入另一个点的事件在当前事件列表执行,当前坐标和楼层不会改变 + this.next = MotaActionBlocks['insert_s'].xmlText([ + data.loc[0],data.loc[1],data.floorId||'',this.next]); + break; case "playSound": this.next = MotaActionBlocks['playSound_s'].xmlText([ data.name,this.next]); diff --git a/_server/comment.js b/_server/comment.js index 0cfcfce0..7477667b 100644 --- a/_server/comment.js +++ b/_server/comment.js @@ -49,28 +49,35 @@ comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "_type": "textarea", "_string": true, "_lint": true, - "_data": "cls为items的即捡即用类物品的效果。" + "_data": "即捡即用类物品的效果,仅对cls为items有效。" }, "itemEffectTip": { "_leaf": true, "_type": "textarea", "_string": true, "_lint": true, - "_data": "cls为items的即捡即用类物品,在获得时左上角额外显示的文字。" + "_data": "即捡即用类物品在获得时提示的文字,仅对cls为items有效。" }, "useItemEffect": { "_leaf": true, "_type": "textarea", "_string": true, "_lint": true, - "_data": "cls为tools或constants时的使用物品效果。" + "_data": "道具效果,仅对cls为tools或constants有效。" }, "canUseItemEffect": { "_leaf": true, "_type": "textarea", "_string": true, "_lint": true, - "_data": "cls为tools或constants时对当前能否使用该物品的判断。" + "_data": "当前能否使用该道具,仅对cls为tools或constants有效。" + }, + "canEquip":{ + "_leaf": true, + "_type": "textarea", + "_string": true, + "_lint": true, + "_data": "当前能否装备某个装备,仅对cls为equips有效。\n与canUseItemEffect不同,这里null代表可以装备。" } } }, @@ -119,54 +126,54 @@ comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "_leaf": true, "_type": "textarea", "_range": "thiseval==null || thiseval instanceof Array || (thiseval==~~thiseval && thiseval>=0)", - "_data": "特殊属性\n\n0:无,1:先攻,2:魔攻,3:坚固,4:2连击,\n5:3连击,6:n连击,7:破甲,8:反击,9:净化,\n10:模仿,11:吸血,12:中毒,13:衰弱,14:诅咒,\n15:领域,16:夹击,17:仇恨,18:阻击,19:自爆,\n20:无敌,21:退化,22:固伤,23:重生,24:激光\n\n多个属性例如用[1,4,11]表示先攻2连击吸血\n模仿怪的攻防设为0就好" + "_data": "特殊属性\n\n0:无,1:先攻,2:魔攻,3:坚固,4:2连击,\n5:3连击,6:n连击,7:破甲,8:反击,9:净化,\n10:模仿,11:吸血,12:中毒,13:衰弱,14:诅咒,\n15:领域,16:夹击,17:仇恨,18:阻击,19:自爆,\n20:无敌,21:退化,22:固伤,23:重生,24:激光,25:光环\n\n多个属性例如用[1,4,11]表示先攻2连击吸血" }, "value": { "_leaf": true, "_type": "textarea", - "_data": "特殊属性的数值\n领域怪需要加value表示领域伤害的数值\n吸血怪需要在后面添加value代表吸血比例" + "_data": "特殊属性的数值\n如:领域/阻激/激光怪的伤害值;吸血怪的吸血比例;光环怪增加生命的比例" }, "zoneSquare": { "_leaf": true, "_type": "checkbox", "_bool": "bool", - "_data": "领域怪zoneSquare代表是否九宫格伤害" + "_data": "领域怪是否九宫格伤害" }, "range": { "_leaf": true, "_type": "textarea", "_range": "(thiseval==~~thiseval && thiseval>0)||thiseval==null", - "_data": "range可选,代表领域伤害的范围;不加默认为1" + "_data": "领域伤害的范围;不加默认为1" }, "notBomb": { "_leaf": true, "_type": "checkbox", "_bool": "bool", - "_data": "加入 \"notBomb\": true 代表该怪物不可被炸弹或圣锤炸掉" + "_data": "该怪物不可被炸" }, "n": { "_leaf": true, "_type": "textarea", "_range": "(thiseval==~~thiseval && thiseval>0)||thiseval==null", - "_data": "多连击需要在后面指定n代表是几连击" + "_data": "多连击的连击数" }, "add": { "_leaf": true, "_type": "checkbox", "_bool": "bool", - "_data": "代表吸血后是否加到自身" + "_data": "吸血后是否加到自身;光环是否叠加" }, "atkValue": { "_leaf": true, "_type": "textarea", "_range": "thiseval==~~thiseval||thiseval==null", - "_data": "退化时勇士下降的攻击力点数" + "_data": "退化时勇士下降的攻击力点数;光环怪增加攻击的比例" }, "defValue": { "_leaf": true, "_type": "textarea", "_range": "thiseval==~~thiseval||thiseval==null", - "_data": "退化时勇士下降的防御力点数" + "_data": "退化时勇士下降的防御力点数;光环怪增加防御的比例" }, "damage": { "_leaf": true, diff --git a/_server/editor.js b/_server/editor.js index 63ca9f47..ae74991b 100644 --- a/_server/editor.js +++ b/_server/editor.js @@ -1079,19 +1079,33 @@ editor.prototype.listen = function () { editor.brushMod=brushMod3.value; } + var bgc = document.getElementById('bg'), fgc = document.getElementById('fg'), + evc = document.getElementById('event'), ev2c = document.getElementById('event2'); + var layerMod=document.getElementById('layerMod'); layerMod.onchange=function(){ editor.layerMod=layerMod.value; + [bgc,fgc,evc,ev2c].forEach(function (x) { + x.style.opacity = 1; + }); } var layerMod2=document.getElementById('layerMod2'); if(layerMod2)layerMod2.onchange=function(){ editor.layerMod=layerMod2.value; + [fgc,evc,ev2c].forEach(function (x) { + x.style.opacity = 0.3; + }); + bgc.style.opacity = 1; } var layerMod3=document.getElementById('layerMod3'); if(layerMod3)layerMod3.onchange=function(){ editor.layerMod=layerMod3.value; + [bgc,evc,ev2c].forEach(function (x) { + x.style.opacity = 0.3; + }); + fgc.style.opacity = 1; } var viewportButtons=document.getElementById('viewportButtons'); diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index 0951f47d..8a982f88 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -108,10 +108,10 @@ editor_blockly = function () { ], '事件控制':[ MotaActionBlocks['if_s'].xmlText(), - MotaActionFunctions.actionParser.parseList({"type": "switch", "condition": "判别量", "caseList": [ + MotaActionFunctions.actionParser.parseList({"type": "switch", "condition": "判别值", "caseList": [ {"action": [{"type": "comment", "text": "当判别值是值的场合执行此事件"}]}, {"action": []}, - {"case": "default", "action": [{"type": "comment", "text": "当没有符合的值的场合执行此事件"}]}, + {"case": "default", "action": [{"type": "comment", "text": "当没有符合的值的场合执行default事件"}]}, ]}), MotaActionBlocks['while_s'].xmlText(), MotaActionBlocks['break_s'].xmlText(), @@ -126,6 +126,7 @@ editor_blockly = function () { MotaActionBlocks['hideBgFgMap_s'].xmlText(), MotaActionBlocks['setBgFgBlock_s'].xmlText(), MotaActionBlocks['trigger_s'].xmlText(), + MotaActionBlocks['insert_s'].xmlText(), MotaActionBlocks['move_s'].xmlText(), MotaActionBlocks['jump_s'].xmlText(), MotaActionBlocks['disableShop_s'].xmlText(), diff --git a/_server/editor_mode.js b/_server/editor_mode.js index cc0022cc..15e40174 100644 --- a/_server/editor_mode.js +++ b/_server/editor_mode.js @@ -556,6 +556,90 @@ editor_mode = function (editor) { } selectAppend.onchange(); + var getPixel=function(imgData, x, y) { + var offset = (x + y * imgData.width) * 4; + var r = imgData.data[offset+0]; + var g = imgData.data[offset+1]; + var b = imgData.data[offset+2]; + var a = imgData.data[offset+3]; + return [r,g,b,a]; + } + var setPixel=function(imgData, x, y, rgba) { + var offset = (x + y * imgData.width) * 4; + imgData.data[offset+0]=rgba[0]; + imgData.data[offset+1]=rgba[1]; + imgData.data[offset+2]=rgba[2]; + imgData.data[offset+3]=rgba[3]; + } + + var autoAdjust = function (image, callback) { + var changed = false; + + // Step 1: 检测白底 + var tempCanvas = document.createElement('canvas').getContext('2d'); + tempCanvas.canvas.width = image.width; + tempCanvas.canvas.height = image.height; + tempCanvas.mozImageSmoothingEnabled = false; + tempCanvas.webkitImageSmoothingEnabled = false; + tempCanvas.msImageSmoothingEnabled = false; + tempCanvas.imageSmoothingEnabled = false; + tempCanvas.drawImage(image, 0, 0); + var imgData = tempCanvas.getImageData(0, 0, image.width, image.height); + var trans = 0, white = 0; + for (var i=0;itrans*10 && confirm("看起来这张图片是以白色为底色,是否自动调整为透明底色?")) { + for (var i=0;i 目前版本**v2.5**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.5.1**,上次更新时间:* {docsify-updated} * 目前样板已经更新到V2.0版本以上,本章将对V2.0的一些内容进行介绍。 diff --git a/docs/api.md b/docs/api.md index 03a5d666..17d3b1df 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1,6 +1,6 @@ # 附录: API列表 -?> 目前版本**v2.5**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.5.1**,上次更新时间:* {docsify-updated} * **这里只列出所有可能会被造塔者用到的常用API,更多的有关内容请在代码内进行查询。** diff --git a/docs/element.md b/docs/element.md index 087937c0..0d82b609 100644 --- a/docs/element.md +++ b/docs/element.md @@ -1,6 +1,6 @@ # 元件说明 -?> 目前版本**v2.5**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.5.1**,上次更新时间:* {docsify-updated} * 在本章中,将对样板里的各个元件进行说明。各个元件主要包括道具、门、怪物、楼梯等等。 @@ -262,6 +262,17 @@ floorId指定的是目标楼层的唯一标识符(ID)。 **从2.1.1开始,楼层属性中提供了`upFloor`和`downFloor`两项。如果设置此项(比如`"upFloor": [2,3]`),则写stair:upFloor或者楼传器的落点将用此点来替换楼梯位置(即类似于RM中的上箭头)。** +## 剧情文本控制 + +在写剧情文本时,可以: + +- 使用`\t[...]`来给文字加上标题和图标。如`\t[老人,man]`。 +- 使用`\b[...]`来制作对话框效果,如`\b[up,3,2]`。 +- 使用`\v[...]`来动态修改局部文本的颜色,如`\v[red]`。 +- 使用`${}`来计算一个表达式的值,如`${status:atk+status:def}`。 + +详细信息请参见[剧情文本控制](event#text:显示一段文字(剧情))中的说明。 + ## 大地图 从V2.4开始,H5魔塔开始支持大地图。 diff --git a/docs/event.md b/docs/event.md index 979f00ab..e0d25940 100644 --- a/docs/event.md +++ b/docs/event.md @@ -1,6 +1,6 @@ # 事件 -?> 目前版本**v2.5**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.5.1**,上次更新时间:* {docsify-updated} * 本章内将对样板所支持的事件进行介绍。 @@ -237,6 +237,15 @@ !> `\t[...]`必须在`\b[...]`前面!不然两者都无法正常显示。 +还可以使用`\v[...]`来调整剧情文本的颜色。 + +``` js +"x,y": [ // 实际执行的事件列表 + "这句话是默认颜色,\v[red]将颜色变成红色,\v[blue]将颜色变成蓝色", + "\v[#FF00FF]还可以使用RGB值来控制颜色,\v如果不加中括号则回到默认颜色", + "\t[hero]\b[up,hero]啊啊啊,别过来,\v[red]别过来!!!\n\v你到底是什么东西!" +] +``` 另外值得一提的是,我们是可以在文字中计算一个表达式的值的。只需要将表达式用 `${ }`整个括起来就可以。 @@ -468,6 +477,32 @@ NPC对话事件结束后如果需要NPC消失也需要调用 `{"type": "hide"}` 例如上面这个例子,下面的文字将不会再被显示,而是直接跳转到`"3,6"`对应的事件列表从头执行。 +### insert:插入另一个地点的事件 + +`{"type":"insert"}` 会插入另一个地点的事件执行。 + +其基本写法如下: + +``` js +"x,y": [ // 实际执行的事件列表 + {"type": "insert", "loc": [3,6]}, // 插入[3,6]点的事件并执行 + {"type": "insert", "loc": [10,10], "floorId": "MT1"}, // 插入MT1层[10,10]点的事件并执行 + "上面的插入事件执行完毕后会接着继续执行后面的事件" +] +``` + +loc是必须的,代表另一个地点的坐标。 + +floorId可选,代表另一个地点所在的楼层;如果不写则默认为当前层。 + +和`type:trigger`不同的是,**`type:trigger`是立刻将当前事件结束(剩下所有内容都忽略),然后重新启动另一个地点的action事件。** + +但是`type:insert`不会结束当前事件,而是直接将另一个地点的事件列表“插入”到当前事件列表中执行。 + +**这个过程中,当前事件不会被结束,当前的楼层和事件坐标不会发生改变。** 插入的事件执行完毕后,会继续执行接下来的内容。 + +我们某个事件写在某个角落的墙上然后远程调用,从而达到“公共事件”的效果。 + ### revisit:立即重启当前事件 revisit和trigger完全相同,只不过是立刻触发的还是本地点的事件 @@ -1215,11 +1250,11 @@ text为提示文字,可以在这里给输入提示文字。这里同样可以 ] ``` -我们可以在condition中给出一个表达式(能将`status:xxx, item:xxx, flag:xxx`来作为参数),并计算它的值 +我们可以在condition中给出一个表达式(能将`status:xxx`, `item:xxx`, `flag:xxx`来作为参数),并计算它的值 如果某条件中的值与其相等,则将执行其对应的列表事件内容。 -如果没有符合的值,则将执行`"default"`中的列表事件内容。 +如果没有符合的值,则将执行`default`中的列表事件内容。 例如下面这个例子,将检查当前游戏难度并赠送不同属性。 @@ -1248,7 +1283,7 @@ text为提示文字,可以在这里给输入提示文字。这里同样可以 需要额外注意的几点: - 各个条件分支的判断是顺序执行的,因此若多个分支的条件都满足,将只执行最靠前的分支,同理,请不要在`"default"`分支后添加分支,这些分支将不可能被执行。 --`"default"`分支并不是必要的,如果删除,则在没有满足条件的分支时将不执行任何事件。 +- `default`分支并不是必要的,如果删除,则在没有满足条件的分支时将不执行任何事件。 - 即使某个场合不执行事件,对应的action数组也需要存在,不过简单的留空就好。 - switch可以不断进行嵌套,一层套一层;如某条件成立的场合再进行另一个switch判断等。 - switch语句内的内容执行完毕后将接着其后面的语句继续执行。 diff --git a/docs/index.md b/docs/index.md index 842078dd..492288f6 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,6 +1,6 @@ # HTML5 魔塔样板说明文档 -?> 目前版本**v2.5**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.5.1**,上次更新时间:* {docsify-updated} * 众所周知,魔塔的趋势是向移动端发展,贴吧中也常常能见到“求手机魔塔”的帖子。然而现有的工具中,NekoRPG有着比较大的局限性,游戏感较差,更是完全没法在iOS上运行。而一些APP的魔塔虽然可用,但是必须要下载安装,对于Android和iOS还必须开发不同的版本,非常麻烦。 diff --git a/docs/personalization.md b/docs/personalization.md index 612f3d46..2fbf4cd4 100644 --- a/docs/personalization.md +++ b/docs/personalization.md @@ -1,6 +1,6 @@ # 个性化 -?> 目前版本**v2.5**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.5.1**,上次更新时间:* {docsify-updated} * 有时候只靠样板本身可能是不够的。我们需要一些个性化、自定义的素材,道具效果,怪物属性,等等。 @@ -521,6 +521,15 @@ case 89: // 使用该按键的keyCode,比如Y键就是89 ## 公共事件 +从2.5.1开始,H5提供了`{"type":"insert"}`事件,完美支持了公共事件的写法。 + +我们只需要将需要的公共事件放在某个角落的墙上(或者甚至单独弄一层专门摆放公共事件),并使用“插入事件”,即可进行调用。 + +具体详见[插入另一个地点的事件](event#insert:插入另一个地点的事件)。 + +当然,继续使用**插件**的写法也是可以的。具体参见“脚本编辑 - 插件编写”。 + + ## 自定义状态栏(新增显示项) 在V2.2以后,我们可以自定义状态栏背景图(全塔属性 - statusLeftBackground)等等。 diff --git a/docs/start.md b/docs/start.md index ac2bc064..ec55095d 100644 --- a/docs/start.md +++ b/docs/start.md @@ -1,6 +1,6 @@ # 快速上手 -?> 目前版本**v2.5**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.5.1**,上次更新时间:* {docsify-updated} * 在这一节中,将详细介绍做一部塔的流程。现在,让我们来做一部单层塔! diff --git a/libs/actions.js b/libs/actions.js index d43972f8..94ad235e 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -767,6 +767,12 @@ actions.prototype.clickAction = function (x,y) { ////// 自定义事件时,按下某个键的操作 ////// actions.prototype.keyDownAction = function (keycode) { + // 视为无效 + var startTime = core.status.event.data.startTime||0; + if (startTime>0 && new Date().getTime()-startTime<250) + return; + core.status.event.data.startTime = 0; + if (core.status.event.data.type=='choices') { var data = core.status.event.data.current; var choices = data.choices; @@ -809,6 +815,15 @@ actions.prototype.keyUpAction = function (keycode) { core.insertAction(choices[core.status.event.selection].action); core.doAction(); } + // 数字键快速选择 + if (keycode>=49 && keycode<=57) { + var index = keycode-49; + if (index=2 && x<=10 && y<=1 && mh>13) { core.ui.drawMaps(index, cx, cy-1); @@ -1002,6 +1027,11 @@ actions.prototype.keyUpViewMaps = function (keycode) { core.ui.drawMaps(core.status.event.data); return; } + if (keycode==90) { + core.status.event.data.all = !core.status.event.data.all; + core.ui.drawMaps(core.status.event.data); + return; + } if (keycode==77) { core.status.event.data.paint = !core.status.event.data.paint; core.ui.drawMaps(core.status.event.data); @@ -1122,6 +1152,14 @@ actions.prototype.keyUpShop = function (keycode) { var topIndex = 6 - parseInt(choices.length / 2); this.clickShop(6, topIndex+core.status.event.selection); } + // 数字键快速选择 + if (keycode>=49 && keycode<=57) { + var index = keycode-49; + if (index<=choices.length) { + var topIndex = 6 - parseInt(choices.length / 2); + this.clickShop(6, topIndex+index); + } + } return; } @@ -1169,6 +1207,13 @@ actions.prototype.keyUpQuickShop = function (keycode) { var topIndex = 6 - parseInt(keys.length / 2); this.clickQuickShop(6, topIndex+core.status.event.selection); } + if (keycode>=49 && keycode<=57) { + var index = keycode-49; + if (index<=keys.length) { + var topIndex = 6 - parseInt(keys.length / 2); + this.clickQuickShop(6, topIndex+index); + } + } return; } @@ -1811,6 +1856,14 @@ actions.prototype.keyUpSwitchs = function (keycode) { var topIndex = 6 - parseInt((choices.length - 1) / 2); this.clickSwitchs(6, topIndex+core.status.event.selection); } + // 数字键快速选择 + if (keycode>=49 && keycode<=57) { + var index = keycode-49; + if (index=49 && keycode<=57) { + var index = keycode-49; + if (index=49 && keycode<=57) { + var index = keycode-49; + if (index=49 && keycode<=57) { + var index = keycode-49; + if (index=49 && keycode<=57) { + var index = keycode-49; + if (index=49 && keycode<=57) { + var index = keycode-49; + if (index=49 && keycode<=57) { + var index = keycode-49; + if (index12) alert("当前状态栏数目("+count+")大于12,请调整到不超过12以避免手机端出现显示问题。"); + var statusLineHeight = BASE_LINEHEIGHT * 9 / count; var statusLineFontSize = DEFAULT_FONT_SIZE; if (count>9) statusLineFontSize = statusLineFontSize * 9 / count; diff --git a/libs/core.js b/libs/core.js index 896989e1..de889da3 100644 --- a/libs/core.js +++ b/libs/core.js @@ -148,7 +148,7 @@ function core() { }, 'textAttribute': { 'position': "center", - "offset": 20, + "offset": 0, "title": [255,215,0,1], "background": [0,0,0,0.85], "text": [255,255,255,1], @@ -203,6 +203,11 @@ core.prototype.init = function (coreData, callback) { document.getElementById("startLogo").innerHTML = core.firstData.title; core.material.items = core.clone(core.items.getItems()); core.material.enemys = core.clone(core.enemys.getEnemys()); + if (main.mode == 'play') { + for (var enemyId in core.material.enemys) { + core.material.enemys[enemyId].id = enemyId; + } + } core.material.icons = core.icons.getIcons(); core.material.events = core.events.getEvents(); diff --git a/libs/events.js b/libs/events.js index d01d6c8b..72d6eacd 100644 --- a/libs/events.js +++ b/libs/events.js @@ -88,8 +88,8 @@ events.prototype.startGame = function (hard, seed, route, callback) { core.status.isStarting = true; if (core.isset(seed)) { - core.setFlag('seed', seed); - core.setFlag('rand', seed); + core.setFlag('__seed__', seed); + core.setFlag('__rand__', seed); } else core.utils.__init_seed(); @@ -195,7 +195,7 @@ events.prototype.gameOver = function (ending, fromReplay, norank) { 'name': core.firstData.name, 'version': core.firstData.version, 'hard': core.status.hard, - 'seed': core.getFlag('seed'), + 'seed': core.getFlag('__seed__'), 'route': core.encodeRoute(core.status.route) } core.download(core.firstData.name+"_"+core.formatDate2(new Date())+".h5route", JSON.stringify(obj)); @@ -238,7 +238,7 @@ events.prototype.gameOver = function (ending, fromReplay, norank) { formData.append('experience', core.status.hero.experience); formData.append('steps', core.status.hero.steps); formData.append('norank', norank||0); - formData.append('seed', core.getFlag('seed')); + formData.append('seed', core.getFlag('__seed__')); formData.append('totalTime', Math.floor(core.status.hero.statistics.totalTime/1000)); formData.append('route', core.encodeRoute(core.status.route)); formData.append('base64', 1); @@ -316,7 +316,7 @@ events.prototype.doEvents = function (list, x, y, callback) { core.status.event = {'id': 'action', 'data': { 'list': [ {"todo": core.clone(list), "total": core.clone(list), "condition": "false"} - ], 'x': x, 'y': y, 'callback': callback + ], 'x': x, 'y': y, 'callback': callback, 'startTime': new Date().getTime() }} // 停止勇士 @@ -702,12 +702,12 @@ events.prototype.doAction = function() { case "setFg": // 颜色渐变 if (data.async) { core.setFg(data.color, data.time); - core.setFlag('color', data.color||null); + core.setFlag('__color__', data.color||null); this.doAction(); } else { core.setFg(data.color, data.time, function() { - core.setFlag('color', data.color||null); + core.setFlag('__color__', data.color||null); core.events.doAction(); }); } @@ -715,8 +715,8 @@ events.prototype.doAction = function() { case "setWeather": // 更改天气 core.setWeather(data.name, data.level); if (core.isset(data.name)) - core.setFlag('weather', [data.name, data.level]); - else core.setFlag('weather', null); + core.setFlag('__weather__', [data.name, data.level]); + else core.setFlag('__weather__', null); this.doAction(); break; case "openDoor": // 开一个门,包括暗墙 @@ -774,6 +774,15 @@ events.prototype.doAction = function() { this.doAction(); break; } + case "insert": + { + var toX=core.calValue(data.loc[0]), toY=core.calValue(data.loc[1]); + var floorId = data.floorId || core.status.floorId; + var event = core.floors[floorId].events[toX+","+toY]; + if (core.isset(event)) core.insertAction(event); + this.doAction(); + break; + } case "playSound": if (!core.status.replay.replaying) core.playSound(data.name); @@ -910,7 +919,7 @@ events.prototype.doAction = function() { case "switch": // 条件选择 var key = core.calValue(data.condition) for (var i = 0; i < data.caseList.length; i++) { - if (core.calValue(data.caseList[i].case) == key || core.calValue(data.caseList[i].case) == "default") { + if (data.caseList[i].case=="default" || core.calValue(data.caseList[i].case) == key) { core.events.insertAction(data.caseList[i].action); break; } @@ -1336,7 +1345,7 @@ events.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback } // 不存在事件时,更改画面色调 - var color = core.getFlag('color', null); + var color = core.getFlag('__color__', null); if (!core.isset(color) && core.isset(core.status.maps[floorId].color)) { color = core.status.maps[floorId].color; } @@ -1356,7 +1365,7 @@ events.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback } // 更改天气 - var weather = core.getFlag('weather', null); + var weather = core.getFlag('__weather__', null); if (!core.isset(weather) && core.isset(core.status.maps[floorId].weather)) { weather = core.status.maps[floorId].weather; } @@ -1641,8 +1650,8 @@ events.prototype.openShop = function(shopId, needVisited) { var choice = shop.choices[i]; var text = choice.text; if (core.isset(choice.need)) - text += "("+eval(choice.need)+use+")" - choices.push(text); + text += "("+eval(choice.need)+use+")"; + choices.push({"text": text, "color":shop.visited?null:"#999999"}); } choices.push("离开"); core.ui.drawChoices(content, choices); @@ -1912,7 +1921,7 @@ events.prototype.uploadCurrent = function (username) { 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('seed', core.getFlag('__seed__')); formData.append('totalTime', Math.floor(core.status.hero.statistics.totalTime/1000)); formData.append('route', core.encodeRoute(core.status.route)); formData.append('deler', 'current'); diff --git a/libs/items.js b/libs/items.js index a576179e..bf20d5bb 100644 --- a/libs/items.js +++ b/libs/items.js @@ -9,6 +9,10 @@ items.prototype.init = function () { this.itemEffectTip = items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a.itemEffectTip; this.useItemEffect = items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a.useItemEffect; this.canUseItemEffect = items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a.canUseItemEffect; + if (!core.isset(items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a.canEquip)) + items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a.canEquip = {}; + this.canEquip = items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a.canEquip; + //delete(items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a); } @@ -162,13 +166,21 @@ items.prototype.loadEquip = function (equipId, callback) { if (!core.isset(core.status.hero.equipment)) core.status.hero.equipment = []; - core.playSound('equip.mp3'); - var loadEquip = core.material.items[equipId]; if (!core.isset(loadEquip)) { if (core.isset(callback)) callback(); return; } + + var can = this.canEquip[equipId]; + if (core.isset(can) && !eval(can)) { + core.drawTip("当前不可换上"+loadEquip.name); + if (core.isset(callback)) callback(); + return; + } + + core.playSound('equip.mp3'); + var loadEquipType = loadEquip.equip.type; var unloadEquipId = core.status.hero.equipment[loadEquipType]; @@ -285,9 +297,19 @@ items.prototype.quickLoadEquip = function (index) { for (var i=0;i0) { var block = core.maps.initBlock(x, y, arr[y][x]); if (core.isset(block.event)) { @@ -454,9 +448,16 @@ maps.prototype.drawMap = function (mapName, callback) { core.removeGlobalAnimate(null, null, true); var drawBg = function(){ + var width = core.floors[mapName].width || 13; + var height = core.floors[mapName].height || 13; - core.maps.drawBgFgMap(mapName, core.canvas.bg, "bg"); - core.maps.drawBgFgMap(mapName, core.canvas.fg, "fg"); + var groundId = (core.status.maps||core.floors)[mapName].defaultGround || "ground"; + var blockIcon = core.material.icons.terrains[groundId]; + for (var x = 0; x < width; x++) { + for (var y = 0; y < height; y++) { + core.canvas.bg.drawImage(core.material.images.terrains, 0, blockIcon * 32, 32, 32, x * 32, y * 32, 32, 32); + } + } var images = []; if (core.isset(core.status.maps[mapName].images)) { @@ -466,6 +467,7 @@ maps.prototype.drawMap = function (mapName, callback) { } } images.forEach(function (t) { + if (typeof t == 'string') t = [0,0,t]; var dx=parseInt(t[0]), dy=parseInt(t[1]), p=t[2]; if (core.isset(dx) && core.isset(dy) && !core.hasFlag("floorimg_"+mapName+"_"+dx+"_"+dy) && @@ -496,7 +498,10 @@ maps.prototype.drawMap = function (mapName, callback) { 32*dx, 32*dy + image.height - 32, image.width, 32); } } - }) + }); + + core.maps.drawBgFgMap(mapName, core.canvas.bg, "bg"); + core.maps.drawBgFgMap(mapName, core.canvas.fg, "fg"); } if (main.mode=='editor'){ diff --git a/libs/ui.js b/libs/ui.js index 0bec6669..befe8172 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -283,6 +283,64 @@ ui.prototype.drawText = function (contents, callback) { // core.drawTextBox(content); } +ui.prototype.getTitleAndIcon = function (content) { + var id=null, name=null, image=null, icon=null, iconHeight=32, animate=null; + + var getInfo = function (v) { + ["enemy48", "enemys", "npc48", "npcs"].forEach(function (x) { + if (core.isset(core.material.icons[x][v])) { + image = core.material.images[x]; + icon = core.material.icons[x][v]; + if (x.indexOf("48")>=0) { + iconHeight = 48; + animate = 4; + } + else { + iconHeight = 32; + animate = 2; + } + } + }); + }; + + if (content.indexOf("\t[")==0 || content.indexOf("\\t[")==0) { + var index = content.indexOf("]"); + if (index>=0) { + var str=content.substring(2, index); + if (content.indexOf("\\t[")==0) str=content.substring(3, index); + content=content.substring(index+1); + var ss=str.split(","); + if (ss.length==1) { + id=ss[0]; + if (id=='hero') name = core.status.hero.name; + else if (core.isset(core.material.enemys[id])) { + name = core.material.enemys[id].name; + getInfo(id); + } + else { + name=id; + id='npc'; + } + } + else { + name=ss[0]; + id = 'npc'; + if (ss[1]=='hero') id = 'hero'; + else getInfo(ss[1]); + } + } + } + return { + "content": content, + "id": id, + "name": name, + "image": image, + "icon": icon, + "iconHeight": iconHeight, + "animate": animate + }; +} + ////// 绘制一个对话框 ////// ui.prototype.drawTextBox = function(content, showAll) { @@ -294,78 +352,9 @@ ui.prototype.drawTextBox = function(content, showAll) { core.status.event.interval = null; // 获得name, image, icon - var id=null, name=null, image=null, icon=null, iconHeight=32, animate=null; - if (content.indexOf("\t[")==0 || content.indexOf("\\t[")==0) { - var index = content.indexOf("]"); - if (index>=0) { - var str=content.substring(2, index); - if (content.indexOf("\\t[")==0) str=content.substring(3, index); - content=content.substring(index+1); - var ss=str.split(","); - if (ss.length==1) { - // id - id=ss[0]; - if (id=='hero') { - name = core.status.hero.name; - } - else { - if (core.isset(core.material.enemys[id])) { - name = core.material.enemys[id].name; - - if (core.isset(core.material.icons.enemy48[id])) { - image = core.material.images.enemy48; - icon = core.material.icons.enemy48[id]; - iconHeight = 48; - animate=4; - } - else { - image = core.material.images.enemys; - icon = core.material.icons.enemys[id]; - iconHeight = 32; - animate=2; - } - } - else { - name=id; - id='npc'; - image=null; - icon=null; - } - } - } - else { - name=ss[0]; - id = 'npc'; - if (ss[1]=='hero') { - id = 'hero'; - } - else if (core.isset(core.material.icons.npc48[ss[1]])) { - image = core.material.images.npc48; - icon = core.material.icons.npc48[ss[1]]; - iconHeight = 48; - animate=4; - } - else if (core.isset(core.material.icons.npcs[ss[1]])){ - image = core.material.images.npcs; - icon = core.material.icons.npcs[ss[1]]; - iconHeight = 32; - animate=2; - } - else if (core.isset(core.material.icons.enemy48[ss[1]])) { - image = core.material.images.enemy48; - icon = core.material.icons.enemy48[ss[1]]; - iconHeight = 48; - animate=4; - } - else if (core.isset(core.material.icons.enemys[ss[1]])) { - image = core.material.images.enemys; - icon = core.material.icons.enemys[ss[1]]; - iconHeight = 32; - animate=2; - } - } - } - } + var info = this.getTitleAndIcon(content); + content = info.content; + var id=info.id, name=info.name, image=info.image, icon=info.icon, iconHeight=info.iconHeight, animate=info.animate; // 获得位置信息 @@ -415,16 +404,17 @@ ui.prototype.drawTextBox = function(content, showAll) { // var contents = content.split('\n'); // var contents = core.splitLines('ui', content, ); - var left=10, right=416-2*left; + var left=7, right=416-2*left; var content_left = left + 25; if (id=='hero' || core.isset(icon)) content_left=left+63; var validWidth = right-(content_left-left)-13; var font = textfont + 'px Verdana'; if (textAttribute.bold) font = "bold "+font; - var contents = core.splitLines("ui", content, validWidth, font); + var realContent = content.replace(/(\v|\\v)(\[.*?])?/g, ""); - var height = 20 + (textfont+5)*(contents.length+1) + (id=='hero'?core.material.icons.hero.height-10:core.isset(name)?iconHeight-10:0); + var height = 20 + (textfont+5)*(core.splitLines("ui", realContent, validWidth, font).length+1) + + (id=='hero'?core.material.icons.hero.height-10:core.isset(name)?iconHeight-10:0); var xoffset = 6, yoffset = 22; @@ -434,20 +424,16 @@ ui.prototype.drawTextBox = function(content, showAll) { top = parseInt((416 - height) / 2); } else if (position=='up') { - if (px==null || py==null) { + if (px==null || py==null) top = 5 + offset; - } - else { + else top = 32 * py - height - ydelta - yoffset; - } } else if (position=='down') { - if (px==null || py==null) { + if (px==null || py==null) top = 416 - height - 5 - offset; - } - else { + else top = 32 * py + 32 + yoffset; - } } // var left = 97, top = 64, right = 416 - 2 * left, bottom = 416 - 2 * top; @@ -459,11 +445,10 @@ ui.prototype.drawTextBox = function(content, showAll) { core.setFillStyle('ui', core.arrayToRGB(textAttribute.background)); core.setStrokeStyle('ui', borderColor); - core.fillRect('ui', left, top, right, height); core.strokeRect('ui', left - 1, top - 1, right + 1, height + 1, borderColor, 2); - var xoffset = 9; + var xoffset = 10; // draw triangle if (position=='up' && core.isset(px) && core.isset(py)) { @@ -534,32 +519,66 @@ ui.prototype.drawTextBox = function(content, showAll) { } } + var defaultColor = core.arrayToRGB(textAttribute.text); + var offsetx = content_left, offsety = content_top; + core.setFont('ui', font); + core.setAlpha('ui', textAttribute.text[3]); + core.setFillStyle('ui', defaultColor); + var index = 0, currcolor = defaultColor, changed = false; - var drawContent = function (content) { - - core.clearMap("ui", content_left, content_top - 18, validWidth, top + height - content_top + 10); - core.setAlpha('ui', textAttribute.background[3]); - core.setFillStyle('ui', core.arrayToRGB(textAttribute.background)); - core.fillRect("ui", content_left, content_top - 18, validWidth, top + height - content_top + 11); - - core.setAlpha('ui', textAttribute.text[3]); - core.setFillStyle('ui', core.arrayToRGB(textAttribute.text)); - var contents = core.splitLines("ui", content, validWidth, font); - - for (var i=0;i= content.length) return false; + if (changed) { + core.setFillStyle('ui', currcolor); + changed = false; } - } + // get next character + var char = content.charAt(index++); + // \n, \\n + if (char == '\n' || (char=='\\' && content.charAt(index)=='n')) { + offsetx = content_left; + offsety += textfont+5; + if (char=='\\') index++; + return drawNext(); + } + // \v, \\v + if (char == '\v' || (char=='\\' && content.charAt(index)=='v')) { + if (char == '\\') index++; + changed = true; + // 检查是不是 [] + var index2; + if (content.charAt(index) == '[' && ((index2=content.indexOf(']', index))>=0)) { + // 变色 + var str = content.substring(index+1, index2); + if (str=="") currcolor = defaultColor; + else currcolor = str; + index = index2+1; + } + else currcolor = defaultColor; + return drawNext(); + } + // 检查是不是自动换行 + var charwidth = core.canvas.ui.measureText(char).width; + if (offsetx + charwidth > content_left + validWidth) { + index--; + offsetx = content_left; + offsety += textfont+5; + return drawNext(); + } + // 输出 + core.fillText('ui', char, offsetx, offsety); + offsetx += charwidth; + return true; + }; if (showAll || textAttribute.time<=0 || core.status.event.id!='action') { - drawContent(content); + while (drawNext()); } else { - var index=0; core.status.event.interval = setInterval(function () { - drawContent(content.substring(0, ++index)); - if (index==content.length) { + changed = true; + if (!drawNext()) { clearInterval(core.status.event.interval); core.status.event.interval = null; } @@ -604,82 +623,13 @@ ui.prototype.drawChoices = function(content, choices) { if (core.isset(content)) { // 获得name, image, icon - if (content.indexOf("\t[")==0 || content.indexOf("\\t[")==0) { - var index = content.indexOf("]"); - if (index>=0) { - var str=content.substring(2, index); - if (content.indexOf("\\t[")==0) str=content.substring(3, index); - content=content.substring(index+1); - var ss=str.split(","); - if (ss.length==1) { - // id - id=ss[0]; - if (id=='hero') { - name = core.status.hero.name; - } - else { - if (core.isset(core.material.enemys[id])) { - name = core.material.enemys[id].name; - - if (core.isset(core.material.icons.enemy48[id])) { - image = core.material.images.enemy48; - icon = core.material.icons.enemy48[id]; - iconHeight = 48; - animate=4; - } - else { - image = core.material.images.enemys; - icon = core.material.icons.enemys[id]; - iconHeight = 32; - animate=2; - } - } - else { - name=id; - id='npc'; - image=null; - icon=null; - } - } - } - else { - name=ss[0]; - id = 'npc'; - if (ss[1]=='hero') { - id = 'hero'; - } - else if (core.isset(core.material.icons.npc48[ss[1]])) { - image = core.material.images.npc48; - icon = core.material.icons.npc48[ss[1]]; - iconHeight = 48; - animate=4; - } - else if (core.isset(core.material.icons.npcs[ss[1]])){ - image = core.material.images.npcs; - icon = core.material.icons.npcs[ss[1]]; - iconHeight = 32; - animate=2; - } - else if (core.isset(core.material.icons.enemy48[ss[1]])) { - image = core.material.images.enemy48; - icon = core.material.icons.enemy48[ss[1]]; - iconHeight = 48; - animate=4; - } - else if (core.isset(core.material.icons.enemys[ss[1]])) { - image = core.material.images.enemys; - icon = core.material.icons.enemys[ss[1]]; - iconHeight = 32; - animate=2; - } - } - } - } - content = core.replaceText(content); - + // 获得name, image, icon + var info = this.getTitleAndIcon(content); + content = core.replaceText(info.content); + id=info.id; name=info.name; image=info.image; + icon=info.icon; iconHeight=info.iconHeight; animate=info.animate; if (id=='hero' || core.isset(icon)) content_left = left+60; - contents = core.splitLines('ui', content, width-(content_left-left)-10, 'bold 15px Verdana'); // content部分高度 @@ -746,7 +696,8 @@ ui.prototype.drawChoices = function(content, choices) { // 选项 core.canvas.ui.textAlign = "center"; for (var i = 0; i < choices.length; i++) { - core.fillText('ui', core.replaceText(choices[i].text || choices[i]), 208, choice_top + 32 * i, "#FFFFFF", "bold 17px Verdana"); + core.setFillStyle('ui', choices[i].color || "#FFFFFF"); + core.fillText('ui', core.replaceText(choices[i].text || choices[i]), 208, choice_top + 32 * i, null, "bold 17px Verdana"); } if (choices.length>0) { @@ -846,7 +797,9 @@ ui.prototype.drawQuickShop = function () { core.status.event.id = 'selectShop'; var shopList = core.status.shops, keys = Object.keys(shopList).filter(function (shopId) {return shopList[shopId].visited || !shopList[shopId].mustEnable}); - var choices = keys.map(function (shopId) {return shopList[shopId].textInList}); + var choices = keys.map(function (shopId) { + return {"text": shopList[shopId].textInList, "color": shopList[shopId].visited?null:"#999999"}; + }); choices.push("返回游戏"); this.drawChoices(null, choices); @@ -1618,6 +1571,13 @@ ui.prototype.drawMaps = function (index, x, y) { core.fillText('ui', "上移地图 [W]", 208, 38, '#FFD700', '20px Arial'); core.fillText('ui', "下移地图 [S]", 208, 390); + core.strokeRect('ui', 2, 2, 28, 28); + core.fillText('ui', 'V', 16, 24); + core.strokeRect('ui', 2, 416-30, 28, 28); + core.fillText('ui', 'M', 16, 408); + core.strokeRect('ui', 416-30, 2, 28, 28); + core.fillText('ui', 'Z', 400, 24); + var top = 150; core.fillText('ui', "左", 32, top); core.fillText('ui', "移", 32, top+32); @@ -1635,6 +1595,7 @@ ui.prototype.drawMaps = function (index, x, y) { core.fillText('ui', "退出 [ESC / ENTER]", 208, 208+8); core.fillText('ui', "[X] 可查看怪物手册", 285, 208+40, null, '13px Arial'); + return; } @@ -1642,8 +1603,10 @@ ui.prototype.drawMaps = function (index, x, y) { core.setOpacity('animate', 1); var damage = (core.status.event.data||{}).damage, paint = (core.status.event.data||{}).paint; + var all = (core.status.event.data||{}).all; if (core.isset(index.damage)) damage=index.damage; if (core.isset(index.paint)) paint=index.paint; + if (core.isset(index.all)) all=index.all; if (core.isset(index.index)) { x=index.x; @@ -1661,7 +1624,7 @@ ui.prototype.drawMaps = function (index, x, y) { if (y<6) y=6; if (y>mh-7) y=mh-7; - core.status.event.data = {"index": index, "x": x, "y": y, "damage": damage, "paint": paint}; + core.status.event.data = {"index": index, "x": x, "y": y, "damage": damage, "paint": paint, "all": all}; clearTimeout(core.interval.tipAnimate); core.clearMap('ui'); @@ -1683,7 +1646,7 @@ ui.prototype.drawMaps = function (index, x, y) { core.setFont('data', '16px Arial'); var text = core.status.maps[floorId].title; - if (mw>13 || mh>13) text+=" ["+(x-6)+","+(y-6)+"]"; + if (!all && (mw>13 || mh>13)) text+=" ["+(x-6)+","+(y-6)+"]"; var textX = 16, textY = 18, width = textX + core.canvas.data.measureText(text).width + 16, height = 42; core.fillRect('data', 5, 5, width, height, '#000'); core.setOpacity('data', 0.4); @@ -2112,8 +2075,13 @@ ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, cente tempCanvas.canvas.height = tempHeight; tempCanvas.clearRect(0, 0, tempWidth, tempHeight); - // background map - core.maps.drawBgFgMap(floorId, tempCanvas, "bg"); + var groundId = (core.status.maps||core.floors)[floorId].defaultGround || "ground"; + var blockIcon = core.material.icons.terrains[groundId]; + for (var i = 0; i < mw; i++) { + for (var j = 0; j < mh; j++) { + tempCanvas.drawImage(core.material.images.terrains, 0, blockIcon * 32, 32, 32, i * 32, j * 32, 32, 32); + } + } // background image var images = []; @@ -2124,6 +2092,7 @@ ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, cente } } images.forEach(function (t) { + if (typeof t == 'string') t = [0,0,t]; var dx=parseInt(t[0]), dy=parseInt(t[1]), p=t[2]; if (core.isset(dx) && core.isset(dy) && !core.hasFlag("floorimg_"+floorId+"_"+dx+"_"+dy) && @@ -2136,6 +2105,10 @@ ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, cente 32 * dx, 32 * dy + image.height - 32, image.width, 32); } }) + + // background map + core.maps.drawBgFgMap(floorId, tempCanvas, "bg"); + // draw block var mapArray = core.maps.getMapArray(blocks,mw,mh); for (var b in blocks) { @@ -2171,8 +2144,6 @@ ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, cente var height = core.material.images.images[heroIcon].height/4; tempCanvas.drawImage(core.material.images.images[heroIcon], icon.stop * 32, icon.loc * height, 32, height, 32*heroLoc.x, 32*heroLoc.y+32-height, 32, height); } - // foreground map - core.maps.drawBgFgMap(floorId, tempCanvas, "fg"); // draw fg images.forEach(function (t) { @@ -2189,6 +2160,9 @@ ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, cente } }) + // foreground map + core.maps.drawBgFgMap(floorId, tempCanvas, "fg"); + // draw damage if (core.status.event.id=='viewMaps' && (core.status.event.data||{}).damage) core.control.updateDamage(floorId, tempCanvas); @@ -2198,9 +2172,28 @@ ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, cente if (!core.isset(centerX)) centerX=parseInt(mw/2); if (!core.isset(centerY)) centerY=parseInt(mh/2); - var offsetX = core.clamp(centerX-6, 0, mw-13), offsetY = core.clamp(centerY-6, 0, mh-13); - // offsetX~offsetX+12; offsetY~offsetY+12 - core.canvas[canvas].drawImage(tempCanvas.canvas, offsetX*32, offsetY*32, 416, 416, x, y, size, size); + // 如果是浏览地图的全模式 + if (core.status.event.id=='viewMaps' && (core.status.event.data||{}).all) { + if (tempWidth<=tempHeight) { + var realHeight = 416, realWidth = realHeight * tempWidth / tempHeight; + var side = (416 - realWidth) / 2; + core.fillRect(canvas, 0, 0, side, realHeight, '#000000'); + core.fillRect(canvas, 416-side, 0, side, realHeight); + core.canvas[canvas].drawImage(tempCanvas.canvas, 0, 0, tempWidth, tempHeight, side, 0, realWidth, realHeight); + } + else { + var realWidth = 416, realHeight = realWidth * tempHeight / tempWidth; + var side = (416 - realHeight) / 2; + core.fillRect(canvas, 0, 0, realWidth, side, '#000000'); + core.fillRect(canvas, 0, 416-side, realWidth, side); + core.canvas[canvas].drawImage(tempCanvas.canvas, 0, 0, tempWidth, tempHeight, 0, side, realWidth, realHeight); + } + } + else { + var offsetX = core.clamp(centerX-6, 0, mw-13), offsetY = core.clamp(centerY-6, 0, mh-13); + // offsetX~offsetX+12; offsetY~offsetY+12 + core.canvas[canvas].drawImage(tempCanvas.canvas, offsetX*32, offsetY*32, 416, 416, x, y, size, size); + } } ui.prototype.drawKeyBoard = function () { diff --git a/libs/utils.js b/libs/utils.js index 24c1eaf9..44e23fd9 100644 --- a/libs/utils.js +++ b/libs/utils.js @@ -13,7 +13,7 @@ utils.prototype.init = function () { ////// 将文字中的${和}(表达式)进行替换 ////// utils.prototype.replaceText = function (text) { - return text.replace(/\${([^}]+)}/g, function (word, value) { + return text.replace(/\${(.*?)}/g, function (word, value) { return core.calValue(value); }); } @@ -486,8 +486,8 @@ utils.prototype.__init_seed = function () { rand = this.__next_rand(rand); rand = this.__next_rand(rand); rand = this.__next_rand(rand); - core.setFlag('seed', rand); - core.setFlag('rand', rand); + core.setFlag('__seed__', rand); + core.setFlag('__rand__', rand); } utils.prototype.__next_rand = function (_rand) { @@ -497,9 +497,9 @@ utils.prototype.__next_rand = function (_rand) { } utils.prototype.rand = function (num) { - var rand = core.getFlag('rand'); + var rand = core.getFlag('__rand__'); rand = this.__next_rand(rand); - core.setFlag('rand', rand); + core.setFlag('__rand__', rand); var ans = rand/2147483647; if (core.isset(num) && num>0) return Math.floor(ans*num); diff --git a/main.js b/main.js index 45ccd438..cdbcdc75 100644 --- a/main.js +++ b/main.js @@ -2,7 +2,7 @@ function main() { //------------------------ 用户修改内容 ------------------------// - this.version = "2.5"; // 游戏版本号;如果更改了游戏内容建议修改此version以免造成缓存问题。 + this.version = "2.5.1"; // 游戏版本号;如果更改了游戏内容建议修改此version以免造成缓存问题。 this.useCompress = false; // 是否使用压缩文件 // 当你即将发布你的塔时,请使用“JS代码压缩工具”将所有js代码进行压缩,然后将这里的useCompress改为true。 @@ -420,15 +420,6 @@ main.statusBar.image.fly.onclick = function () { return; } - // 浏览地图时 - if (main.core.isPlaying() && (core.status.event||{}).id=='viewMaps') { - if (core.isset(core.status.event.data)) { - core.status.event.data.paint = !core.status.event.data.paint; - core.ui.drawMaps(core.status.event.data); - } - return; - } - if (main.core.isPlaying()) { if (!main.core.flags.equipboxButton) { main.core.useFly(true); diff --git a/project/data.js b/project/data.js index 89f513e0..e8c3c64b 100644 --- a/project/data.js +++ b/project/data.js @@ -68,7 +68,7 @@ data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "firstData": { "title": "魔塔样板", "name": "template", - "version": "Ver 2.5", + "version": "Ver 2.5.1", "floorId": "sample0", "hero": { "name": "阳光", diff --git a/project/floors/sample1.js b/project/floors/sample1.js index a7ab22f8..659098a7 100644 --- a/project/floors/sample1.js +++ b/project/floors/sample1.js @@ -594,7 +594,7 @@ main.floors.sample1= ] }, { - "case": "'default'", + "case": "default", "action": [ { "type": "comment", diff --git a/更新说明.txt b/更新说明.txt index 806a3184..7757a557 100644 --- a/更新说明.txt +++ b/更新说明.txt @@ -1,4 +1,22 @@ -HTML5魔塔样板V2.5 +HTML5魔塔样板V2.5.1 + +新增事件type:insert,可以插入另一个地点的事件执行(公共事件) +可以使用\v来控制剧情文本部分文字的颜色 +新增事件type:switch,多重分歧 +绘制前景/背景层时淡化其他图层 +追加素材的自动调整(如白底、不规范的素材) +浏览地图时:左上角/V开启显伤;右上角/Z查看当前层大地图 +允许在受到领域夹击等伤害后禁用快捷商店 +升级的扣除模式,即不显示经验值,只显示升级的所需剩余值 +装备增加可装备条件判定 +选项界面可以使用1-9快速选择 +未开启状态的快捷商店用灰色显示 +修复不能在背景/前景层绘图的Bug +部分其他细节优化 + +----------------------------------------------------------------------- + +HTML5魔塔样板V2.5 添加绘图模式支持;可以用户手动绘图和保存 内置主动技能:二倍斩的支持,可以仿照制作其他主动技能