api for actions & control

This commit is contained in:
oc 2019-04-02 02:38:37 +08:00
parent 075899df87
commit 9ecbd2aa42
11 changed files with 777 additions and 74 deletions

View File

@ -63,7 +63,7 @@ Elements页可以查看网页的源代码调整css布局等。
## 整体项目架构
``` bash
``` text
├── /_server/ # 为可视化地图编辑器提供一些支持的目录
├── /libs/ # ---- 系统库目录 ----
│ ├─ /thirdparty/ # 游戏所用到的第三方库文件
@ -101,11 +101,11 @@ Elements页可以查看网页的源代码调整css布局等。
└── 启动服务.exe # 一个本地的HTTP服务器通过它来运行游戏
```
`_server`为****,里面存放了地图编辑器相关的各项内容。
`_server`为**地图编辑器目录**,里面存放了地图编辑器相关的各项内容。
`libs`为**系统库目录**,里面存放了各个系统核心函数。
从V2.6开始请勿直接修改libs下的代码如有需要修改系统库函数请尝试在插件中[复写函数](#复写函数)
从V2.6开始请勿直接修改libs下的代码如有需要修改系统库函数请尝试在插件中[复写函数](#复写函数)
`project`为**项目目录**你所造的塔的数据全部存放在project下。在不同样板之间接档也是直接迁移project目录即可。
@ -167,10 +167,11 @@ core.getFlag = function (name, defaultValue) {
### 重写怪物手册的背景图绘制使用winskin而不是默认的黑色
直接重写怪物手册的背景图绘制,使用`core.drawBackground`来用winskin绘制一个背景图。
```js
// 重写ui.js中的_drawBook_drawBackground函数
core.ui._drawBook_drawBackground = function () {
// 调用core.drawBackground函数来绘制winskin
// core.__PIXEL__为定义的一个宏对于13x13的值是416对于15x15的值是480
core.drawBackground(0, 0, core.__PIXEL__, core.__PIXEL__);
}
@ -178,8 +179,10 @@ core.ui._drawBook_drawBackground = function () {
### 重写点击楼传事件
重写点击楼传事件使得点击楼传按钮时能使用一个道具比如item:fly
```js
// 重写点击楼传事件
// 重写events.js的useFly函数点击楼传按钮时的事件
core.events.useFly = function (fromUserAction) {
if (core.isMoving()) {
core.drawTip("请先停止勇士行动");
@ -192,10 +195,14 @@ core.events.useFly = function (fromUserAction) {
}
```
其他的几个按钮,如快捷商店`openQuickShop`,虚拟键盘`openKeyBoard`的重写也几乎完全一样。
### 楼层切换时根据flag来播放不同的音效
整体复制并重写整个楼传切换前的函数,将`core.playSound('floor.mp3')`替换成根据flag来判定。
```js
// 重写events.js中的_changeFloor_beforeChange修改音效值
// 复制重写events.js中的_changeFloor_beforeChange修改音效
core.events._changeFloor_beforeChange = function (info, callback) {
// 直接替换原始函数中的 core.playSound('floor.mp3');
if (core.getFlag("floorSound") == 0) core.playSound('floor0.mp3');
@ -203,7 +210,7 @@ core.events._changeFloor_beforeChange = function (info, callback) {
if (core.getFlag("floorSound") == 2) core.playSound('floor2.mp3');
// ...
// 下面是原始函数中的代码
// 下面是原始函数中的剩余代码,保持不变
window.setTimeout(function () {
if (info.time == 0)
core.events._changeFloor_changing(info, callback);
@ -245,16 +252,707 @@ core.maps.drawMap = function (floorId, callback) {
}
```
详见[`call`或`apply`的用法](https://www.jianshu.com/p/80ea0d1c04f8)。
详见[call和apply的用法](https://www.jianshu.com/p/80ea0d1c04f8)。
## 附录API列表
这里将列出所有被转发到core的API没有被转发的函数此处不会列出请自行在代码中查看。
本附录量较大如有什么需求请自行Ctrl+F进行搜索。
如有任何疑问,请联系小艾寻求帮助。
### core.js
core.js中只有很少的几个函数主要是游戏开始前的初始化等。
但是core中定义了很多游戏运行时的状态这些状态很多都会被使用到。
``` text
core.__SIZE__, core.__PIXELS__
游戏窗口大小对于13x13的游戏而言这两个值分别是13和41615x15来说分别是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.platform.extendKeyBoard (是否开启了拓展键盘)
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.experience 当前经验值
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主要是处理一些和用户交互相关的内容。
``` js
core.registerAction(action, name, func, priority)
注册一个用户交互行为。
action要注册的交互类型如 ondown, onclick, keyDown 等等。
name你的自定义名称可被注销使用同名重复注册将后者覆盖前者。
func执行函数可以是一个具体的函数体或者是一个插件中的函数名。
priority优先级优先级高的被注册项将会被执行。此项可不填默认为0。
返回如果func返回true则不会再继续执行其他的交互函数否则会继续执行其他的交互函数。
core.unregisterAction(action, name)
注销一个用户交互行为。
core.doRegisteredAction(action)
执行一个用户交互行为。
此函数将在该交互行为所注册的所有函数中,按照优先级从高到底依次执行。
此函数剩余的参数将会作为参数传入该执行函数中。
当某个执行函数返回true时将终止这一过程。
core.onkeyDown(e)
当按下某个键时的操作e为KeyboardEvent。
请勿直接覆盖或调用此函数,如有需要请注册一个"onkeyDown"的交互函数。
core.onkeyUp(e)
当放开某个键时的操作e为KeyboardEvent。
请勿直接覆盖或调用此函数,如有需要请注册一个"onkeyDown"的交互函数。
core.pressKey(keyCode)
当按住某个键不动时的操作,目前只对方向键有效。
如果需要添加对于其他键的长按请复写_sys_onkeyDown和_sys_onkeyUp。
请勿直接覆盖或调用此函数,如有需要请注册一个"pressKey"的交互函数。
core.keyDown(keyCode)
当按下某个键时的操作参数为该键的keyCode值。
请勿直接覆盖或调用此函数,如有需要请注册一个"keyDown"的交互函数。
core.keyUp(keyCode, altKey, fromReplay)
当按下某个键时的操作参数为该键的keyCode值。
altKey标志了Alt键是否同时被按下fromReplay表示是否是从录像回放中调用的。
请勿直接覆盖或调用此函数,如有需要请注册一个"keyUp"的交互函数。
core.ondown(loc)
当点击屏幕时的操作。loc为点击的信息。
请勿直接覆盖或调用此函数,如有需要请注册一个"ondown"的交互函数。
注册的ondown交互函数需要接受x, y, px, py四个参数代表点击的位置和像素坐标。
core.onmove(loc)
当在屏幕上滑动时的操作。loc为当前的坐标信息。
请勿直接覆盖或调用此函数,如有需要请注册一个"onmove"的交互函数。
注册的onmove交互函数需要接受x, y, px, py四个参数代表当前的的位置和像素坐标。
core.onup()
当从屏幕上离开时的操作。请注意此函数是没有参数的。
请勿直接覆盖或调用此函数,如有需要请注册一个"onup"的交互函数。
core.onclick(x, y)
当点击屏幕上的某点位置时执行的操作请注意这里的x和y是位置坐标。
一般而言一个完整的ondown到onup将触发一个onclick事件。
请勿直接覆盖或调用此函数,如有需要请注册一个"onclick"的交互函数。
core.onmousewheel(direct)
当滚动鼠标滑轮时执行的操作。direct为滑轮方向上为1下为-1。
请勿直接覆盖或调用此函数,如有需要请注册一个"onmousewheel"的交互函数。
core.keyDownCtrl()
当长按Ctrl键不动时执行的操作。
请勿直接覆盖或调用此函数,如有需要请注册一个"keyDownCtrl"的交互函数。
core.longClick()
当长按住屏幕时执行的操作。
请勿直接覆盖或调用此函数,如有需要请注册一个"keyDownCtrl"的交互函数。
注册的交互函数如果某一项返回true则之后仍然会继续触发该长按
如果全部返回false则将停止本次长按行为直到手指离开屏幕并重新进行长按为止。
```
### control.js
control.js将负责整个游戏的核心控制系统分为如下几个部分
- requestAnimationFrame相关
- 标题界面,开始和重新开始游戏
- 自动寻路和人物行走相关
- 画布、位置、阻激夹域、显伤等相关
- 录像的回放相关
- 存读档,自动存档,同步存档等相关
- 人物属性和状态、位置、变量等相关
- 天气、色调、音乐和音效的播放
- 状态栏和工具栏相关
- 界面resize相关
```text
// ------ requestAnimationFrame 相关 ------ //
core.registerAnimationFrame(name, needPlaying, func)
注册一个animationFrame。它将在每次浏览器的帧刷新时约16.6ms)被执行。
name你的自定义名称可被注销使用同名重复注册将后者覆盖前者。
needPlaying如果此项为true则仅在游戏开始后才会被执行标题界面不执行
func执行函数可以是一个具体的函数体或者是一个插件中的函数名。
func可以接受一个timestamp作为参数表示从整个页面加载完毕到当前时刻所经过的毫秒数。
如果func执行报错将在控制台打出一条信息并自动进行注销。
core.unregisterAnimationFrame(name)
注销一个animationFrame参数是你的上面的自定义名称。
// ------ 开始界面相关 ------ //
core.showStartAnimate(noAnimate, callback)
重置所有内容并显示游戏标题界面。
noAnimate如果为true则不会有淡入动画callback为执行完毕的回调。
core.hideStartAnimate(callback)
淡出隐藏游戏标题界面callback为执行完毕的回调。
core.isPlaying()
当前是否正在游戏中。
core.restart()
重新开始游戏。本质上就是播放标题界面的BGM并调用showStartAnimate。
core.confirmRestart()
确认用户是否需要重新开始。
core.clearStatus()
清除所有的游戏状态和数据,包括状态栏的显示。
// ------ 自动寻路、人物行走 ------ //
core.stopAutomaticRoute()
停止自动寻路的操作
core.saveAndStopAutomaticRoute()
保存剩下的寻路路线并停止自动寻路操作。主要用于打怪开门后继续寻路使用。
core.continueAutomaticRoute()
继续剩下的自动寻路操作。主要用于打怪开门后继续寻路使用。
core.clearContinueAutomaticRoute()
清空剩下的自动寻路操作。
core.setAutomaticRoute(destX, destY, stepPostfix)
尝试开始进行一个自动寻路。stepPostfix是鼠标拖动的路径。
此函数将检测是否在寻路中(在则停止或双击瞬移),检测是否点击自己(转身或轻按),
检测是否能单击瞬移,最后找寻自动寻路路线并开始寻路。
core.setAutoHeroMove(steps)
设置勇士的自动行走路线,并立刻开始行走。
core.setHeroMoveInterval(callback)
设置勇士行走动画。callback是每一步行走完毕后的回调。
core.moveOneStep(x, y)
每走完一步后执行的操作,被转发到了脚本编辑中。
core.moveAction(callback)
尝试执行单步行走。callback是执行完毕的回调。
如果勇士面对的方向是noPass的将直接触发事件并执行回调。
core.moveHero(direction, callback)
令勇士朝一个方向行走。如果设置了callback则只会行走一步并执行回调。
否则将一直朝该方向行走直到core.status.heroStop为true为止。
core.isMoving()
当前是否正在处于行走状态
core.waitHeroToStop(callback)
停止勇士的行走,等待行动结束后,再异步执行回调。
core.turnHero(direction)
转向。如果设置了direction则会转到该方向否则会右转。该函数会自动计入录像。
core.moveDirectly(destX, destY)
尝试瞬间移动到某点,被转发到了脚本编辑中。
此函数返回非负值代表成功进行瞬移,返回值是省略的步数;如果返回-1则代表没有成功瞬移。
core.tryMoveDirectly(destX, destY)
尝试单击瞬移到某点。
如果该点可被直接瞬间移动到,则直接瞬移到该点;否则尝试瞬移到相邻的上下左右点并行走一步。
core.drawHero(status, offset)
绘制勇士。
status可选为'stop','leftFoot'和'rightFoot'之一不填或null默认是'stop'。
offset可选表示具体当前格子的偏移量。不填默认为0。
此函数将重新计算地图的偏移量,调整窗口位置,绘制勇士和跟随者信息。
// ------ 画布、位置、阻激夹域、显伤 ------ //
core.setGameCanvasTranslate(canvas, x, y)
设置某个画布的偏移量
core.addGameCanvasTranslate(x, y)
加减所有系统画布ui和data除外的偏移量。主要是被“画面震动”所使用。
core.updateViewport()
根据大地图的偏移量来更新窗口的视野范围。
core.nextX(n) / core.nextY(m)
获得勇士面对的第n个位置的横纵坐标。n可不填默认为1。
core.nearHero(x, y)
判定某个点是否和勇士的距离不大于1。
core.gatherFollowers()
聚集所有的跟随者到勇士的位置。
core.updateFollowers()
更新跟随者们的坐标。
core.updateCheckBlock(floorId)
更新阻激夹域的信息,被转发到了脚本编辑中。
core.checkBlock()
检查勇士坐标点的阻激夹域信息。
core.updateDamage(floorId, ctx)
更新全地图的显伤。floorId可选默认为当前楼层。
ctx可选为画布如果不为空则将会绘制到该画布上而不是damage层上。
// ------ 录像相关 ------ //
core.chooseReplayFile()
弹出选择文件窗口,让用户选择录像文件。
core.startReplay(list)
开始播放一段录像。list为录像的操作数组。
core.triggerReplay()
播放或暂停录像实际上是pauseReplay或resumeReplay之一。
core.pauseReplay() / core.resumeReplay()
暂停和继续录像播放。
core.speedUpReplay() / core.speedDownReplay()
加速和减速录像播放。
core.setReplaySpeed(speed)
直接设置录像回放速度。
core.stopReplay(force)
停止录像回放。如果force为true则强制停止。
core.rewindReplay()
回退一个录像节点。
core.saveReplay() / core.bookReplay() / core.viewMapReplay()
回放录像时的存档、查看怪物手册、浏览地图操作。
core.isReplaying()
当前是否正在录像播放中。
core.registerReplayAction(name, func)
注册一个自定义的录像行为。
name自定义名称可用户注销使用。
func具体执行录像的函数是一个函数体或者插件中的函数名。
func需要接受action参数代表录像回放时的当前操作行为。
如果func返回true则代表成功处理了此次操作返回false代表没有进行处理。
请注意回放录像时的二次记录问题(即回放时录像会重新记录路线)。
core.unregisterReplayAction(name)
注销一个录像行为。此函数一般不应当被使用。
// ------ 存读档相关 ------ //
core.autosave(remoreLast)
进行一个自动存档,实际上是加入到缓存之中。
removeLast如果为true则会从路线中删除最后一项再存打怪开门前的状态
在事件处理中不允许调用本函数,如有需要请呼出存档页面。
core.checkAutosave()
将缓存的自动存档写入存储中。平均每五秒钟,或在窗口失去焦点时被执行。
core.doSL(id, type)
实际执行一个存读档事件。id为存档编号自动存档为'autoSave'。
type只能为'save', 'load', 'replayLoad'之一,代表存档、读档和从存档回放录像。
core.syncSave(type) / core.syncLoad()
向服务器同步存档从服务器加载存档。type如果为'all'则会向服务器同步所有存档。
core.saveData()
获得要存档的内容,实际转发到了脚本编辑中。
core.loadData(data, callback)
实际执行一次读档行为data为读取到的数据callback为执行完毕的回调。
实际转发到了脚本编辑中。
core.getSave(index, callback)
获得某个存档位的存档。index为存档编号0代表自动存档。
core.getSaves(ids, callback)
获得若干个存档位的存档。ids为一个存档编号数组0代表自动存档。
core.getAllSaves(callback)
获得全部的存档内容。目前仅被同步全部存档和下载全部存档所调用。
core.getSaveIndexes(callback)
刷新全部的存档信息将哪些档位有存档的记录到core.saves.ids中。
core.hasSave(index)
判定某个存档位是否存在存档。index为存档编号0代表自动存档。
core.removeSave(index)
删除某个存档。index为存档编号0代表自动存档。
// ------ 属性、状态、位置、变量等 ------ //
core.setStatus(name, value)
设置勇士当前的某个属性。
core.addStatus(name, value)
加减勇士当前的某个属性。等价于 core.setStatus(name, core.getStatus(name) + value)
core.getStatus(name)
获得勇士的某个原始属性值。
core.getStatusOrDefault(status, name)
尝试从status中获得某个原始属性值如果status为null或不存在对应属性值则从勇士属性中获取。
此项在伤害计算函数中使用较多例如传递新的攻击和防御来计算临界和1防减伤。
core.getRealStatus(name)
获得勇士的某个计算属性值。该属性值是在加成buff之后得到的。
该函数等价于 core.getStatus(name) * core.getBuff(name)
core.getRealStatusOrDefault(status, name)
尝试从status中获得某个原始属性值再进行增幅如果不存在则获取勇士本身的计算属性值。
core.setBuff(name, value)
设置勇士的某个属性的增幅值。value为1代表无增幅。
core.addBuff(name, value)
增减勇士的某个属性的增幅值。等价于 core.setBuff(name, core.getBuff(name) + value)
core.getBuff(name)
获得勇士的某个属性的增幅值。默认值是1。
core.setHeroLoc(name, value, noGather)
设置勇士位置属性。name只能为'x', 'y'和'direction'之一。
如果noGather为true则不会聚集所有的跟随者。
core.getHeroLoc(name)
获得勇士的某个位置属性。如果name为null则直接返回core.status.hero.loc。
core.getLvName(lv)
获得某个等级对应的名称其在全塔属性的levelUp中定义。如果不存在则返回原始数值。
core.setFlag(name, value)
设置某个自定义变量或flag。如果value为null则会调用core.removeFlag进行删除。
core.addFlag(name, value)
加减某个自定义的变量或flag。等价于 core.setFlag(name, core.getFlag(name, 0) + value)
core.getFlag(name, defaultValue)
获得某个自定义的变量或flag。如果该flag不存在从未赋值过则返回defaultValue值。
core.hasFlag(name)
判定是否拥有某个自定义变量或flag。等价于 !!core.getFlag(name, 0)
core.removeFlag(name)
删除一个自定义变量或flag。
core.lockControl() / core.unlockControl()
锁定和解锁控制。常常应用于事件处理。
core.debug()
开启调试模式。此模式下可以按住Ctrl进行穿墙。
// ------ 天气,色调,音乐和音效 ------ //
core.setWeather(type, level)
设置当前的天气。type只能为'rain', 'snow'或'fog'level为1-10之间代表强度信息。
core.setCurtain(color, time, callback)
更改画面色调。color为更改到的色调是个三元或四元组time为渐变时间0代表立刻切换。
core.screenFlash(color, time, times, callback)
画面闪烁。color为色调三元或四元组time为单次闪烁时间times为总闪烁次数。
core.playBgm(bgm, startTime)
播放一个bgm。startTime可以控制开始时间不填默认为0。
如果bgm不存在、不被支持或当前不允许播放背景音乐则会跳过。
core.pauseBgm() / core.resumeBgm()
暂停和恢复当前bgm的播放。
core.triggerBgm()
更改当前bgm的播放状态。
core.playSound(sound) / core.stopSound()
播放一个音效,停止全部音效。
如果sound不存在、不被支持或当前不允许播放音效则会忽略。
core.checkBgm()
检查bgm的状态。
有的时候刚打开页面时浏览器是不允许自动播放标题界面bgm的一定要经过一次用户操作行为。
这时候我们可以给开始按钮增加core.checkBgm(),如果之前没有成功播放则重新播放。
// ------ 状态栏和工具栏相关 ------ //
core.clearStatusBar()
清空状态栏的数据。
core.updateStatusBar()
更新状态栏,被转发到了脚本编辑中。此函数还会根据是否在回放来设置工具栏的图标。
core.showStatusBar() / core.hideStatusBar(showToolbox)
显示和隐藏状态栏。
如果showToolbox为true则在竖屏模式下不隐藏工具栏方便手机存读档操作。
core.updateHeroIcon()
更新状态栏上的勇士图标。
core.updateGlobalAttribute()
更新全局属性,例如状态栏的背景图等。
core.setToolbarButton(useButtom)
设置工具栏是否是拓展键盘。
// ------ resize 相关 ------ //
core.registerResize(name, func)
注册一个resize函数。
name为自定义名称可供注销使用。
func可以是一个函数或插件中的函数名可以接受一个obj作为参数。
具体详见resize函数。
core.unregisterResize(name)
注销一个resize函数。
core.resize()
屏幕分辨率改变后的重新自适应。
此函数将根据当前的屏幕分辨率信息生成一个obj并传入各个注册好的resize函数中执行。
```
### enemys.js
### events.js

View File

@ -912,7 +912,7 @@ time为可选的指定的话将作为楼层切换动画的时间。
**如果time指定为小于100则视为没有楼层切换动画。**
### changePos当前位置切换/勇士转向
### changePos当前位置切换/set勇士转向
有时候我们不想要楼层切换的动画效果而是直接让勇士从A点到B点。
@ -1126,15 +1126,15 @@ time为总移动的时间。
async可选如果为true则会异步执行即不等待当前事件执行完毕立刻执行下一个事件
### setFg:更改画面色调
### setCurtain:更改画面色调
我们可以使用 `{"type": "setFg"}` 来更改画面色调。
我们可以使用 `{"type": "setCurtain"}` 来更改画面色调。
``` js
[
{"type": "setFg", "color": [255,255,255,0.6], "time": 1000}, // 更改画面色调为纯白不透明度0.6动画时间1000毫秒
{"type": "setFg", "color": [0,0,0], "async": true}, // 更改画面色调为纯黑不透明度1不指定动画时间使用默认时间且异步执行
{"type": "setFg"} // 如果不指定color则恢复原样。
{"type": "setCurtain", "color": [255,255,255,0.6], "time": 1000}, // 更改画面色调为纯白不透明度0.6动画时间1000毫秒
{"type": "setCurtain", "color": [0,0,0], "async": true}, // 更改画面色调为纯黑不透明度1不指定动画时间使用默认时间且异步执行
{"type": "setCurtain"} // 如果不指定color则恢复原样。
]
```

View File

@ -346,7 +346,7 @@ function (enemy, hero_hp, hero_atk, hero_def, hero_mdef, x, y, floorId) {
"canUseItemEffect": "true" // 任何时候可用
```
除了覆盖楼传事件外,对于快捷商店、虚拟键盘等等也可以进行覆盖,只不过是仿照上述代码重写对应的函数(`openQuickShop`,`openKeyboard`)即可。
除了覆盖楼传事件外,对于快捷商店、虚拟键盘等等也可以进行覆盖,只不过是仿照上述代码重写对应的函数(`openQuickShop`,`openKeyBoard`)即可。
## 自定义怪物属性

View File

@ -305,8 +305,8 @@ action
| moveImage_s
| showGif_0_s
| showGif_1_s
| setFg_0_s
| setFg_1_s
| setCurtain_0_s
| setCurtain_1_s
| screenFlash_s
| setWeather_s
| move_s
@ -1277,35 +1277,35 @@ var code = '{"type": "moveImage", "code": '+Int_0+toloc+EvalString_0+',"time": '
return code;
*/;
setFg_0_s
setCurtain_0_s
: '更改画面色调' EvalString Colour '动画时间' Int? '不等待执行完毕' Bool Newline
/* setFg_0_s
tooltip : setFg: 更改画面色调,动画时间可不填
helpUrl : https://h5mota.com/games/template/docs/#/event?id=setfg%EF%BC%9A%E6%9B%B4%E6%94%B9%E7%94%BB%E9%9D%A2%E8%89%B2%E8%B0%83
/* setCurtain_0_s
tooltip : setCurtain: 更改画面色调,动画时间可不填
helpUrl : https://h5mota.com/games/template/docs/#/event?id=setcurtain%EF%BC%9A%E6%9B%B4%E6%94%B9%E7%94%BB%E9%9D%A2%E8%89%B2%E8%B0%83
default : ["255,255,255,1",'rgba(255,255,255,1)',500,false]
colour : this.soundColor
var colorRe = /^(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(,0(\.\d+)?|,1)?$/;
if (!colorRe.test(EvalString_0))throw new Error('颜色格式错误,形如:0~255,0~255,0~255,0~1');
Int_0 = Int_0!=='' ?(', "time": '+Int_0):'';
var async = Bool_0?', "async": true':'';
var code = '{"type": "setFg", "color": ['+EvalString_0+']'+Int_0 +async+'},\n';
var code = '{"type": "setCurtain", "color": ['+EvalString_0+']'+Int_0 +async+'},\n';
return code;
*/;
setFg_1_s
setCurtain_1_s
: '恢复画面色调' '动画时间' Int? '不等待执行完毕' Bool Newline
/* setFg_1_s
tooltip : setFg: 恢复画面色调,动画时间可不填
helpUrl : https://h5mota.com/games/template/docs/#/event?id=setfg%EF%BC%9A%E6%9B%B4%E6%94%B9%E7%94%BB%E9%9D%A2%E8%89%B2%E8%B0%83
/* setCurtain_1_s
tooltip : setCurtain: 恢复画面色调,动画时间可不填
helpUrl : https://h5mota.com/games/template/docs/#/event?id=setcurtain%EF%BC%9A%E6%9B%B4%E6%94%B9%E7%94%BB%E9%9D%A2%E8%89%B2%E8%B0%83
default : [500,false]
colour : this.soundColor
Int_0 = Int_0!=='' ?(', "time": '+Int_0):'';
var async = Bool_0?', "async": true':'';
var code = '{"type": "setFg"'+Int_0 +async+'},\n';
var code = '{"type": "setCurtain"'+Int_0 +async+'},\n';
return code;
*/;
@ -2433,11 +2433,12 @@ ActionParser.prototype.parseAction = function() {
}
break;
case "setFg": // 颜色渐变
case "setCurtain":
if(this.isset(data.color)){
this.next = MotaActionBlocks['setFg_0_s'].xmlText([
this.next = MotaActionBlocks['setCurtain_0_s'].xmlText([
data.color,'rgba('+data.color+')',data.time||0,data.async||false,this.next]);
} else {
this.next = MotaActionBlocks['setFg_1_s'].xmlText([
this.next = MotaActionBlocks['setCurtain_1_s'].xmlText([
data.time||0,data.async||false,this.next]);
}
break;

View File

@ -141,8 +141,8 @@ editor_blockly = function () {
MotaActionBlocks['animate_s'].xmlText(),
MotaActionBlocks['showStatusBar_s'].xmlText(),
MotaActionBlocks['hideStatusBar_s'].xmlText(),
MotaActionBlocks['setFg_0_s'].xmlText(),
MotaActionBlocks['setFg_1_s'].xmlText(),
MotaActionBlocks['setCurtain_0_s'].xmlText(),
MotaActionBlocks['setCurtain_1_s'].xmlText(),
MotaActionBlocks['screenFlash_s'].xmlText(),
MotaActionBlocks['setWeather_s'].xmlText(),
MotaActionBlocks['playBgm_s'].xmlText(),

View File

@ -105,7 +105,7 @@ actions.prototype.doRegisteredAction = function (action) {
return false;
}
actions.prototype.checkReplaying = function () {
actions.prototype._checkReplaying = function () {
if (core.isReplaying() && core.status.event.id != 'save'
&& (core.status.event.id || "").indexOf('book') != 0 && core.status.event.id != 'viewMaps')
return true;
@ -114,7 +114,7 @@ actions.prototype.checkReplaying = function () {
////// 检查是否在录像播放中,如果是,则停止交互
actions.prototype._sys_checkReplay = function () {
if (this.checkReplaying()) return true;
if (this._checkReplaying()) return true;
}
////// 按下某个键时 //////
@ -145,7 +145,7 @@ actions.prototype.onkeyUp = function (e) {
}
actions.prototype._sys_onkeyUp_replay = function (e) {
if (this.checkReplaying()) {
if (this._checkReplaying()) {
if (e.keyCode == 27) // ESCAPE
core.stopReplay();
else if (e.keyCode == 90) // Z
@ -286,7 +286,7 @@ actions.prototype.keyUp = function (keyCode, altKey, fromReplay) {
}
actions.prototype._sys_keyUp_replay = function (keyCode, altKey, fromReplay) {
if (!fromReplay && this.checkReplaying()) return true;
if (!fromReplay && this._checkReplaying()) return true;
}
actions.prototype._sys_keyUp_lockControl = function (keyCode, altKey) {
@ -389,7 +389,7 @@ actions.prototype._sys_keyUp = function (keyCode, altKey) {
if (core.status.automaticRoute && core.status.automaticRoute.autoHeroMove) {
core.stopAutomaticRoute();
}
core.stopHero();
core.status.heroStop = true;
return true;
}
@ -539,8 +539,8 @@ actions.prototype._sys_onup = function () {
return true;
}
////// 获得点击事件相对左上角的坐标0到12之间 //////
actions.prototype.getClickLoc = function (x, y) {
////// 获得点击事件相对左上角的坐标 //////
actions.prototype._getClickLoc = function (x, y) {
var statusBar = {'x': 0, 'y': 0};
var size = 32;
@ -663,7 +663,7 @@ actions.prototype.onmousewheel = function (direct) {
actions.prototype._sys_onmousewheel = function (direct) {
// 向下滚动是 -1 ,向上是 1
if (this.checkReplaying()) {
if (this._checkReplaying()) {
// 滚轮控制速度
if (direct == 1) core.speedUpReplay();
if (direct == -1) core.speedDownReplay();
@ -2065,7 +2065,7 @@ actions.prototype._clickLocalSaveSelect = function (x, y) {
var selection = y - topIndex;
core.status.event.selection = selection;
if (selection < 2) {
core.getAllSaves(selection == 0 ? null : core.saves.saveIndex, function (saves) {
var callback = function (saves) {
if (saves) {
var content = {
"name": core.firstData.name,
@ -2074,7 +2074,9 @@ actions.prototype._clickLocalSaveSelect = function (x, y) {
}
core.download(core.firstData.name + "_" + core.formatDate2(new Date()) + ".h5save", JSON.stringify(content));
}
})
};
if (selection == 0) core.getAllSaves(callback);
else core.getSave(core.saves.saveIndex, callback);
}
core.status.event.selection = 2;

View File

@ -371,7 +371,6 @@ control.prototype.confirmRestart = function (fromSettings) {
});
}
////// 清除游戏状态和数据 //////
control.prototype.clearStatus = function() {
// 停止各个Timeout和Interval
@ -424,7 +423,7 @@ control.prototype.stopAutomaticRoute = function () {
core.status.automaticRoute.destX=null;
core.status.automaticRoute.destY=null;
core.status.automaticRoute.lastDirection = null;
core.stopHero();
core.status.heroStop = true;
if (core.status.automaticRoute.moveStepBeforeStop.length==0)
core.deleteCanvas('route');
}
@ -751,11 +750,6 @@ control.prototype.waitHeroToStop = function(callback) {
}
}
////// 停止勇士的移动状态 //////
control.prototype.stopHero = function () {
core.status.heroStop = true;
}
////// 转向 //////
control.prototype.turnHero = function(direction) {
if (direction) {
@ -1274,7 +1268,12 @@ control.prototype._doReplayAction = function (action) {
control.prototype._replay_finished = function () {
core.status.replay.replaying = false;
core.status.event.selection = 0;
core.ui.drawConfirmBox("录像播放完毕,你想退出播放吗?", function () {
var str = "录像播放完毕,你想退出播放吗?";
if (core.status.route.length != core.status.replay.totalList.length
|| core.subarray(core.status.route, core.status.replay.totalList) == null) {
str = "录像播放完毕,但记录不一致。\n请检查录像播放时的二次记录问题。\n你想退出播放吗";
}
core.ui.drawConfirmBox(str, function () {
core.ui.closePanel();
core.stopReplay(true);
}, function () {
@ -1462,6 +1461,7 @@ control.prototype._replayAction_moveDirectly = function (action) {
// 忽略连续的瞬移事件
while (core.status.replay.toReplay.length>0 &&
core.status.replay.toReplay[0].indexOf('move:')==0) {
core.status.route.push(action);
action = core.status.replay.toReplay.shift();
}
@ -1617,13 +1617,15 @@ control.prototype._doSL_replayLoad_afterGet = function (id, data) {
////// 同步存档到服务器 //////
control.prototype.syncSave = function (type) {
core.ui.drawWaiting("正在同步,请稍后...");
core.getAllSaves(type=='all'?null:core.saves.saveIndex, function (saves) {
if (!saves) return core.drawText("没有要同步的存档");
var callback = function (saves) {
core.control._syncSave_http(type, saves);
})
}
if (type == 'all') core.getAllSaves(callback);
else core.getSave(core.saves.saveIndex, callback);
}
control.prototype._syncSave_http = function (type, saves) {
if (!saves) return core.drawText("没有要同步的存档");
var formData = new FormData();
formData.append('type', 'save');
formData.append('name', core.firstData.name);
@ -1748,8 +1750,7 @@ control.prototype.getSaves = function (ids, callback) {
}
}
control.prototype.getAllSaves = function (id, callback) {
if (id != null) return this.getSave(id, callback);
control.prototype.getAllSaves = function (callback) {
var ids = Object.keys(core.saves.ids).filter(function(x){return x!=0;})
.sort(function(a,b) {return a-b;}), saves = [];
this.getSaves(ids, function (data) {
@ -1792,7 +1793,7 @@ control.prototype.hasSave = function (index) {
return core.saves.ids[index] || false;
}
////// 删除一个或多个存档
////// 删除个存档
control.prototype.removeSave = function (index, callback) {
if (index == 0 || index == "autoSave") {
index = "autoSave";
@ -1827,8 +1828,6 @@ control.prototype._updateFavoriteSaves = function () {
core.setLocalStorage("favoriteName", core.saves.favoriteName);
}
////// 加载某个存档
// ------ 属性状态位置buff变量锁定控制等 ------ //
////// 设置勇士属性 //////
@ -2019,7 +2018,7 @@ control.prototype._setWeather_createNodes = function (type, level) {
}
////// 更改画面色调 //////
control.prototype.setFg = function(color, time, callback) {
control.prototype.setCurtain = function(color, time, callback) {
if (time == null) time=750;
if (time<=0) time=0;
if (!core.status.curtainColor)
@ -2037,10 +2036,10 @@ control.prototype.setFg = function(color, time, callback) {
return;
}
this._setFg_animate(core.status.curtainColor, color, time, callback);
this._setCurtain_animate(core.status.curtainColor, color, time, callback);
}
control.prototype._setFg_animate = function (nowColor, color, time, callback) {
control.prototype._setCurtain_animate = function (nowColor, color, time, callback) {
var per_time = 10, step = parseInt(time / per_time);
var animate = setInterval(function() {
nowColor = [
@ -2068,8 +2067,8 @@ control.prototype.screenFlash = function (color, time, times, callback) {
times = times || 1;
time = time / 3;
var nowColor = core.clone(core.status.curtainColor);
core.setFg(color, time, function() {
core.setFg(nowColor, time * 2, function() {
core.setCurtain(color, time, function() {
core.setCurtain(nowColor, time * 2, function() {
if (times > 1)
core.screenFlash(color, time * 3, times - 1, callback);
else {
@ -2381,7 +2380,7 @@ control.prototype.updateGlobalAttribute = function (name) {
}
}
////// 改变工具栏为按钮1-7 //////
////// 改变工具栏为按钮1-8 //////
control.prototype.setToolbarButton = function (useButton) {
if (!core.domStyle.showStatusBar) {
// 隐藏状态栏时检查竖屏

View File

@ -16,8 +16,7 @@ function core() {
'ground': null,
'items': {},
'enemys': {},
'icons': {},
'events': {}
'icons': {}
}
this.timeout = {
'tipTimeout': null,
@ -84,8 +83,8 @@ function core() {
this.domStyle = {
scale: 1.0,
isVertical: false,
toolbarBtn: false,
showStatusBar: true,
toolbarBtn: false,
}
this.bigmap = {
canvas: ["bg", "event", "event2", "fg", "damage"],

View File

@ -1068,13 +1068,17 @@ events.prototype._action_moveImage = function (data, x, y, prefix) {
}
events.prototype._action_setFg = function (data, x, y, prefix) {
return this._action_setCurtain(data, x, y, prefix);
}
events.prototype._action_setCurtain = function (data, x, y, prefix) {
if (data.async) {
core.setFg(data.color, data.time);
core.setCurtain(data.color, data.time);
core.setFlag('__color__', data.color || null);
core.doAction();
}
else {
core.setFg(data.color, data.time, function () {
core.setCurtain(data.color, data.time, function () {
core.setFlag('__color__', data.color || null);
core.doAction();
});

View File

@ -364,7 +364,7 @@ main.dom.body.onselectstart = function () {
main.dom.data.onmousedown = function (e) {
try {
e.stopPropagation();
var loc = main.core.getClickLoc(e.clientX, e.clientY);
var loc = main.core.actions._getClickLoc(e.clientX, e.clientY);
if (loc == null) return;
main.core.ondown(loc);
} catch (ee) { main.log(ee); }
@ -374,7 +374,7 @@ main.dom.data.onmousedown = function (e) {
main.dom.data.onmousemove = function (e) {
try {
e.stopPropagation();
var loc = main.core.getClickLoc(e.clientX, e.clientY);
var loc = main.core.actions._getClickLoc(e.clientX, e.clientY);
if (loc == null) return;
main.core.onmove(loc);
}catch (ee) { main.log(ee); }
@ -401,7 +401,7 @@ main.dom.data.onmousewheel = function(e) {
main.dom.data.ontouchstart = function (e) {
try {
e.preventDefault();
var loc = main.core.getClickLoc(e.targetTouches[0].clientX, e.targetTouches[0].clientY);
var loc = main.core.actions._getClickLoc(e.targetTouches[0].clientX, e.targetTouches[0].clientY);
if (loc == null) return;
main.core.ondown(loc);
}catch (ee) { main.log(ee); }
@ -411,7 +411,7 @@ main.dom.data.ontouchstart = function (e) {
main.dom.data.ontouchmove = function (e) {
try {
e.preventDefault();
var loc = main.core.getClickLoc(e.targetTouches[0].clientX, e.targetTouches[0].clientY);
var loc = main.core.actions._getClickLoc(e.targetTouches[0].clientX, e.targetTouches[0].clientY);
if (loc == null) return;
main.core.onmove(loc);
}catch (ee) { main.log(ee); }

View File

@ -151,7 +151,7 @@ main.floors.sample1=
"type": "hide"
},
{
"type": "setFg",
"type": "setCurtain",
"color": [
0,
0,
@ -184,7 +184,7 @@ main.floors.sample1=
"2,11": [
"\t[杰克,thief]喂!醒醒!快醒醒!",
{
"type": "setFg",
"type": "setCurtain",
"time": 1500
},
"\t[hero]额,我这是在什么地方?",