diff --git a/_docs/element.md b/_docs/element.md index 30ddded8..3b622883 100644 --- a/_docs/element.md +++ b/_docs/element.md @@ -1,6 +1,5 @@ # 元件说明 - -?> 目前版本**v2.6.6**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.7**,上次更新时间:* {docsify-updated} * 在本章中,将对样板里的各个元件进行说明。各个元件主要包括道具、门、怪物、楼梯等等。 @@ -9,29 +8,22 @@ ![生成地图](./img/sample0.png) ## 道具 - -本塔目前支持的所有道具列表在样板0层中已全部给出。当你在样板0层中拿到某个宝物时会有提示,这里不再赘述,详见拿到该道具的说明。 +样板自带的所有道具在样板0层中已全部给出。当你在样板0层中拿到某个宝物时会有提示,这里不再赘述,详见拿到该道具的说明。 大多数宝物都有默认的效果,屠龙匕首暂未定义,如有自己的需求可参见[自定义道具效果](personalization#自定义道具效果)。 拿到道具后将触发`afterGetItem`事件,有关事件的详细介绍请参见[事件](event)。 如需修改某个道具的效果,在不同区域宝石数据发生变化等问题,请参见[自定义道具效果](personalization#自定义道具效果)的说明。 - -**有关轻按,在data.js的系统变量中有定义。如果`enableGentleClick`为true,则鼠标(触摸屏)通过双击勇士,键盘通过空格可达到轻按效果,即不向前移动而获得前方物品。** - +
**有关轻按,在全塔属性的系统开关中有定义。如果勾选了 `enableGentleClick` ,则鼠标(触摸屏)通过双击勇士,键盘通过空格,手机通过虚拟数字键 7 可达到轻按效果,即不移动而获得周围物品。** ## 装备 - -如果需要让剑盾等变成装备,可以直接在`data.js`中设置`'equipment': true`即可。 - +如果需要让剑盾等变成装备,可以直接在它们的图块属性中把 `cls` 一项改为 `equips` 。
从V2.4.1开始,HTML5魔塔样板终于拥有了属于自己的装备页面。 ### 装备栏的设置,装备类型 在全塔属性中,有一个`equipName`项,其定义了本塔的所有可装备的装备栏。 - -其需要是一个不小于1且不大于6的数组,其中每一项为装备栏的名称,**建议是两个汉字**。 - +
其需要是一个长度为正数且不大于 6 ( 15×15 样板为不大于 8 )的一维数组,其中每一项为装备栏的名称,**建议是两个汉字**。
例如下面这种写法就是定义了四个装备孔,名称分别为武器、防御、首饰和魔杖。 ``` js @@ -47,9 +39,8 @@ 如果要将一个道具设置为装备,首先需要将其`cls`设为`equips`。 然后在图块属性的`equip`一项中设置装备的具体属性。该项写法如下: - -``` js -{"type": 0, "atk": 0, "def": 0, "mdef":0, "animate": "hand", "percentage": true} +``` json +{"type": 0, "atk": 0, "def": 0, "mdef": 0, "animate": "hand", "percentage": true} ``` type为该装备的类型,必填,和上面装备栏一一对应。例如,0就是武器,2就是首饰等等。 @@ -63,8 +54,7 @@ animate为该装备的攻击动画,仅对type为0时有效。具体可参见[ percentage为该装备是否按比例增加属性。 下面是几个写法例子。 - -``` js +``` json {"type": 0, "atk": 10} // 装备类型是武器,效果是攻击+10,使用默认的攻击动画 {"type": 0, "atk": 40, "animate": "sword"} // 装备类型为武器,效果是攻击+10,攻击动画是sword {"type": 1, "def": 40, "percentage": true} // 装备类型是防具,效果是防御提升40% @@ -75,8 +65,8 @@ percentage为该装备是否按比例增加属性。 所有取值全部向下取整。 -值得注意的是,如果多个装备同时按比例增加属性,使用加法计算。比如武器增加30%攻击,防具增加10%攻击,最终合起来增加的是40%而不是43%的属性。 - +值得注意的是,如果多个装备同时按比例增加属性,使用加法计算。比如武器增加30%攻击,防具增加10%攻击,最终合起来增加的是40%而不是43%的属性。
+如果某件装备需要按常数增加一种属性但按百分比增加另一种属性,请参考[插件库](https://h5mota.com/plugins/) ### 检测是否存在装备 可以使用`core.hasEquip(itemId)`来检测是否装上某个装备。 @@ -92,9 +82,7 @@ percentage为该装备是否按比例增加属性。 从V2.5.4开始,允许支持多重装备,即有若干的装备可共用若干的格子(例如永不复还那样)。 要实现这一点,上面的写法有所改变。 - -在全塔属性中的`equipName`项写法不变,不过可以写重复的装备孔名称。(但仍然最多只能写6个) - +
在全塔属性中的`equipName`项写法不变,不过可以写重复的装备孔名称。(但仍然最多只能写 6 或 8 个) ``` js "equipName": ["武器", "武器", "武器", "防具", "防具", "首饰"] ``` @@ -112,95 +100,52 @@ percentage为该装备是否按比例增加属性。 装备动画仍然会取第一个(装备类型为0)的装备的`animate`项,即使装备了多个有动画的武器。 ## 门 - -本塔支持6种门,黄蓝红绿铁花。前五种门需要有对应的钥匙打开,花门只能通过调用`openDoor`事件进行打开。 - -开门后可触发该层的`afterOpenDoor`事件,有关事件的详细介绍请参见[事件](event)。 - +样板自带6种门,黄蓝红绿铁花。前五种门需要有对应的钥匙打开,花门只能通过调用 `openDoor` 事件进行打开。
+开门后可触发该点的 `afterOpenDoor` 事件,有关事件的详细介绍请参见[事件](event)。
如果要新增自己的门,请参见[新增门和对应的钥匙](personalization#新增门和对应的钥匙)。 ## 暗墙 - -本塔支持暗墙。 - -要制作一个暗墙非常简单:在该点直接放一个普通墙壁,然后事件写“开门”,坐标为该点就行。 - -``` js +样板支持暗墙。要制作一个暗墙非常简单:在该点直接放一个普通墙壁,然后事件写“开门”,坐标为该点就行。 +``` json // 该点画一个普通的墙壁,比如`yellowWall` // 在该点的事件events中: -"x,y": [ - {"type": "openDoor"} // 直接使用开门事件,坐标可忽略表示当前点 -] +[{"type": "openDoor"}] // 直接使用开门事件,坐标可忽略表示当前点 ``` - -系统会自动调用animates中的开暗墙动画。 - -目前只有如下ID支持以这种方式开门: - +系统会自动调用animates中的开暗墙动画。样板自带如下ID支持以这种方式开门: ``` text yellowDoor, blueDoor, redDoor, greenDoor, specialDoor, steelDoor, yellowWall, blueWall, whiteWall ``` ## 怪物 - -本塔支持的怪物列表参见`project/enemys.js`。其与images目录下的`enemys.png`素材按顺序一一对应。 - +样板自带的怪物列表参见 `project\enemys.js` 。其与 `images\enemys.png` 素材按顺序一一对应。
如有自己的怪物素材需求请参见[自定义素材](personalization#自定义素材)的内容。 怪物可以有特殊属性,每个怪物可以有多个自定义属性。 怪物的特殊属性所对应的数字(special)在脚本编辑中的`getSpecials`中定义,请勿对已有的属性进行修改。 - -多属性可采用数组的写法,比如`'special': [1,3]`视为同时拥有先攻和坚固属性;`'special': [5,10,14,18]`视为拥有3连击、模仿、诅咒、阻击四个属性。 - -怪物可以负伤,在全塔属性的全局变量`enableNegativeDamage`中指定。 - +
多属性可直接从图块属性勾选。怪物可以负伤,由全塔属性的系统开关 `enableNegativeDamage` 指定。
打败怪物后可以进行加点操作。有关加点塔的制作可参见[加点事件](event#加点事件)。 - -如果全塔属性中的enableexp为false,即不启用经验的话,怪物手册里将不显示怪物的经验值,打败怪物也不获得任何经验。 - -拿到幸运金币后,打怪获得的金币将翻倍。 - -如果怪物有`"notBomb": true`,则该系列诖怪物均不可被炸。 - +
如果全塔属性中的“显示经验值”未勾选,即不启用经验的话,怪物手册里将不显示怪物的经验值,打败怪物也不获得任何经验。
+拿到幸运金币后,打怪获得的金币将翻倍。如果怪物勾选了 `notBomb` ,则这个种类的怪物均不可被炸。
N连击怪物的special是6,且我们可以为它定义n代表实际连击数。参见样板中剑王的写法。 - -吸血怪需要给怪物设置value,代表吸血的比例。 - -可以给吸血怪添加`'add': true`来将吸血的数值加到自身上。 - -中毒怪让勇士中毒后,每步扣减的生命值由`data.js`中的values定义。 - -衰弱怪让勇士衰弱后,攻防会下降一定比例或固定数值(直到衰弱状态解除恢复);其在`data.js`中的values定义。 - +
吸血怪需要给怪物设置value,代表吸血的比例。可以给吸血怪勾选 `add` 来将吸血的数值加到自身上。
但这样做以后,红色的预估伤害往往带有误导性,这点还务请注意!
+中毒怪让勇士中毒后,每步扣减的生命值由全塔属性中的 `poisonDamage` 定义。
+衰弱怪让勇士衰弱后,攻防会下降一定比例或固定数值(直到衰弱状态解除恢复);由全塔属性中的 `weakValue` 定义。
诅咒怪将让勇士陷入诅咒状态,诅咒状态下杀怪不获得金币和经验值。 - -领域怪需要在怪物后添加value,代表领域伤害的数值。如果勇士生命值扣减到0,则直接死亡触发lose事件。 - -领域是十字伤害还是九宫格伤害由`zoneSquare`设定,如设置为true则为九宫格伤害,不指定或为false则为十字伤害。 - +
领域怪需要需要给怪物设置 `value` ,代表领域伤害的数值。如果勇士生命值扣减到0,则直接死亡触发 `lose` 事件。
+领域是锯齿形状还是正方形由 `zoneSquare` 设定,如勾选则为正方形,不勾选则为锯齿形状。
领域怪还可以设置`range`选项代表该领域怪的范围,不写则默认为1。 - -**将`flag:no_zone`设置为true可以取消领域效果。** - +
**将 `flags.no_zone` 设置为 `true` 可以免疫领域效果。**
阻击怪同样需要设置value,代表阻击伤害的数值。如果勇士生命值扣减到0,则直接死亡触发lose事件。 - -**将`flag:no_snipe`设置为true可以取消阻击效果。** - -!> 阻击怪后退的地点不能有任何事件存在,即使是已经被禁用的自定义事件! - +
**将`flags.no_snipe`设置为true可以免疫阻击效果(包括伤害和移动!)。**
+!> 阻击怪后退的地点不能有任何事件存在,即使是已经被禁用的红绿事件或重生怪!(会导致此事件意外被重新启用)
激光怪同样需要设置value,代表激光伤害的数值。 - -请注意如果吸血、领域、阻击中任何两个同时存在,则value会冲突。**因此请勿将吸血、领域、阻击或激光放置在同一个怪物身上。** - -**将`flag:no_laser`设置为true可以免疫激光效果。** - +
请注意如果吸血、领域、阻击、生命光环中任何两个同时存在,则 `value` 会冲突。**因此请勿将吸血、领域、阻击或激光放置在同一个怪物身上。退化和攻防光环同理!
** +**将 `flags.no_laser` 设置为 `true` 可以免疫激光效果。将 `flags.no_ambush` 设置为 `true` 可以免疫捕捉效果。**
退化怪需要设置'atkValue'和'defValue'表示退化的数值;也可以不设置默认为0。 - -**将`flag:no_betweenAttack`设置为true可以免疫夹击效果。** - +
**将`flags.no_betweenAttack`设置为true可以免疫夹击效果,在全塔属性中还有一个系统开关可以控制夹击伤害是否封顶至夹击怪的战斗伤害。**
固伤怪则需要设置`damage`选项,代表战前扣血数值。 如有额外需求,可参见[自定义怪物属性](personalization#自定义自定义怪物属性),里面讲了如何设置一个新的怪物属性。 @@ -226,9 +171,7 @@ N连击怪物的special是6,且我们可以为它定义n代表实际连击数 我们可以给`E301`和`E302`怪物属性中的`displayIdInBook`项填写为`"E300"`。 这样的话,在怪物手册中,所有的E301和E302均会被视为E300并进行合并。即使只有一只朝向左的怪物(E301),怪物手册仍然会按E300进行显示。 - -从而完美解决了同种怪物不同朝向在怪物手册的显示问题。 - +
从而完美解决了同种怪物不同朝向在怪物手册的显示问题。此做法不兼容夹击属性,漏怪检测也以映射后的怪物为准。 ### NPC的朝向问题 和怪物不同的是,NPC朝向问题更复杂一点。 @@ -238,12 +181,10 @@ N连击怪物的special是6,且我们可以为它定义n代表实际连击数 举个例子,假设我存在一个NPC,其向上的图块ID是N333,向下的图块ID是N334,向左的图块ID是N335,不存在向右的图块ID。 则可以在这几个图块属性中的`faceIds`中写:`{"up": "N333", "down": "N334", "left": "N335"}`。 - -当勇士从左边撞上此怪物后,将从该图块的图块属性中的faceIds中寻求`left`所对应的ID。 -如果存在定义(如N335),则会在触发对话事件前改变当前图块为N335,看起来就是在对话前进行了转向,面向勇士。 - +
当勇士从左边撞上此NPC后,将从该图块的图块属性中的 `faceIds` 中寻求 `left` 所对应的ID。 +如果存在定义(如N335),则会在触发对话事件前改变当前图块为N335,看起来就是在对话前进行了转向,面向勇士。
!> 请注意,在对话结束后朝向不会切换回来,因此如果有必要切换朝向请在事件结束前调用转变图块事件。 - +
从v2.7起,也提供了“事件转向”指令来执行这种转变图块,从而省去了手动填写ID的不便。
同理,使用移动事件让NPC在行走时,不同朝向的行走会自动调用`faceIds`中不同朝向的ID所对应的行走图,看起来就是在行走时也可以不断转向了。 从而,完美解决了NPC的朝向问题(碰触时面向勇士、行走时改变朝向)。 @@ -253,23 +194,11 @@ N连击怪物的special是6,且我们可以为它定义n代表实际连击数 血网的伤害数值、中毒后每步伤害数值、衰弱时暂时攻防下降的数值,都在全塔属性的values内定义。 路障同样会尽量被自动寻路绕过。 - -有关楼梯和传送门,必须在该层样板的changeFloor里指定传送点的目标。 - -floorId指定的是目标楼层的唯一标识符(ID)。 - -也可以写`"floorId": ":before"`和`"floorId": ":next"`表示上一楼和下一楼。 - -后面可以写stair到upFloor或downFloor,表示将前往目标楼层的上楼梯/下楼梯位置。你也可以写loc然后指定目标点的坐标。 - -请注意的是,如果目标楼层有多个楼梯,写stair可能会导致到达的楼梯不确定,这时候请使用loc方式来指定具体的点位置。 - -可以指定direction为up/left/right/down,指定后勇士将面向该方向。 - -可以指定time,指定后切换动画时长为指定的数值。 - -**从2.1.1开始,楼层属性中提供了`upFloor`和`downFloor`两项。如果设置此项(比如`"upFloor": [2,3]`),则写stair:upFloor或者楼传器的落点将用此点来替换楼梯位置(即类似于RM中的上箭头)。** - +
有关楼梯和传送门,必须在该点的 `changeFloor` 事件里指定传送点的目标。![生成地图](./img/changeFloorBlockly.png)
+楼层ID指定的是目标楼层的唯一标识符(ID),也可以在第一个下拉框中选择“前一楼”和“后一楼”。
+第二个下拉框可以选择传送到哪个楼梯,或选择三种对称位置,或显式指定坐标(比如目标楼层有多个楼梯时)。
+“朝向”为勇士上下楼后面对的方向,不填则不改变。“动画时间”为上下楼的黑屏时间,不填则使用玩家设定值。
“穿透性”表示鼠标或触屏寻路时勇士能否穿过此传送点,在转不开身的狭窄区域建议设为可穿透。
+**从v2.1.1开始,楼层属性中提供了 `upFloor` 和 `downFloor` 两项。如果设置此项(比如`"upFloor": [2,3]`),则写传送到哪个楼梯或者楼传器的落点将用此点来替换楼梯位置(即类似于RMXP中的上箭头)。** ## 剧情文本控制与对话框效果 在写剧情文本时,可以: @@ -312,16 +241,12 @@ floorId指定的是目标楼层的唯一标识符(ID)。 从V2.4开始,H5魔塔开始支持大地图。 大地图在创建时可以指定宽高,要求**宽和高都不得小于13(15x15版本则是不小于15),且宽高之积不超过1000**。 - -大地图一旦创建成功则不得修改宽高数值。 - +
大地图一旦创建成功则难以修改宽高数值,如确需修改,请手动打开 `floors` 文件夹中的 `JS` 文件并同时修改宽高和地图矩阵。 ## 动画和天气系统 现在我们的H5魔塔支持播放动画,也支持天气系统了。 - -要播放动画,你需要先使用“RM动画导出器”将动画导出,放在animates目录下,然后在全塔属性的animates中定义。 - -``` js +
要播放动画,你可以先使用“RM动画导出器”将动画导出,放在animates目录下,然后在全塔属性的animates中定义。 +``` json // 在此存放所有可能使用的动画,必须是animate格式,在这里不写后缀名 // 动画必须放在animates目录下;文件名不能使用中文,不能带空格或特殊字符 "animates": ["hand", "sword", "zone", "yongchang", "thunder"] @@ -332,18 +257,15 @@ floorId指定的是目标楼层的唯一标识符(ID)。 导出动画时可能会进行一些压缩以节省流量,因此清晰度可能不如原版。 从2.3.2开始,动画可以同时导出所用的音效。**如果导出音效,请确保将所用到的音效复制到了`sounds`目录下,并且在全塔属性中注册过。** +
确切地说,动画文件中记录着第几帧该用什么音效的文件名,您可以用记事本等文本编辑器打开动画文件并手动修改用到的音效文件名(原本可能是中文甚至日文),以和实际的文件名相匹配 动画播放时,是按照每秒20帧的速度(即50ms/帧)。 定义完毕后,我们可以调用`animate`事件来播放该动画,有关事件的详细介绍请参见[事件](event)。 !> 播放录像时,将默认忽略所有动画。 - -目前天气系统支持雨和雪和雾两种天气。 - -在每层楼的楼层属性中存在一个weather选项,表示该层楼的默认天气。 - -``` js +
目前天气系统支持雨、雪和雾三种天气。在每层楼的楼层属性中存在一个weather选项,表示该层楼的默认天气。 +``` json // 该层的默认天气。本项可忽略表示晴天,如果写则第一项为"rain","snow"或"fog"代表雨雪雾,第二项为1-10之间的数代表强度。 "weather": ["snow",5] ``` @@ -351,12 +273,8 @@ floorId指定的是目标楼层的唯一标识符(ID)。 我们也可以使用`setWeather`事件来设置当前天气,有关事件的详细介绍请参见[事件](event)。 ## 背景音乐 - -本塔支持BGM和SE的播放。 - -要播放音乐和音效,你需要将对应的文件放在sounds目录下,然后在全塔属性中进行定义 - -``` js +样板支持BGM和SE的播放。要播放音乐和音效,你需要将对应的文件放在sounds目录下,然后在全塔属性中进行定义 +``` json // 在此存放所有的bgm,和文件名一致。 // 音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好 "bgms": ["bgm.mp3"] @@ -366,9 +284,7 @@ floorId指定的是目标楼层的唯一标识符(ID)。 ``` !> 音频名不能使用中文,不能带空格或特殊字符。 - -目前BGM支持主流的音乐格式,如mp3, ogg等。不支持mid格式的播放。 - +
目前BGM支持主流的音乐格式,如 `wav, mp3, ogg, flac, m4r` 等。不支持 `mid` 格式的播放。
`iOS` 系统对 `ogg` 的支持性较差,但 `ogg` 比 `mp3` 体积小,请注意权衡。
定义完毕后,我们可以调用`playBgm`/`playSound`事件来播放对应的音乐/音效,有关事件的详细介绍请参见[事件](event)。 **另外,考虑到用户的流量问题,将遵循如下规则:** @@ -382,11 +298,7 @@ floorId指定的是目标楼层的唯一标识符(ID)。 从V2.5.3开始,可以使用`loadBgm`事件来预加载一个bgm,这样到播放时无需等待,直接播放。 同时BGM将使用LRU算法增加缓存机制。默认最多缓存4个BGM(在core.js的musicStatus.cachedBgmCount控制)。 - -系统会自动释放最久未使用的BGM。 - -也可以使用`freeBgm`事件来手动释放一个无需再用的bgm。 - +
系统会自动释放最久未使用的BGM。也可以使用 `freeBgm` 脚本来手动释放一个无需再用的 `bgm` 。 ## 录像 HTML5魔塔一大亮点就是存在录像系统,可以很方便进行录像回放。 @@ -404,6 +316,7 @@ HTML5魔塔一大亮点就是存在录像系统,可以很方便进行录像回 录像播放过程中,可以进行如下操作: +- **步进:** 暂停状态下,按 `N` 键可以单步执行录像,常用于调试。 - **暂停/播放:** 按空格可以随时暂停或播放录像。 - **加速:** 按X可以加速录像播放,最高可达6倍速。 - **减速:** 按Z可以减速录像播放,最低可达0.3倍速。 @@ -413,8 +326,7 @@ HTML5魔塔一大亮点就是存在录像系统,可以很方便进行录像回 - **查看手册:** 按C可以在录像播放过程中查看怪物手册。 - **浏览地图:** 按PgUp/PgDn可以在录像播放过程中浏览地图。 -如果录像出现问题,请加群539113091找小艾反馈Bug。 - +如果录像出现问题,请加 QQ 群 [959329661](https://jq.qq.com/?_wv=1027&k=5C87qeQ) 找小艾反馈Bug。 ## 操作说明 ![](img/keyboard.png) diff --git a/_docs/event.md b/_docs/event.md index 4fd92d4e..be88228b 100644 --- a/_docs/event.md +++ b/_docs/event.md @@ -1,23 +1,18 @@ # 事件 - -?> 目前版本**v2.6.6**,上次更新时间:* {docsify-updated} * - +?> 目前版本**v2.7**,上次更新时间:* {docsify-updated} *
本章内将对样板所支持的事件进行介绍。 ## 事件的机制 - -本塔所有的事件都是依靠触发`trigger`完成的。例如,勇士碰到一个门可以触发一个事件`openDoor`,勇士碰到怪物可以触发一个事件`battle`,勇士碰到一个(上面定义的)楼层传送点可以触发一个事件`changeFloor`,勇士穿过路障可以触发一个事件`passNet`,等等。上面说的这些事件都是系统本身自带的,即类似于RMXP中的公共事件。 - +本塔所有的事件都是依靠触发器 `trigger` 完成的。例如,勇士碰到一个门可以触发一个事件 `openDoor` ,勇士碰到怪物可以触发一个事件 `battle` ,勇士碰到一个(上面定义的)楼层传送点可以触发一个事件 `changeFloor` ,等等。上面说的这些事件都是系统本身自带的,即类似于RMXP中的公共事件。
上述这些默认的事件已经存在处理机制,不需要我们操心。我们真正所需要关心的,其实只是一个自定义的事件。 - -所有事件都存在两种状态:启用和禁用。 +
所有普通事件(红)、楼层传送事件(绿)和重生怪,都存在两种状态:启用和禁用。 - 启用状态下,该事件才处于可见状态,可被触发、交互与处理。 - 禁用状态下该事件相当于不存在,不可见、不可被触发、不可交互。 -所有事件默认情况下都是启用的,除非指定了`enable: false`。 - -在事件列表中使用`type: show`和`type: hide`可以将一个禁用事件启用,或将一个启用事件给禁用。 - +所有普通事件(红)默认情况下都是启用的,除非取消了“启用”的勾选。
+在事件列表中使用“显示事件”和“隐藏事件”可以将一个禁用事件给启用,或将一个启用事件给禁用(如果不是红、绿或重生怪,则会直接永久从地图中删除)。
+因此,非常不推荐仅仅为了初始隐藏一个图块,就去给它绑定一个本身没有任何指令的普通事件。
+如有需求,请使用“转变图块”或“关门”事件 ## 关于V2.0的重要说明 在V2.0以后版本中,所有事件均可以使用blockly来进行块的可视化编辑。 @@ -25,153 +20,50 @@ 它能通过拖动、复制粘贴等方式帮助你快速生成事件列表,而不用手动打大量字符。 下述所说的都是在事件编辑器右边所展示的,该事件的代码化写法;部分增加了可视化事件编辑器的截图示意(感谢秋橙的制作)。 - -强烈建议要对每个事件的写法进行了解,因为在脚本编辑,`insertAction`等地方需要插入自定义事件时,还是很有必要的。 - -## 自定义事件 - +
强烈建议要对每个事件的写法进行了解,因为在脚本编辑,`insertAction` 等地方需要插入临时事件组时,还是很有必要的。 +## 普通事件 打开样板1层(`sample1.js`)有着一些介绍。下面是更为详细的说明。 - -所有自定义的事件都是如下的写法: - -``` js +
所有普通事件都是如下的开头:
+覆盖触发器(Y/N)启用(Y/N)通行状态(不改变/不可通行/可以通行)显伤(Y/N) +1. 覆盖触发器:如果该点原本是道具或怪物等有着系统触发器的图块,那么必须勾选此项,表示用此普通事件中的指令覆盖原本的行为(拾获和战斗等,但炸弹、光环和阻激夹域捕不受影响),如果是在原本的系统行为结束后执行其他行为,请使用三个 `afterXxx` 事件。 +2. 启用:如果不勾选此项,就表示此普通事件初始时是隐藏的。 +3. 通行状态:可以使用此设定来覆盖该点图块的通行性,如果不指定则以图块为准(道具可通行,怪物不可通行,其他图块由图块属性的 `canPass` 项指定) +4. 显伤:如果不勾选此项,则该点为怪物时将取消显伤。 +``` json { - "trigger": "action", // 触发的trigger, action代表自定义事件 + "trigger": "action", // 触发的trigger, action代表覆盖触发器 "enable": true, // 该事件初始状态下是否处于启用状态 "noPass": true, // 该点是否不可通行。true代表不可通行,false代表可通行。 "data": [ // 实际执行的事件列表 - // 事件1 - // 事件2 + {"type": "xxx", ...}, // 事件1 + {"type": "xxx", ...}, // 事件2 // ... - ] -} -``` - -我们上面提到,有很多系统已经默认的事件(例如开门、打怪等,相当于公共事件)。如果我们需要自定义一个事件,则需要`"trigger": "action"`,它表示该点是一个自定义事件。 - -!> **如果系统本身存在事件(如一个怪物),且你指定了`"trigger": "action"`,则原事件会被覆盖。** - -这种情况下一般需采用后面的afterBattle,afterOpenDoor和afterGetItem来进行事件的处理。 - -如果该点本身不存在系统事件,则`"trigger":"action"`可被省略不写: - -``` js -{ - // 除非你要覆盖该点已存在的系统默认事件,否则"trigger": "action"可以省略 - "enable": true, // 该事件初始状态下是否处于启用状态 - "noPass": true, // 该点是否不可通行。true代表不可通行,false代表可通行。 - "data": [ // 实际执行的事件列表 - // 事件1 - // 事件2 - // ... - ] -} -``` - -`"enable": true` 代表该点初始状态下是否是启用的。如果`enable`为`false`,则该点初始状态下禁用,将不会被显示和交互(比如如果该点是个怪,指定了`enable`为`false`,则该怪不会显示在地图上,也不会发生战斗)。 - -默认情况下`enable`是`true`,所以如果`enable`为`true`,该项也可以省略不写: - -``` js -{ - // 除非你要覆盖该点已存在的系统默认事件,否则"trigger": "action"可以省略 - // 该事件初始状态下是启用状态,则可以省略"enable": true;如果是禁用状态则必须加上"enable": false - "noPass": true, // 该点是否不可通行。true代表不可通行,false代表可通行。 - "data": [ // 实际执行的事件列表 - // 事件1 - // 事件2 - // ... - ] -} -``` - -`"noPass"`为该点是否可通行的标记。`true`代表该点不可通行,`false`代表该点可通行。 - -对于目前所有的素材,都存在默认的是否可通行状态。如果你在该点指定`noPass`,则原本的可通行状态会被覆盖。 - -因此,除非你想覆盖默认的可通行选项(比如将一个空地设为不可通行),否则该项可以忽略。 - -``` js -{ - // 除非你要覆盖该点已存在的系统默认事件,否则"trigger": "action"可以省略 - // 该事件初始状态下是启用状态,则可以省略"enable": true;如果是禁用状态则必须加上"enable": false - // 除非你想覆盖系统默认的可通行状态,否则"noPass"项可以忽略 - "data": [ // 实际执行的事件列表 - // 事件1 - // 事件2 - // ... - ] -} -``` - -`"data"`为实际执行的事件列表。类似于RMXP中的"脚本",也是由一系列事件顺序构成的(其中可以使用`if`和`choices`来进行条件判断或用户选择,后面会具体提到)。 - -如果大括号里只有`"data"`,则可以省略大括号和`"data"`,直接写中括号数组,换句话说,上面和下面这种写法也是等价的,可以进行一下比较: - -``` js -// 如果大括号里只有"data"项(没有"action", "enable"或"noPass"),则可以省略到只剩下中括号 -[ - // 事件1 - // 事件2 - // ... -] -``` - -这种简写方式可以极大方便地造塔者进行造塔。 - -!> **请注意:如果该点初始的`enable`为`false`,或者该点本身有系统默认事件且需要覆盖(`trigger`),或者你想覆盖该点的默认通行状态,则必须采用上面那种大括号写的方式来定义。** - -  - -`"data"`中,是由一系列的自定义事件类型组成。每个元素类似于: - -``` js -// 如果大括号里只有"data"项(没有"action"或"enable"),则可以省略到只剩下中括号 -[ - {"type": "xxx", ...}, // 事件1 - {"type": "xxx", ...}, // 事件2 - // ... - // 按顺序写事件,直到结束 + // 按顺序写事件,直到结束 ] ``` `"type"`为该自定义事件的类型;而后面的`...`则为具体的一些事件参数。 - -每次,系统都将取出数组中的下一个事件,并进行处理;直到数组中再无任何事件,才会完全结束本次自定义事件,恢复游戏状态。 - +
每次,系统都将取出数组中的下一个事件,并进行处理;直到数组中再无任何事件,或遇到“立刻结束当前事件”,才会完全结束本次普通事件,恢复游戏状态。
下面将依次对所有自定义事件类型进行介绍。 ### text:显示一段文字(剧情) 使用`{"type": "text"}`可以显示一段文字。后面`"text"`可以指定文字内容。 -``` js +``` json [ - {"type": "text", "text": "在界面上的一段文字"}, // 显示文字事件 - {"type": "text", "text": "这是第二段文字"}, // 显示第二个文字事件 - // ... + {"type": "text", "text": "在界面上的一段文字"}, // 显示文字事件,按空格或单击屏幕继续 + "这是第二段文字", // 显示第二个文字事件,可以简写为字符串 + // 请注意insertAction函数接收单个字符串作为参数时会优先识别为公共事件,建议改用drawText // 按顺序写事件,直到结束 ] ``` ![](img/events/1.jpg) -该项可以简写成直接的字符串的形式,即下面这种方式也是可以的: - -``` js -[ - "在界面上的一段文字",// 直接简写,和下面写法完全等价 - {"type": "text", "text": "这是第二段文字"}, // 显示第二个文字事件 - // ... - // 按顺序写事件,直到结束 -] -``` - -所有文字事件均可以进行简写,系统会自动转成`{"type": "text"}`的形式。 - 值得注意的是,系统会自动对文字进行换行;不过我们也可以手动加入`\n`来换行。 -``` js +``` json [ "这一段文字特别特别长,但是系统可以对它进行自动换行,因此我们无需手动换行", "这是第一行\n这是第二行\n这是第三行", @@ -181,20 +73,10 @@ ``` 我们可以给文字加上标题或图标,只要以`\t[...]`开头就可以。 - -其一般写法是`\t[名字,ID]`,其中名字为你要显示的标题,ID为图块ID,只能为`hero`,或者NPC/怪物的图块ID。 - -如果不需要可以不写ID,则只会显示标题。 - -对于hero和怪物,也可以不写名字代表使用默认值。 - +
其一般写法是 `\t[名字,ID]` ,其中名字为你要显示的标题,ID为图块ID,也可以填 `hero` 。
如果不需要可以不写ID,则只会显示标题。对于非道具,也可以不写名字代表使用默认值。
从V2.5.2以后,新增了绘制大头像的功能。绘制大头像图的基本写法是`\t[1.png]`或者`\t[标题,1.png]`。 - -从V2.6开始,所有图块都允许只写ID,对于非怪物则仅当图块属性中设置了name才有标题(否则不显示标题)。 - -另外注意的是,名字可以用null从而只显示动画而不显示标题。 - -``` js +
从V2.6开始,所有图块都允许只写ID,对于非怪物也非道具则仅当图块属性中设置了 `name` 才有标题(否则不显示标题)。另外注意的是,名字可以用null从而只显示动画而不显示标题。 +``` json [ "一段普通文字", "\t[勇士,hero]这是一段勇士说的话", @@ -213,19 +95,17 @@ ![](img/events/2.jpg) -!> 大头像的头像图需要在全塔属性中注册,且必须是png格式,不可以用jpg或者其他格式,请自行转换。 - +!> 大头像的头像图需要在全塔属性中注册,且必须是png格式,不可以用jpg或者其他格式,请自行另存为。
除此以外,我们还能实现“对话框效果”,只要有`\b[...]`就可以。 - -- `\b[up]` 直接显示在当前点上方。同样把这里的up换成down则为下方。 - - 如果不存在当前点(如在firstArrive或eachArrive中调用),则显示在屏幕最上方(最下方) -- `\b[up,hero]` 显示在勇士上方。同样把这里的up换成down则为下方。 - - 从V2.6开始,也允许写`\b[hero]`来根据勇士位置自动决定上方还是下方 -- `\b[up,x,y]` 显示在(x,y)点的上方(下方);x和y都为整数且在0到12之间 +- `\b[up]` 直接显示在当前点上方。`up` 换成 `down` 则为下方,换成 `null` 则根据当前点在视野中的位置自动选择上下 + - 如果不存在当前点(如在`firstArrive`或`eachArrive`中调用),则显示在屏幕最上方(最下方) + - `\b[up,null]`和`\b[center]`可以无视当前点存在与否,强制显示在屏幕最上方(最下方)或中央 +- `\b[up,hero]` 显示在勇士上方。同样把这里的 `up` 换成 `down` 则为下方。 + - 从V2.6开始,也允许写`\b[hero]`来根据勇士在视野中的位置自动决定上方还是下方 +- `\b[up,x,y]` 显示在(x,y)点的上方(下方);x和y都为整数,表示该点的绝对坐标 - 从V2.6开始,也允许写`\b[null,x,y]`来根据(x,y)位置自动决定上方还是下方 -- `\b[up,x]` 显示在勇士的第x个跟随的行走图的上方(下方);也允许把up换成null来自动适配 - -``` js +- `\b[up,x]` 显示在勇士的第x个跟随的行走图的上方(下方);也允许把 `up` 换成 `down` ,`hero`或`null` 来自动适配 +``` json [ "\b[up]这段文字显示在当前点上方", "\b[down]这段文字显示在当前点上方", @@ -233,7 +113,7 @@ "\t[hero]\b[hero]这是一段勇士说的话,根据勇士位置自动适配上下", "\t[小妖精,fairy]\b[down,2,2]这是一段小妖精说的话,会显示在(2,2)点下方", "\t[null,1,3]根据坐标位置自动适配上下", - "\t[up,1]"显示在勇士第一个跟随的行走图上方", + "\t[up,1]显示在勇士第一个跟随的行走图上方", "\t[null,2]显示在勇士第二个跟随的行走图,自动适配上下", ] ``` @@ -241,10 +121,8 @@ ![](img/events/3.jpg) !> `\t[...]`必须在`\b[...]`前面!不然两者都无法正常显示。 - -还可以使用`\r[...]`来调整剧情文本的颜色。 - -``` js +
还可以使用`\r[...]`来调整剧情文本的颜色,颜色的英文名详见[w3school](https://www.w3school.com.cn/cssref/css_colornames.asp)。样板也会帮你自动补全最标准的这17个:aqua, black, blue, fuchsia, gray, green, lime, maroon, navy, olive, orange, purple, red, silver, teal, white, yellow +``` json [ "这句话是默认颜色,\r[red]将颜色变成红色,\r[blue]将颜色变成蓝色", "\r[#FF00FF]还可以使用RGB值来控制颜色,\r如果不加中括号则回到默认颜色", @@ -261,8 +139,7 @@ 从V2.6.3开始,也可以在最后加上alpha值,即`\f[img,sx,sy,sw,sh,x,y,w,h,alpha]`。 需要注意的是,这个图片是绘制在UI层上的,下一个事件执行时即会擦除;同时如果使用了\t的图标动画效果,重叠的地方也会被图标动画给覆盖掉。 - -``` js +``` json [ "\t[勇士]\b[up,hero]\f[1.png,100,100]以(100,100)为左上角绘制1.png图片", "\t[hero]\f[1.png,100,100]\f[2.png,300,300]同时绘制了两张图片", @@ -277,10 +154,9 @@ 从V2.5.5以后,也可以使用`\\i[...]`来在对话框中绘制一个图标。 这里可以使用一个合法ID(32x48图块除外),或使用一个系统图标(`core.statusBar.icons`中的内容)。 - -``` js +``` json [ - "\t[勇士]\b[up,hero]这是一个飞行器\\i[fly],这是一个破墙镐\\i[pickaxe]", + "\t[勇士]\b[up,hero]这是一个楼层传送器\\i[fly],这是一个破墙镐\\i[pickaxe]", "\t[hero]也可以使用系统图标,比如这是存档\\i[save],这是工具栏\\i[toolbox]", ] ``` @@ -288,36 +164,31 @@ ![](img/events/6.jpg) **可以在控制台中输入`core.statusBar.icons`以查看所有的系统图标定义。** - -!> 注意,在事件块中,允许只写一个反斜杠`\i`,系统会自动转义成`\\i`;但是在脚本中必须两个反斜杠都写上! - -从V2.6.3开始,也可以使用`\\c[...]`来切换当前字体,`\\d`来加粗或取消粗体,`\\e`来加斜体或取消斜体。 - -``` js +
!> 注意,在事件块中,允许只写一个反斜杠`\i`,系统会自动转义成`\\i`;但是在脚本中必须两个反斜杠都写上!`\c`、`\d`、`\e` 和 `\z` 同理
+从V2.6.3开始,也可以使用`\\c[...]`来切换当前字体,`\\d`来加粗或取消粗体,`\\e`来加斜体或取消斜体。
从V2.7开始,还可以使用`\\z[...]`来调节打字速度。 +``` json [ "这是原始字体,\\c[20]使用20号字体,\\c[10]使用10号字体", "\\c如果不加中括号则切换回原始字体。", - "\\d这是粗体\\d取消粗体,\\e加斜体\\e取消斜体" + "\\d这是粗体\\d取消粗体,\\e加斜体\\e取消斜体", + "\t[hero]\b[hero]让我想想...\\z[10]有了!" // 打出省略号后,暂停相当于打10个字的时间 ] ``` - -!> 注意,在事件块中,允许只写一个反斜杠`\c`,系统会自动转义成`\\c`;但是在脚本中必须两个反斜杠都写上!`\d`和`\e`同理。 - 另外值得一提的是,我们是可以在文字中计算一个表达式的值的。只需要将表达式用 `${ }`整个括起来就可以。 - -``` js +``` json [ "1+2=${1+2}, 4*5+6=${4*5+6}", // 显示"1+2=3, 4*5+6=26" ] ``` -我们可以使用 `status:xxx` 代表勇士的一个属性值;`item:xxx` 代表某个道具的个数;`flag:xxx` 代表某个自定义的变量或flag值。 +我们可以使用 `status:xxx` 代表勇士的一个属性值;`item:xxx` 代表某个道具的个数;`flag:xxx` 代表某个自定义的变量或flag值;`switch:A-Z`代表某个独立开关的值。 从V2.6开始,也可以使用`global:xxx`代表全局存储(和存档无关的存储)。 -从V2.6.5开始,也可以使用`enemy:id:atk`来获得某个怪物的属性,`blockId:x,y`来获得某个点的图块ID,`equip:x`来获得某个装备孔的装备ID。 +从V2.6.5开始,也可以使用`enemy:id:xxx`来获得某个怪物的属性,`blockId:x,y`来获得某个点的图块ID,`blockCls:x,y`来获得某个点的图块类别,`equip:N`来获得某个装备孔的装备ID。 -``` js +从V2.7开始,也可以使用`temp:A-Z`来获得某个临时变量,一般在循环遍历中使用。 +``` json [ "你当前的攻击力是${status:atk}, 防御是${status:def},坐标是(${status:x},${status:y})", "你的攻防和的十倍是${10*(status:atk+status:def)}", @@ -327,13 +198,13 @@ "绿色史莱姆的攻击力是${enemy:greenSlime:atk}", "(2,3)点的图块ID是${blockId:2,3},图块类型是${blockCls:2,3}", "装备孔0的当前装备ID是${equip:0}", + "当前的临时变量A的值是${temp:A}", // blockly中还可以使用中文,如图 ] ``` ![](img/events/7.png) - -- `status:xxx` 获取勇士属性时只能使用如下几个:hp(生命值),atk(攻击力),def(防御力),mdef(护盾值),money(金币),exp(经验),x(勇士的横坐标),y(勇士的纵坐标),direction(勇士的方向)。 -- `item:xxx` 中的xxx为道具ID。所有道具的ID定义在items.js中,请自行查看。例如,`item:centerFly` 代表中心对称飞行器的个数。 +- `status:xxx` 获取勇士属性时如下几个较为特殊:x(勇士的横坐标),y(勇士的纵坐标),direction(勇士的方向)。其他的单词 `xxx` 会直接解析为 `core.status.hero.xxx` 的值。 +- `item:xxx` 中的 `xxx `为道具ID。所有道具的ID定义在 `project\items.js` 中,请自行查看。例如,
`item:centerFly` 代表中心对称飞行器的个数。 - `flag:xxx` 中的xxx为一个自定义的变量/Flag(支持中文);如果没有对其进行赋值则默认值为0。 - `global:xxx` 中的xxx为一个全局存储的名称(支持中文);如果没有对其进行赋值则默认值为0。 - `enemy:xxx:yyy` 中的xxx为怪物ID;yyy为要获得的项,比如hp, atk, def等等 @@ -343,8 +214,7 @@ ### autoText:自动剧情文本 使用`{"type": "autoText"}`可以使用剧情文本。 - -``` js +``` json [ {"type": "autoText", "text": "一段自动显示的剧情文字", "time": 5000} ] @@ -359,14 +229,11 @@ time为可选项,代表该自动文本的时间。可以不指定,不指定 用户无法跳过自动剧情文本,只能等待time时间结束后自动过。 回放录像时将忽略自动剧情文本的显示。 - -!> 由于用户无法跳过自动剧情文本,因此对于大段剧情文本请自行添加“是否跳过剧情”的提示,否则可能会非常不友好。 - +
!> 由于用户无法跳过自动剧情文本,因此对于大段剧情文本请自行塞进“是否跳过剧情”的确认框分支,否则可能会非常不友好。 ### scrollText:滚动剧情文本 使用`{"type": "scrollText"}`可以使用滚动剧情文本,即将一段文字从屏幕最下方滚动到屏幕最上方。 - -``` js +``` json [ {"type": "scrollText", "text": "第一排\n第二牌\n\n空行后的一排", "time": 5000, "lineHeight": 1.4, "async": true}, ] @@ -389,8 +256,7 @@ async可选,如果为true则会异步执行(即不等待当前事件执行 ### setText:设置剧情文本的属性 使用`{"type": "setText"}`可以设置剧情文本的各项属性。 - -``` js +``` json [ {"type": "setText", "title": [255,0,0], "text": [255,255,0], "background": [0,0,255,0.3], "time": 70}, {"type": "setText", "position": "up", "offset": 15, "bold": true, "titlefont": 26, "textfont": 17}, @@ -401,7 +267,9 @@ async可选,如果为true则会异步执行(即不等待当前事件执行 ![](img/events/10.jpg) -title为可选项,如果设置则为一个RGB三元组或RGBA四元组,表示标题(名字)颜色。 默认值:`[255,215,0,1]` +title为可选项,如果设置则为一个RGB三元组或RGBA四元组,表示标题(名字)颜色。 默认值:`[255,215,0,1]`, + +可以通过单击RGBA值后面的色块呼出调色器,进行16进制转换等复杂取色操作,其他使用RGBA的事件也是类似的。 text为可选项,如果设置则为一个RGB三元组或RGBA四元组,表示正文颜色。 默认值:`[255,255,255,1]` @@ -423,11 +291,11 @@ time为可选项,表示文字添加的速度。若此项设置为0将直接全 interval为可选项,表示文字之间的间距。单位为像素值。默认值:`0` +lineHeight为可选项,表示行距。单位为像素值。 ### tip:显示一段提示文字 `{"type": "tip"}`可以在左上角显示一段提示文字。 - -``` js +``` json [ {"type": "tip", "text": "这段话将在左上角以气泡形式显示", "icon": "book"} ] @@ -442,8 +310,7 @@ icon是可选的,如果设置则会绘制图标,其可以是一个有效的I ### comment:添加注释 使用`{"type": "comment"}`可以添加一段注释 - -``` js +``` json [ {"type": "comment", "text": "这是一段会被跳过的注释内容"} ] @@ -458,30 +325,26 @@ icon是可选的,如果设置则会绘制图标,其可以是一个有效的I `{"type": "setValue"}` 能修改勇士的某个属性、道具个数、或某个自定义变量或`Flag`的值。 其大致写法如下: - -``` js -[ - {"type": "setValue", "name": "...", "value": "..."}, // 设置一个属性、道具或自定义Flag +``` json +[ // 设置一个属性、道具、自定义Flag、独立开关、全局存储、临时变量 + {"type": "setValue", "name": "...", "operator": "...", "value": "..."}, ] ``` - -使用`setValue`需要指定`name`和`value`选项。 - -name为你要修改的属性/道具/Flag,每次只能修改一个值。写法和上面完全相同,`status:xxx` 表示勇士一个属性,`item:xxx` 表示某个道具个数,`flag:xxx` 表示某个变量或flag值。参见上面的介绍。 - -value是一个表达式,将通过这个表达式计算出的结果赋值给name。该表达式同样可以使用`status:xxx`, `item:xxx`, `flag:xxx`, `global:xxx`的写法表示勇士当前属性,道具个数,某个变量/Flag值和某个全局存储值。 - -``` js +使用 `setValue` 需要指定 `name`、`operator` 和 `value` 选项。
+`name` 为你要修改的属性/道具/Flag/独立开关/全局存储/临时变量,每次只能修改一个值。写法和 `${}` 中完全相同,`status:xxx` 表示勇士一个属性,`item:xxx` 表示某个道具个数,`flag:xxx` 表示某个变量或flag值。参见上面的介绍。
+`operator` 为运算的类型,目前支持八种,详见下面的例子和图示。
+`value` 是一个表达式,将通过这个表达式计算出的结果作为另一个运算量。该表达式同样可以使用`status:xxx`, `item:xxx`, `flag:xxx`, `global:xxx`等的写法表示勇士当前属性,道具个数,某个变量/Flag值和某个全局存储值等。 +``` json [ - {"type": "setValue", "name": "status:atk", "value": "status:atk+10" } // 攻击提高10点 - {"type": "setValue", "name": "status:money", "value": "1000" } // 将金币数设为1000(不是+1000) - {"type": "setValue", "name": "status:hp", "value": "status:hp*2" } // 生命值翻倍 - {"type": "setValue", "name": "item:yellowKey", "value": "item:yellowKey+3" } // 黄钥匙个数加3 - {"type": "setValue", "name": "item:bomb", "value": "item:bomb+10" } // 炸弹个数+10 - {"type": "setValue", "name": "flag:man_times", "value": "0" } // 将变量man_times设为0 - {"type": "setValue", "name": "flag:man_times", "value": "flag:man_times+2*status:atk" } // 将变量man_times的值加上勇士的攻击数值的两倍 - {"type": "setValue", "name": "global:123", "value": "4"} // 设置全局存储233为4(任何存档都可以读取它) -] + {"type": "setValue", "name": "global:一周目已通关", "value": "true", "norefresh": true}, // 设置全局存储“一周目已通关”为true,用于二周目中触发隐藏分支 + {"type": "setValue", "name": "status:name", "operator": "+=", "value": "'之王'", "norefresh": true}, // 勇士名称结尾增加两个字“之王”,不立即刷新状态栏 + {"type": "setValue", "name": "flag:hatred", "operator": "-=", "value": "10", "norefresh": true}, // 减少10点仇恨值 + {"type": "setValue", "name": "status:hp", "operator": "*=", "value": "2", "norefresh": true}, // 生命值加倍,即圣水道具的效果 + {"type": "setValue", "name": "switch:A", "operator": "/=", "value": "10", "norefresh": true}, // 独立开关A的值缩小到原来的十分之一,可能产生小数 + {"type": "setValue", "name": "item:yellowKey", "operator": "**=", "value": "3", "norefresh": true}, // 黄钥匙的数量变为它原来值的立方 + {"type": "setValue", "name": "temp:A", "operator": "//=", "value": "3", "norefresh": true}, // 临时变量缩小到原来的三分之一,向靠近0的方向取整 + {"type": "setValue", "name": "status:atk", "operator": "%=", "value": "100"}, + ] // 攻击力对100取余数,即只保留最后两位,然后刷新状态栏 ``` ![](img/events/13.jpg) @@ -495,7 +358,7 @@ value是一个表达式,将通过这个表达式计算出的结果赋值给nam 使用`{"type":"setEnemy"}`可以设置某个怪物的某个属性 -``` js +``` json [ {"type": "setEnemy", "id": "greenSlime", "name": "hp", "value": "1000"}, // 设置绿色史莱姆生命1000 {"type": "setEnemy", "id": "redSlime", "name": "special", "value": "[1,2]"}, // 设置红色史莱姆先攻魔攻 @@ -586,12 +449,9 @@ name必填项,代表要修改的系统开关,其是全塔属性中的flags value为必填项,只能为true或false,代表要修改到的结果。 ### show:将一个禁用事件启用 - -我们上面提到了,所有事件都必须靠其他事件驱动来完成,不存在当某个flag为true时自动执行的说法。那么,我们自然要有启用事件的写法。 - +我们上面提到了,除自动事件外,事件都必须靠其他事件驱动来完成,不存在当某个 `flag` 为 `true` 时自动执行的说法。那么,我们自然要有启用事件的写法。
使用`{"type":"show"}`可以将一个本身禁用的事件启用。 - -``` js +``` json [ {"type": "show", "loc": [3,6], "floorId": "MT1", "time": 500}, // 启用MT1层[3,6]位置事件,动画500ms {"type": "show", "loc": [3,6], "time": 500}, // 如果启用目标是当前层,则可以省略floorId项 @@ -614,9 +474,7 @@ time为动画效果时间,如果指定了某个大于0的数,则会以动画 async可选,如果为true则会异步执行(即不等待当前事件执行完毕,立刻执行下一个事件)。 !> **要注意的是,调用show事件后只是让该事件从禁用状态变成启用,从不可见不可交互变成可见可交互,但本身不会去执行该点的事件。** - -### hide:将一个启用事件禁用 - +### hide:将一个启用事件禁用,或将非红非绿非重生的图块删除 `{"type":"hide"}`和show刚好相反,它会让一个已经启用的事件被禁用。 其参数和show也完全相同,loc指定事件的位置,floorId为楼层(同层可忽略),time指定的话事件会以动画效果从有到无慢慢消失,async代表是否是异步效果。 @@ -628,8 +486,7 @@ loc同样可以简单的写[x,y]表示单个点,或二维数组[[x1,y1],[x2,y2 请注意,一次性事件必须要加 `{"type":"hide"}`,尤其是例如走到某个点,触发对话或机关门(陷阱)这种,否则每次都会重复触发。 NPC对话事件结束后如果需要NPC消失也需要调用 `{"type": "hide"}`,可以不写loc选项代表当前事件,可以指定time使NPC动画消失。 - -``` js +``` json [ {"type": "hide", "loc": [3,6], "floorId": "MT1", "time": 500}, // 禁用MT1层[3,6]位置事件,动画500ms {"type": "hide", "loc": [3,6], "time": 500}, // 如果启用目标是当前层,则可以省略floorId项 @@ -638,7 +495,7 @@ NPC对话事件结束后如果需要NPC消失也需要调用 `{"type": "hide"}` {"type": "hide", "time": 500}, // 如果不指定loc选项则默认为当前点, 例如这个就是500ms消失当前对话的NPC {"type": "hide"}, // 无动画将当前事件禁用,常常适用于某个空地点(触发陷阱事件、触发机关门这种) {"type": "hide", "loc": [3,6], "time": 500, "async": true} // 可以使用异步动画效果 -] +] // 此事件实际直接调用的函数是core.removeBlock(x, y),开门打怪捡道具后也会自动调用此函数 ``` ![](img/events/20.jpg) @@ -648,8 +505,7 @@ NPC对话事件结束后如果需要NPC消失也需要调用 `{"type": "hide"}` `{"type":"trigger"}` 会立刻触发当层另一个地点的自定义事件。 其基本写法如下: - -``` js +``` json [ {"type": "trigger", "loc": [3,6]}, // 立即触发loc位置的事件,当前剩下的事件全部不再执行 {"type": "trigger", "loc": [3,6], "keep": true}, // 触发loc位置的事件,不结束当前事件 @@ -671,8 +527,7 @@ keep可选,如果此项为true则不会结束当前的事件列表,否则会 `{"type":"insert"}` 会插入公共事件或另一个地点的事件并执行。 其基本写法如下: - -``` js +``` json [ {"type": "insert", "name": "加点事件", "args": [10] }, // 插入公共事件:加点事件,传入参数10 {"type": "insert", "name": "毒衰咒处理", "args": [0]}, // 插入公共事件:毒衰咒处理,传入参数0 @@ -697,7 +552,8 @@ keep可选,如果此项为true则不会结束当前的事件列表,否则会 和`type:trigger`不同点如下: - `type:trigger`只能指定当前楼层且会改变当前点坐标,`type:insert`可以跨楼层且不会改变当前点坐标。 - `type:trigger`如果不设置`keep:true`则还会结束当前事件,`type:insert`而是将另一个点的事件插入到当前事件列表中执行。 -- `type:trigger`可以触发系统事件,`type:insert`只能触发该点的自定义事件或战后事件等。 +- `type:trigger`可以触发系统事件,`type:insert`只能触发该点的普通事件或 `afterXxx` 事件等。 +- `type:trigger`要求目标点启用,`type:insert`会无视目标点启用与否。 插入的事件执行完毕后,会继续执行接下来的内容。 @@ -710,33 +566,10 @@ keep可选,如果此项为true则不会结束当前的事件列表,否则会 (`flag:arg0`则会被置为公共事件名称,或者插入的点的坐标) 即可在事件中直接取用`flag:arg1`等等来获得各项参数值!。 - -### revisit:立即重启当前事件 - -revisit和trigger完全相同,只不过是立刻触发的还是本地点的事件 - -``` js -[ - {"type": "revisit"}, // 立即触发本事件,等价于 {"type": "trigger", "loc": [x,y]} - "执行revisit后,这段文字将不会再被显示" -] -``` - -![](img/events/23.jpg) - -revisit其实是trigger的简写,只不过是loc固定为当前点。 - -revisit常常使用在一些商人之类的地方,当用户购买物品后不是离开,而是立刻重新访问重新进入购买页面。 - ### exit:立刻结束当前事件 - -上面说到像商人一类,购买物品后可以立刻revisit重新访问,但是这样就相当于陷入了死循环导致无法离开。 - -可以使用`{"type":"exit"}`立刻结束事件。调用exit后,将立刻结束一切事件,清空事件列表,并返回游戏。 - +可以使用`{"type":"exit"}`立刻结束事件。调用 `exit` 后,将立刻结束一切事件,清空事件列表,并返回游戏。
例如玩家点击商人的"离开"选项,则可以调用exit返回游戏。 - -``` js +``` json [ {"type": "exit" }, // 立即结束事件并恢复游戏,一切列表中的事件都将不再被执行 "执行exit后,这段文字将不会再被显示" @@ -748,11 +581,10 @@ revisit常常使用在一些商人之类的地方,当用户购买物品后不 ### setBlock:设置某个图块 我们可以采用 `{"type": "setBlock"}` 来改变某个地图块。 - -``` js +``` json [ {"type": "setBlock", "floorId": "MT1", "loc": [3,3], "number": 233}, // 将MT1层的(3,3)点变成数字233 - {"type": "setBlock", "loc": [2,1],setVa "number": 121}, // 省略floorId则默认为本层 + {"type": "setBlock", "loc": [2,1], "number": 121}, // 省略floorId则默认为本层 {"type": "setBlock", "number": 57}, // loc也可省略,默认为当前点 {"type": "setBlock", "number": "yellowDoor"}, // 从V2.6开始也允许写图块ID ] @@ -768,87 +600,48 @@ number为**要更改到的数字**,有关“数字”的定义详见参见[素 从V2.6开始,number也允许写图块的ID,将自动转成对应的数字。 +从V2.7开始,还可以指定转变的淡入动画时间,用于该点原本是空地或空气墙的场合,从而避免“仅仅为了做个淡入效果,就去创建了一个本身没有任何指令的普通事件”。
图块更改后: - 其启用/禁用状态不会发生任何改变。原来是启用还是启用,原来是禁用还是禁用。 - - 可通行状态遵循覆盖原则,即**首先取该图块的默认noPass属性,如果剧本的events中定义该点的noPass则覆盖**。 - - 触发器(trigger)亦采用覆盖原则,即**首先取该图块的默认触发器(例如怪物是battle,道具是getItem,门是openDoor),如果剧本的events中定义了该点的trigger则覆盖**。 - + - 可通行状态遵循覆盖原则,即**首先取该图块的 `canPass` 属性(道具和怪物没有此属性,道具可通行,怪物不可通行),如果该点的普通事件中定义了 `noPass` 则覆盖**。 + - 触发器( `trigger` )亦采用覆盖原则,即**首先取该图块的默认触发器(例如怪物是battle,道具是getItem,门是openDoor),如果该点绑定了楼层转换事件(绿)或普通事件(红)中覆盖触发器,则覆盖**。 图块更改往往与[同一个点的多事件处理](#同一个点的多事件处理)相关。 - -### hideFloorImg:隐藏楼层贴图 - -使用`{"type":"hideFloorImg"}`可以隐藏某个楼层的贴图。 - +### showFloorImg / hideFloorImg:显隐楼层贴图 +使用`{"type":"hideFloorImg"}`可以隐藏某个楼层的贴图。使用`{"type":"showFloorImg"}`可以显示楼层的贴图。
有关贴图说明请参见[使用自己的图片作为某层楼的背景/前景素材](personalization#使用自己的图片作为某层楼的背景前景素材)。 - -``` js +``` json [ - {"type": "hideFloorImg", "loc": [3,6], "floorId": "MT1"}, // 隐藏[3,6]的贴图 - {"type": "hideFloorImg", "loc": [3,6]}, // 如果是当前层,则可以省略floorId项 - {"type": "hideFloorImg", "loc": [[3,6],[2,9],[1,2]]} // 我们也可以同时隐藏多个贴图。 + {"type": "hideFloorImg", "loc": [32,64], "floorId": "MT1"}, // 隐藏[32,64]的贴图 + {"type": "hideFloorImg", "loc": [32,64]}, // 如果是当前层,则可以省略floorId项 + {"type": "showFloorImg", "loc": [[32,64],[256,96],[128,256]]} // 我们也可以同时显隐多个贴图。 ] ``` ![](img/events/26.jpg) - -loc为要隐藏的贴图的左上角坐标,可以简单的写[x,y]代表一个点,也可以写个二维数组[[x1,y1],[x2,y2],...]来同时显示多个点。 - -如果同时存在若干个贴图都是是该坐标为左上角,则这些贴图全部会被隐藏。 - +loc为要显隐的贴图的左上角像素坐标,可以简单的写[x,y]代表一个点,或二维数组[[x1,y1],[x2,y2],...]来同时显隐多个点。
+如果同时存在若干个贴图都是是该坐标为左上角,则这些贴图全部会被显隐。
floorId为目标点的楼层,如果是当前楼层可以忽略不写。 - -### showFloorImg:显示楼层贴图 - -使用`{"type":"showFloorImg"}`可以显示某个楼层的贴图。 - -其做法和参数,和隐藏贴图是完全一致的。 - -``` js -[ - {"type": "showFloorImg", "loc": [3,6], "floorId": "MT1"}, // 显示[3,6]的贴图 -] -``` - -### hideBgFgMap:隐藏楼层的某些背景或前景图块 - -使用`{"type":"hideBgFgMap"}`可以隐藏某个楼层的背景或前景图块。 - -从V2.4.1开始,允许绘制三层图层(背景层,事件层和前景层)。使用`hideBgFgMap`可以隐藏背景或前景层中的图块。 - -``` js +### showBgFgMap / hideBgFgMap:显隐楼层的某些背景或前景图块 +使用`{"type":"hideBgFgMap"}`可以隐藏背景或前景图块。使用`{"type":"showBgFgMap"}`可以显示背景或前景图块。
+从V2.4.1开始,允许绘制三层图层(背景层,事件层和前景层)。 +``` json [ {"type": "hideBgFgMap", "name": "bg", "loc": [3,6], "floorId": "MT1"}, // 隐藏MT1层[3,6]的背景层图块 {"type": "hideBgFgMap", "name": "bg", "loc": [3,6]}, // 如果是当前层,则可以省略floorId项 - {"type": "hideBgFgMap", "name": "fg", "loc": [[3,6],[2,9],[1,2]]} // 我们也可以同时隐藏多个贴图。 + {"type": "showBgFgMap", "name": "fg", "loc": [[3,6],[2,9],[1,2]]} // 我们也可以同时显隐多个图块。 ] ``` ![](img/events/27.jpg) name为必选的,且只能是`bg`和`fg`之一,分别代表背景图层和前景图层。 - -loc为要隐藏的贴图的左上角坐标,可以简单的写[x,y]代表一个点,也可以写个二维数组[[x1,y1],[x2,y2],...]来同时显示多个点。 - +
`loc` 为要显隐的图块的坐标,可以简单的写[x,y]代表一个点,也可以写个二维数组[[x1,y1],[x2,y2],...]来同时显示多个点。
floorId为目标点的楼层,如果是当前楼层可以忽略不写。 - -### showBgFgMap:显示楼层贴图 - -使用`{"type":"showFloorImg"}`可以显示某个楼层的贴图。 - -其做法和参数,和隐藏贴图是完全一致的。 - -``` js -[ - {"type": "showBgFgMap", "name": "bg", "loc": [3,6], "floorId": "MT1"}, // 显示MT1层[3,6]的前景层图块 -] -``` - ### setBgFgBlock:设置某个背景或前景层图块 我们可以采用 `{"type": "setBgFgBlock"}` 来改变某个背景或前景层地图块。 - -``` js +``` json [ {"type": "setBgFgBlock", "name": "bg", "floorId": "MT1", "loc": [3,3], "number": 233}, // 将MT1层背景层的(3,3)点变成数字233 {"type": "setBgFgBlock", "name": "bg", "loc": [2,1], "number": 121}, // 省略floorId则默认为本层 @@ -869,8 +662,7 @@ loc为可选的,表示要更改地图块的坐标。如果忽略此项,则 ### setHeroIcon:更改角色行走图 使用`{"type": "setHeroIcon"}`可以更改角色行走图。 - -``` js +``` json [ {"type": "setHeroIcon", "name": "hero2.png"}, // 将勇士行走图改成hero2.png;必须在全塔属性的images中被定义过。 {"type": "setHeroIcon"}, // 如果不加name则恢复最初默认状态 @@ -881,42 +673,23 @@ loc为可选的,表示要更改地图块的坐标。如果忽略此项,则 ![](img/events/29.jpg) name是可选的,代表目标行走图的文件名。 - -!> **目标行走图必须在全塔属性的this.images中被定义过,且宽度必须是128像素(高度不限)。** - +
!> **目标行走图必须在全塔属性的this.images中被定义过,且宽度至少是128像素(高度不限)。**
如果不加name,则恢复默认的角色行走图。 如果你需要同时修改勇士的名称,可以使用`setValue`事件来修改`status:name`,但请注意value必须加单引号,不然会报错。 +如果你需要获取当前的行走图文件名,可以使用 `flags.heroIcon` ,但不要直接修改它。 ### update:立刻更新状态栏和地图显伤 - -如果你需要刷新状态栏和地图显伤,只需要简单地调用 `{"type": "update"}` 即可。 - -### hideStatusBar:隐藏状态栏 - +如果你需要刷新状态栏和地图显伤,只需要简单地调用 `{"type": "update", "doNotCheckAutoEvents": true}` 。 +### showStatusBar / hideStatusBar:显隐状态栏 使用`{"type": "hideStatusBar"}`可以隐藏状态栏。读档或重新开始游戏时,状态栏会重新显示。 - -可以添加`"toolbox": true`来不隐藏竖屏模式下的工具栏。 - -### showStatusBar:显示状态栏 - -使用`{"type": "showStatusBar"}`会重新显示状态栏。 - -### hideHero:隐藏勇士 - -使用`{"type": "hideHero"}`可以隐藏勇士。 - -### showHero:显示勇士 - -使用`{"type": "showHero"}`会重新显示勇士。 - +
可以添加`"toolbox": true`来不隐藏竖屏模式下的工具栏。使用`{"type": "showStatusBar"}`会重新显示状态栏。 +### showHero / hideHero:显隐勇士 +使用`{"type": "hideHero"}`可以隐藏勇士。使用`{"type": "showHero"}`会重新显示勇士。 ### sleep:等待多少毫秒 - -等价于RMXP中的"等待x帧",不过是以毫秒来计算。 - +等价于RPG Maker中的"等待x帧",不过是以毫秒来计算。
基本写法:`{"type": "sleep", "time": xxx}` ,其中xxx为指定的毫秒数。 - -``` js +``` json [ {"type": "sleep", "time": 1000}, // 等待1000ms "等待1000ms后才开始执行这个事件", @@ -924,17 +697,14 @@ name是可选的,代表目标行走图的文件名。 ] ``` -![](img/events/30.jpg) - -默认的等待事件可以被Ctrl跳过,下面两种情况下不可呗跳过: +![](img/events/30.jpg)
默认的等待事件可以被Ctrl跳过,下面两种情况下不可被跳过: - 加上`"noSkip": true`后 - 当前存在尚未执行完毕的异步事件。 ### battle:强制战斗 调用battle可强制与某怪物进行战斗(而无需去触碰到它)。 - -``` js +``` json [ {"type": "battle", "id": "blackKing"}, // 强制战斗黑衣魔王 {"type": "battle", "loc": [2,3]}, // 强制战斗(2,3)点的怪物 @@ -954,8 +724,7 @@ name是可选的,代表目标行走图的文件名。 ### openDoor:开门 调用`{"type":"openDoor"}`可以打开一扇门。 - -``` js +``` json [ {"type": "openDoor", "loc": [3,6], "floorId": "MT1"}, // 打开MT1层的[3,6]位置的门 {"type": "openDoor", "loc": [3,6]}, // 如果是本层则可省略floorId @@ -971,29 +740,23 @@ loc指定门的坐标,floorId指定门所在的楼层ID。如果是当前层 如果loc所在的点既不是门也不是墙壁,则忽略本事件。 -needKey是可选的,如果设置为true则需要钥匙才能打开此门。如果没有钥匙则跳过此事件。 +needKey是可选的,如果设置为true且门在当前楼层则需要钥匙才能打开此门。如果没有钥匙则跳过此事件。 async可选,如果为true则会异步执行(即不等待当前事件执行完毕,立刻执行下一个事件)。 !> needKey仅对当前楼层开门有效!跨楼层的门仍然不需要钥匙即可打开,如有需求请自行判定。 -值得注意的是,如果该点存在开门事件,执行时会**修改当前点坐标**为目标点。 - +值得注意的是,如果该点存在开门后事件,执行时会**修改当前点坐标**为目标点。 ### closeDoor:关门 从V2.6开始提供了关门事件`{"type": "closeDoor"}`,拥有关门动画和对应的音效。 - -``` js +``` json [ {"type": "closeDoor", "id": "yellowDoor", "loc": [3,6]}, // 给(3,6)点关上黄门 {"type": "closeDoor", "id": "specialDoor"}, // 不写loc则视为当前点 ] ``` - -![](img/events/33.jpg) - -id为你要关门的ID,需要是一个合法的门,系统默认只支持如下几种: - +![](img/events/33.jpg)
id为你要关门的ID,需要是一个合法的门,系统自带支持如下几种: ``` yellowDoor, blueDoor, redDoor, greenDoor, specialDoor, steelDoor, yellowWall, blueWall, whiteWall @@ -1008,40 +771,29 @@ async可选,如果为true则会异步执行(即不等待当前事件执行 关门事件需要保证该点是空地,否则将无视此事件。 ### changeFloor:楼层切换 - -在事件中也可以对楼层进行切换。一个比较典型的例子就是TSW中,勇士在三楼的陷阱被扔到了二楼,就是一个楼层切换事件。 - +在事件中也可以对楼层进行切换。一个比较典型的例子就是51层魔塔中,勇士在三楼的陷阱被扔到了二楼,就是一个楼层切换事件。
changeFloor的事件写法大致如下。 - -``` js +``` json [ - {"type": "changeFloor", "floorId": "sample0","loc": [10, 10], "direction": "left", "time": 1000 }, + {"type": "changeFloor", "floorId": "sample0", "loc": [10, 10], "direction": "left", "time": 1000 }, //后面几项依次为楼层id,楼层位置(这两项为必填);勇士方向可选,切换时间也是可选。 ] ``` - -![](img/events/34.jpg) - -可以看到,与上面的楼梯、传送门的写法十分类似。 - -但是相比那个而言,不支持stair楼梯位置(只能写坐标),没有穿透选项。 - +![](img/events/34.jpg)
可以看到,与之前的楼梯、传送门的写法十分类似。 +但是相比那个而言,这个不支持穿透选项。
direction为可选的,指定的话将使勇士的朝向变成该方向 time为可选的,指定的话将作为楼层切换动画的时间。 **如果time指定为小于100,则视为没有楼层切换动画。** - -### changePos:当前位置切换/set勇士转向 - +### changePos:当前位置切换/勇士转向 有时候我们不想要楼层切换的动画效果,而是直接让勇士从A点到B点。 这时候可以用changePos。其参数和changeFloor类似,但少了floorId和time两个选项。 - -``` js +``` json [ {"type": "changePos", "loc": [10,10], "direction": "left"}, // 直接切换勇士的坐标,loc为目标地点,后面勇士换位后方向 - {"type": "changePos", "loc", [10,10]}, // 如无需指定方向则direction可省略 + {"type": "changePos", "loc": [10,10]}, // 如无需指定方向则direction可省略 {"type": "changePos", "direction": "left"} // loc也可省略,只指定direction;此时等价于当前勇士转向到某个方向。 ] ``` @@ -1051,8 +803,7 @@ time为可选的,指定的话将作为楼层切换动画的时间。 ### useItem:使用道具 调用`{"type": "useItem"}`可以使用一个道具。 - -``` js +``` json [ {"type": "useItem", "id": "pickaxe"}, // 尝试使用破 {"type": "useItem", "id": "bomb"}, // 尝试使用炸 @@ -1067,79 +818,37 @@ time为可选的,指定的话将作为楼层切换动画的时间。 如果当前不可使用该道具(如没有,或者达不到使用条件),则会进行提示并跳过本事件。 不可使用“怪物手册”(请使用【呼出怪物手册】事件)或楼层传送器(如果[覆盖楼传事件](personalization#覆盖楼传事件)则可忽视本项)。 - -### loadEquip:装上装备 - -使用`{"type": "loadEquip"}`可以装上一个装备。 - -``` js +### loadEquip / unloadEquip:装脱装备 +使用`{"type": "loadEquip"}`可以装上一个装备。使用`{"type": "unloadEquip"}`卸下某个装备孔的装备。 +``` json [ {"type": "loadEquip", "id": "sword1"}, // 尝试装上铁剑 + {"type": "unloadEquip", "pos": 0}, // 卸下装备孔0的装备 ] ``` id必填,为需要装备的ID。 使用装备时仍会检查条件(比如装备是否存在,能否装备等等)。 - -### unloadEquip:卸下装备 - -使用`{"type": "unloadEquip"}`卸下某个装备孔的装备。 - -``` js -[ - {"type": "unloadEquip", "pos": 0}, // 卸下装备孔0的装备 -] -``` - pos必填,为要卸下的装备孔编号,从0开始。 - -### openShop:打开一个全局商店 - -使用openShop可以打开一个全局商店。有关全局商店的说明可参见[全局商店](#全局商店)。 - -### disableShop:禁用一个全局商店 - -使用disableShop可以永久禁用全局商店直到再次被openShop打开为止。有关全局商店的说明可参见[全局商店](#全局商店)。 - -### follow:跟随勇士 - +### openShop / disableShop:启用或禁用一个全局商店 +使用openShop可以启用一个全局商店。使用disableShop可以永久禁用全局商店直到再次被openShop启用为止。
有关全局商店的说明可参见[全局商店](#全局商店)。 +### follow / unfollow:跟随勇士或取消跟随 使用 `{"type": "follow"}` 可以让一个npc加入跟随。 - -``` js +``` json [ - {"type": "follow", "name": "npc.png"}, // 将 npc.png 这个行走图加入跟随 - {"type": "follow", "name": "hero.png"}, // 再将另一个行走图加入跟随 + {"type": "follow", "name": "npc48.png"}, // 将 npc48.png 这个行走图加入跟随 + {"type": "follow", "name": "enemy48.png"}, // 再将另一个行走图加入跟随 + {"type": "unfollow", "name": "npc48.png"}, // 将第一个 npc48.png 行走图取消跟随 + {"type": "unfollow"} // 不填name,表示取消所有跟随 ] ``` - -name为必须的,是要加入跟随的行走图文件名。 - -name所指定的图片必须存在,在全塔属性中的images中被定义过,且是一个合法的行走图(宽为128像素,高不限。) - -### unfollow:取消跟随 - -使用 `{"type": "unfollow"}` 来取消一个跟随。 - -``` js -[ - {"type": "unfollow", "name": "npc.png"}, // 将 npc.png 这个行走图取消跟随 - {"type": "unfollow"}, // 取消所有跟随 -] -``` - -name为可选的,是要取消跟随的行走图文件名。 - -如果name指定了,则会检查所有当前正在跟随的行走图,并删除第一个文件名是name的跟随效果。 - -如果name省略,则会取消所有的跟随效果。 - +`name` 为要加入或取消跟随的行走图文件名,取消跟随时取第一个,不填则取消所有。
+`name` 所指定的图片必须存在,在全塔属性中的 `images` 中注册,且为一个合法的行走图(宽至少为128像素,高不限) ### vibrate:画面震动 使用 `{"type": "vibrate", "time": 2000, "async": true}` 可以造成画面震动效果。 - -time可以指定震动时间,默认是2000毫秒。 - +
`time` 可以指定震动时间,必须为500毫秒的倍数,且至少要1000毫秒。
async可选,如果为true则会异步执行(即不等待当前事件执行完毕,立刻执行下一个事件)。 ### animate:显示动画 @@ -1147,8 +856,7 @@ async可选,如果为true则会异步执行(即不等待当前事件执行 我们可以使用 `{"type": "animate"}` 来显示一段动画。 有关动画的详细介绍可参见[动画和天气系统](element#动画和天气系统)。 - -``` js +``` json [ {"type": "animate", "name": "yongchang", "loc": [1,3]}, // 在(1,3)显示“咏唱魔法”动画 {"type": "animate", "name": "zone", "loc": "hero"}, // 在勇士位置显示“领域”动画 @@ -1160,20 +868,17 @@ async可选,如果为true则会异步执行(即不等待当前事件执行 ![](img/events/37.jpg) name为动画名,**请确保动画在全塔属性中的animates中被定义过。** - -loc为动画的位置,可以是`[x,y]`表示在(x,y)点显示,也可以是字符串`"hero"`表示在勇士点显示。 - -loc可忽略,如果忽略则显示为事件当前点。 +
loc为动画的位置,可以是`[x,y]`表示在(x,y)点显示,也可以是字符串`"hero"`表示跟随勇士显示(就像踩到血网时)。
+loc可忽略,如果忽略则视为事件当前点。 如果async指定为true,则不会等待动画绘制完毕,立刻执行下个事件。 否则,在动画播放结束后才会继续执行下一个事件。 - +
从V2.7开始,增加了一个勾选项表示该坐标是绝对坐标还是在视野中的相对坐标,譬如13×13样板中,勾选此项并填写坐标 `[6,6]` 就能无视大地图,强制在视野正中心播放动画。 ### showImage:显示图片 我们可以使用 `{"type": "showImage"}` 来显示一张图片。 - -``` js +``` json [ {"type": "showImage", "code": 1, "image": "bg.jpg", "loc": [231,297], "opacity": 1, "time" : 0}, // 在(231,297)显示bg.jpg {"type": "showImage", "code": 12, "image": "1.png", "loc": [209,267], "opacity": 0.5, "time" : 1000}, // 在(209,267)渐变显示1.png,渐变时间为1000毫秒,完成时不透明度为0.5,这张图片将遮盖上一张 @@ -1186,6 +891,8 @@ loc可忽略,如果忽略则显示为事件当前点。 code为图片编号,如果两张图片重叠,编号较大会覆盖编号较小的。该值需要在1~50之间。 +图片编号的真正意义,请参阅[个性化](personalization)。 + image为图片名。**请确保图片在全塔属性中的images中被定义过。** sloc为可选项;如果设置了则是个2或4元组,代表裁剪原始图片的左上角像素位置和宽高。 @@ -1198,11 +905,10 @@ time为渐变时间,默认值为0,即不渐变直接显示。 async可选,如果为true则会异步执行(即不等待当前事件执行完毕,立刻执行下一个事件)。 -### showTextImage:显示文本化图片 +### showTextImage:显示图片化文本 我们可以使用 `{"type": "showTextImage"}` 以图片的方式显示文本。 - -``` js +``` json [ {"type": "showTextImage", "code": 1, "text": "第一排\n第二排\n\n空行后的一排", "loc": [231,297], "opacity": 1, "time" : 0}, // 在(231,297)显示"第一排\n第二排\n\n空行后的一排" ] @@ -1210,7 +916,7 @@ async可选,如果为true则会异步执行(即不等待当前事件执行 code为图片编号,如果两张图片重叠,编号较大会覆盖编号较小的。该值需要在1~50之间。 -text为要显示的文本。默认行宽为416。 +text为要显示的文本。默认行宽为416(15×15样板为480)。 loc为图片左上角坐标,以像素为单位进行计算。 @@ -1227,8 +933,7 @@ async可选,如果为true则会异步执行(即不等待当前事件执行 ### hideImage:清除图片 我们可以使用 `{"type": "hideImage"}` 来清除一张图片。 - -``` js +``` json [ {"type": "hideImage", "code": 1, "time" : 0}, // 使1号图片消失 {"type": "hideImage", "code": 12, "time" : 1000}, // 使12号图片渐变消失,时间为1000毫秒 @@ -1244,8 +949,7 @@ async可选,如果为true则会异步执行(即不等待当前事件执行 ### showGif:显示动图 我们可以使用 `{"type": "showGif"}` 来显示一张图片。 - -``` js +``` json [ {"type": "showGif", "name": "timg.gif", "loc": [231,297]}, // 在(231,297)显示一张动图 {"type": "showGif"} // 如果不指定name则清除所有动图。 @@ -1261,8 +965,7 @@ loc为动图左上角坐标,以像素为单位进行计算。 ### moveImage:图片移动 我们可以使用 `{"type": "moveImage"}` 来造成图片移动,淡入淡出等效果。 - -``` js +``` json [ {"type": "moveImage", "code": 1, "to": [22,333], "opacity": 1, "time": 1000}, // 将1号图片移动到(22,333),动画时间为1000ms {"type": "moveImage", "code": 12, "opacity": 0.5, "time": 500}, // 将二号图片的透明度变为0.5,动画时间500ms @@ -1285,8 +988,7 @@ async可选,如果为true则会异步执行(即不等待当前事件执行 ### setCurtain:更改画面色调 我们可以使用 `{"type": "setCurtain"}` 来更改画面色调。 - -``` js +``` json [ {"type": "setCurtain", "color": [255,255,255,0.6], "time": 1000}, // 更改画面色调为纯白,不透明度0.6,动画时间1000毫秒 {"type": "setCurtain", "color": [0,0,0], "async": true}, // 更改画面色调为纯黑,不透明度1,不指定动画时间(使用默认时间),且异步执行 @@ -1306,11 +1008,11 @@ time为可选的,如果指定,则会作为更改画面色调的时间。 async可选,如果为true则会异步执行(即不等待当前事件执行完毕,立刻执行下一个事件)。 +从V2.7开始,色调、天气和bgm的更改都提供了“持续到下个本事件”勾选项,勾选此项后,设置的结果将分别计入 `flags.__color__ , flags.__weather__ , flags.__bgm__` ,也会计入存档,并无视楼层切换带来的色调、天气和bgm变化,直到再次遇到本事件。但您也可以随时手动干预或清除这三个 `flag` ### screenFlash:画面闪烁 我们可以使用 `{"type": "screenFlash"}` 来进行画面闪烁。 - -``` js +``` json [ {"type": "screenFlash", "color": [255,255,255,0.6], "time": 500, "times": 1}, // 闪光为白色,不透明度0.6,动画时间1000毫秒 {"type": "screenFlash", "color": [255,0,0,1], "time": 100, "times": 2, "async": true}, // 闪光为红色,强度最大,动画时间100毫秒,闪烁两次且异步执行 @@ -1330,58 +1032,51 @@ async可选,如果为true则会异步执行(即不等待当前事件执行 ### setWeather:更改天气 我们可以使用 `{"type": "setWeather"}` 来更改天气。 - -``` js +``` json [ {"type": "setWeather", "name": "rain", "level": 6}, // 更改为雨天,强度为6级 {"type": "setWeather", "name": "snow", "level": 3}, // 更改为雪天,强度为3级 {"type": "setWeather"} // 更改回晴天 ] ``` - -name为天气选项。目前只支持`rain`和`snow`,即雨天和雪天。 - -从V2.5.3开始,也支持雾天`fog`。 +name为天气名。起初只支持 `rain` 和 `snow` ,即雨天和雪天。从V2.5.3开始,也支持雾天 `fog` level为天气的强度等级,在1-10之间。1级为最弱,10级为最强。 如果想改回晴天则直接不加任何参数。 - -!> 使用setWeather更改的天气在切换地图后会被目标地图的默认天气覆盖。 - ### move:让某个NPC/怪物移动 如果我们需要移动某个NPC或怪物,可以使用`{"type": "move"}`。 下面是该事件常见的写法: - -``` js +``` json [ - {"type": "move", "time": 750, "loc": [x,y], "steps": [// 动画效果,time为移动速度(比如这里每750ms一步),loc为位置可选,steps为移动数组 + {"type": "move", "time": 750, "loc": [x,y], "steps": [ + // 动画效果,time为移动和淡出速度(比如这里每750ms一步),loc为位置可选,steps为移动数组 "right", "right", "down" // 向右两格,向下一格 ], "keep": true, "async":true }, // keep可选,如果为true则不消失,否则渐变消失;async可选,如果为true则异步执行。 ] ``` ![](img/events/41.jpg) - -time选项必须指定,为每移动一步所需要用到的时间。 +
time选项必须指定,为每移动一步和淡出所需要用到的时间。 loc为需要移动的事件位置。可以省略,如果省略则移动本事件。 steps为一个数组,其每一项是`up, down, left, right`之一,表示这一步应该朝哪个方向走。 +对于有 `faceIds` 的NPC,也支持 `forward, backward` ,表示前进和后退 + keep为一个可选项,代表该事件移动完毕后是否消失。如果该项指定了并为true,则移动完毕后将不消失,否则以动画效果消失。 值得注意的是,当调用move事件时,实际上是使事件脱离了原始地点。为了避免冲突,规定:move事件会自动调用该点的hide事件。 换句话说,当move事件被调用后,该点本身的事件将被禁用。 -如果指定了`"keep": true`,则相当于会在目标地点触发一个`setBlock`事件;如需能继续对话交互请在目标地点再写事件。 - +如果指定了 `"keep": true` ,则相当于会在目标地点触发一个 `setBlock` 和一个 `show` 事件;
如需能继续对话交互请在目标地点再写事件。
+阻击属性的移动效果就是这样,推箱子和阻击类似但目标点只 `setBlock` 不 `show` ,请自行注意可能的隐患。
如果想让move后的NPC/怪物仍然可以被交互,需采用如下的写法: - -``` js +``` json "4,3": [ // [4,3]是一个NPC,比如小偷 {"type": "move", "time": 750, "steps": [ // 向上移动两格,每步750毫秒 "up", "up" @@ -1406,8 +1101,7 @@ async可选,如果为true则会异步执行(即不等待当前事件执行 如果我们需要移动勇士,可以使用`{"type": "moveHero"}`。 下面是该事件常见的写法: - -``` js +``` json "x,y": [ // 实际执行的事件列表 {"type": "moveHero", "time": 750, "async": true, "steps": [// 动画效果,time为移动速度(比如这里每750ms一步),steps为移动数组 "down", "right", "forward", "backward" // 向下、右、前、后各走一步 @@ -1422,20 +1116,27 @@ async可选,如果为true则会异步执行(即不等待当前事件执行 不过值得注意的是,用这种方式移动勇士的过程中将无视一切地形,无视一切事件,中毒状态也不会扣血。 async可选,如果为true则会异步执行(即不等待当前事件执行完毕,立刻执行下一个事件)。 - +### moveAction:移动一步 +如果我们需要像事件外一样移动一步,可以使用`{"type": "moveAction"}`。 +下面是该事件常见的写法: +``` json +"x,y": [ // 实际执行的事件列表 + {"type": "moveAction", "time": 750, "direction": "forward"} +] +``` +`time` 可选,为移动的用时,单位是毫秒,不填则取玩家设置值。`direction` 可选,为移动的方向,不填则取 `forward`
+用这种办法移动时会检查通行性,也会正常触发阻激夹域捕和地形效果,如果不可通行则会去撞击(如开门打怪) ### jump:让某个NPC/怪物跳跃 如果我们需要移动某个NPC或怪物,可以使用`{"type": "jump"}`。 下面是该事件常见的写法: - -``` js +``` json [ {"type": "jump", "from": [3,6], "to": [2,1], "time": 750, "keep": true, "async": true}, ] ``` - -from为需要跳跃的事件位置。可以省略,如果省略则移动本事件。 +from为需要跳跃的事件起点。可以省略,如果省略则跳跃本事件。 to为要跳跃到的坐标。可以省略,如果省略则跳跃到当前坐标。 @@ -1443,7 +1144,8 @@ time选项必须指定,为全程跳跃所需要用到的时间。 keep为一个可选项,同上代表该跳跃完毕后是否不消失。如果该项指定了并为true,则跳跃完毕后不会消失,否则以动画效果消失。 -如果指定了`"keep": true`,则相当于会在目标地点触发一个`setBlock`事件;如需能继续对话交互请在目标地点再写事件。 +如果指定了`"keep": true`,则相当于会在目标地点触发一个 `setBlock` 和一个 `show` 事件;
+和移动一样,如需能继续对话交互请在目标地点再写事件。 async可选,如果为true则会异步执行(即不等待当前事件执行完毕,立刻执行下一个事件)。 @@ -1452,8 +1154,7 @@ async可选,如果为true则会异步执行(即不等待当前事件执行 如果我们需要跳跃勇士,可以使用`{"type": "jumpHero"}`。 下面是该事件常见的写法: - -``` js +``` json [ {"type": "jump", "loc": [3,6], "time": 750, "async": true}, ] @@ -1470,13 +1171,13 @@ async可选,如果为true则会异步执行(即不等待当前事件执行 使用playBgm可以播放一个背景音乐。 使用方法:`{"type": "playBgm", "name": "bgm.mp3"}` - -值得注意的是,额外添加进文件的背景音乐,需在main.js中this.bgms里加载它。 - -目前支持mp3/ogg/wav等多种格式的音乐播放。 +
音乐文件放在 `project\sounds` 文件夹,文件名在全塔属性中注册,不得使用中文。
+目前支持 `mp3/ogg/wav/flac/m4r` 等多种格式的音乐播放,不支持 `mid` 格式。 从V2.6.3开始,还提供了keep项。如果此项为真,则会记录该bgm,并且持续到下次调用本事件位置(楼层切换不改变bgm,读档也有效)。 +从V2.7开始,还提供了“从第几秒开始”的参数,可加以利用。 + 有关BGM播放的详细说明参见[背景音乐](element#背景音乐) ### pauseBgm:暂停背景音乐 @@ -1487,6 +1188,7 @@ async可选,如果为true则会异步执行(即不等待当前事件执行 使用`{"type": "resumeBgm"}`可以恢复背景音乐的播放。 +从V2.7开始,还提供了一个勾选项,您可以选择从上次暂停的位置继续播放。 ### loadBgm:预加载一个背景音乐 使用loadBgm可以预加载一个背景音乐。 @@ -1506,9 +1208,7 @@ async可选,如果为true则会异步执行(即不等待当前事件执行 使用playSound可以立刻播放一个音效。 使用方法:`{"type": "playSound", "name": "item.mp3"}` - -值得注意的是,如果是额外添加进文件的音效,则需在main.js中this.sounds里加载它。 - +
音乐文件放在 `project\sounds` 文件夹,文件名在全塔属性中注册,不得使用中文。
从V2.6开始,也可以加`"stop": true`来停止之前正在播放的音效。 ### stopSound:停止所有音效 @@ -1524,27 +1224,23 @@ async可选,如果为true则会异步执行(即不等待当前事件执行 使用方法: `{"type": "setVolume", "value": 90, "time": 500, "async": true}` ![](img/events/43.jpg) - -value为音量大小,在0到100之间,默认为100。设置后,BGM将使用该音量进行播放。SE的音量大小不会发生改变。 +
`value` 为音量大小,在0到100之间(玩家设置值为这个值的平方根),默认为100。设置后,BGM将使用该音量进行播放。SE的音量大小不会发生改变。 可以设置time为音量渐变时间。 async可选,如果为true则会异步执行(即不等待当前事件执行完毕,立刻执行下一个事件)。 ### win:获得胜利 - -`{"type": "win", "reason": "xxx"}` 将会直接调用events.js中的win函数,并将reason作为结局传入。 - +`{"type": "win", "reason": "xxx"}` 将会直接调用脚本编辑中的 `win` 函数,并将 `reason` 作为结局传入。
该事件会显示获胜页面,并重新游戏。 可以增加`"norank": 1`来表示该结局不计入榜单。 !> 如果`reason`不为空,则会以reason作为获胜的结局! +从V2.6.6起,也提供了一个“不结束游戏”勾选项(但录像依然会停止录制),您可以勾选它然后做一些结局演出。 ### lose:游戏失败 - -`{"type": "lose", "reason": "xxx"}` 将会直接调用`events.js`中的lose函数,并将reason作为参数传入。 - +`{"type": "lose", "reason": "xxx"}` 将会直接调用脚本编辑中的lose函数,并将reason作为参数传入。
该事件会显示失败页面,并重新开始游戏。 ### restart:直接回到标题界面 @@ -1576,8 +1272,7 @@ async可选,如果为true则会异步执行(即不等待当前事件执行 ### input:接受用户输入数字 使用`{"type": "input"}`可以接受用户的输入的数字。 - -``` js +``` json [ {"type": "input", "text": "请输入一个数"}, // 显示一个弹窗让用户输入数字 "你刚刚输入的数是${flag:input}" // 输入结果将被赋值为flag:input @@ -1589,16 +1284,13 @@ async可选,如果为true则会异步执行(即不等待当前事件执行 text为提示文字,可以在这里给输入提示文字。这里同样可以使用${ }来计算表达式的值。 当执行input事件时,将显示一个弹窗,并提示用户输入一个内容。 - -!> 该事件只能接受非负整数输入,所有非法的输入将全部变成`0`。例如用户在输入框内输入“你好”或者-3,都将实际得到0。 - +
!> 该事件只能接受非负整数输入,所有非法的输入将全部变成 `0` 。例如用户输入“你好”或者 `-3` ,都将实际得到 `0` 。
输入得到的结果将被赋值给flag:input,可以供后续if来进行判断。 ### input2:接受用户输入文本 类似于input事件,使用`{"type": "input2"}`可以接受用户的输入的文本。 - -``` js +``` json [ {"type": "input2", "text": "请输入你的ID"}, // 显示一个弹窗让用户输入文本 "你好,${flag:input},欢迎来到本塔" // 输入结果将被赋值为flag:input @@ -1616,12 +1308,8 @@ text为提示文字,可以在这里给输入提示文字。这里同样可以 输入得到的结果也将被赋值给flag:input,可以供后续使用。 ### if:条件判断 - -使用`{"type": "if"}`可以对条件进行判断,根据判断结果将会选择不同的分支执行。 - -其大致写法如下: - -``` js +使用`{"type": "if"}`可以对条件进行判断,根据判断结果将会选择不同的分支执行。其大致写法如下: +``` json [ {"type": "if", "condition": "...", // 测试某个条件 "true": [ // 条件成立则执行true里面的事件 @@ -1633,16 +1321,14 @@ text为提示文字,可以在这里给输入提示文字。这里同样可以 }, ] ``` - -我们可以在condition中给出一个表达式(能将`status:xxx, item:xxx, flag:xxx`来作为参数),并进行判断是否成立。 +我们可以在condition中给出一个表达式(能将`status:xxx, item:xxx, flag:xxx`等来作为参数),并进行判断是否成立。 如果条件成立,则将继续执行`"true"`中的列表事件内容。 如果条件不成立,则将继续执行`"false"`中的列表事件内容。 例如下面这个例子,每次将检查你的攻击力是否大于500,不是的场合将给你的攻击力加100点。 - -``` js +``` json [ {"type": "if", "condition": "status:atk>500", // 判断攻击力是否大于500 "true": [ // 条件成立则执行true里面的事件 @@ -1651,11 +1337,11 @@ text为提示文字,可以在这里给输入提示文字。这里同样可以 ], "false": [ // 条件不成立则执行false里的事件 "你当前攻击力为${status:atk}, 不足500!\n给你增加100点攻击力!", - {"type": "setValue", "name": "status:atk", "operator": "+=", "value": "100"}, // 攻击力加100, 接着会执行revisit事件 - ] + {"type": "setValue", "name": "status:atk", "operator": "+=", "value": "100"}, + ] // 攻击力加100, 接着会执行trigger事件 }, - {"type", "revisit"}, // 立刻重启本事件, 直到攻击力大于500后结束 -] + {"type": "trigger", "loc": ["core.nextX()","core.nextY()"]} +] // 立刻重新触发勇士面前的本事件, 直到攻击力大于500后结束 ``` ![](img/events/46.jpg) @@ -1663,8 +1349,9 @@ text为提示文字,可以在这里给输入提示文字。这里同样可以 需要额外注意的几点: - 给定的表达式(condition)一般需要返回true或false。 +- `0、null、undefined、NaN`、空字符串,也会被理解为 `false` - `flag:xxx` 可取用一个自定义变量或flag。如果从未设置过该flag,则其值默认为0。 -- 即使成功失败的场合不执行事件,对应的true或false数组也需要存在,不过简单的留空就好。 +- 即使条件成立的场合不执行事件,对应的 `true` 数组也需要存在,不过简单的留空就好。 - if可以不断进行嵌套,一层套一层;如成立的场合再进行另一个if判断等。 - if语句内的内容执行完毕后将接着其后面的语句继续执行。 @@ -1674,20 +1361,19 @@ text为提示文字,可以在这里给输入提示文字。这里同样可以 使用`{"type": "switch"}`可以比较判别值和不同分支的条件,根据判断结果选择不同的分支执行。 其大致写法如下: - -``` js +``` json [ {"type": "switch", "condition": "...", // 计算某个表达式 "caseList": [ {"case": "a", "action": [// 若表达式的值等于a则执行该处事件 - ], + ]}, {"case": "b", "nobreak": true, "action": [// 若表达式的值等于b则执行该处事件,不跳出 - ], + ]}, {"case": "default", "action": [ // 没有条件成立则执行该处里的事件 - ] + ]} ] }, ] @@ -1699,11 +1385,10 @@ text为提示文字,可以在这里给输入提示文字。这里同样可以 如果没有符合的值,则将执行`default`中的列表事件内容。 -nobreak是可选的,如果设置,则在当前条件满足并插入事件后,不跳出多重分歧,而是继续判定下一个条件。 +nobreak是可选的,如果设置,则在当前条件满足并插入事件后,不跳出多重分歧,而是无视接下来的一切条件,挨个插入事件,直到插入完一组没有nobreak的事件,或抵达多重分歧的最底部。 例如下面这个例子,将检查当前游戏难度并赠送不同属性。 - -``` js +``` json [ {"type": "switch", "condition": "flag:hard", // 判断当前游戏难度 "caseList": [ @@ -1711,15 +1396,15 @@ nobreak是可选的,如果设置,则在当前条件满足并插入事件后 "当前为简单难度,赠送100点攻防!", {"type": "setValue", "name": "status:atk", "value": "status:atk+100"}, {"type": "setValue", "name": "status:def", "value": "status:def+100"}, - ], + ]}, {"case": "1", "action": [// 若表达式的值等于1则执行该处事件 "当前为普通难度,赠送50点攻防!", {"type": "setValue", "name": "status:atk", "value": "status:atk+50"}, {"type": "setValue", "name": "status:def", "value": "status:def+50"}, - ], + ]}, {"case": "default", "action": [ // 其他难度下不赠送属性 - ] + ]} ] }, ] @@ -1736,20 +1421,19 @@ nobreak是可选的,如果设置,则在当前条件满足并插入事件后 - switch语句内的内容执行完毕后将接着其后面的语句继续执行。 另外由于`case`中的内容是会被计算的,因此如下写法也是合法的 - -```js +```json [ {"type": "switch", "condition": "true", // 条件:某一项为真时 "caseList": [ {"case": "flag:a==1", "action": [ // 如果 flag:a == 1 "走进了 flag:a==1 分支!" - ], - {"case": "flag:b>=3", "action": [ // 如果 flag:b >= 3 - "走进了 flag:b>=3 分支!" - ], - {"case": "default", "action": [ // 上述两条均布成立 + ]}, + {"case": "flag:b>=3", "action": [ // 如果 flag:a != 1 && flag:b >= 3 + "走进了 flag:a!=1 && flag:b>=3 分支!" + ]}, + {"case": "default", "action": [ // 上述两条均不成立 "上述两条均不成立" - ] + ]} ] }, ] @@ -1763,11 +1447,10 @@ choices是一个很麻烦的事件,它将弹出一个列表供用户进行选 当用户做出了不同的选择,可以有着不同的分支处理。 -其完全类似于RMXP中的"显示选择项","XX的场合",只不过同样是需要使用数组来定义。 +其完全类似于RPG Maker中的"显示选择项","XX的场合",只不过同样是需要使用数组来定义。 其大致写法如下: - -``` js +``` json [ {"type": "choices", "text": "...", // 提示文字 "choices": [ @@ -1797,13 +1480,13 @@ color为可选的,可以是一个字符串(#FF0000),或者一个RGBA数 icon是可选的,如果设置则会在选项前绘制图标,其可以是一个有效的ID,或者`core.statusBar.icons`中的系统图标。 -选项可以有任意多个,但一般不要超过6个,否则屏幕可能塞不下。 +选项可以有任意多个(没有提示信息时最多为13或15个),但一般不要超过6个,否则屏幕可能塞不下。 +从V2.6.3开始,每个子选项允许附加一个“出现条件”,从而做出类似“怒气值满才显示开大招按钮”的效果。 ### confirm:显示确认框 `{"type": "confirm"}`将提供一个确认框供用户选择,其基本写法如下: - -```js +```json [ {"type": "confirm", "text": "...", // 提示文字 "default": false, // 是否默认选中【确定】 @@ -1825,13 +1508,11 @@ default可选,如果为true则显示选择项时默认选中【确定】,否 yes和no均为必填项,即用户点击确认或取消后执行的事件。 +从V2.7开始,“选择项”、“确认框”和后面要讲的“等待用户操作”事件,都允许提供一个限制时间,效果是如果玩家在若干毫秒内不做出选择,就视为什么都没选,并继续后面的事件。 +
您可以使用这个功能去制作如《新新魔塔2》那样的QTE战斗。 ### while:前置条件循环 - -从2.2.1样板开始,我们提供了循环处理(while事件)。 - -其大致写法如下: - -``` js +从V2.2.1开始,我们提供了循环处理( `while` 事件)。其大致写法如下: +``` json [ {"type": "while", "condition": "...", // 循环测试某个条件 "data": [ // 条件成立则执行data里面的事件 @@ -1840,16 +1521,9 @@ yes和no均为必填项,即用户点击确认或取消后执行的事件。 }, ] ``` - -我们可以在condition中给出一个表达式(能将`status:xxx, item:xxx, flag:xxx`来作为参数),并进行判断是否成立。 - -如果条件成立,则将执行`"data"`中的列表事件内容。 - -该事件列表执行完毕后,将继续测试`"condition"`,如果还为true则重新进行执行data内容。 - -下面是一个输出1到10之间的数字,每隔1秒显示一个的例子。 - -``` js +它和 `if` 事件非常相似,最大的区别是,每次 `data` 事件列表执行完毕后,都将再次测试 `condition` , +
如果还为 `true` ,则将再次执行 `data` 的内容。下面是一个输出1到10之间的数字,每隔1秒显示一个的例子。 +``` json [ {"type":"while", "condition": "flag:i<=10", // 循环处理;注意flag未设置则默认为0 "data":[ @@ -1864,26 +1538,47 @@ yes和no均为必填项,即用户点击确认或取消后执行的事件。 ![](img/events/49.jpg) ### dowhile:后置条件循环 - -`type:dowhile`可以制作一个后置条件循环。 - -其写法与参数和`type:while`完全一致,不过与其不同的是,会先执行一次事件列表,再对条件进行判定,就和C/C++中的 `do {...} while (...);` 语法一样。 - +`type:dowhile`可以制作一个后置条件循环。其写法与参数和 `type:while` 完全一致,不过与其不同的是,
+会先执行一次事件列表(即首次执行是无条件的),再对条件进行判定,和脚本中的 `do {...} while (...);` 一样。 ![](img/events/50.jpg) +### for:计数循环 +从V2.7开始,`type:for` 可以制作一个计数循环,其基本写法为: +``` json +[ + {"type": "for", "name": "temp:A-Z", "from": "...", "to": "...", "step": "...", "data": [ + // 可以在这里引用临时变量A-Z,循环执行一些内容 + ]}, +] +``` +其中 `name` 为循环的计数器,只能使用临时变量 `A-Z` ,`from` 和 `to` 为两个表达式,表示计数器的初始值和边界值 -### break:跳出循环 +`step` 为每轮循环结束后计数器的增量,也允许填表达式甚至负数,填负数的话 `from` 当然就要比 `to` 更大或相等了。 -使用 `{"type": "break"}` 可以跳出当前循环。 +当计数器以正步长越过(即大于)边界值时,循环终止;当计数器以负步长越过(即小于)边界值时,循环也终止。 -!> 如果break事件不在任何循环中被执行,则和exit等价,即会立刻结束当前事件! +下面是13×13小地图中,模拟大黄门钥匙的使用效果: +![大黄门钥匙](./img/bigKey.png) +### forEach:数组迭代 +从V2.7开始,`type: forEach` 可以循环迭代一个数组,逐项读取其每个元素,其基本写法为: +``` json +[ + {"type": "forEach", "name": "temp:A-Z", "list": [..., ..., ..., ...], "data": [ + // 可以在这里引用临时变量A-Z,循环执行一些内容 + ]}, +] +``` +和 `for` 一样只能使用临时变量,实际执行时,每轮循环会从 `list` 的开头移除第一项,代入临时变量,直到 `list` 变空。 -### continue:继续执行当前循环 - -使用 `{"type": "continue"}` 可以继续执行当前循环。 - -上面的输出例子也可以这么写: - -``` js +要注意的是,`list` 中的字符串不会被自动解释为那些带冒号的缩写量,你需要手动调用 `core.calValue()` 去求值: +![数组迭代](./img/forEach.png) +这个事件会让勇士说出“我的`status:atk`属性为`10`”这样的句子。 +### break:跳出当前循环或公共事件 +使用 `{"type": "break"}` 可以跳出当前循环或公共事件。
+跳出公共事件的原理是,公共事件实际上是作为一个“条件为 `false` 的后置条件循环”去执行的。
+!> 如果break事件不在任何循环或公共事件中被执行,则和exit等价,即会立刻结束当前事件! +### continue:提前结束本轮循环 +使用 `{"type": "continue"}` 可以提前结束本轮循环。上面的输出例子也可以这么写: +``` json [ {"type":"while", "condition": "true", // 循环处理;永远为真 "data":[ @@ -1891,7 +1586,7 @@ yes和no均为必填项,即用户点击确认或取消后执行的事件。 "${flag:i}", // 输出i {"type": "sleep","time":1000}, // 等待1秒 {"type": "if", "condition": "flag:i<10", // 测试i是否小于10 - "true": [{"type": "continue"}], // 是的,则继续循环 + "true": [{"type": "continue"}], // 是,提前结束本轮循环,避免被后面的break跳出 "false": [] }, {"type": "break"}, // 跳出循环 @@ -1901,9 +1596,7 @@ yes和no均为必填项,即用户点击确认或取消后执行的事件。 ``` ![](img/events/51.jpg) - -!> 如果continue事件不在任何循环中被执行,则和exit等价,即会立刻结束当前事件! - +
!> 如果continue事件不在任何循环或公共事件中被执行,则和exit等价,即会立刻结束当前事件! ### wait:等待用户操作 使用 `{"type": "wait"}` 可以等待用户进行操作(如点击、按键等)。 @@ -1914,8 +1607,7 @@ yes和no均为必填项,即用户点击确认或取消后执行的事件。 下面是一个while事件和wait合并使用的例子,这个例子将不断接收用户的点击或按键行为,并输出该信息。 如果用户按下了ESC或者点击了屏幕正中心,则退出循环。 - -``` js +``` json [ {"type": "while", "condition": "true", // 永久循环 "data": [ @@ -1944,12 +1636,11 @@ yes和no均为必填项,即用户点击确认或取消后执行的事件。 ![](img/events/52.jpg) 从V2.6.6开始,也允许直接在`type:wait`中增加`data`项判定按键或点击坐标。 - -```js +```json [ {"type": "wait", "data": [ - {"case": "keyboard", "keycode": 13, "action": [ - {"type": "comment", "text": "当按下回车(keycode=13)时执行此事件"}, + {"case": "keyboard", "keycode": "13,32", "action": [ + {"type": "comment", "text": "按下回车(keycode=13)或空格(keycode=32)时执行此事件"}, ]}, {"case": "mouse", "px": [0,32], "py": [0,32], "action": [ {"type": "comment", "text": "当点击地图左上角时执行此事件"}, @@ -1966,8 +1657,7 @@ yes和no均为必填项,即用户点击确认或取消后执行的事件。 action为如果满足该条件时应该执行的事件列表。 - - +从V2.7开始,提供了“限制时间”,如果玩家在若干毫秒内不做出响应,就会跳过这些场合,直接继续执行后面的事件。 ### waitAsync:等待所有异步事件执行完毕 上面有很多很多的异步事件(也就是执行时不等待执行完毕)。 @@ -1994,8 +1684,7 @@ action为如果满足该条件时应该执行的事件列表。 UI绘制事件。 `{"type": "clearMap"}`可以清除`uievent`画布的内容。 - -```js +```json [ {"type": "clearMap", "x": 0, "y": 0, "width": "flag:width", "height": 416}, // 清除画布的一部分 {"type": "clearMap"}, // 清空并删除画布 @@ -2011,8 +1700,7 @@ x, y, width, height均可选,表示要清除的坐标和长宽。也可以使 UI绘制事件。 此项可以设置`uievent`画布的各项属性。 - -```js +```json [ {"type": "setAttribute", "font": "17px Verdana", "fillStyle": [255,0,0,1]}, ] @@ -2025,7 +1713,7 @@ UI绘制事件。 - `lineWidth`:线宽度,必须是正整数 - `alpha`:不透明度,必须是0到1之间的浮点数 - `align`:对齐方式,只能是`left`, `center`, `right`,分别代表左对齐,居中和右对齐 -- `baseline`:基准线,只能是`top`, `middle`, `alphabetic`, `bottom`,分别代表顶部,居中,标准值和底部。 +- `baseline`:基准线,只能是`top`, `middle`, `alphabetic`, `bottom`, `ideographic`, `hanging`,分别代表顶部,居中,标准值、底部、中文和悬挂。 - `z`:画布的z值,必须是正整数。初始创建时画布的z值是135。请注意,闪烁光标所在画布的z值永远比该画布大1。 ### fillText:绘制文本 @@ -2033,10 +1721,9 @@ UI绘制事件。 UI绘制事件。 此项可以绘制一行文本。 - -```js +```json [ - {"type": "fillText", "text":"要绘制的文本", "x": 10, "y": 20, "maxWidth": 50} + {"type": "fillText", "text": "要绘制的文本", "x": 10, "y": 20, "maxWidth": 50} ] ``` @@ -2055,10 +1742,9 @@ maxWidth可选,如果设置且不为0,则代表要绘制的最大宽度; UI绘制事件。 此项可以绘制一行描边文本。 - -```js +```json [ - {"type": "fillText", "text":"要绘制的描边文本", "x": 10, "y": 20, "style": [255,0,0,1]} + {"type": "fillText", "text":"要绘制的描边文本", "x": 10, "y": 20, "style": [255,0,0,1]} ] ``` @@ -2070,15 +1756,15 @@ style可选,如果设置需要是三元组RGB或四元组RBGA,代表绘制 font可选,如果设置则是要绘制的字体。 +从V2.7开始,可以选择描边的颜色,初始为黑色。描边原理是先用描边色绘制4份一样的偏移文本,再以文本色覆盖。 ### drawTextContent:绘制多行文本 UI绘制事件。 此项可以绘制多行文本。 - -```js +```json [ - {"type": "drawTextContent", "text":"要绘制的多行文本", "left": 10, "top": 20, "maxWidth": 100} + {"type": "drawTextContent", "text": "要绘制的多行文本", "left": 10, "top": 20, "maxWidth": 100} ] ``` @@ -2099,12 +1785,9 @@ fontSize可选,为字体大小,如果不设置则使用剧情文本设置中 lineHeight可选,绘制的行距值,如果不设置则使用fontSize*1.3(即1.3倍行距)。 此项不支持字体样式的设置,使用的是全塔属性中的全局字体;如有需要请使用“设置全局属性”事件来设置字体样式。 - -### fillRect:绘制矩形 - -UI绘制事件。此项可以绘制一个矩形。 - -```js +### fillRect:绘制实心矩形 +UI绘制事件。此项可以绘制一个实心矩形。 +```json [ {"type": "fillRect", "x": 100, "y": 100, "width": 120, "height": 120, "style": [255,0,0,1]} ] @@ -2113,12 +1796,9 @@ UI绘制事件。此项可以绘制一个矩形。 x, y, width, height必填,为要绘制的起点坐标和宽高;也可以用`flag:xxx`。 color可选,表示绘制时的颜色,为三元组RGB或四元组RGBA。 - -### strokeRect:绘制矩形边框 - -UI绘制事件。此项可以绘制一个矩形边框。 - -```js +### strokeRect:绘制空心矩形 +UI绘制事件。此项可以绘制一个空心矩形。 +```json [ {"type": "strokeRect", "x": 100, "y": 100, "width": 120, "height": 120, "style": [255,0,0,1], "lineWidth": 4} ] @@ -2131,10 +1811,8 @@ style可选,表示绘制时的颜色,为三元组RGB或四元组RGBA。 lineWidth可选,表示边框的线宽。 ### drawLine:绘制线段 - -UI绘制事件。此事件可以绘制一个函数。 - -```js +UI绘制事件。此事件可以绘制一条直线段,循环使用的话您甚至可以画出带渐变色的复杂曲线。 +```json [ {"type": "drawLine", "x1": 0, "y1": 0, "x2": "flag:x", "y2": 200, "style": [255,0,0,1]} ] @@ -2146,18 +1824,17 @@ style可选,表示绘制时的颜色,为三元组RGB或四元组RGBA。 lineWidth可选,表示边框的线宽。 +下面是一个循环绘制直线段形成抛物线的例子:
+`for (var x = 0; x < 20; ++x) core.drawLine('ui', x * 20, x * x, (x + 1) * 20, (x + 1) ** 2)` ### drawArrow:绘制箭头 UI绘制事件。此事件可以绘制一个箭头。 参数和写法与`drawLine`完全一致,只不过是会多画一个箭头标记。 - -### fillPolygon:绘制多边形 - +### fillPolygon:绘制实心多边形 UI绘制事件。此事件可以绘制一个多边形。 - -```js -[ +```json +[ // 实际绘制原理是把顶点依次用直线段连起来,因此请自行注意顶点的顺序 {"type": "fillPolygon", "nodes": [[0,0],[0,100],[100,0]], "style": [255,0,0,1]} ] ``` @@ -2165,18 +1842,13 @@ UI绘制事件。此事件可以绘制一个多边形。 nodes必填,为一个二维数组,其中每一项都是多边形一个顶点坐标。(与显示/隐藏事件写法相同) style可选,表示绘制时的颜色,为三元组RGB或四元组RGBA。 - -### strokePolygon:绘制多边形边框 - +### strokePolygon:绘制空心多边形 UI绘制事件。此事件可以绘制一个多边形边框。 参数列表和`fillPolygon`基本相同,不过多了一个`lineWidth`表示的绘制线宽。 - -### fillCircle:绘制圆 - -UI绘制事件。此项可以绘制一个圆。 - -```js +### fillCircle:绘制实心圆盘 +UI绘制事件。此项可以绘制一个圆 +```json [ {"type": "fillCircle", "x": 100, "y": 100, "r": 10, "style": [255,0,0,1]} ] @@ -2185,18 +1857,20 @@ UI绘制事件。此项可以绘制一个圆。 x, y, r必填,为要绘制的圆心和半径;也可以用`flag:xxx`。 color可选,表示绘制时的颜色,为三元组RGB或四元组RGBA。 - -### strokeCircle:绘制圆边框 - +### strokeCircle:绘制空心圆环 UI绘制事件。此项可以绘制一个圆边框。 参数列表和`fillCircle`基本相同,不过多了一个`lineWidth`表示的绘制线宽。 +如果您需要绘制椭圆,可以使用参数方程。譬如: +``` js +for(var x = 0; x < 6.28; x += .01) + core.drawLine('ui', 208 + 200 * Math.cos(x), 208 + 100 * Math.sin(x), 208 + 200 * Math.cos(x + .01), 208 + 100 * Math.sin(x + .01)) +``` ### drawImage:绘制图片 UI绘制事件。此事件可以绘制一个图片。 - -```js +```json [ {"type": "drawImage", "image": "bg.jpg", "x": 0, "y": 0}, // 在(0,0)绘制bg.jpg {"type": "drawImage", "image": "bg.jpg", "x": 0, "y": 0, "w": 100, "h": 100}, // 在(0,0)绘制bg.jpg,且放缩到100x100 @@ -2219,8 +1893,7 @@ http://www.w3school.com.cn/html5/canvas_drawimage.asp ### drawIcon:绘制图标 UI绘制事件。此事件可以绘制一个图标。 - -```js +```json [ {"type": "drawIcon", "id": "yellowKey", "x": 100, "y": 100}, // 在(100,100)绘制黄钥匙 ] @@ -2230,11 +1903,11 @@ id必填,为要绘制的图标ID。可以是一个注册过的图标ID,也 x, y必填,为要绘制的左上角坐标。width和height可选,如果设置则会将图标放缩成对应的宽高。 +从V2.7开始,对于多帧图块,允许指定绘制哪一帧,默认绘制第 `0` 帧。 ### drawBackground:绘制背景图 UI绘制事件。此事件可以绘制一个背景图。 - -```js +```json [ {"type": "drawBackground", "background": "winskin.png", "x": 0, "y": 0, "width": 100, "height": 100}, ] @@ -2249,32 +1922,27 @@ x, y, width, height必填,分别为要绘制的起点坐标和长宽。 ### drawSelector:绘制闪烁光标 UI绘制事件。此事件可以绘制闪烁光标。 - -```js +```json [ - {"type": "drawSelector", "image": "winskin.png", "x": 0, "y": 0, "width": 100, "height": 100, "clear": true}, - {"type": "drawSelector"} // 清除闪烁光标 + {"type": "drawSelector", "image": "winskin.png", "code": 1, "x": 0, "y": 0, "width": 100, "height": 100}, + {"type": "drawSelector", "code": 1} // 清除1号闪烁光标 ] ``` image为要绘制的WindowSkin图片名;如果不填则视为“清除闪烁光标”。 -x, y, width, height分别为要绘制的起点坐标和长宽。clear可选,如果为true则在绘制前清空已有光标。 - -请注意,同时只会有一个闪烁光标存在,如果创建多个则后者会替换前者。 - -闪烁光标将会一直存在即使事件流结束;请使用本事件并不填`image`来清除闪烁光标。 +`x, y, width, height` 分别为要绘制的起点坐标和长宽。`code` 为要绘制或清除的光标编号,必须为正整数。 +闪烁光标将会一直存在即使事件流结束;请使用本事件并只填 `code` 来清除闪烁光标。 ### function: 自定义JS脚本 上述给出了这么多事件,但有时候往往不能满足需求,这时候就需要执行自定义脚本了。 - -``` js +``` json [ - {"type": "function", "function": function(){ // 执行一段js脚本 + {"type": "function", "function": "function(){ // 执行一段js脚本 // 这里写js代码 - alert(core.getStatus("atk")); // 弹窗显示勇士的攻击力 - }}, + alert(core.getStatus('atk')); // 弹窗显示勇士的攻击力 + }"}, ] ``` @@ -2295,7 +1963,7 @@ var toFloor = core.floorIds[core.rand(core.floorIds.length)]; // 随机一个楼 var toX = core.rand(13), toY = core.rand(13); // 随机一个点 core.insertAction([ {"type": "changeFloor", "floorId": toFloor, "loc": [toX, toY]} // 插入一个changeFloor事件,并在该脚本结束后执行。 -]) +]) // 你会注意到此时事件参数允许使用var型变量,这也是insertAction的强大之处 // 请勿直接调用 core.changeFloor(toFloor, ...),这个代码是异步的,会导致事件处理和录像出问题! ``` @@ -2343,16 +2011,13 @@ core.insertAction([ 我们可以发现,就目前而且,每个点的事件是和该点进行绑定,并以该点坐标作为唯一索引来查询。 而有时候,我们往往需要在同一个点存在多个不同的事件。这涉及到同一个点的多事件处理。 - -我们可以依靠两来实现。**`setBlock`事件**和**if+flag的条件判断**。 - +
我们可以依靠两种指令来实现。**`setBlock` 事件**和 **`if+flag` 的条件判断**。
下面以几个具体例子来进行详细说明。 ### 打怪掉宝 我们注意到怪物和道具都是系统默认事件,因此无需写events,而是直接在afterBattle中setBlock即可。 - -``` js +``` json "afterBattle": { "x,y": [ {"type": "setBlock", "number": 21} // 变成黄钥匙。注意是当前点因此可省略floorId和loc @@ -2367,8 +2032,7 @@ core.insertAction([ 注意到events中不覆盖trigger,则还是怪物时,存在系统trigger因此会战斗并触发afterBattle;变成NPC后没有系统trigger因此会触发自定义事件(楼层转换)。 请注意打死怪物时默认会禁用该点,因此替换后需要手动进行show来启用。 - -``` js +``` json "events": { "x,y": [ {"type": "changeFloor", "loc": [0,0], "floorId": "MT1"} @@ -2391,8 +2055,7 @@ core.insertAction([ 因此需要我们需要覆盖系统trigger(getItem),并覆盖noPass。 通过if来判断有没有获得圣水,没有则触发圣水(生命x2)然后变成墙,否则不执行。 - -``` js +``` json "events": { "x,y": { "trigger": "action", // 覆盖系统trigger,默认的getItem不会执行 @@ -2401,13 +2064,13 @@ core.insertAction([ {"type": "if", "condition": "flag:hasSuperPotion", // 条件判断:是否喝过圣水 "true": [], // 喝过了,不执行 "false": [ - {"type":"setValue", "name":"status:hp", "value":"status:hp*2"}, // 生命翻倍 - {"type":"setBlock", "number": 1}, // 将该点变成墙 - {"type":"setValue", "name":"flag:hasSuperPotion", "value": "true"} // 标记已经喝过了 - ] + {"type":"setValue", "name":"status:hp", "value":"status:hp*2"}, + {"type":"setBlock", "number": 1}, // 生命翻倍,将该点变成墙 + {"type":"setValue", "name":"flag:hasSuperPotion", "value": "true"} + ] // 标记已经喝过了。你会发现这种写法并不涉及圣水道具本身,它只是个素材 } ] - ] + } } ``` @@ -2416,23 +2079,22 @@ core.insertAction([ 总之,记住如下两点: - 可以使用setBlock来更改一个图块。 - - 可通行状态遵循覆盖原则,即**首先取该图块的默认noPass属性,如果剧本的events中定义该点的noPass则覆盖**。 - - 触发器(trigger)亦采用覆盖原则,即**首先取该图块的默认触发器(例如怪物是battle,道具是getItem,门是openDoor),如果剧本的events中定义了该点的trigger则覆盖**。 + - 可通行状态遵循覆盖原则,即**首先取该图块的默认 `canPass` 属性,如果该点的普通事件中定义该点的 `noPass` 则覆盖**。 + - 触发器(trigger)亦采用覆盖原则,即**首先取该图块的默认触发器(例如怪物是 `battle` ,道具是 `getItem` ,门是 `openDoor` ),如果该点绑定了楼层转换事件(绿)或普通事件(红)中覆盖触发器则覆盖**。 - 可以通过if语句和flag来控制自定义事件具体走向哪个分支。 - - 如果弄不清楚系统trigger和自定义事件等的区别,也可以全部覆盖为自定义事件,然后通过type:battle,type:openDoor等来具体进行控制。 + - 如果弄不清楚系统trigger和覆盖触发器的区别,也可以全部覆盖为自定义事件,然后通过type:battle,type:openDoor等来具体进行控制。 + - 如果弄不清楚通行性,也可以全部覆盖为不可通行,并在本该通行的场合用事件让勇士前进。 + - 在上述两种覆盖的情形下,请善用“图块ID:x,y”和“图块类别:x,y”这两个缩写量去判断该图块是什么。 - 多事件处理时请不要使用`changeFloor`那一项,而是使用`events`或者`afterXXX`来处理。 - -## 并行事件处理 - -从V2.4.3后,H5样板开始支持并行事件处理。 - +## 并行脚本处理 +从V2.4.3后,H5样板开始支持并行脚本处理。
在脚本编辑里面提供了一个parallelDo函数,这个函数可以用来做并行处理内容。 从V2.5.2开始,每层楼的楼层属性中也增加了一个parallelDo选项,可以在里面写任何脚本代码。该部分代码仅在人物在该楼层时才会被反复执行。 ``` js "parallelDo": function (timestamp) { - // 并行事件处理,可以在这里写任何需要并行处理的脚本或事件 + // 并行脚本处理,可以在这里写任何需要并行处理的脚本或事件 // 该函数将被系统反复执行,每次执行间隔视浏览器或设备性能而定,一般约为16.6ms一次 // 参数timestamp为“从游戏资源加载完毕到当前函数执行时”的时间差,以毫秒为单位 @@ -2449,7 +2111,7 @@ core.insertAction([ } // 下面是一个并行事件开门的样例 - /* + /* V2.6.4起,提供了自动事件,不再推荐用并行脚本去做这样的处理 // 如果某个flag为真 if (core.hasFlag("xxx")) { // 千万别忘了将该flag清空!否则下次仍然会执行这段代码。 @@ -2463,8 +2125,7 @@ core.insertAction([ */ } ``` - -该函数将被系统反复执行,执行间隔试浏览器或设备性能而定,一般约为16.6ms一次。 +该函数将被系统反复执行,执行间隔试浏览器或设备性能而定,一般约为16.6ms一次(60fps)。 此函数有个参数timestamp,为**从游戏资源加载完毕到当前函数执行时**的时间差,以毫秒为单位。可以使用此参数来制作一些时间相关内容或者特效等。 @@ -2472,7 +2133,7 @@ core.insertAction([ !> 判定flag后千万别忘了将该flag清空!否则下次仍然会执行这段代码。 -每层楼的并行事件处理类似,只有角色在当前楼层时才会反复执行当前楼层中parallelDo部分的代码。 +每层楼的并行脚本处理类似,只有角色在当前楼层时才会反复执行当前楼层中parallelDo部分的代码。 下面是一个打怪开门的样例:(假设每打一个怪的战后事件把`flag:door`+1) @@ -2489,10 +2150,7 @@ if (core.getFlag("door",0)==2) { ``` ## 加点事件 - -打败怪物后可以进行加点。 - -要启用加点,首先需要在`data.js`中将`enableAddPoint`置为true。 +打败怪物后可以进行加点。要启用加点,首先需要在全塔属性中勾选“启用战后加点”。 如果要对某个怪物进行加点操作,则首先需要修改该怪物的`point`数值,代表怪物本身的加点数值。 @@ -2511,65 +2169,41 @@ if (core.flags.enableAddPoint && point > 0) { 我们可以采用上面的choices方式来给出一个商店。这样的商店确实可以有效地进行操作,但是却是"非全局"的,换句话说,只有在碰到NPC的时候才能触发商店事件。 我们可以定义"全局商店",其可以直接被快捷栏中的"快捷商店"进行调用。换句话说,我们可以定义快捷商店,让用户在任意楼层都能快速使用商店。 - -全局商店定义在`data.js`中,找到shops一项。 - +
全局商店定义在全塔属性中,找到shops一项。
从V2.2以后,全局商店也可以使用图块进行编辑,但仍需知道每一项的使用。 - -``` js -"shops": [ // 定义全局商店(即快捷商店) - { - "id": "moneyShop1", // 商店唯一ID - "name": "贪婪之神", // 商店名称(标题) - "icon": "blueShop", // 商店图标,blueShop为蓝色商店,pinkShop为粉色商店 - "textInList": "1F金币商店", // 在快捷商店栏中显示的名称 - "use": "money", // 商店所要使用的。只能是"money"或"exp"。 - "commonTimes": true, // 是否使用全局次数 - "mustEnable": false, // 如果未开启则不显示在状态栏中 - "need": "20+10*times*(times+1)", // 商店需要的金币/经验数值;可以是一个表达式,以times(访问次数)作为参数计算。 - "text": "勇敢的武士啊,给我${need}金币就可以:", // 显示的文字。可以使用${need}表示上面的need值。 - "choices": [ // 商店的选项 - // effect可以对status,item和flag进行操作;必须是X+=Y的形式,其中Y可以是一个表达式 - {"text": "生命+800", "effect": "status:hp+=800"}, // 生命+800 - {"text": "攻击+4", "need": 30, "effect": "status:atk+=4"}, // 规定具体的数值 - {"text": "防御+2,护盾+4", "effect": "status:def+=2;status:mdef+=4"}, // 多个效果用分号分开 - ] - } -], +``` json +"shops": [{ + "id": "shop1", + "text": "\t[贪婪之神,blueShop]勇敢的武士啊, 给我${20+2*flag:shop1}金币就可以:", + "textInList": "1F金币商店", + "mustEnable": false, + "disablePreview": false, + "choices": [ + {"text": "生命+800", "need": "status:money>=20+2*flag:shop1", "action": [ + {"type": "setValue", "name": "status:money", "operator": "-=", "value": "20+2*flag:shop1"}, // 从V2.7起,全局商店由自带插件实现。标准商店中需要手动扣减金币和增加访问次数 + {"type": "setValue", "name": "flag:shop1", "operator": "+=", "value": "1"}, + {"type": "setValue", "name": "status:hp", "operator": "+=", "value": "800"}]}]}] ``` - -全局商店全部定义在`data.js`中的shops一项里。商店以数组形式存放,每一个商店都是其中的一个对象。 - - id 为商店的唯一标识符(ID),请确保任何两个商店的id都不相同 -- name 为商店的名称(打开商店后的标题) -- icon 为商店的图标,在icons.js的npcs中定义。如woman可代表一个商人。 +- text 为商店所说的话。可以使用\t效果和${}表达式求值。 - textInList 为其在快捷商店栏中显示的名称,如"3楼金币商店"等 -- use 为消耗的类型,是金币(money)还是经验(exp)。 -- commonTimes 是否使用全局次数;如果为true则可以多个快捷商店共享相同的次数 - mustEnable 是否必须是只在开启状态才在列表显示;如果此项为true则未开启的快捷商店不予显示 -- need 是一个表达式,计算商店所需要用到的数值。 - - 可以将times作为参数,times为该商店已经访问过的次数,第一次访问时times是0。 - - 如果对于每个选项都需要不同的数值,这里设为"-1";可参见下面经验商店的例子。 -- text 为商店所说的话。可以用${need}表示需要的数值。 +- disablePreview 是否禁止预览,如果此项为true则不能预览 - choices 为商店的各个选项,是一个list,每一项是一个选项 - - text为显示文字。请注意这里不支持 ${} 的表达式计算。 - - effect 为该选项的效果;effect必须是 `status:xxx+=yyy`, `item:xxx+=yyy`或`flag:xxx+=yyy`的形式。即中间必须是+=符号。 - - 如有多个effect(例如升级全属性提升),使用分号分开。 + - text 为显示文字。同样支持 ${} 的表达式计算,预览时、或未满足购买条件的项则会显示为灰色。 + - need 和 condition 分别为该选项的购买条件和出现条件,“出现条件”的含义和“显示选择项”事件中一致。 + - action 为该选项的效果;从V2.7开始,选项效果支持任意类型的事件,当然也就不再支持长按连续购买。 -像这样定义了全局商店后,即可在快捷栏中看到。 +像这样定义了全局商店后,即可在V键(从V2.7开始,不再支持K键)菜单或非自绘状态栏点击金币图标时看到。 请注意,快捷商店默认是不可被使用的。直到至少调用一次自定义事件中的 `{"type": "openShop"}` 打开商店后,才能真正在快捷栏中被使用。 - -``` js +``` json // 事件列表 [ // 打开商店前,你也可以添加自己的剧情 // 例如,通过if来事件来判断是不是第一次访问商店,是的则显示一段文字(类似宿命的华音那样) - {"type": "openShop", "id": "moneyShop1"}, // 这里的id要和data.js中你定义的商店ID完全一致 - // 调用openShop事件后,所有当前事件都会被结束(同exit事件),然后打开一个全局商店 - - // 如果需要禁用商店,则需要调用disableShop事件 - {"type": "disableShop", "id": "moneyShop1"} + {"type": "openShop", "id": "moneyShop1"}, // 这里的id要和全塔属性中你定义的商店ID完全一致 + {"type": "disableShop", "id": "moneyShop1"} // 如果需要禁用商店,则需要调用disableShop事件 ], ``` @@ -2579,9 +2213,10 @@ if (core.flags.enableAddPoint && point > 0) { 另外需要注意的一点就是,每层楼都有一个 canUseQuickShop 选项。如果该选项置为false则无法在该层使用快捷商店。 -**从V2.6开始,也提出了“公共事件化的全局商店”,即打开使用全局商店实际上是执行一个公共事件。** +从V2.7开始,`canUseQuickShop` 函数被挪动到了插件编写中,且对三种全局商店都有效,您也可以加以利用。 -```js +**从V2.6开始,也提出了“公共事件化的全局商店”,即打开使用全局商店实际上是执行一个公共事件。** +```json "shops": [ // 定义公共事件化的全局商店 { @@ -2602,20 +2237,19 @@ if (core.flags.enableAddPoint && point > 0) { `args`可选,为向该公共事件传递的参数,参见[type:insert](#insert:插入公共事件或另一个地点的事件并执行)的说明。 +从V2.6.4开始,自带了道具商店插件,您可以自由设置道具的价格、出售和回收价、进货数量、出现条件等。 ## 系统引发的自定义事件 +我们知道,所有普通事件都是需要定义在`"x,y"`处,并且得让用户经过或撞上才能触发的。 -我们知道,所有自定义事件都是需要定义在`"x,y"`处,并且得让用户经过或撞上才能触发的。 +但是有一系列的事件,例如战斗、获取道具、开门等,是系统已经预先设定好的事件,我们如果将其覆盖触发器,原本的战斗等事件就会被覆盖。 -但是有一系列的事件,例如战斗、获取道具、开门等,是系统已经预先设定好的事件,我们不能将其覆盖为自定义事件,否则原本的战斗等事件会被覆盖。 - -为了解决此问题,在每层的剧本中引入了三个元素:`afterBattle`, `afterGetItem`, `afterOpenDoor`。 +为了解决此问题,在每个点的事件中引入了三个元素:`afterBattle`, `afterGetItem`, `afterOpenDoor`。 - 当某个战斗结束后,将执行`afterBattle`中,对应位置的事件。 -- 当获取某个道具后,将执行`afterGetItem`中,对应位置的事件。 +- 当获取某个道具后,将执行`afterGetItem`中,对应位置的事件。您还可以指定该事件能否被轻按触发。 - 当开了某个门后,将执行`afterOpenDoor`中,对应位置的事件。 例如,下面就是一个典型的杀怪开门的例子。每当杀死一个守卫机关门的怪物,将检查是否满足打开机关门的条件。如果是,则开启机关门。 - -``` js +``` json "afterBattle": { // 战斗后可能触发的事件列表 "9,6": [ // 初级卫兵1 {"type": "setValue", "name": "flag:door", "value": "flag:door+1"}, // 将"door"这个自定义flag加一 @@ -2634,8 +2268,8 @@ if (core.flags.enableAddPoint && point > 0) { ], "false": [] // 如果条件不成立则无事件触发 }, - ], -}, + ], // 从V2.6.4起,提供了右击快速绑定机关门的操作,绑定以后,战后事件只负责累加杀怪数, +}, // 而判定杀怪数是否足够、以及开门的操作则由机关门处的自动事件执行 ``` ![](img/events/60.jpg) @@ -2656,13 +2290,11 @@ if (core.flags.enableAddPoint && point > 0) { 默认情况下,拾取冰面上道具后将停止滑冰行为。如果要继续滑冰,请在`afterGetItem`中插入公共事件:滑冰事件。打怪和开门同理。 -!> 滑冰图块的数字是167,请勿修改此数字! - +!> 滑冰图块的默认触发器是 `ski` ,您可以将别的图块也改为这个默认触发器并画在背景层,从而做出五颜六色的冰面。 ## 推箱子事件 +关于推箱子,存在三种状态:花(flower),箱子(box)和已经推到花的箱子(boxed)。 -关于推箱子,存在三种状态:花(168),箱子(169)和已经推到花的箱子(170)。 - -!> 推箱子的前方不允许存在任何事件(花除外),包括已经禁用的自定义事件。 +!> 推箱子的前方不允许存在任何事件(花除外),包括已经禁用的红绿事件或者重生怪。(会导致箱子消失) 推完箱子后将触发脚本编辑中的afterPushBox函数,你可以在这里进行开门判断。 @@ -2687,13 +2319,12 @@ if (core.flags.enableAddPoint && point > 0) { 有时候光战后事件`afterBattle`是不够的,我们可能还需要战前剧情,例如Boss战之前和Boss进行一段对话。 -要使用战前剧情,首先你需要覆盖该店的系统默认事件,改成你自己的自定义事件,然后在战前剧情后调用`{"type": "battle"}`强制战斗。 +要使用战前剧情,你需要在该点创建普通事件并覆盖触发器,然后在战前剧情后调用`{"type": "battle"}`强制战斗。 -值得注意的是,使用这种自定义事件来覆盖系统的默认战斗事件时,可以增加`displayDamage`代表该点是否需要显伤。此项可省略,默认为有显伤。 - -``` js +顺便一说,普通事件中还提供了是否显伤的勾选框,您可以不勾选,从而使该怪物在地图上不显示预估伤害。 +``` json { - "trigger": "action", // 覆盖该点触发器,变成自定义事件 + "trigger": "action", // 覆盖触发器 "data": [ // 该点的自定义事件列表 // ... 战前剧情 {"type": "battle", "id": "xxx"}, // 强制战斗 @@ -2710,11 +2341,10 @@ if (core.flags.enableAddPoint && point > 0) { 本塔也支持经验升级,即用户杀怪获得经验后,可以到达某些数值自动进阶,全面提升属性。 -要经验升级,你需要先在`data.js`中的全局变量中启用。你需要将`enableExp`启用经验,且`enableLevelUp`启用进阶。同时你也可以将`enableLv`置为true以在状态栏中显示当前等级(境界)。 +要经验升级,你需要在全塔属性中同时勾选“显示等级称号”、“显示经验值”、“开启自动进阶”。 -同时,你还需要在`data.js`中的`levelUp`来定义每一个进阶所需要的经验值,以及进阶时的效果。 - -``` js +同时,你还需要在全塔属性中的 `levelUp` 来定义每一个进阶所需要的经验值,以及进阶时的效果。 +``` json "levelUp": [ // 经验升级所需要的数值,是一个数组 {"need": "0", "title": "", "action": []}, // 第一项为初始等级,仅title生效 // 每一个里面可以含有四个参数 need, title, clear, action @@ -2742,53 +2372,32 @@ if (core.flags.enableAddPoint && point > 0) { - `action` 为本次等级要执行的事件流。 ## 开始游戏与难度分歧 +游戏开始时将调用全塔属性中的 `startText` 事件,我们可以修改它的内容来对于不同难度分别设置初始属性。 -游戏开始时将调用`events.js`中的`startGame`函数。 - -它将显示全塔属性中的startText内容(可以修改成自己的),提供战斗动画开启选择,设置初始福利,并正式开始游戏。 - -我们可以修改脚本编辑`setInitData`函数来对于不同难度分别设置初始属性。 - -其参数hard分为对应全塔属性中levelChooseButtons中的第二项,分别对应不同的难度,并会在游戏中传输,在状态栏显示。 - -针对不同的难度,我们可以设置一些难度分歧。 - -``` js +其中 `core.status.hard` 为全塔属性“难度分歧”二维数组的第二列(四个单词),会以红色显示在状态栏一角。 +``` json ////// 不同难度分别设置初始属性 ////// -"setInitData": function (hard) { - if (hard=='Easy') { // 简单难度 - core.setFlag('hard', 1); // 可以用flag:hard来获得当前难度 - // 可以在此设置一些初始福利,比如设置初始生命值可以调用: - // core.setStatus('hp', 10000); - // 赠送一把黄钥匙可以调用 - // core.setItem('yellowKey', 1); - } - if (hard=='Normal') { // 普通难度 - core.setFlag('hard', 2); // 可以用flag:hard来获得当前难度 - } - if (hard=='Hard') { // 困难难度 - core.setFlag('hard', 3); // 可以用flag:hard来获得当前难度 - } -} -``` - -难度会赋值给`flag:hard`,即我们可以在上述if语句的condition中进行判断。 - -请不要在任何事件中修改对`flag:hard`进行任何赋值(修改它),不然可能会造成一些不可知的后果。 - -如果是在游戏中根据不同的难度分析来控制地图,比如简单难度删除绿钥匙,则可以在该楼层的`firstArrive`(首次到达楼层)中进行条件判定。 - -```js -// 该楼层的firstArrive -[ - {"type": "if", "condition": "flag:hard==1", // 条件判定flag:hard是否为1 - "true": [{"type":"hide","loc":[0,0]}], // 如果是,则隐藏某点事件 - "false": [] - } +"startText": [ // 根据难度分歧设置<变量:hard>并给其他初始值 + {"type": "switch", "condition": "core.status.hard", "caseList": [ + {"case": "'Easy'", "action": [ // 可以在这里修改初始道具或属性,比如赠送黄钥匙等 + {"type": "setValue", "name": "flag:hard", "value": "1"}, + {"type": "hide", "loc": [[6,6]], "floorId": "MT10"} // 简单难度删除主塔10层中央的图块 + ]}, + {"case": "'Normal'", "action": [ + {"type": "setValue", "name": "flag:hard", "value": "2"} + ]}, + {"case": "'Hard'", "action": [ + {"type": "setValue", "name": "flag:hard", "value": "3"} + ]}, + {"case": "'Hell'", "action": [ + {"type": "setValue", "name": "flag:hard", "value": "4"} + ]} + ]}, // 初始剧情 + "Hi,欢迎来到 HTML5 魔塔样板!\n本样板由艾之葵制作,可以让你在不会写任何代码\n的情况下也能做出属于自己的H5魔塔!", + "这是游戏开始时的剧情。\n你可以在这里写上自己的内容。\n赶快来试一试吧!" ] ``` - -![](img/events/59.jpg) +`flag:hard` 为计榜难度系数,即在线游戏排行榜中只统计此值最大且有人通关的难度。游戏过程中请勿二次修改它。 ========================================================================================== diff --git a/_docs/img/bigKey.png b/_docs/img/bigKey.png new file mode 100644 index 00000000..384d53b8 Binary files /dev/null and b/_docs/img/bigKey.png differ diff --git a/_docs/img/changefloorBlockly.png b/_docs/img/changefloorBlockly.png new file mode 100644 index 00000000..558bb804 Binary files /dev/null and b/_docs/img/changefloorBlockly.png differ diff --git a/_docs/img/events/13.jpg b/_docs/img/events/13.jpg index af81a7f0..075b0814 100644 Binary files a/_docs/img/events/13.jpg and b/_docs/img/events/13.jpg differ diff --git a/_docs/img/events/26.jpg b/_docs/img/events/26.jpg index 6eaca21b..f2b11f44 100644 Binary files a/_docs/img/events/26.jpg and b/_docs/img/events/26.jpg differ diff --git a/_docs/img/events/27.jpg b/_docs/img/events/27.jpg index 6c5b3a25..021b48e6 100644 Binary files a/_docs/img/events/27.jpg and b/_docs/img/events/27.jpg differ diff --git a/_docs/img/events/46.jpg b/_docs/img/events/46.jpg index 1eea4e37..0fff3f91 100644 Binary files a/_docs/img/events/46.jpg and b/_docs/img/events/46.jpg differ diff --git a/_docs/img/events/48.jpg b/_docs/img/events/48.jpg index 2086b1c3..4a0d31a8 100644 Binary files a/_docs/img/events/48.jpg and b/_docs/img/events/48.jpg differ diff --git a/_docs/img/events/7.png b/_docs/img/events/7.png index a2f60686..80b15c87 100644 Binary files a/_docs/img/events/7.png and b/_docs/img/events/7.png differ diff --git a/_docs/img/forEach.png b/_docs/img/forEach.png new file mode 100644 index 00000000..0b9ed39d Binary files /dev/null and b/_docs/img/forEach.png differ diff --git a/_docs/img/keyboard.png b/_docs/img/keyboard.png index c2b9d241..9f2b057a 100644 Binary files a/_docs/img/keyboard.png and b/_docs/img/keyboard.png differ diff --git a/_docs/img/server.png b/_docs/img/server.png index eb905427..74488f31 100644 Binary files a/_docs/img/server.png and b/_docs/img/server.png differ diff --git a/_docs/index.md b/_docs/index.md index d3943d2c..31bacae7 100644 --- a/_docs/index.md +++ b/_docs/index.md @@ -1,18 +1,17 @@ # HTML5 魔塔样板说明文档 +?> 目前版本**v2.7**,上次更新时间:* {docsify-updated} * +
当您打开这份帮助文档的瞬间,相信您一定是抱着幼年时的游戏开发梦想前来的。
+众所周知,即时制游戏的开发要比非即时游戏难上许多,像素级游戏的开发又要比网格地图游戏难上许多。
在非即时的网格地图游戏(譬如策略战棋)中,有一类游戏叫做“固定数值RPG”,或者简称“魔塔”。
这是一种基于运筹学的数学优化建模游戏,虽然小众,却不失有自己的圈子。 -?> 目前版本**v2.6.6**,上次更新时间:* {docsify-updated} * - -众所周知,魔塔的趋势是向移动端发展,贴吧中也常常能见到“求手机魔塔”的帖子。然而现有的工具中,NekoRPG有着比较大的局限性,游戏感较差,更是完全没法在iOS上运行。而一些APP的魔塔虽然可用,但是必须要下载安装,对于Android和iOS还必须开发不同的版本,非常麻烦。 +在当下,魔塔的趋势是向移动端发展,网络上也常常能见到“求手机魔塔”的提问。然而现有的工具中,NekoRPG有着比较大的局限性,游戏感较差,更是完全没法在iOS上运行。而一些APP的魔塔(譬如《魔塔盛宴》和一些登陆了TapTap的魔塔,以及最新的由RPG Maker MV制作的《盖伦排位记》等)虽然可用,但是必须要下载安装,对于Android和iOS还必须开发不同的版本,非常麻烦。 但是,现在我们有了HTML5。 HTML5的画布(canvas)以及它被Android/iOS内置浏览器所支持的特性,可以让我们做出真正意义上的全平台覆盖的魔塔。 -然而,一般而言使用非RMXP制作魔塔往往需要一定的编程技术,HTML5魔塔自然也不例外。但是,为了能让大家更加注重于“做塔”本身,而不用考虑做塔以外的各种脚本问题,我特意制作了这样一部HTML5的魔塔样板。 +然而,一般而言使用非RPG Maker MV制作魔塔往往需要一定的编程技术,HTML5魔塔自然也不例外。但是,为了能让大家更加注重于“做塔”本身,而不用考虑做塔以外的各种脚本问题,@艾之葵(GitHub ckcz123)特意制作了这样一部HTML5的魔塔样板。 +> 这个魔塔样板,可以让你在完全不懂任何编程语言的情况下,做出自己的H5魔塔。不会代码?没关系!只要你想做,就能做出来! -> 这个魔塔样板,可以让你在完全不懂任何编程的情况下,做出自己的H5魔塔。不会代码?没关系!只要你想做,就能做出来! - -继续查看文档的详细介绍,让你学会如何使用这一个样板来制作属于自己的HTML5魔塔。 - -本说明文档配有B站视频教程,对照查看效果更佳哦:[https://www.bilibili.com/video/av32781473/](https://www.bilibili.com/video/av32781473/)。 +继续查看文档的详细介绍,让你学会如何使用这一个样板来制作属于自己的HTML5魔塔,或者……任何非即时的网格地图游戏。
+本说明文档配有较为过时的B站视频教程,可供参考:[https://www.bilibili.com/video/av32781473/](https://www.bilibili.com/video/av32781473/)。 ========================================================================================== diff --git a/_docs/personalization.md b/_docs/personalization.md index ec6f5863..e49bde8a 100644 --- a/_docs/personalization.md +++ b/_docs/personalization.md @@ -1,6 +1,5 @@ # 个性化 - -?> 目前版本**v2.6.6**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.7**,上次更新时间:* {docsify-updated} * 有时候只靠样板本身可能是不够的。我们需要一些个性化、自定义的素材,道具效果,怪物属性,等等。 @@ -69,13 +68,6 @@ core.fillText('test', '这是一段文字', 10, 30, '#FF0000', '16px Verdana'); - `terrains.png` 为所有地形的图标。 系统会读取`icon.js`文件,并获取每个ID对应的图标所在的位置。 - -### 使用预定义的素材 - -在images目录的“默认素材”下给定了若干预定义的自定义素材。 - -如果你需要某个素材已经存在,则可以直接将其覆盖images目录下的同名文件,就能看到效果。 - ### 背景和前景图层 从V2.4.1开始,样板允许多个图层叠加,最多支持背景层、事件层和前景层三个图层。 @@ -246,15 +238,14 @@ ID必须由数字字母下划线组成,数字在1000以内,且均不能和 额外素材可以使用“tileset贴图”的方式进行绘制,一次绘制一个矩形区域。 +“辅助工具”中提供了“额外素材合并”,如果使用此功能,请不要对额外素材进行基于ID、索引和数字的判定和读写等操作,如确有此需求,可以创建一些玩家不可达也不可预览的隐藏样板层,然后用等量代换的办法去从样板层取用。 ## 自定义道具效果 本节中将继续介绍如何自己编辑一个道具的效果。 -道具效果的具体实现都在`items.js`中。 - +道具效果的具体实现都在 `project\items.js` 中。 ### 即捡即用类道具(cls: items) - -对于即捡即用类道具,如宝石、血瓶、剑盾等,我们可以简单地修改`data.js`中的value一栏即可。 +对于即捡即用类道具,如宝石、血瓶等,我们可以简单地修改全塔属性中的 `values` 一栏即可。 如果你想要同种宝石在不同层效果不同的话,可以进行如下操作: @@ -281,11 +272,14 @@ core.status.hero.atk += core.values.redJewel + 2*ratio 具体过程比较复杂,需要一定的JS能力,在这里就不多说了,有需求可以找`艾之葵`进行了解。 +从V2.6.6起,道具的“图块属性”中,提供了 `useItemEvent` 项,您可以用事件而不是脚本去书写道具的使用效果(对 `cls: items` 也有效但会打断寻路),参见样板的黄宝石和生命魔杖。 + +如果弄不清楚 `canUseItem` ,也可以干脆统一填写为 `"true"`,先斩后奏,并在使用效果中再行判定,如果发现其实使用失败了,就悄咪咪返还给勇士一个该道具,参见样板的破墙镐和炸弹。 ### 实战!拿到神圣盾后免疫吸血、领域、夹击效果 1. 在itemEffect中修改拿到神圣盾时的效果,标记一个自定义Flag。 ``` js -core.status.hero.def += core.values.shield5 * ratio; +core.status.hero.def += 100; core.setFlag("shield5", true); // 增加一个自定义Flag:已经拿到神圣盾 ``` 2. 免疫吸血效果:在脚本编辑的getDamageInfo中,编辑成如果存在神圣盾标记,吸血伤害为0。 @@ -310,31 +304,24 @@ function (enemy, hero_hp, hero_atk, hero_def, hero_mdef, x, y, floorId) { // ... 下略 ``` 3. 免疫领域、夹击、阻击效果:在2.4.1之后,可以直接将flag:no_zone设为true来免疫领域效果,其他几个同理。 -``` js -// 写在获得道具后事件 -[ +``` json +[ // 写在获得道具后事件 // 设置不同的flag可以分别无视对应的阻激夹域效果 {"type": "setValue", "name": "flag:no_zone", "value": "true"}, // 免疫领域 {"type": "setValue", "name": "flag:no_snipe", "value": "true"}, // 免疫阻击 {"type": "setValue", "name": "flag:no_laser", "value": "true"}, // 免疫激光 {"type": "setValue", "name": "flag:no_betweenAttack", "value": "true"}, // 免疫夹击 + {"type": "setValue", "name": "flag:no_ambush", "value": "true"}, // 免疫捕捉 + {"type": "setValue", "name": "item:shoes", "value": "1"} // 免疫路障 ] ``` 4. 如果有更高的需求,例如想让吸血效果变成一半,则还是在上面这些地方进行对应的修改即可。 ## 新增门和对应的钥匙 - -如果要新增一个门和对应的钥匙,需要进行如下几步: - -1. 在terrains.png中添加新的门的素材,并在地图编辑器中注册门的ID。该ID必须是以`Door`结尾,例如`abcDoor`。 -2. 在animates.png中添加开门的四格动画,然后直接打开icons.js文件,在animates下直接添加ID和索引信息,例如`'abcDoor': 34`。 -3. 在items.png中添加钥匙的素材,并在地图编辑器中注册钥匙的ID。该ID必须是和门对应且以`Key`结尾,例如`abcKey`。 -4. 该道具的cls应为`tools`,可以自行写道具描述,最下面几项均留`null`即可。 - -!> **请勿在animates中对门的动画素材进行注册!而是请直接打开icons.js文件并添加ID和索引信息!!!** - -!> terrains和animates的门ID必须完全一致,且以`Door`结尾;所对应的钥匙ID应当是把`Door`换成`Key`,这样才能对应的上! - +如果要新增一个门和对应的钥匙,只需要进行如下三步: +1. 在 `project\images\animates.png` 中添加开门的四帧动画并注册,其中第一帧也作为未开启的静止门。 +2. 在图块属性中将其默认触发器改为 `openDoor` ,动画帧数填 `1` 表示门未开启时静止在第一帧。 +3. 在 `doorInfo` 中填写需要哪些钥匙(可以填任何消耗类道具)各多少把,开关门分别播放什么音效等。 ## 覆盖楼传事件 对于特殊的塔,我们可以考虑修改楼传事件来完成一些特殊的要求,比如镜子可以按楼传来切换表里。 @@ -354,23 +341,25 @@ function (enemy, hero_hp, hero_atk, hero_def, hero_mdef, x, y, floorId) { 如果你对现有的怪物不满意,想自行添加怪物属性也是可以的。具体参见脚本编辑的getSpecials。 -你需自己指定一个special数字,修改属性名和属性提示文字。后两者可以直接写字符串,或写个函数传入怪物。 +你需自己指定一个special数字,修改属性名和属性提示文字。提示文字可以直接写字符串,或写个函数传入怪物。 + +如果要改动怪物在手册中的显示数值(也会被用于伤害计算,如模仿),请修改下面的 `getEnemyInfo` 函数。 如果要修改伤害计算公式,请修改下面的getDamageInfo函数。请注意,如果无法战斗,该函数必须返回`null`。 !> 如果改动了伤害计算公式,可能导致临界计算崩掉,因此建议将全塔属性中的`useLoop`置为true。 -对于毒衰弱怪物的战斗后结算在脚本编辑中的afterBattle函数中。 - -对于领域、夹击、阻击怪物的检查在`control.js`中的checkBlock函数中。 +对于毒衰咒、自爆、退化怪物和加点、仇恨值累加等战斗后结算在脚本编辑中的 `afterBattle` 函数中。 +对于领域、夹击、阻击、激光、捕捉怪物的检查在脚本编辑中的 `updateCheckBlock` 函数中。 ## 自定义快捷键 如果需要绑定某个快捷键为处理一段事件,也是可行的。 要修改按键,我们可以在脚本编辑的`onKeyUp`进行处理: -比如,我们设置一个快捷键进行绑定,比如`Y`,其keycode是89。(有关每个键的keycode搜一下就能得到) +我们设置一个快捷键进行绑定,比如 `Y`,其 `keycode` 是 `89` 。
+(大键盘数字键 `0-9` 的 `keycode` 为 `48-57, A-Z` 键的 `keycode` 为 `65-90` ,其他键的 `keycode` 搜一下就能得到) 然后在脚本编辑的`onKeyUp`函数的`switch`中进行处理。 @@ -387,8 +376,7 @@ case 89: // 使用该按键的keyCode,比如Y键就是89 break; ``` - -强烈建议所有新增的自定义快捷键均给个对应的永久道具可点击,以方便手机端的行为。 +强烈建议所有新增的自定义非数字快捷键均给个对应的永久道具可点击,以方便手机端的行为。 使用`core.status.route.push("key:"+keyCode)`可以将这次按键记录在录像中。 @@ -457,7 +445,7 @@ this.myfunc = function(x) { 可以在脚本编辑的onKeyUp中定义每个快捷键的使用效果,比如使用道具或释放技能等。 -默认值下,1使用破,2使用炸,3使用飞,4使用其他存在的道具,5-8未定义。可以相应修改成自己的效果。 +默认值下,1使用破,2使用炸,3使用飞,4使用其他存在的道具,5读取上一个自动存档,6读取下一个自动存档,7轻按,8未定义。可以相应修改成自己的效果。 也可以替换icons.png中的对应图标,以及修改main.js中`main.statusBar.image.btn1~8`中的onclick事件来自定义按钮和对应按键。 @@ -475,6 +463,7 @@ this.myfunc = function(x) { 具体可详见脚本编辑的`drawStatusBar`函数。 +自绘状态栏开启后,金币图标将失去打开快捷商店的功能,您可以修改脚本编辑的 `onStatusBarCLick` 函数来适配。 ## 自定义状态栏的显示项 在V2.2以后,我们可以自定义状态栏背景图(全塔属性 - statusLeftBackground)等等。 @@ -534,13 +523,9 @@ core.statusBar.speed.innerHTML = core.getStatus('speed'); // 设置其显示内容为flag:speed值,无需额外进行定义。 core.statusBar.speed.innerHTML = core.getFlag('speed', 0); ``` - +总的来说不建议这样做,因为 `main.js` 和几个 `html` 文件不在 `project` 文件夹,会导致随样板更新迁移接档变得困难。 ## 技能塔的支持 - -要支持技能塔,可能需要如下几个方面: - -从V2.5开始,内置了"二倍斩"技能,可以仿照其制作自己的技能。 - +从V2.5开始,内置了"二倍斩"技能,可以仿照其制作自己的技能。要支持技能塔,可能需要如下几个方面: - 魔力(和上限)的添加;技能的定义 - 状态栏的显示 - 技能的触发(按键与录像问题) @@ -548,11 +533,9 @@ core.statusBar.speed.innerHTML = core.getFlag('speed', 0); ### 魔力的定义添加;技能的定义 -从V2.5开始,提供了status:mana选项,可以直接代表当前魔力值。 +从V2.5开始,提供了 `status:mana` 选项,可以直接代表当前魔力值。可以在全塔属性勾选来启用它。 -如果要启用,需要开启全塔属性的enableMana选项。 - -如果需要魔力上限,则可以使用flag:manaMax来表示当前的魔力最大值。 +如果需要魔力上限,则可以使用 `status:manaMax` 来表示当前的魔力最大值,负数表示没有上限。 同时,我们可以使用flag:skill表示当前开启的技能编号,flag:skillName表示当前开启的技能名称。 @@ -581,8 +564,7 @@ core.statusBar.skill.innerHTML = core.getFlag('skillName', '无'); ### 技能的触发 #### 使用道具作为技能 - -由于手机端按键十分不方便,虚拟键盘不好用,因此强烈推荐**给每个技能设置一个道具图标,在道具栏点击使用!** +由于手机端按字母键不方便,虚拟键盘不好用,因此强烈推荐**给每个字母键技能设置一个道具,在道具栏点击使用!** 下面是个很简单的例子,要制作一个技能"二倍斩"。 @@ -616,19 +598,17 @@ else { // 关闭技能 在技能的道具定义完毕后,再将该道具绑定到一个快捷键上。有关绑定按键请参见[自定义快捷键](#自定义快捷键)。 -下面是一个很简单的例子,当勇士按下W后,触发我们上面定义的二倍斩技能。 - +下面是一个很简单的例子,当勇士按下 `F` 后,触发我们上面定义的二倍斩技能。 ``` js -case 87: // W:开启技能“二倍斩” +case 70: // F:开启技能“二倍斩” // 是否拥有“二倍斩”这个技能道具 if (core.hasItem('skill1')) { - core.status.route.push("key:87"); + core.status.route.push("key:70"); core.useItem('skill1', true); } break; ``` - -在勇士处于停止的条件下,按下W键时,判断技能的道具是否存在,如果存在再使用它。 +在勇士处于停止的条件下,按下 `F` 键时,判断技能的道具是否存在,如果存在再使用它。 !> 由于现在手机端存在拓展键盘,也强烈建议直接覆盖1-8的使用效果,这样手机端使用也非常方便。 diff --git a/_docs/start.md b/_docs/start.md index 880bfd08..69b6fed1 100644 --- a/_docs/start.md +++ b/_docs/start.md @@ -1,37 +1,34 @@ # 快速上手 - -?> 目前版本**v2.6.6**,上次更新时间:* {docsify-updated} * - +?> 目前版本**v2.7**,上次更新时间:* {docsify-updated} *
在这一节中,将详细介绍做一部塔的流程。现在,让我们来做一部单层塔! ## 前置需求 - -你需要有满足如下条件才能进行制作: - -- Windows 8以上操作系统;Windows 7需要安装.Net Framework 4.0。(能打开同目录下的“启动服务.exe”即可) - - Mac系统则需OS X 10.7及以上,能正确打开启动服务(Mac版).app即可。 - - 安卓手机端需要下载最新版的HTML5安卓造塔器。 -- Chrome浏览器。其他浏览器可能会导致本地服务器产生闪退等现象。 -- 强烈推荐安装一个很好的文本编辑器:VSCode。在某些需要直接修改文件的场合,可能会非常重要。 - -上述软件均可以在群文件的常用软件中找到下载安装包。 +你需要满足如下条件才能进行制作: +- Windows 8 以上操作系统;Windows 7 需要安装 .Net Framework 4.0。(能打开同目录下的“启动服务.exe”即可) + - 其他电脑则需安装 [python 3.8.2](https://www.python.org/getit/) 或更高版本,能打开server.py即可( Windows 也可以这样做)。 + - 安卓手机端需要下载最新版的 [HTML5安卓造塔器](https://h5mota.com/games/_client/H5motaMaker.apk)。 +- [Chrome浏览器](https://www.google.cn/chrome/)。其他浏览器可能会导致本地服务器产生闪退等现象。 +- 强烈推荐安装一个很好的文本编辑器:[VSCode](https://code.visualstudio.com/download)。在某些需要直接修改文件的场合,可能会非常重要。 只要满足了上述条件,你就可以开始做自己的塔啦! ## 启动HTTP服务 - -在根目录下有一个“启动服务.exe”,运行之。(Mac版本则双击运行“启动服务(Mac版).app”,手机端则使用造塔APP。) - +与编辑器闭源的 RPG Maker MV 不同,本样板对文件的绝大部分修改是通过网页编辑器经由本地 HTTP 服务完成的,这样做也有助于编辑器跨平台并最大限度地复用运行时代码,还可以让玩家在在线游戏时查看游戏工程。
+在根目录下有一个“启动服务.exe”,运行之。(非 Windows 电脑则需使用命令行运行 server.py,手机端则使用造塔APP。) ![启动服务](img/server.png) - -* “启动游戏”按钮将打开一个网页,你能在里面看到现在游戏的效果。 -* “地图编辑器”允许你以可视化的方式进行编辑地图。 +* “启动游戏”按钮将打开一个网页(您也可以手动在浏览器中键入 127.0.0.1:1055/index.html ,同时开启多个启动服务则1056、1057顺延),你能在里面看到现在游戏的效果。 +* “地图编辑器”允许你以可视化的方式进行编辑游戏(这个名称为历史遗留,两年前它真的只能编辑地图)。您也可以手动在浏览器中键入 127.0.0.1:1055/editor.html +* 以下为 Windows 专用的一些辅助工具,由C#编写: * “便捷PS工具”能让你很方便的对自定义素材进行添加。参见[自定义素材](personalization#自定义素材)。 * “地图生成器”能让你从已有的截图(如RMXP项目)中立刻生成可被本样板识别的地图数据。 -* “怪物数据导出”能让你从RMXP中导出怪物数据而被H5魔塔使用。 -* “RM动画导出器”能让你从RMXP中导出动画而被H5魔塔使用。 -* “JS代码压缩工具”能对JS代码进行压缩,从而减少IO请求数和文件大小。 +* “怪物数据导出”能让你从RMXP(RPG Maker XP 1.03,下同)中导出怪物数据而被HTML5魔塔使用。 +* “RM动画导出”能让你从RMXP中导出动画而被HTML5魔塔使用。 +* “JS代码压缩”能对JS代码和音像素材进行压缩,从而减少IO请求数和文件大小。 +* “额外素材合并”能将用到的tileset素材重新拼成更少的图片,并更新对应的地图矩阵。 * “伤害和临界值计算器”是一个很便捷的小工具,能对怪物的伤害和临界值进行计算。 +* “动画编辑器”能让你编辑已有的animate动画文件,或自己利用图片制作全新的动画。 +* “[怪物数据生成机](https://pan.baidu.com/s/1w-JMg-ZPRvbsqbbtOwORGA#list/path=%2F +)”能够借助AI生成适当强度的怪物,此工具需要手动下载。 !> **整个造塔过程中,启动服务必须全程处于开启状态!切不可手滑关闭,否则做的都是无用功!** @@ -48,15 +45,10 @@ ![绘制地图](./img/drawmap.jpg) 如果提示“该素材未被定义”或有红色问号框,请参见[素材注册](#素材注册)。 - -绘制地图时可以右键弹出菜单,移动图块和事件。 - -从V2.4.2开始,可以使用`Alt+0~9`对一个图块素材快速保存,`Ctrl+0~9`来快速选用。 - +
绘制地图时可以右键弹出菜单,复制、交换、删除图块、选中素材、更改出生点或快速创建常用事件。
从V2.4.2开始,可以使用 `Alt+0~9` 对一个图块素材快速保存,大键盘 `0~9` 来快速选用。
+从V2.6.6开始,最近使用的图块也会直接显示在地图下方,您可以随时选取或清空它们。 ### 从RMXP导入已有的地图 - -!> 注:现在已经不推荐此方法,如需从RM刻塔请使用 [RM转H5刻塔器使用教程](https://www.bilibili.com/video/av43125840) 进行操作。 - +!> 注:现在已经不推荐此方法,如需从RMXP复刻魔塔请观看 [RM转H5刻塔器使用教程](https://www.bilibili.com/video/av43125840) 进行操作。
如果我们想复刻一个现有的,已经被RMXP所制作的塔,也有很便捷的方式,那就是用到我们的“地图生成器”。 首先,我们打开RMXP和对应的项目,可以看到它的地图。 @@ -64,9 +56,7 @@ ![绘制地图](./img/rmxp2.png) 我们打开地图编辑器,创建一个地图,宽高需要和RM中的地图一致。 - -之后,我们打开Windows自带的“截图工具”,并将整个地图有效区域截图下来,并将其复制到剪切板。 - +
之后,我们打开 Windows 10 自带的“截图工具”(非 Windows 10 请使用 Print Screen 键全屏截图后粘贴到“画图”中裁剪,或使用微信/QQ等自带的截图功能),并将整个地图有效区域截图下来,复制到剪切板。 ![绘制地图](./img/rmxp3.png) 截图时请注意:**只截取有效游戏空间内数据,并且有效空间内的范围必须是创建的地图的大小(至少为13x13)。** @@ -78,8 +68,7 @@ 然后点击“复制地图”,即可将地图数据复制到剪切板,然后再地图编辑器中切换到“地图编辑”,并在左边的框进行粘贴。 !> **地图生成器默认只支持已被定义的素材。如果有自定义素材需求(例如原版的1层小塔那种素材),请先[导入并注册素材](#素材注册)后再进行操作。** - -!> **请确保截图范围为你创建的地图大小,并且保证每个位置的像素都是32x32。** +!> **请确保截图范围为你创建的地图大小,并且保证每个位置的像素都是32x32(譬如48×48的RPG Maker MV就需要缩小到2/3比例再截图)。** !> **如果宽度超过13,地图生成器将无法显示完全,但是仍然可以粘贴到地图编辑器中进行修改。** @@ -90,9 +79,7 @@ ## 编辑属性 当地图绘制完毕后,我们可能需要进行属性的编辑。属性编辑有四类:楼层属性、怪物属性、道具属性、全塔属性。 - -### 楼层属性 - +### 楼层属性(快捷键V) 我们切换到楼层属性,并进行一项项的编辑。将鼠标放在中间有具体的每一项注释,这里不再细说。 ![楼层属性](./img/floor.png) @@ -110,13 +97,9 @@ 同理,点击道具可以对道具属性进行编辑。 目前大多数道具都已有默认效果。更多信息可参见[元件说明:道具](element#道具)。 - -### 全塔属性 - +### 全塔属性(快捷键B) 我们切换到全塔属性,并进行一项项的编辑。同样鼠标放在中间可以查看注释。 - -我们可以在这里定义一些全局的属性,比如开始剧情、宝石血瓶剑盾数值,破甲反击净化的比例,以及一些系统开关比如是否启用加点,是否允许负伤害等等。 - +
我们可以在这里定义一些全局的属性,比如开始剧情、宝石血瓶数值,破甲反击净化的比例,以及一些系统开关比如是否启用加点,是否允许负伤害等等。
!> **注:name作为游戏的唯一标识符必须进行修改,否则可能会导致存档等出现问题。**   @@ -142,9 +125,7 @@ 从上至下有若干项,分别代表该点的一些事件。有关事件的详细信息请参见[事件](event)。 如果一个点存在事件,则在地图编辑器中该点的左下角会有一个小方框表示。 - -红色为自定义事件,绿色为楼层传送事件,黄色为战后事件,青色为道具获得后的事件,粉色为开门后的事件。 - +
红色为普通事件,橙色为自动事件,黄色为战后事件,绿色为楼层转换,青色为拾获道具后事件,靛色为不可通行性(不是事件),粉(紫)色为开门后事件。 ## 自定义素材的添加与注册 有关素材的更多详细信息,包括素材的机制等内容,请参见[自定义素材](personalization#自定义素材)。 @@ -154,15 +135,10 @@ ### 新素材的添加 如果我们需要新增加一些素材,比如样板中没有的怪物等。 - -我们可以从启动服务打开编辑PS工具,然后选择对应的图片进行添加。 - +
我们可以从启动服务打开便捷PS工具,然后选择对应的图片进行添加。 ![便捷PS工具](img/ps.png) - -在左边选择你要导入到的位置,比如怪物就是enemy.png,道具就是items.png等等,再在右边导入你的新素材图片。 - -之后就可以简单的使用Ctrl+C和Ctrl+V来复制粘贴了。 - +在左边选择你要导入到的文件,比如怪物就是enemy.png,道具就是items.png等等,再在右边导入你的新素材图片。
+之后就可以简单的使用 C 和 V 来复制粘贴了。
保存后,刷新地图编辑器即可生效。 ### 素材注册 @@ -172,15 +148,11 @@ ![素材注册](./img/register.png) 出现这种情况,是因为我们没有将该素材定义到游戏中,也无法进行使用。 - -要解决这个问题,只需要在左边的图块属性中定义新的图块ID和图块数字即可。ID必须由数字字母下划线组成,数字在1000以内,且均不能和已有的进行重复。 - +
要解决这个问题,只需要在左边的图块属性中定义新的图块ID和图块数字即可。ID必须由数字字母下划线组成,ID不允许使用纯数字。图块数字在1000以内,ID和图块数字均不能和已有的进行重复。
有关图块的ID和数字定义请参见[素材的机制](personalization#素材的机制)。 之后刷新编辑器即可。 - -也可以进行自动注册,只需要点击“自动注册”按钮,将对该栏下所有未注册的素材进行自动注册(自动分配ID和数字)。 - +
也可以进行自动注册,只需要点击“自动注册”按钮,将对该栏下所有未注册的素材进行自动注册(自动分配ID和数字,随后强烈建议手动修改ID)。
素材注册完毕后,即可在游戏中正常使用,也可以被地图生成器所识别(需要重开地图生成器)。 ### 额外素材 @@ -194,11 +166,8 @@ 有关额外素材的更多说明参见[额外素材](personalization#额外素材) ## 控制台调试 - -HTML5的塔都是可以进行控制台调试的。 - -当我们使用Chrome进入游戏后,可以按 `Ctrl+Shift+I` ,并找到 `Console` 控制台。 - +HTML5游戏都是可以进行控制台调试的。
+当我们使用Chrome进入游戏后,可以按 `Ctrl+Shift+I` (F12),并找到 `Console` 控制台。 ![控制台](./img/console.png) 在控制台中,我们可以输入一些命令对游戏进行调试,常见的命令有: @@ -209,21 +178,21 @@ HTML5的塔都是可以进行控制台调试的。 - `core.status.hero` 获得当前勇士状态信息。例如`core.status.hero.atk`就是当前勇士的攻击力数值。 - `core.material.enemys` 获得所有怪物信息。例如`core.material.enemys.greenSlime`就是获得绿色史莱姆的属性数据。 - `core.material.items` 获得所有道具的信息。例如`core.material.items.pickaxe`就是获得破墙镐的信息。 -- `core.debug()` 开启调试模式;此模式下可以按住Ctrl键进行穿墙。 -- `core.updateStatusBar()` 立刻更新状态栏和地图显伤。 +- `flags.debug = true` 开启调试模式;此模式下可以按住 Ctrl 键进行穿墙。 +- `core.updateStatusBar()` 立刻更新状态栏和地图显伤,并检查自动事件。 - `core.setStatus('atk', 1000)` 直接设置勇士的某项属性。本句等价于 `core.status.hero.atk = 1000`。 - `core.getStatus('atk')` 返回勇士当前某项属性数值。本句等价于 `core.status.hero.atk`。 - `core.setItem('pickaxe', 10)` 直接设置勇士某个道具的个数。这里可以需要写道具的ID。 - `core.getItem('pickaxe', 2)` 令勇士获得两个破墙镐。 - `core.itemCount('pickaxe')` 返回勇士某个道具的个数。 -- `core.hasItem('pickaxe')` 返回勇士是否拥有某个道具。等价于`core.itemCount('pickaxe')!=0`。 +- `core.hasItem('pickaxe')` 返回勇士是否拥有某个道具。等价于`core.itemCount('pickaxe') > 0`。 - `core.getEquip(0)` 返回0号装备类型(武器)的当前装备的itemId,不存在则返回null - `core.hasEquip('sword1')` 返回某个装备当前是否处于被装备状态 - `core.setFlag('xxx', 1)` 设置某个flag/自定义变量的值。 - `core.getFlag('xxx', 10)` 获得某个flag/自定义变量的值;如果该项不存在(未被定义),则返回第二个参数的值。 -- `core.hasFlag('xxx')` 返回是否存在某个变量且不为0。等价于`core.getFlag('xxx', 0)!=0`。 -- `core.removeFlag('xxx')` 删除某个flag/自定义变量 -- `core.insertAction(list)` 执行一段自定义事件。比如 `core.insertAction(["剧情文本"])` 将执行一个剧情文本显示事件。 +- `core.hasFlag('xxx')` 返回是否存在某个变量且不为六种广义 `false` 。等价于 `!!core.getFlag('xxx')` 。 +- `core.setFlag('xxx')` 删除某个flag/自定义变量 +- `core.insertAction(list)` 执行一个公共事件或一段自定义事件。比如 `core.insertAction(["剧情文本"])` 将执行一个剧情文本显示事件。 - `core.changeFloor('MT2', 'downFloor')` 立刻执行楼层切换到MT2层的下楼点位置。 - `core.changeFloor('MT5', null, {'x': 4, 'y': 7})` 立刻切换楼层到MT5层的(4,7)点。 - `core.getBlock(3, 5, 'MT1')` 获得当前地图上某一个块的信息。第三个参数为floorId,可省略表示当前楼层。 @@ -234,16 +203,16 @@ HTML5的塔都是可以进行控制台调试的。 更多API和详细参数介绍可参见[API列表](api)。 ## 编辑器的基本操作 - +- **H** 查看所有快捷键 - **Alt+0~9, 0~9** 保存和读取当前选中图块 - **W/A/S/D** 移动大地图 - **Ctrl+Z** 撤销上次绘图 - **Ctrl+Y** 重做上次绘图 -- **PgUp/PgDn** 切换楼层 +- **PgUp/PgDn,或滚轮** 切换楼层 - **Ctrl+S** 保存事件编辑器/脚本编辑器 - **地图上单击** 选中该点 - **地图上双击** 选中该点图块 -- **地图上右键** 弹出菜单栏,包括选中、复制、清除等操作 +- **地图上右键** 弹出菜单栏,包括选中、复制、交换、清除、更改出生点、快速绑定等操作 - **事件编辑器中Ctrl+C, Ctrl+X, 右键等** 执行相应操作 ## 报错处理 @@ -273,10 +242,7 @@ HTML5的塔都是可以进行控制台调试的。 ![删除ID](./img/floorid.png) 请注意,手动删除楼层时一定要确保“初始楼层ID”是一个有效且存在的floorId! - -  - -如有任何无法解决的问题,欢迎加群**539113091**寻求帮助。 +
如有任何无法解决的问题,欢迎加 QQ 群 [959329661](https://jq.qq.com/?_wv=1027&k=5C87qeQ) 寻求帮助。 ==========================================================================================