docs for events/enemys/items/maps

This commit is contained in:
oc 2019-04-03 00:23:12 +08:00
parent 2fc11cab08
commit e280308da5
8 changed files with 946 additions and 191 deletions

View File

@ -301,7 +301,7 @@ core.musicStatus.soundStatus (音效开启状态)
core.musicStatus.playingBgm 当前正在播放的BGM
core.musicStatus.lastBgm 最近一次尝试播放的BGM
core.musicStatus.volume (当前的音量)
core.musicStatus.cachedBgms (背景音乐的缓存内
core.musicStatus.cachedBgms (背景音乐的缓存内
core.musicStatus.cacheBgmCount 背景音乐的缓存数量默认值是4
@ -557,14 +557,6 @@ core.isPlaying()
当前是否正在游戏中。
core.restart()
重新开始游戏。本质上就是播放标题界面的BGM并调用showStartAnimate。
core.confirmRestart()
确认用户是否需要重新开始。
core.clearStatus()
清除所有的游戏状态和数据,包括状态栏的显示。
@ -1041,9 +1033,17 @@ core.hasEnemyLeft(floorId)
### events.js
events.js将处理所有和事件相关的操作。
events.js将处理所有和事件相关的操作主要分为五个部分
- 游戏的开始和结束
- 系统事件的处理
- 自定义事件的处理
- 点击状态栏图标所进行的操作
- 一些具体事件的执行内容
```js
// ------ 游戏的开始和结束 ------ //
core.resetGame(hero, hard, floorId, maps, values)
重置整个游戏。该函数实际被转发到了脚本编辑中。
@ -1074,18 +1074,774 @@ core.gameOver(ending, fromReplay, norank)
此函数将询问是否上传成绩如果ending不是null是否下载录像等并重新开始。
core.restart()
重新开始游戏。本质上就是播放标题界面的BGM并调用showStartAnimate。
core.confirmRestart()
确认用户是否需要重新开始。
// ------ 系统事件处理 ------ //
core.registerSystemEvent(type, func)
注册一个系统事件,即通过图块的默认触发器所触发的事件。
type为一个要注册的事件类型func为要执行的函数体或插件中的函数名。
func需要接受(data, callback)作为参数,分别是触发点的图块信息,和执行完毕时的回调。
如果注册一个已经存在的系统事件比如openDoor则会覆盖系统的默认函数。
core.unregisterSystemEvent(type)
注销一个系统事件。type是上面你注册的事件类型。
core.doSystemEvent(type, data, callback)
执行一个系统事件。type为事件类型data为该事件点的图块信息callback为执行完毕的回调。
core.battle(id, x, y, force, callback)
和怪物进行战斗。
id为怪物的IDx和y为怪物坐标force如果为真将强制战斗callback为执行完毕的回调。
如果填写了怪物坐标,则会删除对应点的图块并执行该点战后事件。
如果是在事件流的执行过程中调用此函数,则不会进行自动存档,且会强制战斗。
core.beforeBattle(enemyId, x, y)
战前事件。实际被转发到了脚本编辑中,可以在这里加上一些战前特效。
此函数在“检测能否战斗和自动存档”【之后】执行。
如果需要更早的战前事件,请在插件中覆重写 core.events.doSystemEvent 函数。
此函数返回true则将继续本次战斗返回false将不再战斗。
core.afterBattle(enemyId, x, y, callback)
战后事件,将执行扣血、加金币经验、特殊属性处理、战后事件处理等操作。
实际被转发到了脚本编辑中。
core.openDoor(x, y, needKey, callback)
尝试开一个门。x和y为门的坐标needKey表示是否需要钥匙callback为执行完毕的回调。
如果不是一个有效的门需要钥匙且未持有等均会忽略此事件并直接执行callback。
core.afterOpenDoor(doorId, x, y, callback)
开完一个门后执行的事件,实际被转发到了脚本编辑中。
core.getItem(id, num, x, y, callback)
获得若干个道具。itemId为道具IDitemNum为获得的道具个数不填默认为1。
x和y为道具点的坐标如果设置则会擦除地图上的该点。
core.afterGetItem(id, x, y, callback)
获得一个道具后执行的事件,实际被转发到了脚本编辑中。
core.getNextItem(noRoute)
轻按即获得面对的道具。如果noRoute为真则这个轻按行为不会计入录像。
core.changeFloor(floorId, stair, heroLoc, time, callback, fromLoad)
楼层切换。floorId为目标楼层IDstair为是什么楼梯heroLoc为目标点坐标。
time为切换时间callback为切换完毕的回调fromLoad标志是否是从读档造成的切换。
floorId也可以填":before"和":next"表示前一层和后一层。
heroLoc为{"x": 0, "y": 0, "direction": "up"}的形式。不存在则从勇士位置取。
如果stair不为null则会在该楼层中找对应的图块作为目标点的坐标并覆盖heroLoc。
一般设置的是"upFloor"和"downFloor"但也可以用任何其他的图块ID。
core.changingFloor(floorId, heroLoc, fromLoad)
正在执行楼层切换中执行的操作,实际被转发到了脚本编辑中。
core.hasVisitedFloor(floorId)
是否曾经到达过某一层。
core.visitFloor(floorId)
标记曾经到达了某一层。
core.passNet(data)
执行一个路障处理。这里只有毒衰咒网的处理血网被移动到了updateCheckBlock中。
core.pushBox(data)
执行一个推箱子事件。
core.afterPushBox()
推箱子之后触发的事件,实际被转发到了脚本编辑中。
core.changeLight(id, x, y)
踩灯后的事件。
// ------ 自定义事件的处理 ------ //
core.registerEvent(type, func)
注册一个自定义事件。type为事件名func为执行事件的函数体或插件中的函数名。
func可以接受(data, x, y, prefix)参数其中data为事件内容x和y为该点坐标prefix为该点前缀。
同名注册的事件将进行覆盖。
请记得在自定义处理事件完毕后调用core.doAction()再继续执行下一个事件!
core.unregisterEvent(type)
注销一个自定义事件。
core.doEvent(data, x, y, prefix)
执行一个自定义事件。data为事件内容将根据data.type去注册的事件列表中查找对应的执行函数。
x和y为该点坐标prefix为该点前缀。执行事件时也会把(data, x, y, prefix)传入执行函数。
core.setEvents(list, x, y, callback)
设置自定义事件的执行列表,坐标和回调函数。
core.startEvents(list, x, y, callback)
开始执行一系列的自定义事件。list为事件列表x和y为事件坐标callback为执行完毕的回调。
此函数将调用core.setEvents然后停止勇士再执行core.doAction()。
core.doAction()
执行下一个自定义事件。
此函数将检测事件列表是否全部执行完毕,如果是则执行回调函数。
否则将从事件列表中弹出下一个事件并调用core.doEvent进行执行。
core.insertAction(action, x, y, callback, addToLast)
向当前的事件列表中插入一个或多个事件并执行。
如果当前并不是在事件执行流中则会调用core.startEvents()开始执行事件,否则仅仅执行插入操作。
action为要插入的事件可以是一个单独的事件或者是一个事件列表。
x,y,callback如果设置了且不为null则会覆盖当前的坐标和回调函数。
addToLast如果为真则会插入到事件执行列表的尾部否则是插入到执行列表的头部。
core.getCommonEvent(name)
根据名称获得某个公共事件内容。
core.recoverEvents(data)
恢复事件现场。一般用于呼出怪物手册、呼出存读档页面等时,恢复事件执行流。
// ------ 点击状态栏图标时执行的一些操作 ------ //
core.openBook(fromUserAction)
尝试打开怪物手册。fromUserAction标志是否是从用户的行为触发如按键或点击状态栏。下同
不建议复写此函数,否则【呼出怪物手册】事件会出问题。
core.useFly(fromUserAction)
尝试使用楼传器。可以安全的复写此函数,参见文档-个性化-覆盖楼传事件。
core.flyTo(toId, callback)
尝试飞行到某个楼层,被转发到了脚本编辑中。
如果此函数返回true代表成功进行了飞行false代表不能进行飞行。
core.openEquipbox(fromUserAction) / core.openToolbox(fromUserAction)
尝试打开道具栏和装备栏。可以安全复写这两个函数。
core.openQuickShop(fromUserAction) / core.openKeyBoard(fromUserAction)
尝试打开快捷商店和虚拟键盘。可以安全复写这两个函数。
core.save(fromUserAction) / core.load(fromUserAction)
尝试打开存读档页面。
不建议复写这两个函数,否则【呼出存读档页面】事件会出问题。
core.openSettings(fromUserAction)
尝试打开系统菜单。不建议复写此函数。
// ------ 一些具体事件的执行内容 ------ //
core.hasAsync()
当前是否存在未执行完毕的异步事件。请注意正在播放的动画也算异步事件。
core.follow(name) / core.unfollow(name)
跟随勇士/取消跟随。name为行走图名称。
在取消跟随时如果指定了name则会从跟随列表中选取一个该行走图取消否则取消所有跟随。
跟随和取消跟随都会调用core.gatherFollowers()来聚集所有的跟随者。
core.setValue(name, value, prefix) / core.addValue(name, value, prefix)
设置/增减某个数值。name可以是status:xxxitem:xxx或flag:xxx。
value可以是一个表达式将调用core.calValue()计算。prefix为前缀独立开关使用。
core.doEffect(effect, need, times)
执行一个effect操作。该函数目前仅被全局商店的status:xxx+=yyy所调用。
core.setFloorInfo(name, values, floorId, prefix)
设置某层楼的楼层属性。
core.setGlobalAttribute(name, value)
设置一个全局属性,如边框颜色等。
core.setGlobalFlag(name, value)
设置一个全局开关如enableXXX等。
如果需要设置一个全局数值如红宝石数值可以直接简单的修改core.values因此没有单独列出函数。
core.closeDoor(x, y, id, callback)
执行一个关门事件。如果不是一个合法的门,或者该点不为空地,则会忽略本事件。
core.showImage(code, image, sloc, loc, opacityVal, time, callback)
显示一张图片。code为图片编号image为图片内容或图片名。
sloc为[x,y,w,h]形式表示在原始图片上裁剪的区域也可直接设为null表示整张图片。
loc为[x,y,w,h]形式表示在界面上绘制的位置和大小w和h可忽略表示使用绘制大小。
opacityVal为绘制的不透明度time为淡入时间。
此函数将创建一个画布其z-index是100+code即图片编号为1则是101编号50则是150。
请注意curtain层的z-index是125UI层的z-index是140因此可以通过图片编号来调整覆盖关系。
core.hideImage(code, time, callback)
隐藏一张图片。code为图片编号time为淡出时间。
core.moveImage(code, to, opacityVal, time, callback)
移动一张图片。code为图片编号to为[x,y]表示目标位置opacityVal目标不透明度time为移动时间。
core.showGif(name, x, y)
绘制一张gif图片或取消所有绘制内容。如果name不设置则视为取消。x和y为左上角像素坐标。
core.setVolume(value, time, callback)
设置音量。value为目标音量大小在0到1之间。time为音量渐变的时间。
core.vibrate(time, callback)
画面震动。time为震动时间。
请注意画面震动时间必须是500的倍数系统也会自动把time调整为上整的500倍数值。
core.eventMoveHero(steps, time, callback)
使用事件移动勇士。time为每步的移动时间。
steps为移动数组可以接受'up','down','left','right','forward'和'backward'项。
使用事件移动勇士将不会触发任何地图上的事件。
core.jumpHero(ex, ey, time, callback)
跳跃勇士。ex和ey为目标点的坐标可以为null表示原地跳跃。time为总跳跃时间。
core.openShop(shopId, needVisited)
打开一个全局商店。needVisited表示是否需要该商店原本就是启用状态。
如果该商店对应的实际上是一个全局事件,则会直接插入并执行。
core.disableQuickShop(shopId)
禁用一个全局商店,即把一个商店从启用变成禁用状态。
core.canUseQuickShop(shopId)
当前能否使用某个全局商店,实际被转发到了脚本编辑中。
如果此函数返回null则表示可以使用返回一个字符串表示不可以该字符串表示不可以的原因。
core.setHeroIcon(name, noDraw)
设置勇士的行走图。
name为行走图名称noDraw如果为真则不会调用core.drawHero()函数进行刷新。
core.checkLvUp()
检查升级事件。该函数将判定当前是否升级(或连续升级),然后执行升级事件。
core.tryUseItem(itemId)
尝试使用一个道具。
对于怪物手册和楼传器将分别调用core.openBook()和core.useFly()函数。
对于中心对称飞行器则会调用core.drawCenterFly()函数。
对于其他的道具,将检查是否拥有,能否使用,并且进行使用。
core.afterUseBomb()
使用炸弹或圣锤后的事件。实际被转发到了脚本编辑中。
```
### icons.js
icons.js主要是负责素材相关信息比如某个素材在对应的图片上的位置。
```js
core.getClsFromId(id)
根据某个素材的ID获得该素材的cls
core.getTilesetOffset(id)
根据某个素材来获得对应的tileset和坐标信息。
如果该素材不是tileset则返回null。
```
### items.js
items.js主要负责一切和道具相关的内容。
```js
core.getItemEffect(itemId, itemNum)
即捡即用类的道具获得时的效果。实际对应道具图块属性中的itemEffect框。
core.getItemEffectTip(itemId)
即捡即用类的道具获得时的额外提示,比如“,攻击+100”。
实际对应道具图块属性中的itemEffectTip框。
core.useItem(itemId, noRoute, callback)
尝试使用一个道具。实际对应道具图块属性中的useItemEffect框。
此函数也会调用一遍core.canUseItem(),如果无法使用将直接返回。
noRoute如果为真则这次使用道具的过程不会被计入录像。
使用道具完毕后,对于消耗道具将自动扣除,永久道具不会扣除。
core.canUseItem(itemId)
当前能否使用某个道具。
有些系统道具如破炸和上下楼器等会在计算出目标点的坐标后存入core.status.event.ui。
使用道具时将直接从core.status.event.ui调用不会重新计算。
core.itemCount(itemId)
获得某个道具的个数。
core.hasItem(itemId)
当前是否拥有某个道具。等价于 core.itemCount(itemId) > 0
请注意装备上的装备不视为拥有该道具即core.hasEquip()和core.hasItem()是完全不同的。
core.hasEquip(itemId)
当前是否装备上某个装备。
请注意装备上的装备不视为拥有该道具即core.hasEquip()和core.hasItem()是完全不同的。
core.getEquip(equipType)
获得某个装备位的当前装备。equipType为装备类型从0开始。
如果该装备位没有装备则返回null否则返回当前装备的ID。
core.setItem(itemId, itemNum)
设置某个道具的个数。
core.addItem(itemId, itemNum)
增减某个道具的个数itemNum可不填默认为1。
core.getEquipTypeByName(name)
根据装备位名称来找到一个空的装备孔,适用于多重装备。
如果没有一个装备孔是该装备名称,则返回-1。
core.getEquipTypeById(equipId)
获得某个装备的装备类型。
如果其type写的是装备名多重装备则调用core.getEquipTypeByName()函数。
core.canEquip(equipId, hint)
当前能否穿上某个装备。如果hint为真则不可装备时会气泡提示原因。
core.loadEquip(equipId, callback)
穿上某个装备。
core.unloadEquip(equipType, callback)
脱下某个装备孔的装备。
core.compareEquipment(compareEquipId, beComparedEquipId)
比较两个套装的差异。
此函数将对所有的勇士属性包括生命魔力攻防魔防金币等进行比较。
如果存在差异的,将作为一个对象返回其差异内容。
core.quickSaveEquip(index)
保存当前套装。index为保存的套装编号。
core.quickLoadEquip()
读取当前套装。index为读取的套装编号。
```
### loader.js
loader.js主要负责资源加载相关的内容。
```js
core.loadImage(imgName, callback)
从 project/images/ 中加载一张图片。imgName为图片名。
callback为执行完毕的回调函数接收(imgName, image)即图片名和图片内容作为参数。
如果图片不存在或加载失败则会在控制台打出一条错误日志,不会执行回调。
core.loadImages(names, toSave, callback)
从 project/images/ 中加载若干张图片。
names为一个图片名的列表toSave为加载并存到的对象。
callback为全部加载完毕执行的回调。
core.loadOneMusic(name)
从 project/sounds/ 或第三方中加载一个音乐并存入core.material.bgms中。name为音乐名。
core.loadOneSound(name)
从 project/sounds/ 中加载一个音效并存入core.material.sounds中。name为音效名。
core.loadBgm(name)
预加载一个bgm并加入缓存列表core.musicStatus.cachedBgms。
此函数将会检查bgm的缓存预加载和静音播放。
如果缓存列表溢出(core.musicStatus.cacheBgmCount)则通过LRU算法选择一个bgm并调用core.freeBgm()。
core.freeBgm(name)
释放一个bgm的内存并移出缓存列表。如果该bgm正在播放则也会立刻停止。
```
### map.js
maps.js负责一切和地图相关的处理内容包括如下几个方面
- 地图的初始化,保存和读取,地图数组的生成
- 是否可移动或瞬间移动的判定
- 地图的绘制
- 获得某个点的图块信息
- 启用和禁用图块,改变图块
- 移动/跳跃图块,淡入淡出图块
- 全局动画控制,动画的绘制
```js
// ------ 地图的初始化,保存和读取,地图数组的生成 ------ //
core.loadFloor(floorId, map)
从楼层或者存档中生成core.status.maps的内容。
map为存档信息如果某项在map中不存在则会从core.floors中读取。
core.getNumberById(id)
给定一个图块ID找到对应的数字。
core.initBlock(x, y, id, addInfo, eventFloor)
给定一个数字,初始化一个图块信息。
x和y为坐标id为数字或者可以:t或:f结尾表示初始是启用还是禁用状态。
addInfo如果为true则会填充上图块的默认信息比如给怪物添加battle触发器。
eventFloor如果设置为某个楼层信息则会填充上该点的自定义或楼层切换事件。
core.compressMap(mapArr, floorId)
压缩地图。mapArr为要压缩的二维数组floorId为对应的楼层。
此函数将把mapArr和对应的楼层中的数组进行比较并只取差异值进行存储。
通过这种压缩地图的方式,不仅节省了存档空间,还支持了任意修改地图的接档。
core.decompressMap(mapArr, floorId)
解压缩地图。mapArr为压缩后的地图floorId为对应的楼层。
此函数返回解压后的二维数组。
core.saveMap(floorId)
将某层楼的数据生成存档所保存的内容。在core.saveData()中被调用。
core.loadMap(data, floorId)
从data中读取楼层数据并调用core.loadFloor()进行初始化。
core.resizeMap(floorId)
根据某层楼的地图大小来调整大地图的画布大小。floorId可为null表示当前层。
core.getMapArray(floorId, showDisable)
生成某层楼的二维数组。floorId可不填代表当前楼层。
showDisable若为真则对于禁用的点会加上:f表示否则视为0。
core.getMapBlocksObj(floorId, showDisable)
以x,y的形式返回每个点的图块信息。floorId可不填表示当前楼层。
此函数将返回 {"0,0": {...}, "0,1": {...}} 这样的结构其中内部为对应点的block信息。
core.getBgMapArray(floorId, noCache)
获得某层楼的背景层的二维数组。floorId可不填表示当前楼层。
如果noCache为真则重新从剧本中读取而不使用缓存数据。
core.getFgMapArray(floorId, noCache)
获得某层楼的前景层的二维数组。floorId可不填表示当前楼层。
如果noCache为真则重新从剧本中读取而不使用缓存数据。
core.getBgNumber(x, y, floorId, noCache)
获得某层楼的背景层中某个点的数字。floorId可不填表示当前楼层。
如果noCache为真则重新从剧本中读取而不使用缓存数据。
本函数实际等价于 core.getBgMapArray(floorId, noCache)[y][x]
core.getBgNumber(x, y, floorId, noCache)
获得某层楼的前景层中某个点的数字。参数和方法同上。
// ------ 是否可移动或瞬间移动的判定 ------ //
core.generateMovableArray(floorId, x, y, direction)
生成全图或某个点的可通行方向数组。floorId为楼层Id可不填默认为当前点。
这里的可通行方向数组,指的是["up","down","left","right"]中的一个或多个组成的数组。
- 如果不设置x和y则会返回一个三维数组其中每个点都是一个该点可通行方向的数组。
- 如果设置了x和y但没有设置direction则只会返回该点的可通行方向数组
- 如果设置了x和y以及direction则会判定direction是否在该点可通行方向数组中并返回true或false。
可以使用core.inArray()来判定某个方向是否在可通行方向数组中。
core.canMoveHero(x, y, direction, floorId)
某个点是否可朝某个方向移动。x和y可选不填或为null则默认为勇士当前点。
direction可选不填或为null则默认勇士当前朝向。floorId不填则默认为当前楼层。
此函数将直接调用 core.generateMovableArray() 进行判定。
core.canMoveDirectly(destX, destY)
当前能否瞬间移动到某个点。
如果可以瞬移则返回非负数,其值为该次瞬移所少走的步数;如果不能瞬移则返回-1。
core.automaticRoute(destX, destY)
找寻到目标点的一条自动寻路路径。
// ------ 绘制地图相关 ------ //
core.drawBlock(block, animate)
重新绘制一个图块block为图块信息。
如果animate不为null则代表是通过全局动画的绘制其值为当前的帧数。
core.generateGroundPattern(floorId)
生成某个楼层的地板信息。floorId不填默认为当前楼层。
该函数可被怪物手册、对话框帧动画等地方使用。
core.drawMap(floorId, callback)
绘制某层楼的地图。floorId为目标楼层ID可不填表示当前楼层。
此函数会将core.status.floorId设置为floorId并设置core.status.thisMap。
将依次调用core.drawBg(), core.drawEvents()和core.drawFg()函数,最后绘制勇士和更新地图显伤。
core.drawBg(floorId, ctx)
绘制背景层。floorId为目标楼层ID可不填表示当前楼层。
如果ctx不为null则背景层将绘制在该画布上而不是bg层上drawThumbnail使用
可以通过复写该函数调整_drawFloorImages和_drawBgFgMap的顺序来调整背景图块和贴图的遮挡顺序。
core.drawEvents(floorId, blocks, ctx)
绘制事件层。floorId为目标楼层ID可不填表示当前楼层。
block表示要绘制的图块列表可不填使用当前楼层的图块列表。
如果ctx不为null则背景层将绘制在该画布上而不是event层上drawThumbnail使用
core.drawFg(floorId, ctx)
绘制前景层。floorId为目标楼层ID可不填表示当前楼层。
如果ctx不为null则背景层将绘制在该画布上而不是fg层上drawThumbnail使用
可以通过复写该函数调整_drawFloorImages和_drawBgFgMap的顺序来调整前景图块和贴图的遮挡顺序。
core.drawThumbnail(floorId, blocks, options, toDraw)
绘制一个楼层的缩略图。floorId为目标楼层ID可不填表示当前楼层。
block表示要绘制的图块列表可不填使用当前楼层的图块列表。
options为绘制选项可为null包括
heroLoc: 勇士位置heroIcon勇士图标默认当前勇士damage是否绘制显伤
flags当前的flags在存读档时使用
toDraw为要绘制到的信息可为null或为一个画布名包括
ctx要绘制到的画布x,y起点横纵坐标默认0size绘制大小默认416/480
all是否绘制全图默认falsecenterX,centerY截取中心默认为地图正中心
// ------ 获得某个点的图块信息 ------ //
core.noPass(x, y, floorId)
判定某个点是否有noPass的图块。
core.npcExists(x, y, floorId)
判定某个点是否有NPC的存在。
core.terrainExists(x, y, id, floorId)
判定某个点是否有(指定的)地形存在。
如果id为null则只要存在terrains即为真否则还会判定对应点的ID。
core.stairExists(x, y, floorId)
判定某个点是否存在楼梯。
core.nearStair()
判定当前勇士是否在楼梯上或旁边距离不超过1
core.enemyExists(x, y, id, floorId)
判定某个点是否有(指定的)怪物存在。
如果id为null则只要存在怪物即为真否则还会判定对应点的怪物ID。
请注意如果需要判定某个楼层是否存在怪物请使用core.hasEnemyLeft()函数。
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。如果该点不存在图块则返回null。
core.getBlockCls(x, y, floorId, showDisable)
获得某个点的图块类型。如果该点不存在图块则返回null。
core.getBlockInfo(block)
根据某个的图块信息获得其详细的素材信息。
如果参数block为字符串则视为图块ID如果参数为数字则视为图块的数字。
此函数将返回一个非常详尽的素材信息,目前包括如下几项:
number素材数字id素材idcls素材类型image素材所在的素材图片animate素材的帧数。
posX, posY素材在该素材图片上的位置height素材的高度faceIdsNPC朝向记录。
core.searchBlock(id, floorId, showDisable)
搜索一个图块出现过的所有位置。id为图块ID也可以传入图块的数字。
floorId为要搜索的楼层可以是一个楼层ID或者一个楼层数组。如果floorId不填则只搜索当前楼层。
showDisable如果为真则对于禁用的图块也会返回。
此函数将返回一个数组,每一项为一个搜索到的结果:
{"floorId": ..., "index": ..., "block": {...}, "x": ..., "y": ...}
即包含该图块所在的楼层ID在该楼层的blocks数组的索引图块内容和横纵坐标。
// ------ 启用和禁用图块,改变图块 ------ //
core.showBlock(x, y, floorId)
将某个点从禁用变成启用状态。floorId可不填或null表示当前楼层。
core.hideBlock(x, y, floorId)
将某个点从启用变成禁用状态但不会对其进行删除。floorId可不填或null表示当前楼层。
此函数不会实际将该块从地图中进行删除,而是将该点设置为禁用,以供以后可能的启用事件。
core.removeBlock(x, y, floorId)
将从启用变成禁用状态,并尽可能将其从地图上删除。
和hideBlock相比如果该点不存在自定义事件比如门或普通的怪物则将直接从地图中删除。
如果存在自定义事件,则简单的禁用它,以供以后可能的启用事件。
core.removeBlockById(index, floorId)
根据索引从地图的block数组中尽可能删除一个图块。floorId可不填或null表示当前楼层。
core.removeBlockByIds(floorId, ids)
根据索引数组从地图的block数组中尽可能删除一系列图块。floorId可不填或null表示当前楼层。
core.canRemoveBlock(block, floorId)
判定当前能否完全删除某个图块。floorId可不填或null表示当前楼层。
如果该点存在自定义事件,或者是重生怪,则不可进行删除。
core.showBgFgMap(name, loc, floorId, callback)
显示某层楼中某个背景/前景层的图块。name只能为'bg'或'fg'表示背景或前景层。
loc为该点坐标floorId可不填默认为当前楼层。callback为执行完毕的回调。
core.hideBgFgMap(name, loc, floorId, callback)
隐藏某层楼中某个背景/前景层的图块。name只能为'bg'或'fg'表示背景或前景层。
loc为该点坐标floorId可不填默认为当前楼层。callback为执行完毕的回调。
core.showFloorImage(loc, floorId, callback)
显示某层楼中的某个楼层贴图。loc为该贴图的左上角坐标。floorId可省略表示当前楼层。
core.hideFloorImage(loc, floorId, callback)
隐藏某层楼中的某个楼层贴图。loc为该贴图的左上角坐标。floorId可省略表示当前楼层。
core.setBlock(number, x, y, floorId)
改变某个楼层的某个图块。
number为要改变到的数字也可以传入图块id将调用core.getNumberById()来获得数字)。
x,y和floorId为目标点坐标和楼层可忽略为当前点和当前楼层。
core.replaceBlock(fromNumber, toNumber, floorId)
将某个或某些楼层中的所有某个图块替换成另一个图块
fromNumber和toNumber为要被替换和替换到的数字。
floorId可为某个楼层ID或者一个楼层数组如果不填只视为当前楼层。
值得注意的是,使用此函数转了的点上的自定义事件可能无法被执行。
如有需要再对那些存在事件的点执行core.setBlock()即可
core.setBgFgBlock(name, number, x, y, floorId)
设置前景/背景层的某个图块。name只能为'bg'或'fg'表示前景或背景层。
number为要设置到的图块数字x,y和floorId为目标点坐标和楼层可忽略为当前点和当前楼层。
core.resetMap(floorId)
重置某层或若干层的地图和楼层属性。
floorId可为某个楼层ID或者一个楼层数组同时重置若干层如果不填则只重置当前楼层。
// ------ 移动/跳跃图块,淡入淡出图块 ------ //
core.moveBlock(x, y, steps, time, keep, callback)
移动一个图块x和y为图块的坐标。
steps为移动的数组每一项只能是"up","down","left","right"之一。
time为每一步的移动时间不填默认为500ms。
如果keep为真则在移动完毕后将自动调用一个setBlock事件改变目标点的图块即不消失
否则会按照time时间来淡出消失。callback会执行完毕后的回调。
core.jumpBlock(sx, sy, ex, ey, time, keep, callback)
跳跃一个图块sx和sy为图块的坐标ex和ey为目标坐标。time为整个跳跃过程中的全程用时不填默认500。
如果keep为真则在移动完毕后将自动调用一个setBlock事件改变目标点的图块即不消失
否则会按照time时间来淡出消失。callback会执行完毕后的回调。
core.animateBlock(loc, type, time, callback)
淡入/淡出一个或多个图块。
loc为一个图块坐标或者一个二维数组表示一系列图块坐标将同时显示和隐藏
type只能为'show'或'hide'表示是淡入但是淡出。time为动画时间callback为执行完毕的回调。
// ------ 全局动画控制,动画的绘制 ------ //
core.addGlobalAnimate(block)
添加一个全局帧动画。
core.removeGlobalAnimate(x, y, name)
删除一个或全部的全局帧动画。name可为'bg',null或'fg'表示某个图层。
x和y如果为null则会删除全部的全局帧动画否则只会删除该点的该层的帧动画。
core.drawBoxAnimate()
绘制UI层的box动画如怪物手册和对话框中的帧动画等。
core.drawAnimate(name, x, y, callback)
绘制一个动画。name为动画名x和y为绘制的基准坐标callback为绘制完毕的回调函数。
此函数将播放动画音效,并异步开始绘制该动画。
此函数会返回一个动画id可以通过core.stopAnimate()立刻停止该动画的播放。
core.stopAnimate(id, doCallback)
立刻停止某个动画的播放。id为上面core.drawAnimate的返回值。
如果doCallback为真则会执行该动画所对应的回调函数。
```
### ui.js
### utils.js

View File

@ -1920,7 +1920,7 @@ actions.prototype._clickSettings = function (x, y) {
core.ui.drawGameInfo();
break;
case 6:
return core.confirmRestart(true);
return core.confirmRestart();
case 7:
core.ui.closePanel();
break;

View File

@ -349,29 +349,6 @@ control.prototype.isPlaying = function() {
return core.status.played;
}
////// 重新开始游戏;此函数将回到标题页面 //////
control.prototype.restart = function() {
this.showStartAnimate();
core.playBgm(main.startBgm);
}
////// 询问是否需要重新开始 //////
control.prototype.confirmRestart = function (fromSettings) {
core.status.event.selection = 1;
core.ui.drawConfirmBox("你确定要返回标题页面吗?", function () {
core.ui.closePanel();
core.restart();
}, function () {
if (fromSettings) {
core.status.event.selection = 3;
core.ui.drawSettings();
}
else {
core.ui.closePanel();
}
});
}
////// 清除游戏状态和数据 //////
control.prototype.clearStatus = function() {
// 停止各个Timeout和Interval

View File

@ -341,7 +341,7 @@ core.prototype._init_others = function () {
core.prototype._afterLoadResources = function (callback) {
// 初始化地图
core.initStatus.maps = core.maps.initMaps(core.floorIds);
core.initStatus.maps = core.maps._initMaps();
core.control._setRequestAnimationFrame();
core._initPlugins();
core.showStartAnimate();

View File

@ -234,6 +234,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 +296,7 @@ events.prototype._trigger = function (x, y) {
if (trigger == 'changeFloor' && !noPass && this._trigger_ignoreChangeFloor(block))
return;
core.status.automaticRoute.moveDirectly = false;
this.doSystemEvent(trigger, block, function () {
if (trigger == 'openDoor' || trigger == 'changeFloor')
core.replay();
})
this.doSystemEvent(trigger, block);
}
}
@ -341,16 +355,20 @@ events.prototype.afterBattle = function (enemyId, x, y, callback) {
}
events.prototype._sys_openDoor = function (data, callback) {
this.openDoor(data.event.id, data.x, data.y, true, callback);
this.openDoor(data.x, data.y, true, function () {
core.replay();
if (callback) callback();
});
}
////// 开门 //////
events.prototype.openDoor = function (id, x, y, needKey, callback) {
id = id || core.getBlockId(x, y);
events.prototype.openDoor = function (x, y, needKey, callback) {
var id = core.getBlockId(x, y);
core.saveAndStopAutomaticRoute();
if (!this._openDoor_check(id, x, y, needKey)) {
var locked = core.status.lockControl;
core.waitHeroToStop(function () {
core.unLockControl();
if (!locked) core.unLockControl();
if (callback) callback();
});
return;
@ -376,7 +394,7 @@ events.prototype._openDoor_check = function (id, x, y, needKey) {
core.clearContinueAutomaticRoute();
return false;
}
core.autosave(true);
if (!core.status.event.id) core.autosave(true);
core.removeItem(key);
}
return true;
@ -386,6 +404,7 @@ events.prototype._openDoor_animate = function (id, x, y, callback) {
var door = core.material.icons.animates[id];
var speed = id.endsWith("Door") ? 30 : 70;
var locked = core.status.lockControl;
core.lockControl();
core.status.replay.animate = true;
var state = 0;
@ -394,7 +413,7 @@ events.prototype._openDoor_animate = function (id, x, y, callback) {
if (state == 4) {
clearInterval(animate);
core.removeBlock(x, y);
core.unLockControl();
if (!locked) core.unLockControl();
core.status.replay.animate = false;
core.events.afterOpenDoor(id, x, y, callback);
return;
@ -414,29 +433,33 @@ events.prototype._sys_getItem = function (data, callback) {
}
////// 获得某个物品 //////
events.prototype.getItem = function (itemId, itemNum, itemX, itemY, callback) {
itemNum = itemNum || 1;
var itemCls = core.material.items[itemId].cls;
core.items.getItemEffect(itemId, itemNum);
core.removeBlock(itemX, itemY);
var text = '获得 ' + core.material.items[itemId].name;
if (itemNum > 1) text += "x" + itemNum;
if (itemCls === 'items') text += core.items.getItemEffectTip(itemId);
core.drawTip(text, core.material.icons.items[itemId]);
events.prototype.getItem = function (id, num, x, y, callback) {
num = num || 1;
var itemCls = core.material.items[id].cls;
core.items.getItemEffect(id, num);
core.removeBlock(x, y);
var text = '获得 ' + core.material.items[id].name;
if (num > 1) text += "x" + num;
if (itemCls === 'items') text += core.items.getItemEffectTip(id);
core.drawTip(text, core.material.icons.items[id]);
core.updateStatusBar();
this.eventdata.afterGetItem(itemId, itemX, itemY, callback);
this.afterGetItem(id, x, y, callback);
}
events.prototype.afterGetItem = function (id, x, y, callback) {
this.eventdata.afterGetItem(id, x, y, callback);
}
////// 获得面前的物品(轻按) //////
events.prototype.getNextItem = function () {
events.prototype.getNextItem = function (noRoute) {
if (core.isMoving() || !core.canMoveHero() || !core.flags.enableGentleClick) return false;
var nextX = core.nextX(), nextY = core.nextY();
var block = core.getBlock(nextX, nextY);
if (block == null) return false;
if (block.block.event.trigger == 'getItem') {
core.status.route.push("getNext");
if (!noRoute) core.status.route.push("getNext");
this.getItem(block.block.event.id, 1, nextX, nextY);
return true;
}
@ -449,7 +472,10 @@ events.prototype._sys_changeFloor = function (data, callback) {
if (data.loc) heroLoc = {'x': data.loc[0], 'y': data.loc[1]};
if (data.direction) heroLoc.direction = data.direction;
if (core.status.event.id != 'action') core.status.event.id = null;
core.changeFloor(data.floorId, data.stair, heroLoc, data.time, callback);
core.changeFloor(data.floorId, data.stair, heroLoc, data.time, function () {
core.replay();
if (callback) callback();
});
}
////// 楼层切换 //////
@ -461,6 +487,7 @@ events.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback
}
info.fromLoad = fromLoad;
floorId = info.floorId;
info.locked = core.status.lockControl;
core.dom.floorNameLabel.innerHTML = core.status.maps[floorId].title;
core.lockControl();
@ -553,7 +580,7 @@ events.prototype._changeFloor_changing = function (info, callback) {
}
events.prototype._changeFloor_afterChange = function (info, callback) {
core.unLockControl();
if (!info.locked) core.unLockControl();
core.status.replay.animate = false;
core.events.afterChangeFloor(info.floorId, info.fromLoad);
@ -661,11 +688,6 @@ events.prototype._sys_changeLight = function (data, callback) {
events.prototype.changeLight = function (id, x, y) {
if (id != null && id != 'light') return;
core.setBlock(core.getNumberById('darkLight'), x, y);
this.afterChangeLight(x, y);
}
////// 改变亮灯之后,可以触发的事件 //////
events.prototype.afterChangeLight = function (x, y) {
return this.eventdata.afterChangeLight(x, y);
}
@ -724,8 +746,19 @@ events.prototype.doEvent = function (data, x, y, prefix) {
core.doAction();
}
events.prototype.setEvents = function (list, x, y, callback) {
var data = core.status.event.data || {};
if (list)
data.list = [{todo: core.clone(list), total: core.clone(list), condition: "false"}];
if (x != null) data.x = x;
if (y != null) data.y = y;
if (callback) data.callback = callback;
core.status.event.id = 'action';
core.status.event.data = data;
}
////// 开始执行一系列自定义事件 //////
events.prototype.doEvents = function (list, x, y, callback) {
events.prototype.startEvents = function (list, x, y, callback) {
if (!list) return;
if (!(list instanceof Array)) {
list = [list];
@ -738,17 +771,6 @@ events.prototype.doEvents = function (list, x, y, callback) {
});
}
events.prototype.setEvents = function (list, x, y, callback) {
var data = core.status.event.data || {};
if (list)
data.list = [{todo: core.clone(list), total: core.clone(list), condition: "false"}];
if (x != null) data.x = x;
if (y != null) data.y = y;
if (callback) data.callback = callback;
core.status.event.id = 'action';
core.status.event.data = data;
}
////// 执行当前自定义事件列表中的下一个事件 //////
events.prototype.doAction = function () {
// 清空boxAnimate和UI层
@ -799,7 +821,7 @@ events.prototype._popEvents = function (current, prefix) {
return false;
}
////// 往当前事件列表之前添加一个或多个事件 //////
////// 往当前事件列表之前或之后添加一个或多个事件 //////
events.prototype.insertAction = function (action, x, y, callback, addToLast) {
if (core.hasFlag("__statistics__")) return;
if (core.status.gameOver) return;
@ -810,7 +832,7 @@ events.prototype.insertAction = function (action, x, y, callback, addToLast) {
if (!action) return;
if (core.status.event.id != 'action') {
this.doEvents(action, x, y, callback);
this.startEvents(action, x, y, callback);
}
else {
if (addToLast)
@ -1022,10 +1044,7 @@ events.prototype._action_jumpHero = function (data, x, y, prefix) {
events.prototype._action_changeFloor = function (data, x, y, prefix) {
var loc = this.__action_getHeroLoc(data.loc, prefix);
var heroLoc = {x: loc[0], y: loc[1], direction: data.direction};
core.changeFloor(data.floorId || core.status.floorId, null, heroLoc, data.time, function () {
core.lockControl();
core.doAction();
});
core.changeFloor(data.floorId || core.status.floorId, null, heroLoc, data.time, core.doAction);
}
events.prototype._action_changePos = function (data, x, y, prefix) {
@ -1101,10 +1120,7 @@ events.prototype._action_openDoor = function (data, x, y, prefix) {
var loc = this.__action_getLoc(data.loc, x, y, prefix);
var floorId = data.floorId || core.status.floorId;
if (floorId == core.status.floorId) {
core.openDoor(null, loc[0], loc[1], data.needKey, function () {
core.lockControl();
core.doAction();
});
core.openDoor(loc[0], loc[1], data.needKey, core.doAction);
}
else {
core.removeBlock(loc[0], loc[1], floorId);
@ -1152,14 +1168,10 @@ events.prototype._action_trigger = function (data, x, y, prefix) {
if (block != null && block.block.event.trigger) {
block = block.block;
this.setEvents([], block.x, block.y);
var _callback = function () {
core.lockControl();
core.doAction();
}
if (block.event.trigger == 'action')
this.setEvents(block.event.data);
else {
core.doSystemEvent(block.event.trigger, block, _callback);
core.doSystemEvent(block.event.trigger, block, core.doAction);
return;
}
}
@ -1703,24 +1715,6 @@ events.prototype.unfollow = function (name) {
core.drawHero();
}
////// 绘制或取消一张gif图片 //////
events.prototype.showGif = function (name, x, y) {
var image = core.material.images.images[name];
if (image) {
var gif = new Image();
gif.src = image.src;
gif.style.position = 'absolute';
gif.style.left = x * core.domStyle.scale + "px";
gif.style.top = y * core.domStyle.scale + "px";
gif.style.width = image.width * core.domStyle.scale + "px";
gif.style.height = image.height * core.domStyle.scale + "px";
core.dom.gif2.appendChild(gif);
}
else {
core.dom.gif2.innerHTML = "";
}
}
////// 数值操作 //////
events.prototype.setValue = function (name, value, prefix, add) {
var value = core.calValue(value, prefix);
@ -1924,6 +1918,24 @@ events.prototype._moveImage_moving = function (name, moveInfo, callback) {
core.animateFrame.asyncId[animate] = true;
}
////// 绘制或取消一张gif图片 //////
events.prototype.showGif = function (name, x, y) {
var image = core.material.images.images[name];
if (image) {
var gif = new Image();
gif.src = image.src;
gif.style.position = 'absolute';
gif.style.left = x * core.domStyle.scale + "px";
gif.style.top = y * core.domStyle.scale + "px";
gif.style.width = image.width * core.domStyle.scale + "px";
gif.style.height = image.height * core.domStyle.scale + "px";
core.dom.gif2.appendChild(gif);
}
else {
core.dom.gif2.innerHTML = "";
}
}
////// 淡入淡出音乐 //////
events.prototype.setVolume = function (value, time, callback) {
var set = function (value) {
@ -2214,7 +2226,7 @@ events.prototype.afterUseBomb = function () {
}
////// 上传当前数据 //////
events.prototype.uploadCurrent = function (username) {
events.prototype._uploadCurrent = function (username) {
var formData = new FormData();
formData.append('type', 'score');

View File

@ -196,20 +196,6 @@ items.prototype.setItem = function (itemId, itemNum) {
core.updateStatusBar();
}
////// 删除某个物品 //////
items.prototype.removeItem = function (itemId, itemNum) {
if (itemNum == null) itemNum = 1;
if (!core.hasItem(itemId)) return false;
var itemCls = core.material.items[itemId].cls;
core.status.hero.items[itemCls][itemId] -= itemNum;
if (core.status.hero.items[itemCls][itemId] <= 0) {
if (itemCls != 'keys') delete core.status.hero.items[itemCls][itemId];
else core.status.hero.items[itemCls][itemId] = 0;
}
core.updateStatusBar();
return true;
}
////// 增加某个物品的个数 //////
items.prototype.addItem = function (itemId, itemNum) {
if (itemNum == null) itemNum = 1;
@ -230,15 +216,22 @@ items.prototype.addItem = function (itemId, itemNum) {
core.updateStatusBar();
}
// ---------- 装备相关 ------------ //
items.prototype.getEquipTypeById = function (equipId) {
var type = core.material.items[equipId].equip.type;
if (typeof type == 'string')
type = this.getEquipTypeByName(type);
return type;
////// 删除某个物品 //////
items.prototype.removeItem = function (itemId, itemNum) {
if (itemNum == null) itemNum = 1;
if (!core.hasItem(itemId)) return false;
var itemCls = core.material.items[itemId].cls;
core.status.hero.items[itemCls][itemId] -= itemNum;
if (core.status.hero.items[itemCls][itemId] <= 0) {
if (itemCls != 'keys') delete core.status.hero.items[itemCls][itemId];
else core.status.hero.items[itemCls][itemId] = 0;
}
core.updateStatusBar();
return true;
}
// ---------- 装备相关 ------------ //
items.prototype.getEquipTypeByName = function (name) {
var names = core.status.globalAttribute.equipName;
for (var i = 0; i < names.length; ++i) {
@ -249,6 +242,13 @@ items.prototype.getEquipTypeByName = function (name) {
return -1;
}
items.prototype.getEquipTypeById = function (equipId) {
var type = core.material.items[equipId].equip.type;
if (typeof type == 'string')
type = this.getEquipTypeByName(type);
return type;
}
// 当前能否撞上某装备
items.prototype.canEquip = function (equipId, hint) {
// 装备是否合法

View File

@ -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 = {};
for (var i = 0; i < floorIds.length; i++) {
var floorId = floorIds[i];
@ -242,7 +243,7 @@ maps.prototype.saveMap = function (floorId) {
return map;
}
var map = maps[floorId], floor = core.floors[floorId];
var blocks = this.getMapArray(map.blocks, floor.width, floor.height, true);
var blocks = this._getMapArrayFromBlocks(map.blocks, floor.width, floor.height, true);
if (main.mode == 'editor') return blocks;
var thisFloor = this._compressFloorData(map, floor);
@ -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') {
var floorId = blockArray;
blockArray = core.status.maps[floorId].blocks;
@ -313,11 +320,11 @@ maps.prototype.getMapArray = function (blockArray, width, height, checkDisable)
blockArray.forEach(function (block) {
var x = block.x, y = block.y;
if (block.disable) {
if (checkDisable) blocks[y][x] = block.id + ":f";
if (showDisable) blocks[y][x] = block.id + ":f";
}
else {
blocks[y][x] = block.id;
if (checkDisable && block.disable === false)
if (showDisable && block.disable === false)
blocks[y][x] = block.id + ":t";
}
});
@ -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;
if (!floorId) return [];
var width = core.floors[floorId].width;
@ -363,25 +370,25 @@ maps.prototype.getBgFgMapArray = function (name, floorId, noCache) {
}
maps.prototype.getBgMapArray = function (floorId, noCache) {
return this.getBgFgMapArray('bg', floorId, noCache);
return this._getBgFgMapArray('bg', floorId, noCache);
}
maps.prototype.getFgMapArray = function (floorId, noCache) {
return this.getBgFgMapArray('fg', floorId, noCache);
return this._getBgFgMapArray('fg', floorId, noCache);
}
maps.prototype.getBgFgNumber = function (name, x, y, floorId, noCache) {
maps.prototype._getBgFgNumber = function (name, x, y, floorId, noCache) {
if (x == null) x = core.getHeroLoc('x');
if (y == null) y = core.getHeroLoc('y');
return this.getBgFgMapArray(name, floorId, noCache)[y][x];
return this._getBgFgMapArray(name, floorId, noCache)[y][x];
}
maps.prototype.getBgNumber = function (x, y, floorId, noCache) {
return this.getBgFgNumber('bg', x, y, floorId, noCache);
return this._getBgFgNumber('bg', x, y, floorId, noCache);
}
maps.prototype.getFgNumber = function (x, y, floorId, noCache) {
return this.getBgFgNumber('fg', x, y, floorId, noCache);
return this._getBgFgNumber('fg', x, y, floorId, noCache);
}
// ------ 当前能否朝某方向移动,能否瞬间移动 ------ //
@ -701,7 +708,7 @@ maps.prototype._drawMap_drawAll = function (floorId) {
maps.prototype._drawMap_drawBlockInfo = function (ctx, block, blockInfo, arr, onMap) {
if (blockInfo == null) return;
if (blockInfo.cls == 'autotile') { // Autotile单独处理
this.drawAutotile(ctx, arr, block, 32, 0, 0);
this._drawAutotile(ctx, arr, block, 32, 0, 0);
if (onMap) this.addGlobalAnimate(block);
return;
}
@ -716,15 +723,16 @@ maps.prototype._drawMap_drawBlockInfo = function (ctx, block, blockInfo, arr, on
////// 绘制背景层 //////
maps.prototype.drawBg = function (floorId, ctx) {
floorId = floorId || core.status.floorId;
var onMap = ctx == null;
if (onMap) {
ctx = core.canvas.bg;
core.clearMap(ctx);
}
this._drawBg_drawBackground(floorId, ctx);
core.maps._drawBg_drawBackground(floorId, ctx);
// ------ 调整这两行的顺序来控制是先绘制贴图还是先绘制背景图块;后绘制的覆盖先绘制的。
this._drawFloorImages(floorId, ctx, 'bg');
this._drawBgFgMap(floorId, ctx, 'bg', onMap);
core.maps._drawFloorImages(floorId, ctx, 'bg');
core.maps._drawBgFgMap(floorId, ctx, 'bg', onMap);
}
maps.prototype._drawBg_drawBackground = function (floorId, ctx) {
@ -744,7 +752,7 @@ maps.prototype._drawBg_drawBackground = function (floorId, ctx) {
maps.prototype.drawEvents = function (floorId, blocks, ctx) {
floorId = floorId || core.status.floorId;
if (!blocks) blocks = core.status.maps[floorId].blocks;
var arr = this.getMapArray(blocks, core.floors[floorId].width, core.floors[floorId].height);
var arr = this._getMapArrayFromBlocks(blocks, core.floors[floorId].width, core.floors[floorId].height);
var onMap = ctx == null;
if (onMap) ctx = core.canvas.event;
blocks.filter(function (block) {
@ -757,6 +765,7 @@ maps.prototype.drawEvents = function (floorId, blocks, ctx) {
////// 绘制前景层 //////
maps.prototype.drawFg = function (floorId, ctx) {
floorId = floorId || core.status.floorId;
var onMap = ctx == null;
if (onMap) ctx = core.canvas.fg;
// ------ 调整这两行的顺序来控制是先绘制贴图还是先绘制背景图块;后绘制的覆盖先绘制的。
@ -774,7 +783,7 @@ maps.prototype._drawBgFgMap = function (floorId, ctx, name, onMap) {
if (!core.status[name + "maps"])
core.status[name + "maps"] = {};
var arr = this.getBgFgMapArray(name, floorId, true);
var arr = this._getBgFgMapArray(name, floorId, true);
for (var x = 0; x < width; x++) {
for (var y = 0; y < height; y++) {
var block = this.initBlock(x, y, arr[y][x], true);
@ -866,7 +875,7 @@ maps.prototype._drawFloorImage = function (ctx, name, type, image, offsetX, widt
}
////// 绘制Autotile //////
maps.prototype.drawAutotile = function (ctx, mapArr, block, size, left, top, status) {
maps.prototype._drawAutotile = function (ctx, mapArr, block, size, left, top, status) {
var indexArrs = [ //16种组合的图块索引数组; // 将autotile分割成48块16*16的小块; 数组索引即对应各个小块
// +----+----+----+----+----+----+
[10, 9, 4, 3], //0 bin:0000 | 1 | 2 | 3 | 4 | 5 | 6 |
@ -1231,7 +1240,7 @@ maps.prototype.searchBlock = function (id, floorId, showDisable) {
for (var i = 0; i < core.status.maps[floorId].blocks.length; ++i) {
var block = core.status.maps[floorId].blocks[i];
if (block.event.id == id && (showDisable || !block.disable))
result.push({floorId: floorId, index: i, block: block});
result.push({floorId: floorId, index: i, block: block, x: block.x, y: block.y});
}
return result;
}
@ -1317,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 //////
maps.prototype.removeBlockByIds = function (floorId, ids) {
floorId = floorId || core.status.floorId;
@ -1341,24 +1337,17 @@ maps.prototype.removeBlockByIds = function (floorId, ids) {
});
}
////// 将地图中所有某个图块替换成另一个图块 //////
maps.prototype.replaceBlock = function (fromNumber, toNumber, floorId) {
floorId = floorId || core.status.floorId;
if (floorId instanceof Array) {
floorId.forEach(function (floorId) {
core.replaceBlock(fromNumber, toNumber, floorId);
});
return;
}
var toBlock = this.initBlock(0, 0, toNumber, true);
core.status.maps[floorId].blocks.forEach(function (block) {
if (block.id == fromNumber) {
block.id = toNumber;
for (var one in toBlock.event) {
block.event[one] = core.clone(toBlock.event[one]);
}
}
});
////// 能否彻底从地图中删除一个图块 //////
maps.prototype.canRemoveBlock = function (block, floorId) {
var x = block.x, y = block.y;
// 检查该点是否存在事件
if (core.floors[floorId].events[x + "," + y] || core.floors[floorId].changeFloor[x + "," + y])
return false;
// 检查是否存在重生
if (block.event && block.event.cls.indexOf('enemy') == 0 && core.hasSpecial(block.event.id, 23))
return false;
return true;
}
////// 显示前景/背景地图 //////
@ -1436,6 +1425,7 @@ maps.prototype.setBlock = function (number, x, y, floorId) {
floorId = floorId || core.status.floorId;
if (!floorId || number == null || x == null || y == null) return;
if (x < 0 || x >= core.floors[floorId].width || y < 0 || y >= core.floors[floorId].height) return;
if (typeof number == 'string') number = core.getNumberById(number);
var originBlock = core.getBlock(x, y, floorId, true);
var block = this.initBlock(x, y, number, true, core.floors[floorId]);
@ -1463,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) {
floorId = floorId || core.status.floorId;
@ -1776,16 +1786,16 @@ maps.prototype._animateBlock_drawList = function (list, opacity) {
// ------ 全局动画控制,动画绘制 ------ //
////// 添加一个全局动画 //////
maps.prototype.addGlobalAnimate = function (b) {
if (!b.event || b.event.animate == null) return;
if (b.event.cls == 'autotile') {
var id = b.event.id, img = core.material.images.autotile[id];
maps.prototype.addGlobalAnimate = function (block) {
if (!block.event || block.event.animate == null) return;
if (block.event.cls == 'autotile') {
var id = block.event.id, img = core.material.images.autotile[id];
if (!img || img.width == 96) return;
core.status.autotileAnimateObjs.blocks.push(b);
core.status.autotileAnimateObjs.blocks.push(block);
}
else {
if (!b.event.animate || b.event.animate == 1) return;
core.status.globalAnimateObjs.push(b);
if (!block.event.animate || block.event.animate == 1) return;
core.status.globalAnimateObjs.push(block);
}
}

View File

@ -1080,7 +1080,7 @@ utils.prototype._export = function (floorIds) {
// map
var content = floorIds.length + "\n" + core.__SIZE__ + " " + core.__SIZE__ + "\n\n";
floorIds.forEach(function (floorId) {
var arr = core.maps.getMapArray(core.status.maps[floorId].blocks);
var arr = core.maps._getMapArrayFromBlocks(core.status.maps[floorId].blocks);
content += arr.map(function (x) {
// check monster
x.forEach(function (t) {