Merge remote-tracking branch 'refs/remotes/ckcz123/v2.0' into refactoring-editor
This commit is contained in:
commit
28c678d1c4
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,4 +3,5 @@
|
|||||||
- [元件说明](element)
|
- [元件说明](element)
|
||||||
- [事件](event)
|
- [事件](event)
|
||||||
- [个性化](personalization)
|
- [个性化](personalization)
|
||||||
|
- [脚本](script)
|
||||||
- [附录:API列表](api)
|
- [附录:API列表](api)
|
||||||
|
|||||||
2457
_docs/api.md
2457
_docs/api.md
File diff suppressed because it is too large
Load Diff
716
_docs/event.md
716
_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/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,6 +1,6 @@
|
|||||||
# 个性化
|
# 个性化
|
||||||
|
|
||||||
?> 目前版本**v2.5.5**,上次更新时间:* {docsify-updated} *
|
?> 目前版本**v2.6**,上次更新时间:* {docsify-updated} *
|
||||||
|
|
||||||
有时候只靠样板本身可能是不够的。我们需要一些个性化、自定义的素材,道具效果,怪物属性,等等。
|
有时候只靠样板本身可能是不够的。我们需要一些个性化、自定义的素材,道具效果,怪物属性,等等。
|
||||||
|
|
||||||
@ -21,10 +21,14 @@ HTML5魔塔是使用画布(canvas)来绘制,存在若干个图层,它们
|
|||||||
- route**[D]**:路线层;主要用来绘制勇士的行走路线图。 (z-index: 95)
|
- route**[D]**:路线层;主要用来绘制勇士的行走路线图。 (z-index: 95)
|
||||||
- paint**[D]**:绘图层;主要用来进行绘图模式。(z-index: 95)
|
- paint**[D]**:绘图层;主要用来进行绘图模式。(z-index: 95)
|
||||||
- curtain:色调层;用来控制当前楼层的画面色调 (z-index: 125)
|
- curtain:色调层;用来控制当前楼层的画面色调 (z-index: 125)
|
||||||
- image1\~50**[D]**:图片层;用来绘制图片等操作。(z-index: 100+code, 101~150;也就是图片编号在1~25的在色调层之下,26~50的在色调层之上)
|
- image1\~50**[D]**:图片层;用来绘制图片等操作。(z-index: 100+code, 101~150)
|
||||||
- ui:UI层;用来绘制一切UI窗口,如剧情文本、怪物手册、楼传器、系统菜单等等 (z-index: 160)
|
- ui:UI层;用来绘制一切UI窗口,如剧情文本、怪物手册、楼传器、系统菜单等等 (z-index: 140)
|
||||||
- data:数据层;用来绘制一些顶层的或更新比较快的数据,如左上角的提示,战斗界面中数据的变化等等。 (z-index: 170)
|
- data:数据层;用来绘制一些顶层的或更新比较快的数据,如左上角的提示,战斗界面中数据的变化等等。 (z-index: 170)
|
||||||
|
|
||||||
|
请注意:显示图片事件将自动创建一个图片层,z-index是100+图片编号。
|
||||||
|
|
||||||
|
而,色调层的z-index是25,ui层的z-index是140;因此,图片编号在1~24的将被色调层遮挡,25~40的将被ui层遮挡,41~50的将遮挡UI层。
|
||||||
|
|
||||||
### 动态创建canvas
|
### 动态创建canvas
|
||||||
|
|
||||||
从V2.5.3开始,可以在H5样板中任意动态创建canvas并进行使用。
|
从V2.5.3开始,可以在H5样板中任意动态创建canvas并进行使用。
|
||||||
@ -104,11 +108,11 @@ core.fillText('test', '这是一段文字', 10, 30, '#FF0000', '16px Verdana');
|
|||||||
从V2.5.4开始,贴图也允许进行帧动画,只要设置第五项的数值。
|
从V2.5.4开始,贴图也允许进行帧动画,只要设置第五项的数值。
|
||||||
|
|
||||||
``` js
|
``` js
|
||||||
"images": [[96,120,"bg.jpg",0]], // 背景图;你可以选择一张或多张图片来作为背景/前景素材。
|
[[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在前景层
|
[[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,则会自动调节遮挡效果
|
[[96,120,"tree.png",2]] // 如果写2,则会自动调节遮挡效果
|
||||||
"images": [[64,0,"x.png",1,4]] // 这是一个前景层的4帧动画贴图
|
[[64,0,"x.png",1,4]] // 这是一个前景层的4帧动画贴图
|
||||||
```
|
```
|
||||||
|
|
||||||
images为一个数组,代表当前层所有作为背景素材的图片信息。每一项为一个五元组,分别为该背景素材的x,y,图片名,遮挡方式和帧数。
|
images为一个数组,代表当前层所有作为背景素材的图片信息。每一项为一个五元组,分别为该背景素材的x,y,图片名,遮挡方式和帧数。
|
||||||
@ -129,18 +133,21 @@ images为一个数组,代表当前层所有作为背景素材的图片信息
|
|||||||
|
|
||||||
关于楼层贴图和前景、背景层的层叠覆盖关系,默认是:**地板 - 背景贴图 - 背景图块 - 事件 - 勇士 - 前景贴图 - 前景图块**。
|
关于楼层贴图和前景、背景层的层叠覆盖关系,默认是:**地板 - 背景贴图 - 背景图块 - 事件 - 勇士 - 前景贴图 - 前景图块**。
|
||||||
|
|
||||||
可以通过修改`libs/maps.js`的`drawMap`函数中下面三行的顺序来改变其覆盖关系。
|
可以通过修改`libs/maps.js`的`drawBg`和`drawFg`函数来改变其覆盖关系。
|
||||||
|
|
||||||
``` js
|
``` js
|
||||||
// ----- 可以调整这三行的顺序来修改覆盖关系;同层画布上,后绘制的覆盖先绘制的
|
////// 绘制背景层 //////
|
||||||
// ----- ui.js的drawThumbnail函数也需要对应进行修改。
|
maps.prototype.drawBg = function (floorId, ctx) {
|
||||||
|
var onMap = ctx == null;
|
||||||
// 绘制楼层贴图
|
if (onMap) {
|
||||||
core.maps.drawFloorImages(floorId, images);
|
ctx = core.canvas.bg;
|
||||||
// 绘制背景层图块
|
core.clearMap(ctx);
|
||||||
core.maps.drawBgFgMap(floorId, core.canvas.bg, "bg", true);
|
}
|
||||||
// 绘制前景层图块
|
this._drawBg_drawBackground(floorId, ctx);
|
||||||
core.maps.drawBgFgMap(floorId, core.canvas.fg, "fg", true);
|
// ------ 调整这两行的顺序来控制是先绘制贴图还是先绘制背景图块;后绘制的覆盖先绘制的。
|
||||||
|
this._drawFloorImages(floorId, ctx, 'bg');
|
||||||
|
this._drawBgFgMap(floorId, ctx, 'bg', onMap);
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
楼层贴图可以被事件隐藏和显示,详见[隐藏贴图](event#hideFloorImg:隐藏贴图)的写法。
|
楼层贴图可以被事件隐藏和显示,详见[隐藏贴图](event#hideFloorImg:隐藏贴图)的写法。
|
||||||
@ -192,7 +199,7 @@ ID必须由数字字母下划线组成,数字在1000以内,且均不能和
|
|||||||
|
|
||||||
之后刷新编辑器即可。
|
之后刷新编辑器即可。
|
||||||
|
|
||||||
对于怪物和道具,我们也可以进行自动注册,只需要点击“自动注册”按钮,将对该栏下所有未注册的素材进行自动注册(自动分配ID和数字)。
|
我们也可以进行自动注册,只需要点击“自动注册”按钮,将对该栏下所有未注册的素材进行自动注册(自动分配ID和数字)。
|
||||||
|
|
||||||
素材注册完毕后,即可在游戏中正常使用,也可以被地图生成器所识别(需要重开地图生成器)。
|
素材注册完毕后,即可在游戏中正常使用,也可以被地图生成器所识别(需要重开地图生成器)。
|
||||||
|
|
||||||
@ -206,85 +213,6 @@ ID必须由数字字母下划线组成,数字在1000以内,且均不能和
|
|||||||
2. 下拉框选择autotile,然后点“追加”
|
2. 下拉框选择autotile,然后点“追加”
|
||||||
3. 看到成功的提示后刷新编辑器即可。
|
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魔塔样板开始支持额外素材。
|
从V2.4.2开始,HTML5魔塔样板开始支持额外素材。
|
||||||
@ -300,6 +228,7 @@ ID必须由数字字母下划线组成,数字在1000以内,且均不能和
|
|||||||
**该素材的宽高必须都是32的倍数,且图片上的总图块数不超过1000(即最多有1000个32*32的图块在该图片上)。**
|
**该素材的宽高必须都是32的倍数,且图片上的总图块数不超过1000(即最多有1000个32*32的图块在该图片上)。**
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
// 在全塔属性中的tilesets导入素材
|
||||||
"tilesets": ["1.png", "2.png"] // 导入两个额外素材,文件名分别是1.png和2.png
|
"tilesets": ["1.png", "2.png"] // 导入两个额外素材,文件名分别是1.png和2.png
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -350,19 +279,6 @@ core.status.hero.atk += core.values.redJewel + 2*ratio
|
|||||||
|
|
||||||
具体过程比较复杂,需要一定的JS能力,在这里就不多说了,有需求可以找`艾之葵`进行了解。
|
具体过程比较复杂,需要一定的JS能力,在这里就不多说了,有需求可以找`艾之葵`进行了解。
|
||||||
|
|
||||||
但值得一提的是,我们可以使用`core.hasItem(name)` 来判断是否某个道具是否存在。例如下面是passNet(通过路障处理)的一部分:
|
|
||||||
|
|
||||||
``` js
|
|
||||||
/****** 经过路障 ******/
|
|
||||||
events.prototype.passNet = function (data) {
|
|
||||||
// 有鞋子
|
|
||||||
if (core.hasItem('shoes')) return;
|
|
||||||
if (data.event.id=='lavaNet') { // 血网
|
|
||||||
// ... 下略
|
|
||||||
```
|
|
||||||
|
|
||||||
我们进行了一个简单的判断,如果拥有绿鞋,则不进行任何路障的处理。
|
|
||||||
|
|
||||||
### 实战!拿到神圣盾后免疫吸血、领域、夹击效果
|
### 实战!拿到神圣盾后免疫吸血、领域、夹击效果
|
||||||
|
|
||||||
1. 在itemEffect中修改拿到神圣盾时的效果,标记一个自定义Flag。
|
1. 在itemEffect中修改拿到神圣盾时的效果,标记一个自定义Flag。
|
||||||
@ -421,109 +337,20 @@ function (enemy, hero_hp, hero_atk, hero_def, hero_mdef, x, y, floorId) {
|
|||||||
|
|
||||||
对于特殊的塔,我们可以考虑修改楼传事件来完成一些特殊的要求,比如镜子可以按楼传来切换表里。
|
对于特殊的塔,我们可以考虑修改楼传事件来完成一些特殊的要求,比如镜子可以按楼传来切换表里。
|
||||||
|
|
||||||
要修改楼传事件,需要进行如下几步:
|
要修改楼传事件,需要进行如下两步:
|
||||||
|
|
||||||
1. 截获楼传的点击事件。在control.js中找到useFly函数,并将其替换成如下内容:
|
1. 重写楼传的点击事件。在插件中对`core.control.useFly进行重写`。详细代码参见[重写点击楼传事件](script#重写点击楼传事件)。
|
||||||
``` 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);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
2. 修改楼传的使用事件。和其他永久道具一样,在地图编辑器的图块属性中修改楼传的useItemEffect和canUseItemEffect两个内容。例如:
|
2. 修改楼传的使用事件。和其他永久道具一样,在地图编辑器的图块属性中修改楼传的useItemEffect和canUseItemEffect两个内容。例如:
|
||||||
``` js
|
``` js
|
||||||
"useItemEffect": "core.insertAction([...])" // 执行某段自定义事件,或者其他脚本
|
"useItemEffect": "core.insertAction([...])" // 执行某段自定义事件,或者其他脚本
|
||||||
"canUseItemEffect": "true" // 任何时候可用
|
"canUseItemEffect": "true" // 任何时候可用
|
||||||
```
|
```
|
||||||
修改时,请先把`null`改成空字符串`""`,然后再双击进行编辑。
|
|
||||||
|
|
||||||
<!--
|
除了覆盖楼传事件外,对于快捷商店、虚拟键盘等等也可以进行覆盖,只不过是仿照上述代码重写对应的函数(`openQuickShop`,`openKeyBoard`)即可。
|
||||||
|
|
||||||
## 自定义装备
|
|
||||||
|
|
||||||
由于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+正整数的形式,不然会出错!
|
|
||||||
|
|
||||||
-->
|
|
||||||
|
|
||||||
## 自定义怪物属性
|
## 自定义怪物属性
|
||||||
|
|
||||||
如果你对现有的怪物不满意,想自行添加怪物属性也是可以的。具体参见脚本编辑-getSpecials。
|
如果你对现有的怪物不满意,想自行添加怪物属性也是可以的。具体参见脚本编辑的getSpecials。
|
||||||
|
|
||||||
你需自己指定一个special数字,修改属性名和属性提示文字。后两者可以直接写字符串,或写个函数传入怪物。
|
你需自己指定一个special数字,修改属性名和属性提示文字。后两者可以直接写字符串,或写个函数传入怪物。
|
||||||
|
|
||||||
@ -552,7 +379,8 @@ case 89: // 使用该按键的keyCode,比如Y键就是89
|
|||||||
// ... 在这里写你要执行脚本
|
// ... 在这里写你要执行脚本
|
||||||
// **强烈建议所有新增的自定义快捷键均能给个对应的道具可点击,以方便手机端的行为**
|
// **强烈建议所有新增的自定义快捷键均能给个对应的道具可点击,以方便手机端的行为**
|
||||||
if (core.hasItem('...')) {
|
if (core.hasItem('...')) {
|
||||||
core.useItem('...');
|
core.status.route.push("key:0"); // 记录按键到录像中
|
||||||
|
core.useItem('...', true); // 第二个参数true代表该次使用道具是被按键触发的,使用过程不计入录像
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -560,6 +388,10 @@ case 89: // 使用该按键的keyCode,比如Y键就是89
|
|||||||
|
|
||||||
强烈建议所有新增的自定义快捷键均给个对应的永久道具可点击,以方便手机端的行为。
|
强烈建议所有新增的自定义快捷键均给个对应的永久道具可点击,以方便手机端的行为。
|
||||||
|
|
||||||
|
使用`core.status.route.push("key:"+keyCode)`可以将这次按键记录在录像中。
|
||||||
|
|
||||||
|
!> 如果记录了按键,且使用道具的话,需要将useItem的第二个参数设为true,避免重复记录!
|
||||||
|
|
||||||
可以使用altKey来判断Alt键是否被同时按下。
|
可以使用altKey来判断Alt键是否被同时按下。
|
||||||
|
|
||||||
## 公共事件
|
## 公共事件
|
||||||
@ -574,13 +406,9 @@ case 89: // 使用该按键的keyCode,比如Y键就是89
|
|||||||
|
|
||||||
## 插件系统
|
## 插件系统
|
||||||
|
|
||||||
在H5中,提供了“插件”系统。具体参见“脚本编辑 - 插件编写”。
|
在H5中,提供了“插件”系统。在V2.6中提供了一个插件下拉框,用户可以自行创建和写插件。
|
||||||
|
|
||||||

|
在插件编写的过程中,我们可以使用任何[常见API](api)里面的代码调用;也可以通过`core.insertAction`来插入自定义事件执行。
|
||||||
|
|
||||||
当我们在这上面定义了自己需要的函数(插件后),就可以通过任何方式进行调用。
|
|
||||||
|
|
||||||
在这个插件编写的过程中,我们可以使用任何[常见API](api)里面的代码调用;也可以通过`core.insertAction`来插入自定义事件执行。
|
|
||||||
|
|
||||||
下面是一个很简单的例子,我编写一个插件函数,其效果是让勇士生命值变成原来的x倍,并令面前的图块消失。
|
下面是一个很简单的例子,我编写一个插件函数,其效果是让勇士生命值变成原来的x倍,并令面前的图块消失。
|
||||||
|
|
||||||
@ -599,11 +427,13 @@ this.myfunc = function(x) {
|
|||||||
|
|
||||||
网站上也提供了一个[插件库](https://h5mota.com/plugins/),欢迎大家把自己写的插件进行共享。
|
网站上也提供了一个[插件库](https://h5mota.com/plugins/),欢迎大家把自己写的插件进行共享。
|
||||||
|
|
||||||
|
从V2.6开始,在插件中用`this.xxx`定义的函数将会被转发到core中。例如上述的`myfunc`除了`core.plugin.myfunc`外也可以直接`core.myfunc`调用。
|
||||||
|
|
||||||
|
详见[函数的转发](script#函数的转发)。
|
||||||
|
|
||||||
## 标题界面事件化
|
## 标题界面事件化
|
||||||
|
|
||||||
从V2.5.3开始,我们可以将标题界面的绘制和游戏开始用事件来完成。可以通过绘制画布、
|
从V2.5.3开始,我们可以将标题界面的绘制和游戏开始用事件来完成。可以通过绘制画布、全塔属性,flags中的startUsingCanvas可以决定是否开启标题界面事件化。
|
||||||
|
|
||||||
全塔属性,flags中的startUsingCanvas可以决定是否开启标题界面事件化。
|
|
||||||
|
|
||||||
然后就可以使用“事件流”的形式来绘制标题界面、提供选项等等。
|
然后就可以使用“事件流”的形式来绘制标题界面、提供选项等等。
|
||||||
|
|
||||||
@ -619,36 +449,70 @@ this.myfunc = function(x) {
|
|||||||
|
|
||||||
从V2.5.3以后,我们可以给手机端增加按键了,这样将非常有利于技能的释放。
|
从V2.5.3以后,我们可以给手机端增加按键了,这样将非常有利于技能的释放。
|
||||||
|
|
||||||
当用户在竖屏模式下点击工具栏,就会在工具栏按钮和快捷键模式之间进行切换。
|
用户在菜单栏打开“拓展键盘”后,在竖屏模式下点击工具栏,就会在工具栏按钮和快捷键模式之间进行切换。
|
||||||
|
|
||||||
切换到快捷键模式后,可以点1-7,分别等价于在电脑端按键1-7。
|
切换到快捷键模式后,可以点1-8,分别等价于在电脑端按键1-8。
|
||||||
|
|
||||||
可以在脚本编辑的onKeyUp中定义每个快捷键的使用效果,比如使用道具或释放技能等。
|
可以在脚本编辑的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)等等。
|
在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为例。
|
1. 定义ID;比如攻速我就定义speed,暴击可以简单的定义baoji;你也可以定义其他的ID,但是不能和已有的重复。这里以speed为例。
|
||||||
2. 在index.html的statusBar中(44行起),进行该状态栏项的定义。仿照其他几项,插在其应当显示的位置,注意替换掉相应的ID。
|
2. 在index.html的statusBar中(46行起),进行该状态栏项的定义。仿照其他几项,插在其应当显示的位置,注意替换掉相应的ID。
|
||||||
``` html
|
``` html
|
||||||
<div class="status" id="speedCol">
|
<div class="status" id="speedCol">
|
||||||
<img id="img-speed">
|
<img id="img-speed">
|
||||||
<p class='statusLabel' id='speed'></p>
|
<p class='statusLabel' id='speed'></p>
|
||||||
</div>
|
</div>
|
||||||
```
|
```
|
||||||
3. 在editor.html中的statusBar(323行起),仿照第二点同样添加;这一项如果不进行则会地图编辑器报错。editor-mobile.html同理。
|
3. 在editor.html中的statusBar(383行起),仿照第二点同样添加;这一项如果不进行则会地图编辑器报错。editor-mobile.html同理。
|
||||||
4. 使用便捷PS工具,打开icons.png,新增一行并将魔力的图标P上去;记下其索引比如37(从0开始数)。
|
4. 使用便捷PS工具,打开project/icons.png,新增一行并将魔力的图标P上去;记下其索引比如37(从0开始数)。
|
||||||
5. 在main.js的this.statusBar中增加图片、图标和内容的定义。
|
5. 在main.js的this.statusBar中增加图片、图标和内容的定义。
|
||||||
``` js
|
``` js
|
||||||
this.statusBar = {
|
this.statusBar = {
|
||||||
@ -674,17 +538,15 @@ core.statusBar.speed.innerHTML = core.getFlag('speed', 0);
|
|||||||
|
|
||||||
## 技能塔的支持
|
## 技能塔的支持
|
||||||
|
|
||||||
其实,在HTML5上制作技能塔是完全可行的。
|
|
||||||
|
|
||||||
要支持技能塔,可能需要如下几个方面:
|
要支持技能塔,可能需要如下几个方面:
|
||||||
|
|
||||||
|
从V2.5开始,内置了"二倍斩"技能,可以仿照其制作自己的技能。
|
||||||
|
|
||||||
- 魔力(和上限)的添加;技能的定义
|
- 魔力(和上限)的添加;技能的定义
|
||||||
- 状态栏的显示
|
- 状态栏的显示
|
||||||
- 技能的触发(按键与录像问题)
|
- 技能的触发(按键与录像问题)
|
||||||
- 技能的效果
|
- 技能的效果
|
||||||
|
|
||||||
从V2.5开始,内置了"二倍斩"技能,可以仿照其制作自己的技能。
|
|
||||||
|
|
||||||
### 魔力的定义添加;技能的定义
|
### 魔力的定义添加;技能的定义
|
||||||
|
|
||||||
从V2.5开始,提供了status:mana选项,可以直接代表当前魔力值。
|
从V2.5开始,提供了status:mana选项,可以直接代表当前魔力值。
|
||||||
@ -697,6 +559,8 @@ core.statusBar.speed.innerHTML = core.getFlag('speed', 0);
|
|||||||
|
|
||||||
如果flag:skill不为0,则代表当前处于某个技能开启状态,且状态栏显示flag:skillName值。伤害计算函数中只需要对flag:skill进行处理即可。
|
如果flag:skill不为0,则代表当前处于某个技能开启状态,且状态栏显示flag:skillName值。伤害计算函数中只需要对flag:skill进行处理即可。
|
||||||
|
|
||||||
|
!> 关于魔力上限:样板中默认没有提供status:manamax
|
||||||
|
|
||||||
### 状态栏的显示
|
### 状态栏的显示
|
||||||
|
|
||||||
从V2.5开始,魔力值和技能名的状态栏项目已经被添加,可以直接使用。
|
从V2.5开始,魔力值和技能名的状态栏项目已经被添加,可以直接使用。
|
||||||
@ -706,9 +570,14 @@ core.statusBar.speed.innerHTML = core.getFlag('speed', 0);
|
|||||||
``` js
|
``` js
|
||||||
// 设置魔力值
|
// 设置魔力值
|
||||||
if (core.flags.enableMana) {
|
if (core.flags.enableMana) {
|
||||||
// 也可以使用flag:manaMax来表示最大魔力值
|
// status:manamax 只有在非负时才生效。
|
||||||
// core.status.hero.mana = Math.max(core.status.hero.mana, core.getFlag('manaMax', 10));
|
if (core.status.hero.manamax != null && core.status.hero.manamax >= 0) {
|
||||||
// core.statusBar.mana.innerHTML = core.status.hero.mana + "/" + core.getFlag('manaMax', 10);
|
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) {
|
if (core.flags.enableSkill) {
|
||||||
@ -761,14 +630,15 @@ else { // 关闭技能
|
|||||||
case 87: // W:开启技能“二倍斩”
|
case 87: // W:开启技能“二倍斩”
|
||||||
// 检测技能栏是否开启,是否拥有“二倍斩”这个技能道具
|
// 检测技能栏是否开启,是否拥有“二倍斩”这个技能道具
|
||||||
if (core.flags.enableSkill && core.hasItem('skill1')) {
|
if (core.flags.enableSkill && core.hasItem('skill1')) {
|
||||||
core.useItem('skill1');
|
core.status.route.push("key:87");
|
||||||
|
core.useItem('skill1', true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
```
|
```
|
||||||
|
|
||||||
在勇士处于停止的条件下,按下W键时,判断技能的道具是否存在,如果存在再使用它。
|
在勇士处于停止的条件下,按下W键时,判断技能的道具是否存在,如果存在再使用它。
|
||||||
|
|
||||||
!> 1,2,3这三个键被默认绑定到了破炸飞;如果想用的话也是一样,只不过是把已有的实现进行替换。
|
!> 由于现在手机端存在拓展键盘,也强烈建议直接覆盖1-8的使用效果,这样手机端使用也非常方便。
|
||||||
|
|
||||||
### 技能的效果
|
### 技能的效果
|
||||||
|
|
||||||
@ -816,141 +686,6 @@ if (core.flags.enableSkill) {
|
|||||||
|
|
||||||
通过上述这几种方式,我们就能成功的让H5支持技能啦!
|
通过上述这几种方式,我们就能成功的让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变量都可以任意定义并取用(未定义直接取用的flag默认值为0)。
|
众所周知,自定义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)
|
||||||
|
|
||||||
|
|
||||||
@ -305,8 +305,8 @@ action
|
|||||||
| moveImage_s
|
| moveImage_s
|
||||||
| showGif_0_s
|
| showGif_0_s
|
||||||
| showGif_1_s
|
| showGif_1_s
|
||||||
| setFg_0_s
|
| setCurtain_0_s
|
||||||
| setFg_1_s
|
| setCurtain_1_s
|
||||||
| screenFlash_s
|
| screenFlash_s
|
||||||
| setWeather_s
|
| setWeather_s
|
||||||
| move_s
|
| move_s
|
||||||
@ -324,6 +324,7 @@ action
|
|||||||
| win_s
|
| win_s
|
||||||
| lose_s
|
| lose_s
|
||||||
| if_s
|
| if_s
|
||||||
|
| if_1_s
|
||||||
| switch_s
|
| switch_s
|
||||||
| while_s
|
| while_s
|
||||||
| break_s
|
| break_s
|
||||||
@ -1278,35 +1279,35 @@ var code = '{"type": "moveImage", "code": '+Int_0+toloc+EvalString_0+',"time": '
|
|||||||
return code;
|
return code;
|
||||||
*/;
|
*/;
|
||||||
|
|
||||||
setFg_0_s
|
setCurtain_0_s
|
||||||
: '更改画面色调' EvalString Colour '动画时间' Int? '不等待执行完毕' Bool Newline
|
: '更改画面色调' EvalString Colour '动画时间' Int? '不等待执行完毕' Bool Newline
|
||||||
|
|
||||||
|
|
||||||
/* setFg_0_s
|
/* setCurtain_0_s
|
||||||
tooltip : setFg: 更改画面色调,动画时间可不填
|
tooltip : setCurtain: 更改画面色调,动画时间可不填
|
||||||
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
|
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]
|
default : ["255,255,255,1",'rgba(255,255,255,1)',500,false]
|
||||||
colour : this.soundColor
|
colour : this.soundColor
|
||||||
var colorRe = /^(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(,0(\.\d+)?|,1)?$/;
|
var colorRe = /^(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');
|
if (!colorRe.test(EvalString_0))throw new Error('颜色格式错误,形如:0~255,0~255,0~255,0~1');
|
||||||
Int_0 = Int_0!=='' ?(', "time": '+Int_0):'';
|
Int_0 = Int_0!=='' ?(', "time": '+Int_0):'';
|
||||||
var async = Bool_0?', "async": true':'';
|
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;
|
return code;
|
||||||
*/;
|
*/;
|
||||||
|
|
||||||
setFg_1_s
|
setCurtain_1_s
|
||||||
: '恢复画面色调' '动画时间' Int? '不等待执行完毕' Bool Newline
|
: '恢复画面色调' '动画时间' Int? '不等待执行完毕' Bool Newline
|
||||||
|
|
||||||
|
|
||||||
/* setFg_1_s
|
/* setCurtain_1_s
|
||||||
tooltip : setFg: 恢复画面色调,动画时间可不填
|
tooltip : setCurtain: 恢复画面色调,动画时间可不填
|
||||||
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
|
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]
|
default : [500,false]
|
||||||
colour : this.soundColor
|
colour : this.soundColor
|
||||||
Int_0 = Int_0!=='' ?(', "time": '+Int_0):'';
|
Int_0 = Int_0!=='' ?(', "time": '+Int_0):'';
|
||||||
var async = Bool_0?', "async": true':'';
|
var async = Bool_0?', "async": true':'';
|
||||||
var code = '{"type": "setFg"'+Int_0 +async+'},\n';
|
var code = '{"type": "setCurtain"'+Int_0 +async+'},\n';
|
||||||
return code;
|
return code;
|
||||||
*/;
|
*/;
|
||||||
|
|
||||||
@ -1482,15 +1483,16 @@ return code;
|
|||||||
*/;
|
*/;
|
||||||
|
|
||||||
playSound_s
|
playSound_s
|
||||||
: '播放音效' EvalString Newline
|
: '播放音效' EvalString '停止之前音效' Bool? Newline
|
||||||
|
|
||||||
|
|
||||||
/* playSound_s
|
/* playSound_s
|
||||||
tooltip : playSound: 播放音效
|
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
|
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
|
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;
|
return code;
|
||||||
*/;
|
*/;
|
||||||
|
|
||||||
@ -1587,6 +1589,20 @@ var code = ['{"type": "if", "condition": "',expression_0,'",\n',
|
|||||||
return code;
|
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
|
switch_s
|
||||||
: '多重分歧 条件判定' ':' expression BGNL? Newline switchCase+ BEND Newline
|
: '多重分歧 条件判定' ':' expression BGNL? Newline switchCase+ BEND Newline
|
||||||
|
|
||||||
@ -1603,14 +1619,16 @@ return code;
|
|||||||
*/;
|
*/;
|
||||||
|
|
||||||
switchCase
|
switchCase
|
||||||
: '如果是' expression '的场合' BGNL? Newline action+
|
: '如果是' expression '的场合' '不跳出' Bool BGNL? Newline action+
|
||||||
|
|
||||||
|
|
||||||
/* switchCase
|
/* switchCase
|
||||||
tooltip : 选项的选择
|
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
|
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
|
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;
|
return code;
|
||||||
*/;
|
*/;
|
||||||
|
|
||||||
@ -1639,13 +1657,13 @@ return code;
|
|||||||
*/;
|
*/;
|
||||||
|
|
||||||
choicesContext
|
choicesContext
|
||||||
: '子选项' EvalString '图标' IdString? '颜色' EvalString? Colour '不跳出' Bool BGNL? Newline action+
|
: '子选项' EvalString '图标' IdString? '颜色' EvalString? Colour BGNL? Newline action+
|
||||||
|
|
||||||
|
|
||||||
/* choicesContext
|
/* choicesContext
|
||||||
tooltip : 选项的选择
|
tooltip : 选项的选择
|
||||||
helpUrl : https://h5mota.com/games/template/docs/#/event?id=choices%EF%BC%9A%E7%BB%99%E7%94%A8%E6%88%B7%E6%8F%90%E4%BE%9B%E9%80%89%E9%A1%B9
|
helpUrl : https://h5mota.com/games/template/docs/#/event?id=choices%EF%BC%9A%E7%BB%99%E7%94%A8%E6%88%B7%E6%8F%90%E4%BE%9B%E9%80%89%E9%A1%B9
|
||||||
default : ["提示文字:红钥匙","","",null,false]
|
default : ["提示文字:红钥匙","",""]
|
||||||
colour : this.subColor
|
colour : this.subColor
|
||||||
if (EvalString_1) {
|
if (EvalString_1) {
|
||||||
var colorRe = /^(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(,0(\.\d+)?|,1)?$/;
|
var colorRe = /^(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)?$/;
|
||||||
@ -1655,19 +1673,19 @@ if (EvalString_1) {
|
|||||||
EvalString_1 = ', "color": "'+EvalString_1+'"';
|
EvalString_1 = ', "color": "'+EvalString_1+'"';
|
||||||
}
|
}
|
||||||
IdString_0 = IdString_0?(', "icon": "'+IdString_0+'"'):'';
|
IdString_0 = IdString_0?(', "icon": "'+IdString_0+'"'):'';
|
||||||
var nobreak = Bool_0?', "nobreak": true':'';
|
var code = '{"text": "'+EvalString_0+'"'+IdString_0+EvalString_1+', "action": [\n'+action_0+']},\n';
|
||||||
var code = '{"text": "'+EvalString_0+'"'+IdString_0+EvalString_1+', "action": [\n'+action_0+']'+nobreak+'},\n';
|
|
||||||
return code;
|
return code;
|
||||||
*/;
|
*/;
|
||||||
|
|
||||||
confirm_s
|
confirm_s
|
||||||
: '显示确认框' ':' EvalString BGNL? '确定' ':' BGNL? Newline action+ '取消' ':' BGNL? Newline action+ BEND Newline
|
: '显示确认框' ':' EvalString BGNL? '确定的场合' ':' '(默认选中' Bool ')' BGNL? Newline action+ '取消的场合' ':' BGNL? Newline action+ BEND Newline
|
||||||
|
|
||||||
/* confirm_s
|
/* confirm_s
|
||||||
tooltip : 弹出确认框
|
tooltip : 弹出确认框
|
||||||
helpUrl : https://h5mota.com/games/template/docs/#/
|
helpUrl : https://h5mota.com/games/template/docs/#/
|
||||||
default : ["确认要???吗?"]
|
default : ["确认要xxx吗?",false]
|
||||||
var code = ['{"type": "confirm", "text": "',EvalString_0,'",\n',
|
Bool_0 = Bool_0?', "default": true':''
|
||||||
|
var code = ['{"type": "confirm"'+Bool_0+', "text": "',EvalString_0,'",\n',
|
||||||
'"yes": [\n',action_0,'],\n',
|
'"yes": [\n',action_0,'],\n',
|
||||||
'"no": [\n',action_1,']\n',
|
'"no": [\n',action_1,']\n',
|
||||||
'},\n'].join('');
|
'},\n'].join('');
|
||||||
@ -2448,11 +2466,12 @@ ActionParser.prototype.parseAction = function() {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "setFg": // 颜色渐变
|
case "setFg": // 颜色渐变
|
||||||
|
case "setCurtain":
|
||||||
if(this.isset(data.color)){
|
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]);
|
data.color,'rgba('+data.color+')',data.time||0,data.async||false,this.next]);
|
||||||
} else {
|
} else {
|
||||||
this.next = MotaActionBlocks['setFg_1_s'].xmlText([
|
this.next = MotaActionBlocks['setCurtain_1_s'].xmlText([
|
||||||
data.time||0,data.async||false,this.next]);
|
data.time||0,data.async||false,this.next]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2511,7 +2530,7 @@ ActionParser.prototype.parseAction = function() {
|
|||||||
break;
|
break;
|
||||||
case "playSound":
|
case "playSound":
|
||||||
this.next = MotaActionBlocks['playSound_s'].xmlText([
|
this.next = MotaActionBlocks['playSound_s'].xmlText([
|
||||||
data.name,this.next]);
|
data.name,data.stop,this.next]);
|
||||||
break;
|
break;
|
||||||
case "playBgm":
|
case "playBgm":
|
||||||
this.next = MotaActionBlocks['playBgm_s'].xmlText([
|
this.next = MotaActionBlocks['playBgm_s'].xmlText([
|
||||||
@ -2579,16 +2598,23 @@ ActionParser.prototype.parseAction = function() {
|
|||||||
data.text,this.next]);
|
data.text,this.next]);
|
||||||
break;
|
break;
|
||||||
case "if": // 条件判断
|
case "if": // 条件判断
|
||||||
this.next = MotaActionBlocks['if_s'].xmlText([
|
if (data["false"]) {
|
||||||
// MotaActionBlocks['evalString_e'].xmlText([data.condition]),
|
this.next = MotaActionBlocks['if_s'].xmlText([
|
||||||
this.tryToUseEvFlag_e('evalString_e', [data.condition]),
|
this.tryToUseEvFlag_e('evalString_e', [data.condition]),
|
||||||
this.insertActionList(data["true"]),
|
this.insertActionList(data["true"]),
|
||||||
this.insertActionList(data["false"]),
|
this.insertActionList(data["false"]),
|
||||||
this.next]);
|
this.next]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.next = MotaActionBlocks['if_1_s'].xmlText([
|
||||||
|
this.tryToUseEvFlag_e('evalString_e', [data.condition]),
|
||||||
|
this.insertActionList(data["true"]),
|
||||||
|
this.next]);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case "confirm": // 显示确认框
|
case "confirm": // 显示确认框
|
||||||
this.next = MotaActionBlocks['confirm_s'].xmlText([
|
this.next = MotaActionBlocks['confirm_s'].xmlText([
|
||||||
this.EvalString(data.text),
|
this.EvalString(data.text), data["default"],
|
||||||
this.insertActionList(data["yes"]),
|
this.insertActionList(data["yes"]),
|
||||||
this.insertActionList(data["no"]),
|
this.insertActionList(data["no"]),
|
||||||
this.next]);
|
this.next]);
|
||||||
@ -2597,7 +2623,7 @@ ActionParser.prototype.parseAction = function() {
|
|||||||
var case_caseList = null;
|
var case_caseList = null;
|
||||||
for(var ii=data.caseList.length-1,caseNow;caseNow=data.caseList[ii];ii--) {
|
for(var ii=data.caseList.length-1,caseNow;caseNow=data.caseList[ii];ii--) {
|
||||||
case_caseList=MotaActionBlocks['switchCase'].xmlText([
|
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([
|
this.next = MotaActionBlocks['switch_s'].xmlText([
|
||||||
// MotaActionBlocks['evalString_e'].xmlText([data.condition]),
|
// MotaActionBlocks['evalString_e'].xmlText([data.condition]),
|
||||||
@ -2608,7 +2634,7 @@ ActionParser.prototype.parseAction = function() {
|
|||||||
var text_choices = null;
|
var text_choices = null;
|
||||||
for(var ii=data.choices.length-1,choice;choice=data.choices[ii];ii--) {
|
for(var ii=data.choices.length-1,choice;choice=data.choices[ii];ii--) {
|
||||||
text_choices=MotaActionBlocks['choicesContext'].xmlText([
|
text_choices=MotaActionBlocks['choicesContext'].xmlText([
|
||||||
choice.text,choice.icon,choice.color,'rgba('+choice.color+')',choice.nobreak,this.insertActionList(choice.action),text_choices]);
|
choice.text,choice.icon,choice.color,'rgba('+choice.color+')',this.insertActionList(choice.action),text_choices]);
|
||||||
}
|
}
|
||||||
this.next = MotaActionBlocks['choices_s'].xmlText([
|
this.next = MotaActionBlocks['choices_s'].xmlText([
|
||||||
this.isset(data.text)?this.EvalString(data.text):null,'','',text_choices,this.next]);
|
this.isset(data.text)?this.EvalString(data.text):null,'','',text_choices,this.next]);
|
||||||
|
|||||||
@ -187,6 +187,11 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
|
|||||||
"_type": "textarea",
|
"_type": "textarea",
|
||||||
"_data": "初始生命值"
|
"_data": "初始生命值"
|
||||||
},
|
},
|
||||||
|
"manamax": {
|
||||||
|
"_leaf": true,
|
||||||
|
"_type": "textarea",
|
||||||
|
"_data": "魔力上限;此项非负才会生效(null或小于0都不会生效)"
|
||||||
|
},
|
||||||
"mana": {
|
"mana": {
|
||||||
"_leaf": true,
|
"_leaf": true,
|
||||||
"_type": "textarea",
|
"_type": "textarea",
|
||||||
|
|||||||
@ -70,9 +70,9 @@ editor_blockly = function () {
|
|||||||
MotaActionBlocks['lose_s'].xmlText(),
|
MotaActionBlocks['lose_s'].xmlText(),
|
||||||
MotaActionBlocks['choices_s'].xmlText([
|
MotaActionBlocks['choices_s'].xmlText([
|
||||||
'选择剑或者盾','流浪者','man',MotaActionBlocks['choicesContext'].xmlText([
|
'选择剑或者盾','流浪者','man',MotaActionBlocks['choicesContext'].xmlText([
|
||||||
'剑','','',null,null,MotaActionFunctions.actionParser.parseList([{"type": "openDoor", "loc": [3,3]}]),
|
'剑','','',null,MotaActionFunctions.actionParser.parseList([{"type": "openDoor", "loc": [3,3]}]),
|
||||||
MotaActionBlocks['choicesContext'].xmlText([
|
MotaActionBlocks['choicesContext'].xmlText([
|
||||||
'盾','','',null,null,MotaActionFunctions.actionParser.parseList([{"type": "openDoor", "loc": [9,3]}]),
|
'盾','','',null,MotaActionFunctions.actionParser.parseList([{"type": "openDoor", "loc": [9,3]}]),
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
]),
|
]),
|
||||||
@ -111,9 +111,10 @@ editor_blockly = function () {
|
|||||||
],
|
],
|
||||||
'事件控制':[
|
'事件控制':[
|
||||||
MotaActionBlocks['if_s'].xmlText(),
|
MotaActionBlocks['if_s'].xmlText(),
|
||||||
|
MotaActionBlocks['if_1_s'].xmlText(),
|
||||||
MotaActionFunctions.actionParser.parseList({"type": "switch", "condition": "判别值", "caseList": [
|
MotaActionFunctions.actionParser.parseList({"type": "switch", "condition": "判别值", "caseList": [
|
||||||
{"action": [{"type": "comment", "text": "当判别值是值的场合执行此事件"}]},
|
{"action": [{"type": "comment", "text": "当判别值是值的场合执行此事件"}]},
|
||||||
{"action": []},
|
{"action": [], "nobreak": true},
|
||||||
{"case": "default", "action": [{"type": "comment", "text": "当没有符合的值的场合执行default事件"}]},
|
{"case": "default", "action": [{"type": "comment", "text": "当没有符合的值的场合执行default事件"}]},
|
||||||
]}),
|
]}),
|
||||||
MotaActionBlocks['while_s'].xmlText(),
|
MotaActionBlocks['while_s'].xmlText(),
|
||||||
@ -142,8 +143,8 @@ editor_blockly = function () {
|
|||||||
MotaActionBlocks['animate_s'].xmlText(),
|
MotaActionBlocks['animate_s'].xmlText(),
|
||||||
MotaActionBlocks['showStatusBar_s'].xmlText(),
|
MotaActionBlocks['showStatusBar_s'].xmlText(),
|
||||||
MotaActionBlocks['hideStatusBar_s'].xmlText(),
|
MotaActionBlocks['hideStatusBar_s'].xmlText(),
|
||||||
MotaActionBlocks['setFg_0_s'].xmlText(),
|
MotaActionBlocks['setCurtain_0_s'].xmlText(),
|
||||||
MotaActionBlocks['setFg_1_s'].xmlText(),
|
MotaActionBlocks['setCurtain_1_s'].xmlText(),
|
||||||
MotaActionBlocks['screenFlash_s'].xmlText(),
|
MotaActionBlocks['screenFlash_s'].xmlText(),
|
||||||
MotaActionBlocks['setWeather_s'].xmlText(),
|
MotaActionBlocks['setWeather_s'].xmlText(),
|
||||||
MotaActionBlocks['playBgm_s'].xmlText(),
|
MotaActionBlocks['playBgm_s'].xmlText(),
|
||||||
|
|||||||
@ -105,7 +105,7 @@ actions.prototype.doRegisteredAction = function (action) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
actions.prototype.checkReplaying = function () {
|
actions.prototype._checkReplaying = function () {
|
||||||
if (core.isReplaying() && core.status.event.id != 'save'
|
if (core.isReplaying() && core.status.event.id != 'save'
|
||||||
&& (core.status.event.id || "").indexOf('book') != 0 && core.status.event.id != 'viewMaps')
|
&& (core.status.event.id || "").indexOf('book') != 0 && core.status.event.id != 'viewMaps')
|
||||||
return true;
|
return true;
|
||||||
@ -114,7 +114,7 @@ actions.prototype.checkReplaying = function () {
|
|||||||
|
|
||||||
////// 检查是否在录像播放中,如果是,则停止交互
|
////// 检查是否在录像播放中,如果是,则停止交互
|
||||||
actions.prototype._sys_checkReplay = 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) {
|
actions.prototype._sys_onkeyUp_replay = function (e) {
|
||||||
if (this.checkReplaying()) {
|
if (this._checkReplaying()) {
|
||||||
if (e.keyCode == 27) // ESCAPE
|
if (e.keyCode == 27) // ESCAPE
|
||||||
core.stopReplay();
|
core.stopReplay();
|
||||||
else if (e.keyCode == 90) // Z
|
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) {
|
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) {
|
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) {
|
if (core.status.automaticRoute && core.status.automaticRoute.autoHeroMove) {
|
||||||
core.stopAutomaticRoute();
|
core.stopAutomaticRoute();
|
||||||
}
|
}
|
||||||
core.stopHero();
|
core.status.heroStop = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -539,8 +539,8 @@ actions.prototype._sys_onup = function () {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
////// 获得点击事件相对左上角的坐标(0到12之间) //////
|
////// 获得点击事件相对左上角的坐标 //////
|
||||||
actions.prototype.getClickLoc = function (x, y) {
|
actions.prototype._getClickLoc = function (x, y) {
|
||||||
|
|
||||||
var statusBar = {'x': 0, 'y': 0};
|
var statusBar = {'x': 0, 'y': 0};
|
||||||
var size = 32;
|
var size = 32;
|
||||||
@ -663,7 +663,7 @@ actions.prototype.onmousewheel = function (direct) {
|
|||||||
actions.prototype._sys_onmousewheel = function (direct) {
|
actions.prototype._sys_onmousewheel = function (direct) {
|
||||||
// 向下滚动是 -1 ,向上是 1
|
// 向下滚动是 -1 ,向上是 1
|
||||||
|
|
||||||
if (this.checkReplaying()) {
|
if (this._checkReplaying()) {
|
||||||
// 滚轮控制速度
|
// 滚轮控制速度
|
||||||
if (direct == 1) core.speedUpReplay();
|
if (direct == 1) core.speedUpReplay();
|
||||||
if (direct == -1) core.speedDownReplay();
|
if (direct == -1) core.speedDownReplay();
|
||||||
@ -891,6 +891,21 @@ actions.prototype._clickAction = function (x, y) {
|
|||||||
core.doAction();
|
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) {
|
actions.prototype._keyDownAction = function (keycode) {
|
||||||
if (core.status.event.data.type == 'choices') {
|
if (core.status.event.data.type == 'choices') {
|
||||||
this._keyDownChoices(keycode);
|
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) {
|
if (choices.length > 0) {
|
||||||
this._selectChoices(choices.length, keycode, this._clickAction);
|
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);
|
var index = this.HSIZE * page + parseInt(y / 2);
|
||||||
core.ui.drawBook(index);
|
core.ui.drawBook(index);
|
||||||
core.ui.drawBookDetail(index);
|
core.ui.drawBookDetail(index);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1101,17 +1132,20 @@ actions.prototype._clickViewMaps = function (x, y) {
|
|||||||
index++;
|
index++;
|
||||||
if (index < core.floorIds.length)
|
if (index < core.floorIds.length)
|
||||||
core.ui.drawMaps(index);
|
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--;
|
index--;
|
||||||
while (index >= 0 && index != now && core.status.maps[core.floorIds[index]].cannotViewMap)
|
while (index >= 0 && index != now && core.status.maps[core.floorIds[index]].cannotViewMap)
|
||||||
index--;
|
index--;
|
||||||
if (index >= 0)
|
if (index >= 0)
|
||||||
core.ui.drawMaps(index);
|
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.clearMap('data');
|
||||||
core.ui.closePanel();
|
core.ui.closePanel();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1217,7 +1251,9 @@ actions.prototype._clickQuickShop = function (x, y) {
|
|||||||
// 离开
|
// 离开
|
||||||
else if (y == topIndex + keys.length)
|
else if (y == topIndex + keys.length)
|
||||||
core.ui.closePanel();
|
core.ui.closePanel();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
////// 快捷商店界面时,放开某个键的操作 //////
|
////// 快捷商店界面时,放开某个键的操作 //////
|
||||||
@ -1255,7 +1291,7 @@ actions.prototype._clickToolbox = function (x, y) {
|
|||||||
core.ui.drawToolbox(core.status.event.selection);
|
core.ui.drawToolbox(core.status.event.selection);
|
||||||
}
|
}
|
||||||
if (y == this.LAST && constantsPage > 1) {
|
if (y == this.LAST && constantsPage > 1) {
|
||||||
core.status.event.data.toolsPage--;
|
core.status.event.data.constantsPage--;
|
||||||
core.ui.drawToolbox(core.status.event.selection);
|
core.ui.drawToolbox(core.status.event.selection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1904,11 +1940,11 @@ actions.prototype._clickSettings = function (x, y) {
|
|||||||
core.ui.drawKeyBoard();
|
core.ui.drawKeyBoard();
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
core.clearSelector();
|
core.clearUI();
|
||||||
core.ui.drawMaps();
|
core.ui.drawMaps();
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
core.clearSelector();
|
core.clearUI();
|
||||||
core.ui.drawPaint();
|
core.ui.drawPaint();
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
@ -1920,7 +1956,7 @@ actions.prototype._clickSettings = function (x, y) {
|
|||||||
core.ui.drawGameInfo();
|
core.ui.drawGameInfo();
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
return core.confirmRestart(true);
|
return core.confirmRestart();
|
||||||
case 7:
|
case 7:
|
||||||
core.ui.closePanel();
|
core.ui.closePanel();
|
||||||
break;
|
break;
|
||||||
@ -2065,7 +2101,7 @@ actions.prototype._clickLocalSaveSelect = function (x, y) {
|
|||||||
var selection = y - topIndex;
|
var selection = y - topIndex;
|
||||||
core.status.event.selection = selection;
|
core.status.event.selection = selection;
|
||||||
if (selection < 2) {
|
if (selection < 2) {
|
||||||
core.getAllSaves(selection == 0 ? null : core.saves.saveIndex, function (saves) {
|
var callback = function (saves) {
|
||||||
if (saves) {
|
if (saves) {
|
||||||
var content = {
|
var content = {
|
||||||
"name": core.firstData.name,
|
"name": core.firstData.name,
|
||||||
@ -2074,7 +2110,9 @@ actions.prototype._clickLocalSaveSelect = function (x, y) {
|
|||||||
}
|
}
|
||||||
core.download(core.firstData.name + "_" + core.formatDate2(new Date()) + ".h5save", JSON.stringify(content));
|
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;
|
core.status.event.selection = 2;
|
||||||
@ -2209,7 +2247,7 @@ actions.prototype._clickReplay_fromBeginning = function () {
|
|||||||
actions.prototype._clickReplay_fromLoad = function () {
|
actions.prototype._clickReplay_fromLoad = function () {
|
||||||
core.status.event.id = 'replayLoad';
|
core.status.event.id = 'replayLoad';
|
||||||
core.status.event.selection = null;
|
core.status.event.selection = null;
|
||||||
core.ui.clearSelector();
|
core.clearUI();
|
||||||
var saveIndex = core.saves.saveIndex;
|
var saveIndex = core.saves.saveIndex;
|
||||||
var page = parseInt((saveIndex - 1) / 5), offset = saveIndex - 5 * page;
|
var page = parseInt((saveIndex - 1) / 5), offset = saveIndex - 5 * page;
|
||||||
core.ui.drawSLPanel(10 * page + offset);
|
core.ui.drawSLPanel(10 * page + offset);
|
||||||
@ -2448,7 +2486,7 @@ actions.prototype._onupPaint = function () {
|
|||||||
core.status.event.data.x = null;
|
core.status.event.data.x = null;
|
||||||
core.status.event.data.y = 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) {
|
actions.prototype.setPaintMode = function (mode) {
|
||||||
@ -2496,7 +2534,7 @@ actions.prototype.loadPaint = function () {
|
|||||||
core.clearMap('paint');
|
core.clearMap('paint');
|
||||||
var value = core.paint[core.status.floorId];
|
var value = core.paint[core.status.floorId];
|
||||||
if (value) value = lzw_decode(value).split(",");
|
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.drawImage('paint', core.bigmap.tempCanvas.canvas, 0, 0);
|
||||||
|
|
||||||
core.drawTip("读取绘图文件成功");
|
core.drawTip("读取绘图文件成功");
|
||||||
|
|||||||
@ -308,7 +308,7 @@ control.prototype.showStartAnimate = function (noAnimate, callback) {
|
|||||||
this._showStartAnimate_resetDom();
|
this._showStartAnimate_resetDom();
|
||||||
if (core.flags.startUsingCanvas || noAnimate)
|
if (core.flags.startUsingCanvas || noAnimate)
|
||||||
return this._showStartAnimate_finished(core.flags.startUsingCanvas, callback);
|
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);
|
core.control._showStartAnimate_finished(false, callback);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -324,8 +324,8 @@ control.prototype._showStartAnimate_resetDom = function () {
|
|||||||
core.status.played = false;
|
core.status.played = false;
|
||||||
core.clearStatus();
|
core.clearStatus();
|
||||||
core.clearMap('all');
|
core.clearMap('all');
|
||||||
core.deleteAllCanvas();
|
|
||||||
core.dom.musicBtn.style.display = 'block';
|
core.dom.musicBtn.style.display = 'block';
|
||||||
|
core.setMusicBtn();
|
||||||
// 重置音量
|
// 重置音量
|
||||||
core.events.setVolume(1, 0);
|
core.events.setVolume(1, 0);
|
||||||
core.updateStatusBar();
|
core.updateStatusBar();
|
||||||
@ -340,7 +340,7 @@ control.prototype._showStartAnimate_finished = function (start, callback) {
|
|||||||
|
|
||||||
////// 隐藏游戏开始界面 //////
|
////// 隐藏游戏开始界面 //////
|
||||||
control.prototype.hideStartAnimate = function (callback) {
|
control.prototype.hideStartAnimate = function (callback) {
|
||||||
core.hide(core.dom.startPanel, 20, callback);
|
core.hideWithAnimate(core.dom.startPanel, 20, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
////// 游戏是否已经开始 //////
|
////// 游戏是否已经开始 //////
|
||||||
@ -348,30 +348,6 @@ control.prototype.isPlaying = function() {
|
|||||||
return core.status.played;
|
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() {
|
control.prototype.clearStatus = function() {
|
||||||
// 停止各个Timeout和Interval
|
// 停止各个Timeout和Interval
|
||||||
@ -424,7 +400,7 @@ control.prototype.stopAutomaticRoute = function () {
|
|||||||
core.status.automaticRoute.destX=null;
|
core.status.automaticRoute.destX=null;
|
||||||
core.status.automaticRoute.destY=null;
|
core.status.automaticRoute.destY=null;
|
||||||
core.status.automaticRoute.lastDirection = null;
|
core.status.automaticRoute.lastDirection = null;
|
||||||
core.stopHero();
|
core.status.heroStop = true;
|
||||||
if (core.status.automaticRoute.moveStepBeforeStop.length==0)
|
if (core.status.automaticRoute.moveStepBeforeStop.length==0)
|
||||||
core.deleteCanvas('route');
|
core.deleteCanvas('route');
|
||||||
}
|
}
|
||||||
@ -472,8 +448,10 @@ control.prototype.setAutomaticRoute = function (destX, destY, stepPostfix) {
|
|||||||
if (this._setAutomaticRoute_isTurning(destX, destY, stepPostfix)) return;
|
if (this._setAutomaticRoute_isTurning(destX, destY, stepPostfix)) return;
|
||||||
if (this._setAutomaticRoute_clickMoveDirectly(destX, destY, stepPostfix)) return;
|
if (this._setAutomaticRoute_clickMoveDirectly(destX, destY, stepPostfix)) return;
|
||||||
// 找寻自动寻路路线
|
// 找寻自动寻路路线
|
||||||
var moveStep = core.automaticRoute(destX, destY).concat(stepPostfix);
|
var moveStep = core.automaticRoute(destX, destY);
|
||||||
if (moveStep.length == 0) return core.deleteCanvas('route');
|
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.destX=destX;
|
||||||
core.status.automaticRoute.destY=destY;
|
core.status.automaticRoute.destY=destY;
|
||||||
this._setAutomaticRoute_drawRoute(moveStep);
|
this._setAutomaticRoute_drawRoute(moveStep);
|
||||||
@ -659,7 +637,7 @@ control.prototype._moveAction_moving = function (callback) {
|
|||||||
core.updateStatusBar();
|
core.updateStatusBar();
|
||||||
|
|
||||||
// 检查该点是否是滑冰
|
// 检查该点是否是滑冰
|
||||||
if (core.getBgFgNumber('bg') == 167) {
|
if (core.getBgNumber() == 167) {
|
||||||
core.insertAction("滑冰事件", null, null, null, true);
|
core.insertAction("滑冰事件", null, null, null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -749,11 +727,6 @@ control.prototype.waitHeroToStop = function(callback) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////// 停止勇士的移动状态 //////
|
|
||||||
control.prototype.stopHero = function () {
|
|
||||||
core.status.heroStop = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
////// 转向 //////
|
////// 转向 //////
|
||||||
control.prototype.turnHero = function(direction) {
|
control.prototype.turnHero = function(direction) {
|
||||||
if (direction) {
|
if (direction) {
|
||||||
@ -1272,7 +1245,12 @@ control.prototype._doReplayAction = function (action) {
|
|||||||
control.prototype._replay_finished = function () {
|
control.prototype._replay_finished = function () {
|
||||||
core.status.replay.replaying = false;
|
core.status.replay.replaying = false;
|
||||||
core.status.event.selection = 0;
|
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.ui.closePanel();
|
||||||
core.stopReplay(true);
|
core.stopReplay(true);
|
||||||
}, function () {
|
}, function () {
|
||||||
@ -1460,6 +1438,7 @@ control.prototype._replayAction_moveDirectly = function (action) {
|
|||||||
// 忽略连续的瞬移事件
|
// 忽略连续的瞬移事件
|
||||||
while (core.status.replay.toReplay.length>0 &&
|
while (core.status.replay.toReplay.length>0 &&
|
||||||
core.status.replay.toReplay[0].indexOf('move:')==0) {
|
core.status.replay.toReplay[0].indexOf('move:')==0) {
|
||||||
|
core.status.route.push(action);
|
||||||
action = core.status.replay.toReplay.shift();
|
action = core.status.replay.toReplay.shift();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1615,13 +1594,15 @@ control.prototype._doSL_replayLoad_afterGet = function (id, data) {
|
|||||||
////// 同步存档到服务器 //////
|
////// 同步存档到服务器 //////
|
||||||
control.prototype.syncSave = function (type) {
|
control.prototype.syncSave = function (type) {
|
||||||
core.ui.drawWaiting("正在同步,请稍后...");
|
core.ui.drawWaiting("正在同步,请稍后...");
|
||||||
core.getAllSaves(type=='all'?null:core.saves.saveIndex, function (saves) {
|
var callback = function (saves) {
|
||||||
if (!saves) return core.drawText("没有要同步的存档");
|
|
||||||
core.control._syncSave_http(type, 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) {
|
control.prototype._syncSave_http = function (type, saves) {
|
||||||
|
if (!saves) return core.drawText("没有要同步的存档");
|
||||||
var formData = new FormData();
|
var formData = new FormData();
|
||||||
formData.append('type', 'save');
|
formData.append('type', 'save');
|
||||||
formData.append('name', core.firstData.name);
|
formData.append('name', core.firstData.name);
|
||||||
@ -1635,7 +1616,7 @@ control.prototype._syncSave_http = function (type, saves) {
|
|||||||
else {
|
else {
|
||||||
core.drawText((type=='all'?"所有存档":"存档"+core.saves.saveIndex)+"同步成功!\n\n您的存档编号: "
|
core.drawText((type=='all'?"所有存档":"存档"+core.saves.saveIndex)+"同步成功!\n\n您的存档编号: "
|
||||||
+response.code+"\n您的存档密码: "+response.msg
|
+response.code+"\n您的存档密码: "+response.msg
|
||||||
+"\n\n请牢记以上两个信息(如截图等),在从服务器\n同步存档时使用。")
|
+"\n\n请牢记以上两个信息(如截图等),在从服务器\n同步存档时使用。\n\r[yellow]另外请注意,存档同步只会保存一个月的时间。\r")
|
||||||
}
|
}
|
||||||
}, function (e) {
|
}, function (e) {
|
||||||
core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:"+e);
|
core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:"+e);
|
||||||
@ -1746,8 +1727,7 @@ control.prototype.getSaves = function (ids, callback) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
control.prototype.getAllSaves = function (id, callback) {
|
control.prototype.getAllSaves = function (callback) {
|
||||||
if (id != null) return this.getSave(id, callback);
|
|
||||||
var ids = Object.keys(core.saves.ids).filter(function(x){return x!=0;})
|
var ids = Object.keys(core.saves.ids).filter(function(x){return x!=0;})
|
||||||
.sort(function(a,b) {return a-b;}), saves = [];
|
.sort(function(a,b) {return a-b;}), saves = [];
|
||||||
this.getSaves(ids, function (data) {
|
this.getSaves(ids, function (data) {
|
||||||
@ -1790,7 +1770,7 @@ control.prototype.hasSave = function (index) {
|
|||||||
return core.saves.ids[index] || false;
|
return core.saves.ids[index] || false;
|
||||||
}
|
}
|
||||||
|
|
||||||
////// 删除一个或多个存档
|
////// 删除某个存档
|
||||||
control.prototype.removeSave = function (index, callback) {
|
control.prototype.removeSave = function (index, callback) {
|
||||||
if (index == 0 || index == "autoSave") {
|
if (index == 0 || index == "autoSave") {
|
||||||
index = "autoSave";
|
index = "autoSave";
|
||||||
@ -1825,8 +1805,6 @@ control.prototype._updateFavoriteSaves = function () {
|
|||||||
core.setLocalStorage("favoriteName", core.saves.favoriteName);
|
core.setLocalStorage("favoriteName", core.saves.favoriteName);
|
||||||
}
|
}
|
||||||
|
|
||||||
////// 加载某个存档
|
|
||||||
|
|
||||||
// ------ 属性,状态,位置,buff,变量,锁定控制等 ------ //
|
// ------ 属性,状态,位置,buff,变量,锁定控制等 ------ //
|
||||||
|
|
||||||
////// 设置勇士属性 //////
|
////// 设置勇士属性 //////
|
||||||
@ -2017,7 +1995,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 == null) time=750;
|
||||||
if (time<=0) time=0;
|
if (time<=0) time=0;
|
||||||
if (!core.status.curtainColor)
|
if (!core.status.curtainColor)
|
||||||
@ -2035,10 +2013,10 @@ control.prototype.setFg = function(color, time, callback) {
|
|||||||
return;
|
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 per_time = 10, step = parseInt(time / per_time);
|
||||||
var animate = setInterval(function() {
|
var animate = setInterval(function() {
|
||||||
nowColor = [
|
nowColor = [
|
||||||
@ -2066,8 +2044,8 @@ control.prototype.screenFlash = function (color, time, times, callback) {
|
|||||||
times = times || 1;
|
times = times || 1;
|
||||||
time = time / 3;
|
time = time / 3;
|
||||||
var nowColor = core.clone(core.status.curtainColor);
|
var nowColor = core.clone(core.status.curtainColor);
|
||||||
core.setFg(color, time, function() {
|
core.setCurtain(color, time, function() {
|
||||||
core.setFg(nowColor, time * 2, function() {
|
core.setCurtain(nowColor, time * 2, function() {
|
||||||
if (times > 1)
|
if (times > 1)
|
||||||
core.screenFlash(color, time * 3, times - 1, callback);
|
core.screenFlash(color, time * 3, times - 1, callback);
|
||||||
else {
|
else {
|
||||||
@ -2203,8 +2181,8 @@ control.prototype.stopSound = function () {
|
|||||||
for (var i in core.musicStatus.playingSounds) {
|
for (var i in core.musicStatus.playingSounds) {
|
||||||
var source = core.musicStatus.playingSounds[i];
|
var source = core.musicStatus.playingSounds[i];
|
||||||
try {
|
try {
|
||||||
if (source[i].stop) source[i].stop();
|
if (source.stop) source.stop();
|
||||||
else if (source[i].noteOff) source[i].noteOff();
|
else if (source.noteOff) source.noteOff();
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
main.log(e);
|
main.log(e);
|
||||||
@ -2353,10 +2331,11 @@ control.prototype.updateGlobalAttribute = function (name) {
|
|||||||
core.dom.statusBar.style.borderTop = border;
|
core.dom.statusBar.style.borderTop = border;
|
||||||
core.dom.statusBar.style.borderLeft = border;
|
core.dom.statusBar.style.borderLeft = border;
|
||||||
core.dom.statusBar.style.borderRight = core.domStyle.isVertical?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.gameDraw.style.border = border;
|
||||||
core.dom.toolBar.style.borderBottom = border;
|
|
||||||
core.dom.toolBar.style.borderLeft = border;
|
core.dom.toolBar.style.borderLeft = border;
|
||||||
core.dom.toolBar.style.borderRight = core.domStyle.isVertical?border:'';
|
core.dom.toolBar.style.borderRight = core.domStyle.isVertical?border:'';
|
||||||
|
core.dom.toolBar.style.borderBottom = core.domStyle.isVertical?border:'';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'statusBarColor':
|
case 'statusBarColor':
|
||||||
@ -2378,7 +2357,7 @@ control.prototype.updateGlobalAttribute = function (name) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////// 改变工具栏为按钮1-7 //////
|
////// 改变工具栏为按钮1-8 //////
|
||||||
control.prototype.setToolbarButton = function (useButton) {
|
control.prototype.setToolbarButton = function (useButton) {
|
||||||
if (!core.domStyle.showStatusBar) {
|
if (!core.domStyle.showStatusBar) {
|
||||||
// 隐藏状态栏时检查竖屏
|
// 隐藏状态栏时检查竖屏
|
||||||
@ -2544,7 +2523,7 @@ control.prototype._resize_gameGroup = function (obj) {
|
|||||||
floorMsgGroup.style.color = obj.globalAttribute.floorChangingTextColor;
|
floorMsgGroup.style.color = obj.globalAttribute.floorChangingTextColor;
|
||||||
// musicBtn
|
// musicBtn
|
||||||
if (core.domStyle.isVertical || core.domStyle.scale < 1) {
|
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 {
|
else {
|
||||||
core.dom.musicBtn.style.right = (obj.clientWidth - totalWidth) / 2 + "px";
|
core.dom.musicBtn.style.right = (obj.clientWidth - totalWidth) / 2 + "px";
|
||||||
@ -2588,7 +2567,7 @@ control.prototype._resize_statusBar = function (obj) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
statusBar.style.width = obj.BAR_WIDTH * core.domStyle.scale + "px";
|
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.background = obj.globalAttribute.statusLeftBackground;
|
||||||
// --- 计算文字大小
|
// --- 计算文字大小
|
||||||
statusBar.style.fontSize = 16 * Math.min(1, (core.__HALF_SIZE__ + 3) / obj.count) * core.domStyle.scale + "px";
|
statusBar.style.fontSize = 16 * Math.min(1, (core.__HALF_SIZE__ + 3) / obj.count) * core.domStyle.scale + "px";
|
||||||
@ -2596,6 +2575,7 @@ control.prototype._resize_statusBar = function (obj) {
|
|||||||
statusBar.style.display = 'block';
|
statusBar.style.display = 'block';
|
||||||
statusBar.style.borderTop = statusBar.style.borderLeft = obj.border;
|
statusBar.style.borderTop = statusBar.style.borderLeft = obj.border;
|
||||||
statusBar.style.borderRight = core.domStyle.isVertical ? obj.border : '';
|
statusBar.style.borderRight = core.domStyle.isVertical ? obj.border : '';
|
||||||
|
statusBar.style.borderBottom = core.domStyle.isVertical ? '' : obj.border;
|
||||||
// 自绘状态栏
|
// 自绘状态栏
|
||||||
if (core.domStyle.isVertical) {
|
if (core.domStyle.isVertical) {
|
||||||
core.dom.statusCanvas.style.width = obj.outerSize - 6 + "px";
|
core.dom.statusCanvas.style.width = obj.outerSize - 6 + "px";
|
||||||
@ -2651,8 +2631,8 @@ control.prototype._resize_toolBar = function (obj) {
|
|||||||
toolBar.style.background = 'transparent';
|
toolBar.style.background = 'transparent';
|
||||||
}
|
}
|
||||||
toolBar.style.display = 'block';
|
toolBar.style.display = 'block';
|
||||||
toolBar.style.borderLeft = toolBar.style.borderBottom = obj.border;
|
toolBar.style.borderLeft = obj.border;
|
||||||
toolBar.style.borderRight = core.domStyle.isVertical ? obj.border : '';
|
toolBar.style.borderRight = toolBar.style.borderBottom = core.domStyle.isVertical ? obj.border : '';
|
||||||
toolBar.style.fontSize = 16 * core.domStyle.scale + "px";
|
toolBar.style.fontSize = 16 * core.domStyle.scale + "px";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
11
libs/core.js
11
libs/core.js
@ -16,8 +16,7 @@ function core() {
|
|||||||
'ground': null,
|
'ground': null,
|
||||||
'items': {},
|
'items': {},
|
||||||
'enemys': {},
|
'enemys': {},
|
||||||
'icons': {},
|
'icons': {}
|
||||||
'events': {}
|
|
||||||
}
|
}
|
||||||
this.timeout = {
|
this.timeout = {
|
||||||
'tipTimeout': null,
|
'tipTimeout': null,
|
||||||
@ -84,8 +83,8 @@ function core() {
|
|||||||
this.domStyle = {
|
this.domStyle = {
|
||||||
scale: 1.0,
|
scale: 1.0,
|
||||||
isVertical: false,
|
isVertical: false,
|
||||||
toolbarBtn: false,
|
|
||||||
showStatusBar: true,
|
showStatusBar: true,
|
||||||
|
toolbarBtn: false,
|
||||||
}
|
}
|
||||||
this.bigmap = {
|
this.bigmap = {
|
||||||
canvas: ["bg", "event", "event2", "fg", "damage"],
|
canvas: ["bg", "event", "event2", "fg", "damage"],
|
||||||
@ -220,6 +219,7 @@ core.prototype.init = function (coreData, callback) {
|
|||||||
this._init_flags();
|
this._init_flags();
|
||||||
this._init_platform();
|
this._init_platform();
|
||||||
this._init_others();
|
this._init_others();
|
||||||
|
this._initPlugins();
|
||||||
|
|
||||||
core.loader._load(function () {
|
core.loader._load(function () {
|
||||||
core._afterLoadResources(callback);
|
core._afterLoadResources(callback);
|
||||||
@ -342,9 +342,10 @@ core.prototype._init_others = function () {
|
|||||||
|
|
||||||
core.prototype._afterLoadResources = function (callback) {
|
core.prototype._afterLoadResources = function (callback) {
|
||||||
// 初始化地图
|
// 初始化地图
|
||||||
core.initStatus.maps = core.maps.initMaps(core.floorIds);
|
core.initStatus.maps = core.maps._initMaps();
|
||||||
core.control._setRequestAnimationFrame();
|
core.control._setRequestAnimationFrame();
|
||||||
core._initPlugins();
|
if (core.plugin._afterLoadResources)
|
||||||
|
core.plugin._afterLoadResources();
|
||||||
core.showStartAnimate();
|
core.showStartAnimate();
|
||||||
if (callback) callback();
|
if (callback) callback();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -107,13 +107,13 @@ enemys.prototype.canBattle = function (enemy, x, y, floorId) {
|
|||||||
////// 获得某个怪物的伤害 //////
|
////// 获得某个怪物的伤害 //////
|
||||||
enemys.prototype.getDamage = function (enemy, x, y, floorId) {
|
enemys.prototype.getDamage = function (enemy, x, y, floorId) {
|
||||||
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
|
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;
|
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];
|
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
|
||||||
var extra_damage = 0;
|
var extra_damage = 0;
|
||||||
if (this.hasSpecial(enemy.special, 17)) { // 仇恨
|
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) {
|
enemys.prototype.getDefDamage = function (enemy, k, x, y, floorId) {
|
||||||
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
|
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
|
||||||
k = k || 1;
|
k = k || 1;
|
||||||
var nowDamage = this.calDamage(enemy, null, 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);
|
var nextDamage = this._calDamage(enemy, {"def": core.status.hero.def + k}, x, y, floorId);
|
||||||
if (nowDamage == null || nextDamage == null) return "???";
|
if (nowDamage == null || nextDamage == null) return "???";
|
||||||
return nowDamage - nextDamage;
|
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];
|
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
|
||||||
|
|
||||||
var info = this.getDamageInfo(enemy, hero, x, y, floorId);
|
var info = this.getDamageInfo(enemy, hero, x, y, floorId);
|
||||||
@ -358,3 +358,7 @@ enemys.prototype._getCurrentEnemys_sort = function (enemys) {
|
|||||||
return a.damage - b.damage;
|
return a.damage - b.damage;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enemys.prototype.hasEnemyLeft = function (floorId) {
|
||||||
|
return core.getCurrentEnemys(floorId).length > 0;
|
||||||
|
}
|
||||||
226
libs/events.js
226
libs/events.js
@ -52,9 +52,6 @@ events.prototype._startGame_start = function (hard, seed, route, callback) {
|
|||||||
}
|
}
|
||||||
else core.utils.__init_seed();
|
else core.utils.__init_seed();
|
||||||
this.setInitData();
|
this.setInitData();
|
||||||
|
|
||||||
core.clearMap('all');
|
|
||||||
core.deleteAllCanvas();
|
|
||||||
core.clearStatusBar();
|
core.clearStatusBar();
|
||||||
|
|
||||||
var todo = [];
|
var todo = [];
|
||||||
@ -183,7 +180,7 @@ events.prototype._gameOver_doUpload = function (username, ending, norank) {
|
|||||||
formData.append('money', core.status.hero.money);
|
formData.append('money', core.status.hero.money);
|
||||||
formData.append('experience', core.status.hero.experience);
|
formData.append('experience', core.status.hero.experience);
|
||||||
formData.append('steps', core.status.hero.steps);
|
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('seed', core.getFlag('__seed__'));
|
||||||
formData.append('totalTime', Math.floor(core.status.hero.statistics.totalTime / 1000));
|
formData.append('totalTime', Math.floor(core.status.hero.statistics.totalTime / 1000));
|
||||||
formData.append('route', core.encodeRoute(core.status.route));
|
formData.append('route', core.encodeRoute(core.status.route));
|
||||||
@ -234,6 +231,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 +293,7 @@ events.prototype._trigger = function (x, y) {
|
|||||||
if (trigger == 'changeFloor' && !noPass && this._trigger_ignoreChangeFloor(block))
|
if (trigger == 'changeFloor' && !noPass && this._trigger_ignoreChangeFloor(block))
|
||||||
return;
|
return;
|
||||||
core.status.automaticRoute.moveDirectly = false;
|
core.status.automaticRoute.moveDirectly = false;
|
||||||
this.doSystemEvent(trigger, block, function () {
|
this.doSystemEvent(trigger, block);
|
||||||
if (trigger == 'openDoor' || trigger == 'changeFloor')
|
|
||||||
core.replay();
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -341,16 +352,20 @@ events.prototype.afterBattle = function (enemyId, x, y, callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
events.prototype._sys_openDoor = function (data, 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) {
|
events.prototype.openDoor = function (x, y, needKey, callback) {
|
||||||
id = id || core.getBlockId(x, y);
|
var id = core.getBlockId(x, y);
|
||||||
core.saveAndStopAutomaticRoute();
|
core.saveAndStopAutomaticRoute();
|
||||||
if (!this._openDoor_check(id, x, y, needKey)) {
|
if (!this._openDoor_check(id, x, y, needKey)) {
|
||||||
|
var locked = core.status.lockControl;
|
||||||
core.waitHeroToStop(function () {
|
core.waitHeroToStop(function () {
|
||||||
core.unLockControl();
|
if (!locked) core.unLockControl();
|
||||||
if (callback) callback();
|
if (callback) callback();
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@ -362,7 +377,7 @@ events.prototype.openDoor = function (id, x, y, needKey, callback) {
|
|||||||
events.prototype._openDoor_check = function (id, x, y, needKey) {
|
events.prototype._openDoor_check = function (id, x, y, needKey) {
|
||||||
// 是否存在门或暗墙
|
// 是否存在门或暗墙
|
||||||
if (!core.terrainExists(x, y, id) || !(id.endsWith("Door") || id.endsWith("Wall"))
|
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();
|
core.clearContinueAutomaticRoute();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -376,7 +391,7 @@ events.prototype._openDoor_check = function (id, x, y, needKey) {
|
|||||||
core.clearContinueAutomaticRoute();
|
core.clearContinueAutomaticRoute();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
core.autosave(true);
|
if (!core.status.event.id) core.autosave(true);
|
||||||
core.removeItem(key);
|
core.removeItem(key);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -386,6 +401,7 @@ events.prototype._openDoor_animate = function (id, x, y, callback) {
|
|||||||
var door = core.material.icons.animates[id];
|
var door = core.material.icons.animates[id];
|
||||||
var speed = id.endsWith("Door") ? 30 : 70;
|
var speed = id.endsWith("Door") ? 30 : 70;
|
||||||
|
|
||||||
|
var locked = core.status.lockControl;
|
||||||
core.lockControl();
|
core.lockControl();
|
||||||
core.status.replay.animate = true;
|
core.status.replay.animate = true;
|
||||||
var state = 0;
|
var state = 0;
|
||||||
@ -394,7 +410,7 @@ events.prototype._openDoor_animate = function (id, x, y, callback) {
|
|||||||
if (state == 4) {
|
if (state == 4) {
|
||||||
clearInterval(animate);
|
clearInterval(animate);
|
||||||
core.removeBlock(x, y);
|
core.removeBlock(x, y);
|
||||||
core.unLockControl();
|
if (!locked) core.unLockControl();
|
||||||
core.status.replay.animate = false;
|
core.status.replay.animate = false;
|
||||||
core.events.afterOpenDoor(id, x, y, callback);
|
core.events.afterOpenDoor(id, x, y, callback);
|
||||||
return;
|
return;
|
||||||
@ -414,29 +430,33 @@ events.prototype._sys_getItem = function (data, callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////// 获得某个物品 //////
|
////// 获得某个物品 //////
|
||||||
events.prototype.getItem = function (itemId, itemNum, itemX, itemY, callback) {
|
events.prototype.getItem = function (id, num, x, y, callback) {
|
||||||
itemNum = itemNum || 1;
|
num = num || 1;
|
||||||
var itemCls = core.material.items[itemId].cls;
|
var itemCls = core.material.items[id].cls;
|
||||||
core.items.getItemEffect(itemId, itemNum);
|
core.items.getItemEffect(id, num);
|
||||||
core.removeBlock(itemX, itemY);
|
core.removeBlock(x, y);
|
||||||
var text = '获得 ' + core.material.items[itemId].name;
|
var text = '获得 ' + core.material.items[id].name;
|
||||||
if (itemNum > 1) text += "x" + itemNum;
|
if (num > 1) text += "x" + num;
|
||||||
if (itemCls === 'items') text += core.items.getItemEffectTip(itemId);
|
if (itemCls === 'items') text += core.items.getItemEffectTip(id);
|
||||||
core.drawTip(text, core.material.icons.items[itemId]);
|
core.drawTip(text, id);
|
||||||
core.updateStatusBar();
|
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;
|
if (core.isMoving() || !core.canMoveHero() || !core.flags.enableGentleClick) return false;
|
||||||
|
|
||||||
var nextX = core.nextX(), nextY = core.nextY();
|
var nextX = core.nextX(), nextY = core.nextY();
|
||||||
var block = core.getBlock(nextX, nextY);
|
var block = core.getBlock(nextX, nextY);
|
||||||
if (block == null) return false;
|
if (block == null) return false;
|
||||||
if (block.block.event.trigger == 'getItem') {
|
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);
|
this.getItem(block.block.event.id, 1, nextX, nextY);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -449,7 +469,10 @@ events.prototype._sys_changeFloor = function (data, callback) {
|
|||||||
if (data.loc) heroLoc = {'x': data.loc[0], 'y': data.loc[1]};
|
if (data.loc) heroLoc = {'x': data.loc[0], 'y': data.loc[1]};
|
||||||
if (data.direction) heroLoc.direction = data.direction;
|
if (data.direction) heroLoc.direction = data.direction;
|
||||||
if (core.status.event.id != 'action') core.status.event.id = null;
|
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 +484,7 @@ events.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback
|
|||||||
}
|
}
|
||||||
info.fromLoad = fromLoad;
|
info.fromLoad = fromLoad;
|
||||||
floorId = info.floorId;
|
floorId = info.floorId;
|
||||||
|
info.locked = core.status.lockControl;
|
||||||
|
|
||||||
core.dom.floorNameLabel.innerHTML = core.status.maps[floorId].title;
|
core.dom.floorNameLabel.innerHTML = core.status.maps[floorId].title;
|
||||||
core.lockControl();
|
core.lockControl();
|
||||||
@ -535,7 +559,7 @@ events.prototype._changeFloor_beforeChange = function (info, callback) {
|
|||||||
if (info.time == 0)
|
if (info.time == 0)
|
||||||
core.events._changeFloor_changing(info, callback);
|
core.events._changeFloor_changing(info, callback);
|
||||||
else
|
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);
|
core.events._changeFloor_changing(info, callback);
|
||||||
});
|
});
|
||||||
}, 25)
|
}, 25)
|
||||||
@ -547,13 +571,13 @@ events.prototype._changeFloor_changing = function (info, callback) {
|
|||||||
if (info.time == 0)
|
if (info.time == 0)
|
||||||
this._changeFloor_afterChange(info, callback);
|
this._changeFloor_afterChange(info, callback);
|
||||||
else
|
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);
|
core.events._changeFloor_afterChange(info, callback);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
events.prototype._changeFloor_afterChange = function (info, callback) {
|
events.prototype._changeFloor_afterChange = function (info, callback) {
|
||||||
core.unLockControl();
|
if (!info.locked) core.unLockControl();
|
||||||
core.status.replay.animate = false;
|
core.status.replay.animate = false;
|
||||||
core.events.afterChangeFloor(info.floorId, info.fromLoad);
|
core.events.afterChangeFloor(info.floorId, info.fromLoad);
|
||||||
|
|
||||||
@ -661,11 +685,6 @@ events.prototype._sys_changeLight = function (data, callback) {
|
|||||||
events.prototype.changeLight = function (id, x, y) {
|
events.prototype.changeLight = function (id, x, y) {
|
||||||
if (id != null && id != 'light') return;
|
if (id != null && id != 'light') return;
|
||||||
core.setBlock(core.getNumberById('darkLight'), x, y);
|
core.setBlock(core.getNumberById('darkLight'), x, y);
|
||||||
this.afterChangeLight(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
////// 改变亮灯之后,可以触发的事件 //////
|
|
||||||
events.prototype.afterChangeLight = function (x, y) {
|
|
||||||
return this.eventdata.afterChangeLight(x, y);
|
return this.eventdata.afterChangeLight(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -724,8 +743,19 @@ events.prototype.doEvent = function (data, x, y, prefix) {
|
|||||||
core.doAction();
|
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) return;
|
||||||
if (!(list instanceof Array)) {
|
if (!(list instanceof Array)) {
|
||||||
list = [list];
|
list = [list];
|
||||||
@ -738,24 +768,10 @@ 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 () {
|
events.prototype.doAction = function () {
|
||||||
// 清空boxAnimate和UI层
|
// 清空boxAnimate和UI层
|
||||||
core.status.boxAnimateObjs = [];
|
core.clearUI();
|
||||||
clearInterval(core.status.event.interval);
|
|
||||||
core.status.event.interval = null;
|
|
||||||
core.clearSelector();
|
|
||||||
// 判定是否执行完毕
|
// 判定是否执行完毕
|
||||||
if (this._doAction_finishEvents()) return;
|
if (this._doAction_finishEvents()) return;
|
||||||
// 当前点坐标和前缀
|
// 当前点坐标和前缀
|
||||||
@ -799,7 +815,7 @@ events.prototype._popEvents = function (current, prefix) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
////// 往当前事件列表之前添加一个或多个事件 //////
|
////// 往当前事件列表之前或之后添加一个或多个事件 //////
|
||||||
events.prototype.insertAction = function (action, x, y, callback, addToLast) {
|
events.prototype.insertAction = function (action, x, y, callback, addToLast) {
|
||||||
if (core.hasFlag("__statistics__")) return;
|
if (core.hasFlag("__statistics__")) return;
|
||||||
if (core.status.gameOver) return;
|
if (core.status.gameOver) return;
|
||||||
@ -810,7 +826,7 @@ events.prototype.insertAction = function (action, x, y, callback, addToLast) {
|
|||||||
if (!action) return;
|
if (!action) return;
|
||||||
|
|
||||||
if (core.status.event.id != 'action') {
|
if (core.status.event.id != 'action') {
|
||||||
this.doEvents(action, x, y, callback);
|
this.startEvents(action, x, y, callback);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (addToLast)
|
if (addToLast)
|
||||||
@ -1022,10 +1038,7 @@ events.prototype._action_jumpHero = function (data, x, y, prefix) {
|
|||||||
events.prototype._action_changeFloor = function (data, x, y, prefix) {
|
events.prototype._action_changeFloor = function (data, x, y, prefix) {
|
||||||
var loc = this.__action_getHeroLoc(data.loc, prefix);
|
var loc = this.__action_getHeroLoc(data.loc, prefix);
|
||||||
var heroLoc = {x: loc[0], y: loc[1], direction: data.direction};
|
var heroLoc = {x: loc[0], y: loc[1], direction: data.direction};
|
||||||
core.changeFloor(data.floorId || core.status.floorId, null, heroLoc, data.time, function () {
|
core.changeFloor(data.floorId || core.status.floorId, null, heroLoc, data.time, core.doAction);
|
||||||
core.lockControl();
|
|
||||||
core.doAction();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
events.prototype._action_changePos = function (data, x, y, prefix) {
|
events.prototype._action_changePos = function (data, x, y, prefix) {
|
||||||
@ -1068,13 +1081,17 @@ events.prototype._action_moveImage = function (data, x, y, prefix) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
events.prototype._action_setFg = 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) {
|
if (data.async) {
|
||||||
core.setFg(data.color, data.time);
|
core.setCurtain(data.color, data.time);
|
||||||
core.setFlag('__color__', data.color || null);
|
core.setFlag('__color__', data.color || null);
|
||||||
core.doAction();
|
core.doAction();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
core.setFg(data.color, data.time, function () {
|
core.setCurtain(data.color, data.time, function () {
|
||||||
core.setFlag('__color__', data.color || null);
|
core.setFlag('__color__', data.color || null);
|
||||||
core.doAction();
|
core.doAction();
|
||||||
});
|
});
|
||||||
@ -1097,10 +1114,7 @@ events.prototype._action_openDoor = function (data, x, y, prefix) {
|
|||||||
var loc = this.__action_getLoc(data.loc, x, y, prefix);
|
var loc = this.__action_getLoc(data.loc, x, y, prefix);
|
||||||
var floorId = data.floorId || core.status.floorId;
|
var floorId = data.floorId || core.status.floorId;
|
||||||
if (floorId == core.status.floorId) {
|
if (floorId == core.status.floorId) {
|
||||||
core.openDoor(null, loc[0], loc[1], data.needKey, function () {
|
core.openDoor(loc[0], loc[1], data.needKey, core.doAction);
|
||||||
core.lockControl();
|
|
||||||
core.doAction();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
core.removeBlock(loc[0], loc[1], floorId);
|
core.removeBlock(loc[0], loc[1], floorId);
|
||||||
@ -1148,14 +1162,10 @@ events.prototype._action_trigger = function (data, x, y, prefix) {
|
|||||||
if (block != null && block.block.event.trigger) {
|
if (block != null && block.block.event.trigger) {
|
||||||
block = block.block;
|
block = block.block;
|
||||||
this.setEvents([], block.x, block.y);
|
this.setEvents([], block.x, block.y);
|
||||||
var _callback = function () {
|
|
||||||
core.lockControl();
|
|
||||||
core.doAction();
|
|
||||||
}
|
|
||||||
if (block.event.trigger == 'action')
|
if (block.event.trigger == 'action')
|
||||||
this.setEvents(block.event.data);
|
this.setEvents(block.event.data);
|
||||||
else {
|
else {
|
||||||
core.doSystemEvent(block.event.trigger, block, _callback);
|
core.doSystemEvent(block.event.trigger, block, core.doAction);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1213,6 +1223,7 @@ events.prototype._action_freeBgm = function (data, x, y, prefix) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
events.prototype._action_playSound = function (data, x, y, prefix) {
|
events.prototype._action_playSound = function (data, x, y, prefix) {
|
||||||
|
if (data.stop) core.stopSound();
|
||||||
core.playSound(data.name);
|
core.playSound(data.name);
|
||||||
core.doAction();
|
core.doAction();
|
||||||
}
|
}
|
||||||
@ -1318,13 +1329,16 @@ events.prototype._action_if = function (data, x, y, prefix) {
|
|||||||
|
|
||||||
events.prototype._action_switch = function (data, x, y, prefix) {
|
events.prototype._action_switch = function (data, x, y, prefix) {
|
||||||
var key = core.calValue(data.condition, prefix)
|
var key = core.calValue(data.condition, prefix)
|
||||||
|
var list = [];
|
||||||
for (var i = 0; i < data.caseList.length; i++) {
|
for (var i = 0; i < data.caseList.length; i++) {
|
||||||
var condition = data.caseList[i]["case"];
|
var condition = data.caseList[i]["case"];
|
||||||
if (condition == "default" || core.calValue(condition, prefix) == key) {
|
if (condition == "default" || core.calValue(condition, prefix) == key) {
|
||||||
this.insertAction(data.caseList[i].action);
|
core.push(list, data.caseList[i].action);
|
||||||
break;
|
if (!data.caseList[i].nobreak)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
core.insertAction(list);
|
||||||
core.doAction();
|
core.doAction();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1352,6 +1366,35 @@ events.prototype._action_choices = function (data, x, y, prefix) {
|
|||||||
core.ui.drawChoices(data.text, data.choices);
|
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) {
|
events.prototype._action_while = function (data, x, y, prefix) {
|
||||||
if (core.calValue(data.condition, prefix)) {
|
if (core.calValue(data.condition, prefix)) {
|
||||||
core.unshift(core.status.event.data.list,
|
core.unshift(core.status.event.data.list,
|
||||||
@ -1641,7 +1684,6 @@ events.prototype.load = function (fromUserAction) {
|
|||||||
core.dom.startPanel.style.display = 'none';
|
core.dom.startPanel.style.display = 'none';
|
||||||
core.clearStatus();
|
core.clearStatus();
|
||||||
core.clearMap('all');
|
core.clearMap('all');
|
||||||
core.deleteAllCanvas();
|
|
||||||
core.status.event = {'id': 'load', 'data': null};
|
core.status.event = {'id': 'load', 'data': null};
|
||||||
core.status.lockControl = true;
|
core.status.lockControl = true;
|
||||||
core.ui.drawSLPanel(10*page+offset);
|
core.ui.drawSLPanel(10*page+offset);
|
||||||
@ -1698,24 +1740,6 @@ events.prototype.unfollow = function (name) {
|
|||||||
core.drawHero();
|
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) {
|
events.prototype.setValue = function (name, value, prefix, add) {
|
||||||
var value = core.calValue(value, prefix);
|
var value = core.calValue(value, prefix);
|
||||||
@ -1919,6 +1943,24 @@ events.prototype._moveImage_moving = function (name, moveInfo, callback) {
|
|||||||
core.animateFrame.asyncId[animate] = true;
|
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) {
|
events.prototype.setVolume = function (value, time, callback) {
|
||||||
var set = function (value) {
|
var set = function (value) {
|
||||||
@ -2040,7 +2082,7 @@ events.prototype.jumpHero = function (ex, ey, time, callback) {
|
|||||||
var sx=core.status.hero.loc.x, sy=core.status.hero.loc.y;
|
var sx=core.status.hero.loc.x, sy=core.status.hero.loc.y;
|
||||||
if (!core.isset(ex)) ex=sx;
|
if (!core.isset(ex)) ex=sx;
|
||||||
if (!core.isset(ey)) ey=sy;
|
if (!core.isset(ey)) ey=sy;
|
||||||
core.maps.__playJumpSound();
|
core.playSound('jump.mp3');
|
||||||
var jumpInfo = core.maps.__generateJumpInfo(sx, sy, ex, ey, time || 500);
|
var jumpInfo = core.maps.__generateJumpInfo(sx, sy, ex, ey, time || 500);
|
||||||
jumpInfo.icon = core.material.icons.hero[core.getHeroLoc('direction')];
|
jumpInfo.icon = core.material.icons.hero[core.getHeroLoc('direction')];
|
||||||
jumpInfo.height = core.material.icons.hero.height;
|
jumpInfo.height = core.material.icons.hero.height;
|
||||||
@ -2209,7 +2251,7 @@ events.prototype.afterUseBomb = function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////// 上传当前数据 //////
|
////// 上传当前数据 //////
|
||||||
events.prototype.uploadCurrent = function (username) {
|
events.prototype._uploadCurrent = function (username) {
|
||||||
var formData = new FormData();
|
var formData = new FormData();
|
||||||
|
|
||||||
formData.append('type', 'score');
|
formData.append('type', 'score');
|
||||||
|
|||||||
@ -196,20 +196,6 @@ items.prototype.setItem = function (itemId, itemNum) {
|
|||||||
core.updateStatusBar();
|
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) {
|
items.prototype.addItem = function (itemId, itemNum) {
|
||||||
if (itemNum == null) itemNum = 1;
|
if (itemNum == null) itemNum = 1;
|
||||||
@ -230,15 +216,22 @@ items.prototype.addItem = function (itemId, itemNum) {
|
|||||||
core.updateStatusBar();
|
core.updateStatusBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------- 装备相关 ------------ //
|
////// 删除某个物品 //////
|
||||||
|
items.prototype.removeItem = function (itemId, itemNum) {
|
||||||
items.prototype.getEquipTypeById = function (equipId) {
|
if (itemNum == null) itemNum = 1;
|
||||||
var type = core.material.items[equipId].equip.type;
|
if (!core.hasItem(itemId)) return false;
|
||||||
if (typeof type == 'string')
|
var itemCls = core.material.items[itemId].cls;
|
||||||
type = this.getEquipTypeByName(type);
|
core.status.hero.items[itemCls][itemId] -= itemNum;
|
||||||
return type;
|
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) {
|
items.prototype.getEquipTypeByName = function (name) {
|
||||||
var names = core.status.globalAttribute.equipName;
|
var names = core.status.globalAttribute.equipName;
|
||||||
for (var i = 0; i < names.length; ++i) {
|
for (var i = 0; i < names.length; ++i) {
|
||||||
@ -249,6 +242,13 @@ items.prototype.getEquipTypeByName = function (name) {
|
|||||||
return -1;
|
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) {
|
items.prototype.canEquip = function (equipId, hint) {
|
||||||
// 装备是否合法
|
// 装备是否合法
|
||||||
@ -365,8 +365,8 @@ items.prototype._realLoadEquip = function (type, loadId, unloadId, callback) {
|
|||||||
core.status.hero.equipment[type] = loadId || null;
|
core.status.hero.equipment[type] = loadId || null;
|
||||||
|
|
||||||
// --- 提示
|
// --- 提示
|
||||||
if (loadId) core.drawTip("已装备上" + loadEquip.name, core.material.icons.items[loadId]);
|
if (loadId) core.drawTip("已装备上" + loadEquip.name, loadId);
|
||||||
else if (unloadId) core.drawTip("已卸下" + unloadEquip.name, core.material.icons.items[unloadId]);
|
else if (unloadId) core.drawTip("已卸下" + unloadEquip.name, unloadId);
|
||||||
|
|
||||||
if (callback) callback();
|
if (callback) callback();
|
||||||
}
|
}
|
||||||
|
|||||||
152
libs/maps.js
152
libs/maps.js
@ -155,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 = {};
|
var maps = {};
|
||||||
for (var i = 0; i < floorIds.length; i++) {
|
for (var i = 0; i < floorIds.length; i++) {
|
||||||
var floorId = floorIds[i];
|
var floorId = floorIds[i];
|
||||||
@ -242,7 +243,7 @@ maps.prototype.saveMap = function (floorId) {
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
var map = maps[floorId], floor = core.floors[floorId];
|
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;
|
if (main.mode == 'editor') return blocks;
|
||||||
|
|
||||||
var thisFloor = this._compressFloorData(map, floor);
|
var thisFloor = this._compressFloorData(map, floor);
|
||||||
@ -297,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') {
|
if (typeof blockArray == 'string') {
|
||||||
var floorId = blockArray;
|
var floorId = blockArray;
|
||||||
blockArray = core.status.maps[floorId].blocks;
|
blockArray = core.status.maps[floorId].blocks;
|
||||||
@ -313,11 +320,11 @@ maps.prototype.getMapArray = function (blockArray, width, height, checkDisable)
|
|||||||
blockArray.forEach(function (block) {
|
blockArray.forEach(function (block) {
|
||||||
var x = block.x, y = block.y;
|
var x = block.x, y = block.y;
|
||||||
if (block.disable) {
|
if (block.disable) {
|
||||||
if (checkDisable) blocks[y][x] = block.id + ":f";
|
if (showDisable) blocks[y][x] = block.id + ":f";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
blocks[y][x] = block.id;
|
blocks[y][x] = block.id;
|
||||||
if (checkDisable && block.disable === false)
|
if (showDisable && block.disable === false)
|
||||||
blocks[y][x] = block.id + ":t";
|
blocks[y][x] = block.id + ":t";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -336,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;
|
floorId = floorId || core.status.floorId;
|
||||||
if (!floorId) return [];
|
if (!floorId) return [];
|
||||||
var width = core.floors[floorId].width;
|
var width = core.floors[floorId].width;
|
||||||
@ -362,10 +369,26 @@ maps.prototype.getBgFgMapArray = function (name, floorId, noCache) {
|
|||||||
return arr;
|
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 (x == null) x = core.getHeroLoc('x');
|
||||||
if (y == null) y = core.getHeroLoc('y');
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------ 当前能否朝某方向移动,能否瞬间移动 ------ //
|
// ------ 当前能否朝某方向移动,能否瞬间移动 ------ //
|
||||||
@ -375,8 +398,8 @@ maps.prototype.generateMovableArray = function (floorId, x, y, direction) {
|
|||||||
floorId = floorId || core.status.floorId;
|
floorId = floorId || core.status.floorId;
|
||||||
if (!floorId) return null;
|
if (!floorId) return null;
|
||||||
var width = core.floors[floorId].width, height = core.floors[floorId].height;
|
var width = core.floors[floorId].width, height = core.floors[floorId].height;
|
||||||
var bgArray = this.getBgFgMapArray('bg', floorId),
|
var bgArray = this.getBgMapArray(floorId),
|
||||||
fgArray = this.getBgFgMapArray('fg', floorId),
|
fgArray = this.getFgMapArray(floorId),
|
||||||
eventArray = this.getMapArray(floorId);
|
eventArray = this.getMapArray(floorId);
|
||||||
|
|
||||||
var generate = function (x, y, direction) {
|
var generate = function (x, y, direction) {
|
||||||
@ -489,7 +512,7 @@ maps.prototype._canMoveDirectly_bfs = function (sx, sy, ex, ey) {
|
|||||||
var canMoveArray = this.generateMovableArray();
|
var canMoveArray = this.generateMovableArray();
|
||||||
var blocksObj = this.getMapBlocksObj(core.status.floorId);
|
var blocksObj = this.getMapBlocksObj(core.status.floorId);
|
||||||
// 滑冰
|
// 滑冰
|
||||||
var bgMap = this.getBgFgMapArray('bg');
|
var bgMap = this.getBgMapArray();
|
||||||
|
|
||||||
var visited = [], queue = [];
|
var visited = [], queue = [];
|
||||||
visited[sx + "," + sy] = 0;
|
visited[sx + "," + sy] = 0;
|
||||||
@ -685,7 +708,7 @@ maps.prototype._drawMap_drawAll = function (floorId) {
|
|||||||
maps.prototype._drawMap_drawBlockInfo = function (ctx, block, blockInfo, arr, onMap) {
|
maps.prototype._drawMap_drawBlockInfo = function (ctx, block, blockInfo, arr, onMap) {
|
||||||
if (blockInfo == null) return;
|
if (blockInfo == null) return;
|
||||||
if (blockInfo.cls == 'autotile') { // Autotile单独处理
|
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);
|
if (onMap) this.addGlobalAnimate(block);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -700,15 +723,16 @@ maps.prototype._drawMap_drawBlockInfo = function (ctx, block, blockInfo, arr, on
|
|||||||
|
|
||||||
////// 绘制背景层 //////
|
////// 绘制背景层 //////
|
||||||
maps.prototype.drawBg = function (floorId, ctx) {
|
maps.prototype.drawBg = function (floorId, ctx) {
|
||||||
|
floorId = floorId || core.status.floorId;
|
||||||
var onMap = ctx == null;
|
var onMap = ctx == null;
|
||||||
if (onMap) {
|
if (onMap) {
|
||||||
ctx = core.canvas.bg;
|
ctx = core.canvas.bg;
|
||||||
core.clearMap(ctx);
|
core.clearMap(ctx);
|
||||||
}
|
}
|
||||||
this._drawBg_drawBackground(floorId, ctx);
|
core.maps._drawBg_drawBackground(floorId, ctx);
|
||||||
// ------ 调整这两行的顺序来控制是先绘制贴图还是先绘制背景图块;后绘制的覆盖先绘制的。
|
// ------ 调整这两行的顺序来控制是先绘制贴图还是先绘制背景图块;后绘制的覆盖先绘制的。
|
||||||
this._drawFloorImages(floorId, ctx, 'bg');
|
core.maps._drawFloorImages(floorId, ctx, 'bg');
|
||||||
this._drawBgFgMap(floorId, ctx, 'bg', onMap);
|
core.maps._drawBgFgMap(floorId, ctx, 'bg', onMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
maps.prototype._drawBg_drawBackground = function (floorId, ctx) {
|
maps.prototype._drawBg_drawBackground = function (floorId, ctx) {
|
||||||
@ -728,7 +752,7 @@ maps.prototype._drawBg_drawBackground = function (floorId, ctx) {
|
|||||||
maps.prototype.drawEvents = function (floorId, blocks, ctx) {
|
maps.prototype.drawEvents = function (floorId, blocks, ctx) {
|
||||||
floorId = floorId || core.status.floorId;
|
floorId = floorId || core.status.floorId;
|
||||||
if (!blocks) blocks = core.status.maps[floorId].blocks;
|
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;
|
var onMap = ctx == null;
|
||||||
if (onMap) ctx = core.canvas.event;
|
if (onMap) ctx = core.canvas.event;
|
||||||
blocks.filter(function (block) {
|
blocks.filter(function (block) {
|
||||||
@ -741,6 +765,7 @@ maps.prototype.drawEvents = function (floorId, blocks, ctx) {
|
|||||||
|
|
||||||
////// 绘制前景层 //////
|
////// 绘制前景层 //////
|
||||||
maps.prototype.drawFg = function (floorId, ctx) {
|
maps.prototype.drawFg = function (floorId, ctx) {
|
||||||
|
floorId = floorId || core.status.floorId;
|
||||||
var onMap = ctx == null;
|
var onMap = ctx == null;
|
||||||
if (onMap) ctx = core.canvas.fg;
|
if (onMap) ctx = core.canvas.fg;
|
||||||
// ------ 调整这两行的顺序来控制是先绘制贴图还是先绘制背景图块;后绘制的覆盖先绘制的。
|
// ------ 调整这两行的顺序来控制是先绘制贴图还是先绘制背景图块;后绘制的覆盖先绘制的。
|
||||||
@ -758,7 +783,7 @@ maps.prototype._drawBgFgMap = function (floorId, ctx, name, onMap) {
|
|||||||
if (!core.status[name + "maps"])
|
if (!core.status[name + "maps"])
|
||||||
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 x = 0; x < width; x++) {
|
||||||
for (var y = 0; y < height; y++) {
|
for (var y = 0; y < height; y++) {
|
||||||
var block = this.initBlock(x, y, arr[y][x], true);
|
var block = this.initBlock(x, y, arr[y][x], true);
|
||||||
@ -850,7 +875,7 @@ maps.prototype._drawFloorImage = function (ctx, name, type, image, offsetX, widt
|
|||||||
}
|
}
|
||||||
|
|
||||||
////// 绘制Autotile //////
|
////// 绘制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的小块; 数组索引即对应各个小块
|
var indexArrs = [ //16种组合的图块索引数组; // 将autotile分割成48块16*16的小块; 数组索引即对应各个小块
|
||||||
// +----+----+----+----+----+----+
|
// +----+----+----+----+----+----+
|
||||||
[10, 9, 4, 3], //0 bin:0000 | 1 | 2 | 3 | 4 | 5 | 6 |
|
[10, 9, 4, 3], //0 bin:0000 | 1 | 2 | 3 | 4 | 5 | 6 |
|
||||||
@ -1215,7 +1240,7 @@ maps.prototype.searchBlock = function (id, floorId, showDisable) {
|
|||||||
for (var i = 0; i < core.status.maps[floorId].blocks.length; ++i) {
|
for (var i = 0; i < core.status.maps[floorId].blocks.length; ++i) {
|
||||||
var block = core.status.maps[floorId].blocks[i];
|
var block = core.status.maps[floorId].blocks[i];
|
||||||
if (block.event.id == id && (showDisable || !block.disable))
|
if (block.event.id == id && (showDisable || !block.disable))
|
||||||
result.push({floorId: floorId, index: i, block: block});
|
result.push({floorId: floorId, index: i, block: block, x: block.x, y: block.y});
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -1301,19 +1326,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 //////
|
////// 一次性删除多个block //////
|
||||||
maps.prototype.removeBlockByIds = function (floorId, ids) {
|
maps.prototype.removeBlockByIds = function (floorId, ids) {
|
||||||
floorId = floorId || core.status.floorId;
|
floorId = floorId || core.status.floorId;
|
||||||
@ -1325,24 +1337,17 @@ maps.prototype.removeBlockByIds = function (floorId, ids) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
////// 将地图中所有某个图块替换成另一个图块 //////
|
////// 能否彻底从地图中删除一个图块 //////
|
||||||
maps.prototype.replaceBlock = function (fromNumber, toNumber, floorId) {
|
maps.prototype.canRemoveBlock = function (block, floorId) {
|
||||||
floorId = floorId || core.status.floorId;
|
var x = block.x, y = block.y;
|
||||||
if (floorId instanceof Array) {
|
// 检查该点是否存在事件
|
||||||
floorId.forEach(function (floorId) {
|
if (core.floors[floorId].events[x + "," + y] || core.floors[floorId].changeFloor[x + "," + y])
|
||||||
core.replaceBlock(fromNumber, toNumber, floorId);
|
return false;
|
||||||
});
|
// 检查是否存在重生
|
||||||
return;
|
if (block.event && block.event.cls.indexOf('enemy') == 0 && core.hasSpecial(block.event.id, 23))
|
||||||
}
|
return false;
|
||||||
var toBlock = this.initBlock(0, 0, toNumber, true);
|
|
||||||
core.status.maps[floorId].blocks.forEach(function (block) {
|
return true;
|
||||||
if (block.id == fromNumber) {
|
|
||||||
block.id = toNumber;
|
|
||||||
for (var one in toBlock.event) {
|
|
||||||
block.event[one] = core.clone(toBlock.event[one]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////// 显示前景/背景地图 //////
|
////// 显示前景/背景地图 //////
|
||||||
@ -1420,6 +1425,7 @@ maps.prototype.setBlock = function (number, x, y, floorId) {
|
|||||||
floorId = floorId || core.status.floorId;
|
floorId = floorId || core.status.floorId;
|
||||||
if (!floorId || number == null || x == null || y == null) return;
|
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 (x < 0 || x >= core.floors[floorId].width || y < 0 || y >= core.floors[floorId].height) return;
|
||||||
|
if (typeof number == 'string') number = core.getNumberById(number);
|
||||||
|
|
||||||
var originBlock = core.getBlock(x, y, floorId, true);
|
var originBlock = core.getBlock(x, y, floorId, true);
|
||||||
var block = this.initBlock(x, y, number, true, core.floors[floorId]);
|
var block = this.initBlock(x, y, number, true, core.floors[floorId]);
|
||||||
@ -1447,6 +1453,26 @@ 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) {
|
maps.prototype.setBgFgBlock = function (name, number, x, y, floorId) {
|
||||||
floorId = floorId || core.status.floorId;
|
floorId = floorId || core.status.floorId;
|
||||||
@ -1629,10 +1655,8 @@ maps.prototype.jumpBlock = function (sx, sy, ex, ey, time, keep, callback) {
|
|||||||
var block = blockArr[0], blockInfo = blockArr[1];
|
var block = blockArr[0], blockInfo = blockArr[1];
|
||||||
var canvases = this._initDetachedBlock(blockInfo, sx, sy, block.event.animate !== false);
|
var canvases = this._initDetachedBlock(blockInfo, sx, sy, block.event.animate !== false);
|
||||||
this._moveDetachedBlock(blockInfo, 32 * sx, 32 * sy, 1, canvases);
|
this._moveDetachedBlock(blockInfo, 32 * sx, 32 * sy, 1, canvases);
|
||||||
|
core.playSound('jump.mp3');
|
||||||
this.__playJumpSound();
|
var jumpInfo = this.__generateJumpInfo(sx, sy, ex, ey, time);
|
||||||
|
|
||||||
var jumpInfo = ths.__generateJumpInfo(sx, sy, ex, ey, time);
|
|
||||||
jumpInfo.keep = keep;
|
jumpInfo.keep = keep;
|
||||||
|
|
||||||
this._jumpBlock_doJump(blockInfo, canvases, jumpInfo, callback);
|
this._jumpBlock_doJump(blockInfo, canvases, jumpInfo, callback);
|
||||||
@ -1644,14 +1668,10 @@ maps.prototype.__generateJumpInfo = function (sx, sy, ex, ey, time) {
|
|||||||
return {
|
return {
|
||||||
x: sx, y: sy, ex: ex, ey: ey, px: 32 * sx, py: 32 * sy, opacity: 1,
|
x: sx, y: sy, ex: ex, ey: ey, px: 32 * sx, py: 32 * sy, opacity: 1,
|
||||||
jump_peak: jump_peak, jump_count: jump_count,
|
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) {
|
maps.prototype._jumpBlock_doJump = function (blockInfo, canvases, jumpInfo, callback) {
|
||||||
var animate = window.setInterval(function () {
|
var animate = window.setInterval(function () {
|
||||||
if (jumpInfo.jump_count > 0)
|
if (jumpInfo.jump_count > 0)
|
||||||
@ -1766,16 +1786,16 @@ maps.prototype._animateBlock_drawList = function (list, opacity) {
|
|||||||
// ------ 全局动画控制,动画绘制 ------ //
|
// ------ 全局动画控制,动画绘制 ------ //
|
||||||
|
|
||||||
////// 添加一个全局动画 //////
|
////// 添加一个全局动画 //////
|
||||||
maps.prototype.addGlobalAnimate = function (b) {
|
maps.prototype.addGlobalAnimate = function (block) {
|
||||||
if (!b.event || b.event.animate == null) return;
|
if (!block.event || block.event.animate == null) return;
|
||||||
if (b.event.cls == 'autotile') {
|
if (block.event.cls == 'autotile') {
|
||||||
var id = b.event.id, img = core.material.images.autotile[id];
|
var id = block.event.id, img = core.material.images.autotile[id];
|
||||||
if (!img || img.width == 96) return;
|
if (!img || img.width == 96) return;
|
||||||
core.status.autotileAnimateObjs.blocks.push(b);
|
core.status.autotileAnimateObjs.blocks.push(block);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!b.event.animate || b.event.animate == 1) return;
|
if (!block.event.animate || block.event.animate == 1) return;
|
||||||
core.status.globalAnimateObjs.push(b);
|
core.status.globalAnimateObjs.push(block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
132
libs/ui.js
132
libs/ui.js
@ -23,12 +23,13 @@ ui.prototype._init = function () {
|
|||||||
|
|
||||||
////////////////// 地图设置
|
////////////////// 地图设置
|
||||||
|
|
||||||
ui.prototype.getContextByName = function (canvas) {
|
ui.prototype.getContextByName = function (name) {
|
||||||
if (typeof canvas == 'string') {
|
var canvas = name;
|
||||||
if (core.canvas[canvas])
|
if (typeof name == 'string') {
|
||||||
canvas = core.canvas[canvas];
|
if (core.canvas[name])
|
||||||
else if (core.dymCanvas[canvas])
|
canvas = core.canvas[name];
|
||||||
canvas = core.dymCanvas[canvas];
|
else if (core.dymCanvas[name])
|
||||||
|
canvas = core.dymCanvas[name];
|
||||||
}
|
}
|
||||||
if (canvas && canvas.canvas) {
|
if (canvas && canvas.canvas) {
|
||||||
return canvas;
|
return canvas;
|
||||||
@ -190,6 +191,36 @@ ui.prototype.calWidth = function (name, text, font) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// 字符串自动换行的分割 //////
|
||||||
|
ui.prototype.splitLines = function (name, text, maxWidth, font) {
|
||||||
|
var ctx = this.getContextByName(name);
|
||||||
|
if (!ctx) return;
|
||||||
|
if (font) core.setFont(name, 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(name, toAdd);
|
||||||
|
if (maxWidth && width > maxWidth) {
|
||||||
|
contents.push(text.substring(last, i));
|
||||||
|
last = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
contents.push(text.substring(last));
|
||||||
|
return contents;
|
||||||
|
}
|
||||||
|
|
||||||
////// 绘制一张图片 //////
|
////// 绘制一张图片 //////
|
||||||
ui.prototype.drawImage = function (name, image, x, y, w, h, x1, y1, w1, h1) {
|
ui.prototype.drawImage = function (name, image, x, y, w, h, x1, y1, w1, h1) {
|
||||||
var ctx = this.getContextByName(name);
|
var ctx = this.getContextByName(name);
|
||||||
@ -233,25 +264,23 @@ ui.prototype.clearUI = function () {
|
|||||||
clearInterval(core.status.event.interval);
|
clearInterval(core.status.event.interval);
|
||||||
core.status.event.interval = null;
|
core.status.event.interval = null;
|
||||||
core.status.boxAnimateObjs = [];
|
core.status.boxAnimateObjs = [];
|
||||||
core.clearSelector();
|
|
||||||
core.clearMap('ui');
|
|
||||||
core.setAlpha('ui', 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
////// 清除光标 //////
|
|
||||||
ui.prototype.clearSelector = function () {
|
|
||||||
if (core.dymCanvas._selector) core.deleteCanvas("_selector");
|
if (core.dymCanvas._selector) core.deleteCanvas("_selector");
|
||||||
core.clearMap('ui');
|
core.clearMap('ui');
|
||||||
core.setAlpha('ui', 1);
|
core.setAlpha('ui', 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
////// 左上角绘制一段提示 //////
|
////// 左上角绘制一段提示 //////
|
||||||
ui.prototype.drawTip = function (text, itemIcon) {
|
ui.prototype.drawTip = function (text, id) {
|
||||||
var textX, textY, width, height;
|
var textX, textY, width, height;
|
||||||
clearInterval(core.interval.tipAnimate);
|
clearInterval(core.interval.tipAnimate);
|
||||||
core.setFont('data', "16px Arial");
|
core.setFont('data', "16px Arial");
|
||||||
core.setTextAlign('data', 'left');
|
core.setTextAlign('data', 'left');
|
||||||
if (!itemIcon) {
|
if (id != null) {
|
||||||
|
var info = core.getBlockInfo(id);
|
||||||
|
if (info == null || !info.image || info.height != 32) id = null;
|
||||||
|
else id = info;
|
||||||
|
}
|
||||||
|
if (!id) {
|
||||||
textX = 16;
|
textX = 16;
|
||||||
textY = 18;
|
textY = 18;
|
||||||
width = textX + core.calWidth('data', text) + 16;
|
width = textX + core.calWidth('data', text) + 16;
|
||||||
@ -263,10 +292,10 @@ ui.prototype.drawTip = function (text, itemIcon) {
|
|||||||
width = textX + core.calWidth('data', text) + 8;
|
width = textX + core.calWidth('data', text) + 8;
|
||||||
height = 42;
|
height = 42;
|
||||||
}
|
}
|
||||||
this._drawTip_animate(text, itemIcon, textX, textY, width, height);
|
this._drawTip_animate(text, id, textX, textY, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.prototype._drawTip_animate = function (text, itemIcon, textX, textY, width, height) {
|
ui.prototype._drawTip_animate = function (text, info, textX, textY, width, height) {
|
||||||
var alpha = 0, hide = false;
|
var alpha = 0, hide = false;
|
||||||
core.interval.tipAnimate = window.setInterval(function () {
|
core.interval.tipAnimate = window.setInterval(function () {
|
||||||
if (hide) alpha -= 0.1;
|
if (hide) alpha -= 0.1;
|
||||||
@ -274,8 +303,8 @@ ui.prototype._drawTip_animate = function (text, itemIcon, textX, textY, width, h
|
|||||||
core.clearMap('data', 5, 5, core.ui.PIXEL, height);
|
core.clearMap('data', 5, 5, core.ui.PIXEL, height);
|
||||||
core.setAlpha('data', alpha);
|
core.setAlpha('data', alpha);
|
||||||
core.fillRect('data', 5, 5, width, height, '#000');
|
core.fillRect('data', 5, 5, width, height, '#000');
|
||||||
if (itemIcon)
|
if (info)
|
||||||
core.drawImage('data', core.material.images.items, 0, itemIcon * 32, 32, 32, 10, 8, 32, 32);
|
core.drawImage('data', info.image, info.posX * 32, info.posY * 32, 32, 32, 10, 8, 32, 32);
|
||||||
core.fillText('data', text, textX + 5, textY + 15, '#fff');
|
core.fillText('data', text, textX + 5, textY + 15, '#fff');
|
||||||
core.setAlpha('data', 1);
|
core.setAlpha('data', 1);
|
||||||
if (alpha > 0.6 || alpha < 0) {
|
if (alpha > 0.6 || alpha < 0) {
|
||||||
@ -507,13 +536,13 @@ ui.prototype.drawBackground = function (left, top, right, bottom, posInfo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////// 计算有效文本框的宽度
|
////// 计算有效文本框的宽度
|
||||||
ui.prototype.calTextBoxWidth = function (ctx, content, min_width, max_width, font) {
|
ui.prototype._calTextBoxWidth = function (ctx, content, min_width, max_width, font) {
|
||||||
// 无限长度自动换行
|
// 无限长度自动换行
|
||||||
var allLines = core.splitLines(ctx, content, null, font);
|
var allLines = core.splitLines(ctx, content, null, font);
|
||||||
|
|
||||||
// 如果不存在手动换行,尽量调成半行形式
|
// 如果不存在手动换行,尽量调成半行形式
|
||||||
if (allLines.length == 1) {
|
if (allLines.length == 1) {
|
||||||
var w = core.calWidth(ctx, allLines[0]);
|
var w = core.calWidth(ctx, allLines[0]) + 10;
|
||||||
if (w<min_width*2.3) return core.clamp(w / 1.4, min_width, max_width);
|
if (w<min_width*2.3) return core.clamp(w / 1.4, min_width, max_width);
|
||||||
if (w<max_width*2.2) return core.clamp(w / 2.4, min_width, max_width);
|
if (w<max_width*2.2) return core.clamp(w / 2.4, min_width, max_width);
|
||||||
return core.clamp(w / 3.4, min_width, max_width);
|
return core.clamp(w / 3.4, min_width, max_width);
|
||||||
@ -521,7 +550,7 @@ ui.prototype.calTextBoxWidth = function (ctx, content, min_width, max_width, fon
|
|||||||
// 存在手动换行:以最长的为准
|
// 存在手动换行:以最长的为准
|
||||||
else {
|
else {
|
||||||
return core.clamp(allLines.reduce(function (pre, curr) {
|
return core.clamp(allLines.reduce(function (pre, curr) {
|
||||||
return Math.max(pre, core.calWidth(ctx, curr))
|
return Math.max(pre, core.calWidth(ctx, curr) + 10);
|
||||||
}, 0), min_width, max_width);
|
}, 0), min_width, max_width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -794,7 +823,7 @@ ui.prototype._drawTextBox_getHorizontalPosition = function (content, titleInfo,
|
|||||||
var min_width = 220 - paddingLeft, max_width = validWidth;
|
var min_width = 220 - paddingLeft, max_width = validWidth;
|
||||||
// 无行走图或头像,则可以适当缩小min_width
|
// 无行走图或头像,则可以适当缩小min_width
|
||||||
if (titleInfo.image == null) min_width = 160;
|
if (titleInfo.image == null) min_width = 160;
|
||||||
validWidth = this.calTextBoxWidth('ui', realContent, min_width, max_width, this._buildFont());
|
validWidth = this._calTextBoxWidth('ui', realContent, min_width, max_width, this._buildFont());
|
||||||
width = validWidth + paddingLeft + paddingRight;
|
width = validWidth + paddingLeft + paddingRight;
|
||||||
left = core.clamp(32 * posInfo.px + 16 - width / 2 - core.bigmap.offsetX, left, right - width);
|
left = core.clamp(32 * posInfo.px + 16 - width / 2 - core.bigmap.offsetX, left, right - width);
|
||||||
right = left + width;
|
right = left + width;
|
||||||
@ -1052,9 +1081,13 @@ ui.prototype.drawConfirmBox = function (text, yesCallback, noCallback) {
|
|||||||
core.lockControl();
|
core.lockControl();
|
||||||
text = core.replaceText(text || "");
|
text = core.replaceText(text || "");
|
||||||
|
|
||||||
core.status.event.id = 'confirmBox';
|
// 处理自定义事件
|
||||||
core.status.event.data = {'yes': yesCallback, 'no': noCallback};
|
if (core.status.event.id != 'action') {
|
||||||
core.status.event.ui = text;
|
core.status.event.id = 'confirmBox';
|
||||||
|
core.status.event.ui = text;
|
||||||
|
core.status.event.data = {'yes': yesCallback, 'no': noCallback};
|
||||||
|
}
|
||||||
|
|
||||||
if (core.status.event.selection != 0) core.status.event.selection = 1;
|
if (core.status.event.selection != 0) core.status.event.selection = 1;
|
||||||
this.clearUI();
|
this.clearUI();
|
||||||
|
|
||||||
@ -1090,6 +1123,20 @@ ui.prototype._drawConfirmBox_getRect = function (contents) {
|
|||||||
return { top: top, left: left, bottom: bottom, right: right, width: right - left, height: bottom - top };
|
return { top: top, left: left, bottom: bottom, right: right, width: right - left, height: bottom - top };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////// 绘制等待界面 //////
|
||||||
|
ui.prototype.drawWaiting = function(text) {
|
||||||
|
core.lockControl();
|
||||||
|
core.status.event.id = 'waiting';
|
||||||
|
core.clearUI();
|
||||||
|
text = core.replaceText(text || "");
|
||||||
|
var text_length = core.calWidth('ui', text, this._buildFont(19, true));
|
||||||
|
var width = Math.max(text_length + 80, 220), left = this.HPIXEL - parseInt(width / 2), right = left + width;
|
||||||
|
var top = this.HPIXEL - 48, height = 96, bottom = top + height;
|
||||||
|
this.drawBackground(left, top, right, bottom);
|
||||||
|
core.setTextAlign('ui', 'center');
|
||||||
|
core.fillText('ui', text, this.HPIXEL, top + 56, core.arrayToRGBA(core.status.textAttribute.text));
|
||||||
|
}
|
||||||
|
|
||||||
////// 绘制系统设置界面 //////
|
////// 绘制系统设置界面 //////
|
||||||
ui.prototype.drawSwitchs = function() {
|
ui.prototype.drawSwitchs = function() {
|
||||||
core.status.event.id = 'switchs';
|
core.status.event.id = 'switchs';
|
||||||
@ -1128,20 +1175,6 @@ ui.prototype.drawQuickShop = function () {
|
|||||||
this.drawChoices(null, choices);
|
this.drawChoices(null, choices);
|
||||||
}
|
}
|
||||||
|
|
||||||
////// 绘制等待界面 //////
|
|
||||||
ui.prototype.drawWaiting = function(text) {
|
|
||||||
core.lockControl();
|
|
||||||
core.status.event.id = 'waiting';
|
|
||||||
core.clearSelector();
|
|
||||||
text = core.replaceText(text || "");
|
|
||||||
var text_length = core.calWidth('ui', text, this._buildFont(19, true));
|
|
||||||
var width = Math.max(text_length + 80, 220), left = this.HPIXEL - parseInt(width / 2), right = left + width;
|
|
||||||
var top = this.HPIXEL - 48, height = 96, bottom = top + height;
|
|
||||||
this.drawBackground(left, top, right, bottom);
|
|
||||||
core.setTextAlign('ui', 'center');
|
|
||||||
core.fillText('ui', text, this.HPIXEL, top + 56, core.arrayToRGBA(core.status.textAttribute.text));
|
|
||||||
}
|
|
||||||
|
|
||||||
////// 绘制存档同步界面 //////
|
////// 绘制存档同步界面 //////
|
||||||
ui.prototype.drawSyncSave = function () {
|
ui.prototype.drawSyncSave = function () {
|
||||||
core.status.event.id = 'syncSave';
|
core.status.event.id = 'syncSave';
|
||||||
@ -1190,22 +1223,22 @@ ui.prototype.drawGameInfo = function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////// 绘制分页 //////
|
////// 绘制分页 //////
|
||||||
ui.prototype.drawPagination = function (page, totalPage, top) {
|
ui.prototype.drawPagination = function (page, totalPage, y) {
|
||||||
// if (totalPage<page) totalPage=page;
|
// if (totalPage<page) totalPage=page;
|
||||||
if (totalPage <= 1) return;
|
if (totalPage <= 1) return;
|
||||||
if (top == null) top = this.LAST;
|
if (y == null) y = this.LAST;
|
||||||
|
|
||||||
core.setFillStyle('ui', '#DDDDDD');
|
core.setFillStyle('ui', '#DDDDDD');
|
||||||
var length = core.calWidth('ui', page + " / " + page, this._buildFont(15, true));
|
var length = core.calWidth('ui', page + " / " + page, this._buildFont(15, true));
|
||||||
|
|
||||||
core.setTextAlign('ui', 'left');
|
core.setTextAlign('ui', 'left');
|
||||||
core.fillText('ui', page + " / " + totalPage, parseInt((this.PIXEL - length) / 2), top*32+19);
|
core.fillText('ui', page + " / " + totalPage, parseInt((this.PIXEL - length) / 2), y*32+19);
|
||||||
|
|
||||||
core.setTextAlign('ui', 'center');
|
core.setTextAlign('ui', 'center');
|
||||||
if (page > 1)
|
if (page > 1)
|
||||||
core.fillText('ui', '上一页', this.HPIXEL - 80, top*32+19);
|
core.fillText('ui', '上一页', this.HPIXEL - 80, y*32+19);
|
||||||
if (page < totalPage)
|
if (page < totalPage)
|
||||||
core.fillText('ui', '下一页', this.HPIXEL + 80, top*32+19);
|
core.fillText('ui', '下一页', this.HPIXEL + 80, y*32+19);
|
||||||
}
|
}
|
||||||
|
|
||||||
////// 绘制键盘光标 //////
|
////// 绘制键盘光标 //////
|
||||||
@ -1254,6 +1287,7 @@ ui.prototype.drawBook = function (index) {
|
|||||||
|
|
||||||
core.drawBoxAnimate();
|
core.drawBoxAnimate();
|
||||||
this.drawPagination(page, totalPage);
|
this.drawPagination(page, totalPage);
|
||||||
|
core.setTextAlign('ui', 'center');
|
||||||
core.fillText('ui', '返回游戏', this.PIXEL - 46, this.PIXEL - 13,'#DDDDDD', this._buildFont(15, true));
|
core.fillText('ui', '返回游戏', this.PIXEL - 46, this.PIXEL - 13,'#DDDDDD', this._buildFont(15, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1632,7 +1666,7 @@ ui.prototype.drawMaps = function (index, x, y) {
|
|||||||
var offsetX = 32 * (data.x - this.HSIZE), offsetY = 32 * (data.y - this.HSIZE);
|
var offsetX = 32 * (data.x - this.HSIZE), offsetY = 32 * (data.y - this.HSIZE);
|
||||||
var value = core.paint[data.floorId];
|
var value = core.paint[data.floorId];
|
||||||
if (value) value = lzw_decode(value).split(",");
|
if (value) value = lzw_decode(value).split(",");
|
||||||
core.utils.decodeCanvas(value, 32 * data.mw, 32 * data.mh);
|
core.utils._decodeCanvas(value, 32 * data.mw, 32 * data.mh);
|
||||||
core.drawImage('ui', core.bigmap.tempCanvas.canvas, offsetX * 32, offsetY * 32,
|
core.drawImage('ui', core.bigmap.tempCanvas.canvas, offsetX * 32, offsetY * 32,
|
||||||
this.PIXEL, this.PIXEL, 0, 0, this.PIXEL, this.PIXEL);
|
this.PIXEL, this.PIXEL, 0, 0, this.PIXEL, this.PIXEL);
|
||||||
}
|
}
|
||||||
@ -2358,13 +2392,13 @@ ui.prototype._drawPaint_draw = function () {
|
|||||||
core.status.event.id = 'paint';
|
core.status.event.id = 'paint';
|
||||||
core.status.event.data = {"x": null, "y": null, "erase": false};
|
core.status.event.data = {"x": null, "y": null, "erase": false};
|
||||||
|
|
||||||
core.clearSelector();
|
core.clearUI();
|
||||||
core.createCanvas('paint', -core.bigmap.offsetX, -core.bigmap.offsetY, 32*core.bigmap.width, 32*core.bigmap.height, 95);
|
core.createCanvas('paint', -core.bigmap.offsetX, -core.bigmap.offsetY, 32*core.bigmap.width, 32*core.bigmap.height, 95);
|
||||||
|
|
||||||
// 将已有的内容绘制到route上
|
// 将已有的内容绘制到route上
|
||||||
var value = core.paint[core.status.floorId];
|
var value = core.paint[core.status.floorId];
|
||||||
if (core.isset(value)) value = lzw_decode(value).split(",");
|
if (core.isset(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.drawImage('paint', core.bigmap.tempCanvas.canvas, 0, 0);
|
||||||
|
|
||||||
core.setLineWidth('paint', 3);
|
core.setLineWidth('paint', 3);
|
||||||
@ -2383,7 +2417,7 @@ ui.prototype._drawPaint_draw = function () {
|
|||||||
|
|
||||||
////// 绘制帮助页面 //////
|
////// 绘制帮助页面 //////
|
||||||
ui.prototype.drawHelp = function () {
|
ui.prototype.drawHelp = function () {
|
||||||
core.clearSelector();
|
core.clearUI();
|
||||||
if (core.material.images.keyboard) {
|
if (core.material.images.keyboard) {
|
||||||
core.status.event.id = 'help';
|
core.status.event.id = 'help';
|
||||||
core.lockControl();
|
core.lockControl();
|
||||||
|
|||||||
100
libs/utils.js
100
libs/utils.js
@ -75,35 +75,6 @@ utils.prototype.calValue = function (value, prefix, need, times) {
|
|||||||
return value;
|
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) {
|
utils.prototype.unshift = function (a, b) {
|
||||||
if (!(a instanceof Array) || b == null) return;
|
if (!(a instanceof Array) || b == null) return;
|
||||||
@ -128,6 +99,28 @@ utils.prototype.push = function (a, b) {
|
|||||||
return a;
|
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) {
|
utils.prototype.setLocalStorage = function (key, value) {
|
||||||
try {
|
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) {
|
utils.prototype.getLocalStorage = function (key, defaultValue) {
|
||||||
var res = this.decompress(localStorage.getItem(core.firstData.name + "_" + key));
|
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);
|
return 'K' + t.substring(4);
|
||||||
else if (t.indexOf('random:') == 0)
|
else if (t.indexOf('random:') == 0)
|
||||||
return 'X' + t.substring(7);
|
return 'X' + t.substring(7);
|
||||||
return '';
|
return '('+t+')';
|
||||||
}
|
}
|
||||||
|
|
||||||
////// 解密路线 //////
|
////// 解密路线 //////
|
||||||
@ -485,8 +456,9 @@ utils.prototype.decodeRoute = function (route) {
|
|||||||
// 解压缩
|
// 解压缩
|
||||||
try {
|
try {
|
||||||
var v = LZString.decompressFromBase64(route);
|
var v = LZString.decompressFromBase64(route);
|
||||||
if (/^[a-zA-Z0-9+\/=:]*$/.test(v)) {
|
if (v != null && /^[-_a-zA-Z0-9+\/=:()]*$/.test(v)) {
|
||||||
route = v;
|
if (v != "" || route.length < 8)
|
||||||
|
route = v;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
}
|
}
|
||||||
@ -525,6 +497,15 @@ utils.prototype._decodeRoute_number2id = function (number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
utils.prototype._decodeRoute_decodeOne = function (decodeObj, c) {
|
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') ?
|
var nxt = (c == 'I' || c == 'e' || c == 'F' || c == 'S' || c == 'Q' || c == 't') ?
|
||||||
this._decodeRoute_getString(decodeObj) : this._decodeRoute_getNumber(decodeObj);
|
this._decodeRoute_getString(decodeObj) : this._decodeRoute_getNumber(decodeObj);
|
||||||
|
|
||||||
@ -618,6 +599,7 @@ utils.prototype.getCookie = function (name) {
|
|||||||
|
|
||||||
////// 设置statusBar的innerHTML,会自动斜体和放缩,也可以增加自定义css //////
|
////// 设置statusBar的innerHTML,会自动斜体和放缩,也可以增加自定义css //////
|
||||||
utils.prototype.setStatusBarInnerHTML = function (name, value, css) {
|
utils.prototype.setStatusBarInnerHTML = function (name, value, css) {
|
||||||
|
if (!core.statusBar[name]) return;
|
||||||
if (typeof value == 'number') value = this.formatBigNumber(value);
|
if (typeof value == 'number') value = this.formatBigNumber(value);
|
||||||
// 判定是否斜体
|
// 判定是否斜体
|
||||||
var italic = /^[-a-zA-Z0-9`~!@#$%^&*()_=+\[{\]}\\|;:'",<.>\/?]*$/.test(value);
|
var italic = /^[-a-zA-Z0-9`~!@#$%^&*()_=+\[{\]}\\|;:'",<.>\/?]*$/.test(value);
|
||||||
@ -921,7 +903,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';
|
obj.style.display = 'block';
|
||||||
if (!speed && main.mode != 'play') {
|
if (!speed && main.mode != 'play') {
|
||||||
obj.style.opacity = 1;
|
obj.style.opacity = 1;
|
||||||
@ -941,7 +923,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') {
|
if (!speed || main.mode != 'play') {
|
||||||
obj.style.display = 'none';
|
obj.style.display = 'none';
|
||||||
if (callback) callback();
|
if (callback) callback();
|
||||||
@ -960,7 +942,7 @@ utils.prototype.hide = function (obj, speed, callback) {
|
|||||||
}, speed);
|
}, speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
utils.prototype.encodeCanvas = function (ctx) {
|
utils.prototype._encodeCanvas = function (ctx) {
|
||||||
var list = [];
|
var list = [];
|
||||||
var width = ctx.canvas.width, height = ctx.canvas.height;
|
var width = ctx.canvas.width, height = ctx.canvas.height;
|
||||||
ctx.mozImageSmoothingEnabled = false;
|
ctx.mozImageSmoothingEnabled = false;
|
||||||
@ -987,7 +969,7 @@ utils.prototype.encodeCanvas = function (ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////// 解析arr数组,并绘制到tempCanvas上 //////
|
////// 解析arr数组,并绘制到tempCanvas上 //////
|
||||||
utils.prototype.decodeCanvas = function (arr, width, height) {
|
utils.prototype._decodeCanvas = function (arr, width, height) {
|
||||||
// 清空tempCanvas
|
// 清空tempCanvas
|
||||||
var tempCanvas = core.bigmap.tempCanvas;
|
var tempCanvas = core.bigmap.tempCanvas;
|
||||||
tempCanvas.canvas.width = width;
|
tempCanvas.canvas.width = width;
|
||||||
@ -1070,7 +1052,7 @@ utils.prototype._export = function (floorIds) {
|
|||||||
// map
|
// map
|
||||||
var content = floorIds.length + "\n" + core.__SIZE__ + " " + core.__SIZE__ + "\n\n";
|
var content = floorIds.length + "\n" + core.__SIZE__ + " " + core.__SIZE__ + "\n\n";
|
||||||
floorIds.forEach(function (floorId) {
|
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) {
|
content += arr.map(function (x) {
|
||||||
// check monster
|
// check monster
|
||||||
x.forEach(function (t) {
|
x.forEach(function (t) {
|
||||||
|
|||||||
8
main.js
8
main.js
@ -364,7 +364,7 @@ main.dom.body.onselectstart = function () {
|
|||||||
main.dom.data.onmousedown = function (e) {
|
main.dom.data.onmousedown = function (e) {
|
||||||
try {
|
try {
|
||||||
e.stopPropagation();
|
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;
|
if (loc == null) return;
|
||||||
main.core.ondown(loc);
|
main.core.ondown(loc);
|
||||||
} catch (ee) { main.log(ee); }
|
} catch (ee) { main.log(ee); }
|
||||||
@ -374,7 +374,7 @@ main.dom.data.onmousedown = function (e) {
|
|||||||
main.dom.data.onmousemove = function (e) {
|
main.dom.data.onmousemove = function (e) {
|
||||||
try {
|
try {
|
||||||
e.stopPropagation();
|
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;
|
if (loc == null) return;
|
||||||
main.core.onmove(loc);
|
main.core.onmove(loc);
|
||||||
}catch (ee) { main.log(ee); }
|
}catch (ee) { main.log(ee); }
|
||||||
@ -401,7 +401,7 @@ main.dom.data.onmousewheel = function(e) {
|
|||||||
main.dom.data.ontouchstart = function (e) {
|
main.dom.data.ontouchstart = function (e) {
|
||||||
try {
|
try {
|
||||||
e.preventDefault();
|
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;
|
if (loc == null) return;
|
||||||
main.core.ondown(loc);
|
main.core.ondown(loc);
|
||||||
}catch (ee) { main.log(ee); }
|
}catch (ee) { main.log(ee); }
|
||||||
@ -411,7 +411,7 @@ main.dom.data.ontouchstart = function (e) {
|
|||||||
main.dom.data.ontouchmove = function (e) {
|
main.dom.data.ontouchmove = function (e) {
|
||||||
try {
|
try {
|
||||||
e.preventDefault();
|
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;
|
if (loc == null) return;
|
||||||
main.core.onmove(loc);
|
main.core.onmove(loc);
|
||||||
}catch (ee) { main.log(ee); }
|
}catch (ee) { main.log(ee); }
|
||||||
|
|||||||
@ -78,6 +78,7 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
|
|||||||
"lv": 1,
|
"lv": 1,
|
||||||
"hpmax": 9999,
|
"hpmax": 9999,
|
||||||
"hp": 1000,
|
"hp": 1000,
|
||||||
|
"manamax": -1,
|
||||||
"mana": 0,
|
"mana": 0,
|
||||||
"atk": 100,
|
"atk": 100,
|
||||||
"def": 100,
|
"def": 100,
|
||||||
|
|||||||
@ -223,7 +223,7 @@ var events_c12a15a8_c380_4b28_8144_256cba95f760 =
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "if",
|
"type": "if",
|
||||||
"condition": "core.getBgFgNumber('bg') == 167",
|
"condition": "core.getBgNumber() == 167",
|
||||||
"true": [
|
"true": [
|
||||||
{
|
{
|
||||||
"type": "function",
|
"type": "function",
|
||||||
|
|||||||
@ -151,7 +151,7 @@ main.floors.sample1=
|
|||||||
"type": "hide"
|
"type": "hide"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "setFg",
|
"type": "setCurtain",
|
||||||
"color": [
|
"color": [
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@ -184,7 +184,7 @@ main.floors.sample1=
|
|||||||
"2,11": [
|
"2,11": [
|
||||||
"\t[杰克,thief]喂!醒醒!快醒醒!",
|
"\t[杰克,thief]喂!醒醒!快醒醒!",
|
||||||
{
|
{
|
||||||
"type": "setFg",
|
"type": "setCurtain",
|
||||||
"time": 1500
|
"time": 1500
|
||||||
},
|
},
|
||||||
"\t[hero]额,我这是在什么地方?",
|
"\t[hero]额,我这是在什么地方?",
|
||||||
|
|||||||
@ -6,6 +6,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
|||||||
// hero:勇士信息;hard:难度;floorId:当前楼层ID;maps:地图信息;values:全局数值信息
|
// hero:勇士信息;hard:难度;floorId:当前楼层ID;maps:地图信息;values:全局数值信息
|
||||||
|
|
||||||
// 清除游戏数据
|
// 清除游戏数据
|
||||||
|
// 这一步会清空状态栏和全部画布内容,并删除所有动态创建的画布
|
||||||
core.clearStatus();
|
core.clearStatus();
|
||||||
// 初始化status
|
// 初始化status
|
||||||
core.status = core.clone(core.initStatus);
|
core.status = core.clone(core.initStatus);
|
||||||
@ -755,149 +756,153 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
|||||||
// 可以在这里任意增加或编辑每个按键的行为
|
// 可以在这里任意增加或编辑每个按键的行为
|
||||||
|
|
||||||
// 如果处于正在行走状态,则不处理
|
// 如果处于正在行走状态,则不处理
|
||||||
if (!core.status.heroStop || core.status.heroMoving > 0)
|
if (core.isMoving())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Alt+0~9,快捷换上套装
|
// Alt+0~9,快捷换上套装
|
||||||
if (altKey && keyCode>=48 && keyCode<=57) {
|
if (altKey && keyCode >= 48 && keyCode <= 57) {
|
||||||
core.items.quickLoadEquip(keyCode-48);
|
core.items.quickLoadEquip(keyCode - 48);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据keyCode值来执行对应操作
|
// 根据keyCode值来执行对应操作
|
||||||
switch (keyCode) {
|
switch (keyCode) {
|
||||||
case 27: // ESC:打开菜单栏
|
case 27: // ESC:打开菜单栏
|
||||||
core.openSettings(true);
|
core.openSettings(true);
|
||||||
break;
|
break;
|
||||||
case 88: // X:使用怪物手册
|
case 88: // X:使用怪物手册
|
||||||
core.openBook(true);
|
core.openBook(true);
|
||||||
break;
|
break;
|
||||||
case 71: // G:使用楼传器
|
case 71: // G:使用楼传器
|
||||||
core.useFly(true);
|
core.useFly(true);
|
||||||
break;
|
break;
|
||||||
case 65: // A:读取自动存档(回退)
|
case 65: // A:读取自动存档(回退)
|
||||||
core.doSL("autoSave", "load");
|
core.doSL("autoSave", "load");
|
||||||
break;
|
break;
|
||||||
case 83: // S:存档
|
case 83: // S:存档
|
||||||
core.save(true);
|
core.save(true);
|
||||||
break;
|
break;
|
||||||
case 68: // D:读档
|
case 68: // D:读档
|
||||||
core.load(true);
|
core.load(true);
|
||||||
break;
|
break;
|
||||||
case 69: // E:打开光标
|
case 69: // E:打开光标
|
||||||
core.ui.drawCursor();
|
core.ui.drawCursor();
|
||||||
break;
|
break;
|
||||||
case 84: // T:打开道具栏
|
case 84: // T:打开道具栏
|
||||||
core.openToolbox(true);
|
core.openToolbox(true);
|
||||||
break;
|
break;
|
||||||
case 81: // Q:打开装备栏
|
case 81: // Q:打开装备栏
|
||||||
core.openEquipbox(true);
|
core.openEquipbox(true);
|
||||||
break;
|
break;
|
||||||
case 90: // Z:转向
|
case 90: // Z:转向
|
||||||
core.turnHero();
|
core.turnHero();
|
||||||
break;
|
break;
|
||||||
case 75: case 86: // V:打开快捷商店列表
|
case 75:
|
||||||
core.openQuickShop(true);
|
case 86: // V:打开快捷商店列表
|
||||||
break;
|
core.openQuickShop(true);
|
||||||
case 32: // SPACE:轻按
|
break;
|
||||||
core.getNextItem();
|
case 32: // SPACE:轻按
|
||||||
break;
|
core.getNextItem();
|
||||||
case 82: // R:回放录像
|
break;
|
||||||
core.actions._clickSyncSave_replay();
|
case 82: // R:回放录像
|
||||||
break;
|
core.actions._clickSyncSave_replay();
|
||||||
case 33: case 34: // PgUp/PgDn:浏览地图
|
break;
|
||||||
core.ui.drawMaps();
|
case 33:
|
||||||
break;
|
case 34: // PgUp/PgDn:浏览地图
|
||||||
case 77: // M:绘图模式
|
core.ui.drawMaps();
|
||||||
core.ui.drawPaint();
|
break;
|
||||||
break;
|
case 77: // M:绘图模式
|
||||||
case 66: // B:打开数据统计
|
core.ui.drawPaint();
|
||||||
core.ui.drawStatistics();
|
break;
|
||||||
break;
|
case 66: // B:打开数据统计
|
||||||
case 72: // H:打开帮助页面
|
core.ui.drawStatistics();
|
||||||
core.ui.drawHelp();
|
break;
|
||||||
break;
|
case 72: // H:打开帮助页面
|
||||||
case 78: // N:重新开始
|
core.ui.drawHelp();
|
||||||
core.confirmRestart();
|
break;
|
||||||
break;
|
case 78: // N:重新开始
|
||||||
case 79: // O:查看工程
|
core.confirmRestart();
|
||||||
core.actions._clickGameInfo_openProject();
|
break;
|
||||||
break;
|
case 79: // O:查看工程
|
||||||
case 80: // P:游戏主页
|
core.actions._clickGameInfo_openProject();
|
||||||
core.actions._clickGameInfo_openComments();
|
break;
|
||||||
break;
|
case 80: // P:游戏主页
|
||||||
case 49: // 快捷键1: 破
|
core.actions._clickGameInfo_openComments();
|
||||||
if (core.hasItem('pickaxe')) {
|
break;
|
||||||
if (core.canUseItem('pickaxe')) {
|
case 49: // 快捷键1: 破
|
||||||
core.useItem('pickaxe');
|
if (core.hasItem('pickaxe')) {
|
||||||
}
|
if (core.canUseItem('pickaxe')) {
|
||||||
else {
|
core.status.route.push("key:49"); // 将按键记在录像中
|
||||||
core.drawTip('当前不能使用破墙镐');
|
core.useItem('pickaxe', true); // 第二个参数true代表该次使用道具是被按键触发的,使用过程不计入录像
|
||||||
}
|
} else {
|
||||||
|
core.drawTip('当前不能使用破墙镐');
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case 50: // 快捷键2: 炸
|
break;
|
||||||
if (core.hasItem('bomb')) {
|
case 50: // 快捷键2: 炸
|
||||||
if (core.canUseItem('bomb')) {
|
if (core.hasItem('bomb')) {
|
||||||
core.useItem('bomb');
|
if (core.canUseItem('bomb')) {
|
||||||
}
|
core.status.route.push("key:50"); // 将按键记在录像中
|
||||||
else {
|
core.useItem('bomb', true); // 第二个参数true代表该次使用道具是被按键触发的,使用过程不计入录像
|
||||||
core.drawTip('当前不能使用炸弹');
|
} else {
|
||||||
}
|
core.drawTip('当前不能使用炸弹');
|
||||||
}
|
}
|
||||||
else if (core.hasItem('hammer')) {
|
} else if (core.hasItem('hammer')) {
|
||||||
if (core.canUseItem('hammer')) {
|
if (core.canUseItem('hammer')) {
|
||||||
core.useItem('hammer');
|
core.status.route.push("key:50"); // 将按键记在录像中
|
||||||
}
|
core.useItem('hammer', true); // 第二个参数true代表该次使用道具是被按键触发的,使用过程不计入录像
|
||||||
else {
|
} else {
|
||||||
core.drawTip('当前不能使用圣锤');
|
core.drawTip('当前不能使用圣锤');
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 51: // 快捷键3: 飞
|
|
||||||
if (core.hasItem('centerFly')) {
|
|
||||||
core.ui.drawCenterFly();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 52: // 快捷键4:破冰/冰冻/地震/上下楼器/... 其他道具依次判断
|
|
||||||
{
|
|
||||||
var list = ["icePickaxe", "snow", "earthquake", "upFly", "downFly", "jumpShoes", "lifeWand", "poisonWine", "weakWine", "curseWine", "superWine"];
|
|
||||||
for (var i=0;i<list.length;i++) {
|
|
||||||
var itemId = list[i];
|
|
||||||
if (core.canUseItem(itemId)) {
|
|
||||||
core.useItem(itemId);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 55: // 快捷键7:绑定为轻按,方便手机版操作
|
|
||||||
core.getNextItem();
|
|
||||||
break;
|
|
||||||
case 118: // F7:开启debug模式
|
|
||||||
core.debug();
|
|
||||||
break;
|
|
||||||
case 87: // W:开启技能“二倍斩”
|
|
||||||
// 检测是否拥有“二倍斩”这个技能道具
|
|
||||||
if (core.hasItem('skill1')) {
|
|
||||||
core.useItem('skill1');
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
// 在这里可以任意新增或编辑已有的快捷键内容
|
|
||||||
/*
|
|
||||||
case 0: // 使用该按键的keyCode
|
|
||||||
// 还可以再判定altKey是否被按下,即 if (altKey) { ...
|
|
||||||
|
|
||||||
// ... 在这里写你要执行脚本
|
|
||||||
// **强烈建议所有新增的自定义快捷键均能给个对应的道具可点击,以方便手机端的行为**
|
|
||||||
if (core.hasItem('...')) {
|
|
||||||
core.useItem('...');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
}
|
||||||
*/
|
break;
|
||||||
}
|
case 51: // 快捷键3: 飞
|
||||||
|
if (core.hasItem('centerFly')) {
|
||||||
|
core.ui.drawCenterFly();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 52: // 快捷键4:破冰/冰冻/地震/上下楼器/... 其他道具依次判断
|
||||||
|
{
|
||||||
|
var list = ["icePickaxe", "snow", "earthquake", "upFly", "downFly", "jumpShoes", "lifeWand", "poisonWine", "weakWine", "curseWine", "superWine"];
|
||||||
|
for (var i = 0; i < list.length; i++) {
|
||||||
|
var itemId = list[i];
|
||||||
|
if (core.canUseItem(itemId)) {
|
||||||
|
core.status.route.push("key:52");
|
||||||
|
core.useItem(itemId, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 55: // 快捷键7:绑定为轻按,方便手机版操作
|
||||||
|
core.getNextItem();
|
||||||
|
break;
|
||||||
|
case 118: // F7:开启debug模式
|
||||||
|
core.debug();
|
||||||
|
break;
|
||||||
|
case 87: // W:开启技能“二倍斩”
|
||||||
|
// 检测是否拥有“二倍斩”这个技能道具
|
||||||
|
if (core.hasItem('skill1')) {
|
||||||
|
core.status.route.push("key:87");
|
||||||
|
core.useItem('skill1', true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
// 在这里可以任意新增或编辑已有的快捷键内容
|
||||||
|
/*
|
||||||
|
case 0: // 使用该按键的keyCode
|
||||||
|
// 还可以再判定altKey是否被按下,即 if (altKey) { ...
|
||||||
|
|
||||||
|
// ... 在这里写你要执行脚本
|
||||||
|
// **强烈建议所有新增的自定义快捷键均能给个对应的道具可点击,以方便手机端的行为**
|
||||||
|
if (core.hasItem('...')) {
|
||||||
|
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) {
|
if (core.flags.enableMana) {
|
||||||
// 也可以使用flag:manaMax来表示最大魔力值;详见文档-个性化-技能塔的支持
|
// status:manamax 只有在非负时才生效。
|
||||||
// core.status.hero.mana = Math.max(core.status.hero.mana, core.getFlag('manaMax', 10));
|
if (core.status.hero.manamax != null && core.status.hero.manamax >= 0) {
|
||||||
// core.setStatusBarInnerHTML('mana', core.status.hero.mana + "/" + core.getFlag('manaMax', 10));
|
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) {
|
if (core.flags.enableSkill) {
|
||||||
|
|||||||
@ -1,18 +1,28 @@
|
|||||||
var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
|
var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
|
||||||
{
|
{
|
||||||
"init": function () {
|
"init": function () {
|
||||||
// 在这里写的代码,在所有模块加载完毕后,游戏开始前会被执行
|
|
||||||
console.log("插件编写测试");
|
console.log("插件编写测试");
|
||||||
|
|
||||||
// 可以写一些其他的被直接执行的代码
|
// 可以写一些直接执行的代码
|
||||||
|
// 在这里写的代码将会在【资源加载前】被执行,此时图片等资源尚未被加载。
|
||||||
|
// 请勿在这里对包括bgm,图片等资源进行操作。
|
||||||
|
|
||||||
|
|
||||||
this.test = function () {
|
this._afterLoadResources = function () {
|
||||||
console.log("插件函数执行测试");
|
// 本函数将在所有资源加载完毕后,游戏开启前被执行
|
||||||
console.log(this);
|
// 可以在这个函数里面对资源进行一些操作,比如切分图片等。
|
||||||
|
|
||||||
|
// 这是一个将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();
|
// 可以在任何地方(如afterXXX或自定义脚本事件)调用函数,方法为 core.plugin.xxx();
|
||||||
|
// 从V2.6开始,插件中用this.XXX方式定义的函数也会被转发到core中,详见文档-脚本-函数的转发。
|
||||||
},
|
},
|
||||||
"drawLight": function () {
|
"drawLight": function () {
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user