# 附录：API列表

?> 样板全部的API列表都在这里了！

这里将列出所有被转发到core的API，没有被转发的函数此处不会列出，请自行在代码中查看。

本附录量较大，如有什么需求请自行Ctrl+F进行搜索。

如有任何疑问，请联系小艾寻求帮助。

## core.js

core.js中只有很少的几个函数，主要是游戏开始前的初始化等。

但是，core中定义了很多游戏运行时的状态，这些状态很多都会被使用到。

```text
<b>core.__SIZE__, core.__PIXELS__</b>
游戏窗口大小；对于13x13的游戏而言这两个值分别是13和416，15x15来说分别是15和480。


core.material
游戏中的所有资源列表，具体分为如下内容：
core.material.animates  （动画）
core.material.bgms    （背景音乐）
core.material.enemys    （怪物信息，来自于 project/enemys.js）
core.material.icons    （图标信息，来自于 project/icons.js）
core.material.images    （图片素材，存放了各项素材图片如items.png等）
    core.material.images.autotile    （所有的自动元件图片）
    core.material.images.tilesets    （所有的额外素材图片）
    core.material.images.images    （用户引入的其他图片）
core.material.items    （道具信息）
core.material.sounds    （音效）


core.animateFrame
主要是记录和requestAnimationFrame相关的一些数据，常用的如下：
core.animateFrame.totalTime    （游戏总的运行时时间）
core.animateFrame.weather    （当前的天气信息）
core.animateFrame.asyncId    （当前的异步处理事件的内容）


core.musicStatus
主要是记录和音效相关的内容，常用的如下：
core.musicStatus.bgmStatus    （音乐开启状态）
core.musicStatus.soundStatus    （音效开启状态）
core.musicStatus.playingBgm    （当前正在播放的BGM）
core.musicStatus.lastBgm    （最近一次尝试播放的BGM）
core.musicStatus.volume    （当前的音量）
core.musicStatus.cachedBgms    （背景音乐的缓存内容）
core.musicStatus.cacheBgmCount    （背景音乐的缓存数量，默认值是4）


core.platform
游戏平台相关信息，常见的几个如下：
core.platform.isPC    （是否是电脑端）
core.platform.isAndroid    （是否是安卓端）
core.platform.isIOS    （是否是iOS端）
core.platform.useLocalForage    （是否开启了新版存档）


core.domStyle
游戏的界面信息，包含如下几个：
core.domStyle.scale    （当前的放缩比）
core.domStyle.isVertical    （当前是否是竖屏状态）
core.domStyle.showStatusBar    （当前是否显示状态栏）
core.domStyle.toolbarBtn    （当前是否显示工具栏）


core.bigmap
当前的地图的尺寸信息，主要包含如下几个
core.bigmap.width    （当前地图的宽度）
core.bigmap.height    （当前地图的高度）
core.bigmap.offsetX    （当前地图针对窗口左上角的偏移像素x）
core.bigmap.offsetX    （当前地图针对窗口左上角的偏移像素y）
core.bigmap.tempCanvas    （一个临时画布，可以用来临时绘制很多东西）


core.saves
和存档相关的信息，包含如下几个：
core.saves.saveIndex    （上次保存或读取的存档编号）
core.saves.ids    （当前存在存档的编号列表）
core.saves.autosave    （自动存档的信息）
core.saves.favorite    （收藏的存档）
core.saves.favoriteNames    （自定义存档的名称）


core.status
游戏的状态相关，是整个游戏中最重要的东西，其核心是如下几条：
请注意，每次重新开始、存档或读档时，core.status都会重新初始化。
core.status.played    （当前是否在游戏中）
core.status.gameOver    （当前是否已经游戏结束，即win或lose）
core.status.hero    （勇士信息；此项和全塔属性中的hero大体是对应的）
    core.status.hero.name    勇士名
    core.status.hero.lv      当前等级
    core.status.hero.hpmax   当前生命上限
    core.status.hero.hp      当前生命值
    core.status.hero.manamax   当前魔力上限
    core.status.hero.mana    当前魔力值
    core.status.hero.atk     当前攻击力
    core.status.hero.def     当前防御力
    core.status.hero.mdef    当前护盾值
    core.status.hero.money   当前金币值
    core.status.hero.exp    当前经验值
    core.status.hero.loc     当前的位置信息
    core.status.hero.equipment     当前装上的装备
    core.status.hero.items   当前拥有的道具信息
    core.status.hero.flags   当前的各项flag信息
    core.status.hero.step    当前的步数值
    core.status.hero.statistics    当前的统计信息
core.status.floorId    （当前所在的楼层）    
core.status.maps    （所有的地图信息）
core.status.thisMap    （当前的地图信息，等价于core.status.maps[core.status.floorId]）
core.status.bgmaps   （所有背景层的信息）
core.status.fgmaps    （所有的前景层的信息）
core.status.checkBlock    （地图上的阻激夹域信息，也作为光环的缓存）
core.status.lockControl    （当前是否是控制锁定状态）
core.status.automaticRoute    （当前的自动寻路信息）
core.status.route    （当前记录的录像）
core.status.replay    （录像回放时要用到的信息）
core.status.shops    （所有全局商店信息）
core.status.textAttribute    （当前的文字属性，如颜色、背景等信息，和setText事件对应）
core.status.globalAttribute    （当前的全局属性，如边框色、装备栏等）
core.status.curtainColor    （当前色调层的颜色）
core.status.globalAnimateObjs    （当前的全局帧动画效果）
core.status.floorAnimateObjs    （当前的楼层贴图帧动画效果）
core.status.boxAnimateObjs    （当前的盒子帧动画效果，例如怪物手册中的怪物）
core.status.autotileAnimateObjs    （当前楼层的自动元件动画效果）
core.status.globalAnimateStatus    （当前的帧动画的状态）
core.status.animateObjs    （当前的播放动画信息）


core.floorIds
一个数组，表示所有的楼层ID，和全塔属性中的floorIds一致。


core.floors
从楼层文件中读取全部的地图数据。
和core.status.maps不同的是，后者在每次重新开始和读档时都会重置，也允许被修改（会存入存档）。
而core.floors全程唯一，不允许被修改。


core.statusBar
状态栏信息，例如状态栏图片，图标，以及各个内容的DOM定义等。
core.statusBar.images    （所有的系统图标，和icons.png对应）
core.statusBar.icons    （状态栏中绘制的图标内容）


core.values
所有的全局数值信息，和全塔属性中的values一致。
此项允许被直接修改，会存入存档。


core.flags
所有的全塔开关，和全塔属性中的flags一致。
此项不允许被直接修改，如有需要请使用“设置系统开关”事件，或者调用core.setGlobalFlag这个API。


core.plugin
定义的插件函数。


core.doFunc(func, _this)
执行一个函数，func为函数体或者插件中的函数名，_this为使用的this。
如果func为一个字符串，则视为插件中的函数名，同时_this将被设置成core.plugin。
此函数剩余参数将作为参数被传入func。
```

## actions.js

actions.js主要是处理一些和用户交互相关的内容。

```text
onup: fn(loc: {x: number, y: number, size: number})
当点击（触摸）事件放开时

pressKey: fn(keyCode: number)
按住某个键时

keyUp: fn(keyCode: number, altKey?: bool, fromReplay?: bool)
根据放开键的code来执行一系列操作

ondown: fn(loc: {x: number, y: number, size: number})
点击（触摸）事件按下时

registerAction: fn(action: string, name: string, func: string|fn(params: ?), priority?: number)
此函数将注册一个用户交互行为。
action: 要注册的交互类型，如 ondown, onclick, keyDown 等等。
name: 你的自定义名称，可被注销使用；同名重复注册将后者覆盖前者。
func: 执行函数。
如果func返回true，则不会再继续执行其他的交互函数；否则会继续执行其他的交互函数。
priority: 优先级；优先级高的将会被执行。此项可不填，默认为0

onkeyDown: fn(e: Event)
按下某个键时

keyDown: fn(keyCode: number)
根据按下键的code来执行一系列操作

onStatusBarClick: fn(e?: Event)
点击自绘状态栏时

longClick: fn(x: number, y: number, fromEvent?: bool)
长按

unregisterAction: fn(action: string, name: string)
注销一个用户交互行为

keyDownCtrl: fn() -> bool
长按Ctrl键时

onclick: fn(x: number, y: number, stepPostfix?: ?)
具体点击屏幕上(x,y)点时，执行的操作

doRegisteredAction: fn(action: string, params: ?)
执行一个用户交互行为

onkeyUp: fn(e: Event)
放开某个键时

onmousewheel: fn(direct: number)
滑动鼠标滚轮时的操作

onmove: fn(loc: {x: number, y: number, size: number})
当在触摸屏上滑动时
```

## control.js

control.js将负责整个游戏的核心控制系统，分为如下几个部分：
- requestAnimationFrame相关
- 标题界面，开始和重新开始游戏
- 自动寻路和人物行走相关
- 画布、位置、阻激夹域、显伤等相关
- 录像的回放相关
- 存读档，自动存档，同步存档等相关
- 人物属性和状态、位置、变量等相关
- 天气、色调、音乐和音效的播放
- 状态栏和工具栏相关
- 界面resize相关

```text
showStatusBar: fn()
显示状态栏

startReplay: fn(list: [string])
开始播放录像

triggerReplay: fn()
播放或暂停录像回放

screenFlash: fn(color: [number], time: number, times?: number, callback?: fn())
画面闪烁
例如：core.screenFlash([255, 0, 0, 1], 3); // 红屏一闪而过
color: 一行三列（第四列视为1）或一行四列（第四列若大于1则会被视为1，第四列若填负数则会被视为0）的颜色数组，必填
time: 单次闪烁时长，实际闪烁效果为先花其三分之一的时间渐变到目标色调，再花剩余三分之二的时间渐变回去
times: 闪烁的总次数，不填或填0都视为1
callback: 闪烁全部完毕后的回调函数，可选

setCurtain: fn(color?: [number], time?: number, callback?: fn())
更改画面色调，不计入存档。如需长期生效请使用core.events._action_setCurtain()函数
例如：core.setCurtain(); // 恢复画面色调，用时四分之三秒
color: 一行三列（第四列视为1）或一行四列（第四列若大于1则会被视为1，第四列若为负数则会被视为0）的颜色数组，不填视为[0, 0, 0, 0]
time: 渐变时间，单位为毫秒。不填视为750ms，负数视为0（无渐变，立即更改）
callback: 更改完毕后的回调函数，可选。事件流中常取core.doAction

updateDamage: fn(floorId?: string, ctx?: string|CanvasRenderingContext2D)
更新地图显伤
例如：core.updateDamage(); // 更新当前地图的显伤，绘制在显伤层（废话）
floorId: 地图id，不填视为当前地图。预览地图时填写
ctx: 绘制到的画布，如果填写了就会画在该画布而不是显伤层

nextX: fn(n?: number) -> number
获取主角面前第n格的横坐标
例如：core.closeDoor(core.nextX(), core.nextY(), 'yellowDoor', core.turnHero); // 在主角面前关上一扇黄门，然后主角顺时针旋转90°
n: 目标格与主角的距离，面前为正数，背后为负数，脚下为0，不填视为1

nextY: fn(n?: number) -> number
获取主角面前第n格的纵坐标
例如：core.jumpHero(core.nextX(2), core.nextY(2)); // 主角向前跃过一格，即跳跃靴道具的使用效果
n: 目标格与主角的距离，面前为正数，背后为负数，脚下为0，不填视为1

clearContinueAutomaticRoute: fn(callback?: fn())
清空剩下的自动寻路列表

updateViewport: fn()
更新大地图的可见区域

getMappedName: fn(name: string) -> string
获得映射文件名

addFlag: fn(name: string, value: number)
增减一个flag变量，等价于 core.setFlag(name, core.getFlag(name, 0) + value)
例如：core.addFlag('hatred', 1); // 增加1点仇恨值
name: 变量名，支持中文
value: 变量的增量

setFlag: fn(name: string, value: ?)
设置一个flag变量
例如：core.setFlag('poison', true); // 令主角中毒
name: 变量名，支持中文
value: 变量的新值，不填或填null视为删除

viewMapReplay: fn()
回放录像时浏览地图

playSound: fn(sound: string)
播放一个音效

stopSound: fn()
停止所有SE

addGameCanvasTranslate: fn(x?: number, y?: number)
加减画布偏移

addBuff: fn(name: string, value: number)
增减主角某个属性的百分比修正倍率，加减法叠加和抵消。等价于 core.setBuff(name, core.getBuff(name) + value)
例如：core.addBuff('atk', -0.1); // 主角获得一层“攻击力减一成”的负面效果
name: 属性的英文名，请注意只能用于数值类属性哦，否则随后的乘法会得到NaN
value: 倍率的增量

drawHero: fn(status?: string, offset?: number, frame?: number)
绘制主角和跟随者并重置视野到以主角为中心
例如：core.drawHero(); // 原地绘制主角的静止帧并重置视野野
status: 只能为 stop, leftFoot 和 rightFoot，不填用stop。
offset: 相对主角逻辑位置的偏移量，不填视为无偏移。
frame: 绘制的第几帧

pauseBgm: fn()
暂停背景音乐的播放

setReplaySpeed: fn(speed: number)
设置播放速度

pauseReplay: fn()
暂停播放

doSL: fn(id?: string, type?: string)
实际进行存读档事件

setStatus: fn(name: string, value: number)
设置主角的某个属性
例如：core.setStatus('atk', 100); // 设置攻击力为100
name: 属性的英文名，其中'x'、'y'和'direction'会被特殊处理为 core.setHeroLoc(name, value)，其他的会直接对 core.status.hero[name] 赋值
value: 属性的新值

setAutomaticRoute: fn(destX: number, destY: number, stepPostfix: [{x: number, y: number, direction: string}])
半自动寻路，用于鼠标或手指拖动
例如：core.setAutomaticRoute(0, 0, [{direction: "right", x: 4, y: 9}, {direction: "right", x: 5, y: 9}]);
destX: 鼠标或手指的起拖点横坐标
destY: 鼠标或手指的起拖点纵坐标
stepPostfix: 拖动轨迹的数组表示，每项为一步的方向和目标点。

triggerHero: fn(type?: string, time?: number, callback?: fn())
改变勇士的显隐状态

gatherFollowers: fn()
立刻聚集所有的跟随者

getStatus: fn(name: string) -> number
读取主角的某个属性，不包括百分比修正
例如：core.getStatus('atk'); // 读取主角的攻击力
name: 属性的英文名，其中'x'、'y'和'direction'会被特殊处理为 core.getHeroLoc(name)，其他的会直接读取 core.status.hero[name]

setHeroLoc: fn(name: string, value: string|number, noGather?: bool)
设置勇士位置
值得注意的是，这句话虽然会使勇士改变位置，但并不会使界面重新绘制；
如需立刻重新绘制地图还需调用：core.clearMap('hero'); core.drawHero(); 来对界面进行更新。
例如：core.setHeroLoc('x', 5) // 将勇士当前位置的横坐标设置为5。
name: 要设置的坐标属性
value: 新值
noGather: 是否聚集跟随者

getLvName: fn(lv?: number) -> string|number
根据级别的数字获取对应的名称，后者定义在全塔属性
例如：core.getLvName(); // 获取主角当前级别的名称，如“下级佣兵”
lv: 级别的数字，不填则视为主角当前的级别
返回值：级别的名称，如果不存在就还是返回数字

addStatus: fn(name: string, value: number)
增减主角的某个属性，等价于core.setStatus(name, core.getStatus(name) + value)
例如：core.addStatus('atk', 100'); // 给主角攻击力加100
name: 属性的英文名
value: 属性的增量

speedUpReplay: fn()
加速播放

loadData: fn(data?: ?, callback?: fn())
从本地读档

debug: fn()
开启调试模式, 此模式下可以按Ctrl键进行穿墙, 并忽略一切事件。
此模式下不可回放录像和上传成绩。

moveOneStep: fn(callback?: fn())
每移动一格后执行的事件
【异步脚本，请勿在脚本中直接调用（而是使用对应的事件），否则可能导致录像出错】

clearStatus: fn()
清除游戏状态和数据

updateFollowers: fn()
更新跟随者坐标

waitHeroToStop: fn(callback?: fn())
等待主角停下
例如：core.waitHeroToStop(core.vibrate); // 等待主角停下，然后视野左右抖动1秒
callback: 主角停止后的回调函数

hideStatusBar: fn(showToolbox?: bool)
隐藏状态栏
showToolbox: 是否不隐藏竖屏工具栏

getBuff: fn(name: string) -> number
读取主角某个属性的百分比修正倍率，初始值为1
例如：core.getBuff('atk'); // 主角当前能发挥出多大比例的攻击力
name: 属性的英文名

setToolbarButton: fn(useButton?: bool)
改变工具栏为按钮1-8

getSaves: fn(ids?: ?, callback?: fn())
获得某些存档内容

replay: fn()
回放下一个操作

getStatusOrDefault: fn(status?: ?, name?: string)
从status中获得属性，如果不存在则从勇士属性中获取

unregisterReplayAction: fn(name: string)
注销一个录像行为

setBuff: fn(name: string, value: number)
设置主角某个属性的百分比修正倍率，初始值为1，
倍率存放在flag: '__'+name+'_buff__' 中
例如：core.setBuff('atk', 0.5); // 主角能发挥出的攻击力减半
name: 属性的英文名，请注意只能用于数值类属性哦，否则随后的乘法会得到NaN
value: 新的百分比修正倍率，不填（效果上）视为1

continueAutomaticRoute: fn()
继续剩下的自动寻路操作

saveReplay: fn()
回放时存档

setAutoHeroMove: fn(steps: [?])
连续行走
例如：core.setAutoHeroMove([{direction: "up", step: 1}, {direction: "left", step: 3}]); // 上左左左
steps: 压缩的步伐数组，每项表示朝某方向走多少步

fillPosWithPoint: fn(pos?: ?)
显示离散的寻路点

unregisterResize: fn(name: string)
注销一个resize函数

saveAndStopAutomaticRoute: fn()
保存剩下的寻路，并停止

hideStartAnimate: fn(callback?: fn())
淡出标题画面
例如：core.hideStartAnimate(core.startGame); // 淡出标题画面并开始新游戏，跳过难度选择
callback: 标题画面完全淡出后的回调函数

getAllSaves: fn(callback?: fn())
获得所有存档内容

updateHeroIcon: fn(name: string)
更新状态栏的勇士图标

setMusicBtn: fn()
设置音乐图标的显隐状态

isPlaying: fn() -> bool
游戏是否已经开始

triggerBgm: fn()
开启或关闭背景音乐的播放

moveHero: fn(direction?: string, callback?: fn())
连续前进，不撞南墙不回头
例如：core.moveHero(); // 连续前进
direction: 可选，如果设置了就会先转身到该方向
callback: 可选，如果设置了就只走一步
【异步脚本，请勿在脚本中直接调用（而是使用对应的事件），否则可能导致录像出错】

getRealStatusOrDefault: fn(status?: ?, name?: string)
从status中获得实际属性（增幅后的），如果不存在则从勇士属性中获取

removeSave: fn(index?: number, callback?: fn())
删除某个存档

registerAnimationFrame: fn(name: string, needPlaying: bool, func?: fn(timestamp: number))
注册一个 animationFrame
name: 名称，可用来作为注销使用
needPlaying: 是否只在游戏运行时才执行（在标题界面不执行）
func: 要执行的函数，或插件中的函数名；可接受timestamp（从页面加载完毕到当前所经过的时间）作为参数

getHeroLoc: fn(name: string) -> string|number
读取主角的位置和/或朝向
例如：core.getHeroLoc(); // 读取主角的位置和朝向
name: 要读取横坐标还是纵坐标还是朝向还是都读取
返回值：name ? core.status.hero.loc[name] : core.status.hero.loc

stopAutomaticRoute: fn()
停止自动寻路操作

setWeather: fn(type?: string, level?: number)
设置天气，不计入存档。如需长期生效请使用core.events._action_setWeather()函数
例如：core.setWeather('fog', 10); // 设置十级大雾天
type: 新天气的类型，不填视为晴天
level: 新天气（晴天除外）的级别，必须为不大于10的正整数，不填视为5

updateStatusBar: fn(doNotCheckAutoEvents?: bool)
立刻刷新状态栏和地图显伤
doNotCheckAutoEvents: 是否不检查自动事件

autosave: fn(removeLast?: bool)
自动存档

clearStatusBar: fn()
清空状态栏

moveAction: fn(callback?: fn())
尝试前进一步，如果面前不可被踏入就会直接触发该点事件
与「勇士前进一步或撞击」事件等价
【异步脚本，请勿在脚本中直接调用（而是使用对应的事件），否则可能导致录像出错】

hasFlag: fn(name: string) -> bool
判定一个flag变量是否存在且不为false、0、''、null、undefined和NaN
例如：core.hasFlag('poison'); // 判断主角当前是否中毒
name: 变量名，支持中文
此函数等价于 !!core.getFlag(name)

rewindReplay: fn()
回退到上一个录像节点

toolboxReplay: fn()
回放录像时打开道具栏

playBgm: fn(bgm: string, startTime?: number)
播放背景音乐，中途开播但不计入存档且只会持续到下次场景切换。如需长期生效请将背景音乐的文件名赋值给flags.__bgm__
例如：core.playBgm('bgm.mp3', 30); // 播放bgm.mp3，并跳过前半分钟
bgm: 背景音乐的文件名，支持全塔属性中映射前的中文名
startTime: 跳过前多少秒，不填则不跳过

isReplaying: fn() -> bool
是否正在播放录像

isMoving: fn() -> bool
当前是否正在移动

getSaveIndexes: fn(callback?: fn())
获得所有存在存档的存档位

unlockControl: fn()
解锁用户控制行为

syncSave: fn(type?: string)
同步存档到服务器

removeFlag: fn(name: string)
删除某个flag/变量

registerResize: fn(name: string, func: fn(obj: ?))
注册一个resize函数
name: 名称，可供注销使用
func: 可以是一个函数，或者是插件中的函数名；可以接受obj参数，详见resize函数。

stopReplay: fn(force?: bool)
停止播放

bookReplay: fn()
回放时查看怪物手册

turnHero: fn(direction?: string)
主角转向并计入录像，不会导致跟随者聚集，会导致视野重置到以主角为中心
例如：core.turnHero(); // 主角顺时针旋转90°，即单击主角或按下Z键的效果
direction: 主角的新朝向，可为 up, down, left, right, :left, :right, :back 七种之一

resumeReplay: fn()
恢复播放

resize: fn()
屏幕分辨率改变后重新自适应

equipboxReplay: fn()
回放录像时打开装备栏

getSave: fn(index?: number, callback?: fn(data: ?))
获得某个存档内容

setViewport: fn(x?: number, y?: number)
设置视野范围
x,y: 左上角相对大地图的像素坐标，不需要为32倍数

chooseReplayFile: fn()
选择录像文件

lockControl: fn()
锁定用户控制，常常用于事件处理

updateCheckBlock: fn(floorId?: string)
更新领域、夹击、阻击的伤害地图

checkBlock: fn()
检查并执行领域、夹击、阻击事件

clearAutomaticRouteNode: fn(x?: number, y?: number)
清除自动寻路路线

getFlag: fn(name: string, defaultValue?: ?)
读取一个flag变量
name: 变量名，支持中文
defaultValue: 当变量不存在时的返回值，可选（事件流中默认填0）。

getNakedStatus: fn(name: string)
获得勇士原始属性（无装备和衰弱影响）

nearHero: fn(x: number, y: number, n?: number) -> bool
判定主角是否身处某个点的锯齿领域(取曼哈顿距离)
例如：core.nearHero(6, 6, 6); // 判定主角是否身处点（6，6）的半径为6的锯齿领域
x: 领域的中心横坐标
y: 领域的中心纵坐标
n: 领域的半径，不填视为1

stepReplay: fn()
单步播放

hasSave: fn(index?: number) -> bool
判断某个存档位是否存在存档

showStartAnimate: fn(noAnimate?: bool, callback?: fn())
进入标题画面
例如：core.showStartAnimate(); // 重启游戏但不重置bgm
noAnimate: 可选，true表示不由黑屏淡入而是立即亮屏
callback: 可选，完全亮屏后的回调函数

moveViewport: fn(steps?: ?, time?: number, callback?: fn())
移动视野范围

syncLoad: fn()
从服务器加载存档

setHeroMoveInterval: fn(callback?: fn())
设置行走的效果动画

registerReplayAction: fn(name: string, func: fn(action?: string) -> bool)
注册一个录像行为
name: 自定义名称，可用于注销使用
func: 具体执行录像的函数，可为一个函数或插件中的函数名；
需要接受一个action参数，代表录像回放时的下一个操作
func返回true代表成功处理了此录像行为，false代表没有处理此录像行为。

checkAutosave: fn()
实际将自动存档写入存储

resumeBgm: fn(resumeTime?: number)
恢复背景音乐的播放
resumeTime: 从哪一秒开始恢复播放

setGameCanvasTranslate: fn(ctx: string|CanvasRenderingContext2D, x: number, y: number)
设置大地图的偏移量

checkBgm: fn()
检查bgm状态

speedDownReplay: fn()
减速播放

getRealStatus: fn(name: string)
计算主角的某个属性，包括百分比修正
例如：core.getRealStatus('atk'); // 计算主角的攻击力，包括百分比修正。战斗使用的就是这个值
name: 属性的英文名，请注意只能用于数值类属性哦，否则乘法会得到NaN

saveData: fn()
存档到本地

unregisterAnimationFrame: fn(name: string)
注销一个animationFrame

tryMoveDirectly: fn(destX: number, destY: number)
尝试瞬移，如果该点有图块/事件/阻激夹域捕则会瞬移到它旁边再走一步（不可踏入的话当然还是触发该点事件），这一步的方向优先和瞬移前主角的朝向一致
例如：core.tryMoveDirectly(6, 0); // 尝试瞬移到地图顶部的正中央，以样板0层为例，实际效果是瞬移到了上楼梯下面一格然后向上走一步并触发上楼事件
destX: 目标点的横坐标
destY: 目标点的纵坐标

moveDirectly: fn(destX?: number, destY?: number, ignoreSteps?: number)
瞬间移动
```

## enemys.js

enemys.js中定义了一系列和怪物相关的API函数。

```text
getEnemys: fn()
获得所有怪物原始数据的一个副本。
请使用core.material.enemys获得当前各项怪物属性。

getSpecials: fn() -> [[?]]
获得所有特殊属性的定义

getSpecialColor: fn(enemy: string|enemy) -> [string]
获得某个怪物所有特殊属性的颜色

getSpecialFlag: fn(enemy: string|enemy) -> number
获得某个怪物所有特殊属性的额外标记。

例如，1为全图性技能，需要进行遍历全图（光环/支援等)

getSpecialHint: fn(enemy: string|enemy, special: number) -> string
获得某种敌人的某种特殊属性的介绍
例如：core.getSpecialHint('bat', 1) // '先攻：怪物首先攻击'
enemy: 敌人id或敌人对象，用于确定属性的具体数值，否则可选
special: 属性编号，可以是该敌人没有的属性
返回值：属性的介绍，以属性名加中文冒号开头

getSpecialText: fn(enemy: string|enemy) -> [string]
获得某种敌人的全部特殊属性名称
例如：core.getSpecialText('greenSlime') // ['先攻', '3连击', '破甲', '反击']
enemy: 敌人id或敌人对象，如core.material.enemys.greenSlime
返回值：字符串数组

hasSpecial: fn(special: number|[number]|string|number, test: number) -> bool
判定某种特殊属性的有无
例如：core.hasSpecial('greenSlime', 1) // 判定绿头怪有无先攻属性
special: 敌人id或敌人对象或正整数数组或自然数
test: 待检查的属性编号


nextCriticals: fn(enemy: string|enemy, number?: number, x?: number, y?: number, floorId?: string) -> [[number]]
获得某只敌人接下来的若干个临界及其减伤，算法基于useLoop开关选择回合法或二分法
例如：core.nextCriticals('greenSlime', 9, 0, 0, 'MT0') // 绿头怪接下来的9个临界
enemy: 敌人id或敌人对象
number: 要计算的临界数量，可选，默认为1
x: 敌人的横坐标，可选
y: 敌人的纵坐标，可选
floorId: 敌人所在的地图，可选
返回：两列的二维数组，每行表示一个临界及其减伤

getDefDamage: fn(enemy: string|enemy, k?: number, x?: number, y?: number, floorId?: string) -> number
计算再加若干点防御能使某只敌人对主角的总伤害降低多少
例如：core.getDefDamage('greenSlime', 10, 0, 0, 'MT0') // 再加10点防御能使绿头怪的伤害降低多少
enemy: 敌人id或敌人对象
k: 假设主角增加的防御力，可选，默认为1
x: 敌人的横坐标，可选
y: 敌人的纵坐标，可选
floorId: 敌人所在的地图，可选

canBattle: fn(enemy: string|enemy, x?: number, y?: number, floorId?: string) -> bool
判定主角当前能否打败某只敌人
例如：core.canBattle('greenSlime',0,0,'MT0') // 能否打败主塔0层左上角的绿头怪（假设有）
enemy: 敌人id或敌人对象
x: 敌人的横坐标，可选
y: 敌人的纵坐标，可选
floorId: 敌人所在的地图，可选
返回值：true表示可以打败，false表示无法打败

getEnemyInfo: fn(enemy: string|enemy, hero?: ?, x?: number, y?: number, floorId?: string) -> {hp: number, atk: number, def: number, money: number, exp: number, special: [number], point: number, guards: [?]}
获得怪物真实属性
hero: 可选，此时的勇士属性
此函数将会计算包括坚固、模仿、光环等若干效果，将同时被怪物手册和伤害计算调用

getDamageInfo: fn(enemy: string|enemy, hero?: ?, x?: number, y?: number, floorId?: string) -> {damage: number, per_damage: number, hero_per_damage: number, init_damage: number, mon_hp: number, mon_atk: number, mon_def: number, turn: number}
获得战斗伤害信息
例如：core.getDamage('greenSlime',0,0,'MT0') // 绿头怪的总伤害
enemy: 敌人id或敌人对象
hero: 可选，此时的勇士属性
x: 敌人的横坐标，可选
y: 敌人的纵坐标，可选
floorId: 敌人所在的地图，可选
返回值：伤害计算信息，如果因为没有破防或无敌怪等其他原因无法战斗，则返回null

getDamage: fn(enemy: string|enemy, x?: number, y?: number, floorId?: string) -> number
获得某只敌人对主角的总伤害
例如：core.getDamage('greenSlime',0,0,'MT0') // 绿头怪的总伤害
enemy: 敌人id或敌人对象
x: 敌人的横坐标，可选
y: 敌人的纵坐标，可选
floorId: 敌人所在的地图，可选
返回值：总伤害，如果因为没有破防或无敌怪等其他原因无法战斗，则返回null

getDamageString: fn(enemy: string|enemy, x?: number, y?: number, floorId?: string) -> {color: string, damage: string}
获得某只敌人的地图显伤，包括颜色
例如：core.getDamageString('greenSlime', 0, 0, 'MT0') // 绿头怪的地图显伤
enemy: 敌人id或敌人对象
x: 敌人的横坐标，可选
y: 敌人的纵坐标，可选
floorId: 敌人所在的地图，可选
返回值：damage: 表示伤害值或为'???'，color: 形如'#RrGgBb'

getCurrentEnemys: fn(floorId?: string) -> [enemy]
获得某张地图的敌人集合，用于手册绘制
例如：core.getCurrentEnemys('MT0') // 主塔0层的敌人集合
floorId: 地图id，可选
返回值：敌人集合，按伤害升序排列，支持多朝向怪合并

hasEnemyLeft: fn(enemyId?: string, floorId?: string|[string]) -> bool
检查某些楼层是否还有漏打的（某种）敌人
例如：core.hasEnemyLeft('greenSlime', ['sample0', 'sample1']) // 样板0层和1层是否有漏打的绿头怪
enemyId: 敌人id，可选，null表示任意敌人
floorId: 地图id或其数组，可选，不填为当前地图
返回值：地图中是否还存在该种敌人
```

## events.js

events.js将处理所有和事件相关的操作，主要分为五个部分：
- 游戏的开始和结束
- 系统事件的处理
- 自定义事件的处理
- 点击状态栏图标所进行的操作
- 一些具体事件的执行内容


```text
afterChangeFloor: fn(floorId?: string)
转换楼层结束的事件

popEventLoc: fn()
将当前点坐标入栈

afterOpenDoor: fn(doorId?: string, x?: number, y?: number)
开一个门后触发的事件

checkLvUp: fn()
检查升级事件

insertAction: fn(action: string|?|[?], x?: number, y?: number, callback?: fn(), addToLast?: bool)
插入一段事件；此项不可插入公共事件，请用 core.insertCommonEvent
例如：core.insertAction('一段文字'); // 插入一个显示文章
action: 单个事件指令，或事件指令数组
x: 新的当前点横坐标，可选
y: 新的当前点纵坐标，可选
callback: 新的回调函数，可选
addToLast: 插入的位置，true表示插入到末尾，否则插入到开头

unfollow: fn(name?: string)
取消跟随
name: 取消跟随的行走图，不填则取消全部跟随者

hasVisitedFloor: fn(floorId?: string) -> bool
是否到达过某个楼层

startEvents: fn(list?: [?], x?: number, y?: number, callback?: fn())
开始执行一系列自定义事件

setHeroIcon: fn(name: string, noDraw?: bool)
更改主角行走图
例如：core.setHeroIcon('npc48.png', true); // 把主角从阳光变成样板0层左下角的小姐姐，但不立即刷新
name: 新的行走图文件名，可以是全塔属性中映射前的中文名。映射后会被存入core.status.hero.image
noDraw: true表示不立即刷新（刷新会导致大地图下视野重置到以主角为中心）

changingFloor: fn(floorId?: string, heroLoc?: {x: number, y: number, direction: string})
楼层转换中

setEvents: fn(list?: [?], x?: number, y?: number, callback?: fn())
直接设置事件列表

setValue: fn(name: string, operator: string, value: ?, prefix?: string)
数值操作

precompile: fn(data?: ?)
预编辑事件

vibrate: fn(time?: number, callback?: fn())
视野左右抖动
例如：core.vibrate(); // 视野左右抖动1秒
time: 抖动时长，单位为毫秒。必须为半秒的倍数，不填或小于1秒都视为1秒
callback: 抖动平息后的回调函数，可选

confirmRestart: fn()
询问是否需要重新开始

battle: fn(id: string, x?: number, y?: number, force?: bool, callback?: fn())
战斗，如果填写了坐标就会删除该点的敌人并触发战后事件
例如：core.battle('greenSlime'); // 和从天而降的绿头怪战斗（如果打得过）
id: 敌人id，必填
x: 敌人的横坐标，可选
y: 敌人的纵坐标，可选
force: true表示强制战斗，可选
callback: 回调函数，可选

follow: fn(name: string)
跟随
name: 要跟随的一个合法的4x4的行走图名称，需要在全塔属性注册

beforeBattle: fn(enemyId?: string, x?: number, y?: number) -> bool
战斗前触发的事件；返回false代表不进行战斗

registerEvent: fn(type: string, func: fn(data: ?, x?: number, y?: number, prefix?: string))
注册一个自定义事件
type: 事件类型
func: 事件的处理函数，可接受(data, x, y, prefix)参数
data为事件内容，x和y为当前点坐标（可为null），prefix为当前点前缀

flyTo: fn(toId?: string, callback?: fn()) -> bool
飞往某一层

afterGetItem: fn(id?: string, x?: number, y?: number, isGentleClick?: bool)
获得一个道具后的事件

doAction: fn(keepUI?: true)
执行下一个事件指令，常作为回调
例如：core.setCurtain([0,0,0,1], undefined, core.doAction); // 事件中的原生脚本，配合勾选“不自动执行下一个事件”来达到此改变色调只持续到下次场景切换的效果
keepUI: true表示不清除UI画布和选择光标

openBook: fn(fromUserAction?: bool)
点击怪物手册时的打开操作

save: fn(fromUserAction?: bool)
点击存档按钮时的打开操作

load: fn(fromUserAction?: bool)
点击读档按钮时的打开操作

getNextItem: fn(noRoute?: bool)
轻按获得面前的物品或周围唯一物品
noRoute: 若为true则不计入录像

hasAsync: fn() -> bool
当前是否有未处理完毕的异步事件

openEquipbox: fn(fromUserAction?: bool)
点击装备栏时的打开操作

recoverEvents: fn(data?: ?)
恢复一个事件

setGlobalFlag: fn(name: string, value: bool)
设置一个系统开关
例如：core.setGlobalFlag('steelDoorWithoutKey', true); // 使全塔的所有铁门都不再需要钥匙就能打开
name: 系统开关的英文名
value: 开关的新值，您可以用!core.flags[name]简单地表示将此开关反转

moveImage: fn(code: number, to?: [number], opacityVal?: number, time?: number, callback?: fn())
移动一张图片并/或改变其透明度
例如：core.moveImage(1, null, 0.5); // 1秒内把1号图片变为50%透明
code: 图片编号
to: 新的左上角坐标，省略表示原地改变透明度
opacityVal: 新的透明度，省略表示不变
time: 移动用时，单位为毫秒。不填视为1秒
callback: 图片移动完毕后的回调函数，可选

openSettings: fn(fromUserAction?: bool)
点击设置按钮时的操作

afterPushBox: fn()
推箱子后的事件

unregisterSystemEvent: fn(type: string)
注销一个系统事件

trigger: fn(x?: number, y?: number, callback?: fn())
触发(x,y)点的系统事件；会执行该点图块的script属性，同时支持战斗（会触发战后）、道具（会触发道具后）、楼层切换等等
callback: 执行完毕的回调函数
【异步脚本，请勿在脚本中直接调用（而是使用对应的事件），否则可能导致录像出错】

restart: fn()
重新开始游戏；此函数将回到标题页面

doEvent: fn(data?: ?, x?: number, y?: number, prefix?: string)
执行一个自定义事件

win: fn(reason?: string, norank?: bool, noexit?: bool)
游戏获胜事件

setGlobalAttribute: fn(name: string, value: string)
设置全塔属性

openToolbox: fn(fromUserAction?: bool)
点击工具栏时的打开操作

setVolume: fn(value: number, time?: number, callback?: fn())
调节bgm的音量
例如：core.setVolume(0, 100, core.jumpHero); // 0.1秒内淡出bgm，然后主角原地跳跃半秒
value: 新的音量，为0或不大于1的正数。注意系统设置中是这个值的平方根的十倍
time: 渐变用时，单位为毫秒。不填或小于100毫秒都视为0
callback: 渐变完成后的回调函数，可选

pushEventLoc: fn(x?: number, y?: number, floorId?: string) -> bool
将当前点坐标入栈

openKeyBoard: fn(fromUserAction?: bool)
点击虚拟键盘时的打开操作

insertCommonEvent: fn(name?: string, args?: [?], x?: number, y?: number, callback?: fn(), addToLast?: bool)
插入一个公共事件
例如：core.insertCommonEvent('加点事件', [3]);
name: 公共事件名；如果公共事件不存在则直接忽略
args: 参数列表，为一个数组，将依次赋值给 flag:arg1, flag:arg2, ...
x: 新的当前点横坐标，可选
y: 新的当前点纵坐标，可选
callback： 新的回调函数，可选
addToLast: 插入的位置，true表示插入到末尾，否则插入到开头

hideImage: fn(code: number, time?: number, callback?: fn())
隐藏一张图片
例如：core.hideImage(1, 1000, core.jumpHero); // 1秒内淡出1号图片，然后主角原地跳跃半秒
code: 图片编号
time: 淡出时间，单位为毫秒
callback: 图片完全消失后的回调函数，可选

visitFloor: fn(floorId?: string)
到达某楼层

openQuickShop: fn(fromUserAction?: bool)
点击快捷商店按钮时的打开操作

afterBattle: fn(enemyId?: string, x?: number, y?: number)
战斗结束后触发的事件

pushBox: fn(data?: ?)
推箱子

autoEventExecuted: fn(symbol?: string, value?: ?) -> bool
当前是否执行过某个自动事件

onSki: fn(number?: number) -> bool
当前是否在冰上

showImage: fn(code: number, image: string|image, sloc?: [number], loc?: [number], opacityVal?: number, time?: number, callback?: fn())
显示一张图片
例如：core.showImage(1, core.material.images.images['winskin.png'], [0,0,128,128], [0,0,416,416], 0.5, 1000); // 裁剪winskin.png的最左边128×128px，放大到铺满整个视野，1秒内淡入到50%透明，编号为1
code: 图片编号，为不大于50的正整数，加上100后就是对应画布层的z值，较大的会遮罩较小的，注意色调层的z值为125，UI层为140
image: 图片文件名（可以是全塔属性中映射前的中文名）或图片对象（见上面的例子）
sloc: 一行且至多四列的数组，表示从原图裁剪的左上角坐标和宽高，可选
loc: 一行且至多四列的数组，表示图片在视野中的左上角坐标和宽高，可选
opacityVal: 不透明度，为小于1的正数。不填视为1
time: 淡入时间，单位为毫秒。不填视为0
callback: 图片完全显示出来后的回调函数，可选

getItem: fn(id: string, num?: number, x?: number, y?: number, callback?: fn())
获得道具并提示，如果填写了坐标就会删除该点的该道具
例如：core.getItem('book'); // 获得敌人手册并提示
id: 道具id，必填
num: 获得的数量，不填视为1，填了就别填坐标了
x: 道具的横坐标，可选
y: 道具的纵坐标，可选
callback: 回调函数，可选

registerSystemEvent: fn(type: string, func: fn(data?: ?, callback?: fn()))
注册一个系统事件
type: 事件名
func: 为事件的处理函数，可接受(data,callback)参数

startGame: fn(hard: string, seed: number, route: string, callback?: fn())
开始新游戏
例如：core.startGame('咸鱼乱撞', 0, ''); // 开始一局咸鱼乱撞难度的新游戏，随机种子为0
hard: 难度名，会显示在左下角（横屏）或右下角（竖屏）
seed: 随机种子，相同的种子保证了录像的可重复性
route: 经由base64压缩后的录像，用于从头开始的录像回放
callback: 回调函数，可选

doSystemEvent: fn(type: string, data?: ?, callback?: fn())
执行一个系统事件

resetGame: fn(hero?: ?, hard?: ?, floorId?: string, maps?: ?, values?: ?)
初始化游戏

setFloorInfo: fn(name: string, values: ?, floorId?: string, prefix?: string)
设置一项楼层属性并刷新状态栏
例如：core.setFloorInfo('ratio', 2, 'MT0'); // 把主塔0层的血瓶和宝石变为双倍效果
name: 要修改的属性名
values: 属性的新值。
floorId: 楼层id，不填视为当前层
prefix: 独立开关前缀，一般不需要

openDoor: fn(x: number, y: number, needKey?: bool, callback?: fn())
开门（包括三种基础墙）
例如：core.openDoor(0, 0, true, core.jumpHero); // 打开左上角的门，需要钥匙，然后主角原地跳跃半秒
x: 门的横坐标
y: 门的纵坐标
needKey: true表示需要钥匙，会导致机关门打不开
callback: 门完全打开后或打不开时的回调函数，可选
【异步脚本，请勿在脚本中直接调用（而是使用对应的事件），否则可能导致录像出错】

setEnemy: fn(id: string, name: string, value: ?, prefix?: string)
设置一项敌人属性并计入存档
例如：core.setEnemy('greenSlime', 'def', 0); // 把绿头怪的防御设为0
id: 敌人id
name: 属性的英文缩写
value: 属性的新值，可选
prefix: 独立开关前缀，一般不需要，下同

autoEventExecuting: fn(symbol?: string, value?: ?) -> bool
当前是否在执行某个自动事件

checkAutoEvents: fn()
检测自动事件

showGif: fn(name?: string, x?: number, y?: number)
绘制一张动图或擦除所有动图
例如：core.showGif(); // 擦除所有动图
name: 动图文件名，可以是全塔属性中映射前的中文名
x: 动图在视野中的左上角横坐标
y: 动图在视野中的左上角纵坐标

unregisterEvent: fn(type: string)
注销一个自定义事件

jumpHero: fn(ex?: number, ey?: number, time?: number, callback?: fn())
主角跳跃，跳跃勇士。ex和ey为目标点的坐标，可以为null表示原地跳跃。time为总跳跃时间。
例如：core.jumpHero(); // 主角原地跳跃半秒
ex: 跳跃后的横坐标
ey: 跳跃后的纵坐标
time: 跳跃时长，单位为毫秒。不填视为半秒
callback: 跳跃完毕后的回调函数，可选
【异步脚本，请勿在脚本中直接调用（而是使用对应的事件），否则可能导致录像出错】

closeDoor: fn(x: number, y: number, id: string, callback?: fn())
关门，目标点必须为空地
例如：core.closeDoor(0, 0, 'yellowWall', core.jumpHero); // 在左上角关掉一堵黄墙，然后主角原地跳跃半秒
x: 横坐标
y: 纵坐标
id: 门的id，也可以用三种基础墙
callback: 门完全关上后的回调函数，可选
【异步脚本，请勿在脚本中直接调用（而是使用对应的事件），否则可能导致录像出错】

eventMoveHero: fn(steps: [step], time?: number, callback?: fn())
强制移动主角（包括后退），这个函数的作者已经看不懂这个函数了
例如：core.eventMoveHero(['forward'], 125, core.jumpHero); // 主角强制前进一步，用时1/8秒，然后主角原地跳跃半秒
steps: 步伐数组，注意后退时跟随者的行为会很难看
time: 每步的用时，单位为毫秒。0或不填则取主角的移速，如果后者也不存在就取0.1秒
callback: 移动完毕后的回调函数，可选
【异步脚本，请勿在脚本中直接调用（而是使用对应的事件），否则可能导致录像出错】

changeFloor: fn(floorId: string, stair?: string, heroLoc?: {x?: number, y?: number, direction?: string}, time?: number, callback?: fn())
场景切换
例如：core.changeFloor('MT0'); // 传送到主塔0层，主角坐标和朝向不变，黑屏时间取用户定义的值
floorId: 传送的目标地图id，可以填':before'和':after'分别表示楼下或楼上
stair: 传送的位置
heroLoc: 传送的坐标；会覆盖stair
time: 传送的黑屏时间，单位为毫秒；不填为用户设置值
callback: 传送的回调函数
【异步脚本，请勿在脚本中直接调用（而是使用对应的事件），否则可能导致录像出错】

getCommonEvent: fn(name: string) -> [?]
获得一个公共事件

lose: fn(reason?: string)
游戏失败事件

gameOver: fn(ending?: string, fromReplay?: bool, norank?: bool)
游戏结束
例如：core.gameOver(); // 游戏失败
ending: 结局名，省略表示失败
fromReplay: true表示在播放录像，可选
norank: true表示不计入榜单，可选

useFly: fn(fromUserAction?: bool)
点击楼层传送器时的打开操作

tryUseItem: fn(itemId: string)
尝试使用一个道具
例如：core.tryUseItem('pickaxe'); // 尝试使用破墙镐
itemId: 道具id，其中敌人手册、传送器和飞行器会被特殊处理
```

## map.js

maps.js负责一切和地图相关的处理内容，包括如下几个方面：	插件编写中内置了一些常用的插件。
- 地图的初始化，保存和读取，地图数组的生成	
- 是否可移动或瞬间移动的判定	
- 地图的绘制	
- 获得某个点的图块信息	
- 启用和禁用图块，改变图块	
- 移动/跳跃图块，淡入淡出图块	
- 全局动画控制，动画的绘制

```text
noPass: fn(x: number, y: number, floorId?: string) -> bool
判定某个点是否不可被踏入（不基于主角生命值和图块cannotIn属性）
例如：core.noPass(0, 0); // 判断地图左上角能否被踏入
x: 目标点的横坐标
y: 目标点的纵坐标
floorId: 目标点所在的地图id，不填视为当前地图
返回值：true表示可踏入

drawAnimate: fn(name: string, x: number, y: number, alignWindow: bool, callback?: fn()) -> number
播放动画，注意即使指定了主角的坐标也不会跟随主角移动，如有需要请使用core.drawHeroAnimate(name, callback)函数
例如：core.drawAnimate('attack', core.nextX(), core.nextY(), false, core.vibrate); // 在主角面前一格播放普攻动画，动画停止后视野左右抖动1秒
name: 动画文件名，不含后缀
x: 横坐标
y: 纵坐标
alignWindow: 是否是相对窗口的坐标
callback: 动画停止后的回调函数，可选
返回值：一个数字，可作为core.stopAnimate()的参数来立即停止播放（届时还可选择是否执行此次播放的回调函数）

drawHeroAnimate: fn(name: string, callback?: fn()) -> number
播放跟随勇士的动画
name: 动画名
callback: 动画停止后的回调函数，可选
返回值：一个数字，可作为core.stopAnimate()的参数来立即停止播放（届时还可选择是否执行此次播放的回调函数）

stopAnimate: fn(id: number, doCallback?: bool)
立刻停止一个动画播放
id: 播放动画的编号，即drawAnimate或drawHeroAnimate的返回值
doCallback: 是否执行该动画的回调函数

getBlockCls: fn(x: number, y: number, floorId?: string, showDisable?: bool) -> string
判定某个点的图块类型
例如：if(core.getBlockCls(x1, y1) != 'enemys' && core.getBlockCls(x2, y2) != 'enemy48') core.openDoor(x3, y3); // 另一个简单的机关门事件，打败或炸掉这一对不同身高的敌人就开门
x: 横坐标
y: 纵坐标
floorId: 地图id，不填视为当前地图
showDisable: 隐藏点是否不返回null，true表示不返回null
返回值：图块类型，即“地形、四帧动画、矮敌人、高敌人、道具、矮npc、高npc、自动元件、额外地形”之一

drawMap: fn(floorId?: string)
地图重绘
例如：core.drawMap(); // 重绘当前地图，常用于更改贴图或改变自动元件后的刷新
floorId: 地图id，可省略表示当前楼层
callback: 重绘完毕后的回调函数，可选

nearStair: fn() -> bool
当前位置是否在楼梯边；在楼传平面塔模式下对箭头也有效

turnBlock: fn(direction?: string, x?: number, y?: number, floorId?: string)
事件转向

getMapArray: fn(floorId?: string) -> [[number]]
生成事件层矩阵
例如：core.getMapArray('MT0'); // 生成主塔0层的事件层矩阵，隐藏的图块视为0
floorId: 地图id，不填视为当前地图
showDisable: 可选，true表示隐藏的图块也会被表示出来
返回值：事件层矩阵，注意对其阵元的访问是[y][x]

jumpBlock: fn(sx: number, sy: number, ex: number, ey: number, time?: number, keep?: bool, callback?: fn())
跳跃图块；从V2.7开始不再有音效
例如：core.jumpBlock(0, 0, 0, 0); // 令地图左上角的图块原地跳跃半秒，再花半秒淡出
sx: 起点的横坐标
sy: 起点的纵坐标
ex: 终点的横坐标
ey: 终点的纵坐标
time: 单步和淡出用时，单位为毫秒。不填视为半秒
keep: 是否不淡出，true表示不淡出
callback: 落地或淡出后的回调函数，可选

replaceBlock: fn(fromNumber: number, toNumber: number, floorId?: string|[string])
批量替换图块
例如：core.replaceBlock(21, 22, core.floorIds); // 把游戏中地上当前所有的黄钥匙都变成蓝钥匙
fromNumber: 旧图块的数字
toNumber: 新图块的数字
floorId: 地图id或其数组，不填视为当前地图

drawBlock: fn(block?: block, animate?: number)
绘制一个图块

resetMap: fn(floorId?: string|[string])
重置地图

animateSetBlock: fn(number: number|string, x: number, y: number, floorId?: string, time?: number, callback?: fn())
动画形式转变某点图块

animateSetBlocks: fn(number: number|string, locs: [?], floorId?: string, time?: number, callback?: fn())
动画形式同时转变若干点图块

compressMap: fn(mapArr: [[number]], floorId?: string) -> [[number]]
压缩地图

enemyExists: fn(x: number, y: number, id?: string, floorId?: string) -> bool
某个点是否存在（指定的）怪物

npcExists: fn(x: number, y: number, floorId?: string) -> bool
某个点是否存在NPC

getBlockByNumber: fn(number: number) -> block
根据数字获得图块

removeBlock: fn(x: number, y: number, floorId?: string)
删除一个图块，对应于「隐藏事件」并同时删除
例如：core.removeBlock(0, 0); // 尝试删除地图左上角的图块
x: 横坐标
y: 纵坐标
floorId: 地图id，不填视为当前地图

hideBlock: fn(x: number, y: number, floorId?: string)
隐藏一个图块，对应于「隐藏事件」且不删除
例如：core.hideBlock(0, 0); // 隐藏地图左上角的图块
x: 横坐标
y: 纵坐标
floorId: 地图id，不填视为当前地图

removeBlockByIndex: fn(index: number, floorId?: string)
根据block的索引删除该块

stairExists: fn(x: number, y: number, floorId?: string) -> bool
某个点是否存在楼梯

isMapBlockDisabled: fn(floorId?: string, x?: number, y?: number, flags?: ?) -> bool
某个点图块是否被强制启用或禁用

setMapBlockDisabled: fn(floorId?: string, x?: number, y?: number, disabled?: bool)
设置某个点图块的强制启用或禁用状态

decompressMap: fn(mapArr: [[number]], floorId?: string) -> [[number]]
解压缩地图

automaticRoute: fn(destX: number, destY: number) -> [{x: number, y: number, direction: string}]
自动寻路
例如：core.automaticRoute(0, 0); // 自动寻路到地图左上角
destX: 目标点的横坐标
destY: 目标点的纵坐标
返回值：每步走完后主角的loc属性组成的一维数组

resizeMap: fn(floorId?: string)
更改地图画布的尺寸

getFgNumber: fn(x: number, y: number, floorId?: string, noCache?: bool) -> number
判定某点的前景层的数字
例如：core.getFgNumber(); // 判断主角脚下的前景层图块的数字
x: 横坐标，不填为勇士坐标
y: 纵坐标，不填为勇士坐标floorId: 地图id，不填视为当前地图
noCache: 可选，true表示不使用缓存而强制重算

moveBlock: fn(x: number, y: number, steps: [string], time?: number, keep?: bool, callback?: fn())
移动图块
例如：core.moveBlock(0, 0, ['down']); // 令地图左上角的图块下移一格
x: 起点的横坐标
y: 起点的纵坐标
steps: 步伐数组
time: 单步和淡出用时，单位为毫秒。不填视为半秒
keep: 是否不淡出，true表示不淡出
callback: 移动或淡出后的回调函数，可选

getBgNumber: fn(x?: number, y?: number, floorId?: string, noCache?: bool) -> number
判定某点的背景层的数字
例如：core.getBgNumber(); // 判断主角脚下的背景层图块的数字
x: 横坐标，不填为勇士坐标
y: 纵坐标，不填为勇士坐标
floorId: 地图id，不填视为当前地图
noCache: 可选，true表示不使用缓存而强制重算

getIdOfThis: fn(id?: string) -> string
获得当前事件点的ID

searchBlock: fn(id: string, floorId?: string, showDisable?: bool) -> [{floorId: string, index: number, x: number, y: number, block: block}]
搜索图块, 支持通配符和正则表达式
例如：core.searchBlock('*Door'); // 搜索当前地图的所有门
id: 图块id，支持星号表示任意多个（0个起）字符
floorId: 地图id，不填视为当前地图
showDisable: 隐藏点是否计入，true表示计入
返回值：一个详尽的数组，一般只用到其长度

hideBgFgMap: fn(name?: string, loc?: [number]|[[number]], floorId?: string, callback?: fn())
隐藏前景/背景地图

getBlockInfo: fn(block?: number|string|block) -> blockInfo
获得某个图块或素材的信息，包括ID，cls，图片，坐标，faceIds等等

canMoveDirectlyArray: fn(locs?: [[number]])
获得某些点可否通行的信息

hideFloorImage: fn(loc?: [number]|[[number]], floorId?: string, callback?: fn())
隐藏一个楼层贴图

extractBlocks: fn(map?: [[number]], flags?: flags)
根据需求解析出blocks

getBlockId: fn(x: number, y: number, floorId?: string, showDisable?: bool) -> string
判定某个点的图块id
例如：if(core.getBlockId(x1, y1) != 'greenSlime' && core.getBlockId(x2, y2) != 'redSlime') core.openDoor(x3, y3); // 一个简单的机关门事件，打败或炸掉这一对绿头怪和红头怪就开门
x: 横坐标
y: 纵坐标
floorId: 地图id，不填视为当前地图
showDisable: 隐藏点是否不返回null，true表示不返回null
返回值：图块id，该点无图块则返回null

loadFloor: fn(floorId?: string, map?: ?)
从文件或存档中加载某个楼层

generateMovableArray: fn(floorId?: string, x?: number, y?: number, direction?: string)
可通行性判定
例如：core.generateMovableArray(); // 判断当前地图主角从各点能向何方向移动
floorId: 地图id，不填视为当前地图
x: 起点横坐标，不填视为挨个判定
y: 起点纵坐标，不填视为挨个判定
direction: 可选，必须和坐标一起使用。填写后将只检查是否可向该方向移动并返回布尔值
返回值：不设置坐标时为从各点可移动方向的三维数组，设置坐标但不设置方向时为该点可移动方向的一维数组，都设置时为布尔值

terrainExists: fn(x: number, y: number, id?: string, floorId?: string) -> bool
某个点是否存在（指定的）地形

getBlockById: fn(id: string) -> block
根据ID获得图块

drawBg: fn(floorId?: string, ctx?: CanvasRenderingContext2D)
绘制背景层（含贴图，其与背景层矩阵的绘制顺序可通过复写此函数来改变）
例如：core.drawBg(); // 绘制当前地图的背景层
floorId: 地图id，不填视为当前地图
ctx: 某画布的ctx，用于绘制缩略图，一般不需要

showBlock: fn(x: number, y: number, floorId?: string)
显示（隐藏或显示的）图块，此函数将被“显示事件”指令和勾选了“不消失”的“移动/跳跃事件”指令（如阻击怪）的终点调用
例如：core.showBlock(0, 0); // 显示地图左上角的图块
x: 横坐标
y: 纵坐标
floorId: 地图id，不填视为当前地图

getMapBlocksObj: fn(floorId?: string, showDisable?: bool)
以x,y的形式返回每个点的事件

removeGlobalAnimate: fn(x?: number, y?: number, name?: string)
删除一个或所有全局动画

drawEvents: fn(floorId?: string, blocks?: [block], ctx?: CanvasRenderingContext2D)
绘制事件层
例如：core.drawEvents(); // 绘制当前地图的事件层
floorId: 地图id，不填视为当前地图
blocks: 一般不需要
ctx: 某画布的ctx，用于绘制缩略图，一般不需要

canMoveDirectly: fn(destX: number, destY: number) -> number
能否瞬移到某点，并求出节约的步数。
例如：core.canMoveDirectly(0, 0); // 能否瞬移到地图左上角
destX: 目标点的横坐标
destY: 目标点的纵坐标
返回值：正数表示节约的步数，-1表示不可瞬移

saveMap: fn(floorId?: string)
将当前地图重新变成数字，以便于存档

drawBoxAnimate: fn()
绘制UI层的box动画

setBgFgBlock: fn(name: string, number: number|string, x: number, y: number, floorId?: string)
转变图层块
例如：core.setBgFgBlock('bg', 167, 6, 6); // 把当前地图背景层的中心块改为滑冰
name: 背景还是前景
number: 新图层块的数字（也支持纯数字字符串如'1'）或id
x: 横坐标
y: 纵坐标
floorId: 地图id，不填视为当前地图

drawFg: fn(floorId?: string, ctx?: CanvasRenderingContext2D)
绘制前景层（含贴图，其与前景层矩阵的绘制顺序可通过复写此函数来改变）
例如：core.drawFg(); // 绘制当前地图的前景层
floorId: 地图id，不填视为当前地图
ctx: 某画布的ctx，用于绘制缩略图，一般不需要

getBlock: fn(x: number, y: number, floorId?: string, showDisable?: bool) -> {index: number, block: block}
获得某个点的block

initBlock: fn(x: number, y: number, id: string|number, addInfo?: bool, eventFloor?: ?, flags?: ?) -> block
初始化一个图块

addGlobalAnimate: fn(block?: block)
添加一个全局动画

animateBlock: fn(loc?: [number]|[[number]], type?: string, time?: number, callback?: fn())
显示/隐藏某个块时的动画效果

loadMap: fn(data?: ?, floorId?: string)
将存档中的地图信息重新读取出来

setBlock: fn(number: number|string, x: number, y: number, floorId?: string)
转变图块
例如：core.setBlock(1, 0, 0); // 把地图左上角变成黄墙
number: 新图块的数字（也支持纯数字字符串如'1'）或id
x: 横坐标
y: 纵坐标
floorId: 地图id，不填视为当前地图

getFgMapArray: fn(floorId?: string, noCache?: bool) -> [[number]]
生成前景层矩阵
例如：core.getFgMapArray('MT0'); // 生成主塔0层的前景层矩阵，使用缓存
floorId: 地图id，不填视为当前地图
noCache: 可选，true表示不使用缓存
返回值：前景层矩阵，注意对其阵元的访问是[y][x]

getBgMapArray: fn(floorId?: string, noCache?: bool) -> [[number]]
生成背景层矩阵
例如：core.getBgMapArray('MT0'); // 生成主塔0层的背景层矩阵，使用缓存
floorId: 地图id，不填视为当前地图
noCache: 可选，true表示不使用缓存
返回值：背景层矩阵，注意对其阵元的访问是[y][x]

canMoveHero: fn(x?: number, y?: number, direction?: string, floorId?: string) -> bool
单点单朝向的可通行性判定；受各图层cannotInOut、起点cannotMove和canGoDeadZone影响，不受canPass和noPass影响
x: 起点横坐标，不填视为主角当前的
y: 起点纵坐标，不填视为主角当前的
direction: 移动的方向，不填视为主角面对的方向
floorId: 地图id，不填视为当前地图

drawThumbnail: fn(floorId?: string, blocks?: [block], options?: ?, toDraw?: string|CanvasRenderingContext2D|?)
绘制缩略图
例如：core.drawThumbnail(); // 绘制当前地图的缩略图
floorId: 地图id，不填视为当前地图
blocks: 一般不需要
options: 额外的绘制项，可选。可以增绘主角位置和朝向、采用不同于游戏中的主角行走图、增绘显伤、提供flags用于存读档
toDraw: 要绘制到的画布名或画布的ctx或还有其他信息，如起绘坐标、绘制大小、是否绘制全图、截取中心

hideBlockByIndex: fn(index?: number, floorId?: string)
根据图块的索引来隐藏图块

getNumberById: fn(id: string) -> number
根据图块id得到数字（地图矩阵中的值）
例如：core.getNumberById('yellowWall'); // 1
id: 图块id
返回值：图块的数字，定义在project\maps.js（请注意和project\icons.js中的“图块索引”相区分！）

removeBlockByIndexes: fn(indexes?: [number], floorId?: string)
一次性删除多个block

hideBlockByIndexes: fn(indexes?: [number], floorId?: string)
一次性隐藏多个block

generateGroundPattern: fn(floorId?: string)
生成groundPattern

showBgFgMap: fn(name?: string, loc?: [number]|[[number]], floorId?: string, callback?: fn())
显示前景/背景地图

showFloorImage: fn(loc?: [number]|[[number]], floorId?: string, callback?: fn())
显示一个楼层贴图
```

## ui.js

ui.js负责一切UI界面的绘制。主要包括三个部分：
- 设置某个画布的属性的相关API
- 具体的某个UI界面的绘制
- 动态创建画布相关的API

```text
resizeCanvas: fn(name: string, x: number, y: number)
重新设置一个自定义画布的大小

deleteCanvas: fn(name: string)
删除一个自定义画布

drawSLPanel: fn(index?: ?, refresh?: bool)
绘制存档/读档界面

drawKeyBoard: fn()
绘制虚拟键盘

drawStorageRemove: fn()
绘制存档删除页面

deleteAllCanvas: fn()
清空所有的自定义画布

drawIcon: fn(name: string|CanvasRenderingContext2D, id: string, x: number, y: number, w?: number, h?: number, frame?: number)
在某个canvas上绘制一个图标

drawFly: fn(page?: ?)
绘制楼层传送器

setOpacity: fn(name: string|CanvasRenderingContext2D, opacity: number)
设置某个canvas整体的透明度；此函数直接改变画布本身，对已经绘制的内容也生效
如果仅想对接下来的绘制生效请使用setAlpha

drawAbout: fn()
绘制“关于”界面

getTextContentHeight: fn(content: string, config?: ?)
获得某段文字的预计绘制高度；参数说明详见 drawTextContent

drawSwitchs: fn()
绘制系统设置界面

drawSyncSelect: fn()
绘制存档同步选择页面

drawArrow: fn(name: string|CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number, style?: string, lineWidth?: number)
在某个canvas上绘制一个箭头

drawReplay: fn()
绘制回放界面

strokeEllipse: fn(name: string|CanvasRenderingContext2D, x: number, y: number, a: number, b: number, angle?: number, style?: string, lineWidth?: number)
在某个canvas上绘制一个椭圆的边框

fillCircle: fn(name: string|CanvasRenderingContext2D, x: number, y: number, r: number, style?: string)
在某个canvas上绘制一个圆
参考资料：https://www.w3school.com.cn/tags/canvas_arc.asp

clearTip: fn()
清除左上角提示内容

strokeRoundRect: fn(name: string|CanvasRenderingContext2D, x: number, y: number, width: number, height: number, radius: number, style?: string, lineWidth?: number, angle?: number)
在某个canvas上绘制一个圆角矩形的边框

getContextByName: fn(canvas: string|CanvasRenderingContext2D) -> CanvasRenderingContext2D
根据画布名找到一个画布的context；支持系统画布和自定义画布。如果不存在画布返回null。
也可以传画布的context自身，则返回自己。

drawImage: fn(name: string|CanvasRenderingContext2D, image: string|image, x: number, y: number, w?: number, h?: number, x1?: number, y1?: number, w1?: number, h1?: number, angle?: number)
在一个画布上绘制图片
后面的8个坐标参数与canvas的drawImage的八个参数完全相同。
name: 可以是系统画布之一，也可以是任意自定义动态创建的画布名 画布名称或者画布的context
image: 要绘制的图片，可以是一个全塔属性中定义的图片名（会从images中去获取；支持加':x',':y',':o'翻转），图片本身，或者一个画布。
angle：旋转角度
参考资料：http://www.w3school.com.cn/html5/canvas_drawimage.asp

drawTip: fn(text: string, id?: string, frame?: number)
左上角绘制一段提示
text: 要提示的字符串，支持${}语法
id: 要绘制的图标ID
frame: 要绘制该图标的第几帧

drawBackground: fn(left: string, top: string, right: string, bottom: string, posInfo?: {px: number, py: number, direction: string})
绘制一个背景图，可绘制winskin或纯色背景；支持小箭头绘制

fillEllipse: fn(name: string|CanvasRenderingContext2D, x: number, y: number, a: number, b: number, angle?: number, style?: string)
在某个canvas上绘制一个椭圆

setFillStyle: fn(name: string|CanvasRenderingContext2D, style: string)
设置某个canvas的绘制属性（如颜色等）
参考资料：https://www.w3school.com.cn/tags/canvas_fillstyle.asp

drawText: fn(contents: string, callback?: fn())
地图中间绘制一段文字

drawConfirmBox: fn(text: string, yesCallback?: fn(), noCallback?: fn())
绘制一个确认框
此项会打断事件流，如需不打断版本的请使用core.myconfirm()
text: 要绘制的内容，支持 ${} 语法
yesCallback: 点击确认后的回调
noCallback: 点击取消后的回调

fillPolygon: fn(name: string|CanvasRenderingContext2D, nodes?: [[number]], style?: string)
在某个canvas上绘制一个多边形

drawStatistics: fn(floorIds?: string)
绘制“数据统计”界面

fillText: fn(name: string|CanvasRenderingContext2D, text: string, x: number, y: number, style?: string, font?: string, maxWidth?: number)
在某个画布上绘制一段文字
text: 要绘制的文本
style: 绘制的样式
font: 绘制的字体
最大宽度，超过此宽度会自动放缩
参考资料：https://www.w3school.com.cn/tags/canvas_filltext.asp

setTextBaseline: fn(name: string|CanvasRenderingContext2D, baseline: string)
设置某个canvas的基准线
baseline: 可为alphabetic, top, hanging, middle, ideographic, bottom
参考资料：https://www.w3school.com.cn/tags/canvas_textbaseline.asp

drawSettings: fn()
绘制系统菜单栏

loadCanvas: fn(name: string|CanvasRenderingContext2D)
加载某个canvas状态

splitLines: fn(name: string|CanvasRenderingContext2D, text: string, maxWidth?: number, font?: string)
字符串自动换行的分割；具有标点禁则功能

setAlpha: fn(name: string|CanvasRenderingContext2D, alpha: number)
设置某个canvas接下来绘制的不透明度；不会影响已经绘制的内容
如果需要修改画布本身的不透明度请使用setOpacity
参考资料：https://www.w3school.com.cn/tags/canvas_globalalpha.asp

setLineWidth: fn(name: string|CanvasRenderingContext2D, lineWidth: number)
设置某个canvas的线宽度
参考资料：https://www.w3school.com.cn/tags/canvas_linewidth.asp

drawEquipbox: fn(index?: ?)
绘制装备界面

drawTextBox: fn(content: string, showAll?: bool)
绘制一个对话框

relocateCanvas: fn(name: string, x: number, y: number)
重新定位一个自定义画布

closePanel: fn()
结束一切事件和绘制，关闭UI窗口，返回游戏进程

textImage: fn(content: string, lineHeight?: number) -> image
文本图片化

drawStatusBar: fn()
绘制状态栏

setStrokeStyle: fn(name: string|CanvasRenderingContext2D, style: string)
设置某个canvas边框属性
参考资料：https://www.w3school.com.cn/tags/canvas_strokestyle.asp

clearUI: fn()
清空UI层内容

drawWindowSkin: fn(background: string, ctx: string|CanvasRenderingContext2D, x: number, y: number, w: string, h: string, direction?: string, px?: number, py?: number)
绘制WindowSkin

drawGameInfo: fn()
绘制游戏信息界面

fillRect: fn(name: string|CanvasRenderingContext2D, text: string, x: number, y: number, style?: string, font?: string)
绘制一个矩形。style可选为绘制样式
text: 要绘制的文本
style: 绘制的样式
font: 绘制的字体
参考资料：https://www.w3school.com.cn/tags/canvas_fillrect.asp

drawScrollText: fn(content: string, time: number, lineHeight?: number, callback?: fn())
绘制滚动字幕

strokePolygon: fn(name: string|CanvasRenderingContext2D, nodes?: [[number]], style?: string, lineWidth?: number)
在某个canvas上绘制一个多边形的边框

strokeCircle: fn(name: string|CanvasRenderingContext2D, x: number, y: number, r: ?, style?: string, lineWidth?: number)
在某个canvas上绘制一个圆的边框
参考资料：https://www.w3school.com.cn/tags/canvas_arc.asp

drawLocalSaveSelect: fn()
绘制单存档界面

drawWaiting: fn(text: string)
绘制等待界面

setFont: fn(name: string|CanvasRenderingContext2D, font: string)
设置某个canvas的文字字体
参考资料：https://www.w3school.com.cn/tags/canvas_font.asp

drawChoices: fn(content?: string, choices?: [?])
绘制一个选项界面

setFontForMaxWidth: fn(name: string|CanvasRenderingContext2D, text: string, maxWidth: number, font?: ?) -> string
根据最大宽度自动缩小字体

clearMap: fn(name: string|CanvasRenderingContext2D, x?: number, y?: number, width?: number, height?: number)
清空某个画布图层
name为画布名，可以是系统画布之一，也可以是任意自定义动态创建的画布名；还可以直接传画布的context本身。
如果name也可以是'all'，若为all则为清空所有系统画布。
参考资料：https://www.w3school.com.cn/tags/canvas_clearrect.asp

drawTextContent: fn(ctx: string|CanvasRenderingContext2D, content: string, config: ?)
绘制一段文字到某个画布上面
ctx: 要绘制到的画布
content: 要绘制的内容；转义字符不允许保留 \t, \b 和 \f
config: 绘制配置项，目前暂时包含如下内容（均为可选）
left, top：起始点位置；maxWidth：单行最大宽度；color：默认颜色；align：左中右
fontSize：字体大小；lineHeight：行高；time：打字机间隔
返回值：绘制信息

calWidth: fn(name: string|CanvasRenderingContext2D, text: string, font?: string) -> number
计算某段文字的宽度
参考资料：https://www.w3school.com.cn/tags/canvas_measuretext.asp

fillArc: fn(name: string|CanvasRenderingContext2D, x: number, y: number, r: number, start: number, end: number, style?: string)
在某个canvas上绘制一个扇形
参考资料：https://www.w3school.com.cn/tags/canvas_arc.asp

drawWindowSelector: fn(background: ?, x: number, y: number, w: number, h: number)
绘制选择光标

strokeArc: fn(name: string|CanvasRenderingContext2D, x: number, y: number, r: number, start: number, end: number, style?: string, lineWidth?: number)
在某个canvas上绘制一段弧
参考资料：https://www.w3school.com.cn/tags/canvas_arc.asp

drawLine: fn(name: string|CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number, style?: string, lineWidth?: number)
在某个canvas上绘制一条线
参考资料：https://www.w3school.com.cn/tags/canvas_lineto.asp

drawPagination: fn(page?: ?, totalPage?: ?, y?: number)
绘制分页

drawBookDetail: fn(index?: ?)
绘制怪物属性的详细信息

drawToolbox: fn(index?: ?)
绘制道具栏

drawHelp: fn()
绘制帮助页面

drawQuickShop: fn()
绘制快捷商店选择栏

drawCenterFly: fn()
绘制中心对称飞行器

strokeRect: fn(name: string|CanvasRenderingContext2D, x: number, y: number, width: number, height: number, style: string)
绘制一个矩形的边框
style: 绘制的样式
参考资料：https://www.w3school.com.cn/tags/canvas_strokerect.asp

drawBook: fn(index?: ?)
绘制怪物手册

fillRoundRect: fn(name: string|CanvasRenderingContext2D, x: number, y: number, width: number, height: number, radius: number, style?: string, angle?: number)
在某个canvas上绘制一个圆角矩形

fillBoldText: fn(name: string|CanvasRenderingContext2D, text: string, x: number, y: number, style?: string, strokeStyle?: string, font?: string)
在某个画布上绘制一个描边文字
text: 要绘制的文本
style: 绘制的样式
strokeStyle: 要绘制的描边颜色
font: 绘制的字体

drawSyncSave: fn()
绘制存档同步界面

saveCanvas: fn(name: string|CanvasRenderingContext2D)
保存某个canvas状态

drawCursor: fn()
绘制键盘光标

createCanvas: fn(name: string, x: number, y: number, width: number, height: number, zIndex: number) -> CanvasRenderingContext2D
动态创建一个画布。
name： 要创建的画布名，如果已存在则会直接取用当前存在的。
x,y: 创建的画布相对窗口左上角的像素坐标
width,height: 创建的长宽。
zIndex: 创建的纵向高度（关系到画布之间的覆盖），z值高的将覆盖z值低的；系统画布的z值可在个性化中查看。
返回创建的画布的context，也可以通过core.dymCanvas[name]调用。

setTextAlign: fn(name: string|CanvasRenderingContext2D, align: string)
设置某个canvas的对齐
参考资料：https://www.w3school.com.cn/tags/canvas_textalign.asp

drawMaps: fn(index?: ?, x?: number, y?: number)
绘制浏览地图界面
```

## utils.js

utils.js是一个工具函数库，里面有各个样板中使用到的工具函数。

```text
clamp: fn(x: number, a: number, b: number) -> number
将x限定在[a,b]区间内，注意a和b可交换
例如：core.clamp(1200, 1, 1000); // 1000
x: 原始值，!x为true时x一律视为0
a: 下限值，大于b将导致与b交换
b: 上限值，小于a将导致与a交换

rand: fn(num?: number) -> number
不支持SL的随机数
例如：1 + core.rand(6); // 随机生成一个小于7的正整数，模拟骰子的效果
num: 填正数表示生成小于num的随机自然数，否则生成小于1的随机正数
返回值：随机数，即使读档也不会改变结果

clone: fn(data?: ?, filter?: fn(name: string, value: ?) -> bool, recursion?: bool)
深拷贝一个对象(函数将原样返回)
例如：core.clone(core.status.hero, (name, value) => (name == 'items' || typeof value == 'number'), false); // 深拷贝主角的属性和道具
data: 待拷贝对象
filter: 过滤器，可选，表示data为数组或对象时拷贝哪些项或属性，true表示拷贝
recursion: 过滤器是否递归，可选。true表示过滤器也被递归
返回值：拷贝的结果，注意函数将原样返回

setLocalForage: fn(key: string, value?: ?, successCallback?: fn(), errorCallback?: fn())
往数据库写入一段数据

getGlobal: fn(key: string, defaultValue?: ?)
读取一个全局存储，适用于global:xxx，支持录像。
例如：if (core.getGlobal('一周目已通关', false) === true) core.getItem('dagger'); // 二周目游戏进行到此处时会获得一把屠龙匕首
key: 全局变量名称，支持中文
defaultValue: 可选，当此全局变量不存在或值为null、undefined时，用此值代替
返回值：全局变量的值

replaceText: fn(text: string, prefix?: string) -> string
将一段文字中的${}（表达式）进行替换。
例如：core.replaceText('衬衫的价格是${status:hp}镑${item:yellowKey}便士。'); // 把主角的生命值和持有的黄钥匙数量代入这句话
text: 模板字符串，可以使用${}计算js表达式，支持“状态、物品、变量、独立开关、全局存储、图块id、图块类型、敌人数据、装备id”等量参与运算
返回值：替换完毕后的字符串

removeLocalStorage: fn(key: string)
移除本地存储

unzip: fn(blobOrUrl?: ?, success?: fn(data: ?), error?: fn(error: string), convertToText?: bool, onprogress?: fn(loaded: number, total: number))
解压一段内容

formatTime: fn(time: number) -> string
格式化时间

readFile: fn(success?: fn(data: string), error?: fn(message: string), readType?: bool)
尝试请求读取一个本地文件内容 [异步]
success: 成功后的回调
error: 失败后的回调
readType: 不设置则以文本读取，否则以DataUrl形式读取

readFileContent: fn(content: string)
文件读取完毕后的内容处理 [异步]

formatDate: fn(date: ?) -> string
格式化日期为字符串

download: fn(filename: string, content: string)
弹窗请求下载一个文本文件
例如：core.download('route.txt', JSON.stringify(core.status.route)); // 弹窗请求下载录像
filename: 文件名
content: 文件内容

encodeBase64: fn(str: string) -> string
base64加密
例如：core.encodeBase64('abcd'); // 'YWJjZA=='
str: 明文
返回值：密文

strlen: fn(str: string) -> number
求字符串的国标码字节数，也可用于等宽字体下文本的宽度测算。请注意样板的默认字体Verdana不是等宽字体
例如：core.strlen('无敌ad'); // 6
str: 待测字符串
返回值：字符串的国标码字节数，每个汉字为2，每个ASCII字符为1

myprompt: fn(hint: string, value: string, callback?: fn(data?: string))
让用户输入一段文字

getCookie: fn(name: string) -> string
访问浏览器cookie

decodeRoute: fn(route: string) -> [string]
录像解压的最后一步，即一压的逆过程
例如：core.decodeRoute(core.encodeRoute(core.status.route)); // 一压当前录像再解压-_-|
route: 录像解压倒数第二步的结果，即一压的结果
返回值：原始录像

formatDate2: fn(date: ?) -> string
格式化日期为最简字符串

unshift: fn(a: [?], b: ?) -> [?]
将b（可以是另一个数组）插入数组a的开头，此函数用于弥补a.unshift(b)中b只能是单项的不足。
例如：core.unshift(todo, {type: 'unfollow'}); // 在事件指令数组todo的开头插入“取消所有跟随者”指令
a: 原数组
b: 待插入的新首项或前缀数组
返回值：插入完毕后的新数组，它是改变原数组a本身得到的

same: fn(a?: ?, b?: ?) -> bool
判定深层相等, 会逐层比较每个元素
例如：core.same(['1', 2], ['1', 2]); // true

setTwoDigits: fn(x: number) -> string
两位数显示

splitImage: fn(image?: string|image, width?: number, height?: number) -> [image]
等比例切分一张图片
例如：core.splitImage(core.material.images.images['npc48.png'], 32, 48); // 把npc48.png切分成若干32×48px的小人
image: 图片名（支持映射前的中文名）或图片对象（参见上面的例子），获取不到时返回[]
width: 子图的宽度，单位为像素。原图总宽度必须是其倍数，不填视为32
height: 子图的高度，单位为像素。原图总高度必须是其倍数，不填视为正方形
返回值：子图组成的数组，在原图中呈先行后列，从左到右、从上到下排列。

decompress: fn(value: ?)
解压缩一个数据

showWithAnimate: fn(obj?: ?, speed?: number, callback?: fn())
动画显示某对象

subarray: fn(a?: [?], b?: [?]) -> [?]|null
判定一个数组是否为另一个数组的前缀，用于录像接续播放。请注意函数名没有大写字母
例如：core.subarray(['ad', '米库', '小精灵', '小破草', '小艾'], ['ad', '米库', '小精灵']); // ['小破草', '小艾']
a: 可能的母数组，不填或比b短将返回null
b: 可能的前缀，不填或比a长将返回null
返回值：如果b不是a的前缀将返回null，否则将返回a去掉此前缀后的剩余数组

turnDirection: fn(turn: string, direction?: string) -> string
计算应当转向某个方向
turn: 转向的方向，可为 up,down,left,right,:left,:right,:back 七种
direction: 当前方向

myconfirm: fn(hint: string, yesCallback?: fn(), noCallback?: fn())
显示确认框，类似core.drawConfirmBox()，但不打断事件流
例如：core.myconfirm('重启游戏？', core.restart); // 弹窗询问玩家是否重启游戏
hint: 弹窗的内容，支持 ${} 语法
yesCallback: 确定后的回调函数
noCallback: 取消后的回调函数，可选

calValue: fn(value: string, prefix?: string)
计算一个表达式的值，支持status:xxx等的计算。
例如：core.calValue('status:hp + status:def'); // 计算主角的生命值加防御力
value: 待求值的表达式
prefix: 独立开关前缀，一般可省略
返回值：求出的值

encodeRoute: fn(route: [string]) -> string
录像压缩缩
例如：core.encodeRoute(core.status.route); // 压缩当前录像
route: 原始录像，自定义内容（不予压缩，原样写入）必须由0-9A-Za-z和下划线、冒号组成，所以中文和数组需要用JSON.stringify预处理再base64压缩才能交由一压
返回值：一压的结果

decodeBase64: fn(str: string) -> string
base64解密
例如：core.decodeBase64('YWJjZA=='); // "abcd"
str: 密文
返回值：明文

http: fn(type: string, url: string, formData: ?, success?: fn(data: string), error?: fn(message: string), mimeType?: string, responseType?: string, onprogress?: fn(loaded: number, total: number))
发送一个HTTP请求 [异步]
type: 请求类型，只能为GET或POST
url: 目标地址
formData: 如果是POST请求则为表单数据
success: 成功后的回调
error: 失败后的回调

getLocalStorage: fn(key: string, defaultValue?: ?)
获得本地存储

arrayToRGB: fn(color: [number]) -> string
颜色数组转字符串
例如：core.arrayToRGB([102, 204, 255]); // "#66ccff"
color: 一行三列的数组，必须为不大于255的自然数
返回值：该颜色的#xxxxxx字符串表示

arrayToRGBA: fn(color: [number]) -> string
颜色数组转字符串
例如：core.arrayToRGBA([102, 204, 255, 0.3]); // "rgba(102,204,255,0.3)"
color: 一行三列或一行四列的数组，前三个元素必须为不大于255的自然数。第四个元素（如果有）必须为0或不大于1的数字，第四个元素不填视为1
返回值：该颜色的rgba(...)字符串表示

formatBigNumber: fn(x: number, onMap?: bool) -> string
大数字格式化，单位为10000的倍数（w,e,z,j,g），末尾四舍五入
例如：core.formatBigNumber(123456789, false); // "12346w"
x: 原数字
onMap: 可选，true表示用于地图显伤，结果总字符数最多为5，否则最多为6
返回值：格式化结果

removeLocalForage: fn(key: string, successCallback?: fn(), errorCallback?: fn())
移除本地数据库的数据

matchWildcard: fn(pattern: string, string: string) -> bool
通配符匹配，用于搜索图块等批量处理。
例如：core.playSound(core.matchWildcard('*Key', itemId) ? 'item.mp3' : 'door.mp3'); // 判断捡到的是钥匙还是别的道具，从而播放不同的音效
pattern: 模式串，每个星号表示任意多个（0个起）字符
string: 待测串
返回值：true表示匹配成功，false表示匹配失败

setLocalStorage: fn(key: string, value?: ?)
设置本地存储

hideWithAnimate: fn(obj?: ?, speed?: number, callback?: fn())
动画使某对象消失

copy: fn(data: string) -> bool
尝试复制一段文本到剪切板。

isset: fn(v?: ?) -> bool
判断一个值是否不为null，undefined和NaN
例如：core.isset(0/0); // false，因为0/0等于NaN
v: 待测值，可选
返回值：false表示待测值为null、undefined、NaN或未填写，true表示为其他值。

replaceValue: fn(value: string) -> string
对一个表达式中的特殊规则进行替换，如status:xxx等。
例如：core.replaceValue('status:atk+item:yellowKey'); // 把这两个冒号表达式替换为core.getStatus('hp')和core.itemCount('yellowKey')这样的函数调用
value: 模板字符串，注意独立开关不会被替换
返回值：替换完毕后的字符串

getLocalForage: fn(key: string, defaultValue?: ?, successCallback?: fn(data: ?), errorCallback?: fn())
从本地数据库读出一段数据

inArray: fn(array?: ?, element?: ?) -> bool
判定array是不是一个数组，以及element是否在该数组中。
array: 可能的数组，不为数组或不填将导致返回值为false
element: 待查找的元素
返回值：如果array为数组且具有element这项，就返回true，否则返回false

setGlobal: fn(key: string, value?: ?)
设置一个全局存储，适用于global:xxx，录像播放时将忽略此函数。
例如：core.setBlobal('一周目已通关', true); // 设置全局存储“一周目已通关”为true，方便二周目游戏中的新要素。
key: 全局变量名称，支持中文
value: 全局变量的新值，不填或null表示清除此全局存储

rand2: fn(num?: number) -> number
支持SL的随机数，并计入录像
例如：1 + core.rand2(6); // 随机生成一个小于7的正整数，模拟骰子的效果
num: 正整数，0或不填会被视为2147483648
返回值：属于 [0, num) 的随机数

setStatusBarInnerHTML: fn(name: string, value: ?, css?: string)
填写非自绘状态栏
例如：core.setStatusBarInnerHTML('hp', core.status.hero.hp, 'color: #66CCFF'); // 更新状态栏中的主角生命，使用加载画面的宣传色
name: 状态栏项的名称，如'hp', 'atk', 'def'等。必须是core.statusBar中的一个合法项
value: 要填写的内容，大数字会被格式化为至多6个字符，无中文的内容会被自动设为斜体
css: 额外的css样式，可选。如更改颜色等

matchRegex: fn(pattern: string, string: string) -> string
是否满足正则表达式

push: fn(a: [?], b: ?) -> [?]
将b（可以是另一个数组）插入数组a的末尾，此函数用于弥补a.push(b)中b只能是单项的不足。
例如：core.push(todo, {type: 'unfollow'}); // 在事件指令数组todo的末尾插入“取消所有跟随者”指令
a: 原数组
b: 待插入的新末项或后缀数组
返回值：插入完毕后的新数组，它是改变原数组a本身得到的

formatSize: fn(size: number) -> string
格式化文件大小

lzw_encode: fn(s: string) -> string
LZW压缩算法，来自https://gist.github.com/revolunet/843889

lzw_decode: fn(s: string) -> string
LZW解压算法，来自https://gist.github.com/revolunet/843889
```

## plugins.js

插件编写中内置了一些常用的插件。

```text
drawLight: fn(name: string|CanvasRenderingContext2D, color?: number, lights?: [[number]], lightDec?: number)
绘制一段灯光效果
name：必填，要绘制到的画布名；可以是一个系统画布，或者是个自定义画布；如果不存在则创建
color：可选，只能是一个0~1之间的数，为不透明度的值。不填则默认为0.9。
lights：可选，一个数组，定义了每个独立的灯光。其中每一项是三元组 [x,y,r] x和y分别为该灯光的横纵坐标，r为该灯光的半径。
lightDec：可选，0到1之间，光从多少百分比才开始衰减（在此范围内保持全亮），不设置默认为0。比如lightDec为0.5代表，每个灯光部分内圈50%的范围全亮，50%以后才开始快速衰减。
例如：core.plugin.drawLight('test', 0.2, [[25,11,46,0.1]]); // 创建一个test图层，不透明度0.2，其中在(25,11)点存在一个半径为46的灯光效果，灯光中心不透明度0.1。
core.plugin.drawLight('test2', 0.9, [[25,11,46],[105,121,88],[301,221,106]]); // 创建test2图层，且存在三个灯光效果，分别是中心(25,11)半径46，中心(105,121)半径88，中心(301,221)半径106。

openShop: fn(shopId: string, noRoute?: bool)
打开一个全局商店
shopId: 要开启的商店ID
noRoute: 打开行为是否不计入录像

isShopVisited: fn(id: string) -> bool
某个全局商店是否被访问过

listShopIds: fn() -> [string]
列出所有应当显示的快捷商店列表

canOpenShop: fn(id: string) -> bool
当前能否打开某个商店

setShopVisited: fn(id: string, visited?: bool)
设置某个商店的访问状态

canUseQuickShop: fn(id: string) -> string
当前能否使用某个快捷商店
如果返回一个字符串，则代表不能，返回的字符串作为不能的提示；返回null表示可以使用

removeMaps: fn(fromId: string, toId?: string)
删除某一些楼层；删除后不会存入存档，不可浏览地图也不可飞到。
fromId: 开始删除的楼层ID
toId: 删除到的楼层编号；可选，不填则视为fromId
例如：core.removeMaps("MT1", "MT300") 删除MT1~MT300之间的全部层
core.removeMaps("MT10") 只删除MT10层

resumeMaps: fn(fromId: string, toId?: string)
恢复某一些被删除楼层。
fromId: 开始恢复的楼层ID
toId: 恢复到的楼层编号；可选，不填则视为fromId
例如：core.resumeMaps("MT1", "MT300") 恢复MT1~MT300之间的全部层
core.resumeMaps("MT10") 只删恢复MT10层

openItemShop: fn(itemShopId: string)
打开一个道具商店
```
