commit
8a16a48420
11
API列表.txt
11
API列表.txt
@ -1949,6 +1949,17 @@ errorCallback可选,如果失败,则会将错误信息传入errorCallback()
|
||||
此函数是异步的,只能通过回调函数来获得读取的结果或错误信息。
|
||||
|
||||
|
||||
core.setGlobal(key, value)
|
||||
设置一个全局存储,适用于global:xxx。
|
||||
录像播放时将忽略此函数,否则直接调用core.setLocalStorage。
|
||||
|
||||
|
||||
core.getGlobal(key, value)
|
||||
获得一个全局存储,适用于global:xxx,支持录像。
|
||||
正常游戏时将使用core.getLocalStorage获得具体的数据,并将结果存放到录像中。
|
||||
录像播放时会直接从录像中获得对应的数据。
|
||||
|
||||
|
||||
core.clone(data, filter, recursion)
|
||||
深拷贝一个对象。有关浅拷贝,深拷贝,基本类型和引用类型等相关知识可参见:
|
||||
https://zhuanlan.zhihu.com/p/26282765
|
||||
|
||||
19
README.md
19
README.md
@ -55,6 +55,25 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏!
|
||||
|
||||
## 更新说明
|
||||
|
||||
### 2019.5.2 V2.6.1
|
||||
|
||||
* [x] 区域优化的录像播放功能,R键使用
|
||||
* [x] 强制战斗可以指定怪物坐标,将自动隐藏并执行该点战后事件
|
||||
* [x] flag:xxx也支持中文,例如 flag:2楼机关门
|
||||
* [x] 增加文件名映射,可以用中文映射到某个图片或bgm文件并使用
|
||||
* [x] 勇士宽度可以超过32(例如48x48的勇士行走图)
|
||||
* [x] 现在允许修改floorId和图块ID了(在表格下方)
|
||||
* [x] 增加事件:自动存档,返回标题界面;部分事件优化
|
||||
* [x] 商店长按空格可以连续加点
|
||||
* [x] 增设global:xxx使用全局存储,可被录像支持
|
||||
* [x] 支持\b[hero]和\b[null,x,y]来自动调整上下方向
|
||||
* [x] 支持\t[yellowKey]等只显示图标而没有标题
|
||||
* [x] 编辑器中前景层对于有事件的点半透明显示
|
||||
* [x] 存档改成1000页,长按上下页可快速翻页
|
||||
* [x] 录像播放初始默认暂停,N键可以单步执行
|
||||
* [x] 增设本地API文档,部分API和事件的优化
|
||||
* [x] 所有已知的bug修复,大量细节优化
|
||||
|
||||
### 2019.4.13 V2.6
|
||||
|
||||
* [x] 拆分整个项目,大幅重构代码,新增大量API
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# V2.0版本介绍
|
||||
|
||||
?> 目前版本**v2.5.5**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.6.1**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
目前样板已经更新到V2.0版本以上,本章将对V2.0的一些内容进行介绍。
|
||||
|
||||
|
||||
13
_docs/api.md
13
_docs/api.md
@ -1,6 +1,6 @@
|
||||
# 附录:API列表
|
||||
|
||||
?> 目前版本**v2.6**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.6.1**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
这里将列出所有被转发到core的API,没有被转发的函数此处不会列出,请自行在代码中查看。
|
||||
|
||||
@ -1915,6 +1915,17 @@ errorCallback可选,如果失败,则会将错误信息传入errorCallback()
|
||||
此函数是异步的,只能通过回调函数来获得读取的结果或错误信息。
|
||||
|
||||
|
||||
core.setGlobal(key, value)
|
||||
设置一个全局存储,适用于global:xxx。
|
||||
录像播放时将忽略此函数,否则直接调用core.setLocalStorage。
|
||||
|
||||
|
||||
core.getGlobal(key, value)
|
||||
获得一个全局存储,适用于global:xxx,支持录像。
|
||||
正常游戏时将使用core.getLocalStorage获得具体的数据,并将结果存放到录像中。
|
||||
录像播放时会直接从录像中获得对应的数据。
|
||||
|
||||
|
||||
core.clone(data, filter, recursion)
|
||||
深拷贝一个对象。有关浅拷贝,深拷贝,基本类型和引用类型等相关知识可参见:
|
||||
https://zhuanlan.zhihu.com/p/26282765
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# 元件说明
|
||||
|
||||
?> 目前版本**v2.6**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.6.1**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
在本章中,将对样板里的各个元件进行说明。各个元件主要包括道具、门、怪物、楼梯等等。
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# 事件
|
||||
|
||||
?> 目前版本**v2.6**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.6.1**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
本章内将对样板所支持的事件进行介绍。
|
||||
|
||||
@ -188,6 +188,8 @@
|
||||
|
||||
从V2.5.2以后,新增了绘制大头像的功能。绘制大头像图的基本写法是`\t[1.png]`或者`\t[标题,1.png]`。
|
||||
|
||||
从V2.6开始,所有图块都允许只写ID,对于非怪物则没有标题。
|
||||
|
||||
``` js
|
||||
[
|
||||
"一段普通文字",
|
||||
@ -198,7 +200,9 @@
|
||||
"\t[小妖精,fairy]这是一段小妖精说的话,使用仙子(fairy)的图标",
|
||||
"\t[你赢了]直接显示标题为【你赢了】",
|
||||
"\t[1.png]绘制1.png这个头像图",
|
||||
"\t[标题,1.png]同时绘制标题和1.png这个头像图"
|
||||
"\t[标题,1.png]同时绘制标题和1.png这个头像图",
|
||||
"\t[sword1]获得铁剑,没有标题",
|
||||
"\t[man]没有标题的npc动画"
|
||||
]
|
||||
```
|
||||
|
||||
@ -283,18 +287,22 @@
|
||||
|
||||
我们可以使用 `status:xxx` 代表勇士的一个属性值;`item:xxx` 代表某个道具的个数;`flag:xxx` 代表某个自定义的变量或flag值。
|
||||
|
||||
从V2.6开始,也可以使用`global:xxx`代表全局存储(和存档无关的存储)。
|
||||
|
||||
``` js
|
||||
[
|
||||
"你当前的攻击力是${status:atk}, 防御是${status:def},坐标是(${status:x},${status:y})",
|
||||
"你的攻防和的十倍是${10*(status:atk+status:def)}",
|
||||
"你的红黄蓝钥匙总数为${item:yellowKey+item:blueKey+item:redKey}",
|
||||
"你访问某个老人的次数为${flag:man_times}",
|
||||
"当前的存档编号是${global:saveIndex}",
|
||||
]
|
||||
```
|
||||
|
||||
- `status:xxx` 获取勇士属性时只能使用如下几个:hp(生命值),atk(攻击力),def(防御力),mdef(魔防值),money(金币),experience(经验),x(勇士的横坐标),y(勇士的纵坐标),direction(勇士的方向)。
|
||||
- `item:xxx` 中的xxx为道具ID。所有道具的ID定义在items.js中,请自行查看。例如,`item:centerFly` 代表中心对称飞行器的个数。
|
||||
- `flag:xxx` 中的xxx为一个自定义的变量/Flag;如果没有对其进行赋值则默认值为false。
|
||||
- `flag:xxx` 中的xxx为一个自定义的变量/Flag(支持中文);如果没有对其进行赋值则默认值为0。
|
||||
- `global:xxx` 中的xxx为一个全局存储的名称(支持中文);如果没有对其进行赋值则默认值为0。
|
||||
|
||||
### autoText:自动剧情文本
|
||||
|
||||
@ -413,7 +421,7 @@ icon是可选的,如果设置则会绘制图标,其可以是一个有效的I
|
||||
|
||||
name为你要修改的属性/道具/Flag,每次只能修改一个值。写法和上面完全相同,`status:xxx` 表示勇士一个属性,`item:xxx` 表示某个道具个数,`flag:xxx` 表示某个变量或flag值。参见上面的介绍。
|
||||
|
||||
value是一个表达式,将通过这个表达式计算出的结果赋值给name。该表达式同样可以使用`status:xxx`, `item:xxx`, `flag:xxx`的写法表示勇士当前属性,道具个数和某个变量/Flag值。
|
||||
value是一个表达式,将通过这个表达式计算出的结果赋值给name。该表达式同样可以使用`status:xxx`, `item:xxx`, `flag:xxx`, `global:xxx`的写法表示勇士当前属性,道具个数,某个变量/Flag值和某个全局存储值。
|
||||
|
||||
``` js
|
||||
[
|
||||
@ -424,6 +432,7 @@ value是一个表达式,将通过这个表达式计算出的结果赋值给nam
|
||||
{"type": "setValue", "name": "item:bomb", "value": "item:bomb+10" } // 炸弹个数+10
|
||||
{"type": "setValue", "name": "flag:man_times", "value": "0" } // 将变量man_times设为0
|
||||
{"type": "setValue", "name": "flag:man_times", "value": "flag:man_times+2*status:atk" } // 将变量man_times的值加上勇士的攻击数值的两倍
|
||||
{"type": "setValue", "name": "global:123", "value": "4"} // 设置全局存储233为4(任何存档都可以读取它)
|
||||
]
|
||||
```
|
||||
|
||||
@ -570,24 +579,22 @@ NPC对话事件结束后如果需要NPC消失也需要调用 `{"type": "hide"}`
|
||||
|
||||
`{"type":"trigger"}` 会立刻触发当层另一个地点的自定义事件。
|
||||
|
||||
上面我们说到,show事件会让一个禁用事件启用且可被交互;但是如果我想立刻让它执行应该怎么办呢?使用trigger就行。
|
||||
|
||||
其基本写法如下:
|
||||
|
||||
``` js
|
||||
[
|
||||
{"type": "trigger", "loc": [3,6]}, // 立即触发loc位置的事件,当前剩下的事件全部不再执行
|
||||
"执行trigger后,这段文字将不会再被显示"
|
||||
{"type": "trigger", "loc": [3,6], "keep": true}, // 触发loc位置的事件,不结束当前事件
|
||||
]
|
||||
```
|
||||
|
||||
其后面带有loc选项,代表另一个地点的坐标。
|
||||
|
||||
执行trigger事件后,当前事件将立刻被结束,剩下所有内容被忽略;然后重新启动另一个地点的action事件。
|
||||
keep可选,如果此项为true则不会结束当前的事件列表,否则会中断当前的事件流。
|
||||
|
||||
例如上面这个例子,下面的文字将不会再被显示,而是直接跳转到`"3,6"`对应的事件列表从头执行。
|
||||
从V2.5.4开始允许执行另一个点的系统事件,如打怪开门拾取道具等等,对应点的战后等事件也会被插入执行。
|
||||
|
||||
!> 从V2.5.4开始,允许执行另一个点的“系统事件”,如打怪、开门、拾取道具等等。对应点的战后事件等也会被执行。
|
||||
值得注意的是,此事件会**改变当前点坐标**为目标点。
|
||||
|
||||
### insert:插入公共事件或另一个地点的事件并执行
|
||||
|
||||
@ -615,11 +622,12 @@ NPC对话事件结束后如果需要NPC消失也需要调用 `{"type": "hide"}`
|
||||
- floorId可选,代表另一个地点所在的楼层;如果不写则默认为当前层。
|
||||
- 从V2.6开始,还可以传可选的which,可以为`afterBattle`/`afterGetItem`/`afterOpenDoor`,代表插入该点的战后/获得道具后/开门后事件。
|
||||
|
||||
和`type:trigger`不同的是,**`type:trigger`是立刻将当前事件结束(剩下所有内容都忽略),然后重新启动另一个地点的action事件。**
|
||||
和`type:trigger`不同点如下:
|
||||
- `type:trigger`只能指定当前楼层且会改变当前点坐标,`type:insert`可以跨楼层且不会改变当前点坐标。
|
||||
- `type:trigger`如果不设置`keep:true`则还会结束当前事件,`type:insert`而是将另一个点的事件插入到当前事件列表中执行。
|
||||
- `type:trigger`可以触发系统事件,`type:insert`只能触发该点的自定义事件或战后事件等。
|
||||
|
||||
但是`type:insert`不会结束当前事件,而是直接将另一个地点的事件列表“插入”到当前事件列表中执行。
|
||||
|
||||
**这个过程中,当前事件不会被结束,当前的楼层和事件坐标不会发生改变。** 插入的事件执行完毕后,会继续执行接下来的内容。
|
||||
插入的事件执行完毕后,会继续执行接下来的内容。
|
||||
|
||||
从V2.6开始,插入事件允许传参。如果需要传参,则需要增加一个`args`数组。
|
||||
|
||||
@ -836,28 +844,20 @@ name是可选的,代表目标行走图的文件名。
|
||||
|
||||
调用battle可强制与某怪物进行战斗(而无需去触碰到它)。
|
||||
|
||||
其基本写法是: `{"type": "battle", "id": xxx}`,其中xxx为怪物ID。
|
||||
|
||||
``` js
|
||||
[
|
||||
"\t[blackKing]你终于还是来了。",
|
||||
"\t[hero]放开我们的公主!",
|
||||
"\t[blackKing]如果我不愿意呢?",
|
||||
"\t[hero]无需多说,拔剑吧!",
|
||||
{"type": "battle", "id": "blackKing"}, // 强制战斗
|
||||
// 如果战斗失败直接死亡,不会继续触发接下来的剧情。
|
||||
{"type": "hide", "loc": [10,2]}, // 战斗后需要手动使怪物消失;战斗后不会引发afterBattle事件。
|
||||
{"type": "openDoor", "loc": [8,7]}, // 开门口的机关门
|
||||
"\t[blackKing]没想到你已经变得这么强大了... 算你厉害。\n公主就交给你了,请好好对她。",
|
||||
{"type": "hide"} // 隐藏本事件
|
||||
{"type": "battle", "id": "blackKing"}, // 强制战斗黑衣魔王
|
||||
{"type": "battle", "loc": [2,3]}, // 强制战斗(2,3)点的怪物
|
||||
],
|
||||
```
|
||||
|
||||
上面就是样板层中右上角的强制战斗例子。
|
||||
从V2.6开始,有两种写法:
|
||||
- 写id,则视为和空降怪物进行强制战斗,不会执行一些战后事件,也不会隐藏任何点。
|
||||
- 写loc(可选,不填默认当前点),则视为和某点怪物进行强制战斗,会隐藏该点并且插入该点战后事件执行。
|
||||
|
||||
如果强制战斗失败,则会立刻生命归0并死亡,调用lose函数,接下来的事件不会再被执行。
|
||||
强制战斗不会自动存档,如果战斗失败则立刻死亡。
|
||||
|
||||
强制战斗没有指定loc的选项,因此战斗后需要调用hide使怪物消失(如果有必要)。
|
||||
值得注意的是,如果是和某个点的怪物强制战斗,并且该点存在战后事件,执行时会**修改当前点坐标**为目标点。
|
||||
|
||||
### openDoor:开门
|
||||
|
||||
@ -867,7 +867,7 @@ name是可选的,代表目标行走图的文件名。
|
||||
[
|
||||
{"type": "openDoor", "loc": [3,6], "floorId": "MT1"}, // 打开MT1层的[3,6]位置的门
|
||||
{"type": "openDoor", "loc": [3,6]}, // 如果是本层则可省略floorId
|
||||
{"type": "openDoor", "loc": [3,6], "needKey": true} // 打开此门需要钥匙
|
||||
{"type": "openDoor", "loc": [3,6], "needKey": true, "async": true} // 打开此门需要钥匙,异步执行
|
||||
]
|
||||
```
|
||||
|
||||
@ -879,8 +879,12 @@ loc指定门的坐标,floorId指定门所在的楼层ID。如果是当前层
|
||||
|
||||
needKey是可选的,如果设置为true则需要钥匙才能打开此门。如果没有钥匙则跳过此事件。
|
||||
|
||||
async可选,如果为true则会异步执行(即不等待当前事件执行完毕,立刻执行下一个事件)。
|
||||
|
||||
!> needKey仅对当前楼层开门有效!跨楼层的门仍然不需要钥匙即可打开,如有需求请自行判定。
|
||||
|
||||
值得注意的是,如果该点存在开门事件,执行时会**修改当前点坐标**为目标点。
|
||||
|
||||
### closeDoor:关门
|
||||
|
||||
从V2.6开始提供了关门事件`{"type": "closeDoor"}`,拥有关门动画和对应的音效。
|
||||
@ -903,6 +907,8 @@ yellowWall, blueWall, whiteWall
|
||||
|
||||
loc可选,为要关的位置,不填默认为当前点。
|
||||
|
||||
async可选,如果为true则会异步执行(即不等待当前事件执行完毕,立刻执行下一个事件)。
|
||||
|
||||
关门事件需要保证该点是空地,否则将无视此事件。
|
||||
|
||||
### changeFloor:楼层切换
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# HTML5 魔塔样板说明文档
|
||||
|
||||
?> 目前版本**v2.6**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.6.1**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
众所周知,魔塔的趋势是向移动端发展,贴吧中也常常能见到“求手机魔塔”的帖子。然而现有的工具中,NekoRPG有着比较大的局限性,游戏感较差,更是完全没法在iOS上运行。而一些APP的魔塔虽然可用,但是必须要下载安装,对于Android和iOS还必须开发不同的版本,非常麻烦。
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# 个性化
|
||||
|
||||
?> 目前版本**v2.6**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.6.1**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
有时候只靠样板本身可能是不够的。我们需要一些个性化、自定义的素材,道具效果,怪物属性,等等。
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# 脚本
|
||||
|
||||
?> 目前版本**v2.6**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.6.1**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
在V2.6版本中,基本对整个项目代码进行了重写,更加方便造塔者的使用和复写函数。
|
||||
|
||||
@ -224,7 +224,11 @@ function () {
|
||||
- 清晰明了。很容易方便知道自己修改过什么,尤其是可以和系统原有代码进行对比。
|
||||
- 方便整理成新的插件,给其他的塔使用。
|
||||
|
||||
如果我想对xxx文件中的yyy函数进行重写,其模式一般是:`core.xxx.yyy = function (参数列表) { ... }`
|
||||
一般而言,复写规则如下:
|
||||
|
||||
**对xxx文件中的yyy函数进行复写,规则是`core.xxx.yyy = function (参数列表) { ... }`。**
|
||||
|
||||
但是,对于`registerXXX`所注册的函数是无效的,例如直接复写`core.control._animationFrame_globalAnimate`函数是没有效果的。对于这种情况引入的函数,需要注册同名函数,可参见最下面的样例。
|
||||
|
||||
下面是几个例子,从简单到复杂。
|
||||
|
||||
@ -317,6 +321,32 @@ core.maps.drawMap = function (floorId, callback) {
|
||||
|
||||
详见[call和apply的用法](https://www.jianshu.com/p/80ea0d1c04f8)。
|
||||
|
||||
### 复写全局动画绘制函数
|
||||
|
||||
全局动画绘制在`control.js`的`_animationFrame_globalAnimate`函数。
|
||||
|
||||
注意到此函数是由`registerAnimationFrame`注册的,因此直接复写是无效的。
|
||||
|
||||
其在control.js的注册的定义如下:
|
||||
|
||||
```js
|
||||
// 注册全局动画函数
|
||||
this.registerAnimationFrame("globalAnimate", true, this._animationFrame_globalAnimate);
|
||||
```
|
||||
|
||||
因此,可以在插件中自行注册一个**同名**的函数来覆盖原始的内容。
|
||||
|
||||
```js
|
||||
// 插件中复写全局动画绘制函数
|
||||
this.myGlobalAnimate = function (timestamp) {
|
||||
// ...... 实际复写的函数内容
|
||||
}
|
||||
|
||||
// 注册同名(globalAnimate)函数来覆盖系统原始内容
|
||||
core.registerAnimationFrame("globalAnimate", true, "myGlobalAnimate");
|
||||
```
|
||||
|
||||
|
||||
==========================================================================================
|
||||
|
||||
[继续阅读下一章:API列表](api)
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# 快速上手
|
||||
|
||||
?> 目前版本**v2.6**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.6.1**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
在这一节中,将详细介绍做一部塔的流程。现在,让我们来做一部单层塔!
|
||||
|
||||
|
||||
@ -287,6 +287,7 @@ action
|
||||
| wait_s
|
||||
| waitAsync_s
|
||||
| battle_s
|
||||
| battle_1_s
|
||||
| openDoor_s
|
||||
| closeDoor_s
|
||||
| changeFloor_s
|
||||
@ -441,7 +442,7 @@ helpUrl : https://h5mota.com/games/template/docs/#/event?id=settext%EF%BC%9A%E8%
|
||||
default : [null,"",null,"",'rgba(255,255,255,1)',"",'rgba(255,255,255,1)',"",'rgba(255,255,255,1)',null,"","",""]
|
||||
SetTextPosition_List_0 =SetTextPosition_List_0==='null'?'': ', "position": "'+SetTextPosition_List_0+'"';
|
||||
SetTextAlign_List_0 =SetTextAlign_List_0==='null'?'': ', "align": "'+SetTextAlign_List_0+'"';
|
||||
var colorRe = /^(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(,0(\.\d+)?|,1)?$/;
|
||||
var colorRe = MotaActionFunctions.pattern.colorRe;
|
||||
if (EvalString_0) {
|
||||
if (!/^\d+$/.test(EvalString_0))throw new Error('像素偏移量必须是整数或不填');
|
||||
EvalString_0 = ', "offset": '+EvalString_0;
|
||||
@ -587,7 +588,7 @@ default : ["","","",500,false]
|
||||
colour : this.mapColor
|
||||
var floorstr = '';
|
||||
if (EvalString_0 && EvalString_1) {
|
||||
var pattern1 = /^flag:([a-zA-Z0-9_\u4E00-\u9FCC]+)$/;
|
||||
var pattern1 = MotaActionFunctions.pattern.id;
|
||||
if(pattern1.test(EvalString_0) || pattern1.test(EvalString_1)){
|
||||
EvalString_0=MotaActionFunctions.PosString_pre(EvalString_0);
|
||||
EvalString_1=MotaActionFunctions.PosString_pre(EvalString_1);
|
||||
@ -620,7 +621,7 @@ default : ["","","",500,false]
|
||||
colour : this.mapColor
|
||||
var floorstr = '';
|
||||
if (EvalString_0 && EvalString_1) {
|
||||
var pattern1 = /^flag:([a-zA-Z0-9_\u4E00-\u9FCC]+)$/;
|
||||
var pattern1 = MotaActionFunctions.pattern.id;
|
||||
if(pattern1.test(EvalString_0) || pattern1.test(EvalString_1)){
|
||||
EvalString_0=MotaActionFunctions.PosString_pre(EvalString_0);
|
||||
EvalString_1=MotaActionFunctions.PosString_pre(EvalString_1);
|
||||
@ -643,15 +644,16 @@ return code;
|
||||
*/;
|
||||
|
||||
trigger_s
|
||||
: '触发事件' 'x' PosString ',' 'y' PosString Newline
|
||||
: '触发事件' 'x' PosString ',' 'y' PosString '不结束当前事件' Bool Newline
|
||||
|
||||
|
||||
/* trigger_s
|
||||
tooltip : trigger: 立即触发另一个地点的事件
|
||||
helpUrl : https://h5mota.com/games/template/docs/#/event?id=trigger%EF%BC%9A%E7%AB%8B%E5%8D%B3%E8%A7%A6%E5%8F%91%E5%8F%A6%E4%B8%80%E4%B8%AA%E5%9C%B0%E7%82%B9%E7%9A%84%E4%BA%8B%E4%BB%B6
|
||||
default : ["0","0"]
|
||||
default : ["0","0",false]
|
||||
colour : this.eventColor
|
||||
var code = '{"type": "trigger", "loc": ['+PosString_0+','+PosString_1+']},\n';
|
||||
Bool_0 = Bool_0 ?', "keep": true':'';
|
||||
var code = '{"type": "trigger", "loc": ['+PosString_0+','+PosString_1+']'+Bool_0+'},\n';
|
||||
return code;
|
||||
*/;
|
||||
|
||||
@ -761,7 +763,7 @@ default : ["","",""]
|
||||
colour : this.mapColor
|
||||
var floorstr = '';
|
||||
if (EvalString_0 && EvalString_1) {
|
||||
var pattern1 = /^flag:([a-zA-Z0-9_\u4E00-\u9FCC]+)$/;
|
||||
var pattern1 = MotaActionFunctions.pattern.id;
|
||||
if(pattern1.test(EvalString_0) || pattern1.test(EvalString_1)){
|
||||
EvalString_0=MotaActionFunctions.PosString_pre(EvalString_0);
|
||||
EvalString_1=MotaActionFunctions.PosString_pre(EvalString_1);
|
||||
@ -792,7 +794,7 @@ default : ["","",""]
|
||||
colour : this.mapColor
|
||||
var floorstr = '';
|
||||
if (EvalString_0 && EvalString_1) {
|
||||
var pattern1 = /^flag:([a-zA-Z0-9_\u4E00-\u9FCC]+)$/;
|
||||
var pattern1 = MotaActionFunctions.pattern.id;
|
||||
if(pattern1.test(EvalString_0) || pattern1.test(EvalString_1)){
|
||||
EvalString_0=MotaActionFunctions.PosString_pre(EvalString_0);
|
||||
EvalString_1=MotaActionFunctions.PosString_pre(EvalString_1);
|
||||
@ -823,7 +825,7 @@ default : ["bg","","",""]
|
||||
colour : this.mapColor
|
||||
var floorstr = '';
|
||||
if (EvalString_0 && EvalString_1) {
|
||||
var pattern1 = /^flag:([a-zA-Z0-9_\u4E00-\u9FCC]+)$/;
|
||||
var pattern1 = MotaActionFunctions.pattern.id;
|
||||
if(pattern1.test(EvalString_0) || pattern1.test(EvalString_1)){
|
||||
EvalString_0=MotaActionFunctions.PosString_pre(EvalString_0);
|
||||
EvalString_1=MotaActionFunctions.PosString_pre(EvalString_1);
|
||||
@ -854,7 +856,7 @@ default : ["bg","","",""]
|
||||
colour : this.mapColor
|
||||
var floorstr = '';
|
||||
if (EvalString_0 && EvalString_1) {
|
||||
var pattern1 = /^flag:([a-zA-Z0-9_\u4E00-\u9FCC]+)$/;
|
||||
var pattern1 = MotaActionFunctions.pattern.id;
|
||||
if(pattern1.test(EvalString_0) || pattern1.test(EvalString_1)){
|
||||
EvalString_0=MotaActionFunctions.PosString_pre(EvalString_0);
|
||||
EvalString_1=MotaActionFunctions.PosString_pre(EvalString_1);
|
||||
@ -984,14 +986,32 @@ var code = '{"type": "battle", "id": "'+IdString_0+'"},\n';
|
||||
return code;
|
||||
*/;
|
||||
|
||||
|
||||
battle_1_s
|
||||
: '强制战斗' 'x' PosString? ',' 'y' PosString? Newline
|
||||
|
||||
|
||||
/* battle_1_s
|
||||
tooltip : battle: 强制战斗
|
||||
helpUrl : https://h5mota.com/games/template/docs/#/event?id=battle%EF%BC%9A%E5%BC%BA%E5%88%B6%E6%88%98%E6%96%97
|
||||
default : ["","",""]
|
||||
colour : this.mapColor
|
||||
var floorstr = '';
|
||||
if (PosString_0 && PosString_1) {
|
||||
floorstr = ', "loc": ['+PosString_0+','+PosString_1+']';
|
||||
}
|
||||
var code = '{"type": "battle"'+floorstr+'},\n';
|
||||
return code;
|
||||
*/;
|
||||
|
||||
openDoor_s
|
||||
: '开门' 'x' PosString? ',' 'y' PosString? '楼层' IdString? '需要钥匙' Bool? Newline
|
||||
: '开门' 'x' PosString? ',' 'y' PosString? '楼层' IdString? '需要钥匙' Bool? '不等待执行完毕' Bool Newline
|
||||
|
||||
|
||||
/* openDoor_s
|
||||
tooltip : openDoor: 开门,楼层可不填表示当前层
|
||||
helpUrl : https://h5mota.com/games/template/docs/#/event?id=opendoor%EF%BC%9A%E5%BC%80%E9%97%A8
|
||||
default : ["","","",false]
|
||||
default : ["","","",false,false]
|
||||
colour : this.mapColor
|
||||
IdString_0 = IdString_0 && (', "floorId": "'+IdString_0+'"');
|
||||
var floorstr = '';
|
||||
@ -999,24 +1019,26 @@ if (PosString_0 && PosString_1) {
|
||||
floorstr = ', "loc": ['+PosString_0+','+PosString_1+']';
|
||||
}
|
||||
Bool_0 = Bool_0 ? ', "needKey": true' : '';
|
||||
var code = '{"type": "openDoor"'+floorstr+IdString_0+Bool_0+'},\n';
|
||||
Bool_1 = Bool_1 ? ', "async": true' : '';
|
||||
var code = '{"type": "openDoor"'+floorstr+IdString_0+Bool_0+Bool_1+'},\n';
|
||||
return code;
|
||||
*/;
|
||||
|
||||
closeDoor_s
|
||||
: '关门' 'x' PosString? ',' 'y' PosString? 'ID' IdString Newline
|
||||
: '关门' 'x' PosString? ',' 'y' PosString? 'ID' IdString '不等待执行完毕' Bool Newline
|
||||
|
||||
|
||||
/* closeDoor_s
|
||||
tooltip : closeDoor: 关门事件,需要该点本身无事件
|
||||
helpUrl : https://h5mota.com/games/template/docs/#/event?id=opendoor%EF%BC%9A%E5%BC%80%E9%97%A8
|
||||
default : ["","","yellowDoor"]
|
||||
default : ["","","yellowDoor",false]
|
||||
colour : this.mapColor
|
||||
var floorstr = '';
|
||||
if (PosString_0 && PosString_1) {
|
||||
floorstr = ', "loc": ['+PosString_0+','+PosString_1+']';
|
||||
}
|
||||
var code = '{"type": "closeDoor", "id": "'+IdString_0+'"'+floorstr+'},\n';
|
||||
Bool_0 = Bool_0 ? ', "async": true' : '';
|
||||
var code = '{"type": "closeDoor", "id": "'+IdString_0+'"'+floorstr+Bool_0+'},\n';
|
||||
return code;
|
||||
*/;
|
||||
|
||||
@ -1157,7 +1179,7 @@ helpUrl : https://h5mota.com/games/template/docs/#/event?id=animate%EF%BC%9A%E6%
|
||||
default : ["zone","hero",false]
|
||||
colour : this.soundColor
|
||||
if (EvalString_0) {
|
||||
if(/^flag:([a-zA-Z0-9_\u4E00-\u9FCC]+),flag:([a-zA-Z0-9_\u4E00-\u9FCC]+)$/.test(EvalString_0)) {
|
||||
if(MotaActionFunctions.pattern.id2.test(EvalString_0)) {
|
||||
EvalString_0=', "loc": ["'+EvalString_0.split(',').join('","')+'"]';
|
||||
} else if (/hero|([+-]?\d+),([+-]?\d+)/.test(EvalString_0)) {
|
||||
if(EvalString_0.indexOf(',')!==-1)EvalString_0='['+EvalString_0+']';
|
||||
@ -1293,7 +1315,7 @@ tooltip : setCurtain: 更改画面色调,动画时间可不填
|
||||
helpUrl : https://h5mota.com/games/template/docs/#/event?id=setcurtain%EF%BC%9A%E6%9B%B4%E6%94%B9%E7%94%BB%E9%9D%A2%E8%89%B2%E8%B0%83
|
||||
default : ["255,255,255,1",'rgba(255,255,255,1)',500,false]
|
||||
colour : this.soundColor
|
||||
var colorRe = /^(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(,0(\.\d+)?|,1)?$/;
|
||||
var colorRe = MotaActionFunctions.pattern.colorRe;
|
||||
if (!colorRe.test(EvalString_0))throw new Error('颜色格式错误,形如:0~255,0~255,0~255,0~1');
|
||||
Int_0 = Int_0!=='' ?(', "time": '+Int_0):'';
|
||||
var async = Bool_0?', "async": true':'';
|
||||
@ -1324,7 +1346,7 @@ tooltip : screenFlash: 画面闪烁,动画时间可不填
|
||||
helpUrl : https://h5mota.com/games/template/docs/#/event?id=screenFlash%EF%BC%9A%E7%94%BB%E9%9D%A2%E9%97%AA%E7%83%81
|
||||
default : ["255,255,255,1",'rgba(255,255,255,1)',500,1,false]
|
||||
colour : this.soundColor
|
||||
var colorRe = /^(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(,0(\.\d+)?|,1)?$/;
|
||||
var colorRe = MotaActionFunctions.pattern.colorRe;
|
||||
if (!colorRe.test(EvalString_0))throw new Error('颜色格式错误,形如:0~255,0~255,0~255,0~1');
|
||||
Int_1 = Int_1!=='' ?(', "times": '+Int_1):'';
|
||||
var async = Bool_0?', "async": true':'';
|
||||
@ -1354,7 +1376,7 @@ move_s
|
||||
/* move_s
|
||||
tooltip : move: 让某个NPC/怪物移动,位置可不填代表当前事件
|
||||
helpUrl : https://h5mota.com/games/template/docs/#/event?id=move%EF%BC%9A%E8%AE%A9%E6%9F%90%E4%B8%AAnpc%E6%80%AA%E7%89%A9%E7%A7%BB%E5%8A%A8
|
||||
default : ["","",500,false,false,"上右3下2左上左2"]
|
||||
default : ["","",500,false,false,"上右3下2后4左前2"]
|
||||
colour : this.mapColor
|
||||
var floorstr = '';
|
||||
if (PosString_0 && PosString_1) {
|
||||
@ -1682,7 +1704,7 @@ helpUrl : https://h5mota.com/games/template/docs/#/event?id=choices%EF%BC%9A%E7%
|
||||
default : ["提示文字:红钥匙","",""]
|
||||
colour : this.subColor
|
||||
if (EvalString_1) {
|
||||
var colorRe = /^(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(,0(\.\d+)?|,1)?$/;
|
||||
var colorRe = MotaActionFunctions.pattern.colorRe;
|
||||
if (colorRe.test(EvalString_1))
|
||||
EvalString_1 = ', "color": ['+EvalString_1+']';
|
||||
else
|
||||
@ -1735,7 +1757,7 @@ return code;
|
||||
*/;
|
||||
|
||||
break_s
|
||||
: '跳出循环' Newline
|
||||
: '跳出当前循环或公共事件' Newline
|
||||
|
||||
/* break_s
|
||||
tooltip : break:跳出循环, 如果break事件不在任何循环中被执行,则和exit等价,即会立刻结束当前事件!
|
||||
@ -2113,8 +2135,8 @@ FixedId_List
|
||||
/*FixedId_List ['status:hp','status:atk','status:def','status:mdef','item:yellowKey','item:blueKey','item:redKey','status:money','status:experience']*/;
|
||||
|
||||
Id_List
|
||||
: '变量' | '状态' | '物品' | '独立开关'
|
||||
/*Id_List ['flag','status','item', 'switch']*/;
|
||||
: '变量' | '状态' | '物品' | '独立开关' | '全局存储'
|
||||
/*Id_List ['flag','status','item', 'switch', 'global']*/;
|
||||
|
||||
//转blockly后不保留需要加"
|
||||
EvalString
|
||||
@ -2532,12 +2554,12 @@ ActionParser.prototype.parseAction = function() {
|
||||
case "openDoor": // 开一个门, 包括暗墙
|
||||
data.loc=data.loc||['','']
|
||||
this.next = MotaActionBlocks['openDoor_s'].xmlText([
|
||||
data.loc[0],data.loc[1],data.floorId||'',data.needKey||false,this.next]);
|
||||
data.loc[0],data.loc[1],data.floorId||'',data.needKey||false,data.async||false,this.next]);
|
||||
break;
|
||||
case "closeDoor": // 关一个门,需要该点无事件
|
||||
data.loc=data.loc||['','']
|
||||
this.next = MotaActionBlocks['closeDoor_s'].xmlText([
|
||||
data.loc[0],data.loc[1],data.id,this.next]);
|
||||
data.loc[0],data.loc[1],data.id,data.async||false,this.next]);
|
||||
break;
|
||||
case "useItem": // 使用道具
|
||||
this.next = MotaActionBlocks['useItem_s'].xmlText([
|
||||
@ -2552,12 +2574,19 @@ ActionParser.prototype.parseAction = function() {
|
||||
data.id,this.next]);
|
||||
break;
|
||||
case "battle": // 强制战斗
|
||||
this.next = MotaActionBlocks['battle_s'].xmlText([
|
||||
data.id,this.next]);
|
||||
if (data.id) {
|
||||
this.next = MotaActionBlocks['battle_s'].xmlText([
|
||||
data.id,this.next]);
|
||||
}
|
||||
else {
|
||||
data.loc = data.loc || [];
|
||||
this.next = MotaActionBlocks['battle_1_s'].xmlText([
|
||||
data.loc[0],data.loc[1],this.next]);
|
||||
}
|
||||
break;
|
||||
case "trigger": // 触发另一个事件;当前事件会被立刻结束。需要另一个地点的事件是有效的
|
||||
this.next = MotaActionBlocks['trigger_s'].xmlText([
|
||||
data.loc[0],data.loc[1],this.next]);
|
||||
data.loc[0],data.loc[1],data.keep,this.next]);
|
||||
break;
|
||||
case "insert": // 强制插入另一个点的事件在当前事件列表执行,当前坐标和楼层不会改变
|
||||
if (data.args instanceof Array) {
|
||||
@ -2857,14 +2886,14 @@ MotaActionFunctions.EvalString_pre = function(EvalString){
|
||||
|
||||
MotaActionFunctions.IdString_pre = function(IdString){
|
||||
if (IdString.indexOf('__door__')!==-1) throw new Error('请修改开门变量__door__,如door1,door2,door3等依次向后。请勿存在两个门使用相同的开门变量。');
|
||||
if (IdString && !(/^flag:([a-zA-Z0-9_\u4E00-\u9FCC]+)$/.test(IdString)) && !(/^[0-9a-zA-Z_][0-9a-zA-Z_\-:]*$/.test(IdString)))
|
||||
if (IdString && !(MotaActionFunctions.pattern.id.test(IdString)) && !(MotaActionFunctions.pattern.idWithoutFlag.test(IdString)))
|
||||
throw new Error('id: '+IdString+'中包含了0-9 a-z A-Z _ - :之外的字符');
|
||||
return IdString;
|
||||
}
|
||||
|
||||
MotaActionFunctions.PosString_pre = function(PosString){
|
||||
if (!PosString || /^-?\d+$/.test(PosString)) return PosString;
|
||||
if (!(/^flag:([a-zA-Z0-9_\u4E00-\u9FCC]+)$/.test(PosString)))throw new Error(PosString+'中包含了0-9 a-z A-Z _ 和中文之外的字符,或者是没有以flag: 开头');
|
||||
if (!(MotaActionFunctions.pattern.id.test(PosString)))throw new Error(PosString+'中包含了0-9 a-z A-Z _ 和中文之外的字符,或者是没有以flag: 开头');
|
||||
return '"'+PosString+'"';
|
||||
}
|
||||
|
||||
@ -2906,4 +2935,10 @@ MotaActionFunctions.StepString_pre = function(StepString){
|
||||
return ans;
|
||||
}
|
||||
|
||||
MotaActionFunctions.pattern=MotaActionFunctions.pattern||{};
|
||||
MotaActionFunctions.pattern.id=/^flag:([a-zA-Z0-9_\u4E00-\u9FCC]+)$/;
|
||||
MotaActionFunctions.pattern.id2=/^flag:([a-zA-Z0-9_\u4E00-\u9FCC]+),flag:([a-zA-Z0-9_\u4E00-\u9FCC]+)$/;
|
||||
MotaActionFunctions.pattern.idWithoutFlag=/^[0-9a-zA-Z_][0-9a-zA-Z_\-:]*$/;
|
||||
MotaActionFunctions.pattern.colorRe=/^(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(,0(\.\d+)?|,1)?$/;
|
||||
|
||||
*/
|
||||
@ -42,8 +42,6 @@ editor.util.guid()//产生一个可以作为id的长随机字符串
|
||||
|
||||
提供了以下函数进行楼层`map`数组相关的操作
|
||||
```javascript
|
||||
editor.file.getFloorFileList
|
||||
editor.file.loadFloorFile
|
||||
editor.file.saveFloorFile
|
||||
editor.file.saveFloorFileAs
|
||||
```
|
||||
|
||||
@ -53,6 +53,7 @@ editor.prototype.init = function (callback) {
|
||||
editor_file_wrapper(editor);
|
||||
editor_table_wrapper(editor);
|
||||
editor_unsorted_1_wrapper(editor);
|
||||
editor.printe=printe;
|
||||
afterMainInit();
|
||||
});
|
||||
|
||||
|
||||
@ -112,6 +112,7 @@ editor_blockly = function () {
|
||||
MotaActionBlocks['unfollow_s'].xmlText(),
|
||||
],
|
||||
'地图处理':[
|
||||
MotaActionBlocks['battle_1_s'].xmlText(),
|
||||
MotaActionBlocks['openDoor_s'].xmlText(),
|
||||
MotaActionBlocks['closeDoor_s'].xmlText(),
|
||||
MotaActionBlocks['show_s'].xmlText(),
|
||||
|
||||
@ -3,6 +3,7 @@ editor_file_wrapper = function (editor) {
|
||||
|
||||
}
|
||||
|
||||
// 这个函数之后挪到editor.table?
|
||||
editor_file_proto.prototype.loadCommentjs=function(callback){
|
||||
var commentjs = {
|
||||
'comment': 'comment',
|
||||
|
||||
@ -7,23 +7,6 @@ editor_file = function (editor, callback) {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
editor.file.getFloorFileList = function (callback) {
|
||||
checkCallback(callback);
|
||||
/* var fs = editor.fs;
|
||||
fs.readdir('project/floors',function(err, data){
|
||||
callback([data,err]);
|
||||
}); */
|
||||
callback([editor.core.floorIds, null]);
|
||||
}
|
||||
//callback([Array<String>,err:String])
|
||||
editor.file.loadFloorFile = function (filename, callback) {
|
||||
//filename不含'/'不含'.js'
|
||||
checkCallback(callback);
|
||||
|
||||
editor.currentFloorId = editor.core.status.floorId;
|
||||
editor.currentFloorData = editor.core.floors[editor.currentFloorId];
|
||||
}
|
||||
//callback(err:String)
|
||||
editor.file.saveFloorFile = function (callback) {
|
||||
checkCallback(callback);
|
||||
/* if (!isset(editor.currentFloorId) || !isset(editor.currentFloorData)) {
|
||||
@ -31,31 +14,16 @@ editor_file = function (editor, callback) {
|
||||
} */
|
||||
var filename = 'project/floors/' + editor.currentFloorId + '.js';
|
||||
var datastr = ['main.floors.', editor.currentFloorId, '=\n'];
|
||||
if (editor.currentFloorData.map == 'new') {
|
||||
/*
|
||||
editor.currentFloorData.map = editor.map.map(function (v) {
|
||||
return v.map(function () {
|
||||
return 0
|
||||
|
||||
for(var ii=0,name;name=['map','bgmap','fgmap'][ii];ii++){
|
||||
var mapArray=editor[name].map(function (v) {
|
||||
return v.map(function (v) {
|
||||
return v.idnum || v || 0
|
||||
})
|
||||
});
|
||||
*/
|
||||
var width = parseInt(document.getElementById('newMapWidth').value);
|
||||
var height = parseInt(document.getElementById('newMapHeight').value);
|
||||
var row = [];
|
||||
for (var i=0;i<width;i++) row.push(0);
|
||||
editor.currentFloorData.map = [];
|
||||
for (var i=0;i<height;i++) editor.currentFloorData.map.push(row);
|
||||
}
|
||||
else{
|
||||
for(var ii=0,name;name=['map','bgmap','fgmap'][ii];ii++){
|
||||
var mapArray=editor[name].map(function (v) {
|
||||
return v.map(function (v) {
|
||||
return v.idnum || v || 0
|
||||
})
|
||||
});
|
||||
editor.currentFloorData[name]=mapArray;
|
||||
}
|
||||
editor.currentFloorData[name]=mapArray;
|
||||
}
|
||||
|
||||
// format 更改实现方式以支持undefined删除
|
||||
var tempJsonObj=Object.assign({},editor.currentFloorData);
|
||||
var tempMap=[['map',editor.util.guid()],['bgmap',editor.util.guid()],['fgmap',editor.util.guid()]];
|
||||
@ -87,39 +55,35 @@ editor_file = function (editor, callback) {
|
||||
name = saveFilename.substring(2);
|
||||
title = "主塔 "+name+" 层";
|
||||
}
|
||||
editor.currentFloorData = {
|
||||
|
||||
var width = parseInt(document.getElementById('newMapsWidth').value);
|
||||
var height = parseInt(document.getElementById('newMapsHeight').value);
|
||||
var row = [], map = [];
|
||||
for (var i=0;i<width;i++) row.push(0);
|
||||
for (var i=0;i<height;i++) map.push(row);
|
||||
editor.currentFloorData = Object.assign(JSON.parse(JSON.stringify(editor.file.comment._data.floors_template)), {
|
||||
floorId: saveFilename,
|
||||
title: title,
|
||||
name: name,
|
||||
width: parseInt(document.getElementById('newMapWidth').value),
|
||||
height: parseInt(document.getElementById('newMapHeight').value),
|
||||
canFlyTo: saveStatus?currData.canFlyTo:true,
|
||||
canUseQuickShop: saveStatus?currData.canUseQuickShop:true,
|
||||
cannotViewMap: saveStatus?currData.cannotViewMap:false,
|
||||
cannotMoveDirectly: saveStatus?currData.cannotMoveDirectly:false,
|
||||
images: [],
|
||||
item_ratio: saveStatus?currData.item_ratio:1,
|
||||
defaultGround: saveStatus?currData.defaultGround:"ground",
|
||||
bgm: saveStatus?currData.bgm:null,
|
||||
upFloor: null,
|
||||
downFloor: null,
|
||||
color: saveStatus?currData.color:null,
|
||||
weather: saveStatus?currData.weather:null,
|
||||
firstArrive: [],
|
||||
eachArrive: [],
|
||||
parallelDo: "",
|
||||
events: {},
|
||||
changeFloor: {},
|
||||
afterBattle: {},
|
||||
afterGetItem: {},
|
||||
afterOpenDoor: {},
|
||||
cannotMove: {}
|
||||
};
|
||||
width: width,
|
||||
height: height,
|
||||
map: map,
|
||||
},saveStatus?{
|
||||
canFlyTo: currData.canFlyTo,
|
||||
canUseQuickShop: currData.canUseQuickShop,
|
||||
cannotViewMap: currData.cannotViewMap,
|
||||
cannotMoveDirectly: currData.cannotMoveDirectly,
|
||||
item_ratio: currData.item_ratio,
|
||||
defaultGround: currData.defaultGround,
|
||||
bgm: currData.bgm,
|
||||
color: currData.color,
|
||||
weather: currData.weather,
|
||||
}:{});
|
||||
|
||||
Object.keys(editor.currentFloorData).forEach(function (t) {
|
||||
if (editor.currentFloorData[t] == null)
|
||||
delete editor.currentFloorData[t];
|
||||
})
|
||||
editor.currentFloorData.map = "new";
|
||||
editor.currentFloorId = saveFilename;
|
||||
editor.file.saveFloorFile(callback);
|
||||
}
|
||||
@ -145,35 +109,24 @@ editor_file = function (editor, callback) {
|
||||
var datas = [];
|
||||
for (var i=from;i<=to;i++) {
|
||||
var datastr = ['main.floors.', floorIdList[i-from], '=\n{'];
|
||||
var data = {
|
||||
var data = Object.assign(JSON.parse(JSON.stringify(editor.file.comment._data.floors_template)), {
|
||||
floorId: floorIdList[i-from],
|
||||
title: calValue(document.getElementById('newFloorTitles').value, i),
|
||||
name: calValue(document.getElementById('newFloorNames').value, i),
|
||||
width: width,
|
||||
height: height,
|
||||
map: map,
|
||||
canFlyTo: saveStatus?currData.canFlyTo:true,
|
||||
canUseQuickShop: saveStatus?currData.canUseQuickShop:true,
|
||||
cannotViewMap: saveStatus?currData.cannotViewMap:false,
|
||||
cannotMoveDirectly: saveStatus?currData.cannotMoveDirectly:false,
|
||||
images: [],
|
||||
item_ratio: saveStatus?currData.item_ratio:1,
|
||||
defaultGround: saveStatus?currData.defaultGround:"ground",
|
||||
bgm: saveStatus?currData.bgm:null,
|
||||
upFloor: null,
|
||||
downFloor: null,
|
||||
color: saveStatus?currData.color:null,
|
||||
weather: saveStatus?currData.weather:null,
|
||||
firstArrive: [],
|
||||
eachArrive: [],
|
||||
parallelDo: "",
|
||||
events: {},
|
||||
changeFloor: {},
|
||||
afterBattle: {},
|
||||
afterGetItem: {},
|
||||
afterOpenDoor: {},
|
||||
cannotMove: {}
|
||||
};
|
||||
},saveStatus?{
|
||||
canFlyTo: currData.canFlyTo,
|
||||
canUseQuickShop: currData.canUseQuickShop,
|
||||
cannotViewMap: currData.cannotViewMap,
|
||||
cannotMoveDirectly: currData.cannotMoveDirectly,
|
||||
item_ratio: currData.item_ratio,
|
||||
defaultGround: currData.defaultGround,
|
||||
bgm: currData.bgm,
|
||||
color: currData.color,
|
||||
weather: currData.weather,
|
||||
}:{});
|
||||
Object.keys(data).forEach(function (t) {
|
||||
if (data[t] == null)
|
||||
delete data[t];
|
||||
@ -308,70 +261,78 @@ editor_file = function (editor, callback) {
|
||||
|
||||
editor.file.changeIdAndIdnum = function (id, idnum, info, callback) {
|
||||
checkCallback(callback);
|
||||
//检查maps中是否有重复的idnum或id
|
||||
var change = -1;
|
||||
for (var ii in editor.core.maps.blocksInfo) {
|
||||
if (ii == idnum) {
|
||||
//暂时只允许创建新的不允许修改已有的
|
||||
//if (info.idnum==idnum){change=ii;break;}//修改id
|
||||
callback('idnum重复了');
|
||||
return;
|
||||
}
|
||||
if (editor.core.maps.blocksInfo[ii].id == id) {
|
||||
//if (info.id==id){change=ii;break;}//修改idnum
|
||||
callback('id重复了');
|
||||
return;
|
||||
}
|
||||
}
|
||||
/*
|
||||
if (change!=-1 && change!=idnum){//修改idnum
|
||||
editor.core.maps.blocksInfo[idnum] = editor.core.maps.blocksInfo[change];
|
||||
delete(editor.core.maps.blocksInfo[change]);
|
||||
} else if (change==idnum) {//修改id
|
||||
var oldid = editor.core.maps.blocksInfo[idnum].id;
|
||||
editor.core.maps.blocksInfo[idnum].id = id;
|
||||
for(var ii in editor.core.icons.icons){
|
||||
if (ii.hasOwnProperty(oldid)){
|
||||
ii[id]=ii[oldid];
|
||||
delete(ii[oldid]);
|
||||
}
|
||||
}
|
||||
} else {//创建新的
|
||||
editor.core.maps.blocksInfo[idnum]={'cls': info.images, 'id':id};
|
||||
editor.core.icons.icons[info.images][id]=info.y;
|
||||
}
|
||||
*/
|
||||
var templist = [];
|
||||
var tempcallback = function (err) {
|
||||
templist.push(err);
|
||||
if (templist.length == 2) {
|
||||
if (templist[0] != null || templist[1] != null)
|
||||
callback((templist[0] || '') + '\n' + (templist[1] || ''));
|
||||
//这里如果一个成功一个失败会出严重bug
|
||||
else
|
||||
callback(null);
|
||||
}
|
||||
}
|
||||
saveSetting('maps', [["add", "['" + idnum + "']", {'cls': info.images, 'id': id}]], tempcallback);
|
||||
saveSetting('icons', [["add", "['" + info.images + "']['" + id + "']", info.y]], tempcallback);
|
||||
if (info.images === 'items') {
|
||||
saveSetting('items', [["add", "['items']['" + id + "']", editor.file.comment._data.items_template]], function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw(err)
|
||||
|
||||
var changeOrNew=core.isset(editor_mode.info.id)?'change':'new'
|
||||
if(changeOrNew=='new'){
|
||||
//检查maps中是否有重复的idnum或id
|
||||
for (var ii in editor.core.maps.blocksInfo) {
|
||||
if (ii == idnum) {
|
||||
callback('idnum重复了');
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (info.images === 'enemys' || info.images === 'enemy48') {
|
||||
saveSetting('enemys', [["add", "['" + id + "']", editor.file.comment._data.enemys_template]], function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw(err)
|
||||
if (editor.core.maps.blocksInfo[ii].id == id) {
|
||||
callback('id重复了');
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
var templist = [];
|
||||
var tempcallback = function (err) {
|
||||
templist.push(err);
|
||||
if (templist.length == 2) {
|
||||
if (templist[0] != null || templist[1] != null)
|
||||
callback((templist[0] || '') + '\n' + (templist[1] || ''));
|
||||
//这里如果一个成功一个失败会出严重bug
|
||||
else
|
||||
callback(null);
|
||||
}
|
||||
}
|
||||
saveSetting('maps', [["add", "['" + idnum + "']", {'cls': info.images, 'id': id}]], tempcallback);
|
||||
saveSetting('icons', [["add", "['" + info.images + "']['" + id + "']", info.y]], tempcallback);
|
||||
if (info.images === 'items') {
|
||||
saveSetting('items', [["add", "['items']['" + id + "']", editor.file.comment._data.items_template]], function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw(err)
|
||||
}
|
||||
});
|
||||
}
|
||||
if (info.images === 'enemys' || info.images === 'enemy48') {
|
||||
saveSetting('enemys', [["add", "['" + id + "']", editor.file.comment._data.enemys_template]], function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw(err)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
callback(null);
|
||||
callback(null);
|
||||
|
||||
}else{
|
||||
//检查maps中是否有重复的idnum或id
|
||||
for (var ii in editor.core.maps.blocksInfo) {
|
||||
if (editor.core.maps.blocksInfo[ii].id == id) {
|
||||
callback('id重复了');
|
||||
return;
|
||||
}
|
||||
}
|
||||
idnum = info.idnum;
|
||||
|
||||
maps_90f36752_8815_4be8_b32b_d7fad1d0542e[idnum].id = id;
|
||||
|
||||
var arr=[icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1,items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a,{enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80:enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80}]
|
||||
arr.forEach(function (obj) {
|
||||
for(var jj in obj){
|
||||
var ii=obj[jj]
|
||||
if (ii.hasOwnProperty(info.id)){
|
||||
ii[id]=ii[info.id];
|
||||
delete(ii[info.id]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
editor.file.save_icons_maps_items_enemys(callback)
|
||||
|
||||
}
|
||||
}
|
||||
//callback(err:String)
|
||||
editor.file.editItem = function (id, actionList, callback) {
|
||||
@ -770,6 +731,30 @@ editor_file = function (editor, callback) {
|
||||
}
|
||||
}
|
||||
|
||||
editor.file.save_icons_maps_items_enemys=function(callback){
|
||||
var check=[]
|
||||
saveSetting('icons',[],function(err){
|
||||
if(err){callback(err);return;}
|
||||
check.push('icons')
|
||||
if(check.length==4)callback(null);
|
||||
})
|
||||
saveSetting('maps',[],function(err){
|
||||
if(err){callback(err);return;}
|
||||
check.push('maps')
|
||||
if(check.length==4)callback(null);
|
||||
})
|
||||
saveSetting('items',[],function(err){
|
||||
if(err){callback(err);return;}
|
||||
check.push('items')
|
||||
if(check.length==4)callback(null);
|
||||
})
|
||||
saveSetting('enemys',[],function(err){
|
||||
if(err){callback(err);return;}
|
||||
check.push('enemys')
|
||||
if(check.length==4)callback(null);
|
||||
})
|
||||
}
|
||||
|
||||
var saveSetting = function (file, actionList, callback) {
|
||||
//console.log(file);
|
||||
//console.log(actionList);
|
||||
|
||||
@ -5,7 +5,10 @@ editor_game_wrapper = function (editor, main, core) {
|
||||
this.replacerRecord = {}
|
||||
}
|
||||
|
||||
|
||||
//////////////////// 修改数据相关 ////////////////////
|
||||
// 三个 replacer 和 replacerRecord 暂时放在此处
|
||||
|
||||
editor_game.prototype.replacerForLoading = function (_key, value) {
|
||||
var rmap = editor.game.replacerRecord;
|
||||
if (value instanceof Function) {
|
||||
@ -29,7 +32,7 @@ editor_game_wrapper = function (editor, main, core) {
|
||||
return value
|
||||
}
|
||||
|
||||
editor_game.prototype.getValue = function(field){
|
||||
editor_game.prototype.getValue = function (field) {
|
||||
var rmap = editor.game.replacerRecord;
|
||||
var value = eval(field)
|
||||
if (rmap.hasOwnProperty(oldval)) {
|
||||
@ -39,13 +42,13 @@ editor_game_wrapper = function (editor, main, core) {
|
||||
}
|
||||
}
|
||||
|
||||
editor_game.prototype.setValue = function(field,value){
|
||||
editor_game.prototype.setValue = function (field, value) {
|
||||
var rmap = editor.game.replacerRecord;
|
||||
var oldval = eval(field)
|
||||
if (rmap.hasOwnProperty(oldval)) {
|
||||
rmap[value]=eval(value)
|
||||
rmap[value] = eval(value)
|
||||
} else {
|
||||
eval(field+'='+value)
|
||||
eval(field + '=' + value)
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,6 +65,9 @@ editor_game_wrapper = function (editor, main, core) {
|
||||
data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = JSON.parse(JSON.stringify(data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d, rf));
|
||||
}
|
||||
|
||||
//////////////////// 加载游戏数据相关 ////////////////////
|
||||
|
||||
// 初始化数字与地图图块的对应
|
||||
editor_game.prototype.idsInit = function (maps, icons) {
|
||||
editor.ids = [0];
|
||||
editor.indexs = [];
|
||||
@ -125,6 +131,7 @@ editor_game_wrapper = function (editor, main, core) {
|
||||
}
|
||||
}
|
||||
|
||||
// 获取当前地图
|
||||
editor_game.prototype.fetchMapFromCore = function () {
|
||||
var mapArray = core.maps.saveMap(core.status.floorId);
|
||||
editor.map = mapArray.map(function (v) {
|
||||
@ -158,6 +165,16 @@ editor_game_wrapper = function (editor, main, core) {
|
||||
}
|
||||
}
|
||||
|
||||
// 获取地图列表
|
||||
editor_game.prototype.getFloorFileList = function (callback) {
|
||||
// callback([Array<String>,err:String])
|
||||
editor.util.checkCallback(callback);
|
||||
/* editor.fs.readdir('project/floors',function(err, data){
|
||||
callback([data,err]);
|
||||
}); */
|
||||
callback([editor.core.floorIds, null]);
|
||||
}
|
||||
|
||||
editor.constructor.prototype.game = new editor_game();
|
||||
}
|
||||
//editor_game_wrapper(editor);
|
||||
@ -145,13 +145,15 @@ editor_mode = function (editor) {
|
||||
|
||||
if (!core.isset(editor_mode.info.id)) {
|
||||
// document.getElementById('table_a3f03d4c_55b8_4ef6_b362_b345783acd72').innerHTML = '';
|
||||
document.getElementById('enemyItemTable').style.display = 'none';
|
||||
document.getElementById('newIdIdnum').style.display = 'block';
|
||||
document.getElementById('enemyItemTable').style.display = 'none';
|
||||
document.getElementById('changeId').style.display = 'none';
|
||||
return;
|
||||
}
|
||||
|
||||
document.getElementById('newIdIdnum').style.display = 'none';
|
||||
document.getElementById('enemyItemTable').style.display = 'block';
|
||||
document.getElementById('changeId').style.display = 'block';
|
||||
|
||||
var objs = [];
|
||||
if (editor_mode.info.images == 'enemys' || editor_mode.info.images == 'enemy48') {
|
||||
|
||||
@ -19,7 +19,7 @@ editor_unsorted_2_wrapper=function(editor_mode){
|
||||
printe(err);
|
||||
throw(err)
|
||||
}
|
||||
printe('添加id的idnum成功,请F5刷新编辑器');
|
||||
printe('添加id和idnum成功,请F5刷新编辑器');
|
||||
});
|
||||
} else {
|
||||
printe('请输入id和idnum');
|
||||
@ -36,8 +36,28 @@ editor_unsorted_2_wrapper=function(editor_mode){
|
||||
})
|
||||
}
|
||||
|
||||
var changeId = document.getElementById('changeId');
|
||||
changeId.children[1].onclick = function () {
|
||||
var id = changeId.children[0].value;
|
||||
if (id) {
|
||||
if (!/^[0-9a-zA-Z_]+$/.test(id)) {
|
||||
printe('不合法的id,请使用字母、数字或下划线')
|
||||
return;
|
||||
}
|
||||
editor.file.changeIdAndIdnum(id, null, editor_mode.info, function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw(err);
|
||||
}
|
||||
printe('修改id成功,请F5刷新编辑器');
|
||||
});
|
||||
} else {
|
||||
printe('请输入要修改到的ID');
|
||||
}
|
||||
}
|
||||
|
||||
var selectFloor = document.getElementById('selectFloor');
|
||||
editor.file.getFloorFileList(function (floors) {
|
||||
editor.game.getFloorFileList(function (floors) {
|
||||
var outstr = [];
|
||||
floors[0].forEach(function (floor) {
|
||||
outstr.push(["<option value='", floor, "'>", floor, '</option>\n'].join(''));
|
||||
@ -165,6 +185,41 @@ editor_unsorted_2_wrapper=function(editor_mode){
|
||||
});
|
||||
}
|
||||
|
||||
var changeFloorId = document.getElementById('changeFloorId');
|
||||
changeFloorId.children[1].onclick = function () {
|
||||
var floorId = changeFloorId.children[0].value;
|
||||
if (floorId) {
|
||||
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(floorId)) {
|
||||
printe("楼层名 "+floorId+" 不合法!请使用字母、数字、下划线,且不能以数字开头!");
|
||||
return;
|
||||
}
|
||||
if (main.floorIds.indexOf(floorId)>=0) {
|
||||
printe("楼层名 "+floorId+" 已存在!");
|
||||
return;
|
||||
}
|
||||
var currentFloorId = editor.currentFloorId;
|
||||
editor.currentFloorId = floorId;
|
||||
editor.currentFloorData.floorId = floorId;
|
||||
editor.file.saveFloorFile(function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw(err);
|
||||
}
|
||||
core.floorIds[core.floorIds.indexOf(currentFloorId)] = floorId;
|
||||
editor.file.editTower([['change', "['main']['floorIds']", core.floorIds]], function (objs_) {//console.log(objs_);
|
||||
if (objs_.slice(-1)[0] != null) {
|
||||
printe(objs_.slice(-1)[0]);
|
||||
throw(objs_.slice(-1)[0])
|
||||
}
|
||||
alert("修改floorId成功,需要刷新编辑器生效。\n请注意,原始的楼层文件没有删除,请根据需要手动删除。");
|
||||
window.location.reload();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
printe('请输入要修改到的floorId');
|
||||
}
|
||||
}
|
||||
|
||||
var ratio = 1;
|
||||
var appendPicCanvas = document.getElementById('appendPicCanvas');
|
||||
var bg = appendPicCanvas.children[0];
|
||||
|
||||
@ -157,6 +157,17 @@ editor_util_wrapper = function (editor) {
|
||||
}).join(''))
|
||||
}
|
||||
|
||||
editor_util.prototype.isset = function (val) {
|
||||
return val != null && !(typeof val == 'number' && isNaN(val));
|
||||
}
|
||||
|
||||
editor_util.prototype.checkCallback=function(callback){
|
||||
if (!editor.util.isset(callback)) {
|
||||
editor.printe('未设置callback');
|
||||
throw('未设置callback')
|
||||
}
|
||||
}
|
||||
|
||||
editor.constructor.prototype.util = new editor_util();
|
||||
}
|
||||
//editor_util_wrapper(editor);
|
||||
@ -1,18 +1,27 @@
|
||||
# 重构
|
||||
|
||||
总体思路
|
||||
+ 按功能拆分文件
|
||||
+ 左侧页面模块化, 方便添加
|
||||
+ 不同的模式的文件操作尽可能模块化
|
||||
|
||||
目前主要在重构editor_file, 思路是editor.file负责把editor.game内的游戏数据格式化成字符串以及写入到文件, 由editor.game来修改数据
|
||||
+ editor.file维护一些标记, 描述哪些数据需要格式化并写入, 在save时写入文件(自动保存的话就是每次修改数据都触发save)
|
||||
+ editor.game修改数据, 并修改editor.file中的标记
|
||||
+ 此思路下editor.file的大部分内容会挪到editor.game, editor.game和editor.table可能会再进一步合并拆分
|
||||
|
||||
editor_file之后是更改editor.map的储存方式, 现有的存对象的模式要在对象和数字间来回转换, 非常繁琐和奇怪
|
||||
|
||||
再之后是把editor_unsorted_*.js整理清晰
|
||||
|
||||
## 文件结构
|
||||
|
||||
+ [ ] editor_blockly 图块化事件编辑器
|
||||
+ [ ] editor_multi 多行文本编辑器
|
||||
+ [x] editor_table 处理表格的生成, 及其响应的事件, 从原editor\_mode中分离
|
||||
+ [ ] editor_file 调用fs.js编辑文件, 把原editor\_file模块化
|
||||
+ [ ] editor_game 处理来自core的数据, 导入为editor的数据, 从原editor中分离. **只有此文件允许`\s(main|core)`形式的调用**(以及其初始化`editor_game_wrapper(editor, main, core);`)
|
||||
+ [x] editor_util 生成guid等函数, 从editor分离
|
||||
+ [ ] editor_file 调用fs.js编辑文件, 把原editor\_file模块化, 并且只负责文件写入
|
||||
+ [ ] editor_game 处理游戏数据, 导入为editor的数据, 编辑数据, 从原editor和editor_file中抽离. **只有此文件允许`\s(main|core)`形式的调用**(以及其初始化`editor_game_wrapper(editor, main, core);`)
|
||||
+ [x] editor_util 生成guid/处理颜色 等函数, 从editor分离
|
||||
+ [ ] editor 执行初始化流程加组合各组件
|
||||
+ [ ] 原editor_mode 移除
|
||||
+ [x] 原vm 移除
|
||||
|
||||
@ -81,12 +81,12 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc = {
|
||||
"_lint": true,
|
||||
"_data": "当前能否使用该道具,仅对cls为tools或constants有效。"
|
||||
},
|
||||
"canEquip": {
|
||||
"equipCondition": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_lint": true,
|
||||
"_data": "当前能否装备某个装备,仅对cls为equips有效。\n与canUseItemEffect不同,这里null代表可以装备。"
|
||||
"_data": "能装备某个装备的条件,仅对cls为equips有效。\n与canUseItemEffect不同,这里null代表可以装备。"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -230,7 +230,7 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc = {
|
||||
"_type": "select",
|
||||
"_select": {
|
||||
"values": [
|
||||
null,
|
||||
"null",
|
||||
"openDoor",
|
||||
"passNet",
|
||||
"changeLight",
|
||||
@ -245,9 +245,9 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc = {
|
||||
"_type": "select",
|
||||
"_select": {
|
||||
"values": [
|
||||
null,
|
||||
true,
|
||||
false
|
||||
"null",
|
||||
"true",
|
||||
"false"
|
||||
]
|
||||
},
|
||||
"_data": "该图块是否不可通行;true代表不可通行,false代表可通行,null代表使用系统缺省值"
|
||||
@ -462,6 +462,35 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc = {
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"floors_template": {
|
||||
"floorId": "to be covered",
|
||||
"title": "new floor",
|
||||
"name": "new floor",
|
||||
"width": 13,
|
||||
"height": 13,
|
||||
"canFlyTo": true,
|
||||
"canUseQuickShop": true,
|
||||
"cannotViewMap": false,
|
||||
"cannotMoveDirectly": false,
|
||||
"images": [],
|
||||
"item_ratio": 1,
|
||||
"defaultGround": "ground",
|
||||
"bgm": null,
|
||||
"upFloor": null,
|
||||
"downFloor": null,
|
||||
"color": null,
|
||||
"weather": null,
|
||||
"firstArrive": [],
|
||||
"eachArrive": [],
|
||||
"parallelDo": "",
|
||||
"events": {},
|
||||
"changeFloor": {},
|
||||
"afterBattle": {},
|
||||
"afterGetItem": {},
|
||||
"afterOpenDoor": {},
|
||||
"cannotMove": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -121,13 +121,6 @@
|
||||
<h3 class="leftTabHeader">图块属性 <button onclick="editor.mode.onmode('save')">保存</button> <button onclick="editor.mode.changeDoubleClickModeByButton('add')">添加</button> <button onclick="editor.mode.changeDoubleClickModeByButton('delete')">删除</button> <button onclick="editor_multi.editCommentJs('enemyitem')">配置表格</button>
|
||||
</h3>
|
||||
<div class="leftTabContent">
|
||||
<div id='newIdIdnum'><!-- id and idnum -->
|
||||
<input placeholder="新id(唯一标识符)"/>
|
||||
<input placeholder="新idnum(10000以内数字)"/>
|
||||
<button>save</button>
|
||||
<br/>
|
||||
<button style="margin-top: 10px">自动注册</button>
|
||||
</div>
|
||||
<div id="enemyItemTable"><!-- enemy and item -->
|
||||
<div class='etable'>
|
||||
<table>
|
||||
@ -141,6 +134,17 @@
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div id='newIdIdnum'><!-- id and idnum -->
|
||||
<input placeholder="新id(唯一标识符)"/>
|
||||
<input placeholder="新idnum(10000以内数字)"/>
|
||||
<button>save</button>
|
||||
<br/>
|
||||
<button style="margin-top: 10px">自动注册</button>
|
||||
</div>
|
||||
<div id='changeId'><!-- id and idnum -->
|
||||
<input placeholder="修改图块id为"/>
|
||||
<button>save</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="left4" class='leftTab' style="z-index:-1;opacity: 0;"><!-- floor -->
|
||||
@ -158,6 +162,10 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div id='changeFloorId'><!-- id and idnum -->
|
||||
<input placeholder="修改floorId为"/>
|
||||
<button>save</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="left5" class='leftTab' style="z-index:-1;opacity: 0;"><!-- tower -->
|
||||
|
||||
32
editor.html
32
editor.html
@ -117,6 +117,19 @@
|
||||
<h3 class="leftTabHeader">图块属性 <button onclick="editor.mode.onmode('save')">保存</button> <button onclick="editor.mode.changeDoubleClickModeByButton('add')">添加</button> <button onclick="editor.mode.changeDoubleClickModeByButton('delete')">删除</button> <button onclick="editor_multi.editCommentJs('enemyitem')">配置表格</button>
|
||||
</h3>
|
||||
<div class="leftTabContent">
|
||||
<div id="enemyItemTable"><!-- enemy and item -->
|
||||
<div class='etable'>
|
||||
<table>
|
||||
<tbody id='table_a3f03d4c_55b8_4ef6_b362_b345783acd72'>
|
||||
<tr>
|
||||
<td>条目</td>
|
||||
<td>注释</td>
|
||||
<td>值</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div id='newIdIdnum'><!-- id and idnum -->
|
||||
<input placeholder="新id(唯一标识符)"/>
|
||||
<input placeholder="新idnum(10000以内数字)"/>
|
||||
@ -124,18 +137,9 @@
|
||||
<br/>
|
||||
<button style="margin-top: 10px">自动注册</button>
|
||||
</div>
|
||||
<div id="enemyItemTable"><!-- enemy and item -->
|
||||
<div class='etable'>
|
||||
<table>
|
||||
<tbody id='table_a3f03d4c_55b8_4ef6_b362_b345783acd72'>
|
||||
<tr>
|
||||
<td>条目</td>
|
||||
<td>注释</td>
|
||||
<td>值</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div id='changeId'><!-- id and idnum -->
|
||||
<input placeholder="修改图块id为"/>
|
||||
<button>save</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -154,6 +158,10 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div id='changeFloorId'><!-- id and idnum -->
|
||||
<input placeholder="修改floorId为"/>
|
||||
<button>save</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="left5" class='leftTab' style="z-index:-1;opacity: 0;"><!-- tower -->
|
||||
|
||||
@ -162,19 +162,21 @@ actions.prototype._sys_onkeyUp_replay = function (e) {
|
||||
core.triggerReplay();
|
||||
else if (e.keyCode == 65) // A
|
||||
core.rewindReplay();
|
||||
else if (e.keyCode == 83)
|
||||
else if (e.keyCode == 83) // S
|
||||
core.saveReplay();
|
||||
else if (e.keyCode == 67)
|
||||
else if (e.keyCode == 67) // C
|
||||
core.bookReplay();
|
||||
else if (e.keyCode == 33 || e.keyCode == 34)
|
||||
else if (e.keyCode == 33 || e.keyCode == 34) // PgUp/PgDn
|
||||
core.viewMapReplay();
|
||||
else if (e.keyCode >= 49 && e.keyCode <= 51)
|
||||
else if (e.keyCode == 78) // N
|
||||
core.stepReplay();
|
||||
else if (e.keyCode >= 49 && e.keyCode <= 51) // 1-3
|
||||
core.setReplaySpeed(e.keyCode - 48);
|
||||
else if (e.keyCode == 52)
|
||||
else if (e.keyCode == 52) // 4
|
||||
core.setReplaySpeed(6);
|
||||
else if (e.keyCode == 53)
|
||||
else if (e.keyCode == 53) // 5
|
||||
core.setReplaySpeed(12);
|
||||
else if (e.keyCode == 54)
|
||||
else if (e.keyCode == 54) // 6
|
||||
core.setReplaySpeed(24);
|
||||
return true;
|
||||
}
|
||||
@ -249,6 +251,8 @@ actions.prototype._sys_keyDown_lockControl = function (keyCode) {
|
||||
this._keyDownSL(keyCode);
|
||||
break;
|
||||
case 'shop':
|
||||
this._keyDownShop(keyCode);
|
||||
break;
|
||||
case 'selectShop':
|
||||
case 'switchs':
|
||||
case 'settings':
|
||||
@ -758,13 +762,17 @@ actions.prototype._sys_longClick_lockControl = function (x, y) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// 长按SL快速翻页
|
||||
// 长按SL上下页快速翻页
|
||||
if (["save","load","replayLoad","replayRemain"].indexOf(core.status.event.id) >= 0) {
|
||||
if ([this.HSIZE-2, this.HSIZE-3, this.HSIZE+2, this.HSIZE+3].indexOf(x) >= 0 && y == this.LAST) {
|
||||
this._clickSL(x, y);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// 长按商店连续购买
|
||||
if (core.status.event.id == 'shop' && x >= this.CHOICES_LEFT && x <= this.CHOICES_RIGHT) {
|
||||
return this._clickShop(x, y);
|
||||
}
|
||||
// 长按可以跳过等待事件
|
||||
if (core.status.event.id == 'action' && core.status.event.data.type == 'sleep'
|
||||
&& !core.status.event.data.current.noSkip) {
|
||||
@ -916,7 +924,7 @@ actions.prototype._clickAction = function (x, y) {
|
||||
core.insertAction(core.status.event.ui.yes);
|
||||
core.doAction();
|
||||
}
|
||||
if ((x == this.HSIZE+2 || x == this.HSIZE+1) && y == this.HSIZE+1) {
|
||||
else if ((x == this.HSIZE+2 || x == this.HSIZE+1) && y == this.HSIZE+1) {
|
||||
core.status.route.push("choices:1");
|
||||
core.insertAction(core.status.event.ui.no);
|
||||
core.doAction();
|
||||
@ -1243,13 +1251,25 @@ actions.prototype._clickShop = function (x, y) {
|
||||
return true;
|
||||
}
|
||||
|
||||
actions.prototype._keyDownShop = function (keycode) {
|
||||
// 商店界面长按空格连续购买
|
||||
if (keycode == 32) {
|
||||
this._selectChoices(core.status.event.data.shop.choices.length + 1, keycode, this._clickShop);
|
||||
return;
|
||||
}
|
||||
this._keyDownChoices(keycode);
|
||||
}
|
||||
|
||||
////// 商店界面时,放开某个键的操作 //////
|
||||
actions.prototype._keyUpShop = function (keycode) {
|
||||
if (keycode == 27 || keycode == 88) {
|
||||
core.events._exitShop();
|
||||
return;
|
||||
}
|
||||
this._selectChoices(core.status.event.data.shop.choices.length + 1, keycode, this._clickShop);
|
||||
if (keycode != 32) {
|
||||
this._selectChoices(core.status.event.data.shop.choices.length + 1, keycode, this._clickShop);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -189,7 +189,6 @@ control.prototype._animationFrame_animate = function (timestamp) {
|
||||
|
||||
control.prototype._animationFrame_heroMoving = function (timestamp) {
|
||||
if (core.status.heroMoving <= 0) return;
|
||||
var x=core.getHeroLoc('x'), y=core.getHeroLoc('y'), direction = core.getHeroLoc('direction');
|
||||
// 换腿
|
||||
if (timestamp - core.animateFrame.moveTime > (core.values.moveSpeed||100)) {
|
||||
core.animateFrame.leftLeg = !core.animateFrame.leftLeg;
|
||||
@ -777,9 +776,9 @@ control.prototype.drawHero = function (status, offset) {
|
||||
core.clearMap('hero');
|
||||
|
||||
this._drawHero_getDrawObjs(direction, x, y, status, offset).forEach(function (block) {
|
||||
core.drawImage('hero', block.img, block.heroIcon[block.status]*32,
|
||||
block.heroIcon.loc * block.height, 32, block.height,
|
||||
block.posx, block.posy+32-block.height, 32, block.height);
|
||||
core.drawImage('hero', block.img, block.heroIcon[block.status]*block.width,
|
||||
block.heroIcon.loc * block.height, block.width, block.height,
|
||||
block.posx+(32-block.width)/2, block.posy+32-block.height, block.width, block.height);
|
||||
});
|
||||
|
||||
core.control.updateViewport();
|
||||
@ -789,6 +788,7 @@ control.prototype._drawHero_getDrawObjs = function (direction, x, y, status, off
|
||||
var heroIconArr = core.material.icons.hero, drawObjs = [], index = 0;
|
||||
drawObjs.push({
|
||||
"img": core.material.images.hero,
|
||||
"width": core.material.icons.hero.width || 32,
|
||||
"height": core.material.icons.hero.height,
|
||||
"heroIcon": heroIconArr[direction],
|
||||
"posx": x * 32 - core.bigmap.offsetX + core.utils.scan[direction].x * offset,
|
||||
@ -799,6 +799,7 @@ control.prototype._drawHero_getDrawObjs = function (direction, x, y, status, off
|
||||
(core.status.hero.followers||[]).forEach(function (t) {
|
||||
drawObjs.push({
|
||||
"img": core.material.images.images[t.name],
|
||||
"width": core.material.images.images[t.name].width/4,
|
||||
"height": core.material.images.images[t.name].height/4,
|
||||
"heroIcon": heroIconArr[t.direction],
|
||||
"posx": 32*t.x - core.bigmap.offsetX + (t.stop?0:core.utils.scan[t.direction].x*offset),
|
||||
@ -1056,7 +1057,7 @@ control.prototype.chooseReplayFile = function () {
|
||||
control.prototype.startReplay = function (list) {
|
||||
if (!core.isPlaying()) return;
|
||||
core.status.replay.replaying=true;
|
||||
core.status.replay.pausing=false;
|
||||
core.status.replay.pausing=true;
|
||||
core.status.replay.speed=1.0;
|
||||
core.status.replay.toReplay = core.clone(list);
|
||||
core.status.replay.totalList = core.status.route.concat(list);
|
||||
@ -1092,16 +1093,24 @@ control.prototype.resumeReplay = function () {
|
||||
core.replay();
|
||||
}
|
||||
|
||||
////// 单步播放 //////
|
||||
control.prototype.stepReplay = function () {
|
||||
if (!core.isPlaying() || !core.isReplaying()) return;
|
||||
if (!core.status.replay.pausing) return core.drawTip("请先暂停录像");
|
||||
if (core.isMoving() || core.status.replay.animate || core.status.event.id)
|
||||
return core.drawTip("请等待当前事件的处理结束");
|
||||
core.replay(true);
|
||||
}
|
||||
|
||||
////// 加速播放 //////
|
||||
control.prototype.speedUpReplay = function () {
|
||||
if (!core.isPlaying() || !core.isReplaying()) return;
|
||||
if (core.status.replay.speed==12) core.status.replay.speed=24;
|
||||
else if (core.status.replay.speed==6) core.status.replay.speed=12;
|
||||
else if (core.status.replay.speed==3) core.status.replay.speed=6;
|
||||
else if (core.status.replay.speed==2.5) core.status.replay.speed=3;
|
||||
else if (core.status.replay.speed==2) core.status.replay.speed=2.5;
|
||||
else if (core.status.replay.speed<2) {
|
||||
core.status.replay.speed = parseInt(10*core.status.replay.speed + 2)/10;
|
||||
var speeds = [0.2, 0.5, 1, 2, 3, 6, 12, 24];
|
||||
for (var i = speeds.length - 2; i >= 0; i--) {
|
||||
if (speeds[i] <= core.status.replay.speed) {
|
||||
core.status.replay.speed = speeds[i+1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
core.drawTip("x"+core.status.replay.speed+"倍");
|
||||
}
|
||||
@ -1109,15 +1118,13 @@ control.prototype.speedUpReplay = function () {
|
||||
////// 减速播放 //////
|
||||
control.prototype.speedDownReplay = function () {
|
||||
if (!core.isPlaying() || !core.isReplaying()) return;
|
||||
if (core.status.replay.speed==24) core.status.replay.speed=12;
|
||||
else if (core.status.replay.speed==12) core.status.replay.speed=6;
|
||||
else if (core.status.replay.speed==6) core.status.replay.speed=3;
|
||||
else if (core.status.replay.speed==3) core.status.replay.speed=2.5;
|
||||
else if (core.status.replay.speed==2.5) core.status.replay.speed=2;
|
||||
else {
|
||||
core.status.replay.speed = parseInt(10*core.status.replay.speed - 2)/10;
|
||||
var speeds = [0.2, 0.5, 1, 2, 3, 6, 12, 24];
|
||||
for (var i = 1; i <= speeds.length; i++) {
|
||||
if (speeds[i] >= core.status.replay.speed) {
|
||||
core.status.replay.speed = speeds[i-1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (core.status.replay.speed<0.2) core.status.replay.speed=0.2;
|
||||
core.drawTip("x"+core.status.replay.speed+"倍");
|
||||
}
|
||||
|
||||
@ -1218,9 +1225,10 @@ control.prototype.isReplaying = function () {
|
||||
}
|
||||
|
||||
////// 回放 //////
|
||||
control.prototype.replay = function () {
|
||||
control.prototype.replay = function (force) {
|
||||
if (!core.isPlaying() || !core.isReplaying()
|
||||
|| core.status.replay.pausing || core.status.replay.animate || core.status.event.id) return;
|
||||
|| core.status.replay.animate || core.status.event.id) return;
|
||||
if (core.status.replay.pausing && !force) return;
|
||||
if (core.status.replay.toReplay.length==0)
|
||||
return this._replay_finished();
|
||||
this._replay_save();
|
||||
@ -1291,6 +1299,7 @@ control.prototype._replay_save = function () {
|
||||
}
|
||||
|
||||
control.prototype._replay_error = function (action) {
|
||||
core.ui.closePanel();
|
||||
core.status.replay.replaying = false;
|
||||
var len = core.status.replay.toReplay.length;
|
||||
var prevList = core.status.replay.totalList.slice(-len - 11, -len - 1);
|
||||
@ -1412,14 +1421,13 @@ control.prototype._replayAction_shop = function (action) {
|
||||
return true;
|
||||
}
|
||||
var choices = shop.choices;
|
||||
var topIndex = core.__HALF_SIZE__ - parseInt(choices.length / 2);
|
||||
core.status.event.selection = parseInt(selections.shift());
|
||||
core.events.openShop(shopId, false);
|
||||
var topIndex = core.__HALF_SIZE__ - parseInt(choices.length / 2) + (core.status.event.ui.offset || 0);
|
||||
var shopInterval = setInterval(function () {
|
||||
if (!core.actions._clickShop(core.__HALF_SIZE__, topIndex+core.status.event.selection)) {
|
||||
clearInterval(shopInterval);
|
||||
core.stopReplay();
|
||||
core.drawTip("录像文件出错");
|
||||
core.control._replay_error(action);
|
||||
return;
|
||||
}
|
||||
if (selections.length==0) {
|
||||
@ -2065,6 +2073,7 @@ control.prototype.setCurtain = function(color, time, callback) {
|
||||
}
|
||||
|
||||
control.prototype._setCurtain_animate = function (nowColor, color, time, callback) {
|
||||
time /= Math.max(core.status.replay.speed, 1)
|
||||
var per_time = 10, step = parseInt(time / per_time);
|
||||
var animate = setInterval(function() {
|
||||
nowColor = [
|
||||
@ -2337,14 +2346,15 @@ control.prototype.updateHeroIcon = function (name) {
|
||||
|
||||
var image = core.material.images.hero;
|
||||
// 全身图
|
||||
var height = core.material.icons.hero.height;
|
||||
var ratio = 32 / height, width = 32 * ratio, left = 16-width/2;
|
||||
var w = core.material.icons.hero.width || 32;
|
||||
var h = core.material.icons.hero.height || 48;
|
||||
var ratio = Math.max(w / h, 1), width = 32 * ratio, left = 16 - width/2;
|
||||
|
||||
var canvas = document.createElement("canvas");
|
||||
var context = canvas.getContext("2d");
|
||||
canvas.width = 32;
|
||||
canvas.height = 32;
|
||||
context.drawImage(image, 0, 0, 32, height, left, 0, width, 32);
|
||||
context.drawImage(image, 0, 0, w, h, left, 0, width, 32);
|
||||
|
||||
core.statusBar.image.name.src = canvas.toDataURL("image/png");
|
||||
}
|
||||
|
||||
@ -241,6 +241,11 @@ enemys.prototype._nextCriticals_useBinarySearch = function (enemy, info, number,
|
||||
|
||||
enemys.prototype._nextCriticals_useTurn = function (enemy, info, number, x, y, floorId) {
|
||||
var mon_hp = info.mon_hp, hero_atk = core.status.hero.atk, mon_def = info.mon_def, turn = info.turn;
|
||||
// ------ 超大回合数强制使用二分算临界
|
||||
// 以避免1攻10e回合,2攻5e回合导致下述循环卡死问题
|
||||
if (turn >= 1e6) { // 100w回合以上强制二分计算临界
|
||||
return this._nextCriticals_useBinarySearch(enemy, info, number, x, y, floorId);
|
||||
}
|
||||
var list = [], pre = null;
|
||||
for (var t = turn - 1; t >= 1; t--) {
|
||||
var nextAtk = Math.ceil(mon_hp / t) + mon_def;
|
||||
|
||||
@ -419,20 +419,23 @@ events.prototype._openDoor_animate = function (id, x, y, callback) {
|
||||
var locked = core.status.lockControl;
|
||||
core.lockControl();
|
||||
core.status.replay.animate = true;
|
||||
core.removeBlock(x, y);
|
||||
core.drawImage('event', core.material.images.animates, 0, 32 * door, 32, 32, 32 * x, 32 * y, 32, 32);
|
||||
var state = 0;
|
||||
var animate = window.setInterval(function () {
|
||||
core.clearMap('event', 32 * x, 32 * y, 32, 32);
|
||||
state++;
|
||||
if (state == 4) {
|
||||
clearInterval(animate);
|
||||
core.removeBlock(x, y);
|
||||
delete core.animateFrame.asyncId[animate];
|
||||
if (!locked) core.unLockControl();
|
||||
core.status.replay.animate = false;
|
||||
core.events.afterOpenDoor(id, x, y, callback);
|
||||
return;
|
||||
}
|
||||
core.clearMap('event', 32 * x, 32 * y, 32, 32);
|
||||
core.drawImage('event', core.material.images.animates, 32 * state, 32 * door, 32, 32, 32 * x, 32 * y, 32, 32);
|
||||
}, speed / core.status.replay.speed);
|
||||
}, speed / Math.max(core.status.replay.speed, 1));
|
||||
core.animateFrame.asyncId[animate] = true;
|
||||
}
|
||||
|
||||
////// 开一个门后触发的事件 //////
|
||||
@ -840,7 +843,10 @@ events.prototype.insertAction = function (action, x, y, callback, addToLast) {
|
||||
|
||||
// ------ 判定commonEvent
|
||||
var commonEvent = this.getCommonEvent(action);
|
||||
if (commonEvent instanceof Array) action = commonEvent;
|
||||
if (commonEvent instanceof Array) {
|
||||
// 将公共事件视为一个do-while事件插入执行,可被break跳出
|
||||
action = [{"type": "dowhile", "condition": "false", "data": commonEvent}];
|
||||
}
|
||||
if (!action) return;
|
||||
|
||||
if (core.status.event.id != 'action') {
|
||||
@ -1133,7 +1139,7 @@ events.prototype._action_openDoor = function (data, x, y, prefix) {
|
||||
var loc = this.__action_getLoc(data.loc, x, y, prefix);
|
||||
var floorId = data.floorId || core.status.floorId;
|
||||
if (floorId == core.status.floorId) {
|
||||
core.openDoor(loc[0], loc[1], data.needKey, core.doAction);
|
||||
this.__action_doAsyncFunc(data.async, core.openDoor, loc[0], loc[1], data.needKey);
|
||||
}
|
||||
else {
|
||||
core.removeBlock(loc[0], loc[1], floorId);
|
||||
@ -1143,7 +1149,7 @@ events.prototype._action_openDoor = function (data, x, y, prefix) {
|
||||
|
||||
events.prototype._action_closeDoor = function (data, x, y, prefix) {
|
||||
var loc = this.__action_getLoc(data.loc, x, y, prefix);
|
||||
core.closeDoor(loc[0], loc[1], data.id, core.doAction);
|
||||
this.__action_doAsyncFunc(data.async, core.closeDoor, loc[0], loc[1], data.id);
|
||||
}
|
||||
|
||||
events.prototype._action_useItem = function (data, x, y, prefix) {
|
||||
@ -1172,7 +1178,13 @@ events.prototype._action_disableShop = function (data, x, y, prefix) {
|
||||
}
|
||||
|
||||
events.prototype._action_battle = function (data, x, y, prefix) {
|
||||
this.battle(data.id, null, null, true, core.doAction);
|
||||
if (data.id) {
|
||||
this.battle(data.id, null, null, true, core.doAction);
|
||||
}
|
||||
else {
|
||||
var loc = this.__action_getLoc(data.loc, x, y, prefix);
|
||||
this.battle(null, loc[0], loc[1], true, core.doAction);
|
||||
}
|
||||
}
|
||||
|
||||
events.prototype._action_trigger = function (data, x, y, prefix) {
|
||||
@ -1180,9 +1192,9 @@ events.prototype._action_trigger = function (data, x, y, prefix) {
|
||||
var block = core.getBlock(loc[0], loc[1]);
|
||||
if (block != null && block.block.event.trigger) {
|
||||
block = block.block;
|
||||
this.setEvents([], block.x, block.y);
|
||||
this.setEvents(data.keep ? null : [], block.x, block.y);
|
||||
if (block.event.trigger == 'action')
|
||||
this.setEvents(block.event.data);
|
||||
this.insertAction(block.event.data);
|
||||
else {
|
||||
core.doSystemEvent(block.event.trigger, block, core.doAction);
|
||||
return;
|
||||
@ -1327,10 +1339,8 @@ events.prototype.__action_getInput = function (hint, isText, callback) {
|
||||
callback(value);
|
||||
}
|
||||
catch (e) {
|
||||
main.log(e);
|
||||
core.stopReplay();
|
||||
core.insertAction(["录像文件出错,请在控制台查看报错信息。", {"type": "exit"}]);
|
||||
core.doAction();
|
||||
core.control._replay_error(action);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -1375,10 +1385,7 @@ events.prototype._action_choices = function (data, x, y, prefix) {
|
||||
}, 750 / Math.max(1, core.status.replay.speed))
|
||||
}
|
||||
else {
|
||||
main.log("录像文件出错!当前需要一个 choices: 项,实际为 " + action);
|
||||
core.stopReplay();
|
||||
core.insertAction(["录像文件出错,请在控制台查看报错信息。", {"type": "exit"}]);
|
||||
core.doAction();
|
||||
core.control._replay_error(action);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1401,10 +1408,7 @@ events.prototype._action_confirm = function (data, x, y, prefix) {
|
||||
}, 750 / Math.max(1, core.status.replay.speed))
|
||||
}
|
||||
else {
|
||||
main.log("录像文件出错!当前需要一个 choices: 项,实际为 " + action);
|
||||
core.stopReplay();
|
||||
core.insertAction(["录像文件出错,请在控制台查看报错信息。", {"type": "exit"}]);
|
||||
core.doAction();
|
||||
core.control._replay_error(action);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1749,8 +1753,7 @@ events.prototype.hasAsync = function () {
|
||||
events.prototype.follow = function (name) {
|
||||
core.status.hero.followers = core.status.hero.followers || [];
|
||||
name = core.getMappedName(name);
|
||||
if (core.material.images.images[name]
|
||||
&& core.material.images.images[name].width == 128) {
|
||||
if (core.material.images.images[name]) {
|
||||
core.status.hero.followers.push({"name": name});
|
||||
core.gatherFollowers();
|
||||
core.clearMap('hero');
|
||||
@ -1786,6 +1789,7 @@ events.prototype.setValue = function (name, value, prefix, add) {
|
||||
this._setValue_setItem(name, value);
|
||||
this._setValue_setFlag(name, value);
|
||||
this._setValue_setSwitch(name, value, prefix);
|
||||
this._setValue_setGlobal(name, value);
|
||||
core.updateStatusBar();
|
||||
}
|
||||
|
||||
@ -1816,6 +1820,11 @@ events.prototype._setValue_setSwitch = function (name, value, prefix) {
|
||||
core.setFlag((prefix || ":f@x@y") + "@" + name.substring(7), value);
|
||||
}
|
||||
|
||||
events.prototype._setValue_setGlobal = function (name, value) {
|
||||
if (name.indexOf("global:") !== 0) return;
|
||||
core.setGlobal(name.substring(7), value);
|
||||
}
|
||||
|
||||
////// 数值增减 //////
|
||||
events.prototype.addValue = function (name, value, prefix) {
|
||||
this.setValue(name, value, prefix, true);
|
||||
@ -1884,7 +1893,7 @@ events.prototype.closeDoor = function (x, y, id, callback) {
|
||||
}
|
||||
core.clearMap('event', 32 * x, 32 * y, 32, 32);
|
||||
core.drawImage('event', core.material.images.animates, 32 * (4-state), 32 * door, 32, 32, 32 * x, 32 * y, 32, 32);
|
||||
}, speed / core.status.replay.speed);
|
||||
}, speed / Math.max(core.status.replay.speed, 1));
|
||||
core.animateFrame.asyncId[animate] = true;
|
||||
}
|
||||
|
||||
@ -1958,7 +1967,8 @@ events.prototype.moveImage = function (code, to, opacityVal, time, callback) {
|
||||
var opacity = parseFloat(canvas.style.opacity), toOpacity = getOrDefault(opacityVal, opacity);
|
||||
|
||||
this._moveImage_moving(name, {
|
||||
fromX: fromX, fromY: fromY, toX: toX, toY: toY, opacity: opacity, toOpacity: toOpacity, time: time
|
||||
fromX: fromX, fromY: fromY, toX: toX, toY: toY, opacity: opacity, toOpacity: toOpacity,
|
||||
time: time / Math.max(core.status.replay.speed, 1)
|
||||
}, callback)
|
||||
}
|
||||
|
||||
@ -2016,6 +2026,7 @@ events.prototype.setVolume = function (value, time, callback) {
|
||||
return;
|
||||
}
|
||||
var currVolume = core.musicStatus.volume;
|
||||
time /= Math.max(core.status.replay.speed, 1);
|
||||
var per_time = 10, step = 0, steps = parseInt(time / per_time);
|
||||
var fade = setInterval(function () {
|
||||
step++;
|
||||
@ -2037,6 +2048,7 @@ events.prototype.vibrate = function (time, callback) {
|
||||
}
|
||||
if (!time || time < 1000) time = 1000;
|
||||
// --- 将time调整为500的倍数(上整),不然会出错
|
||||
time /= Math.max(core.status.replay.speed, 1)
|
||||
time = Math.ceil(time / 500) * 500;
|
||||
var shakeInfo = {duration: time * 3 / 50, speed: 5, power: 5, direction: 1, shake: 0};
|
||||
var animate = setInterval(function () {
|
||||
@ -2127,6 +2139,7 @@ events.prototype.jumpHero = function (ex, ey, time, callback) {
|
||||
core.playSound('jump.mp3');
|
||||
var jumpInfo = core.maps.__generateJumpInfo(sx, sy, ex, ey, time || 500);
|
||||
jumpInfo.icon = core.material.icons.hero[core.getHeroLoc('direction')];
|
||||
jumpInfo.width = core.material.icons.hero.width || 32;
|
||||
jumpInfo.height = core.material.icons.hero.height;
|
||||
|
||||
this._jumpHero_doJump(jumpInfo, callback);
|
||||
@ -2146,12 +2159,12 @@ events.prototype._jumpHero_doJump = function (jumpInfo, callback) {
|
||||
events.prototype._jumpHero_jumping = function (jumpInfo) {
|
||||
core.clearMap('hero');
|
||||
core.maps.__updateJumpInfo(jumpInfo);
|
||||
var nowx = jumpInfo.px, nowy = jumpInfo.py, height = jumpInfo.height;
|
||||
var nowx = jumpInfo.px, nowy = jumpInfo.py, width = jumpInfo.width || 32, height = jumpInfo.height;
|
||||
core.bigmap.offsetX = core.clamp(nowx - 32*core.__HALF_SIZE__, 0, 32*core.bigmap.width-core.__PIXELS__);
|
||||
core.bigmap.offsetY = core.clamp(nowy - 32*core.__HALF_SIZE__, 0, 32*core.bigmap.height-core.__PIXELS__);
|
||||
core.control.updateViewport();
|
||||
core.drawImage('hero', core.material.images.hero, jumpInfo.icon.stop, jumpInfo.icon.loc * height, 32, height,
|
||||
nowx - core.bigmap.offsetX, nowy + 32-height - core.bigmap.offsetY, 32, height);
|
||||
core.drawImage('hero', core.material.images.hero, jumpInfo.icon.stop, jumpInfo.icon.loc * height, width, height,
|
||||
nowx + (32 - width) / 2 - core.bigmap.offsetX, nowy + 32-height - core.bigmap.offsetY, width, height);
|
||||
}
|
||||
|
||||
events.prototype._jumpHero_finished = function (animate, ex, ey, callback) {
|
||||
@ -2239,14 +2252,13 @@ events.prototype.canUseQuickShop = function (shopId) {
|
||||
events.prototype.setHeroIcon = function (name, noDraw) {
|
||||
name = core.getMappedName(name);
|
||||
var img = core.material.images.images[name];
|
||||
if (!img || img.width != 128) return;
|
||||
if (!img) return;
|
||||
core.setFlag("heroIcon", name);
|
||||
core.material.images.hero.onload = function () {
|
||||
core.material.icons.hero.height = img.height / 4;
|
||||
core.control.updateHeroIcon(name);
|
||||
if (!noDraw) core.drawHero();
|
||||
}
|
||||
core.material.images.hero.src = img.src;
|
||||
core.material.images.hero = img;
|
||||
core.material.icons.hero.width = img.width / 4;
|
||||
core.material.icons.hero.height = img.height / 4;
|
||||
core.control.updateHeroIcon(name);
|
||||
if (!noDraw) core.drawHero();
|
||||
}
|
||||
|
||||
////// 检查升级事件 //////
|
||||
|
||||
@ -11,9 +11,9 @@ items.prototype._init = function () {
|
||||
this.itemEffectTip = items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a.itemEffectTip;
|
||||
this.useItemEffect = items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a.useItemEffect;
|
||||
this.canUseItemEffect = items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a.canUseItemEffect;
|
||||
if (!items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a.canEquip)
|
||||
items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a.canEquip = {};
|
||||
this.equipCondition = items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a.canEquip;
|
||||
if (!items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a.equipCondition)
|
||||
items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a.equipCondition = {};
|
||||
this.equipCondition = items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a.equipCondition;
|
||||
}
|
||||
|
||||
////// 获得所有道具 //////
|
||||
@ -35,7 +35,7 @@ items.prototype._resetItems = function () {
|
||||
if (core.flags.bombFourDirections)
|
||||
core.material.items.bomb.text = "可以炸掉勇士四周的怪物";
|
||||
if (core.flags.snowFourDirections)
|
||||
core.material.items.bomb.text = "可以将四周的熔岩变成平地";
|
||||
core.material.items.snow.text = "可以将四周的熔岩变成平地";
|
||||
if (core.flags.equipment) {
|
||||
core.material.items.sword1.cls = 'equips';
|
||||
core.material.items.sword2.cls = 'equips';
|
||||
|
||||
66
libs/maps.js
66
libs/maps.js
@ -91,6 +91,9 @@ maps.prototype.initBlock = function (x, y, id, addInfo, eventFloor) {
|
||||
else if (core.icons.getTilesetOffset(id)) block.event = {"cls": "tileset", "id": "X" + id, "noPass": true};
|
||||
else block.event = {'cls': 'terrains', 'id': 'none', 'noPass': false};
|
||||
|
||||
if (typeof block.event.noPass === 'string')
|
||||
block.event.noPass = JSON.parse(block.event.noPass);
|
||||
|
||||
if (addInfo) this._addInfo(block);
|
||||
if (eventFloor) {
|
||||
this._addEvent(block, x, y, (eventFloor.events || {})[x + "," + y]);
|
||||
@ -238,7 +241,8 @@ maps.prototype.saveMap = function (floorId) {
|
||||
if (!floorId) {
|
||||
var map = {};
|
||||
for (var id in maps) {
|
||||
map[id] = this.saveMap(id);
|
||||
var obj = this.saveMap(id);
|
||||
if (Object.keys(obj).length > 0) map[id] = obj;
|
||||
}
|
||||
return map;
|
||||
}
|
||||
@ -1446,8 +1450,13 @@ maps.prototype.setBlock = function (number, x, y, floorId) {
|
||||
else number = core.getNumberById(number);
|
||||
}
|
||||
|
||||
var originBlock = core.getBlock(x, y, floorId, true);
|
||||
var block = this.initBlock(x, y, number, true, core.floors[floorId]);
|
||||
if (block.id == 0 && !block.event.trigger) {
|
||||
// 转变图块为0且该点无事件,视为隐藏
|
||||
core.removeBlock(x, y, floorId);
|
||||
return;
|
||||
}
|
||||
var originBlock = core.getBlock(x, y, floorId, true);
|
||||
if (floorId == core.status.floorId) {
|
||||
core.removeGlobalAnimate(x, y);
|
||||
core.clearMap('event', x * 32, y * 32, 32, 32);
|
||||
@ -1614,13 +1623,13 @@ maps.prototype.moveBlock = function (x, y, steps, time, keep, callback) {
|
||||
}
|
||||
var block = blockArr[0], blockInfo = blockArr[1];
|
||||
var moveSteps = (steps||[]).filter(function (t) {
|
||||
return ['up','down','left','right'].indexOf(t)>=0;
|
||||
return ['up','down','left','right','forward','backward'].indexOf(t)>=0;
|
||||
});
|
||||
var canvases = this._initDetachedBlock(blockInfo, x, y, block.event.animate !== false);
|
||||
this._moveDetachedBlock(blockInfo, 32 * x, 32 * y, 1, canvases);
|
||||
|
||||
var moveInfo = {
|
||||
x: x, y: y, px: 32 * x, py: 32 * y, opacity: 1, keep: keep,
|
||||
x: x, y: y, px: 32 * x, py: 32 * y, opacity: 1, keep: keep, lastDirection: null, offset: 1,
|
||||
moveSteps: moveSteps, step: 0, per_time: time / 16 / core.status.replay.speed
|
||||
}
|
||||
this._moveBlock_doMove(blockInfo, canvases, moveInfo, callback);
|
||||
@ -1645,21 +1654,46 @@ maps.prototype._moveBlock_doMove = function (blockInfo, canvases, moveInfo, call
|
||||
core.animateFrame.asyncId[animate] = true;
|
||||
}
|
||||
|
||||
maps.prototype._moveBlock_moving = function (blockInfo, canvases, moveInfo) {
|
||||
maps.prototype._moveBlock_updateDirection = function (blockInfo, moveInfo) {
|
||||
moveInfo.offset = 1;
|
||||
var direction = moveInfo.moveSteps[0];
|
||||
if (moveInfo.step == 0) {
|
||||
moveInfo.x += core.utils.scan[direction].x;
|
||||
moveInfo.y += core.utils.scan[direction].y;
|
||||
// 根据faceIds修改朝向
|
||||
var currid = blockInfo.faceIds[direction];
|
||||
if (currid) {
|
||||
var posY = core.material.icons[blockInfo.cls][currid];
|
||||
if (posY != null) blockInfo.posY = posY;
|
||||
if (moveInfo.lastDirection == null) {
|
||||
for (var d in blockInfo.faceIds) {
|
||||
if (blockInfo.faceIds[d] == blockInfo.id) {
|
||||
moveInfo.lastDirection = d;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (direction == 'forward' || direction == 'backward') {
|
||||
if (moveInfo.lastDirection == null) {
|
||||
moveInfo.moveSteps.shift();
|
||||
return false;
|
||||
}
|
||||
if (direction == 'backward')
|
||||
moveInfo.offset = -1;
|
||||
direction = moveInfo.lastDirection;
|
||||
}
|
||||
moveInfo.lastDirection = moveInfo.moveSteps[0] = direction;
|
||||
moveInfo.x += core.utils.scan[direction].x * moveInfo.offset;
|
||||
moveInfo.y += core.utils.scan[direction].y * moveInfo.offset;
|
||||
// 根据faceIds修改朝向
|
||||
var currid = blockInfo.faceIds[direction];
|
||||
if (currid) {
|
||||
var posY = core.material.icons[blockInfo.cls][currid];
|
||||
if (posY != null) blockInfo.posY = posY;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
maps.prototype._moveBlock_moving = function (blockInfo, canvases, moveInfo) {
|
||||
if (moveInfo.step == 0) {
|
||||
if (!this._moveBlock_updateDirection(blockInfo, moveInfo)) return;
|
||||
}
|
||||
var direction = moveInfo.moveSteps[0];
|
||||
moveInfo.step++;
|
||||
moveInfo.px += core.utils.scan[direction].x * 2;
|
||||
moveInfo.py += core.utils.scan[direction].y * 2;
|
||||
moveInfo.px += core.utils.scan[direction].x * 2 * moveInfo.offset;
|
||||
moveInfo.py += core.utils.scan[direction].y * 2 * moveInfo.offset;
|
||||
this._moveDetachedBlock(blockInfo, moveInfo.px, moveInfo.py, moveInfo.opacity, canvases);
|
||||
if (moveInfo.step == 16) {
|
||||
moveInfo.step = 0;
|
||||
@ -1688,6 +1722,7 @@ maps.prototype.jumpBlock = function (sx, sy, ex, ey, time, keep, callback) {
|
||||
maps.prototype.__generateJumpInfo = function (sx, sy, ex, ey, time) {
|
||||
var dx = ex - sx, dy = ey - sy, distance = Math.round(Math.sqrt(dx * dx + dy * dy));
|
||||
var jump_peak = 6 + distance, jump_count = jump_peak * 2;
|
||||
time /= Math.max(core.status.replay.speed, 1)
|
||||
return {
|
||||
x: sx, y: sy, ex: ex, ey: ey, px: 32 * sx, py: 32 * sy, opacity: 1,
|
||||
jump_peak: jump_peak, jump_count: jump_count,
|
||||
@ -1751,6 +1786,7 @@ maps.prototype.animateBlock = function (loc, type, time, callback) {
|
||||
return;
|
||||
}
|
||||
this._animateBlock_drawList(list, isHide ? 1 : 0);
|
||||
time /= Math.max(core.status.replay.speed, 1)
|
||||
this._animateBlock_doAnimate(loc, list, isHide, 10 / time, callback);
|
||||
}
|
||||
|
||||
|
||||
44
libs/ui.js
44
libs/ui.js
@ -373,7 +373,8 @@ ui.prototype._getTitleAndIcon = function (content) {
|
||||
title = core.status.hero.name;
|
||||
image = core.material.images.hero;
|
||||
icon = 0;
|
||||
height = core.material.icons.hero.height;
|
||||
var w = core.material.icons.hero.width || 32;
|
||||
height = 32 * core.material.icons.hero.height / w;
|
||||
}
|
||||
else if (s4.endsWith(".png")) {
|
||||
s4 = core.getMappedName(s4);
|
||||
@ -383,7 +384,6 @@ ui.prototype._getTitleAndIcon = function (content) {
|
||||
var blockInfo = core.getBlockInfo(s4);
|
||||
if (blockInfo != null) {
|
||||
if (core.material.enemys[s4]) title = core.material.enemys[s4].name;
|
||||
else title = s4;
|
||||
image = blockInfo.image;
|
||||
icon = blockInfo.posY;
|
||||
height = blockInfo.height;
|
||||
@ -467,6 +467,11 @@ ui.prototype.drawWindowSelector = function(background, x, y, w, h) {
|
||||
|
||||
////// 绘制 WindowSkin
|
||||
ui.prototype.drawWindowSkin = function(background, ctx, x, y, w, h, direction, px, py) {
|
||||
background = background || core.status.textAttribute.background;
|
||||
if (typeof background == 'string') {
|
||||
background = core.getMappedName(background);
|
||||
background = core.material.images.images[background];
|
||||
}
|
||||
// 仿RM窗口皮肤 ↓
|
||||
var dstImage = core.getContextByName(ctx);
|
||||
if (!dstImage) return;
|
||||
@ -874,8 +879,10 @@ ui.prototype._drawTextBox_getVerticalPosition = function (content, titleInfo, po
|
||||
var realContent = this._getRealContent(content);
|
||||
var height = 30 + lineHeight * core.splitLines("ui", realContent, validWidth, this._buildFont()).length;
|
||||
if (titleInfo.title) height += textAttribute.titlefont + 5;
|
||||
if (titleInfo.icon != null)
|
||||
height = Math.max(height, titleInfo.height+50);
|
||||
if (titleInfo.icon != null) {
|
||||
if (titleInfo.title) height = Math.max(height, titleInfo.height+50);
|
||||
else height = Math.max(height, titleInfo.height + 30);
|
||||
}
|
||||
else if (titleInfo.image)
|
||||
height = Math.max(height, 90);
|
||||
|
||||
@ -904,9 +911,11 @@ ui.prototype._drawTextBox_drawTitleAndIcon = function (titleInfo, hPos, vPos, al
|
||||
core.setTextAlign('ui', 'left');
|
||||
var textAttribute = core.status.textAttribute;
|
||||
var content_top = vPos.top + 15;
|
||||
var image_top = vPos.top + 15;
|
||||
if (titleInfo.title != null) {
|
||||
var titlefont = textAttribute.titlefont;
|
||||
content_top += titlefont + 5;
|
||||
image_top = vPos.top + 40;
|
||||
core.setFillStyle('ui', core.arrayToRGB(textAttribute.title));
|
||||
core.setStrokeStyle('ui', core.arrayToRGB(textAttribute.title));
|
||||
|
||||
@ -919,19 +928,27 @@ ui.prototype._drawTextBox_drawTitleAndIcon = function (titleInfo, hPos, vPos, al
|
||||
title_left = hPos.right - title_width - 12;
|
||||
|
||||
core.fillText('ui', titleInfo.title, title_left, vPos.top + 8 + titlefont);
|
||||
|
||||
if (titleInfo.icon != null) {
|
||||
core.setAlpha('ui', alpha);
|
||||
core.strokeRect('ui', hPos.left + 15 - 1, vPos.top + 40-1, 34, titleInfo.height + 2, null, 2);
|
||||
core.setAlpha('ui', 1);
|
||||
core.status.boxAnimateObjs = [];
|
||||
}
|
||||
if (titleInfo.icon != null) {
|
||||
core.setAlpha('ui', alpha);
|
||||
core.strokeRect('ui', hPos.left + 15 - 1, image_top-1, 34, titleInfo.height + 2, null, 2);
|
||||
core.setAlpha('ui', 1);
|
||||
core.status.boxAnimateObjs = [];
|
||||
// --- 勇士
|
||||
if (titleInfo.image == core.material.images.hero) {
|
||||
core.clearMap('ui', hPos.left + 15, image_top, 32, titleInfo.height);
|
||||
core.fillRect('ui', hPos.left + 15, image_top, 32, titleInfo.height, core.material.groundPattern);
|
||||
core.drawImage('ui', titleInfo.image, 0, 0, core.material.icons.hero.width || 32, core.material.icons.hero.height,
|
||||
hPos.left + 15, image_top, 32, titleInfo.height);
|
||||
}
|
||||
else {
|
||||
core.status.boxAnimateObjs.push({
|
||||
'bgx': hPos.left + 15, 'bgy': vPos.top + 40, 'bgWidth': 32, 'bgHeight': titleInfo.height,
|
||||
'x': hPos.left + 15, 'y': vPos.top + 40, 'height': titleInfo.height, 'animate': titleInfo.animate,
|
||||
'bgx': hPos.left + 15, 'bgy': image_top, 'bgWidth': 32, 'bgHeight': titleInfo.height,
|
||||
'x': hPos.left + 15, 'y': image_top, 'height': titleInfo.height, 'animate': titleInfo.animate,
|
||||
'image': titleInfo.image, 'pos': titleInfo.icon * titleInfo.height
|
||||
});
|
||||
core.drawBoxAnimate();
|
||||
}
|
||||
core.drawBoxAnimate();
|
||||
}
|
||||
if (titleInfo.image != null && titleInfo.icon == null) { // 头像图
|
||||
core.drawImage('ui', titleInfo.image, 0, 0, titleInfo.image.width, titleInfo.image.height,
|
||||
@ -969,6 +986,7 @@ ui.prototype.drawScrollText = function (content, time, lineHeight, callback) {
|
||||
|
||||
ui.prototype._drawScrollText_animate = function (ctx, time, callback) {
|
||||
// 开始绘制到UI上
|
||||
time /= Math.max(core.status.replay.speed, 1)
|
||||
var per_pixel = 1, height = ctx.canvas.height, per_time = time * per_pixel / (this.PIXEL+height);
|
||||
var currH = this.PIXEL;
|
||||
core.drawImage('ui', ctx.canvas, 0, currH);
|
||||
|
||||
@ -67,6 +67,7 @@ utils.prototype.calValue = function (value, prefix, need, times) {
|
||||
value = value.replace(/item:([a-zA-Z0-9_]+)/g, "core.itemCount('$1')");
|
||||
value = value.replace(/flag:([a-zA-Z0-9_\u4E00-\u9FCC]+)/g, "core.getFlag('$1', 0)");
|
||||
value = value.replace(/switch:([a-zA-Z0-9_]+)/g, "core.getFlag('" + (prefix || ":f@x@y") + "@$1', 0)");
|
||||
value = value.replace(/global:([a-zA-Z0-9_\u4E00-\u9FCC]+)/g, "core.getGlobal('$1', 0)");
|
||||
return eval(value);
|
||||
}
|
||||
if (value instanceof Function) {
|
||||
@ -246,6 +247,31 @@ utils.prototype.removeLocalForage = function (key, successCallback, errorCallbac
|
||||
})
|
||||
}
|
||||
|
||||
utils.prototype.setGlobal = function (key, value) {
|
||||
if (core.isReplaying()) return;
|
||||
core.setLocalStorage(key, value);
|
||||
}
|
||||
|
||||
utils.prototype.getGlobal = function (key, defaultValue) {
|
||||
var value;
|
||||
if (core.isReplaying()) {
|
||||
// 不考虑key不一致的情况
|
||||
var action = core.status.replay.toReplay.shift();
|
||||
if (action.indexOf("input2:") == 0) {
|
||||
value = JSON.parse(core.decodeBase64(action.substring(7)));
|
||||
}
|
||||
else {
|
||||
core.control._replay_error(action);
|
||||
return core.getLocalStorage(key, defaultValue);
|
||||
}
|
||||
}
|
||||
else {
|
||||
value = core.getLocalStorage(key, defaultValue);
|
||||
}
|
||||
core.status.route.push("input2:" + core.encodeBase64(JSON.stringify(value)));
|
||||
return value;
|
||||
}
|
||||
|
||||
////// 深拷贝一个对象 //////
|
||||
utils.prototype.clone = function (data, filter, recursion) {
|
||||
if (!core.isset(data)) return null;
|
||||
@ -686,9 +712,8 @@ utils.prototype.rand2 = function (num) {
|
||||
value = parseInt(action.substring(7));
|
||||
}
|
||||
else {
|
||||
core.stopReplay();
|
||||
core.drawTip("录像文件出错");
|
||||
return;
|
||||
core.control._replay_error(action);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
6
main.js
6
main.js
@ -2,7 +2,7 @@ function main() {
|
||||
|
||||
//------------------------ 用户修改内容 ------------------------//
|
||||
|
||||
this.version = "2.6"; // 游戏版本号;如果更改了游戏内容建议修改此version以免造成缓存问题。
|
||||
this.version = "2.6.1"; // 游戏版本号;如果更改了游戏内容建议修改此version以免造成缓存问题。
|
||||
|
||||
this.useCompress = false; // 是否使用压缩文件
|
||||
// 当你即将发布你的塔时,请使用“JS代码压缩工具”将所有js代码进行压缩,然后将这里的useCompress改为true。
|
||||
@ -188,8 +188,8 @@ function main() {
|
||||
this.floors = {}
|
||||
this.canvas = {};
|
||||
|
||||
this.__VERSION__ = "2.6";
|
||||
this.__VERSION_CODE__ = 30;
|
||||
this.__VERSION__ = "2.6.1";
|
||||
this.__VERSION_CODE__ = 36;
|
||||
}
|
||||
|
||||
main.prototype.init = function (mode, callback) {
|
||||
|
||||
@ -77,7 +77,7 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
|
||||
"firstData": {
|
||||
"title": "魔塔样板",
|
||||
"name": "template",
|
||||
"version": "Ver 2.6",
|
||||
"version": "Ver 2.6.1",
|
||||
"floorId": "sample0",
|
||||
"hero": {
|
||||
"name": "阳光",
|
||||
|
||||
@ -465,7 +465,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
[12, "中毒", "战斗后,勇士陷入中毒状态,每一步损失生命" + core.values.poisonDamage + "点"],
|
||||
[13, "衰弱", "战斗后,勇士陷入衰弱状态,攻防暂时下降" + (core.values.weakValue >= 1 ? core.values.weakValue + "点" : parseInt(core.values.weakValue * 100) + "%")],
|
||||
[14, "诅咒", "战斗后,勇士陷入诅咒状态,战斗无法获得金币和经验"],
|
||||
[15, "领域", function (enemy) { return "经过怪物周围" + (enemy.range || 1) + "格时自动减生命" + (enemy.value || 0) + "点"; }],
|
||||
[15, "领域", function (enemy) { return "经过怪物周围" + (enemy.zoneSquare ? "九宫格" : "十字") + "范围内" + (enemy.range || 1) + "格时自动减生命" + (enemy.value || 0) + "点"; }],
|
||||
[16, "夹击", "经过两只相同的怪物中间,勇士生命值变成一半"],
|
||||
[17, "仇恨", "战斗前,怪物附加之前积累的仇恨值作为伤害" + (core.flags.hatredDecrease ? ";战斗后,释放一半的仇恨值" : "") + "。(每杀死一个怪物获得" + (core.values.hatred || 0) + "点仇恨值)"],
|
||||
[18, "阻击", function (enemy) { return "经过怪物的十字领域时自动减生命" + (enemy.value || 0) + "点,同时怪物后退一格"; }],
|
||||
@ -973,6 +973,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
icon = core.getMappedName(icon);
|
||||
if (core.material.images.images[icon]) {
|
||||
core.material.images.hero.src = core.material.images.images[icon].src;
|
||||
core.material.icons.hero.width = core.material.images.images[icon].width / 4;
|
||||
core.material.icons.hero.height = core.material.images.images[icon].height / 4;
|
||||
}
|
||||
// 刷新怪物数据
|
||||
|
||||
@ -25,6 +25,7 @@ var icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1 =
|
||||
"leftFoot": 1,
|
||||
"rightFoot": 3
|
||||
},
|
||||
"width": 32,
|
||||
"height": 48
|
||||
},
|
||||
"terrains": {
|
||||
|
||||
@ -416,5 +416,5 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a =
|
||||
"yellowJewel": "true",
|
||||
"skill1": "true"
|
||||
},
|
||||
"canEquip": {}
|
||||
"equipCondition": {}
|
||||
}
|
||||
23
更新说明.txt
23
更新说明.txt
@ -1,4 +1,25 @@
|
||||
HTML5魔塔样板V2.6
|
||||
HTML5魔塔样板V2.6.1
|
||||
|
||||
区域优化的录像播放功能,R键使用
|
||||
强制战斗可以指定怪物坐标,将自动隐藏并执行该点战后事件
|
||||
flag:xxx也支持中文,例如 flag:2楼机关门
|
||||
增加文件名映射,可以用中文映射到某个图片或bgm文件并使用
|
||||
勇士宽度可以超过32(例如48x48的勇士行走图)
|
||||
现在允许修改floorId和图块ID了(在表格下方)
|
||||
增加事件:自动存档,返回标题界面;部分事件优化
|
||||
商店长按空格可以连续加点
|
||||
增设global:xxx使用全局存储,可被录像支持
|
||||
支持\b[hero]和\b[null,x,y]来自动调整上下方向
|
||||
支持\t[yellowKey]等只显示图标而没有标题
|
||||
编辑器中前景层对于有事件的点半透明显示
|
||||
存档改成1000页,长按上下页可快速翻页
|
||||
录像播放初始默认暂停,N键可以单步执行
|
||||
增设本地API文档,部分API和事件的优化
|
||||
所有已知的bug修复,大量细节优化
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
HTML5魔塔样板V2.6
|
||||
|
||||
拆分整个项目,大幅重构代码,新增大量API
|
||||
重写文档,尤其是脚本和API列表
|
||||
|
||||
Loading…
Reference in New Issue
Block a user