git pull
104
README.md
@ -17,6 +17,7 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏!
|
||||
``` bash
|
||||
├── /_server/ # 为可视化地图编辑器提供一些支持的目录
|
||||
├── /docs/ # 文档目录
|
||||
├── /extensions/ # 拓展工具目录,发布到网站后不会加载
|
||||
├── /libs/ # 系统库目录
|
||||
│ ├─ /thirdparty/ # 游戏所用到的第三方库文件
|
||||
│ ├─ actions.js # 处理用户交互的文件
|
||||
@ -25,6 +26,7 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏!
|
||||
│ ├─ data.js # 记录了一些初始化信息
|
||||
│ ├─ enemys.js # 记录了怪物的信息,包括特殊属性、伤害计算公式、临界值计算等。
|
||||
│ ├─ events.js # 处理事件的文件,所有自定义事件都会在此文件中进行处理
|
||||
│ ├─ extensions.js # 加载拓展工具的文件
|
||||
│ ├─ icons.js # 图标信息,会被转发到project下
|
||||
│ ├─ items.js # 道具信息,会被转发到project下
|
||||
│ ├─ loader.js # 动态加载JS代码、图片、音效等
|
||||
@ -55,6 +57,108 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏!
|
||||
|
||||
## 更新说明
|
||||
|
||||
### 2019.12.31 HTML5魔塔样板V2.6.6
|
||||
|
||||
* [x] 编辑器增加【最近使用的图块】的区域
|
||||
* [x] 编辑器拉伸到铺满全屏幕,还可以Ctrl+滚轮放缩
|
||||
* [x] 编辑器支持连续Ctrl+Z的撤销,Ctrl+Y的重做
|
||||
* [x] 新增tileset右键绑定宽高,以替代贴图模式
|
||||
* [x] 多重自动存档,可以连续A键读档
|
||||
* [x] 高层塔分区域支持
|
||||
* [x] 自绘状态栏点击事件
|
||||
* [x] 绘制的锁定模式
|
||||
* [x] 等待用户操作增设分歧选项
|
||||
* [x] 增设压缩模式,会对图片等进行zip压缩
|
||||
* [x] 追加素材现在可以同时进行自动注册
|
||||
* [x] 可以复制和粘贴怪物或道具的属性
|
||||
* [x] 折叠素材时设置每一列个数
|
||||
* [x] 标题界面和显示选择项时光标跟随鼠标
|
||||
* [x] 修复所有已知的bug,大量细节优化
|
||||
|
||||
### 2019.12.1 HTML5魔塔样板V2.6.5
|
||||
|
||||
* [x] 事件:设置怪物属性;穿脱装备
|
||||
* [x] 新值块:enemy:xxx:atk可获得怪物数据
|
||||
* [x] 新值块:blockId:x,y获得某点图块ID
|
||||
* [x] 部分事件预编译,加快执行速度
|
||||
* [x] 在系统设置中可以设置bgm的播放音量
|
||||
* [x] 通关事件可以不退出游戏
|
||||
* [x] 失败时允许直接读取自动存档
|
||||
* [x] NPC48自动注册可以自动绑定faceIds
|
||||
* [x] 编辑器Alt+1-9存图块,1-9读取图块
|
||||
* [x] 编辑器现在可以跨楼层复制粘贴图块了
|
||||
* [x] 可以对flags.进行自动补全
|
||||
* [x] 部分Bug修复,大量细节优化
|
||||
|
||||
### 2019.10.29 HTML5魔塔样板V2.6.4
|
||||
|
||||
* [x] 自动事件,多事件页
|
||||
* [x] 增加开场logo动画
|
||||
* [x] 拓展:游戏时动态修改地图和怪物数据
|
||||
* [x] 插件:道具商店,支持买入和卖出道具
|
||||
* [x] 编辑器可以搜索变量出现位置
|
||||
* [x] 变量的中文替换
|
||||
* [x] 可以给图块绑定自定义脚本,碰触时触发
|
||||
* [x] 编辑器右键可以绑定机关门和出生点
|
||||
* [x] 支持多个drawTip同时出现
|
||||
* [x] 闪烁光标同时支持多个同时存在
|
||||
* [x] 插件:镜头平滑移动,默认禁用
|
||||
* [x] 素材的快速追加
|
||||
* [x] 批量导出动画
|
||||
* [x] 部分Bug修复,大量细节优化
|
||||
|
||||
### 2019.7.24 V2.6.3
|
||||
|
||||
* [x] 标题界面大幅美化,增加闪烁光标,支持键盘开始游戏
|
||||
* [x] 事件编辑器支持自动补全,能对flag和API列表等进行补全
|
||||
* [x] 剧情文本中\\c修改字体大小,\\d和\\e切换粗体和斜体
|
||||
* [x] 事件:设置视角&移动视角
|
||||
* [x] 可以指定显示选择项的出现条件并动态生成
|
||||
* [x] 楼层传送器的平面传送模式(哪里离开飞回到哪里)
|
||||
* [x] UI绘制事件增添绘制圆和绘制圆边框
|
||||
* [x] 所有的UI绘制事件均可以双击预览
|
||||
* [x] 播放BGM事件可以一直持续播放直到下次调用
|
||||
* [x] \f立绘支持alpha值
|
||||
* [x] 支持在脚本编辑中直接flags.xxx调用自定义变量
|
||||
* [x] 首次获得道具将给予提示
|
||||
* [x] 等待用户操作支持滚轮,视为PgUp和PgDn
|
||||
* [x] 脚本编辑器语法错误将禁止保存
|
||||
* [x] 录像播放时B键查看数据统计
|
||||
* [x] 所有已知bug的修复,大量细节优化
|
||||
|
||||
### 2019.6.7 V2.6.2
|
||||
|
||||
* [x] 可以拖动地图上的图块和事件,复制剪切和跨楼层粘贴
|
||||
* [x] 新增事件的地图选点功能,可以在地图上选择落点
|
||||
* [x] 现在素材区可以进行折叠与自动换列了
|
||||
* [x] 新增UI绘制系列事件,并且可以进行预览
|
||||
* [x] 显示文本事件的标题解析
|
||||
* [x] 新增常用工具:额外素材合并工具
|
||||
* [x] 进一步提升24倍速的播放速度
|
||||
* [x] 楼层转换增加对称点
|
||||
* [x] 增加编辑器快捷键说明,H键查看
|
||||
* [x] 文档-事件增加事件编辑器截图
|
||||
* [x] 大量细节优化,所有已知的Bug修复
|
||||
|
||||
### 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.6*,上次更新时间:* {docsify-updated} *
|
||||
|
||||
目前样板已经更新到V2.0版本以上,本章将对V2.0的一些内容进行介绍。
|
||||
|
||||
|
||||
216
_docs/api.md
@ -1,6 +1,6 @@
|
||||
# 附录:API列表
|
||||
|
||||
?> 目前版本**v2.6**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.6.6**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
这里将列出所有被转发到core的API,没有被转发的函数此处不会列出,请自行在代码中查看。
|
||||
|
||||
@ -57,7 +57,6 @@ core.platform.isPC (是否是电脑端)
|
||||
core.platform.isAndroid (是否是安卓端)
|
||||
core.platform.isIOS (是否是iOS端)
|
||||
core.platform.useLocalForage (是否开启了新版存档)
|
||||
core.platform.extendKeyBoard (是否开启了拓展键盘)
|
||||
|
||||
|
||||
core.domStyle
|
||||
@ -339,7 +338,7 @@ core.setHeroMoveInterval(callback)
|
||||
|
||||
|
||||
core.moveOneStep(x, y)
|
||||
每走完一步后执行的操作,被转发到了脚本编辑中。
|
||||
每走完一步后执行的操作,被转发到了脚本编辑中,执行脚本编辑moveOneStep中的内容。
|
||||
|
||||
|
||||
core.moveAction(callback)
|
||||
@ -350,6 +349,7 @@ core.moveAction(callback)
|
||||
core.moveHero(direction, callback)
|
||||
令勇士朝一个方向行走。如果设置了callback,则只会行走一步,并执行回调。
|
||||
否则,将一直朝该方向行走,直到core.status.heroStop为true为止。
|
||||
direction可为"up","down","right","left",分别对应上,下,右,左。
|
||||
|
||||
|
||||
core.isMoving()
|
||||
@ -362,10 +362,11 @@ core.waitHeroToStop(callback)
|
||||
|
||||
core.turnHero(direction)
|
||||
转向。如果设置了direction则会转到该方向,否则会右转。该函数会自动计入录像。
|
||||
direction可为"up","down","right","left",分别对应上,下,右,左。
|
||||
|
||||
|
||||
core.moveDirectly(destX, destY)
|
||||
尝试瞬间移动到某点,被转发到了脚本编辑中。
|
||||
尝试瞬间移动到某点,被转发到了脚本编辑中,执行脚本编辑中的内容。
|
||||
此函数返回非负值代表成功进行瞬移,返回值是省略的步数;如果返回-1则代表没有成功瞬移。
|
||||
|
||||
|
||||
@ -500,12 +501,12 @@ core.syncSave(type) / core.syncLoad()
|
||||
|
||||
|
||||
core.saveData()
|
||||
获得要存档的内容,实际转发到了脚本编辑中。
|
||||
获得要存档的内容,实际转发到了脚本编辑中,执行脚本编辑中的内容。
|
||||
|
||||
|
||||
core.loadData(data, callback)
|
||||
实际执行一次读档行为,data为读取到的数据,callback为执行完毕的回调。
|
||||
实际转发到了脚本编辑中。
|
||||
实际转发到了脚本编辑中,执行脚本编辑中的内容。
|
||||
|
||||
|
||||
core.getSave(index, callback)
|
||||
@ -535,19 +536,23 @@ core.removeSave(index)
|
||||
// ------ 属性、状态、位置、变量等 ------ //
|
||||
|
||||
core.setStatus(name, value)
|
||||
设置勇士当前的某个属性。
|
||||
设置勇士当前的某个属性,name可为"atk","def","hp"等。
|
||||
如core.setStatus("atk", 100)则为设置勇士攻击为100。
|
||||
|
||||
|
||||
core.addStatus(name, value)
|
||||
加减勇士当前的某个属性。等价于 core.setStatus(name, core.getStatus(name) + value)
|
||||
加减勇士当前的某个属性,name可为"atk","def","hp"等。
|
||||
如core.addStatus("atk", 100)则为增加勇士攻击100点。
|
||||
等价于 core.setStatus(name, core.getStatus(name) + value)。
|
||||
|
||||
|
||||
core.getStatus(name)
|
||||
获得勇士的某个原始属性值。
|
||||
获得勇士的某个原始属性值,该值不受百分比增幅影响。
|
||||
譬如你有一件道具加10%的攻击,你可以使用该函数获得你的攻击被增幅前的数值
|
||||
|
||||
|
||||
core.getStatusOrDefault(status, name)
|
||||
尝试从status中获得某个原始属性值;如果status为null或不存在对应属性值则从勇士属性中获取。
|
||||
尝试从status中获得某个原始属性值,该值不受百分比增幅影响;如果status为null或不存在对应属性值则从勇士属性中获取。
|
||||
此项在伤害计算函数中使用较多,例如传递新的攻击和防御来计算临界和1防减伤。
|
||||
|
||||
|
||||
@ -573,12 +578,14 @@ core.getBuff(name)
|
||||
|
||||
|
||||
core.setHeroLoc(name, value, noGather)
|
||||
设置勇士位置属性。name只能为'x', 'y'和'direction'之一。
|
||||
设置勇士位置属性。name只能为'x'(勇士x坐标), 'y'(勇士y坐标)和'direction'(勇士朝向)之一。
|
||||
如果noGather为true,则不会聚集所有的跟随者。
|
||||
譬如core.setHeroLoc("x", 1, true)则为设置勇士x坐标为1,不聚集所有跟随者。
|
||||
|
||||
|
||||
core.getHeroLoc(name)
|
||||
获得勇士的某个位置属性。如果name为null则直接返回core.status.hero.loc。
|
||||
譬如core.getHeroLoc("x")则返回勇士当前x坐标
|
||||
|
||||
|
||||
core.getLvName(lv)
|
||||
@ -587,19 +594,26 @@ core.getLvName(lv)
|
||||
|
||||
core.setFlag(name, value)
|
||||
设置某个自定义变量或flag。如果value为null则会调用core.removeFlag进行删除。
|
||||
这里的变量与事件中使用的变量等价
|
||||
譬如core.setFlag("xxx",1)则为设置变量xxx为1。
|
||||
|
||||
|
||||
core.addFlag(name, value)
|
||||
加减某个自定义的变量或flag。等价于 core.setFlag(name, core.getFlag(name, 0) + value)
|
||||
这里的变量与事件中使用的变量等价
|
||||
譬如core.addFlag("xxx",1)则为增加变量xxx1
|
||||
|
||||
|
||||
core.getFlag(name, defaultValue)
|
||||
获得某个自定义的变量或flag。如果该flag不存在(从未赋值过),则返回defaultValue值。
|
||||
获得某个自定义的变量或flag。如果该flag不存在(从未赋值过),则返回defaultValue的值。
|
||||
这里的变量与事件中使用的变量等价
|
||||
譬如core.getFlag("xxx",1)则为获得变量xxx的值,如变量xxx不存在则返回1
|
||||
|
||||
|
||||
core.hasFlag(name)
|
||||
判定是否拥有某个自定义变量或flag。等价于 !!core.getFlag(name, 0)
|
||||
|
||||
这里的变量与事件中使用的变量等价
|
||||
譬如core.hasFlag("xxx",1)则为判断变量xxx是否存在
|
||||
|
||||
core.removeFlag(name)
|
||||
删除一个自定义变量或flag。
|
||||
@ -620,6 +634,8 @@ core.setWeather(type, level)
|
||||
|
||||
core.setCurtain(color, time, callback)
|
||||
更改画面色调。color为更改到的色调,是个三元或四元组;time为渐变时间,0代表立刻切换。
|
||||
譬如core.setCurtain([255,255,255,1], 0)即为无回调无等待更改画面色调为白色
|
||||
|
||||
|
||||
|
||||
core.screenFlash(color, time, times, callback)
|
||||
@ -655,9 +671,9 @@ core.clearStatusBar()
|
||||
清空状态栏的数据。
|
||||
|
||||
|
||||
core.updateStatusBar()
|
||||
core.updateStatusBar(doNotCheckAutoEvents)
|
||||
更新状态栏,被转发到了脚本编辑中。此函数还会根据是否在回放来设置工具栏的图标。
|
||||
|
||||
如果doNotCheckAutoEvents为true则此时不检查自动事件。
|
||||
|
||||
core.showStatusBar() / core.hideStatusBar(showToolbox)
|
||||
显示和隐藏状态栏。
|
||||
@ -708,7 +724,7 @@ special为要测试的内容,允许接收如下类型参数:
|
||||
|
||||
|
||||
core.getSpecials()
|
||||
获得所有特殊属性的列表。实际上被转发到了脚本编辑中。
|
||||
获得所有特殊属性的列表。实际上被转发到了脚本编辑中,执行脚本编辑中的内容。
|
||||
|
||||
|
||||
core.getSpecialText(enemy)
|
||||
@ -748,7 +764,7 @@ number为要计算的临界值数量,不填默认为1。
|
||||
|
||||
|
||||
core.getDefDamage(enemy, k, x, y, floorId)
|
||||
获得某个怪物的k防减伤值。k可不填默认为1。
|
||||
获得某个怪物的k防减伤值。k可不填默认为1,x,y,floorId为当前xy坐标和楼层。
|
||||
|
||||
|
||||
core.getEnemyInfo(enemy, hero, x, y, floorId)
|
||||
@ -765,10 +781,6 @@ hero可为null或一个对象,具体将使用core.getRealStatusOrDefault(hero,
|
||||
从V2.5.5开始,该函数也允许直接返回一个数字,代表战斗伤害值,此时回合数将视为0。
|
||||
|
||||
|
||||
core.updateEnemys()
|
||||
更新怪物数据。该函数实际被转发到了脚本编辑中。详见文档-事件-更新怪物数据。
|
||||
|
||||
|
||||
core.getCurrentEnemys(floorId)
|
||||
获得某个楼层不重复的怪物信息,floorId不填默认为当前楼层。该函数会被怪物手册所调用。
|
||||
该函数将返回一个列表,每一项都是一个不同的怪物,按照伤害值从小到大排序。
|
||||
@ -776,7 +788,8 @@ core.getCurrentEnemys(floorId)
|
||||
|
||||
|
||||
core.hasEnemyLeft(enemyId, floorId)
|
||||
检查某个楼层是否还有剩余的(指定)怪物。floorId为楼层ID,可忽略表示当前楼层。
|
||||
检查某个楼层是否还有剩余的(指定)怪物。
|
||||
floorId为楼层ID,可忽略表示当前楼层。也可以填数组如["MT0","MT1"]同时检测多个楼层。
|
||||
enemyId如果不填或null则检查是否剩余任何怪物,否则只检查是否剩余指定的某类怪物。
|
||||
```
|
||||
|
||||
@ -806,16 +819,16 @@ seed为开始时要设置的的种子,route为要开始播放的录像,callb
|
||||
|
||||
core.setInitData()
|
||||
根据难度分歧来初始化难度,包括设置flag:hard,设置初始属性等。
|
||||
该函数实际被转发到了脚本编辑中。
|
||||
该函数实际被转发到了脚本编辑中,执行脚本编辑中的内容。
|
||||
|
||||
|
||||
core.win(reason, norank)
|
||||
游戏胜利,reason为结局名,norank如果为真则该结局不计入榜单。
|
||||
该函数实际被转发到了脚本编辑中。
|
||||
该函数实际被转发到了脚本编辑中,执行脚本编辑中的内容。
|
||||
|
||||
|
||||
core.lose(reason)
|
||||
游戏失败,reason为结局名。该函数实际被转发到了脚本编辑中。
|
||||
游戏失败,reason为结局名。该函数实际被转发到了脚本编辑中,执行脚本编辑中的内容。
|
||||
|
||||
|
||||
core.gameOver(ending, fromReplay, norank)
|
||||
@ -855,7 +868,7 @@ id为怪物的ID,x和y为怪物坐标,force如果为真将强制战斗,cal
|
||||
|
||||
|
||||
core.beforeBattle(enemyId, x, y)
|
||||
战前事件。实际被转发到了脚本编辑中,可以在这里加上一些战前特效。
|
||||
战前事件。实际被转发到了脚本编辑中,执行脚本编辑中的内容,可以用于加上一些战前特效。
|
||||
此函数在“检测能否战斗和自动存档”【之后】执行。
|
||||
如果需要更早的战前事件,请在插件中覆重写 core.events.doSystemEvent 函数。
|
||||
此函数返回true则将继续本次战斗,返回false将不再战斗。
|
||||
@ -863,7 +876,7 @@ core.beforeBattle(enemyId, x, y)
|
||||
|
||||
core.afterBattle(enemyId, x, y, callback)
|
||||
战后事件,将执行扣血、加金币经验、特殊属性处理、战后事件处理等操作。
|
||||
实际被转发到了脚本编辑中。
|
||||
实际被转发到了脚本编辑中,执行脚本编辑中的内容。
|
||||
|
||||
|
||||
core.openDoor(x, y, needKey, callback)
|
||||
@ -872,16 +885,17 @@ core.openDoor(x, y, needKey, callback)
|
||||
|
||||
|
||||
core.afterOpenDoor(doorId, x, y, callback)
|
||||
开完一个门后执行的事件,实际被转发到了脚本编辑中。
|
||||
开完一个门后执行的事件,实际被转发到了脚本编辑中,执行脚本编辑中的内容。
|
||||
|
||||
|
||||
core.getItem(id, num, x, y, callback)
|
||||
获得若干个道具。itemId为道具ID,itemNum为获得的道具个数,不填默认为1。
|
||||
x和y为道具点的坐标,如果设置则会擦除地图上的该点。
|
||||
x和y为道具点的坐标,如果设置则会擦除地图上的该点,也可不填。
|
||||
譬如core.getItem("yellowKey",2)会直接获得两把黄钥匙。
|
||||
|
||||
|
||||
core.afterGetItem(id, x, y, callback)
|
||||
获得一个道具后执行的事件,实际被转发到了脚本编辑中。
|
||||
获得一个道具后执行的事件,实际被转发到了脚本编辑中,执行脚本编辑中的内容。
|
||||
|
||||
|
||||
core.getNextItem(noRoute)
|
||||
@ -918,7 +932,7 @@ core.pushBox(data)
|
||||
|
||||
|
||||
core.afterPushBox()
|
||||
推箱子之后触发的事件,实际被转发到了脚本编辑中。
|
||||
推箱子之后触发的事件,实际被转发到了脚本编辑中,执行脚本编辑中的内容。
|
||||
|
||||
|
||||
core.changeLight(id, x, y)
|
||||
@ -951,10 +965,11 @@ core.startEvents(list, x, y, callback)
|
||||
此函数将调用core.setEvents,然后停止勇士,再执行core.doAction()。
|
||||
|
||||
|
||||
core.doAction()
|
||||
core.doAction(keepUI)
|
||||
执行下一个自定义事件。
|
||||
此函数将检测事件列表是否全部执行完毕,如果是则执行回调函数。
|
||||
否则,将从事件列表中弹出下一个事件,并调用core.doEvent进行执行。
|
||||
如果keepUI为true,则不会清掉UI层和selector,适合于自己用脚本的绘制。
|
||||
|
||||
|
||||
core.insertAction(action, x, y, callback, addToLast)
|
||||
@ -972,6 +987,15 @@ core.getCommonEvent(name)
|
||||
core.recoverEvents(data)
|
||||
恢复事件现场。一般用于呼出怪物手册、呼出存读档页面等时,恢复事件执行流。
|
||||
|
||||
|
||||
core.checkAutoEvents()
|
||||
检测自动事件并执行。
|
||||
|
||||
|
||||
core.precompile(events)
|
||||
尝试预编译一段事件。
|
||||
|
||||
|
||||
// ------ 点击状态栏图标时执行的一些操作 ------ //
|
||||
|
||||
core.openBook(fromUserAction)
|
||||
@ -1019,15 +1043,21 @@ core.follow(name) / core.unfollow(name)
|
||||
|
||||
core.setValue(name, value, prefix) / core.addValue(name, value, prefix)
|
||||
设置/增减某个数值。name可以是status:xxx,item:xxx或flag:xxx。
|
||||
value可以是一个表达式,将调用core.calValue()计算。prefix为前缀,独立开关使用。
|
||||
value可以是一个表达式,将调用core.calValue()计算。prefix为前缀,独立开关使用,脚本中一般忽略。
|
||||
|
||||
|
||||
core.doEffect(effect, need, times)
|
||||
执行一个effect操作。该函数目前仅被全局商店的status:xxx+=yyy所调用。
|
||||
|
||||
|
||||
core.setEnemy(id, name, value, prefix)
|
||||
设置一个怪物属性。id为怪物的ID,name为要设置的项,比如hp,atk,def等等。
|
||||
value可以是一个表达式,将调用core.calValue()计算。prefix为前缀,独立开关使用,脚本中一般忽略。
|
||||
|
||||
|
||||
core.setFloorInfo(name, values, floorId, prefix)
|
||||
设置某层楼的楼层属性。
|
||||
设置某层楼的楼层属性,其中name为该楼层属性对应的条目,values为要设置的值,floorId为楼层id,prefix一般直接忽略。
|
||||
譬如core.setFloorInfo("name","4", "MT1")则为设置MT1显示在状态栏中的层数为4
|
||||
|
||||
|
||||
core.setGlobalAttribute(name, value)
|
||||
@ -1186,8 +1216,9 @@ core.addItem(itemId, itemNum)
|
||||
|
||||
|
||||
core.getEquipTypeByName(name)
|
||||
根据装备位名称来找到一个空的装备孔,适用于多重装备。
|
||||
根据装备位名称来找到一个空的装备孔,适用于多重装备,装备位名称可在全塔属性中设置。
|
||||
如果没有一个装备孔是该装备名称,则返回-1。
|
||||
譬如:core.getEquipTypeByName("武器")默认返回全塔属性中武器对应的装备孔号0。
|
||||
|
||||
|
||||
core.getEquipTypeById(equipId)
|
||||
@ -1200,11 +1231,12 @@ core.canEquip(equipId, hint)
|
||||
|
||||
|
||||
core.loadEquip(equipId, callback)
|
||||
穿上某个装备。
|
||||
穿上某个装备,equipId为装备id。
|
||||
|
||||
|
||||
core.unloadEquip(equipType, callback)
|
||||
脱下某个装备孔的装备。
|
||||
譬如core.unloadEquip(0)则为脱下0号装备孔中的装备,默认0号装备孔对应“武器”,1号装备孔对应“盾牌”
|
||||
|
||||
|
||||
core.compareEquipment(compareEquipId, beComparedEquipId)
|
||||
@ -1219,6 +1251,10 @@ core.quickSaveEquip(index)
|
||||
|
||||
core.quickLoadEquip()
|
||||
读取当前套装。index为读取的套装编号。
|
||||
|
||||
|
||||
core.getEquippedStatus(name)
|
||||
获得装备直接增加的属性数据。
|
||||
```
|
||||
|
||||
## loader.js
|
||||
@ -1276,7 +1312,7 @@ map为存档信息,如果某项在map中不存在则会从core.floors中读取
|
||||
|
||||
|
||||
core.getNumberById(id)
|
||||
给定一个图块ID,找到对应的数字。
|
||||
给定一个图块ID,找到图块对应的图块编号。
|
||||
|
||||
|
||||
core.initBlock(x, y, id, addInfo, eventFloor)
|
||||
@ -1305,6 +1341,12 @@ core.loadMap(data, floorId)
|
||||
从data中读取楼层数据,并调用core.loadFloor()进行初始化。
|
||||
|
||||
|
||||
core.removeMaps(fromId, toId)
|
||||
删除某个区域的地图。调用此函数后,这些楼层将不可飞,不可被浏览地图,也不计入存档。
|
||||
fromId和toId为要删除的起终点楼层ID;toId也可以不填代表只删除某一层。
|
||||
此函数适用于高层塔的砍层,例如每100层一个区域且互相独立,不可再返回的情况。
|
||||
|
||||
|
||||
core.resizeMap(floorId)
|
||||
根据某层楼的地图大小来调整大地图的画布大小。floorId可为null表示当前层。
|
||||
|
||||
@ -1412,7 +1454,7 @@ toDraw为要绘制到的信息(可为null,或为一个画布名),包括
|
||||
// ------ 获得某个点的图块信息 ------ //
|
||||
|
||||
core.noPass(x, y, floorId)
|
||||
判定某个点是否有noPass的图块。
|
||||
判定某个点是否有noPass(不可通行)的图块。
|
||||
|
||||
|
||||
core.npcExists(x, y, floorId)
|
||||
@ -1420,7 +1462,7 @@ core.npcExists(x, y, floorId)
|
||||
|
||||
|
||||
core.terrainExists(x, y, id, floorId)
|
||||
判定某个点是否有(指定的)地形存在。
|
||||
判定某个点是否有(id对应的)地形存在。
|
||||
如果id为null,则只要存在terrains即为真,否则还会判定对应点的ID。
|
||||
|
||||
|
||||
@ -1433,7 +1475,7 @@ core.nearStair()
|
||||
|
||||
|
||||
core.enemyExists(x, y, id, floorId)
|
||||
判定某个点是否有(指定的)怪物存在。
|
||||
判定某个点是否有(id对应的)怪物存在。
|
||||
如果id为null,则只要存在怪物即为真,否则还会判定对应点的怪物ID。
|
||||
请注意,如果需要判定某个楼层是否存在怪物请使用core.hasEnemyLeft()函数。
|
||||
|
||||
@ -1490,14 +1532,17 @@ core.removeBlock(x, y, floorId)
|
||||
|
||||
|
||||
core.removeBlockById(index, floorId)
|
||||
每个楼层的图块存成一个数组,index即为该数组中的索引,每个索引对应该地图中的一个图块
|
||||
根据索引从地图的block数组中尽可能删除一个图块。floorId可不填或null表示当前楼层。
|
||||
|
||||
|
||||
core.removeBlockByIds(floorId, ids)
|
||||
ids为由索引组成的数组,如[0,1]等
|
||||
根据索引数组从地图的block数组中尽可能删除一系列图块。floorId可不填或null表示当前楼层。
|
||||
|
||||
|
||||
core.canRemoveBlock(block, floorId)
|
||||
block为图块信息,可由core.getBlock获取
|
||||
判定当前能否完全删除某个图块。floorId可不填或null表示当前楼层。
|
||||
如果该点存在自定义事件,或者是重生怪,则不可进行删除。
|
||||
|
||||
@ -1541,7 +1586,7 @@ number为要设置到的图块数字,x,y和floorId为目标点坐标和楼层
|
||||
|
||||
core.resetMap(floorId)
|
||||
重置某层或若干层的地图和楼层属性。
|
||||
floorId可为某个楼层ID,或者一个楼层数组(同时重置若干层);如果不填则只重置当前楼层。
|
||||
floorId可为某个楼层ID,或者一个楼层数组如["MT1","MT2"](同时重置若干层);如果不填则只重置当前楼层。
|
||||
|
||||
// ------ 移动/跳跃图块,淡入淡出图块 ------ //
|
||||
|
||||
@ -1585,6 +1630,12 @@ core.drawAnimate(name, x, y, callback)
|
||||
此函数会返回一个动画id,可以通过core.stopAnimate()立刻停止该动画的播放。
|
||||
|
||||
|
||||
core.drawHeroAnimate(name, callback)
|
||||
绘制一个跟随勇士行动的动画。name为动画名,callback为绘制完毕的回调函数。
|
||||
此函数将播放动画音效,并异步开始绘制该动画。
|
||||
此函数会返回一个动画id,可以通过core.stopAnimate()立刻停止该动画的播放。
|
||||
|
||||
|
||||
core.stopAnimate(id, doCallback)
|
||||
立刻停止某个动画的播放。id为上面core.drawAnimate的返回值。
|
||||
如果doCallback为真,则会执行该动画所对应的回调函数。
|
||||
@ -1614,11 +1665,16 @@ core.clearMap(name)
|
||||
该函数的name也可以是'all',若为'all'则为清空所有系统画布。
|
||||
|
||||
|
||||
core.fillText(name, text, x, y, style, font)
|
||||
core.fillText(name, text, x, y, style, font, maxWidth)
|
||||
在某个画布上绘制一段文字。
|
||||
text为要绘制的文本,x,y为要绘制的坐标,style可选为绘制的样式,font可选为绘制的字体。(下同)
|
||||
style可直接使用"red","white"等或用"rgba(255,255,255,1)"或用"#FFFFFF"等方式来获得字体对应的颜色
|
||||
font的格式为"20px Verdana"前者为字体大小,后者为字体
|
||||
如果maxWidth不为null,则视为文字最大宽度,如果超过此宽度则会自动放缩文字直到自适应为止。
|
||||
请注意textAlign和textBaseline将决定绘制的左右对齐和上下对齐方式。
|
||||
具体可详见core.setTextAlign()和core.setTextBaseline()函数。
|
||||
譬如:core.fillText("ui", "这是要描绘的文字", 10, 10, "red", "20px Verdana", 100)
|
||||
即是在ui图层上,以10,10为起始点,描绘20像素大小,Verdana字体的红色字,长度不超过100像素
|
||||
|
||||
|
||||
core.fillBoldText(name, text, x, y, style, font)
|
||||
@ -1626,7 +1682,7 @@ core.fillBoldText(name, text, x, y, style, font)
|
||||
|
||||
|
||||
core.fillRect(name, x, y, width, height, style)
|
||||
绘制一个矩形。style可选为绘制样式。如果设置将调用core.setFillStyle()。(下同)
|
||||
绘制一个矩形。width, height为矩形宽高,style可选为绘制样式。如果设置将调用core.setFillStyle()。(下同)
|
||||
|
||||
|
||||
core.strokeRect(name, x, y, width, height, style, lineWidth)
|
||||
@ -1635,11 +1691,11 @@ lineWidth如果设置将调用core.setLineWidth()。(下同)
|
||||
|
||||
|
||||
core.drawLine(name, x1, y1, x2, y2, style, lineWidth)
|
||||
绘制一条线。
|
||||
绘制一条线,x1y1为起始点像素,x2y2为终止点像素。
|
||||
|
||||
|
||||
core.drawArrow(name, x1, y1, x2, y2, style, lineWidth)
|
||||
绘制一个箭头。
|
||||
绘制一个箭头,x1y1为起始点像素,x2y2为终止点像素。
|
||||
|
||||
|
||||
core.setFont(name, font) / core.setLineWidth(name, lineWidth)
|
||||
@ -1661,7 +1717,7 @@ core.setFillStyle(name, style) / core.setStrokeStyle(name, style)
|
||||
|
||||
|
||||
core.setTextAlign(name, align)
|
||||
设置一个画布的文字横向对齐模式,这里的align只能为'left', 'right'和'center'。
|
||||
设置一个画布的文字横向对齐模式,这里的align只能为'left', 'right'和'center',分别对应左对齐,右对齐,居中。
|
||||
默认为'left'。
|
||||
|
||||
|
||||
@ -1692,6 +1748,13 @@ core.drawImage(name, image, x, y, w, h, x1, y1, w1, h1)
|
||||
http://www.w3school.com.cn/html5/canvas_drawimage.asp
|
||||
这里的image允许传一个图片,画布。也允许传递图片名,将从你导入的图片中获取图片内容。
|
||||
|
||||
|
||||
core.drawIcon(name, id, x, y, w, h)
|
||||
在一张画布上绘制一个图标。
|
||||
id为注册过的图标ID,也可以使用状态栏的图标ID,例如lv, hp, up, save, settings等。
|
||||
x和y为绘制的左上角坐标;w和h可选为绘制的宽高,如果不填或null则使用该图标的默认宽高。
|
||||
|
||||
|
||||
// ------ 具体的某个UI界面的绘制 ------ //
|
||||
core.closePanel()
|
||||
结束一切事件和UI绘制,关闭UI窗口,返回游戏。
|
||||
@ -1702,16 +1765,21 @@ core.clearUI()
|
||||
重置UI窗口。此函数将清掉所有的UI帧动画和光标,清空UI画布,并将alpha设为1。
|
||||
|
||||
|
||||
core.drawTip(text, id)
|
||||
core.drawTip(text, id, clear)
|
||||
在左上角以气泡的形式绘制一段提示。
|
||||
text为文字内容,仅支持${}的表达式计算,不支持换行和变色。
|
||||
id可选,为同时绘制的图标ID,如果不为null则会同时绘制该图标(仅对32x32的素材有效)。
|
||||
也可以使用状态栏的图标ID,例如lv, hp, up, save, settings等。
|
||||
如果clear为true,则会清空当前所有正在显示的提示。
|
||||
|
||||
|
||||
core.clearTip()
|
||||
清空当前所有正在显示的提示。
|
||||
|
||||
|
||||
core.drawText(content, callback)
|
||||
绘制一段文字。contents为一个字符串或一个字符串数组,callback为全部绘制完毕的回调。
|
||||
支持所有的文字效果(如\n,${},\r,\\i等),也支持\t和\b的语法。
|
||||
支持所有的文字效果(如\n,${},\r,\\i,\\c,\\d,\\e等),也支持\t和\b的语法。
|
||||
如果当前在事件处理中或录像回放中,则会自动转成core.insertAction处理。
|
||||
不建议使用该函数,如有绘制文字的需求请尽量使用core.insertAction()插入剧情文本事件。
|
||||
|
||||
@ -1736,7 +1804,8 @@ posInfo如果不为null则是一个含position, px和py的对象,表示一个
|
||||
core.drawTextContent(ctx, content, config)
|
||||
根据配置在某个画布上绘制一段文字。此函数会被core.drawTextBox()所调用。
|
||||
ctx为画布名或画布本身,如果不设置则会忽略该函数。
|
||||
content为要绘制的文字内容,支持所有的文字效果(如\n,${},\r,\\i等),但不支持支持\t和\b的语法。
|
||||
content为要绘制的文字内容,支持所有的文字效果(如\n,${},\r,\\i,\\c,\\d,\\e等)
|
||||
,但不支持支持\t和\b的语法。
|
||||
config为绘制的配置项,目前可以包括如下几项:
|
||||
- left, top:在该画布上绘制的左上角像素位置,不设置默认为(0,0)。
|
||||
> 该函数绘制时会将textBaseline设置为'top',因此只需要考虑第一个字的左上角位置。
|
||||
@ -1745,13 +1814,14 @@ config为绘制的配置项,目前可以包括如下几项:
|
||||
- bold:是否粗体。如果不设置默认为false。
|
||||
- align:文字对齐方式,仅在maxWidth设置时有效,默认为'left'。
|
||||
- fontSize:字体大小,如果不设置则使用剧情文本设置中的正文字体大小。
|
||||
- lineHeight:绘制的行距值,如果不设置则使用fontSize*1.3(即1.3被行距)。
|
||||
- lineHeight:绘制的行距值,如果不设置则使用fontSize*1.3(即1.3倍行距)。
|
||||
- time:打字机效果。若不为0,则会逐个字进行绘制,并设置core.status.event.interval定时器。
|
||||
- interval:字符间的间距。值表示绘制每个字符之间间隔的距离,默认为0。
|
||||
|
||||
|
||||
core.drawTextBox(content, showAll)
|
||||
绘制一个对话框。content为一个字符串或一个字符串数组。
|
||||
支持所有的文字效果(如\n,${},\r,\\i等),也支持\t和\b的语法。
|
||||
支持所有的文字效果(如\n,${},\r,\\i,\\c,\\d,\\e等),也支持\t和\b的语法。
|
||||
该函数将使用用户在剧情文本设置中的配置项进行绘制。
|
||||
实际执行时,会计算文本框宽度并绘制背景,绘制标题和头像,再调用core.drawTextContent()绘制正文内容。
|
||||
showAll可选,如果为true则不会使用打字机效果而全部显示,主要用于打字机效果的点击显示全部。
|
||||
@ -1759,7 +1829,7 @@ showAll可选,如果为true则不会使用打字机效果而全部显示,主
|
||||
|
||||
core.drawScrollText(content, time, lineHeight, callback)
|
||||
绘制一个滚动字幕。content为绘制内容,time为总时间(默认为5000),lineHeight为行距比例(默认为1.4)。
|
||||
滚动字幕将绘制在UI上,支持所有的文字效果(如\n,${},\r,\\i等),但不支持\t和\b效果。
|
||||
滚动字幕将绘制在UI上,支持所有的文字效果(如\n,${},\r,\\i,\\c,\\d,\\e等),但不支持\t和\b效果。
|
||||
可以通过剧情文本设置中的align控制是否居中绘制,offset控制其距离左边的偏移量。
|
||||
|
||||
|
||||
@ -1771,7 +1841,7 @@ core.textImage(content, lineHeight)
|
||||
|
||||
core.drawChoices(content, choices)
|
||||
绘制一个选项框。
|
||||
content可选,为选项上方的提示文字,支持所有的文字效果(如\n,${},\r,\\i等),也支持\t效果。
|
||||
content可选,为选项上方的提示文字,支持所有的文字效果(如\n,${},\r,\\i,\\c,\\d,\\e等),也支持\t。
|
||||
choices必选,为要绘制的选项内容,是一个列表。其中的每一项:
|
||||
- 可以是一个字符串,表示选项文字,将使用剧情文本设置中的正文颜色来绘制,仅支持${}表达式计算。
|
||||
- 或者是一个包含text, color和icon的对象。
|
||||
@ -1838,11 +1908,14 @@ z值为创建的纵向高度(关系到画布之间的覆盖),z值高的将
|
||||
|
||||
|
||||
core.ui.relocateCanvas(name, x, y)
|
||||
重新定位一个自定义画布。x和y为画布的左上角坐标。
|
||||
重新定位一个自定义画布。x和y为画布的左上角坐标,name为画布名。
|
||||
|
||||
|
||||
core.ui.resizeCanvas(name, width, height)
|
||||
重新设置一个自定义画布的大小。width和height为新设置的宽高。此操作会清空画布。
|
||||
core.ui.resizeCanvas(name, width, height, styleOnly)
|
||||
重新设置一个自定义画布的大小。width和height为新设置的宽高。
|
||||
styleOnly控制是否只修改画布的显示大小(而不修改画布的内部大小)。
|
||||
如果styleOnly为true,则只修改其显示大小(即canvas.style.width);
|
||||
否则,则会同时修改画布的显示大小和内部大小并清空画布内容。
|
||||
|
||||
|
||||
core.ui.deleteCanvas(name)
|
||||
@ -1862,6 +1935,11 @@ core.replayText(text, need, times)
|
||||
将一段文字中的${}(表达式)进行替换。need和time一般可以直接忽略。
|
||||
|
||||
|
||||
core.replaceValue(value)
|
||||
对一个表达式中的特殊规则进行替换,如status:xxx等。
|
||||
请注意,此项不会对独立开关如switch:A进行替换。
|
||||
|
||||
|
||||
core.calValue(value, prefix, need, time)
|
||||
计算一个表达式的值,支持status:xxx等的计算。
|
||||
prefix为前缀(switch:xxx的独立开关使用),need和time一般可以直接忽略。
|
||||
@ -1914,6 +1992,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
|
||||
@ -2013,6 +2102,7 @@ core.matchWildcard(pattern, string)
|
||||
|
||||
core.encodeBase64(str) / core.decodeBase64(str)
|
||||
将字符串进行base64加密或解密。
|
||||
可用于解压缩录像数据
|
||||
|
||||
|
||||
core.convertBase(str, fromBase, toBase)
|
||||
@ -2035,8 +2125,9 @@ num如果设置大于0,则生成一个[0, num-1]之间的数;否则生成一
|
||||
即先生成一个真随机数,根据该数来推进伪随机的种子,这样就可以放心调用core.rand()啦。
|
||||
|
||||
|
||||
core.readFile(success, error)
|
||||
core.readFile(success, error, accept)
|
||||
读取一个本地文件内容。success和error分别为读取成功或失败的回调函数。
|
||||
accept如果设置则控制能选择的文件类型。
|
||||
iOS平台暂不支持读取文件操作。
|
||||
|
||||
|
||||
@ -2087,7 +2178,16 @@ core.same(a, b)
|
||||
如果a和b都是数组,则会递归依次比较数组中的值;如果都是对象亦然。
|
||||
|
||||
|
||||
core.utils.http(type, url, formData, success, error, mimeType, responseType)
|
||||
core.unzip(blobOrUrl, success, error, convertToText)
|
||||
解压一个zip文件。
|
||||
blobOrUrl为传入的二进制zip文件Blob格式,或zip文件的地址。
|
||||
success为成功后的回调,接收 文件名-文件内容 形式的对象,即
|
||||
{"filename1": ..., "filename2": ...}
|
||||
error为失败的回调,接收参数message为错误信息。
|
||||
convertToText如果为true则会将每个文件内容转成纯文本而不是二进制格式。
|
||||
|
||||
|
||||
core.http(type, url, formData, success, error, mimeType, responseType)
|
||||
发送一个异步HTTP请求。
|
||||
type为'GET'或者'POST';url为目标地址;formData如果是POST请求则为表单数据。
|
||||
success为成功后的回调,error为失败后的回调。
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# 元件说明
|
||||
|
||||
?> 目前版本**v2.6**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.6.6**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
在本章中,将对样板里的各个元件进行说明。各个元件主要包括道具、门、怪物、楼梯等等。
|
||||
|
||||
@ -282,10 +282,13 @@ floorId指定的是目标楼层的唯一标识符(ID)。
|
||||
- 使用`${}`来计算一个表达式的值,如`${status:atk+status:def}`。
|
||||
- 使用`\f[...]`来同时插入一张立绘图,如`\f[1.png,100,200]`。
|
||||
- 使用`\\i[...]`来在对话框中绘制一个图标,如`\\i[fly]`。
|
||||
- 使用`\\c[...]`来修改字体大小,如`\\b[16]`。
|
||||
- 使用`\\d`来加粗或者取消粗体。
|
||||
- 使用`\\e`来加斜体或取消斜体。
|
||||
|
||||
从V2.5.2开始,也允许绘制一张头像图在对话框中,只要通过`\t[1.png]`或`\t[标题,1.png]`的写法。
|
||||
|
||||
**使用`\\i[...]`绘制图标请注意:在事件块中,允许只写一个反斜杠`\i`,系统会自动转义成`\\i`;但是在脚本中必须两个反斜杠都写上!**
|
||||
**使用`\\i,\\c,\\d,\\e`时请注意:在事件块中,允许只写一个反斜杠`\`,系统会自动转义成`\\`;但是在脚本中必须两个反斜杠都写上!**
|
||||
|
||||
详细信息请参见[剧情文本控制](event#text:显示一段文字(剧情))中的说明。
|
||||
|
||||
|
||||
660
_docs/event.md
BIN
_docs/img/autoEvent.png
Normal file
|
After Width: | Height: | Size: 54 KiB |
BIN
_docs/img/events/1.jpg
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
_docs/img/events/10.jpg
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
_docs/img/events/11.jpg
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
_docs/img/events/12.jpg
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
_docs/img/events/13.jpg
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
_docs/img/events/14.jpg
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
_docs/img/events/15.jpg
Normal file
|
After Width: | Height: | Size: 49 KiB |
BIN
_docs/img/events/15.png
Normal file
|
After Width: | Height: | Size: 77 KiB |
BIN
_docs/img/events/16.jpg
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
_docs/img/events/17.jpg
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
_docs/img/events/18.jpg
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
_docs/img/events/19.jpg
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
_docs/img/events/2.jpg
Normal file
|
After Width: | Height: | Size: 48 KiB |
BIN
_docs/img/events/20.jpg
Normal file
|
After Width: | Height: | Size: 50 KiB |
BIN
_docs/img/events/21.jpg
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
_docs/img/events/22.jpg
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
_docs/img/events/23.jpg
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
_docs/img/events/24.jpg
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
_docs/img/events/25.jpg
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
_docs/img/events/26.jpg
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
_docs/img/events/27.jpg
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
_docs/img/events/28.jpg
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
_docs/img/events/29.jpg
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
_docs/img/events/3.jpg
Normal file
|
After Width: | Height: | Size: 41 KiB |
BIN
_docs/img/events/30.jpg
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
_docs/img/events/31.jpg
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
_docs/img/events/32.jpg
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
_docs/img/events/33.jpg
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
_docs/img/events/34.jpg
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
_docs/img/events/35.jpg
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
_docs/img/events/36.jpg
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
_docs/img/events/37.jpg
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
_docs/img/events/38.jpg
Normal file
|
After Width: | Height: | Size: 43 KiB |
BIN
_docs/img/events/39.jpg
Normal file
|
After Width: | Height: | Size: 41 KiB |
BIN
_docs/img/events/4.jpg
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
_docs/img/events/40.jpg
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
_docs/img/events/41.jpg
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
_docs/img/events/42.jpg
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
_docs/img/events/43.jpg
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
_docs/img/events/44.jpg
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
_docs/img/events/45.jpg
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
_docs/img/events/46.jpg
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
_docs/img/events/47.jpg
Normal file
|
After Width: | Height: | Size: 75 KiB |
BIN
_docs/img/events/48.jpg
Normal file
|
After Width: | Height: | Size: 50 KiB |
BIN
_docs/img/events/49.jpg
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
_docs/img/events/5.jpg
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
_docs/img/events/50.jpg
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
_docs/img/events/51.jpg
Normal file
|
After Width: | Height: | Size: 45 KiB |
BIN
_docs/img/events/52.jpg
Normal file
|
After Width: | Height: | Size: 46 KiB |
BIN
_docs/img/events/52.png
Normal file
|
After Width: | Height: | Size: 104 KiB |
BIN
_docs/img/events/53.jpg
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
_docs/img/events/54.jpg
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
_docs/img/events/55.jpg
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
_docs/img/events/56.jpg
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
_docs/img/events/57.jpg
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
_docs/img/events/58.jpg
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
_docs/img/events/59.jpg
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
_docs/img/events/6.jpg
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
_docs/img/events/60.jpg
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
_docs/img/events/7.jpg
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
_docs/img/events/7.png
Normal file
|
After Width: | Height: | Size: 187 KiB |
BIN
_docs/img/events/8.jpg
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
_docs/img/events/9.jpg
Normal file
|
After Width: | Height: | Size: 19 KiB |
@ -1,6 +1,6 @@
|
||||
# HTML5 魔塔样板说明文档
|
||||
|
||||
?> 目前版本**v2.6**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.6.6**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
众所周知,魔塔的趋势是向移动端发展,贴吧中也常常能见到“求手机魔塔”的帖子。然而现有的工具中,NekoRPG有着比较大的局限性,游戏感较差,更是完全没法在iOS上运行。而一些APP的魔塔虽然可用,但是必须要下载安装,对于Android和iOS还必须开发不同的版本,非常麻烦。
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# 个性化
|
||||
|
||||
?> 目前版本**v2.6**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.6.6**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
有时候只靠样板本身可能是不够的。我们需要一些个性化、自定义的素材,道具效果,怪物属性,等等。
|
||||
|
||||
@ -22,6 +22,7 @@ HTML5魔塔是使用画布(canvas)来绘制,存在若干个图层,它们
|
||||
- paint**[D]**:绘图层;主要用来进行绘图模式。(z-index: 95)
|
||||
- curtain:色调层;用来控制当前楼层的画面色调 (z-index: 125)
|
||||
- image1\~50**[D]**:图片层;用来绘制图片等操作。(z-index: 100+code, 101~150)
|
||||
- uievent**[D]**:自定义UI绘制层;用来进行自定义UI绘制等操作。(z-index:135,可以通过事件设置该值)
|
||||
- ui:UI层;用来绘制一切UI窗口,如剧情文本、怪物手册、楼传器、系统菜单等等 (z-index: 140)
|
||||
- data:数据层;用来绘制一些顶层的或更新比较快的数据,如左上角的提示,战斗界面中数据的变化等等。 (z-index: 170)
|
||||
|
||||
@ -29,6 +30,8 @@ HTML5魔塔是使用画布(canvas)来绘制,存在若干个图层,它们
|
||||
|
||||
而,色调层的z-index是25,ui层的z-index是140;因此,图片编号在1~24的将被色调层遮挡,25~40的将被ui层遮挡,41~50的将遮挡UI层。
|
||||
|
||||
uievent层为自定义UI绘制所在的层,其z值初始是135,可以通过事件设置;自定义绘制的闪烁光标所在层的z值永远比该值大1。
|
||||
|
||||
### 动态创建canvas
|
||||
|
||||
从V2.5.3开始,可以在H5样板中任意动态创建canvas并进行使用。
|
||||
@ -559,8 +562,6 @@ core.statusBar.speed.innerHTML = core.getFlag('speed', 0);
|
||||
|
||||
如果flag:skill不为0,则代表当前处于某个技能开启状态,且状态栏显示flag:skillName值。伤害计算函数中只需要对flag:skill进行处理即可。
|
||||
|
||||
!> 关于魔力上限:样板中默认没有提供status:manamax
|
||||
|
||||
### 状态栏的显示
|
||||
|
||||
从V2.5开始,魔力值和技能名的状态栏项目已经被添加,可以直接使用。
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# 脚本
|
||||
|
||||
?> 目前版本**v2.6**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.6.6**,上次更新时间:* {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.6**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
在这一节中,将详细介绍做一部塔的流程。现在,让我们来做一部单层塔!
|
||||
|
||||
@ -235,7 +235,7 @@ HTML5的塔都是可以进行控制台调试的。
|
||||
|
||||
## 编辑器的基本操作
|
||||
|
||||
- **Alt+0~9, Ctrl+0~9** 保存和读取当前选中图块
|
||||
- **Alt+0~9, 0~9** 保存和读取当前选中图块
|
||||
- **W/A/S/D** 移动大地图
|
||||
- **Ctrl+Z** 撤销上次绘图
|
||||
- **Ctrl+Y** 重做上次绘图
|
||||
|
||||
@ -1,142 +1,57 @@
|
||||
# editor
|
||||
|
||||
[重构](refactoring.md)
|
||||
直接使用游戏运行时(之后简称core)的代码来绘制游戏画面, 借助fs.js来实现浏览器编辑文件. 通过表格编辑数据, blockly图块编辑事件, code mirror编辑文本的可视化魔塔编辑器.
|
||||
|
||||
>! 以下均是v2.0时的说明, 未及时改动
|
||||

|
||||
|
||||
本目录下所有文件,以及`../editor.html`和`../启动服务.exe`([源码](http://github.com/ckcz123/mota-js-server/))是地图编辑器的所有组件.
|
||||
左侧数据区, 中间地图区, 右侧素材区
|
||||
|
||||
`editor.js`,`editor_file.js`和`editor_mode.js`耦合较强,`editor_blockly.js`和`editor_multi.js`和`fs.js`基本可以独立使用.
|
||||

|
||||
|
||||
## 各组件功能
|
||||
事件编辑器
|
||||
|
||||
### 总体上
|
||||

|
||||
|
||||
以`display:none`的形式引入了`index.html`的`dom`,修改了原来的`.gameCanvas #ui #data`等的名字以避免冲突
|
||||
脚本编辑器
|
||||
|
||||
通过`main.init('editor')`加载数据
|
||||
> 此文件是editor的结构说明, 不是使用文档
|
||||
|
||||
`editor`模式关闭了部分动画
|
||||
## 组成
|
||||
|
||||
`core.drawMap`中`editor`模式下不再画图,而是生成画图的函数提供给`editor`
|
||||
本目录下所有文件,以及`../editor.html`,`../editor-mobile.html`和`../启动服务.exe`,`../server.py`是地图编辑器的所有组件.
|
||||
|
||||
`editor`模式下`GlobalAnimate`可以独立的选择是否播放
|
||||
### 父目录
|
||||
+ editor(-mobile).html
|
||||
编辑器的[入口页面](http://127.0.0.1:1055/editor.html)
|
||||
以`display:none`的形式引入了core的`index.html`的`dom`,修改了原来的`.gameCanvas #ui #data`等的名字以避免冲突
|
||||
+ 启动服务.exe [源码](http://github.com/ckcz123/mota-js-server/)
|
||||
为fs.js提供后端支持, 同时集成了一些实用工具
|
||||
+ server.py
|
||||
非windows平台中为fs.js提供后端支持
|
||||
|
||||
`core.playBgm`和`core.playSound`中非`play`模式不再播放声音
|
||||
### core
|
||||
|
||||
`core.show`和`core.hide`中非`play`模式不再进行动画而是立刻完成并执行回调
|
||||
游戏运行时中部分代码根据`main.mod=='editor'`进行了调整
|
||||
|
||||
`editor`模式不执行`core.resize`
|
||||
+ 通过`main.init('editor')`加载数据
|
||||
|
||||
### editor.js
|
||||
+ `editor`模式关闭了部分动画
|
||||
|
||||
``` js
|
||||
editor.mapInit();//清空地图
|
||||
editor.changeFloor('MT2')//切换地图
|
||||
editor.util.guid()//产生一个可以作为id的长随机字符串
|
||||
```
|
||||
+ `core.drawMap`中`editor`模式下不再画图,而是生成画图的函数提+ 供给`editor`
|
||||
|
||||
`editor.updateMap`中画未定义快的报错
|
||||
+ `editor`模式下`GlobalAnimate`可以独立的选择是否播放
|
||||
|
||||
### editor_file.js
|
||||
+ `core.playBgm`和`core.playSound`中非`play`模式不再播放声音
|
||||
|
||||
提供了以下函数进行楼层`map`数组相关的操作
|
||||
```javascript
|
||||
editor.file.getFloorFileList
|
||||
editor.file.loadFloorFile
|
||||
editor.file.saveFloorFile
|
||||
editor.file.saveFloorFileAs
|
||||
```
|
||||
+ `core.show`和`core.hide`中非`play`模式不再进行动画而是立刻+ 完成并执行回调
|
||||
|
||||
编辑模式有关的查询
|
||||
```javascript
|
||||
editor.file.editItem('redJewel',[],function(a){console.log(a)});
|
||||
editor.file.editEnemy('redBat',[],function(a){console.log(a)});
|
||||
editor.file.editLoc(2,0,[],function(a){console.log(a)});
|
||||
editor.file.editFloor([],function(a){console.log(a)});
|
||||
editor.file.editTower([],function(a){console.log(a)});
|
||||
editor.file.editFunctions([],function(a){console.log(a)});
|
||||
```
|
||||
+ `editor`模式不执行`core.resize`
|
||||
|
||||
编辑模式有关的编辑
|
||||
```javascript
|
||||
editor.info={images: "terrains", y: 9};
|
||||
editor.file.changeIdAndIdnum('yellowWall2',16,editor.info,function(a){console.log(a)});
|
||||
editor.file.editItem('book',[["change","['items']['name']","怪物手册的新名字"]],function(a){console.log(a)});
|
||||
editor.file.editEnemy('redBat',[['change',"['atk']",20]],function(a){console.log(a)});
|
||||
editor.file.editLoc(2,6,[["change","['afterBattle']",null]],function(a){console.log(a)});
|
||||
editor.file.editFloor([["change","['title']",'样板 33 层']],function(a){console.log(a)});
|
||||
editor.file.editTower([["change","['values']['lavaDamage']",200]],function(a){console.log(a)});
|
||||
editor.file.editFunctions(["change","['events']['afterChangeLight']","function(x,y){console.log(x,y)}"],function(a){console.log(a)});
|
||||
```
|
||||
|
||||
### editor_mode.js
|
||||
生成表格并绑定事件的函数
|
||||
```javascript
|
||||
editor.mode.loc();
|
||||
editor.mode.enemyitem();
|
||||
editor.mode.floor();
|
||||
editor.mode.tower();
|
||||
editor.mode.functions();
|
||||
```
|
||||
|
||||
切换模式
|
||||
```javascript
|
||||
editor.mode.onmode('');//清空
|
||||
editor.mode.onmode('save');//保存
|
||||
editor.mode.onmode('nextChange');//下次onmode时前端进行切换
|
||||
|
||||
editor.mode.onmode('loc');
|
||||
editor.mode.onmode('enemyitem');
|
||||
editor.mode.onmode('floor');
|
||||
editor.mode.onmode('tower');
|
||||
editor.mode.onmode('functions');
|
||||
editor.mode.onmode('map');
|
||||
editor.mode.onmode('appendpic');
|
||||
```
|
||||
在`onmode('save')`时,改动才会保存到文件,涉及到图片的改动需要刷新页面使得`editor`能看到
|
||||
|
||||
表格的`onchange`的实现中,获得当前模式的方式.不注意的话,修改`index.html`中页面的结构,会被坑
|
||||
```javascript
|
||||
var node = thisTr.parentNode;
|
||||
while (!editor_mode._ids.hasOwnProperty(node.getAttribute('id'))) {
|
||||
node = node.parentNode;
|
||||
}
|
||||
editor_mode.onmode(editor_mode._ids[node.getAttribute('id')]);
|
||||
```
|
||||
|
||||
`editor.mode.listen`中提供了追加素材的支持.
|
||||
|
||||
|
||||
### editor_blockly.js
|
||||
|
||||
把选定`id_`的事件用blockly编辑
|
||||
``` js
|
||||
editor_blockly.import(id_,{type:'event'});
|
||||
```
|
||||
|
||||
把文本区域的代码转换成图块
|
||||
``` js
|
||||
editor_blockly.parse();
|
||||
```
|
||||
|
||||
### editor_multi.js
|
||||
|
||||
用[CodeMirror](https://github.com/codemirror/CodeMirror) 实现有高亮的多行文本编辑
|
||||
|
||||
编辑选定`id_`的文本域
|
||||
``` js
|
||||
editor_multi.import(id_,{lint:true})
|
||||
```
|
||||
|
||||
编辑blockly方块的特定域
|
||||
``` js
|
||||
editor_multi.multiLineEdit(value,b,f,{lint:true},callback)
|
||||
```
|
||||
|
||||
### fs.js
|
||||
|
||||
模仿node的fs模块提供如下api,与`启动服务.exe`配合为js提供文件读写功能
|
||||
依照[issue#31](https://github.com/ckcz123/mota-js/issues/13)的约定, 模仿node的fs模块提供如下api,与`启动服务.exe`,`server.py`配合为js提供文件读写功能, 是编辑器成立的前提
|
||||
|
||||
``` js
|
||||
fs.readFile('file.in','utf-8',callback)
|
||||
//读文本文件
|
||||
@ -164,3 +79,195 @@ fs.readdir(path, callback)
|
||||
//所有参数不允许缺省
|
||||
```
|
||||
|
||||
### editor_multi.js
|
||||
|
||||
用[CodeMirror](https://github.com/codemirror/CodeMirror) 实现有高亮的多行文本编辑
|
||||
|
||||
编辑选定`id_`的文本域
|
||||
``` js
|
||||
editor_multi.import(id_,{lint:true})
|
||||
```
|
||||
|
||||
编辑blockly方块的特定域
|
||||
``` js
|
||||
editor_multi.multiLineEdit(value,b,f,{lint:true},callback)
|
||||
```
|
||||
|
||||
配置表格
|
||||
``` js
|
||||
editor_multi.editCommentJs(mod)
|
||||
```
|
||||
|
||||
### MotaAction.g4
|
||||
|
||||
通过[antlr-blockly](https://github.com/zhaouv/antlr-blockly)的语法定义core中各事件对应的方块.
|
||||
|
||||
借助google的[blockly](https://github.com/google/blockly)来实现事件的可视化编辑.
|
||||
|
||||
入口方块以`_m`结尾
|
||||
|
||||
一般语句写在`action`中, 以`_s`结尾
|
||||
|
||||
### editor_blockly.js
|
||||
|
||||
把选定`id_`的事件用blockly编辑
|
||||
``` js
|
||||
editor_blockly.import(id_,{type:'event'});
|
||||
```
|
||||
|
||||
把文本区域的代码转换成图块
|
||||
``` js
|
||||
editor_blockly.parse();
|
||||
```
|
||||
|
||||
`initscript中`的`toolboxObj`定义了侧边栏中显示的图块
|
||||
|
||||
自定义`Blockly.FieldColour.prototype.createWidget_`修改了颜色选择器的行为
|
||||
|
||||
自定义`Blockly.FieldTextInput.prototype.showInlineEditor_`添加了自动补全
|
||||
|
||||
|
||||
### editor_mode.js
|
||||
|
||||
用于切换数据区
|
||||
|
||||
加载数据
|
||||
```javascript
|
||||
editor.mode.loc();
|
||||
editor.mode.enemyitem();
|
||||
editor.mode.floor();
|
||||
editor.mode.tower();
|
||||
editor.mode.functions();
|
||||
```
|
||||
|
||||
切换模式
|
||||
```javascript
|
||||
editor.mode.onmode('');//清空
|
||||
editor.mode.onmode('save');//保存
|
||||
editor.mode.onmode('nextChange');//下次onmode时前端进行切换
|
||||
|
||||
editor.mode.onmode('loc');
|
||||
editor.mode.onmode('enemyitem');
|
||||
editor.mode.onmode('floor');
|
||||
editor.mode.onmode('tower');
|
||||
editor.mode.onmode('functions');
|
||||
editor.mode.onmode('map');
|
||||
editor.mode.onmode('appendpic');
|
||||
```
|
||||
在`onmode('save')`时,改动才会保存到文件,涉及到图片的改动需要刷新页面使得`editor`能看到
|
||||
|
||||
数据区一些通用的函数也定义在这里
|
||||
|
||||
### editor_table.js
|
||||
|
||||
处理表格的生成, 及其响应的事件
|
||||
|
||||
其接受来自../project/\*.js的数据`obj`和来自table/\*.comment.js的注释`commentObj`
|
||||
|
||||
commentObj的结构如示例
|
||||
``` js
|
||||
{
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"events": {
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"resetGame": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "重置整个游戏"
|
||||
},
|
||||
"setInitData": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "设置初始属性"
|
||||
},
|
||||
```
|
||||
一层正常数据, 一层`_`开头的结构说明, 忽略`_`层的话与obj同结构
|
||||
|
||||
通过
|
||||
``` js
|
||||
editor.table.objToTable(obj, commentObj)
|
||||
editor.table.objToTr
|
||||
editor.table.objToTd
|
||||
```
|
||||
遍历这两个对象来生成表格, 叶节点根据`_type`渲染成对应的dom
|
||||
|
||||
表格的值变化`onchange`, 双击`dblclickfunc`, 删除`deletefunc`, 添加`addfunc`也定义在此文件
|
||||
|
||||
### editor_mappanel.js
|
||||
|
||||
与地图区相关的功能
|
||||
+ 画地图 线/矩形/tileset
|
||||
+ 通过地图选中事件或素材
|
||||
+ 右键菜单
|
||||
+ 切换楼层
|
||||
+ 大地图移动可视窗口
|
||||
|
||||
### editor_materialpanel.js
|
||||
|
||||
与素材区相关的功能
|
||||
+ 选中
|
||||
+ 展开/折叠
|
||||
|
||||
### editor_datapanel.js
|
||||
|
||||
与数据区相关的功能 (且与表格无关的功能)
|
||||
+ 地图编辑
|
||||
- 创建新地图
|
||||
- 批量创建
|
||||
+ 地图选点
|
||||
+ 图块属性
|
||||
- 注册素材
|
||||
- 修改id
|
||||
+ 楼层属性
|
||||
- 修改楼层id
|
||||
+ 全塔属性
|
||||
+ 脚本编辑
|
||||
+ 追加素材
|
||||
- 选择导入的区域
|
||||
- 导入图片
|
||||
- 改色相
|
||||
- 选中图片中的格子
|
||||
- 确认追加
|
||||
+ 公共事件
|
||||
+ 插件编写
|
||||
|
||||
### editor_ui.js
|
||||
|
||||
ui事件中没有具体到前三个区中的函数
|
||||
+ 响应点击
|
||||
+ 快捷键
|
||||
+ 显示帮助
|
||||
+ UI预览 & 地图选点相关
|
||||
|
||||
### editor_util.js
|
||||
|
||||
一些通用的函数
|
||||
+ 生成id
|
||||
+ HTML转义
|
||||
+ 像素处理
|
||||
+ base64的encode/decode
|
||||
+ 检查值是否为空
|
||||
|
||||
### editor_listen.js
|
||||
|
||||
界面与功能的绑定
|
||||
|
||||
### editor_file.js
|
||||
|
||||
包装fs.js, 把数据读写到对应的文件
|
||||
|
||||
### editor_game.js
|
||||
|
||||
游戏数据的处理
|
||||
|
||||
此部分的重构未完成, 实际上是由editor_file.js和editor_file_unsorted.js来做的
|
||||
|
||||
### editor.js
|
||||
|
||||
初始化加整合各模块
|
||||
|
||||
现状是还放了一些游戏数据有关的函数未挪到editor_game, 以及部分和入口页面生成有关的函数
|
||||
@ -1,21 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Peter Dematté
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
1
_server/config.json
Normal file
@ -0,0 +1 @@
|
||||
{"lastUsed":[],"foldPerCol":50,"folded":false,"editorLastFloorId":null,"disableBlocklyReplace":false,"shortcut":{"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0}}
|
||||
@ -40,7 +40,7 @@ body {
|
||||
width: 104px;
|
||||
}
|
||||
|
||||
#left, #mid, #right {
|
||||
#left, #mid, #mid2, #right {
|
||||
border-radius: 2px;
|
||||
box-sizing: border-box;
|
||||
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14), 0 3px 1px -2px rgba(0, 0, 0, .2), 0 1px 5px 0 rgba(0, 0, 0, .12);
|
||||
@ -130,6 +130,14 @@ body {
|
||||
height: 630px;
|
||||
}
|
||||
|
||||
#mid2 {
|
||||
position: absolute;
|
||||
left: 448px;
|
||||
top: 650px;
|
||||
width: 440px;
|
||||
bottom: 10px;
|
||||
}
|
||||
|
||||
#mapEdit {
|
||||
overflow: hidden;
|
||||
}
|
||||
@ -142,6 +150,13 @@ body {
|
||||
height: 416px;
|
||||
}
|
||||
|
||||
#lastUsedDiv {
|
||||
height: auto;
|
||||
bottom: 0;
|
||||
margin-top: 20px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#mid .tools {
|
||||
position: absolute;
|
||||
width: 425px;
|
||||
@ -239,15 +254,15 @@ body {
|
||||
position: absolute;
|
||||
left: 900px;
|
||||
top: 10px;
|
||||
width: 440px;
|
||||
height: 630px;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
/* border: 1px solid rgb(238, 13, 13); */
|
||||
}
|
||||
|
||||
#iconLib {
|
||||
position: absolute;
|
||||
width: 435px;
|
||||
height: 620px;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 5px;
|
||||
top: 5px;
|
||||
overflow: auto;
|
||||
@ -262,10 +277,6 @@ body {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.egameCanvas {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.gameCanvas {
|
||||
position: absolute;
|
||||
}
|
||||
@ -287,6 +298,15 @@ body {
|
||||
0 0 0 3px #000;
|
||||
}
|
||||
|
||||
#iconExpandBtn {
|
||||
position: absolute;
|
||||
left: 20px;
|
||||
bottom: 30px;
|
||||
font-size: 15px;
|
||||
padding: 6px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.warnText {
|
||||
color: #D50000;
|
||||
font-weight: 700;
|
||||
@ -458,4 +478,88 @@ table.row td {
|
||||
left: 6px;
|
||||
top: 6px;
|
||||
background-image:url('data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIGJhc2VQcm9maWxlPSJmdWxsIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWxuczpldj0iaHR0cDovL3d3dy53My5vcmcvMjAwMS94bWwtZXZlbnRzIj4KPGc%2BCgk8cG9seWdvbiBmaWxsPSIjNjY2IiBwb2ludHM9IjkuMjA3LDYuMTI2IDcuNzkzLDcuNTQxIDExLjc5MywxMS41NDEgMTMuMjA3LDEwLjEyNiIgLz4KCTxwYXRoIGZpbGw9IiM2NjYiIGQ9Ik01LjkxNywyYzEuNjA4LDAsMi45MTcsMS4zMDgsMi45MTcsMi45MTdTNy41MjUsNy44MzMsNS45MTcsNy44MzNTMyw2LjUyNSwzLDQuOTE3UzQuMzA4LDIsNS45MTcsMgoJCSBNNS45MTcsMEMzLjIwMSwwLDEsMi4yMDEsMSw0LjkxN3MyLjIwMSw0LjkxNyw0LjkxNyw0LjkxN3M0LjkxNy0yLjIwMSw0LjkxNy00LjkxN0MxMC44MzMsMi4yMDEsOC42MzIsMCw1LjkxNywwTDUuOTE3LDB6IiAvPgo8L2c%2BCjwvc3ZnPgo%3D');
|
||||
}
|
||||
|
||||
#uieventDiv {
|
||||
display: none;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background: rgba(127,127,127,0.6);
|
||||
z-index: 2000
|
||||
}
|
||||
|
||||
#uieventDialog {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -60%);
|
||||
background: white;
|
||||
width: 436px;
|
||||
}
|
||||
|
||||
#uieventHead {
|
||||
margin: 10px 20px;
|
||||
}
|
||||
|
||||
#uieventTitle {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#uieventNo {
|
||||
float: right;
|
||||
}
|
||||
|
||||
#uieventYes {
|
||||
display: none;
|
||||
float: right;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
#uieventBody {
|
||||
width: 416px;
|
||||
height: 416px;
|
||||
position: relative;
|
||||
margin-left: 10px;
|
||||
margin-bottom: 5px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#uievent {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
#selectPoint {
|
||||
display: none;
|
||||
margin-left: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#selectPointFloor {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
#selectPointButtons {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
#selectPointBox {
|
||||
position: absolute;
|
||||
z-index: 75;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
margin: 3px 0 0 3px;
|
||||
padding: 0;
|
||||
/* display: none; */
|
||||
box-sizing: border-box;
|
||||
background-color: rgba(255, 255, 255, 0.0);
|
||||
border: 1px solid #000;
|
||||
box-shadow: 0 0 0 2px #fff,
|
||||
0 0 0 3px #000;
|
||||
}
|
||||
@ -110,6 +110,10 @@ body {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
#mid2 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#mapEdit {
|
||||
overflow: hidden;
|
||||
}
|
||||
@ -247,10 +251,6 @@ body {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.egameCanvas {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.gameCanvas {
|
||||
position: absolute;
|
||||
}
|
||||
@ -272,6 +272,15 @@ body {
|
||||
0 0 0 3px #000;
|
||||
}
|
||||
|
||||
#iconExpandBtn {
|
||||
position: absolute;
|
||||
left: 20px;
|
||||
bottom: 30px;
|
||||
font-size: 15px;
|
||||
padding: 6px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.warnText {
|
||||
color: #D50000;
|
||||
font-weight: 700;
|
||||
@ -433,7 +442,7 @@ div.row .rowtd .rowtext{
|
||||
font: normal 2.5vw Arial, sans-serif;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 4px 7em 4px 28px;
|
||||
padding: 4px 7em 4px 4px;
|
||||
white-space: nowrap;
|
||||
|
||||
/* padding-left: 12px; */
|
||||
@ -482,4 +491,88 @@ div.row .rowtd .rowtext{
|
||||
margin: 2px 0;
|
||||
border-radius: 3px;
|
||||
width: 90px;
|
||||
}
|
||||
|
||||
#uieventDiv {
|
||||
display: none;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background: rgba(127,127,127,0.6);
|
||||
z-index: 2000
|
||||
}
|
||||
|
||||
#uieventDialog {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
transform: translateY(-50%);
|
||||
background: white;
|
||||
width: 100vw;
|
||||
}
|
||||
|
||||
#uieventHead {
|
||||
margin: 10px 20px;
|
||||
}
|
||||
|
||||
#uieventTitle {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#uieventNo {
|
||||
float: right;
|
||||
}
|
||||
|
||||
#uieventYes {
|
||||
display: none;
|
||||
float: right;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
#uieventBody {
|
||||
width: 100vw;
|
||||
height: 100vw;
|
||||
position: relative;
|
||||
margin-left: 0;
|
||||
margin-bottom: 5px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#uievent {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
#selectPoint {
|
||||
display: none;
|
||||
margin-left: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#selectPointFloor {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
#selectPointButtons {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
#selectPointBox {
|
||||
position: absolute;
|
||||
z-index: 75;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
margin: 3px 0 0 3px;
|
||||
padding: 0;
|
||||
/* display: none; */
|
||||
box-sizing: border-box;
|
||||
background-color: rgba(255, 255, 255, 0.0);
|
||||
border: 1px solid #000;
|
||||
box-shadow: 0 0 0 2px #fff,
|
||||
0 0 0 3px #000;
|
||||
}
|
||||
@ -7,7 +7,7 @@
|
||||
.leftTab {
|
||||
overflow: auto;
|
||||
position: absolute;
|
||||
height: 630px;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.leftTab > * {
|
||||
@ -121,6 +121,7 @@
|
||||
display: block;
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.etable table th {
|
||||
@ -157,14 +158,19 @@
|
||||
}
|
||||
|
||||
.etable tr > :nth-child(3) {
|
||||
width: 60%
|
||||
width: 35%;
|
||||
}
|
||||
|
||||
.etable tr > :nth-child(4) {
|
||||
width: 25%;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.etable table {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.etable tr:not(:first-child) > :last-child:hover {
|
||||
.etable tr:not(:first-child) > :nth-child(3):hover {
|
||||
border: 1px solid rgb(87, 198, 232);
|
||||
box-shadow: 0px 0px 3px rgb(87, 198, 232);
|
||||
}
|
||||
@ -175,14 +181,17 @@
|
||||
box-shadow: 0px 0px 3px rgb(87, 232, 198);
|
||||
}
|
||||
|
||||
.etable tr:not(:first-child) > :last-child {
|
||||
.etable tr:not(:first-child) > :nth-child(3) {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.etable tr > :nth-child(4) {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
div.etableInputDiv {
|
||||
position: absolute;
|
||||
padding: 5px 0 0 5px;
|
||||
|
||||
@ -135,6 +135,7 @@
|
||||
display: block;
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.etable table th {
|
||||
@ -171,14 +172,19 @@
|
||||
}
|
||||
|
||||
.etable tr > :nth-child(3) {
|
||||
width: 60%
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
.etable tr > :nth-child(4) {
|
||||
width: 30%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.etable table {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.etable tr:not(:first-child) > :last-child:hover {
|
||||
.etable tr:not(:first-child) > :nth-child(3):hover {
|
||||
border: 1px solid rgb(87, 198, 232);
|
||||
box-shadow: 0px 0px 3px rgb(87, 198, 232);
|
||||
}
|
||||
@ -189,11 +195,10 @@
|
||||
box-shadow: 0px 0px 3px rgb(87, 232, 198);
|
||||
}
|
||||
|
||||
.etable tr:not(:first-child) > :last-child {
|
||||
.etable tr:not(:first-child) > :nth-child(3) {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
|
||||
@ -4,6 +4,107 @@ function editor() {
|
||||
this.layerMod = "map";//["fgmap","map","bgmap"]
|
||||
this.isMobile = false;
|
||||
|
||||
this.dom={
|
||||
body:document.body,
|
||||
eui:document.getElementById('eui'),
|
||||
euiCtx:document.getElementById('eui').getContext('2d'),
|
||||
efgCtx:document.getElementById('efg').getContext('2d'),
|
||||
mid:document.getElementById('mid'),
|
||||
mapEdit:document.getElementById('mapEdit'),
|
||||
selectFloor:document.getElementById('selectFloor'),
|
||||
iconExpandBtn :document.getElementById('iconExpandBtn'),
|
||||
dataSelection : document.getElementById('dataSelection'),
|
||||
iconLib:document.getElementById('iconLib'),
|
||||
midMenu:document.getElementById('midMenu'),
|
||||
extraEvent: document.getElementById('extraEvent'),
|
||||
chooseThis : document.getElementById('chooseThis'),
|
||||
chooseInRight : document.getElementById('chooseInRight'),
|
||||
copyLoc : document.getElementById('copyLoc'),
|
||||
moveLoc : document.getElementById('moveLoc'),
|
||||
clearEvent : document.getElementById('clearEvent'),
|
||||
clearLoc : document.getElementById('clearLoc'),
|
||||
brushMod:document.getElementById('brushMod'),
|
||||
brushMod2:document.getElementById('brushMod2'),
|
||||
brushMod3:document.getElementById('brushMod3'),
|
||||
bgc : document.getElementById('bg'),
|
||||
bgCtx : document.getElementById('bg').getContext('2d'),
|
||||
fgc : document.getElementById('fg'),
|
||||
fgCtx : document.getElementById('fg').getContext('2d'),
|
||||
evc : document.getElementById('event'),
|
||||
evCtx : document.getElementById('event').getContext('2d'),
|
||||
ev2c : document.getElementById('event2'),
|
||||
ev2Ctx : document.getElementById('event2').getContext('2d'),
|
||||
layerMod:document.getElementById('layerMod'),
|
||||
layerMod2:document.getElementById('layerMod2'),
|
||||
layerMod3:document.getElementById('layerMod3'),
|
||||
viewportButtons:document.getElementById('viewportButtons'),
|
||||
appendPicCanvas : document.getElementById('appendPicCanvas'),
|
||||
bg : document.getElementById('appendPicCanvas').children[0],
|
||||
source : document.getElementById('appendPicCanvas').children[1],
|
||||
picClick : document.getElementById('appendPicCanvas').children[2],
|
||||
sprite : document.getElementById('appendPicCanvas').children[3],
|
||||
sourceCtx:document.getElementById('appendPicCanvas').children[1].getContext('2d'),
|
||||
spriteCtx:document.getElementById('appendPicCanvas').children[3].getContext('2d'),
|
||||
appendPicSelection : document.getElementById('appendPicSelection'),
|
||||
selectAppend : document.getElementById('selectAppend'),
|
||||
selectFileBtn :document.getElementById('selectFileBtn'),
|
||||
changeFloorId :document.getElementById('changeFloorId'),
|
||||
left1 : document.getElementById('left1'),
|
||||
editModeSelect :document.getElementById('editModeSelect'),
|
||||
mid2 : document.getElementById('mid2'),
|
||||
lastUsedDiv: document.getElementById('lastUsedDiv'),
|
||||
lastUsed: document.getElementById('lastUsed'),
|
||||
lastUsedCtx: document.getElementById('lastUsed').getContext('2d'),
|
||||
lockMode: document.getElementById('lockMode'),
|
||||
};
|
||||
|
||||
this.uivalues={
|
||||
// 绘制区拖动有关
|
||||
holdingPath : 0,
|
||||
stepPostfix : null,//用于存放寻路检测的第一个点之后的后续移动
|
||||
mouseOutCheck : 2,
|
||||
startPos:null,
|
||||
endPos:null,
|
||||
// 撤销/恢复
|
||||
preMapData : [],
|
||||
preMapMax: 10,
|
||||
postMapData: [],
|
||||
//
|
||||
shortcut:{},
|
||||
copyedInfo : null,
|
||||
// 折叠素材
|
||||
scrollBarHeight :0,
|
||||
folded:false,
|
||||
foldPerCol: 50,
|
||||
// 画图区菜单
|
||||
lastRightButtonPos:[{x:0,y:0},{x:0,y:0}],
|
||||
lastCopyedInfo : [null, null],
|
||||
//
|
||||
ratio : 1,
|
||||
// blockly转义
|
||||
disableBlocklyReplace: false,
|
||||
|
||||
// 绑定机关门事件相关
|
||||
bindSpecialDoor: {
|
||||
loc: null,
|
||||
n: -1,
|
||||
enemys: []
|
||||
},
|
||||
|
||||
// 复制怪物或道具属性
|
||||
copyEnemyItem : {
|
||||
type: null,
|
||||
data: {}
|
||||
},
|
||||
|
||||
// tile
|
||||
tileSize: [1,1],
|
||||
lockMode: false,
|
||||
|
||||
// 最近使用的图块
|
||||
lastUsed: [],
|
||||
};
|
||||
|
||||
window.onerror = function (msg, url, lineNo, columnNo, error) {
|
||||
var string = msg.toLowerCase();
|
||||
var substring = "script error";
|
||||
@ -30,6 +131,8 @@ function editor() {
|
||||
};
|
||||
}
|
||||
|
||||
editor.prototype.uifunctions={};
|
||||
|
||||
/*
|
||||
editor.loc
|
||||
editor.pos
|
||||
@ -48,11 +151,20 @@ editor.prototype.init = function (callback) {
|
||||
editor.airwallImg.src = './project/images/airwall.png';
|
||||
|
||||
main.init('editor', function () {
|
||||
editor_util_wrapper(editor);
|
||||
editor_game_wrapper(editor, main, core);
|
||||
editor_table_wrapper(editor);
|
||||
editor_unsorted_1_wrapper(editor);
|
||||
afterMainInit();
|
||||
editor.config = new editor_config();
|
||||
editor.config.load(function() {
|
||||
editor_util_wrapper(editor);
|
||||
editor_game_wrapper(editor, main, core);
|
||||
editor_file_wrapper(editor);
|
||||
editor_table_wrapper(editor);
|
||||
editor_ui_wrapper(editor);
|
||||
editor_mappanel_wrapper(editor);
|
||||
editor_datapanel_wrapper(editor);
|
||||
editor_materialpanel_wrapper(editor);
|
||||
editor_listen_wrapper(editor);
|
||||
editor.printe=printe;
|
||||
afterMainInit();
|
||||
})
|
||||
});
|
||||
|
||||
var afterMainInit = function () {
|
||||
@ -63,10 +175,11 @@ editor.prototype.init = function (callback) {
|
||||
editor_file = editor_file(editor, function () {
|
||||
editor.file = editor_file;
|
||||
editor_mode = editor_mode(editor);
|
||||
editor_unsorted_2_wrapper(editor_mode);
|
||||
editor.mode = editor_mode;
|
||||
core.resetGame(core.firstData.hero, null, core.firstData.floorId, core.initStatus.maps);
|
||||
core.changeFloor(core.status.floorId, null, core.firstData.hero.loc, null, function () {
|
||||
core.resetGame(core.firstData.hero, null, core.firstData.floorId, core.clone(core.initStatus.maps));
|
||||
var lastFloorId = editor.config.get('editorLastFloorId', core.status.floorId);
|
||||
if (core.floorIds.indexOf(lastFloorId) < 0) lastFloorId = core.status.floorId;
|
||||
core.changeFloor(lastFloorId, null, core.firstData.hero.loc, null, function () {
|
||||
afterCoreReset();
|
||||
}, true);
|
||||
core.events.setInitData(null);
|
||||
@ -96,6 +209,17 @@ editor.prototype.init = function (callback) {
|
||||
editor_multi = editor_multi();
|
||||
editor_blockly = editor_blockly();
|
||||
|
||||
// --- 所有用到的flags
|
||||
editor.used_flags = {};
|
||||
for (var floorId in editor.main.floors) {
|
||||
editor.addUsedFlags(JSON.stringify(editor.main.floors[floorId]));
|
||||
}
|
||||
if (events_c12a15a8_c380_4b28_8144_256cba95f760.commonEvent) {
|
||||
for (var name in events_c12a15a8_c380_4b28_8144_256cba95f760.commonEvent) {
|
||||
editor.addUsedFlags(JSON.stringify(events_c12a15a8_c380_4b28_8144_256cba95f760.commonEvent[name]));
|
||||
}
|
||||
}
|
||||
|
||||
if (editor.useCompress == null) editor.useCompress = useCompress;
|
||||
if (Boolean(callback)) callback();
|
||||
|
||||
@ -105,9 +229,9 @@ editor.prototype.init = function (callback) {
|
||||
}
|
||||
|
||||
editor.prototype.mapInit = function () {
|
||||
var ec = document.getElementById('event').getContext('2d');
|
||||
var ec = editor.dom.evCtx;
|
||||
ec.clearRect(0, 0, core.bigmap.width*32, core.bigmap.height*32);
|
||||
document.getElementById('event2').getContext('2d').clearRect(0, 0, core.bigmap.width*32, core.bigmap.height*32);
|
||||
editor.dom.ev2Ctx.clearRect(0, 0, core.bigmap.width*32, core.bigmap.height*32);
|
||||
editor.map = [];
|
||||
var sy=editor.currentFloorData.map.length,sx=editor.currentFloorData.map[0].length;
|
||||
for (var y = 0; y < sy; y++) {
|
||||
@ -140,53 +264,80 @@ editor.prototype.changeFloor = function (floorId, callback) {
|
||||
});
|
||||
editor.currentFloorData[name]=mapArray;
|
||||
}
|
||||
editor.preMapData = null;
|
||||
editor.uivalues.preMapData = [];
|
||||
editor.uivalues.postMapData = [];
|
||||
editor.uifunctions._extraEvent_bindSpecialDoor_doAction(true);
|
||||
core.changeFloor(floorId, null, {"x": 0, "y": 0, "direction": "up"}, null, function () {
|
||||
core.bigmap.offsetX=0;
|
||||
core.bigmap.offsetY=0;
|
||||
editor.moveViewport(0,0);
|
||||
|
||||
editor.game.fetchMapFromCore();
|
||||
editor.updateMap();
|
||||
editor_mode.floor();
|
||||
editor.drawEventBlock();
|
||||
if (callback) callback();
|
||||
|
||||
editor.viewportLoc = editor.viewportLoc || {};
|
||||
var loc = editor.viewportLoc[floorId] || [], x = loc[0] || 0, y = loc[1] || 0;
|
||||
editor.setViewport(x, y);
|
||||
|
||||
editor.config.set('editorLastFloorId', floorId, function() {
|
||||
if (callback) callback();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/////////// 游戏绘图相关 ///////////
|
||||
|
||||
editor.prototype.drawEventBlock = function () {
|
||||
var fg=document.getElementById('efg').getContext('2d');
|
||||
var fg=editor.dom.efgCtx;
|
||||
|
||||
fg.clearRect(0, 0, core.__PIXELS__, core.__PIXELS__);
|
||||
var firstData = editor.game.getFirstData();
|
||||
for (var i=0;i<core.__SIZE__;i++) {
|
||||
for (var j=0;j<core.__SIZE__;j++) {
|
||||
var color=[];
|
||||
var loc=(i+core.bigmap.offsetX/32)+","+(j+core.bigmap.offsetY/32);
|
||||
if (editor.currentFloorId == firstData.floorId
|
||||
&& loc == firstData.hero.loc.x + "," + firstData.hero.loc.y) {
|
||||
fg.textAlign = 'center';
|
||||
editor.game.doCoreFunc('fillBoldText', fg, 'S',
|
||||
32 * i + 16, 32 * j + 28, '#FFFFFF', 'bold 30px Verdana');
|
||||
}
|
||||
if (editor.currentFloorData.events[loc])
|
||||
color.push('#FF0000');
|
||||
if (editor.currentFloorData.changeFloor[loc])
|
||||
color.push('#00FF00');
|
||||
if (editor.currentFloorData.autoEvent[loc]) {
|
||||
var x = editor.currentFloorData.autoEvent[loc];
|
||||
for (var index in x) {
|
||||
if (x[index] && x[index].data) {
|
||||
color.push('#FFA500');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (editor.currentFloorData.afterBattle[loc])
|
||||
color.push('#FFFF00');
|
||||
if (editor.currentFloorData.changeFloor[loc])
|
||||
color.push('#00FF00');
|
||||
if (editor.currentFloorData.afterGetItem[loc])
|
||||
color.push('#00FFFF');
|
||||
if (editor.currentFloorData.afterOpenDoor[loc])
|
||||
color.push('#FF00FF');
|
||||
if (editor.currentFloorData.cannotMove[loc])
|
||||
color.push('#0000FF');
|
||||
if (editor.currentFloorData.afterOpenDoor[loc])
|
||||
color.push('#FF00FF');
|
||||
for(var kk=0,cc;cc=color[kk];kk++){
|
||||
fg.fillStyle = cc;
|
||||
fg.fillRect(32*i+8*kk, 32*j+32-8, 8, 8);
|
||||
}
|
||||
var index = editor.uivalues.bindSpecialDoor.enemys.indexOf(loc);
|
||||
if (index >= 0) {
|
||||
fg.textAlign = 'right';
|
||||
editor.game.doCoreFunc("fillBoldText", fg, index + 1,
|
||||
32 * i + 28, 32 * j + 15, '#FF7F00', '14px Verdana');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
editor.prototype.drawPosSelection = function () {
|
||||
this.drawEventBlock();
|
||||
var fg=document.getElementById('efg').getContext('2d');
|
||||
var fg=editor.dom.efgCtx;
|
||||
fg.strokeStyle = 'rgba(255,255,255,0.7)';
|
||||
fg.lineWidth = 4;
|
||||
fg.strokeRect(32*editor.pos.x - core.bigmap.offsetX + 4, 32*editor.pos.y - core.bigmap.offsetY + 4, 24, 24);
|
||||
@ -238,30 +389,61 @@ editor.prototype.updateMap = function () {
|
||||
//ctx.drawImage(core.material.images[tileInfo.images], 0, tileInfo.y*32, 32, 32, x*32, y*32, 32, 32);
|
||||
}
|
||||
// 绘制地图 start
|
||||
var eventCtx = document.getElementById('event').getContext("2d");
|
||||
var fgCtx = document.getElementById('fg').getContext("2d");
|
||||
var bgCtx = document.getElementById('bg').getContext("2d");
|
||||
for (var y = 0; y < editor.map.length; y++)
|
||||
for (var y = 0; y < editor.map.length; y++) {
|
||||
for (var x = 0; x < editor.map[0].length; x++) {
|
||||
var tileInfo = editor.map[y][x];
|
||||
drawTile(eventCtx, x, y, tileInfo);
|
||||
drawTile(editor.dom.evCtx, x, y, tileInfo);
|
||||
tileInfo = editor.fgmap[y][x];
|
||||
drawTile(fgCtx, x, y, tileInfo);
|
||||
drawTile(editor.dom.fgCtx, x, y, tileInfo);
|
||||
tileInfo = editor.bgmap[y][x];
|
||||
drawTile(bgCtx, x, y, tileInfo);
|
||||
drawTile(editor.dom.bgCtx, x, y, tileInfo);
|
||||
}
|
||||
}
|
||||
// 绘制地图 end
|
||||
|
||||
|
||||
this.updateLastUsedMap();
|
||||
}
|
||||
|
||||
editor.prototype.moveViewport=function(x,y){
|
||||
core.bigmap.offsetX = core.clamp(core.bigmap.offsetX+32*x, 0, 32*core.bigmap.width-core.__PIXELS__);
|
||||
core.bigmap.offsetY = core.clamp(core.bigmap.offsetY+32*y, 0, 32*core.bigmap.height-core.__PIXELS__);
|
||||
editor.prototype.updateLastUsedMap = function () {
|
||||
// 绘制最近使用事件
|
||||
var ctx = editor.dom.lastUsedCtx;
|
||||
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
|
||||
ctx.strokeStyle = 'rgba(255,128,0,0.85)';
|
||||
ctx.lineWidth = 4;
|
||||
for (var i = 0; i < editor.uivalues.lastUsed.length; ++i) {
|
||||
try {
|
||||
var x = i % core.__SIZE__, y = parseInt(i / core.__SIZE__);
|
||||
var info = editor.uivalues.lastUsed[i];
|
||||
if (!info || !info.images) continue;
|
||||
if (info.isTile && core.material.images.tilesets[info.images]) {
|
||||
ctx.drawImage(core.material.images.tilesets[info.images], 32 * info.x, 32 * info.y, 32, 32, x*32, y*32, 32, 32);
|
||||
} else if (info.images == 'autotile' && core.material.images.autotile[info.id]) {
|
||||
ctx.drawImage(core.material.images.autotile[info.id], 0, 0, 32, 32, x * 32, y * 32, 32, 32);
|
||||
} else {
|
||||
var per_height = info.images.endsWith('48') ? 48 : 32;
|
||||
ctx.drawImage(core.material.images[info.images], 0, info.y * per_height, 32, per_height, x * 32, y * 32, 32, 32);
|
||||
}
|
||||
if (selectBox.isSelected() && editor.info.id == info.id) {
|
||||
ctx.strokeRect(32 * x + 2, 32 * y + 2, 28, 28);
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
}
|
||||
|
||||
editor.prototype.setViewport=function (x, y) {
|
||||
core.bigmap.offsetX = core.clamp(x, 0, 32*core.bigmap.width-core.__PIXELS__);
|
||||
core.bigmap.offsetY = core.clamp(y, 0, 32*core.bigmap.height-core.__PIXELS__);
|
||||
editor.viewportLoc = editor.viewportLoc || {};
|
||||
editor.viewportLoc[editor.currentFloorId] = [core.bigmap.offsetX, core.bigmap.offsetY];
|
||||
core.control.updateViewport();
|
||||
editor.buildMark();
|
||||
editor.drawPosSelection();
|
||||
}
|
||||
|
||||
editor.prototype.moveViewport=function(x,y){
|
||||
editor.setViewport(core.bigmap.offsetX+32*x, core.bigmap.offsetY+32*y);
|
||||
}
|
||||
|
||||
/////////// 界面交互相关 ///////////
|
||||
|
||||
editor.prototype.drawInitData = function (icons) {
|
||||
@ -270,7 +452,11 @@ editor.prototype.drawInitData = function (icons) {
|
||||
var maxHeight = 700;
|
||||
var sumWidth = 0;
|
||||
editor.widthsX = {};
|
||||
editor.uivalues.folded = editor.config.get('folded', false);
|
||||
// editor.uivalues.folded = true;
|
||||
editor.uivalues.foldPerCol = editor.config.get('foldPerCol', 50);
|
||||
// var imgNames = Object.keys(images); //还是固定顺序吧;
|
||||
editor.uivalues.lastUsed = editor.config.get("lastUsed", []);
|
||||
var imgNames = ["terrains", "animates", "enemys", "enemy48", "items", "npcs", "npc48", "autotile"];
|
||||
|
||||
for (var ii = 0; ii < imgNames.length; ii++) {
|
||||
@ -280,20 +466,21 @@ editor.prototype.drawInitData = function (icons) {
|
||||
for (var im in autotiles) {
|
||||
tempy += autotiles[im].height;
|
||||
}
|
||||
editor.widthsX[img] = [img, sumWidth / 32, (sumWidth + 3 * 32) / 32, tempy];
|
||||
sumWidth += 3 * 32;
|
||||
var tempx = editor.uivalues.folded ? 32 : 3 * 32;
|
||||
editor.widthsX[img] = [img, sumWidth / 32, (sumWidth + tempx) / 32, tempy];
|
||||
sumWidth += tempx;
|
||||
maxHeight = Math.max(maxHeight, tempy);
|
||||
continue;
|
||||
}
|
||||
if (img == 'terrains') {
|
||||
editor.widthsX[img] = [img, sumWidth / 32, (sumWidth + images[img].width) / 32, images[img].height + 32*2]
|
||||
sumWidth += images[img].width;
|
||||
maxHeight = Math.max(maxHeight, images[img].height + 32*2);
|
||||
continue;
|
||||
var width = images[img].width, height = images[img].height, mh = height;
|
||||
if (editor.uivalues.folded) {
|
||||
var per_height = (img == 'enemy48' || img == 'npc48' ? 48 : 32);
|
||||
width = Math.ceil(height / per_height / editor.uivalues.foldPerCol) * 32;
|
||||
if (width > 32) mh = per_height * editor.uivalues.foldPerCol;
|
||||
}
|
||||
editor.widthsX[img] = [img, sumWidth / 32, (sumWidth + images[img].width) / 32, images[img].height];
|
||||
sumWidth += images[img].width;
|
||||
maxHeight = Math.max(maxHeight, images[img].height);
|
||||
editor.widthsX[img] = [img, sumWidth / 32, (sumWidth + width) / 32, height];
|
||||
sumWidth += width;
|
||||
maxHeight = Math.max(maxHeight, mh + 64);
|
||||
}
|
||||
var tilesets = images.tilesets;
|
||||
for (var ii in core.tilesets) {
|
||||
@ -310,82 +497,75 @@ editor.prototype.drawInitData = function (icons) {
|
||||
if (fullWidth > edata.width) edata.style.width = (edata.width = fullWidth) / ratio + 'px';
|
||||
edata.style.height = (edata.height = fullHeight) / ratio + 'px';
|
||||
*/
|
||||
var iconImages = document.getElementById('iconImages');
|
||||
iconImages.style.width = (iconImages.width = fullWidth) / ratio + 'px';
|
||||
iconImages.style.height = (iconImages.height = fullHeight) / ratio + 'px';
|
||||
var dc = {drawImage:function(){
|
||||
var image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight;
|
||||
var a=Array.prototype.slice.call(arguments)
|
||||
if(arguments.length==3){
|
||||
// [image, dx, dy]=arguments
|
||||
// [sx, sy, sWidth, sHeight, dWidth, dHeight]=[0,0,image.width,image.height,image.width,image.height]
|
||||
image=a[0]
|
||||
a=[a[0],0,0,image.width,image.height,a[1],a[2],image.width,image.height]
|
||||
}
|
||||
if(arguments.length==5){
|
||||
// [image, dx, dy, dWidth, dHeight]=arguments
|
||||
// [sx, sy, sWidth, sHeight]=[0,0,image.width,image.height]
|
||||
image=a[0]
|
||||
a=[a[0],0,0,image.width,image.height,a[1],a[2],a[3],a[4]]
|
||||
}
|
||||
if(arguments.length==9){
|
||||
// [image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight]=arguments
|
||||
}
|
||||
image=a[0];
|
||||
sx=a[1];
|
||||
sy=a[2];
|
||||
sWidth=a[3];
|
||||
sHeight=a[4];
|
||||
dx=a[5];
|
||||
dy=a[6];
|
||||
dWidth=a[7];
|
||||
dHeight=a[8];
|
||||
//放弃对 dWidth, dHeight 的支持, 始终画一样大的
|
||||
var dimg=new Image()
|
||||
dimg.src = image.src;
|
||||
dimg.style.clip=['rect(',sy,'px,',sx+sWidth,'px,',sy+sHeight,'px,',sx,'px)'].join('')
|
||||
dimg.style.top=dy-sy+'px'
|
||||
dimg.style.left=dx-sx+'px'
|
||||
dimg.width=image.width/ratio
|
||||
dimg.height=image.height/ratio
|
||||
iconImages.appendChild(dimg)
|
||||
}}
|
||||
// var dc = edata.getContext('2d');
|
||||
var nowx = 0;
|
||||
var nowy = 0;
|
||||
var drawImage = function (image, x, y) {
|
||||
image.style.left = x + 'px';
|
||||
image.style.top = y + 'px';
|
||||
iconImages.appendChild(image);
|
||||
}
|
||||
|
||||
var nowx = 0, nowy = 0;
|
||||
for (var ii = 0; ii < imgNames.length; ii++) {
|
||||
var img = imgNames[ii];
|
||||
if (img == 'terrains') {
|
||||
(function(image,dc,nowx){
|
||||
(function(image,nowx){
|
||||
if (image.complete) {
|
||||
dc.drawImage(image, nowx, 32);
|
||||
drawImage(image, nowx, 32);
|
||||
core.material.images.airwall = image;
|
||||
delete(editor.airwallImg);
|
||||
} else image.onload = function () {
|
||||
dc.drawImage(image, nowx, 32);
|
||||
drawImage(image, nowx, 32);
|
||||
core.material.images.airwall = image;
|
||||
delete(editor.airwallImg);
|
||||
editor.updateMap();
|
||||
}
|
||||
})(editor.airwallImg,dc,nowx);
|
||||
dc.drawImage(images[img], nowx, 32*2);
|
||||
nowx += images[img].width;
|
||||
})(editor.airwallImg,nowx);
|
||||
if (editor.uivalues.folded) {
|
||||
// --- 单列 & 折行
|
||||
var subimgs = core.splitImage(images[img], 32, editor.uivalues.foldPerCol * 32);
|
||||
var frames = images[img].width / 32;
|
||||
for (var i = 0; i < subimgs.length; i+=frames) {
|
||||
drawImage(subimgs[i], nowx, i==0?2*32:0);
|
||||
nowx += 32;
|
||||
}
|
||||
}
|
||||
else {
|
||||
drawImage(images[img], nowx, 32*2);
|
||||
nowx += images[img].width;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (img == 'autotile') {
|
||||
var autotiles = images[img];
|
||||
var tempx = editor.uivalues.folded ? 32 : 96;
|
||||
for (var im in autotiles) {
|
||||
dc.drawImage(autotiles[im], 0, 0, 96, 128, nowx, nowy, 96, 128);
|
||||
var subimgs = core.splitImage(autotiles[im], tempx, autotiles[im].height);
|
||||
drawImage(subimgs[0], nowx, nowy);
|
||||
nowy += autotiles[im].height;
|
||||
}
|
||||
nowx += 3 * 32;
|
||||
nowx += tempx;
|
||||
continue;
|
||||
}
|
||||
dc.drawImage(images[img], nowx, 0)
|
||||
nowx += images[img].width;
|
||||
if (editor.uivalues.folded) {
|
||||
// --- 单列 & 折行
|
||||
var per_height = img.endsWith('48') ? 48 : 32;
|
||||
var subimgs = core.splitImage(images[img], 32, editor.uivalues.foldPerCol * per_height);
|
||||
var frames = images[img].width / 32;
|
||||
for (var i = 0; i < subimgs.length; i+=frames) {
|
||||
drawImage(subimgs[i], nowx, 0);
|
||||
nowx += 32;
|
||||
}
|
||||
}
|
||||
else {
|
||||
drawImage(images[img], nowx, 0);
|
||||
nowx += images[img].width;
|
||||
}
|
||||
}
|
||||
for (var ii in core.tilesets) {
|
||||
var img = core.tilesets[ii];
|
||||
dc.drawImage(tilesets[img], nowx, 0)
|
||||
drawImage(tilesets[img], nowx, 0);
|
||||
nowx += tilesets[img].width;
|
||||
}
|
||||
//editor.mapInit();
|
||||
@ -459,14 +639,20 @@ editor.prototype.setSelectBoxFromInfo=function(thisevent){
|
||||
pos.x=editor.widthsX[thisevent.images][1];
|
||||
pos.y=thisevent.y;
|
||||
if(thisevent.x)pos.x+=thisevent.x;
|
||||
if(thisevent.images=='terrains')pos.y+=2;
|
||||
ysize = thisevent.images.endsWith('48') ? 48 : 32;
|
||||
if (editor.uivalues.folded && core.tilesets.indexOf(thisevent.images)==-1) {
|
||||
pos.x += Math.floor(pos.y / editor.uivalues.foldPerCol);
|
||||
pos.y %= editor.uivalues.foldPerCol;
|
||||
}
|
||||
if(pos.x == 0) pos.y+=2;
|
||||
}
|
||||
var dataSelection = document.getElementById('dataSelection');
|
||||
dataSelection.style.left = pos.x * 32 + 'px';
|
||||
dataSelection.style.top = pos.y * ysize + 'px';
|
||||
dataSelection.style.height = ysize - 6 + 'px';
|
||||
setTimeout(function(){selectBox.isSelected(true);});
|
||||
editor.dom.dataSelection.style.left = pos.x * 32 + 'px';
|
||||
editor.dom.dataSelection.style.top = pos.y * ysize + 'px';
|
||||
editor.dom.dataSelection.style.height = ysize - 6 + 'px';
|
||||
setTimeout(function(){
|
||||
selectBox.isSelected(true);
|
||||
editor.updateLastUsedMap();
|
||||
});
|
||||
editor.info = JSON.parse(JSON.stringify(thisevent));
|
||||
tip.infos(JSON.parse(JSON.stringify(thisevent)));
|
||||
editor.pos=pos;
|
||||
@ -474,12 +660,31 @@ editor.prototype.setSelectBoxFromInfo=function(thisevent){
|
||||
editor_mode.onmode('enemyitem');
|
||||
}
|
||||
|
||||
editor.prototype.addUsedFlags = function (s) {
|
||||
s.replace(/flag:([a-zA-Z0-9_\u4E00-\u9FCC]+)/g, function (s0, s1) {
|
||||
editor.used_flags[s1] = true; return s0;
|
||||
});
|
||||
s.replace(/flags\.([a-zA-Z_]\w*)/g, function (s0, s1) {
|
||||
editor.used_flags[s1] = true; return s0;
|
||||
});
|
||||
if (window.flags) {
|
||||
for (var s in editor.used_flags) {
|
||||
if (!(s in window.flags)) {
|
||||
window.flags[s] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
editor.prototype.listen = function () {
|
||||
// 移动至 editor_unsorted_1.js
|
||||
// 移动至 editor_listen.js
|
||||
}//绑定事件
|
||||
|
||||
editor.prototype.mobile_listen=function(){
|
||||
// 移动至 editor_unsorted_1.js
|
||||
// 移动至 editor_listen.js
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
editor = new editor();
|
||||
@ -2,7 +2,11 @@ editor_blockly = function () {
|
||||
|
||||
var editor_blockly = {};
|
||||
|
||||
initscript = String.raw`
|
||||
/////////////////initscript start/////////////////////////////
|
||||
// do not use String.raw because of highlighting
|
||||
// Comment tagged templates
|
||||
// https://marketplace.visualstudio.com/items?itemName=bierner.comment-tagged-templates
|
||||
initscript = /* js */`
|
||||
(function(){
|
||||
var getCategory = function(name,custom){
|
||||
for(var node of document.getElementById('toolbox').children) {
|
||||
@ -22,6 +26,16 @@ editor_blockly = function () {
|
||||
"本事件触发一次后会消失",
|
||||
{"type": "hide", "time": 500},
|
||||
],'event'),
|
||||
MotaActionFunctions.actionParser.parse({
|
||||
"condition": "flag:__door__==2",
|
||||
"currentFloor": true,
|
||||
"priority": 0,
|
||||
"delayExecute": false,
|
||||
"multiExecute": false,
|
||||
"data": [
|
||||
{"type": "openDoor", "loc": [10,5]}
|
||||
],
|
||||
},'autoEvent'),
|
||||
MotaActionBlocks['changeFloor_m'].xmlText(),
|
||||
MotaActionFunctions.actionParser.parse([{
|
||||
"id": "moneyShop1",
|
||||
@ -30,12 +44,17 @@ editor_blockly = function () {
|
||||
"textInList": "1F金币商店",
|
||||
"use": "money",
|
||||
"need": "20+10*times*(times+1)",
|
||||
"text": "勇敢的武士啊,给我\${need}金币就可以:",
|
||||
"text": "勇敢的武士啊,给我\\\${need}金币就可以:",
|
||||
"choices": [
|
||||
{"text": "生命+800", "effect": "status:hp+=800"},
|
||||
{"text": "攻击+4", "effect": "status:atk+=4"},
|
||||
{"text": "防御+4", "effect": "status:def+=4"},
|
||||
{"text": "魔防+10", "effect": "status:mdef+=10"}
|
||||
]
|
||||
},{
|
||||
"id": "itemShop",
|
||||
"item": true,
|
||||
"textInList": "道具商店",
|
||||
"choices": [
|
||||
{"id": "yellowKey", "number": 10, "money": 10}
|
||||
]
|
||||
},{
|
||||
"id": "keyShop1",
|
||||
@ -50,6 +69,7 @@ editor_blockly = function () {
|
||||
MotaActionBlocks['eachArrive_m'].xmlText(),
|
||||
MotaActionBlocks['level_m'].xmlText(),
|
||||
MotaActionBlocks['commonEvent_m'].xmlText(),
|
||||
MotaActionBlocks['item_m'].xmlText(),
|
||||
],
|
||||
'显示文字':[
|
||||
MotaActionBlocks['text_0_s'].xmlText(),
|
||||
@ -72,20 +92,21 @@ editor_blockly = function () {
|
||||
MotaActionBlocks['confirm_s'].xmlText(),
|
||||
MotaActionBlocks['choices_s'].xmlText([
|
||||
'选择剑或者盾','流浪者','man',MotaActionBlocks['choicesContext'].xmlText([
|
||||
'剑','','',null,MotaActionFunctions.actionParser.parseList([{"type": "openDoor", "loc": [3,3]}]),
|
||||
'剑','','',null,'',MotaActionFunctions.actionParser.parseList([{"type": "openDoor", "loc": [3,3]}]),
|
||||
MotaActionBlocks['choicesContext'].xmlText([
|
||||
'盾','','',null,MotaActionFunctions.actionParser.parseList([{"type": "openDoor", "loc": [9,3]}]),
|
||||
'盾','','',null,'',MotaActionFunctions.actionParser.parseList([{"type": "openDoor", "loc": [9,3]}]),
|
||||
])
|
||||
])
|
||||
]),
|
||||
],
|
||||
'数据相关':[
|
||||
MotaActionBlocks['setValue_s'].xmlText([
|
||||
MotaActionBlocks['idString_1_e'].xmlText(['status','hp'])
|
||||
]),
|
||||
MotaActionBlocks['addValue_s'].xmlText([
|
||||
MotaActionBlocks['idString_1_e'].xmlText(['status','hp'])
|
||||
MotaActionBlocks['idString_1_e'].xmlText(['status','生命']), '', false
|
||||
]),
|
||||
MotaActionBlocks['setValue_s'].xmlText([
|
||||
MotaActionBlocks['idString_1_e'].xmlText(['status','生命']), '', false
|
||||
]),
|
||||
MotaActionBlocks['setEnemy_s'].xmlText(),
|
||||
MotaActionBlocks['setFloor_s'].xmlText(),
|
||||
MotaActionBlocks['setGlobalAttribute_s'].xmlText(),
|
||||
MotaActionBlocks['setGlobalValue_s'].xmlText(),
|
||||
@ -93,7 +114,6 @@ editor_blockly = function () {
|
||||
MotaActionBlocks['input_s'].xmlText(),
|
||||
MotaActionBlocks['input2_s'].xmlText(),
|
||||
MotaActionBlocks['update_s'].xmlText(),
|
||||
MotaActionBlocks['updateEnemys_s'].xmlText(),
|
||||
MotaActionBlocks['moveHero_s'].xmlText(),
|
||||
MotaActionBlocks['jumpHero_s'].xmlText(),
|
||||
MotaActionBlocks['changeFloor_s'].xmlText(),
|
||||
@ -101,6 +121,8 @@ editor_blockly = function () {
|
||||
MotaActionBlocks['changePos_1_s'].xmlText(),
|
||||
MotaActionBlocks['battle_s'].xmlText(),
|
||||
MotaActionBlocks['useItem_s'].xmlText(),
|
||||
MotaActionBlocks['loadEquip_s'].xmlText(),
|
||||
MotaActionBlocks['unloadEquip_s'].xmlText(),
|
||||
MotaActionBlocks['openShop_s'].xmlText(),
|
||||
MotaActionBlocks['disableShop_s'].xmlText(),
|
||||
MotaActionBlocks['setHeroIcon_s'].xmlText(),
|
||||
@ -108,6 +130,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(),
|
||||
@ -122,8 +145,8 @@ editor_blockly = function () {
|
||||
MotaActionBlocks['hideFloorImg_s'].xmlText(),
|
||||
],
|
||||
'事件控制':[
|
||||
MotaActionBlocks['if_s'].xmlText(),
|
||||
MotaActionBlocks['if_1_s'].xmlText(),
|
||||
MotaActionBlocks['if_s'].xmlText(),
|
||||
MotaActionFunctions.actionParser.parseList({"type": "switch", "condition": "判别值", "caseList": [
|
||||
{"action": [{"type": "comment", "text": "当判别值是值的场合执行此事件"}]},
|
||||
{"action": [], "nobreak": true},
|
||||
@ -141,12 +164,19 @@ editor_blockly = function () {
|
||||
],
|
||||
'特效/声音':[
|
||||
MotaActionBlocks['sleep_s'].xmlText(),
|
||||
MotaActionBlocks['wait_s'].xmlText(),
|
||||
MotaActionFunctions.actionParser.parseList({"type": "wait", "data": [
|
||||
{"case": "keyboard", "keycode": 13, "action": [{"type": "comment", "text": "当按下回车(keycode=13)时执行此事件"}]},
|
||||
{"case": "mouse", "px": [0,32], "py": [0,32], "action": [{"type": "comment", "text": "当点击地图左上角时执行此事件"}]},
|
||||
]}),
|
||||
MotaActionBlocks['waitAsync_s'].xmlText(),
|
||||
MotaActionBlocks['vibrate_s'].xmlText(),
|
||||
MotaActionBlocks['animate_s'].xmlText(),
|
||||
MotaActionBlocks['setViewport_s'].xmlText(),
|
||||
MotaActionBlocks['moveViewport_s'].xmlText(),
|
||||
MotaActionBlocks['showStatusBar_s'].xmlText(),
|
||||
MotaActionBlocks['hideStatusBar_s'].xmlText(),
|
||||
MotaActionBlocks['showHero_s'].xmlText(),
|
||||
MotaActionBlocks['hideHero_s'].xmlText(),
|
||||
MotaActionBlocks['setCurtain_0_s'].xmlText(),
|
||||
MotaActionBlocks['setCurtain_1_s'].xmlText(),
|
||||
MotaActionBlocks['screenFlash_s'].xmlText(),
|
||||
@ -164,16 +194,39 @@ editor_blockly = function () {
|
||||
MotaActionBlocks['autoSave_s'].xmlText(),
|
||||
MotaActionBlocks['callLoad_s'].xmlText(),
|
||||
],
|
||||
'UI绘制':[
|
||||
MotaActionBlocks['previewUI_s'].xmlText(),
|
||||
MotaActionBlocks['clearMap_s'].xmlText(),
|
||||
MotaActionBlocks['clearMap_1_s'].xmlText(),
|
||||
MotaActionBlocks['setAttribute_s'].xmlText(),
|
||||
MotaActionBlocks['fillText_s'].xmlText(),
|
||||
MotaActionBlocks['fillBoldText_s'].xmlText(),
|
||||
MotaActionBlocks['drawTextContent_s'].xmlText(),
|
||||
MotaActionBlocks['fillRect_s'].xmlText(),
|
||||
MotaActionBlocks['strokeRect_s'].xmlText(),
|
||||
MotaActionBlocks['drawLine_s'].xmlText(),
|
||||
MotaActionBlocks['drawArrow_s'].xmlText(),
|
||||
MotaActionBlocks['fillPolygon_s'].xmlText(),
|
||||
MotaActionBlocks['strokePolygon_s'].xmlText(),
|
||||
MotaActionBlocks['fillCircle_s'].xmlText(),
|
||||
MotaActionBlocks['strokeCircle_s'].xmlText(),
|
||||
MotaActionBlocks['drawImage_s'].xmlText(),
|
||||
MotaActionBlocks['drawImage_1_s'].xmlText(),
|
||||
MotaActionBlocks['drawIcon_s'].xmlText(),
|
||||
MotaActionBlocks['drawBackground_s'].xmlText(),
|
||||
MotaActionBlocks['drawSelector_s'].xmlText(),
|
||||
MotaActionBlocks['drawSelector_1_s'].xmlText(),
|
||||
],
|
||||
'原生脚本':[
|
||||
MotaActionBlocks['function_s'].xmlText(),
|
||||
MotaActionBlocks['unknown_s'].xmlText(),
|
||||
],
|
||||
'值块':[
|
||||
MotaActionBlocks['setValue_s'].xmlText([
|
||||
MotaActionBlocks['idString_1_e'].xmlText(['status','hp'])
|
||||
]),
|
||||
MotaActionBlocks['addValue_s'].xmlText([
|
||||
MotaActionBlocks['idString_1_e'].xmlText(['status','hp'])
|
||||
MotaActionBlocks['idString_1_e'].xmlText(['status','生命']), '', false
|
||||
]),
|
||||
MotaActionBlocks['setValue_s'].xmlText([
|
||||
MotaActionBlocks['idString_1_e'].xmlText(['status','生命']), '', false
|
||||
]),
|
||||
MotaActionBlocks['expression_arithmetic_0'].xmlText(),
|
||||
MotaActionBlocks['evFlag_e'].xmlText(),
|
||||
@ -182,33 +235,37 @@ editor_blockly = function () {
|
||||
MotaActionBlocks['idString_e'].xmlText(),
|
||||
MotaActionBlocks['idString_1_e'].xmlText(),
|
||||
MotaActionBlocks['idString_2_e'].xmlText(),
|
||||
MotaActionBlocks['idString_3_e'].xmlText(),
|
||||
MotaActionBlocks['idString_4_e'].xmlText(),
|
||||
MotaActionBlocks['idString_5_e'].xmlText(),
|
||||
MotaActionBlocks['idString_6_e'].xmlText(),
|
||||
MotaActionBlocks['evalString_e'].xmlText(),
|
||||
],
|
||||
'常见事件模板':[
|
||||
'<label text="检测音乐如果没有开启则系统提示开启"></label>',
|
||||
MotaActionFunctions.actionParser.parseList({"type": "if", "condition": "!core.musicStatus.bgmStatus",
|
||||
"true": [
|
||||
"\t[系统提示]你当前音乐处于关闭状态,本塔开音乐游戏效果更佳"
|
||||
"\\t[系统提示]你当前音乐处于关闭状态,本塔开音乐游戏效果更佳"
|
||||
],
|
||||
"false": []
|
||||
}),
|
||||
'<label text="商店购买属性/钥匙"></label>',
|
||||
MotaActionFunctions.actionParser.parse([
|
||||
{"type": "choices", "text": "\t[老人,man]少年,你需要钥匙吗?\n我这里有大把的!",
|
||||
{"type": "choices", "text": "\\t[老人,man]少年,你需要钥匙吗?\\n我这里有大把的!",
|
||||
"choices": [
|
||||
{"text": "黄钥匙(\${9+flag:shop_times}金币)", "color": [255,255,0,1], "action": [
|
||||
{"text": "黄钥匙(\\\${9+flag:shop_times}金币)", "color": [255,255,0,1], "action": [
|
||||
{"type": "if", "condition": "status:money>=9+flag:shop_times",
|
||||
"true": [
|
||||
{"type": "addValue", "name": "status:money", "value": "-(9+flag:shop_times)"},
|
||||
{"type": "addValue", "name": "item:yellowKey", "value": "1"},
|
||||
],
|
||||
"false": [
|
||||
"\t[老人,man]你的金钱不足!",
|
||||
"\\t[老人,man]你的金钱不足!",
|
||||
{"type": "revisit"}
|
||||
]
|
||||
}
|
||||
]},
|
||||
{"text": "蓝钥匙(\${18+2*flag:shop_times}金币)", "color": [0,0,255,1], "action": [
|
||||
{"text": "蓝钥匙(\\\${18+2*flag:shop_times}金币)", "color": [0,0,255,1], "action": [
|
||||
]},
|
||||
{"text": "离开", "action": [
|
||||
{"type": "exit"}
|
||||
@ -361,7 +418,7 @@ function omitedcheckUpdateFunction(event) {
|
||||
}
|
||||
}
|
||||
try {
|
||||
var code = Blockly.JavaScript.workspaceToCode(workspace).replace(/\\i/g, '\\\\i');
|
||||
var code = Blockly.JavaScript.workspaceToCode(workspace).replace(/\\\\(i|c|d|e)/g, '\\\\\\\\$1');
|
||||
codeAreaHL.setValue(code);
|
||||
} catch (error) {
|
||||
codeAreaHL.setValue(String(error));
|
||||
@ -433,6 +490,18 @@ function omitedcheckUpdateFunction(event) {
|
||||
}
|
||||
})();
|
||||
`;
|
||||
/////////////////initscript end /////////////////////////////
|
||||
|
||||
editor.uivalues.disableBlocklyReplace = editor.config.get("disableBlocklyReplace", false);
|
||||
var replaceCheckbox = document.getElementById('blocklyReplace');
|
||||
replaceCheckbox.checked = !editor.uivalues.disableBlocklyReplace;
|
||||
|
||||
editor_blockly.triggerReplace = function () {
|
||||
editor.uivalues.disableBlocklyReplace = !replaceCheckbox.checked;
|
||||
editor.config.set("disableBlocklyReplace", !replaceCheckbox.checked);
|
||||
if (MotaActionFunctions) MotaActionFunctions.disableReplace = !replaceCheckbox.checked;
|
||||
alert("已" + (replaceCheckbox.checked ? "开启" : "关闭") + "中文变量名替换!\n关闭并重开事件编辑器以生效。");
|
||||
}
|
||||
|
||||
var input_ = '';
|
||||
editor_blockly.runOne = function () {
|
||||
@ -463,6 +532,7 @@ function omitedcheckUpdateFunction(event) {
|
||||
}
|
||||
input_ = xhr.responseText;
|
||||
editor_blockly.runOne();
|
||||
MotaActionFunctions.disableReplace = editor.uivalues.disableBlocklyReplace;
|
||||
}
|
||||
xhr.open('GET', '_server/MotaAction.g4', true);
|
||||
xhr.send(null);
|
||||
@ -503,8 +573,7 @@ function omitedcheckUpdateFunction(event) {
|
||||
MotaActionFunctions.parse(
|
||||
eval('obj=' + codeAreaHL.getValue().replace(/[<>&]/g, function (c) {
|
||||
return {'<': '<', '>': '>', '&': '&'}[c];
|
||||
}).replace(/\\r/g, '\\\\r').replace(/\\f/g, '\\\\f')
|
||||
.replace(/\\i/,'\\\\i')),
|
||||
}).replace(/\\(r|f|i|c|d|e)/g,'\\\\$1')),
|
||||
document.getElementById('entryType').value
|
||||
);
|
||||
}
|
||||
@ -578,14 +647,86 @@ function omitedcheckUpdateFunction(event) {
|
||||
return;
|
||||
}
|
||||
var code = Blockly.JavaScript.workspaceToCode(editor_blockly.workspace);
|
||||
code = code.replace(/\\i/g, '\\\\i');
|
||||
code = code.replace(/\\(i|c|d|e)/g, '\\\\$1');
|
||||
eval('var obj=' + code);
|
||||
if (this.checkAsync(obj) && confirm("警告!存在不等待执行完毕的事件但却没有用【等待所有异步事件处理完毕】来等待" +
|
||||
"它们执行完毕,这样可能会导致录像检测系统出问题。\n你要返回修改么?")) return;
|
||||
setvalue(JSON.stringify(obj));
|
||||
}
|
||||
|
||||
// 检查"不等待处理完毕"
|
||||
editor_blockly.checkAsync = function (obj) {
|
||||
if (!(obj instanceof Array)) return false;
|
||||
var hasAsync = false;
|
||||
for (var i = 0; i < obj.length; ++i) {
|
||||
var one = obj[i];
|
||||
if (one.type == 'if' && (this.checkAsync(one['true']) || this.checkAsync(one['false'])))
|
||||
return true;
|
||||
if ((one.type == 'while' || one.type == 'dowhile') && this.checkAsync(one.data))
|
||||
return true;
|
||||
if (one.type == 'if' && (this.checkAsync(one.yes) || this.checkAsync(one.no)))
|
||||
return true;
|
||||
if (one.type == 'choices') {
|
||||
var list = one.choices;
|
||||
if (list instanceof Array) {
|
||||
for (var j = 0; j < list.length; j++) {
|
||||
if (this.checkAsync(list[j].action)) return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (one.type == 'switch') {
|
||||
var list = one.caseList;
|
||||
if (list instanceof Array) {
|
||||
for (var j = 0; j < list.length; j++) {
|
||||
if (this.checkAsync(list[j].action)) return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (one.async && one.type != 'animate') hasAsync = true;
|
||||
if (one.type == 'waitAsync') hasAsync = false;
|
||||
}
|
||||
return hasAsync;
|
||||
}
|
||||
|
||||
var previewBlock = function (b) {
|
||||
var types = [
|
||||
"previewUI_s", "clearMap_s", "clearMap_1_s", "setAttribute_s", "fillText_s",
|
||||
"fillBoldText_s", "fillRect_s", "strokeRect_s", "drawLine_s",
|
||||
"drawArrow_s", "fillPolygon_s", "strokePolygon_s", "fillCircle_s", "strokeCircle_s",
|
||||
"drawImage_s", "drawImage_1_s", "drawIcon_s", "drawBackground_s", "drawSelector_s", "drawSelector_1_s",
|
||||
"waitContext_2"
|
||||
];
|
||||
if (b && types.indexOf(b.type)>=0) {
|
||||
try {
|
||||
var code = "[" + Blockly.JavaScript.blockToCode(b).replace(/\\(i|c|d|e)/g, '\\\\$1') + "]";
|
||||
eval("var obj="+code);
|
||||
if (obj.length > 0 && b.type == 'waitContext_2') {
|
||||
var dt = obj[0];
|
||||
editor.uievent.previewUI([{"type": "fillRect", "x": dt.px[0], "y": dt.py[0],
|
||||
"width": "(" + dt.px[1] + ")-(" + dt.px[0] + ")", "height": "(" + dt.py[1] + ")-(" + dt.py[0] + ")",
|
||||
"style": "rgba(255,0,0,0.5)"}])
|
||||
}
|
||||
else if (obj.length > 0 && b.type.startsWith(obj[0].type)) {
|
||||
if (b.type == 'previewUI_s')
|
||||
editor.uievent.previewUI(obj[0].action);
|
||||
else editor.uievent.previewUI([obj[0]]);
|
||||
}
|
||||
} catch (e) {main.log(e);}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
editor_blockly.doubleClickBlock = function (blockId) {
|
||||
var b = editor_blockly.workspace.getBlockById(blockId);
|
||||
//console.log(b);
|
||||
|
||||
if (previewBlock(b)) return;
|
||||
|
||||
if (b && b.type in selectPointBlocks) { // selectPoint
|
||||
this.selectPoint();
|
||||
return;
|
||||
}
|
||||
|
||||
var textStringDict = {
|
||||
'text_0_s': 'EvalString_0',
|
||||
'text_1_s': 'EvalString_2',
|
||||
@ -597,6 +738,7 @@ function omitedcheckUpdateFunction(event) {
|
||||
'function_s': 'RawEvalString_0',
|
||||
'shopsub': 'EvalString_3',
|
||||
'confirm_s': 'EvalString_0',
|
||||
'drawTextContent_s': 'EvalString_0',
|
||||
}
|
||||
var f = b ? textStringDict[b.type] : null;
|
||||
if (f) {
|
||||
@ -615,7 +757,7 @@ function omitedcheckUpdateFunction(event) {
|
||||
'comment_s',
|
||||
'show_s',
|
||||
'hide_s',
|
||||
'setValue_s',
|
||||
'addValue_s',
|
||||
'if_s',
|
||||
'battle_s',
|
||||
'openDoor_s',
|
||||
@ -644,40 +786,26 @@ function omitedcheckUpdateFunction(event) {
|
||||
|
||||
// Index from 1 - 9
|
||||
editor_blockly.openToolbox = function(index) {
|
||||
// var element = document.getElementById(':'+index);
|
||||
// if (element == null || element.getAttribute("aria-selected")=="true") return;
|
||||
// element.click();
|
||||
editor_blockly.workspace.toolbox_.tree_.setSelectedItem(editor_blockly.workspace.toolbox_.tree_.children_[index-1]);
|
||||
if (index < 0) index += editor_blockly.workspace.toolbox_.tree_.children_.length;
|
||||
editor_blockly.workspace.toolbox_.tree_.setSelectedItem(editor_blockly.workspace.toolbox_.tree_.children_[index]);
|
||||
}
|
||||
editor_blockly.reopenToolbox = function(index) {
|
||||
// var element = document.getElementById(':'+index);
|
||||
// if (element == null) return;
|
||||
// if (element.getAttribute("aria-selected")=="true") element.click();
|
||||
// element.click();
|
||||
editor_blockly.workspace.toolbox_.tree_.setSelectedItem(editor_blockly.workspace.toolbox_.tree_.children_[index-1]);
|
||||
editor_blockly.workspace.getFlyout_().show(editor_blockly.workspace.toolbox_.tree_.children_[index-1].blocks);
|
||||
if (index < 0) index += editor_blockly.workspace.toolbox_.tree_.children_.length;
|
||||
editor_blockly.workspace.toolbox_.tree_.setSelectedItem(editor_blockly.workspace.toolbox_.tree_.children_[index]);
|
||||
editor_blockly.workspace.getFlyout_().show(editor_blockly.workspace.toolbox_.tree_.children_[index].blocks);
|
||||
}
|
||||
|
||||
editor_blockly.closeToolbox = function() {
|
||||
/*
|
||||
for (var i=1; i<=10; i++) {
|
||||
var element = document.getElementById(':'+i);
|
||||
if (element && element.getAttribute("aria-selected")=="true") {
|
||||
element.click();
|
||||
return;
|
||||
}
|
||||
}
|
||||
*/
|
||||
editor_blockly.workspace.toolbox_.clearSelection();
|
||||
}
|
||||
|
||||
var searchInput = document.getElementById("searchBlock");
|
||||
searchInput.onfocus = function () {
|
||||
editor_blockly.reopenToolbox(10);
|
||||
editor_blockly.reopenToolbox(-1);
|
||||
}
|
||||
|
||||
searchInput.oninput = function () {
|
||||
editor_blockly.reopenToolbox(10);
|
||||
editor_blockly.reopenToolbox(-1);
|
||||
}
|
||||
|
||||
editor_blockly.searchBlock = function (value) {
|
||||
@ -702,6 +830,342 @@ function omitedcheckUpdateFunction(event) {
|
||||
return results.length == 0 ? editor_blockly.lastUsedType : results;
|
||||
}
|
||||
|
||||
// ------ select point ------
|
||||
|
||||
// id: [x, y, floorId, forceFloor]
|
||||
var selectPointBlocks = {
|
||||
"changeFloor_m": ["Number_0", "Number_1", "IdString_0", true],
|
||||
"jumpHero_s": ["PosString_0", "PosString_1"],
|
||||
"changeFloor_s": ["PosString_0", "PosString_1", "IdString_0", true],
|
||||
"changePos_0_s": ["PosString_0", "PosString_1"],
|
||||
"battle_1_s": ["PosString_0", "PosString_1"],
|
||||
"openDoor_s": ["PosString_0", "PosString_1", "IdString_0"],
|
||||
"closeDoor_s": ["PosString_0", "PosString_1"],
|
||||
"show_s": ["EvalString_0", "EvalString_1", "IdString_0"],
|
||||
"hide_s": ["EvalString_0", "EvalString_1", "IdString_0"],
|
||||
"setBlock_s": ["EvalString_1", "EvalString_2", "IdString_0"],
|
||||
"move_s": ["PosString_0", "PosString_1"],
|
||||
"jump_s": ["PosString_2", "PosString_3"], // 跳跃暂时只考虑终点
|
||||
"showBgFgMap_s": ["EvalString_0", "EvalString_1", "IdString_0"],
|
||||
"hideBgFgMap_s": ["EvalString_0", "EvalString_1", "IdString_0"],
|
||||
"setBgFgBlock_s": ["EvalString_1", "EvalString_2", "IdString_0"],
|
||||
"showFloorImg_s": ["EvalString_0", "EvalString_1", "IdString_0"],
|
||||
"hideFloorImg_s": ["EvalString_0", "EvalString_1", "IdString_0"],
|
||||
"trigger_s": ["PosString_0", "PosString_1"],
|
||||
"insert_2_s": ["PosString_0", "PosString_1", "IdString_0"],
|
||||
"animate_s": ["EvalString_0", "EvalString_0"],
|
||||
"setViewport_s": ["PosString_0", "PosString_1"]
|
||||
}
|
||||
|
||||
editor_blockly.selectPoint = function () {
|
||||
var block = Blockly.selected, arr = null;
|
||||
var floorId = editor.currentFloorId, pos = editor.pos, x = pos.x, y = pos.y;
|
||||
if (block != null && block.type in selectPointBlocks) {
|
||||
arr = selectPointBlocks[block.type];
|
||||
var xv = parseInt(block.getFieldValue(arr[0])), yv = parseInt(block.getFieldValue(arr[1]));
|
||||
if (block.type == 'animate_s') {
|
||||
var v = block.getFieldValue(arr[0]).split(",");
|
||||
xv = parseInt(v[0]); yv = parseInt(v[1]);
|
||||
}
|
||||
if (!isNaN(xv)) x = xv;
|
||||
if (!isNaN(yv)) y = yv;
|
||||
if (arr[2] != null) floorId = block.getFieldValue(arr[2]) || floorId;
|
||||
}
|
||||
editor.uievent.selectPoint(floorId, x, y, arr && arr[2] == null, function (fv, xv, yv) {
|
||||
if (!arr) return;
|
||||
if (arr[2] != null) {
|
||||
if (fv != editor.currentFloorId) block.setFieldValue(fv, arr[2]);
|
||||
else block.setFieldValue(arr[3] ? fv : "", arr[2]);
|
||||
}
|
||||
if (block.type == 'animate_s') {
|
||||
block.setFieldValue(xv+","+yv, arr[0]);
|
||||
}
|
||||
else {
|
||||
block.setFieldValue(xv+"", arr[0]);
|
||||
block.setFieldValue(yv+"", arr[1]);
|
||||
}
|
||||
if (block.type == 'changeFloor_m') {
|
||||
block.setFieldValue("floorId", "Floor_List_0");
|
||||
block.setFieldValue("loc", "Stair_List_0");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
editor_blockly.getAutoCompletions = function (content) {
|
||||
// --- content为当前框中输入内容;将返回一个列表,为后续所有可补全内容
|
||||
|
||||
// 检查 status:xxx,item:xxx和flag:xxx
|
||||
var index = Math.max(content.lastIndexOf(":"), content.lastIndexOf(":"));
|
||||
if (index >= 0) {
|
||||
var ch = content.charAt(index);
|
||||
var before = content.substring(0, index), token = content.substring(index+1);
|
||||
if (/^[a-zA-Z0-9_\u4E00-\u9FCC]*$/.test(token)) {
|
||||
if (before.endsWith("状态") || (ch == ':' && before.endsWith("status"))) {
|
||||
var list = Object.keys(core.status.hero);
|
||||
if (before.endsWith("状态") && MotaActionFunctions) {
|
||||
list = MotaActionFunctions.pattern.replaceStatusList.map(function (v) {
|
||||
return v[1];
|
||||
}).concat(list);
|
||||
}
|
||||
return list.filter(function (one) {
|
||||
return one != token && one.startsWith(token);
|
||||
}).sort();
|
||||
}
|
||||
else if (before.endsWith("物品") || (ch == ':' && before.endsWith("item"))) {
|
||||
var list = Object.keys(core.material.items);
|
||||
if (before.endsWith("物品") && MotaActionFunctions) {
|
||||
list = MotaActionFunctions.pattern.replaceItemList.map(function (v) {
|
||||
return v[1];
|
||||
}).concat(list);
|
||||
}
|
||||
return list.filter(function (one) {
|
||||
return one != token && one.startsWith(token);
|
||||
}).sort();
|
||||
}
|
||||
else if (before.endsWith("变量") || (ch == ':' && before.endsWith("flag"))) {
|
||||
return Object.keys(editor.used_flags || {}).filter(function (one) {
|
||||
return one != token && one.startsWith(token);
|
||||
}).sort();
|
||||
} else if (before.endsWith("怪物") || (ch == ':' && before.endsWith("enemy"))) {
|
||||
return Object.keys(core.material.enemys).filter(function (one) {
|
||||
return one != token && one.startsWith(token);
|
||||
})
|
||||
} else {
|
||||
var index2 = Math.max(content.lastIndexOf(":", index-1), content.lastIndexOf(":", index-1));
|
||||
var ch2 = content.charAt(index2);
|
||||
if (index2 >= 0) {
|
||||
before = content.substring(0, index2);
|
||||
if (before.endsWith("怪物") || (ch == ':' && ch2 == ':' && before.endsWith("enemy"))) {
|
||||
var list = ["name", "hp", "atk", "def", "money", "experience", "point", "special"];
|
||||
if (before.endsWith("怪物") && MotaActionFunctions) {
|
||||
list = MotaActionFunctions.pattern.replaceEnemyList.map(function (v) {
|
||||
return v[1];
|
||||
}).concat(list);
|
||||
}
|
||||
return list.filter(function (one) {
|
||||
return one != token && one.startsWith(token);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 提供 core.xxx 的补全
|
||||
index = content.lastIndexOf("core.");
|
||||
if (index >= 0) {
|
||||
var s = content.substring(index + 5);
|
||||
if (/^[\w.]*$/.test(s)) {
|
||||
var tokens = s.split(".");
|
||||
var now = core, prefix = tokens[tokens.length - 1];
|
||||
for (var i = 0; i < tokens.length - 1; ++i) {
|
||||
now = now[tokens[i]];
|
||||
if (now == null) break;
|
||||
}
|
||||
if (now != null) {
|
||||
var candidates = [];
|
||||
for (var i in now) {
|
||||
candidates.push(i);
|
||||
}
|
||||
return candidates.filter(function (one) {
|
||||
return one != prefix && one.startsWith(prefix);
|
||||
}).sort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 提供 flags.xxx 补全
|
||||
index = content.lastIndexOf("flags.");
|
||||
if (index >= 0) {
|
||||
var token = content.substring(index+6);
|
||||
return Object.keys(editor.used_flags || {}).filter(function (one) {
|
||||
return one != token && one.startsWith(token)
|
||||
&& /^[a-zA-Z_]\w*$/.test(one);
|
||||
}).sort();
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
editor_blockly.completeItems = [];
|
||||
return editor_blockly;
|
||||
}
|
||||
//editor_blockly=editor_blockly();
|
||||
|
||||
// --- modify Blockly
|
||||
|
||||
Blockly.FieldColour.prototype.createWidget_ = function() {
|
||||
Blockly.WidgetDiv.hide();
|
||||
|
||||
// console.log('here')
|
||||
var self=this;
|
||||
var pb=self.sourceBlock_
|
||||
var args = MotaActionBlocks[pb.type].args
|
||||
var targetf=args[args.indexOf(self.name)-1]
|
||||
|
||||
var getValue=function(){
|
||||
// return self.getValue() // css颜色
|
||||
var f = pb.getFieldValue(targetf);
|
||||
if (/^(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)?$/.test(f)) {
|
||||
return f;
|
||||
}
|
||||
return "";
|
||||
// 也可以用 pb.getFieldValue(targetf) 获得颜色块左边的域的内容
|
||||
}
|
||||
|
||||
var setValue=function(newValue){ // css颜色
|
||||
self.setValue(newValue)
|
||||
var c=new Colors();
|
||||
c.setColor(newValue)
|
||||
var rgbatext = [c.colors.webSmart.r,c.colors.webSmart.g,c.colors.webSmart.b,c.colors.alpha].join(",");
|
||||
pb.setFieldValue(rgbatext, targetf) // 放在颜色块左边的域中
|
||||
}
|
||||
|
||||
setTimeout(function () {
|
||||
document.getElementById("colorPicker").value = getValue();
|
||||
window.jsColorPicker.confirm = setValue;
|
||||
// 设置位置
|
||||
triggerColorPicker(Blockly.WidgetDiv.DIV.style.left, Blockly.WidgetDiv.DIV.style.top);
|
||||
});
|
||||
|
||||
return document.createElement('table');
|
||||
};
|
||||
|
||||
Blockly.FieldTextInput.prototype.showInlineEditor_ = function(quietInput) {
|
||||
Blockly.WidgetDiv.show(this, this.sourceBlock_.RTL, this.widgetDispose_());
|
||||
var div = Blockly.WidgetDiv.DIV;
|
||||
// Create the input.
|
||||
var htmlInput =
|
||||
goog.dom.createDom(goog.dom.TagName.INPUT, 'blocklyHtmlInput');
|
||||
htmlInput.setAttribute('spellcheck', this.spellcheck_);
|
||||
var fontSize =
|
||||
(Blockly.FieldTextInput.FONTSIZE * this.workspace_.scale) + 'pt';
|
||||
div.style.fontSize = fontSize;
|
||||
htmlInput.style.fontSize = fontSize;
|
||||
|
||||
Blockly.FieldTextInput.htmlInput_ = htmlInput;
|
||||
div.appendChild(htmlInput);
|
||||
|
||||
htmlInput.value = htmlInput.defaultValue = this.text_;
|
||||
htmlInput.oldValue_ = null;
|
||||
|
||||
// console.log('here')
|
||||
var self=this;
|
||||
var pb=self.sourceBlock_
|
||||
var args = MotaActionBlocks[pb.type].args
|
||||
var targetf=args[args.indexOf(self.name)+1]
|
||||
|
||||
// ------ colour
|
||||
|
||||
if(targetf && targetf.slice(0,7)==='Colour_'){
|
||||
var inputDom = htmlInput;
|
||||
// var getValue=function(){ // 获得自己的字符串
|
||||
// return pb.getFieldValue(self.name);
|
||||
// }
|
||||
var setValue = function(newValue){ // 设置右边颜色块的css颜色
|
||||
pb.setFieldValue(newValue, targetf)
|
||||
}
|
||||
// 给inputDom绑事件
|
||||
inputDom.oninput=function(){
|
||||
var value=inputDom.value
|
||||
if(/[0-9 ]+,[0-9 ]+,[0-9 ]+(,[0-9. ]+)?/.test(value)){
|
||||
setValue('rgba('+value+')')
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
htmlInput.onkeydown = function (e) {
|
||||
if (e.keyCode == 13 && awesomplete.opened && awesomplete.selected) {
|
||||
e.stopPropagation();
|
||||
e.stopImmediatePropagation();
|
||||
e.preventDefault();
|
||||
awesomplete.select();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// --- awesomplete
|
||||
var awesomplete = new Awesomplete(htmlInput, {
|
||||
minChars: pb.type == "idString_3_e" ? 1 : 2,
|
||||
maxItems: 12,
|
||||
autoFirst: true,
|
||||
replace: function (text) {
|
||||
text = text.toString();
|
||||
var value = this.input.value, index = this.input.selectionEnd;
|
||||
if (index == null) index = value.length;
|
||||
if (index < awesomplete.prefix.length) index = awesomplete.prefix.length;
|
||||
var str = value.substring(0, index - awesomplete.prefix.length) + text + value.substring(index);
|
||||
this.input.value = str;
|
||||
pb.setFieldValue(str, self.name);
|
||||
index += text.length - awesomplete.prefix.length;
|
||||
this.input.setSelectionRange(index, index);
|
||||
|
||||
editor_blockly.completeItems = editor_blockly.completeItems.filter(function (x) {
|
||||
return x != text;
|
||||
});
|
||||
editor_blockly.completeItems.unshift(text);
|
||||
},
|
||||
filter: function () {return true;},
|
||||
item: function (text, input) {
|
||||
var li = document.createElement("li");
|
||||
li.setAttribute("role", "option");
|
||||
li.setAttribute("aria-selected", "false");
|
||||
input = awesomplete.prefix.trim();
|
||||
if (input != "") text = text.replace(new RegExp("^"+input, "i"), "<mark>$&</mark>");
|
||||
li.innerHTML = text;
|
||||
return li;
|
||||
},
|
||||
sort: function (a, b) {
|
||||
a = a.toString(); b = b.toString();
|
||||
var ia = editor_blockly.completeItems.indexOf(a), ib = editor_blockly.completeItems.indexOf(b);
|
||||
if (ia < 0) ia = editor_blockly.completeItems.length;
|
||||
if (ib < 0) ib = editor_blockly.completeItems.length;
|
||||
if (ia != ib) return ia - ib;
|
||||
if (a.length != b.length) return a.length - b.length;
|
||||
return a < b ? -1 : 1;
|
||||
}
|
||||
});
|
||||
|
||||
htmlInput.oninput = function () {
|
||||
var value = htmlInput.value, index = htmlInput.selectionEnd;
|
||||
if (index == null) index = value.length;
|
||||
value = value.substring(0, index);
|
||||
// cal prefix
|
||||
awesomplete.prefix = "";
|
||||
for (var i = index - 1; i>=0; i--) {
|
||||
var c = value.charAt(i);
|
||||
if (!/^[a-zA-Z0-9_\u4E00-\u9FCC]$/.test(c)) {
|
||||
awesomplete.prefix = value.substring(i+1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var list = editor_blockly.getAutoCompletions(value);
|
||||
if (pb.type == "idString_3_e") {
|
||||
list = list.concat(Object.keys(core.material.enemys).filter(function (one) {
|
||||
return one != value && one.startsWith(value);
|
||||
}));
|
||||
list.sort();
|
||||
}
|
||||
|
||||
awesomplete.list = list;
|
||||
awesomplete.ul.style.marginLeft = getCaretCoordinates(htmlInput, htmlInput.selectionStart).left -
|
||||
htmlInput.scrollLeft - 20 + "px";
|
||||
awesomplete.evaluate();
|
||||
}
|
||||
|
||||
awesomplete.container.style.width = "100%";
|
||||
|
||||
window.awesomplete = awesomplete;
|
||||
}
|
||||
|
||||
if (!quietInput) {
|
||||
htmlInput.focus();
|
||||
htmlInput.select();
|
||||
}
|
||||
this.validate_();
|
||||
this.resizeEditor_();
|
||||
|
||||
this.bindEvents_(htmlInput);
|
||||
};
|
||||
34
_server/editor_config.js
Normal file
@ -0,0 +1,34 @@
|
||||
function editor_config() {
|
||||
this.address = "_server/config.json";
|
||||
}
|
||||
|
||||
editor_config.prototype.load = function(callback) {
|
||||
var _this = this;
|
||||
fs.readFile(this.address, "utf-8", function(e, d) {
|
||||
if (e) {
|
||||
console.warn("无法读取配置文件, 已重新生成");
|
||||
_this.config = {};
|
||||
_this.save(callback);
|
||||
} else {
|
||||
_this.config = JSON.parse(d);
|
||||
if (callback) callback();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
editor_config.prototype.get = function(key, defaultValue) {
|
||||
value = this.config[key];
|
||||
return value != null ? value : defaultValue;
|
||||
}
|
||||
|
||||
editor_config.prototype.set = function(key, value, callback) {
|
||||
this.config[key] = value;
|
||||
if (callback !== false) this.save(callback);
|
||||
}
|
||||
|
||||
editor_config.prototype.save = function(callback) {
|
||||
fs.writeFile(this.address, JSON.stringify(this.config) ,'utf-8', function(e) {
|
||||
if (e) alert("写入配置文件失败");
|
||||
if (callback instanceof Function) callback();
|
||||
})
|
||||
}
|
||||
809
_server/editor_datapanel.js
Normal file
@ -0,0 +1,809 @@
|
||||
editor_datapanel_wrapper = function (editor) {
|
||||
|
||||
// 此文件内的内容仅做了分类, 未仔细整理函数
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//////////////////// 地图编辑 //////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
editor.uifunctions.newMap_func = function () {
|
||||
|
||||
var newMap = document.getElementById('newMap');
|
||||
var newFileName = document.getElementById('newFileName');
|
||||
newMap.onclick = function () {
|
||||
if (!newFileName.value) return;
|
||||
if (core.floorIds.indexOf(newFileName.value) >= 0) {
|
||||
printe("该楼层已存在!");
|
||||
return;
|
||||
}
|
||||
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(newFileName.value)) {
|
||||
printe("楼层名不合法!请使用字母、数字、下划线,且不能以数字开头!");
|
||||
return;
|
||||
}
|
||||
var width = parseInt(document.getElementById('newMapWidth').value);
|
||||
var height = parseInt(document.getElementById('newMapHeight').value);
|
||||
if (!core.isset(width) || !core.isset(height) || width < core.__SIZE__ || height < core.__SIZE__ || width * height > 1000) {
|
||||
printe("新建地图的宽高都不得小于" + core.__SIZE__ + ",且宽高之积不能超过1000");
|
||||
return;
|
||||
}
|
||||
|
||||
editor_mode.onmode('');
|
||||
editor.file.saveNewFile(newFileName.value, function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw (err)
|
||||
}
|
||||
core.floorIds.push(newFileName.value);
|
||||
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])
|
||||
}
|
||||
; printe('新建成功,请F5刷新编辑器生效');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
editor.uifunctions.createNewMaps_func = function () {
|
||||
var newMaps = document.getElementById('newMaps');
|
||||
var newFloors = document.getElementById('newFloors');
|
||||
newMaps.onclick = function () {
|
||||
if (newFloors.style.display == 'none') newFloors.style.display = 'block';
|
||||
else newFloors.style.display = 'none';
|
||||
}
|
||||
|
||||
var createNewMaps = document.getElementById('createNewMaps');
|
||||
createNewMaps.onclick = function () {
|
||||
var floorIds = document.getElementById('newFloorIds').value;
|
||||
if (!floorIds) return;
|
||||
var from = parseInt(document.getElementById('newMapsFrom').value),
|
||||
to = parseInt(document.getElementById('newMapsTo').value);
|
||||
if (!core.isset(from) || !core.isset(to) || from > to || from < 0 || to < 0) {
|
||||
printe("请输入有效的起始和终止楼层");
|
||||
return;
|
||||
}
|
||||
if (to - from >= 100) {
|
||||
printe("一次最多创建99个楼层");
|
||||
return;
|
||||
}
|
||||
var floorIdList = [];
|
||||
for (var i = from; i <= to; i++) {
|
||||
var floorId = floorIds.replace(/\${(.*?)}/g, function (word, value) {
|
||||
return eval(value);
|
||||
});
|
||||
if (core.floorIds.indexOf(floorId) >= 0) {
|
||||
printe("要创建的楼层 " + floorId + " 已存在!");
|
||||
return;
|
||||
}
|
||||
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(floorId)) {
|
||||
printe("楼层名 " + floorId + " 不合法!请使用字母、数字、下划线,且不能以数字开头!");
|
||||
return;
|
||||
}
|
||||
if (floorIdList.indexOf(floorId) >= 0) {
|
||||
printe("尝试重复创建楼层 " + floorId + " !");
|
||||
return;
|
||||
}
|
||||
floorIdList.push(floorId);
|
||||
}
|
||||
|
||||
var width = parseInt(document.getElementById('newMapsWidth').value);
|
||||
var height = parseInt(document.getElementById('newMapsHeight').value);
|
||||
if (!core.isset(width) || !core.isset(height) || width < core.__SIZE__ || height < core.__SIZE__ || width * height > 1000) {
|
||||
printe("新建地图的宽高都不得小于" + core.__SIZE__ + ",且宽高之积不能超过1000");
|
||||
return;
|
||||
}
|
||||
editor_mode.onmode('');
|
||||
|
||||
editor.file.saveNewFiles(floorIdList, from, to, function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw (err)
|
||||
}
|
||||
core.floorIds = core.floorIds.concat(floorIdList);
|
||||
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])
|
||||
}
|
||||
; printe('批量创建 ' + floorIdList[0] + '~' + floorIdList[floorIdList.length - 1] + ' 成功,请F5刷新编辑器生效');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//////////////////// 地图选点 //////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// 添加自动事件页,无需双击
|
||||
editor.uifunctions.addAutoEvent = function () {
|
||||
if (editor_mode.mode != 'loc') return false;
|
||||
var newid = '2';
|
||||
var ae = editor.currentFloorData.autoEvent[editor_mode.pos.x + ',' + editor_mode.pos.y];
|
||||
if (ae != null) {
|
||||
var testid;
|
||||
for (testid = 2; Object.hasOwnProperty.call(ae, testid); testid++);
|
||||
newid = testid + '';
|
||||
}
|
||||
editor_mode.addAction(['add', "['autoEvent']['" + newid + "']", null]);
|
||||
editor_mode.onmode('save');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//////////////////// 图块属性 //////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
editor.uifunctions.newIdIdnum_func = function () {
|
||||
var newIdIdnum = document.getElementById('newIdIdnum');
|
||||
newIdIdnum.children[2].onclick = function () {
|
||||
if (newIdIdnum.children[0].value && newIdIdnum.children[1].value) {
|
||||
var id = newIdIdnum.children[0].value;
|
||||
var idnum = parseInt(newIdIdnum.children[1].value);
|
||||
if (!core.isset(idnum)) {
|
||||
printe('不合法的idnum');
|
||||
return;
|
||||
}
|
||||
if (!/^[0-9a-zA-Z_]+$/.test(id)) {
|
||||
printe('不合法的id,请使用字母、数字或下划线')
|
||||
return;
|
||||
}
|
||||
editor.file.changeIdAndIdnum(id, idnum, editor_mode.info, function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw (err)
|
||||
}
|
||||
printe('添加id和idnum成功,请F5刷新编辑器');
|
||||
});
|
||||
} else {
|
||||
printe('请输入id和idnum');
|
||||
}
|
||||
}
|
||||
newIdIdnum.children[4].onclick = function () {
|
||||
editor.file.autoRegister(editor_mode.info, function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw (err)
|
||||
}
|
||||
printe('该列所有剩余项全部自动注册成功,请F5刷新编辑器');
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
editor.uifunctions.changeId_func = function () {
|
||||
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');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
editor.uifunctions.copyPasteEnemyItem_func = function () {
|
||||
var copyEnemyItem = document.getElementById('copyEnemyItem');
|
||||
var pasteEnemyItem = document.getElementById('pasteEnemyItem');
|
||||
|
||||
copyEnemyItem.onclick = function () {
|
||||
var cls = (editor_mode.info || {}).images;
|
||||
if (editor_mode.mode != 'enemyitem' || (cls != 'enemys' && cls != 'enemy48' && cls != 'items')) return;
|
||||
editor.uivalues.copyEnemyItem.type = cls;
|
||||
var id = editor_mode.info.id;
|
||||
if (cls == 'enemys' || cls == 'enemy48') {
|
||||
editor.uivalues.copyEnemyItem.data = core.clone(enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80[id]);
|
||||
printf("怪物属性复制成功");
|
||||
} else {
|
||||
editor.uivalues.copyEnemyItem.data = {};
|
||||
for (var x in items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a) {
|
||||
if (items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a[x][id] != null) {
|
||||
editor.uivalues.copyEnemyItem.data[x] = core.clone(items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a[x][id]);
|
||||
}
|
||||
}
|
||||
printf("道具属性复制成功");
|
||||
}
|
||||
}
|
||||
|
||||
pasteEnemyItem.onclick = function () {
|
||||
var cls = (editor_mode.info || {}).images;
|
||||
if (editor_mode.mode != 'enemyitem' || !cls || cls != editor.uivalues.copyEnemyItem.type) return;
|
||||
var id = editor_mode.info.id;
|
||||
if (cls == 'enemys' || cls == 'enemy48') {
|
||||
if (confirm("你确定要覆盖此怪物的全部属性么?这是个不可逆操作!")) {
|
||||
enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80[id] = core.clone(editor.uivalues.copyEnemyItem.data);
|
||||
editor.file.saveSetting('enemys', [], function (err) {
|
||||
if (err) printe(err);
|
||||
else printf("怪物属性粘贴成功\n请再重新选中该怪物方可查看更新后的表格。");
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if (confirm("你确定要覆盖此道具的全部属性么?这是个不可逆操作!")) {
|
||||
for (var x in editor.uivalues.copyEnemyItem.data) {
|
||||
items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a[x][id] = core.clone(editor.uivalues.copyEnemyItem.data[x]);
|
||||
}
|
||||
editor.file.saveSetting('items', [], function (err) {
|
||||
if (err) printe(err);
|
||||
else printf("道具属性粘贴成功\n请再重新选中该道具方可查看更新后的表格。");
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//////////////////// 楼层属性 //////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
editor.uifunctions.changeFloorId_func = function () {
|
||||
|
||||
editor.dom.changeFloorId.children[1].onclick = function () {
|
||||
var floorId = editor.dom.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');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//////////////////// 全塔属性 //////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//////////////////// 脚本编辑 //////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//////////////////// 追加素材 //////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
editor.uifunctions.fixCtx_func = function () {
|
||||
[editor.dom.sourceCtx, editor.dom.spriteCtx].forEach(function (ctx) {
|
||||
ctx.mozImageSmoothingEnabled = false;
|
||||
ctx.webkitImageSmoothingEnabled = false;
|
||||
ctx.msImageSmoothingEnabled = false;
|
||||
ctx.imageSmoothingEnabled = false;
|
||||
})
|
||||
}
|
||||
|
||||
editor.uifunctions.selectAppend_func = function () {
|
||||
|
||||
var selectAppend_str = [];
|
||||
["terrains", "animates", "enemys", "enemy48", "items", "npcs", "npc48", "autotile"].forEach(function (image) {
|
||||
selectAppend_str.push(["<option value='", image, "'>", image, '</option>\n'].join(''));
|
||||
});
|
||||
editor.dom.selectAppend.innerHTML = selectAppend_str.join('');
|
||||
editor.dom.selectAppend.onchange = function () {
|
||||
|
||||
var value = editor.dom.selectAppend.value;
|
||||
|
||||
if (value == 'autotile') {
|
||||
editor_mode.appendPic.imageName = 'autotile';
|
||||
for (var jj = 0; jj < 4; jj++) editor.dom.appendPicSelection.children[jj].style = 'display:none';
|
||||
if (editor_mode.appendPic.img) {
|
||||
editor.dom.sprite.style.width = (editor.dom.sprite.width = editor_mode.appendPic.img.width) / editor.uivalues.ratio + 'px';
|
||||
editor.dom.sprite.style.height = (editor.dom.sprite.height = editor_mode.appendPic.img.height) / editor.uivalues.ratio + 'px';
|
||||
editor.dom.spriteCtx.clearRect(0, 0, editor.dom.sprite.width, editor.dom.sprite.height);
|
||||
editor.dom.spriteCtx.drawImage(editor_mode.appendPic.img, 0, 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var ysize = editor.dom.selectAppend.value.endsWith('48') ? 48 : 32;
|
||||
editor_mode.appendPic.imageName = value;
|
||||
var img = core.material.images[value];
|
||||
editor_mode.appendPic.toImg = img;
|
||||
var num = ~~img.width / 32;
|
||||
editor_mode.appendPic.num = num;
|
||||
editor_mode.appendPic.index = 0;
|
||||
var selectStr = '';
|
||||
for (var ii = 0; ii < num; ii++) {
|
||||
editor.dom.appendPicSelection.children[ii].style = 'left:0;top:0;height:' + (ysize - 6) + 'px';
|
||||
selectStr += '{"x":0,"y":0},'
|
||||
}
|
||||
editor_mode.appendPic.selectPos = eval('[' + selectStr + ']');
|
||||
for (var jj = num; jj < 4; jj++) {
|
||||
editor.dom.appendPicSelection.children[jj].style = 'display:none';
|
||||
}
|
||||
editor.dom.sprite.style.width = (editor.dom.sprite.width = img.width) / editor.uivalues.ratio + 'px';
|
||||
editor.dom.sprite.style.height = (editor.dom.sprite.height = img.height + ysize) / editor.uivalues.ratio + 'px';
|
||||
editor.dom.spriteCtx.drawImage(img, 0, 0);
|
||||
}
|
||||
editor.dom.selectAppend.onchange();
|
||||
}
|
||||
|
||||
editor.uifunctions.selectFileBtn_func = function () {
|
||||
|
||||
var autoAdjust = function (image, callback) {
|
||||
var changed = false;
|
||||
|
||||
// Step 1: 检测白底
|
||||
var tempCanvas = document.createElement('canvas').getContext('2d');
|
||||
tempCanvas.canvas.width = image.width;
|
||||
tempCanvas.canvas.height = image.height;
|
||||
tempCanvas.mozImageSmoothingEnabled = false;
|
||||
tempCanvas.webkitImageSmoothingEnabled = false;
|
||||
tempCanvas.msImageSmoothingEnabled = false;
|
||||
tempCanvas.imageSmoothingEnabled = false;
|
||||
tempCanvas.drawImage(image, 0, 0);
|
||||
var imgData = tempCanvas.getImageData(0, 0, image.width, image.height);
|
||||
var trans = 0, white = 0, black = 0;
|
||||
for (var i = 0; i < image.width; i++) {
|
||||
for (var j = 0; j < image.height; j++) {
|
||||
var pixel = editor.util.getPixel(imgData, i, j);
|
||||
if (pixel[3] == 0) trans++;
|
||||
if (pixel[0] == 255 && pixel[1] == 255 && pixel[2] == 255 && pixel[3] == 255) white++;
|
||||
// if (pixel[0]==0 && pixel[1]==0 && pixel[2]==0 && pixel[3]==255) black++;
|
||||
}
|
||||
}
|
||||
if (white > black && white > trans * 10 && confirm("看起来这张图片是以纯白为底色,是否自动调整为透明底色?")) {
|
||||
for (var i = 0; i < image.width; i++) {
|
||||
for (var j = 0; j < image.height; j++) {
|
||||
var pixel = editor.util.getPixel(imgData, i, j);
|
||||
if (pixel[0] == 255 && pixel[1] == 255 && pixel[2] == 255 && pixel[3] == 255) {
|
||||
editor.util.setPixel(imgData, i, j, [0, 0, 0, 0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
tempCanvas.clearRect(0, 0, image.width, image.height);
|
||||
tempCanvas.putImageData(imgData, 0, 0);
|
||||
changed = true;
|
||||
}
|
||||
/*
|
||||
if (black>white && black>trans*10 && confirm("看起来这张图片是以纯黑为底色,是否自动调整为透明底色?")) {
|
||||
for (var i=0;i<image.width;i++) {
|
||||
for (var j=0;j<image.height;j++) {
|
||||
var pixel = editor.util.getPixel(imgData, i, j);
|
||||
if (pixel[0]==0 && pixel[1]==0 && pixel[2]==0 && pixel[3]==255) {
|
||||
editor.util.setPixel(imgData, i, j, [0,0,0,0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
tempCanvas.clearRect(0, 0, image.width, image.height);
|
||||
tempCanvas.putImageData(imgData, 0, 0);
|
||||
changed = true;
|
||||
}
|
||||
*/
|
||||
|
||||
// Step 2: 检测长宽比
|
||||
var ysize = editor.dom.selectAppend.value.endsWith('48') ? 48 : 32;
|
||||
if ((image.width % 32 != 0 || image.height % ysize != 0) && (image.width <= 128 && image.height <= ysize * 4)
|
||||
&& confirm("目标长宽不符合条件,是否自动进行调整?")) {
|
||||
var ncanvas = document.createElement('canvas').getContext('2d');
|
||||
ncanvas.canvas.width = 128;
|
||||
ncanvas.canvas.height = 4 * ysize;
|
||||
ncanvas.mozImageSmoothingEnabled = false;
|
||||
ncanvas.webkitImageSmoothingEnabled = false;
|
||||
ncanvas.msImageSmoothingEnabled = false;
|
||||
ncanvas.imageSmoothingEnabled = false;
|
||||
var w = image.width / 4, h = image.height / 4;
|
||||
for (var i = 0; i < 4; i++) {
|
||||
for (var j = 0; j < 4; j++) {
|
||||
ncanvas.drawImage(tempCanvas.canvas, i * w, j * h, w, h, i * 32 + (32 - w) / 2, j * ysize + (ysize - h) / 2, w, h);
|
||||
}
|
||||
}
|
||||
tempCanvas = ncanvas;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (!changed) {
|
||||
callback(image);
|
||||
}
|
||||
else {
|
||||
var nimg = new Image();
|
||||
nimg.onload = function () {
|
||||
callback(nimg);
|
||||
};
|
||||
nimg.src = tempCanvas.canvas.toDataURL();
|
||||
}
|
||||
}
|
||||
|
||||
editor.dom.selectFileBtn.onclick = function () {
|
||||
var loadImage = function (content, callback) {
|
||||
var image = new Image();
|
||||
try {
|
||||
image.onload = function () {
|
||||
callback(image);
|
||||
}
|
||||
image.src = content;
|
||||
}
|
||||
catch (e) {
|
||||
printe(e);
|
||||
}
|
||||
}
|
||||
core.readFile(function (content) {
|
||||
loadImage(content, function (image) {
|
||||
autoAdjust(image, function (image) {
|
||||
editor_mode.appendPic.img = image;
|
||||
editor_mode.appendPic.width = image.width;
|
||||
editor_mode.appendPic.height = image.height;
|
||||
|
||||
if (editor.dom.selectAppend.value == 'autotile') {
|
||||
for (var ii = 0; ii < 3; ii++) {
|
||||
var newsprite = editor.dom.appendPicCanvas.children[ii];
|
||||
newsprite.style.width = (newsprite.width = image.width) / editor.uivalues.ratio + 'px';
|
||||
newsprite.style.height = (newsprite.height = image.height) / editor.uivalues.ratio + 'px';
|
||||
}
|
||||
editor.dom.spriteCtx.clearRect(0, 0, editor.dom.sprite.width, editor.dom.sprite.height);
|
||||
editor.dom.spriteCtx.drawImage(image, 0, 0);
|
||||
}
|
||||
else {
|
||||
var ysize = editor.dom.selectAppend.value.endsWith('48') ? 48 : 32;
|
||||
for (var ii = 0; ii < 3; ii++) {
|
||||
var newsprite = editor.dom.appendPicCanvas.children[ii];
|
||||
newsprite.style.width = (newsprite.width = Math.floor(image.width / 32) * 32) / editor.uivalues.ratio + 'px';
|
||||
newsprite.style.height = (newsprite.height = Math.floor(image.height / ysize) * ysize) / editor.uivalues.ratio + 'px';
|
||||
}
|
||||
}
|
||||
|
||||
//画灰白相间的格子
|
||||
var bgc = editor.dom.bgCtx;
|
||||
var colorA = ["#f8f8f8", "#cccccc"];
|
||||
var colorIndex;
|
||||
var sratio = 4;
|
||||
for (var ii = 0; ii < image.width / 32 * sratio; ii++) {
|
||||
colorIndex = 1 - ii % 2;
|
||||
for (var jj = 0; jj < image.height / 32 * sratio; jj++) {
|
||||
bgc.fillStyle = colorA[colorIndex];
|
||||
colorIndex = 1 - colorIndex;
|
||||
bgc.fillRect(ii * 32 / sratio, jj * 32 / sratio, 32 / sratio, 32 / sratio);
|
||||
}
|
||||
}
|
||||
|
||||
//把导入的图片画出
|
||||
editor.dom.sourceCtx.drawImage(image, 0, 0);
|
||||
editor_mode.appendPic.sourceImageData = editor.dom.sourceCtx.getImageData(0, 0, image.width, image.height);
|
||||
|
||||
//重置临时变量
|
||||
editor.dom.selectAppend.onchange();
|
||||
});
|
||||
});
|
||||
}, null, 'image/*', 'img');
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
editor.uifunctions.changeColorInput_func = function () {
|
||||
var changeColorInput = document.getElementById('changeColorInput')
|
||||
changeColorInput.oninput = function () {
|
||||
var delta = (~~changeColorInput.value) * 30;
|
||||
var imgData = editor_mode.appendPic.sourceImageData;
|
||||
var nimgData = new ImageData(imgData.width, imgData.height);
|
||||
// ImageData .data 形如一维数组,依次排着每个点的 R(0~255) G(0~255) B(0~255) A(0~255)
|
||||
var convert = function (rgba, delta) {
|
||||
var rgbToHsl = editor.util.rgbToHsl
|
||||
var hue2rgb = editor.util.hue2rgb
|
||||
var hslToRgb = editor.util.hslToRgb
|
||||
//
|
||||
var hsl = rgbToHsl(rgba)
|
||||
hsl[0] = (hsl[0] + delta) % 360
|
||||
var nrgb = hslToRgb(hsl)
|
||||
nrgb.push(rgba[3])
|
||||
return nrgb
|
||||
}
|
||||
for (var x = 0; x < imgData.width; x++) {
|
||||
for (var y = 0; y < imgData.height; y++) {
|
||||
editor.util.setPixel(nimgData, x, y, convert(editor.util.getPixel(imgData, x, y), delta))
|
||||
}
|
||||
}
|
||||
editor.dom.sourceCtx.clearRect(0, 0, imgData.width, imgData.height);
|
||||
editor.dom.sourceCtx.putImageData(nimgData, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
editor.uifunctions.picClick_func = function () {
|
||||
|
||||
|
||||
var eToLoc = function (e) {
|
||||
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft
|
||||
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop
|
||||
var loc = {
|
||||
'x': scrollLeft + e.clientX + editor.dom.appendPicCanvas.scrollLeft - editor.dom.left1.offsetLeft - editor.dom.appendPicCanvas.offsetLeft,
|
||||
'y': scrollTop + e.clientY + editor.dom.appendPicCanvas.scrollTop - editor.dom.left1.offsetTop - editor.dom.appendPicCanvas.offsetTop,
|
||||
'size': 32,
|
||||
'ysize': editor.dom.selectAppend.value.endsWith('48') ? 48 : 32
|
||||
};
|
||||
return loc;
|
||||
}//返回可用的组件内坐标
|
||||
|
||||
var locToPos = function (loc) {
|
||||
var pos = { 'x': ~~(loc.x / loc.size), 'y': ~~(loc.y / loc.ysize), 'ysize': loc.ysize }
|
||||
return pos;
|
||||
}
|
||||
|
||||
editor.dom.picClick.onclick = function (e) {
|
||||
var loc = eToLoc(e);
|
||||
var pos = locToPos(loc);
|
||||
//console.log(e,loc,pos);
|
||||
var num = editor_mode.appendPic.num;
|
||||
var ii = editor_mode.appendPic.index;
|
||||
if (ii + 1 >= num) editor_mode.appendPic.index = ii + 1 - num;
|
||||
else editor_mode.appendPic.index++;
|
||||
editor_mode.appendPic.selectPos[ii] = pos;
|
||||
editor.dom.appendPicSelection.children[ii].style = [
|
||||
'left:', pos.x * 32, 'px;',
|
||||
'top:', pos.y * pos.ysize, 'px;',
|
||||
'height:', pos.ysize - 6, 'px;'
|
||||
].join('');
|
||||
}
|
||||
}
|
||||
|
||||
editor.uifunctions.appendConfirm_func = function () {
|
||||
|
||||
var appendRegister = document.getElementById('appendRegister');
|
||||
|
||||
var appendConfirm = document.getElementById('appendConfirm');
|
||||
appendConfirm.onclick = function () {
|
||||
|
||||
var confirmAutotile = function () {
|
||||
var image = editor_mode.appendPic.img;
|
||||
if (image.width % 96 != 0 || image.height != 128) {
|
||||
printe("不合法的Autotile图片!");
|
||||
return;
|
||||
}
|
||||
var imgData = editor.dom.sourceCtx.getImageData(0, 0, image.width, image.height);
|
||||
editor.dom.spriteCtx.putImageData(imgData, 0, 0);
|
||||
var imgbase64 = editor.dom.sprite.toDataURL().split(',')[1];
|
||||
|
||||
// Step 1: List文件名
|
||||
fs.readdir('./project/images', function (err, data) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw (err);
|
||||
}
|
||||
|
||||
// Step 2: 选择Autotile文件名
|
||||
var filename;
|
||||
for (var i = 1; ; ++i) {
|
||||
filename = 'autotile' + i;
|
||||
if (data.indexOf(filename + ".png") == -1) break;
|
||||
}
|
||||
|
||||
// Step 3: 写入文件
|
||||
fs.writeFile('./project/images/' + filename + ".png", imgbase64, 'base64', function (err, data) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw (err);
|
||||
}
|
||||
// Step 4: 自动注册
|
||||
editor.file.registerAutotile(filename, function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw (err);
|
||||
}
|
||||
printe('自动元件' + filename + '注册成功,请F5刷新编辑器');
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
if (editor.dom.selectAppend.value == 'autotile') {
|
||||
confirmAutotile();
|
||||
return;
|
||||
}
|
||||
|
||||
var ysize = editor.dom.selectAppend.value.endsWith('48') ? 48 : 32;
|
||||
for (var ii = 0, v; v = editor_mode.appendPic.selectPos[ii]; ii++) {
|
||||
// var imgData = editor.dom.sourceCtx.getImageData(v.x * 32, v.y * ysize, 32, ysize);
|
||||
// editor.dom.spriteCtx.putImageData(imgData, ii * 32, editor.dom.sprite.height - ysize);
|
||||
// editor.dom.spriteCtx.drawImage(editor_mode.appendPic.img, v.x * 32, v.y * ysize, 32, ysize, ii * 32, height, 32, ysize)
|
||||
|
||||
editor.dom.spriteCtx.drawImage(editor.dom.sourceCtx.canvas, v.x * 32, v.y * ysize, 32, ysize, 32 * ii, editor.dom.sprite.height - ysize, 32, ysize);
|
||||
}
|
||||
var dt = editor.dom.spriteCtx.getImageData(0, 0, editor.dom.sprite.width, editor.dom.sprite.height);
|
||||
var imgbase64 = editor.dom.sprite.toDataURL('image/png');
|
||||
var imgName = editor_mode.appendPic.imageName;
|
||||
fs.writeFile('./project/images/' + imgName + '.png', imgbase64.split(',')[1], 'base64', function (err, data) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw (err)
|
||||
}
|
||||
var currHeight = editor.dom.sprite.height;
|
||||
editor.dom.sprite.style.height = (editor.dom.sprite.height = (currHeight + ysize)) + "px";
|
||||
editor.dom.spriteCtx.putImageData(dt, 0, 0);
|
||||
core.material.images[imgName].src = imgbase64;
|
||||
editor.widthsX[imgName][3] = currHeight;
|
||||
if (appendRegister && appendRegister.checked) {
|
||||
editor.file.autoRegister({images: imgName}, function (e) {
|
||||
if (e) {
|
||||
printe(e);
|
||||
throw e;
|
||||
}
|
||||
printf('追加素材并自动注册成功!你可以继续追加其他素材,最后再刷新以使用。');
|
||||
});
|
||||
} else {
|
||||
printf('追加素材成功!你可以继续追加其他素材,最后再刷新以使用。');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var quickAppendConfirm = document.getElementById('quickAppendConfirm');
|
||||
quickAppendConfirm.onclick = function () {
|
||||
var value = editor.dom.selectAppend.value;
|
||||
if (value != 'enemys' && value != 'enemy48' && value != 'npcs' && value != 'npc48')
|
||||
return printe("只有怪物或NPC才能快速导入!");
|
||||
var ysize = value.endsWith('48') ? 48 : 32;
|
||||
if (editor.dom.sourceCtx.canvas.width != 128 || editor.dom.sourceCtx.canvas.height != 4 * ysize)
|
||||
return printe("只有 4*4 的素材图片才可以快速导入!");
|
||||
|
||||
var dt = editor.dom.spriteCtx.getImageData(0, 0, editor.dom.sprite.width, editor.dom.sprite.height);
|
||||
editor.dom.sprite.style.height = (editor.dom.sprite.height = (editor.dom.sprite.height + 3 * ysize)) + "px";
|
||||
editor.dom.spriteCtx.putImageData(dt, 0, 0);
|
||||
if (editor.dom.sprite.width == 64) { // 两帧
|
||||
editor.dom.spriteCtx.drawImage(editor.dom.sourceCtx.canvas, 32, 0, 64, 4 * ysize, 0, editor.dom.sprite.height - 4 * ysize, 64, 4 * ysize);
|
||||
} else { // 四帧
|
||||
editor.dom.spriteCtx.drawImage(editor.dom.sourceCtx.canvas, 0, 0, 128, 4 * ysize, 0, editor.dom.sprite.height - 4 * ysize, 128, 4 * ysize);
|
||||
}
|
||||
|
||||
dt = editor.dom.spriteCtx.getImageData(0, 0, editor.dom.sprite.width, editor.dom.sprite.height);
|
||||
var imgbase64 = editor.dom.sprite.toDataURL('image/png');
|
||||
var imgName = editor_mode.appendPic.imageName;
|
||||
fs.writeFile('./project/images/' + imgName + '.png', imgbase64.split(',')[1], 'base64', function (err, data) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw (err)
|
||||
}
|
||||
var currHeight = editor.dom.sprite.height;
|
||||
editor.dom.sprite.style.height = (editor.dom.sprite.height = (currHeight + ysize)) + "px";
|
||||
editor.dom.spriteCtx.putImageData(dt, 0, 0);
|
||||
core.material.images[imgName].src = imgbase64;
|
||||
editor.widthsX[imgName][3] = currHeight;
|
||||
if (appendRegister && appendRegister.checked) {
|
||||
editor.file.autoRegister({images: imgName}, function (e) {
|
||||
if (e) {
|
||||
printe(e);
|
||||
throw e;
|
||||
}
|
||||
printf('快速追加素材并自动注册成功!你可以继续追加其他素材,最后再刷新以使用。');
|
||||
})
|
||||
} else {
|
||||
printf('快速追加素材成功!你可以继续追加其他素材,最后再刷新以使用。');
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//////////////////// 公共事件 //////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//////////////////// 插件编写 //////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
904
_server/editor_file_unsorted.js
Normal file
@ -0,0 +1,904 @@
|
||||
editor_file = function (editor, callback) {
|
||||
|
||||
var editor_file = new editor_file_proto();
|
||||
editor.file=editor_file;
|
||||
|
||||
editor.file.loadCommentjs(callback);
|
||||
|
||||
editor.file.saveFloorFile = function (callback) {
|
||||
//callback(err:String)
|
||||
checkCallback(callback);
|
||||
/* if (!isset(editor.currentFloorId) || !isset(editor.currentFloorData)) {
|
||||
callback('未选中文件或无数据');
|
||||
} */
|
||||
var filename = 'project/floors/' + editor.currentFloorId + '.js';
|
||||
var datastr = ['main.floors.', editor.currentFloorId, '=\n'];
|
||||
|
||||
if (core.floorIds.indexOf(editor.currentFloorId) >= 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
|
||||
})
|
||||
});
|
||||
editor.currentFloorData[name]=mapArray;
|
||||
}
|
||||
}
|
||||
editor.file.saveFloor(editor.currentFloorData, callback)
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
editor.file.saveNewFile = function (saveFilename, callback) {
|
||||
//saveAsFilename不含'/'不含'.js'
|
||||
checkCallback(callback);
|
||||
var currData=editor.currentFloorData;
|
||||
var saveStatus = document.getElementById('newMapStatus').checked;
|
||||
|
||||
var title = saveStatus?currData.title:"新建楼层";
|
||||
var name = saveStatus?currData.name:"0";
|
||||
if (/^mt\d+$/i.test(saveFilename)) {
|
||||
name = saveFilename.substring(2);
|
||||
title = "主塔 "+name+" 层";
|
||||
}
|
||||
|
||||
var width = parseInt(document.getElementById('newMapWidth').value);
|
||||
var height = parseInt(document.getElementById('newMapHeight').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: 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.currentFloorId = saveFilename;
|
||||
editor.file.saveFloorFile(callback);
|
||||
}
|
||||
editor.file.saveNewFiles = function (floorIdList, from, to, callback) {
|
||||
checkCallback(callback);
|
||||
var currData=editor.currentFloorData;
|
||||
var saveStatus = document.getElementById('newMapsStatus').checked;
|
||||
|
||||
var calValue = function (text, i) {
|
||||
return text.replace(/\${(.*?)}/g, function (word, value) {
|
||||
return eval(value);
|
||||
});
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
var filenames = floorIdList.map(function (v) {return "project/floors/"+v+".js";});
|
||||
var datas = [];
|
||||
for (var i=from;i<=to;i++) {
|
||||
var datastr = ['main.floors.', floorIdList[i-from], '=\n{'];
|
||||
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,
|
||||
},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];
|
||||
else {
|
||||
if (t=='map') {
|
||||
datastr = datastr.concat(['\n"', t, '": [\n', editor.file.formatMap(data[t]), '\n],']);
|
||||
}
|
||||
else {
|
||||
datastr = datastr.concat(['\n"', t, '": ', JSON.stringify(data[t], null, 4), ',']);
|
||||
}
|
||||
}
|
||||
});
|
||||
datastr = datastr.concat(['\n}']);
|
||||
datastr = datastr.join('');
|
||||
datas.push(encode(datastr));
|
||||
}
|
||||
editor.file.alertWhenCompress();
|
||||
fs.writeMultiFiles(filenames, datas, function (err, data) {
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
|
||||
//callback(err:String)
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
editor.file.autoRegister = function (info, callback) {
|
||||
|
||||
var iconActions = [];
|
||||
var mapActions = [];
|
||||
var templateActions = [];
|
||||
|
||||
var image = info.images;
|
||||
var bindFaceIds = false;
|
||||
|
||||
if (image=='autotile') {
|
||||
callback('不能对自动元件进行自动注册!');
|
||||
return;
|
||||
}
|
||||
if (image=='npc48' && confirm("你想绑定npc48的朝向么?\n如果是,则会连续四个一组的对npc48的faceIds进行自动绑定。")) {
|
||||
bindFaceIds = true;
|
||||
}
|
||||
var c=image.toUpperCase().charAt(0);
|
||||
|
||||
// terrains id
|
||||
var terrainsId = [];
|
||||
Object.keys(core.material.icons.terrains).forEach(function (id) {
|
||||
terrainsId[core.material.icons.terrains[id]]=id;
|
||||
})
|
||||
|
||||
var allIds = [];
|
||||
editor.ids.forEach(function (v) {
|
||||
if (v.images==image) {
|
||||
allIds[v.y]=v;
|
||||
}
|
||||
})
|
||||
|
||||
var per_height = image.endsWith('48')?48:32;
|
||||
|
||||
var faceIds = []; // down, left, right, up
|
||||
|
||||
var idnum=300;
|
||||
for (var y=0; y<editor.widthsX[image][3]/per_height;y++) {
|
||||
if (allIds[y] != null) {
|
||||
faceIds.push(allIds[y]);
|
||||
continue;
|
||||
}
|
||||
while (editor.core.maps.blocksInfo[idnum]) idnum++;
|
||||
|
||||
// get id num
|
||||
var id = c+idnum;
|
||||
|
||||
if (image=='terrains' && terrainsId[y] != null) {
|
||||
id=terrainsId[y];
|
||||
}
|
||||
else {
|
||||
iconActions.push(["add", "['" + image + "']['" + id + "']", y])
|
||||
}
|
||||
mapActions.push(["add", "['" + idnum + "']", {'cls': image, 'id': id}]);
|
||||
faceIds.push({idnum: idnum, id: id});
|
||||
if (image=='items')
|
||||
templateActions.push(["add", "['items']['" + id + "']", editor.file.comment._data.items_template]);
|
||||
else if (image.indexOf('enemy')==0)
|
||||
templateActions.push(["add", "['" + id + "']", editor.file.comment._data.enemys_template]);
|
||||
idnum++;
|
||||
}
|
||||
|
||||
if (bindFaceIds) {
|
||||
for (var i = 0; i < faceIds.length - 3; i+=4) {
|
||||
var down = faceIds[i], left = faceIds[i+1], right = faceIds[i+2], up = faceIds[i+3];
|
||||
var obj = {down: down.id, left: left.id, right: right.id, up: up.id};
|
||||
mapActions.push(["add", "['" + down.idnum + "']['faceIds']", obj]);
|
||||
mapActions.push(["add", "['" + left.idnum + "']['faceIds']", obj]);
|
||||
mapActions.push(["add", "['" + right.idnum + "']['faceIds']", obj]);
|
||||
mapActions.push(["add", "['" + up.idnum + "']['faceIds']", obj]);
|
||||
}
|
||||
}
|
||||
|
||||
if (mapActions.length==0) {
|
||||
callback("没有要注册的项!");
|
||||
return;
|
||||
}
|
||||
|
||||
var templist = [];
|
||||
var tempcallback = function (err) {
|
||||
templist.push(err);
|
||||
if (templist.length == 3) {
|
||||
if (templist[0] != null || templist[1] != null || templist[2] != null)
|
||||
callback((templist[0] || '') + '\n' + (templist[1] || '') + '\n' + (templist[2] || ''));
|
||||
//这里如果一个成功一个失败会出严重bug
|
||||
else
|
||||
callback(null);
|
||||
}
|
||||
}
|
||||
if (iconActions.length>0)
|
||||
saveSetting('icons', iconActions, tempcallback);
|
||||
else tempcallback(null);
|
||||
|
||||
saveSetting('maps', mapActions, tempcallback);
|
||||
|
||||
if (image=='items')
|
||||
saveSetting('items', templateActions, tempcallback);
|
||||
else if (image.indexOf('enemy')==0)
|
||||
saveSetting('enemys', templateActions, tempcallback);
|
||||
else tempcallback(null);
|
||||
}
|
||||
|
||||
editor.file.registerAutotile = function (filename, callback) {
|
||||
var idnum = 140;
|
||||
while (editor.core.maps.blocksInfo[idnum]) idnum++;
|
||||
|
||||
var iconActions = [];
|
||||
var mapActions = [];
|
||||
|
||||
iconActions.push(["add", "['autotile']['" + filename + "']", 0]);
|
||||
mapActions.push(["add", "['" + idnum + "']", {'cls': 'autotile', 'id': filename, 'noPass': true}]);
|
||||
|
||||
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('icons', iconActions, tempcallback);
|
||||
saveSetting('maps', mapActions, tempcallback);
|
||||
}
|
||||
|
||||
editor.file.changeIdAndIdnum = function (id, idnum, info, callback) {
|
||||
checkCallback(callback);
|
||||
|
||||
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 (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);
|
||||
|
||||
}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) {
|
||||
/*actionList:[
|
||||
["change","['items']['name']","红宝石的新名字"],
|
||||
["add","['items']['新的和name同级的属性']",123],
|
||||
["change","['itemEffectTip']","',攻击力+'+editor.core.values.redJewel"],
|
||||
]
|
||||
为[]时只查询不修改
|
||||
*/
|
||||
checkCallback(callback);
|
||||
if (isset(actionList) && actionList.length > 0) {
|
||||
actionList.forEach(function (value) {
|
||||
var tempindex = value[1].indexOf(']') + 1;
|
||||
value[1] = [value[1].slice(0, tempindex), "['" + id + "']", value[1].slice(tempindex)].join('');
|
||||
});
|
||||
saveSetting('items', actionList, function (err) {
|
||||
callback([err]);
|
||||
});
|
||||
} else {
|
||||
callback([
|
||||
(function () {
|
||||
var locObj_ = {};
|
||||
Object.keys(editor.file.comment._data.items._data).forEach(function (v) {
|
||||
if (isset(editor.core.items[v][id]) && v !== 'items')
|
||||
locObj_[v] = editor.core.items[v][id];
|
||||
else
|
||||
locObj_[v] = null;
|
||||
});
|
||||
locObj_['items'] = (function () {
|
||||
var locObj = Object.assign({}, editor.core.items.items[id]);
|
||||
Object.keys(editor.file.comment._data.items._data.items._data).forEach(function (v) {
|
||||
if (!isset(editor.core.items.items[id][v]))
|
||||
locObj[v] = null;
|
||||
});
|
||||
return locObj;
|
||||
})();
|
||||
return locObj_;
|
||||
})(),
|
||||
editor.file.comment._data.items,
|
||||
null]);
|
||||
}
|
||||
//只有items.cls是items的才有itemEffect和itemEffectTip,keys和constants和tools只有items
|
||||
}
|
||||
//callback([obj,commentObj,err:String])
|
||||
editor.file.editEnemy = function (id, actionList, callback) {
|
||||
/*actionList:[
|
||||
["change","['name']","初级巫师的新名字"],
|
||||
["add","['新的和name同级的属性']",123],
|
||||
["change","['bomb']",null],
|
||||
]
|
||||
为[]时只查询不修改
|
||||
*/
|
||||
checkCallback(callback);
|
||||
if (isset(actionList) && actionList.length > 0) {
|
||||
actionList.forEach(function (value) {
|
||||
value[1] = "['" + id + "']" + value[1];
|
||||
});
|
||||
saveSetting('enemys', actionList, function (err) {
|
||||
callback([err]);
|
||||
});
|
||||
} else {
|
||||
callback([
|
||||
(function () {
|
||||
var locObj = Object.assign({}, editor.core.enemys.enemys[id]);
|
||||
Object.keys(editor.file.comment._data.enemys._data).forEach(function (v) {
|
||||
if (!isset(editor.core.enemys.enemys[id][v]))
|
||||
/* locObj[v]=editor.core.enemys.enemys[id][v];
|
||||
else */
|
||||
locObj[v] = null;
|
||||
});
|
||||
return locObj;
|
||||
})(),
|
||||
editor.file.comment._data.enemys,
|
||||
null]);
|
||||
}
|
||||
}
|
||||
//callback([obj,commentObj,err:String])
|
||||
|
||||
editor.file.editMapBlocksInfo = function (idnum, actionList, callback) {
|
||||
/*actionList:[
|
||||
["change","['events']",["\t[老人,magician]领域、夹击。\n请注意领域怪需要设置value为伤害数值,可参见样板中初级巫师的写法。"]],
|
||||
["change","['afterBattle']",null],
|
||||
]
|
||||
为[]时只查询不修改
|
||||
*/
|
||||
checkCallback(callback);
|
||||
if (isset(actionList) && actionList.length > 0) {
|
||||
var tempmap=[];
|
||||
for(var ii=0;ii<actionList.length;ii++){
|
||||
var value=actionList[ii];
|
||||
// 是tilesets 且未定义 且在这里是第一次定义
|
||||
if(idnum>=editor.core.icons.tilesetStartOffset && !isset(editor.core.maps.blocksInfo[idnum]) && tempmap.indexOf(idnum)===-1){
|
||||
actionList.splice(ii,0,["add","['" + idnum + "']",{"cls": "tileset", "id": "X"+idnum, "noPass": true}]);
|
||||
tempmap.push(idnum);
|
||||
ii++;
|
||||
}
|
||||
value[1] = "['" + idnum + "']" + value[1];
|
||||
}
|
||||
saveSetting('maps', actionList, function (err) {
|
||||
callback([err]);
|
||||
});
|
||||
} else {
|
||||
callback([
|
||||
(function () {
|
||||
var sourceobj=editor.core.maps.blocksInfo[idnum];
|
||||
if(!isset(sourceobj) && idnum>=editor.core.icons.tilesetStartOffset)sourceobj={"cls": "tileset", "id": "X"+idnum, "noPass": true}
|
||||
var locObj = Object.assign({}, sourceobj);
|
||||
Object.keys(editor.file.comment._data.maps._data).forEach(function (v) {
|
||||
if (!isset(sourceobj[v]))
|
||||
locObj[v] = null;
|
||||
});
|
||||
locObj.idnum = idnum;
|
||||
return locObj;
|
||||
})(),
|
||||
editor.file.comment._data.maps,
|
||||
null]);
|
||||
}
|
||||
}
|
||||
//callback([obj,commentObj,err:String])
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
editor.file.editLoc = function (x, y, actionList, callback) {
|
||||
/*actionList:[
|
||||
["change","['events']",["\t[老人,magician]领域、夹击。\n请注意领域怪需要设置value为伤害数值,可参见样板中初级巫师的写法。"]],
|
||||
["change","['afterBattle']",null],
|
||||
]
|
||||
为[]时只查询不修改
|
||||
*/
|
||||
checkCallback(callback);
|
||||
if (isset(actionList) && actionList.length > 0) {
|
||||
actionList.forEach(function (value) {
|
||||
if(/\['autoEvent'\]\['\d+'\]$/.test(value[1]))value[1]=value[1].replace(/\['\d+'\]$/,function(v){return "['" + x + "," + y + "']"+v})
|
||||
else value[1] = value[1] + "['" + x + "," + y + "']";
|
||||
});
|
||||
saveSetting('floorloc', actionList, function (err) {
|
||||
callback([err]);
|
||||
});
|
||||
} else {
|
||||
callback([
|
||||
(function () {
|
||||
var locObj = {};
|
||||
Object.keys(editor.file.comment._data.floors._data.loc._data).forEach(function (v) {
|
||||
if (isset(editor.currentFloorData[v][x + ',' + y]))
|
||||
locObj[v] = editor.currentFloorData[v][x + ',' + y];
|
||||
else
|
||||
locObj[v] = null;
|
||||
});
|
||||
return locObj;
|
||||
})(),
|
||||
editor.file.comment._data.floors._data.loc,
|
||||
null]);
|
||||
}
|
||||
|
||||
}
|
||||
//callback([obj,commentObj,err:String])
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
editor.file.editFloor = function (actionList, callback) {
|
||||
/*actionList:[
|
||||
["change","['title']",'样板 3 层'],
|
||||
["change","['color']",null],
|
||||
]
|
||||
为[]时只查询不修改
|
||||
*/
|
||||
checkCallback(callback);
|
||||
if (isset(actionList) && actionList.length > 0) {
|
||||
saveSetting('floors', actionList, function (err) {
|
||||
callback([err]);
|
||||
});
|
||||
} else {
|
||||
callback([
|
||||
(function () {
|
||||
var locObj = Object.assign({}, editor.currentFloorData);
|
||||
Object.keys(editor.file.comment._data.floors._data.floor._data).forEach(function (v) {
|
||||
if (!isset(editor.currentFloorData[v]))
|
||||
/* locObj[v]=editor.currentFloorData[v];
|
||||
else */
|
||||
locObj[v] = null;
|
||||
});
|
||||
Object.keys(editor.file.comment._data.floors._data.loc._data).forEach(function (v) {
|
||||
delete(locObj[v]);
|
||||
});
|
||||
delete(locObj.map);
|
||||
delete(locObj.bgmap);
|
||||
delete(locObj.fgmap);
|
||||
return locObj;
|
||||
})(),
|
||||
editor.file.comment._data.floors._data.floor,
|
||||
null]);
|
||||
}
|
||||
}
|
||||
//callback([obj,commentObj,err:String])
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
editor.file.editTower = function (actionList, callback) {
|
||||
/*actionList:[
|
||||
["change","['firstData']['version']",'Ver 1.0.1 (Beta)'],
|
||||
["change","['values']['lavaDamage']",200],
|
||||
]
|
||||
为[]时只查询不修改
|
||||
*/
|
||||
var data_obj = data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d;
|
||||
checkCallback(callback);
|
||||
if (isset(actionList) && actionList.length > 0) {
|
||||
saveSetting('data', actionList, function (err) {
|
||||
callback([err]);
|
||||
});
|
||||
} else {
|
||||
callback([
|
||||
(function () {
|
||||
//var locObj=Object.assign({'main':{}},editor.core.data);
|
||||
var locObj = Object.assign({}, data_obj, {'main': {}});
|
||||
Object.keys(editor.file.dataComment._data.main._data).forEach(function (v) {
|
||||
if (isset(editor.main[v]))
|
||||
locObj.main[v] = data_obj.main[v];
|
||||
else
|
||||
locObj.main[v] = null;
|
||||
});
|
||||
return locObj;
|
||||
})(),
|
||||
editor.file.dataComment,
|
||||
null]);
|
||||
}
|
||||
}
|
||||
//callback([obj,commentObj,err:String])
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
var fmap = {};
|
||||
var fjson = JSON.stringify(functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a, function (k, v) {
|
||||
if (v instanceof Function) {
|
||||
var id_ = editor.util.guid();
|
||||
fmap[id_] = v.toString();
|
||||
return id_;
|
||||
} else return v
|
||||
}, 4);
|
||||
var fobj = JSON.parse(fjson);
|
||||
editor.file.functionsMap = fmap;
|
||||
editor.file.functionsJSON = fjson;
|
||||
var buildlocobj = function (locObj) {
|
||||
for (var key in locObj) {
|
||||
if (typeof(locObj[key]) !== typeof('')) buildlocobj(locObj[key]);
|
||||
else locObj[key] = fmap[locObj[key]];
|
||||
}
|
||||
};
|
||||
|
||||
editor.file.editFunctions = function (actionList, callback) {
|
||||
/*actionList:[
|
||||
["change","['events']['afterChangeLight']","function(x,y){console.log(x,y)}"],
|
||||
["change","['ui']['drawAbout']","function(){...}"],
|
||||
]
|
||||
为[]时只查询不修改
|
||||
*/
|
||||
checkCallback(callback);
|
||||
if (isset(actionList) && actionList.length > 0) {
|
||||
saveSetting('functions', actionList, function (err) {
|
||||
callback([err]);
|
||||
});
|
||||
} else {
|
||||
callback([
|
||||
(function () {
|
||||
var locObj = JSON.parse(fjson);
|
||||
buildlocobj(locObj);
|
||||
return locObj;
|
||||
})(),
|
||||
editor.file.functionsComment,
|
||||
null]);
|
||||
}
|
||||
}
|
||||
//callback([obj,commentObj,err:String])
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
editor.file.editCommonEvent = function (actionList, callback) {
|
||||
/*actionList:[
|
||||
["change","['test']",['123']],
|
||||
]
|
||||
为[]时只查询不修改
|
||||
*/
|
||||
var data_obj = events_c12a15a8_c380_4b28_8144_256cba95f760.commonEvent;
|
||||
checkCallback(callback);
|
||||
if (isset(actionList) && actionList.length > 0) {
|
||||
actionList.forEach(function (value) {
|
||||
value[1] = "['commonEvent']" + value[1];
|
||||
});
|
||||
saveSetting('events', actionList, function (err) {
|
||||
callback([err]);
|
||||
});
|
||||
} else {
|
||||
callback([
|
||||
Object.assign({},data_obj),
|
||||
editor.file.eventsComment._data.commonEvent,
|
||||
null]);
|
||||
}
|
||||
}
|
||||
//callback([obj,commentObj,err:String])
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
var plmap = {};
|
||||
var pljson = JSON.stringify(plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1, function (k, v) {
|
||||
if (v instanceof Function) {
|
||||
var id_ = editor.util.guid();
|
||||
plmap[id_] = v.toString();
|
||||
return id_;
|
||||
} else if(v===null){
|
||||
var id_ = editor.util.guid();
|
||||
plmap[id_] = null;
|
||||
return id_;
|
||||
} return v
|
||||
}, 4);
|
||||
var plobj = JSON.parse(pljson);
|
||||
editor.file.pluginsMap = plmap;
|
||||
editor.file.pluginsObj = plobj;
|
||||
var buildpllocobj = function (locObj) {
|
||||
for (var key in locObj) {
|
||||
if (typeof(locObj[key]) !== typeof('')) buildpllocobj(locObj[key]);
|
||||
else locObj[key] = plmap[locObj[key]];
|
||||
}
|
||||
};
|
||||
|
||||
editor.file.editPlugins = function (actionList, callback) {
|
||||
/*actionList:[
|
||||
["change","['test']","function(x,y){console.log(x,y)}"],
|
||||
]
|
||||
为[]时只查询不修改
|
||||
*/
|
||||
checkCallback(callback);
|
||||
if (isset(actionList) && actionList.length > 0) {
|
||||
saveSetting('plugins', actionList, function (err) {
|
||||
callback([err]);
|
||||
});
|
||||
} else {
|
||||
callback([
|
||||
(function () {
|
||||
var locObj = JSON.parse(JSON.stringify(plobj));
|
||||
buildpllocobj(locObj);
|
||||
return locObj;
|
||||
})(),
|
||||
editor.file.pluginsComment,
|
||||
null]);
|
||||
}
|
||||
}
|
||||
//callback([obj,commentObj,err:String])
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
var isset = function (val) {
|
||||
if (val == undefined || val == null) {
|
||||
return false;
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
var checkCallback=function(callback){
|
||||
if (!isset(callback)) {
|
||||
printe('未设置callback');
|
||||
throw('未设置callback')
|
||||
}
|
||||
}
|
||||
|
||||
var encode = editor.util.encode64;
|
||||
|
||||
var alertWhenCompress = function(){
|
||||
if(editor.useCompress===true){
|
||||
editor.useCompress='alerted';
|
||||
setTimeout("alert('当前游戏使用的是压缩文件,修改完成后请使用启动服务.exe->Js代码压缩工具重新压缩,或者把main.js的useCompress改成false来使用原始文件')",1000)
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
editor.file.alertWhenCompress();
|
||||
|
||||
if (file == 'icons') {
|
||||
actionList.forEach(function (value) {
|
||||
eval("icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1" + value[1] + '=' + JSON.stringify(value[2]));
|
||||
});
|
||||
var datastr = 'var icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1 = \n';
|
||||
datastr += JSON.stringify(icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1, null, '\t');
|
||||
fs.writeFile('project/icons.js', encode(datastr), 'base64', function (err, data) {
|
||||
callback(err);
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (file == 'maps') {
|
||||
actionList.forEach(function (value) {
|
||||
eval("maps_90f36752_8815_4be8_b32b_d7fad1d0542e" + value[1] + '=' + JSON.stringify(value[2]));
|
||||
});
|
||||
var datastr = 'var maps_90f36752_8815_4be8_b32b_d7fad1d0542e = \n';
|
||||
//datastr+=JSON.stringify(maps_90f36752_8815_4be8_b32b_d7fad1d0542e,null,4);
|
||||
|
||||
var emap = {};
|
||||
var estr = JSON.stringify(maps_90f36752_8815_4be8_b32b_d7fad1d0542e, function (k, v) {
|
||||
if (v.id != null) {
|
||||
var id_ = editor.util.guid();
|
||||
emap[id_] = JSON.stringify(v);
|
||||
return id_;
|
||||
} else return v
|
||||
}, '\t');
|
||||
for (var id_ in emap) {
|
||||
estr = estr.replace('"' + id_ + '"', emap[id_])
|
||||
}
|
||||
datastr += estr;
|
||||
|
||||
fs.writeFile('project/maps.js', encode(datastr), 'base64', function (err, data) {
|
||||
callback(err);
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (file == 'items') {
|
||||
actionList.forEach(function (value) {
|
||||
eval("items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a" + value[1] + '=' + JSON.stringify(value[2]));
|
||||
});
|
||||
var datastr = 'var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a = \n';
|
||||
datastr += JSON.stringify(items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a, null, '\t');
|
||||
fs.writeFile('project/items.js', encode(datastr), 'base64', function (err, data) {
|
||||
callback(err);
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (file == 'enemys') {
|
||||
actionList.forEach(function (value) {
|
||||
eval("enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80" + value[1] + '=' + JSON.stringify(value[2]));
|
||||
});
|
||||
var datastr = 'var enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80 = \n';
|
||||
var emap = {};
|
||||
var estr = JSON.stringify(enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80, function (k, v) {
|
||||
if (v.hp != null) {
|
||||
var id_ = editor.util.guid();
|
||||
emap[id_] = JSON.stringify(v);
|
||||
return id_;
|
||||
} else return v
|
||||
}, '\t');
|
||||
for (var id_ in emap) {
|
||||
estr = estr.replace('"' + id_ + '"', emap[id_])
|
||||
}
|
||||
datastr += estr;
|
||||
fs.writeFile('project/enemys.js', encode(datastr), 'base64', function (err, data) {
|
||||
callback(err);
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (file == 'data') {
|
||||
actionList.forEach(function (value) {
|
||||
eval("data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d" + value[1] + '=' + JSON.stringify(value[2]));
|
||||
});
|
||||
if (data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.main.floorIds.indexOf(data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.floorId) < 0)
|
||||
data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.floorId = data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.main.floorIds[0];
|
||||
var datastr = 'var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = \n';
|
||||
datastr += JSON.stringify(data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d, null, '\t');
|
||||
fs.writeFile('project/data.js', encode(datastr), 'base64', function (err, data) {
|
||||
callback(err);
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (file == 'functions') {
|
||||
actionList.forEach(function (value) {
|
||||
eval("fmap[fobj" + value[1] + ']=' + JSON.stringify(value[2]));
|
||||
});
|
||||
var fraw = fjson;
|
||||
for (var id_ in fmap) {
|
||||
fraw = fraw.replace('"' + id_ + '"', fmap[id_])
|
||||
}
|
||||
var datastr = 'var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = \n';
|
||||
datastr += fraw;
|
||||
fs.writeFile('project/functions.js', encode(datastr), 'base64', function (err, data) {
|
||||
callback(err);
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (file == 'floorloc') {
|
||||
actionList.forEach(function (value) {
|
||||
// 检测null/undefined
|
||||
if(/\['autoEvent'\]\['\d+,\d+'\]\['\d+'\]$/.test(value[1])){
|
||||
var tempvalue=value[1].replace(/\['\d+'\]$/,'')
|
||||
tempvalue="editor.currentFloorData" +tempvalue
|
||||
tempvalue=tempvalue+'='+tempvalue+'||{}'
|
||||
eval(tempvalue)
|
||||
}
|
||||
if (value[2]==null && value[0]!=='add')
|
||||
eval("delete editor.currentFloorData" + value[1]);
|
||||
else
|
||||
eval("editor.currentFloorData" + value[1] + '=' + JSON.stringify(value[2]));
|
||||
});
|
||||
editor.file.saveFloorFile(callback);
|
||||
return;
|
||||
}
|
||||
if (file == 'floors') {
|
||||
actionList.forEach(function (value) {
|
||||
eval("editor.currentFloorData" + value[1] + '=' + JSON.stringify(value[2]));
|
||||
});
|
||||
editor.file.saveFloorFile(callback);
|
||||
return;
|
||||
}
|
||||
if (file == 'events') {
|
||||
actionList.forEach(function (value) {
|
||||
eval("events_c12a15a8_c380_4b28_8144_256cba95f760" + value[1] + '=' + JSON.stringify(value[2]));
|
||||
});
|
||||
var datastr = 'var events_c12a15a8_c380_4b28_8144_256cba95f760 = \n';
|
||||
datastr += JSON.stringify(events_c12a15a8_c380_4b28_8144_256cba95f760, null, '\t');
|
||||
fs.writeFile('project/events.js', encode(datastr), 'base64', function (err, data) {
|
||||
callback(err);
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (file == 'plugins') {
|
||||
actionList.forEach(function (value) {
|
||||
if(value[0]==='add'){
|
||||
eval("plobj" + value[1] + '=' + JSON.stringify(value[2]));
|
||||
} else {
|
||||
eval("plmap[plobj" + value[1] + ']=' + JSON.stringify(value[2]));
|
||||
}
|
||||
});
|
||||
var plraw = JSON.stringify(plobj,null,4);
|
||||
for (var id_ in plmap) {
|
||||
plraw = plraw.replace('"' + id_ + '"', plmap[id_])
|
||||
}
|
||||
var datastr = 'var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = \n';
|
||||
datastr += plraw;
|
||||
fs.writeFile('project/plugins.js', encode(datastr), 'base64', function (err, data) {
|
||||
callback(err);
|
||||
});
|
||||
return;
|
||||
}
|
||||
callback('出错了,要设置的文件名不识别');
|
||||
}
|
||||
|
||||
editor.file.saveSetting = saveSetting;
|
||||
|
||||
return editor_file;
|
||||
}
|
||||
//editor_file = editor_file(editor);
|
||||
@ -1,37 +1,83 @@
|
||||
editor_game_wrapper = function (editor, main, core) {
|
||||
// 原则上重构后只有此文件允许`\s(main|core)`形式的调用, 以及其初始化 editor_game_wrapper(editor, main, core)
|
||||
|
||||
editor_game = function () {
|
||||
this.replacerRecord = {}
|
||||
}
|
||||
|
||||
|
||||
//////////////////// 修改数据相关 ////////////////////
|
||||
// 三个 replacer 和 replacerRecord 暂时放在此处
|
||||
|
||||
editor_game.prototype.replacerForLoading = function (_key, value) {
|
||||
var rmap = editor.game.replacerRecord;
|
||||
if (value instanceof Function) {
|
||||
var guid_ = editor.util.guid()
|
||||
rmap[guid_] = value.toString()
|
||||
return guid_
|
||||
} else if (value === null) {
|
||||
// 为了包含plugins的新建
|
||||
var guid_ = editor.util.guid()
|
||||
rmap[guid_] = null
|
||||
return guid_
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
editor_game.prototype.replacerForSaving = function (_key, value) {
|
||||
var rmap = editor.game.replacerRecord;
|
||||
if (rmap.hasOwnProperty(value)) {
|
||||
return rmap[value]
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
editor_game.prototype.getValue = function (field) {
|
||||
var rmap = editor.game.replacerRecord;
|
||||
var value = eval(field)
|
||||
if (rmap.hasOwnProperty(oldval)) {
|
||||
return rmap[value]
|
||||
} else {
|
||||
return 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)
|
||||
} else {
|
||||
eval(field + '=' + value)
|
||||
}
|
||||
}
|
||||
|
||||
editor_game.prototype.replacerWithoutRecord = function (_key, value) {
|
||||
if (value instanceof Function) {
|
||||
return value.toString()
|
||||
} else return value
|
||||
}
|
||||
|
||||
editor_game.prototype.fixFunctionInGameData = function () {
|
||||
core.floors = JSON.parse(JSON.stringify(core.floors, function (_k, v) {
|
||||
if (v instanceof Function) {
|
||||
return v.toString()
|
||||
} else return v
|
||||
}));
|
||||
core.data = JSON.parse(JSON.stringify(core.data, function (_k, v) {
|
||||
if (v instanceof Function) {
|
||||
return v.toString()
|
||||
} else return v
|
||||
}));
|
||||
data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = JSON.parse(JSON.stringify(data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d, function (_k, v) {
|
||||
if (v instanceof Function) {
|
||||
return v.toString()
|
||||
} else return v
|
||||
}));
|
||||
var rf = editor.game.replacerWithoutRecord
|
||||
core.floors = JSON.parse(JSON.stringify(core.floors, rf));
|
||||
core.data = JSON.parse(JSON.stringify(core.data, rf));
|
||||
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 = [];
|
||||
var MAX_NUM = 0;
|
||||
var keys=Object.keys(maps_90f36752_8815_4be8_b32b_d7fad1d0542e);
|
||||
for(var ii=0;ii<keys.length;ii++){
|
||||
var v=~~keys[ii];
|
||||
if(v>MAX_NUM && v<core.icons.tilesetStartOffset)MAX_NUM=v;
|
||||
var keys = Object.keys(maps_90f36752_8815_4be8_b32b_d7fad1d0542e);
|
||||
for (var ii = 0; ii < keys.length; ii++) {
|
||||
var v = ~~keys[ii];
|
||||
if (v > MAX_NUM && v < core.icons.tilesetStartOffset) MAX_NUM = v;
|
||||
}
|
||||
editor.MAX_NUM=MAX_NUM;
|
||||
editor.MAX_NUM = MAX_NUM;
|
||||
var getInfoById = function (id) {
|
||||
var block = maps.initBlock(0, 0, id);
|
||||
if (Object.prototype.hasOwnProperty.call(block, 'event')) {
|
||||
@ -46,15 +92,15 @@ editor_game_wrapper = function (editor, main, core) {
|
||||
var id = indexBlock.event.id;
|
||||
var indexId = indexBlock.id;
|
||||
var allCls = Object.keys(icons);
|
||||
if(i==17){
|
||||
editor.ids.push({'idnum': 17, 'id': id, 'images': 'terrains'});
|
||||
if (i == 17) {
|
||||
editor.ids.push({ 'idnum': 17, 'id': id, 'images': 'terrains' });
|
||||
point++;
|
||||
editor.indexs[i].push(point);
|
||||
continue;
|
||||
}
|
||||
for (var j = 0; j < allCls.length; j++) {
|
||||
if (id in icons[allCls[j]]) {
|
||||
editor.ids.push({'idnum': indexId, 'id': id, 'images': allCls[j], 'y': icons[allCls[j]][id]});
|
||||
editor.ids.push({ 'idnum': indexId, 'id': id, 'images': allCls[j], 'y': icons[allCls[j]][id] });
|
||||
point++;
|
||||
editor.indexs[i].push(point);
|
||||
}
|
||||
@ -62,36 +108,39 @@ editor_game_wrapper = function (editor, main, core) {
|
||||
}
|
||||
}
|
||||
editor.indexs[0] = [0];
|
||||
|
||||
|
||||
var startOffset = core.icons.tilesetStartOffset;
|
||||
for (var i in core.tilesets) {
|
||||
var imgName = core.tilesets[i];
|
||||
var img = core.material.images.tilesets[imgName];
|
||||
var width = Math.floor(img.width/32), height = Math.floor(img.height/32);
|
||||
if(img.width%32 || img.height%32){
|
||||
alert(imgName+'的长或宽不是32的整数倍, 请修改后刷新页面');
|
||||
var width = Math.floor(img.width / 32), height = Math.floor(img.height / 32);
|
||||
if (img.width % 32 || img.height % 32) {
|
||||
// alert(imgName + '的长或宽不是32的整数倍, 请修改后刷新页面');
|
||||
console.warn(imgName + '的长或宽不是32的整数倍, 请修改后刷新页面');
|
||||
}
|
||||
if(img.width*img.height > 32*32*3000){
|
||||
alert(imgName+'上的图块数量超过了3000,请修改后刷新页面');
|
||||
if (img.width * img.height > 32 * 32 * 3000) {
|
||||
// alert(imgName + '上的图块数量超过了3000,请修改后刷新页面');
|
||||
console.warn(imgName + '上的图块数量超过了3000,请修改后刷新页面');
|
||||
}
|
||||
for (var id=startOffset; id<startOffset+width*height;id++) {
|
||||
var x = (id-startOffset)%width, y = parseInt((id-startOffset)/width);
|
||||
for (var id = startOffset; id < startOffset + width * height; id++) {
|
||||
var x = (id - startOffset) % width, y = parseInt((id - startOffset) / width);
|
||||
var indexBlock = getInfoById(id);
|
||||
editor.ids.push({'idnum': id, 'id': indexBlock.event.id, 'images': imgName, "x": x, "y": y, isTile: true});
|
||||
editor.ids.push({ 'idnum': id, 'id': indexBlock.event.id, 'images': imgName, "x": x, "y": y, isTile: true });
|
||||
point++;
|
||||
editor.indexs[id]=[point];
|
||||
editor.indexs[id] = [point];
|
||||
}
|
||||
startOffset += core.icons.tilesetStartOffset;
|
||||
}
|
||||
}
|
||||
|
||||
editor_game.prototype.fetchMapFromCore = function(){
|
||||
// 获取当前地图
|
||||
editor_game.prototype.fetchMapFromCore = function () {
|
||||
var mapArray = core.maps.saveMap(core.status.floorId);
|
||||
editor.map = mapArray.map(function (v) {
|
||||
return v.map(function (v) {
|
||||
var x = parseInt(v), y = editor.indexs[x];
|
||||
if (y == null) {
|
||||
printe("素材数字"+x+"未定义。是不是忘了注册,或者接档时没有覆盖icons.js和maps.js?");
|
||||
printe("素材数字" + x + "未定义。是不是忘了注册,或者接档时没有覆盖icons.js和maps.js?");
|
||||
y = [0];
|
||||
}
|
||||
return editor.ids[y[0]]
|
||||
@ -99,17 +148,20 @@ editor_game_wrapper = function (editor, main, core) {
|
||||
});
|
||||
editor.currentFloorId = core.status.floorId;
|
||||
editor.currentFloorData = core.floors[core.status.floorId];
|
||||
for(var ii=0,name;name=['bgmap','fgmap'][ii];ii++){
|
||||
// 补出缺省的数据
|
||||
editor.currentFloorData.autoEvent = editor.currentFloorData.autoEvent || {};
|
||||
//
|
||||
for (var ii = 0, name; name = ['bgmap', 'fgmap'][ii]; ii++) {
|
||||
var mapArray = editor.currentFloorData[name];
|
||||
if(!mapArray || JSON.stringify(mapArray)==JSON.stringify([])){//未设置或空数组
|
||||
if (!mapArray || JSON.stringify(mapArray) == JSON.stringify([])) {//未设置或空数组
|
||||
//与editor.map同形的全0
|
||||
mapArray=eval('['+Array(editor.map.length+1).join('['+Array(editor.map[0].length+1).join('0,')+'],')+']');
|
||||
mapArray = eval('[' + Array(editor.map.length + 1).join('[' + Array(editor.map[0].length + 1).join('0,') + '],') + ']');
|
||||
}
|
||||
editor[name]=mapArray.map(function (v) {
|
||||
editor[name] = mapArray.map(function (v) {
|
||||
return v.map(function (v) {
|
||||
var x = parseInt(v), y = editor.indexs[x];
|
||||
if (y == null) {
|
||||
printe("素材数字"+x+"未定义。是不是忘了注册,或者接档时没有覆盖icons.js和maps.js?");
|
||||
printe("素材数字" + x + "未定义。是不是忘了注册,或者接档时没有覆盖icons.js和maps.js?");
|
||||
y = [0];
|
||||
}
|
||||
return editor.ids[y[0]]
|
||||
@ -118,6 +170,27 @@ 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_game.prototype.doCoreFunc = function (funcname) {
|
||||
return core[funcname].apply(core, Array.prototype.slice.call(arguments, 1));
|
||||
}
|
||||
|
||||
editor_game.prototype.getEnemy = function (id) {
|
||||
return core.material.enemys[id];
|
||||
}
|
||||
|
||||
editor_game.prototype.getFirstData = function () {
|
||||
return core.firstData;
|
||||
}
|
||||
|
||||
editor.constructor.prototype.game = new editor_game();
|
||||
}
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
|
||||
// 由于历史遗留原因, 以下变量作为全局变量使用
|
||||
// exportMap mapEditArea pout mapEditArea copyMap clearMapButton deleteMap printf printe tip selectBox
|
||||
// 除对这些量的功能修改外, 误在此文件中增加新变量或函数
|
||||
exportMap = document.getElementById('exportMap')
|
||||
exportMap.isExport=false
|
||||
exportMap.onclick=function(){
|
||||
@ -206,13 +208,21 @@ printf = function (str_, type) {
|
||||
printe = function (str_) {
|
||||
printf(str_, 'error')
|
||||
}
|
||||
tip_in_showMode = [
|
||||
'涉及图片的更改需要F5刷新浏览器来生效',
|
||||
'文本域可以通过双击,在文本编辑器或事件编辑器中编辑',
|
||||
'事件编辑器中的显示文本和自定义脚本的方块也可以双击',
|
||||
"画出的地图要点击\"保存地图\"才会写入到文件中",
|
||||
];
|
||||
tip=document.getElementById('tip')
|
||||
tip.showHelp = function(value) {
|
||||
var tips = [
|
||||
'表格的文本域可以双击进行编辑',
|
||||
'双击地图可以选中素材,右键可以弹出菜单',
|
||||
'双击事件编辑器的图块可以进行长文本编辑/脚本编辑/地图选点/UI绘制预览等操作',
|
||||
'ESC或点击空白处可以自动保存当前修改',
|
||||
'H键可以打开操作帮助哦',
|
||||
'tileset贴图模式可以在地图上拖动来一次绘制一个区域;右键额外素材也可以绑定宽高',
|
||||
'可以拖动地图上的图块和事件,或按Ctrl+C, Ctrl+X和Ctrl+V进行复制,剪切和粘贴,Delete删除',
|
||||
'Alt+数字键保存图块,数字键读取保存的图块',
|
||||
];
|
||||
if (value == null) value = Math.floor(Math.random() * tips.length);
|
||||
printf('tips: ' + tips[value])
|
||||
}
|
||||
tip._infos= {}
|
||||
tip.infos=function(value){
|
||||
if(value!=null){
|
||||
@ -354,7 +364,6 @@ tip.whichShow=function(value){
|
||||
return tip._whichShow
|
||||
}
|
||||
selectBox=document.getElementById('selectBox')
|
||||
dataSelection=document.getElementById('dataSelection')
|
||||
selectBox._isSelected=false
|
||||
selectBox.isSelected=function(value){
|
||||
if(value!=null){
|
||||
@ -362,8 +371,9 @@ selectBox.isSelected=function(value){
|
||||
tip.isSelectedBlock(value);
|
||||
tip.whichShow(0);
|
||||
clearTimeout(tip.timer);
|
||||
dataSelection.style.display=value?'':'none'
|
||||
editor.dom.dataSelection.style.display=value?'':'none'
|
||||
}
|
||||
return selectBox._isSelected
|
||||
}
|
||||
|
||||
// 修改此文件前先看文件开头的说明
|
||||
164
_server/editor_listen.js
Normal file
@ -0,0 +1,164 @@
|
||||
editor_listen_wrapper = function (editor) {
|
||||
|
||||
editor.constructor.prototype.listen = function () {
|
||||
|
||||
editor.dom.body.onmousedown = editor.uifunctions.body_click;
|
||||
|
||||
editor.dom.eui.oncontextmenu = function (e) { e.preventDefault() } // 自定义了右键菜单, 阻止默认行为
|
||||
editor.dom.midMenu.oncontextmenu = function (e) { e.preventDefault() }
|
||||
|
||||
editor.dom.eui.ondblclick = editor.uifunctions.map_doubleClick
|
||||
|
||||
editor.dom.eui.onmousedown = editor.uifunctions.map_ondown
|
||||
editor.dom.eui.onmousemove = editor.uifunctions.map_onmove
|
||||
editor.dom.eui.onmouseup = editor.uifunctions.map_onup
|
||||
|
||||
editor.dom.mid.onmousewheel = editor.uifunctions.map_mousewheel
|
||||
|
||||
editor.uivalues.shortcut = editor.config.get('shortcut', { 48: 0, 49: 0, 50: 0, 51: 0, 52: 0, 53: 0, 54: 0, 55: 0, 56: 0, 57: 0 });
|
||||
editor.dom.body.onkeydown = editor.uifunctions.body_shortcut
|
||||
|
||||
editor.uivalues.scrollBarHeight = editor.uifunctions.getScrollBarHeight();
|
||||
editor.dom.iconExpandBtn.style.display = 'block';
|
||||
editor.dom.iconExpandBtn.innerText = editor.uivalues.folded ? "展开素材区" : "折叠素材区";
|
||||
editor.dom.iconExpandBtn.onclick = editor.uifunctions.fold_material_click
|
||||
|
||||
editor.dom.iconLib.onmousedown = editor.uifunctions.material_ondown
|
||||
editor.dom.iconLib.oncontextmenu = function (e) { e.preventDefault() }
|
||||
|
||||
editor.dom.extraEvent.onmousedown = editor.uifunctions.extraEvent_click
|
||||
editor.dom.chooseThis.onmousedown = editor.uifunctions.chooseThis_click
|
||||
editor.dom.chooseInRight.onmousedown = editor.uifunctions.chooseInRight_click
|
||||
editor.dom.copyLoc.onmousedown = editor.uifunctions.copyLoc_click
|
||||
editor.dom.moveLoc.onmousedown = editor.uifunctions.moveLoc_click
|
||||
editor.dom.clearEvent.onmousedown = editor.uifunctions.clearEvent_click
|
||||
editor.dom.clearLoc.onmousedown = editor.uifunctions.clearLoc_click
|
||||
|
||||
editor.dom.lastUsed.onmousedown = editor.uifunctions.lastUsed_click;
|
||||
editor.dom.lockMode.onchange = editor.uifunctions.lockMode_onchange;
|
||||
|
||||
editor.dom.brushMod.onchange = editor.uifunctions.brushMod_onchange
|
||||
if (editor.dom.brushMod2) editor.dom.brushMod2.onchange = editor.uifunctions.brushMod2_onchange;
|
||||
if (editor.dom.brushMod3) editor.dom.brushMod3.onchange = editor.uifunctions.brushMod3_onchange;
|
||||
|
||||
editor.dom.layerMod.onchange = editor.uifunctions.layerMod_onchange
|
||||
if (editor.dom.layerMod2) editor.dom.layerMod2.onchange = editor.uifunctions.layerMod2_onchange;
|
||||
if (editor.dom.layerMod3) editor.dom.layerMod3.onchange = editor.uifunctions.layerMod3_onchange;
|
||||
|
||||
editor.uifunctions.viewportButtons_func()
|
||||
}
|
||||
|
||||
editor.constructor.prototype.mobile_listen = function () {
|
||||
if (!editor.isMobile) return;
|
||||
|
||||
var mobileview = document.getElementById('mobileview');
|
||||
var mid = document.getElementById('mid');
|
||||
var right = document.getElementById('right');
|
||||
// var mobileeditdata = document.getElementById('mobileeditdata');
|
||||
|
||||
|
||||
editor.showdataarea = function (callShowMode) {
|
||||
mid.style = 'z-index:-1;opacity: 0;';
|
||||
right.style = 'z-index:-1;opacity: 0;';
|
||||
// mobileeditdata.style = '';
|
||||
if (callShowMode) editor.mode.showMode(editor.dom.editModeSelect.value);
|
||||
editor.uifunctions.hideMidMenu();
|
||||
}
|
||||
mobileview.children[0].onclick = function () {
|
||||
editor.showdataarea(true)
|
||||
}
|
||||
mobileview.children[1].onclick = function () {
|
||||
mid.style = '';
|
||||
right.style = 'z-index:-1;opacity: 0;';
|
||||
// mobileeditdata.style = 'z-index:-1;opacity: 0;';
|
||||
editor.lastClickId = '';
|
||||
}
|
||||
mobileview.children[3].onclick = function () {
|
||||
mid.style = 'z-index:-1;opacity: 0;';
|
||||
right.style = '';
|
||||
// mobileeditdata.style = 'z-index:-1;opacity: 0;';
|
||||
editor.lastClickId = '';
|
||||
}
|
||||
|
||||
/*
|
||||
var gettrbyid = function () {
|
||||
if (!editor.lastClickId) return false;
|
||||
thisTr = document.getElementById(editor.lastClickId);
|
||||
input = thisTr.children[2].children[0].children[0];
|
||||
field = thisTr.children[0].getAttribute('title');
|
||||
cobj = JSON.parse(thisTr.children[1].getAttribute('cobj'));
|
||||
return [thisTr, input, field, cobj];
|
||||
}
|
||||
mobileeditdata.children[0].onclick = function () {
|
||||
var info = gettrbyid()
|
||||
if (!info) return;
|
||||
info[1].ondblclick()
|
||||
}
|
||||
mobileeditdata.children[1].onclick = function () {
|
||||
var info = gettrbyid()
|
||||
if (!info) return;
|
||||
printf(info[2])
|
||||
}
|
||||
mobileeditdata.children[2].onclick = function () {
|
||||
var info = gettrbyid()
|
||||
if (!info) return;
|
||||
printf(info[0].children[1].getAttribute('title'))
|
||||
}
|
||||
*/
|
||||
|
||||
//=====
|
||||
|
||||
document.body.ontouchstart = document.body.onmousedown;
|
||||
document.body.onmousedown = null;
|
||||
|
||||
editor.dom.eui.ontouchstart = editor.dom.eui.onmousedown
|
||||
editor.dom.eui.onmousedown = null
|
||||
editor.dom.eui.ontouchmove = editor.dom.eui.onmousemove
|
||||
editor.dom.eui.onmousemove = null
|
||||
editor.dom.eui.ontouchend = editor.dom.eui.onmouseup
|
||||
editor.dom.eui.onmouseup = null
|
||||
|
||||
|
||||
editor.dom.chooseThis.ontouchstart = editor.dom.chooseThis.onmousedown
|
||||
editor.dom.chooseThis.onmousedown = null
|
||||
editor.dom.chooseInRight.ontouchstart = editor.dom.chooseInRight.onmousedown
|
||||
editor.dom.chooseInRight.onmousedown = null
|
||||
editor.dom.copyLoc.ontouchstart = editor.dom.copyLoc.onmousedown
|
||||
editor.dom.copyLoc.onmousedown = null
|
||||
editor.dom.moveLoc.ontouchstart = editor.dom.moveLoc.onmousedown
|
||||
editor.dom.moveLoc.onmousedown = null
|
||||
editor.dom.clearLoc.ontouchstart = editor.dom.clearLoc.onmousedown
|
||||
editor.dom.clearLoc.onmousedown = null
|
||||
}
|
||||
|
||||
editor.constructor.prototype.mode_listen = function (callback) {
|
||||
|
||||
// 这里的函数还没有写jsdoc, 通过_func()的方式先完成分类
|
||||
|
||||
editor.uifunctions.newIdIdnum_func()
|
||||
editor.uifunctions.changeId_func()
|
||||
editor.uifunctions.copyPasteEnemyItem_func();
|
||||
|
||||
editor.uifunctions.selectFloor_func()
|
||||
editor.uifunctions.saveFloor_func()
|
||||
|
||||
editor.uifunctions.newMap_func()
|
||||
|
||||
editor.uifunctions.createNewMaps_func()
|
||||
|
||||
editor.uifunctions.changeFloorId_func()
|
||||
|
||||
editor.uifunctions.fixCtx_func()
|
||||
|
||||
editor.uifunctions.selectAppend_func()
|
||||
editor.uifunctions.selectFileBtn_func()
|
||||
editor.uifunctions.changeColorInput_func()
|
||||
editor.uifunctions.picClick_func()
|
||||
editor.uifunctions.appendConfirm_func()
|
||||
|
||||
editor.dom.editModeSelect.onchange = editor.mode.editModeSelect_onchange
|
||||
|
||||
if (Boolean(callback)) callback();
|
||||
}
|
||||
|
||||
}
|
||||
898
_server/editor_mappanel.js
Normal file
@ -0,0 +1,898 @@
|
||||
editor_mappanel_wrapper = function (editor) {
|
||||
|
||||
// 暂时先 注释+分类 内部函数未完成重构
|
||||
|
||||
/**
|
||||
* 在绘图区格子内画一个随机色块
|
||||
*/
|
||||
editor.uifunctions.fillPos = function (pos) {
|
||||
editor.dom.euiCtx.fillStyle = '#' + ~~(Math.random() * 8) + ~~(Math.random() * 8) + ~~(Math.random() * 8);
|
||||
editor.dom.euiCtx.fillRect(pos.x * 32 + 12 - core.bigmap.offsetX, pos.y * 32 + 12 - core.bigmap.offsetY, 8, 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从鼠标点击返回可用的组件内坐标
|
||||
*/
|
||||
editor.uifunctions.eToLoc = function (e) {
|
||||
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft
|
||||
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop
|
||||
var xx = e.clientX, yy = e.clientY
|
||||
if (editor.isMobile) { xx = e.touches[0].clientX, yy = e.touches[0].clientY }
|
||||
editor.loc = {
|
||||
'x': scrollLeft + xx - editor.dom.mid.offsetLeft - editor.dom.mapEdit.offsetLeft,
|
||||
'y': scrollTop + yy - editor.dom.mid.offsetTop - editor.dom.mapEdit.offsetTop,
|
||||
'size': editor.isMobile ? (32 * innerWidth * 0.96 / core.__PIXELS__) : 32
|
||||
};
|
||||
return editor.loc;
|
||||
}
|
||||
|
||||
/**
|
||||
* 组件内坐标转地图位置
|
||||
* @param {Boolean} addViewportOffset 是否加上大地图的偏置
|
||||
*/
|
||||
editor.uifunctions.locToPos = function (loc, addViewportOffset) {
|
||||
var offsetX = 0, offsetY = 0;
|
||||
if (addViewportOffset) {
|
||||
offsetX = core.bigmap.offsetX / 32;
|
||||
offsetY = core.bigmap.offsetY / 32;
|
||||
}
|
||||
editor.pos = { 'x': ~~(loc.x / loc.size) + offsetX, 'y': ~~(loc.y / loc.size) + offsetY }
|
||||
return editor.pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* editor.dom.eui.ondblclick
|
||||
* 双击地图可以选中素材
|
||||
*/
|
||||
editor.uifunctions.map_doubleClick = function (e) {
|
||||
if (editor.uivalues.bindSpecialDoor.loc != null) return;
|
||||
var loc = editor.uifunctions.eToLoc(e);
|
||||
var pos = editor.uifunctions.locToPos(loc, true);
|
||||
editor.setSelectBoxFromInfo(editor[editor.layerMod][pos.y][pos.x]);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用于鼠标移出map后清除状态
|
||||
*/
|
||||
editor.uifunctions.clearMapStepStatus = function () {
|
||||
if (editor.uivalues.mouseOutCheck > 1) {
|
||||
editor.uivalues.mouseOutCheck--;
|
||||
setTimeout(editor.uifunctions.clearMapStepStatus, 1000);
|
||||
return;
|
||||
}
|
||||
editor.uivalues.holdingPath = 0;
|
||||
editor.uivalues.stepPostfix = [];
|
||||
editor.dom.euiCtx.clearRect(0, 0, core.__PIXELS__, core.__PIXELS__);
|
||||
editor.uivalues.startPos = editor.uivalues.endPos = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* editor.dom.eui.onmousedown
|
||||
* + 绑定机关门事件的选择怪物
|
||||
* + 右键进入菜单
|
||||
* + 非绘图时选中
|
||||
* + 绘图时画个矩形在那个位置
|
||||
*/
|
||||
editor.uifunctions.map_ondown = function (e) {
|
||||
var loc = editor.uifunctions.eToLoc(e);
|
||||
var pos = editor.uifunctions.locToPos(loc, true);
|
||||
if (editor.uivalues.bindSpecialDoor.loc != null) {
|
||||
var x = editor.pos.x, y = editor.pos.y, id = (editor.map[y][x] || {}).id;
|
||||
// 检测是否是怪物
|
||||
if (id && editor.game.getEnemy(id)) {
|
||||
var locstr = x + "," + y, index = editor.uivalues.bindSpecialDoor.enemys.indexOf(locstr);
|
||||
if (index >= 0) editor.uivalues.bindSpecialDoor.enemys.splice(index, 1);
|
||||
else editor.uivalues.bindSpecialDoor.enemys.push(locstr);
|
||||
editor.drawEventBlock();
|
||||
editor.uifunctions._extraEvent_bindSpecialDoor_doAction();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (e.button == 2) {
|
||||
editor.uifunctions.showMidMenu(e.clientX, e.clientY);
|
||||
return false;
|
||||
}
|
||||
if (!selectBox.isSelected()) {
|
||||
editor_mode.onmode('nextChange');
|
||||
editor_mode.onmode('loc');
|
||||
//editor_mode.loc();
|
||||
//tip.whichShow(1);
|
||||
tip.showHelp(6);
|
||||
editor.uivalues.startPos = pos;
|
||||
editor.dom.euiCtx.strokeStyle = '#FF0000';
|
||||
editor.dom.euiCtx.lineWidth = 3;
|
||||
if (editor.isMobile) editor.uifunctions.showMidMenu(e.clientX, e.clientY);
|
||||
return false;
|
||||
}
|
||||
|
||||
editor.uivalues.holdingPath = 1;
|
||||
editor.uivalues.mouseOutCheck = 2;
|
||||
setTimeout(editor.uifunctions.clearMapStepStatus);
|
||||
editor.dom.euiCtx.clearRect(0, 0, core.__PIXELS__, core.__PIXELS__);
|
||||
editor.uivalues.stepPostfix = [];
|
||||
editor.uivalues.stepPostfix.push(pos);
|
||||
if (editor.brushMod == 'line') editor.uifunctions.fillPos(pos);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* editor.dom.eui.onmousemove
|
||||
* + 非绘图模式时维护起止位置并画箭头
|
||||
* + 绘图模式时找到与队列尾相邻的鼠标方向的点画个矩形
|
||||
*/
|
||||
editor.uifunctions.map_onmove = function (e) {
|
||||
if (!selectBox.isSelected()) {
|
||||
if (editor.uivalues.startPos == null) return;
|
||||
//tip.whichShow(1);
|
||||
var loc = editor.uifunctions.eToLoc(e);
|
||||
var pos = editor.uifunctions.locToPos(loc, true);
|
||||
if (editor.uivalues.endPos != null && editor.uivalues.endPos.x == pos.x && editor.uivalues.endPos.y == pos.y) return;
|
||||
if (editor.uivalues.endPos != null) {
|
||||
editor.dom.euiCtx.clearRect(Math.min(32 * editor.uivalues.startPos.x - core.bigmap.offsetX, 32 * editor.uivalues.endPos.x - core.bigmap.offsetX),
|
||||
Math.min(32 * editor.uivalues.startPos.y - core.bigmap.offsetY, 32 * editor.uivalues.endPos.y - core.bigmap.offsetY),
|
||||
(Math.abs(editor.uivalues.startPos.x - editor.uivalues.endPos.x) + 1) * 32, (Math.abs(editor.uivalues.startPos.y - editor.uivalues.endPos.y) + 1) * 32)
|
||||
}
|
||||
editor.uivalues.endPos = pos;
|
||||
if (editor.uivalues.startPos != null) {
|
||||
if (editor.uivalues.startPos.x != editor.uivalues.endPos.x || editor.uivalues.startPos.y != editor.uivalues.endPos.y) {
|
||||
core.drawArrow('eui',
|
||||
32 * editor.uivalues.startPos.x + 16 - core.bigmap.offsetX, 32 * editor.uivalues.startPos.y + 16 - core.bigmap.offsetY,
|
||||
32 * editor.uivalues.endPos.x + 16 - core.bigmap.offsetX, 32 * editor.uivalues.endPos.y + 16 - core.bigmap.offsetY);
|
||||
}
|
||||
}
|
||||
// editor_mode.onmode('nextChange');
|
||||
// editor_mode.onmode('loc');
|
||||
//editor_mode.loc();
|
||||
//tip.whichShow(1);
|
||||
// tip.showHelp(6);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (editor.uivalues.holdingPath == 0) {
|
||||
return false;
|
||||
}
|
||||
editor.uivalues.mouseOutCheck = 2;
|
||||
var loc = editor.uifunctions.eToLoc(e);
|
||||
var pos = editor.uifunctions.locToPos(loc, true);
|
||||
var pos0 = editor.uivalues.stepPostfix[editor.uivalues.stepPostfix.length - 1]
|
||||
var directionDistance = [pos.y - pos0.y, pos0.x - pos.x, pos0.y - pos.y, pos.x - pos0.x]
|
||||
var max = 0, index = 4;
|
||||
for (var i = 0; i < 4; i++) {
|
||||
if (directionDistance[i] > max) {
|
||||
index = i;
|
||||
max = directionDistance[i];
|
||||
}
|
||||
}
|
||||
var pos = [{ 'x': 0, 'y': 1 }, { 'x': -1, 'y': 0 }, { 'x': 0, 'y': -1 }, { 'x': 1, 'y': 0 }, false][index]
|
||||
if (pos) {
|
||||
pos.x += pos0.x;
|
||||
pos.y += pos0.y;
|
||||
if (editor.brushMod == 'line') editor.uifunctions.fillPos(pos);
|
||||
else {
|
||||
var x0 = editor.uivalues.stepPostfix[0].x;
|
||||
var y0 = editor.uivalues.stepPostfix[0].y;
|
||||
var x1 = pos.x;
|
||||
var y1 = pos.y;
|
||||
if (x0 > x1) { x0 ^= x1; x1 ^= x0; x0 ^= x1; }//swap
|
||||
if (y0 > y1) { y0 ^= y1; y1 ^= y0; y0 ^= y1; }//swap
|
||||
// draw rect
|
||||
editor.dom.euiCtx.clearRect(0, 0, editor.dom.euiCtx.canvas.width, editor.dom.euiCtx.canvas.height);
|
||||
editor.dom.euiCtx.fillStyle = 'rgba(0, 127, 255, 0.4)';
|
||||
editor.dom.euiCtx.fillRect(32 * x0 - core.bigmap.offsetX, 32 * y0 - core.bigmap.offsetY,
|
||||
32 * (x1 - x0) + 32, 32 * (y1 - y0) + 32);
|
||||
}
|
||||
editor.uivalues.stepPostfix.push(pos);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* editor.dom.eui.onmouseup
|
||||
* + 非绘图模式时, 交换首末点的内容
|
||||
* + 绘图模式时, 根据画线/画矩形/画tileset 做对应的绘制
|
||||
*/
|
||||
editor.uifunctions.map_onup = function (e) {
|
||||
if (!selectBox.isSelected()) {
|
||||
//tip.whichShow(1);
|
||||
// editor.movePos(editor.uivalues.startPos, editor.uivalues.endPos);
|
||||
if (editor.layerMod == 'map')
|
||||
editor.exchangePos(editor.uivalues.startPos, editor.uivalues.endPos);
|
||||
else
|
||||
editor.exchangeBgFg(editor.uivalues.startPos, editor.uivalues.endPos, editor.layerMod);
|
||||
editor.uivalues.startPos = editor.uivalues.endPos = null;
|
||||
editor.dom.euiCtx.clearRect(0, 0, core.__PIXELS__, core.__PIXELS__);
|
||||
return false;
|
||||
}
|
||||
editor.uivalues.holdingPath = 0;
|
||||
if (editor.uivalues.stepPostfix && editor.uivalues.stepPostfix.length) {
|
||||
editor.savePreMap();
|
||||
if (editor.brushMod !== 'line') {
|
||||
var x0 = editor.uivalues.stepPostfix[0].x;
|
||||
var y0 = editor.uivalues.stepPostfix[0].y;
|
||||
var x1 = editor.uivalues.stepPostfix[editor.uivalues.stepPostfix.length - 1].x;
|
||||
var y1 = editor.uivalues.stepPostfix[editor.uivalues.stepPostfix.length - 1].y;
|
||||
if (x0 > x1) { x0 ^= x1; x1 ^= x0; x0 ^= x1; }//swap
|
||||
if (y0 > y1) { y0 ^= y1; y1 ^= y0; y0 ^= y1; }//swap
|
||||
editor.uivalues.stepPostfix = [];
|
||||
for (var jj = y0; jj <= y1; jj++) {
|
||||
for (var ii = x0; ii <= x1; ii++) {
|
||||
editor.uivalues.stepPostfix.push({ x: ii, y: jj })
|
||||
}
|
||||
}
|
||||
}
|
||||
var useBrushMode = editor.brushMod == 'tileset';
|
||||
if (editor.uivalues.stepPostfix.length == 1 && (editor.uivalues.tileSize[0] > 1 || editor.uivalues.tileSize[1] > 1)) {
|
||||
useBrushMode = true;
|
||||
var x0 = editor.uivalues.stepPostfix[0].x;
|
||||
var y0 = editor.uivalues.stepPostfix[0].y;
|
||||
editor.uivalues.stepPostfix = [];
|
||||
for (var jj = y0; jj < y0 + editor.uivalues.tileSize[1]; ++jj) {
|
||||
for (var ii = x0; ii < x0 + editor.uivalues.tileSize[0]; ++ii) {
|
||||
if (jj >= editor[editor.layerMod].length || ii >= editor[editor.layerMod][0].length) continue;
|
||||
editor.uivalues.stepPostfix.push({ x: ii, y: jj });
|
||||
}
|
||||
}
|
||||
}
|
||||
if (useBrushMode && core.tilesets.indexOf(editor.info.images) !== -1) {
|
||||
var imgWidth = ~~(core.material.images.tilesets[editor.info.images].width / 32);
|
||||
var x0 = editor.uivalues.stepPostfix[0].x;
|
||||
var y0 = editor.uivalues.stepPostfix[0].y;
|
||||
var idnum = editor.info.idnum;
|
||||
for (var ii = 0; ii < editor.uivalues.stepPostfix.length; ii++) {
|
||||
if (editor.uivalues.stepPostfix[ii].y != y0) {
|
||||
y0++;
|
||||
idnum += imgWidth;
|
||||
}
|
||||
editor[editor.layerMod][editor.uivalues.stepPostfix[ii].y][editor.uivalues.stepPostfix[ii].x] = editor.ids[editor.indexs[idnum + editor.uivalues.stepPostfix[ii].x - x0]];
|
||||
}
|
||||
} else {
|
||||
for (var ii = 0; ii < editor.uivalues.stepPostfix.length; ii++)
|
||||
editor[editor.layerMod][editor.uivalues.stepPostfix[ii].y][editor.uivalues.stepPostfix[ii].x] = editor.info;
|
||||
}
|
||||
// console.log(editor.map);
|
||||
if (editor.info.y != null) {
|
||||
editor.uivalues.lastUsed = [editor.info].concat(editor.uivalues.lastUsed.filter(function (e) { return e.id != editor.info.id}));
|
||||
editor.config.set("lastUsed", editor.uivalues.lastUsed);
|
||||
}
|
||||
editor.updateMap();
|
||||
editor.uivalues.holdingPath = 0;
|
||||
editor.uivalues.stepPostfix = [];
|
||||
editor.dom.euiCtx.clearRect(0, 0, core.__PIXELS__, core.__PIXELS__);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* editor.dom.mid.onmousewheel
|
||||
* 在地图编辑区域滚轮切换楼层
|
||||
*/
|
||||
editor.uifunctions.map_mousewheel = function (e) {
|
||||
var wheel = function (direct) {
|
||||
var index = editor.core.floorIds.indexOf(editor.currentFloorId);
|
||||
var toId = editor.currentFloorId;
|
||||
|
||||
if (direct > 0 && index < editor.core.floorIds.length - 1)
|
||||
toId = editor.core.floorIds[index + 1];
|
||||
else if (direct < 0 && index > 0)
|
||||
toId = editor.core.floorIds[index - 1];
|
||||
else return;
|
||||
|
||||
editor_mode.onmode('nextChange');
|
||||
editor_mode.onmode('floor');
|
||||
editor.dom.selectFloor.value = toId;
|
||||
editor.changeFloor(toId);
|
||||
}
|
||||
|
||||
try {
|
||||
if (e.wheelDelta)
|
||||
wheel(Math.sign(e.wheelDelta))
|
||||
else if (e.detail)
|
||||
wheel(Math.sign(e.detail));
|
||||
}
|
||||
catch (ee) {
|
||||
console.log(ee);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示右键菜单
|
||||
*/
|
||||
editor.uifunctions.showMidMenu = function (x, y) {
|
||||
editor.uivalues.lastRightButtonPos = JSON.parse(JSON.stringify(
|
||||
[editor.pos, editor.uivalues.lastRightButtonPos[0]]
|
||||
));
|
||||
// --- copy
|
||||
editor.uivalues.lastCopyedInfo = [editor.copyFromPos(), editor.uivalues.lastCopyedInfo[0]];
|
||||
var locStr = '(' + editor.uivalues.lastRightButtonPos[1].x + ',' + editor.uivalues.lastRightButtonPos[1].y + ')';
|
||||
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
|
||||
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
|
||||
|
||||
// 检测是否是上下楼
|
||||
var thisevent = editor.map[editor.pos.y][editor.pos.x];
|
||||
var extraEvent = editor.dom.extraEvent, parent = extraEvent.parentElement;
|
||||
if (thisevent == 0) {
|
||||
parent.removeChild(extraEvent);
|
||||
parent.appendChild(extraEvent);
|
||||
editor.dom.extraEvent.style.display = 'block';
|
||||
editor.dom.extraEvent.children[0].innerHTML = '绑定出生点为此点';
|
||||
} else if (thisevent.id == 'upFloor') {
|
||||
parent.removeChild(extraEvent);
|
||||
parent.insertBefore(extraEvent, parent.firstChild);
|
||||
editor.dom.extraEvent.style.display = 'block';
|
||||
editor.dom.extraEvent.children[0].innerHTML = '绑定上楼事件';
|
||||
}
|
||||
else if (thisevent.id == 'downFloor') {
|
||||
parent.removeChild(extraEvent);
|
||||
parent.insertBefore(extraEvent, parent.firstChild);
|
||||
editor.dom.extraEvent.style.display = 'block';
|
||||
editor.dom.extraEvent.children[0].innerHTML = '绑定下楼事件';
|
||||
}
|
||||
else if (['leftPortal', 'rightPortal', 'downPortal', 'upPortal'].indexOf(thisevent.id) >= 0) {
|
||||
parent.removeChild(extraEvent);
|
||||
parent.insertBefore(extraEvent, parent.firstChild);
|
||||
editor.dom.extraEvent.style.display = 'block';
|
||||
editor.dom.extraEvent.children[0].innerHTML = '绑定楼传事件';
|
||||
}
|
||||
else if (thisevent.id == 'specialDoor') {
|
||||
parent.removeChild(extraEvent);
|
||||
parent.insertBefore(extraEvent, parent.firstChild);
|
||||
editor.dom.extraEvent.style.display = 'block';
|
||||
editor.dom.extraEvent.children[0].innerHTML = '绑定机关门事件';
|
||||
}
|
||||
else editor.dom.extraEvent.style.display = 'none';
|
||||
|
||||
editor.dom.chooseThis.children[0].innerHTML = '选中此点' + '(' + editor.pos.x + ',' + editor.pos.y + ')'
|
||||
editor.dom.copyLoc.children[0].innerHTML = '复制事件' + locStr + '到此处';
|
||||
editor.dom.moveLoc.children[0].innerHTML = '交换事件' + locStr + '与此事件的位置';
|
||||
editor.dom.midMenu.style = 'top:' + (y + scrollTop) + 'px;left:' + (x + scrollLeft) + 'px;';
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏右键菜单
|
||||
*/
|
||||
editor.uifunctions.hideMidMenu = function () {
|
||||
if (editor.isMobile) {
|
||||
setTimeout(function () {
|
||||
editor.dom.midMenu.style = 'display:none';
|
||||
}, 200)
|
||||
} else {
|
||||
editor.dom.midMenu.style = 'display:none';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* editor.dom.extraEvent.onmousedown
|
||||
* 菜单 附加点操作
|
||||
*/
|
||||
editor.uifunctions.extraEvent_click = function (e) {
|
||||
editor.uifunctions.hideMidMenu();
|
||||
e.stopPropagation();
|
||||
|
||||
var thisevent = editor.map[editor.pos.y][editor.pos.x];
|
||||
return editor.uifunctions._extraEvent_bindStartPoint(thisevent)
|
||||
|| editor.uifunctions._extraEvent_bindStair(thisevent)
|
||||
|| editor.uifunctions._extraEvent_bindSpecialDoor(thisevent);
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定该空地点为起始点
|
||||
*/
|
||||
editor.uifunctions._extraEvent_bindStartPoint = function (thisevent) {
|
||||
if (thisevent != 0) return false;
|
||||
editor.mode.onmode('tower');
|
||||
editor.mode.addAction(["change", "['firstData']['floorId']", editor.currentFloorId]);
|
||||
editor.mode.addAction(["change", "['firstData']['hero']['loc']['x']", editor.pos.x]);
|
||||
editor.mode.addAction(["change", "['firstData']['hero']['loc']['y']", editor.pos.y]);
|
||||
editor.mode.onmode('save', function () {
|
||||
core.firstData.floorId = editor.currentFloorId;
|
||||
core.firstData.hero.loc.x = editor.pos.x;
|
||||
core.firstData.hero.loc.y = editor.pos.y;
|
||||
editor.drawPosSelection();
|
||||
editor.drawEventBlock();
|
||||
editor.mode.tower();
|
||||
printf('绑定初始点成功');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定该楼梯的楼传事件
|
||||
*/
|
||||
editor.uifunctions._extraEvent_bindStair = function (thisevent) {
|
||||
if (['upFloor', 'downFloor', 'leftPortal', 'rightPortal', 'upPortal', 'downPortal'].indexOf(thisevent.id) < 0)
|
||||
return false;
|
||||
var loc = editor.pos.x + "," + editor.pos.y;
|
||||
if (thisevent.id == 'upFloor') {
|
||||
editor.currentFloorData.changeFloor[loc] = { "floorId": ":next", "stair": "downFloor" };
|
||||
}
|
||||
else if (thisevent.id == 'downFloor') {
|
||||
editor.currentFloorData.changeFloor[loc] = { "floorId": ":before", "stair": "upFloor" };
|
||||
}
|
||||
else if (thisevent.id == 'leftPortal' || thisevent.id == 'rightPortal') {
|
||||
editor.currentFloorData.changeFloor[loc] = { "floorId": ":next", "stair": ":symmetry_x" }
|
||||
}
|
||||
else if (thisevent.id == 'upPortal' || thisevent.id == 'downPortal') {
|
||||
editor.currentFloorData.changeFloor[loc] = { "floorId": ":next", "stair": ":symmetry_y" }
|
||||
}
|
||||
editor.file.saveFloorFile(function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw (err)
|
||||
}
|
||||
editor.drawPosSelection();
|
||||
editor.drawEventBlock();
|
||||
editor_mode.showMode('loc');
|
||||
printf('添加楼梯事件成功');
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定该机关门的事件
|
||||
*/
|
||||
editor.uifunctions._extraEvent_bindSpecialDoor = function (thisevent) {
|
||||
if (thisevent.id != 'specialDoor') return false;
|
||||
var number = parseInt(prompt("请输入该机关门的怪物数量", "0"))|| 0;
|
||||
if (number <= 0) return true;
|
||||
editor.uivalues.bindSpecialDoor.n = number;
|
||||
editor.uivalues.bindSpecialDoor.loc = editor.pos.x + ',' + editor.pos.y;
|
||||
editor.uivalues.bindSpecialDoor.enemys = [];
|
||||
printf("请点击选择" + number + "个怪物;切换楼层或刷新页面取消操作。");
|
||||
}
|
||||
|
||||
/**
|
||||
* 确定绑定该机关门的事件
|
||||
* cancel:是否取消此模式
|
||||
*/
|
||||
editor.uifunctions._extraEvent_bindSpecialDoor_doAction = function (cancel) {
|
||||
var bindSpecialDoor = editor.uivalues.bindSpecialDoor;
|
||||
if (cancel) {
|
||||
bindSpecialDoor.loc = null;
|
||||
bindSpecialDoor.enemys = [];
|
||||
bindSpecialDoor.n = 0;
|
||||
editor.drawEventBlock();
|
||||
printf("");
|
||||
return;
|
||||
}
|
||||
if (bindSpecialDoor.loc == null || bindSpecialDoor.enemys.length != bindSpecialDoor.n) return;
|
||||
// 添加机关门自动事件
|
||||
var doorFlag = "flag:door_" + editor.currentFloorId + "_" + bindSpecialDoor.loc.replace(',', '_');
|
||||
editor.currentFloorData.autoEvent[bindSpecialDoor.loc] = {
|
||||
'0': {
|
||||
"condition": doorFlag + "==" + bindSpecialDoor.n,
|
||||
"currentFloor": true,
|
||||
"priority": 0,
|
||||
"delayExecute": false,
|
||||
"multiExecute": false,
|
||||
"data": [
|
||||
{"type": "openDoor"}
|
||||
]
|
||||
}
|
||||
};
|
||||
bindSpecialDoor.enemys.forEach(function (loc) {
|
||||
editor.currentFloorData.afterBattle[loc] = [
|
||||
{"type": "addValue", "name": doorFlag, "value": "1"}
|
||||
]
|
||||
});
|
||||
editor.file.saveFloorFile(function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw (err)
|
||||
}
|
||||
editor.drawEventBlock();
|
||||
editor.drawPosSelection();
|
||||
editor_mode.showMode('loc');
|
||||
printf('绑定机关门事件成功');
|
||||
});
|
||||
bindSpecialDoor.loc = null;
|
||||
bindSpecialDoor.enemys = [];
|
||||
bindSpecialDoor.n = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* editor.dom.chooseThis.onmousedown
|
||||
* 菜单 选中此点
|
||||
*/
|
||||
editor.uifunctions.chooseThis_click = function (e) {
|
||||
editor.uifunctions.hideMidMenu();
|
||||
e.stopPropagation();
|
||||
selectBox.isSelected(false);
|
||||
|
||||
editor_mode.onmode('nextChange');
|
||||
editor_mode.onmode('loc');
|
||||
//editor_mode.loc();
|
||||
//tip.whichShow(1);
|
||||
if (editor.isMobile) editor.showdataarea(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* editor.dom.chooseInRight.onmousedown
|
||||
* 菜单 在素材区选中此图块
|
||||
*/
|
||||
editor.uifunctions.chooseInRight_click = function (e) {
|
||||
editor.uifunctions.hideMidMenu();
|
||||
e.stopPropagation();
|
||||
var thisevent = editor[editor.layerMod][editor.pos.y][editor.pos.x];
|
||||
editor.setSelectBoxFromInfo(thisevent);
|
||||
}
|
||||
|
||||
/**
|
||||
* editor.dom.copyLoc.onmousedown
|
||||
* 菜单 复制此事件
|
||||
*/
|
||||
editor.uifunctions.copyLoc_click = function (e) {
|
||||
editor.uifunctions.hideMidMenu();
|
||||
e.stopPropagation();
|
||||
editor.savePreMap();
|
||||
editor_mode.onmode('');
|
||||
var now = editor.pos, last = editor.uivalues.lastRightButtonPos[1];
|
||||
if (now.x == last.x && now.y == last.y) return;
|
||||
editor.pasteToPos(editor.uivalues.lastCopyedInfo[1]);
|
||||
editor.updateMap();
|
||||
editor.file.saveFloorFile(function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw (err)
|
||||
}
|
||||
; printf('复制事件成功');
|
||||
editor.drawPosSelection();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* editor.dom.moveLoc.onmousedown
|
||||
* 菜单 移动此事件
|
||||
*/
|
||||
editor.uifunctions.moveLoc_click = function (e) {
|
||||
editor.uifunctions.hideMidMenu();
|
||||
e.stopPropagation();
|
||||
editor.savePreMap();
|
||||
editor_mode.onmode('');
|
||||
editor.exchangePos(editor.pos, editor.uivalues.lastRightButtonPos[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* editor.dom.clearEvent.onmousedown
|
||||
* 菜单 仅清空此点事件
|
||||
*/
|
||||
editor.uifunctions.clearEvent_click = function (e) {
|
||||
e.stopPropagation();
|
||||
editor.clearPos(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* editor.dom.clearLoc.onmousedown
|
||||
* 菜单 清空此点及事件
|
||||
*/
|
||||
editor.uifunctions.clearLoc_click = function (e) {
|
||||
e.stopPropagation();
|
||||
editor.clearPos(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* editor.dom.lockMode.onchange
|
||||
* 点击【】
|
||||
*/
|
||||
editor.uifunctions.lockMode_onchange = function () {
|
||||
tip.msgs[11] = String('锁定模式开启下将不再点击空白处自动保存,请谨慎操作。');
|
||||
tip.whichShow(12);
|
||||
editor.uivalues.lockMode = editor.dom.lockMode.checked;
|
||||
}
|
||||
|
||||
/**
|
||||
* editor.dom.brushMod.onchange
|
||||
* 切换画笔模式
|
||||
*/
|
||||
editor.uifunctions.brushMod_onchange = function () {
|
||||
editor.brushMod = editor.dom.brushMod.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* editor.dom.brushMod2.onchange
|
||||
* 切换画笔模式
|
||||
*/
|
||||
editor.uifunctions.brushMod2_onchange = function () {
|
||||
editor.brushMod = editor.dom.brushMod2.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* editor.dom.brushMod3.onchange
|
||||
* 切换画笔模式
|
||||
*/
|
||||
editor.uifunctions.brushMod3_onchange = function () {
|
||||
if (!editor.config.get('alertTileMode') &&
|
||||
!confirm("从V2.6.6开始,tileset贴图模式已被废弃。\n请右键额外素材,并输入所需要绘制的宽高,然后单击地图以绘制一个区域。\n\n点取消将不再显示此提示。")) {
|
||||
editor.config.set('alertTileMode', true);
|
||||
}
|
||||
// tip.showHelp(5)
|
||||
tip.isSelectedBlock(false)
|
||||
tip.msgs[11] = String('tileset贴图模式下可以按选中tileset素材,并在地图上拖动来一次绘制一个区域');
|
||||
tip.whichShow(12);
|
||||
editor.brushMod = editor.dom.brushMod3.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* editor.dom.layerMod.onchange
|
||||
* 切换编辑的层
|
||||
*/
|
||||
editor.uifunctions.layerMod_onchange = function () {
|
||||
editor.layerMod = editor.dom.layerMod.value;
|
||||
[editor.dom.bgc, editor.dom.fgc, editor.dom.evc, editor.dom.ev2c].forEach(function (x) {
|
||||
x.style.opacity = 1;
|
||||
});
|
||||
|
||||
// 手机端....
|
||||
if (editor.isMobile) {
|
||||
if (editor.dom.layerMod.value == 'bgmap') {
|
||||
[editor.dom.fgc, editor.dom.evc, editor.dom.ev2c].forEach(function (x) {
|
||||
x.style.opacity = 0.3;
|
||||
});
|
||||
}
|
||||
if (editor.dom.layerMod.value == 'fgmap') {
|
||||
[editor.dom.bgc, editor.dom.evc, editor.dom.ev2c].forEach(function (x) {
|
||||
x.style.opacity = 0.3;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* editor.dom.layerMod2.onchange
|
||||
* 切换编辑的层
|
||||
*/
|
||||
editor.uifunctions.layerMod2_onchange = function () {
|
||||
editor.layerMod = editor.dom.layerMod2.value;
|
||||
[editor.dom.fgc, editor.dom.evc, editor.dom.ev2c].forEach(function (x) {
|
||||
x.style.opacity = 0.3;
|
||||
});
|
||||
editor.dom.bgc.style.opacity = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* editor.dom.layerMod3.onchange
|
||||
* 切换编辑的层
|
||||
*/
|
||||
editor.uifunctions.layerMod3_onchange = function () {
|
||||
editor.layerMod = editor.dom.layerMod3.value;
|
||||
[editor.dom.bgc, editor.dom.evc, editor.dom.ev2c].forEach(function (x) {
|
||||
x.style.opacity = 0.3;
|
||||
});
|
||||
editor.dom.fgc.style.opacity = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 移动大地图可视窗口的绑定
|
||||
*/
|
||||
editor.uifunctions.viewportButtons_func = function () {
|
||||
var pressTimer = null;
|
||||
for (var ii = 0, node; node = editor.dom.viewportButtons.children[ii]; ii++) {
|
||||
(function (x, y) {
|
||||
var move = function () {
|
||||
editor.moveViewport(x, y);
|
||||
}
|
||||
node.onmousedown = function () {
|
||||
clearTimeout(pressTimer);
|
||||
pressTimer = setTimeout(function () {
|
||||
pressTimer = -1;
|
||||
var f = function () {
|
||||
if (pressTimer != null) {
|
||||
move();
|
||||
setTimeout(f, 150);
|
||||
}
|
||||
}
|
||||
f();
|
||||
}, 500);
|
||||
};
|
||||
node.onmouseup = function () {
|
||||
if (pressTimer > 0) {
|
||||
clearTimeout(pressTimer);
|
||||
move();
|
||||
}
|
||||
pressTimer = null;
|
||||
}
|
||||
})([-1, 0, 0, 1][ii], [0, -1, 1, 0][ii]);
|
||||
}
|
||||
}
|
||||
|
||||
editor.uifunctions.selectFloor_func = function () {
|
||||
var selectFloor = document.getElementById('selectFloor');
|
||||
editor.game.getFloorFileList(function (floors) {
|
||||
var outstr = [];
|
||||
floors[0].forEach(function (floor) {
|
||||
outstr.push(["<option value='", floor, "'>", floor, '</option>\n'].join(''));
|
||||
});
|
||||
selectFloor.innerHTML = outstr.join('');
|
||||
selectFloor.value = core.status.floorId;
|
||||
selectFloor.onchange = function () {
|
||||
editor_mode.onmode('nextChange');
|
||||
editor_mode.onmode('floor');
|
||||
editor.changeFloor(selectFloor.value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
editor.uifunctions.saveFloor_func = function () {
|
||||
var saveFloor = document.getElementById('saveFloor');
|
||||
editor_mode.saveFloor = function () {
|
||||
editor_mode.onmode('');
|
||||
editor.file.saveFloorFile(function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw (err)
|
||||
}
|
||||
; printf('保存成功');
|
||||
});
|
||||
}
|
||||
saveFloor.onclick = editor_mode.saveFloor;
|
||||
}
|
||||
|
||||
editor.uifunctions.lastUsed_click = function (e) {
|
||||
if (editor.isMobile) return;
|
||||
|
||||
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft
|
||||
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop
|
||||
var px = scrollLeft + e.clientX - editor.dom.mid2.offsetLeft - editor.dom.lastUsedDiv.offsetLeft,
|
||||
py = scrollTop + e.clientY - editor.dom.mid2.offsetTop - editor.dom.lastUsedDiv.offsetTop;
|
||||
var x = parseInt(px / 32), y = parseInt(py / 32);
|
||||
var index = x + core.__SIZE__ * y;
|
||||
if (index >= editor.uivalues.lastUsed.length) return;
|
||||
editor.setSelectBoxFromInfo(editor.uivalues.lastUsed[index]);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
editor.constructor.prototype.copyFromPos = function (pos) {
|
||||
var fields = Object.keys(editor.file.comment._data.floors._data.loc._data);
|
||||
pos = pos || editor.pos;
|
||||
var map = core.clone(editor.map[pos.y][pos.x]);
|
||||
var events = {};
|
||||
fields.forEach(function(v){
|
||||
events[v] = core.clone(editor.currentFloorData[v][pos.x+','+pos.y]);
|
||||
})
|
||||
return {map: map, events: events};
|
||||
}
|
||||
|
||||
editor.constructor.prototype.pasteToPos = function (info, pos) {
|
||||
if (info == null) return;
|
||||
var fields = Object.keys(editor.file.comment._data.floors._data.loc._data);
|
||||
pos = pos || editor.pos;
|
||||
editor.map[pos.y][pos.x] = core.clone(info.map);
|
||||
fields.forEach(function(v){
|
||||
if (info.events[v] == null) delete editor.currentFloorData[v][pos.x+","+pos.y];
|
||||
else editor.currentFloorData[v][pos.x+","+pos.y] = core.clone(info.events[v]);
|
||||
});
|
||||
}
|
||||
|
||||
editor.constructor.prototype.movePos = function (startPos, endPos, callback) {
|
||||
if (!startPos || !endPos) return;
|
||||
if (startPos.x == endPos.x && startPos.y == endPos.y) return;
|
||||
var copyed = editor.copyFromPos(startPos);
|
||||
editor.pasteToPos({map:0, events: {}}, startPos);
|
||||
editor.pasteToPos(copyed, endPos);
|
||||
editor.updateMap();
|
||||
editor.file.saveFloorFile(function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw(err)
|
||||
}
|
||||
;printf('移动事件成功');
|
||||
editor.drawPosSelection();
|
||||
if (callback) callback();
|
||||
});
|
||||
}
|
||||
|
||||
editor.constructor.prototype.exchangePos = function (startPos, endPos, callback) {
|
||||
if (!startPos || !endPos) return;
|
||||
if (startPos.x == endPos.x && startPos.y == endPos.y) return;
|
||||
var startInfo = editor.copyFromPos(startPos);
|
||||
var endInfo = editor.copyFromPos(endPos);
|
||||
editor.pasteToPos(startInfo, endPos);
|
||||
editor.pasteToPos(endInfo, startPos);
|
||||
editor.updateMap();
|
||||
editor.file.saveFloorFile(function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw(err)
|
||||
}
|
||||
;printf('交换事件成功');
|
||||
editor.drawPosSelection();
|
||||
if (callback) callback();
|
||||
});
|
||||
}
|
||||
|
||||
editor.constructor.prototype.savePreMap = function () {
|
||||
var dt = {
|
||||
map: editor.map,
|
||||
fgmap: editor.fgmap,
|
||||
bgmap: editor.bgmap,
|
||||
};
|
||||
if (editor.uivalues.preMapData.length == 0
|
||||
|| !core.same(editor.uivalues.preMapData[editor.uivalues.preMapData.length - 1], dt)) {
|
||||
editor.uivalues.preMapData.push(core.clone(dt));
|
||||
if (editor.uivalues.preMapData.length > editor.uivalues.preMapMax) {
|
||||
editor.uivalues.preMapData.shift();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
editor.constructor.prototype.moveBgFg = function (startPos, endPos, name, callback) {
|
||||
if (!startPos || !endPos || ["bgmap","fgmap"].indexOf(name)<0) return;
|
||||
if (startPos.x == endPos.x && startPos.y == endPos.y) return;
|
||||
editor[name][endPos.y][endPos.x] = editor[name][startPos.y][startPos.x];
|
||||
editor[name][startPos.y][startPos.x] = 0;
|
||||
editor.updateMap();
|
||||
editor.file.saveFloorFile(function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw(err)
|
||||
}
|
||||
;printf('移动图块成功');
|
||||
editor.drawPosSelection();
|
||||
if (callback) callback();
|
||||
});
|
||||
}
|
||||
|
||||
editor.constructor.prototype.exchangeBgFg = function (startPos, endPos, name, callback) {
|
||||
if (!startPos || !endPos || ["bgmap","fgmap"].indexOf(name)<0) return;
|
||||
if (startPos.x == endPos.x && startPos.y == endPos.y) return;
|
||||
var value = editor[name][endPos.y][endPos.x];
|
||||
editor[name][endPos.y][endPos.x] = editor[name][startPos.y][startPos.x];
|
||||
editor[name][startPos.y][startPos.x] = value;
|
||||
editor.updateMap();
|
||||
editor.file.saveFloorFile(function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw(err)
|
||||
}
|
||||
;printf('交换图块成功');
|
||||
editor.drawPosSelection();
|
||||
if (callback) callback();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
editor.constructor.prototype.clearPos = function (clearPos, pos, callback) {
|
||||
var fields = Object.keys(editor.file.comment._data.floors._data.loc._data);
|
||||
pos = pos || editor.pos;
|
||||
editor.uifunctions.hideMidMenu();
|
||||
editor.savePreMap();
|
||||
editor.info = 0;
|
||||
editor_mode.onmode('');
|
||||
if (clearPos)
|
||||
editor.map[pos.y][pos.x]=editor.info;
|
||||
editor.updateMap();
|
||||
fields.forEach(function(v){
|
||||
delete editor.currentFloorData[v][pos.x+','+pos.y];
|
||||
})
|
||||
editor.file.saveFloorFile(function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw(err)
|
||||
}
|
||||
;printf(clearPos?'清空该点和事件成功':'只清空该点事件成功');
|
||||
editor.drawPosSelection();
|
||||
if (callback) callback();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
158
_server/editor_materialpanel.js
Normal file
@ -0,0 +1,158 @@
|
||||
editor_materialpanel_wrapper = function (editor) {
|
||||
|
||||
editor.uifunctions.getScrollBarHeight = function () {
|
||||
var outer = document.createElement("div");
|
||||
outer.style.visibility = "hidden";
|
||||
outer.style.width = "100px";
|
||||
outer.style.msOverflowStyle = "scrollbar"; // needed for WinJS apps
|
||||
|
||||
document.body.appendChild(outer);
|
||||
|
||||
var widthNoScroll = outer.offsetWidth;
|
||||
// force scrollbars
|
||||
outer.style.overflow = "scroll";
|
||||
|
||||
// add innerdiv
|
||||
var inner = document.createElement("div");
|
||||
inner.style.width = "100%";
|
||||
outer.appendChild(inner);
|
||||
|
||||
var widthWithScroll = inner.offsetWidth;
|
||||
|
||||
// remove divs
|
||||
outer.parentNode.removeChild(outer);
|
||||
|
||||
return widthNoScroll - widthWithScroll;
|
||||
}
|
||||
|
||||
/**
|
||||
* editor.dom.iconExpandBtn.onclick
|
||||
*/
|
||||
editor.uifunctions.fold_material_click = function () {
|
||||
if (editor.uivalues.folded) {
|
||||
if (confirm("你想要展开素材吗?\n展开模式下将显示全素材内容。")) {
|
||||
editor.config.set('folded', false, function() {
|
||||
window.location.reload();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
var perCol = parseInt(prompt("请输入折叠素材模式下每列的个数:", "50")) || 0;
|
||||
if (perCol > 0) {
|
||||
editor.config.set('foldPerCol', perCol, false);
|
||||
editor.config.set('folded', true, function() {
|
||||
window.location.reload();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* editor.dom.iconLib.onmousedown
|
||||
* 素材区的单击事件
|
||||
*/
|
||||
editor.uifunctions.material_ondown = function (e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
if (!editor.isMobile && e.clientY >= editor.dom.iconLib.offsetHeight - editor.uivalues.scrollBarHeight) return;
|
||||
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
|
||||
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
|
||||
var loc = {
|
||||
'x': scrollLeft + e.clientX + editor.dom.iconLib.scrollLeft - right.offsetLeft - editor.dom.iconLib.offsetLeft,
|
||||
'y': scrollTop + e.clientY + editor.dom.iconLib.scrollTop - right.offsetTop - editor.dom.iconLib.offsetTop,
|
||||
'size': 32
|
||||
};
|
||||
editor.loc = loc;
|
||||
editor.uivalues.tileSize = [1,1];
|
||||
var pos = editor.uifunctions.locToPos(loc);
|
||||
for (var spriter in editor.widthsX) {
|
||||
if (pos.x >= editor.widthsX[spriter][1] && pos.x < editor.widthsX[spriter][2]) {
|
||||
var ysize = spriter.endsWith('48') ? 48 : 32;
|
||||
loc.ysize = ysize;
|
||||
pos.images = editor.widthsX[spriter][0];
|
||||
pos.y = ~~(loc.y / loc.ysize);
|
||||
if (!editor.uivalues.folded && core.tilesets.indexOf(pos.images) == -1) pos.x = editor.widthsX[spriter][1];
|
||||
var autotiles = core.material.images['autotile'];
|
||||
if (pos.images == 'autotile') {
|
||||
var imNames = Object.keys(autotiles);
|
||||
if ((pos.y + 1) * ysize > editor.widthsX[spriter][3])
|
||||
pos.y = ~~(editor.widthsX[spriter][3] / ysize) - 4;
|
||||
else {
|
||||
for (var i = 0; i < imNames.length; i++) {
|
||||
if (pos.y >= 4 * i && pos.y < 4 * (i + 1)) {
|
||||
pos.images = imNames[i];
|
||||
pos.y = 4 * i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
var height = editor.widthsX[spriter][3], col = height / ysize;
|
||||
if (editor.uivalues.folded && core.tilesets.indexOf(pos.images) == -1) {
|
||||
col = (pos.x == editor.widthsX[spriter][2] - 1) ? ((col - 1) % editor.uivalues.foldPerCol + 1) : editor.uivalues.foldPerCol;
|
||||
}
|
||||
if (spriter == 'terrains' && pos.x == editor.widthsX[spriter][1]) col += 2;
|
||||
pos.y = Math.min(pos.y, col - 1);
|
||||
}
|
||||
|
||||
selectBox.isSelected(true);
|
||||
// console.log(pos,core.material.images[pos.images].height)
|
||||
editor.dom.dataSelection.style.left = pos.x * 32 + 'px';
|
||||
editor.dom.dataSelection.style.top = pos.y * ysize + 'px';
|
||||
editor.dom.dataSelection.style.height = ysize - 6 + 'px';
|
||||
|
||||
if (pos.x == 0 && pos.y == 0) {
|
||||
// editor.info={idnum:0, id:'empty','images':'清除块', 'y':0};
|
||||
editor.info = 0;
|
||||
} else if (pos.x == 0 && pos.y == 1) {
|
||||
editor.info = editor.ids[editor.indexs[17]];
|
||||
} else {
|
||||
if (autotiles[pos.images]) editor.info = { 'images': pos.images, 'y': 0 };
|
||||
else if (core.tilesets.indexOf(pos.images) != -1) editor.info = { 'images': pos.images, 'y': pos.y, 'x': pos.x - editor.widthsX[spriter][1] };
|
||||
else {
|
||||
var y = pos.y;
|
||||
if (editor.uivalues.folded) {
|
||||
y += editor.uivalues.foldPerCol * (pos.x - editor.widthsX[spriter][1]);
|
||||
}
|
||||
if (pos.images == 'terrains' && pos.x == 0) y -= 2;
|
||||
editor.info = { 'images': pos.images, 'y': y }
|
||||
}
|
||||
|
||||
for (var ii = 0; ii < editor.ids.length; ii++) {
|
||||
if ((core.tilesets.indexOf(pos.images) != -1 && editor.info.images == editor.ids[ii].images
|
||||
&& editor.info.y == editor.ids[ii].y && editor.info.x == editor.ids[ii].x)
|
||||
|| (Object.prototype.hasOwnProperty.call(autotiles, pos.images) && editor.info.images == editor.ids[ii].id
|
||||
&& editor.info.y == editor.ids[ii].y)
|
||||
|| (core.tilesets.indexOf(pos.images) == -1 && editor.info.images == editor.ids[ii].images
|
||||
&& editor.info.y == editor.ids[ii].y)
|
||||
) {
|
||||
|
||||
editor.info = editor.ids[ii];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (editor.info.isTile && e.button == 2) {
|
||||
var v = prompt("请输入该额外素材区域绑定宽高,以逗号分隔", "1,1");
|
||||
if (v != null && /^\d+,\d+$/.test(v)) {
|
||||
v = v.split(",");
|
||||
var x = parseInt(v[0]), y = parseInt(v[1]);
|
||||
var widthX = editor.widthsX[editor.info.images];
|
||||
if (x <= 0 || y <= 0 || editor.info.x + x > widthX[2] - widthX[1] || 32*(editor.info.y + y) > widthX[3]) {
|
||||
alert("不合法的输入范围,已经越界");
|
||||
} else {
|
||||
editor.uivalues.tileSize = [x, y];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
tip.infos(JSON.parse(JSON.stringify(editor.info)));
|
||||
editor_mode.onmode('nextChange');
|
||||
editor_mode.onmode('enemyitem');
|
||||
editor.updateLastUsedMap();
|
||||
//editor_mode.enemyitem();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -21,7 +21,7 @@ editor_mode = function (editor) {
|
||||
this.mode = '';
|
||||
this.info = {};
|
||||
this.appendPic = {};
|
||||
this.doubleClickMode='change';
|
||||
this.doubleClickMode = 'change';
|
||||
}
|
||||
|
||||
editor_mode.prototype.init = function (callback) {
|
||||
@ -49,15 +49,16 @@ editor_mode = function (editor) {
|
||||
editor_mode.actionList.push(action);
|
||||
}
|
||||
|
||||
editor_mode.prototype.doActionList = function (mode, actionList) {
|
||||
editor_mode.prototype.doActionList = function (mode, actionList, callback) {
|
||||
if (actionList.length == 0) return;
|
||||
printf('修改中...');
|
||||
var cb=function(objs_){
|
||||
var cb = function (objs_) {
|
||||
if (objs_.slice(-1)[0] != null) {
|
||||
printe(objs_.slice(-1)[0]);
|
||||
throw(objs_.slice(-1)[0])
|
||||
throw (objs_.slice(-1)[0])
|
||||
}
|
||||
;printf('修改成功');
|
||||
; printf('修改成功' + (data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.name == 'template' ? '\n\n请注意:全塔属性的name尚未修改,请及时予以设置' : ''));
|
||||
if (callback) callback();
|
||||
}
|
||||
switch (mode) {
|
||||
case 'loc':
|
||||
@ -95,9 +96,9 @@ editor_mode = function (editor) {
|
||||
}
|
||||
}
|
||||
|
||||
editor_mode.prototype.onmode = function (mode) {
|
||||
editor_mode.prototype.onmode = function (mode, callback) {
|
||||
if (editor_mode.mode != mode) {
|
||||
if (mode === 'save') editor_mode.doActionList(editor_mode.mode, editor_mode.actionList);
|
||||
if (mode === 'save') editor_mode.doActionList(editor_mode.mode, editor_mode.actionList, callback);
|
||||
if (editor_mode.mode === 'nextChange' && mode) editor_mode.showMode(mode);
|
||||
if (mode !== 'save') editor_mode.mode = mode;
|
||||
editor_mode.actionList = [];
|
||||
@ -109,15 +110,78 @@ editor_mode = function (editor) {
|
||||
editor_mode.dom[name].style = 'z-index:-1;opacity: 0;';
|
||||
}
|
||||
editor_mode.dom[mode].style = '';
|
||||
editor_mode.doubleClickMode='change';
|
||||
editor_mode.doubleClickMode = 'change';
|
||||
// clear
|
||||
editor.drawEventBlock();
|
||||
if (editor_mode[mode]) editor_mode[mode]();
|
||||
document.getElementById('editModeSelect').value = mode;
|
||||
var tips = tip_in_showMode;
|
||||
if (!selectBox.isSelected()) printf('tips: ' + tips[~~(tips.length * Math.random())]);
|
||||
editor.dom.editModeSelect.value = mode;
|
||||
if (!selectBox.isSelected()) tip.showHelp();
|
||||
}
|
||||
|
||||
editor_mode.prototype.change = function (value) {
|
||||
editor_mode.onmode('nextChange');
|
||||
editor_mode.onmode(value);
|
||||
if (editor.isMobile) editor.showdataarea(false);
|
||||
}
|
||||
|
||||
|
||||
editor_mode.prototype.checkUnique = function (thiseval) {
|
||||
if (!(thiseval instanceof Array)) return false;
|
||||
var map = {};
|
||||
for (var i = 0; i < thiseval.length; ++i) {
|
||||
if (map[thiseval[i]]) {
|
||||
alert("警告:存在重复定义!");
|
||||
return false;
|
||||
}
|
||||
map[thiseval[i]] = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
editor_mode.prototype.checkFloorIds = function (thiseval) {
|
||||
if (!editor_mode.checkUnique(thiseval)) return false;
|
||||
var oldvalue = data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.main.floorIds;
|
||||
fs.readdir('project/floors', function (err, data) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw Error(err);
|
||||
}
|
||||
var newfiles = thiseval.map(function (v) { return v + '.js' });
|
||||
var notExist = '';
|
||||
for (var name, ii = 0; name = newfiles[ii]; ii++) {
|
||||
if (data.indexOf(name) === -1) notExist = name;
|
||||
}
|
||||
if (notExist) {
|
||||
var discard = confirm('文件' + notExist + '不存在, 保存会导致工程无法打开, 是否放弃更改');
|
||||
if (discard) {
|
||||
editor.file.editTower([['change', "['main']['floorIds']", oldvalue]], function (objs_) {//console.log(objs_);
|
||||
if (objs_.slice(-1)[0] != null) {
|
||||
printe(objs_.slice(-1)[0]);
|
||||
throw (objs_.slice(-1)[0])
|
||||
}
|
||||
; printe('已放弃floorIds的修改,请F5进行刷新');
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
return true
|
||||
}
|
||||
|
||||
editor_mode.prototype.changeDoubleClickModeByButton = function (mode) {
|
||||
({
|
||||
delete: function () {
|
||||
printf('下一次双击表格的项删除,切换下拉菜单可取消;编辑后需刷新浏览器生效。');
|
||||
editor_mode.doubleClickMode = mode;
|
||||
},
|
||||
add: function () {
|
||||
printf('下一次双击表格的项则在同级添加新项,切换下拉菜单可取消;编辑后需刷新浏览器生效。');
|
||||
editor_mode.doubleClickMode = mode;
|
||||
}
|
||||
}[mode])();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
editor_mode.prototype.loc = function (callback) {
|
||||
//editor.pos={x: 0, y: 0};
|
||||
if (!core.isset(editor.pos)) return;
|
||||
@ -141,17 +205,19 @@ editor_mode = function (editor) {
|
||||
//editor.info=editor.ids[editor.indexs[201]];
|
||||
if (!core.isset(editor.info)) return;
|
||||
|
||||
if (Object.keys(editor.info).length !== 0 && editor.info.idnum!=17) editor_mode.info = editor.info;//避免editor.info被清空导致无法获得是物品还是怪物
|
||||
if (Object.keys(editor.info).length !== 0 && editor.info.idnum != 17) editor_mode.info = editor.info;//避免editor.info被清空导致无法获得是物品还是怪物
|
||||
|
||||
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') {
|
||||
@ -231,7 +297,7 @@ editor_mode = function (editor) {
|
||||
tableinfo.listen(tableinfo.guids);
|
||||
if (Boolean(callback)) callback();
|
||||
}
|
||||
|
||||
|
||||
editor_mode.prototype.plugins = function (callback) {
|
||||
var objs = [];
|
||||
editor.file.editPlugins([], function (objs_) {
|
||||
@ -245,11 +311,17 @@ editor_mode = function (editor) {
|
||||
if (Boolean(callback)) callback();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* editor.dom.editModeSelect.onchange
|
||||
*/
|
||||
editor_mode.prototype.editModeSelect_onchange = function () {
|
||||
editor_mode.change(editor.dom.editModeSelect.value);
|
||||
}
|
||||
|
||||
editor_mode.prototype.listen = function (callback) {
|
||||
|
||||
// 移动至 editor_unsorted_2.js
|
||||
// 移动至 editor_listen.js -> editor.constructor.prototype.mode_listen
|
||||
}
|
||||
|
||||
var editor_mode = new editor_mode();
|
||||
|
||||
@ -81,6 +81,12 @@ editor_multi = function () {
|
||||
_format();
|
||||
}
|
||||
|
||||
editor_multi.hasError = function () {
|
||||
if (!editor_multi.lintAutocomplete) return false;
|
||||
return JSHINT.errors.filter(function (e) {
|
||||
return e.code.startsWith("E")
|
||||
}).length > 0;
|
||||
}
|
||||
|
||||
editor_multi.import = function (id_, args) {
|
||||
var thisTr = document.getElementById(id_);
|
||||
@ -94,6 +100,8 @@ editor_multi = function () {
|
||||
editor_multi.lintAutocomplete = false;
|
||||
if (args.lint === true) editor_multi.lintAutocomplete = true;
|
||||
if (field.indexOf('Effect') !== -1) editor_multi.lintAutocomplete = true;
|
||||
if ((!input.value || input.value == 'null') && editor_mode.mode == 'plugins')
|
||||
input.value = '"function () {\\n\\t// 在此增加新插件\\n\\t\\n}"';
|
||||
if (input.value.slice(0, 1) === '"' || args.string) {
|
||||
editor_multi.isString = true;
|
||||
codeEditor.setValue(JSON.parse(input.value) || '');
|
||||
@ -113,6 +121,7 @@ editor_multi = function () {
|
||||
}
|
||||
codeEditor.setValue(tstr || '');
|
||||
}
|
||||
document.getElementById('showPlugins').style.display = editor_mode.mode == 'plugins' ? 'block': 'none';
|
||||
editor_multi.show();
|
||||
return true;
|
||||
}
|
||||
@ -124,6 +133,11 @@ editor_multi = function () {
|
||||
}
|
||||
|
||||
editor_multi.confirm = function () {
|
||||
if (editor_multi.hasError()) {
|
||||
alert("当前好像存在严重的语法错误,请处理后再保存。\n严重的语法错误可能会导致整个编辑器的崩溃。");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!editor_multi.id) {
|
||||
editor_multi.id = '';
|
||||
return;
|
||||
@ -173,6 +187,11 @@ editor_multi = function () {
|
||||
setvalue(codeEditor.getValue() || '');
|
||||
}
|
||||
|
||||
editor_multi.showPlugins = function () {
|
||||
if (editor.isMobile && !confirm("你确定要跳转到云端插件列表吗?")) return;
|
||||
window.open("https://h5mota.com/plugins/", "_blank");
|
||||
}
|
||||
|
||||
var multiLineArgs = [null, null, null];
|
||||
editor_multi.multiLineEdit = function (value, b, f, args, callback) {
|
||||
editor_multi.id = 'callFromBlockly';
|
||||
|
||||
@ -12,34 +12,41 @@ editor_table_wrapper = function (editor) {
|
||||
values.map(function (v) {
|
||||
return editor.table.option(v)
|
||||
}).join('')
|
||||
return `<select>\n${content}</select>\n`
|
||||
return /* html */`<select>\n${content}</select>\n`
|
||||
}
|
||||
editor_table.prototype.option = function (value) {
|
||||
return `<option value='${JSON.stringify(value)}'>${JSON.stringify(value)}</option>\n`
|
||||
return /* html */`<option value='${JSON.stringify(value)}'>${JSON.stringify(value)}</option>\n`
|
||||
}
|
||||
editor_table.prototype.text = function (value) {
|
||||
return `<input type='text' spellcheck='false' value='${JSON.stringify(value)}'/>\n`
|
||||
return /* html */`<input type='text' spellcheck='false' value='${JSON.stringify(value)}'/>\n`
|
||||
}
|
||||
editor_table.prototype.checkbox = function (value) {
|
||||
return `<input type='checkbox' ${(value ? 'checked ' : '')}/>\n`
|
||||
return /* html */`<input type='checkbox' ${(value ? 'checked ' : '')}/>\n`
|
||||
}
|
||||
editor_table.prototype.textarea = function (value, indent) {
|
||||
return `<textarea spellcheck='false'>${JSON.stringify(value, null, indent || 0)}</textarea>\n`
|
||||
return /* html */`<textarea spellcheck='false'>${JSON.stringify(value, null, indent || 0)}</textarea>\n`
|
||||
}
|
||||
editor_table.prototype.editGrid = function (showComment) {
|
||||
var html = "";
|
||||
if (showComment) html += "<button onclick='editor.table.onCommentBtnClick(this)'>显示完整注释</button><br/>";
|
||||
html += "<button onclick='editor.table.onEditBtnClick(this)'>编辑表格内容</button>";
|
||||
return html;
|
||||
}
|
||||
|
||||
editor_table.prototype.title = function () {
|
||||
return `\n<tr><td>条目</td><td>注释</td><td>值</td></tr>\n`
|
||||
return /* html */`\n<tr><td>条目</td><td>注释</td><td>值</td><td>操作</td></tr>\n`
|
||||
}
|
||||
|
||||
editor_table.prototype.gap = function (field) {
|
||||
return `<tr><td>----</td><td>----</td><td>${field}</td></tr>\n`
|
||||
return /* html */`<tr><td>----</td><td>----</td><td>${field}</td><td>----</td></tr>\n`
|
||||
}
|
||||
|
||||
editor_table.prototype.tr = function (guid, field, shortField, commentHTMLescape, cobjstr, shortCommentHTMLescape, tdstr) {
|
||||
return `<tr id="${guid}">
|
||||
return /* html */`<tr id="${guid}">
|
||||
<td title="${field}">${shortField}</td>
|
||||
<td title="${commentHTMLescape}" cobj="${cobjstr}">${shortCommentHTMLescape}</td>
|
||||
<td><div class="etableInputDiv">${tdstr}</div></td>
|
||||
<td>${editor.table.editGrid(commentHTMLescape != shortCommentHTMLescape)}</td>
|
||||
</tr>\n`
|
||||
}
|
||||
|
||||
@ -145,6 +152,7 @@ editor_table_wrapper = function (editor) {
|
||||
if (key === '_data') continue;
|
||||
if (cobj[key] instanceof Function) cobj[key] = cobj[key](args);
|
||||
}
|
||||
pvobj[ii] = vobj = args.vobj;
|
||||
// 标记为_hide的属性不展示
|
||||
if (cobj._hide) continue;
|
||||
if (!cobj._leaf) {
|
||||
@ -193,7 +201,7 @@ editor_table_wrapper = function (editor) {
|
||||
// "['a']['b']" => "b"
|
||||
var shortField = field.split("']").slice(-2)[0].split("['").slice(-1)[0];
|
||||
// 把长度超过 charlength 的字符改成 固定长度+...的形式
|
||||
shortField = (shortField.length < charlength ? shortField : shortField.slice(0, charlength) + '...');
|
||||
// shortField = (shortField.length < charlength ? shortField : shortField.slice(0, charlength) + '...');
|
||||
|
||||
// 完整的内容转义后供悬停查看
|
||||
var commentHTMLescape = editor.util.HTMLescape(comment);
|
||||
@ -285,6 +293,7 @@ editor_table_wrapper = function (editor) {
|
||||
var thiseval = null;
|
||||
if (input.checked != null) input.value = input.checked;
|
||||
try {
|
||||
if (input.value == '') input.value = 'null';
|
||||
thiseval = JSON.parse(input.value);
|
||||
} catch (ee) {
|
||||
printe(field + ' : ' + ee);
|
||||
@ -298,6 +307,25 @@ editor_table_wrapper = function (editor) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 当"显示完整注释"被按下时
|
||||
*/
|
||||
editor_table.prototype.onCommentBtnClick = function (button) {
|
||||
var tr = button.parentNode.parentNode;
|
||||
printf(tr.children[1].getAttribute('title'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 当"编辑表格内容"被按下时
|
||||
*/
|
||||
editor_table.prototype.onEditBtnClick = function (button) {
|
||||
var tr = button.parentNode.parentNode;
|
||||
var guid = tr.getAttribute('id');
|
||||
var cobj = JSON.parse(tr.children[1].getAttribute('cobj'));
|
||||
if (cobj._type === 'event') editor_blockly.import(guid, { type: cobj._event });
|
||||
if (cobj._type === 'textarea') editor_multi.import(guid, { lint: cobj._lint, string: cobj._string });
|
||||
}
|
||||
|
||||
/**
|
||||
* 双击表格时
|
||||
* 正常编辑: 尝试用事件编辑器或多行文本编辑器打开
|
||||
@ -337,12 +365,22 @@ editor_table_wrapper = function (editor) {
|
||||
editor_table.prototype.addfunc = function (guid, obj, commentObj, thisTr, input, field, cobj, modeNode) {
|
||||
editor_mode.onmode(editor_mode._ids[modeNode.getAttribute('id')]);
|
||||
|
||||
var mode = document.getElementById('editModeSelect').value;
|
||||
var mode = editor.dom.editModeSelect.value;
|
||||
|
||||
// 1.输入id
|
||||
var newid = prompt('请输入新项的ID(仅公共事件支持中文ID)');
|
||||
if (newid == null || newid.length == 0) {
|
||||
return;
|
||||
var newid = '2';
|
||||
if (mode == 'loc') {
|
||||
var ae = editor.currentFloorData.autoEvent[editor_mode.pos.x + ',' + editor_mode.pos.y];
|
||||
if (ae != null) {
|
||||
var testid;
|
||||
for (testid = 2; Object.hasOwnProperty.call(ae, testid); testid++); // 从3开始是因为comment中设置了始终显示012
|
||||
newid = testid + '';
|
||||
}
|
||||
} else {
|
||||
newid = prompt('请输入新项的ID(仅公共事件支持中文ID)');
|
||||
if (newid == null || newid.length == 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 检查commentEvents
|
||||
|
||||
570
_server/editor_ui.js
Normal file
@ -0,0 +1,570 @@
|
||||
editor_ui_wrapper = function (editor) {
|
||||
|
||||
|
||||
/**
|
||||
* 根据鼠标点击, 得到从元素向上到body的所有id
|
||||
*/
|
||||
editor.uifunctions.getClickpath = function (e) {
|
||||
//console.log(e);
|
||||
var clickpath = [];
|
||||
var getpath = function (e) {
|
||||
var path = [];
|
||||
var currentElem = e.target;
|
||||
while (currentElem) {
|
||||
path.push(currentElem);
|
||||
currentElem = currentElem.parentElement;
|
||||
}
|
||||
if (path.indexOf(window) === -1 && path.indexOf(document) === -1)
|
||||
path.push(document);
|
||||
if (path.indexOf(window) === -1)
|
||||
path.push(window);
|
||||
return path;
|
||||
}
|
||||
getpath(e).forEach(function (node) {
|
||||
if (!node.getAttribute) return;
|
||||
var id_ = node.getAttribute('id');
|
||||
if (id_) {
|
||||
if (['left', 'left1', 'left2', 'left3', 'left4', 'left5', 'left8', 'mobileview'].indexOf(id_) !== -1) clickpath.push('edit');
|
||||
clickpath.push(id_);
|
||||
}
|
||||
});
|
||||
return clickpath;
|
||||
}
|
||||
|
||||
/**
|
||||
* editor.dom.body.onmousedown
|
||||
* 检测鼠标点击,
|
||||
* + 如果选中了绘图区域之外, 就保存地图
|
||||
* + 维护绘图区的菜单的隐藏
|
||||
* + 记录最后一次点击的id(主要为了数据区服务)
|
||||
*/
|
||||
editor.uifunctions.body_click = function (e) {
|
||||
var clickpath = editor.uifunctions.getClickpath(e);
|
||||
|
||||
var unselect = true;
|
||||
for (var ii = 0, thisId; thisId = ['edit', 'tip', 'brushMod', 'brushMod2', 'brushMod3', 'layerMod', 'layerMod2', 'layerMod3', 'viewportButtons'][ii]; ii++) {
|
||||
if (clickpath.indexOf(thisId) !== -1) {
|
||||
unselect = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (unselect && !editor.uivalues.lockMode) {
|
||||
if (clickpath.indexOf('eui') === -1 && clickpath.indexOf('lastUsed') === -1) {
|
||||
if (selectBox.isSelected()) {
|
||||
editor_mode.onmode('');
|
||||
editor.file.saveFloorFile(function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw (err)
|
||||
}
|
||||
; printf('地图保存成功');
|
||||
});
|
||||
}
|
||||
selectBox.isSelected(false);
|
||||
editor.info = {};
|
||||
}
|
||||
}
|
||||
//editor.mode.onmode('');
|
||||
if (e.button != 2 && !editor.isMobile) {
|
||||
editor.uifunctions.hideMidMenu();
|
||||
}
|
||||
if (clickpath.indexOf('down') !== -1 && editor.isMobile && clickpath.indexOf('midMenu') === -1) {
|
||||
editor.uifunctions.hideMidMenu();
|
||||
}
|
||||
if (clickpath.length >= 2 && clickpath[0].indexOf('id_') === 0) { editor.lastClickId = clickpath[0] }
|
||||
}
|
||||
|
||||
/**
|
||||
* editor.dom.body.onkeydown
|
||||
* 绑定快捷键
|
||||
*/
|
||||
editor.uifunctions.body_shortcut = function (e) {
|
||||
|
||||
// UI预览 & 地图选点
|
||||
if (editor.uievent && editor.uievent.isOpen) {
|
||||
e.preventDefault();
|
||||
if (e.keyCode == 27) editor.uievent.close();
|
||||
else if (e.keyCode == 13) editor.uievent.confirm();
|
||||
else if (e.keyCode == 87) editor.uievent.move(0, -1)
|
||||
else if (e.keyCode == 65) editor.uievent.move(-1, 0)
|
||||
else if (e.keyCode == 83) editor.uievent.move(0, 1);
|
||||
else if (e.keyCode == 68) editor.uievent.move(1, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// 监听Ctrl+S保存
|
||||
if (e.ctrlKey && e.keyCode == 83) {
|
||||
e.preventDefault();
|
||||
if (editor_multi.id != "") {
|
||||
editor_multi.confirm(); // 保存脚本编辑器
|
||||
}
|
||||
else if (editor_blockly.id != "") {
|
||||
editor_blockly.confirm(); // 保存事件编辑器
|
||||
}
|
||||
else {
|
||||
editor_mode.saveFloor();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果是开启事件/脚本编辑器状态,则忽略
|
||||
if (editor_multi.id != "" || editor_blockly.id != "")
|
||||
return;
|
||||
|
||||
// PGUP和PGDOWN切换楼层
|
||||
if (e.keyCode == 33 || e.keyCode == 34) {
|
||||
e.preventDefault();
|
||||
var index = editor.core.floorIds.indexOf(editor.currentFloorId);
|
||||
var nextIndex = index + (e.keyCode == 33 ? 1 : -1);
|
||||
if (nextIndex >= 0 && nextIndex < editor.core.floorIds.length) {
|
||||
var toId = editor.core.floorIds[nextIndex];
|
||||
editor_mode.onmode('nextChange');
|
||||
editor_mode.onmode('floor');
|
||||
document.getElementById('selectFloor').value = toId;
|
||||
editor.changeFloor(toId);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var focusElement = document.activeElement;
|
||||
if (!focusElement || focusElement.tagName.toLowerCase() == 'body'
|
||||
|| focusElement.id == 'selectFloor') {
|
||||
|
||||
//Ctrl+z 撤销上一步undo
|
||||
if (e.keyCode == 90 && e.ctrlKey) {
|
||||
e.preventDefault();
|
||||
if (editor.uivalues.preMapData.length > 0) {
|
||||
var data = editor.uivalues.preMapData.pop();
|
||||
editor.map = JSON.parse(JSON.stringify(data.map));
|
||||
editor.fgmap = JSON.parse(JSON.stringify(data.fgmap));
|
||||
editor.bgmap = JSON.parse(JSON.stringify(data.bgmap));
|
||||
editor.updateMap();
|
||||
editor.uivalues.postMapData.push(data);
|
||||
printf("已撤销此操作,你可能需要重新保存地图。");
|
||||
}
|
||||
return;
|
||||
}
|
||||
//Ctrl+y 重做一步redo
|
||||
if (e.keyCode == 89 && e.ctrlKey) {
|
||||
e.preventDefault();
|
||||
if (editor.uivalues.postMapData.length > 0) {
|
||||
var data = editor.uivalues.postMapData.pop();
|
||||
editor.map = JSON.parse(JSON.stringify(data.map));
|
||||
editor.fgmap = JSON.parse(JSON.stringify(data.fgmap));
|
||||
editor.bgmap = JSON.parse(JSON.stringify(data.bgmap));
|
||||
editor.updateMap();
|
||||
editor.uivalues.preMapData.push(data);
|
||||
printf("已重做此操作,你可能需要重新保存地图。");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Ctrl+C, Ctrl+X, Ctrl+V
|
||||
if (e.ctrlKey && e.keyCode == 67 && !selectBox.isSelected()) {
|
||||
e.preventDefault();
|
||||
editor.uivalues.copyedInfo = editor.copyFromPos();
|
||||
printf('该点事件已复制');
|
||||
return;
|
||||
}
|
||||
if (e.ctrlKey && e.keyCode == 88 && !selectBox.isSelected()) {
|
||||
e.preventDefault();
|
||||
editor.uivalues.copyedInfo = editor.copyFromPos();
|
||||
editor.clearPos(true, null, function () {
|
||||
printf('该点事件已剪切');
|
||||
})
|
||||
return;
|
||||
}
|
||||
if (e.ctrlKey && e.keyCode == 86 && !selectBox.isSelected()) {
|
||||
e.preventDefault();
|
||||
if (!editor.uivalues.copyedInfo) {
|
||||
printe("没有复制的事件");
|
||||
return;
|
||||
}
|
||||
editor.pasteToPos(editor.uivalues.copyedInfo);
|
||||
editor.updateMap();
|
||||
editor.file.saveFloorFile(function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw (err)
|
||||
}
|
||||
; printf('粘贴事件成功');
|
||||
editor.drawPosSelection();
|
||||
});
|
||||
return;
|
||||
}
|
||||
// DELETE
|
||||
if (e.keyCode == 46 && !selectBox.isSelected()) {
|
||||
editor.clearPos(true);
|
||||
return;
|
||||
}
|
||||
// ESC
|
||||
if (e.keyCode == 27) {
|
||||
if (selectBox.isSelected()) {
|
||||
editor_mode.onmode('');
|
||||
editor.file.saveFloorFile(function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw (err)
|
||||
}
|
||||
; printf('地图保存成功');
|
||||
});
|
||||
}
|
||||
selectBox.isSelected(false);
|
||||
editor.info = {};
|
||||
return;
|
||||
}
|
||||
//alt + 0~9 改变快捷图块
|
||||
if (e.altKey && [48, 49, 50, 51, 52, 53, 54, 55, 56, 57].indexOf(e.keyCode) !== -1) {
|
||||
var infoToSave = JSON.stringify(editor.info || 0);
|
||||
if (infoToSave == JSON.stringify({})) return;
|
||||
editor.uivalues.shortcut[e.keyCode] = JSON.parse(infoToSave);
|
||||
printf('已保存该快捷图块, 数字键 ' + (e.keyCode - 48) + ' 使用.')
|
||||
editor.config.set('shortcut', editor.uivalues.shortcut);
|
||||
return;
|
||||
}
|
||||
//ctrl + 0~9 切换到快捷图块
|
||||
if ([48, 49, 50, 51, 52, 53, 54, 55, 56, 57].indexOf(e.keyCode) !== -1) {
|
||||
editor.setSelectBoxFromInfo(JSON.parse(JSON.stringify(editor.uivalues.shortcut[e.keyCode] || 0)));
|
||||
return;
|
||||
}
|
||||
switch (e.keyCode) {
|
||||
// WASD
|
||||
case 87: editor.moveViewport(0, -1); break;
|
||||
case 65: editor.moveViewport(-1, 0); break;
|
||||
case 83: editor.moveViewport(0, 1); break;
|
||||
case 68: editor.moveViewport(1, 0); break;
|
||||
// Z~.
|
||||
case 90: editor_mode.change('map'); break; // Z
|
||||
case 88: editor_mode.change('loc'); break; // X
|
||||
case 67: editor_mode.change('enemyitem'); break; // C
|
||||
case 86: editor_mode.change('floor'); break; // V
|
||||
case 66: editor_mode.change('tower'); break; // B
|
||||
case 78: editor_mode.change('functions'); break; // N
|
||||
case 77: editor_mode.change('appendpic'); break; // M
|
||||
case 188: editor_mode.change('commonevent'); break; // ,
|
||||
case 190: editor_mode.change('plugins'); break; // .
|
||||
// H
|
||||
case 72: editor.uifunctions.showHelp(); break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
editor.uifunctions.showHelp = function () {
|
||||
alert(
|
||||
"快捷操作帮助:\n" +
|
||||
"ESC / 点击空白处:自动保存当前修改" +
|
||||
"WASD / 长按箭头:平移大地图\n" +
|
||||
"PgUp, PgDn / 鼠标滚轮:上下切换楼层\n" +
|
||||
"Z~.(键盘的第三排):快捷切换标签\n" +
|
||||
"双击地图:选中对应点的素材\n" +
|
||||
"右键地图:弹出菜单栏\n" +
|
||||
"Alt+0~9:保存当前使用的图块\n" +
|
||||
"0~9:选中保存的图块\n" +
|
||||
"Ctrl+Z / Ctrl+Y:撤销/重做上次绘制\n" +
|
||||
"Ctrl+S:事件与脚本编辑器的保存并退出\n" +
|
||||
"双击事件编辑器:长文本编辑/脚本编辑/地图选点/UI绘制预览"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// ------ UI预览 & 地图选点相关 ------ //
|
||||
|
||||
var uievent = {
|
||||
elements: {},
|
||||
values: {},
|
||||
isOpen: false,
|
||||
mode: ""
|
||||
};
|
||||
|
||||
uievent.elements.div = document.getElementById('uieventDiv');
|
||||
uievent.elements.title = document.getElementById('uieventTitle');
|
||||
uievent.elements.yes = document.getElementById('uieventYes');
|
||||
uievent.elements.no = document.getElementById('uieventNo');
|
||||
uievent.elements.selectBackground = document.getElementById('uieventBackground');
|
||||
uievent.elements.selectPoint = document.getElementById('selectPoint');
|
||||
uievent.elements.selectFloor = document.getElementById('selectPointFloor');
|
||||
uievent.elements.selectPointBox = document.getElementById('selectPointBox');
|
||||
uievent.elements.body = document.getElementById('uieventBody');
|
||||
uievent.elements.selectPointButtons = document.getElementById('selectPointButtons');
|
||||
uievent.elements.canvas = document.getElementById('uievent');
|
||||
uievent.elements.usedFlags = document.getElementById('uieventUsedFlags');
|
||||
uievent.elements.usedFlagList = document.getElementById('uieventUsedFlagList');
|
||||
|
||||
uievent.confirm = function () {
|
||||
var callback = uievent.values.callback, floorId = uievent.values.floorId,
|
||||
x = uievent.values.x, y = uievent.values.y;
|
||||
uievent.close();
|
||||
if (callback) {
|
||||
callback(floorId, x, y);
|
||||
}
|
||||
}
|
||||
uievent.elements.yes.onclick = uievent.confirm;
|
||||
|
||||
uievent.close = function () {
|
||||
uievent.isOpen = false;
|
||||
uievent.elements.div.style.display = 'none';
|
||||
uievent.values = {};
|
||||
}
|
||||
uievent.elements.no.onclick = uievent.close;
|
||||
|
||||
uievent.elements.selectBackground.onchange = function () {
|
||||
uievent.drawPreviewUI();
|
||||
}
|
||||
|
||||
uievent.drawPreviewUI = function () {
|
||||
core.setAlpha('uievent', 1);
|
||||
core.clearMap('uievent');
|
||||
|
||||
// 绘制UI
|
||||
var background = uievent.elements.selectBackground.value;
|
||||
if (background == 'thumbnail') {
|
||||
core.drawThumbnail(editor.currentFloorId, null, {}, 'uievent');
|
||||
}
|
||||
else {
|
||||
core.fillRect('uievent', 0, 0, core.__PIXELS__, core.__PIXELS__, background);
|
||||
}
|
||||
|
||||
if (uievent.values.list instanceof Array) {
|
||||
uievent.values.list.forEach(function (data) {
|
||||
var type = data.type;
|
||||
if (!type || !core.ui["_uievent_" + type]) return;
|
||||
core.ui["_uievent_" + type](data);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
uievent.previewUI = function (list) {
|
||||
uievent.isOpen = true;
|
||||
uievent.elements.div.style.display = 'block';
|
||||
uievent.mode = 'previewUI';
|
||||
uievent.elements.selectPoint.style.display = 'none';
|
||||
uievent.elements.yes.style.display = 'none';
|
||||
uievent.elements.title.innerText = 'UI绘制预览';
|
||||
uievent.elements.selectBackground.style.display = 'inline';
|
||||
uievent.elements.selectBackground.value = 'thumbnail';
|
||||
uievent.elements.selectFloor.style.display = 'none';
|
||||
uievent.elements.selectPointBox.style.display = 'none';
|
||||
uievent.elements.canvas.style.display = 'block';
|
||||
uievent.elements.usedFlags.style.display = 'none';
|
||||
uievent.elements.usedFlagList.style.display = 'none';
|
||||
uievent.elements.body.style.overflow = "hidden";
|
||||
|
||||
uievent.values.list = list;
|
||||
uievent.drawPreviewUI();
|
||||
}
|
||||
|
||||
uievent.selectPoint = function (floorId, x, y, hideFloor, callback) {
|
||||
uievent.values.hideFloor = hideFloor;
|
||||
uievent.values.callback = callback;
|
||||
uievent.values.size = editor.isMobile ? window.innerWidth / core.__SIZE__ : 32;
|
||||
uievent.elements.selectPointBox.style.width = (uievent.values.size - 6) + "px";
|
||||
uievent.elements.selectPointBox.style.height = (uievent.values.size - 6) + "px";
|
||||
|
||||
uievent.isOpen = true;
|
||||
uievent.elements.div.style.display = 'block';
|
||||
uievent.mode = 'selectPoint';
|
||||
uievent.elements.selectPoint.style.display = 'block';
|
||||
uievent.elements.yes.style.display = 'inline';
|
||||
uievent.elements.selectBackground.style.display = 'none';
|
||||
uievent.elements.selectFloor.style.display = hideFloor ? 'none' : 'inline';
|
||||
uievent.elements.selectPointBox.style.display = 'block';
|
||||
uievent.elements.canvas.style.display = 'block';
|
||||
uievent.elements.usedFlags.style.display = 'none';
|
||||
uievent.elements.usedFlagList.style.display = 'none';
|
||||
uievent.elements.body.style.overflow = "hidden";
|
||||
|
||||
// Append children
|
||||
var floors = "";
|
||||
core.floorIds.forEach(function (f) {
|
||||
floors += "<option value=" + f + ">" + f + "</option>";
|
||||
})
|
||||
uievent.elements.selectFloor.innerHTML = floors;
|
||||
|
||||
this.setPoint(floorId || editor.currentFloorId, core.calValue(x) || 0, core.calValue(y) || 0);
|
||||
}
|
||||
|
||||
uievent.updateSelectPoint = function (redraw) {
|
||||
uievent.elements.title.innerText = '地图选点 (' + uievent.values.x + "," + uievent.values.y + ')';
|
||||
if (redraw) {
|
||||
core.setAlpha('uievent', 1);
|
||||
core.clearMap('uievent');
|
||||
core.drawThumbnail(uievent.values.floorId, null, null,
|
||||
{
|
||||
ctx: 'uievent', centerX: uievent.values.left + core.__HALF_SIZE__,
|
||||
centerY: uievent.values.top + core.__HALF_SIZE__
|
||||
});
|
||||
}
|
||||
uievent.elements.selectPointBox.style.left = uievent.values.size * (uievent.values.x - uievent.values.left) + "px";
|
||||
uievent.elements.selectPointBox.style.top = uievent.values.size * (uievent.values.y - uievent.values.top) + "px";
|
||||
}
|
||||
|
||||
uievent.setPoint = function (floorId, x, y) {
|
||||
if (core.floorIds.indexOf(floorId) == -1) floorId = editor.currentFloorId;
|
||||
uievent.values.floorId = floorId;
|
||||
uievent.elements.selectFloor.value = floorId;
|
||||
uievent.values.x = x != null ? x : (uievent.values.x || 0);
|
||||
uievent.values.y = y != null ? y : (uievent.values.y || 0);
|
||||
uievent.values.width = core.floors[uievent.values.floorId].width || core.__SIZE__;
|
||||
uievent.values.height = core.floors[uievent.values.floorId].height || core.__SIZE__;
|
||||
uievent.values.left = core.clamp(uievent.values.x - core.__HALF_SIZE__, 0, uievent.values.width - core.__SIZE__);
|
||||
uievent.values.top = core.clamp(uievent.values.y - core.__HALF_SIZE__, 0, uievent.values.height - core.__SIZE__);
|
||||
uievent.updateSelectPoint(true);
|
||||
}
|
||||
|
||||
uievent.elements.selectFloor.onchange = function () {
|
||||
uievent.setPoint(uievent.elements.selectFloor.value);
|
||||
}
|
||||
|
||||
uievent.elements.selectPointBox.onclick = function (e) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
uievent.elements.body.onclick = function (e) {
|
||||
if (uievent.mode != 'selectPoint') return;
|
||||
uievent.values.x = uievent.values.left + Math.floor(e.offsetX / uievent.values.size);
|
||||
uievent.values.y = uievent.values.top + Math.floor(e.offsetY / uievent.values.size);
|
||||
uievent.updateSelectPoint(false);
|
||||
}
|
||||
|
||||
uievent.move = function (dx, dy) {
|
||||
if (uievent.mode != 'selectPoint') return;
|
||||
uievent.values.left = core.clamp(uievent.values.left + dx, 0, uievent.values.width - core.__SIZE__);
|
||||
uievent.values.top = core.clamp(uievent.values.top + dy, 0, uievent.values.height - core.__SIZE__);
|
||||
this.updateSelectPoint(true);
|
||||
};
|
||||
|
||||
(function () {
|
||||
|
||||
var viewportButtons = uievent.elements.selectPointButtons;
|
||||
var pressTimer = null;
|
||||
for (var ii = 0, node; node = viewportButtons.children[ii]; ii++) {
|
||||
(function (x, y) {
|
||||
var move = function () {
|
||||
uievent.move(x, y);
|
||||
}
|
||||
node.onmousedown = function () {
|
||||
clearTimeout(pressTimer);
|
||||
pressTimer = setTimeout(function () {
|
||||
pressTimer = -1;
|
||||
var f = function () {
|
||||
if (pressTimer != null) {
|
||||
move();
|
||||
setTimeout(f, 150);
|
||||
}
|
||||
}
|
||||
f();
|
||||
}, 500);
|
||||
};
|
||||
node.onmouseup = function () {
|
||||
if (pressTimer > 0) {
|
||||
clearTimeout(pressTimer);
|
||||
move();
|
||||
}
|
||||
pressTimer = null;
|
||||
}
|
||||
})([-1, 0, 0, 1][ii], [0, -1, 1, 0][ii]);
|
||||
}
|
||||
})();
|
||||
|
||||
uievent.elements.div.onmousewheel = function (e) {
|
||||
if (uievent.mode != 'selectPoint' || uievent.values.hideFloor) return;
|
||||
var index = core.floorIds.indexOf(uievent.values.floorId);
|
||||
try {
|
||||
if (e.wheelDelta)
|
||||
index += Math.sign(e.wheelDelta);
|
||||
else if (e.detail)
|
||||
index += Math.sign(e.detail);
|
||||
} catch (ee) { main.log(ee); }
|
||||
index = core.clamp(index, 0, core.floorIds.length - 1);
|
||||
uievent.setPoint(core.floorIds[index]);
|
||||
}
|
||||
|
||||
// ------ 搜索变量出现的位置,也放在uievent好了 ------ //
|
||||
|
||||
uievent.searchUsedFlags = function () {
|
||||
uievent.isOpen = true;
|
||||
uievent.elements.div.style.display = 'block';
|
||||
uievent.mode = 'searchUsedFlags';
|
||||
uievent.elements.selectPoint.style.display = 'none';
|
||||
uievent.elements.yes.style.display = 'none';
|
||||
uievent.elements.title.innerText = '搜索变量';
|
||||
uievent.elements.selectBackground.style.display = 'none';
|
||||
uievent.elements.selectFloor.style.display = 'none';
|
||||
uievent.elements.selectPointBox.style.display = 'none';
|
||||
uievent.elements.canvas.style.display = 'none';
|
||||
uievent.elements.usedFlags.style.display = 'inline';
|
||||
uievent.elements.usedFlagList.style.display = 'block';
|
||||
uievent.elements.body.style.overflow = "auto";
|
||||
|
||||
// build flags
|
||||
var html = "";
|
||||
Object.keys(editor.used_flags).sort().forEach(function (v) {
|
||||
v = "flag:" + v;
|
||||
html += "<option value='" + v + "'>" + v + "</option>";
|
||||
});
|
||||
uievent.elements.usedFlags.innerHTML = html;
|
||||
|
||||
uievent.doSearchUsedFlags();
|
||||
}
|
||||
|
||||
uievent.doSearchUsedFlags = function () {
|
||||
var flag = uievent.elements.usedFlags.value;
|
||||
|
||||
var html = "<p style='margin-left: 10px'>该变量出现的所有位置如下:</p><ul>";
|
||||
var list = uievent._searchUsedFlags(flag);
|
||||
list.forEach(function (v) {
|
||||
var x = "<li>";
|
||||
if (v[0] != null) x += v[0] + "层 ";
|
||||
else x += "公共事件 ";
|
||||
x += v[1];
|
||||
if (v[2] != null) x += " 的 (" + v[2] + ") 点";
|
||||
x += "</li>";
|
||||
html += x;
|
||||
});
|
||||
html += "</ul>";
|
||||
uievent.elements.usedFlagList.innerHTML = html;
|
||||
}
|
||||
|
||||
var hasUsedFlags = function (obj, flag) {
|
||||
if (obj == null) return false;
|
||||
if (typeof obj != 'string') return hasUsedFlags(JSON.stringify(obj), flag);
|
||||
|
||||
var index = -1, length = flag.length;
|
||||
while (true) {
|
||||
index = obj.indexOf(flag, index + 1);
|
||||
if (index < 0) return false;
|
||||
if (!/^[a-zA-Z0-9_\u4E00-\u9FCC]$/.test(obj.charAt(index + length))) return true;
|
||||
}
|
||||
}
|
||||
|
||||
uievent._searchUsedFlags = function (flag) {
|
||||
var list = [];
|
||||
var events = ["events", "autoEvent", "changeFloor", "afterBattle", "afterGetItem", "afterOpenDoor"]
|
||||
for (var floorId in core.floors) {
|
||||
var floor = core.floors[floorId];
|
||||
if (hasUsedFlags(floor.firstArrive, flag)) list.push([floorId, "firstArrive"]);
|
||||
if (hasUsedFlags(floor.eachArrive, flag)) list.push([floorId, "eachArrive"]);
|
||||
events.forEach(function (e) {
|
||||
if (floor[e]) {
|
||||
for (var loc in floor[e]) {
|
||||
if (hasUsedFlags(floor[e][loc], flag)) {
|
||||
list.push([floorId, e, loc]);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
// 公共事件
|
||||
if (core.events.commonEvent) {
|
||||
for (var name in core.events.commonEvent) {
|
||||
if (hasUsedFlags(core.events.commonEvent[name], flag))
|
||||
list.push([null, name]);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
editor.constructor.prototype.uievent=uievent;
|
||||
|
||||
}
|
||||
@ -1,839 +0,0 @@
|
||||
editor_unsorted_1_wrapper=function(editor){
|
||||
|
||||
editor.constructor.prototype.listen=function () {
|
||||
document.body.onmousedown = function (e) {
|
||||
//console.log(e);
|
||||
var clickpath = [];
|
||||
var getpath=function(e) {
|
||||
var path = [];
|
||||
var currentElem = e.target;
|
||||
while (currentElem) {
|
||||
path.push(currentElem);
|
||||
currentElem = currentElem.parentElement;
|
||||
}
|
||||
if (path.indexOf(window) === -1 && path.indexOf(document) === -1)
|
||||
path.push(document);
|
||||
if (path.indexOf(window) === -1)
|
||||
path.push(window);
|
||||
return path;
|
||||
}
|
||||
getpath(e).forEach(function (node) {
|
||||
if (!node.getAttribute) return;
|
||||
var id_ = node.getAttribute('id');
|
||||
if (id_) {
|
||||
if (['left', 'left1', 'left2', 'left3', 'left4', 'left5', 'left8', 'mobileview'].indexOf(id_) !== -1) clickpath.push('edit');
|
||||
clickpath.push(id_);
|
||||
}
|
||||
});
|
||||
|
||||
var unselect=true;
|
||||
for(var ii=0,thisId;thisId=['edit','tip','brushMod','brushMod2','brushMod3','layerMod','layerMod2','layerMod3','viewportButtons'][ii];ii++){
|
||||
if (clickpath.indexOf(thisId) !== -1){
|
||||
unselect=false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (unselect) {
|
||||
if (clickpath.indexOf('eui') === -1) {
|
||||
if (selectBox.isSelected()) {
|
||||
editor_mode.onmode('');
|
||||
editor.file.saveFloorFile(function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw(err)
|
||||
}
|
||||
;printf('地图保存成功');
|
||||
});
|
||||
}
|
||||
selectBox.isSelected(false);
|
||||
editor.info = {};
|
||||
}
|
||||
}
|
||||
//editor.mode.onmode('');
|
||||
if (e.button!=2 && !editor.isMobile){
|
||||
editor.hideMidMenu();
|
||||
}
|
||||
if (clickpath.indexOf('down') !== -1 && editor.isMobile && clickpath.indexOf('midMenu') === -1){
|
||||
editor.hideMidMenu();
|
||||
}
|
||||
if(clickpath.length>=2 && clickpath[0].indexOf('id_')===0){editor.lastClickId=clickpath[0]}
|
||||
}
|
||||
|
||||
var eui=document.getElementById('eui');
|
||||
var uc = eui.getContext('2d');
|
||||
|
||||
function fillPos(pos) {
|
||||
uc.fillStyle = '#' + ~~(Math.random() * 8) + ~~(Math.random() * 8) + ~~(Math.random() * 8);
|
||||
uc.fillRect(pos.x * 32 + 12 - core.bigmap.offsetX, pos.y * 32 + 12 - core.bigmap.offsetY, 8, 8);
|
||||
}//在格子内画一个随机色块
|
||||
|
||||
function eToLoc(e) {
|
||||
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft
|
||||
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop
|
||||
var xx=e.clientX,yy=e.clientY
|
||||
if(editor.isMobile){xx=e.touches[0].clientX,yy=e.touches[0].clientY}
|
||||
editor.loc = {
|
||||
'x': scrollLeft + xx - mid.offsetLeft - mapEdit.offsetLeft,
|
||||
'y': scrollTop + yy - mid.offsetTop - mapEdit.offsetTop,
|
||||
'size': editor.isMobile?(32*innerWidth*0.96/core.__PIXELS__):32
|
||||
};
|
||||
return editor.loc;
|
||||
}//返回可用的组件内坐标
|
||||
|
||||
function locToPos(loc, addViewportOffset) {
|
||||
var offsetX=0, offsetY=0;
|
||||
if (addViewportOffset){
|
||||
offsetX=core.bigmap.offsetX/32;
|
||||
offsetY=core.bigmap.offsetY/32;
|
||||
}
|
||||
editor.pos = {'x': ~~(loc.x / loc.size)+offsetX, 'y': ~~(loc.y / loc.size)+offsetY}
|
||||
return editor.pos;
|
||||
}
|
||||
|
||||
var holdingPath = 0;
|
||||
var stepPostfix = null;//用于存放寻路检测的第一个点之后的后续移动
|
||||
|
||||
var mouseOutCheck = 2;
|
||||
|
||||
function clear1() {
|
||||
if (mouseOutCheck > 1) {
|
||||
mouseOutCheck--;
|
||||
setTimeout(clear1, 1000);
|
||||
return;
|
||||
}
|
||||
holdingPath = 0;
|
||||
stepPostfix = [];
|
||||
uc.clearRect(0, 0, core.__PIXELS__, core.__PIXELS__);
|
||||
}//用于鼠标移出canvas时的自动清除状态
|
||||
|
||||
eui.oncontextmenu=function(e){e.preventDefault()}
|
||||
|
||||
eui.ondblclick = function(e) {
|
||||
// 双击地图可以选中素材
|
||||
var loc = eToLoc(e);
|
||||
var pos = locToPos(loc,true);
|
||||
editor.setSelectBoxFromInfo(editor[editor.layerMod][pos.y][pos.x]);
|
||||
return;
|
||||
}
|
||||
|
||||
eui.onmousedown = function (e) {
|
||||
if (e.button==2){
|
||||
var loc = eToLoc(e);
|
||||
var pos = locToPos(loc,true);
|
||||
editor.showMidMenu(e.clientX,e.clientY);
|
||||
return;
|
||||
}
|
||||
if (!selectBox.isSelected()) {
|
||||
var loc = eToLoc(e);
|
||||
var pos = locToPos(loc,true);
|
||||
editor_mode.onmode('nextChange');
|
||||
editor_mode.onmode('loc');
|
||||
//editor_mode.loc();
|
||||
//tip.whichShow(1);
|
||||
if(editor.isMobile)editor.showMidMenu(e.clientX,e.clientY);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
holdingPath = 1;
|
||||
mouseOutCheck = 2;
|
||||
setTimeout(clear1);
|
||||
e.stopPropagation();
|
||||
uc.clearRect(0, 0, core.__PIXELS__, core.__PIXELS__);
|
||||
var loc = eToLoc(e);
|
||||
var pos = locToPos(loc,true);
|
||||
stepPostfix = [];
|
||||
stepPostfix.push(pos);
|
||||
fillPos(pos);
|
||||
}
|
||||
|
||||
eui.onmousemove = function (e) {
|
||||
if (!selectBox.isSelected()) {
|
||||
//tip.whichShow(1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (holdingPath == 0) {
|
||||
return;
|
||||
}
|
||||
mouseOutCheck = 2;
|
||||
e.stopPropagation();
|
||||
var loc = eToLoc(e);
|
||||
var pos = locToPos(loc,true);
|
||||
var pos0 = stepPostfix[stepPostfix.length - 1]
|
||||
var directionDistance = [pos.y - pos0.y, pos0.x - pos.x, pos0.y - pos.y, pos.x - pos0.x]
|
||||
var max = 0, index = 4;
|
||||
for (var i = 0; i < 4; i++) {
|
||||
if (directionDistance[i] > max) {
|
||||
index = i;
|
||||
max = directionDistance[i];
|
||||
}
|
||||
}
|
||||
var pos = [{'x': 0, 'y': 1}, {'x': -1, 'y': 0}, {'x': 0, 'y': -1}, {'x': 1, 'y': 0}, false][index]
|
||||
if (pos) {
|
||||
pos.x += pos0.x;
|
||||
pos.y += pos0.y;
|
||||
stepPostfix.push(pos);
|
||||
fillPos(pos);
|
||||
}
|
||||
}
|
||||
|
||||
eui.onmouseup = function (e) {
|
||||
if (!selectBox.isSelected()) {
|
||||
//tip.whichShow(1);
|
||||
return;
|
||||
}
|
||||
holdingPath = 0;
|
||||
e.stopPropagation();
|
||||
if (stepPostfix && stepPostfix.length) {
|
||||
editor.preMapData = JSON.parse(JSON.stringify({map:editor.map,fgmap:editor.fgmap,bgmap:editor.bgmap}));
|
||||
if(editor.brushMod!=='line'){
|
||||
var x0=stepPostfix[0].x;
|
||||
var y0=stepPostfix[0].y;
|
||||
var x1=stepPostfix[stepPostfix.length-1].x;
|
||||
var y1=stepPostfix[stepPostfix.length-1].y;
|
||||
if(x0>x1){x0^=x1;x1^=x0;x0^=x1;}//swap
|
||||
if(y0>y1){y0^=y1;y1^=y0;y0^=y1;}//swap
|
||||
stepPostfix=[];
|
||||
for(var jj=y0;jj<=y1;jj++){
|
||||
for(var ii=x0;ii<=x1;ii++){
|
||||
stepPostfix.push({x:ii,y:jj})
|
||||
}
|
||||
}
|
||||
}
|
||||
currDrawData.pos = JSON.parse(JSON.stringify(stepPostfix));
|
||||
currDrawData.info = JSON.parse(JSON.stringify(editor.info));
|
||||
reDo = null;
|
||||
// console.log(stepPostfix);
|
||||
if(editor.brushMod==='tileset' && core.tilesets.indexOf(editor.info.images)!==-1){
|
||||
var imgWidth=~~(core.material.images.tilesets[editor.info.images].width/32);
|
||||
var x0=stepPostfix[0].x;
|
||||
var y0=stepPostfix[0].y;
|
||||
var idnum=editor.info.idnum;
|
||||
for (var ii = 0; ii < stepPostfix.length; ii++){
|
||||
if(stepPostfix[ii].y!=y0){
|
||||
y0++;
|
||||
idnum+=imgWidth;
|
||||
}
|
||||
editor[editor.layerMod][stepPostfix[ii].y][stepPostfix[ii].x] = editor.ids[editor.indexs[idnum+stepPostfix[ii].x-x0]];
|
||||
}
|
||||
} else {
|
||||
for (var ii = 0; ii < stepPostfix.length; ii++)
|
||||
editor[editor.layerMod][stepPostfix[ii].y][stepPostfix[ii].x] = editor.info;
|
||||
}
|
||||
// console.log(editor.map);
|
||||
editor.updateMap();
|
||||
holdingPath = 0;
|
||||
stepPostfix = [];
|
||||
uc.clearRect(0, 0, core.__PIXELS__, core.__PIXELS__);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
document.getElementById('mid').onkeydown = function (e) {
|
||||
console.log(e);
|
||||
if (e.keyCode==37) {
|
||||
editor.moveViewport(-1, 0);
|
||||
}
|
||||
if (e.keyCode==38) {
|
||||
editor.moveViewport(0, -1);
|
||||
}
|
||||
if (e.keyCode==39) {
|
||||
editor.moveViewport(1, 0);
|
||||
}
|
||||
if (e.keyCode==40) {
|
||||
editor.moveViewport(0, 1);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
document.getElementById('mid').onmousewheel = function (e) {
|
||||
e.preventDefault();
|
||||
var wheel = function (direct) {
|
||||
var index=editor.core.floorIds.indexOf(editor.currentFloorId);
|
||||
var toId = editor.currentFloorId;
|
||||
|
||||
if (direct>0 && index<editor.core.floorIds.length-1)
|
||||
toId = editor.core.floorIds[index+1];
|
||||
else if (direct<0 && index>0)
|
||||
toId = editor.core.floorIds[index-1];
|
||||
else return;
|
||||
|
||||
editor_mode.onmode('nextChange');
|
||||
editor_mode.onmode('floor');
|
||||
document.getElementById('selectFloor').value = toId;
|
||||
editor.changeFloor(toId);
|
||||
}
|
||||
|
||||
try {
|
||||
if (e.wheelDelta)
|
||||
wheel(Math.sign(e.wheelDelta))
|
||||
else if (e.detail)
|
||||
wheel(Math.sign(e.detail));
|
||||
}
|
||||
catch (ee) {
|
||||
console.log(ee);
|
||||
}
|
||||
}
|
||||
|
||||
editor.preMapData = null;
|
||||
var currDrawData = {
|
||||
pos: [],
|
||||
info: {}
|
||||
};
|
||||
var reDo = null;
|
||||
var shortcut = core.getLocalStorage('shortcut',{48: 0, 49: 0, 50: 0, 51: 0, 52: 0, 53: 0, 54: 0, 55: 0, 56: 0, 57: 0});
|
||||
document.body.onkeydown = function (e) {
|
||||
|
||||
// 监听Ctrl+S保存
|
||||
if (e.ctrlKey && e.keyCode == 83) {
|
||||
e.preventDefault();
|
||||
if (editor_multi.id != "") {
|
||||
editor_multi.confirm(); // 保存脚本编辑器
|
||||
}
|
||||
else if (editor_blockly.id != "") {
|
||||
editor_blockly.confirm(); // 保存事件编辑器
|
||||
}
|
||||
else {
|
||||
editor_mode.saveFloor();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果是开启事件/脚本编辑器状态,则忽略
|
||||
if (editor_multi.id!="" || editor_blockly.id!="")
|
||||
return;
|
||||
|
||||
// 禁止快捷键的默认行为
|
||||
if (e.ctrlKey && [89, 90, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57].indexOf(e.keyCode) !== -1)
|
||||
e.preventDefault();
|
||||
if (e.altKey && [48, 49, 50, 51, 52, 53, 54, 55, 56, 57].indexOf(e.keyCode) !== -1)
|
||||
e.preventDefault();
|
||||
//Ctrl+z 撤销上一步undo
|
||||
if (e.keyCode == 90 && e.ctrlKey && editor.preMapData && currDrawData.pos.length && selectBox.isSelected()) {
|
||||
editor.map = JSON.parse(JSON.stringify(editor.preMapData.map));
|
||||
editor.fgmap = JSON.parse(JSON.stringify(editor.preMapData.fgmap));
|
||||
editor.bgmap = JSON.parse(JSON.stringify(editor.preMapData.bgmap));
|
||||
editor.updateMap();
|
||||
reDo = JSON.parse(JSON.stringify(currDrawData));
|
||||
currDrawData = {pos: [], info: {}};
|
||||
editor.preMapData = null;
|
||||
}
|
||||
//Ctrl+y 重做一步redo
|
||||
if (e.keyCode == 89 && e.ctrlKey && reDo && reDo.pos.length && selectBox.isSelected()) {
|
||||
editor.preMapData = JSON.parse(JSON.stringify({map:editor.map,fgmap:editor.fgmap,bgmap:editor.bgmap}));
|
||||
for (var j = 0; j < reDo.pos.length; j++)
|
||||
editor.map[reDo.pos[j].y][reDo.pos[j].x] = JSON.parse(JSON.stringify(reDo.info));
|
||||
|
||||
editor.updateMap();
|
||||
currDrawData = JSON.parse(JSON.stringify(reDo));
|
||||
reDo = null;
|
||||
}
|
||||
|
||||
// PGUP和PGDOWN切换楼层
|
||||
if (e.keyCode==33) {
|
||||
e.preventDefault();
|
||||
var index=editor.core.floorIds.indexOf(editor.currentFloorId);
|
||||
if (index<editor.core.floorIds.length-1) {
|
||||
var toId = editor.core.floorIds[index+1];
|
||||
editor_mode.onmode('nextChange');
|
||||
editor_mode.onmode('floor');
|
||||
document.getElementById('selectFloor').value = toId;
|
||||
editor.changeFloor(toId);
|
||||
}
|
||||
}
|
||||
if (e.keyCode==34) {
|
||||
e.preventDefault();
|
||||
var index=editor.core.floorIds.indexOf(editor.currentFloorId);
|
||||
if (index>0) {
|
||||
var toId = editor.core.floorIds[index-1];
|
||||
editor_mode.onmode('nextChange');
|
||||
editor_mode.onmode('floor');
|
||||
document.getElementById('selectFloor').value = toId;
|
||||
editor.changeFloor(toId);
|
||||
}
|
||||
}
|
||||
//ctrl + 0~9 切换到快捷图块
|
||||
if (e.ctrlKey && [48, 49, 50, 51, 52, 53, 54, 55, 56, 57].indexOf(e.keyCode) !== -1){
|
||||
editor.setSelectBoxFromInfo(JSON.parse(JSON.stringify(shortcut[e.keyCode]||0)));
|
||||
}
|
||||
//alt + 0~9 改变快捷图块
|
||||
if (e.altKey && [48, 49, 50, 51, 52, 53, 54, 55, 56, 57].indexOf(e.keyCode) !== -1){
|
||||
var infoToSave = JSON.stringify(editor.info||0);
|
||||
if(infoToSave==JSON.stringify({}))return;
|
||||
shortcut[e.keyCode]=JSON.parse(infoToSave);
|
||||
printf('已保存该快捷图块, ctrl + '+(e.keyCode-48)+' 使用.')
|
||||
core.setLocalStorage('shortcut',shortcut);
|
||||
}
|
||||
var focusElement = document.activeElement;
|
||||
if (!focusElement || focusElement.tagName.toLowerCase()=='body') {
|
||||
// wasd平移大地图
|
||||
if (e.keyCode==87)
|
||||
editor.moveViewport(0,-1)
|
||||
else if (e.keyCode==65)
|
||||
editor.moveViewport(-1,0)
|
||||
else if (e.keyCode==83)
|
||||
editor.moveViewport(0,1);
|
||||
else if (e.keyCode==68)
|
||||
editor.moveViewport(1,0);
|
||||
}
|
||||
}
|
||||
|
||||
var getScrollBarHeight = function () {
|
||||
var outer = document.createElement("div");
|
||||
outer.style.visibility = "hidden";
|
||||
outer.style.width = "100px";
|
||||
outer.style.msOverflowStyle = "scrollbar"; // needed for WinJS apps
|
||||
|
||||
document.body.appendChild(outer);
|
||||
|
||||
var widthNoScroll = outer.offsetWidth;
|
||||
// force scrollbars
|
||||
outer.style.overflow = "scroll";
|
||||
|
||||
// add innerdiv
|
||||
var inner = document.createElement("div");
|
||||
inner.style.width = "100%";
|
||||
outer.appendChild(inner);
|
||||
|
||||
var widthWithScroll = inner.offsetWidth;
|
||||
|
||||
// remove divs
|
||||
outer.parentNode.removeChild(outer);
|
||||
|
||||
return widthNoScroll - widthWithScroll;
|
||||
}
|
||||
var scrollBarHeight = getScrollBarHeight();
|
||||
|
||||
var dataSelection = document.getElementById('dataSelection');
|
||||
var iconLib=document.getElementById('iconLib');
|
||||
iconLib.onmousedown = function (e) {
|
||||
e.stopPropagation();
|
||||
if (!editor.isMobile && e.clientY>=((core.__SIZE__==13?630:655) - scrollBarHeight)) return;
|
||||
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
|
||||
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
|
||||
var loc = {
|
||||
'x': scrollLeft + e.clientX + iconLib.scrollLeft - right.offsetLeft - iconLib.offsetLeft,
|
||||
'y': scrollTop + e.clientY + iconLib.scrollTop - right.offsetTop - iconLib.offsetTop,
|
||||
'size': 32
|
||||
};
|
||||
editor.loc = loc;
|
||||
var pos = locToPos(loc);
|
||||
for (var spriter in editor.widthsX) {
|
||||
if (pos.x >= editor.widthsX[spriter][1] && pos.x < editor.widthsX[spriter][2]) {
|
||||
var ysize = spriter.indexOf('48') === -1 ? 32 : 48;
|
||||
loc.ysize = ysize;
|
||||
pos.images = editor.widthsX[spriter][0];
|
||||
pos.y = ~~(loc.y / loc.ysize);
|
||||
if(core.tilesets.indexOf(pos.images)==-1)pos.x = editor.widthsX[spriter][1];
|
||||
var autotiles = core.material.images['autotile'];
|
||||
if (pos.images == 'autotile') {
|
||||
var imNames = Object.keys(autotiles);
|
||||
if ((pos.y + 1) * ysize > editor.widthsX[spriter][3])
|
||||
pos.y = ~~(editor.widthsX[spriter][3] / ysize) - 4;
|
||||
else {
|
||||
for (var i = 0; i < imNames.length; i++) {
|
||||
if (pos.y >= 4 * i && pos.y < 4 * (i + 1)) {
|
||||
pos.images = imNames[i];
|
||||
pos.y = 4 * i;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ((pos.y + 1) * ysize > editor.widthsX[spriter][3])
|
||||
pos.y = ~~(editor.widthsX[spriter][3] / ysize) - 1;
|
||||
|
||||
selectBox.isSelected(true);
|
||||
// console.log(pos,core.material.images[pos.images].height)
|
||||
dataSelection.style.left = pos.x * 32 + 'px';
|
||||
dataSelection.style.top = pos.y * ysize + 'px';
|
||||
dataSelection.style.height = ysize - 6 + 'px';
|
||||
|
||||
if (pos.x == 0 && pos.y == 0) {
|
||||
// editor.info={idnum:0, id:'empty','images':'清除块', 'y':0};
|
||||
editor.info = 0;
|
||||
} else if(pos.x == 0 && pos.y == 1){
|
||||
editor.info = editor.ids[editor.indexs[17]];
|
||||
} else {
|
||||
if (Object.prototype.hasOwnProperty.call(autotiles, pos.images)) editor.info = {'images': pos.images, 'y': 0};
|
||||
else if (pos.images == 'terrains') editor.info = {'images': pos.images, 'y': pos.y - 2};
|
||||
else if (core.tilesets.indexOf(pos.images)!=-1) editor.info = {'images': pos.images, 'y': pos.y, 'x': pos.x-editor.widthsX[spriter][1]};
|
||||
else editor.info = {'images': pos.images, 'y': pos.y};
|
||||
|
||||
for (var ii = 0; ii < editor.ids.length; ii++) {
|
||||
if ((core.tilesets.indexOf(pos.images)!=-1 && editor.info.images == editor.ids[ii].images
|
||||
&& editor.info.y == editor.ids[ii].y && editor.info.x == editor.ids[ii].x)
|
||||
|| (Object.prototype.hasOwnProperty.call(autotiles, pos.images) && editor.info.images == editor.ids[ii].id
|
||||
&& editor.info.y == editor.ids[ii].y)
|
||||
|| (core.tilesets.indexOf(pos.images)==-1 && editor.info.images == editor.ids[ii].images
|
||||
&& editor.info.y == editor.ids[ii].y )
|
||||
) {
|
||||
|
||||
editor.info = editor.ids[ii];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
tip.infos(JSON.parse(JSON.stringify(editor.info)));
|
||||
editor_mode.onmode('nextChange');
|
||||
editor_mode.onmode('enemyitem');
|
||||
//editor_mode.enemyitem();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var midMenu=document.getElementById('midMenu');
|
||||
midMenu.oncontextmenu=function(e){e.preventDefault()}
|
||||
editor.lastRightButtonPos=[{x:0,y:0},{x:0,y:0}];
|
||||
editor.showMidMenu=function(x,y){
|
||||
editor.lastRightButtonPos=JSON.parse(JSON.stringify(
|
||||
[editor.pos,editor.lastRightButtonPos[0]]
|
||||
));
|
||||
var locStr='('+editor.lastRightButtonPos[1].x+','+editor.lastRightButtonPos[1].y+')';
|
||||
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
|
||||
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
|
||||
|
||||
// 检测是否是上下楼
|
||||
var thisevent = editor.map[editor.pos.y][editor.pos.x];
|
||||
if (thisevent.id=='upFloor') {
|
||||
addFloorEvent.style.display='block';
|
||||
addFloorEvent.children[0].innerHTML='绑定上楼事件';
|
||||
}
|
||||
else if (thisevent.id=='downFloor') {
|
||||
addFloorEvent.style.display='block';
|
||||
addFloorEvent.children[0].innerHTML='绑定下楼事件';
|
||||
}
|
||||
else addFloorEvent.style.display='none';
|
||||
|
||||
chooseThis.children[0].innerHTML='选中此点'+'('+editor.pos.x+','+editor.pos.y+')'
|
||||
copyLoc.children[0].innerHTML='复制事件'+locStr+'到此处';
|
||||
moveLoc.children[0].innerHTML='交换事件'+locStr+'与此事件的位置';
|
||||
midMenu.style='top:'+(y+scrollTop)+'px;left:'+(x+scrollLeft)+'px;';
|
||||
}
|
||||
editor.hideMidMenu=function(){
|
||||
if(editor.isMobile){
|
||||
setTimeout(function(){
|
||||
midMenu.style='display:none';
|
||||
},200)
|
||||
} else {
|
||||
midMenu.style='display:none';
|
||||
}
|
||||
}
|
||||
|
||||
var addFloorEvent = document.getElementById('addFloorEvent');
|
||||
addFloorEvent.onmousedown = function(e) {
|
||||
editor.hideMidMenu();
|
||||
e.stopPropagation();
|
||||
var thisevent = editor.map[editor.pos.y][editor.pos.x];
|
||||
if (thisevent.id=='upFloor') {
|
||||
editor.currentFloorData.changeFloor[editor.pos.x+","+editor.pos.y] = {"floorId": ":next", "stair": "downFloor"};
|
||||
}
|
||||
else if (thisevent.id=='downFloor') {
|
||||
editor.currentFloorData.changeFloor[editor.pos.x+","+editor.pos.y] = {"floorId": ":before", "stair": "upFloor"};
|
||||
}
|
||||
editor.file.saveFloorFile(function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw(err)
|
||||
}
|
||||
;printf('添加楼梯事件成功');
|
||||
editor.drawPosSelection();
|
||||
editor_mode.showMode('loc');
|
||||
});
|
||||
}
|
||||
|
||||
var chooseThis = document.getElementById('chooseThis');
|
||||
chooseThis.onmousedown = function(e){
|
||||
editor.hideMidMenu();
|
||||
e.stopPropagation();
|
||||
selectBox.isSelected(false);
|
||||
|
||||
editor_mode.onmode('nextChange');
|
||||
editor_mode.onmode('loc');
|
||||
//editor_mode.loc();
|
||||
//tip.whichShow(1);
|
||||
if(editor.isMobile)editor.showdataarea(false);
|
||||
}
|
||||
|
||||
var chooseInRight = document.getElementById('chooseInRight');
|
||||
chooseInRight.onmousedown = function(e){
|
||||
editor.hideMidMenu();
|
||||
e.stopPropagation();
|
||||
var thisevent = editor[editor.layerMod][editor.pos.y][editor.pos.x];
|
||||
editor.setSelectBoxFromInfo(thisevent);
|
||||
}
|
||||
|
||||
var fields = Object.keys(editor.file.comment._data.floors._data.loc._data);
|
||||
|
||||
var copyLoc = document.getElementById('copyLoc');
|
||||
copyLoc.onmousedown = function(e){
|
||||
editor.hideMidMenu();
|
||||
e.stopPropagation();
|
||||
editor.preMapData = null;
|
||||
reDo = null;
|
||||
editor_mode.onmode('');
|
||||
var now = editor.pos;
|
||||
var last = editor.lastRightButtonPos[1];
|
||||
var lastevent = editor.map[last.y][last.x];
|
||||
var lastinfo = 0;
|
||||
if(lastevent==0){
|
||||
lastinfo = 0;
|
||||
} else {
|
||||
var ids=editor.indexs[lastevent.idnum];
|
||||
ids=ids[0]?ids[0]:ids;
|
||||
lastinfo=editor.ids[ids];
|
||||
}
|
||||
editor.map[now.y][now.x]=lastinfo;
|
||||
editor.updateMap();
|
||||
fields.forEach(function(v){
|
||||
editor.currentFloorData[v][now.x+','+now.y]=editor.currentFloorData[v][last.x+','+last.y]
|
||||
})
|
||||
editor.file.saveFloorFile(function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw(err)
|
||||
}
|
||||
;printf('复制事件成功');
|
||||
editor.drawPosSelection();
|
||||
});
|
||||
}
|
||||
|
||||
var moveLoc = document.getElementById('moveLoc');
|
||||
moveLoc.onmousedown = function(e){
|
||||
editor.hideMidMenu();
|
||||
e.stopPropagation();
|
||||
editor.preMapData = null;
|
||||
reDo = null;
|
||||
var thisevent = editor.map[editor.pos.y][editor.pos.x];
|
||||
if(thisevent==0){
|
||||
editor.info = 0;
|
||||
} else {
|
||||
var ids=editor.indexs[thisevent.idnum];
|
||||
ids=ids[0]?ids[0]:ids;
|
||||
editor.info=editor.ids[ids];
|
||||
}
|
||||
editor_mode.onmode('');
|
||||
var now = editor.pos;
|
||||
var last = editor.lastRightButtonPos[1];
|
||||
|
||||
var lastevent = editor.map[last.y][last.x];
|
||||
var lastinfo = 0;
|
||||
if(lastevent==0){
|
||||
lastinfo = 0;
|
||||
} else {
|
||||
var ids=editor.indexs[lastevent.idnum];
|
||||
ids=ids[0]?ids[0]:ids;
|
||||
lastinfo=editor.ids[ids];
|
||||
}
|
||||
editor.map[last.y][last.x]=editor.info;
|
||||
editor.map[now.y][now.x]=lastinfo;
|
||||
editor.updateMap();
|
||||
|
||||
fields.forEach(function(v){
|
||||
var temp_atsfcytaf=editor.currentFloorData[v][now.x+','+now.y];
|
||||
editor.currentFloorData[v][now.x+','+now.y]=editor.currentFloorData[v][last.x+','+last.y];
|
||||
editor.currentFloorData[v][last.x+','+last.y]=temp_atsfcytaf;
|
||||
})
|
||||
editor.file.saveFloorFile(function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw(err)
|
||||
}
|
||||
;printf('两位置的事件已互换');
|
||||
editor.drawPosSelection();
|
||||
});
|
||||
}
|
||||
|
||||
var _clearPoint = function (clearPoint) {
|
||||
editor.hideMidMenu();
|
||||
editor.preMapData = null;
|
||||
reDo = null;
|
||||
editor.info = 0;
|
||||
editor_mode.onmode('');
|
||||
var now = editor.pos;
|
||||
if (clearPoint)
|
||||
editor.map[now.y][now.x]=editor.info;
|
||||
editor.updateMap();
|
||||
fields.forEach(function(v){
|
||||
delete editor.currentFloorData[v][now.x+','+now.y];
|
||||
})
|
||||
editor.file.saveFloorFile(function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw(err)
|
||||
}
|
||||
;printf(clearPoint?'清空该点和事件成功':'只清空该点事件成功');
|
||||
editor.drawPosSelection();
|
||||
});
|
||||
}
|
||||
|
||||
var clearEvent = document.getElementById('clearEvent');
|
||||
clearEvent.onmousedown = function (e) {
|
||||
e.stopPropagation();
|
||||
_clearPoint(false);
|
||||
}
|
||||
|
||||
var clearLoc = document.getElementById('clearLoc');
|
||||
clearLoc.onmousedown = function(e){
|
||||
e.stopPropagation();
|
||||
_clearPoint(true);
|
||||
}
|
||||
|
||||
var brushMod=document.getElementById('brushMod');
|
||||
brushMod.onchange=function(){
|
||||
editor.brushMod=brushMod.value;
|
||||
}
|
||||
|
||||
var brushMod2=document.getElementById('brushMod2');
|
||||
if(brushMod2)brushMod2.onchange=function(){
|
||||
editor.brushMod=brushMod2.value;
|
||||
}
|
||||
|
||||
var brushMod3=document.getElementById('brushMod3');
|
||||
if(brushMod3)brushMod3.onchange=function(){
|
||||
editor.brushMod=brushMod3.value;
|
||||
}
|
||||
|
||||
var bgc = document.getElementById('bg'), fgc = document.getElementById('fg'),
|
||||
evc = document.getElementById('event'), ev2c = document.getElementById('event2');
|
||||
|
||||
var layerMod=document.getElementById('layerMod');
|
||||
layerMod.onchange=function(){
|
||||
editor.layerMod=layerMod.value;
|
||||
[bgc,fgc,evc,ev2c].forEach(function (x) {
|
||||
x.style.opacity = 1;
|
||||
});
|
||||
|
||||
// 手机端....
|
||||
if (editor.isMobile) {
|
||||
if (layerMod.value == 'bgmap') {
|
||||
[fgc,evc,ev2c].forEach(function (x) {
|
||||
x.style.opacity = 0.3;
|
||||
});
|
||||
}
|
||||
if (layerMod.value == 'fgmap') {
|
||||
[bgc,evc,ev2c].forEach(function (x) {
|
||||
x.style.opacity = 0.3;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var layerMod2=document.getElementById('layerMod2');
|
||||
if(layerMod2)layerMod2.onchange=function(){
|
||||
editor.layerMod=layerMod2.value;
|
||||
[fgc,evc,ev2c].forEach(function (x) {
|
||||
x.style.opacity = 0.3;
|
||||
});
|
||||
bgc.style.opacity = 1;
|
||||
}
|
||||
|
||||
var layerMod3=document.getElementById('layerMod3');
|
||||
if(layerMod3)layerMod3.onchange=function(){
|
||||
editor.layerMod=layerMod3.value;
|
||||
[bgc,evc,ev2c].forEach(function (x) {
|
||||
x.style.opacity = 0.3;
|
||||
});
|
||||
fgc.style.opacity = 1;
|
||||
}
|
||||
|
||||
var viewportButtons=document.getElementById('viewportButtons');
|
||||
for(var ii=0,node;node=viewportButtons.children[ii];ii++){
|
||||
(function(x,y){
|
||||
node.onclick=function(){
|
||||
editor.moveViewport(x,y);
|
||||
}
|
||||
})([-1,0,0,1][ii],[0,-1,1,0][ii]);
|
||||
}
|
||||
}
|
||||
|
||||
editor.constructor.prototype.mobile_listen=function () {
|
||||
if(!editor.isMobile)return;
|
||||
|
||||
var mobileview=document.getElementById('mobileview');
|
||||
var editModeSelect=document.getElementById('editModeSelect');
|
||||
var mid=document.getElementById('mid');
|
||||
var right=document.getElementById('right');
|
||||
var mobileeditdata=document.getElementById('mobileeditdata');
|
||||
|
||||
|
||||
editor.showdataarea=function(callShowMode){
|
||||
mid.style='z-index:-1;opacity: 0;';
|
||||
right.style='z-index:-1;opacity: 0;';
|
||||
mobileeditdata.style='';
|
||||
if(callShowMode)editor.mode.showMode(editModeSelect.value);
|
||||
editor.hideMidMenu();
|
||||
}
|
||||
mobileview.children[0].onclick=function(){
|
||||
editor.showdataarea(true)
|
||||
}
|
||||
mobileview.children[1].onclick=function(){
|
||||
mid.style='';
|
||||
right.style='z-index:-1;opacity: 0;';
|
||||
mobileeditdata.style='z-index:-1;opacity: 0;';
|
||||
editor.lastClickId='';
|
||||
}
|
||||
mobileview.children[3].onclick=function(){
|
||||
mid.style='z-index:-1;opacity: 0;';
|
||||
right.style='';
|
||||
mobileeditdata.style='z-index:-1;opacity: 0;';
|
||||
editor.lastClickId='';
|
||||
}
|
||||
|
||||
|
||||
var gettrbyid=function(){
|
||||
if(!editor.lastClickId)return false;
|
||||
thisTr = document.getElementById(editor.lastClickId);
|
||||
input = thisTr.children[2].children[0].children[0];
|
||||
field = thisTr.children[0].getAttribute('title');
|
||||
cobj = JSON.parse(thisTr.children[1].getAttribute('cobj'));
|
||||
return [thisTr,input,field,cobj];
|
||||
}
|
||||
mobileeditdata.children[0].onclick=function(){
|
||||
var info = gettrbyid()
|
||||
if(!info)return;
|
||||
info[1].ondblclick()
|
||||
}
|
||||
mobileeditdata.children[1].onclick=function(){
|
||||
var info = gettrbyid()
|
||||
if(!info)return;
|
||||
printf(info[2])
|
||||
}
|
||||
mobileeditdata.children[2].onclick=function(){
|
||||
var info = gettrbyid()
|
||||
if(!info)return;
|
||||
printf(info[0].children[1].getAttribute('title'))
|
||||
}
|
||||
|
||||
//=====
|
||||
|
||||
document.body.ontouchstart=document.body.onmousedown;
|
||||
document.body.onmousedown=null;
|
||||
|
||||
|
||||
var eui=document.getElementById('eui');
|
||||
eui.ontouchstart=eui.onmousedown
|
||||
eui.onmousedown=null
|
||||
eui.ontouchmove=eui.onmousemove
|
||||
eui.onmousemove=null
|
||||
eui.ontouchend=eui.onmouseup
|
||||
eui.onmouseup=null
|
||||
|
||||
|
||||
var chooseThis = document.getElementById('chooseThis');
|
||||
chooseThis.ontouchstart=chooseThis.onmousedown
|
||||
chooseThis.onmousedown=null
|
||||
var chooseInRight = document.getElementById('chooseInRight');
|
||||
chooseInRight.ontouchstart=chooseInRight.onmousedown
|
||||
chooseInRight.onmousedown=null
|
||||
var copyLoc = document.getElementById('copyLoc');
|
||||
copyLoc.ontouchstart=copyLoc.onmousedown
|
||||
copyLoc.onmousedown=null
|
||||
var moveLoc = document.getElementById('moveLoc');
|
||||
moveLoc.ontouchstart=moveLoc.onmousedown
|
||||
moveLoc.onmousedown=null
|
||||
var clearLoc = document.getElementById('clearLoc');
|
||||
clearLoc.ontouchstart=clearLoc.onmousedown
|
||||
clearLoc.onmousedown=null
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,581 +0,0 @@
|
||||
editor_unsorted_2_wrapper=function(editor_mode){
|
||||
|
||||
editor_mode.constructor.prototype.listen=function (callback) {
|
||||
var newIdIdnum = document.getElementById('newIdIdnum');
|
||||
newIdIdnum.children[2].onclick = function () {
|
||||
if (newIdIdnum.children[0].value && newIdIdnum.children[1].value) {
|
||||
var id = newIdIdnum.children[0].value;
|
||||
var idnum = parseInt(newIdIdnum.children[1].value);
|
||||
if (!core.isset(idnum)) {
|
||||
printe('不合法的idnum');
|
||||
return;
|
||||
}
|
||||
if (!/^[0-9a-zA-Z_]+$/.test(id)) {
|
||||
printe('不合法的id,请使用字母、数字或下划线')
|
||||
return;
|
||||
}
|
||||
editor.file.changeIdAndIdnum(id, idnum, editor_mode.info, function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw(err)
|
||||
}
|
||||
printe('添加id的idnum成功,请F5刷新编辑器');
|
||||
});
|
||||
} else {
|
||||
printe('请输入id和idnum');
|
||||
}
|
||||
}
|
||||
|
||||
newIdIdnum.children[4].onclick = function () {
|
||||
editor.file.autoRegister(editor_mode.info, function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw(err)
|
||||
}
|
||||
printe('该列所有剩余项全部自动注册成功,请F5刷新编辑器');
|
||||
})
|
||||
}
|
||||
|
||||
var selectFloor = document.getElementById('selectFloor');
|
||||
editor.file.getFloorFileList(function (floors) {
|
||||
var outstr = [];
|
||||
floors[0].forEach(function (floor) {
|
||||
outstr.push(["<option value='", floor, "'>", floor, '</option>\n'].join(''));
|
||||
});
|
||||
selectFloor.innerHTML = outstr.join('');
|
||||
selectFloor.value = core.status.floorId;
|
||||
selectFloor.onchange = function () {
|
||||
editor_mode.onmode('nextChange');
|
||||
editor_mode.onmode('floor');
|
||||
editor.changeFloor(selectFloor.value);
|
||||
}
|
||||
});
|
||||
|
||||
var saveFloor = document.getElementById('saveFloor');
|
||||
editor_mode.saveFloor = function () {
|
||||
editor_mode.onmode('');
|
||||
editor.file.saveFloorFile(function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw(err)
|
||||
}
|
||||
;printf('保存成功');
|
||||
});
|
||||
}
|
||||
saveFloor.onclick = editor_mode.saveFloor;
|
||||
|
||||
var newMap = document.getElementById('newMap');
|
||||
var newFileName = document.getElementById('newFileName');
|
||||
newMap.onclick = function () {
|
||||
if (!newFileName.value) return;
|
||||
if (core.floorIds.indexOf(newFileName.value)>=0) {
|
||||
printe("该楼层已存在!");
|
||||
return;
|
||||
}
|
||||
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(newFileName.value)) {
|
||||
printe("楼层名不合法!请使用字母、数字、下划线,且不能以数字开头!");
|
||||
return;
|
||||
}
|
||||
var width = parseInt(document.getElementById('newMapWidth').value);
|
||||
var height = parseInt(document.getElementById('newMapHeight').value);
|
||||
if (!core.isset(width) || !core.isset(height) || width<core.__SIZE__ || height<core.__SIZE__ || width*height>1000) {
|
||||
printe("新建地图的宽高都不得小于"+core.__SIZE__+",且宽高之积不能超过1000");
|
||||
return;
|
||||
}
|
||||
|
||||
editor_mode.onmode('');
|
||||
editor.file.saveNewFile(newFileName.value, function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw(err)
|
||||
}
|
||||
core.floorIds.push(newFileName.value);
|
||||
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])
|
||||
}
|
||||
;printe('新建成功,请F5刷新编辑器生效');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var newMaps = document.getElementById('newMaps');
|
||||
var newFloors = document.getElementById('newFloors');
|
||||
newMaps.onclick = function () {
|
||||
if (newFloors.style.display == 'none') newFloors.style.display = 'block';
|
||||
else newFloors.style.display = 'none';
|
||||
}
|
||||
|
||||
var createNewMaps = document.getElementById('createNewMaps');
|
||||
createNewMaps.onclick = function () {
|
||||
var floorIds = document.getElementById('newFloorIds').value;
|
||||
if (!floorIds) return;
|
||||
var from = parseInt(document.getElementById('newMapsFrom').value),
|
||||
to = parseInt(document.getElementById('newMapsTo').value);
|
||||
if (!core.isset(from) || !core.isset(to) || from>to || from<0 || to<0) {
|
||||
printe("请输入有效的起始和终止楼层");
|
||||
return;
|
||||
}
|
||||
if (to-from >= 100) {
|
||||
printe("一次最多创建99个楼层");
|
||||
return;
|
||||
}
|
||||
var floorIdList = [];
|
||||
for (var i = from; i<=to; i++) {
|
||||
var floorId = floorIds.replace(/\${(.*?)}/g, function (word, value) {
|
||||
return eval(value);
|
||||
});
|
||||
if (core.floorIds.indexOf(floorId)>=0) {
|
||||
printe("要创建的楼层 "+floorId+" 已存在!");
|
||||
return;
|
||||
}
|
||||
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(floorId)) {
|
||||
printe("楼层名 "+floorId+" 不合法!请使用字母、数字、下划线,且不能以数字开头!");
|
||||
return;
|
||||
}
|
||||
if (floorIdList.indexOf(floorId)>=0) {
|
||||
printe("尝试重复创建楼层 "+floorId+" !");
|
||||
return;
|
||||
}
|
||||
floorIdList.push(floorId);
|
||||
}
|
||||
|
||||
var width = parseInt(document.getElementById('newMapsWidth').value);
|
||||
var height = parseInt(document.getElementById('newMapsHeight').value);
|
||||
if (!core.isset(width) || !core.isset(height) || width<core.__SIZE__ || height<core.__SIZE__ || width*height>1000) {
|
||||
printe("新建地图的宽高都不得小于"+core.__SIZE__+",且宽高之积不能超过1000");
|
||||
return;
|
||||
}
|
||||
editor_mode.onmode('');
|
||||
|
||||
editor.file.saveNewFiles(floorIdList, from, to, function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw(err)
|
||||
}
|
||||
core.floorIds = core.floorIds.concat(floorIdList);
|
||||
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])
|
||||
}
|
||||
;printe('批量创建 '+floorIdList[0]+'~'+floorIdList[floorIdList.length-1]+' 成功,请F5刷新编辑器生效');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var ratio = 1;
|
||||
var appendPicCanvas = document.getElementById('appendPicCanvas');
|
||||
var bg = appendPicCanvas.children[0];
|
||||
var source = appendPicCanvas.children[1];
|
||||
var source_ctx=source.getContext('2d');
|
||||
var picClick = appendPicCanvas.children[2];
|
||||
var sprite = appendPicCanvas.children[3];
|
||||
var sprite_ctx=sprite.getContext('2d');
|
||||
var appendPicSelection = document.getElementById('appendPicSelection');
|
||||
|
||||
[source_ctx,sprite_ctx].forEach(function(ctx){
|
||||
ctx.mozImageSmoothingEnabled = false;
|
||||
ctx.webkitImageSmoothingEnabled = false;
|
||||
ctx.msImageSmoothingEnabled = false;
|
||||
ctx.imageSmoothingEnabled = false;
|
||||
})
|
||||
|
||||
var selectAppend = document.getElementById('selectAppend');
|
||||
var selectAppend_str = [];
|
||||
["terrains", "animates", "enemys", "enemy48", "items", "npcs", "npc48", "autotile"].forEach(function (image) {
|
||||
selectAppend_str.push(["<option value='", image, "'>", image, '</option>\n'].join(''));
|
||||
});
|
||||
selectAppend.innerHTML = selectAppend_str.join('');
|
||||
selectAppend.onchange = function () {
|
||||
|
||||
var value = selectAppend.value;
|
||||
|
||||
if (value == 'autotile') {
|
||||
editor_mode.appendPic.imageName = 'autotile';
|
||||
for (var jj=0;jj<4;jj++) appendPicSelection.children[jj].style = 'display:none';
|
||||
if (editor_mode.appendPic.img) {
|
||||
sprite.style.width = (sprite.width = editor_mode.appendPic.img.width) / ratio + 'px';
|
||||
sprite.style.height = (sprite.height = editor_mode.appendPic.img.height) / ratio + 'px';
|
||||
sprite_ctx.clearRect(0, 0, sprite.width, sprite.height);
|
||||
sprite_ctx.drawImage(editor_mode.appendPic.img, 0, 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var ysize = selectAppend.value.endsWith('48') ? 48 : 32;
|
||||
editor_mode.appendPic.imageName = value;
|
||||
var img = core.material.images[value];
|
||||
editor_mode.appendPic.toImg = img;
|
||||
var num = ~~img.width / 32;
|
||||
editor_mode.appendPic.num = num;
|
||||
editor_mode.appendPic.index = 0;
|
||||
var selectStr = '';
|
||||
for (var ii = 0; ii < num; ii++) {
|
||||
appendPicSelection.children[ii].style = 'left:0;top:0;height:' + (ysize - 6) + 'px';
|
||||
selectStr += '{"x":0,"y":0},'
|
||||
}
|
||||
editor_mode.appendPic.selectPos = eval('[' + selectStr + ']');
|
||||
for (var jj = num; jj < 4; jj++) {
|
||||
appendPicSelection.children[jj].style = 'display:none';
|
||||
}
|
||||
sprite.style.width = (sprite.width = img.width) / ratio + 'px';
|
||||
sprite.style.height = (sprite.height = img.height + ysize) / ratio + 'px';
|
||||
sprite_ctx.drawImage(img, 0, 0);
|
||||
}
|
||||
selectAppend.onchange();
|
||||
|
||||
var getPixel=editor.util.getPixel
|
||||
var setPixel=editor.util.setPixel
|
||||
|
||||
var autoAdjust = function (image, callback) {
|
||||
var changed = false;
|
||||
|
||||
// Step 1: 检测白底
|
||||
var tempCanvas = document.createElement('canvas').getContext('2d');
|
||||
tempCanvas.canvas.width = image.width;
|
||||
tempCanvas.canvas.height = image.height;
|
||||
tempCanvas.mozImageSmoothingEnabled = false;
|
||||
tempCanvas.webkitImageSmoothingEnabled = false;
|
||||
tempCanvas.msImageSmoothingEnabled = false;
|
||||
tempCanvas.imageSmoothingEnabled = false;
|
||||
tempCanvas.drawImage(image, 0, 0);
|
||||
var imgData = tempCanvas.getImageData(0, 0, image.width, image.height);
|
||||
var trans = 0, white = 0, black=0;
|
||||
for (var i=0;i<image.width;i++) {
|
||||
for (var j=0;j<image.height;j++) {
|
||||
var pixel = getPixel(imgData, i, j);
|
||||
if (pixel[3]==0) trans++;
|
||||
if (pixel[0]==255 && pixel[1]==255 && pixel[2]==255 && pixel[3]==255) white++;
|
||||
// if (pixel[0]==0 && pixel[1]==0 && pixel[2]==0 && pixel[3]==255) black++;
|
||||
}
|
||||
}
|
||||
if (white>black && white>trans*10 && confirm("看起来这张图片是以纯白为底色,是否自动调整为透明底色?")) {
|
||||
for (var i=0;i<image.width;i++) {
|
||||
for (var j=0;j<image.height;j++) {
|
||||
var pixel = getPixel(imgData, i, j);
|
||||
if (pixel[0]==255 && pixel[1]==255 && pixel[2]==255 && pixel[3]==255) {
|
||||
setPixel(imgData, i, j, [0,0,0,0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
tempCanvas.clearRect(0, 0, image.width, image.height);
|
||||
tempCanvas.putImageData(imgData, 0, 0);
|
||||
changed = true;
|
||||
}
|
||||
/*
|
||||
if (black>white && black>trans*10 && confirm("看起来这张图片是以纯黑为底色,是否自动调整为透明底色?")) {
|
||||
for (var i=0;i<image.width;i++) {
|
||||
for (var j=0;j<image.height;j++) {
|
||||
var pixel = getPixel(imgData, i, j);
|
||||
if (pixel[0]==0 && pixel[1]==0 && pixel[2]==0 && pixel[3]==255) {
|
||||
setPixel(imgData, i, j, [0,0,0,0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
tempCanvas.clearRect(0, 0, image.width, image.height);
|
||||
tempCanvas.putImageData(imgData, 0, 0);
|
||||
changed = true;
|
||||
}
|
||||
*/
|
||||
|
||||
// Step 2: 检测长宽比
|
||||
var ysize = selectAppend.value.endsWith('48') ? 48 : 32;
|
||||
if ((image.width%32!=0 || image.height%ysize!=0) && (image.width<=128 && image.height<=ysize*4)
|
||||
&& confirm("目标长宽不符合条件,是否自动进行调整?")) {
|
||||
var ncanvas = document.createElement('canvas').getContext('2d');
|
||||
ncanvas.canvas.width = 128;
|
||||
ncanvas.canvas.height = 4*ysize;
|
||||
ncanvas.mozImageSmoothingEnabled = false;
|
||||
ncanvas.webkitImageSmoothingEnabled = false;
|
||||
ncanvas.msImageSmoothingEnabled = false;
|
||||
ncanvas.imageSmoothingEnabled = false;
|
||||
var w = image.width / 4, h = image.height / 4;
|
||||
for (var i=0;i<4;i++) {
|
||||
for (var j=0;j<4;j++) {
|
||||
ncanvas.drawImage(tempCanvas.canvas, i*w, j*h, w, h, i*32 + (32-w)/2, j*ysize + (ysize-h)/2, w, h);
|
||||
}
|
||||
}
|
||||
tempCanvas = ncanvas;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (!changed) {
|
||||
callback(image);
|
||||
}
|
||||
else {
|
||||
var nimg = new Image();
|
||||
nimg.onload = function () {
|
||||
callback(nimg);
|
||||
};
|
||||
nimg.src = tempCanvas.canvas.toDataURL();
|
||||
}
|
||||
}
|
||||
|
||||
var selectFileBtn = document.getElementById('selectFileBtn');
|
||||
selectFileBtn.onclick = function () {
|
||||
var loadImage = function (content, callback) {
|
||||
var image = new Image();
|
||||
try {
|
||||
image.onload = function () {
|
||||
callback(image);
|
||||
}
|
||||
image.src = content;
|
||||
}
|
||||
catch (e) {
|
||||
printe(e);
|
||||
}
|
||||
}
|
||||
core.readFile(function (content) {
|
||||
loadImage(content, function (image) {
|
||||
autoAdjust(image, function (image) {
|
||||
editor_mode.appendPic.img = image;
|
||||
editor_mode.appendPic.width = image.width;
|
||||
editor_mode.appendPic.height = image.height;
|
||||
|
||||
if (selectAppend.value == 'autotile') {
|
||||
for (var ii = 0; ii < 3; ii++) {
|
||||
var newsprite = appendPicCanvas.children[ii];
|
||||
newsprite.style.width = (newsprite.width = image.width) / ratio + 'px';
|
||||
newsprite.style.height = (newsprite.height = image.height) / ratio + 'px';
|
||||
}
|
||||
sprite_ctx.clearRect(0, 0, sprite.width, sprite.height);
|
||||
sprite_ctx.drawImage(image, 0, 0);
|
||||
}
|
||||
else {
|
||||
var ysize = selectAppend.value.endsWith('48') ? 48 : 32;
|
||||
for (var ii = 0; ii < 3; ii++) {
|
||||
var newsprite = appendPicCanvas.children[ii];
|
||||
newsprite.style.width = (newsprite.width = Math.floor(image.width / 32) * 32) / ratio + 'px';
|
||||
newsprite.style.height = (newsprite.height = Math.floor(image.height / ysize) * ysize) / ratio + 'px';
|
||||
}
|
||||
}
|
||||
|
||||
//画灰白相间的格子
|
||||
var bgc = bg.getContext('2d');
|
||||
var colorA = ["#f8f8f8", "#cccccc"];
|
||||
var colorIndex;
|
||||
var sratio = 4;
|
||||
for (var ii = 0; ii < image.width / 32 * sratio; ii++) {
|
||||
colorIndex = 1 - ii % 2;
|
||||
for (var jj = 0; jj < image.height / 32 * sratio; jj++) {
|
||||
bgc.fillStyle = colorA[colorIndex];
|
||||
colorIndex = 1 - colorIndex;
|
||||
bgc.fillRect(ii * 32 / sratio, jj * 32 / sratio, 32 / sratio, 32 / sratio);
|
||||
}
|
||||
}
|
||||
|
||||
//把导入的图片画出
|
||||
source_ctx.drawImage(image, 0, 0);
|
||||
editor_mode.appendPic.sourceImageData=source_ctx.getImageData(0,0,image.width,image.height);
|
||||
|
||||
//重置临时变量
|
||||
selectAppend.onchange();
|
||||
});
|
||||
});
|
||||
}, null, 'img');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var changeColorInput=document.getElementById('changeColorInput')
|
||||
changeColorInput.oninput=function(){
|
||||
var delta=(~~changeColorInput.value)*30;
|
||||
var imgData=editor_mode.appendPic.sourceImageData;
|
||||
var nimgData=new ImageData(imgData.width,imgData.height);
|
||||
// ImageData .data 形如一维数组,依次排着每个点的 R(0~255) G(0~255) B(0~255) A(0~255)
|
||||
var convert=function(rgba,delta){
|
||||
var rgbToHsl = editor.util.rgbToHsl
|
||||
var hue2rgb = editor.util.hue2rgb
|
||||
var hslToRgb = editor.util.hslToRgb
|
||||
//
|
||||
var hsl=rgbToHsl(rgba)
|
||||
hsl[0]=(hsl[0]+delta)%360
|
||||
var nrgb=hslToRgb(hsl)
|
||||
nrgb.push(rgba[3])
|
||||
return nrgb
|
||||
}
|
||||
for(var x=0; x<imgData.width; x++){
|
||||
for(var y=0 ; y<imgData.height; y++){
|
||||
setPixel(nimgData,x,y,convert(getPixel(imgData,x,y),delta))
|
||||
}
|
||||
}
|
||||
source_ctx.clearRect(0, 0, imgData.width, imgData.height);
|
||||
source_ctx.putImageData(nimgData, 0, 0);
|
||||
}
|
||||
|
||||
var left1 = document.getElementById('left1');
|
||||
var eToLoc = function (e) {
|
||||
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft
|
||||
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop
|
||||
var loc = {
|
||||
'x': scrollLeft + e.clientX + appendPicCanvas.scrollLeft - left1.offsetLeft - appendPicCanvas.offsetLeft,
|
||||
'y': scrollTop + e.clientY + appendPicCanvas.scrollTop - left1.offsetTop - appendPicCanvas.offsetTop,
|
||||
'size': 32,
|
||||
'ysize': selectAppend.value.endsWith('48') ? 48 : 32
|
||||
};
|
||||
return loc;
|
||||
}//返回可用的组件内坐标
|
||||
|
||||
var locToPos = function (loc) {
|
||||
var pos = {'x': ~~(loc.x / loc.size), 'y': ~~(loc.y / loc.ysize), 'ysize': loc.ysize}
|
||||
return pos;
|
||||
}
|
||||
|
||||
picClick.onclick = function (e) {
|
||||
var loc = eToLoc(e);
|
||||
var pos = locToPos(loc);
|
||||
//console.log(e,loc,pos);
|
||||
var num = editor_mode.appendPic.num;
|
||||
var ii = editor_mode.appendPic.index;
|
||||
if (ii + 1 >= num) editor_mode.appendPic.index = ii + 1 - num;
|
||||
else editor_mode.appendPic.index++;
|
||||
editor_mode.appendPic.selectPos[ii] = pos;
|
||||
appendPicSelection.children[ii].style = [
|
||||
'left:', pos.x * 32, 'px;',
|
||||
'top:', pos.y * pos.ysize, 'px;',
|
||||
'height:', pos.ysize - 6, 'px;'
|
||||
].join('');
|
||||
}
|
||||
|
||||
var appendConfirm = document.getElementById('appendConfirm');
|
||||
appendConfirm.onclick = function () {
|
||||
|
||||
var confirmAutotile = function () {
|
||||
var image = editor_mode.appendPic.img;
|
||||
if (image.width % 96 !=0 || image.height != 128) {
|
||||
printe("不合法的Autotile图片!");
|
||||
return;
|
||||
}
|
||||
var imgData = source_ctx.getImageData(0,0,image.width,image.height);
|
||||
sprite_ctx.putImageData(imgData, 0, 0);
|
||||
var imgbase64 = sprite.toDataURL().split(',')[1];
|
||||
|
||||
// Step 1: List文件名
|
||||
fs.readdir('./project/images', function (err, data) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw(err);
|
||||
}
|
||||
|
||||
// Step 2: 选择Autotile文件名
|
||||
var filename;
|
||||
for (var i=1;;++i) {
|
||||
filename = 'autotile'+i;
|
||||
if (data.indexOf(filename+".png")==-1) break;
|
||||
}
|
||||
|
||||
// Step 3: 写入文件
|
||||
fs.writeFile('./project/images/'+filename+".png", imgbase64, 'base64', function (err, data) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw(err);
|
||||
}
|
||||
// Step 4: 自动注册
|
||||
editor_file.registerAutotile(filename, function (err) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw(err);
|
||||
}
|
||||
printe('自动元件'+filename+'注册成功,请F5刷新编辑器');
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
if (selectAppend.value == 'autotile') {
|
||||
confirmAutotile();
|
||||
return;
|
||||
}
|
||||
|
||||
var ysize = selectAppend.value.endsWith('48') ? 48 : 32;
|
||||
for (var ii = 0, v; v = editor_mode.appendPic.selectPos[ii]; ii++) {
|
||||
// var imgData = source_ctx.getImageData(v.x * 32, v.y * ysize, 32, ysize);
|
||||
// sprite_ctx.putImageData(imgData, ii * 32, sprite.height - ysize);
|
||||
// sprite_ctx.drawImage(editor_mode.appendPic.img, v.x * 32, v.y * ysize, 32, ysize, ii * 32, height, 32, ysize)
|
||||
|
||||
sprite_ctx.drawImage(source_ctx.canvas, v.x*32, v.y*ysize, 32, ysize, 32*ii, sprite.height - ysize, 32, ysize);
|
||||
}
|
||||
var dt = sprite_ctx.getImageData(0, 0, sprite.width, sprite.height);
|
||||
var imgbase64 = sprite.toDataURL().split(',')[1];
|
||||
fs.writeFile('./project/images/' + editor_mode.appendPic.imageName + '.png', imgbase64, 'base64', function (err, data) {
|
||||
if (err) {
|
||||
printe(err);
|
||||
throw(err)
|
||||
}
|
||||
printe('追加素材成功,请F5刷新编辑器,或继续追加当前素材');
|
||||
sprite.style.height = (sprite.height = (sprite.height+ysize)) + "px";
|
||||
sprite_ctx.putImageData(dt, 0, 0);
|
||||
});
|
||||
}
|
||||
|
||||
var editModeSelect = document.getElementById('editModeSelect');
|
||||
editModeSelect.onchange = function () {
|
||||
editor_mode.onmode('nextChange');
|
||||
editor_mode.onmode(editModeSelect.value);
|
||||
if(editor.isMobile)editor.showdataarea(false);
|
||||
}
|
||||
|
||||
editor_mode.checkUnique = function (thiseval) {
|
||||
if (!(thiseval instanceof Array)) return false;
|
||||
var map = {};
|
||||
for (var i = 0; i<thiseval.length; ++i) {
|
||||
if (map[thiseval[i]]) {
|
||||
alert("警告:存在重复定义!");
|
||||
return false;
|
||||
}
|
||||
map[thiseval[i]] = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
editor_mode.checkFloorIds = function(thiseval){
|
||||
if (!editor_mode.checkUnique(thiseval)) return false;
|
||||
var oldvalue = data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.main.floorIds;
|
||||
fs.readdir('project/floors',function(err, data){
|
||||
if(err){
|
||||
printe(err);
|
||||
throw Error(err);
|
||||
}
|
||||
var newfiles=thiseval.map(function(v){return v+'.js'});
|
||||
var notExist='';
|
||||
for(var name,ii=0;name=newfiles[ii];ii++){
|
||||
if(data.indexOf(name)===-1)notExist=name;
|
||||
}
|
||||
if(notExist){
|
||||
var discard=confirm('文件'+notExist+'不存在, 保存会导致工程无法打开, 是否放弃更改');
|
||||
if(discard){
|
||||
editor.file.editTower([['change', "['main']['floorIds']", oldvalue]], function (objs_) {//console.log(objs_);
|
||||
if (objs_.slice(-1)[0] != null) {
|
||||
printe(objs_.slice(-1)[0]);
|
||||
throw(objs_.slice(-1)[0])
|
||||
}
|
||||
;printe('已放弃floorIds的修改,请F5进行刷新');
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
return true
|
||||
}
|
||||
|
||||
editor_mode.changeDoubleClickModeByButton=function(mode){
|
||||
({
|
||||
delete:function(){
|
||||
printf('下一次双击表格的项删除,切换下拉菜单可取消;编辑后需刷新浏览器生效。');
|
||||
editor_mode.doubleClickMode=mode;
|
||||
},
|
||||
add:function(){
|
||||
printf('下一次双击表格的项则在同级添加新项,切换下拉菜单可取消;编辑后需刷新浏览器生效。');
|
||||
editor_mode.doubleClickMode=mode;
|
||||
}
|
||||
}[mode])();
|
||||
}
|
||||
|
||||
if (Boolean(callback)) callback();
|
||||
}
|
||||
|
||||
}
|
||||
@ -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);
|
||||