commit
eb108f8f7c
689
_docs/_api.md
Normal file
689
_docs/_api.md
Normal file
@ -0,0 +1,689 @@
|
||||
# 附录: API列表
|
||||
|
||||
?> 目前版本**v2.6**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
**这里只列出所有可能会被造塔者用到的常用API,更多的有关内容请在代码内进行查询。**
|
||||
|
||||
如有任何疑问,请联系小艾寻求帮助。
|
||||
|
||||
可以在chrome浏览器的控制台中(`ctrl+shift+I`,找到Console)中直接进行调用,以查看效果。
|
||||
|
||||
**以下所有异步API都会加上[异步]的说明,存在此说明的请勿在事件处理的自定义脚本中使用。**
|
||||
|
||||
!> 最常用的新手向命令,强烈建议每个人了解
|
||||
|
||||
``` text
|
||||
|
||||
core.status.floorId
|
||||
获得当前层的floorId。
|
||||
|
||||
|
||||
core.status.maps
|
||||
获得所有楼层的地图信息。
|
||||
|
||||
|
||||
core.status.thisMap
|
||||
获得当前楼层信息,其等价于core.status.maps[core.status.floorId]。
|
||||
|
||||
|
||||
core.floors
|
||||
获得所有楼层的信息。例如core.floors[core.status.floorId].events可获得本楼层的所有自定义事件。
|
||||
|
||||
|
||||
core.status.hero
|
||||
获得当前勇士状态信息。例如core.status.hero.atk就是当前勇士的攻击力数值。
|
||||
|
||||
|
||||
core.material.enemys
|
||||
获得所有怪物信息。例如core.material.enemys.greenSlime就是获得绿色史莱姆的属性数据。
|
||||
|
||||
|
||||
core.material.items
|
||||
获得所有道具的信息。
|
||||
|
||||
|
||||
core.debug()
|
||||
开启调试模式。此模式下可以按Ctrl键进行穿墙,并忽略一切事件。
|
||||
此模式下不可回放录像和上传成绩。
|
||||
|
||||
|
||||
core.updateStatusBar()
|
||||
立刻刷新状态栏和地图显伤。
|
||||
|
||||
|
||||
core.setStatus('atk', 1000)
|
||||
将攻击力设置为1000;这里把atk可以改成hp, def, mdef, money, experience等等。
|
||||
本句等价于 core.status.hero.atk = 1000
|
||||
|
||||
|
||||
core.getStatus('atk')
|
||||
返回当前攻击力数值。本句等价于 core.status.hero.atk。
|
||||
|
||||
|
||||
core.setHeroLoc('x', 5)
|
||||
设置勇士位置。这句话的意思是将勇士当前位置的横坐标设置为5。
|
||||
同理可以设置勇士纵坐标 core.setHeroLoc('y', 3)。
|
||||
值得注意的是,这句话虽然会使勇士改变位置,但并不会使界面重新绘制;如需立刻重新绘制地图还需调用:
|
||||
core.clearMap('hero'); core.drawHero();
|
||||
来对界面进行更新。
|
||||
|
||||
|
||||
core.setItem('pickaxe', 10)
|
||||
将破墙镐个数设置为10个。这里可以写任何道具的ID。
|
||||
|
||||
|
||||
core.addItem('pickaxe', 2)
|
||||
将破墙镐的个数增加2个,无任何特效。这里可以写任何道具的ID。
|
||||
|
||||
|
||||
core.getItem('pickaxe', 4)
|
||||
令勇士获得4个破墙镐。这里可以写任何道具的ID。
|
||||
和addItem相比,使用getItem会播放获得道具的音效,也会在左上角绘制获得提示。
|
||||
|
||||
|
||||
core.removeItem('pickaxe', 3)
|
||||
删除3个破墙镐。第二项可忽略,默认值为1。
|
||||
|
||||
|
||||
core.itemCount('pickaxe')
|
||||
返回当前破墙镐的个数。这里可以写任何道具的ID。
|
||||
|
||||
|
||||
core.hasItem('pickaxe')
|
||||
返回当前是否存在某个道具。等价于 core.itemCount('pickaxe')>0 。
|
||||
|
||||
|
||||
core.getEquip(0)
|
||||
获得0号装备类型(武器)的当前装备的itemId。如果不存在则返回null。
|
||||
这里可以写任意装备类型,从0开始和全塔属性中的equipName一一对应。
|
||||
|
||||
|
||||
core.hasEquip('sword1')
|
||||
获得当前某个具体的装备是否处于正在被装备状态。
|
||||
|
||||
|
||||
core.setFlag('xyz', 2)
|
||||
设置某个flag/变量的值为2。这里可以写任何的flag变量名。
|
||||
|
||||
|
||||
core.getFlag('xyz', 7)
|
||||
获得某个flag/变量的值;如果该变量不存在,则返回第二个参数。
|
||||
比如 core.getFlag('point', 2) 则获得变量point的值;如果该变量从未定义过则返回2。
|
||||
|
||||
|
||||
core.hasFlag('xyz')
|
||||
返回是否存在某个变量且不为0。等价于 core.getFlag('xyz', 0)!=0 。
|
||||
|
||||
|
||||
core.removeFlag('xyz')
|
||||
删除某个flag/变量。
|
||||
|
||||
|
||||
core.insertAction(list, x, y, callback)
|
||||
插入并执行一段自定义事件。在这里你可以写任意的自定义事件列表,有关详细写法请参见文档-事件。
|
||||
x和y如果设置则覆盖"当前事件点"的坐标,callback如果设置则覆盖事件执行完毕后的回调函数。
|
||||
例如: core.insertAction(["楼层切换", {"type":"changeFloor", "floorId": "MT3"}])
|
||||
将依次显示剧情文本,并执行一个楼层切换的自定义事件。
|
||||
--------
|
||||
从V2.5.4开始提出了“公共事件”的说法,这里也可以插入一个公共事件名。
|
||||
例如:core.insertAction("毒衰咒处理") 将插入公共事件“毒衰咒处理”。
|
||||
|
||||
|
||||
core.changeFloor(floorId, stair, heroLoc, time, callback) [异步]
|
||||
立刻切换到指定楼层。
|
||||
floorId为目标楼层ID,stair为到达的目标楼梯,heroLoc为到达的指定点,time为动画时间,callback为切换完毕后的回调。
|
||||
例如:
|
||||
core.changeFloor('MT2', 'upFloor', null, 600) 切换到MT2层的上楼点,动画事件600ms
|
||||
core.changeFloor('MT5', null, {'x': 3, 'y': 6}, 0) 无动画切换到MT5层的(3,6)位置。
|
||||
|
||||
|
||||
core.resetMap()
|
||||
重置当前楼层地图和楼层属性。
|
||||
此函数参数有三种形式:
|
||||
- 不加任何参数,表示重置当前层:core.resetMap()
|
||||
- 加上一个floorId,表示重置某一层:core.resetMap("MT1")
|
||||
- 使用一个数组,表示重置若干层:core.resetMap(["MT1", "MT2", "MT3"])
|
||||
---------------------------
|
||||
** 说明:从V2.5.5开始存档方式发生了改变,在编辑器修改了地图后现在将直接生效,无需再重置地图。
|
||||
|
||||
R
|
||||
录像回放的快捷键;这不是一个控制台命令,但是也把它放在这里供使用。
|
||||
录像回放在修改地图或新增数据后会很有用。
|
||||
|
||||
```
|
||||
|
||||
!> 一些相对高级的命令,针对有一定脚本经验的人
|
||||
|
||||
``` text
|
||||
|
||||
========== 可直接从core中调用的,最常被使用的函数 ==========
|
||||
core.js实际上是所有API的入口(路由),核心API的实现在其他几个文件中,core.js主要进行转发操作。
|
||||
|
||||
|
||||
core.nextX(n)
|
||||
获得勇士面向的第n个位置的x坐标,n可以省略默认为1(即正前方)
|
||||
|
||||
|
||||
core.nextY(n)
|
||||
获得勇士面向的第n个位置的y坐标,n可以省略默认为1(即正前方)
|
||||
|
||||
|
||||
core.nearHero(x, y)
|
||||
判断某个点是否和勇士的距离不超过1。
|
||||
|
||||
|
||||
core.openDoor(id, x, y, needKey, callback) [异步]
|
||||
尝试开门操作。id为目标点的ID,x和y为坐标,needKey表示是否需要使用钥匙,callback为开门完毕后的回调函数。
|
||||
id可为null代表使用地图上的值。
|
||||
例如:core.openDoor('yellowDoor', 10, 3, false, function() {console.log("1")})
|
||||
此函数返回true代表成功开门,并将执行callback回调;返回false代表无法开门,且不会执行回调函数。
|
||||
|
||||
|
||||
core.battle(id, x, y, force, callback) [异步]
|
||||
执行战斗事件。id为怪物的id,x和y为坐标,force为bool值表示是否是强制战斗,callback为战斗完毕后的回调函数。
|
||||
id可为null代表使用地图上的值。
|
||||
例如:core.battle('greenSlime', null, null, true)
|
||||
|
||||
|
||||
core.trigger(x, y) [异步]
|
||||
触发某个地点的事件。
|
||||
|
||||
|
||||
core.isReplaying()
|
||||
当前是否正在录像播放中
|
||||
|
||||
|
||||
core.drawBlock(block)
|
||||
重绘某个图块。block应为core.status.thisMap.blocks中的一项。
|
||||
|
||||
|
||||
core.drawMap(floorId, callback)
|
||||
重绘某一层的地图。floorId为要绘制楼层的floorId,callback为绘制完毕后的回调函数。
|
||||
|
||||
|
||||
core.terrainExists(x, y, id, floorId)
|
||||
检测某个点是否存在(指定的)地形。
|
||||
x和y为坐标;id为地形ID,可为null表示任意地形;floorId为楼层ID,可忽略表示当前楼层。
|
||||
|
||||
|
||||
core.enemyExists(x, y, id, floorId)
|
||||
检测某个点是否存在(指定的)怪物。
|
||||
x和y为坐标;id为怪物ID,可为null表示任意怪物;floorId为楼层ID,可忽略表示当前楼层。
|
||||
|
||||
|
||||
core.getBlock(x, y, floorId, showDisable)
|
||||
获得某个点的当前图块信息。
|
||||
x和y为坐标;floorId为楼层ID,可忽略或null表示当前楼层。
|
||||
showDisable如果为true,则对于禁用的点和事件也会进行返回。
|
||||
如果该点不存在图块,则返回null。
|
||||
否则,返回值如下: {"index": xxx, "block": xxx}
|
||||
其中index为该点在该楼层blocks数组中的索引,block为该图块实际内容。
|
||||
|
||||
|
||||
core.getBlockId(x, y, floorId, showDisable)
|
||||
获得某个点的图块ID。
|
||||
x和y为坐标;floorId为楼层ID,可忽略或null表示当前楼层。
|
||||
showDisable如果为true,则对于禁用的点和事件也会进行返回。
|
||||
如果该点不存在图块,则返回null,否则返回该点的图块ID。
|
||||
|
||||
|
||||
core.getBlockCls(x, y, floorId, showDisable)
|
||||
获得某个点的图块cls。
|
||||
x和y为坐标;floorId为楼层ID,可忽略或null表示当前楼层。
|
||||
showDisable如果为true,则对于禁用的点和事件也会进行返回。
|
||||
如果该点不存在图块,则返回null,否则返回该点的图块cls。
|
||||
|
||||
|
||||
core.showBlock(x, y, floorId)
|
||||
将某个点从禁用变成启用状态。
|
||||
|
||||
|
||||
core.hideBlock(x, y, floorId)
|
||||
将某个点从启用变成禁用状态,但不会对其进行删除。
|
||||
此函数不会实际将该块从地图中进行删除,而是将该点设置为禁用,以供以后可能的启用事件。
|
||||
|
||||
|
||||
core.removeBlock(x, y, floorId)
|
||||
将从启用变成禁用状态,并尽可能将其从地图上删除。
|
||||
和hideBlock相比,如果该点不存在自定义事件(比如门或普通的怪物),则将直接从地图中删除。
|
||||
如果存在自定义事件,则简单的禁用它,以供以后可能的启用事件。
|
||||
|
||||
|
||||
core.setBlock(number, x, y, floorId)
|
||||
改变图块。number为要改变到的图块数字,x和y为坐标,floorId为楼层ID,可忽略表示当前楼层。
|
||||
|
||||
|
||||
core.useItem(itemId, noRoute, callback)
|
||||
尝试使用某个道具。itemId为道具ID,noRoute如果为真则该道具的使用不计入录像。
|
||||
callback为成功或失败后的回调。
|
||||
|
||||
|
||||
core.canUseItem(itemId)
|
||||
返回当前能否使用某个道具。
|
||||
|
||||
|
||||
core.loadEquip(itemId, callback)
|
||||
装备上某个装备。itemId为装备的ID,callback为成功或失败后的回调。
|
||||
|
||||
|
||||
core.unloadEquip(equipType, callback)
|
||||
卸下某个部位的装备。equipType为装备类型,从0开始;callback为成功或失败后的回调。
|
||||
|
||||
|
||||
core.getNextItem()
|
||||
轻按。
|
||||
|
||||
|
||||
core.drawTip(text, itemIcon)
|
||||
在左上角绘制一段提示信息,2秒后消失。itemIcon为道具图标的索引。
|
||||
|
||||
|
||||
core.drawText(contents, callback) [异步]
|
||||
绘制一段文字。
|
||||
不推荐使用此函数,尽量使用core.insertAction(contents)来显示剧情文本。
|
||||
|
||||
|
||||
core.closePanel()
|
||||
结束一切事件和绘制,关闭UI窗口,返回游戏进程。
|
||||
|
||||
|
||||
core.replaceText(text)
|
||||
将一段文字中的${}进行计算并替换。
|
||||
|
||||
|
||||
core.calValue(value, prefix, need, times)
|
||||
计算表达式的实际值。这个函数可以传入status:atk等这样的参数。
|
||||
|
||||
|
||||
core.getLocalStorage(key, defaultValue)
|
||||
从localStorage中获得某个数据(已被parse);如果对应的key不存在则返回defaultValue。
|
||||
|
||||
|
||||
core.getLocalForage(key, defaultValue, successCallback, errorCallback)
|
||||
从localForage中获得某个数据(已被parse),如果对应的key不存在则返回defaultValue。
|
||||
如果成功则通过successCallback回调,失败则通过errorCallback回调。
|
||||
|
||||
|
||||
core.hasSave(index)
|
||||
判定当前某个存档位是否存在存档,返回true/false。
|
||||
index为存档编号,0代表自动存档,大于0则为正常的存档位。
|
||||
|
||||
|
||||
core.clone(data)
|
||||
深拷贝某个对象。
|
||||
|
||||
|
||||
core.isset(x)
|
||||
测试x是否不为null,不为undefined也不为NaN。
|
||||
|
||||
|
||||
core.rand(num)
|
||||
使用伪种子生成伪随机数。该随机函数能被录像支持。
|
||||
num如果设置大于0,则生成一个[0, num-1]之间的数;否则生成一个0到1之间的浮点数。
|
||||
此函数为伪随机算法,SL大法无效。(即多次SL后调用的该函数返回的值都是相同的。)
|
||||
|
||||
|
||||
core.rand2(num)
|
||||
使用系统的随机数算法得到的随机数。该随机函数能被录像支持。
|
||||
num如果设置大于0,则生成一个[0, num-1]之间的数;否则生成一个0到2147483647之间的整数。
|
||||
此函数使用了系统的Math.random()函数,支持SL大法。
|
||||
但是,此函数会将生成的随机数值存入录像,因此如果调用次数太多则会导致录像文件过大。
|
||||
|
||||
|
||||
core.restart() [异步]
|
||||
返回标题界面。
|
||||
|
||||
|
||||
========== core.actions.XXX 和游戏控制相关的函数 ==========
|
||||
actions.js主要用来进行用户交互行为的处理。
|
||||
所有用户行为,比如按键、点击、滑动等等,都会被此文件接收并进行操作。
|
||||
|
||||
|
||||
========== core.control.XXX 和游戏控制相关的函数 ==========
|
||||
control.js主要用来进行游戏控制,比如行走控制、自动寻路、存读档等等游戏核心内容。
|
||||
|
||||
core.control.setGameCanvasTranslate(canvasId, x, y)
|
||||
设置大地图的偏移量
|
||||
|
||||
|
||||
core.control.updateViewport()
|
||||
更新大地图的可见区域
|
||||
|
||||
|
||||
core.control.gatherFollowers()
|
||||
立刻聚集所有的跟随者
|
||||
|
||||
|
||||
core.control.replay()
|
||||
回放下一个操作
|
||||
|
||||
|
||||
========== core.enemys.XXX 和怪物相关的函数 ==========
|
||||
enemys.js主要用来进行怪物相关的内容,比如怪物的特殊属性,伤害和临界计算等。
|
||||
|
||||
|
||||
core.enemys.hasSpecial(special, test)
|
||||
测试怪物是否含有某个特殊属性。
|
||||
常见用法: core.enemys.hasSpecial(monster.special, 3) ## 测试是否拥有坚固
|
||||
|
||||
|
||||
core.enemys.getSpecialText(enemyId)
|
||||
返回一个列表,包含该怪物ID对应的所有特殊属性。
|
||||
|
||||
|
||||
core.enemys.getSpecialHint(enemy, special)
|
||||
获得怪物某个(或全部)特殊属性的文字说明。
|
||||
|
||||
|
||||
core.enemys.canBattle(enemyId, x, y, floorId)
|
||||
返回当前能否战胜某个怪物。
|
||||
后面三个参数是怪物坐标和楼层。
|
||||
|
||||
|
||||
core.enemys.getDamage(enemyId, x, y, floorId)
|
||||
返回当前对某个怪物的战斗伤害。如果无法战斗,返回null。
|
||||
后面三个参数是怪物坐标和楼层。
|
||||
|
||||
|
||||
core.enemys.getExtraDamage(enemyId)
|
||||
返回某个怪物会对勇士造成的额外伤害(不可被魔防抵消),例如仇恨、固伤等等。
|
||||
|
||||
|
||||
core.enemys.nextCriticals(enemyId, number, x, y, floorId)
|
||||
返回一个列表,为接下来number(可忽略,默认为1)个该怪物的临界值和临界减伤。
|
||||
列表每一项类似 [x,y] 表示临界值为x,且临界减伤为y。
|
||||
如果无临界值,则返回空列表。
|
||||
|
||||
|
||||
core.enemys.getDefDamage(enemyId, k, x, y, floorId)
|
||||
获得k(可忽略,默认为1)防减伤值。
|
||||
|
||||
|
||||
core.enemys.getDamageInfo(enemy, hero_hp, hero_atk, hero_def, hero_mdef, x, y, floorId)
|
||||
获得实际战斗信息,比如伤害,回合数,每回合伤害等等。
|
||||
此函数是实际战斗过程的计算。
|
||||
|
||||
|
||||
core.enemys.calDamage(enemy, hero_hp, hero_atk, hero_def, hero_mdef, x, y, floorId)
|
||||
获得在某个勇士属性下怪物伤害;实际返回的是上面getDamageInfo中伤害的数值。
|
||||
|
||||
|
||||
core.enemys.getCurrentEnemys(floorId)
|
||||
获得某一层楼剩余所有怪物的信息(供怪物手册使用)
|
||||
|
||||
|
||||
========== core.events.XXX 和事件相关的函数 ==========
|
||||
events.js主要用来进行事件处理,比如自定义事件,以及某些条件下可能会被触发的事件。
|
||||
大多数事件API都在脚本编辑中存在,这里只列出部分比较重要的脚本编辑中不存在的API。
|
||||
|
||||
|
||||
core.events.gameOver(ending, fromReplay)
|
||||
游戏结束并上传的事件。
|
||||
该函数将提问是否上传和是否下载录像,并返回标题界面。
|
||||
|
||||
|
||||
core.events.doEvents(list, x, y, callback) [异步]
|
||||
开始执行某个事件。
|
||||
请不要执行此函数,尽量使用 core.insertAction(list, x, y, callback) 来开始执行一段事件。
|
||||
|
||||
|
||||
core.events.doAction()
|
||||
执行下一个事件。此函数中将对所有自定义事件类型分别处理。
|
||||
|
||||
|
||||
core.events.getCommonEvent(name)
|
||||
根据名称获得一个公共事件;如果不存在对应的公共事件则返回null。
|
||||
|
||||
|
||||
core.events.openShop(shopId, needVisited) [异步]
|
||||
打开一个全局商店。needVisited表示是否需要该商店已被打开过。
|
||||
|
||||
|
||||
core.events.disableQuickShop(shopId)
|
||||
禁用一个全局商店
|
||||
|
||||
|
||||
core.events.canUseQuickShop(shopId)
|
||||
当前能否使用某个快捷商店
|
||||
|
||||
|
||||
core.events.setHeroIcon(name)
|
||||
设置勇士行走图
|
||||
|
||||
|
||||
========== core.items.XXX 和道具相关的函数 ==========
|
||||
items.js将处理和道具相关的内容,比如道具的使用,获取和删除等等。
|
||||
|
||||
|
||||
core.items.compareEquipment(equipId1, equipId2)
|
||||
比较两个装备的属性变化值
|
||||
|
||||
|
||||
========== core.loader.XXX 和游戏加载相关的函数 ==========
|
||||
loader.js将主要用来进行资源的加载,比如加载音乐、图片、动画等等。
|
||||
|
||||
|
||||
========== core.maps.XXX 和地图处理相关的函数 ==========
|
||||
maps.js主要用来进行地图相关的的操作。包括绘制地图,获取地图上的点等等。
|
||||
|
||||
|
||||
core.maps.getNumberById(id)
|
||||
根据ID来获得对应的数字。如果该ID不存在对应的数字则返回0。
|
||||
|
||||
|
||||
core.maps.canMoveHero(x,y,direction,floorId)
|
||||
判断能否前往某个方向。x,y为坐标,可忽略为当前点;direction为方向,可忽略为当前方向。
|
||||
floorId为楼层ID,可忽略为当前楼层。
|
||||
|
||||
|
||||
core.maps.canMoveDirectly(destX, destY)
|
||||
判断当前能否瞬间移动到某个点。
|
||||
该函数如果返回0则不可瞬间移动,大于0则可以瞬间移动,且返回值是跨度(即少走的步数)。
|
||||
|
||||
|
||||
core.maps.removeBlockById(index, floorId)
|
||||
根据索引删除或禁用某块。
|
||||
|
||||
|
||||
core.maps.removeBlockByIds(floorId, ids)
|
||||
根据索引删除或禁用若干块。
|
||||
|
||||
|
||||
core.maps.drawAnimate(name, x, y, callback)
|
||||
播放一段动画,name为动画名(需在全塔属性注册),x和y为坐标(0-12之间),callback可选,为播放完毕的回调函数。
|
||||
播放过程是异步的,如需等待播放完毕请使用insertAction插入一条type:waitAsync事件。
|
||||
此函数将随机返回一个数字id,为此异步动画的唯一标识符。
|
||||
|
||||
|
||||
core.maps.stopAnimate(id, doCallback)
|
||||
立刻停止一个异步动画。
|
||||
id为该动画的唯一标识符(由drawAnimate函数返回),doCallback可选,若为true则会执行该动画所绑定的回调函数。
|
||||
|
||||
|
||||
========== core.ui.XXX 和对话框绘制相关的函数 ==========
|
||||
ui.js主要用来进行UI窗口的绘制,比如对话框、怪物手册、楼传器、存读档界面等等。
|
||||
|
||||
|
||||
core.ui.getContextByName(canvas)
|
||||
根据画布名找到一个画布的context;支持系统画布和自定义画布。如果不存在画布返回null。
|
||||
也可以传画布的context自身,则返回自己。
|
||||
|
||||
|
||||
core.clearMap(name)
|
||||
清空某个画布图层。
|
||||
name为画布名,可以是系统画布之一,也可以是任意自定义动态创建的画布名;还可以直接传画布的context本身。(下同)
|
||||
如果name也可以是'all',若为all则为清空所有系统画布。
|
||||
|
||||
|
||||
core.ui.fillText(name, text, x, y, style, font)
|
||||
在某个画布上绘制一段文字。
|
||||
text为要绘制的文本,x,y为要绘制的坐标,style可选为绘制的样式,font可选为绘制的字体。(下同)
|
||||
|
||||
|
||||
core.ui.fillBoldText(name, text, x, y, style, font)
|
||||
在某个画布上绘制一个描黑边的文字。
|
||||
|
||||
|
||||
core.ui.fillRect(name, x, y, width, height, style)
|
||||
绘制一个矩形。style可选为绘制样式。
|
||||
|
||||
|
||||
core.ui.strokeRect(name, x, y, width, height, style)
|
||||
绘制一个矩形的边框。
|
||||
|
||||
|
||||
core.ui.drawLine(name, x1, y1, x2, y2, style, lineWidth)
|
||||
绘制一条线。lineWidth可选为线宽。
|
||||
|
||||
|
||||
core.ui.drawArrow(name, x1, y1, x2, y2, style, lineWidth)
|
||||
绘制一个箭头。
|
||||
|
||||
|
||||
core.ui.setFont(name, font) / core.ui.setLineWidth(name, lineWidth)
|
||||
设置一个画布的字体/线宽。
|
||||
|
||||
|
||||
core.ui.setAlpha(name, font) / core.ui.setOpacity(name, font)
|
||||
设置一个画布的绘制不透明度和画布本身的不透明度。
|
||||
两者区别如下:
|
||||
- setAlpha是设置"接下来绘制的内容的不透明度",不会对已经绘制的内容产生影响。比如setAlpha('ui', 0.5)则会在接下来的绘制中使用0.5的不透明度。
|
||||
- setOpacity是设置"画布本身的不透明度",已经绘制的内容也会产生影响。比如我已经在UI层绘制了一段文字,再setOpacity则也会看起来变得透明。
|
||||
尽量不要对系统画布使用setOpacity(因为会对已经绘制的内容产生影响),自定义创建的画布则不受此限制。
|
||||
|
||||
|
||||
core.ui.setFillStyle(name, style) / core.ui.setStrokeStyle(name, style)
|
||||
设置一个画布的填充样式/描边样式。
|
||||
|
||||
|
||||
core.ui.setTextAlign(name, align)
|
||||
设置一个画布的文字对齐模式。
|
||||
|
||||
|
||||
core.ui.calWidth(name, text, font)
|
||||
计算一段文字在画布上的绘制宽度
|
||||
font可选,如果存在则会先设置该画布上的字体。
|
||||
|
||||
|
||||
core.ui.drawImage(name, image, x, y, w, h, x1, y1, w1, h1)
|
||||
在一个画布上绘制图片。
|
||||
name为画布名,可以是系统画布之一,也可以是任意自定义动态创建的画布名;还可以直接传画布的context本身。
|
||||
image为要绘制的图片,可以是一个全塔属性中定义的图片名(会从images中去获取),图片本身,或者一个画布。
|
||||
后面的8个坐标参数与canvas的drawImage的八个参数完全相同。
|
||||
请查看 http://www.w3school.com.cn/html5/canvas_drawimage.asp 了解更多。
|
||||
|
||||
|
||||
core.ui.createCanvas(name, x, y, width, height, zIndex)
|
||||
动态创建一个画布。name为要创建的画布名,如果已存在则会直接取用当前存在的。
|
||||
x,y为创建的画布相对窗口左上角的像素坐标,width,height为创建的长宽。
|
||||
zIndex为创建的纵向高度(关系到画布之间的覆盖),z值高的将覆盖z值低的;系统画布的z值可在个性化中查看。
|
||||
返回创建的画布的context,也可以通过core.dymCanvas[name]调用。
|
||||
|
||||
|
||||
core.ui.relocateCanvas(name, x, y)
|
||||
重新定位一个自定义画布。
|
||||
|
||||
|
||||
core.ui.resizeCanvas(name, x, y)
|
||||
重新设置一个自定义画布的大小。
|
||||
|
||||
|
||||
core.ui.deleteCanvas(name)
|
||||
删除一个自定义画布。
|
||||
|
||||
|
||||
core.ui.deleteAllCanvas()
|
||||
清空所有的自定义画布。
|
||||
|
||||
|
||||
core.ui.drawThumbnail(floorId, canvas, blocks, x, y, size, heroLoc, heroIcon)
|
||||
绘制一个缩略图,比如楼传器界面,存读档界面等情况。
|
||||
floorId为目标楼层ID,canvas为要绘制到的图层,blocks为要绘制的所有图块。
|
||||
x,y为该图层开始绘制的起始点坐标,size为每一格的像素,heroLoc为勇士坐标,heroIcon为勇士图标。
|
||||
|
||||
|
||||
========== core.utils.XXX 工具类的辅助函数 ==========
|
||||
utils.js主要用来进行一些辅助函数的计算。
|
||||
|
||||
|
||||
core.utils.splitLines(canvas, text, maxLength, font)
|
||||
自动切分长文本的换行。
|
||||
canvas为图层,text为要自动换行的内容,maxLength为每行最长像素,font为文本的字体。
|
||||
|
||||
|
||||
core.utils.cropImage(image, size)
|
||||
纵向对图片进行切分(裁剪)。
|
||||
|
||||
|
||||
core.utils.push(a,b)
|
||||
向某个数组后插入另一个数组或元素
|
||||
|
||||
|
||||
core.utils.unshift(a, b)
|
||||
向某个数组前插入另一个数组或元素
|
||||
|
||||
|
||||
core.utils.encodeBase64(str)
|
||||
Base64加密字符串
|
||||
|
||||
|
||||
core.utils.decodeBase64(str)
|
||||
Base64解密字符串
|
||||
|
||||
|
||||
core.utils.formatBigNumber(x, onMap)
|
||||
大数据的格式化
|
||||
|
||||
|
||||
core.utils.subarray(a, b)
|
||||
检查b是否是a的从头开始子串。
|
||||
如果是,则返回a删去b的一段;否则返回null。
|
||||
|
||||
|
||||
core.utils.same(a, b)
|
||||
比较a和b两个对象是否相同
|
||||
|
||||
|
||||
core.utils.clamp(x, a, b)
|
||||
将x限制在[a,b]之间的范围内
|
||||
|
||||
|
||||
core.utils.arrayToRGB(color)
|
||||
将形如[255,0,0]之类的数组转成#FF0000这样的RGB形式。
|
||||
|
||||
|
||||
core.utils.arrayToRGBA(color)
|
||||
将形如[255,0,0,1]之类的数组转成rgba(255,0,0,1)这样的RGBA形式。
|
||||
|
||||
|
||||
core.utils.encodeRoute(list)
|
||||
压缩加密路线。可以使用core.encodeRoute(core.status.route)来压缩当前路线。
|
||||
|
||||
|
||||
core.utils.decodeRoute(route)
|
||||
解压缩(解密)路线。
|
||||
|
||||
|
||||
core.utils.readFile(success, error, readType) [异步]
|
||||
尝试请求读取一个本地文件内容。
|
||||
success和error为成功/失败后的回调,readType不设置则以文本读取,否则以DataUrl形式读取。
|
||||
|
||||
|
||||
core.utils.readFileContent(content) [异步]
|
||||
文件读取完毕后的内容处理。
|
||||
|
||||
|
||||
core.utils.download(filename, content)
|
||||
尝试生成并下载一个文件。
|
||||
|
||||
|
||||
core.utils.copy(data)
|
||||
尝试复制一段文本到剪切板。
|
||||
|
||||
|
||||
core.utils.http(type, url, formData, success, error) [异步]
|
||||
发送一个异步HTTP请求。
|
||||
type为'GET'或者'POST';url为目标地址;formData如果是POST请求则为表单数据。
|
||||
success为成功后的回调,error为失败后的回调。
|
||||
|
||||
```
|
||||
@ -3,5 +3,5 @@
|
||||
- [元件说明](element)
|
||||
- [事件](event)
|
||||
- [个性化](personalization)
|
||||
- [V2.0版本介绍](V2.0)
|
||||
- [脚本](script)
|
||||
- [附录:API列表](api)
|
||||
|
||||
2465
_docs/api.md
2465
_docs/api.md
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
# 元件说明
|
||||
|
||||
?> 目前版本**v2.5.5**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.6**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
在本章中,将对样板里的各个元件进行说明。各个元件主要包括道具、门、怪物、楼梯等等。
|
||||
|
||||
@ -56,6 +56,8 @@ type为该装备的类型,必填,和上面装备栏一一对应。例如,0
|
||||
|
||||
atk/def/mdef为该装备分别增加的攻防魔防数值(支持负数);如果不加也可省略不写。
|
||||
|
||||
从V2.6开始,可以拓展到任何勇士的属性,如hpmax, atk, def, mdef, experience等等;自行添加的属性包括攻速speed也能使用。
|
||||
|
||||
animate为该装备的攻击动画,仅对type为0时有效。具体可参见[动画和天气系统](#动画和天气系统)。
|
||||
|
||||
percentage为该装备是否按比例增加属性。
|
||||
@ -151,49 +153,13 @@ yellowWall, blueWall, whiteWall
|
||||
|
||||
怪物的特殊属性所对应的数字(special)在脚本编辑中的`getSpecials`中定义,请勿对已有的属性进行修改。
|
||||
|
||||
``` js
|
||||
function() {
|
||||
// 获得怪物的特殊属性,每一行定义一个特殊属性。
|
||||
// 分为三项,第一项为该特殊属性的数字,第二项为特殊属性的名字,第三项为特殊属性的描述
|
||||
// 可以直接写字符串,也可以写个function将怪物传进去
|
||||
return [
|
||||
[1, "先攻", "怪物首先攻击"],
|
||||
[2, "魔攻", "怪物无视勇士的防御"],
|
||||
[3, "坚固", "勇士每回合最多只能对怪物造成1点伤害"],
|
||||
[4, "2连击", "怪物每回合攻击2次"],
|
||||
[5, "3连击", "怪物每回合攻击3次"],
|
||||
[6, function(enemy) {return (enemy.n||4)+"连击";}, function(enemy) {return "怪物每回合攻击"+(enemy.n||4)+"次";}],
|
||||
[7, "破甲", "战斗前,怪物附加角色防御的"+Math.floor(100*core.values.breakArmor||0)+"%作为伤害"],
|
||||
[8, "反击", "战斗时,怪物每回合附加角色攻击的"+Math.floor(100*core.values.counterAttack||0)+"%作为伤害,无视角色防御"],
|
||||
[9, "净化", "战斗前,怪物附加勇士魔防的"+core.values.purify+"倍作为伤害"],
|
||||
[10, "模仿", "怪物的攻防和勇士攻防相等"],
|
||||
[11, "吸血", function (enemy) {return "战斗前,怪物首先吸取角色的"+Math.floor(100*enemy.value||0)+"%生命作为伤害"+(enemy.add?",并把伤害数值加到自身生命上":"");}],
|
||||
[12, "中毒", "战斗后,勇士陷入中毒状态,每一步损失生命"+core.values.poisonDamage+"点"],
|
||||
[13, "衰弱", "战斗后,勇士陷入衰弱状态,攻防暂时下降"+(core.values.weakValue>=1?core.values.weakValue+"点":parseInt(core.values.weakValue*100)+"%")],
|
||||
[14, "诅咒", "战斗后,勇士陷入诅咒状态,战斗无法获得金币和经验"],
|
||||
[15, "领域", function (enemy) {return "经过怪物周围"+(enemy.range||1)+"格时自动减生命"+(enemy.value||0)+"点";}],
|
||||
[16, "夹击", "经过两只相同的怪物中间,勇士生命值变成一半"],
|
||||
[17, "仇恨", "战斗前,怪物附加之前积累的仇恨值作为伤害"+(core.flags.hatredDecrease?";战斗后,释放一半的仇恨值":"")+"。(每杀死一个怪物获得"+(core.values.hatred||0)+"点仇恨值)"],
|
||||
[18, "阻击", function (enemy) {return "经过怪物的十字领域时自动减生命"+(enemy.value||0)+"点,同时怪物后退一格";}],
|
||||
[19, "自爆", "战斗后勇士的生命值变成1"],
|
||||
[20, "无敌", "勇士无法打败怪物,除非拥有十字架"],
|
||||
[21, "退化", function (enemy) {return "战斗后勇士永久下降"+(enemy.atkValue||0)+"点攻击和"+(enemy.defValue||0)+"点防御";}],
|
||||
[22, "固伤", function (enemy) {return "战斗前,怪物对勇士造成"+(enemy.damage||0)+"点固定伤害,无视勇士魔防。";}],
|
||||
[23, "重生", "怪物被击败后,角色转换楼层则怪物将再次出现"],
|
||||
[24, "激光", function (enemy) {return "经过怪物同行或同列时自动减生命"+(enemy.value||0)+"点";}]
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
多属性可采用数组的写法,比如`'special': [1,3]`视为同时拥有先攻和坚固属性;`'special': [5,10,14,18]`视为拥有3连击、魔防、诅咒、阻击四个属性。
|
||||
|
||||
怪物可以负伤,在`data.js`的全局变量`enableNegativeDamage`中指定。
|
||||
|
||||
下面的`getSpecialHint`函数则给定了每个特殊属性的详细描述。这个描述将在怪物手册中看到。
|
||||
怪物可以负伤,在全塔属性的全局变量`enableNegativeDamage`中指定。
|
||||
|
||||
打败怪物后可以进行加点操作。有关加点塔的制作可参见[加点事件](event#加点事件)。
|
||||
|
||||
如果`data.js`中的enableExperience为false,即不启用经验的话,怪物手册里将不显示怪物的经验值,打败怪物也不获得任何经验。
|
||||
如果全塔属性中的enableExperience为false,即不启用经验的话,怪物手册里将不显示怪物的经验值,打败怪物也不获得任何经验。
|
||||
|
||||
拿到幸运金币后,打怪获得的金币将翻倍。
|
||||
|
||||
@ -286,16 +252,12 @@ N连击怪物的special是6,且我们可以为它定义n代表实际连击数
|
||||
|
||||
## 路障,楼梯,传送门
|
||||
|
||||
血网的伤害数值、中毒后每步伤害数值、衰弱时暂时攻防下降的数值,都在 `data.js` 的values内定义。
|
||||
血网的伤害数值、中毒后每步伤害数值、衰弱时暂时攻防下降的数值,都在全塔属性的values内定义。
|
||||
|
||||
路障同样会尽量被自动寻路绕过。
|
||||
|
||||
有关楼梯和传送门,必须在该层样板的changeFloor里指定传送点的目标。
|
||||
|
||||

|
||||
|
||||
!> **请注意这里的`"x,y"`代表该点的横坐标为x,纵坐标为y;即从左到右第x列,从上到下的第y行(从0开始计算)。如(6,0)代表最上面一行的正中间一列。**
|
||||
|
||||
floorId指定的是目标楼层的唯一标识符(ID)。
|
||||
|
||||
也可以写`"floorId": ":before"`和`"floorId": ":next"`表示上一楼和下一楼。
|
||||
@ -347,7 +309,7 @@ floorId指定的是目标楼层的唯一标识符(ID)。
|
||||
|
||||
从V2.4开始,H5魔塔开始支持大地图。
|
||||
|
||||
大地图在创建时可以指定宽高,要求**宽和高都不得小于13,且宽高之积不超过1000**。
|
||||
大地图在创建时可以指定宽高,要求**宽和高都不得小于13(15x15版本则是不小于15),且宽高之积不超过1000**。
|
||||
|
||||
大地图一旦创建成功则不得修改宽高数值。
|
||||
|
||||
@ -355,13 +317,12 @@ floorId指定的是目标楼层的唯一标识符(ID)。
|
||||
|
||||
现在我们的H5魔塔支持播放动画,也支持天气系统了。
|
||||
|
||||
要播放动画,你需要先使用“RM动画导出器”将动画导出,放在animates目录下,然后再data.js中定义。
|
||||
要播放动画,你需要先使用“RM动画导出器”将动画导出,放在animates目录下,然后在全塔属性的animates中定义。
|
||||
|
||||
``` js
|
||||
"animates": [// 在此存放所有可能使用的动画,必须是animate格式,在这里不写后缀名
|
||||
// 在此存放所有可能使用的动画,必须是animate格式,在这里不写后缀名
|
||||
// 动画必须放在animates目录下;文件名不能使用中文,不能带空格或特殊字符
|
||||
"hand", "sword", "zone", "yongchang", "thunder" // 根据需求自行添加
|
||||
]
|
||||
"animates": ["hand", "sword", "zone", "yongchang", "thunder"]
|
||||
```
|
||||
|
||||
!> 动画必须是animate格式,名称不能使用中文,不能带空格或特殊字符。
|
||||
@ -376,9 +337,9 @@ floorId指定的是目标楼层的唯一标识符(ID)。
|
||||
|
||||
!> 播放录像时,将默认忽略所有动画。
|
||||
|
||||
目前天气系统只支持雨和雪两种天气。
|
||||
目前天气系统支持雨和雪和雾两种天气。
|
||||
|
||||
在每层楼的剧本文件里存在一个weather选项,表示该层楼的默认天气。
|
||||
在每层楼的楼层属性中存在一个weather选项,表示该层楼的默认天气。
|
||||
|
||||
``` js
|
||||
// 该层的默认天气。本项可忽略表示晴天,如果写则第一项为"rain","snow"或"fog"代表雨雪雾,第二项为1-10之间的数代表强度。
|
||||
@ -394,24 +355,18 @@ floorId指定的是目标楼层的唯一标识符(ID)。
|
||||
要播放音乐和音效,你需要将对应的文件放在sounds目录下,然后在全塔属性中进行定义
|
||||
|
||||
``` js
|
||||
"bgms": [ // 在此存放所有的bgm,和文件名一致。
|
||||
// 在此存放所有的bgm,和文件名一致。
|
||||
// 音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好
|
||||
'bgm.mp3'
|
||||
];
|
||||
"sounds": [ // 在此存放所有的SE,和文件名一致
|
||||
// 音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好
|
||||
'floor.mp3', 'attack.mp3', 'door.mp3', 'item.mp3', 'zone.mp3'
|
||||
]
|
||||
"bgms": ["bgm.mp3"]
|
||||
|
||||
// 在此存放所有的SE,和文件名一致
|
||||
"sounds": ["floor.mp3", "attack.mp3", "door.mp3", "item.mp3", "zone.mp3"]
|
||||
```
|
||||
|
||||
!> 音频名不能使用中文,不能带空格或特殊字符。
|
||||
|
||||
目前BGM支持主流的音乐格式,如mp3, ogg,格式等。不支持mid格式的播放。
|
||||
<!--
|
||||
!> mid格式是通过数学方法模拟出来的音乐效果,质量可能会和实际效果差距较大。
|
||||
目前BGM支持主流的音乐格式,如mp3, ogg等。不支持mid格式的播放。
|
||||
|
||||
!> **警告!** mid格式在手机端播放可能会特别卡,仍推荐直接使用mp3/ogg来播放。
|
||||
-->
|
||||
定义完毕后,我们可以调用`playBgm`/`playSound`事件来播放对应的音乐/音效,有关事件的详细介绍请参见[事件](event)。
|
||||
|
||||
**另外,考虑到用户的流量问题,将遵循如下规则:**
|
||||
@ -443,7 +398,7 @@ HTML5魔塔一大亮点就是存在录像系统,可以很方便进行录像回
|
||||
录像的回放主要有两种方式:
|
||||
|
||||
1. 保存成的录像文件(.h5route文件):在标题界面点录像回放,再选择文件即可。
|
||||
2. 游戏过程中时的当前录像:随时按R可以进行回放;手机端则长按任何位置3秒以上调出虚拟键盘,再按R。
|
||||
2. 游戏过程中时的当前录像:随时按R可以进行回放;手机端则可调出虚拟键盘,再按R。
|
||||
|
||||
录像播放过程中,可以进行如下操作:
|
||||
|
||||
@ -474,6 +429,9 @@ HTML5魔塔一大亮点就是存在录像系统,可以很方便进行录像回
|
||||
|
||||
## 操作说明
|
||||
|
||||

|
||||
|
||||
<!--
|
||||
本塔主要支持鼠标(触摸屏)操作和键盘操作。
|
||||
|
||||
鼠标(触摸屏)操作说明如下:
|
||||
@ -511,6 +469,7 @@ HTML5魔塔一大亮点就是存在录像系统,可以很方便进行录像回
|
||||
- **[Alt+0~9]** 快捷换装
|
||||
|
||||
以上快捷键也能在游戏菜单中的操作说明中看到。
|
||||
-->
|
||||
|
||||
|
||||
|
||||
|
||||
593
_docs/event.md
593
_docs/event.md
File diff suppressed because it is too large
Load Diff
BIN
_docs/img/console.jpg
Normal file
BIN
_docs/img/console.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
BIN
_docs/img/console1.jpg
Normal file
BIN
_docs/img/console1.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 49 KiB |
BIN
_docs/img/elements.jpg
Normal file
BIN
_docs/img/elements.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 171 KiB |
BIN
_docs/img/keyboard.png
Normal file
BIN
_docs/img/keyboard.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 53 KiB |
BIN
_docs/img/plugin.jpg
Normal file
BIN
_docs/img/plugin.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
BIN
_docs/img/sources.jpg
Normal file
BIN
_docs/img/sources.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 116 KiB |
@ -1,11 +1,10 @@
|
||||
# HTML5 魔塔样板说明文档
|
||||
|
||||
?> 目前版本**v2.5.5**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.6**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
众所周知,魔塔的趋势是向移动端发展,贴吧中也常常能见到“求手机魔塔”的帖子。然而现有的工具中,NekoRPG有着比较大的局限性,游戏感较差,更是完全没法在iOS上运行。而一些APP的魔塔虽然可用,但是必须要下载安装,对于Android和iOS还必须开发不同的版本,非常麻烦。
|
||||
|
||||
但是,现在我们有了HTML5。 HTML5的画布(canvas)以及它被Android/iOS内置浏览器所支持的特性,可以让我们做出真正意义上的全平台覆盖的魔塔。
|
||||
事实上,在贴吧的试水发布也证明了,H5魔塔确实是可以成功的。两部即使是复刻的魔塔也受到了不少人的追捧,其流畅的手感和全平台支持的特性,也让很多没办法打开电脑的人爱不释手。
|
||||
|
||||
然而,一般而言使用非RMXP制作魔塔往往需要一定的编程技术,HTML5魔塔自然也不例外。但是,为了能让大家更加注重于“做塔”本身,而不用考虑做塔以外的各种脚本问题,我特意制作了这样一部HTML5的魔塔样板。
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# 个性化
|
||||
|
||||
?> 目前版本**v2.5.5**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.6**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
有时候只靠样板本身可能是不够的。我们需要一些个性化、自定义的素材,道具效果,怪物属性,等等。
|
||||
|
||||
@ -21,10 +21,14 @@ HTML5魔塔是使用画布(canvas)来绘制,存在若干个图层,它们
|
||||
- route**[D]**:路线层;主要用来绘制勇士的行走路线图。 (z-index: 95)
|
||||
- paint**[D]**:绘图层;主要用来进行绘图模式。(z-index: 95)
|
||||
- curtain:色调层;用来控制当前楼层的画面色调 (z-index: 125)
|
||||
- image1\~50**[D]**:图片层;用来绘制图片等操作。(z-index: 100+code, 101~150;也就是图片编号在1~25的在色调层之下,26~50的在色调层之上)
|
||||
- ui:UI层;用来绘制一切UI窗口,如剧情文本、怪物手册、楼传器、系统菜单等等 (z-index: 160)
|
||||
- image1\~50**[D]**:图片层;用来绘制图片等操作。(z-index: 100+code, 101~150)
|
||||
- ui:UI层;用来绘制一切UI窗口,如剧情文本、怪物手册、楼传器、系统菜单等等 (z-index: 140)
|
||||
- data:数据层;用来绘制一些顶层的或更新比较快的数据,如左上角的提示,战斗界面中数据的变化等等。 (z-index: 170)
|
||||
|
||||
请注意:显示图片事件将自动创建一个图片层,z-index是100+图片编号。
|
||||
|
||||
而,色调层的z-index是25,ui层的z-index是140;因此,图片编号在1~24的将被色调层遮挡,25~40的将被ui层遮挡,41~50的将遮挡UI层。
|
||||
|
||||
### 动态创建canvas
|
||||
|
||||
从V2.5.3开始,可以在H5样板中任意动态创建canvas并进行使用。
|
||||
@ -104,11 +108,11 @@ core.fillText('test', '这是一段文字', 10, 30, '#FF0000', '16px Verdana');
|
||||
从V2.5.4开始,贴图也允许进行帧动画,只要设置第五项的数值。
|
||||
|
||||
``` js
|
||||
"images": [[96,120,"bg.jpg",0]], // 背景图;你可以选择一张或多张图片来作为背景/前景素材。
|
||||
"images": [], // 无任何背景图
|
||||
"images": [[32,32,"house.png",0], [160,170,"bed.png",1]] // 在(32,32)放一个house.png在背景层,且(160,170)放bed.png在前景层
|
||||
"images": [[96,120,"tree.png",2]] // 如果写2,则会自动调节遮挡效果
|
||||
"images": [[64,0,"x.png",1,4]] // 这是一个前景层的4帧动画贴图
|
||||
[[96,120,"bg.jpg",0]] // 背景图;你可以选择一张或多张图片来作为背景/前景素材。
|
||||
[] // 无任何背景图
|
||||
[[32,32,"house.png",0], [160,170,"bed.png",1]] // 在(32,32)放一个house.png在背景层,且(160,170)放bed.png在前景层
|
||||
[[96,120,"tree.png",2]] // 如果写2,则会自动调节遮挡效果
|
||||
[[64,0,"x.png",1,4]] // 这是一个前景层的4帧动画贴图
|
||||
```
|
||||
|
||||
images为一个数组,代表当前层所有作为背景素材的图片信息。每一项为一个五元组,分别为该背景素材的x,y,图片名,遮挡方式和帧数。
|
||||
@ -129,18 +133,21 @@ images为一个数组,代表当前层所有作为背景素材的图片信息
|
||||
|
||||
关于楼层贴图和前景、背景层的层叠覆盖关系,默认是:**地板 - 背景贴图 - 背景图块 - 事件 - 勇士 - 前景贴图 - 前景图块**。
|
||||
|
||||
可以通过修改`libs/maps.js`的`drawMap`函数中下面三行的顺序来改变其覆盖关系。
|
||||
可以通过修改`libs/maps.js`的`drawBg`和`drawFg`函数来改变其覆盖关系。
|
||||
|
||||
``` js
|
||||
// ----- 可以调整这三行的顺序来修改覆盖关系;同层画布上,后绘制的覆盖先绘制的
|
||||
// ----- ui.js的drawThumbnail函数也需要对应进行修改。
|
||||
|
||||
// 绘制楼层贴图
|
||||
core.maps.drawFloorImages(floorId, images);
|
||||
// 绘制背景层图块
|
||||
core.maps.drawBgFgMap(floorId, core.canvas.bg, "bg", true);
|
||||
// 绘制前景层图块
|
||||
core.maps.drawBgFgMap(floorId, core.canvas.fg, "fg", true);
|
||||
////// 绘制背景层 //////
|
||||
maps.prototype.drawBg = function (floorId, ctx) {
|
||||
var onMap = ctx == null;
|
||||
if (onMap) {
|
||||
ctx = core.canvas.bg;
|
||||
core.clearMap(ctx);
|
||||
}
|
||||
this._drawBg_drawBackground(floorId, ctx);
|
||||
// ------ 调整这两行的顺序来控制是先绘制贴图还是先绘制背景图块;后绘制的覆盖先绘制的。
|
||||
this._drawFloorImages(floorId, ctx, 'bg');
|
||||
this._drawBgFgMap(floorId, ctx, 'bg', onMap);
|
||||
}
|
||||
```
|
||||
|
||||
楼层贴图可以被事件隐藏和显示,详见[隐藏贴图](event#hideFloorImg:隐藏贴图)的写法。
|
||||
@ -192,7 +199,7 @@ ID必须由数字字母下划线组成,数字在1000以内,且均不能和
|
||||
|
||||
之后刷新编辑器即可。
|
||||
|
||||
对于怪物和道具,我们也可以进行自动注册,只需要点击“自动注册”按钮,将对该栏下所有未注册的素材进行自动注册(自动分配ID和数字)。
|
||||
我们也可以进行自动注册,只需要点击“自动注册”按钮,将对该栏下所有未注册的素材进行自动注册(自动分配ID和数字)。
|
||||
|
||||
素材注册完毕后,即可在游戏中正常使用,也可以被地图生成器所识别(需要重开地图生成器)。
|
||||
|
||||
@ -206,85 +213,6 @@ ID必须由数字字母下划线组成,数字在1000以内,且均不能和
|
||||
2. 下拉框选择autotile,然后点“追加”
|
||||
3. 看到成功的提示后刷新编辑器即可。
|
||||
|
||||
<!--
|
||||
|
||||
1. 将新的Autotile图片复制到images目录下。文件名必须是字母数字和下划线组成。
|
||||
2. 进入icons.js,在autotile分类下进行添加该文件的名称,索引简单的写0。
|
||||
3. 指定一个数字,在maps.js中类似进行添加。
|
||||
|
||||
!> Autotile的ID和文件名应确保完全相同!
|
||||
|
||||
-->
|
||||
<!--
|
||||
#### 新添加自定义地形(路面、墙壁等)
|
||||
|
||||
如果你在terrains.png中新增了一行:
|
||||
|
||||
1. 指定一个唯一的英文ID,不能和现有的重复。
|
||||
2. 进入icons.js,在terrains分类下进行添加索引(对应图标在图片上的位置,即index)
|
||||
|
||||
**如果你无须在游戏内使用本地形,而仅仅是将其作为“背景图”使用,则操作如下:**
|
||||
3. 修改对应楼层的剧本文件的`defaultGround`项,改成新的ID。
|
||||
|
||||
**如果你要在游戏内使用本地形,则操作如下:**
|
||||
3. 指定一个数字,在maps.js中类似进行添加。
|
||||
|
||||
#### 新添加Autotile
|
||||
|
||||
如果你需要新增一个Autotile:
|
||||
|
||||
1. 将新的Autotile图片复制到images目录下。
|
||||
2. 进入icons.js,在autotile分类下进行添加该文件的名称,索引简单的写0。
|
||||
3. 指定一个数字,在maps.js中类似进行添加。
|
||||
|
||||
!> Autotile的ID和文件名完全相同!且其ID/文件名不能含有中文、空格或特殊字符。
|
||||
|
||||
!> V2.0版本不能在地图编辑器中添加Autotile,请按上面的操作来执行。
|
||||
|
||||
#### 新添加道具
|
||||
|
||||
如果你需要新增一个未被定义的道具:
|
||||
|
||||
1. 指定一个唯一的英文ID,不能和现有的重复。
|
||||
2. 进入icons.js,在items分类下进行添加索引(对应图标在图片上的位置,即index)
|
||||
3. 指定一个数字,在maps.js中类似进行添加。
|
||||
4. 在items.js中仿照其他道具,来添加道具的信息。
|
||||
|
||||
有关如何自行实现一个道具的效果,参见[自定义道具效果](#自定义道具效果)。
|
||||
|
||||
#### 新添加怪物
|
||||
|
||||
如果我们需要新添加怪物,请在enemys.png中新增一行。
|
||||
|
||||
你可以通过便捷PS工具的“更改色相”来将红头怪变成橙头怪等。
|
||||
|
||||
然后执行如下操作:
|
||||
|
||||
1. 指定一个唯一的英文ID,不能和enemys中现有的重复。
|
||||
2. 进入icons.js,在enemys分类下进行添加索引(对应图标在图片上的位置,即index)
|
||||
3. 在maps.js中继续进行添加。
|
||||
4. 在enemys.js中仿照其他怪物,来添加怪物的信息。
|
||||
|
||||
!> 如果是48x32的怪物素材,请放在enemy48.png中,然后在icons.js的enemy48下添加索引。
|
||||
|
||||
有关如何自行实现一个怪物的特殊属性或伤害计算公式,参见[怪物的特殊属性](#怪物的特殊属性)。
|
||||
|
||||
#### 新添加NPC
|
||||
|
||||
1. 指定一个唯一的英文ID,不能和现有的重复。
|
||||
2. 进入icons.js,在npcs分类下进行添加索引(对应图标在图片上的位置,即index)
|
||||
3. 指定一个数字,在maps.js的getBlock下类似进行添加。
|
||||
|
||||
!> 如果是48x32的怪物素材,请放在npc48.png中,然后在icons.js的npc48下添加索引。
|
||||
|
||||
-->
|
||||
|
||||
### 地图生成器使用自定义素材
|
||||
|
||||
地图生成器是直接从js文件中读取数字-图标对应关系的。
|
||||
|
||||
因此,在你修改了icons.js和maps.js两个文件,也就是将素材添加到游戏后,地图生成器的对应关系也将同步更新。
|
||||
|
||||
### 额外素材
|
||||
|
||||
从V2.4.2开始,HTML5魔塔样板开始支持额外素材。
|
||||
@ -300,6 +228,7 @@ ID必须由数字字母下划线组成,数字在1000以内,且均不能和
|
||||
**该素材的宽高必须都是32的倍数,且图片上的总图块数不超过1000(即最多有1000个32*32的图块在该图片上)。**
|
||||
|
||||
```js
|
||||
// 在全塔属性中的tilesets导入素材
|
||||
"tilesets": ["1.png", "2.png"] // 导入两个额外素材,文件名分别是1.png和2.png
|
||||
```
|
||||
|
||||
@ -350,19 +279,6 @@ core.status.hero.atk += core.values.redJewel + 2*ratio
|
||||
|
||||
具体过程比较复杂,需要一定的JS能力,在这里就不多说了,有需求可以找`艾之葵`进行了解。
|
||||
|
||||
但值得一提的是,我们可以使用`core.hasItem(name)` 来判断是否某个道具是否存在。例如下面是passNet(通过路障处理)的一部分:
|
||||
|
||||
``` js
|
||||
/****** 经过路障 ******/
|
||||
events.prototype.passNet = function (data) {
|
||||
// 有鞋子
|
||||
if (core.hasItem('shoes')) return;
|
||||
if (data.event.id=='lavaNet') { // 血网
|
||||
// ... 下略
|
||||
```
|
||||
|
||||
我们进行了一个简单的判断,如果拥有绿鞋,则不进行任何路障的处理。
|
||||
|
||||
### 实战!拿到神圣盾后免疫吸血、领域、夹击效果
|
||||
|
||||
1. 在itemEffect中修改拿到神圣盾时的效果,标记一个自定义Flag。
|
||||
@ -421,109 +337,20 @@ function (enemy, hero_hp, hero_atk, hero_def, hero_mdef, x, y, floorId) {
|
||||
|
||||
对于特殊的塔,我们可以考虑修改楼传事件来完成一些特殊的要求,比如镜子可以按楼传来切换表里。
|
||||
|
||||
要修改楼传事件,需要进行如下几步:
|
||||
要修改楼传事件,需要进行如下两步:
|
||||
|
||||
1. 截获楼传的点击事件。在control.js中找到useFly函数,并将其替换成如下内容:
|
||||
``` js
|
||||
////// 点击楼层传送器时的打开操作 //////
|
||||
control.prototype.useFly = function (need) {
|
||||
if (core.isMoving()) {
|
||||
core.drawTip("请先停止勇士行动");
|
||||
return;
|
||||
}
|
||||
if (core.status.lockControl || core.status.event.id != null) return;
|
||||
|
||||
if (core.canUseItem('fly')) core.useItem('fly');
|
||||
else core.drawTip("当前无法使用"+core.material.items.fly.name);
|
||||
}
|
||||
```
|
||||
1. 重写楼传的点击事件。在插件中对`core.control.useFly进行重写`。详细代码参见[重写点击楼传事件](script#重写点击楼传事件)。
|
||||
2. 修改楼传的使用事件。和其他永久道具一样,在地图编辑器的图块属性中修改楼传的useItemEffect和canUseItemEffect两个内容。例如:
|
||||
``` js
|
||||
"useItemEffect": "core.insertAction([...])" // 执行某段自定义事件,或者其他脚本
|
||||
"canUseItemEffect": "true" // 任何时候可用
|
||||
```
|
||||
修改时,请先把`null`改成空字符串`""`,然后再双击进行编辑。
|
||||
|
||||
<!--
|
||||
|
||||
## 自定义装备
|
||||
|
||||
由于HTML5魔塔并不像RM那样存在一个装备界面可供我们对装备进行调整,但是我们也可以使用一个替代的方式实现这个目标。
|
||||
|
||||
### 装备的实现原理
|
||||
|
||||
在HTML5中,装备将全部看成是永久道具(constants),同时对于每个装备位置,勇士都定义一个flag域表示正在装备的内容。
|
||||
|
||||
例如:当勇士获得银剑时,将获得一个永久道具“银剑”;当使用这个银剑,首先检查勇士当前是否装备了武器(比如铁剑),如果
|
||||
装备了则先脱掉装备(减去已装备的铁剑所加的属性,并获得永久道具铁剑),然后再穿上新的银剑。
|
||||
|
||||
同时由于脱剑术和脱盾术的存在,我们还需要一个“脱掉装备”的永久道具(比如sword0),使用它可以脱掉对应位置的装备。
|
||||
|
||||
### 装备加值的修改
|
||||
|
||||
要启用装备,首先需要在data.js(全塔属性)中设置`'equipment': true`。此时,游戏内将自动将剑盾变成装备的存在,其
|
||||
所加的数值就是全塔属性中对应的数值(比如铁剑sword1就加的全塔属性中sword1的值)。
|
||||
|
||||
有时候,我们还会有一个装备加多种属性的需求,此时需要将对应的项从数值改变成一个对象。
|
||||
|
||||
``` js
|
||||
"sword1": {"atk": 10, "def": 0, "mdef": 5}, // 铁剑加10攻和5魔防
|
||||
"shield1": {"atk": 0, "def": 10, "mdef": 10}, // 铁盾加10防和10魔防
|
||||
```
|
||||
|
||||
通过这种方式,当穿上装备时,将会给你的三围分别加上对应项的数值(支持负数,比如装剑减防御)。
|
||||
|
||||
### 新增剑盾
|
||||
|
||||
样板默认提供了铁剑(盾),银剑(盾),骑士剑(盾),圣剑(盾)和神圣剑(盾)这五类装备。但有时候,五类是不够的,
|
||||
我们可能还需要更多的剑盾。
|
||||
|
||||
要增加更多的剑盾,我们需要进行如下步骤:(以新增剑为例)
|
||||
|
||||
1. 新注册一个素材到游戏;**其ID必须是sword+数字的形式,比如sword6等。**(同理如果是盾就必须是shield+数字的形式比如shield6。)
|
||||
2. 将其cls设置为`constants`,`useItemEffect`和`canUseItem`直接复制其他几个剑盾的内容。
|
||||
(即:`useItemEffect`必须为`"core.plugin.useEquipment(itemId)"`,`canUseItemEffect`必须为`"true"`)。
|
||||
3. 使用VSCode或其他文本编辑器直接打开`data.js`文件,并在`"values"`中仿照已有的内容添加剑盾的属性。
|
||||
(例如:`"sword6": 100`,或者`"sword6": `{"atk": 100, "def": 0, "mdef": 50}`)
|
||||
|
||||
!> 请注意:新的剑的ID必须是sword+数字,新的盾的ID必须是shield+数字的形式,不然装备将无效!
|
||||
|
||||
### 新增其他部位的装备
|
||||
|
||||
如果我们还需要新增更多部位的装备,比如戒指、首饰等等,也是可以的,只需要依次进行如下步骤:(以新建戒指为例)
|
||||
|
||||
1. 选择一个装备的部位的ID;比如假设我们的装备部位为戒指,那么我们可以选择"ring"作为装备的部位。
|
||||
2. 定义一个空戒指,相当于脱掉戒指。注册一个素材到游戏,**其ID必须是ring0**(即部位ID+数字0)。
|
||||
3. 同上述新建剑盾的方式来设置ring0这个空戒指的属性。请注意打开data.js后,设置的其值必须为0。
|
||||
(即:必须是`"ring0": 0`)
|
||||
3. 创建更多的戒指;每加一个新的戒指到游戏,其ID必须是**ring+数字**的形式,比如`ring1`, `ring2`,等等。
|
||||
4. 对于每一个创建的戒指,按照上述新建剑盾的方式设置属性(图块属性,打开data.js直接编辑)。
|
||||
(例如:`"ring2": {"atk": 3, "def": 5, "mdef": 8}`)
|
||||
5. **切换到脚本编辑 - 自定义插件编写,在`this.useEquipment`中仿照着新增一行代表戒指的使用。**
|
||||
|
||||
``` js
|
||||
this.useEquipment = function (itemId) { // 使用装备
|
||||
_useEquipment(itemId, "sword", "atk"); // 剑
|
||||
_useEquipment(itemId, "shield", "def"); // 盾
|
||||
_useEquipment(itemId, "ring", "mdef"); // 新增的戒指
|
||||
}
|
||||
```
|
||||
|
||||
我们仿照着新增一行`_useEquipment(itemId, "ring", "mdef")`。
|
||||
|
||||
其中第二项为装备部位的ID,比如我们上述定义的是ring;第三项表示“如果values中该值为数字,则加到什么属性上”。
|
||||
比如如果我们这里写mdef,那么我们假设在data.js的values中设置`"ring1": 20`,则使用该戒指会增加20点魔防。
|
||||
|
||||
如果你定义的是对象`{"atk": xxx, "def": xxx, "mdef": xxx}`的形式,则不会受到第三项的影响。
|
||||
|
||||
!> 必须对于每一个装备部位定义唯一一个不同的ID;脱掉装备(空装备)必须是该ID加数字0的形式,其他有效装备必须是
|
||||
该ID+正整数的形式,不然会出错!
|
||||
|
||||
-->
|
||||
除了覆盖楼传事件外,对于快捷商店、虚拟键盘等等也可以进行覆盖,只不过是仿照上述代码重写对应的函数(`openQuickShop`,`openKeyBoard`)即可。
|
||||
|
||||
## 自定义怪物属性
|
||||
|
||||
如果你对现有的怪物不满意,想自行添加怪物属性也是可以的。具体参见脚本编辑-getSpecials。
|
||||
如果你对现有的怪物不满意,想自行添加怪物属性也是可以的。具体参见脚本编辑的getSpecials。
|
||||
|
||||
你需自己指定一个special数字,修改属性名和属性提示文字。后两者可以直接写字符串,或写个函数传入怪物。
|
||||
|
||||
@ -552,7 +379,8 @@ case 89: // 使用该按键的keyCode,比如Y键就是89
|
||||
// ... 在这里写你要执行脚本
|
||||
// **强烈建议所有新增的自定义快捷键均能给个对应的道具可点击,以方便手机端的行为**
|
||||
if (core.hasItem('...')) {
|
||||
core.useItem('...');
|
||||
core.status.route.push("key:0"); // 记录按键到录像中
|
||||
core.useItem('...', true); // 第二个参数true代表该次使用道具是被按键触发的,使用过程不计入录像
|
||||
}
|
||||
|
||||
break;
|
||||
@ -560,6 +388,10 @@ case 89: // 使用该按键的keyCode,比如Y键就是89
|
||||
|
||||
强烈建议所有新增的自定义快捷键均给个对应的永久道具可点击,以方便手机端的行为。
|
||||
|
||||
使用`core.status.route.push("key:"+keyCode)`可以将这次按键记录在录像中。
|
||||
|
||||
!> 如果记录了按键,且使用道具的话,需要将useItem的第二个参数设为true,避免重复记录!
|
||||
|
||||
可以使用altKey来判断Alt键是否被同时按下。
|
||||
|
||||
## 公共事件
|
||||
@ -574,13 +406,9 @@ case 89: // 使用该按键的keyCode,比如Y键就是89
|
||||
|
||||
## 插件系统
|
||||
|
||||
在H5中,提供了“插件”系统。具体参见“脚本编辑 - 插件编写”。
|
||||
在H5中,提供了“插件”系统。在V2.6中提供了一个插件下拉框,用户可以自行创建和写插件。
|
||||
|
||||

|
||||
|
||||
当我们在这上面定义了自己需要的函数(插件后),就可以通过任何方式进行调用。
|
||||
|
||||
在这个插件编写的过程中,我们可以使用任何[常见API](api)里面的代码调用;也可以通过`core.insertAction`来插入自定义事件执行。
|
||||
在插件编写的过程中,我们可以使用任何[常见API](api)里面的代码调用;也可以通过`core.insertAction`来插入自定义事件执行。
|
||||
|
||||
下面是一个很简单的例子,我编写一个插件函数,其效果是让勇士生命值变成原来的x倍,并令面前的图块消失。
|
||||
|
||||
@ -599,11 +427,13 @@ this.myfunc = function(x) {
|
||||
|
||||
网站上也提供了一个[插件库](https://h5mota.com/plugins/),欢迎大家把自己写的插件进行共享。
|
||||
|
||||
从V2.6开始,在插件中用`this.xxx`定义的函数将会被转发到core中。例如上述的`myfunc`除了`core.plugin.myfunc`外也可以直接`core.myfunc`调用。
|
||||
|
||||
详见[函数的转发](script#函数的转发)。
|
||||
|
||||
## 标题界面事件化
|
||||
|
||||
从V2.5.3开始,我们可以将标题界面的绘制和游戏开始用事件来完成。可以通过绘制画布、
|
||||
|
||||
全塔属性,flags中的startUsingCanvas可以决定是否开启标题界面事件化。
|
||||
从V2.5.3开始,我们可以将标题界面的绘制和游戏开始用事件来完成。可以通过绘制画布、全塔属性,flags中的startUsingCanvas可以决定是否开启标题界面事件化。
|
||||
|
||||
然后就可以使用“事件流”的形式来绘制标题界面、提供选项等等。
|
||||
|
||||
@ -619,36 +449,70 @@ this.myfunc = function(x) {
|
||||
|
||||
从V2.5.3以后,我们可以给手机端增加按键了,这样将非常有利于技能的释放。
|
||||
|
||||
当用户在竖屏模式下点击工具栏,就会在工具栏按钮和快捷键模式之间进行切换。
|
||||
用户在菜单栏打开“拓展键盘”后,在竖屏模式下点击工具栏,就会在工具栏按钮和快捷键模式之间进行切换。
|
||||
|
||||
切换到快捷键模式后,可以点1-7,分别等价于在电脑端按键1-7。
|
||||
切换到快捷键模式后,可以点1-8,分别等价于在电脑端按键1-8。
|
||||
|
||||
可以在脚本编辑的onKeyUp中定义每个快捷键的使用效果,比如使用道具或释放技能等。
|
||||
|
||||
默认值下,1使用破,2使用炸,3使用飞,4使用其他存在的道具,5-7未定义。可以相应修改成自己的效果。
|
||||
默认值下,1使用破,2使用炸,3使用飞,4使用其他存在的道具,5-8未定义。可以相应修改成自己的效果。
|
||||
|
||||
也可以替换icons.png中的对应图标,以及修改main.js中`main.statusBar.image.btn1~7`中的onclick事件来自定义按钮和对应按键。
|
||||
也可以替换icons.png中的对应图标,以及修改main.js中`main.statusBar.image.btn1~8`中的onclick事件来自定义按钮和对应按键。
|
||||
|
||||
非竖屏模式下、回放录像中、隐藏状态栏中,将不允许进行切换。
|
||||
|
||||
## 自定义状态栏(新增显示项)
|
||||
## 自绘状态栏
|
||||
|
||||
从V2.5.3开始允许自绘状态栏。要自绘状态栏,则应该打开全塔属性中的`statusCanvas`开关。
|
||||
|
||||
自绘模式下,全塔属性中的`statusCanvasRowsOnMobile`将控制竖屏模式下的状态栏行数。
|
||||
|
||||
开启自绘模式后,可以在脚本编辑的`drawStatusBar`中自行进行绘制。
|
||||
|
||||
横屏模式下的状态栏为`129x416`(15x15则是`149x480`);竖屏模式下的状态栏为`416*(32*rows+9)`(15x15是480)。
|
||||
|
||||
具体可详见脚本编辑的`drawStatusBar`函数。
|
||||
|
||||
## 自定义状态栏的显示项
|
||||
|
||||
在V2.2以后,我们可以自定义状态栏背景图(全塔属性 - statusLeftBackground)等等。
|
||||
|
||||
但是,如果我们还想新增其他项目的显示,比如攻速或者暴击,该怎么办?
|
||||
|
||||
需要进行如下几个操作:
|
||||
我们可以[自绘状态栏](#自绘状态栏),或者采用下面两个方式之一来新增。
|
||||
|
||||
### 利用已有项目
|
||||
|
||||
一个最为简单的方式是,直接利用已有项目。
|
||||
|
||||
例如,如果本塔中没有技能栏,则可以使用技能栏所对应的显示项。
|
||||
|
||||
1. 覆盖project/icons.png中技能的图标
|
||||
2. 打开全塔属性的enableSkill开关
|
||||
3. 在脚本编辑-updateStatusBar中可以直接替换技能栏的显示内容
|
||||
|
||||
```
|
||||
// 设置技能栏
|
||||
if (core.flags.enableSkill) {
|
||||
// 替换成你想显示的内容,比如你定义的一个flag:abc。
|
||||
core.setStatusBarInnerHTML('skill', core.getFlag("abc", 0));
|
||||
}
|
||||
```
|
||||
|
||||
### 额外新增新项目
|
||||
|
||||
如果是在需要给状态栏新定义项目,则需要进行如下几个操作:
|
||||
|
||||
1. 定义ID;比如攻速我就定义speed,暴击可以简单的定义baoji;你也可以定义其他的ID,但是不能和已有的重复。这里以speed为例。
|
||||
2. 在index.html的statusBar中(44行起),进行该状态栏项的定义。仿照其他几项,插在其应当显示的位置,注意替换掉相应的ID。
|
||||
2. 在index.html的statusBar中(46行起),进行该状态栏项的定义。仿照其他几项,插在其应当显示的位置,注意替换掉相应的ID。
|
||||
``` html
|
||||
<div class="status" id="speedCol">
|
||||
<img id="img-speed">
|
||||
<p class='statusLabel' id='speed'></p>
|
||||
</div>
|
||||
```
|
||||
3. 在editor.html中的statusBar(323行起),仿照第二点同样添加;这一项如果不进行则会地图编辑器报错。editor-mobile.html同理。
|
||||
4. 使用便捷PS工具,打开icons.png,新增一行并将魔力的图标P上去;记下其索引比如37(从0开始数)。
|
||||
3. 在editor.html中的statusBar(383行起),仿照第二点同样添加;这一项如果不进行则会地图编辑器报错。editor-mobile.html同理。
|
||||
4. 使用便捷PS工具,打开project/icons.png,新增一行并将魔力的图标P上去;记下其索引比如37(从0开始数)。
|
||||
5. 在main.js的this.statusBar中增加图片、图标和内容的定义。
|
||||
``` js
|
||||
this.statusBar = {
|
||||
@ -674,17 +538,15 @@ core.statusBar.speed.innerHTML = core.getFlag('speed', 0);
|
||||
|
||||
## 技能塔的支持
|
||||
|
||||
其实,在HTML5上制作技能塔是完全可行的。
|
||||
|
||||
要支持技能塔,可能需要如下几个方面:
|
||||
|
||||
从V2.5开始,内置了"二倍斩"技能,可以仿照其制作自己的技能。
|
||||
|
||||
- 魔力(和上限)的添加;技能的定义
|
||||
- 状态栏的显示
|
||||
- 技能的触发(按键与录像问题)
|
||||
- 技能的效果
|
||||
|
||||
从V2.5开始,内置了"二倍斩"技能,可以仿照其制作自己的技能。
|
||||
|
||||
### 魔力的定义添加;技能的定义
|
||||
|
||||
从V2.5开始,提供了status:mana选项,可以直接代表当前魔力值。
|
||||
@ -697,6 +559,8 @@ core.statusBar.speed.innerHTML = core.getFlag('speed', 0);
|
||||
|
||||
如果flag:skill不为0,则代表当前处于某个技能开启状态,且状态栏显示flag:skillName值。伤害计算函数中只需要对flag:skill进行处理即可。
|
||||
|
||||
!> 关于魔力上限:样板中默认没有提供status:manamax
|
||||
|
||||
### 状态栏的显示
|
||||
|
||||
从V2.5开始,魔力值和技能名的状态栏项目已经被添加,可以直接使用。
|
||||
@ -706,9 +570,14 @@ core.statusBar.speed.innerHTML = core.getFlag('speed', 0);
|
||||
``` js
|
||||
// 设置魔力值
|
||||
if (core.flags.enableMana) {
|
||||
// 也可以使用flag:manaMax来表示最大魔力值
|
||||
// core.status.hero.mana = Math.max(core.status.hero.mana, core.getFlag('manaMax', 10));
|
||||
// core.statusBar.mana.innerHTML = core.status.hero.mana + "/" + core.getFlag('manaMax', 10);
|
||||
// status:manamax 只有在非负时才生效。
|
||||
if (core.status.hero.manamax != null && core.status.hero.manamax >= 0) {
|
||||
core.status.hero.mana = Math.min(core.status.hero.mana, core.status.hero.manamax);
|
||||
core.setStatusBarInnerHTML('mana', core.status.hero.mana + "/" + core.status.hero.manamax);
|
||||
}
|
||||
else {
|
||||
core.setStatusBarInnerHTML("mana", core.status.hero.mana);
|
||||
}
|
||||
}
|
||||
// 设置技能栏
|
||||
if (core.flags.enableSkill) {
|
||||
@ -761,14 +630,15 @@ else { // 关闭技能
|
||||
case 87: // W:开启技能“二倍斩”
|
||||
// 检测技能栏是否开启,是否拥有“二倍斩”这个技能道具
|
||||
if (core.flags.enableSkill && core.hasItem('skill1')) {
|
||||
core.useItem('skill1');
|
||||
core.status.route.push("key:87");
|
||||
core.useItem('skill1', true);
|
||||
}
|
||||
break;
|
||||
```
|
||||
|
||||
在勇士处于停止的条件下,按下W键时,判断技能的道具是否存在,如果存在再使用它。
|
||||
|
||||
!> 1,2,3这三个键被默认绑定到了破炸飞;如果想用的话也是一样,只不过是把已有的实现进行替换。
|
||||
!> 由于现在手机端存在拓展键盘,也强烈建议直接覆盖1-8的使用效果,这样手机端使用也非常方便。
|
||||
|
||||
### 技能的效果
|
||||
|
||||
@ -816,141 +686,6 @@ if (core.flags.enableSkill) {
|
||||
|
||||
通过上述这几种方式,我们就能成功的让H5支持技能啦!
|
||||
|
||||
## 成就系统
|
||||
|
||||
我们还可以给HTML5魔塔增加成就系统。注意到成就是和游戏相关,因此需要使用getLocalStorage而不是getFlag判定。
|
||||
|
||||
可将下面的代码粘贴到脚本编辑 - 插件编写中。
|
||||
|
||||
``` js
|
||||
// 所有成就项的定义
|
||||
this.achievements = [
|
||||
// 每行一个,分别定义flag、名称、描述、是否存在提示、成就点数
|
||||
{"flag": "a1", "name": "成就1", "text": "成就1的达成描述", "hint": false, "point": 1},
|
||||
// 可以继续往后新增其他的。
|
||||
];
|
||||
|
||||
// 达成成就;如 core.plugin.achieve("a1") 即达成a1对应的成就
|
||||
this.achieve = function (flag) {
|
||||
// 获得已达成的成就;如果跟存档而不是跟游戏则改成getFlag
|
||||
var achieved = core.getLocalStorage("achievements", []);
|
||||
var point = core.getLocalStorage("achievePoint", 0);
|
||||
// 已经获得该成就
|
||||
if (achieved.indexOf(flag)>=0) return;
|
||||
// 尝试达成成就;找到对应的成就项
|
||||
this.achievements.forEach(function (one) {
|
||||
if (one.flag == flag) {
|
||||
// 执行达成成就的操作;也可以自行在上面加上达成成就后的事件
|
||||
core.insertAction("\t[达成成就:"+one.name+"]"+one.text);
|
||||
point += one.point || 0;
|
||||
}
|
||||
});
|
||||
achieved.push(flag);
|
||||
// 存入localStorage中;如果跟存档走则使用setFlag
|
||||
core.setLocalStorage("achievements", achieved);
|
||||
core.setLocalStorage("achievePoint", point);
|
||||
}
|
||||
|
||||
// 获得所有成就说明;这里简单使用两个insertAction,你也可以修改成自己的实现
|
||||
// 简单一点的可以使用insertAction+剧情文本;稍微复杂一点的可以使用图片化文本等;更复杂的可以自绘UI。
|
||||
this.getAchievements = function () {
|
||||
var achieved = core.getLocalStorage("achievements", []);
|
||||
var yes = [], no = [];
|
||||
// 对所有成就进行遍历
|
||||
this.achievements.forEach(function (one) {
|
||||
// 检测是否达成
|
||||
if (achieved.indexOf(one.flag)>=0) {
|
||||
yes.push(one.name+":"+one.text);
|
||||
}
|
||||
else {
|
||||
no.push(one.name+":"+(one.hint?one.text:"达成条件请自行探索"));
|
||||
}
|
||||
});
|
||||
core.insertAction([
|
||||
"\t[已达成的成就]"+(yes.length==0?"暂无":yes.join("\n")),
|
||||
"\t[尚未达成的成就]"+(no.length==0?"暂无":no.join("\n"))
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 多角色的支持
|
||||
|
||||
其实,我们的样板还能支持多角色的制作。比如《黑·白·间》之类的塔也是完全可以刻的。
|
||||
|
||||
你只需要如下几步来达到多角色的效果。
|
||||
|
||||
1. 每个角色弄一张行走图。相关信息参见[自定义事件:setHeroIcon](event#setHeroIcon:更改角色行走图)。
|
||||
2. [覆盖楼传事件](#覆盖楼传事件),这样可以通过点工具栏的楼层传送按钮来切换角色。当然你也完全可以自己写一个道具,或[自定义快捷键](#自定义快捷键)来进行绑定。
|
||||
3. 将下述代码直接贴入脚本编辑 - 插件编写中。
|
||||
``` js
|
||||
// 所有需要保存的内容;这些保存的内容不会多角色共用,在切换时会进行恢复。
|
||||
// 你也可以自行新增或删除,比如不共用金币则可以加上"money"的初始化,不共用道具则可以加上"items"的初始化,
|
||||
// 多角色共用hp的话则删除hp,等等。总之,不共用的属性都在这里进行定义就好。
|
||||
var hero1 = { // 1号勇士(默认的是0号)
|
||||
"floorId": "MT0", // 该角色楼层ID
|
||||
"icon": "hero1.png", // 角色的行走图名称
|
||||
"name": "1号角色",
|
||||
"lv": 1,
|
||||
"hp": 1000,
|
||||
"atk": 10,
|
||||
"def": 10,
|
||||
"mdef": 0,
|
||||
"loc": {"x": 0, "y": 0, "direction": "up"},
|
||||
// 如果道具不共用就将下面这句话取消注释
|
||||
// "items": {"keys":{"yellowKey":0,"blueKey":0,"redKey":0},"tools":{},"constants":{}}
|
||||
}
|
||||
// 也可以类似新增其他勇士
|
||||
// var hero2 = { ...
|
||||
|
||||
var heroCount = 2; // 包含默认的在内总共多少个勇士,该值需手动修改。
|
||||
|
||||
// 初始化该勇士
|
||||
this.initHeros = function () {
|
||||
core.status.hero.icon = "hero.png";
|
||||
core.setFlag("hero1", core.clone(hero1)); // 将属性值存到变量中
|
||||
// core.setFlag("hero2", core.clone(hero2)); // 更多的勇士...
|
||||
}
|
||||
|
||||
// 切换勇士
|
||||
this.changeHero = function (toHeroId) {
|
||||
var currHeroId = core.getFlag("heroId", 0); // 获得当前角色ID
|
||||
if (!core.isset(toHeroId)) {
|
||||
toHeroId = (currHeroId+1)%heroCount;
|
||||
}
|
||||
if (currHeroId == toHeroId) return;
|
||||
|
||||
var saveList = Object.keys(hero1);
|
||||
|
||||
// 保存当前内容
|
||||
var toSave = {};
|
||||
saveList.forEach(function(name) {
|
||||
if (name=='floorId') toSave[name] = core.status.floorId; // 楼层单独设置
|
||||
else toSave[name] = core.clone(core.status.hero[name]); // 使用core.clone()来创建新对象
|
||||
})
|
||||
|
||||
core.setFlag("hero"+currHeroId, toSave); // 将当前角色信息进行保存
|
||||
var data = core.getFlag("hero"+toHeroId); // 获得要切换的角色保存内容
|
||||
|
||||
// 设置角色的属性值
|
||||
saveList.forEach(function(name) {
|
||||
if (name != 'floorId')
|
||||
core.status.hero[name] = core.clone(data[name]);
|
||||
})
|
||||
|
||||
// 插入事件:改变角色行走图并进行楼层切换
|
||||
core.insertAction([
|
||||
{"type": "setHeroIcon", "name": data.icon||"hero.png"}, // 改变行走图
|
||||
{"type": "changeFloor", "floorId": data.floorId, "loc": [data.loc.x, data.loc.y],
|
||||
"direction": data.loc.direction, "time": 0} // 楼层切换事件
|
||||
])
|
||||
core.setFlag("heroId", toHeroId); // 保存切换到的角色ID
|
||||
}
|
||||
```
|
||||
3. 在脚本编辑 - setInitData中加上`core.plugin.initHeros()`来初始化新勇士。(写在`core.events.afterLoadData()`后,反大括号之前。)
|
||||
4. 如果需要切换角色(包括事件、道具或者快捷键等),可以直接调用自定义JS脚本:`core.plugin.changeHero();`进行切换。也可以指定参数调用`core.plugin.changeHero(1)`来切换到某个具体的勇士上。
|
||||
|
||||
## 系统使用的flag变量
|
||||
|
||||
众所周知,自定义flag变量都可以任意定义并取用(未定义直接取用的flag默认值为0)。
|
||||
@ -979,4 +714,4 @@ this.getAchievements = function () {
|
||||
|
||||
==========================================================================================
|
||||
|
||||
[继续阅读附录:所有API列表](api)
|
||||
[继续阅读脚本](script)
|
||||
|
||||
324
_docs/script.md
Normal file
324
_docs/script.md
Normal file
@ -0,0 +1,324 @@
|
||||
# 脚本
|
||||
|
||||
?> 目前版本**v2.6**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
在V2.6版本中,基本对整个项目代码进行了重写,更加方便造塔者的使用和复写函数。
|
||||
|
||||
## 控制台的使用
|
||||
|
||||
在Chrome浏览器中,按(Ctrl+Shift+I)可打开控制台。
|
||||
|
||||

|
||||
|
||||
控制台中有很多的标签,最常用的是`Console`, `Sources`和`Elements`。
|
||||
|
||||
有关更详尽的控制台使用可自行搜索[Chrome开发者工具](https://www.baidu.com/s?wd=chrome%20%E5%BC%80%E5%8F%91%E8%80%85%E5%B7%A5%E5%85%B7)了解更多。
|
||||
|
||||
### Console:命令行
|
||||
|
||||
Console页为命令行。可以在这里输入一些命令进行调试。
|
||||
|
||||
比如,进入游戏后,输入`core.status.hero.atk`即可获得勇士的当前攻击力数值。`core.status.hero.atk=100`可以设置攻击力为100。
|
||||
|
||||
更多的API可参见[附录:API列表](#附录:API列表)。
|
||||
|
||||
除此以外,游戏中的报错等信息也是可以在Console中进行查看的。
|
||||
|
||||

|
||||
|
||||
### Sources:断点调试
|
||||
|
||||
Sources页可以查看JS源代码,并进行断点调试等。
|
||||
|
||||
例如,如果相对脚本编辑中的伤害计算函数进行断点调试:
|
||||
1. 在左边找到`project/functions.js`,单击打开文件
|
||||
2. 并找到对应的行(可以Ctrl+F搜索),比如搜索`getDamageInfo`
|
||||
3. 在行号上点一下打断点,会出现一个蓝色标签
|
||||
|
||||
之后,当代码运行到你的断点处时,将自动停止运行。
|
||||
|
||||

|
||||
|
||||
可以将鼠标移动到变量上,将弹窗形式显示这个变量的各项数值,从而查看变量值是否符合预期。
|
||||
|
||||
图中红色框内有几个按钮,从左到右分别是:**继续执行**,**执行到下一行**,**进入当前函数**,**跳出当前函数**,**单步执行**。
|
||||
|
||||
通过这几个按钮,可以一行一行的对代码进行执行,执行过程中能不断查看各个变量的数值变化,从而定位问题所在。
|
||||
|
||||
红圈下方是Call Stack,即当前的函数调用链(从哪些地方调用过来的)。
|
||||
|
||||
Sources还有更多有趣的功能,在此不做介绍,有兴趣的可自行网上搜索了解。
|
||||
|
||||
### Elements:网页元素查看
|
||||
|
||||
Elements页可以查看网页的源代码,调整css布局等。
|
||||
|
||||

|
||||
|
||||
不过对魔塔样板来说,最重要的是红圈中的按钮。点击此按钮可以进入**手机模式**。
|
||||
|
||||
手机模式下,左边可以对屏幕分辨率进行调整和模拟。
|
||||
|
||||
这可以很有效的帮我们进行测试样板在手机端的表现。
|
||||
|
||||
## 整体项目架构
|
||||
|
||||
``` text
|
||||
├── /_server/ # 为可视化地图编辑器提供一些支持的目录
|
||||
├── /libs/ # ---- 系统库目录 ----
|
||||
│ ├─ /thirdparty/ # 游戏所用到的第三方库文件
|
||||
│ ├─ actions.js # 用户交互处理
|
||||
│ ├─ core.js # 系统核心文件(游戏入口,接口&转发)
|
||||
│ ├─ control.js # 游戏逻辑控制
|
||||
│ ├─ data.js # 全塔属性等
|
||||
│ ├─ enemys.js # 怪物相关处理
|
||||
│ ├─ events.js # 各个事件的执行
|
||||
│ ├─ icons.js # 图标和素材
|
||||
│ ├─ items.js # 道具效果
|
||||
│ ├─ loader.js # 各个资源加载
|
||||
│ ├─ maps.js # 地图数据和绘制
|
||||
│ ├─ ui.js # UI窗口绘制
|
||||
│ └─ utils.js # 工具类函数
|
||||
├── /project/ # ---- 项目目录 ----
|
||||
│ ├─ /animates/ # 动画目录
|
||||
│ ├─ /floors/ # 楼层文件
|
||||
│ ├─ /images/ # 图片素材
|
||||
│ ├─ /sounds/ # bgm和音效
|
||||
│ ├─ data.js # 全塔属性
|
||||
│ ├─ enemys.js # 怪物属性
|
||||
│ ├─ events.js # 公共事件
|
||||
│ ├─ functions.js # 脚本编辑
|
||||
│ ├─ icons.js # 素材和ID的对应关系定义
|
||||
│ ├─ items.js # 道具的定义和效果
|
||||
│ ├─ maps.js # 地图和数字的对应关系
|
||||
│ └─ plugins.js # 自定义插件
|
||||
├── /常用工具/ # 辅助造塔的小工具
|
||||
├── editor.html # 地图编辑器
|
||||
├── editor-mobile.html # 手机版的地图编辑器
|
||||
├── index.html # 主程序,游戏的入口
|
||||
├── main.js # JS程序的入口,将动态对所需JS进行加载
|
||||
├── style.css # 游戏所需要用到的样式表
|
||||
└── 启动服务.exe # 一个本地的HTTP服务器,通过它来运行游戏
|
||||
```
|
||||
|
||||
`_server`为**地图编辑器目录**,里面存放了地图编辑器相关的各项内容。
|
||||
|
||||
`libs`为**系统库目录**,里面存放了各个系统核心函数。
|
||||
|
||||
从V2.6开始,请勿直接修改libs下的代码,如有需要修改系统库函数请尝试在插件中[复写函数](#复写函数)。
|
||||
|
||||
`project`为**项目目录**,你所造的塔的数据全部存放在project下。在不同样板之间接档也是直接迁移project目录即可。
|
||||
|
||||
## 函数的转发
|
||||
|
||||
在本样板中,`core.js`里面基本是没有定义什么函数的,所有的游戏内函数都在其他几个文件中实现。
|
||||
|
||||
例如,常见的获得某个变量值`getFlag`是定义在`control.js`中的:
|
||||
|
||||
```js
|
||||
////// 获得某个自定义变量或flag //////
|
||||
control.prototype.getFlag = function(name, defaultValue) {
|
||||
if (!core.status.hero) return defaultValue;
|
||||
var value = core.status.hero.flags[name];
|
||||
return value != null ? value : defaultValue;
|
||||
}
|
||||
```
|
||||
|
||||
也就是,我们可以通过`core.control.getFlag(name, value)`来调用此函数。
|
||||
|
||||
但是这样会十分不便,我们希望能直接调用`core.getFlag(name, value)`,而不需要中间的control。
|
||||
|
||||
为了达到这个目的,样板设置了**函数转发**,即**将其他文件中定义的函数,转发到core中执行**。
|
||||
|
||||
上述`getFlag`代码的转发实际上是增加了如下函数:
|
||||
|
||||
```js
|
||||
////// getFlag函数的转发 //////
|
||||
core.getFlag = function (name, defaultValue) {
|
||||
return core.control.getFlag(name, defaultValue);
|
||||
}
|
||||
// 转发后,即可通过 core.getFlag() 来实际调用 core.control.getFlag()
|
||||
```
|
||||
|
||||
转发是自动完成的,其满足如下两条规则:
|
||||
- **在libs中其他文件定义的函数,如果不以下划线`_`开头,就会进行转发。**
|
||||
- **如果core中已经存在同名函数,则会在控制台中打出一条报错信息,并不转发该函数。**
|
||||
|
||||
具体函数的转发实现代码可参见`core.js`的`_forwardFunc`函数。
|
||||
|
||||
!> 除此以外,插件中以`this.xxx`来定义的函数也会被转发!
|
||||
|
||||
例如,你可以直接调用`core.drawLight()`来实际调用插件中的`core.plugin.drawLight`。
|
||||
|
||||
## 插件编写
|
||||
|
||||
插件编写是H5魔塔的一个重大特点,从V2.0.1引入,并逐渐发扬光大。
|
||||
|
||||
对于有一定脚本经验的人来说,可以编写插件来实现各种各样的功能,包括且不仅限于拓展功能的实现,系统代码的复写等等。
|
||||
|
||||
在V2.5.5以前,插件位置都在脚本编辑中;从V2.6开始则迁移到了新的下拉框中,并进行了切分。
|
||||
|
||||
你也可以创建自己的插件。
|
||||
|
||||

|
||||
|
||||
新的插件切分和原来的单插件使用方法完全一致,单纯进行了切分而已。可参见已有的`init`和`drawLight`的样例。
|
||||
|
||||
拆分的意义主要是将各个可能的功能独立出来,避免单个框内内容太长,过大和混杂等。
|
||||
|
||||
在V2.6中,应当每个独立的额外功能实现都新建一个自己的插件,这样也方便进行拓展,例如打包迁移到别的塔上,或发布在网页插件库中。
|
||||
|
||||
另外一点需要注意的是,所有插件的初始化都会在系统资源加载之前,此时图片等资源尚未进行加载。
|
||||
|
||||
在所有资源加载完毕时,将会执行init插件中的_afterLoadResources函数,可以在这里对资源进行一些操作,比如切分图片等。
|
||||
|
||||
```js
|
||||
function () {
|
||||
console.log("插件编写测试");
|
||||
|
||||
// 可以写一些直接执行的代码
|
||||
// 在这里写的代码将会在【资源加载前】被执行,此时图片等资源尚未被加载。
|
||||
// 请勿在这里对包括bgm,图片等资源进行操作。
|
||||
|
||||
|
||||
this._afterLoadResources = function () {
|
||||
// 本函数将在所有资源加载完毕后,游戏开启前被执行
|
||||
// 可以在这个函数里面对资源进行一些操作,比如切分图片等。
|
||||
|
||||
// 这是一个将assets.png拆分成若干个32x32像素的小图片并保存的样例。
|
||||
// var arr = core.splitImage("assets.png", 32, 32);
|
||||
// for (var i = 0; i < arr.length; i++) {
|
||||
// core.material.images.images["asset"+i+".png"] = arr[i];
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
// 可以在任何地方(如afterXXX或自定义脚本事件)调用函数,方法为 core.plugin.xxx();
|
||||
// 从V2.6开始,插件中用this.XXX方式定义的函数也会被转发到core中,详见文档-脚本-函数的转发。
|
||||
}
|
||||
```
|
||||
|
||||
网站上提供了一个插件库,[https://h5mota.com/plugins/](https://h5mota.com/plugins/),上面有一些大家分享的插件,可供使用。
|
||||
|
||||
可以查看附录中的[API列表](api)来查看所有的系统API内容。
|
||||
|
||||
## 复写函数
|
||||
|
||||
样板的功能毕竟是写死的,有时候我们也需要修改样板的一些行为。
|
||||
|
||||
在V2.6以前,需要直接打开libs目录下的对应文件并进行修改。但是开libs下的文件就会出现各种问题:
|
||||
|
||||
- 不容易记得自己修改过什么,而且如果改错了很麻烦
|
||||
- 例如,直接修改了某函数加了新功能,结果过段时间发现不需要,想删掉,但是这时候已经很难找到自己改过了什么了。
|
||||
- 或者,如果代码改错了,不断往上面打补丁,也只会使得libs越来越乱,最后连自己做过什么都不记得。
|
||||
- 不容易随着新样板接档进行迁移
|
||||
- 不方便能整理成新的插件在别的塔使用(总不能让别的塔也去修改libs吧)
|
||||
- ……
|
||||
|
||||
好消息的是,从V2.6开始,我们再也不需要开文件了,而是可以直接在插件中对原始函数进行复写。
|
||||
|
||||
函数复写的好处如下:
|
||||
|
||||
- 不会影响系统原有代码。
|
||||
- 即使写错了或不需要了,也只用把插件中的函数注释或删除即可,不会对原来的系统代码产生任何影响。
|
||||
- 清晰明了。很容易方便知道自己修改过什么,尤其是可以和系统原有代码进行对比。
|
||||
- 方便整理成新的插件,给其他的塔使用。
|
||||
|
||||
如果我想对xxx文件中的yyy函数进行重写,其模式一般是:`core.xxx.yyy = function (参数列表) { ... }`
|
||||
|
||||
下面是几个例子,从简单到复杂。
|
||||
|
||||
### 重写怪物手册的背景图绘制,使用winskin而不是默认的黑色
|
||||
|
||||
直接重写怪物手册的背景图绘制,使用`core.drawBackground`来用winskin绘制一个背景图。
|
||||
|
||||
```js
|
||||
// 重写ui.js中的_drawBook_drawBackground函数
|
||||
core.ui._drawBook_drawBackground = function () {
|
||||
// core.__PIXELS__为定义的一个宏,对于13x13的值是416,对于15x15的值是480
|
||||
core.drawBackground(0, 0, core.__PIXELS__, core.__PIXELS__);
|
||||
}
|
||||
```
|
||||
|
||||
### 重写点击楼传事件
|
||||
|
||||
重写点击楼传事件,使得点击楼传按钮时能使用一个道具(比如item:fly)。
|
||||
|
||||
```js
|
||||
// 重写events.js的useFly函数,即点击楼传按钮时的事件
|
||||
core.events.useFly = function (fromUserAction) {
|
||||
if (core.isMoving()) {
|
||||
core.drawTip("请先停止勇士行动");
|
||||
return;
|
||||
}
|
||||
if (core.status.lockControl || core.status.event.id != null) return;
|
||||
|
||||
if (core.canUseItem('fly')) core.useItem('fly');
|
||||
else core.drawTip("当前无法使用"+core.material.items.fly.name);
|
||||
}
|
||||
```
|
||||
|
||||
其他的几个按钮,如快捷商店`openQuickShop`,虚拟键盘`openKeyBoard`的重写也几乎完全一样。
|
||||
|
||||
### 楼层切换时根据flag来播放不同的音效
|
||||
|
||||
整体复制并重写整个楼传切换前的函数,将`core.playSound('floor.mp3')`替换成根据flag来判定。
|
||||
|
||||
```js
|
||||
// 复制重写events.js中的_changeFloor_beforeChange,修改音效
|
||||
core.events._changeFloor_beforeChange = function (info, callback) {
|
||||
// 直接替换原始函数中的 core.playSound('floor.mp3');
|
||||
if (core.getFlag("floorSound") == 0) core.playSound('floor0.mp3');
|
||||
if (core.getFlag("floorSound") == 1) core.playSound('floor1.mp3');
|
||||
if (core.getFlag("floorSound") == 2) core.playSound('floor2.mp3');
|
||||
// ...
|
||||
|
||||
// 下面是原始函数中的剩余代码,保持不变
|
||||
window.setTimeout(function () {
|
||||
if (info.time == 0)
|
||||
core.events._changeFloor_changing(info, callback);
|
||||
else
|
||||
core.showWithAnimate(core.dom.floorMsgGroup, info.time / 2, function () {
|
||||
core.events._changeFloor_changing(info, callback);
|
||||
});
|
||||
}, 25)
|
||||
}
|
||||
```
|
||||
|
||||
### 每次打开全局商店时播放一个音效
|
||||
|
||||
打开全局商店是在`events.js`中的`openShop`函数,因此需要对其进行重写。
|
||||
|
||||
然而,我们只需要在这个函数执行之前插一句音效播放,所以并不需要重写整个函数,而是直接插入一行就行。
|
||||
|
||||
```js
|
||||
var openShop = core.events.openShop; // 先把原始函数用一个变量记录下来
|
||||
core.events.openShop = function (shopId, needVisited) {
|
||||
core.playSound("shop.mp3"); // 播放一个音效
|
||||
return openShop(shopId, needVisited); // 直接调用原始函数
|
||||
}
|
||||
```
|
||||
|
||||
### 每次绘制地图前在控制台打出一条信息
|
||||
|
||||
绘制地图在`maps.js`的`drawMap`函数,因此需要对其进行重写。
|
||||
|
||||
由于只需要额外在函数执行前增加一句控制台输出,所以直接插入一行即可。
|
||||
|
||||
但是需要注意的是,`drawMap`中使用了`this._drawMap_drawAll()`,因此使用函数时需要用`call`或者`apply`来告知this是什么。
|
||||
|
||||
```js
|
||||
var drawMap = core.maps.drawMap; // 先把原始函数用一个变量记录下来
|
||||
core.maps.drawMap = function (floorId, callback) {
|
||||
console.log("drawMap..."); // 控制台打出一条信息
|
||||
return drawMap.call(core.maps, floorId, callback); // 需要使用`call`来告知this是core.maps
|
||||
}
|
||||
```
|
||||
|
||||
详见[call和apply的用法](https://www.jianshu.com/p/80ea0d1c04f8)。
|
||||
|
||||
==========================================================================================
|
||||
|
||||
[继续阅读下一章:API列表](api)
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# 快速上手
|
||||
|
||||
?> 目前版本**v2.5.5**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.6**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
在这一节中,将详细介绍做一部塔的流程。现在,让我们来做一部单层塔!
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
* “地图编辑器”允许你以可视化的方式进行编辑地图。
|
||||
* “便捷PS工具”能让你很方便的对自定义素材进行添加。参见[自定义素材](personalization#自定义素材)。
|
||||
* “地图生成器”能让你从已有的截图(如RMXP项目)中立刻生成可被本样板识别的地图数据。
|
||||
* “怪物数据导出”能让你从RMXP中导出怪物数据而被H5魔塔使用。
|
||||
* “RM动画导出器”能让你从RMXP中导出动画而被H5魔塔使用。
|
||||
* “JS代码压缩工具”能对JS代码进行压缩,从而减少IO请求数和文件大小。
|
||||
* “伤害和临界值计算器”是一个很便捷的小工具,能对怪物的伤害和临界值进行计算。
|
||||
@ -54,6 +55,8 @@
|
||||
|
||||
### 从RMXP导入已有的地图
|
||||
|
||||
!> 注:现在已经不推荐此方法,如需从RM刻塔请使用 [RM转H5刻塔器使用教程](https://www.bilibili.com/video/av43125840) 进行操作。
|
||||
|
||||
如果我们想复刻一个现有的,已经被RMXP所制作的塔,也有很便捷的方式,那就是用到我们的“地图生成器”。
|
||||
|
||||
首先,我们打开RMXP和对应的项目,可以看到它的地图。
|
||||
@ -176,7 +179,7 @@
|
||||
|
||||
之后刷新编辑器即可。
|
||||
|
||||
对于怪物和道具,我们也可以进行自动注册,只需要点击“自动注册”按钮,将对该栏下所有未注册的素材进行自动注册(自动分配ID和数字)。
|
||||
也可以进行自动注册,只需要点击“自动注册”按钮,将对该栏下所有未注册的素材进行自动注册(自动分配ID和数字)。
|
||||
|
||||
素材注册完毕后,即可在游戏中正常使用,也可以被地图生成器所识别(需要重开地图生成器)。
|
||||
|
||||
@ -230,6 +233,18 @@ HTML5的塔都是可以进行控制台调试的。
|
||||
|
||||
更多API和详细参数介绍可参见[API列表](api)。
|
||||
|
||||
## 编辑器的基本操作
|
||||
|
||||
- **Alt+0~9, Ctrl+0~9** 保存和读取当前选中图块
|
||||
- **W/A/S/D** 移动大地图
|
||||
- **Ctrl+Z** 撤销上次绘图
|
||||
- **Ctrl+Y** 重做上次绘图
|
||||
- **PgUp/PgDn** 切换楼层
|
||||
- **Ctrl+S** 保存事件编辑器/脚本编辑器
|
||||
- **地图上单击** 选中该点
|
||||
- **地图上双击** 选中该点图块
|
||||
- **地图上右键** 弹出菜单栏,包括选中、复制、清除等操作
|
||||
- **事件编辑器中Ctrl+C, Ctrl+X, 右键等** 执行相应操作
|
||||
|
||||
## 报错处理
|
||||
|
||||
|
||||
@ -65,6 +65,7 @@ return code;
|
||||
|
||||
shoplist
|
||||
: shopsub
|
||||
| shopcommonevent
|
||||
| emptyshop
|
||||
;
|
||||
|
||||
@ -77,6 +78,36 @@ var code = ' \n';
|
||||
return code;
|
||||
*/;
|
||||
|
||||
shopcommonevent
|
||||
: '商店 id' IdString '快捷商店栏中名称' EvalString BGNL? '未开启状态则不显示在列表中' Bool BGNL? '执行的公共事件 id' EvalString '参数列表' EvalString?
|
||||
|
||||
/* shopcommonevent
|
||||
tooltip : 全局商店, 执行一个公共事件
|
||||
helpUrl : https://h5mota.com/games/template/docs/#/
|
||||
default : ["shop1","回收钥匙商店",false,"回收钥匙商店",""]
|
||||
if (EvalString_2) {
|
||||
if (EvalString_2.indexOf('"')>=0)
|
||||
throw new Error('请勿在此处使用双引号!尝试使用单引号吧~');
|
||||
// 检查是不是数组
|
||||
try {
|
||||
EvalString_2 = JSON.parse(EvalString_2.replace(/'/g, '"'));
|
||||
if (!(EvalString_2 instanceof Array)) throw new Error();
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error('参数列表必须是个有效的数组!');
|
||||
}
|
||||
}
|
||||
var code = {
|
||||
'id': IdString_0,
|
||||
'textInList': EvalString_0,
|
||||
'mustEnable': Bool_0,
|
||||
'commonEvent': EvalString_1
|
||||
}
|
||||
if (EvalString_2) code.args = EvalString_2;
|
||||
code=JSON.stringify(code,null,2)+',\n';
|
||||
return code;
|
||||
*/;
|
||||
|
||||
shopsub
|
||||
: '商店 id' IdString '标题' EvalString '图标' IdString BGNL? Newline '快捷商店栏中名称' EvalString '共用times' Bool BGNL? Newline '未开启状态则不显示在列表中' Bool BGNL? NewLine '使用' ShopUse_List '消耗' EvalString BGNL? Newline '显示文字' EvalString BGNL? Newline shopChoices+ BEND
|
||||
|
||||
@ -274,8 +305,8 @@ action
|
||||
| moveImage_s
|
||||
| showGif_0_s
|
||||
| showGif_1_s
|
||||
| setFg_0_s
|
||||
| setFg_1_s
|
||||
| setCurtain_0_s
|
||||
| setCurtain_1_s
|
||||
| screenFlash_s
|
||||
| setWeather_s
|
||||
| move_s
|
||||
@ -293,16 +324,20 @@ action
|
||||
| win_s
|
||||
| lose_s
|
||||
| if_s
|
||||
| if_1_s
|
||||
| switch_s
|
||||
| while_s
|
||||
| dowhile_s
|
||||
| break_s
|
||||
| continue_s
|
||||
| input_s
|
||||
| input2_s
|
||||
| choices_s
|
||||
| confirm_s
|
||||
| callBook_s
|
||||
| callSave_s
|
||||
| callLoad_s
|
||||
| unknown_s
|
||||
| function_s
|
||||
| pass_s
|
||||
;
|
||||
@ -694,20 +729,20 @@ return code;
|
||||
*/;
|
||||
|
||||
setBlock_s
|
||||
: '转变图块为' Int 'x' PosString? ',' 'y' PosString? '楼层' IdString? Newline
|
||||
: '转变图块为' EvalString 'x' PosString? ',' 'y' PosString? '楼层' IdString? Newline
|
||||
|
||||
|
||||
/* setBlock_s
|
||||
tooltip : setBlock:设置某个图块,忽略坐标楼层则为当前事件
|
||||
helpUrl : https://h5mota.com/games/template/docs/#/event?id=setblock%EF%BC%9A%E8%AE%BE%E7%BD%AE%E6%9F%90%E4%B8%AA%E5%9B%BE%E5%9D%97
|
||||
colour : this.dataColor
|
||||
default : [0,"","",""]
|
||||
default : ["yellowDoor","","",""]
|
||||
var floorstr = '';
|
||||
if (PosString_0 && PosString_1) {
|
||||
floorstr = ', "loc": ['+PosString_0+','+PosString_1+']';
|
||||
}
|
||||
IdString_0 = IdString_0 && (', "floorId": "'+IdString_0+'"');
|
||||
var code = '{"type": "setBlock", "number":'+Int_0+floorstr+IdString_0+'},\n';
|
||||
var code = '{"type": "setBlock", "number": "'+EvalString_0+'"'+floorstr+IdString_0+'},\n';
|
||||
return code;
|
||||
*/;
|
||||
|
||||
@ -836,20 +871,20 @@ return code;
|
||||
*/;
|
||||
|
||||
setBgFgBlock_s
|
||||
: '转变图层块' Bg_Fg_List '为' Int 'x' PosString? ',' 'y' PosString? '楼层' IdString? Newline
|
||||
: '转变图层块' Bg_Fg_List '为' EvalString 'x' PosString? ',' 'y' PosString? '楼层' IdString? Newline
|
||||
|
||||
|
||||
/* setBgFgBlock_s
|
||||
tooltip : setBgFgBlock:设置某个图层块,忽略坐标楼层则为当前点
|
||||
helpUrl : https://h5mota.com/games/template/docs/#/event?id=setblock%EF%BC%9A%E8%AE%BE%E7%BD%AE%E6%9F%90%E4%B8%AA%E5%9B%BE%E5%9D%97
|
||||
colour : this.dataColor
|
||||
default : ["bg",0,"","",""]
|
||||
default : ["bg","yellowDoor","","",""]
|
||||
var floorstr = '';
|
||||
if (PosString_0 && PosString_1) {
|
||||
floorstr = ', "loc": ['+PosString_0+','+PosString_1+']';
|
||||
}
|
||||
IdString_0 = IdString_0 && (', "floorId": "'+IdString_0+'"');
|
||||
var code = '{"type": "setBgFgBlock", "name": "' + Bg_Fg_List_0 + '", "number":'+Int_0+floorstr+IdString_0+'},\n';
|
||||
var code = '{"type": "setBgFgBlock", "name": "' + Bg_Fg_List_0 + '", "number": "'+EvalString_0+'"'+floorstr+IdString_0+'},\n';
|
||||
return code;
|
||||
*/;
|
||||
|
||||
@ -1245,35 +1280,35 @@ var code = '{"type": "moveImage", "code": '+Int_0+toloc+EvalString_0+',"time": '
|
||||
return code;
|
||||
*/;
|
||||
|
||||
setFg_0_s
|
||||
setCurtain_0_s
|
||||
: '更改画面色调' EvalString Colour '动画时间' Int? '不等待执行完毕' Bool Newline
|
||||
|
||||
|
||||
/* setFg_0_s
|
||||
tooltip : setFg: 更改画面色调,动画时间可不填
|
||||
helpUrl : https://h5mota.com/games/template/docs/#/event?id=setfg%EF%BC%9A%E6%9B%B4%E6%94%B9%E7%94%BB%E9%9D%A2%E8%89%B2%E8%B0%83
|
||||
/* setCurtain_0_s
|
||||
tooltip : setCurtain: 更改画面色调,动画时间可不填
|
||||
helpUrl : https://h5mota.com/games/template/docs/#/event?id=setcurtain%EF%BC%9A%E6%9B%B4%E6%94%B9%E7%94%BB%E9%9D%A2%E8%89%B2%E8%B0%83
|
||||
default : ["255,255,255,1",'rgba(255,255,255,1)',500,false]
|
||||
colour : this.soundColor
|
||||
var colorRe = /^(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(,0(\.\d+)?|,1)?$/;
|
||||
if (!colorRe.test(EvalString_0))throw new Error('颜色格式错误,形如:0~255,0~255,0~255,0~1');
|
||||
Int_0 = Int_0!=='' ?(', "time": '+Int_0):'';
|
||||
var async = Bool_0?', "async": true':'';
|
||||
var code = '{"type": "setFg", "color": ['+EvalString_0+']'+Int_0 +async+'},\n';
|
||||
var code = '{"type": "setCurtain", "color": ['+EvalString_0+']'+Int_0 +async+'},\n';
|
||||
return code;
|
||||
*/;
|
||||
|
||||
setFg_1_s
|
||||
setCurtain_1_s
|
||||
: '恢复画面色调' '动画时间' Int? '不等待执行完毕' Bool Newline
|
||||
|
||||
|
||||
/* setFg_1_s
|
||||
tooltip : setFg: 恢复画面色调,动画时间可不填
|
||||
helpUrl : https://h5mota.com/games/template/docs/#/event?id=setfg%EF%BC%9A%E6%9B%B4%E6%94%B9%E7%94%BB%E9%9D%A2%E8%89%B2%E8%B0%83
|
||||
/* setCurtain_1_s
|
||||
tooltip : setCurtain: 恢复画面色调,动画时间可不填
|
||||
helpUrl : https://h5mota.com/games/template/docs/#/event?id=setcurtain%EF%BC%9A%E6%9B%B4%E6%94%B9%E7%94%BB%E9%9D%A2%E8%89%B2%E8%B0%83
|
||||
default : [500,false]
|
||||
colour : this.soundColor
|
||||
Int_0 = Int_0!=='' ?(', "time": '+Int_0):'';
|
||||
var async = Bool_0?', "async": true':'';
|
||||
var code = '{"type": "setFg"'+Int_0 +async+'},\n';
|
||||
var code = '{"type": "setCurtain"'+Int_0 +async+'},\n';
|
||||
return code;
|
||||
*/;
|
||||
|
||||
@ -1449,15 +1484,16 @@ return code;
|
||||
*/;
|
||||
|
||||
playSound_s
|
||||
: '播放音效' EvalString Newline
|
||||
: '播放音效' EvalString '停止之前音效' Bool? Newline
|
||||
|
||||
|
||||
/* playSound_s
|
||||
tooltip : playSound: 播放音效
|
||||
helpUrl : https://h5mota.com/games/template/docs/#/event?id=playsound%EF%BC%9A%E6%92%AD%E6%94%BE%E9%9F%B3%E6%95%88
|
||||
default : ["item.mp3"]
|
||||
default : ["item.mp3",false]
|
||||
colour : this.soundColor
|
||||
var code = '{"type": "playSound", "name": "'+EvalString_0+'"},\n';
|
||||
Bool_0 = Bool_0 ? ', "stop": true' : '';
|
||||
var code = '{"type": "playSound", "name": "'+EvalString_0+'"'+Bool_0+'},\n';
|
||||
return code;
|
||||
*/;
|
||||
|
||||
@ -1554,6 +1590,20 @@ var code = ['{"type": "if", "condition": "',expression_0,'",\n',
|
||||
return code;
|
||||
*/;
|
||||
|
||||
if_1_s
|
||||
: '如果' ':' expression BGNL? Newline action+ BEND Newline
|
||||
|
||||
|
||||
/* if_1_s
|
||||
tooltip : if: 条件判断
|
||||
helpUrl : https://h5mota.com/games/template/docs/#/event?id=if%EF%BC%9A%E6%9D%A1%E4%BB%B6%E5%88%A4%E6%96%AD
|
||||
colour : this.eventColor
|
||||
var code = ['{"type": "if", "condition": "',expression_0,'",\n',
|
||||
'"true": [\n',action_0,'],\n',
|
||||
'},\n'].join('');
|
||||
return code;
|
||||
*/;
|
||||
|
||||
switch_s
|
||||
: '多重分歧 条件判定' ':' expression BGNL? Newline switchCase+ BEND Newline
|
||||
|
||||
@ -1570,14 +1620,16 @@ return code;
|
||||
*/;
|
||||
|
||||
switchCase
|
||||
: '如果是' expression '的场合' BGNL? Newline action+
|
||||
: '如果是' expression '的场合' '不跳出' Bool BGNL? Newline action+
|
||||
|
||||
|
||||
/* switchCase
|
||||
tooltip : 选项的选择
|
||||
helpUrl : https://h5mota.com/games/template/docs/#/event?id=switch%EF%BC%9A%E5%A4%9A%E9%87%8D%E6%9D%A1%E4%BB%B6%E5%88%86%E6%AD%A7
|
||||
default : ["", false]
|
||||
colour : this.subColor
|
||||
var code = '{"case": "'+expression_0+'", "action": [\n'+action_0+']},\n';
|
||||
Bool_0 = Bool_0?', "nobreak": true':'';
|
||||
var code = '{"case": "'+expression_0+'"'+Bool_0+', "action": [\n'+action_0+']},\n';
|
||||
return code;
|
||||
*/;
|
||||
|
||||
@ -1626,12 +1678,27 @@ var code = '{"text": "'+EvalString_0+'"'+IdString_0+EvalString_1+', "action": [\
|
||||
return code;
|
||||
*/;
|
||||
|
||||
confirm_s
|
||||
: '显示确认框' ':' EvalString BGNL? '确定的场合' ':' '(默认选中' Bool ')' BGNL? Newline action+ '取消的场合' ':' BGNL? Newline action+ BEND Newline
|
||||
|
||||
/* confirm_s
|
||||
tooltip : 弹出确认框
|
||||
helpUrl : https://h5mota.com/games/template/docs/#/
|
||||
default : ["确认要xxx吗?",false]
|
||||
Bool_0 = Bool_0?', "default": true':''
|
||||
var code = ['{"type": "confirm"'+Bool_0+', "text": "',EvalString_0,'",\n',
|
||||
'"yes": [\n',action_0,'],\n',
|
||||
'"no": [\n',action_1,']\n',
|
||||
'},\n'].join('');
|
||||
return code;
|
||||
*/;
|
||||
|
||||
while_s
|
||||
: '循环处理' ':' '当' expression '时' BGNL? Newline action+ BEND Newline
|
||||
: '前置条件循环' ':' '当' expression '时' BGNL? Newline action+ BEND Newline
|
||||
|
||||
/* while_s
|
||||
tooltip : while:循环处理
|
||||
helpUrl : https://h5mota.com/games/template/docs/#/event?id=while%EF%BC%9A%E5%BE%AA%E7%8E%AF%E5%A4%84%E7%90%86
|
||||
tooltip : while:前置条件循环
|
||||
helpUrl : https://h5mota.com/games/template/docs/#/event?id=while%ef%bc%9a%e5%89%8d%e7%bd%ae%e6%9d%a1%e4%bb%b6%e5%be%aa%e7%8e%af
|
||||
colour : this.eventColor
|
||||
var code = ['{"type": "while", "condition": "',expression_0,'",\n',
|
||||
'"data": [\n',action_0,'],\n',
|
||||
@ -1639,6 +1706,19 @@ var code = ['{"type": "while", "condition": "',expression_0,'",\n',
|
||||
return code;
|
||||
*/;
|
||||
|
||||
dowhile_s
|
||||
: '后置条件循环' ':' BGNL? Newline action+ BEND '当' expression '时' Newline
|
||||
|
||||
/* dowhile_s
|
||||
tooltip : dowhile:后置条件循环
|
||||
helpUrl : https://h5mota.com/games/template/docs/#/event?id=dowhile%ef%bc%9a%e5%90%8e%e7%bd%ae%e6%9d%a1%e4%bb%b6%e5%be%aa%e7%8e%af
|
||||
colour : this.eventColor
|
||||
var code = ['{"type": "dowhile", "condition": "',expression_0,'",\n',
|
||||
'"data": [\n',action_0,'],\n',
|
||||
'},\n'].join('');
|
||||
return code;
|
||||
*/;
|
||||
|
||||
break_s
|
||||
: '跳出循环' Newline
|
||||
|
||||
@ -1726,6 +1806,21 @@ var code = '{"type": "callLoad"},\n';
|
||||
return code;
|
||||
*/;
|
||||
|
||||
unknown_s
|
||||
: '自定义事件' BGNL? RawEvalString
|
||||
|
||||
/* unknown_s
|
||||
tooltip : 通过脚本自定义的事件类型, 以及编辑器不识别的事件类型
|
||||
helpUrl : https://h5mota.com/games/template/docs/#/
|
||||
default : ['{"type":"test", "data": "这是自定义的参数"}']
|
||||
colour : this.dataColor
|
||||
try {
|
||||
var tempobj = JSON.parse(RawEvalString_0);
|
||||
} catch (e) {throw new Error("不合法的JSON格式!");}
|
||||
if (!tempobj.type) throw new Error("自定义事件需要一个type:xxx");
|
||||
var code = JSON.stringify(tempobj) +',\n';
|
||||
return code;
|
||||
*/;
|
||||
|
||||
function_s
|
||||
: '自定义JS脚本' '不自动执行下一个事件' Bool BGNL? Newline RawEvalString Newline BEND Newline
|
||||
@ -1940,8 +2035,8 @@ Global_Value_List
|
||||
|
||||
|
||||
Global_Flag_List
|
||||
: '显示当前楼层'|'显示勇士图标'|'显示当前等级'|'启用生命上限'|'显示魔力值'|'显示魔防值'|'显示金币值'|'显示经验值'|'允许等级提升'|'升级扣除模式'|'显示钥匙数量'|'显示破炸飞'|'显示毒衰咒'|'显示当前技能'|'楼梯边才能楼传'|'开启加点'|'开启负伤'|'仇恨怪战后扣减一半'|'夹击是否上整'|'循环计算临界'|'允许轻按'|'寻路算法不绕血瓶'|'允许走到将死领域'|'允许瞬间移动'|'允许查看禁用商店'|'阻激夹域后禁用快捷商店'|'检查控制台'
|
||||
/*Global_Flag_List ['enableFloor','enableName','enableLv', 'enableHPMax', 'enableMana', 'enableMDef', 'enableMoney', 'enableExperience', 'enableLevelUp', 'levelUpLeftMode', 'enableKeys', 'enablePZF', 'enableDebuff', 'enableSkill', 'flyNearStair', 'enableAddPoint', 'enableNegativeDamage', 'hatredDecrease', 'betweenAttackCeil', 'useLoop', 'enableGentleClick', 'potionWhileRouting', 'canGoDeadZone', 'enableMoveDirectly', 'enableDisabledShop', 'disableShopOnDamage', 'checkConsole']*/;
|
||||
: '显示当前楼层'|'显示勇士图标'|'显示当前等级'|'启用生命上限'|'显示魔力值'|'显示魔防值'|'显示金币值'|'显示经验值'|'允许等级提升'|'升级扣除模式'|'显示钥匙数量'|'显示破炸飞'|'显示毒衰咒'|'显示当前技能'|'楼梯边才能楼传'|'破墙镐四方向'|'炸弹四方向'|'冰冻徽章四方向'|'铁门不需要钥匙'|'开启加点'|'开启负伤'|'仇恨怪战后扣减一半'|'夹击是否上整'|'循环计算临界'|'允许轻按'|'寻路算法不绕血瓶'|'允许走到将死领域'|'允许瞬间移动'|'允许查看禁用商店'|'阻激夹域后禁用快捷商店'|'检查控制台'
|
||||
/*Global_Flag_List ['enableFloor','enableName','enableLv', 'enableHPMax', 'enableMana', 'enableMDef', 'enableMoney', 'enableExperience', 'enableLevelUp', 'levelUpLeftMode', 'enableKeys', 'enablePZF', 'enableDebuff', 'enableSkill', 'flyNearStair', 'pickaxeFourDirections', 'bombFourDirections', 'snowFourDirections', 'steelDoorWithoutKey', 'enableAddPoint', 'enableNegativeDamage', 'hatredDecrease', 'betweenAttackCeil', 'useLoop', 'enableGentleClick', 'potionWhileRouting', 'canGoDeadZone', 'enableMoveDirectly', 'enableDisabledShop', 'disableShopOnDamage', 'checkConsole']*/;
|
||||
|
||||
Colour
|
||||
: 'sdeirughvuiyasdeb'+ //为了被识别为复杂词法规则
|
||||
@ -2114,10 +2209,26 @@ ActionParser.prototype.parse = function (obj,type) {
|
||||
obj.id,obj.name,obj.icon,obj.textInList,obj.commonTimes,obj.mustEnable,obj.use,obj.need,parser.EvalString(obj.text),text_choices,next
|
||||
]);
|
||||
}
|
||||
var buildcommentevent = function(obj,parser,next){
|
||||
if (obj.args instanceof Array) {
|
||||
try { obj.args = JSON.stringify(obj.args).replace(/"/g, "'"); }
|
||||
catch (e) {obj.args = '';}
|
||||
}
|
||||
else obj.args = null;
|
||||
return MotaActionBlocks['shopcommonevent'].xmlText([
|
||||
obj.id,parser.EvalString(obj.textInList),obj.mustEnable,parser.EvalString(obj.commonEvent),obj.args,next
|
||||
]);
|
||||
}
|
||||
var next=null;
|
||||
if(!obj)obj=[];
|
||||
while(obj.length){
|
||||
next=buildsub(obj.pop(),this,next);
|
||||
var shopobj=obj.pop()
|
||||
if(shopobj.choices)
|
||||
next=buildsub(shopobj,this,next);
|
||||
else if(shopobj.commonEvent)
|
||||
next=buildcommentevent(shopobj,this,next);
|
||||
else
|
||||
throw new Error("[警告]出错啦!\n"+shopobj.id+" 无效的商店");
|
||||
}
|
||||
return MotaActionBlocks['shop_m'].xmlText([next]);
|
||||
|
||||
@ -2369,11 +2480,12 @@ ActionParser.prototype.parseAction = function() {
|
||||
}
|
||||
break;
|
||||
case "setFg": // 颜色渐变
|
||||
case "setCurtain":
|
||||
if(this.isset(data.color)){
|
||||
this.next = MotaActionBlocks['setFg_0_s'].xmlText([
|
||||
this.next = MotaActionBlocks['setCurtain_0_s'].xmlText([
|
||||
data.color,'rgba('+data.color+')',data.time||0,data.async||false,this.next]);
|
||||
} else {
|
||||
this.next = MotaActionBlocks['setFg_1_s'].xmlText([
|
||||
this.next = MotaActionBlocks['setCurtain_1_s'].xmlText([
|
||||
data.time||0,data.async||false,this.next]);
|
||||
}
|
||||
break;
|
||||
@ -2432,7 +2544,7 @@ ActionParser.prototype.parseAction = function() {
|
||||
break;
|
||||
case "playSound":
|
||||
this.next = MotaActionBlocks['playSound_s'].xmlText([
|
||||
data.name,this.next]);
|
||||
data.name,data.stop,this.next]);
|
||||
break;
|
||||
case "playBgm":
|
||||
this.next = MotaActionBlocks['playBgm_s'].xmlText([
|
||||
@ -2500,18 +2612,32 @@ ActionParser.prototype.parseAction = function() {
|
||||
data.text,this.next]);
|
||||
break;
|
||||
case "if": // 条件判断
|
||||
if (data["false"]) {
|
||||
this.next = MotaActionBlocks['if_s'].xmlText([
|
||||
// MotaActionBlocks['evalString_e'].xmlText([data.condition]),
|
||||
this.tryToUseEvFlag_e('evalString_e', [data.condition]),
|
||||
this.insertActionList(data["true"]),
|
||||
this.insertActionList(data["false"]),
|
||||
this.next]);
|
||||
}
|
||||
else {
|
||||
this.next = MotaActionBlocks['if_1_s'].xmlText([
|
||||
this.tryToUseEvFlag_e('evalString_e', [data.condition]),
|
||||
this.insertActionList(data["true"]),
|
||||
this.next]);
|
||||
}
|
||||
break;
|
||||
case "confirm": // 显示确认框
|
||||
this.next = MotaActionBlocks['confirm_s'].xmlText([
|
||||
this.EvalString(data.text), data["default"],
|
||||
this.insertActionList(data["yes"]),
|
||||
this.insertActionList(data["no"]),
|
||||
this.next]);
|
||||
break;
|
||||
case "switch": // 多重条件分歧
|
||||
var case_caseList = null;
|
||||
for(var ii=data.caseList.length-1,caseNow;caseNow=data.caseList[ii];ii--) {
|
||||
case_caseList=MotaActionBlocks['switchCase'].xmlText([
|
||||
this.isset(caseNow.case)?MotaActionBlocks['evalString_e'].xmlText([caseNow.case]):"值",this.insertActionList(caseNow.action),case_caseList]);
|
||||
this.isset(caseNow.case)?MotaActionBlocks['evalString_e'].xmlText([caseNow.case]):"值",caseNow.nobreak,this.insertActionList(caseNow.action),case_caseList]);
|
||||
}
|
||||
this.next = MotaActionBlocks['switch_s'].xmlText([
|
||||
// MotaActionBlocks['evalString_e'].xmlText([data.condition]),
|
||||
@ -2527,13 +2653,20 @@ ActionParser.prototype.parseAction = function() {
|
||||
this.next = MotaActionBlocks['choices_s'].xmlText([
|
||||
this.isset(data.text)?this.EvalString(data.text):null,'','',text_choices,this.next]);
|
||||
break;
|
||||
case "while": // 循环处理
|
||||
case "while": // 前置条件循环处理
|
||||
this.next = MotaActionBlocks['while_s'].xmlText([
|
||||
// MotaActionBlocks['evalString_e'].xmlText([data.condition]),
|
||||
this.tryToUseEvFlag_e('evalString_e', [data.condition]),
|
||||
this.insertActionList(data["data"]),
|
||||
this.next]);
|
||||
break;
|
||||
case "dowhile": // 后置条件循环处理
|
||||
this.next = MotaActionBlocks['dowhile_s'].xmlText([
|
||||
this.insertActionList(data["data"]),
|
||||
// MotaActionBlocks['evalString_e'].xmlText([data.condition]),
|
||||
this.tryToUseEvFlag_e('evalString_e', [data.condition]),
|
||||
this.next]);
|
||||
break;
|
||||
case "break": // 跳出循环
|
||||
this.next = MotaActionBlocks['break_s'].xmlText([
|
||||
this.next]);
|
||||
@ -2607,7 +2740,8 @@ ActionParser.prototype.parseAction = function() {
|
||||
case "animateImage": // 兼容 animateImage
|
||||
break;
|
||||
default:
|
||||
throw new Error("[警告]出错啦!\n"+data.type+" 事件不被支持...");
|
||||
this.next = MotaActionBlocks['unknown_s'].xmlText([
|
||||
JSON.stringify(data),this.next]);
|
||||
}
|
||||
this.parseAction();
|
||||
return;
|
||||
|
||||
@ -1,460 +0,0 @@
|
||||
var comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
|
||||
{
|
||||
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"items": {
|
||||
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"items": {
|
||||
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"cls": {
|
||||
"_leaf": true,
|
||||
"_type": "select",
|
||||
"_select": {
|
||||
"values": [
|
||||
"keys",
|
||||
"items",
|
||||
"constants",
|
||||
"tools",
|
||||
"equips"
|
||||
]
|
||||
},
|
||||
"_data": "只能取keys(钥匙) items(宝石、血瓶) constants(永久物品) tools(消耗道具) equips(装备)"
|
||||
},
|
||||
"name": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "名称"
|
||||
},
|
||||
"text": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "道具在道具栏中显示的描述"
|
||||
},
|
||||
"equip": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "装备属性设置,仅对cls为equips有效。\n如果此项不为null,需要是一个对象,里面可含\"type\",\"atk\",\"def\",\"mdef\",\"animate\"五项,分别对应装备部位、攻防魔防和动画。\n具体详见文档(元件说明-装备)和已有的几个装备的写法。"
|
||||
},
|
||||
"hideInReplay": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否回放时绘制道具栏。\n如果此项为true,则在回放录像时使用本道具将不会绘制道具栏页面,而是直接使用。\n此项建议在会频繁连续多次使用的道具开启(如开启技能,或者《镜子》那样的镜像切换等等)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"itemEffect": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_lint": true,
|
||||
"_data": "即捡即用类物品的效果,仅对cls为items有效。"
|
||||
},
|
||||
"itemEffectTip": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_lint": true,
|
||||
"_data": "即捡即用类物品在获得时提示的文字,仅对cls为items有效。"
|
||||
},
|
||||
"useItemEffect": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_lint": true,
|
||||
"_data": "道具效果,仅对cls为tools或constants有效。"
|
||||
},
|
||||
"canUseItemEffect": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_lint": true,
|
||||
"_data": "当前能否使用该道具,仅对cls为tools或constants有效。"
|
||||
},
|
||||
"canEquip":{
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_lint": true,
|
||||
"_data": "当前能否装备某个装备,仅对cls为equips有效。\n与canUseItemEffect不同,这里null代表可以装备。"
|
||||
}
|
||||
}
|
||||
},
|
||||
"items_template" : {'cls': 'items', 'name': '新物品'},
|
||||
"enemys": {
|
||||
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"name": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "名称"
|
||||
},
|
||||
"displayIdInBook": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "在怪物手册中映射到的怪物ID。如果此项不为null,则在怪物手册中,将用目标ID来替换该怪物原本的ID。\n此项应被运用在同一个怪物的多朝向上。\n例如,如果想定义同一个怪物的向下和向左的行走图,则需要建立两个属性完全相同的怪物。\n但是这样会导致在怪物手册中同时存在向下和向左的两种怪物的显示。\n可以将朝向左的怪物的displayIdInBook项指定为朝向下的怪物ID,这样在怪物手册中则会归一化,只显示一个。"
|
||||
},
|
||||
"hp": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "生命值"
|
||||
},
|
||||
"atk": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "攻击力"
|
||||
},
|
||||
"def": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "防御力"
|
||||
},
|
||||
"money": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "金币"
|
||||
},
|
||||
"experience": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "经验"
|
||||
},
|
||||
"point": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "加点"
|
||||
},
|
||||
"special": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval==null || thiseval instanceof Array || (thiseval==~~thiseval && thiseval>=0)",
|
||||
"_data": "特殊属性\n\n0:无,1:先攻,2:魔攻,3:坚固,4:2连击,\n5:3连击,6:n连击,7:破甲,8:反击,9:净化,\n10:模仿,11:吸血,12:中毒,13:衰弱,14:诅咒,\n15:领域,16:夹击,17:仇恨,18:阻击,19:自爆,\n20:无敌,21:退化,22:固伤,23:重生,24:激光,25:光环\n\n多个属性例如用[1,4,11]表示先攻2连击吸血"
|
||||
},
|
||||
"value": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "特殊属性的数值\n如:领域/阻激/激光怪的伤害值;吸血怪的吸血比例;光环怪增加生命的比例"
|
||||
},
|
||||
"zoneSquare": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "领域怪是否九宫格伤害"
|
||||
},
|
||||
"range": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "(thiseval==~~thiseval && thiseval>0)||thiseval==null",
|
||||
"_data": "领域伤害的范围;不加默认为1"
|
||||
},
|
||||
"notBomb": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "该怪物不可被炸"
|
||||
},
|
||||
"n": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "(thiseval==~~thiseval && thiseval>0)||thiseval==null",
|
||||
"_data": "多连击的连击数"
|
||||
},
|
||||
"add": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "吸血后是否加到自身;光环是否叠加"
|
||||
},
|
||||
"atkValue": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval==~~thiseval||thiseval==null",
|
||||
"_data": "退化时勇士下降的攻击力点数;光环怪增加攻击的比例"
|
||||
},
|
||||
"defValue": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval==~~thiseval||thiseval==null",
|
||||
"_data": "退化时勇士下降的防御力点数;光环怪增加防御的比例"
|
||||
},
|
||||
"damage": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval==~~thiseval||thiseval==null",
|
||||
"_data": "战前扣血的点数"
|
||||
}
|
||||
}
|
||||
},
|
||||
"enemys_template" : {'name': '新敌人', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0},
|
||||
"maps": {
|
||||
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"id": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "false",
|
||||
"_data": "图块ID"
|
||||
},
|
||||
"idnum": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "false",
|
||||
"_data": "图块数字"
|
||||
},
|
||||
"cls": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "false",
|
||||
"_data": "图块类别"
|
||||
},
|
||||
"trigger": {
|
||||
"_leaf": true,
|
||||
"_type": "select",
|
||||
"_select": {
|
||||
"values": [
|
||||
null,
|
||||
"openDoor",
|
||||
"passNet",
|
||||
"changeLight",
|
||||
"pushBox",
|
||||
"custom"
|
||||
]
|
||||
},
|
||||
"_data": "该图块的默认触发器"
|
||||
},
|
||||
"noPass": {
|
||||
"_leaf": true,
|
||||
"_type": "select",
|
||||
"_select": {
|
||||
"values": [
|
||||
null,
|
||||
true,
|
||||
false
|
||||
]
|
||||
},
|
||||
"_data": "该图块是否不可通行;true代表不可通行,false代表可通行,null代表使用系统缺省值"
|
||||
},
|
||||
"canBreak": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "该图块是否可被破墙或地震"
|
||||
},
|
||||
"cannotOut": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval==null||(thiseval instanceof Array)",
|
||||
"_data": "该图块的不可出方向\n可以在这里定义在该图块时不能前往哪个方向,可以达到悬崖之类的效果\n例如 [\"up\", \"left\"] 代表在该图块时不能往上和左走\n此值对背景层、事件层、前景层上的图块均有效"
|
||||
},
|
||||
"cannotIn": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval==null||(thiseval instanceof Array)",
|
||||
"_data": "该图块的不可入方向\n可以在这里定义不能朝哪个方向进入该图块,可以达到悬崖之类的效果\n例如 [\"down\"] 代表不能从该图块的上方点朝向下进入此图块\n此值对背景层、事件层、前景层上的图块均有效"
|
||||
},
|
||||
"animate": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval==~~thiseval||thiseval==null",
|
||||
"_data": "该图块的全局动画帧数。\n如果此项为null,则对于除了npc48外,使用素材默认帧数;npc48默认是1帧(即静止)。"
|
||||
},
|
||||
"faceIds": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "行走图朝向,仅对NPC有效。可以在这里定义同一个NPC的多个朝向行走图。\n比如 {\"up\":\"N333\",\"down\":\"N334\",\"left\":\"N335\",\"right\":\"N336\"} 就将该素材的上下左右朝向分别绑定到N333,N334,N335和N336四个图块。\n在勇士撞上NPC时,或NPC在移动时,会自动选择最合适的朝向图块(如果存在定义)来进行绘制。"
|
||||
}
|
||||
}
|
||||
},
|
||||
"floors": {
|
||||
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"floor": {
|
||||
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"floorId": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "false",
|
||||
"_data": "文件名和floorId需要保持完全一致 \n楼层唯一标识符仅能由字母、数字、下划线组成,且不能由数字开头 \n推荐用法:第20层就用MT20,第38层就用MT38,地下6层就用MT_6(用下划线代替负号),隐藏3层用MT3h(h表示隐藏),等等 \n楼层唯一标识符,需要和名字完全一致 \n这里不能更改floorId,请通过另存为来实现"
|
||||
},
|
||||
"title": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "楼层中文名,将在切换楼层和浏览地图时显示"
|
||||
},
|
||||
"name": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "显示在状态栏中的层数"
|
||||
},
|
||||
"width": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "false",
|
||||
"_data": "地图x方向大小,这里不能更改,仅能在新建地图时设置,null视为13"
|
||||
},
|
||||
"height": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "false",
|
||||
"_data": "地图y方向大小,这里不能更改,仅能在新建地图时设置,null视为13"
|
||||
},
|
||||
"canFlyTo": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器)"
|
||||
},
|
||||
"canUseQuickShop": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "该层是否允许使用快捷商店"
|
||||
},
|
||||
"cannotViewMap": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "该层是否不允许被浏览地图看到;如果勾上则浏览地图会跳过该层"
|
||||
},
|
||||
"cannotMoveDirectly": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "该层是否不允许瞬间移动;如果勾上则不可在此层进行瞬移"
|
||||
},
|
||||
"firstArrive": {
|
||||
"_leaf": true,
|
||||
"_type": "event",
|
||||
"_event": "firstArrive",
|
||||
"_data": "第一次到该楼层触发的事件,可以双击进入事件编辑器。"
|
||||
},
|
||||
"eachArrive": {
|
||||
"_leaf": true,
|
||||
"_type": "event",
|
||||
"_event": "eachArrive",
|
||||
"_data": "每次到该楼层触发的事件,可以双击进入事件编辑器;该事件会在firstArrive执行后再执行。"
|
||||
},
|
||||
"parallelDo": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_lint": true,
|
||||
"_data": "在该层楼时执行的并行事件处理。\n可以在这里写上任意需要自动执行的脚本,比如打怪自动开门等。\n详见文档-事件-并行事件处理。"
|
||||
},
|
||||
"upFloor": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval==null||((thiseval instanceof Array) && thiseval.length==2)",
|
||||
"_data": "该层上楼点,如[2,3]。\n如果此项不为null,则楼层转换时的stair:upFloor,以及楼传器的落点会被替换成该点而不是该层的上楼梯。"
|
||||
},
|
||||
"downFloor": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval==null||((thiseval instanceof Array) && thiseval.length==2)",
|
||||
"_data": "该层下楼点,如[2,3]。\n如果此项不为null,则楼层转换时的stair:downFloor,以及楼传器的落点会被替换成该点而不是该层的下楼梯。"
|
||||
},
|
||||
"defaultGround": {
|
||||
"_leaf": true,
|
||||
"_type": "select",
|
||||
"_select": {
|
||||
"values": Object.keys(editor.core.icons.icons.terrains)
|
||||
},
|
||||
"_data": "默认地面的图块ID,此项修改后需要刷新才能看到效果。"
|
||||
},
|
||||
"images": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "背景/前景图;你可以选择若干张图片来作为背景/前景素材。详细用法请参见文档“自定义素材”中的说明。"
|
||||
},
|
||||
"color": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "该层的默认画面色调。本项可不写(代表无色调),如果写需要是一个RGBA数组如[255,0,0,0.3]"
|
||||
},
|
||||
"weather": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "该层的默认天气。本项可忽略表示晴天,如果写则第一项为\"rain\",\"snow\"或\"fog\"代表雨雪雾,第二项为1-10之间的数代表强度。\n如[\"rain\", 8]代表8级雨天。"
|
||||
},
|
||||
"bgm": {
|
||||
"_leaf": true,
|
||||
"_type": "select",
|
||||
"_select": {
|
||||
"values": [null].concat(Object.keys(editor.core.material.bgms))
|
||||
},
|
||||
"_data": "到达该层后默认播放的BGM。本项可忽略,或者为一个定义过的背景音乐如\"bgm.mp3\"。"
|
||||
},
|
||||
"item_ratio": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "(thiseval==~~thiseval && thiseval>=0)||thiseval==null",
|
||||
"_data": "每一层的宝石/血瓶效果,即获得宝石和血瓶时框内\"ratio\"的值。"
|
||||
},
|
||||
"underGround": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否是地下层;如果该项为true则同层传送将传送至上楼梯"
|
||||
}
|
||||
}
|
||||
},
|
||||
"loc": {
|
||||
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"events": {
|
||||
"_leaf": true,
|
||||
"_type": "event",
|
||||
"_event": "event",
|
||||
"_data": "该点的可能事件列表,可以双击进入事件编辑器。"
|
||||
},
|
||||
"changeFloor": {
|
||||
"_leaf": true,
|
||||
"_type": "event",
|
||||
"_event": "changeFloor",
|
||||
"_data": "该点楼层转换事件;该事件不能和上面的events同时出现,否则会被覆盖"
|
||||
},
|
||||
"afterBattle": {
|
||||
"_leaf": true,
|
||||
"_type": "event",
|
||||
"_event": "afterBattle",
|
||||
"_data": "该点战斗后可能触发的事件列表,可以双击进入事件编辑器。"
|
||||
},
|
||||
"afterGetItem": {
|
||||
"_leaf": true,
|
||||
"_type": "event",
|
||||
"_event": "afterGetItem",
|
||||
"_data": "该点获得道具后可能触发的事件列表,可以双击进入事件编辑器。"
|
||||
},
|
||||
"afterOpenDoor": {
|
||||
"_leaf": true,
|
||||
"_type": "event",
|
||||
"_event": "afterOpenDoor",
|
||||
"_data": "该点开完门后可能触发的事件列表,可以双击进入事件编辑器。"
|
||||
},
|
||||
"cannotMove": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval==null||(thiseval instanceof Array)",
|
||||
"_data": "该点不可通行的方向 \n 可以在这里定义该点不能前往哪个方向,可以达到悬崖之类的效果\n例如 [\"up\", \"left\"] 代表该点不能往上和左走"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,672 +0,0 @@
|
||||
var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
|
||||
{
|
||||
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"main": {
|
||||
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"floorIds": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "editor.mode.checkFloorIds(thiseval)",
|
||||
"_data": "在这里按顺序放所有的楼层;其顺序直接影响到楼层传送器、浏览地图和上/下楼器的顺序"
|
||||
},
|
||||
"images": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "editor.mode.checkUnique(thiseval)",
|
||||
"_data": "在此存放所有可能使用的图片(tilesets除外) \n图片可以被作为背景图(的一部分),也可以直接用自定义事件进行显示。 \n 图片名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好 \n 建议对于较大的图片,在网上使用在线的“图片压缩工具(http://compresspng.com/zh/)”来进行压缩,以节省流量 \n 依次向后添加"
|
||||
},
|
||||
"tilesets": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "editor.mode.checkUnique(thiseval)",
|
||||
"_data": "在此存放额外素材的图片名, \n可以自定导入任意张素材图片,无需PS,无需注册,即可直接在游戏中使用 \n 形式如[\"1.png\", \"2.png\"] ,将需要的素材图片放在images目录下 \n 素材的宽高必须都是32的倍数,且图片上的总图块数不超过1000(即最多有1000个32*32的图块在该图片上)"
|
||||
},
|
||||
"animates": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "editor.mode.checkUnique(thiseval)",
|
||||
"_data": "在此存放所有可能使用的动画,必须是animate格式,在这里不写后缀名 \n动画必须放在animates目录下;文件名不能使用中文,不能带空格或特殊字符 \n \"jianji\", \"thunder\" \n 根据需求自行添加"
|
||||
},
|
||||
"bgms": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "editor.mode.checkUnique(thiseval)",
|
||||
"_data": "在此存放所有的bgm,和文件名一致。 \n音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好"
|
||||
},
|
||||
"sounds": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "editor.mode.checkUnique(thiseval)",
|
||||
"_data": "在此存放所有的SE,和文件名一致 \n音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好"
|
||||
},
|
||||
"startBackground": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "标题界面的背景,建议使用jpg格式以压缩背景图空间"
|
||||
},
|
||||
"startLogoStyle": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "标题样式:可以改变颜色,也可以写\"display: none\"来隐藏标题"
|
||||
},
|
||||
"levelChoose": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval instanceof Array && thiseval.length>=1 && thiseval[0] instanceof Array && thiseval[0].length==2",
|
||||
"_data": "难度选择:每个数组的第一个是其在标题界面显示的难度,第二个是在游戏内部传输的字符串,会显示在状态栏,修改此处后需要在project/functions中作相应更改。\n如果需直接开始游戏将下面的startDirectly开关打开即可。"
|
||||
},
|
||||
"equipName": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "(thiseval instanceof Array && thiseval.length<=6)||thiseval==null",
|
||||
"_data": "装备位名称,为不超过6个的数组,此项的顺序与equiptype数值关联;例如可写[\"武器\",\"防具\",\"首饰\"]等等。"
|
||||
},
|
||||
"startBgm": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "在标题界面应该播放的bgm内容"
|
||||
},
|
||||
"statusLeftBackground": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "横屏时左侧状态栏的背景样式,可以定义背景图、平铺方式等。\n具体请网上搜索\"css background\"了解写法。\n如果弄一张图片作为背景图,推荐写法:\n\"url(project/images/XXX.png) 0 0/100% 100% no-repeat\"\n图片最好进行一些压缩等操作节省流量。"
|
||||
},
|
||||
"statusTopBackground": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "竖屏时上方状态栏的背景样式,可以定义背景图、平铺方式等。\n具体请网上搜索\"css background\"了解写法。\n如果弄一张图片作为背景图,推荐写法:\n\"url(project/images/XXX.png) 0 0/100% 100% no-repeat\"\n图片最好进行一些压缩等操作节省流量。"
|
||||
},
|
||||
"toolsBackground": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "竖屏时下方道具栏的背景样式,可以定义背景图、平铺方式等。\n具体请网上搜索\"css background\"了解写法。\n如果弄一张图片作为背景图,推荐写法:\n\"url(project/images/XXX.png) 0 0/100% 100% no-repeat\"\n图片最好进行一些压缩等操作节省流量。"
|
||||
},
|
||||
"borderColor": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "边框颜色,包括游戏边界的边框和对话框边框等。"
|
||||
},
|
||||
"statusBarColor": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "状态栏的文字颜色,默认是白色"
|
||||
},
|
||||
"hardLabelColor": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "难度显示的颜色,默认是红色"
|
||||
},
|
||||
"floorChangingBackground": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "楼层转换界面的背景样式;可以使用纯色(默认值black),也可以使用图片(参见状态栏的图片写法)"
|
||||
},
|
||||
"floorChangingTextColor": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "楼层转换界面的文字颜色,默认是白色"
|
||||
},
|
||||
"font": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "游戏中使用的字体,默认是Verdana"
|
||||
}
|
||||
}
|
||||
},
|
||||
"firstData": {
|
||||
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"title": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "游戏名,将显示在标题页面以及切换楼层的界面中"
|
||||
},
|
||||
"name": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_range": "/^[a-zA-Z0-9_]{1,30}$/.test(thiseval)",
|
||||
"_data": "游戏的唯一英文标识符。由英文、数字、下划线组成,不能超过30个字符。\n此项必须修改,其将直接影响到存档的定位!"
|
||||
},
|
||||
"version": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "当前游戏版本;版本不一致的存档不能通用。"
|
||||
},
|
||||
"floorId": {
|
||||
"_leaf": true,
|
||||
"_type": "select",
|
||||
"_select": {
|
||||
"values": data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.main.floorIds
|
||||
},
|
||||
"_range": "data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.main.floorIds.indexOf(thiseval)!==-1",
|
||||
"_data": "初始楼层的ID"
|
||||
},
|
||||
"hero": {
|
||||
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"name": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "勇士名;可以改成喜欢的"
|
||||
},
|
||||
"lv": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval==~~thiseval &&thiseval>0",
|
||||
"_data": "初始等级,该项必须为正整数"
|
||||
},
|
||||
"hpmax": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "初始生命上限,只有在enableHPMax开启时才有效"
|
||||
},
|
||||
"hp": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "初始生命值"
|
||||
},
|
||||
"mana": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "初始魔力值,只在enableMana开启时才有效"
|
||||
},
|
||||
"atk": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "初始攻击"
|
||||
},
|
||||
"def": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "初始防御"
|
||||
},
|
||||
"mdef": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "初始魔防"
|
||||
},
|
||||
"money": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "初始金币"
|
||||
},
|
||||
"experience": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "初始经验"
|
||||
},
|
||||
"equipment": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval instanceof Array",
|
||||
"_data": "初始装上的装备,此处建议请直接留空数组"
|
||||
},
|
||||
"items": {
|
||||
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"keys": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval instanceof Object && !(thiseval instanceof Array)",
|
||||
"_data": "初始三种钥匙个数"
|
||||
},
|
||||
"constants": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval instanceof Object && !(thiseval instanceof Array)",
|
||||
"_data": "初始永久道具个数,例如初始送手册可以写 {\"book\": 1}"
|
||||
},
|
||||
"tools": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval instanceof Object && !(thiseval instanceof Array)",
|
||||
"_data": "初始消耗道具个数,例如初始有两破可以写 {\"pickaxe\": 2}"
|
||||
},
|
||||
"equips": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval instanceof Object && !(thiseval instanceof Array)",
|
||||
"_data": "初始装备个数,例如初始送铁剑可以写 {\"sword1\": 1}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"loc": {
|
||||
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"direction": {
|
||||
"_leaf": true,
|
||||
"_type": "select",
|
||||
"_data": "勇士初始方向",
|
||||
"_select": {
|
||||
"values": [
|
||||
"up",
|
||||
"down",
|
||||
"left",
|
||||
"right"
|
||||
]
|
||||
},
|
||||
},
|
||||
"x": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "勇士初始x坐标"
|
||||
},
|
||||
"y": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "勇士初始y坐标"
|
||||
}
|
||||
}
|
||||
},
|
||||
"flags": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval instanceof Object && !(thiseval instanceof Array)",
|
||||
"_data": "游戏过程中的变量或flags"
|
||||
},
|
||||
"steps": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "行走步数统计"
|
||||
}
|
||||
}
|
||||
},
|
||||
"startCanvas": {
|
||||
"_leaf": true,
|
||||
"_type": "event",
|
||||
"_event": "firstArrive",
|
||||
"_range": "thiseval==null || thiseval instanceof Array",
|
||||
"_data": "标题界面事件化,可以使用事件流的形式来绘制开始界面等。\n需要开启startUsingCanvas这个开关。\n详见文档-个性化-标题界面事件化。"
|
||||
},
|
||||
"startText": {
|
||||
"_leaf": true,
|
||||
"_type": "event",
|
||||
"_event": "firstArrive",
|
||||
"_range": "thiseval==null || thiseval instanceof Array",
|
||||
"_data": "游戏开始前剧情,可以执行任意自定义事件。\n双击进入事件编辑器。\n如果无剧情直接留一个空数组即可。"
|
||||
},
|
||||
"shops": {
|
||||
"_leaf": true,
|
||||
"_type": "event",
|
||||
"_event": "shop",
|
||||
"_range": "thiseval instanceof Array",
|
||||
"_data": "全局商店,是一个数组,可以双击进入事件编辑器。"
|
||||
},
|
||||
"levelUp": {
|
||||
"_leaf": true,
|
||||
"_type": "event",
|
||||
"_event": "level",
|
||||
"_range": "thiseval==null || thiseval instanceof Array",
|
||||
"_data": "经验升级所需要的数值,是一个数组,可以双击进行编辑。 \n 第一项为初始等级,仅title生效 \n 每一个里面可以含有三个参数 need, title, action \n need为所需要的经验数值,可以是个表达式。请确保need依次递增 \n title为该等级的名称,也可以省略代表使用系统默认值;本项将显示在状态栏中 \n action为本次升级所执行的事件,可由若干项组成"
|
||||
}
|
||||
}
|
||||
},
|
||||
"values": {
|
||||
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"lavaDamage": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "经过血网受到的伤害"
|
||||
},
|
||||
"poisonDamage": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "中毒后每步受到的伤害"
|
||||
},
|
||||
"weakValue": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "衰弱状态下攻防减少的数值\n如果此项不小于1,则作为实际下降的数值(比如10就是攻防各下降10)\n如果在0到1之间则为下降的比例(比如0.3就是下降30%的攻防)"
|
||||
},
|
||||
"redJewel": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "红宝石加攻击的数值"
|
||||
},
|
||||
"blueJewel": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "蓝宝石加防御的数值"
|
||||
},
|
||||
"greenJewel": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "绿宝石加魔防的数值"
|
||||
},
|
||||
"redPotion": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "红血瓶加血数值"
|
||||
},
|
||||
"bluePotion": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "蓝血瓶加血数值"
|
||||
},
|
||||
"yellowPotion": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "黄血瓶加血数值"
|
||||
},
|
||||
"greenPotion": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "绿血瓶加血数值"
|
||||
},
|
||||
"breakArmor": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "破甲的比例(战斗前,怪物附加角色防御的x倍作为伤害)"
|
||||
},
|
||||
"counterAttack": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "反击的比例(战斗时,怪物每回合附加角色攻击的x倍作为伤害,无视角色防御)"
|
||||
},
|
||||
"purify": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "净化的比例(战斗前,怪物附加勇士魔防的x倍作为伤害)"
|
||||
},
|
||||
"hatred": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "仇恨属性中,每杀死一个怪物获得的仇恨值"
|
||||
},
|
||||
"moveSpeed": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "行走速度,即勇士每走一格的时间,一般100比较合适"
|
||||
},
|
||||
"animateSpeed": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "全局动画时间,即怪物振动频率,一般300比较合适"
|
||||
},
|
||||
"floorChangeTime": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "默认楼层切换时间"
|
||||
}
|
||||
}
|
||||
},
|
||||
"flags": {
|
||||
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"enableFloor": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否在状态栏显示当前楼层"
|
||||
},
|
||||
"enableName": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否在状态栏显示勇士名字"
|
||||
},
|
||||
"enableLv": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否在状态栏显示当前等级"
|
||||
},
|
||||
"enableHPMax": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否是否启用生命上限"
|
||||
},
|
||||
"enableMana": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否开启魔力值"
|
||||
},
|
||||
"enableMDef": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否在状态栏及战斗界面显示魔防(护盾)"
|
||||
},
|
||||
"enableMoney": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否在状态栏、怪物手册及战斗界面显示金币"
|
||||
},
|
||||
"enableExperience": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否在状态栏、怪物手册及战斗界面显示经验"
|
||||
},
|
||||
"enableLevelUp": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否允许等级提升(进阶);如果上面enableExperience为false,则此项恒视为false"
|
||||
},
|
||||
"levelUpLeftMode": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "进阶使用扣除模式,即在状态栏显示距离下个等级所需要的经验值;只有enableExperience和enableLevelUp均开启时才有效。"
|
||||
},
|
||||
"enableKeys": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否在状态栏显示三色钥匙数量"
|
||||
},
|
||||
"enablePZF": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否在状态栏显示破炸飞数量"
|
||||
},
|
||||
"enableDebuff": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否在状态栏显示毒衰咒"
|
||||
},
|
||||
"enableSkill": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否启用技能栏"
|
||||
},
|
||||
"flyNearStair": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否需要在楼梯边使用传送器"
|
||||
},
|
||||
"pickaxeFourDirections": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "使用破墙镐是否四个方向都破坏;如果false则只破坏面前的墙壁"
|
||||
},
|
||||
"bombFourDirections": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "使用炸弹是否四个方向都会炸;如果false则只炸面前的怪物(即和圣锤等价)"
|
||||
},
|
||||
"snowFourDirections": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "使用冰冻徽章是否四个方向都会消除熔岩;如果false则只消除面前的熔岩"
|
||||
},
|
||||
"bigKeyIsBox": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "如果此项为true,则视为钥匙盒,红黄蓝钥匙+1;若为false,则视为大黄门钥匙"
|
||||
},
|
||||
"equipment": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "剑和盾是否作为装备。如果此项为true,则作为装备,需要在装备栏使用,否则将直接加属性。"
|
||||
},
|
||||
"equipboxButton": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "状态栏的装备按钮。若此项为true则将状态栏中的楼层转换器按钮换为装备栏按钮"
|
||||
},
|
||||
"enableAddPoint": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否支持加点"
|
||||
},
|
||||
"enableNegativeDamage": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否支持负伤害(回血)"
|
||||
},
|
||||
"hatredDecrease": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否在和仇恨怪战斗后减一半的仇恨值,此项为false则和仇恨怪不会扣减仇恨值。"
|
||||
},
|
||||
"betweenAttackCeil": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "夹击方式是向上取整还是向下取整。如果此项为true则为向上取整,为false则为向下取整"
|
||||
},
|
||||
"useLoop": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否循环计算临界;如果此项为true则使用循环法(而不是回合数计算法)来算临界\n从V2.5.3开始,对于大数据的循环法将改为使用二分法进行计算"
|
||||
},
|
||||
"startUsingCanvas": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否开始菜单canvas化;如果此项为true,则将使用canvas来绘制开始菜单"
|
||||
},
|
||||
"startDirectly": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "点击“开始游戏”后是否立刻开始游戏而不显示难度选择界面"
|
||||
},
|
||||
"statusCanvas": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否状态栏canvas化,即手动自定义绘制状态栏。\n如果此项开启,则可在脚本编辑的drawStatusBar中自定义绘制菜单栏。"
|
||||
},
|
||||
"statusCanvasRowsOnMobile": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval==null || (thiseval>0 && thiseval<=4)",
|
||||
"_data": "竖屏模式下,顶端状态栏canvas化后的行数。\n此项将决定竖屏的状态栏高度,如果设置则不小于1且不大于4。\n仅在statusCanvas开启时才有效"
|
||||
},
|
||||
"displayEnemyDamage": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否地图怪物显伤;用户可以手动在菜单栏中开关"
|
||||
},
|
||||
"displayCritical": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否地图显示临界;用户可以手动在菜单栏中开关"
|
||||
},
|
||||
"displayExtraDamage": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否地图高级显伤(领域、夹击等);用户可以手动在菜单栏中开关"
|
||||
},
|
||||
"enableGentleClick": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否允许轻触(获得面前物品)"
|
||||
},
|
||||
"potionWhileRouting": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "寻路算法是否经过血瓶;如果该项为false,则寻路算法会自动尽量绕过血瓶"
|
||||
},
|
||||
"ignoreChangeFloor": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "经过楼梯、传送门时是否能“穿透”。\n穿透的意思是,自动寻路得到的的路径中间经过了楼梯,行走时是否触发楼层转换事件"
|
||||
},
|
||||
"canGoDeadZone": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否允许走到将死的领域上。如果此项为true,则可以走到将死的领域上"
|
||||
},
|
||||
"enableMoveDirectly": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否允许瞬间移动"
|
||||
},
|
||||
"enableDisabledShop": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否允许查看未开启状态的快捷商店内容;如果此项为真,则对于未开启状态的商店允许查看其内容(但不能购买)"
|
||||
},
|
||||
"disableShopOnDamage": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否在经过领域/夹击/路障等伤害后禁用快捷商店。"
|
||||
},
|
||||
"checkConsole": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否检查控制台的开启情况。"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -43,24 +43,11 @@ editor.info
|
||||
editor.prototype.init = function (callback) {
|
||||
|
||||
editor_util_wrapper(editor);
|
||||
editor_game_wrapper(editor, main, core);
|
||||
editor_table_wrapper(editor);
|
||||
|
||||
var afterMainInit = 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
|
||||
}));
|
||||
editor.game.fixFunctionInGameData();
|
||||
editor.main = main;
|
||||
editor.core = core;
|
||||
editor.fs = fs;
|
||||
@ -78,10 +65,10 @@ editor.prototype.init = function (callback) {
|
||||
|
||||
var afterCoreReset = function () {
|
||||
|
||||
editor.idsInit(core.maps, core.icons.icons); // 初始化图片素材信息
|
||||
editor.game.idsInit(core.maps, core.icons.icons); // 初始化图片素材信息
|
||||
editor.drawInitData(core.icons.icons); // 初始化绘图
|
||||
|
||||
editor.fetchMapFromCore();
|
||||
editor.game.fetchMapFromCore();
|
||||
editor.updateMap();
|
||||
editor.buildMark();
|
||||
editor.drawEventBlock();
|
||||
@ -105,69 +92,6 @@ editor.prototype.init = function (callback) {
|
||||
afterMainInit();
|
||||
}
|
||||
|
||||
editor.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;
|
||||
}
|
||||
editor.MAX_NUM=MAX_NUM;
|
||||
var getInfoById = function (id) {
|
||||
var block = maps.initBlock(0, 0, id);
|
||||
if (hasOwnProp(block, 'event')) {
|
||||
return block;
|
||||
}
|
||||
}
|
||||
var point = 0;
|
||||
for (var i = 0; i <= MAX_NUM; i++) {
|
||||
var indexBlock = getInfoById(i);
|
||||
editor.indexs[i] = [];
|
||||
if (indexBlock) {
|
||||
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'});
|
||||
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]});
|
||||
point++;
|
||||
editor.indexs[i].push(point);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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的整数倍, 请修改后刷新页面');
|
||||
}
|
||||
if(img.width*img.height > 32*32*3000){
|
||||
alert(imgName+'上的图块数量超过了3000,请修改后刷新页面');
|
||||
}
|
||||
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});
|
||||
point++;
|
||||
editor.indexs[id]=[point];
|
||||
}
|
||||
startOffset += core.icons.tilesetStartOffset;
|
||||
}
|
||||
}
|
||||
|
||||
editor.prototype.mapInit = function () {
|
||||
var ec = document.getElementById('event').getContext('2d');
|
||||
ec.clearRect(0, 0, core.bigmap.width*32, core.bigmap.height*32);
|
||||
@ -195,39 +119,6 @@ editor.prototype.mapInit = function () {
|
||||
editor.currentFloorData.cannotMove = {};
|
||||
}
|
||||
|
||||
editor.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?");
|
||||
y = [0];
|
||||
}
|
||||
return editor.ids[y[0]]
|
||||
})
|
||||
});
|
||||
editor.currentFloorId = core.status.floorId;
|
||||
editor.currentFloorData = core.floors[core.status.floorId];
|
||||
for(var ii=0,name;name=['bgmap','fgmap'][ii];ii++){
|
||||
var mapArray = editor.currentFloorData[name];
|
||||
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,')+'],')+']');
|
||||
}
|
||||
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?");
|
||||
y = [0];
|
||||
}
|
||||
return editor.ids[y[0]]
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
editor.prototype.changeFloor = function (floorId, callback) {
|
||||
for(var ii=0,name;name=['map','bgmap','fgmap'][ii];ii++){
|
||||
var mapArray=editor[name].map(function (v) {
|
||||
@ -243,7 +134,7 @@ editor.prototype.changeFloor = function (floorId, callback) {
|
||||
core.bigmap.offsetY=0;
|
||||
editor.moveViewport(0,0);
|
||||
|
||||
editor.fetchMapFromCore();
|
||||
editor.game.fetchMapFromCore();
|
||||
editor.updateMap();
|
||||
editor_mode.floor();
|
||||
editor.drawEventBlock();
|
||||
|
||||
@ -37,6 +37,11 @@ editor_blockly = function () {
|
||||
{"text": "防御+4", "effect": "status:def+=4"},
|
||||
{"text": "魔防+10", "effect": "status:mdef+=10"}
|
||||
]
|
||||
},{
|
||||
"id": "keyShop1",
|
||||
"textInList": "回收钥匙商店",
|
||||
"commonEvent": "回收钥匙商店",
|
||||
"args": ""
|
||||
}],'shop'),
|
||||
MotaActionBlocks['afterBattle_m'].xmlText(),
|
||||
MotaActionBlocks['afterGetItem_m'].xmlText(),
|
||||
@ -71,6 +76,7 @@ editor_blockly = function () {
|
||||
])
|
||||
])
|
||||
]),
|
||||
MotaActionBlocks['confirm_s'].xmlText(),
|
||||
],
|
||||
'数据相关':[
|
||||
MotaActionBlocks['setValue_s'].xmlText([
|
||||
@ -105,12 +111,14 @@ editor_blockly = function () {
|
||||
],
|
||||
'事件控制':[
|
||||
MotaActionBlocks['if_s'].xmlText(),
|
||||
MotaActionBlocks['if_1_s'].xmlText(),
|
||||
MotaActionFunctions.actionParser.parseList({"type": "switch", "condition": "判别值", "caseList": [
|
||||
{"action": [{"type": "comment", "text": "当判别值是值的场合执行此事件"}]},
|
||||
{"action": []},
|
||||
{"action": [], "nobreak": true},
|
||||
{"case": "default", "action": [{"type": "comment", "text": "当没有符合的值的场合执行default事件"}]},
|
||||
]}),
|
||||
MotaActionBlocks['while_s'].xmlText(),
|
||||
MotaActionBlocks['dowhile_s'].xmlText(),
|
||||
MotaActionBlocks['break_s'].xmlText(),
|
||||
MotaActionBlocks['continue_s'].xmlText(),
|
||||
MotaActionBlocks['revisit_s'].xmlText(),
|
||||
@ -136,8 +144,8 @@ editor_blockly = function () {
|
||||
MotaActionBlocks['animate_s'].xmlText(),
|
||||
MotaActionBlocks['showStatusBar_s'].xmlText(),
|
||||
MotaActionBlocks['hideStatusBar_s'].xmlText(),
|
||||
MotaActionBlocks['setFg_0_s'].xmlText(),
|
||||
MotaActionBlocks['setFg_1_s'].xmlText(),
|
||||
MotaActionBlocks['setCurtain_0_s'].xmlText(),
|
||||
MotaActionBlocks['setCurtain_1_s'].xmlText(),
|
||||
MotaActionBlocks['screenFlash_s'].xmlText(),
|
||||
MotaActionBlocks['setWeather_s'].xmlText(),
|
||||
MotaActionBlocks['playBgm_s'].xmlText(),
|
||||
@ -154,6 +162,7 @@ editor_blockly = function () {
|
||||
],
|
||||
'原生脚本':[
|
||||
MotaActionBlocks['function_s'].xmlText(),
|
||||
MotaActionBlocks['unknown_s'].xmlText(),
|
||||
],
|
||||
'值块':[
|
||||
MotaActionBlocks['setValue_s'].xmlText([
|
||||
@ -583,6 +592,7 @@ function omitedcheckUpdateFunction(event) {
|
||||
'showTextImage_s': 'EvalString_0',
|
||||
'function_s': 'RawEvalString_0',
|
||||
'shopsub': 'EvalString_3',
|
||||
'confirm_s': 'EvalString_0',
|
||||
}
|
||||
var f = b ? textStringDict[b.type] : null;
|
||||
if (f) {
|
||||
|
||||
@ -17,7 +17,7 @@ editor_file = function (editor, callback) {
|
||||
if (window.location.href.indexOf('_server') !== -1)
|
||||
script.src = key + '.js';
|
||||
else
|
||||
script.src = '_server/' + key + '.js';
|
||||
script.src = '_server/table/' + key + '.js';
|
||||
document.body.appendChild(script);
|
||||
script.onload = function () {
|
||||
editor_file[value] = eval(key.replace('.', '_') + '_c456ea59_6018_45ef_8bcc_211a24c627dc');
|
||||
@ -941,11 +941,7 @@ editor_file = function (editor, callback) {
|
||||
return formatArrStr;
|
||||
}
|
||||
|
||||
var encode = function (str) {
|
||||
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) {
|
||||
return String.fromCharCode(parseInt(p1, 16))
|
||||
}))
|
||||
}
|
||||
var encode = editor.util.encode64
|
||||
|
||||
var alertWhenCompress = function(){
|
||||
if(editor.useCompress===true){
|
||||
|
||||
124
_server/editor_game.js
Normal file
124
_server/editor_game.js
Normal file
@ -0,0 +1,124 @@
|
||||
editor_game_wrapper = function (editor, main, core) {
|
||||
|
||||
editor_game = function () {
|
||||
|
||||
}
|
||||
|
||||
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
|
||||
}));
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
editor.MAX_NUM=MAX_NUM;
|
||||
var getInfoById = function (id) {
|
||||
var block = maps.initBlock(0, 0, id);
|
||||
if (hasOwnProp(block, 'event')) {
|
||||
return block;
|
||||
}
|
||||
}
|
||||
var point = 0;
|
||||
for (var i = 0; i <= MAX_NUM; i++) {
|
||||
var indexBlock = getInfoById(i);
|
||||
editor.indexs[i] = [];
|
||||
if (indexBlock) {
|
||||
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'});
|
||||
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]});
|
||||
point++;
|
||||
editor.indexs[i].push(point);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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的整数倍, 请修改后刷新页面');
|
||||
}
|
||||
if(img.width*img.height > 32*32*3000){
|
||||
alert(imgName+'上的图块数量超过了3000,请修改后刷新页面');
|
||||
}
|
||||
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});
|
||||
point++;
|
||||
editor.indexs[id]=[point];
|
||||
}
|
||||
startOffset += core.icons.tilesetStartOffset;
|
||||
}
|
||||
}
|
||||
|
||||
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?");
|
||||
y = [0];
|
||||
}
|
||||
return editor.ids[y[0]]
|
||||
})
|
||||
});
|
||||
editor.currentFloorId = core.status.floorId;
|
||||
editor.currentFloorData = core.floors[core.status.floorId];
|
||||
for(var ii=0,name;name=['bgmap','fgmap'][ii];ii++){
|
||||
var mapArray = editor.currentFloorData[name];
|
||||
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,')+'],')+']');
|
||||
}
|
||||
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?");
|
||||
y = [0];
|
||||
}
|
||||
return editor.ids[y[0]]
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
editor.constructor.prototype.game = new editor_game();
|
||||
}
|
||||
//editor_game_wrapper(editor);
|
||||
@ -128,13 +128,22 @@ editor_multi = function () {
|
||||
editor_multi.id = '';
|
||||
return;
|
||||
}
|
||||
|
||||
if (editor_multi.id === 'callFromBlockly') {
|
||||
// ----- 自动格式化
|
||||
_format();
|
||||
if (editor_multi.id === 'callFromBlockly') {
|
||||
editor_multi.id = '';
|
||||
editor_multi.multiLineDone();
|
||||
return;
|
||||
}
|
||||
|
||||
if (editor_multi.id === 'importFile') {
|
||||
_format();
|
||||
editor_multi.id = '';
|
||||
editor_multi.writeFileDone();
|
||||
return;
|
||||
}
|
||||
|
||||
var setvalue = function (value) {
|
||||
var thisTr = document.getElementById(editor_multi.id);
|
||||
editor_multi.id = '';
|
||||
@ -159,6 +168,8 @@ editor_multi = function () {
|
||||
editor_multi.hide();
|
||||
input.onchange();
|
||||
}
|
||||
// ----- 自动格式化
|
||||
_format();
|
||||
setvalue(codeEditor.getValue() || '');
|
||||
}
|
||||
|
||||
@ -179,6 +190,49 @@ editor_multi = function () {
|
||||
multiLineArgs[2](newvalue, multiLineArgs[0], multiLineArgs[1])
|
||||
}
|
||||
|
||||
var _fileValues = ['']
|
||||
editor_multi.importFile = function (filename) {
|
||||
editor_multi.id = 'importFile'
|
||||
_fileValues[0] = filename
|
||||
codeEditor.setValue('loading')
|
||||
editor_multi.show();
|
||||
fs.readFile(filename, 'base64', function (e, d) {
|
||||
if (e) {
|
||||
codeEditor.setValue('加载文件失败:\n' + e)
|
||||
editor_multi.id = ''
|
||||
return;
|
||||
}
|
||||
var str = editor.util.decode64(d)
|
||||
codeEditor.setValue(str)
|
||||
_fileValues[1] = str
|
||||
})
|
||||
}
|
||||
|
||||
editor_multi.writeFileDone = function () {
|
||||
fs.writeFile(_fileValues[0], editor.util.encode64(codeEditor.getValue() || ''), 'base64', function (err, data) {
|
||||
if (err) printe('文件写入失败,请手动粘贴至' + _fileValues[0] + '\n' + err);
|
||||
else {
|
||||
editor_multi.hide();
|
||||
printf(_fileValues[0] + " 写入成功,F5刷新后生效");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
editor_multi.editCommentJs = function (mod) {
|
||||
var dict = {
|
||||
loc: '_server/table/comment.js',
|
||||
enemyitem: '_server/table/comment.js',
|
||||
floor: '_server/table/comment.js',
|
||||
tower: '_server/table/data.comment.js',
|
||||
functions: '_server/table/functions.comment.js',
|
||||
commonevent: '_server/table/events.comment.js',
|
||||
plugins: '_server/table/plugins.comment.js',
|
||||
}
|
||||
editor_multi.lintAutocomplete = true
|
||||
editor_multi.setLint()
|
||||
editor_multi.importFile(dict[mod])
|
||||
}
|
||||
|
||||
return editor_multi;
|
||||
}
|
||||
//editor_multi=editor_multi();
|
||||
@ -121,7 +121,7 @@ editor_table_wrapper = function (editor) {
|
||||
// 事实上能执行到这一步工程没崩掉打不开,就继续吧..
|
||||
if (keysForTableOrder[ii] === voidMark) {
|
||||
if (typeof id_815975ad_ee6f_4684_aac7_397b7e392702 === "undefined") {
|
||||
alert('comment和data不匹配,请在群 HTML5造塔技术交流群 959329661 内反馈')
|
||||
// alert('comment和data不匹配,请在群 HTML5造塔技术交流群 959329661 内反馈')
|
||||
console.error('comment和data不匹配,请在群 HTML5造塔技术交流群 959329661 内反馈')
|
||||
id_815975ad_ee6f_4684_aac7_397b7e392702 = 1;
|
||||
}
|
||||
|
||||
@ -145,6 +145,18 @@ editor_util_wrapper = function (editor) {
|
||||
editor_util.prototype.hue2rgb = hue2rgb
|
||||
editor_util.prototype.hslToRgb = hslToRgb
|
||||
|
||||
editor_util.prototype.encode64 = function (str) {
|
||||
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) {
|
||||
return String.fromCharCode(parseInt(p1, 16))
|
||||
}))
|
||||
}
|
||||
|
||||
editor_util.prototype.decode64 = function (str) {
|
||||
return decodeURIComponent(atob(str.replace(/-/g, '+').replace(/_/g, '/').replace(/\s/g, '')).split('').map(function (c) {
|
||||
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)
|
||||
}).join(''))
|
||||
}
|
||||
|
||||
editor.constructor.prototype.util = new editor_util();
|
||||
}
|
||||
//editor_util_wrapper(editor);
|
||||
@ -1,43 +0,0 @@
|
||||
var events_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
|
||||
{
|
||||
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"commonEvent": {
|
||||
|
||||
"_type": "object",
|
||||
"_data": function (key) {
|
||||
var obj = {
|
||||
"加点事件": {
|
||||
"_leaf": true,
|
||||
"_type": "event",
|
||||
"_range": "thiseval instanceof Array",
|
||||
"_event": "commonEvent",
|
||||
"_data": "打败怪物后加点"
|
||||
},
|
||||
"毒衰咒处理": {
|
||||
"_leaf": true,
|
||||
"_type": "event",
|
||||
"_range": "thiseval instanceof Array",
|
||||
"_event": "commonEvent",
|
||||
"_data": "毒衰咒效果处理"
|
||||
},
|
||||
"滑冰事件": {
|
||||
"_leaf": true,
|
||||
"_type": "event",
|
||||
"_range": "thiseval instanceof Array",
|
||||
"_event": "commonEvent",
|
||||
"_data": "滑冰事件"
|
||||
},
|
||||
}
|
||||
if (obj[key]) return obj[key];
|
||||
return {
|
||||
"_leaf": true,
|
||||
"_type": "event",
|
||||
"_event": "commonEvent",
|
||||
"_data": "自定义公共事件,可以双击进入事件编辑器"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,212 +0,0 @@
|
||||
var functions_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
|
||||
{
|
||||
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"events": {
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"resetGame": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "重置整个游戏"
|
||||
},
|
||||
"setInitData": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "设置初始属性"
|
||||
},
|
||||
"win": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "游戏获胜事件"
|
||||
},
|
||||
"lose": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "游戏失败事件"
|
||||
},
|
||||
"changingFloor": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "切换楼层中"
|
||||
},
|
||||
"afterChangeFloor": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "切换楼层后"
|
||||
},
|
||||
"flyTo": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "楼层飞行"
|
||||
},
|
||||
"beforeBattle": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "战前事件"
|
||||
},
|
||||
"afterBattle": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "战后事件"
|
||||
},
|
||||
"afterOpenDoor": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "开门后事件"
|
||||
},
|
||||
"afterGetItem": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "获得道具后事件"
|
||||
},
|
||||
"afterChangeLight": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "改变亮灯事件"
|
||||
},
|
||||
"afterPushBox": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "推箱子事件"
|
||||
},
|
||||
"afterUseBomb": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "炸弹事件"
|
||||
},
|
||||
"canUseQuickShop": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "能否用快捷商店"
|
||||
}
|
||||
}
|
||||
},
|
||||
"enemys": {
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"getSpecials": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "怪物特殊属性定义"
|
||||
},
|
||||
"getEnemyInfo": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "获得怪物真实属性"
|
||||
},
|
||||
"getDamageInfo": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "获得战斗伤害信息"
|
||||
},
|
||||
"updateEnemys": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "更新怪物数据"
|
||||
}
|
||||
}
|
||||
},
|
||||
"actions": {
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"onKeyUp": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "按键处理"
|
||||
}
|
||||
}
|
||||
},
|
||||
"control": {
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"saveData": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "存档操作"
|
||||
},
|
||||
"loadData": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "读档操作"
|
||||
},
|
||||
"updateStatusBar": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "更新状态栏"
|
||||
},
|
||||
"updateCheckBlock": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "阻激夹域伤害"
|
||||
},
|
||||
"moveOneStep": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "每一步后的操作"
|
||||
},
|
||||
"moveDirectly": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "瞬间移动处理"
|
||||
},
|
||||
"parallelDo": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "并行事件处理"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ui": {
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"drawStatusBar": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "自绘状态栏"
|
||||
},
|
||||
"drawStatistics": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "地图数据统计"
|
||||
},
|
||||
"drawAbout": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "绘制关于界面"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,27 +0,0 @@
|
||||
var plugins_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
|
||||
{
|
||||
"_type": "object",
|
||||
"_data": function (key) {
|
||||
var obj = {
|
||||
"init": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "typeof(thiseval)=='string'",
|
||||
"_data": "自定义插件"
|
||||
},
|
||||
"drawLight": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "typeof(thiseval)=='string' || thiseval==null",
|
||||
"_data": "绘制灯光效果"
|
||||
},
|
||||
}
|
||||
if (obj[key]) return obj[key];
|
||||
return {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "typeof(thiseval)=='string' || thiseval==null",
|
||||
"_data": "自定义插件"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,48 +1,52 @@
|
||||
# 重构
|
||||
|
||||
+ [ ] 按功能拆分文件
|
||||
+ [ ] 左侧页面模块化, 方便添加
|
||||
+ [ ] 不同的模式的文件操作尽可能模块化
|
||||
+ 按功能拆分文件
|
||||
+ 左侧页面模块化, 方便添加
|
||||
+ 不同的模式的文件操作尽可能模块化
|
||||
|
||||
---
|
||||
|
||||
文件结构
|
||||
## 文件结构
|
||||
|
||||
+ [x] editor_blockly 图块化事件编辑器, 基本不改动
|
||||
+ [x] editor_multi 多行文本编辑器, 基本不改动
|
||||
+ [ ] editor_table 处理表格的生成, 及其响应的事件, 从原editor\_mode中分离
|
||||
+ [ ] editor_blockly 图块化事件编辑器
|
||||
+ [ ] editor_multi 多行文本编辑器
|
||||
+ [x] editor_table 处理表格的生成, 及其响应的事件, 从原editor\_mode中分离
|
||||
+ [ ] editor_file 调用fs.js编辑文件, 把原editor\_file模块化
|
||||
+ [ ] editor_game 处理来自core的数据, 导入为editor的数据, 从原editor中分离
|
||||
+ [ ] editor_util 生成guid等函数, 从editor分离
|
||||
+ [x] editor_util 生成guid等函数, 从editor分离
|
||||
+ [ ] editor 执行初始化流程加组合各组件
|
||||
|
||||
+ [ ] 原editor_mode 移除
|
||||
+ [ ] 原vm 移除
|
||||
+ [x] \*comment.js 表格注释与结构, 移至table/\*comment.js
|
||||
|
||||
---
|
||||
|
||||
对象结构
|
||||
## 对象结构
|
||||
|
||||
```
|
||||
editor: {
|
||||
__proto__: {
|
||||
blockly: 组件
|
||||
multi: 组件
|
||||
file: 组件
|
||||
table: 组件
|
||||
util: 组件
|
||||
fs
|
||||
util
|
||||
file
|
||||
table
|
||||
multi
|
||||
blockly
|
||||
game
|
||||
}
|
||||
game: 来自游戏的数据
|
||||
config: 编辑器配置
|
||||
mode: 当前的模式(左侧的选择)
|
||||
map: 当前编辑层的地图
|
||||
isMobile: 编辑器是否是手机端
|
||||
currentFloorData: 当前编辑的楼层数据
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
某些注意到的点
|
||||
## 某些注意到的点&准备修改的内容
|
||||
|
||||
+ 插入公共事件的参数的转义处理, .g4中添加ObjectString, 要求其中的值可以JSON.parse, 生成的code中也是作为对象而不是字符串出现
|
||||
|
||||
+ 转义改由editor.blockly处理,editor.multi原样接受和返回
|
||||
|
||||
+ 地图的编辑与其他(如全塔属性和楼层属性), 现在的文件操作的模式是完全不同的
|
||||
楼层文件的储存与其他不同
|
||||
@ -51,16 +55,19 @@ editor: {
|
||||
|
||||
+ 目前editor.map中储存的是info\<object\>, 准备改为和core一致只储存数字
|
||||
|
||||
+ editor.file在修改是不再返回obj和commentobj,只在查询时返回
|
||||
|
||||
## 功能改进
|
||||
|
||||
+ [ ] 大地图
|
||||
在切换时, 每次都回到最左上->每个楼层记录一个位置
|
||||
四个箭头目前不能长按
|
||||
四个箭头支持长按
|
||||
? 滚动条
|
||||
|
||||
+ [ ] ? 表格折叠
|
||||
变为四栏, 可以折叠展开
|
||||
|
||||
+ [ ] blockly对于无法识别的图块原样返回
|
||||
+ [x] blockly对于无法识别的图块原样返回
|
||||
|
||||
+ [ ] ? 简洁的事件方块注册
|
||||
`editor.registerEvent('log',[['test','Int','测试',0],['floorId','Idstring','楼层','MT0']])`
|
||||
@ -78,7 +85,12 @@ editor: {
|
||||
|
||||
+ [ ] 画地图也自动保存
|
||||
|
||||
+ [x] 修改系统的触发器(下拉菜单增加新项)
|
||||
在编辑器修改`comment.js`:现场发readFile请求读文件,然后开脚本编辑器进行编辑
|
||||
|
||||
+ [ ] ? 删除注册项/修改图块ID
|
||||
|
||||
+ [ ] ? 怪物和道具也能像其他类型那样查看“图块信息”(而不只是具体的怪物属性)
|
||||
|
||||
## 左侧页面模式
|
||||
|
||||
|
||||
467
_server/table/comment.js
Normal file
467
_server/table/comment.js
Normal file
@ -0,0 +1,467 @@
|
||||
/*
|
||||
* 表格配置项。
|
||||
* 在这里可以对表格中的各项显示进行配置,包括表格项、提示内容等内容。具体写法照葫芦画瓢即可。
|
||||
* 本配置项包括:道具、怪物、图块属性、楼层属性等内容。
|
||||
*/
|
||||
|
||||
var comment_c456ea59_6018_45ef_8bcc_211a24c627dc = {
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
// --------------------------- 【道具】相关的表格配置 --------------------------- //
|
||||
"items": {
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"items": {
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"cls": {
|
||||
"_leaf": true,
|
||||
"_type": "select",
|
||||
"_select": {
|
||||
"values": [
|
||||
"keys",
|
||||
"items",
|
||||
"constants",
|
||||
"tools",
|
||||
"equips"
|
||||
]
|
||||
},
|
||||
"_data": "只能取keys(钥匙) items(宝石、血瓶) constants(永久物品) tools(消耗道具) equips(装备)"
|
||||
},
|
||||
"name": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "名称"
|
||||
},
|
||||
"text": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "道具在道具栏中显示的描述"
|
||||
},
|
||||
"equip": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "装备属性设置,仅对cls为equips有效。\n如果此项不为null,需要是一个对象,里面可含\"type\",\"atk\",\"def\",\"mdef\",\"animate\"五项,分别对应装备部位、攻防魔防和动画。\n具体详见文档(元件说明-装备)和已有的几个装备的写法。"
|
||||
},
|
||||
"hideInReplay": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否回放时绘制道具栏。\n如果此项为true,则在回放录像时使用本道具将不会绘制道具栏页面,而是直接使用。\n此项建议在会频繁连续多次使用的道具开启(如开启技能,或者《镜子》那样的镜像切换等等)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"itemEffect": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_lint": true,
|
||||
"_data": "即捡即用类物品的效果,仅对cls为items有效。"
|
||||
},
|
||||
"itemEffectTip": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_lint": true,
|
||||
"_data": "即捡即用类物品在获得时提示的文字,仅对cls为items有效。"
|
||||
},
|
||||
"useItemEffect": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_lint": true,
|
||||
"_data": "道具效果,仅对cls为tools或constants有效。"
|
||||
},
|
||||
"canUseItemEffect": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_lint": true,
|
||||
"_data": "当前能否使用该道具,仅对cls为tools或constants有效。"
|
||||
},
|
||||
"canEquip": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_lint": true,
|
||||
"_data": "当前能否装备某个装备,仅对cls为equips有效。\n与canUseItemEffect不同,这里null代表可以装备。"
|
||||
}
|
||||
}
|
||||
},
|
||||
"items_template": { 'cls': 'items', 'name': '新物品' },
|
||||
|
||||
|
||||
// --------------------------- 【怪物】相关的表格配置 --------------------------- //
|
||||
"enemys": {
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"name": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "名称"
|
||||
},
|
||||
"displayIdInBook": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "在怪物手册中映射到的怪物ID。如果此项不为null,则在怪物手册中,将用目标ID来替换该怪物原本的ID。\n此项应被运用在同一个怪物的多朝向上。\n例如,如果想定义同一个怪物的向下和向左的行走图,则需要建立两个属性完全相同的怪物。\n但是这样会导致在怪物手册中同时存在向下和向左的两种怪物的显示。\n可以将朝向左的怪物的displayIdInBook项指定为朝向下的怪物ID,这样在怪物手册中则会归一化,只显示一个。"
|
||||
},
|
||||
"hp": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "生命值"
|
||||
},
|
||||
"atk": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "攻击力"
|
||||
},
|
||||
"def": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "防御力"
|
||||
},
|
||||
"money": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "金币"
|
||||
},
|
||||
"experience": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "经验"
|
||||
},
|
||||
"point": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "加点"
|
||||
},
|
||||
"special": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval==null || thiseval instanceof Array || (thiseval==~~thiseval && thiseval>=0)",
|
||||
"_data": "特殊属性\n\n0:无,1:先攻,2:魔攻,3:坚固,4:2连击,\n5:3连击,6:n连击,7:破甲,8:反击,9:净化,\n10:模仿,11:吸血,12:中毒,13:衰弱,14:诅咒,\n15:领域,16:夹击,17:仇恨,18:阻击,19:自爆,\n20:无敌,21:退化,22:固伤,23:重生,24:激光,25:光环\n\n多个属性例如用[1,4,11]表示先攻2连击吸血"
|
||||
},
|
||||
"value": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "特殊属性的数值\n如:领域/阻激/激光怪的伤害值;吸血怪的吸血比例;光环怪增加生命的比例"
|
||||
},
|
||||
"zoneSquare": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "领域怪是否九宫格伤害"
|
||||
},
|
||||
"range": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "(thiseval==~~thiseval && thiseval>0)||thiseval==null",
|
||||
"_data": "领域伤害的范围;不加默认为1"
|
||||
},
|
||||
"notBomb": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "该怪物不可被炸"
|
||||
},
|
||||
"n": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "(thiseval==~~thiseval && thiseval>0)||thiseval==null",
|
||||
"_data": "多连击的连击数"
|
||||
},
|
||||
"add": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "吸血后是否加到自身;光环是否叠加"
|
||||
},
|
||||
"atkValue": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval==~~thiseval||thiseval==null",
|
||||
"_data": "退化时勇士下降的攻击力点数;光环怪增加攻击的比例"
|
||||
},
|
||||
"defValue": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval==~~thiseval||thiseval==null",
|
||||
"_data": "退化时勇士下降的防御力点数;光环怪增加防御的比例"
|
||||
},
|
||||
"damage": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval==~~thiseval||thiseval==null",
|
||||
"_data": "战前扣血的点数"
|
||||
}
|
||||
}
|
||||
},
|
||||
"enemys_template": { 'name': '新敌人', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'point': 0, 'special': 0 },
|
||||
|
||||
|
||||
// --------------------------- 【图块属性】相关的表格配置 --------------------------- //
|
||||
"maps": {
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"id": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "false",
|
||||
"_data": "图块ID"
|
||||
},
|
||||
"idnum": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "false",
|
||||
"_data": "图块数字"
|
||||
},
|
||||
"cls": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "false",
|
||||
"_data": "图块类别"
|
||||
},
|
||||
"trigger": {
|
||||
"_leaf": true,
|
||||
"_type": "select",
|
||||
"_select": {
|
||||
"values": [
|
||||
null,
|
||||
"openDoor",
|
||||
"passNet",
|
||||
"changeLight",
|
||||
"pushBox",
|
||||
"custom"
|
||||
]
|
||||
},
|
||||
"_data": "该图块的默认触发器"
|
||||
},
|
||||
"noPass": {
|
||||
"_leaf": true,
|
||||
"_type": "select",
|
||||
"_select": {
|
||||
"values": [
|
||||
null,
|
||||
true,
|
||||
false
|
||||
]
|
||||
},
|
||||
"_data": "该图块是否不可通行;true代表不可通行,false代表可通行,null代表使用系统缺省值"
|
||||
},
|
||||
"canBreak": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "该图块是否可被破墙或地震"
|
||||
},
|
||||
"cannotOut": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval==null||(thiseval instanceof Array)",
|
||||
"_data": "该图块的不可出方向\n可以在这里定义在该图块时不能前往哪个方向,可以达到悬崖之类的效果\n例如 [\"up\", \"left\"] 代表在该图块时不能往上和左走\n此值对背景层、事件层、前景层上的图块均有效"
|
||||
},
|
||||
"cannotIn": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval==null||(thiseval instanceof Array)",
|
||||
"_data": "该图块的不可入方向\n可以在这里定义不能朝哪个方向进入该图块,可以达到悬崖之类的效果\n例如 [\"down\"] 代表不能从该图块的上方点朝向下进入此图块\n此值对背景层、事件层、前景层上的图块均有效"
|
||||
},
|
||||
"animate": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval==~~thiseval||thiseval==null",
|
||||
"_data": "该图块的全局动画帧数。\n如果此项为null,则对于除了npc48外,使用素材默认帧数;npc48默认是1帧(即静止)。"
|
||||
},
|
||||
"faceIds": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "行走图朝向,仅对NPC有效。可以在这里定义同一个NPC的多个朝向行走图。\n比如 {\"up\":\"N333\",\"down\":\"N334\",\"left\":\"N335\",\"right\":\"N336\"} 就将该素材的上下左右朝向分别绑定到N333,N334,N335和N336四个图块。\n在勇士撞上NPC时,或NPC在移动时,会自动选择最合适的朝向图块(如果存在定义)来进行绘制。"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// --------------------------- 【楼层属性】相关的表格配置 --------------------------- //
|
||||
"floors": {
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"floor": {
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"floorId": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "false",
|
||||
"_data": "文件名和floorId需要保持完全一致 \n楼层唯一标识符仅能由字母、数字、下划线组成,且不能由数字开头 \n推荐用法:第20层就用MT20,第38层就用MT38,地下6层就用MT_6(用下划线代替负号),隐藏3层用MT3h(h表示隐藏),等等 \n楼层唯一标识符,需要和名字完全一致 \n这里不能更改floorId,请通过另存为来实现"
|
||||
},
|
||||
"title": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "楼层中文名,将在切换楼层和浏览地图时显示"
|
||||
},
|
||||
"name": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "显示在状态栏中的层数"
|
||||
},
|
||||
"width": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "false",
|
||||
"_data": "地图x方向大小,这里不能更改,仅能在新建地图时设置,null视为13"
|
||||
},
|
||||
"height": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "false",
|
||||
"_data": "地图y方向大小,这里不能更改,仅能在新建地图时设置,null视为13"
|
||||
},
|
||||
"canFlyTo": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器)"
|
||||
},
|
||||
"canUseQuickShop": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "该层是否允许使用快捷商店"
|
||||
},
|
||||
"cannotViewMap": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "该层是否不允许被浏览地图看到;如果勾上则浏览地图会跳过该层"
|
||||
},
|
||||
"cannotMoveDirectly": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "该层是否不允许瞬间移动;如果勾上则不可在此层进行瞬移"
|
||||
},
|
||||
"firstArrive": {
|
||||
"_leaf": true,
|
||||
"_type": "event",
|
||||
"_event": "firstArrive",
|
||||
"_data": "第一次到该楼层触发的事件,可以双击进入事件编辑器。"
|
||||
},
|
||||
"eachArrive": {
|
||||
"_leaf": true,
|
||||
"_type": "event",
|
||||
"_event": "eachArrive",
|
||||
"_data": "每次到该楼层触发的事件,可以双击进入事件编辑器;该事件会在firstArrive执行后再执行。"
|
||||
},
|
||||
"parallelDo": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_lint": true,
|
||||
"_data": "在该层楼时执行的并行事件处理。\n可以在这里写上任意需要自动执行的脚本,比如打怪自动开门等。\n详见文档-事件-并行事件处理。"
|
||||
},
|
||||
"upFloor": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval==null||((thiseval instanceof Array) && thiseval.length==2)",
|
||||
"_data": "该层上楼点,如[2,3]。\n如果此项不为null,则楼层转换时的stair:upFloor,以及楼传器的落点会被替换成该点而不是该层的上楼梯。"
|
||||
},
|
||||
"downFloor": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval==null||((thiseval instanceof Array) && thiseval.length==2)",
|
||||
"_data": "该层下楼点,如[2,3]。\n如果此项不为null,则楼层转换时的stair:downFloor,以及楼传器的落点会被替换成该点而不是该层的下楼梯。"
|
||||
},
|
||||
"defaultGround": {
|
||||
"_leaf": true,
|
||||
"_type": "select",
|
||||
"_select": {
|
||||
"values": Object.keys(editor.core.icons.icons.terrains)
|
||||
},
|
||||
"_data": "默认地面的图块ID,此项修改后需要刷新才能看到效果。"
|
||||
},
|
||||
"images": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "背景/前景图;你可以选择若干张图片来作为背景/前景素材。详细用法请参见文档“自定义素材”中的说明。"
|
||||
},
|
||||
"color": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "该层的默认画面色调。本项可不写(代表无色调),如果写需要是一个RGBA数组如[255,0,0,0.3]"
|
||||
},
|
||||
"weather": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "该层的默认天气。本项可忽略表示晴天,如果写则第一项为\"rain\",\"snow\"或\"fog\"代表雨雪雾,第二项为1-10之间的数代表强度。\n如[\"rain\", 8]代表8级雨天。"
|
||||
},
|
||||
"bgm": {
|
||||
"_leaf": true,
|
||||
"_type": "select",
|
||||
"_select": {
|
||||
"values": [null].concat(Object.keys(editor.core.material.bgms))
|
||||
},
|
||||
"_data": "到达该层后默认播放的BGM。本项可忽略,或者为一个定义过的背景音乐如\"bgm.mp3\"。"
|
||||
},
|
||||
"item_ratio": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "(thiseval==~~thiseval && thiseval>=0)||thiseval==null",
|
||||
"_data": "每一层的宝石/血瓶效果,即获得宝石和血瓶时框内\"ratio\"的值。"
|
||||
},
|
||||
"underGround": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否是地下层;如果该项为true则同层传送将传送至上楼梯"
|
||||
}
|
||||
}
|
||||
},
|
||||
"loc": {
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"events": {
|
||||
"_leaf": true,
|
||||
"_type": "event",
|
||||
"_event": "event",
|
||||
"_data": "该点的可能事件列表,可以双击进入事件编辑器。"
|
||||
},
|
||||
"changeFloor": {
|
||||
"_leaf": true,
|
||||
"_type": "event",
|
||||
"_event": "changeFloor",
|
||||
"_data": "该点楼层转换事件;该事件不能和上面的events同时出现,否则会被覆盖"
|
||||
},
|
||||
"afterBattle": {
|
||||
"_leaf": true,
|
||||
"_type": "event",
|
||||
"_event": "afterBattle",
|
||||
"_data": "该点战斗后可能触发的事件列表,可以双击进入事件编辑器。"
|
||||
},
|
||||
"afterGetItem": {
|
||||
"_leaf": true,
|
||||
"_type": "event",
|
||||
"_event": "afterGetItem",
|
||||
"_data": "该点获得道具后可能触发的事件列表,可以双击进入事件编辑器。"
|
||||
},
|
||||
"afterOpenDoor": {
|
||||
"_leaf": true,
|
||||
"_type": "event",
|
||||
"_event": "afterOpenDoor",
|
||||
"_data": "该点开完门后可能触发的事件列表,可以双击进入事件编辑器。"
|
||||
},
|
||||
"cannotMove": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval==null||(thiseval instanceof Array)",
|
||||
"_data": "该点不可通行的方向 \n 可以在这里定义该点不能前往哪个方向,可以达到悬崖之类的效果\n例如 [\"up\", \"left\"] 代表该点不能往上和左走"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
686
_server/table/data.comment.js
Normal file
686
_server/table/data.comment.js
Normal file
@ -0,0 +1,686 @@
|
||||
/*
|
||||
* 表格配置项。
|
||||
* 在这里可以对表格中的各项显示进行配置,包括表格项、提示内容等内容。具体写法照葫芦画瓢即可。
|
||||
* 本配置项包括:全塔属性的配置项。
|
||||
*/
|
||||
|
||||
var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = {
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"main": {
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"floorIds": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "editor.mode.checkFloorIds(thiseval)",
|
||||
"_data": "在这里按顺序放所有的楼层;其顺序直接影响到楼层传送器、浏览地图和上/下楼器的顺序"
|
||||
},
|
||||
"images": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "editor.mode.checkUnique(thiseval)",
|
||||
"_data": "在此存放所有可能使用的图片(tilesets除外) \n图片可以被作为背景图(的一部分),也可以直接用自定义事件进行显示。 \n 图片名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好 \n 建议对于较大的图片,在网上使用在线的“图片压缩工具(http://compresspng.com/zh/)”来进行压缩,以节省流量 \n 依次向后添加"
|
||||
},
|
||||
"tilesets": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "editor.mode.checkUnique(thiseval)",
|
||||
"_data": "在此存放额外素材的图片名, \n可以自定导入任意张素材图片,无需PS,无需注册,即可直接在游戏中使用 \n 形式如[\"1.png\", \"2.png\"] ,将需要的素材图片放在images目录下 \n 素材的宽高必须都是32的倍数,且图片上的总图块数不超过1000(即最多有1000个32*32的图块在该图片上)"
|
||||
},
|
||||
"animates": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "editor.mode.checkUnique(thiseval)",
|
||||
"_data": "在此存放所有可能使用的动画,必须是animate格式,在这里不写后缀名 \n动画必须放在animates目录下;文件名不能使用中文,不能带空格或特殊字符 \n \"jianji\", \"thunder\" \n 根据需求自行添加"
|
||||
},
|
||||
"bgms": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "editor.mode.checkUnique(thiseval)",
|
||||
"_data": "在此存放所有的bgm,和文件名一致。 \n音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好"
|
||||
},
|
||||
"sounds": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "editor.mode.checkUnique(thiseval)",
|
||||
"_data": "在此存放所有的SE,和文件名一致 \n音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好"
|
||||
},
|
||||
"startBackground": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "标题界面的背景,建议使用jpg格式以压缩背景图空间"
|
||||
},
|
||||
"startLogoStyle": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "标题样式:可以改变颜色,也可以写\"display: none\"来隐藏标题"
|
||||
},
|
||||
"levelChoose": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval instanceof Array && thiseval.length>=1 && thiseval[0] instanceof Array && thiseval[0].length==2",
|
||||
"_data": "难度选择:每个数组的第一个是其在标题界面显示的难度,第二个是在游戏内部传输的字符串,会显示在状态栏,修改此处后需要在project/functions中作相应更改。\n如果需直接开始游戏将下面的startDirectly开关打开即可。"
|
||||
},
|
||||
"equipName": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "(thiseval instanceof Array && thiseval.length<=6)||thiseval==null",
|
||||
"_data": "装备位名称,为不超过6个的数组,此项的顺序与equiptype数值关联;例如可写[\"武器\",\"防具\",\"首饰\"]等等。"
|
||||
},
|
||||
"startBgm": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "在标题界面应该播放的bgm内容"
|
||||
},
|
||||
"statusLeftBackground": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "横屏时左侧状态栏的背景样式,可以定义背景图、平铺方式等。\n具体请网上搜索\"css background\"了解写法。\n如果弄一张图片作为背景图,推荐写法:\n\"url(project/images/XXX.png) 0 0/100% 100% no-repeat\"\n图片最好进行一些压缩等操作节省流量。"
|
||||
},
|
||||
"statusTopBackground": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "竖屏时上方状态栏的背景样式,可以定义背景图、平铺方式等。\n具体请网上搜索\"css background\"了解写法。\n如果弄一张图片作为背景图,推荐写法:\n\"url(project/images/XXX.png) 0 0/100% 100% no-repeat\"\n图片最好进行一些压缩等操作节省流量。"
|
||||
},
|
||||
"toolsBackground": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "竖屏时下方道具栏的背景样式,可以定义背景图、平铺方式等。\n具体请网上搜索\"css background\"了解写法。\n如果弄一张图片作为背景图,推荐写法:\n\"url(project/images/XXX.png) 0 0/100% 100% no-repeat\"\n图片最好进行一些压缩等操作节省流量。"
|
||||
},
|
||||
"borderColor": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "边框颜色,包括游戏边界的边框和对话框边框等。"
|
||||
},
|
||||
"statusBarColor": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "状态栏的文字颜色,默认是白色"
|
||||
},
|
||||
"hardLabelColor": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "难度显示的颜色,默认是红色"
|
||||
},
|
||||
"floorChangingBackground": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "楼层转换界面的背景样式;可以使用纯色(默认值black),也可以使用图片(参见状态栏的图片写法)"
|
||||
},
|
||||
"floorChangingTextColor": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "楼层转换界面的文字颜色,默认是白色"
|
||||
},
|
||||
"font": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "游戏中使用的字体,默认是Verdana"
|
||||
}
|
||||
}
|
||||
},
|
||||
"firstData": {
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"title": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "游戏名,将显示在标题页面以及切换楼层的界面中"
|
||||
},
|
||||
"name": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_range": "/^[a-zA-Z0-9_]{1,30}$/.test(thiseval)",
|
||||
"_data": "游戏的唯一英文标识符。由英文、数字、下划线组成,不能超过30个字符。\n此项必须修改,其将直接影响到存档的定位!"
|
||||
},
|
||||
"version": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "当前游戏版本;版本不一致的存档不能通用。"
|
||||
},
|
||||
"floorId": {
|
||||
"_leaf": true,
|
||||
"_type": "select",
|
||||
"_select": {
|
||||
"values": data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.main.floorIds
|
||||
},
|
||||
"_range": "data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.main.floorIds.indexOf(thiseval)!==-1",
|
||||
"_data": "初始楼层的ID"
|
||||
},
|
||||
"hero": {
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"name": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "勇士名;可以改成喜欢的"
|
||||
},
|
||||
"lv": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval==~~thiseval &&thiseval>0",
|
||||
"_data": "初始等级,该项必须为正整数"
|
||||
},
|
||||
"hpmax": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "初始生命上限,只有在enableHPMax开启时才有效"
|
||||
},
|
||||
"hp": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "初始生命值"
|
||||
},
|
||||
"manamax": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "魔力上限;此项非负才会生效(null或小于0都不会生效)"
|
||||
},
|
||||
"mana": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "初始魔力值,只在enableMana开启时才有效"
|
||||
},
|
||||
"atk": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "初始攻击"
|
||||
},
|
||||
"def": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "初始防御"
|
||||
},
|
||||
"mdef": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "初始魔防"
|
||||
},
|
||||
"money": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "初始金币"
|
||||
},
|
||||
"experience": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "初始经验"
|
||||
},
|
||||
"equipment": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval instanceof Array",
|
||||
"_data": "初始装上的装备,此处建议请直接留空数组"
|
||||
},
|
||||
"items": {
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"keys": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval instanceof Object && !(thiseval instanceof Array)",
|
||||
"_data": "初始三种钥匙个数"
|
||||
},
|
||||
"constants": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval instanceof Object && !(thiseval instanceof Array)",
|
||||
"_data": "初始永久道具个数,例如初始送手册可以写 {\"book\": 1}"
|
||||
},
|
||||
"tools": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval instanceof Object && !(thiseval instanceof Array)",
|
||||
"_data": "初始消耗道具个数,例如初始有两破可以写 {\"pickaxe\": 2}"
|
||||
},
|
||||
"equips": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval instanceof Object && !(thiseval instanceof Array)",
|
||||
"_data": "初始装备个数,例如初始送铁剑可以写 {\"sword1\": 1}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"loc": {
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"direction": {
|
||||
"_leaf": true,
|
||||
"_type": "select",
|
||||
"_data": "勇士初始方向",
|
||||
"_select": {
|
||||
"values": [
|
||||
"up",
|
||||
"down",
|
||||
"left",
|
||||
"right"
|
||||
]
|
||||
},
|
||||
},
|
||||
"x": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "勇士初始x坐标"
|
||||
},
|
||||
"y": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "勇士初始y坐标"
|
||||
}
|
||||
}
|
||||
},
|
||||
"flags": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval instanceof Object && !(thiseval instanceof Array)",
|
||||
"_data": "游戏过程中的变量或flags"
|
||||
},
|
||||
"steps": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "行走步数统计"
|
||||
}
|
||||
}
|
||||
},
|
||||
"startCanvas": {
|
||||
"_leaf": true,
|
||||
"_type": "event",
|
||||
"_event": "firstArrive",
|
||||
"_range": "thiseval==null || thiseval instanceof Array",
|
||||
"_data": "标题界面事件化,可以使用事件流的形式来绘制开始界面等。\n需要开启startUsingCanvas这个开关。\n详见文档-个性化-标题界面事件化。"
|
||||
},
|
||||
"startText": {
|
||||
"_leaf": true,
|
||||
"_type": "event",
|
||||
"_event": "firstArrive",
|
||||
"_range": "thiseval==null || thiseval instanceof Array",
|
||||
"_data": "游戏开始前剧情,可以执行任意自定义事件。\n双击进入事件编辑器。\n如果无剧情直接留一个空数组即可。"
|
||||
},
|
||||
"shops": {
|
||||
"_leaf": true,
|
||||
"_type": "event",
|
||||
"_event": "shop",
|
||||
"_range": "thiseval instanceof Array",
|
||||
"_data": "全局商店,是一个数组,可以双击进入事件编辑器。"
|
||||
},
|
||||
"levelUp": {
|
||||
"_leaf": true,
|
||||
"_type": "event",
|
||||
"_event": "level",
|
||||
"_range": "thiseval==null || thiseval instanceof Array",
|
||||
"_data": "经验升级所需要的数值,是一个数组,可以双击进行编辑。 \n 第一项为初始等级,仅title生效 \n 每一个里面可以含有三个参数 need, title, action \n need为所需要的经验数值,可以是个表达式。请确保need依次递增 \n title为该等级的名称,也可以省略代表使用系统默认值;本项将显示在状态栏中 \n action为本次升级所执行的事件,可由若干项组成"
|
||||
}
|
||||
}
|
||||
},
|
||||
"values": {
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"lavaDamage": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "经过血网受到的伤害"
|
||||
},
|
||||
"poisonDamage": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "中毒后每步受到的伤害"
|
||||
},
|
||||
"weakValue": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "衰弱状态下攻防减少的数值\n如果此项不小于1,则作为实际下降的数值(比如10就是攻防各下降10)\n如果在0到1之间则为下降的比例(比如0.3就是下降30%的攻防)"
|
||||
},
|
||||
"redJewel": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "红宝石加攻击的数值"
|
||||
},
|
||||
"blueJewel": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "蓝宝石加防御的数值"
|
||||
},
|
||||
"greenJewel": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "绿宝石加魔防的数值"
|
||||
},
|
||||
"redPotion": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "红血瓶加血数值"
|
||||
},
|
||||
"bluePotion": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "蓝血瓶加血数值"
|
||||
},
|
||||
"yellowPotion": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "黄血瓶加血数值"
|
||||
},
|
||||
"greenPotion": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "绿血瓶加血数值"
|
||||
},
|
||||
"breakArmor": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "破甲的比例(战斗前,怪物附加角色防御的x倍作为伤害)"
|
||||
},
|
||||
"counterAttack": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "反击的比例(战斗时,怪物每回合附加角色攻击的x倍作为伤害,无视角色防御)"
|
||||
},
|
||||
"purify": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "净化的比例(战斗前,怪物附加勇士魔防的x倍作为伤害)"
|
||||
},
|
||||
"hatred": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "仇恨属性中,每杀死一个怪物获得的仇恨值"
|
||||
},
|
||||
"moveSpeed": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "行走速度,即勇士每走一格的时间,一般100比较合适"
|
||||
},
|
||||
"animateSpeed": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "全局动画时间,即怪物振动频率,一般300比较合适"
|
||||
},
|
||||
"floorChangeTime": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_data": "默认楼层切换时间"
|
||||
}
|
||||
}
|
||||
},
|
||||
"flags": {
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"enableFloor": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否在状态栏显示当前楼层"
|
||||
},
|
||||
"enableName": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否在状态栏显示勇士名字"
|
||||
},
|
||||
"enableLv": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否在状态栏显示当前等级"
|
||||
},
|
||||
"enableHPMax": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否是否启用生命上限"
|
||||
},
|
||||
"enableMana": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否开启魔力值"
|
||||
},
|
||||
"enableMDef": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否在状态栏及战斗界面显示魔防(护盾)"
|
||||
},
|
||||
"enableMoney": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否在状态栏、怪物手册及战斗界面显示金币"
|
||||
},
|
||||
"enableExperience": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否在状态栏、怪物手册及战斗界面显示经验"
|
||||
},
|
||||
"enableLevelUp": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否允许等级提升(进阶);如果上面enableExperience为false,则此项恒视为false"
|
||||
},
|
||||
"levelUpLeftMode": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "进阶使用扣除模式,即在状态栏显示距离下个等级所需要的经验值;只有enableExperience和enableLevelUp均开启时才有效。"
|
||||
},
|
||||
"enableKeys": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否在状态栏显示三色钥匙数量"
|
||||
},
|
||||
"enablePZF": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否在状态栏显示破炸飞数量"
|
||||
},
|
||||
"enableDebuff": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否在状态栏显示毒衰咒"
|
||||
},
|
||||
"enableSkill": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否启用技能栏"
|
||||
},
|
||||
"flyNearStair": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否需要在楼梯边使用传送器"
|
||||
},
|
||||
"pickaxeFourDirections": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "使用破墙镐是否四个方向都破坏;如果false则只破坏面前的墙壁"
|
||||
},
|
||||
"bombFourDirections": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "使用炸弹是否四个方向都会炸;如果false则只炸面前的怪物(即和圣锤等价)"
|
||||
},
|
||||
"snowFourDirections": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "使用冰冻徽章是否四个方向都会消除熔岩;如果false则只消除面前的熔岩"
|
||||
},
|
||||
"bigKeyIsBox": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "如果此项为true,则视为钥匙盒,红黄蓝钥匙+1;若为false,则视为大黄门钥匙"
|
||||
},
|
||||
"steelDoorWithoutKey": {
|
||||
"_left": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "铁门是否不需要钥匙开启。如果此项为true,则无需钥匙也可以开铁门。"
|
||||
},
|
||||
"equipment": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "剑和盾是否作为装备。如果此项为true,则作为装备,需要在装备栏使用,否则将直接加属性。"
|
||||
},
|
||||
"equipboxButton": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "状态栏的装备按钮。若此项为true则将状态栏中的楼层转换器按钮换为装备栏按钮"
|
||||
},
|
||||
"iconInEquipbox": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "在装备栏中的属性变化,是否绘制图标;如果此项开启,则会绘制图标而不是文字"
|
||||
},
|
||||
"enableAddPoint": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否支持加点"
|
||||
},
|
||||
"enableNegativeDamage": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否支持负伤害(回血)"
|
||||
},
|
||||
"hatredDecrease": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否在和仇恨怪战斗后减一半的仇恨值,此项为false则和仇恨怪不会扣减仇恨值。"
|
||||
},
|
||||
"betweenAttackCeil": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "夹击方式是向上取整还是向下取整。如果此项为true则为向上取整,为false则为向下取整"
|
||||
},
|
||||
"useLoop": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否循环计算临界;如果此项为true则使用循环法(而不是回合数计算法)来算临界\n从V2.5.3开始,对于大数据的循环法将改为使用二分法进行计算"
|
||||
},
|
||||
"startUsingCanvas": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否开始菜单canvas化;如果此项为true,则将使用canvas来绘制开始菜单"
|
||||
},
|
||||
"startDirectly": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "点击“开始游戏”后是否立刻开始游戏而不显示难度选择界面"
|
||||
},
|
||||
"statusCanvas": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否状态栏canvas化,即手动自定义绘制状态栏。\n如果此项开启,则可在脚本编辑的drawStatusBar中自定义绘制菜单栏。"
|
||||
},
|
||||
"statusCanvasRowsOnMobile": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "thiseval==null || (thiseval>0 && thiseval<=4)",
|
||||
"_data": "竖屏模式下,顶端状态栏canvas化后的行数。\n此项将决定竖屏的状态栏高度,如果设置则不小于1且不大于4。\n仅在statusCanvas开启时才有效"
|
||||
},
|
||||
"displayEnemyDamage": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否地图怪物显伤;用户可以手动在菜单栏中开关"
|
||||
},
|
||||
"displayCritical": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否地图显示临界;用户可以手动在菜单栏中开关"
|
||||
},
|
||||
"displayExtraDamage": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否地图高级显伤(领域、夹击等);用户可以手动在菜单栏中开关"
|
||||
},
|
||||
"enableGentleClick": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否允许轻触(获得面前物品)"
|
||||
},
|
||||
"potionWhileRouting": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "寻路算法是否经过血瓶;如果该项为false,则寻路算法会自动尽量绕过血瓶"
|
||||
},
|
||||
"ignoreChangeFloor": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "经过楼梯、传送门时是否能“穿透”。\n穿透的意思是,自动寻路得到的的路径中间经过了楼梯,行走时是否触发楼层转换事件"
|
||||
},
|
||||
"canGoDeadZone": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否允许走到将死的领域上。如果此项为true,则可以走到将死的领域上"
|
||||
},
|
||||
"enableMoveDirectly": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否允许瞬间移动"
|
||||
},
|
||||
"enableDisabledShop": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否允许查看未开启状态的快捷商店内容;如果此项为真,则对于未开启状态的商店允许查看其内容(但不能购买)"
|
||||
},
|
||||
"disableShopOnDamage": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否在经过领域/夹击/路障等伤害后禁用快捷商店。"
|
||||
},
|
||||
"checkConsole": {
|
||||
"_leaf": true,
|
||||
"_type": "checkbox",
|
||||
"_bool": "bool",
|
||||
"_data": "是否检查控制台的开启情况。"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
46
_server/table/events.comment.js
Normal file
46
_server/table/events.comment.js
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 表格配置项。
|
||||
* 在这里可以对表格中的各项显示进行配置,包括表格项、提示内容等内容。具体写法照葫芦画瓢即可。
|
||||
* 本配置项包括:公共事件。
|
||||
*/
|
||||
|
||||
var events_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = {
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"commonEvent": {
|
||||
"_type": "object",
|
||||
"_data": function (key) {
|
||||
var obj = {
|
||||
"加点事件": {
|
||||
"_leaf": true,
|
||||
"_type": "event",
|
||||
"_range": "thiseval instanceof Array",
|
||||
"_event": "commonEvent",
|
||||
"_data": "打败怪物后加点"
|
||||
},
|
||||
"毒衰咒处理": {
|
||||
"_leaf": true,
|
||||
"_type": "event",
|
||||
"_range": "thiseval instanceof Array",
|
||||
"_event": "commonEvent",
|
||||
"_data": "毒衰咒效果处理"
|
||||
},
|
||||
"滑冰事件": {
|
||||
"_leaf": true,
|
||||
"_type": "event",
|
||||
"_range": "thiseval instanceof Array",
|
||||
"_event": "commonEvent",
|
||||
"_data": "滑冰事件"
|
||||
},
|
||||
}
|
||||
if (obj[key]) return obj[key];
|
||||
return {
|
||||
"_leaf": true,
|
||||
"_type": "event",
|
||||
"_event": "commonEvent",
|
||||
"_data": "自定义公共事件,可以双击进入事件编辑器"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
216
_server/table/functions.comment.js
Normal file
216
_server/table/functions.comment.js
Normal file
@ -0,0 +1,216 @@
|
||||
/*
|
||||
* 表格配置项。
|
||||
* 在这里可以对表格中的各项显示进行配置,包括表格项、提示内容等内容。具体写法照葫芦画瓢即可。
|
||||
* 本配置项包括:脚本编辑。
|
||||
*/
|
||||
|
||||
var functions_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = {
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"events": {
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"resetGame": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "重置整个游戏"
|
||||
},
|
||||
"setInitData": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "设置初始属性"
|
||||
},
|
||||
"win": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "游戏获胜事件"
|
||||
},
|
||||
"lose": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "游戏失败事件"
|
||||
},
|
||||
"changingFloor": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "切换楼层中"
|
||||
},
|
||||
"afterChangeFloor": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "切换楼层后"
|
||||
},
|
||||
"flyTo": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "楼层飞行"
|
||||
},
|
||||
"beforeBattle": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "战前事件"
|
||||
},
|
||||
"afterBattle": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "战后事件"
|
||||
},
|
||||
"afterOpenDoor": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "开门后事件"
|
||||
},
|
||||
"afterGetItem": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "获得道具后事件"
|
||||
},
|
||||
"afterChangeLight": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "改变亮灯事件"
|
||||
},
|
||||
"afterPushBox": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "推箱子事件"
|
||||
},
|
||||
"afterUseBomb": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "炸弹事件"
|
||||
},
|
||||
"canUseQuickShop": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "能否用快捷商店"
|
||||
}
|
||||
}
|
||||
},
|
||||
"enemys": {
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"getSpecials": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "怪物特殊属性定义"
|
||||
},
|
||||
"getEnemyInfo": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "获得怪物真实属性"
|
||||
},
|
||||
"getDamageInfo": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "获得战斗伤害信息"
|
||||
},
|
||||
"updateEnemys": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "更新怪物数据"
|
||||
}
|
||||
}
|
||||
},
|
||||
"actions": {
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"onKeyUp": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "按键处理"
|
||||
}
|
||||
}
|
||||
},
|
||||
"control": {
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"saveData": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "存档操作"
|
||||
},
|
||||
"loadData": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "读档操作"
|
||||
},
|
||||
"updateStatusBar": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "更新状态栏"
|
||||
},
|
||||
"updateCheckBlock": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "阻激夹域伤害"
|
||||
},
|
||||
"moveOneStep": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "每一步后的操作"
|
||||
},
|
||||
"moveDirectly": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "瞬间移动处理"
|
||||
},
|
||||
"parallelDo": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "并行事件处理"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ui": {
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"drawStatusBar": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "自绘状态栏"
|
||||
},
|
||||
"drawStatistics": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "地图数据统计"
|
||||
},
|
||||
"drawAbout": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "绘制关于界面"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
32
_server/table/plugins.comment.js
Normal file
32
_server/table/plugins.comment.js
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 表格配置项。
|
||||
* 在这里可以对表格中的各项显示进行配置,包括表格项、提示内容等内容。具体写法照葫芦画瓢即可。
|
||||
* 本配置项包括:插件编写。
|
||||
*/
|
||||
|
||||
var plugins_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = {
|
||||
"_type": "object",
|
||||
"_data": function (key) {
|
||||
var obj = {
|
||||
"init": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "typeof(thiseval)=='string'",
|
||||
"_data": "自定义插件"
|
||||
},
|
||||
"drawLight": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "typeof(thiseval)=='string' || thiseval==null",
|
||||
"_data": "绘制灯光效果"
|
||||
},
|
||||
}
|
||||
if (obj[key]) return obj[key];
|
||||
return {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "typeof(thiseval)=='string' || thiseval==null",
|
||||
"_data": "自定义插件"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -240,7 +240,7 @@ tip.infos=function(value){
|
||||
document.getElementById('isAirwall-else').innerHTML=(tip.hasId?`<p>图块编号:<span class="infoText">${ value['idnum'] }</span></p>
|
||||
<p>图块ID:<span class="infoText">${ value['id'] }</span></p>`:`
|
||||
<p class="warnText">该图块无对应的数字或ID存在,请先前往icons.js和maps.js中进行定义!</p>`)+`
|
||||
<p>图块所在素材:<span class="infoText">${ value['images'] + (tip.isAutotile ? '( '+infos['id']+' )' : '') }</span>
|
||||
<p>图块所在素材:<span class="infoText">${ value['images'] + (tip.isAutotile ? '( '+value['id']+' )' : '') }</span>
|
||||
</p>
|
||||
<p>图块索引:<span class="infoText">${ value['y'] }</span></p>`
|
||||
}
|
||||
|
||||
@ -97,7 +97,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="left2" class='leftTab' style="z-index:-1;opacity: 0;"><!-- loc -->
|
||||
<h3 class="leftTabHeader">地图选点 <button onclick="editor.mode.onmode('save')">保存</button>
|
||||
<h3 class="leftTabHeader">地图选点 <button onclick="editor.mode.onmode('save')">保存</button> <button onclick="editor_multi.editCommentJs('loc')">配置表格</button>
|
||||
</h3>
|
||||
<div class="leftTabContent">
|
||||
<p id='pos_a6771a78_a099_417c_828f_0a24851ebfce' style="margin-left: 15px">0,0</p>
|
||||
@ -115,12 +115,12 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="left3" class='leftTab' style="z-index:-1;opacity: 0;"><!-- enemyitem -->
|
||||
<h3 class="leftTabHeader">图块属性 <button onclick="editor.mode.onmode('save')">保存</button> <button onclick="editor.mode.changeDoubleClickModeByButton('add')">添加</button> <button onclick="editor.mode.changeDoubleClickModeByButton('delete')">删除</button>
|
||||
<h3 class="leftTabHeader">图块属性 <button onclick="editor.mode.onmode('save')">保存</button> <button onclick="editor.mode.changeDoubleClickModeByButton('add')">添加</button> <button onclick="editor.mode.changeDoubleClickModeByButton('delete')">删除</button> <button onclick="editor_multi.editCommentJs('enemyitem')">配置表格</button>
|
||||
</h3>
|
||||
<div class="leftTabContent">
|
||||
<div id='newIdIdnum'><!-- id and idnum -->
|
||||
<input placeholder="新id(唯一标识符)"/>
|
||||
<input placeholder="新idnum(1000以内数字)"/>
|
||||
<input placeholder="新idnum(10000以内数字)"/>
|
||||
<button>save</button>
|
||||
<br/>
|
||||
<button style="margin-top: 10px">自动注册</button>
|
||||
@ -141,7 +141,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="left4" class='leftTab' style="z-index:-1;opacity: 0;"><!-- floor -->
|
||||
<h3 class="leftTabHeader">楼层属性 <button onclick="editor.mode.onmode('save')">保存</button> <button onclick="editor.mode.changeDoubleClickModeByButton('add')">添加</button> <button onclick="editor.mode.changeDoubleClickModeByButton('delete')">删除</button>
|
||||
<h3 class="leftTabHeader">楼层属性 <button onclick="editor.mode.onmode('save')">保存</button> <button onclick="editor.mode.changeDoubleClickModeByButton('add')">添加</button> <button onclick="editor.mode.changeDoubleClickModeByButton('delete')">删除</button> <button onclick="editor_multi.editCommentJs('floor')">配置表格</button>
|
||||
</h3>
|
||||
<div class="leftTabContent">
|
||||
<div class='etable'>
|
||||
@ -158,7 +158,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="left5" class='leftTab' style="z-index:-1;opacity: 0;"><!-- tower -->
|
||||
<h3 class="leftTabHeader">全塔属性 <button onclick="editor.mode.onmode('save')">保存</button> <button onclick="editor.mode.changeDoubleClickModeByButton('add')">添加</button>
|
||||
<h3 class="leftTabHeader">全塔属性 <button onclick="editor.mode.onmode('save')">保存</button> <button onclick="editor.mode.changeDoubleClickModeByButton('add')">添加</button> <button onclick="editor_multi.editCommentJs('tower')">配置表格</button>
|
||||
</h3>
|
||||
<div class="leftTabContent">
|
||||
<div class='etable'>
|
||||
@ -226,7 +226,7 @@
|
||||
<textarea id="multiLineCode" name="multiLineCode"></textarea>
|
||||
</div>
|
||||
<div id="left8" class='leftTab' style="z-index:-1;opacity: 0;"><!-- functions -->
|
||||
<h3 class="leftTabHeader">脚本编辑 <button onclick="editor.mode.onmode('save')">保存</button>
|
||||
<h3 class="leftTabHeader">脚本编辑 <button onclick="editor.mode.onmode('save')">保存</button> <button onclick="editor_multi.editCommentJs('functions')">配置表格</button>
|
||||
</h3>
|
||||
<div class="leftTabContent">
|
||||
<div class='etable'>
|
||||
@ -243,7 +243,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="left9" class='leftTab' style="z-index:-1;opacity: 0;"><!-- commonevent -->
|
||||
<h3 class="leftTabHeader">公共事件 <button onclick="editor.mode.onmode('save')">保存</button> <button onclick="editor.mode.changeDoubleClickModeByButton('add')">添加</button> <button onclick="editor.mode.changeDoubleClickModeByButton('delete')">删除</button>
|
||||
<h3 class="leftTabHeader">公共事件 <button onclick="editor.mode.onmode('save')">保存</button> <button onclick="editor.mode.changeDoubleClickModeByButton('add')">添加</button> <button onclick="editor.mode.changeDoubleClickModeByButton('delete')">删除</button> <button onclick="editor_multi.editCommentJs('commonevent')">配置表格</button>
|
||||
</h3>
|
||||
<div class="leftTabContent">
|
||||
<div class='etable'>
|
||||
@ -260,7 +260,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="left10" class='leftTab' style="z-index:-1;opacity: 0;"><!-- plugins -->
|
||||
<h3 class="leftTabHeader">插件编写 <button onclick="editor.mode.onmode('save')">保存</button> <button onclick="editor.mode.changeDoubleClickModeByButton('add')">添加</button> <button onclick="editor.mode.changeDoubleClickModeByButton('delete')">删除</button>
|
||||
<h3 class="leftTabHeader">插件编写 <button onclick="editor.mode.onmode('save')">保存</button> <button onclick="editor.mode.changeDoubleClickModeByButton('add')">添加</button> <button onclick="editor.mode.changeDoubleClickModeByButton('delete')">删除</button> <button onclick="editor_multi.editCommentJs('plugins')">配置表格</button>
|
||||
</h3>
|
||||
<div class="leftTabContent">
|
||||
<div class='etable'>
|
||||
@ -527,6 +527,7 @@ if (location.protocol.indexOf("http")!=0) {
|
||||
<script src='_server/fs.js'></script>
|
||||
<script src='_server/editor_util.js'></script>
|
||||
<script src='_server/editor_file.js'></script>
|
||||
<script src='_server/editor_game.js'></script>
|
||||
<script src='_server/editor_table.js'></script>
|
||||
<script src='_server/editor_mode.js'></script>
|
||||
<script src='_server/vm.js'></script>
|
||||
|
||||
17
editor.html
17
editor.html
@ -93,7 +93,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="left2" class='leftTab' style="z-index:-1;opacity: 0;"><!-- loc -->
|
||||
<h3 class="leftTabHeader">地图选点 <button onclick="editor.mode.onmode('save')">保存</button>
|
||||
<h3 class="leftTabHeader">地图选点 <button onclick="editor.mode.onmode('save')">保存</button> <button onclick="editor_multi.editCommentJs('loc')">配置表格</button>
|
||||
</h3>
|
||||
<div class="leftTabContent">
|
||||
<p id='pos_a6771a78_a099_417c_828f_0a24851ebfce' style="margin-left: 15px">0,0</p>
|
||||
@ -111,12 +111,12 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="left3" class='leftTab' style="z-index:-1;opacity: 0;"><!-- enemyitem -->
|
||||
<h3 class="leftTabHeader">图块属性 <button onclick="editor.mode.onmode('save')">保存</button> <button onclick="editor.mode.changeDoubleClickModeByButton('add')">添加</button> <button onclick="editor.mode.changeDoubleClickModeByButton('delete')">删除</button>
|
||||
<h3 class="leftTabHeader">图块属性 <button onclick="editor.mode.onmode('save')">保存</button> <button onclick="editor.mode.changeDoubleClickModeByButton('add')">添加</button> <button onclick="editor.mode.changeDoubleClickModeByButton('delete')">删除</button> <button onclick="editor_multi.editCommentJs('enemyitem')">配置表格</button>
|
||||
</h3>
|
||||
<div class="leftTabContent">
|
||||
<div id='newIdIdnum'><!-- id and idnum -->
|
||||
<input placeholder="新id(唯一标识符)"/>
|
||||
<input placeholder="新idnum(1000以内数字)"/>
|
||||
<input placeholder="新idnum(10000以内数字)"/>
|
||||
<button>save</button>
|
||||
<br/>
|
||||
<button style="margin-top: 10px">自动注册</button>
|
||||
@ -137,7 +137,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="left4" class='leftTab' style="z-index:-1;opacity: 0;"><!-- floor -->
|
||||
<h3 class="leftTabHeader">楼层属性 <button onclick="editor.mode.onmode('save')">保存</button> <button onclick="editor.mode.changeDoubleClickModeByButton('add')">添加</button> <button onclick="editor.mode.changeDoubleClickModeByButton('delete')">删除</button>
|
||||
<h3 class="leftTabHeader">楼层属性 <button onclick="editor.mode.onmode('save')">保存</button> <button onclick="editor.mode.changeDoubleClickModeByButton('add')">添加</button> <button onclick="editor.mode.changeDoubleClickModeByButton('delete')">删除</button> <button onclick="editor_multi.editCommentJs('floor')">配置表格</button>
|
||||
</h3>
|
||||
<div class="leftTabContent">
|
||||
<div class='etable'>
|
||||
@ -154,7 +154,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="left5" class='leftTab' style="z-index:-1;opacity: 0;"><!-- tower -->
|
||||
<h3 class="leftTabHeader">全塔属性 <button onclick="editor.mode.onmode('save')">保存</button> <button onclick="editor.mode.changeDoubleClickModeByButton('add')">添加</button>
|
||||
<h3 class="leftTabHeader">全塔属性 <button onclick="editor.mode.onmode('save')">保存</button> <button onclick="editor.mode.changeDoubleClickModeByButton('add')">添加</button> <button onclick="editor_multi.editCommentJs('tower')">配置表格</button>
|
||||
</h3>
|
||||
<div class="leftTabContent">
|
||||
<div class='etable'>
|
||||
@ -222,7 +222,7 @@
|
||||
<textarea id="multiLineCode" name="multiLineCode"></textarea>
|
||||
</div>
|
||||
<div id="left8" class='leftTab' style="z-index:-1;opacity: 0;"><!-- functions -->
|
||||
<h3 class="leftTabHeader">脚本编辑 <button onclick="editor.mode.onmode('save')">保存</button>
|
||||
<h3 class="leftTabHeader">脚本编辑 <button onclick="editor.mode.onmode('save')">保存</button> <button onclick="editor_multi.editCommentJs('functions')">配置表格</button>
|
||||
</h3>
|
||||
<div class="leftTabContent">
|
||||
<div class='etable'>
|
||||
@ -239,7 +239,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="left9" class='leftTab' style="z-index:-1;opacity: 0;"><!-- commonevent -->
|
||||
<h3 class="leftTabHeader">公共事件 <button onclick="editor.mode.onmode('save')">保存</button> <button onclick="editor.mode.changeDoubleClickModeByButton('add')">添加</button> <button onclick="editor.mode.changeDoubleClickModeByButton('delete')">删除</button>
|
||||
<h3 class="leftTabHeader">公共事件 <button onclick="editor.mode.onmode('save')">保存</button> <button onclick="editor.mode.changeDoubleClickModeByButton('add')">添加</button> <button onclick="editor.mode.changeDoubleClickModeByButton('delete')">删除</button> <button onclick="editor_multi.editCommentJs('commonevent')">配置表格</button>
|
||||
</h3>
|
||||
<div class="leftTabContent">
|
||||
<div class='etable'>
|
||||
@ -256,7 +256,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="left10" class='leftTab' style="z-index:-1;opacity: 0;"><!-- plugins -->
|
||||
<h3 class="leftTabHeader">插件编写 <button onclick="editor.mode.onmode('save')">保存</button> <button onclick="editor.mode.changeDoubleClickModeByButton('add')">添加</button> <button onclick="editor.mode.changeDoubleClickModeByButton('delete')">删除</button>
|
||||
<h3 class="leftTabHeader">插件编写 <button onclick="editor.mode.onmode('save')">保存</button> <button onclick="editor.mode.changeDoubleClickModeByButton('add')">添加</button> <button onclick="editor.mode.changeDoubleClickModeByButton('delete')">删除</button> <button onclick="editor_multi.editCommentJs('plugins')">配置表格</button>
|
||||
</h3>
|
||||
<div class="leftTabContent">
|
||||
<div class='etable'>
|
||||
@ -510,6 +510,7 @@ if (location.protocol.indexOf("http")!=0) {
|
||||
<script src='_server/fs.js'></script>
|
||||
<script src='_server/editor_util.js'></script>
|
||||
<script src='_server/editor_file.js'></script>
|
||||
<script src='_server/editor_game.js'></script>
|
||||
<script src='_server/editor_table.js'></script>
|
||||
<script src='_server/editor_mode.js'></script>
|
||||
<script src='_server/vm.js'></script>
|
||||
|
||||
456
libs/actions.js
456
libs/actions.js
@ -105,7 +105,7 @@ actions.prototype.doRegisteredAction = function (action) {
|
||||
return false;
|
||||
}
|
||||
|
||||
actions.prototype.checkReplaying = function () {
|
||||
actions.prototype._checkReplaying = function () {
|
||||
if (core.isReplaying() && core.status.event.id != 'save'
|
||||
&& (core.status.event.id || "").indexOf('book') != 0 && core.status.event.id != 'viewMaps')
|
||||
return true;
|
||||
@ -114,7 +114,7 @@ actions.prototype.checkReplaying = function () {
|
||||
|
||||
////// 检查是否在录像播放中,如果是,则停止交互
|
||||
actions.prototype._sys_checkReplay = function () {
|
||||
if (this.checkReplaying()) return true;
|
||||
if (this._checkReplaying()) return true;
|
||||
}
|
||||
|
||||
////// 按下某个键时 //////
|
||||
@ -145,7 +145,7 @@ actions.prototype.onkeyUp = function (e) {
|
||||
}
|
||||
|
||||
actions.prototype._sys_onkeyUp_replay = function (e) {
|
||||
if (this.checkReplaying()) {
|
||||
if (this._checkReplaying()) {
|
||||
if (e.keyCode == 27) // ESCAPE
|
||||
core.stopReplay();
|
||||
else if (e.keyCode == 90) // Z
|
||||
@ -286,7 +286,7 @@ actions.prototype.keyUp = function (keyCode, altKey, fromReplay) {
|
||||
}
|
||||
|
||||
actions.prototype._sys_keyUp_replay = function (keyCode, altKey, fromReplay) {
|
||||
if (!fromReplay && this.checkReplaying()) return true;
|
||||
if (!fromReplay && this._checkReplaying()) return true;
|
||||
}
|
||||
|
||||
actions.prototype._sys_keyUp_lockControl = function (keyCode, altKey) {
|
||||
@ -389,7 +389,7 @@ actions.prototype._sys_keyUp = function (keyCode, altKey) {
|
||||
if (core.status.automaticRoute && core.status.automaticRoute.autoHeroMove) {
|
||||
core.stopAutomaticRoute();
|
||||
}
|
||||
core.stopHero();
|
||||
core.status.heroStop = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -539,8 +539,8 @@ actions.prototype._sys_onup = function () {
|
||||
return true;
|
||||
}
|
||||
|
||||
////// 获得点击事件相对左上角的坐标(0到12之间) //////
|
||||
actions.prototype.getClickLoc = function (x, y) {
|
||||
////// 获得点击事件相对左上角的坐标 //////
|
||||
actions.prototype._getClickLoc = function (x, y) {
|
||||
|
||||
var statusBar = {'x': 0, 'y': 0};
|
||||
var size = 32;
|
||||
@ -663,7 +663,7 @@ actions.prototype.onmousewheel = function (direct) {
|
||||
actions.prototype._sys_onmousewheel = function (direct) {
|
||||
// 向下滚动是 -1 ,向上是 1
|
||||
|
||||
if (this.checkReplaying()) {
|
||||
if (this._checkReplaying()) {
|
||||
// 滚轮控制速度
|
||||
if (direct == 1) core.speedUpReplay();
|
||||
if (direct == -1) core.speedDownReplay();
|
||||
@ -717,7 +717,7 @@ actions.prototype._sys_keyDownCtrl = function () {
|
||||
}
|
||||
if (core.status.event.id == 'action' && core.status.event.data.type == 'sleep'
|
||||
&& !core.status.event.data.current.noSkip) {
|
||||
if (core.timeout.sleepTimeout && Object.keys(core.animateFrame.asyncId).length == 0) {
|
||||
if (core.timeout.sleepTimeout && !core.hasAsync()) {
|
||||
clearTimeout(core.timeout.sleepTimeout);
|
||||
core.timeout.sleepTimeout = null;
|
||||
core.doAction();
|
||||
@ -752,7 +752,7 @@ actions.prototype._sys_longClick_lockControl = function (x, y) {
|
||||
// 长按可以跳过等待事件
|
||||
if (core.status.event.id == 'action' && core.status.event.data.type == 'sleep'
|
||||
&& !core.status.event.data.current.noSkip) {
|
||||
if (core.timeout.sleepTimeout && Object.keys(core.animateFrame.asyncId).length == 0) {
|
||||
if (core.timeout.sleepTimeout && !core.hasAsync()) {
|
||||
clearTimeout(core.timeout.sleepTimeout);
|
||||
core.timeout.sleepTimeout = null;
|
||||
core.doAction();
|
||||
@ -891,6 +891,21 @@ actions.prototype._clickAction = function (x, y) {
|
||||
core.doAction();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (core.status.event.data.type == 'confirm') {
|
||||
if ((x == this.HSIZE-2 || x == this.HSIZE-1) && y == this.HSIZE+1) {
|
||||
core.status.route.push("choices:0");
|
||||
core.insertAction(core.status.event.ui.yes);
|
||||
core.doAction();
|
||||
}
|
||||
if ((x == this.HSIZE+2 || x == this.HSIZE+1) && y == this.HSIZE+1) {
|
||||
core.status.route.push("choices:1");
|
||||
core.insertAction(core.status.event.ui.no);
|
||||
core.doAction();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -898,6 +913,12 @@ actions.prototype._clickAction = function (x, y) {
|
||||
actions.prototype._keyDownAction = function (keycode) {
|
||||
if (core.status.event.data.type == 'choices') {
|
||||
this._keyDownChoices(keycode);
|
||||
return;
|
||||
}
|
||||
if (core.status.event.data.type == 'confirm' && (keycode == 37 || keycode == 39)) {
|
||||
core.status.event.selection = 1 - core.status.event.selection;
|
||||
core.drawConfirmBox(core.status.event.ui.text);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -924,6 +945,15 @@ actions.prototype._keyUpAction = function (keycode) {
|
||||
if (choices.length > 0) {
|
||||
this._selectChoices(choices.length, keycode, this._clickAction);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (core.status.event.data.type == 'confirm'&& (keycode == 13 || keycode == 32 || keycode == 67)) {
|
||||
core.status.route.push("choices:" + core.status.event.selection);
|
||||
if (core.status.event.selection == 0)
|
||||
core.insertAction(core.status.event.ui.yes);
|
||||
else core.insertAction(core.status.event.ui.no);
|
||||
core.doAction();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -958,6 +988,7 @@ actions.prototype._clickBook = function (x, y) {
|
||||
var index = this.HSIZE * page + parseInt(y / 2);
|
||||
core.ui.drawBook(index);
|
||||
core.ui.drawBookDetail(index);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -1101,17 +1132,20 @@ actions.prototype._clickViewMaps = function (x, y) {
|
||||
index++;
|
||||
if (index < core.floorIds.length)
|
||||
core.ui.drawMaps(index);
|
||||
return;
|
||||
}
|
||||
else if (y >= this.HSIZE + 2 && (mh == this.SIZE || (x >= per && x <= this.LAST - per))) {
|
||||
if (y >= this.HSIZE + 2 && (mh == this.SIZE || (x >= per && x <= this.LAST - per))) {
|
||||
index--;
|
||||
while (index >= 0 && index != now && core.status.maps[core.floorIds[index]].cannotViewMap)
|
||||
index--;
|
||||
if (index >= 0)
|
||||
core.ui.drawMaps(index);
|
||||
return;
|
||||
}
|
||||
else if (x >= per && x <= this.LAST - per && y >= this.HSIZE - 1 && y <= this.HSIZE + 1) {
|
||||
if (x >= per && x <= this.LAST - per && y >= this.HSIZE - 1 && y <= this.HSIZE + 1) {
|
||||
core.clearMap('data');
|
||||
core.ui.closePanel();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1198,9 +1232,10 @@ actions.prototype._keyUpShop = function (keycode) {
|
||||
|
||||
////// 快捷商店界面时的点击操作 //////
|
||||
actions.prototype._clickQuickShop = function (x, y) {
|
||||
var shopList = core.status.shops, keys = Object.keys(shopList).filter(function (shopId) {
|
||||
return shopList[shopId].visited || !shopList[shopId].mustEnable
|
||||
var keys = Object.keys(core.status.shops).filter(function (shopId) {
|
||||
return core.status.shops[shopId].visited || !core.status.shops[shopId].mustEnable
|
||||
});
|
||||
|
||||
if (x >= this.CHOICES_LEFT && x <= this.CHOICES_RIGHT) {
|
||||
var topIndex = this.HSIZE - parseInt(keys.length / 2);
|
||||
if (y >= topIndex && y < topIndex + keys.length) {
|
||||
@ -1216,7 +1251,9 @@ actions.prototype._clickQuickShop = function (x, y) {
|
||||
// 离开
|
||||
else if (y == topIndex + keys.length)
|
||||
core.ui.closePanel();
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
////// 快捷商店界面时,放开某个键的操作 //////
|
||||
@ -1225,8 +1262,8 @@ actions.prototype._keyUpQuickShop = function (keycode) {
|
||||
core.ui.closePanel();
|
||||
return;
|
||||
}
|
||||
var shopList = core.status.shops, keys = Object.keys(shopList).filter(function (shopId) {
|
||||
return shopList[shopId].visited || !shopList[shopId].mustEnable
|
||||
var keys = Object.keys(core.status.shops).filter(function (shopId) {
|
||||
return core.status.shops[shopId].visited || !core.status.shops[shopId].mustEnable
|
||||
});
|
||||
this._selectChoices(keys.length + 1, keycode, this._clickQuickShop);
|
||||
return;
|
||||
@ -1235,49 +1272,47 @@ actions.prototype._keyUpQuickShop = function (keycode) {
|
||||
////// 工具栏界面时的点击操作 //////
|
||||
actions.prototype._clickToolbox = function (x, y) {
|
||||
// 装备栏
|
||||
if (x >= 10 && x <= 12 && y == 0) {
|
||||
if (x >= this.LAST - 2 && y == 0) {
|
||||
core.ui.closePanel();
|
||||
core.openEquipbox();
|
||||
return;
|
||||
}
|
||||
// 返回
|
||||
if (x >= 10 && x <= 12 && y == 12) {
|
||||
if (x >= this.LAST - 2 && y == this.LAST) {
|
||||
core.ui.closePanel();
|
||||
return;
|
||||
}
|
||||
|
||||
var toolsPage = core.status.event.data.toolsPage;
|
||||
var constantsPage = core.status.event.data.constantsPage;
|
||||
// 上一页
|
||||
if (x == 3 || x == 4) {
|
||||
if (y == 7 && toolsPage > 1) {
|
||||
if (x == this.HSIZE-2 || x == this.HSIZE-3) {
|
||||
if (y == this.LAST - 5 && toolsPage > 1) {
|
||||
core.status.event.data.toolsPage--;
|
||||
core.ui.drawToolbox(core.status.event.selection);
|
||||
}
|
||||
if (y == 12 && constantsPage > 1) {
|
||||
core.status.event.data.toolsPage--;
|
||||
if (y == this.LAST && constantsPage > 1) {
|
||||
core.status.event.data.constantsPage--;
|
||||
core.ui.drawToolbox(core.status.event.selection);
|
||||
}
|
||||
}
|
||||
// 下一页
|
||||
if (x == 8 || x == 9) {
|
||||
if (y == 7 && toolsPage < Math.ceil(Object.keys(core.status.hero.items.tools).length / 12)) {
|
||||
if (x == this.HSIZE+2 || x == this.HSIZE+3) {
|
||||
if (y == this.LAST - 5 && toolsPage < Math.ceil(Object.keys(core.status.hero.items.tools).length / this.LAST)) {
|
||||
core.status.event.data.toolsPage++;
|
||||
core.ui.drawToolbox(core.status.event.selection);
|
||||
}
|
||||
if (y == 12 && constantsPage < Math.ceil(Object.keys(core.status.hero.items.constants).length / 12)) {
|
||||
if (y == this.LAST && constantsPage < Math.ceil(Object.keys(core.status.hero.items.constants).length / this.LAST)) {
|
||||
core.status.event.data.constantsPage++;
|
||||
core.ui.drawToolbox(core.status.event.selection);
|
||||
}
|
||||
}
|
||||
|
||||
var index = parseInt(x / 2);
|
||||
;
|
||||
if (y == 4) index += 0;
|
||||
else if (y == 6) index += 6;
|
||||
else if (y == 9) index += 12;
|
||||
else if (y == 11) index += 18;
|
||||
if (y == this.LAST - 8) index += 0;
|
||||
else if (y == this.LAST - 6) index += this.HSIZE;
|
||||
else if (y == this.LAST - 3) index += this.LAST;
|
||||
else if (y == this.LAST - 1) index += this.LAST + this.HSIZE;
|
||||
else index = -1;
|
||||
|
||||
if (index >= 0)
|
||||
this._clickToolboxIndex(index);
|
||||
}
|
||||
@ -1286,12 +1321,12 @@ actions.prototype._clickToolbox = function (x, y) {
|
||||
actions.prototype._clickToolboxIndex = function (index) {
|
||||
var items = null;
|
||||
var select;
|
||||
if (index < 12) {
|
||||
select = index + 12 * (core.status.event.data.toolsPage - 1);
|
||||
if (index < this.LAST) {
|
||||
select = index + this.LAST * (core.status.event.data.toolsPage - 1);
|
||||
items = Object.keys(core.status.hero.items.tools).sort();
|
||||
}
|
||||
else {
|
||||
select = index % 12 + 12 * (core.status.event.data.constantsPage - 1);
|
||||
select = index % this.LAST + this.LAST * (core.status.event.data.constantsPage - 1);
|
||||
items = Object.keys(core.status.hero.items.constants).sort();
|
||||
}
|
||||
if (items == null) return;
|
||||
@ -1309,33 +1344,35 @@ actions.prototype._clickToolboxIndex = function (index) {
|
||||
actions.prototype._keyDownToolbox = function (keycode) {
|
||||
if (core.status.event.data == null) return;
|
||||
|
||||
var last_index = this.LAST - 1;
|
||||
|
||||
var tools = Object.keys(core.status.hero.items.tools).sort();
|
||||
var constants = Object.keys(core.status.hero.items.constants).sort();
|
||||
var index = core.status.event.selection;
|
||||
var toolsPage = core.status.event.data.toolsPage;
|
||||
var constantsPage = core.status.event.data.constantsPage;
|
||||
var toolsTotalPage = Math.ceil(tools.length / 12);
|
||||
var constantsTotalPage = Math.ceil(constants.length / 12);
|
||||
var toolsLastIndex = toolsPage < toolsTotalPage ? 11 : (tools.length + 11) % 12;
|
||||
var constantsLastIndex = 12 + (constantsPage < constantsTotalPage ? 11 : (constants.length + 11) % 12);
|
||||
var toolsTotalPage = Math.ceil(tools.length / this.LAST);
|
||||
var constantsTotalPage = Math.ceil(constants.length / this.LAST);
|
||||
var toolsLastIndex = toolsPage < toolsTotalPage ? last_index : (tools.length + last_index) % this.LAST;
|
||||
var constantsLastIndex = this.LAST + (constantsPage < constantsTotalPage ? last_index : (constants.length + last_index) % this.LAST);
|
||||
|
||||
if (keycode == 37) { // left
|
||||
if (index == 0) { // 处理向前翻页
|
||||
if (toolsPage > 1) {
|
||||
core.status.event.data.toolsPage--;
|
||||
index = 11;
|
||||
index = last_index;
|
||||
}
|
||||
else return; // 第一页不向前翻
|
||||
}
|
||||
else if (index == 12) {
|
||||
else if (index == this.LAST) {
|
||||
if (constantsPage == 1) {
|
||||
if (toolsTotalPage == 0) return;
|
||||
core.status.event.data.toolsPage = toolsTotalPage;
|
||||
index = (tools.length + 11) % 12;
|
||||
index = (tools.length + last_index) % this.LAST;
|
||||
}
|
||||
else {
|
||||
core.status.event.data.constantsPage--;
|
||||
index = 23;
|
||||
index = 2 * this.LAST - 1;
|
||||
}
|
||||
}
|
||||
else index -= 1;
|
||||
@ -1343,29 +1380,29 @@ actions.prototype._keyDownToolbox = function (keycode) {
|
||||
return;
|
||||
}
|
||||
if (keycode == 38) { // up
|
||||
if (index >= 12 && index <= 17) { // 进入tools
|
||||
if (index >= this.LAST && index < this.LAST + this.HSIZE) { // 进入tools
|
||||
if (toolsTotalPage == 0) return;
|
||||
if (toolsLastIndex >= 6) index = Math.min(toolsLastIndex, index - 6);
|
||||
else index = Math.min(toolsLastIndex, index - 12);
|
||||
if (toolsLastIndex >= this.HSIZE) index = Math.min(toolsLastIndex, index - this.HSIZE);
|
||||
else index = Math.min(toolsLastIndex, index - this.LAST);
|
||||
}
|
||||
else if (index < 6) return; // 第一行没有向上
|
||||
else index -= 6;
|
||||
else if (index < this.HSIZE) return; // 第一行没有向上
|
||||
else index -= this.HSIZE;
|
||||
this._clickToolboxIndex(index);
|
||||
return;
|
||||
}
|
||||
if (keycode == 39) { // right
|
||||
if (toolsPage < toolsTotalPage && index == 11) {
|
||||
if (toolsPage < toolsTotalPage && index == last_index) {
|
||||
core.status.event.data.toolsPage++;
|
||||
index = 0;
|
||||
}
|
||||
else if (constantsPage < constantsTotalPage && index == 23) {
|
||||
else if (constantsPage < constantsTotalPage && index == 2 * this.LAST - 1) {
|
||||
core.status.event.data.constantsPage++;
|
||||
index = 12;
|
||||
index = this.LAST;
|
||||
}
|
||||
else if (index == toolsLastIndex) {
|
||||
if (constantsTotalPage == 0) return;
|
||||
core.status.event.data.constantsPage = 1;
|
||||
index = 12;
|
||||
index = this.LAST;
|
||||
}
|
||||
else if (index == constantsLastIndex) // 一个物品无操作
|
||||
return;
|
||||
@ -1375,16 +1412,17 @@ actions.prototype._keyDownToolbox = function (keycode) {
|
||||
}
|
||||
if (keycode == 40) { // down
|
||||
var nextIndex = null;
|
||||
if (index <= 5) {
|
||||
if (toolsLastIndex > 5) nextIndex = Math.min(toolsLastIndex, index + 6);
|
||||
else index += 6;
|
||||
if (index < this.HSIZE) {
|
||||
if (toolsLastIndex >= this.HSIZE) nextIndex = Math.min(toolsLastIndex, index + this.HSIZE);
|
||||
else index += this.HSIZE;
|
||||
}
|
||||
if (nextIndex == null && index <= 11) {
|
||||
if (nextIndex == null && index < this.LAST) {
|
||||
if (constantsTotalPage == 0) return;
|
||||
nextIndex = Math.min(index + 6, constantsLastIndex);
|
||||
nextIndex = Math.min(index + this.HSIZE, constantsLastIndex);
|
||||
}
|
||||
if (nextIndex == null && index <= 17) {
|
||||
if (constantsLastIndex > 17) nextIndex = Math.min(constantsLastIndex, index + 6);
|
||||
if (nextIndex == null && index < this.LAST + this.HSIZE) {
|
||||
if (constantsLastIndex >= this.LAST + this.HSIZE)
|
||||
nextIndex = Math.min(constantsLastIndex, index + this.HSIZE);
|
||||
}
|
||||
if (nextIndex != null) {
|
||||
this._clickToolboxIndex(nextIndex);
|
||||
@ -1415,64 +1453,65 @@ actions.prototype._keyUpToolbox = function (keycode) {
|
||||
////// 装备栏界面时的点击操作 //////
|
||||
actions.prototype._clickEquipbox = function (x, y) {
|
||||
// 道具栏
|
||||
if (x >= 10 && x <= 12 && y == 0) {
|
||||
if (x >= this.LAST - 2 && y == 0) {
|
||||
core.ui.closePanel();
|
||||
core.openToolbox();
|
||||
return;
|
||||
}
|
||||
// 返回
|
||||
if (x >= 10 && x <= 12 && y == 12) {
|
||||
if (x >= this.LAST - 2 && y == this.LAST) {
|
||||
core.ui.closePanel();
|
||||
return;
|
||||
}
|
||||
|
||||
// 当前页面
|
||||
var page = core.status.event.data.page;
|
||||
|
||||
// 上一页
|
||||
if ((x == 3 || x == 4) && y == 12) {
|
||||
if (page > 1) {
|
||||
if ((x == this.HSIZE-2 || x == this.HSIZE-3) && y == this.LAST) {
|
||||
if (core.status.event.data.page > 1) {
|
||||
core.status.event.data.page--;
|
||||
core.ui.drawEquipbox(core.status.event.selection);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// 下一页
|
||||
if ((x == 8 || x == 9) && y == 12) {
|
||||
var lastPage = Math.ceil(Object.keys(core.status.hero.items.equips).length / 12);
|
||||
if (page < lastPage) {
|
||||
if ((x == this.HSIZE+2 || x == this.HSIZE+3) && y == this.LAST) {
|
||||
var lastPage = Math.ceil(Object.keys(core.status.hero.items.equips).length / this.LAST);
|
||||
if (core.status.event.data.page < lastPage) {
|
||||
core.status.event.data.page++;
|
||||
core.ui.drawEquipbox(core.status.event.selection);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var index = parseInt(x / 2);
|
||||
if (y == 4) index += 0;
|
||||
else if (y == 6) index += 6;
|
||||
else if (y == 9) index += 12;
|
||||
else if (y == 11) index += 18;
|
||||
else index = -1;
|
||||
|
||||
if (index >= 0) {
|
||||
if (index < 12) index = parseInt(index / 2);
|
||||
this._clickEquipboxIndex(index);
|
||||
var per_page = this.HSIZE - 3, v = this.SIZE / per_page;
|
||||
if (y == this.LAST - 8) {
|
||||
for (var i = 0; i < per_page; ++i)
|
||||
if (x >= i * v && x <= (i + 1) * v)
|
||||
return this._clickEquipboxIndex(i);
|
||||
}
|
||||
else if (y == this.LAST - 6) {
|
||||
for (var i = 0; i < per_page; ++i)
|
||||
if (x >= i * v && x <= (i + 1) * v)
|
||||
return this._clickEquipboxIndex(per_page + i);
|
||||
}
|
||||
else if (y == this.LAST - 3)
|
||||
this._clickEquipboxIndex(this.LAST + parseInt(x / 2))
|
||||
else if (y == this.LAST - 1)
|
||||
this._clickEquipboxIndex(this.LAST + this.HSIZE + parseInt(x / 2));
|
||||
}
|
||||
|
||||
////// 选择装备栏界面中某个Index后的操作 //////
|
||||
actions.prototype._clickEquipboxIndex = function (index) {
|
||||
if (index < 6) {
|
||||
if (index < this.LAST) {
|
||||
if (index >= core.status.globalAttribute.equipName.length) return;
|
||||
if (index == core.status.event.selection && core.status.hero.equipment[index]) {
|
||||
core.unloadEquip(index);
|
||||
core.status.route.push("unEquip:" + index);
|
||||
}
|
||||
}
|
||||
else if (index >= 12) {
|
||||
else {
|
||||
var equips = Object.keys(core.status.hero.items.equips || {}).sort();
|
||||
if (index == core.status.event.selection) {
|
||||
var equipId = equips[index - 12 + (core.status.event.data.page - 1) * 12];
|
||||
var equipId = equips[index - this.LAST + (core.status.event.data.page - 1) * this.LAST];
|
||||
core.loadEquip(equipId);
|
||||
core.status.route.push("equip:" + equipId);
|
||||
}
|
||||
@ -1482,21 +1521,23 @@ actions.prototype._clickEquipboxIndex = function (index) {
|
||||
|
||||
////// 装备栏界面时,按下某个键的操作 //////
|
||||
actions.prototype._keyDownEquipbox = function (keycode) {
|
||||
if (core.status.event.data != null) return;
|
||||
if (core.status.event.data == null) return;
|
||||
|
||||
var last_index = this.LAST - 1;
|
||||
var per_line = this.HSIZE - 3;
|
||||
var equipCapacity = core.status.globalAttribute.equipName.length;
|
||||
var ownEquipment = Object.keys(core.status.hero.items.equips).sort();
|
||||
var index = core.status.event.selection;
|
||||
var page = core.status.event.data.page;
|
||||
var totalPage = Math.ceil(ownEquipment.length / 12);
|
||||
var totalLastIndex = 12 + (page < totalPage ? 11 : (ownEquipment.length + 11) % 12);
|
||||
var totalPage = Math.ceil(ownEquipment.length / this.LAST);
|
||||
var totalLastIndex = this.LAST + (page < totalPage ? last_index : (ownEquipment.length + last_index) % this.LAST);
|
||||
|
||||
if (keycode == 37) { // left
|
||||
if (index == 0) return;
|
||||
if (index == 12) {
|
||||
if (index == this.LAST) {
|
||||
if (page > 1) {
|
||||
core.status.event.data.page--;
|
||||
index = 23;
|
||||
index = this.LAST + last_index;
|
||||
}
|
||||
else if (page == 1)
|
||||
index = equipCapacity - 1;
|
||||
@ -1507,25 +1548,25 @@ actions.prototype._keyDownEquipbox = function (keycode) {
|
||||
return;
|
||||
}
|
||||
if (keycode == 38) { // up
|
||||
if (index < 3) return;
|
||||
else if (index < 6) index -= 3;
|
||||
else if (index < 18) {
|
||||
index = parseInt((index - 12) / 2);
|
||||
if (equipCapacity > 3) index = Math.min(equipCapacity - 1, index + 3);
|
||||
if (index < per_line) return;
|
||||
else if (index < 2 * per_line) index -= per_line;
|
||||
else if (index < this.LAST + this.HSIZE) {
|
||||
index = parseInt((index - this.LAST) / 2);
|
||||
if (equipCapacity > per_line) index = Math.min(equipCapacity - 1, index + per_line);
|
||||
else index = Math.min(equipCapacity - 1, index);
|
||||
}
|
||||
else index -= 6;
|
||||
else index -= this.HSIZE;
|
||||
this._clickEquipboxIndex(index);
|
||||
return;
|
||||
}
|
||||
if (keycode == 39) { // right
|
||||
if (page < totalPage && index == 23) {
|
||||
if (page < totalPage && index == this.LAST + last_index) {
|
||||
core.status.event.data.page++;
|
||||
index = 12;
|
||||
index = this.LAST;
|
||||
}
|
||||
else if (index == equipCapacity - 1) {
|
||||
if (totalPage == 0) return;
|
||||
index = 12;
|
||||
index = this.LAST;
|
||||
}
|
||||
else if (index == totalLastIndex)
|
||||
return;
|
||||
@ -1534,19 +1575,19 @@ actions.prototype._keyDownEquipbox = function (keycode) {
|
||||
return;
|
||||
}
|
||||
if (keycode == 40) { // down
|
||||
if (index < 3) {
|
||||
if (equipCapacity > 3) index = Math.min(index + 3, equipCapacity - 1);
|
||||
if (index < per_line) {
|
||||
if (equipCapacity > per_line) index = Math.min(index + per_line, equipCapacity - 1);
|
||||
else {
|
||||
if (totalPage == 0) return;
|
||||
index = Math.min(2 * index + 1 + 12, totalLastIndex);
|
||||
index = Math.min(2 * index + 1 + this.LAST, totalLastIndex);
|
||||
}
|
||||
}
|
||||
else if (index < 6) {
|
||||
else if (index < 2 * per_line) {
|
||||
if (totalPage == 0) return;
|
||||
index = Math.min(2 * (index - 3) + 1 + 12, totalLastIndex);
|
||||
index = Math.min(2 * (index - per_line) + 1 + this.LAST, totalLastIndex);
|
||||
}
|
||||
else if (index < 18)
|
||||
index = Math.min(index + 6, totalLastIndex);
|
||||
else if (index < this.LAST + this.HSIZE)
|
||||
index = Math.min(index + this.HSIZE, totalLastIndex);
|
||||
else return;
|
||||
this._clickEquipboxIndex(index);
|
||||
return;
|
||||
@ -1577,11 +1618,9 @@ actions.prototype._keyUpEquipbox = function (keycode, altKey) {
|
||||
}
|
||||
|
||||
////// 存读档界面时的点击操作 //////
|
||||
actions.prototype._clickSL = function (x, y, px, py) {
|
||||
actions.prototype._clickSL = function (x, y) {
|
||||
var page = core.status.event.data.page, offset = core.status.event.data.offset;
|
||||
var index = page * 10 + offset;
|
||||
//var index = core.status.event.data;
|
||||
//var page = parseInt(index / 10), offset = index % 10;
|
||||
|
||||
// 上一页
|
||||
if ((x == this.HSIZE-2 || x == this.HSIZE-3) && y == this.LAST) {
|
||||
@ -1595,13 +1634,11 @@ actions.prototype._clickSL = function (x, y, px, py) {
|
||||
}
|
||||
// 返回
|
||||
if (x >= this.LAST-2 && y == this.LAST) {
|
||||
if (core.events.recoverEvents(core.status.event.interval)) {
|
||||
if (core.events.recoverEvents(core.status.event.interval))
|
||||
return;
|
||||
}
|
||||
core.ui.closePanel();
|
||||
if (!core.isPlaying()) {
|
||||
if (!core.isPlaying())
|
||||
core.showStartAnimate(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// 删除
|
||||
@ -1612,72 +1649,88 @@ actions.prototype._clickSL = function (x, y, px, py) {
|
||||
}
|
||||
else { // 显示收藏
|
||||
core.status.event.data.mode = core.status.event.data.mode == 'all'?'fav':'all';
|
||||
core.saves.index = {};
|
||||
for(var i in core.saves.favorite){
|
||||
core.saves.index[i] = core.saves.favorite[i];
|
||||
if (core.status.event.data.mode == 'fav')
|
||||
core.ui.drawSLPanel(1, true);
|
||||
else {
|
||||
page = parseInt((core.saves.saveIndex-1)/5);
|
||||
offset = core.saves.saveIndex-5*page;
|
||||
core.ui.drawSLPanel(10*page + offset, true);
|
||||
}
|
||||
core.ui.drawSLPanel(index,true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// 收藏
|
||||
var fav = null;
|
||||
var centerX = parseInt(this.SIZE/2), leftX = 2, rightX = this.LAST-2;
|
||||
|
||||
// 三个关键坐标:
|
||||
// 点存档名
|
||||
var xLeft = parseInt(this.SIZE/3), xRight = parseInt(this.SIZE*2/3);
|
||||
var topY1 = 0, topY2 = parseInt(this.SIZE/2);
|
||||
var topY1 = 0, topY2 = this.HSIZE;
|
||||
if(y >= topY1 && y <= topY1 + 1) {
|
||||
if (x >= xLeft && x < xRight) return this._clickSL_favorite(page, 1);
|
||||
if (x >= xRight) return this._clickSL_favorite(page, 2);
|
||||
}
|
||||
if(y >= topY2 && y <= topY2 + 1) {
|
||||
if (x < xLeft) return this._clickSL_favorite(page, 3);
|
||||
if (x >= xLeft && x < xRight) return this._clickSL_favorite(page, 4);
|
||||
if (x >= xRight) return this._clickSL_favorite(page, 5);
|
||||
}
|
||||
|
||||
if(y==topY1){
|
||||
if (x >= xLeft && x < xRight) fav = 5 * page + 1;
|
||||
if (x >= xRight) fav = 5 * page + 2;
|
||||
}
|
||||
if(y==topY2){
|
||||
if (x < xLeft) fav = 5 * page + 3;
|
||||
if (x >= xLeft && x < xRight) fav = 5 * page + 4;
|
||||
if (x >= xRight) fav = 5 * page + 5;
|
||||
}
|
||||
if (fav != null){
|
||||
this._keyDownFav(page,fav%5);
|
||||
}
|
||||
var id = null;
|
||||
var topSpan = parseInt(this.SIZE/7);
|
||||
if (y >= topY1 + topSpan && y <= topY1 + topSpan + 3) {
|
||||
if (y >= topY1 + 2 && y < this.HSIZE - 1) {
|
||||
if (x < xLeft) id = "autoSave";
|
||||
if (x >= xLeft && x < xRight) id = 5 * page + 1;
|
||||
if (x >= xRight) id = 5 * page + 2;
|
||||
}
|
||||
if (y >= topY2+1 && y <= topY2+5) {
|
||||
if (y >= topY2 + 2 && y < this.SIZE - 1) {
|
||||
if (x < xLeft) id = 5 * page + 3;
|
||||
if (x >= xLeft && x < xRight) id = 5 * page + 4;
|
||||
if (x >= xRight) id = 5 * page + 5;
|
||||
}
|
||||
if (id != null) {
|
||||
if (core.status.event.selection) {
|
||||
if (id == 'autoSave') {
|
||||
if (id == 'autoSave')
|
||||
core.drawTip("无法删除自动存档!");
|
||||
}
|
||||
else {
|
||||
// core.removeLocalStorage("save"+id);
|
||||
core.removeLocalForage("save" + id, function () {
|
||||
var idx = core.saves.favorite.indexOf(id);
|
||||
core.saves.favorite.splice(idx,1);
|
||||
delete core.saves.favName[id];
|
||||
core.ui._drawSLPanel_saveFav(function(){
|
||||
core.ui._drawSLPanel_flushIndex();
|
||||
core.ui.drawSLPanel(index, true)});
|
||||
}, function () {
|
||||
core.drawTip("无法删除存档!");
|
||||
})
|
||||
core.removeSave(id, function () {
|
||||
core.ui.drawSLPanel(index, true);
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(core.status.event.data.mode=='fav')id = core.saves.favIndex[id];
|
||||
if(core.status.event.data.mode == 'fav' && id != 'autoSave')
|
||||
id = core.saves.favorite[id - 1];
|
||||
core.doSL(id, core.status.event.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
actions.prototype._clickSL_favorite = function (page, offset) {
|
||||
if (offset == 0) return;
|
||||
var index = 5 * page + offset;
|
||||
if (core.status.event.data.mode == 'fav') { // 收藏模式下点击的下标直接对应favorite
|
||||
index = core.saves.favorite[index - 1];
|
||||
core.myprompt("请输入想要显示的存档名(长度不超过5字符)", null, function (value) {
|
||||
if(value && value.length <= 5){
|
||||
core.saves.favoriteName[index] = value;
|
||||
core.control._updateFavoriteSaves();
|
||||
core.drawSLPanel(10 * page + offset);
|
||||
} else if (value) {
|
||||
alert("无效的输入!");
|
||||
}
|
||||
});
|
||||
} else {
|
||||
var v = core.saves.favorite.indexOf(index);
|
||||
if (v >= 0) { // 已经处于收藏状态:取消收藏
|
||||
core.saves.favorite.splice(v, 1);
|
||||
delete core.saves.favoriteName[index];
|
||||
}
|
||||
else if (core.hasSave(index)) { // 存在存档则进行收藏
|
||||
core.saves.favorite.push(index);
|
||||
core.saves.favorite = core.saves.favorite.sort(function (a,b) {return a-b;}); // 保证有序
|
||||
core.drawTip("收藏成功!");
|
||||
}
|
||||
core.control._updateFavoriteSaves();
|
||||
core.ui.drawSLPanel(10 * page + offset);
|
||||
}
|
||||
}
|
||||
|
||||
////// 存读档界面时,按下某个键的操作 //////
|
||||
actions.prototype._keyDownSL = function (keycode) {
|
||||
|
||||
@ -1729,40 +1782,6 @@ actions.prototype._keyDownSL = function (keycode) {
|
||||
core.ui.drawSLPanel(10 * (page + 1) + offset);
|
||||
return;
|
||||
}
|
||||
if (keycode == 70){ // F
|
||||
this._keyDownFav(page,offset);
|
||||
}
|
||||
}
|
||||
actions.prototype._keyDownFav = function(page, offset){
|
||||
var fav = page*5+offset;
|
||||
var idx = fav;
|
||||
var index = page*10 + offset;
|
||||
if(core.status.event.data.mode=='fav'){//收藏模式下点击的下标直接对应favorite
|
||||
fav = core.saves.favIndex[idx];
|
||||
var dataIdx = index;
|
||||
core.myprompt("请输入想要显示的存档名(长度不超过5字符)", null, function (index) {
|
||||
if(index && index.length<=5 && index.length>0){
|
||||
core.saves.favName[fav]=index;
|
||||
core.ui._drawSLPanel_saveFav(function(){core.ui.drawSLPanel(dataIdx, false)});
|
||||
}else{
|
||||
alert("无效的输入!");
|
||||
}
|
||||
});
|
||||
}else{
|
||||
idx = core.saves.favorite.indexOf(fav);
|
||||
if(idx>=0){
|
||||
core.saves.favorite.splice(idx,1);
|
||||
delete core.saves.favName[fav];
|
||||
}else{
|
||||
if(core.hasSave(fav)){
|
||||
core.saves.favorite.push(fav);
|
||||
core.saves.favName[idx] = fav;//暂时的 收藏下标到名字的映射(实际存储的是收藏ID到名字的映射)
|
||||
}
|
||||
}
|
||||
core.ui._drawSLPanel_saveFav(function(){
|
||||
core.ui._drawSLPanel_flushIndex();
|
||||
core.ui.drawSLPanel(index, false)});
|
||||
}
|
||||
}
|
||||
|
||||
////// 存读档界面时,放开某个键的操作 //////
|
||||
@ -1770,35 +1789,23 @@ actions.prototype._keyUpSL = function (keycode) {
|
||||
var page = core.status.event.data.page, offset = core.status.event.data.offset;
|
||||
var index = page * 10 + offset;
|
||||
|
||||
if (keycode == 27 || keycode == 88 || (core.status.event.id == 'save' && keycode == 83) || (core.status.event.id == 'load' && keycode == 68)) {
|
||||
if (core.events.recoverEvents(core.status.event.interval)) {
|
||||
return;
|
||||
}
|
||||
core.ui.closePanel();
|
||||
if (!core.isPlaying()) {
|
||||
core.showStartAnimate(true);
|
||||
}
|
||||
if (keycode == 27 || keycode == 88 || (core.status.event.id == 'save' && keycode == 83)
|
||||
|| (core.status.event.id == 'load' && keycode == 68)) {
|
||||
this._clickSL(this.LAST, this.LAST);
|
||||
return;
|
||||
}
|
||||
if (keycode == 13 || keycode == 32 || keycode == 67) {
|
||||
if (offset == 0) {
|
||||
if (offset == 0)
|
||||
core.doSL("autoSave", core.status.event.id);
|
||||
}
|
||||
else {
|
||||
var id = 5 * page + offset;
|
||||
if(core.status.event.data.mode=='fav')id = core.saves.favIndex[id];
|
||||
if(core.status.event.data.mode == 'fav') id = core.saves.favorite[id - 1];
|
||||
core.doSL(id, core.status.event.id);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (keycode == 69 && core.status.event.id != 'save') { // E 收藏切换
|
||||
core.status.event.data.mode = core.status.event.data.mode == 'all'?'fav':'all';
|
||||
core.saves.index = {};
|
||||
for(var i in core.saves.favorite){
|
||||
core.saves.index[i] = core.saves.favorite[i];
|
||||
}
|
||||
core.ui.drawSLPanel(core.saves.saveIndex,true);
|
||||
|
||||
this._clickSL(0, this.LAST);
|
||||
return;
|
||||
}
|
||||
if (keycode == 46) {
|
||||
@ -1806,19 +1813,16 @@ actions.prototype._keyUpSL = function (keycode) {
|
||||
core.drawTip("无法删除自动存档!");
|
||||
}
|
||||
else {
|
||||
core.removeLocalForage("save" + (5 * page + offset), function () {
|
||||
var id = 5 * page + offset;
|
||||
var idx = core.saves.favorite.indexOf(id);
|
||||
core.saves.favorite.splice(idx,1);
|
||||
delete core.saves.favName[id];
|
||||
core.ui._drawSLPanel_saveFav(function(){
|
||||
core.ui._drawSLPanel_flushIndex();
|
||||
core.ui.drawSLPanel(index, true)});
|
||||
}, function () {
|
||||
core.drawTip("无法删除存档!");
|
||||
})
|
||||
if(core.status.event.data.mode == 'fav') id = core.saves.favorite[id - 1];
|
||||
core.removeSave(id, function () {
|
||||
core.ui.drawSLPanel(index, true);
|
||||
});
|
||||
}
|
||||
}
|
||||
if (keycode == 70 && core.status.event.data.mode == 'all') { // F
|
||||
this._clickSL_favorite(page, offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1936,11 +1940,11 @@ actions.prototype._clickSettings = function (x, y) {
|
||||
core.ui.drawKeyBoard();
|
||||
break;
|
||||
case 2:
|
||||
core.clearSelector();
|
||||
core.clearUI();
|
||||
core.ui.drawMaps();
|
||||
break;
|
||||
case 3:
|
||||
core.clearSelector();
|
||||
core.clearUI();
|
||||
core.ui.drawPaint();
|
||||
break;
|
||||
case 4:
|
||||
@ -1952,7 +1956,7 @@ actions.prototype._clickSettings = function (x, y) {
|
||||
core.ui.drawGameInfo();
|
||||
break;
|
||||
case 6:
|
||||
return core.confirmRestart(true);
|
||||
return core.confirmRestart();
|
||||
case 7:
|
||||
core.ui.closePanel();
|
||||
break;
|
||||
@ -2097,7 +2101,7 @@ actions.prototype._clickLocalSaveSelect = function (x, y) {
|
||||
var selection = y - topIndex;
|
||||
core.status.event.selection = selection;
|
||||
if (selection < 2) {
|
||||
core.control.getSaves(selection == 0 ? null : core.saves.saveIndex, function (saves) {
|
||||
var callback = function (saves) {
|
||||
if (saves) {
|
||||
var content = {
|
||||
"name": core.firstData.name,
|
||||
@ -2106,7 +2110,9 @@ actions.prototype._clickLocalSaveSelect = function (x, y) {
|
||||
}
|
||||
core.download(core.firstData.name + "_" + core.formatDate2(new Date()) + ".h5save", JSON.stringify(content));
|
||||
}
|
||||
})
|
||||
};
|
||||
if (selection == 0) core.getAllSaves(callback);
|
||||
else core.getSave(core.saves.saveIndex, callback);
|
||||
}
|
||||
|
||||
core.status.event.selection = 2;
|
||||
@ -2150,12 +2156,16 @@ actions.prototype._clickStorageRemove = function (x, y) {
|
||||
actions.prototype._clickStorageRemove_all = function () {
|
||||
core.myconfirm("你确定要清除【全部塔】的所有本地存档?\n此行为不可逆!!!", function () {
|
||||
var done = function () {
|
||||
core.saves.ids = {};
|
||||
core.saves.autosave.data = null;
|
||||
core.saves.autosave.updated = false;
|
||||
core.ui.closePanel();
|
||||
core.drawText("\t[操作成功]你的所有存档已被清空。");
|
||||
core.saves.saveIndex = 1;
|
||||
core.saves.favorite = [];
|
||||
core.saves.favoriteName = {};
|
||||
core.control._updateFavoriteSaves();
|
||||
core.removeLocalStorage('saveIndex');
|
||||
core.drawText("\t[操作成功]你的所有存档已被清空。");
|
||||
};
|
||||
if (core.platform.useLocalForage) {
|
||||
core.ui.drawWaiting("正在清空,请稍后...");
|
||||
@ -2171,12 +2181,16 @@ actions.prototype._clickStorageRemove_all = function () {
|
||||
actions.prototype._clickStorageRemove_current = function () {
|
||||
core.myconfirm("你确定要清除本塔的所有本地存档?\n此行为不可逆!!!", function () {
|
||||
var done = function () {
|
||||
core.saves.ids = {};
|
||||
core.saves.autosave.data = null;
|
||||
core.saves.autosave.updated = false;
|
||||
core.ui.closePanel();
|
||||
core.drawText("\t[操作成功]当前塔的存档已被清空。");
|
||||
core.saves.saveIndex = 1;
|
||||
core.saves.favorite = [];
|
||||
core.saves.favoriteName = {};
|
||||
core.control._updateFavoriteSaves();
|
||||
core.removeLocalStorage('saveIndex');
|
||||
core.drawText("\t[操作成功]当前塔的存档已被清空。");
|
||||
}
|
||||
if (core.platform.useLocalForage) {
|
||||
core.ui.drawWaiting("正在清空,请稍后...");
|
||||
@ -2233,7 +2247,7 @@ actions.prototype._clickReplay_fromBeginning = function () {
|
||||
actions.prototype._clickReplay_fromLoad = function () {
|
||||
core.status.event.id = 'replayLoad';
|
||||
core.status.event.selection = null;
|
||||
core.ui.clearSelector();
|
||||
core.clearUI();
|
||||
var saveIndex = core.saves.saveIndex;
|
||||
var page = parseInt((saveIndex - 1) / 5), offset = saveIndex - 5 * page;
|
||||
core.ui.drawSLPanel(10 * page + offset);
|
||||
@ -2472,7 +2486,7 @@ actions.prototype._onupPaint = function () {
|
||||
core.status.event.data.x = null;
|
||||
core.status.event.data.y = null;
|
||||
// 保存
|
||||
core.paint[core.status.floorId] = lzw_encode(core.utils.encodeCanvas(core.dymCanvas.paint).join(","));
|
||||
core.paint[core.status.floorId] = lzw_encode(core.utils._encodeCanvas(core.dymCanvas.paint).join(","));
|
||||
}
|
||||
|
||||
actions.prototype.setPaintMode = function (mode) {
|
||||
@ -2520,7 +2534,7 @@ actions.prototype.loadPaint = function () {
|
||||
core.clearMap('paint');
|
||||
var value = core.paint[core.status.floorId];
|
||||
if (value) value = lzw_decode(value).split(",");
|
||||
core.utils.decodeCanvas(value, 32 * core.bigmap.width, 32 * core.bigmap.height);
|
||||
core.utils._decodeCanvas(value, 32 * core.bigmap.width, 32 * core.bigmap.height);
|
||||
core.drawImage('paint', core.bigmap.tempCanvas.canvas, 0, 0);
|
||||
|
||||
core.drawTip("读取绘图文件成功");
|
||||
|
||||
246
libs/control.js
246
libs/control.js
@ -168,25 +168,22 @@ control.prototype._animationFrame_animate = function (timestamp) {
|
||||
if (timestamp - core.animateFrame.animateTime < 50 || !core.status.animateObjs || core.status.animateObjs.length == 0) return;
|
||||
core.clearMap('animate');
|
||||
// 更新帧
|
||||
var animateObjs = [];
|
||||
for (var i = 0; i < core.status.animateObjs.length; i++) {
|
||||
var obj = core.status.animateObjs[i];
|
||||
if (obj.index == obj.animate.frames.length) {
|
||||
// 绘制完毕
|
||||
delete core.animateFrame.asyncId[obj.id];
|
||||
// 异步执行回调...
|
||||
(function (callback) {
|
||||
setTimeout(function () {
|
||||
if (callback) callback();
|
||||
});
|
||||
})(obj.callback);
|
||||
}
|
||||
else {
|
||||
}
|
||||
core.status.animateObjs = core.status.animateObjs.filter(function (obj) {
|
||||
return obj.index < obj.animate.frames.length;
|
||||
});
|
||||
core.status.animateObjs.forEach(function (obj) {
|
||||
core.maps._drawAnimateFrame(obj.animate, obj.centerX, obj.centerY, obj.index++);
|
||||
animateObjs.push(obj);
|
||||
}
|
||||
}
|
||||
core.status.animateObjs = animateObjs;
|
||||
});
|
||||
core.animateFrame.animateTime = timestamp;
|
||||
}
|
||||
|
||||
@ -311,7 +308,7 @@ control.prototype.showStartAnimate = function (noAnimate, callback) {
|
||||
this._showStartAnimate_resetDom();
|
||||
if (core.flags.startUsingCanvas || noAnimate)
|
||||
return this._showStartAnimate_finished(core.flags.startUsingCanvas, callback);
|
||||
core.hide(core.dom.startTop, 20, function () {
|
||||
core.hideWithAnimate(core.dom.startTop, 20, function () {
|
||||
core.control._showStartAnimate_finished(false, callback);
|
||||
});
|
||||
}
|
||||
@ -327,8 +324,8 @@ control.prototype._showStartAnimate_resetDom = function () {
|
||||
core.status.played = false;
|
||||
core.clearStatus();
|
||||
core.clearMap('all');
|
||||
core.deleteAllCanvas();
|
||||
core.dom.musicBtn.style.display = 'block';
|
||||
core.setMusicBtn();
|
||||
// 重置音量
|
||||
core.events.setVolume(1, 0);
|
||||
core.updateStatusBar();
|
||||
@ -343,7 +340,7 @@ control.prototype._showStartAnimate_finished = function (start, callback) {
|
||||
|
||||
////// 隐藏游戏开始界面 //////
|
||||
control.prototype.hideStartAnimate = function (callback) {
|
||||
core.hide(core.dom.startPanel, 20, callback);
|
||||
core.hideWithAnimate(core.dom.startPanel, 20, callback);
|
||||
}
|
||||
|
||||
////// 游戏是否已经开始 //////
|
||||
@ -351,30 +348,6 @@ control.prototype.isPlaying = function() {
|
||||
return core.status.played;
|
||||
}
|
||||
|
||||
////// 重新开始游戏;此函数将回到标题页面 //////
|
||||
control.prototype.restart = function() {
|
||||
this.showStartAnimate();
|
||||
core.playBgm(main.startBgm);
|
||||
}
|
||||
|
||||
////// 询问是否需要重新开始 //////
|
||||
control.prototype.confirmRestart = function (fromSettings) {
|
||||
core.status.event.selection = 1;
|
||||
core.ui.drawConfirmBox("你确定要返回标题页面吗?", function () {
|
||||
core.ui.closePanel();
|
||||
core.restart();
|
||||
}, function () {
|
||||
if (fromSettings) {
|
||||
core.status.event.selection = 3;
|
||||
core.ui.drawSettings();
|
||||
}
|
||||
else {
|
||||
core.ui.closePanel();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
////// 清除游戏状态和数据 //////
|
||||
control.prototype.clearStatus = function() {
|
||||
// 停止各个Timeout和Interval
|
||||
@ -427,7 +400,7 @@ control.prototype.stopAutomaticRoute = function () {
|
||||
core.status.automaticRoute.destX=null;
|
||||
core.status.automaticRoute.destY=null;
|
||||
core.status.automaticRoute.lastDirection = null;
|
||||
core.stopHero();
|
||||
core.status.heroStop = true;
|
||||
if (core.status.automaticRoute.moveStepBeforeStop.length==0)
|
||||
core.deleteCanvas('route');
|
||||
}
|
||||
@ -475,8 +448,10 @@ control.prototype.setAutomaticRoute = function (destX, destY, stepPostfix) {
|
||||
if (this._setAutomaticRoute_isTurning(destX, destY, stepPostfix)) return;
|
||||
if (this._setAutomaticRoute_clickMoveDirectly(destX, destY, stepPostfix)) return;
|
||||
// 找寻自动寻路路线
|
||||
var moveStep = core.automaticRoute(destX, destY).concat(stepPostfix);
|
||||
if (moveStep.length == 0) return core.deleteCanvas('route');
|
||||
var moveStep = core.automaticRoute(destX, destY);
|
||||
if (moveStep.length == 0 && (destX != core.status.hero.loc.x || destY != core.status.hero.loc.y || stepPostfix.length == 0))
|
||||
return;
|
||||
moveStep = moveStep.concat(stepPostfix);
|
||||
core.status.automaticRoute.destX=destX;
|
||||
core.status.automaticRoute.destY=destY;
|
||||
this._setAutomaticRoute_drawRoute(moveStep);
|
||||
@ -662,7 +637,7 @@ control.prototype._moveAction_moving = function (callback) {
|
||||
core.updateStatusBar();
|
||||
|
||||
// 检查该点是否是滑冰
|
||||
if (core.getBgFgNumber('bg') == 167) {
|
||||
if (core.getBgNumber() == 167) {
|
||||
core.insertAction("滑冰事件", null, null, null, true);
|
||||
}
|
||||
|
||||
@ -752,11 +727,6 @@ control.prototype.waitHeroToStop = function(callback) {
|
||||
}
|
||||
}
|
||||
|
||||
////// 停止勇士的移动状态 //////
|
||||
control.prototype.stopHero = function () {
|
||||
core.status.heroStop = true;
|
||||
}
|
||||
|
||||
////// 转向 //////
|
||||
control.prototype.turnHero = function(direction) {
|
||||
if (direction) {
|
||||
@ -828,8 +798,8 @@ control.prototype._drawHero_getDrawObjs = function (direction, x, y, status, off
|
||||
});
|
||||
(core.status.hero.followers||[]).forEach(function (t) {
|
||||
drawObjs.push({
|
||||
"img": t.img,
|
||||
"height": t.img.height/4,
|
||||
"img": core.material.images.images[t.name],
|
||||
"height": core.material.images.images[t.name].height/4,
|
||||
"heroIcon": heroIconArr[t.direction],
|
||||
"posx": 32*t.x - core.bigmap.offsetX + (t.stop?0:core.utils.scan[t.direction].x*offset),
|
||||
"posy": 32*t.y - core.bigmap.offsetY + (t.stop?0:core.utils.scan[t.direction].y*offset),
|
||||
@ -886,17 +856,20 @@ control.prototype.updateViewport = function() {
|
||||
|
||||
////// 获得勇士面对位置的x坐标 //////
|
||||
control.prototype.nextX = function(n) {
|
||||
return core.getHeroLoc('x')+core.utils.scan[core.getHeroLoc('direction')].x*(n||1);
|
||||
if (n == null) n = 1;
|
||||
return core.getHeroLoc('x')+core.utils.scan[core.getHeroLoc('direction')].x*n;
|
||||
}
|
||||
|
||||
////// 获得勇士面对位置的y坐标 //////
|
||||
control.prototype.nextY = function (n) {
|
||||
return core.getHeroLoc('y')+core.utils.scan[core.getHeroLoc('direction')].y*(n||1);
|
||||
if (n == null) n = 1;
|
||||
return core.getHeroLoc('y')+core.utils.scan[core.getHeroLoc('direction')].y*n;
|
||||
}
|
||||
|
||||
////// 某个点是否在勇士旁边 //////
|
||||
control.prototype.nearHero = function (x, y) {
|
||||
return Math.abs(x-core.getHeroLoc('x'))+Math.abs(y-core.getHeroLoc('y'))<=1;
|
||||
control.prototype.nearHero = function (x, y, n) {
|
||||
if (n == null) n = 1;
|
||||
return Math.abs(x-core.getHeroLoc('x'))+Math.abs(y-core.getHeroLoc('y'))<=n;
|
||||
}
|
||||
|
||||
////// 聚集跟随者 //////
|
||||
@ -1275,7 +1248,12 @@ control.prototype._doReplayAction = function (action) {
|
||||
control.prototype._replay_finished = function () {
|
||||
core.status.replay.replaying = false;
|
||||
core.status.event.selection = 0;
|
||||
core.ui.drawConfirmBox("录像播放完毕,你想退出播放吗?", function () {
|
||||
var str = "录像播放完毕,你想退出播放吗?";
|
||||
if (core.status.route.length != core.status.replay.totalList.length
|
||||
|| core.subarray(core.status.route, core.status.replay.totalList) == null) {
|
||||
str = "录像播放完毕,但记录不一致。\n请检查录像播放时的二次记录问题。\n你想退出播放吗?";
|
||||
}
|
||||
core.ui.drawConfirmBox(str, function () {
|
||||
core.ui.closePanel();
|
||||
core.stopReplay(true);
|
||||
}, function () {
|
||||
@ -1301,8 +1279,12 @@ control.prototype._replay_save = function () {
|
||||
|
||||
control.prototype._replay_error = function (action) {
|
||||
core.status.replay.replaying = false;
|
||||
main.log("录像文件出错,当前操作:" + action +
|
||||
"\n接下来10个操作是:"+core.status.replay.toReplay.slice(0, 10).toString());
|
||||
var len = core.status.replay.toReplay.length;
|
||||
var prevList = core.status.replay.totalList.slice(-len - 11, -len - 1);
|
||||
var nextList = core.status.replay.toReplay.slice(0, 10);
|
||||
main.log("录像文件出错,当前操作:" + action);
|
||||
main.log("之前的10个操作是:\n" + prevList.toString());
|
||||
main.log("接下来10个操作是:\n" + nextList.toString());
|
||||
core.ui.drawConfirmBox("录像文件出错,你想回到上个节点吗?", function () {
|
||||
core.ui.closePanel();
|
||||
if (core.status.replay.save.length > 0) {
|
||||
@ -1410,6 +1392,12 @@ control.prototype._replayAction_shop = function (action) {
|
||||
if (selections.length == 0) return false;
|
||||
var shop=core.status.shops[shopId];
|
||||
if (!shop || !shop.visited) return false;
|
||||
// --- 判定commonEvent
|
||||
if (shop.commonEvent) {
|
||||
core.openShop(shopId, false);
|
||||
setTimeout(core.replay);
|
||||
return true;
|
||||
}
|
||||
var choices = shop.choices;
|
||||
var topIndex = core.__HALF_SIZE__ - parseInt(choices.length / 2);
|
||||
core.status.event.selection = parseInt(selections.shift());
|
||||
@ -1453,6 +1441,7 @@ control.prototype._replayAction_moveDirectly = function (action) {
|
||||
// 忽略连续的瞬移事件
|
||||
while (core.status.replay.toReplay.length>0 &&
|
||||
core.status.replay.toReplay[0].indexOf('move:')==0) {
|
||||
core.status.route.push(action);
|
||||
action = core.status.replay.toReplay.shift();
|
||||
}
|
||||
|
||||
@ -1608,13 +1597,15 @@ control.prototype._doSL_replayLoad_afterGet = function (id, data) {
|
||||
////// 同步存档到服务器 //////
|
||||
control.prototype.syncSave = function (type) {
|
||||
core.ui.drawWaiting("正在同步,请稍后...");
|
||||
core.control.getSaves(type=='all'?null:core.saves.saveIndex, function (saves) {
|
||||
if (!saves) return core.drawText("没有要同步的存档");
|
||||
var callback = function (saves) {
|
||||
core.control._syncSave_http(type, saves);
|
||||
})
|
||||
}
|
||||
if (type == 'all') core.getAllSaves(callback);
|
||||
else core.getSave(core.saves.saveIndex, callback);
|
||||
}
|
||||
|
||||
control.prototype._syncSave_http = function (type, saves) {
|
||||
if (!saves) return core.drawText("没有要同步的存档");
|
||||
var formData = new FormData();
|
||||
formData.append('type', 'save');
|
||||
formData.append('name', core.firstData.name);
|
||||
@ -1628,7 +1619,7 @@ control.prototype._syncSave_http = function (type, saves) {
|
||||
else {
|
||||
core.drawText((type=='all'?"所有存档":"存档"+core.saves.saveIndex)+"同步成功!\n\n您的存档编号: "
|
||||
+response.code+"\n您的存档密码: "+response.msg
|
||||
+"\n\n请牢记以上两个信息(如截图等),在从服务器\n同步存档时使用。")
|
||||
+"\n\n请牢记以上两个信息(如截图等),在从服务器\n同步存档时使用。\n\r[yellow]另外请注意,存档同步只会保存一个月的时间。\r")
|
||||
}
|
||||
}, function (e) {
|
||||
core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:"+e);
|
||||
@ -1702,32 +1693,53 @@ control.prototype.loadData = function (data, callback) {
|
||||
return this.controldata.loadData(data, callback);
|
||||
}
|
||||
|
||||
control.prototype.getSaves = function (index, callback) {
|
||||
if (index != null) {
|
||||
control.prototype.getSave = function (index, callback) {
|
||||
if (index == 0) {
|
||||
// --- 自动存档先从缓存中获取
|
||||
if (core.saves.autosave.data != null)
|
||||
callback(core.clone(core.saves.autosave.data));
|
||||
else {
|
||||
core.getLocalForage("autoSave", null, function(data) {
|
||||
callback(data);
|
||||
}, function(err) {
|
||||
main.log(err);
|
||||
callback(null);
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
core.getLocalForage("save"+index, null, function(data) {
|
||||
if (callback) callback(data);
|
||||
}, function(err) {
|
||||
main.log(err);
|
||||
if (callback) callback(null);
|
||||
})
|
||||
return;
|
||||
});
|
||||
}
|
||||
|
||||
control.prototype.getSaves = function (ids, callback) {
|
||||
if (!(ids instanceof Array)) return this.getSave(ids, callback);
|
||||
var count = ids.length, data = {};
|
||||
for (var i = 0; i < ids.length; ++i) {
|
||||
(function (i) {
|
||||
core.getSave(ids[i], function (result) {
|
||||
data[i] = result;
|
||||
if (Object.keys(data).length == count)
|
||||
callback(data);
|
||||
})
|
||||
})(i);
|
||||
}
|
||||
}
|
||||
|
||||
control.prototype.getAllSaves = function (callback) {
|
||||
var ids = Object.keys(core.saves.ids).filter(function(x){return x!=0;})
|
||||
.sort(function(a,b) {return a-b;}), number = ids.length, saves = [];
|
||||
var load = function (index, callback) {
|
||||
if (index > number) {
|
||||
if (callback) callback(saves);
|
||||
return;
|
||||
.sort(function(a,b) {return a-b;}), saves = [];
|
||||
this.getSaves(ids, function (data) {
|
||||
for (var i = 0; i < ids.length; ++i) {
|
||||
if (data[i] != null)
|
||||
saves.push(data[i]);
|
||||
}
|
||||
core.getLocalForage("save"+ids[index], null, function (data) {
|
||||
saves.push(data);
|
||||
load(index+1, callback);
|
||||
}, function(err) {
|
||||
main.log(err);
|
||||
load(index+1, callback);
|
||||
})
|
||||
}
|
||||
load(0, callback);
|
||||
callback(saves);
|
||||
});
|
||||
}
|
||||
|
||||
////// 获得所有存在存档的存档位 //////
|
||||
@ -1761,6 +1773,41 @@ control.prototype.hasSave = function (index) {
|
||||
return core.saves.ids[index] || false;
|
||||
}
|
||||
|
||||
////// 删除某个存档
|
||||
control.prototype.removeSave = function (index, callback) {
|
||||
if (index == 0 || index == "autoSave") {
|
||||
index = "autoSave";
|
||||
core.removeLocalForage(index, function () {
|
||||
core.saves.autosave.data = null;
|
||||
core.saves.autosave.updated = false;
|
||||
if (callback) callback();
|
||||
});
|
||||
return;
|
||||
}
|
||||
core.removeLocalForage("save" + index, function () {
|
||||
core.saves.favorite = core.saves.favorite.filter(function (i) { return core.hasSave(i); });
|
||||
delete core.saves.favoriteName[index];
|
||||
core.control._updateFavoriteSaves();
|
||||
if (callback) callback();
|
||||
}, function () {
|
||||
core.drawTip("无法删除存档!");
|
||||
if (callback) callback();
|
||||
});
|
||||
}
|
||||
|
||||
////// 读取收藏信息
|
||||
control.prototype._loadFavoriteSaves = function () {
|
||||
core.saves.favorite = core.getLocalStorage("favorite", []);
|
||||
// --- 移除不存在的收藏
|
||||
core.saves.favorite = core.saves.favorite.filter(function (i) { return core.hasSave(i); });
|
||||
core.saves.favoriteName = core.getLocalStorage("favoriteName", {});
|
||||
}
|
||||
|
||||
control.prototype._updateFavoriteSaves = function () {
|
||||
core.setLocalStorage("favorite", core.saves.favorite);
|
||||
core.setLocalStorage("favoriteName", core.saves.favoriteName);
|
||||
}
|
||||
|
||||
// ------ 属性,状态,位置,buff,变量,锁定控制等 ------ //
|
||||
|
||||
////// 设置勇士属性 //////
|
||||
@ -1782,7 +1829,7 @@ control.prototype.addStatus = function (name, value) {
|
||||
control.prototype.getStatus = function (name) {
|
||||
if (!core.status.hero) return null;
|
||||
if (name == 'x' || name == 'y' || name == 'direction')
|
||||
return this.getHeroLoc('x');
|
||||
return this.getHeroLoc(name);
|
||||
if (name == 'exp') name = 'experience';
|
||||
return core.status.hero[name];
|
||||
}
|
||||
@ -1806,12 +1853,12 @@ control.prototype.getRealStatusOrDefault = function (status, name) {
|
||||
|
||||
////// 设置某个属性的增幅值 //////
|
||||
control.prototype.setBuff = function (name, value) {
|
||||
this.setFlag('flag:__'+name+'_buff__', value);
|
||||
this.setFlag('__'+name+'_buff__', value);
|
||||
}
|
||||
|
||||
////// 加减某个属性的增幅值 //////
|
||||
control.prototype.addBuff = function (name, value) {
|
||||
this.setFlag('flag:__'+name+'_buff__', this.getBuff(name) + value);
|
||||
this.setFlag('__'+name+'_buff__', this.getBuff(name) + value);
|
||||
}
|
||||
|
||||
////// 获得某个属性的增幅值 //////
|
||||
@ -1835,6 +1882,15 @@ control.prototype.getHeroLoc = function (name) {
|
||||
return core.status.hero.loc[name];
|
||||
}
|
||||
|
||||
////// 获得某个属性的中文名 //////
|
||||
control.prototype.getStatusName = function (name) {
|
||||
var map = {
|
||||
name: "名称", lv: "等级", hpmax: "生命上限", hp: "生命", manamax: "魔力上限", mana: "魔力",
|
||||
atk: "攻击", def: "防御", mdef: "魔防", money: "金币", exp: "经验", experience: "经验", steps: "步数"
|
||||
};
|
||||
return map[name] || name;
|
||||
}
|
||||
|
||||
////// 获得某个等级的名称 //////
|
||||
control.prototype.getLvName = function (lv) {
|
||||
if (!core.status.hero) return null;
|
||||
@ -1951,7 +2007,7 @@ control.prototype._setWeather_createNodes = function (type, level) {
|
||||
}
|
||||
|
||||
////// 更改画面色调 //////
|
||||
control.prototype.setFg = function(color, time, callback) {
|
||||
control.prototype.setCurtain = function(color, time, callback) {
|
||||
if (time == null) time=750;
|
||||
if (time<=0) time=0;
|
||||
if (!core.status.curtainColor)
|
||||
@ -1969,10 +2025,10 @@ control.prototype.setFg = function(color, time, callback) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._setFg_animate(core.status.curtainColor, color, time, callback);
|
||||
this._setCurtain_animate(core.status.curtainColor, color, time, callback);
|
||||
}
|
||||
|
||||
control.prototype._setFg_animate = function (nowColor, color, time, callback) {
|
||||
control.prototype._setCurtain_animate = function (nowColor, color, time, callback) {
|
||||
var per_time = 10, step = parseInt(time / per_time);
|
||||
var animate = setInterval(function() {
|
||||
nowColor = [
|
||||
@ -2000,8 +2056,8 @@ control.prototype.screenFlash = function (color, time, times, callback) {
|
||||
times = times || 1;
|
||||
time = time / 3;
|
||||
var nowColor = core.clone(core.status.curtainColor);
|
||||
core.setFg(color, time, function() {
|
||||
core.setFg(nowColor, time * 2, function() {
|
||||
core.setCurtain(color, time, function() {
|
||||
core.setCurtain(nowColor, time * 2, function() {
|
||||
if (times > 1)
|
||||
core.screenFlash(color, time * 3, times - 1, callback);
|
||||
else {
|
||||
@ -2113,7 +2169,7 @@ control.prototype.playSound = function (sound) {
|
||||
var source = core.musicStatus.audioContext.createBufferSource();
|
||||
source.buffer = core.material.sounds[sound];
|
||||
source.connect(core.musicStatus.gainNode);
|
||||
var id = parseInt(Math.random()*10000000);
|
||||
var id = setTimeout(null);
|
||||
source.onended = function () {
|
||||
delete core.musicStatus.playingSounds[id];
|
||||
}
|
||||
@ -2137,8 +2193,8 @@ control.prototype.stopSound = function () {
|
||||
for (var i in core.musicStatus.playingSounds) {
|
||||
var source = core.musicStatus.playingSounds[i];
|
||||
try {
|
||||
if (source[i].stop) source[i].stop();
|
||||
else if (source[i].noteOff) source[i].noteOff();
|
||||
if (source.stop) source.stop();
|
||||
else if (source.noteOff) source.noteOff();
|
||||
}
|
||||
catch (e) {
|
||||
main.log(e);
|
||||
@ -2287,10 +2343,11 @@ control.prototype.updateGlobalAttribute = function (name) {
|
||||
core.dom.statusBar.style.borderTop = border;
|
||||
core.dom.statusBar.style.borderLeft = border;
|
||||
core.dom.statusBar.style.borderRight = core.domStyle.isVertical?border:'';
|
||||
core.dom.statusBar.style.borderBottom = core.domStyle.isVertical?'':border;
|
||||
core.dom.gameDraw.style.border = border;
|
||||
core.dom.toolBar.style.borderBottom = border;
|
||||
core.dom.toolBar.style.borderLeft = border;
|
||||
core.dom.toolBar.style.borderRight = core.domStyle.isVertical?border:'';
|
||||
core.dom.toolBar.style.borderBottom = core.domStyle.isVertical?border:'';
|
||||
break;
|
||||
}
|
||||
case 'statusBarColor':
|
||||
@ -2312,7 +2369,7 @@ control.prototype.updateGlobalAttribute = function (name) {
|
||||
}
|
||||
}
|
||||
|
||||
////// 改变工具栏为按钮1-7 //////
|
||||
////// 改变工具栏为按钮1-8 //////
|
||||
control.prototype.setToolbarButton = function (useButton) {
|
||||
if (!core.domStyle.showStatusBar) {
|
||||
// 隐藏状态栏时检查竖屏
|
||||
@ -2478,7 +2535,7 @@ control.prototype._resize_gameGroup = function (obj) {
|
||||
floorMsgGroup.style.color = obj.globalAttribute.floorChangingTextColor;
|
||||
// musicBtn
|
||||
if (core.domStyle.isVertical || core.domStyle.scale < 1) {
|
||||
core.dom.musicBtn.style.right = core.dom.musicBtn.style.height = "3px";
|
||||
core.dom.musicBtn.style.right = core.dom.musicBtn.style.bottom = "3px";
|
||||
}
|
||||
else {
|
||||
core.dom.musicBtn.style.right = (obj.clientWidth - totalWidth) / 2 + "px";
|
||||
@ -2522,7 +2579,7 @@ control.prototype._resize_statusBar = function (obj) {
|
||||
}
|
||||
else {
|
||||
statusBar.style.width = obj.BAR_WIDTH * core.domStyle.scale + "px";
|
||||
statusBar.style.height = obj.outerSize - 3 + "px";
|
||||
statusBar.style.height = obj.outerSize + "px";
|
||||
statusBar.style.background = obj.globalAttribute.statusLeftBackground;
|
||||
// --- 计算文字大小
|
||||
statusBar.style.fontSize = 16 * Math.min(1, (core.__HALF_SIZE__ + 3) / obj.count) * core.domStyle.scale + "px";
|
||||
@ -2530,6 +2587,7 @@ control.prototype._resize_statusBar = function (obj) {
|
||||
statusBar.style.display = 'block';
|
||||
statusBar.style.borderTop = statusBar.style.borderLeft = obj.border;
|
||||
statusBar.style.borderRight = core.domStyle.isVertical ? obj.border : '';
|
||||
statusBar.style.borderBottom = core.domStyle.isVertical ? '' : obj.border;
|
||||
// 自绘状态栏
|
||||
if (core.domStyle.isVertical) {
|
||||
core.dom.statusCanvas.style.width = obj.outerSize - 6 + "px";
|
||||
@ -2585,13 +2643,13 @@ control.prototype._resize_toolBar = function (obj) {
|
||||
toolBar.style.background = 'transparent';
|
||||
}
|
||||
toolBar.style.display = 'block';
|
||||
toolBar.style.borderLeft = toolBar.style.borderBottom = obj.border;
|
||||
toolBar.style.borderRight = core.domStyle.isVertical ? obj.border : '';
|
||||
toolBar.style.borderLeft = obj.border;
|
||||
toolBar.style.borderRight = toolBar.style.borderBottom = core.domStyle.isVertical ? obj.border : '';
|
||||
toolBar.style.fontSize = 16 * core.domStyle.scale + "px";
|
||||
}
|
||||
|
||||
control.prototype._resize_tools = function (obj) {
|
||||
var toolsHeight = 32 * core.domStyle.scale * (core.domStyle.isVertical ? 0.95 : 1);
|
||||
var toolsHeight = 32 * core.domStyle.scale * (core.domStyle.isVertical && !obj.is15x15 ? 0.95 : 1);
|
||||
var toolsMarginLeft;
|
||||
if (core.domStyle.isVertical)
|
||||
toolsMarginLeft = (core.__HALF_SIZE__ - 3) * 3 * core.domStyle.scale;
|
||||
|
||||
24
libs/core.js
24
libs/core.js
@ -16,8 +16,7 @@ function core() {
|
||||
'ground': null,
|
||||
'items': {},
|
||||
'enemys': {},
|
||||
'icons': {},
|
||||
'events': {}
|
||||
'icons': {}
|
||||
}
|
||||
this.timeout = {
|
||||
'tipTimeout': null,
|
||||
@ -67,6 +66,7 @@ function core() {
|
||||
'isPC': true, // 是否是PC
|
||||
'isAndroid': false, // 是否是Android
|
||||
'isIOS': false, // 是否是iOS
|
||||
'string': 'PC',
|
||||
'isWeChat': false, // 是否是微信
|
||||
'isQQ': false, // 是否是QQ
|
||||
'isChrome': false, // 是否是Chrome
|
||||
@ -83,8 +83,8 @@ function core() {
|
||||
this.domStyle = {
|
||||
scale: 1.0,
|
||||
isVertical: false,
|
||||
toolbarBtn: false,
|
||||
showStatusBar: true,
|
||||
toolbarBtn: false,
|
||||
}
|
||||
this.bigmap = {
|
||||
canvas: ["bg", "event", "event2", "fg", "damage"],
|
||||
@ -102,7 +102,9 @@ function core() {
|
||||
"data": null,
|
||||
"time": 0,
|
||||
"updated": false,
|
||||
}
|
||||
},
|
||||
"favorite": [],
|
||||
"favoriteName": {}
|
||||
}
|
||||
this.initStatus = {
|
||||
'played': false,
|
||||
@ -217,6 +219,7 @@ core.prototype.init = function (coreData, callback) {
|
||||
this._init_flags();
|
||||
this._init_platform();
|
||||
this._init_others();
|
||||
this._initPlugins();
|
||||
|
||||
core.loader._load(function () {
|
||||
core._afterLoadResources(callback);
|
||||
@ -272,6 +275,7 @@ core.prototype._init_platform = function () {
|
||||
core.platform.isPC = false;
|
||||
}
|
||||
});
|
||||
core.platform.string = core.platform.isPC ? "PC" : core.platform.isAndroid ? "Android" : core.platform.isIOS ? "iOS" : "";
|
||||
core.platform.supportCopy = document.queryCommandSupported || document.queryCommandSupported("copy");
|
||||
var chrome = /Chrome\/(\d+)\./i.exec(navigator.userAgent);
|
||||
if (chrome && parseInt(chrome[1]) >= 50) core.platform.isChrome = true;
|
||||
@ -293,7 +297,7 @@ core.prototype._init_platform = function () {
|
||||
}
|
||||
|
||||
core.prototype._init_checkLocalForage = function () {
|
||||
core.platform.useLocalForage = core.getLocalStorage('useLocalForage', !core.platform.isIOS);
|
||||
core.platform.useLocalForage = core.getLocalStorage('useLocalForage', true);
|
||||
var _error = function (e) {
|
||||
main.log(e);
|
||||
core.platform.useLocalForage = false;
|
||||
@ -338,9 +342,10 @@ core.prototype._init_others = function () {
|
||||
|
||||
core.prototype._afterLoadResources = function (callback) {
|
||||
// 初始化地图
|
||||
core.initStatus.maps = core.maps.initMaps(core.floorIds);
|
||||
core.initStatus.maps = core.maps._initMaps();
|
||||
core.control._setRequestAnimationFrame();
|
||||
core._initPlugins();
|
||||
if (core.plugin._afterLoadResources)
|
||||
core.plugin._afterLoadResources();
|
||||
core.showStartAnimate();
|
||||
if (callback) callback();
|
||||
}
|
||||
@ -382,13 +387,16 @@ core.prototype._forwardFunc = function (name, funcname) {
|
||||
}
|
||||
|
||||
if (core[funcname]) {
|
||||
console.error("ERROR: Cannot forward function " + funcname + " from " + name + "!");
|
||||
console.error("ERROR: 无法转发 "+name+" 中的函数 "+funcname+" 到 core 中!同名函数已存在。");
|
||||
return;
|
||||
}
|
||||
var parameterInfo = /^\s*function\s*[\w_$]*\(([\w_,$\s]*)\)\s*\{/.exec(core[name][funcname].toString());
|
||||
var parameters = (parameterInfo == null ? "" : parameterInfo[1]).replace(/\s*/g, '').replace(/,/g, ', ');
|
||||
// core[funcname] = new Function(parameters, "return core."+name+"."+funcname+"("+parameters+");");
|
||||
eval("core." + funcname + " = function (" + parameters + ") {\n\treturn core." + name + "." + funcname + "(" + parameters + ");\n}");
|
||||
if (name == 'plugin') {
|
||||
main.log("插件函数转发:core."+funcname+" = core.plugin."+funcname);
|
||||
}
|
||||
}
|
||||
|
||||
core.prototype.doFunc = function (func, _this) {
|
||||
|
||||
@ -107,13 +107,13 @@ enemys.prototype.canBattle = function (enemy, x, y, floorId) {
|
||||
////// 获得某个怪物的伤害 //////
|
||||
enemys.prototype.getDamage = function (enemy, x, y, floorId) {
|
||||
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
|
||||
var damage = this.calDamage(enemy, null, x, y, floorId);
|
||||
var damage = this._calDamage(enemy, null, x, y, floorId);
|
||||
if (damage == null) return null;
|
||||
return damage + this.getExtraDamage(enemy);
|
||||
return damage + this.getExtraDamage(enemy, x, y, floorId);
|
||||
}
|
||||
|
||||
////// 获得某个怪物的额外伤害 //////
|
||||
enemys.prototype.getExtraDamage = function (enemy) {
|
||||
enemys.prototype.getExtraDamage = function (enemy, x, y, floorId) {
|
||||
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
|
||||
var extra_damage = 0;
|
||||
if (this.hasSpecial(enemy.special, 17)) { // 仇恨
|
||||
@ -265,8 +265,8 @@ enemys.prototype._nextCriticals_useTurn = function (enemy, info, number, x, y, f
|
||||
enemys.prototype.getDefDamage = function (enemy, k, x, y, floorId) {
|
||||
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
|
||||
k = k || 1;
|
||||
var nowDamage = this.calDamage(enemy, null, x, y, floorId);
|
||||
var nextDamage = this.calDamage(enemy, {"def": core.status.hero.def + k}, x, y, floorId);
|
||||
var nowDamage = this._calDamage(enemy, null, x, y, floorId);
|
||||
var nextDamage = this._calDamage(enemy, {"def": core.status.hero.def + k}, x, y, floorId);
|
||||
if (nowDamage == null || nextDamage == null) return "???";
|
||||
return nowDamage - nextDamage;
|
||||
}
|
||||
@ -284,7 +284,7 @@ enemys.prototype.getDamageInfo = function (enemy, hero, x, y, floorId) {
|
||||
}
|
||||
|
||||
////// 获得在某个勇士属性下怪物伤害 //////
|
||||
enemys.prototype.calDamage = function (enemy, hero, x, y, floorId) {
|
||||
enemys.prototype._calDamage = function (enemy, hero, x, y, floorId) {
|
||||
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
|
||||
|
||||
var info = this.getDamageInfo(enemy, hero, x, y, floorId);
|
||||
@ -358,3 +358,9 @@ enemys.prototype._getCurrentEnemys_sort = function (enemys) {
|
||||
return a.damage - b.damage;
|
||||
});
|
||||
}
|
||||
|
||||
enemys.prototype.hasEnemyLeft = function (enemyId, floorId) {
|
||||
return core.getCurrentEnemys(floorId).filter(function (enemy) {
|
||||
return enemyId == null || enemy.id == enemyId;
|
||||
}).length > 0;
|
||||
}
|
||||
279
libs/events.js
279
libs/events.js
@ -52,9 +52,6 @@ events.prototype._startGame_start = function (hard, seed, route, callback) {
|
||||
}
|
||||
else core.utils.__init_seed();
|
||||
this.setInitData();
|
||||
|
||||
core.clearMap('all');
|
||||
core.deleteAllCanvas();
|
||||
core.clearStatusBar();
|
||||
|
||||
var todo = [];
|
||||
@ -73,7 +70,7 @@ events.prototype._startGame_start = function (hard, seed, route, callback) {
|
||||
|
||||
events.prototype._startGame_afterStart = function (nowLoc, callback) {
|
||||
core.ui.closePanel();
|
||||
core.showStatusBar();
|
||||
this._startGame_statusBar();
|
||||
core.dom.musicBtn.style.display = 'none';
|
||||
core.changeFloor(core.firstData.floorId, null, nowLoc, null, function () {
|
||||
// 插入一个空事件避免直接回放录像出错
|
||||
@ -83,13 +80,21 @@ events.prototype._startGame_afterStart = function (nowLoc, callback) {
|
||||
this._startGame_upload();
|
||||
}
|
||||
|
||||
// 开始游戏时是否显示状态栏
|
||||
events.prototype._startGame_statusBar = function () {
|
||||
if (core.flags.startUsingCanvas)
|
||||
core.hideStatusBar();
|
||||
else
|
||||
core.showStatusBar();
|
||||
}
|
||||
|
||||
events.prototype._startGame_upload = function () {
|
||||
// Upload
|
||||
var formData = new FormData();
|
||||
formData.append('type', 'people');
|
||||
formData.append('name', core.firstData.name);
|
||||
formData.append('version', core.firstData.version);
|
||||
formData.append('platform', core.platform.isPC ? "PC" : core.platform.isAndroid ? "Android" : core.platform.isIOS ? "iOS" : "");
|
||||
formData.append('platform', core.platform.string);
|
||||
formData.append('hard', core.encodeBase64(core.status.hard));
|
||||
formData.append('hardCode', core.getFlag('hard', 0));
|
||||
formData.append('base64', 1);
|
||||
@ -171,7 +176,7 @@ events.prototype._gameOver_doUpload = function (username, ending, norank) {
|
||||
formData.append('type', 'score');
|
||||
formData.append('name', core.firstData.name);
|
||||
formData.append('version', core.firstData.version);
|
||||
formData.append('platform', core.platform.isPC ? "PC" : core.platform.isAndroid ? "Android" : core.platform.isIOS ? "iOS" : "");
|
||||
formData.append('platform', core.platform.string);
|
||||
formData.append('hard', core.encodeBase64(core.status.hard));
|
||||
formData.append('username', core.encodeBase64(username || ""));
|
||||
formData.append('ending', core.encodeBase64(ending));
|
||||
@ -183,7 +188,7 @@ events.prototype._gameOver_doUpload = function (username, ending, norank) {
|
||||
formData.append('money', core.status.hero.money);
|
||||
formData.append('experience', core.status.hero.experience);
|
||||
formData.append('steps', core.status.hero.steps);
|
||||
formData.append('norank', norank || 0);
|
||||
formData.append('norank', norank ? 1 : 0);
|
||||
formData.append('seed', core.getFlag('__seed__'));
|
||||
formData.append('totalTime', Math.floor(core.status.hero.statistics.totalTime / 1000));
|
||||
formData.append('route', core.encodeRoute(core.status.route));
|
||||
@ -234,6 +239,23 @@ events.prototype._gameOver_askRate = function (ending) {
|
||||
});
|
||||
}
|
||||
|
||||
////// 重新开始游戏;此函数将回到标题页面 //////
|
||||
events.prototype.restart = function() {
|
||||
core.showStartAnimate();
|
||||
core.playBgm(main.startBgm);
|
||||
}
|
||||
|
||||
////// 询问是否需要重新开始 //////
|
||||
events.prototype.confirmRestart = function () {
|
||||
core.status.event.selection = 1;
|
||||
core.ui.drawConfirmBox("你确定要返回标题页面吗?", function () {
|
||||
core.ui.closePanel();
|
||||
core.restart();
|
||||
}, function () {
|
||||
core.ui.closePanel();
|
||||
});
|
||||
}
|
||||
|
||||
// ------ 系统事件的处理 ------ //
|
||||
|
||||
////// 注册一个系统事件 //////
|
||||
@ -279,10 +301,7 @@ events.prototype._trigger = function (x, y) {
|
||||
if (trigger == 'changeFloor' && !noPass && this._trigger_ignoreChangeFloor(block))
|
||||
return;
|
||||
core.status.automaticRoute.moveDirectly = false;
|
||||
this.doSystemEvent(trigger, block, function () {
|
||||
if (trigger == 'openDoor' || trigger == 'changeFloor')
|
||||
core.replay();
|
||||
})
|
||||
this.doSystemEvent(trigger, block);
|
||||
}
|
||||
}
|
||||
|
||||
@ -341,16 +360,20 @@ events.prototype.afterBattle = function (enemyId, x, y, callback) {
|
||||
}
|
||||
|
||||
events.prototype._sys_openDoor = function (data, callback) {
|
||||
this.openDoor(data.event.id, data.x, data.y, true, callback);
|
||||
this.openDoor(data.x, data.y, true, function () {
|
||||
core.replay();
|
||||
if (callback) callback();
|
||||
});
|
||||
}
|
||||
|
||||
////// 开门 //////
|
||||
events.prototype.openDoor = function (id, x, y, needKey, callback) {
|
||||
id = id || core.getBlockId(x, y);
|
||||
events.prototype.openDoor = function (x, y, needKey, callback) {
|
||||
var id = core.getBlockId(x, y);
|
||||
core.saveAndStopAutomaticRoute();
|
||||
if (!this._openDoor_check(id, x, y, needKey)) {
|
||||
var locked = core.status.lockControl;
|
||||
core.waitHeroToStop(function () {
|
||||
core.unLockControl();
|
||||
if (!locked) core.unLockControl();
|
||||
if (callback) callback();
|
||||
});
|
||||
return;
|
||||
@ -362,11 +385,14 @@ events.prototype.openDoor = function (id, x, y, needKey, callback) {
|
||||
events.prototype._openDoor_check = function (id, x, y, needKey) {
|
||||
// 是否存在门或暗墙
|
||||
if (!core.terrainExists(x, y, id) || !(id.endsWith("Door") || id.endsWith("Wall"))
|
||||
|| !core.material.icons.animates[id]) {
|
||||
|| core.material.icons.animates[id] == null) {
|
||||
core.clearContinueAutomaticRoute();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (id == 'steelDoor' && core.flags.steelDoorWithoutKey)
|
||||
needKey = false;
|
||||
|
||||
if (needKey && id.endsWith("Door")) {
|
||||
var key = id.replace("Door", "Key");
|
||||
if (!core.hasItem(key)) {
|
||||
@ -376,7 +402,7 @@ events.prototype._openDoor_check = function (id, x, y, needKey) {
|
||||
core.clearContinueAutomaticRoute();
|
||||
return false;
|
||||
}
|
||||
core.autosave(true);
|
||||
if (!core.status.event.id) core.autosave(true);
|
||||
core.removeItem(key);
|
||||
}
|
||||
return true;
|
||||
@ -386,6 +412,7 @@ events.prototype._openDoor_animate = function (id, x, y, callback) {
|
||||
var door = core.material.icons.animates[id];
|
||||
var speed = id.endsWith("Door") ? 30 : 70;
|
||||
|
||||
var locked = core.status.lockControl;
|
||||
core.lockControl();
|
||||
core.status.replay.animate = true;
|
||||
var state = 0;
|
||||
@ -394,7 +421,7 @@ events.prototype._openDoor_animate = function (id, x, y, callback) {
|
||||
if (state == 4) {
|
||||
clearInterval(animate);
|
||||
core.removeBlock(x, y);
|
||||
core.unLockControl();
|
||||
if (!locked) core.unLockControl();
|
||||
core.status.replay.animate = false;
|
||||
core.events.afterOpenDoor(id, x, y, callback);
|
||||
return;
|
||||
@ -414,29 +441,34 @@ events.prototype._sys_getItem = function (data, callback) {
|
||||
}
|
||||
|
||||
////// 获得某个物品 //////
|
||||
events.prototype.getItem = function (itemId, itemNum, itemX, itemY, callback) {
|
||||
itemNum = itemNum || 1;
|
||||
var itemCls = core.material.items[itemId].cls;
|
||||
core.items.getItemEffect(itemId, itemNum);
|
||||
core.removeBlock(itemX, itemY);
|
||||
var text = '获得 ' + core.material.items[itemId].name;
|
||||
if (itemNum > 1) text += "x" + itemNum;
|
||||
if (itemCls === 'items') text += core.items.getItemEffectTip(itemId);
|
||||
core.drawTip(text, core.material.icons.items[itemId]);
|
||||
events.prototype.getItem = function (id, num, x, y, callback) {
|
||||
if (num == null) num = 1;
|
||||
num = num || 1;
|
||||
var itemCls = core.material.items[id].cls;
|
||||
core.items.getItemEffect(id, num);
|
||||
core.removeBlock(x, y);
|
||||
var text = '获得 ' + core.material.items[id].name;
|
||||
if (num > 1) text += "x" + num;
|
||||
if (itemCls === 'items') text += core.items.getItemEffectTip(id);
|
||||
core.drawTip(text, id);
|
||||
core.updateStatusBar();
|
||||
|
||||
this.eventdata.afterGetItem(itemId, itemX, itemY, callback);
|
||||
this.afterGetItem(id, x, y, callback);
|
||||
}
|
||||
|
||||
events.prototype.afterGetItem = function (id, x, y, callback) {
|
||||
this.eventdata.afterGetItem(id, x, y, callback);
|
||||
}
|
||||
|
||||
////// 获得面前的物品(轻按) //////
|
||||
events.prototype.getNextItem = function () {
|
||||
events.prototype.getNextItem = function (noRoute) {
|
||||
if (core.isMoving() || !core.canMoveHero() || !core.flags.enableGentleClick) return false;
|
||||
|
||||
var nextX = core.nextX(), nextY = core.nextY();
|
||||
var block = core.getBlock(nextX, nextY);
|
||||
if (block == null) return false;
|
||||
if (block.block.event.trigger == 'getItem') {
|
||||
core.status.route.push("getNext");
|
||||
if (!noRoute) core.status.route.push("getNext");
|
||||
this.getItem(block.block.event.id, 1, nextX, nextY);
|
||||
return true;
|
||||
}
|
||||
@ -449,7 +481,10 @@ events.prototype._sys_changeFloor = function (data, callback) {
|
||||
if (data.loc) heroLoc = {'x': data.loc[0], 'y': data.loc[1]};
|
||||
if (data.direction) heroLoc.direction = data.direction;
|
||||
if (core.status.event.id != 'action') core.status.event.id = null;
|
||||
core.changeFloor(data.floorId, data.stair, heroLoc, data.time, callback);
|
||||
core.changeFloor(data.floorId, data.stair, heroLoc, data.time, function () {
|
||||
core.replay();
|
||||
if (callback) callback();
|
||||
});
|
||||
}
|
||||
|
||||
////// 楼层切换 //////
|
||||
@ -461,6 +496,7 @@ events.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback
|
||||
}
|
||||
info.fromLoad = fromLoad;
|
||||
floorId = info.floorId;
|
||||
info.locked = core.status.lockControl;
|
||||
|
||||
core.dom.floorNameLabel.innerHTML = core.status.maps[floorId].title;
|
||||
core.lockControl();
|
||||
@ -535,7 +571,7 @@ events.prototype._changeFloor_beforeChange = function (info, callback) {
|
||||
if (info.time == 0)
|
||||
core.events._changeFloor_changing(info, callback);
|
||||
else
|
||||
core.show(core.dom.floorMsgGroup, info.time / 2, function () {
|
||||
core.showWithAnimate(core.dom.floorMsgGroup, info.time / 2, function () {
|
||||
core.events._changeFloor_changing(info, callback);
|
||||
});
|
||||
}, 25)
|
||||
@ -547,13 +583,13 @@ events.prototype._changeFloor_changing = function (info, callback) {
|
||||
if (info.time == 0)
|
||||
this._changeFloor_afterChange(info, callback);
|
||||
else
|
||||
core.hide(core.dom.floorMsgGroup, info.time / 4, function () {
|
||||
core.hideWithAnimate(core.dom.floorMsgGroup, info.time / 4, function () {
|
||||
core.events._changeFloor_afterChange(info, callback);
|
||||
});
|
||||
}
|
||||
|
||||
events.prototype._changeFloor_afterChange = function (info, callback) {
|
||||
core.unLockControl();
|
||||
if (!info.locked) core.unLockControl();
|
||||
core.status.replay.animate = false;
|
||||
core.events.afterChangeFloor(info.floorId, info.fromLoad);
|
||||
|
||||
@ -661,11 +697,6 @@ events.prototype._sys_changeLight = function (data, callback) {
|
||||
events.prototype.changeLight = function (id, x, y) {
|
||||
if (id != null && id != 'light') return;
|
||||
core.setBlock(core.getNumberById('darkLight'), x, y);
|
||||
this.afterChangeLight(x, y);
|
||||
}
|
||||
|
||||
////// 改变亮灯之后,可以触发的事件 //////
|
||||
events.prototype.afterChangeLight = function (x, y) {
|
||||
return this.eventdata.afterChangeLight(x, y);
|
||||
}
|
||||
|
||||
@ -724,8 +755,19 @@ events.prototype.doEvent = function (data, x, y, prefix) {
|
||||
core.doAction();
|
||||
}
|
||||
|
||||
events.prototype.setEvents = function (list, x, y, callback) {
|
||||
var data = core.status.event.data || {};
|
||||
if (list)
|
||||
data.list = [{todo: core.clone(list), total: core.clone(list), condition: "false"}];
|
||||
if (x != null) data.x = x;
|
||||
if (y != null) data.y = y;
|
||||
if (callback) data.callback = callback;
|
||||
core.status.event.id = 'action';
|
||||
core.status.event.data = data;
|
||||
}
|
||||
|
||||
////// 开始执行一系列自定义事件 //////
|
||||
events.prototype.doEvents = function (list, x, y, callback) {
|
||||
events.prototype.startEvents = function (list, x, y, callback) {
|
||||
if (!list) return;
|
||||
if (!(list instanceof Array)) {
|
||||
list = [list];
|
||||
@ -738,24 +780,12 @@ events.prototype.doEvents = function (list, x, y, callback) {
|
||||
});
|
||||
}
|
||||
|
||||
events.prototype.setEvents = function (list, x, y, callback) {
|
||||
var data = core.status.event.data || {};
|
||||
if (list)
|
||||
data.list = [{todo: core.clone(list), total: core.clone(list), condition: "false"}];
|
||||
if (x != null) data.x = x;
|
||||
if (y != null) data.y = y;
|
||||
if (callback) data.callback = callback;
|
||||
core.status.event.id = 'action';
|
||||
core.status.event.data = data;
|
||||
}
|
||||
|
||||
////// 执行当前自定义事件列表中的下一个事件 //////
|
||||
events.prototype.doAction = function () {
|
||||
// 清空boxAnimate和UI层
|
||||
core.status.boxAnimateObjs = [];
|
||||
core.clearUI();
|
||||
clearInterval(core.status.event.interval);
|
||||
core.status.event.interval = null;
|
||||
core.clearSelector();
|
||||
// 判定是否执行完毕
|
||||
if (this._doAction_finishEvents()) return;
|
||||
// 当前点坐标和前缀
|
||||
@ -799,7 +829,7 @@ events.prototype._popEvents = function (current, prefix) {
|
||||
return false;
|
||||
}
|
||||
|
||||
////// 往当前事件列表之前添加一个或多个事件 //////
|
||||
////// 往当前事件列表之前或之后添加一个或多个事件 //////
|
||||
events.prototype.insertAction = function (action, x, y, callback, addToLast) {
|
||||
if (core.hasFlag("__statistics__")) return;
|
||||
if (core.status.gameOver) return;
|
||||
@ -810,7 +840,7 @@ events.prototype.insertAction = function (action, x, y, callback, addToLast) {
|
||||
if (!action) return;
|
||||
|
||||
if (core.status.event.id != 'action') {
|
||||
this.doEvents(action, x, y, callback);
|
||||
this.startEvents(action, x, y, callback);
|
||||
}
|
||||
else {
|
||||
if (addToLast)
|
||||
@ -1022,10 +1052,7 @@ events.prototype._action_jumpHero = function (data, x, y, prefix) {
|
||||
events.prototype._action_changeFloor = function (data, x, y, prefix) {
|
||||
var loc = this.__action_getHeroLoc(data.loc, prefix);
|
||||
var heroLoc = {x: loc[0], y: loc[1], direction: data.direction};
|
||||
core.changeFloor(data.floorId || core.status.floorId, null, heroLoc, data.time, function () {
|
||||
core.lockControl();
|
||||
core.doAction();
|
||||
});
|
||||
core.changeFloor(data.floorId || core.status.floorId, null, heroLoc, data.time, core.doAction);
|
||||
}
|
||||
|
||||
events.prototype._action_changePos = function (data, x, y, prefix) {
|
||||
@ -1068,13 +1095,17 @@ events.prototype._action_moveImage = function (data, x, y, prefix) {
|
||||
}
|
||||
|
||||
events.prototype._action_setFg = function (data, x, y, prefix) {
|
||||
return this._action_setCurtain(data, x, y, prefix);
|
||||
}
|
||||
|
||||
events.prototype._action_setCurtain = function (data, x, y, prefix) {
|
||||
if (data.async) {
|
||||
core.setFg(data.color, data.time);
|
||||
core.setCurtain(data.color, data.time);
|
||||
core.setFlag('__color__', data.color || null);
|
||||
core.doAction();
|
||||
}
|
||||
else {
|
||||
core.setFg(data.color, data.time, function () {
|
||||
core.setCurtain(data.color, data.time, function () {
|
||||
core.setFlag('__color__', data.color || null);
|
||||
core.doAction();
|
||||
});
|
||||
@ -1097,10 +1128,7 @@ events.prototype._action_openDoor = function (data, x, y, prefix) {
|
||||
var loc = this.__action_getLoc(data.loc, x, y, prefix);
|
||||
var floorId = data.floorId || core.status.floorId;
|
||||
if (floorId == core.status.floorId) {
|
||||
core.openDoor(null, loc[0], loc[1], data.needKey, function () {
|
||||
core.lockControl();
|
||||
core.doAction();
|
||||
});
|
||||
core.openDoor(loc[0], loc[1], data.needKey, core.doAction);
|
||||
}
|
||||
else {
|
||||
core.removeBlock(loc[0], loc[1], floorId);
|
||||
@ -1125,13 +1153,12 @@ events.prototype._action_useItem = function (data, x, y, prefix) {
|
||||
}
|
||||
|
||||
events.prototype._action_openShop = function (data, x, y, prefix) {
|
||||
if (core.isReplaying()) { // 正在播放录像,简单将visited置为true
|
||||
core.status.shops[data.id].visited = true;
|
||||
this.setEvents([]);
|
||||
core.doAction();
|
||||
}
|
||||
else
|
||||
if (!core.isReplaying())
|
||||
this.openShop(data.id);
|
||||
if (core.status.event.id == 'action')
|
||||
core.doAction();
|
||||
}
|
||||
|
||||
events.prototype._action_disableShop = function (data, x, y, prefix) {
|
||||
@ -1149,14 +1176,10 @@ events.prototype._action_trigger = function (data, x, y, prefix) {
|
||||
if (block != null && block.block.event.trigger) {
|
||||
block = block.block;
|
||||
this.setEvents([], block.x, block.y);
|
||||
var _callback = function () {
|
||||
core.lockControl();
|
||||
core.doAction();
|
||||
}
|
||||
if (block.event.trigger == 'action')
|
||||
this.setEvents(block.event.data);
|
||||
else {
|
||||
core.doSystemEvent(block.event.trigger, block, _callback);
|
||||
core.doSystemEvent(block.event.trigger, block, core.doAction);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1175,7 +1198,7 @@ events.prototype._action_insert = function (data, x, y, prefix) {
|
||||
}
|
||||
if (data.name) { // 公共事件
|
||||
core.setFlag('arg0', data.name);
|
||||
core.insertAction(this.getCommonEvent(data.name));
|
||||
core.insertAction(data.name);
|
||||
}
|
||||
else {
|
||||
var loc = this.__action_getLoc(data.loc, x, y, prefix);
|
||||
@ -1214,6 +1237,7 @@ events.prototype._action_freeBgm = function (data, x, y, prefix) {
|
||||
}
|
||||
|
||||
events.prototype._action_playSound = function (data, x, y, prefix) {
|
||||
if (data.stop) core.stopSound();
|
||||
core.playSound(data.name);
|
||||
core.doAction();
|
||||
}
|
||||
@ -1319,13 +1343,16 @@ events.prototype._action_if = function (data, x, y, prefix) {
|
||||
|
||||
events.prototype._action_switch = function (data, x, y, prefix) {
|
||||
var key = core.calValue(data.condition, prefix)
|
||||
var list = [];
|
||||
for (var i = 0; i < data.caseList.length; i++) {
|
||||
var condition = data.caseList[i]["case"];
|
||||
if (condition == "default" || core.calValue(condition, prefix) == key) {
|
||||
this.insertAction(data.caseList[i].action);
|
||||
core.push(list, data.caseList[i].action);
|
||||
if (!data.caseList[i].nobreak)
|
||||
break;
|
||||
}
|
||||
}
|
||||
core.insertAction(list);
|
||||
core.doAction();
|
||||
}
|
||||
|
||||
@ -1353,6 +1380,35 @@ events.prototype._action_choices = function (data, x, y, prefix) {
|
||||
core.ui.drawChoices(data.text, data.choices);
|
||||
}
|
||||
|
||||
events.prototype._action_confirm = function (data, x, y, prefix) {
|
||||
core.status.event.ui = {"text": data.text, "yes": data.yes, "no": data.no};
|
||||
if (core.isReplaying()) {
|
||||
var action = core.status.replay.toReplay.shift(), index;
|
||||
// --- 忽略可能的turn事件
|
||||
if (action == 'turn') action = core.status.replay.toReplay.shift();
|
||||
if (action.indexOf("choices:") == 0 && ((index = parseInt(action.substring(8))) >= 0) && index < 2) {
|
||||
core.status.event.selection = index;
|
||||
setTimeout(function () {
|
||||
core.status.route.push("choices:" + index);
|
||||
if (index == 0) core.insertAction(data.yes);
|
||||
else core.insertAction(data.no);
|
||||
core.doAction();
|
||||
}, 750 / Math.max(1, core.status.replay.speed))
|
||||
}
|
||||
else {
|
||||
main.log("录像文件出错!当前需要一个 choices: 项,实际为 " + action);
|
||||
core.stopReplay();
|
||||
core.insertAction(["录像文件出错,请在控制台查看报错信息。", {"type": "exit"}]);
|
||||
core.doAction();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
core.status.event.selection = data["default"] ? 0 : 1;
|
||||
}
|
||||
core.ui.drawConfirmBox(data.text);
|
||||
}
|
||||
|
||||
events.prototype._action_while = function (data, x, y, prefix) {
|
||||
if (core.calValue(data.condition, prefix)) {
|
||||
core.unshift(core.status.event.data.list,
|
||||
@ -1362,6 +1418,13 @@ events.prototype._action_while = function (data, x, y, prefix) {
|
||||
core.doAction();
|
||||
}
|
||||
|
||||
events.prototype._action_dowhile = function (data, x, y, prefix) {
|
||||
core.unshift(core.status.event.data.list,
|
||||
{"todo": core.clone(data.data), "total": core.clone(data.data), "condition": data.condition}
|
||||
);
|
||||
core.doAction();
|
||||
}
|
||||
|
||||
events.prototype._action_break = function (data, x, y, prefix) {
|
||||
core.status.event.data.list.shift();
|
||||
core.doAction();
|
||||
@ -1473,7 +1536,7 @@ events.prototype.__action_wait_getValue = function (value) {
|
||||
|
||||
events.prototype._action_waitAsync = function (data, x, y, prefix) {
|
||||
var test = window.setInterval(function () {
|
||||
if (Object.keys(core.animateFrame.asyncId).length == 0) {
|
||||
if (!core.hasAsync()) {
|
||||
clearInterval(test);
|
||||
core.doAction();
|
||||
}
|
||||
@ -1642,7 +1705,6 @@ events.prototype.load = function (fromUserAction) {
|
||||
core.dom.startPanel.style.display = 'none';
|
||||
core.clearStatus();
|
||||
core.clearMap('all');
|
||||
core.deleteAllCanvas();
|
||||
core.status.event = {'id': 'load', 'data': null};
|
||||
core.status.lockControl = true;
|
||||
core.ui.drawSLPanel(10*page+offset);
|
||||
@ -1664,12 +1726,16 @@ events.prototype.openSettings = function (fromUserAction) {
|
||||
|
||||
// ------ 一些事件的具体执行过程 ------ //
|
||||
|
||||
events.prototype.hasAsync = function () {
|
||||
return Object.keys(core.animateFrame.asyncId).length > 0 || (core.status.animateObjs || []).length > 0;
|
||||
}
|
||||
|
||||
////// 跟随 //////
|
||||
events.prototype.follow = function (name) {
|
||||
core.status.hero.followers = core.status.hero.followers || [];
|
||||
if (core.material.images.images[name]
|
||||
&& core.material.images.images[name].width == 128) {
|
||||
core.status.hero.followers.push({"name": name, "img": core.material.images.images[name]});
|
||||
core.status.hero.followers.push({"name": name});
|
||||
core.gatherFollowers();
|
||||
core.clearMap('hero');
|
||||
core.drawHero();
|
||||
@ -1695,24 +1761,6 @@ events.prototype.unfollow = function (name) {
|
||||
core.drawHero();
|
||||
}
|
||||
|
||||
////// 绘制或取消一张gif图片 //////
|
||||
events.prototype.showGif = function (name, x, y) {
|
||||
var image = core.material.images.images[name];
|
||||
if (image) {
|
||||
var gif = new Image();
|
||||
gif.src = image.src;
|
||||
gif.style.position = 'absolute';
|
||||
gif.style.left = x * core.domStyle.scale + "px";
|
||||
gif.style.top = y * core.domStyle.scale + "px";
|
||||
gif.style.width = image.width * core.domStyle.scale + "px";
|
||||
gif.style.height = image.height * core.domStyle.scale + "px";
|
||||
core.dom.gif2.appendChild(gif);
|
||||
}
|
||||
else {
|
||||
core.dom.gif2.innerHTML = "";
|
||||
}
|
||||
}
|
||||
|
||||
////// 数值操作 //////
|
||||
events.prototype.setValue = function (name, value, prefix, add) {
|
||||
var value = core.calValue(value, prefix);
|
||||
@ -1916,6 +1964,24 @@ events.prototype._moveImage_moving = function (name, moveInfo, callback) {
|
||||
core.animateFrame.asyncId[animate] = true;
|
||||
}
|
||||
|
||||
////// 绘制或取消一张gif图片 //////
|
||||
events.prototype.showGif = function (name, x, y) {
|
||||
var image = core.material.images.images[name];
|
||||
if (image) {
|
||||
var gif = new Image();
|
||||
gif.src = image.src;
|
||||
gif.style.position = 'absolute';
|
||||
gif.style.left = x * core.domStyle.scale + "px";
|
||||
gif.style.top = y * core.domStyle.scale + "px";
|
||||
gif.style.width = image.width * core.domStyle.scale + "px";
|
||||
gif.style.height = image.height * core.domStyle.scale + "px";
|
||||
core.dom.gif2.appendChild(gif);
|
||||
}
|
||||
else {
|
||||
core.dom.gif2.innerHTML = "";
|
||||
}
|
||||
}
|
||||
|
||||
////// 淡入淡出音乐 //////
|
||||
events.prototype.setVolume = function (value, time, callback) {
|
||||
var set = function (value) {
|
||||
@ -2037,7 +2103,7 @@ events.prototype.jumpHero = function (ex, ey, time, callback) {
|
||||
var sx=core.status.hero.loc.x, sy=core.status.hero.loc.y;
|
||||
if (!core.isset(ex)) ex=sx;
|
||||
if (!core.isset(ey)) ey=sy;
|
||||
core.maps.__playJumpSound();
|
||||
core.playSound('jump.mp3');
|
||||
var jumpInfo = core.maps.__generateJumpInfo(sx, sy, ex, ey, time || 500);
|
||||
jumpInfo.icon = core.material.icons.hero[core.getHeroLoc('direction')];
|
||||
jumpInfo.height = core.material.icons.hero.height;
|
||||
@ -2082,9 +2148,9 @@ events.prototype.openShop = function (shopId, needVisited) {
|
||||
shop.times = shop.times || 0;
|
||||
if (shop.commonTimes) shop.times = core.getFlag('commonTimes', 0);
|
||||
if (needVisited && !shop.visited) {
|
||||
if (!core.flags.enableDisabledShop) {
|
||||
if (shop.times == 0) core.drawTip("该商店尚未开启");
|
||||
else core.drawTip("该商店已失效");
|
||||
if (!core.flags.enableDisabledShop || shop.commonEvent) {
|
||||
if (shop.times == 0) core.drawTip("该项尚未开启");
|
||||
else core.drawTip("该项已失效");
|
||||
return;
|
||||
}
|
||||
else {
|
||||
@ -2092,6 +2158,13 @@ events.prototype.openShop = function (shopId, needVisited) {
|
||||
}
|
||||
}
|
||||
else shop.visited = true;
|
||||
|
||||
// --- 商店
|
||||
if (shop.commonEvent) {
|
||||
core.status.route.push("shop:"+shopId+":0");
|
||||
core.insertAction({"type": "insert", "name": shop.commonEvent, "args": shop.args});
|
||||
return;
|
||||
}
|
||||
core.ui.drawShop(shopId);
|
||||
}
|
||||
|
||||
@ -2199,13 +2272,13 @@ events.prototype.afterUseBomb = function () {
|
||||
}
|
||||
|
||||
////// 上传当前数据 //////
|
||||
events.prototype.uploadCurrent = function (username) {
|
||||
events.prototype._uploadCurrent = function (username) {
|
||||
var formData = new FormData();
|
||||
|
||||
formData.append('type', 'score');
|
||||
formData.append('name', core.firstData.name);
|
||||
formData.append('version', core.firstData.version);
|
||||
formData.append('platform', core.platform.isPC ? "PC" : core.platform.isAndroid ? "Android" : core.platform.isIOS ? "iOS" : "");
|
||||
formData.append('platform', core.platform.string);
|
||||
formData.append('hard', core.encodeBase64(core.status.hard));
|
||||
formData.append('username', core.encodeBase64(username || "current"));
|
||||
formData.append('lv', core.status.hero.lv);
|
||||
|
||||
@ -196,20 +196,6 @@ items.prototype.setItem = function (itemId, itemNum) {
|
||||
core.updateStatusBar();
|
||||
}
|
||||
|
||||
////// 删除某个物品 //////
|
||||
items.prototype.removeItem = function (itemId, itemNum) {
|
||||
if (itemNum == null) itemNum = 1;
|
||||
if (!core.hasItem(itemId)) return false;
|
||||
var itemCls = core.material.items[itemId].cls;
|
||||
core.status.hero.items[itemCls][itemId] -= itemNum;
|
||||
if (core.status.hero.items[itemCls][itemId] <= 0) {
|
||||
if (itemCls != 'keys') delete core.status.hero.items[itemCls][itemId];
|
||||
else core.status.hero.items[itemCls][itemId] = 0;
|
||||
}
|
||||
core.updateStatusBar();
|
||||
return true;
|
||||
}
|
||||
|
||||
////// 增加某个物品的个数 //////
|
||||
items.prototype.addItem = function (itemId, itemNum) {
|
||||
if (itemNum == null) itemNum = 1;
|
||||
@ -230,14 +216,21 @@ items.prototype.addItem = function (itemId, itemNum) {
|
||||
core.updateStatusBar();
|
||||
}
|
||||
|
||||
// ---------- 装备相关 ------------ //
|
||||
|
||||
items.prototype.getEquipTypeById = function (equipId) {
|
||||
var type = core.material.items[equipId].equip.type;
|
||||
if (typeof type == 'string')
|
||||
type = this.getEquipTypeByName(type);
|
||||
return type;
|
||||
////// 删除某个物品 //////
|
||||
items.prototype.removeItem = function (itemId, itemNum) {
|
||||
if (itemNum == null) itemNum = 1;
|
||||
if (!core.hasItem(itemId)) return false;
|
||||
var itemCls = core.material.items[itemId].cls;
|
||||
core.status.hero.items[itemCls][itemId] -= itemNum;
|
||||
if (core.status.hero.items[itemCls][itemId] <= 0) {
|
||||
if (itemCls != 'keys') delete core.status.hero.items[itemCls][itemId];
|
||||
else core.status.hero.items[itemCls][itemId] = 0;
|
||||
}
|
||||
core.updateStatusBar();
|
||||
return true;
|
||||
}
|
||||
|
||||
// ---------- 装备相关 ------------ //
|
||||
|
||||
items.prototype.getEquipTypeByName = function (name) {
|
||||
var names = core.status.globalAttribute.equipName;
|
||||
@ -249,6 +242,13 @@ items.prototype.getEquipTypeByName = function (name) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
items.prototype.getEquipTypeById = function (equipId) {
|
||||
var type = core.material.items[equipId].equip.type;
|
||||
if (typeof type == 'string')
|
||||
type = this.getEquipTypeByName(type);
|
||||
return type;
|
||||
}
|
||||
|
||||
// 当前能否撞上某装备
|
||||
items.prototype.canEquip = function (equipId, hint) {
|
||||
// 装备是否合法
|
||||
@ -311,20 +311,17 @@ items.prototype.unloadEquip = function (equipType, callback) {
|
||||
}
|
||||
|
||||
items.prototype.compareEquipment = function (compareEquipId, beComparedEquipId) {
|
||||
var compareAtk = 0, compareDef = 0, compareMdef = 0;
|
||||
if (compareEquipId) {
|
||||
var compareEquip = core.material.items[compareEquipId];
|
||||
compareAtk += (compareEquip.equip || {}).atk || 0;
|
||||
compareDef += (compareEquip.equip || {}).def || 0;
|
||||
compareMdef += (compareEquip.equip || {}).mdef || 0;
|
||||
var result = {};
|
||||
var first = core.material.items[compareEquipId], second = core.material.items[beComparedEquipId];
|
||||
for (var name in core.status.hero) {
|
||||
if (typeof core.status.hero[name] == 'number') {
|
||||
var ans = 0;
|
||||
if (first) ans += (first.equip || {})[name] || 0;
|
||||
if (second) ans -= (second.equip || {})[name] || 0;
|
||||
if (ans != 0) result[name] = ans;
|
||||
}
|
||||
if (beComparedEquipId) {
|
||||
var beComparedEquip = core.material.items[beComparedEquipId];
|
||||
compareAtk -= (beComparedEquip.equip || {}).atk || 0;
|
||||
compareDef -= (beComparedEquip.equip || {}).def || 0;
|
||||
compareMdef -= (beComparedEquip.equip || {}).mdef || 0;
|
||||
}
|
||||
return {"atk": compareAtk, "def": compareDef, "mdef": compareMdef};
|
||||
return result;
|
||||
}
|
||||
|
||||
////// 实际换装的效果 //////
|
||||
@ -349,7 +346,7 @@ items.prototype._realLoadEquip = function (type, loadId, unloadId, callback) {
|
||||
|
||||
var loadPercentage = loadEquip.equip.percentage, unloadPercentage = unloadEquip.equip.percentage;
|
||||
|
||||
if (loadPercentage != null && unloadPercentage != null && loadPercentage != unloadPercentage) {
|
||||
if (loadId && unloadId && (loadPercentage || false) != (unloadPercentage || false)) {
|
||||
this.unloadEquip(type);
|
||||
this.loadEquip(loadId);
|
||||
if (callback) callback();
|
||||
@ -368,8 +365,8 @@ items.prototype._realLoadEquip = function (type, loadId, unloadId, callback) {
|
||||
core.status.hero.equipment[type] = loadId || null;
|
||||
|
||||
// --- 提示
|
||||
if (loadId) core.drawTip("已装备上" + loadEquip.name, core.material.icons.items[loadId]);
|
||||
else if (unloadId) core.drawTip("已卸下" + unloadEquip.name, core.material.icons.items[unloadId]);
|
||||
if (loadId) core.drawTip("已装备上" + loadEquip.name, loadId);
|
||||
else if (unloadId) core.drawTip("已卸下" + unloadEquip.name, unloadId);
|
||||
|
||||
if (callback) callback();
|
||||
}
|
||||
|
||||
197
libs/maps.js
197
libs/maps.js
@ -30,11 +30,16 @@ maps.prototype.loadFloor = function (floorId, map) {
|
||||
map = {"map": map};
|
||||
}
|
||||
var content = {};
|
||||
["floorId", "title", "name", "canFlyTo", "canUseQuickShop", "cannotViewMap", "cannotMoveDirectly", "color", "weather",
|
||||
"defaultGround", "images", "item_ratio", "upFloor", "bgm", "downFloor", "underGround"].forEach(function (e) {
|
||||
if (map[e] != null) content[e] = core.clone(map[e]);
|
||||
else content[e] = core.clone(floor[e]);
|
||||
});
|
||||
var notCopy = ["firstArrive", "eachArrive", "parallelDo", "map", "bgmap", "fgmap",
|
||||
"events", "changeFloor", "afterBattle", "afterGetItem", "afterOpenDoor", "cannotMove"];
|
||||
for (var name in floor) {
|
||||
if (notCopy.indexOf(name) == -1 && floor[name] != null)
|
||||
content[name] = core.clone(floor[name]);
|
||||
}
|
||||
for (var name in map) {
|
||||
if (notCopy.indexOf(name) == -1 && map[name] != null)
|
||||
content[name] = core.clone(map[name]);
|
||||
}
|
||||
map = this.decompressMap(map.map, floorId);
|
||||
// 事件处理
|
||||
content['blocks'] = this._mapIntoBlocks(map, floor, floorId);
|
||||
@ -150,7 +155,8 @@ maps.prototype._addEvent = function (block, x, y, event) {
|
||||
}
|
||||
|
||||
////// 初始化所有地图 //////
|
||||
maps.prototype.initMaps = function (floorIds) {
|
||||
maps.prototype._initMaps = function () {
|
||||
var floorIds = core.floorIds;
|
||||
var maps = {};
|
||||
for (var i = 0; i < floorIds.length; i++) {
|
||||
var floorId = floorIds[i];
|
||||
@ -237,7 +243,7 @@ maps.prototype.saveMap = function (floorId) {
|
||||
return map;
|
||||
}
|
||||
var map = maps[floorId], floor = core.floors[floorId];
|
||||
var blocks = this.getMapArray(map.blocks, floor.width, floor.height, true);
|
||||
var blocks = this._getMapArrayFromBlocks(map.blocks, floor.width, floor.height, true);
|
||||
if (main.mode == 'editor') return blocks;
|
||||
|
||||
var thisFloor = this._compressFloorData(map, floor);
|
||||
@ -292,7 +298,13 @@ maps.prototype.resizeMap = function (floorId) {
|
||||
}
|
||||
|
||||
////// 将当前地图重新变成二维数组形式 //////
|
||||
maps.prototype.getMapArray = function (blockArray, width, height, checkDisable) {
|
||||
maps.prototype.getMapArray = function (floorId, showDisable) {
|
||||
floorId = floorId || core.status.floorId;
|
||||
return this._getMapArrayFromBlocks(core.status.maps[floorId].blocks,
|
||||
core.floors[floorId].width, core.floors[floorId].height, showDisable);
|
||||
}
|
||||
|
||||
maps.prototype._getMapArrayFromBlocks = function (blockArray, width, height, showDisable) {
|
||||
if (typeof blockArray == 'string') {
|
||||
var floorId = blockArray;
|
||||
blockArray = core.status.maps[floorId].blocks;
|
||||
@ -308,11 +320,11 @@ maps.prototype.getMapArray = function (blockArray, width, height, checkDisable)
|
||||
blockArray.forEach(function (block) {
|
||||
var x = block.x, y = block.y;
|
||||
if (block.disable) {
|
||||
if (checkDisable) blocks[y][x] = block.id + ":f";
|
||||
if (showDisable) blocks[y][x] = block.id + ":f";
|
||||
}
|
||||
else {
|
||||
blocks[y][x] = block.id;
|
||||
if (checkDisable && block.disable === false)
|
||||
if (showDisable && block.disable === false)
|
||||
blocks[y][x] = block.id + ":t";
|
||||
}
|
||||
});
|
||||
@ -331,7 +343,7 @@ maps.prototype.getMapBlocksObj = function (floorId, showDisable) {
|
||||
}
|
||||
|
||||
////// 将背景前景层变成二维数组的形式 //////
|
||||
maps.prototype.getBgFgMapArray = function (name, floorId, noCache) {
|
||||
maps.prototype._getBgFgMapArray = function (name, floorId, noCache) {
|
||||
floorId = floorId || core.status.floorId;
|
||||
if (!floorId) return [];
|
||||
var width = core.floors[floorId].width;
|
||||
@ -357,10 +369,26 @@ maps.prototype.getBgFgMapArray = function (name, floorId, noCache) {
|
||||
return arr;
|
||||
}
|
||||
|
||||
maps.prototype.getBgFgNumber = function (name, x, y, floorId, noCache) {
|
||||
maps.prototype.getBgMapArray = function (floorId, noCache) {
|
||||
return this._getBgFgMapArray('bg', floorId, noCache);
|
||||
}
|
||||
|
||||
maps.prototype.getFgMapArray = function (floorId, noCache) {
|
||||
return this._getBgFgMapArray('fg', floorId, noCache);
|
||||
}
|
||||
|
||||
maps.prototype._getBgFgNumber = function (name, x, y, floorId, noCache) {
|
||||
if (x == null) x = core.getHeroLoc('x');
|
||||
if (y == null) y = core.getHeroLoc('y');
|
||||
return this.getBgFgMapArray(name, floorId, noCache)[y][x];
|
||||
return this._getBgFgMapArray(name, floorId, noCache)[y][x];
|
||||
}
|
||||
|
||||
maps.prototype.getBgNumber = function (x, y, floorId, noCache) {
|
||||
return this._getBgFgNumber('bg', x, y, floorId, noCache);
|
||||
}
|
||||
|
||||
maps.prototype.getFgNumber = function (x, y, floorId, noCache) {
|
||||
return this._getBgFgNumber('fg', x, y, floorId, noCache);
|
||||
}
|
||||
|
||||
// ------ 当前能否朝某方向移动,能否瞬间移动 ------ //
|
||||
@ -370,8 +398,8 @@ maps.prototype.generateMovableArray = function (floorId, x, y, direction) {
|
||||
floorId = floorId || core.status.floorId;
|
||||
if (!floorId) return null;
|
||||
var width = core.floors[floorId].width, height = core.floors[floorId].height;
|
||||
var bgArray = this.getBgFgMapArray('bg', floorId),
|
||||
fgArray = this.getBgFgMapArray('fg', floorId),
|
||||
var bgArray = this.getBgMapArray(floorId),
|
||||
fgArray = this.getFgMapArray(floorId),
|
||||
eventArray = this.getMapArray(floorId);
|
||||
|
||||
var generate = function (x, y, direction) {
|
||||
@ -484,7 +512,7 @@ maps.prototype._canMoveDirectly_bfs = function (sx, sy, ex, ey) {
|
||||
var canMoveArray = this.generateMovableArray();
|
||||
var blocksObj = this.getMapBlocksObj(core.status.floorId);
|
||||
// 滑冰
|
||||
var bgMap = this.getBgFgMapArray('bg');
|
||||
var bgMap = this.getBgMapArray();
|
||||
|
||||
var visited = [], queue = [];
|
||||
visited[sx + "," + sy] = 0;
|
||||
@ -680,7 +708,7 @@ maps.prototype._drawMap_drawAll = function (floorId) {
|
||||
maps.prototype._drawMap_drawBlockInfo = function (ctx, block, blockInfo, arr, onMap) {
|
||||
if (blockInfo == null) return;
|
||||
if (blockInfo.cls == 'autotile') { // Autotile单独处理
|
||||
this.drawAutotile(ctx, arr, block, 32, 0, 0);
|
||||
this._drawAutotile(ctx, arr, block, 32, 0, 0);
|
||||
if (onMap) this.addGlobalAnimate(block);
|
||||
return;
|
||||
}
|
||||
@ -695,15 +723,16 @@ maps.prototype._drawMap_drawBlockInfo = function (ctx, block, blockInfo, arr, on
|
||||
|
||||
////// 绘制背景层 //////
|
||||
maps.prototype.drawBg = function (floorId, ctx) {
|
||||
floorId = floorId || core.status.floorId;
|
||||
var onMap = ctx == null;
|
||||
if (onMap) {
|
||||
ctx = core.canvas.bg;
|
||||
core.clearMap(ctx);
|
||||
}
|
||||
this._drawBg_drawBackground(floorId, ctx);
|
||||
core.maps._drawBg_drawBackground(floorId, ctx);
|
||||
// ------ 调整这两行的顺序来控制是先绘制贴图还是先绘制背景图块;后绘制的覆盖先绘制的。
|
||||
this._drawFloorImages(floorId, ctx, 'bg');
|
||||
this._drawBgFgMap(floorId, ctx, 'bg', onMap);
|
||||
core.maps._drawFloorImages(floorId, ctx, 'bg');
|
||||
core.maps._drawBgFgMap(floorId, ctx, 'bg', onMap);
|
||||
}
|
||||
|
||||
maps.prototype._drawBg_drawBackground = function (floorId, ctx) {
|
||||
@ -723,7 +752,7 @@ maps.prototype._drawBg_drawBackground = function (floorId, ctx) {
|
||||
maps.prototype.drawEvents = function (floorId, blocks, ctx) {
|
||||
floorId = floorId || core.status.floorId;
|
||||
if (!blocks) blocks = core.status.maps[floorId].blocks;
|
||||
var arr = this.getMapArray(blocks, core.floors[floorId].width, core.floors[floorId].height);
|
||||
var arr = this._getMapArrayFromBlocks(blocks, core.floors[floorId].width, core.floors[floorId].height);
|
||||
var onMap = ctx == null;
|
||||
if (onMap) ctx = core.canvas.event;
|
||||
blocks.filter(function (block) {
|
||||
@ -736,6 +765,7 @@ maps.prototype.drawEvents = function (floorId, blocks, ctx) {
|
||||
|
||||
////// 绘制前景层 //////
|
||||
maps.prototype.drawFg = function (floorId, ctx) {
|
||||
floorId = floorId || core.status.floorId;
|
||||
var onMap = ctx == null;
|
||||
if (onMap) ctx = core.canvas.fg;
|
||||
// ------ 调整这两行的顺序来控制是先绘制贴图还是先绘制背景图块;后绘制的覆盖先绘制的。
|
||||
@ -753,7 +783,7 @@ maps.prototype._drawBgFgMap = function (floorId, ctx, name, onMap) {
|
||||
if (!core.status[name + "maps"])
|
||||
core.status[name + "maps"] = {};
|
||||
|
||||
var arr = this.getBgFgMapArray(name, floorId, true);
|
||||
var arr = this._getBgFgMapArray(name, floorId, true);
|
||||
for (var x = 0; x < width; x++) {
|
||||
for (var y = 0; y < height; y++) {
|
||||
var block = this.initBlock(x, y, arr[y][x], true);
|
||||
@ -845,7 +875,7 @@ maps.prototype._drawFloorImage = function (ctx, name, type, image, offsetX, widt
|
||||
}
|
||||
|
||||
////// 绘制Autotile //////
|
||||
maps.prototype.drawAutotile = function (ctx, mapArr, block, size, left, top, status) {
|
||||
maps.prototype._drawAutotile = function (ctx, mapArr, block, size, left, top, status) {
|
||||
var indexArrs = [ //16种组合的图块索引数组; // 将autotile分割成48块16*16的小块; 数组索引即对应各个小块
|
||||
// +----+----+----+----+----+----+
|
||||
[10, 9, 4, 3], //0 bin:0000 | 1 | 2 | 3 | 4 | 5 | 6 |
|
||||
@ -947,10 +977,10 @@ maps.prototype._drawAutotileAnimate = function (block, animate) {
|
||||
if (block.name) {
|
||||
if (block.name == 'bg')
|
||||
core.drawImage('bg', core.material.groundCanvas.canvas, 32 * x, 32 * y);
|
||||
this.drawAutotile(cv, core.status.autotileAnimateObjs[block.name+"map"], block, 32, 0, 0, animate);
|
||||
this._drawAutotile(cv, core.status.autotileAnimateObjs[block.name+"map"], block, 32, 0, 0, animate);
|
||||
}
|
||||
else {
|
||||
this.drawAutotile(cv, core.status.autotileAnimateObjs.map, block, 32, 0, 0, animate);
|
||||
this._drawAutotile(cv, core.status.autotileAnimateObjs.map, block, 32, 0, 0, animate);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1209,8 +1239,9 @@ maps.prototype.searchBlock = function (id, floorId, showDisable) {
|
||||
}
|
||||
for (var i = 0; i < core.status.maps[floorId].blocks.length; ++i) {
|
||||
var block = core.status.maps[floorId].blocks[i];
|
||||
if (block.event.id == id && (showDisable || !block.disable))
|
||||
result.push({floorId: floorId, index: i, block: block});
|
||||
if ((showDisable || !block.disable) && core.matchWildcard(id, block.event.id)) {
|
||||
result.push({floorId: floorId, index: i, block: block, x: block.x, y: block.y});
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -1296,19 +1327,6 @@ maps.prototype.removeBlockById = function (index, floorId) {
|
||||
}
|
||||
}
|
||||
|
||||
////// 能否彻底从地图中删除一个图块 //////
|
||||
maps.prototype.canRemoveBlock = function (block, floorId) {
|
||||
var x = block.x, y = block.y;
|
||||
// 检查该点是否存在事件
|
||||
if (core.floors[floorId].events[x + "," + y] || core.floors[floorId].changeFloor[x + "," + y])
|
||||
return false;
|
||||
// 检查是否存在重生
|
||||
if (block.event && block.event.cls.indexOf('enemy') == 0 && core.hasSpecial(block.event.id, 23))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////// 一次性删除多个block //////
|
||||
maps.prototype.removeBlockByIds = function (floorId, ids) {
|
||||
floorId = floorId || core.status.floorId;
|
||||
@ -1320,24 +1338,17 @@ maps.prototype.removeBlockByIds = function (floorId, ids) {
|
||||
});
|
||||
}
|
||||
|
||||
////// 将地图中所有某个图块替换成另一个图块 //////
|
||||
maps.prototype.replaceBlock = function (fromNumber, toNumber, floorId) {
|
||||
floorId = floorId || core.status.floorId;
|
||||
if (floorId instanceof Array) {
|
||||
floorId.forEach(function (floorId) {
|
||||
core.replaceBlock(fromNumber, toNumber, floorId);
|
||||
});
|
||||
return;
|
||||
}
|
||||
var toBlock = this.initBlock(0, 0, toNumber, true);
|
||||
core.status.maps[floorId].blocks.forEach(function (block) {
|
||||
if (block.id == fromNumber) {
|
||||
block.id = toNumber;
|
||||
for (var one in toBlock.event) {
|
||||
block.event[one] = core.clone(toBlock.event[one]);
|
||||
}
|
||||
}
|
||||
});
|
||||
////// 能否彻底从地图中删除一个图块 //////
|
||||
maps.prototype.canRemoveBlock = function (block, floorId) {
|
||||
var x = block.x, y = block.y;
|
||||
// 检查该点是否存在事件
|
||||
if (core.floors[floorId].events[x + "," + y] || core.floors[floorId].changeFloor[x + "," + y])
|
||||
return false;
|
||||
// 检查是否存在重生
|
||||
if (block.event && block.event.cls.indexOf('enemy') == 0 && core.hasSpecial(block.event.id, 23))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////// 显示前景/背景地图 //////
|
||||
@ -1415,6 +1426,10 @@ maps.prototype.setBlock = function (number, x, y, floorId) {
|
||||
floorId = floorId || core.status.floorId;
|
||||
if (!floorId || number == null || x == null || y == null) return;
|
||||
if (x < 0 || x >= core.floors[floorId].width || y < 0 || y >= core.floors[floorId].height) return;
|
||||
if (typeof number == 'string') {
|
||||
if (/^\d+$/.test(number)) number = parseInt(number);
|
||||
else number = core.getNumberById(number);
|
||||
}
|
||||
|
||||
var originBlock = core.getBlock(x, y, floorId, true);
|
||||
var block = this.initBlock(x, y, number, true, core.floors[floorId]);
|
||||
@ -1442,12 +1457,36 @@ maps.prototype.setBlock = function (number, x, y, floorId) {
|
||||
}
|
||||
}
|
||||
|
||||
////// 将地图中所有某个图块替换成另一个图块 //////
|
||||
maps.prototype.replaceBlock = function (fromNumber, toNumber, floorId) {
|
||||
floorId = floorId || core.status.floorId;
|
||||
if (floorId instanceof Array) {
|
||||
floorId.forEach(function (floorId) {
|
||||
core.replaceBlock(fromNumber, toNumber, floorId);
|
||||
});
|
||||
return;
|
||||
}
|
||||
var toBlock = this.initBlock(0, 0, toNumber, true);
|
||||
core.status.maps[floorId].blocks.forEach(function (block) {
|
||||
if (block.id == fromNumber) {
|
||||
block.id = toNumber;
|
||||
for (var one in toBlock.event) {
|
||||
block.event[one] = core.clone(toBlock.event[one]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
////// 改变前景背景的图块 //////
|
||||
maps.prototype.setBgFgBlock = function (name, number, x, y, floorId) {
|
||||
floorId = floorId || core.status.floorId;
|
||||
if (!floorId || number == null || x == null || y == null) return;
|
||||
if (x < 0 || x >= core.floors[floorId].width || y < 0 || y >= core.floors[floorId].height) return;
|
||||
if (name != 'bg' && name != 'fg') return;
|
||||
if (typeof number == 'string') {
|
||||
if (/^\d+$/.test(number)) number = parseInt(number);
|
||||
else number = core.getNumberById(number);
|
||||
}
|
||||
|
||||
var vFlag = "__" + name + "Value__" + floorId + "_" + x + "_" + y;
|
||||
core.setFlag(vFlag, number);
|
||||
@ -1624,10 +1663,8 @@ maps.prototype.jumpBlock = function (sx, sy, ex, ey, time, keep, callback) {
|
||||
var block = blockArr[0], blockInfo = blockArr[1];
|
||||
var canvases = this._initDetachedBlock(blockInfo, sx, sy, block.event.animate !== false);
|
||||
this._moveDetachedBlock(blockInfo, 32 * sx, 32 * sy, 1, canvases);
|
||||
|
||||
this.__playJumpSound();
|
||||
|
||||
var jumpInfo = ths.__generateJumpInfo(sx, sy, ex, ey, time);
|
||||
core.playSound('jump.mp3');
|
||||
var jumpInfo = this.__generateJumpInfo(sx, sy, ex, ey, time);
|
||||
jumpInfo.keep = keep;
|
||||
|
||||
this._jumpBlock_doJump(blockInfo, canvases, jumpInfo, callback);
|
||||
@ -1639,14 +1676,10 @@ maps.prototype.__generateJumpInfo = function (sx, sy, ex, ey, time) {
|
||||
return {
|
||||
x: sx, y: sy, ex: ex, ey: ey, px: 32 * sx, py: 32 * sy, opacity: 1,
|
||||
jump_peak: jump_peak, jump_count: jump_count,
|
||||
step: 0, per_time: time / 16 / core.status.replay.speed
|
||||
step: 0, per_time: time / jump_count
|
||||
};
|
||||
}
|
||||
|
||||
maps.prototype.__playJumpSound = function () {
|
||||
core.playSound('jump.mp3');
|
||||
}
|
||||
|
||||
maps.prototype._jumpBlock_doJump = function (blockInfo, canvases, jumpInfo, callback) {
|
||||
var animate = window.setInterval(function () {
|
||||
if (jumpInfo.jump_count > 0)
|
||||
@ -1761,16 +1794,16 @@ maps.prototype._animateBlock_drawList = function (list, opacity) {
|
||||
// ------ 全局动画控制,动画绘制 ------ //
|
||||
|
||||
////// 添加一个全局动画 //////
|
||||
maps.prototype.addGlobalAnimate = function (b) {
|
||||
if (!b.event || b.event.animate == null) return;
|
||||
if (b.event.cls == 'autotile') {
|
||||
var id = b.event.id, img = core.material.images.autotile[id];
|
||||
maps.prototype.addGlobalAnimate = function (block) {
|
||||
if (!block.event || block.event.animate == null) return;
|
||||
if (block.event.cls == 'autotile') {
|
||||
var id = block.event.id, img = core.material.images.autotile[id];
|
||||
if (!img || img.width == 96) return;
|
||||
core.status.autotileAnimateObjs.blocks.push(b);
|
||||
core.status.autotileAnimateObjs.blocks.push(block);
|
||||
}
|
||||
else {
|
||||
if (!b.event.animate || b.event.animate == 1) return;
|
||||
core.status.globalAnimateObjs.push(b);
|
||||
if (!block.event.animate || block.event.animate == 1) return;
|
||||
core.status.globalAnimateObjs.push(block);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1829,18 +1862,17 @@ maps.prototype.drawAnimate = function (name, x, y, callback) {
|
||||
// 播放音效
|
||||
core.playSound(animate.se);
|
||||
|
||||
var animateId = parseInt(Math.random() * 100000000);
|
||||
var id = setTimeout(null);
|
||||
core.status.animateObjs.push({
|
||||
"id": id,
|
||||
"animate": animate,
|
||||
"centerX": centerX,
|
||||
"centerY": centerY,
|
||||
"index": 0,
|
||||
"id": animateId,
|
||||
"callback": callback
|
||||
});
|
||||
|
||||
core.animateFrame.asyncId[animateId] = true;
|
||||
return animateId;
|
||||
return id;
|
||||
}
|
||||
|
||||
////// 绘制动画的某一帧 //////
|
||||
@ -1878,7 +1910,6 @@ maps.prototype.stopAnimate = function (id, doCallback) {
|
||||
for (var i = 0; i < core.status.animateObjs.length; i++) {
|
||||
var obj = core.status.animateObjs[i];
|
||||
if (obj.id == id) {
|
||||
delete core.animateFrame.asyncId[obj.id];
|
||||
if (doCallback) {
|
||||
(function (callback) {
|
||||
setTimeout(function () {
|
||||
@ -1887,10 +1918,8 @@ maps.prototype.stopAnimate = function (id, doCallback) {
|
||||
})(obj.callback);
|
||||
}
|
||||
}
|
||||
core.status.animateObjs.splice(i, 1);
|
||||
if (core.status.animateObjs.length == 0) {
|
||||
}
|
||||
core.status.animateObjs = core.status.animateObjs.filter(function (x) { return x.id != id });
|
||||
if (core.status.animateObjs.length == 0)
|
||||
core.clearMap('animate');
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
759
libs/ui.js
759
libs/ui.js
File diff suppressed because it is too large
Load Diff
104
libs/utils.js
104
libs/utils.js
@ -75,35 +75,6 @@ utils.prototype.calValue = function (value, prefix, need, times) {
|
||||
return value;
|
||||
}
|
||||
|
||||
////// 字符串自动换行的分割 //////
|
||||
utils.prototype.splitLines = function (canvas, text, maxLength, font) {
|
||||
if (font) core.setFont(canvas, font);
|
||||
|
||||
var contents = [];
|
||||
var last = 0;
|
||||
for (var i = 0; i < text.length; i++) {
|
||||
|
||||
if (text.charAt(i) == '\n') {
|
||||
contents.push(text.substring(last, i));
|
||||
last = i + 1;
|
||||
}
|
||||
else if (text.charAt(i) == '\\' && text.charAt(i + 1) == 'n') {
|
||||
contents.push(text.substring(last, i));
|
||||
last = i + 2;
|
||||
}
|
||||
else {
|
||||
var toAdd = text.substring(last, i + 1);
|
||||
var width = core.calWidth(canvas, toAdd);
|
||||
if (maxLength && width > maxLength) {
|
||||
contents.push(text.substring(last, i));
|
||||
last = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
contents.push(text.substring(last));
|
||||
return contents;
|
||||
}
|
||||
|
||||
////// 向某个数组前插入另一个数组或元素 //////
|
||||
utils.prototype.unshift = function (a, b) {
|
||||
if (!(a instanceof Array) || b == null) return;
|
||||
@ -128,6 +99,28 @@ utils.prototype.push = function (a, b) {
|
||||
return a;
|
||||
}
|
||||
|
||||
utils.prototype.decompress = function (value) {
|
||||
try {
|
||||
var output = lzw_decode(value);
|
||||
if (output) return JSON.parse(output);
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
try {
|
||||
var output = LZString.decompress(value);
|
||||
if (output) return JSON.parse(output);
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
try {
|
||||
return JSON.parse(value);
|
||||
}
|
||||
catch (e) {
|
||||
main.log(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
////// 设置本地存储 //////
|
||||
utils.prototype.setLocalStorage = function (key, value) {
|
||||
try {
|
||||
@ -163,28 +156,6 @@ utils.prototype.setLocalStorage = function (key, value) {
|
||||
}
|
||||
}
|
||||
|
||||
utils.prototype.decompress = function (value) {
|
||||
try {
|
||||
var output = lzw_decode(value);
|
||||
if (output) return JSON.parse(output);
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
try {
|
||||
var output = LZString.decompress(value);
|
||||
if (output) return JSON.parse(output);
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
try {
|
||||
return JSON.parse(value);
|
||||
}
|
||||
catch (e) {
|
||||
main.log(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
////// 获得本地存储 //////
|
||||
utils.prototype.getLocalStorage = function (key, defaultValue) {
|
||||
var res = this.decompress(localStorage.getItem(core.firstData.name + "_" + key));
|
||||
@ -475,7 +446,7 @@ utils.prototype._encodeRoute_encodeOne = function (t) {
|
||||
return 'K' + t.substring(4);
|
||||
else if (t.indexOf('random:') == 0)
|
||||
return 'X' + t.substring(7);
|
||||
return '';
|
||||
return '('+t+')';
|
||||
}
|
||||
|
||||
////// 解密路线 //////
|
||||
@ -485,7 +456,8 @@ utils.prototype.decodeRoute = function (route) {
|
||||
// 解压缩
|
||||
try {
|
||||
var v = LZString.decompressFromBase64(route);
|
||||
if (/^[a-zA-Z0-9+\/=:]*$/.test(v)) {
|
||||
if (v != null && /^[-_a-zA-Z0-9+\/=:()]*$/.test(v)) {
|
||||
if (v != "" || route.length < 8)
|
||||
route = v;
|
||||
}
|
||||
} catch (e) {
|
||||
@ -525,6 +497,15 @@ utils.prototype._decodeRoute_number2id = function (number) {
|
||||
}
|
||||
|
||||
utils.prototype._decodeRoute_decodeOne = function (decodeObj, c) {
|
||||
// --- 特殊处理自定义项
|
||||
if (c == '(') {
|
||||
var idx = decodeObj.route.indexOf(')', decodeObj.index);
|
||||
if (idx >= 0) {
|
||||
decodeObj.ans.push(decodeObj.route.substring(decodeObj.index, idx));
|
||||
decodeObj.index = idx + 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
var nxt = (c == 'I' || c == 'e' || c == 'F' || c == 'S' || c == 'Q' || c == 't') ?
|
||||
this._decodeRoute_getString(decodeObj) : this._decodeRoute_getNumber(decodeObj);
|
||||
|
||||
@ -618,6 +599,7 @@ utils.prototype.getCookie = function (name) {
|
||||
|
||||
////// 设置statusBar的innerHTML,会自动斜体和放缩,也可以增加自定义css //////
|
||||
utils.prototype.setStatusBarInnerHTML = function (name, value, css) {
|
||||
if (!core.statusBar[name]) return;
|
||||
if (typeof value == 'number') value = this.formatBigNumber(value);
|
||||
// 判定是否斜体
|
||||
var italic = /^[-a-zA-Z0-9`~!@#$%^&*()_=+\[{\]}\\|;:'",<.>\/?]*$/.test(value);
|
||||
@ -642,6 +624,12 @@ utils.prototype.reverseDirection = function (direction) {
|
||||
return {"left":"right","right":"left","down":"up","up":"down"}[direction] || direction;
|
||||
}
|
||||
|
||||
utils.prototype.matchWildcard = function (pattern, string) {
|
||||
return new RegExp('^' + pattern.split(/\*+/).map(function (s) {
|
||||
return s.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&');
|
||||
}).join('.*') + '$').test(string);
|
||||
}
|
||||
|
||||
////// Base64加密 //////
|
||||
utils.prototype.encodeBase64 = function (str) {
|
||||
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) {
|
||||
@ -921,7 +909,7 @@ utils.prototype.myprompt = function (hint, value, callback) {
|
||||
}
|
||||
|
||||
////// 动画显示某对象 //////
|
||||
utils.prototype.show = function (obj, speed, callback) {
|
||||
utils.prototype.showWithAnimate = function (obj, speed, callback) {
|
||||
obj.style.display = 'block';
|
||||
if (!speed && main.mode != 'play') {
|
||||
obj.style.opacity = 1;
|
||||
@ -941,7 +929,7 @@ utils.prototype.show = function (obj, speed, callback) {
|
||||
}
|
||||
|
||||
////// 动画使某对象消失 //////
|
||||
utils.prototype.hide = function (obj, speed, callback) {
|
||||
utils.prototype.hideWithAnimate = function (obj, speed, callback) {
|
||||
if (!speed || main.mode != 'play') {
|
||||
obj.style.display = 'none';
|
||||
if (callback) callback();
|
||||
@ -960,7 +948,7 @@ utils.prototype.hide = function (obj, speed, callback) {
|
||||
}, speed);
|
||||
}
|
||||
|
||||
utils.prototype.encodeCanvas = function (ctx) {
|
||||
utils.prototype._encodeCanvas = function (ctx) {
|
||||
var list = [];
|
||||
var width = ctx.canvas.width, height = ctx.canvas.height;
|
||||
ctx.mozImageSmoothingEnabled = false;
|
||||
@ -987,7 +975,7 @@ utils.prototype.encodeCanvas = function (ctx) {
|
||||
}
|
||||
|
||||
////// 解析arr数组,并绘制到tempCanvas上 //////
|
||||
utils.prototype.decodeCanvas = function (arr, width, height) {
|
||||
utils.prototype._decodeCanvas = function (arr, width, height) {
|
||||
// 清空tempCanvas
|
||||
var tempCanvas = core.bigmap.tempCanvas;
|
||||
tempCanvas.canvas.width = width;
|
||||
@ -1070,7 +1058,7 @@ utils.prototype._export = function (floorIds) {
|
||||
// map
|
||||
var content = floorIds.length + "\n" + core.__SIZE__ + " " + core.__SIZE__ + "\n\n";
|
||||
floorIds.forEach(function (floorId) {
|
||||
var arr = core.maps.getMapArray(core.status.maps[floorId].blocks);
|
||||
var arr = core.maps._getMapArrayFromBlocks(core.status.maps[floorId].blocks);
|
||||
content += arr.map(function (x) {
|
||||
// check monster
|
||||
x.forEach(function (t) {
|
||||
|
||||
10
main.js
10
main.js
@ -364,7 +364,7 @@ main.dom.body.onselectstart = function () {
|
||||
main.dom.data.onmousedown = function (e) {
|
||||
try {
|
||||
e.stopPropagation();
|
||||
var loc = main.core.getClickLoc(e.clientX, e.clientY);
|
||||
var loc = main.core.actions._getClickLoc(e.clientX, e.clientY);
|
||||
if (loc == null) return;
|
||||
main.core.ondown(loc);
|
||||
} catch (ee) { main.log(ee); }
|
||||
@ -374,7 +374,7 @@ main.dom.data.onmousedown = function (e) {
|
||||
main.dom.data.onmousemove = function (e) {
|
||||
try {
|
||||
e.stopPropagation();
|
||||
var loc = main.core.getClickLoc(e.clientX, e.clientY);
|
||||
var loc = main.core.actions._getClickLoc(e.clientX, e.clientY);
|
||||
if (loc == null) return;
|
||||
main.core.onmove(loc);
|
||||
}catch (ee) { main.log(ee); }
|
||||
@ -401,7 +401,7 @@ main.dom.data.onmousewheel = function(e) {
|
||||
main.dom.data.ontouchstart = function (e) {
|
||||
try {
|
||||
e.preventDefault();
|
||||
var loc = main.core.getClickLoc(e.targetTouches[0].clientX, e.targetTouches[0].clientY);
|
||||
var loc = main.core.actions._getClickLoc(e.targetTouches[0].clientX, e.targetTouches[0].clientY);
|
||||
if (loc == null) return;
|
||||
main.core.ondown(loc);
|
||||
}catch (ee) { main.log(ee); }
|
||||
@ -411,7 +411,7 @@ main.dom.data.ontouchstart = function (e) {
|
||||
main.dom.data.ontouchmove = function (e) {
|
||||
try {
|
||||
e.preventDefault();
|
||||
var loc = main.core.getClickLoc(e.targetTouches[0].clientX, e.targetTouches[0].clientY);
|
||||
var loc = main.core.actions._getClickLoc(e.targetTouches[0].clientX, e.targetTouches[0].clientY);
|
||||
if (loc == null) return;
|
||||
main.core.onmove(loc);
|
||||
}catch (ee) { main.log(ee); }
|
||||
@ -675,7 +675,7 @@ window.onblur = function () {
|
||||
if (main.core && main.core.control) {
|
||||
try {
|
||||
main.core.control.checkAutosave();
|
||||
} catch (e) {main.log(e);}
|
||||
} catch (e) {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -78,6 +78,7 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
|
||||
"lv": 1,
|
||||
"hpmax": 9999,
|
||||
"hp": 1000,
|
||||
"manamax": -1,
|
||||
"mana": 0,
|
||||
"atk": 100,
|
||||
"def": 100,
|
||||
@ -249,6 +250,8 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
|
||||
"name": "贪婪之神",
|
||||
"icon": "blueShop",
|
||||
"textInList": "1F金币商店",
|
||||
"commonTimes": false,
|
||||
"mustEnable": false,
|
||||
"use": "money",
|
||||
"need": "20+10*times*(times+1)",
|
||||
"text": "勇敢的武士啊,给我${need}金币就可以:",
|
||||
@ -276,6 +279,8 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
|
||||
"name": "经验之神",
|
||||
"icon": "pinkShop",
|
||||
"textInList": "1F经验商店",
|
||||
"commonTimes": false,
|
||||
"mustEnable": false,
|
||||
"use": "experience",
|
||||
"need": "-1",
|
||||
"text": "勇敢的武士啊,给我若干经验就可以:",
|
||||
@ -296,6 +301,12 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
|
||||
"effect": "status:def+=5"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "keyShop1",
|
||||
"textInList": "回收钥匙商店",
|
||||
"mustEnable": false,
|
||||
"commonEvent": "回收钥匙商店"
|
||||
}
|
||||
],
|
||||
"levelUp": [
|
||||
@ -376,8 +387,10 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
|
||||
"bombFourDirections": false,
|
||||
"snowFourDirections": false,
|
||||
"bigKeyIsBox": false,
|
||||
"steelDoorWithoutKey": false,
|
||||
"equipment": false,
|
||||
"equipboxButton": false,
|
||||
"iconInEquipbox": false,
|
||||
"enableAddPoint": false,
|
||||
"enableNegativeDamage": false,
|
||||
"hatredDecrease": true,
|
||||
|
||||
@ -223,7 +223,7 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 =
|
||||
},
|
||||
{
|
||||
"type": "if",
|
||||
"condition": "core.getBgFgNumber('bg') == 167",
|
||||
"condition": "core.getBgNumber() == 167",
|
||||
"true": [
|
||||
{
|
||||
"type": "function",
|
||||
@ -237,6 +237,100 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 =
|
||||
],
|
||||
"false": []
|
||||
}
|
||||
],
|
||||
"回收钥匙商店": [
|
||||
{
|
||||
"type": "comment",
|
||||
"text": "此事件在全局商店中被引用了(全局商店keyShop1)"
|
||||
},
|
||||
{
|
||||
"type": "comment",
|
||||
"text": "解除引用前勿删除此事件"
|
||||
},
|
||||
{
|
||||
"type": "comment",
|
||||
"text": "玩家在快捷列表(V键)中可以使用本公共事件"
|
||||
},
|
||||
{
|
||||
"type": "while",
|
||||
"condition": "1",
|
||||
"data": [
|
||||
{
|
||||
"type": "choices",
|
||||
"text": "\t[商人,woman]你有多余的钥匙想要出售吗?",
|
||||
"choices": [
|
||||
{
|
||||
"text": "黄钥匙(10金币)",
|
||||
"color": [
|
||||
255,
|
||||
255,
|
||||
0,
|
||||
1
|
||||
],
|
||||
"action": [
|
||||
{
|
||||
"type": "if",
|
||||
"condition": "item:yellowKey >= 1",
|
||||
"true": [
|
||||
{
|
||||
"type": "addValue",
|
||||
"name": "item:yellowKey",
|
||||
"value": "-1"
|
||||
},
|
||||
{
|
||||
"type": "addValue",
|
||||
"name": "status:money",
|
||||
"value": "10"
|
||||
}
|
||||
],
|
||||
"false": [
|
||||
"\t[商人,woman]你没有黄钥匙!"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "蓝钥匙(50金币)",
|
||||
"color": [
|
||||
0,
|
||||
0,
|
||||
255,
|
||||
1
|
||||
],
|
||||
"action": [
|
||||
{
|
||||
"type": "if",
|
||||
"condition": "item:blueKey >= 1",
|
||||
"true": [
|
||||
{
|
||||
"type": "addValue",
|
||||
"name": "item:blueKey",
|
||||
"value": "-1"
|
||||
},
|
||||
{
|
||||
"type": "addValue",
|
||||
"name": "status:money",
|
||||
"value": "50"
|
||||
}
|
||||
],
|
||||
"false": [
|
||||
"\t[商人,woman]你没有蓝钥匙!"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "离开",
|
||||
"action": [
|
||||
{
|
||||
"type": "exit"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -151,7 +151,7 @@ main.floors.sample1=
|
||||
"type": "hide"
|
||||
},
|
||||
{
|
||||
"type": "setFg",
|
||||
"type": "setCurtain",
|
||||
"color": [
|
||||
0,
|
||||
0,
|
||||
@ -184,7 +184,7 @@ main.floors.sample1=
|
||||
"2,11": [
|
||||
"\t[杰克,thief]喂!醒醒!快醒醒!",
|
||||
{
|
||||
"type": "setFg",
|
||||
"type": "setCurtain",
|
||||
"time": 1500
|
||||
},
|
||||
"\t[hero]额,我这是在什么地方?",
|
||||
|
||||
@ -6,6 +6,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
// hero:勇士信息;hard:难度;floorId:当前楼层ID;maps:地图信息;values:全局数值信息
|
||||
|
||||
// 清除游戏数据
|
||||
// 这一步会清空状态栏和全部画布内容,并删除所有动态创建的画布
|
||||
core.clearStatus();
|
||||
// 初始化status
|
||||
core.status = core.clone(core.initStatus);
|
||||
@ -699,7 +700,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
gid = guards[i][2];
|
||||
// 递归计算支援怪伤害信息,这里不传x,y保证不会重复调用
|
||||
// 这里的mdef传0,因为护盾应该只会被计算一次
|
||||
var info = core.enemys.getDamageInfo(core.material.enemys[gid], origin_hero_hp, origin_hero_atk, origin_hero_def, 0);
|
||||
var info = core.enemys.getDamageInfo(core.material.enemys[gid], { hp: origin_hero_hp, atk: origin_hero_atk, def: origin_hero_def, mdef: 0 });
|
||||
if (info == null) { // 小队中任何一个怪物不可战斗,直接返回null
|
||||
return null;
|
||||
}
|
||||
@ -755,7 +756,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
// 可以在这里任意增加或编辑每个按键的行为
|
||||
|
||||
// 如果处于正在行走状态,则不处理
|
||||
if (!core.status.heroStop || core.status.heroMoving > 0)
|
||||
if (core.isMoving())
|
||||
return;
|
||||
|
||||
// Alt+0~9,快捷换上套装
|
||||
@ -796,7 +797,8 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
case 90: // Z:转向
|
||||
core.turnHero();
|
||||
break;
|
||||
case 75: case 86: // V:打开快捷商店列表
|
||||
case 75:
|
||||
case 86: // V:打开快捷商店列表
|
||||
core.openQuickShop(true);
|
||||
break;
|
||||
case 32: // SPACE:轻按
|
||||
@ -805,7 +807,8 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
case 82: // R:回放录像
|
||||
core.actions._clickSyncSave_replay();
|
||||
break;
|
||||
case 33: case 34: // PgUp/PgDn:浏览地图
|
||||
case 33:
|
||||
case 34: // PgUp/PgDn:浏览地图
|
||||
core.ui.drawMaps();
|
||||
break;
|
||||
case 77: // M:绘图模式
|
||||
@ -829,9 +832,9 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
case 49: // 快捷键1: 破
|
||||
if (core.hasItem('pickaxe')) {
|
||||
if (core.canUseItem('pickaxe')) {
|
||||
core.useItem('pickaxe');
|
||||
}
|
||||
else {
|
||||
core.status.route.push("key:49"); // 将按键记在录像中
|
||||
core.useItem('pickaxe', true); // 第二个参数true代表该次使用道具是被按键触发的,使用过程不计入录像
|
||||
} else {
|
||||
core.drawTip('当前不能使用破墙镐');
|
||||
}
|
||||
}
|
||||
@ -839,17 +842,16 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
case 50: // 快捷键2: 炸
|
||||
if (core.hasItem('bomb')) {
|
||||
if (core.canUseItem('bomb')) {
|
||||
core.useItem('bomb');
|
||||
}
|
||||
else {
|
||||
core.status.route.push("key:50"); // 将按键记在录像中
|
||||
core.useItem('bomb', true); // 第二个参数true代表该次使用道具是被按键触发的,使用过程不计入录像
|
||||
} else {
|
||||
core.drawTip('当前不能使用炸弹');
|
||||
}
|
||||
}
|
||||
else if (core.hasItem('hammer')) {
|
||||
} else if (core.hasItem('hammer')) {
|
||||
if (core.canUseItem('hammer')) {
|
||||
core.useItem('hammer');
|
||||
}
|
||||
else {
|
||||
core.status.route.push("key:50"); // 将按键记在录像中
|
||||
core.useItem('hammer', true); // 第二个参数true代表该次使用道具是被按键触发的,使用过程不计入录像
|
||||
} else {
|
||||
core.drawTip('当前不能使用圣锤');
|
||||
}
|
||||
|
||||
@ -866,7 +868,8 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
var itemId = list[i];
|
||||
if (core.canUseItem(itemId)) {
|
||||
core.useItem(itemId);
|
||||
core.status.route.push("key:52");
|
||||
core.useItem(itemId, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -881,7 +884,8 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
case 87: // W:开启技能“二倍斩”
|
||||
// 检测是否拥有“二倍斩”这个技能道具
|
||||
if (core.hasItem('skill1')) {
|
||||
core.useItem('skill1');
|
||||
core.status.route.push("key:87");
|
||||
core.useItem('skill1', true);
|
||||
}
|
||||
break;
|
||||
// 在这里可以任意新增或编辑已有的快捷键内容
|
||||
@ -892,7 +896,8 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
// ... 在这里写你要执行脚本
|
||||
// **强烈建议所有新增的自定义快捷键均能给个对应的道具可点击,以方便手机端的行为**
|
||||
if (core.hasItem('...')) {
|
||||
core.useItem('...');
|
||||
core.status.route.push("key:0");
|
||||
core.useItem('...', true); // 增加true代表该使用道具不计入录像
|
||||
}
|
||||
|
||||
break;
|
||||
@ -1006,9 +1011,14 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
|
||||
// 设置魔力值
|
||||
if (core.flags.enableMana) {
|
||||
// 也可以使用flag:manaMax来表示最大魔力值;详见文档-个性化-技能塔的支持
|
||||
// core.status.hero.mana = Math.max(core.status.hero.mana, core.getFlag('manaMax', 10));
|
||||
// core.setStatusBarInnerHTML('mana', core.status.hero.mana + "/" + core.getFlag('manaMax', 10));
|
||||
// status:manamax 只有在非负时才生效。
|
||||
if (core.status.hero.manamax != null && core.status.hero.manamax >= 0) {
|
||||
core.status.hero.mana = Math.min(core.status.hero.mana, core.status.hero.manamax);
|
||||
core.setStatusBarInnerHTML('mana', core.status.hero.mana + "/" + core.status.hero.manamax);
|
||||
}
|
||||
else {
|
||||
core.setStatusBarInnerHTML("mana", core.status.hero.mana);
|
||||
}
|
||||
}
|
||||
// 设置技能栏
|
||||
if (core.flags.enableSkill) {
|
||||
|
||||
@ -259,7 +259,7 @@ var icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1 =
|
||||
"hammer": 48,
|
||||
"jumpShoes": 49,
|
||||
"skill1": 30,
|
||||
"I73": 10
|
||||
"wand": 10
|
||||
},
|
||||
"autotile": {
|
||||
"autotile": 0,
|
||||
|
||||
@ -303,7 +303,7 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a =
|
||||
"text": "可以打开或关闭主动技能二倍斩",
|
||||
"hideInReplay": true
|
||||
},
|
||||
"I73": {
|
||||
"wand": {
|
||||
"cls": "items",
|
||||
"name": "新物品"
|
||||
}
|
||||
|
||||
@ -67,7 +67,7 @@ var maps_90f36752_8815_4be8_b32b_d7fad1d0542e =
|
||||
"70": {"cls":"items","id":"sword0"},
|
||||
"71": {"cls":"items","id":"shield0"},
|
||||
"72": {"cls":"items","id":"skill1"},
|
||||
"73": {"cls":"items","id":"I73"},
|
||||
"73": {"cls":"items","id":"wand"},
|
||||
"81": {"cls":"terrains","id":"yellowDoor","trigger":"openDoor"},
|
||||
"82": {"cls":"terrains","id":"blueDoor","trigger":"openDoor"},
|
||||
"83": {"cls":"terrains","id":"redDoor","trigger":"openDoor"},
|
||||
|
||||
@ -1,18 +1,28 @@
|
||||
var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
|
||||
{
|
||||
"init": function () {
|
||||
// 在这里写的代码,在所有模块加载完毕后,游戏开始前会被执行
|
||||
|
||||
console.log("插件编写测试");
|
||||
|
||||
// 可以写一些其他的被直接执行的代码
|
||||
// 可以写一些直接执行的代码
|
||||
// 在这里写的代码将会在【资源加载前】被执行,此时图片等资源尚未被加载。
|
||||
// 请勿在这里对包括bgm,图片等资源进行操作。
|
||||
|
||||
|
||||
this.test = function () {
|
||||
console.log("插件函数执行测试");
|
||||
console.log(this);
|
||||
this._afterLoadResources = function () {
|
||||
// 本函数将在所有资源加载完毕后,游戏开启前被执行
|
||||
// 可以在这个函数里面对资源进行一些操作,比如切分图片等。
|
||||
|
||||
// 这是一个将assets.png拆分成若干个32x32像素的小图片并保存的样例。
|
||||
// var arr = core.splitImage("assets.png", 32, 32);
|
||||
// for (var i = 0; i < arr.length; i++) {
|
||||
// core.material.images.images["asset"+i+".png"] = arr[i];
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
// 可以在任何地方(如afterXXX或自定义脚本事件)调用函数,方法为 core.plugin.xxx();
|
||||
// 从V2.6开始,插件中用this.XXX方式定义的函数也会被转发到core中,详见文档-脚本-函数的转发。
|
||||
},
|
||||
"drawLight": function () {
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user