diff --git a/_docs/V2.0.md b/_docs/V2.0.md
deleted file mode 100644
index 00d1084e..00000000
--- a/_docs/V2.0.md
+++ /dev/null
@@ -1,89 +0,0 @@
-# V2.0版本介绍
-
-?> 目前版本**v2.6.6*,上次更新时间:* {docsify-updated} *
-
-目前样板已经更新到V2.0版本以上,本章将对V2.0的一些内容进行介绍。
-
-请确保已经看过前面的几个文档(2.0都有部分更新),前面已经描述过的东西这里将不再赘述。
-
-也欢迎通过看B站的视频教程来具体了解2.0版本的使用方法。
-
-## 目录结构的改变
-
-在1.x中,所有数据和逻辑都是一体的,例如怪物数据和怪物伤害计算公式等等。这导致样板的版本更新时会十分不便。
-
-在2.0中,我们将数据和逻辑进行了分离,拆分成了libs和project两个目录。
-
-- libs目录为游戏核心库文件,包括一些游戏逻辑等内容
-- project目录为针对每个塔的目录,是和游戏逻辑是分离的。
-
-我们只需要修改project目录下的各项内容,而无需去动libs目录(有特殊需求除外);
-将来如果想把塔迁移到新的版本上,也只需要迁移project即可。
-
-另外一点的就是,我们将libs目录中的core.js进行了拆分,从而使每个文件的具体工作更加一目了然,也避免了接近6K行的大文件会导致打开IDE的卡顿问题。
-
-## 全GUI造塔
-
-在1.X版本中,我们提供了一个地图编辑器。但是它的功能十分弱,只能进行绘图的功能,实际的各项操作还是需要通过VSCode打开js文件实际进行编写代码。
-
-但是在2.0中,我们大大拓展了地图编辑器的功能,从而达到了“全GUI造塔”的功能,用户再也不用手动打开任何一个文件进行编辑了。
-
-GUI界面分为`地图编辑器`,`事件编辑器`和`文本编辑器`。
-
-!> 即使现在可以全GUI造塔,也强烈建议对1.X的造塔方式进行了解,因为这是一切的基础。
-
-### 地图编辑器
-
-地图编辑器分为三个区域,左侧的`编辑区`,中间的`画布区`,右侧的`素材区`。
-
-画布区下方有切换地图和编辑器模式的下拉菜单,点击`保存地图`后画布的内容才会真正写入到js文件中。
-
-在素材区点击图块时,会选中该图块,此时tips会显示该图块的信息,编辑区会进入图块属性模式,怪物或物品可以直接在里面编辑数值。如果图块的数字和ID没有被定义,则可以直接在左侧定义,**定义新图块后需要保存并刷新页面后才能生效**。
-
-在tips中有图块信息时,在画布上点击或拖拽可以把图块画上去,可以使用ctrl+Z撤销操作以及对应的ctrl+Y恢复撤销。擦除方块可以使用素材区最左上角的擦除块。
-
-点击界面中的空白,tips中的图块信息会被清空,此时再点击画布上的点,则编辑器会进入地图选点模式。此模式下可以编辑改点的`events`,`afterBattle`,`changeFloor`等事件或者是`canMove`来改变各方向的通行状态。
-
-切换地图会使编辑区进入楼层属性模式,这里可以修改首次到达该楼层时会触发的事件`firstArrive`,楼层显示的名称,默认的前景背景图片,默认天气和色调等等。
-
-!> 这里不允许编辑楼层的ID,需要修改ID的场合请直接改js文件,并保持三个标识符完全一致。`data.js`中的`floorIds`也需要对应进行修改。
-
-全塔属性中编辑整个塔为单位的属性,例如起始剧情`startText`,`name`,提供哪些难度,主角的起始属性,全局商店,各种数值以及系统FLAG等。**创建新塔时需要认真编辑这里面的所有选项。**
-
-脚本编辑模式可以修改常用的需要更改的函数。例如,给不同的难度设置不同的内容`setInitData`,加点`addPoint`,以及修改游戏中的关于界面`drawAbout`等等。
-
-追加素材模式可以导入一个图片到该标签的画板中,然后依次点击画板中的图块,点追加就可以按顺序把这些图片添加到对应的画布区素材的最下方,**需要刷新来生效**。
-
-地图编辑模式中可以导入来自地图生成器的地图数组,同时创建新楼层需要在这里通过另存为来实现,可以点清除地图把另存为出的新楼层清空。
-
-!> 编辑区的表格可以直接修改,推荐通过双击,在事件编辑器和文本编辑器中进行编辑。编辑区中的修改需要点保存才会生效。
-
-### 事件编辑器
-
-地图选点中的事件类表格,以及楼层属性中的`firstArrive`和全塔属性的`startText`,在双击时会进入事件编辑器,是由[antlr-blockly](https://github.com/zhaouv/antlr-blockly)生成的图块式的可视化编辑器.
-
-把左侧的方块拖到面板中,下方就会实时的显示对应的js的代码(以及数值不正确时的提示).
-
-每个方块点击右键会展开一个菜单,点帮助可以跳转到此文档中对应的内容。利用好复制功能可以极大提高编辑的效率。注释选项请不要使用,编辑器并不会保留这里的注释。
-
-`template`中提供了一些模板事件,例如战前剧情,打怪开门。
-
-`显示文章`的两个方块,以及`自动剧情文本`,`选项`和`自定义JS脚本`这5个方块,可以通过双击在文本编辑器中(以多行的方式)编辑其中的文字。
-
-### 文本编辑器
-
-事件编辑器之外的内容双击后由文本编辑器来编辑,是有js高亮支持的多行文本编辑器[CodeMirror](https://github.com/codemirror/CodeMirror),点confirm即可使编辑的文本替换到表格中。
-
-### 拓展地图编辑器
-
-> 面向有一定编程基础的用户
-
-修改`_server/`下的`*comment.js`可以让地图编辑器对自己添加的属性有更好的支持.例如:
-+ 给`comment.js`中`enemys`加入新的键值对,就可以更方便的给怪物在UI界面中添加对应的值.
-+ 在`data.comment.js`中把自己添加的内容标记为叶节点,不再在表格中展开到最末端.
-
-地图编辑器的部分API见`_server/README.md`
-
-## 部分事件和API更新
-
-在2.0中,有部分的事件和API存在更新,也增加了包括48x32素材的支持,在这里将不再赘述,请仔细阅读前面的几个文档进行了解。
diff --git a/_docs/element.md b/_docs/element.md
index f804b40e..69f5f30a 100644
--- a/_docs/element.md
+++ b/_docs/element.md
@@ -13,7 +13,11 @@
5. `project\materials\npcs.png`:32×32px的NPC,如老人、商人、小偷、公主、仙子、木牌、魔龙和章鱼的其他8块,您可以随意修改它们的任何属性。
6. `project\materials\npc48.png`:32×48的NPC,自带只有样板0层的小姐姐,但您也可以用它来制作32×48px的门。
7. `project\autotiles`:自动元件,会随着在地图上的连续摆放而自动采取适当的绘制方式。
-8. `project\tilesets`:额外素材,用来突破其他素材合计不得超过1000个的限制。您可以在这个区域拖动来批量框选,再在地图区单击成片绘制或拖动平铺。
+8. `project\tilesets`:额外素材,用来突破其他素材合计不得超过10000个的限制。您可以在这个区域拖动来批量框选,再在地图区单击成片绘制或拖动平铺。
+
+V2.7.3中,terrains.png追加了薄墙图块(红线),V2.8中它们被挪到了最下方,可供利用。
+
+V2.8中,自动元件在素材区折叠模式下会只显示左上角一格,与RPG Maker一致。
## 地图编辑(快捷键Z)
@@ -21,9 +25,9 @@
如图所示,您可以在此对地图进行清空或删除操作,也可以新建或批量新建任意宽高的空白地图。
-其中“导出并复制地图”是指显示出左侧的矩阵并复制(一般用来跨塔复制地图),您也可以直接改动其中的数字,再点击“从框中导入地图”就能将改动的结果同步到地图上。
+其中“导出并复制地图”是指显示出左侧的矩阵并复制(一般用来跨塔复制地图),您也可以直接改动其中的数字(例如将绿色史莱姆批量替换为红色史莱姆),再点击“从框中导入地图”就能将改动的结果同步到地图上。
-下面的“楼层ID、中文名、状态栏名”分别对应楼层属性(快捷键V)的floorId、title和name,其中floorId也作为文件名(不能使用中文),title会显示在楼传界面和楼层切换黑屏,name也允许使用中文。
+下面的“楼层ID、中文名、状态栏名”分别对应楼层属性(快捷键V)的floorId、title和name,其中floorId也作为文件名(不能使用中文,注意大小写问题),title会显示在楼传界面和楼层切换黑屏,name也允许使用中文。
## 图块属性(快捷键C)
@@ -36,6 +40,10 @@
3. **图块类别:**图块素材的类型。
4. **图块名称:**怪物在手册中、道具在道具栏中、其他图块在剧情对话中的默认名称,可以随意修改。但原则上不推荐不同的怪物和道具有重复的名称,否则会影响事件编辑器的中文替换功能。
+V2.8中,图块名称在有罗马数字、希腊字母、日文假名的情况下也支持事件编辑器中的中文替换了,这大大方便了一些科幻或魔法题材的作品。
+
+V2.8中,道具名称支持使用${表达式计算}语法,但这样做会使其在事件编辑器中的中文替换失效。
+
你可以随时使用 `core.getBlockId(x, y, floorId, showDisable)` 获得地图上任何一个点的图块ID;`core.getBlockCls(x, y, floorId, showDisable)` 或的地图上任何一个点的图块类别;详见[API列表](api)。
在讲解其他属性之前,这里简单介绍一下素材的注册机制:
@@ -44,28 +52,41 @@
* 未注册的图块则只有“索引”,索引为n表示该图块在图片的第(n+1)行,
* ID和索引的对应关系定义在`project\icons.js`中。
* 尝试用未注册的图块(如利用便捷PS工具新追加的图块)在地图上绘制,就会出现红色的问号方框。
-* 此时请在数据区手动注册此图块,只需填写一个新ID和数字(1000以内)即可。
-* 也可以点击“自动注册”按钮批量注册该图片的所有未注册素材,自动注册出的ID无任何意义,建议手动修改成有意义的内容。
+* 此时请在数据区手动注册此图块,只需填写一个新ID和数字(10000以内)即可。
+* 也可以点击“自动注册”按钮批量注册该图片的所有未注册素材,自动注册出的ID无任何语义(一般是一个表示图块类别的大写字母加几个数字),建议手动修改成有语义的内容(如史莱姆以Slime结尾)。
自动元件的注册与此不同,除了替换样板现有的几个外,如果还需要追加新的,请在地图区下方的下拉框中切换到“追加素材”(快捷键M),然后导入文件到画板autotile,再点击“追加”按钮即可。非Windows系统追加其他素材也主要依靠这种方式,具体用法请自行探索。
+V2.7起,电脑端支持将文件直接拖动到素材区对应的列,进行追加。具体规则如下:
+1. 道具的图片宽高必须为32的倍数,每格会被追加为一个新道具
+2. 其他类别的多帧图块(不包括自动元件和tileset),规格必须为128×128、128×192、96×128、96×192之一,分别对应32×32和32×48的四行四列或四行三列。
+3. 向两帧的enemys.png或npcs.png追加时,四列的图片取中间两列,三列的图片取两边两列。
+4. 向四帧的animates.png、enemy48.png、npc48.png追加时,三列的图片按2123排布。
+
+V2.8起,图块支持“(注销并)删除”操作,执行后将(对已注册的)删除该图块在maps.js和icons.js的信息(如果是怪物和道具则还会删除对应的信息),然后将该图块从图片上删除,图片上更靠下的图块会被统一上移一格。
+
### 非怪物非道具属性
1. **触发器:**当碰触到地图上此图块时触发的系统事件,详见[事件](event)。
- * **battle**: (未列出)战斗;当撞上一个怪物且没有覆盖触发器时(参见[事件](event))将自动调用此触发器产生战斗,并此战后事件。
- * **getItem**: (未列出)获得道具;当撞上一个道具且没有覆盖触发器时(参见[事件](event))将自动调用此触发器获得它,并触发道具后事件。
- * **changeFloor**: (未列出)楼层切换;对于地图上绑定的绿点将自动调用此触发器产生楼层切换事件。
- * **openDoor**: 用于制作门效果,当撞上此图块时将尝试开门(仅对`animates`和`npc48`生效);具体开门动画参见下面的门信息。
- * **pushBox**: 推箱子信息;请勿对非箱子使用此触发器。
- * **ski**: 冰信息;拥有此触发器的图块放置在背景层时,走上去将触发滑冰效果。
+ * **battle**: (未列出)战斗;当撞上一个怪物且没有覆盖触发器时(参见[事件](event))将自动调用此触发器产生战斗,并触发战后事件。
+ * **getItem**: (未列出)拾获道具;当撞上一个道具且没有覆盖触发器时(参见[事件](event))将自动调用此触发器获得它,并触发(拾获)道具后事件。
+ * **changeFloor**: (未列出)楼层切换;对于地图上绑定的绿点(常见于楼梯或彩色箭头)将自动调用此触发器产生楼层切换事件。
+ * **openDoor**: 用于制作门效果,当撞上此图块时将尝试开门(仅对`animates`和`npc48`生效),并触发开门后事件;具体开门动画参见下面的门信息。
+ * **pushBox**: 推箱子;请勿对非箱子使用此触发器。
+ * **ski**: 滑冰;拥有此触发器的图块放置在背景层时,走上去将触发滑冰效果。
* **custom**: 自定义系统触发器;你可以使用 `core.registerSystemEvent` 来自己定义一个系统触发器,参见[API列表](api)。
2. **可通行性:**勾选后勇士才可以踏入此图块,否则只能撞击此图块。(怪物被锁定为不可通行,道具被锁定为可通行,如有需要可以修改点上的不可通行性)
-3. **碰触脚本:**勇士踏入或撞击此图块时执行的脚本,该项会被eval,相当于一种自定义的触发器,您可以参考踩灯和四种路障去填写它。
-4. **不可出入方向:**对三个图层的图块都有效。不可出方向指的是勇士站在这种图块上不能向哪个方向走(包括撞击),不可入方向指的是勇士不能从哪个方向走向这种图块(包括撞击)。例如,勾选了“上”则不能从上方向下走向这个图块。请参考素材区第一列最下面的四个箭头。
+3. **碰触脚本/碰触事件:**勇士踏入或撞击此图块时执行的脚本,该项会被eval,相当于一种自定义的触发器,您可以参考踩灯和四种路障去填写它。V2.8起,新增了“碰触事件”,使用起来更方便也更安全。
+4. **不可出入方向:**对三个图层的图块都有效。不可出方向指的是勇士站在这种图块上不能向哪个方向走(包括撞击),不可入方向指的是勇士不能从哪个方向走向这种图块(包括撞击)。例如,不可入方向勾选了“上”则不能“从上方、向下”走向这个图块。请参考素材区第一列的四个灰色箭头(样板1层右下角也有)。
5. **可破震:**勾选后,此图块将成为破墙镐(pickaxe)和地震卷轴(earthquake)这两个道具的目标。
-6. **动画帧数:**您可以修改此帧数来让本来有4帧的图块只用前3帧循环播放,另外制作门时请务必将此帧数改为1,表示门在打开前静止在第1帧。
+6. **动画帧数:**您可以修改此帧数来让本来有4帧的图块只用前2或3帧循环播放,另外制作门时请务必将此帧数改为1,表示门在打开前静止在第1帧。
7. **门信息:**只对`animates`和`npc48`有效,您可以点击“编辑按钮”来填写此图块作为门的开关耗时、开关音效以及需要哪些钥匙各多少把(可以填写任何消耗类道具,也可以选择某些道具只需持有一定数量而不消耗)。修改此信息后,您需要将上面的“动画帧数”改为1,并可能需要将“触发器”改为openDoor(不改的话将无法通过撞击来开门,但可以像三色墙一样用来制作暗墙)。
-8. **行走图朝向:**只对npc48有效。设置后,当勇士撞击该npc时npc会尝试转身面向勇士(对话事件结束前请使用“事件转向”指令将其转回去)。走动时也会尝试自动转向,请参考样板0层使用的小姐姐。
+ * 该项在V2.7首次提供,只支持“同时需要多种钥匙各多少把、消耗其中哪几种”的“且运算”条件。
+ * 如果您需要指定“或运算”条件(如优先消耗一种钥匙,没有再消耗另一种),或“消耗量”少于“需要持有量”,或者需要判断的条件不是道具而是其他条件(比如勇士状态或flag),请使用“碰触事件”,但这样将无法自动存档。
+ * V2.8新增了(批量)开门后事件,它和(单点)开门后事件的执行先后顺序,由“脚本编辑——开门后脚本”指定。
+ * 因此,复杂的开门条件也可以换个角度思考,把开门条件设为什么都不需要(先斩后奏,这一思想在道具使用条件中也很常见),开门后事件中再进行判断,如果开门成功就按照条件扣除钥匙,开门失败就再把门关上就好了,这样就保留了自动存档功能。
+8. **行走图朝向:**设置后,当勇士撞击该图块时,图块会尝试转身面向勇士(对话事件结束前请使用“事件转向”指令将其转回去)。走动时也会尝试自动转向,请参考样板0层使用的小姐姐。
+ * V2.8起,“行走图朝向”可以用于怪物,绑定后只需手动设置脸朝下的怪物属性而不用管其他的,手册显示、实际战斗、阻激夹域、漏怪检测(hasEnemyLeft)等都会强制读取脸朝下的怪物,游戏中动态修改任何一个朝向的怪物属性都会立即强制同步到四个怪物身上。
### 道具属性
@@ -73,53 +94,74 @@
1. **道具类别:**虽然和图块类别的英文缩写都是cls,但有本质区别,请注意区分。道具的图块类别都是items,而道具类别分为以下几种:
* items:是的你没看错,又是`items`这个词,请注意和图块类别的`items`相区分。它表示即捡即用类不进背包的道具,如四种血瓶、三种宝石等。这类道具需要用到的其他属性有“即捡即用效果”、“即捡即用提示”、“碰触或使用事件”。
- * tools:进背包的消耗类道具,如钥匙和解药瓶、便携式血瓶蓝瓶(生命魔杖)、破震炸飞和跳鞋等。这类道具需要用到的其他属性有“道具描述”、“不显示在道具栏”、“回放不绘制道具栏”、“碰触或使用事件”、“使用效果”、“能否使用”。
+ * tools:进背包的消耗类道具,如钥匙和解药瓶、便携式血瓶蓝瓶(生命魔杖)、破震炸飞和跳跃靴等。这类道具需要用到的其他属性有“道具描述”、“不显示在道具栏”、“回放不绘制道具栏”、“碰触或使用事件”、“使用效果”、“能否使用或装备”。
* constants:进背包的永久道具(每件在背包的数量要么为1要么为0),如手册、楼传、幸运金币、十字架、护符、二倍斩等,这类道具需要用到的其他属性和tools一致。
- * equips:装备,它需要用到的其他属性有“道具描述”、“道具的装备属性”、“能否装备”。
- * 例如:如果您想把四种血瓶和三种宝石改为便携式,就只需把其道具类别改为tools(当然,楼层属性中的宝石血瓶效果一项也就失效了)。
+ * equips:装备,它需要用到的其他属性有“道具描述”、“道具的装备属性”、“能否使用或装备”。
+ * 例如:如果您想把四种血瓶和三种宝石改为便携式,只需把其道具类别改为tools(当然,楼层属性中的ratio一项也就失效了)。
* 如果想把大黄门钥匙变为钥匙盒(红黄蓝钥匙各一把),只需把其道具类别从tools改为items
- * 如果想把剑盾变成装备,只需把其道具类别改为`equips`,等等
+ * 如果想把剑盾变成装备,只需把其道具类别改为`equips`;
+ * 如果想修改破墙镐和炸弹的目标个数或让炸弹能够触发战后事件,请修改它们的使用效果。
2. **道具描述:**对除即捡即用类外的道具都有效。一个字符串,为道具在道具栏里的描述,也作为首次捡到时的提示信息的一部分(如果全塔属性中开启了这一提示功能的话)。支持使用`${表达式计算}`语法(如四种血瓶和三种宝石那样,但不支持中文替换),此语法的详细规则见“显示文章正文的转义序列”,和“值块和冒号缩写量”。
-3. **不显示在道具栏:**对tools和constants有效,勾选此项后,该道具在背包中将不显示出来。常用于不能主动使用或已有专门的使用按钮的道具来节省显示篇幅,如手册、楼传、幸运金币、十字架、护符和钥匙等。
+3. **不显示在道具栏:**对tools和constants有效,勾选此项后,该道具在背包中将不显示出来。常用于不能主动使用或已有专门的使用按钮的道具来节省显示篇幅,如手册、楼传、幸运金币、十字架、护符和钥匙等。该属性的详细原理,见“脚本编辑(N键)”最下面的“道具栏显示项”。
4. **回放不绘制道具栏:**勾选此项后,录像回放中使用此道具将不显示黑黑的道具栏。常用于频繁使用的道具,如楼传、技能和冰冻徽章等。
5. **即捡即用效果:**如题,该项会被eval,一般为一行下述的代码: `core.status.hero.xxx += yyy * core.status.thisMap.ratio`
- * 其中xxx为勇士的某种状态(如生命hp、生命上限hpmax、魔力mana、魔力上限manamax、护盾mef、攻防和金经)
+ * 其中xxx为勇士的某种状态(如生命hp、生命上限hpmax、魔力mana、魔力上限manamax、护盾mdef、攻防、金经)
* yyy为此道具的基础效果(如四种血瓶和三种宝石的基础效果定义在了全塔属性中)
* `core.status.thisMap.ratio`则是指该道具所在楼层的“楼层属性”最下面的“宝石血瓶效果”。
+ * 此效果会在“B键数据统计”被模拟执行(使用道具所在楼层的ratio)然后计算执行前后勇士状态差异,因此请尽量只在里面用脚本直接操作`core.status.hero`,而不要使用tip或特效。
+ * 可以在此项中使用`core.insertAction([...])`或`core.insertCommonEvent()`插入事件或公共事件,但不会计入数据统计。
6. **即捡即用提示:**实际显示时会被接在“获得xxx”后面,所以该项总是一个以逗号开头的字符串,同样支持`${表达式计算}`语法。
-7. **碰触或使用事件:**对除equips外都有效。该项用于代替“即捡即用效果”(但会使勇士停下脚步,且会晚于afterGetItem事件被执行)和“使用效果”,如样板中的黄宝石和生命魔杖。如果您的js语法基础薄弱,那么它将是您的不二之选。
+7. **碰触或使用事件:**对除equips外都有效。该项用于代替“即捡即用效果”(但会使勇士停下脚步,且会晚于地图上的afterGetItem事件被执行,且不计入B键数据统计)和“使用效果”,如样板中的黄宝石和生命魔杖。如果您的js语法基础薄弱,那么它将是您的不二之选。
8. **使用效果:**对tools和constants有效。该项会被eval,一般为一个js函数,较为简单的使用效果(如解药瓶)也可能是一行代码,破炸冰的目标个数请直接在该项中修改。总的来说因为事件比起脚本更容易实现异步特效且录像安全性更好,所以如非必要,不建议用此项。
9. **能否使用:**对tools和constants有效。该项也会被eval,一般为一个js函数,较为简单的使用条件(如解药瓶)也可能是一行形如`core.hasFlag('xxx')`的代码。如果该道具在任何情况下都不能主动使用,请留null(并最好勾选“不显示在道具栏”以节约显示篇幅),如果该道具在任何情况下都可以使用,请填“true”,如果使用条件较为复杂,也推荐直接填“true”先斩后奏,在使用效果中再行判定,并在使用失败的场合使用`core.addItem('xxx')`静默返还一件该道具,如样板中的破墙镐和炸弹。
10. **能否装备:**对equips有效,请注意在装上装备后如果条件不再满足也不会自动卸下。和“能否使用”不同,此项留null表示任何情况下都可以装备。
11. **道具的装备属性:**在介绍此项之前,请先留意一下“全塔属性”中的“装备孔”一项。该项为一个字符串数组,最多允许6项(13×13样板)或8项(15×15样板)。每一项为装备的类型名称,建议是两个汉字(如“武器”、“防具”)。类型允许重复,如可以让勇士最多同时装备两块盾牌。
- * 装备类型:一个自然数,和前面的“装备孔”对应,如0表示武器,1表示防具。如果装备孔有重复的名称则这里也直接写名称(不用加引号),穿戴时会自动尝试寻找第一个同类型的空闲装备位,没有空闲的话会提示玩家先卸下一件。
+ * 装备类型:一个自然数,和前面的“装备孔”对应,如0表示武器,1表示防具。如果装备孔有重复的名称则这里也直接写名称(不用加引号),穿戴时会自动尝试寻找第一个同类型的空闲装备位(如果同类型的装备位唯一则会不管空闲与否直接替换),没有空闲的话会提示玩家先卸下一件。
* 普攻动画:`project\animates`文件夹中任何一个文件的名称(不带后缀,但需要在全塔属性中注册过),只对第一个装备孔有效。普攻动画会播放在和勇士战斗的怪物位置处,如果是强制战斗的天降怪物,则会播放在勇士身上并跟随,请自行注意。详见“文件注册”使用动画。
* 数值提升项:若干个键值对,表示该装备增加属性的常数值(支持负数)。7个常用属性可以通过下拉框选取,自定义的新属性也可以手动输入。
* 百分比提升项:若干个键值对,表示该装备增加属性的百分比(支持负数,如填-10就表示减少10%),修改方法同上。
+ * 请注意,两种提升项只能写常数,请不要认为写个flag变量就能自动变化了。
+ * V2.8中,两种提升项可以在游戏过程中通过事件指令来修改(包括已经穿在身上的装备,但是修改后的值仍然视为常数),同时每件装备新增了“穿脱时事件”属性,该事件以自动事件方式实现,在换好装备后关闭装备栏的瞬间触发。而且下述各种buff可以使用冒号缩写量来读写了,详见[事件](event)。
+ * “穿脱时事件”指的是身上某件装备“从无到有”和“从有到无”,不包括“从多到少”和“从少到多”(在装备孔有重复名称的情况下)。
+ * “穿脱时事件”的自动事件定义在`libs\core.js`,如需修改(例如改为检测“多少”而不是“有无”),请在插件“init”中直接修改`core.initStatus.autoEvents`,这是一个一维数组,数组的每项为一个自动事件对象,对象的`symbol`属性含有`"equipEvent_"`时就表明这是一个穿脱时事件,然后您可以修改其触发条件以及执行内容的第一项(flag变化)。
* 装备对属性的影响原理:在穿脱装备时,会根据数值提升项和百分比提升项,分别调用`core.status.hero.xxx += yyy`和`core.addBuff('xxx', yyy)`这两个API(衰弱的附加和解除同理),而状态栏的显示值和战斗中的使用值则是`core.getStatus('xxx')`和buff值相乘再向下取整所得。
- * PC端可以按Alt+0~9快速更换套装。
+ * 可以按Alt+0~9快速更换套装(在装备界面按这个组合键则是保存套装),手机端的Alt键在V2.8被提供为粘滞键,点击状态栏右下角的难度标签就能看到。
道具相关API请阅读[API列表](api)。
### 怪物属性
-1. **手册映射ID:**如前所述,npc48提供了“行走图朝向”来实现多朝向,而怪物则没有这么好的待遇。如果您制作了四种面朝不同方向但属性完全一致的怪物,那么您可以将其中三种怪物的“手册映射ID”填写为剩下一种怪物的ID,这样手册中(确切地说,`core.getCurrentEnemys()`函数的因变量)就会统一显示为剩下那一种怪物。
+1. **手册ID:**【已弃用】,原本是V2.8以前用来不完全实现多朝向怪物和大型怪物缩略图的手段,现在建议全部用新增的“行走图朝向”属性和“单点图块不透明度设置”代替。该项设置后怪物将在手册中不显示为原怪物而显示为对应的怪物ID.
2. **生命、攻防、金经:**如题,注意金经必须在“全塔属性”(快捷键B)中的“状态栏显示项”中也勾选才能真正被启用。持有幸运金币时打怪获得的金币翻倍,附加诅咒状态时打怪不获得金经。
3. **加点:**若全塔属性勾选了“加点”,则此项为正数时将作为与该怪物每场战斗胜利后传递给“公共事件——加点事件”的参数(即那里的flag:arg1,默认表示加点的倍率),您可以自行修改该事件。
-4. **不可炸:**勾选后该怪物不会成为炸弹的目标,有阻击怪在场的情况下请务必给有战后事件的怪物(如机关门守卫和boss)勾选此项,否则玩家可能会偷梁换柱地炸掉该怪物并把阻击怪推过去打死来触发战后事件。
-5. **特殊属性:**一个由正整数组成的一维数组,您可以点击“勾选框编辑”按钮来修改它。所有特殊属性都定义在“脚本编辑——怪物特殊属性”,您可以在那里追加新的。它们大体分为四类:
+4. **不可炸:**勾选后该怪物不会成为炸弹的目标,有阻击怪在场的情况下请务必给有(单点)战后事件的怪物(如机关门守卫和boss)勾选此项,否则玩家可能会偷梁换柱地炸掉该怪物并把阻击怪推过去打死来触发战后事件。不过V2.8起,炸弹的使用效果中提供了炸单点怪物触发战后事件的示例,可供利用。
+5. **(批量)战前/战后事件:**V2.8新增,用于解决阻击怪等会移动的怪物不能使用地图上的战前/战后事件的问题。
+ * 两种战前事件都会在“撞击怪物、判定可以战胜、自动存档”后触发,这比起曾经的“覆盖触发器+天降强制战斗”对玩家更为友好。
+ * 批量战前事件默认晚于单点战前事件(修改需要复写函数),批量战后事件与单点战后事件的执行顺序可以直接在“脚本编辑——战后脚本”中调整。
+ * 两种战前事件在强制战斗时都不会触发,并且都早于支援怪的跳跃动画,因此捕捉怪的战前事件也不会触发。
+ * 两种战前事件中如果使用“立刻结束当前事件”就会取消战斗,必要时您可以利用这一点制作回合制战斗。
+ * 批量战前事件可以方便地制作“怪物先打一下勇士,再被勇士打死”的效果,同时延迟了怪物的消失,使得怪物根据“行走图朝向”转身后的效果能够来得及被看到。
+ * 批量战后事件可以方便地制作“被打败后立即变身为另一种怪物/路障,或掉落一种道具”的效果。
+ * 您新增加的类似先攻、破甲、净化、吸血、仇恨、固伤的属性可以使用战前/战后事件更便捷地实现并无视护盾,同时也避免了下面提到的各项value冲突的问题,但这样做的后果是不计入显伤,详见下面的解释。如果一定要这样实现,建议通过额外的说明提醒玩家。
+6. **特殊属性:**一个由正整数组成的一维数组,您可以点击“多选框编辑”按钮来修改它。所有特殊属性都定义在“脚本编辑——怪物特殊属性”,您可以在那里追加新的。它们大体分为四类:
1. 手册中属性值的修正:(按照结算顺序)模仿、坚固、光环,修正后的属性也将被用于战斗,详见“脚本编辑——怪物真实属性”。
2. 战损的修正:这类最多,先攻、魔攻、连击(次数为n)、破甲(比例为defValue)、反击(比例为atkValue,回合数为勇士的攻击回合数)、净化(倍数为n,1表示单纯无视护盾)、吸血(比例为value,是否加到自身为add)、仇恨(每场战斗的仇恨增值由全塔属性指定)、无敌、固伤(数值为damage)、支援。其中又以仇恨和固伤不能被护盾直接抵消而和无敌较为特殊,详见“脚本编辑——战斗伤害信息”。
- 3. 战后的影响:中毒、衰弱、诅咒、仇恨(的累加和减半)、自爆、退化(扣减值分别为atkValue和defValue)、重生,详见“脚本编辑——战后脚本”和“脚本编辑——毒衰咒”。
+ 3. 战后的影响:中毒、衰弱、诅咒、仇恨(的累加和减半)、自爆、退化(扣减值分别为atkValue和defValue)、重生,详见“脚本编辑——战后脚本”和“脚本编辑——毒衰咒处理”。由于上面的“批量战前/战后事件”的存在,这种技能不再推荐由脚本实现。
4. 阻激夹域捕捉:即对主角行走的妨害,详见“脚本编辑——阻激夹域伤害”,该函数也负责了血网(图块ID为lavaNet,请勿修改)的伤害。
-阻激域的伤害都为value且在夹击之前结算,领域的形状和半径与光环一致。
+您会发现一个可怕的事情,那就是上述1和2会影响显伤,而3(例如自爆)和战前/战后事件不会(且后者对勇士生命的影响默认是无视护盾的)。这对于魔塔来说可能是致命的,毕竟没有玩家想看到“一个明明显伤不是红色的怪物打了却会死”等情况。当然,也有一种办法是像flash版新新魔塔1和2那样“战斗过程带有随机性或QTE,手册只显示预估伤害”,这种设计模式在rm和h5魔塔界并不常用,请谨慎尝试。
-如果需要更复杂的形状(如米字形激光),请自行研究该函数。
+支援怪在进行支援时(护盾默认只计算一次)不具有坐标(类似天降强制战斗),因此不支持V2.8的“定点设置怪物属性”,同时基于坐标的一些判定也会失效。
-请勿给同一种怪物设置阻击和捕捉,否则其阻击只会变得类似固伤。
+发生支援时,金经(以及加点塔的加点值)都会累加,但加点事件只执行一次,也就是这次所有点数必须加在同一项属性,如需修改,请修改公共事件。
-可以看到,怪物属性中有很多值是彼此互相冲突的。请自行注意,比如分散给各项而不要都吊死在三个value上。最后介绍一些和怪物相关的API:
+阻激域的伤害都为value且在夹击之前结算,领域的形状和半径与光环一致。如果需要更复杂的形状(如米字形激光),请自行研究该函数。
+
+V2.8起,阻击和捕捉支持九宫格形状,由zoneSquare属性指定。如需实现九宫格夹击,请仿照它们。阻击默认可以推到已隐藏的事件处,如需禁止,请修改所在的函数。
+
+您甚至可以给同一种怪物设置阻击和捕捉,那么它会先后退然后在原位置留下一个残影和勇士战斗,从而起到刷金经的作用。
+
+可以看到,怪物属性中有很多值是彼此互相冲突的。请自行注意,比如设计新属性时分散给各项而不要都吊死在三个value上。最后介绍一些和怪物相关的API:
``` js
core.status.hero.flags.no_repulse = true; // 禁用阻击,包括伤害和后退效果
core.status.hero.flags.no_laser = true; // 禁用激光
@@ -136,38 +178,49 @@
如果您想在数据区的表格中追加新的属性项,或修改已有项的格式、范围和长短注释,请点击数据区顶部的“配置表格”按钮,并参照已有的项去追加和修改,具体可查阅[修改编辑器](editor)。
+至此您会发现,每种怪物不管出现在地图上的什么地方,其属性都是一样的(除非受到局部光环的影响)。所幸的是,V2.8提供了读写/移动单点怪物属性的API和事件,这种属性会在“脚本编辑——怪物真实属性”中最早生效,战后脚本中重置。此外,因受此属性或光环影响而导致同层多个同种怪物在手册中的数值不一致时,玩家可以选择作为多种怪物分别显示(包括具体坐标),详见游戏中的Esc菜单。
+
## 楼层属性(快捷键V)
-
+
-1. **楼层ID:**`project/floors`中的文件名,不允许使用中文也不能直接修改。修改方法见上图底部,修改后必须立即刷新浏览器页面。
+1. **楼层ID:**`project/floors`中的文件名,不允许使用中文也不能直接修改。修改方法见上图底部,修改后必须立即刷新浏览器页面,该项需要注意大小写问题。另外,作品发布时会统计楼层总数,如果有一些剧情层或连载塔半成品层不希望被统计进去,请使用“sample”+纯数字楼层ID即可,就像三个样板层一样。
2. **楼层名:**楼层在楼传、上下楼黑屏和浏览地图界面的名称。
-3. **状态栏显示:**勇士在此楼层时状态栏左上角上楼梯图标右边的文字,允许使用中文,但请注意控制字数。
+3. **状态栏显示:**勇士在此楼层时状态栏左上角“上楼梯”图标右边的文字,允许使用中文,但请注意控制字数。
4. **地图宽度和高度:**可在表格最下方修改。
* 如果地图被加宽或加高,则“偏移”表示右移或下移的格子数(左边缘或上边缘用空格子填补)。
* 如果地图被减窄或减矮,则“偏移”表示左移或上移的格子数(被移出左边缘或上边缘的图块将丢失)。
+ * 在大地图中,您可能需要对地图中的绝对坐标和视野中的相对坐标进行互相转换。这需要用到`core.bigmap`的以下几个属性:
+ * `core.bigmap.width`和`core.bigmap.height`表示大地图的宽高(单位为格子)。
+ * `core.bigmap.offsetX`和`core.bigmap.offsetY`表示视野左上角在大地图中的绝对像素坐标,再除以32就是格子坐标。
+ * 因此,对于任意绝对坐标(x,y),它在视野中的相对坐标就是(x-offsetX/32,y-offsetY/32)。
+ * 在大地图的非边缘区域,`hero.loc.x-core.bigmap.offsetX/32`和`hero.loc.y-core.bigmap.offsetY/32`总是都为6或7(样板尺寸的一半)。
+ * 反之,已知相对坐标求绝对坐标就用加法,请举一反三。
5. **几个勾选框:**
- * 可楼传:如果不勾选,则此楼层禁止成为楼传的目标楼层,勇士在此楼层也禁止使用楼传。
- * 快捷商店:如果不勾选,则勇士在此楼层禁止快捷使用商店。事件中的“启用全局商店同时打开”不受影响,详见“插件编写——全局商店”。
- * 不可浏览:如果勾选,则此楼层无法通过PageUp/PageDown键浏览,也不会计入B键数据统计。
- * 不可瞬移:如果勾选,则勇士在此楼层无法用E键和单击瞬移,常用于用自动事件去监听勇士坐标时。
- * 是否是地下层:如果勾选,则非平面模式下勇士在此楼层原地使用楼传会传送到上楼点,详见“脚本编辑——楼层飞行”。
-6. **首次到达事件、每次到达事件:**如题,详见“脚本编辑——切换楼层后”。
+ * 可楼传飞到:如果不勾选,则此楼层禁止成为楼传的目标楼层。该项的具体原理见“脚本编辑——flyTo楼层飞行”。
+ * 可楼传飞出:如果不勾选,则勇士在此楼层禁止使用楼传。
+ * 快捷商店:如果不勾选,则勇士在此楼层禁止快捷使用全局商店。事件中的“启用全局商店同时打开”不受影响,详见“插件编写——全局商店”。
+ * 不可浏览:如果勾选,则此楼层无法通过PageUp/PageDown键浏览,也不会计入全塔B键数据统计。
+ * 不可瞬移:如果勾选,则勇士在此楼层无法用E键和点击瞬移,常用于用自动事件去监听勇士坐标时,或者需要严格的计步属性时(如每走10步失去一把黄钥匙)。
+ * 是否是地下层:如果勾选,则楼传非平面模式下(或平面模式下该层还没有锚点时)勇士在此楼层原地使用楼传会传送到上楼点,详见“脚本编辑——楼层飞行”。
+6. **首次到达事件、每次到达事件:**如题,详见“脚本编辑——切换楼层后”。每层的这两个事件是共用独立开关的,常见用法有“进入新区时清空已到达的楼层列表,只保留当前楼层”从而实现勇士不能再飞回从前区域的效果。
7. **并行处理脚本:**一个字符串,为勇士在此楼层时浏览器每帧都会执行一次(eval)的脚本,最快每秒60次。一般用来制作一些定时特效如bgs、bgv,详见“脚本编辑——并行脚本”。
8. **上下楼点:**两个自然数构成的一维数组,将作为“楼层转换”事件(在地图上以图块左下角出现绿色小方块作为标记)和“楼层切换”指令中“上下楼梯”以及非平面楼传的目标坐标。
- * 如果不设置,则在传送时会尝试从地图中搜索上下楼梯图块。因此当某个楼层没有楼梯或有多个楼梯时(如《[新新魔塔](http://ckcz123.com/games/xinxin/editor.html)》),请务必设置这个属性。点击“编辑”按钮从地图选点即可。
+ * 如果不设置,则在传送时会尝试从地图中搜索上下楼梯图块。因此当某个楼层没有楼梯或有多个楼梯时(如《[新新魔塔](http://h5mota.com/games/xinxin/editor.html)》),请务必设置这个属性。点击“编辑”按钮从地图选点即可。
9. **楼传落点:**格式和设置方法同上。如果设置了此项,则楼传在此层的落点将强制变为该点,无视平面模式下的离开点和上面的上下楼点以及该层实际的楼梯位置。
10. **地面图块:**可以填写任何一个图块ID,此项也会作为手册和剧情对话中的帧动画背景。
-11. **色调:**一行四列的数组,前三项为小于256的自然数(分别表示红、绿、蓝),最后一项为0到1的浮点数表示不透明度,可以点击“编辑”按钮用取色器调色(见样板的主塔40层)。
- * 值得一提的是,很多事件也以颜色作为参数,这些都是可以使用取色器调色的。
-12. **天气:**一行两列的数组,第一项为字符串“rain”、“snow”或“fog”,第二项为不大于10的正整数,分别表示1—10级的雨天(见样板的主塔40层)、雪天(由大小不一的白色实心圆组成,详见样板1层)和雾天(由`project/materials/fog.png`放大后随时间加入不规则扰动得到)。
+11. **色调:**一行四列的数组,前三项为小于256的自然数(分别表示红、绿、蓝),最后一项为0到1的浮点数表示不透明度,可以点击“编辑”按钮用调色器调色。
+ * 值得一提的是,很多事件也以颜色作为参数,这些都是可以使用调色器调色的。
+12. **天气:**一行两列的数组,第一项为字符串“rain”、“snow”、“fog”、“cloud”、“sun”,第二项为不大于10的正整数,分别表示1—10级的雨天(雨丝数量和等级正相关)、雪天(由大小不一的白色实心圆组成,详见样板1层,雪花的数量和横飘速度和等级正相关)、雾天、多云、晴天(左上角洒下金色的阳光)。
* 色调层在天气层上方、UI层下方(如不透明色调会遮盖天气,浏览地图看不到色调),关于图层的详细说明,参见“个性化”
13. **背景音乐:**如题,当在游戏中触发楼层切换时(包括读档),如果`flag:__color__、flag:__weather__、flag:__bgm__`没有值,游戏当时的画面色调、天气、背景音乐就会变为楼层属性中的这三个设置项,详见“脚本编辑——切换楼层中”。
+ * V2.8起,该项允许多选,会随机播放其中一个。
14. **宝石血瓶效果:**如题,必须填写且必须为非负数。此项的用法为core.status.thisMap.ratio,请参考四种血瓶和三种宝石的捡拾效果。
+ * V2.8起,手册中的“1防”改为“加防”,表示加ratio点防御能减伤多少。
* 您还可以将其用于其他各种场合作为系数,如血网的伤害、中毒后每步的损血等。
15. **楼层贴图:**
- * 由于样板提供的图块只有32×32px和32×48px两种尺寸,且后者只能画在事件层,每个图块最多只能有4帧,因此对于一些大图块十分不便。
- * 你可以使用“楼层贴图”,该项允许您使用任何尺寸、任何帧数的素材,唯一的缺点是不支持伸缩、移动跳跃和淡入淡出效果。
+ * 由于样板提供的图块只有32×32px和32×48px两种尺寸,且后者只能画在事件层,每个图块最多只能有4帧,因此对于一些大图块十分不便,如npcs.png中被大卸八块的魔龙和章鱼。
+ * 你可以使用“楼层贴图”,该项允许您使用任何尺寸、任何帧数的素材,唯一的缺点是不支持移动跳跃和淡入淡出效果。
* 点击“编辑”按钮进入事件编辑器,每张图片的写法为(可从入口方块拖出,然后双击预览第一帧的效果):
1. 图片名(name):如题,图片需要放在`project/images`文件夹并注册。
2. 翻转(:x/:y/:o):您可以对贴图的每帧进行三种翻转,当然,帧顺序在原图中依然是从左到右的。
@@ -177,8 +230,8 @@
6. 裁剪起点坐标(x,y)和宽高(w,h):此项规定了贴图在按帧切分前从原图中取哪一部分,x和y为所取部分在原图中的左上角坐标(不填视为两个0),w和h为所取部分的宽高(不填表示一直取到右下角)。
7. 帧数(frame):不填视为1,如果填写了大于1的整数,就会把上述裁剪得到的结果再从左到右等分为若干份,并在实际绘制时从左到右逐帧(可能还带有翻转)循环绘制,每帧的持续时间和其他图块一致。
* 贴图本身只具有观赏性,您仍然需要使用空气墙等手段去控制其绘制区域各个点的通行性。
- * 在使用贴图来表现魔龙和章鱼这类大型怪物时,可以预先注册两种一样属性的怪物。一种透明,另一种为缩小到32×32px且只有两到四帧的版本。将前者画在地图上,怪物属性的“手册映射ID”填后者,最后在该点的战后事件中隐藏贴图即可。
- * 你可以在插件重复写`drawBg`和`drawFg`函数以控制贴图和图块的绘制顺序,详见[脚本](script)。
+ * 在使用贴图来表现魔龙和章鱼这类大型怪物时,需要预先准备一种32×32(2帧)或32×48(4帧)的行走图,并注册为怪物,放在地图上时指定该点的不透明度为0,最后在该点的战后事件中隐藏贴图即可。
+ * 你可以在插件中复写`drawBg`和`drawFg`函数以控制贴图和图块的绘制顺序(默认先绘制图块),详见[脚本](script)。
``` js
////// 绘制背景层 //////
core.maps.drawBg = function (floorId, ctx) {
@@ -204,80 +257,102 @@
### 文件注册
这部分基本上都是经由多选框半自动完成的,下面逐一讲解:
-1. **楼层列表:**`project/floors`文件夹中的文件名(不含后缀),此数组的顺序决定了楼传和上下楼器(fly、upFly、downFly)的顺序。
+1. **楼层列表:**`project/floors`文件夹中的文件名(不含后缀,但请务必注意大小写问题),此数组的顺序决定了楼传和上下楼器(fly、upFly、downFly)的顺序。
* 如果您不慎将勇士的出生楼层注销了或不慎删除了某些楼层的js文件,导致编辑器页面打开后一片白屏,请手动打开`project/data.js`去小心地修改floorIds以和实际的文件名相匹配,并将出生楼层改为一个存在的楼层。
* 其他更复杂的白屏请在控制台根据报错信息(安卓手机则使用ES文件浏览器查看日志)去小心地修改文件(如某个楼层文件有问题则可以注销它),如果难以独立解决,欢迎加QQ群959329661寻求帮助。
-2. **使用图片:**`project/images`文件夹中的文件名(需要后缀,必须全英数),单击“编辑”按钮,编辑器会自动扫描文件系统中格式合适的图片(如jpg、png和gif)。
- * 您可以预览并将需要的图片勾选。请注意,勇士的初始行走图必须在这里注册。另外,`winskin.png`只许替换为相同规格的图片而不要注销,否则道具商店插件无法正常绘制。
-3. **额外素材:**`project/tilesets`中的文件名(需要后缀,只支持png)。
+2. **分区指定:**一行两列的数组,可以使用事件编辑器编辑,每行表示塔的一个区域,该行的两列分别表示该区域的第一层和最后一层(后者不填表示到塔顶),不在任何区域的楼层组成公区。
+ * 游戏中,除了公区和勇士当前所在区以外的地图都将处于冻结状态,无法被浏览、无法被飞到、无法触发其自动事件、地图中的图块无法被读写。冻结状态的地图不会存入存档,从而节约了存档大小并加快了存读档速度,上百层的高层塔必备!
+3. **使用图片:**`project/images`文件夹中的文件名(需要后缀,必须全英数),单击“编辑”按钮,编辑器会自动扫描文件系统中格式合适的图片(如jpg、png和gif)。
+ * 您可以预览并将需要的图片勾选。请注意,勇士的初始行走图必须在这里注册。另外,`winskin.png`只许替换为相同规格的图片而不要注销,否则道具商店等插件无法正常绘制。
+4. **额外素材:**`project/tilesets`中的文件名(需要后缀,只支持png)。
* 注册方法同上,最大的区别在于这个数组的顺序必须保持好。如果随意调换其中的顺序,或注销不在数组末尾的图片,就会导致地图上最终呈现的素材发生错位。因此,新勾选的图片总会被自动追加到数组的末尾。
* 比起常规素材,额外素材最大的好处有几点:
- 1. 图片没有数量限制。常规素材的总数量最多只允许不到一千个,而额外素材每张图片上的图块数量最多允许一千个。
+ 1. 图片没有数量限制。常规素材的总数量最多只允许不到一万个,而额外素材每张图片上的图块数量最多允许一千个。
2. 查看和绘制更为方便。常规素材每个图块独占一行,每列为一帧,导致不方便观察,且用多个图块拼图必须逐图块绘制。额外素材都是静止的,所以每个图块只占一格,多个图块可以在准备素材时就直接以相邻的样子绘制在同一张图片上,绘制地图时直接从素材区拖动来批量框选,再在地图区单击成片绘制或拖动平铺。
- 3. 批量替换也更为方便。譬如您如果想制作形如“一场大战/天灾过后/多年以后,村庄/城镇化为了一片废墟”的效果,可以预先准备两张甚至更多张相同规格的额外素材图片,然后在适当的时候遍历某个/某些楼层的图块ID,将以“X1”开头的图块统一替换为“X2”开头等。发布单机版游戏时,您也可以提供多张相同规格的额外素材图片供玩家直接替换。当然,使用这类做法的话就没法再使用“额外素材合并”了。
- * 当您即将发布您的游戏时,可以使用“额外素材合并”工具将用到的额外素材图块重新拼成更少的图片,以减少游戏体积和加快在线游戏的加载。执行此操作后,额外素材的图块ID和数字(包括第一位)都将被打乱,因此请勿在制作中以任何方式直接引用其ID和数字。如确有此需求,请间接引用、等量代换。
-4. **使用动画:**`project/animates`文件夹中的文件名(不含后缀,请注意与`animates.png`相区分)。
+ 3. 批量替换也更为方便。譬如您如果想制作形如“一场大战/天灾过后/多年以后,村庄/城镇化为了一片废墟”的效果,可以预先准备两张甚至更多张相同规格的额外素材图片,然后在适当的时候遍历某个/某些楼层的图块ID,将以“X1”开头的图块统一替换为“X2”开头等。发布单机版游戏时,您也可以提供多张相同规格的额外素材图片供玩家直接替换。
+5. **使用动画:**`project/animates`文件夹中的文件名(不含后缀,请注意与`animates.png`相区分)。
* 要使用动画,您可以使用“RM动画导出”工具从RPG Maker XP 1.03及其制作的游戏中导出动画,也可以用动画编辑器修改已有的动画或用图片新建。但这些办法都只适用于Windows系统,非Windows系统建议直接从我们的官网下载他人的作品取用其中的动画。
- * 每个动画将其用到的各张图片直接以base64硬编码进同一个animate文件,每个动画为一个animate文件。这样做的缺点是如果多个动画使用了相同的图片那么图片会被重复存储,优点则是跨作品迁移动画更加方便。animate文件为文本文件,文件末尾记录了动画的帧信息,文件开头则记录了动画的伸缩比和唯一音效(会和动画同时开播)。
- * 在导出动画时,会出现一个输入框并提示动画的唯一音效名。不管该文件名是什么语种,请直接点击下一步。音效文件会被尝试自动复制,随后您只需手动注册该动画和音效并将音效文件名改为全英数。
- * 可以在编辑器中预览动画和修改音效。
- * 可以使用如下动画相关的脚本对动画进行处理,或在事件中使用「播放动画」事件。
+ * 每个动画将其用到的各张图片直接以base64硬编码进同一个animate文件,每个动画为一个animate文件。这样做的缺点是如果多个动画使用了相同的图片那么图片会被重复存储,优点则是跨作品迁移动画更加方便。
+ * animate文件为json格式的文本文件,文件末尾记录了动画的帧信息,文件开头则记录了动画的伸缩比和所有音效(第几帧用什么音效,音调是多高)。
+ * 在导出动画时,会出现一个输入框并提示动画的第一音效文件名。不管该文件名是什么语言,请直接点击下一步。音效文件会被尝试自动复制,随后您只需手动注册该动画并在编辑器中预览,然后重新按帧绑定需要的音效。
+ * 可以使用如下动画相关的脚本对动画进行播放,或在事件中使用「播放动画」事件。
``` js
core.drawAnimate(name, x, y, alignWindow, callback);
// 播放一个动画,name为不带后缀的动画文件名,x和y为播放的格子坐标。
- // alignWindow表示该坐标在大地图中是绝对坐标还是相对坐标,填true表示相对坐标。
+ // alignWindow表示在大地图中该坐标是绝对坐标还是视野中的相对坐标,填true表示相对坐标。
// 相对坐标模式下,坐标应填写为小于13或15的自然数,譬如对13×13样板来说,
// 填两个6就会强制播放在视野中心。
// callback为动画播放完毕后(和音效无关)的回调函数,因为动画播放本身是异步的。
core.drawHeroAnimate(name, callback); // 和上面类似,但该动画会跟随勇士移动。
- // 每场战斗后,都会根据怪物坐标尝试用前者播放普攻动画。若坐标不存在
- // (天降强制战斗),则会尝试用后者播放。看上去就像勇士在打自己,请自行注意。
- core.stopAnimate(id, doCallback); // 停止一段动画
+ // 每场战斗后,都会根据怪物坐标尝试用前者播放普攻动画。若坐标不存在,
+ // (即天降强制战斗),则会尝试用后者播放。看上去就像勇士在打自己,请自行注意。
+ core.stopAnimate(id, doCallback); // 停止一段动画,id为上面两个函数的返回值,
+ // 第二个参数表示本次停止后是否依然执行前两个函数的回调
+
+ // 您可以用前两个函数回调自己,从而做到一个动画反复循环,
+ // 但务必要将每次的id记录在flags中,以便于第三个函数去停止它。
```
-5. **使用音乐:**`project/bgms`文件夹中的文件名(需要后缀,默认只支持wav、mp3和ogg)。
+6. **使用音乐:**`project/bgms`文件夹中的文件名(需要后缀,默认只支持wav、mp3、ogg、m4a、flac)。
* 如果玩家使用的是手机且没有连接WiFi(iOS和部分浏览器无法获知网络状态,将始终视为流量党),那么背景音乐默认不会开启,可以在标题画面点击右下角的圆形按钮来开启。
- * 发布到官网的作品还可以从远程加载背景音乐,您可以点击此链接试听和下载其他作品的背景音乐。
+ * V2.8起,这个圆形的音乐开关旁边还增加了一个放大镜按钮,您可以在标题画面连续点击它来获得一个最佳的屏幕缩放倍率。
+ * 发布到官网的作品还可以从远程加载背景音乐,您可以点击此链接试听和下载其他作品的背景音乐。
* 是否启用远程加载、以及启用时远程加载的根目录,由main.js指定。因此从官网下载其他作品的离线版本后请先关闭远程加载功能,才能正常加载本地注册的音乐。
- * 使用core.material.bgms可以查看所有的背景音乐,如果需要同时播放多个背景音乐并独立控制时刻和音量,请直接对它们使用play()方法并修改其currentTime(可读)和volume属性。
-6. **使用音效:**`project/sounds`文件夹中的文件名(写法同上)。和动画不同,音效的播放不支持回调,只支持提前停止,而且一停就会停止所有的。
- * 音效的音量是固定的,无法调节。此外,样板没有背景音效(bgs、bgv)的默认实现。如有需求,请使用并行脚本处理。
- * 音乐和音效在使用多选框注册时都支持试听,您可以看到它们的总时长和已播时长(精确到秒),从而指定音乐的开播秒数或配合使用“等待n毫秒”事件或并行脚本处理。
-7. **使用字体:**project\fonts文件夹中的文件名(只支持ttf格式,不写后缀)。不建议给在线游戏版本添加中文字体,因为文件真的很大……
-8. **文件映射:**如前所述,样板所有需要加载的文件名都必须全部是英文或数字。这一项允许你给文件取别名,别名可以使用任何语言的文字。
-9. **装备孔:**见“道具的装备属性”。
-10. **标题音乐:**如题,请注意部分浏览器不会在刚打开某个页面时就播放音频,必须用户操作一下才行。
-11. **主样式:**一些css设置项,单击“编辑”按钮可以看到具体含义和用法,这里不再赘述(横竖屏标题画面背景支持gif动图)。
-12. **游戏名:**标题画面和网页选项卡上显示的名字,可以和官网别的作品重名。
-13. **唯一英文标识符:** **必须修改,且不得和官网别的作品重名**。只能使用字母数字下划线,如果您不确定一个标识符是否已被别的作品使用,请输入[https://h5mota.com/games/xxx](https://h5mota.com/games/xxx),如出现404就说明此项未被使用。
-14. **游戏版本:**当您的游戏发生版本更迭后,旧版本的存档直接读取可能会出现bug.因此届时您可以修改此项来让旧存档无法直接读取,只能回放其录像。
-15. **难度分歧:**单击“编辑”按钮进入事件编辑器,每个难度分为以下几项。
+ * 使用`core.material.bgms`可以查看所有的背景音乐,如果需要(不存档的情况下)同时播放多个背景音乐并独立控制时刻、音量、速度、音调,请直接对它们使用`play()`和`pause()`方法并按照下图操作。
+ * `duration`表示总时长(秒,音效也适用),`currentTime`表示当前进度(秒,可读写)
+ * `volume`表示音量(0到1),`playbackRate`表示播放的倍速
+ * `preservesPitch`表示变速播放时是否不变调,`false`表示变调
+ * V2.8起,背景音乐“变速不变调”和“变速且变调”、音效“变速且变调”正式作为样板API提供,同时也有对应的事件指令,这是样板在追逐RPG Maker上迈出的一大步,且行且珍惜!
+ 
+7. **使用音效:**`project/sounds`文件夹中的文件名(格式要求和写法同上)。
+ * V2.8起,音效的播放和动画一样会返回一个ID并且有回调。音效不能像bgm一样只变速不变调,而是必须一起变。
+ * 可以指定ID来提前停止某个音效(不指定ID则全部停止),但不能像停止动画时一样取消回调。
+ * 对玩家来说音效的音量和bgm是绑定的,无法分开调节。此外,样板没有背景音效(bgs、bgv)的默认实现。如有需求,请使用并行脚本处理。
+ * 音乐和音效在使用多选框注册时都支持试听(但此时不支持变速变调),您可以看到它们的总时长和已播时长(精确到秒),从而指定音乐的开播秒数或配合使用“等待n毫秒”事件或并行脚本处理。
+8. **使用字体:**project\fonts文件夹中的文件名(只支持ttf格式,不写后缀)。不建议给在线游戏版本添加中文字体,因为文件真的很大……
+9. **文件别名:**如前所述,样板所有需要加载的文件名都必须全部是英文或数字。这一项允许你给文件取别名,别名可以使用任何语言的文字。
+ * V2.8起,此项改由事件编辑器编辑,同时样板新增了大量系统音效,可供灵活配置,务必善用!
+10. **装备孔:**见“道具的装备属性”。
+11. **标题音乐:**如题,请注意部分浏览器不会在刚打开某个页面时就播放音频,必须用户操作一下才行。
+12. **主样式:**一些css设置项,单击“编辑”按钮可以看到具体含义和用法,这里不再赘述(横竖屏标题画面背景支持gif动图)。
+13. **游戏名:**标题画面和网页选项卡上显示的名字,可以和官网别的作品重名。
+14. **唯一英文标识符:** **必须修改,且不得和官网别的作品重名**。只能使用字母数字下划线,如果您不确定一个标识符是否已被别的作品使用,请输入`https://h5mota.com/games/xxx`,如出现404就说明此名称未被使用。
+15. **游戏版本:**当您的游戏发生版本更迭后,旧版本的存档直接读取可能会出现bug.因此届时您可以修改此项来让旧存档无法直接读取,只能回放其录像。
+16. **难度分歧:**单击“编辑”按钮进入事件编辑器,每个难度分为以下几项。
* 名称:标题界面单击“开始游戏”后出现的二级菜单中的文字。一般为该难度的最简要的介绍,如减伤比例、初始福利等。
- * 简写:横屏状态栏左下角(竖屏右下角,也作为数字键切换按钮)和存读档界面缩略图上的文字,也会出现在在线游戏排行榜和旧版官网的作品卡片上。允许使用中文但请注意控制字数,用core.status.hard表示。
- * 变量hard值:若同一结局有多个难度有人通关,则上述排行榜只统计此值最高的难度。
+ * 简写:横屏状态栏左下角(竖屏右下角,也作为数字键切换按钮)和存读档界面缩略图上的文字,也会出现在在线游戏排行榜和旧版官网的作品卡片上。允许使用中文但请注意控制字数,用`core.status.hard`表示。
+ * 变量hard值:即`core.status.hero.flags.hard`的值,建议填自然数。若同一结局有多个难度有人通关,则站点排行榜只统计其中此值最高的难度。请务必保证有一个难度的此值为0,理由见下。
* 颜色:上述“简写”的颜色,用`core.status.hero.flags.__hardColor__`表示,默认为红色。详见“脚本编辑——更新状态栏”。
* 事件:此事件比下述的“开场剧情”更早执行,一般用来设置初始福利。
* 如果将难度分歧数组留空,那么标题界面单击“开始游戏”就会直接进入开场剧情。
-
+ * 请注意,游戏中的难度分歧最好只通过`core.status.hero.flags.hard`进行,这是因为除非开启了标题界面事件化,否则`core.status.hard`是可以由玩家在标题画面任意指定的,而未定义过的难度的“变量:hard”值都会为0,这也是为什么上面要求务必要有一个难度指定0值的原因。
+ * 关于如何在标题画面任意指定难度和随机种子,参见[事件](event)一章的最底部。
+
### 初始勇士
1. **初始楼层、朝向和坐标:**如题,请注意初始楼层必须在上述的“楼层列表”中。初始坐标一般通过右击地图上的空地快速绑定,但您也可以手动在这里填写负数或超出初始楼层宽高的值。然后使用“无视地形移动勇士”或“跳跃勇士”等改变勇士位置的事件指令,做出“勇士从地图外进入”的演出效果。
- * 如需根据难度分歧或用户选项来改变它们,请在“开场剧情”中修改core.firstData.floorId和core.firstData.hero.loc
+ * 如需根据难度分歧或用户选项等条件来改变它们,请在“开场剧情”中修改`core.firstData.floorId`和`core.firstData.hero.loc`
2. **行走图:**如题,必须在“使用图片”中注册过。宽高必须为4的倍数,宽度至少为128px(即每帧32px)。高度不限,剧情对话中和状态栏中会尝试保持比例压缩到每帧32px宽。
- * 在游戏中,勇士当前的行走图文件名用core.status.hero.image表示(只读)。
-3. **帧动画:**勾选此项后,勇士在剧情对话中(朝上视为朝下)和原地不动时会循环播放四帧踏步动画,一般用于长翅膀的勇士。
+ * 在游戏中,勇士当前的行走图文件名用`core.status.hero.image`表示(只读)
+ * 游戏中如需更改行走图请使用事件指令,但请注意它并不会计入站点录像验证,而且更换新行走图后如果立即重绘勇士就会重置视角。
+3. **帧动画:**勾选此项后,勇士在剧情对话中(朝上视为朝下)和原地不动时会循环播放四帧踏步动画,一般用于长翅膀的勇士。但是勾选后会导致视角随时锁定在勇士身上,也就是说大地图中操作视角的指令都会失效!
4. **勇士名:**如题,也会作为剧情对话中`\t[hero]`的默认标题。
5. **初始等级:**如果开启了自动进阶功能,请不要修改此项。
6. **生命上限、魔力上限、初始生命/魔力/攻防/护盾/金经:**如题。注意生命上限和金经需要在系统开关中勾选后才会启用,魔力上限填负数代表没有上限。
7. **初始装备、游戏变量:**建议留空(事件中的变量初始时都会视为0,脚本中也有办法做到)。
8. **永久道具、消耗道具、初始拥有装备个数:**点击“注释”按钮,按照提示进行修改。
9. **标题事件:**需要配合系统开关中勾选“标题开启事件化”来使用,可以在“开始游戏”、“读取存档”之余添加一些额外的功能。如成就系统、音像和回想鉴赏,但这并不是唯一的方法,请自行研究。
+ * 使用此项的后果主要是开局的若干操作也会计入录像,观感较差。
+ * 使用此项后,难度分歧会通过用户操作(如显示选择项)实现,因而成为了录像的一部分。
+ * 使用此项后,会导致因为无法像默认标题一样做成长方形,只能采用“黑色边框+状态栏黑底+隐藏状态栏”的妥协方法得到一个偏右的正方形画面。
+ * V2.8提供了一个插件,可以将这个正方形画面暂时居中,这是没有办法的办法。
10. **开场剧情:**会在难度分歧事件之后执行,可以在这里设置各种变量的初始值、穿上初始拥有的装备、隐藏勇士和一些初始不希望显示的图层块、追加跟随者等。
+ * 需要注意的是,此时`core.status.floorId`还没有值,因此无法进行相关操作,包括存档!
11. **全局商店:**详见“QTE与全局商店”。
12. **等级提升:**需要配合系统开关中勾选“等级”、“经验”和“升级”来使用,每个等级分为以下几项:
* 需求:刷新状态栏时,如果勇士当前等级是此等级的前一级,且经验值大于等于此需求,就会触发升级。
* 称号:状态栏显示的等级默认是个正整数,会尝试替换为这里的称号(调用core.getLvName()函数),请注意控制字数。
- * 是否扣除经验:如果勾选了此项,则触发升级时经验值会扣除需求值。
- * 事件:触发升级时执行的事件,如全面提升属性。
+ * 是否扣除经验:如果勾选了此项,则触发升级时经验值会扣除需求值,这一项主要是为了应对一次升多级的情况。
+ * 事件:触发升级时执行的事件,如全面提升属性。事件中甚至可以降低等级,从而反复触发升同一级。
### 全局数值
@@ -286,12 +361,13 @@
这个类型的数值会保存在core.values中,可以直接在游戏中修改。
1. **血网伤害和中毒伤害:**如题,如果不想用常数,请修改“脚本编辑”的“阻激夹域伤害”和“每步后操作”。
-2. **衰弱效果:**填小于1的正数代表扣减的比例,否则为扣减的常数。扣减和恢复的原理和装备相同,详见“脚本编辑——毒衰咒”、解衰药水和万能药水的使用效果。
-3. **三种宝石和四种血瓶的值:**如题,此值为基础值。实际效果还需乘以楼层属性最下面的“宝石血瓶效果”(限即捡即用类,详见这七种道具的属性。此外,B键数据统计是按照此值乘以“宝石血瓶效果”统计的,与道具的实际效果无关,请自行注意。
+2. **衰弱效果:**填小于1的正数代表扣减的比例,否则为扣减的常数。扣减和恢复的原理和装备相同,详见“脚本编辑——毒衰咒处理”。
+3. **三种宝石和四种血瓶的值:**如题,此值为基础值。实际效果还需乘以楼层属性最下面的“宝石血瓶效果”(限即捡即用类,详见这七种道具的属性)。
4. **反击、破甲、净化比例:**如果反击、破甲、净化怪物没有指定atkValue、defValue和n,就会用这三个值。请注意反击的总回合数是勇士的攻击回合数,净化比例填1表示单纯无视护盾。
5. **仇恨增值:**每进行一场战斗,core.status.hero.flags.hatred的增加量。如果不想用常数,请修改“脚本编辑——战后脚本”。
6. **全局帧动画时间:**即怪物和NPC的振动速度,建议改为300毫秒。
7. **竖状态栏自绘行数:**需要配合系统开关“开启自绘状态栏”使用,建议改为4.
+8. **楼层切换时间:**此项可被玩家更改,单位为毫秒,必须为0.1秒的0到10倍。
### 系统开关
@@ -300,34 +376,40 @@
1. **状态栏显示项:**如题,总个数请控制在12个以内,否则竖屏可能塞不下。
* 这些项的图标都在`project\materials\icons.png`中。该文件夹下也提供了一个`icons_old.png`可供替换。
* “血限”、“金币”和“经验”必须勾选才会启用(指会处理生命溢出、金经会显示在手册、打怪也会掉落),
- * 必须勾选“升级”才会启用自动进阶,“升级扣除模式”如果不勾选就会同时显示下一级的需求(NEXT)和当前经验(EXP,如果勾选了的话),否则会只显示两者的差(依然用NEXT图标)。
+ * 必须勾选“升级”才会启用自动进阶,“升级扣除模式”如果不勾选就会同时显示下一级的需求(NEXT)和当前经验(EXP,如果勾选了的话),否则会只显示两者的差(依然用NEXT图标),“扣除”这个词用的不太好。
* 如果同时勾选了“钥匙”和“绿钥”,则每种钥匙的数量都会被缩小尺寸显示,因此如非必要请不要勾选“绿钥”。
-2. **楼传需在楼梯边:**如果勾选了此项,则只有勇士在楼梯旁边(如果开启了下述的平面模式则还包括四种三帧箭头旁边)时才允许使用楼传。
+2. **楼传需在楼梯边:**如果勾选了此项,则只有勇士在楼梯旁边(包括六种portal旁边)时才允许使用楼传。
* 请注意,此项是在楼传道具使用条件之外额外进行的判定,目的是给出不同的提示信息。
* 因此如果您要修改楼传的使用条件(指总的使用条件,具体能否飞到某层的条件则在“脚本编辑——楼层飞行”),则可能需要一并取消此勾选。
-3. **楼传开平面模式:**如果勾选了此项,则勇士在使用楼传飞往某层时会落在上次离开该层的位置。此外,上述“在楼梯边”也会包括“在四种三帧箭头旁边”。
-4. **铁门不消耗钥匙:**如果勾选了此项,则铁门无需钥匙也能撞开。
-5. **首次道具进行提示:**勾选后,首次捡到非即捡即用类道具都会弹窗提示(晚于afterGetItem事件被执行)。
+ * V2.8起,浏览地图界面按下G键或点击楼传图标则会尝试飞到当前正在浏览的楼层,这大大方便了玩家。
+3. **楼传开平面模式:**如果勾选了此项,则勇士在使用楼传飞往某层时会落在上次离开该层的位置(锚点)。
+ * 此项和上一项建议要么同时勾选要么同时不勾选,同时勾选以后建议在“脚本编辑——flyTo楼层飞行”中禁止同层传送,否则可能有意想不到的后果。
+ * 楼层切换过程中可以根据局部变量`fromLoad`和`isFlying`进行不同的处理(例如播放不同的音效),前者表示是否为读档,后者表示是否为楼传,建议由这两者导致的楼层切换一律不更新锚点。
+4. **铁门不消耗钥匙:**如果勾选了此项,则铁门无需钥匙也能撞开。【不建议使用!】因为此项会导致撞铁门时不再自动存档,因此建议修改铁门的`doorInfo`属性将钥匙栏留空即可。
+5. **首次道具进行提示:**勾选后,首次捡到非即捡即用类道具都会弹窗提示(晚于`afterGetItem`事件被执行)。
6. **状态栏装备按钮:**勾选后,状态栏的楼传按钮会变为装备栏按钮,但玩家仍然可以双击道具栏来呼出装备栏。
-7. **加点:**勾选后怪物的加点值会在“脚本编辑——战后脚本”中作为参数core.status.hero.flags.arg1被传递给“公共事件——加点事件”。
+7. **加点:**勾选后怪物的加点值会在“脚本编辑——战后脚本”中作为参数`core.status.hero.flags.arg1`被传递给“公共事件——加点事件”。
8. **负伤:**勾选后,战斗结束时如果勇士的护盾没有完全被打破,则剩余的护盾值会加到其生命上。所以勾选此项后,护盾可以这样“间接”抵消掉仇恨伤害和固伤。
-9. **夹击不超伤害值:**勾选此项后,夹击伤害将封顶至夹击怪的战损。同时被四只怪夹击时,取两个战损中较小的。
+9. **夹击不超伤害值:**勾选此项后,夹击伤害将封顶至夹击怪的战损。同时被四只怪夹击时,取两个战损中较小的。
10. **二分临界:**我们知道,打败怪物所需的回合数,取决于勇士的攻击减去怪物的防御。这个值并非每增大1都能使回合数减少,因而有了“临界”的说法,即“再至少增加多少攻击力,才能减少回合数”。然而,当您修改“脚本编辑——战斗伤害信息”函数后,攻击力的增加可能反而导致回合数也增加,于是临界值计算出错。您可以勾选此开关来修复,代价是游戏可能较卡,请自行权衡。
-11. **标题开启事件化:**勾选此项后,标题画面将改为执行前述的“标题事件”,请自行研究。
+11. **标题开启事件化:**勾选此项后,标题画面将改为执行前述的“标题事件”,请自行研究,V2.8起建议配合“标题事件居中”插件。
12. **开启自绘状态栏:**勾选此项后,状态栏将改用“脚本编辑——自绘状态栏”来绘制,同时“脚本编辑——点击状态栏”也将启用,请自行研究。
-13. **三个显伤:**略,玩家依然可以在设置菜单中开关之。
-14. **允许轻按:**勾选此项后,玩家可以按下空格/大键盘数字7/双击勇士来拾取相邻的唯一道具,或面前的道具。
+13. **四个显伤:**略,玩家依然可以在设置菜单中开关之,其中“定点怪显”指的是手册中把受到额外影响而数值不同的同种怪物分开显示。
+14. **允许轻按:**勾选此项后,玩家可以按下空格/大键盘数字7/双击勇士来拾取相邻的道具(优先面前)。
15. **允许穿透楼梯:**在狭窄的区域拦路放置一个可通行的“楼层转换”事件时(图块左下角出现绿色标记),玩家可能希望勇士能直接走过去。您可以逐个去设置其能否被这样走过,或者让其依据本勾选项。
* 值得注意的是,当玩家从允许穿透的楼梯向一个不可走的方向(如旁边是墙,或不勾选下一个开关时的致命领域)手动寻路时,可以停在楼梯上(进而再轻按拾取周围物品等)。不建议您利用这类极端情况去迫使玩家进行非常规操作,毕竟穿透楼梯和不能踏入致命领域的本意是方便玩家,不是么?
-16. **允许将死领域:**“脚本编辑——阻激夹域伤害”会将地图中每个点的阻激夹域和血网伤害加总,如果不勾选此开关,则当勇士生命小于等于相邻空格子的总伤害(没有则视为0)时,勇士无法走向该格子。
+ * 确切地说,即使旁边没有障碍物,录像意义下勇士也一定能停在任何可穿透的楼梯上。因此笔者再次强调,非常不建议利用这样的盲点戏弄玩家。
+16. **允许将死领域:**“脚本编辑——阻激夹域伤害”会将地图中每个点的阻激夹域和血网伤害加总,如果不勾选此开关,则当勇士生命小于等于相邻空格子的总伤害(没有伤害则没关系)时,勇士无法走向该格子。
* 值得注意的是,这种判定方式并没有考虑“走这一步后、结算该点伤害前”可能的加血或该点伤害变化,因此如有必要可根据“脚本编辑——每步后操作”去修改core.canMoveHero()函数。
-17. **允许瞬移:**若不勾选此开关,将全程禁用瞬移功能。一般只建议在需要的楼层逐层勾选禁止瞬移。
+ * 另外,此项的保护作用只会在“勇士可以自由行动”(`core.status.lockControl`为`false`)时生效,因此事件中(滑冰等场合)踩到致命领域仍然会死亡。
+17. **允许瞬移:**若不勾选此开关,将全程禁用瞬移功能。一般只建议在需要的楼层逐层勾选禁止瞬移,或通过`flags.cannotMoveDirectly`来控制。
18. **录像折叠:**勾选此项后,将开启录像折叠功能。录像折叠将尽可能优化掉在一个地方无意义的行走,从而减少录像长度并提升播放观感。
* 当经过一段时间的行走、转向和瞬移后,若勇士的坐标、朝向和状态(步数除外)和之前某个时刻完全相同,那么将会直接删除这中间的录像记录。
* 当中毒状态、触发任何系统或自定义事件、图块脚本、楼层切换、受到阻激夹域伤害等等时,将清除录像折叠信息。
* 请注意:录像折叠将会优化步数,所以如果游戏和步数有直接关系(比如步数算分)请关闭录像折叠功能。另外,如果你的塔存在楼层并行脚本且对游戏数据有直接影响,也请关闭录像折叠功能。
19. **伤害禁用商店:**勾选此项后,每当勇士踩到阻激夹域和血网并受到伤害时,所有全局商店都将被禁用,需要重新去启用(譬如勇士去撞击该商店的实体NPC)。
20. **虚化前景层:**前景层会遮挡事件层,这对魔塔来说有时可能不太友好。勾选此项后,事件层有东西(如道具)时将虚化该格子的前景层,使得该东西以半透明状态可见。
+ * 出于布景需要,某点事件层为自动元件或tileset时,必须有“碰触脚本/碰触事件”,该点前景层才会虚化。
上面就是整个样板中的各个元件说明。通过这种方式,你就已经可以做出一部没有任何事件的塔了。
diff --git a/_docs/event.md b/_docs/event.md
index f481cda4..1aa0f7cd 100644
--- a/_docs/event.md
+++ b/_docs/event.md
@@ -4,37 +4,38 @@
## 事件编辑(地图选点,快捷键X)
-
+
-样板所有的事件都是依靠“触发器”完成的。例如,勇士碰到(绑定好的)楼梯可以触发changeFloor,碰到门可以触发openDoor,碰到怪物可以触发battle,碰到道具可以触发getItem,碰到箱子可以触发pushBox,走上冰面(背景层)可以触发ski.
+样板所有的事件都是依靠“触发器”完成的。例如,勇士踩到(绑定好的)楼梯可以触发changeFloor,碰到门可以触发openDoor,碰到怪物可以触发battle,踩到/轻拾道具可以触发getItem,推到箱子可以触发pushBox,走上冰面(背景层)可以触发ski.
这些触发器都是系统自带的(称为系统事件),已经存在处理机制,不需要我们操心。我们真正所需要关心的,其实只是自定义的事件(如NPC)。
-地图选点(快捷键X)一共有七项,在地图中以图块左下角用七色小方块标记。
+地图选点(快捷键X)一共有八项,在地图中以图块左下角用八色小方块标记。
-* **红色:**普通事件
-* **橙色:**自动事件
-* **黄色:**战后事件
-* **绿色:**楼层转换
-* **青色:**获得道具后事件
-* **靛色:**不是事件,为勇士站在该点不能朝哪些方向走
+* **红色:**普通事件,也包括该点的一些特效。
+* **橙色:**自动事件,可以设置为“仅执行一次”、“仅在本层检测”。
+* **暗绿色:**战前事件,强制战斗时不触发。
+* **黄色:**战后事件。
+* **亮绿色:**楼层转换,可以设置为“可穿透”。
+* **青色:**获得道具后事件,可以设置为“轻按时不触发”。
+* **靛色:**不是事件,为勇士站在该点不能朝哪些方向走。
* **紫(粉)色:**开门后事件。
-此外还有一些事件不在地图上,如“首次到达”、“每次到达”(这两个的触发原理,详见“脚本编辑——切换楼层后”)、“道具效果”、“公共事件”和全塔属性中那五个事件。
+此外还有一些事件不在地图上,如“首次/每次到达”(这两个的触发原理,详见“脚本编辑——切换楼层后”)、“道具效果”、“碰触事件”、“(批量)战前/战后事件”、“公共事件”和全塔属性中那五个事件。
### 事件的机制
地图上的所有事件都存在两种状态:启用和禁用。
* 启用状态下,该事件才处于可见状态,可被触发、交互与处理。
-* 禁用状态下,该事件几乎相当于不存在,不可见、不可被触发、不可交互,只能通过“插入事件”指令远程调用。
+* 禁用状态下,该事件几乎相当于不存在(默认可以被阻击怪和箱子推上去),不可见、不可被触发、不可交互,只能通过“插入事件”指令远程调用。
所有事件默认情况下初始都是启用的,只有普通事件可以通过不勾选“启用”来初始隐藏。
在事件列表中使用“显示事件”和“隐藏事件”可以将一个禁用事件给启用,或将一个启用事件给禁用,甚至直接从地图中删除。
**【重要警告】:**
-1. 打怪开门捡道具后,如果有对应的坐标,则该点的事件会被从地图中删除(重生怪除外,它只会被暂时隐藏)。然后会尝试执行该点的战后事件、开门后事件或(拾获)道具后事件(您可以勾选“轻按时不触发”)。如果执行,则“当前点坐标”(core.status.event.data的坐标)也会变为该点。
+1. 打怪开门捡道具后,如果有对应的坐标,则该点的事件会被从地图中删除(重生怪除外,它只会被暂时隐藏)。然后会尝试执行该点的战后事件、开门后事件或(拾获)道具后事件(您可以勾选“轻按时不触发”)。如果执行,则“当前点坐标”(`core.status.event.data`的坐标)也会变为该点。
* 所以,这三个XX后事件,其实是有可能被多次触发或意外触发的(如打死或炸掉某个有战后事件的怪,推了个阻击怪过去打死),请自行注意。
2. “移动事件”(如阻击和捕捉)和“跳跃事件”(如支援)会将起点处的事件从地图中删除,如果不勾选“不消失”(如阻击),则会在终点处“转变图块”并“显示事件”。但事件的内容不会被跟着移动到终点,推箱子同理,但在终点只转变图块而不予显示。
@@ -50,10 +51,11 @@
1. **目标楼层(floorId):**如题,如果选择了“楼层ID”就需要在第二个框中输入目标楼层的ID(会自动提示补全,也可以双击整个紫色块从地图选点)。如果选择了其他三种,则json代码中`:before`、`:next`、`:now`分别表示“前一楼”、“后一楼”(顺序由“全塔属性——楼层列表”指定,上下楼器同理)和“当前楼”,函数中也是一样的写法。
2. **目标位置(stair):**如果选择了“坐标”则需要在后面两个框里输入(同样可以地图选点,在函数中则将`stair`填`null`并填写`heroLoc`),也可以选择下拉框中的其他几项(在函数中则将`heroLoc`填`null`),如保持不变(`:now`)、中心对称(`:symmetry`)、左右对称(`:symmetry_x`)、上下对称(`:symmetry_y`)或任何一个图块ID.
- * 填写三种对称位置时请注意,坐标计算以当前楼层而不是目标楼层为准,尤其要注意防止勇士出界。
- * 填写图块ID时请注意,“上下楼梯”提供在了下拉框中,实际传送时会优先尝试取用目标层的“楼层属性——上下楼点”。其次尝试像其他ID一样从目标楼层搜索,因此请确保该图块在目标楼层中存在且唯一。
+ * 填写三种对称位置时请注意,坐标计算以【当前楼层的勇士】位置(对不可踏入的楼梯来说,这个位置与楼梯相邻而不重合)而不是目标楼层或该楼梯为准,注意防止勇士出界。
+ * 填写图块ID时请注意,“上下楼梯”和“楼传落点”提供在了下拉框中,实际传送时会优先尝试取用目标层的“楼层属性——上下楼点”。其次尝试像其他ID(必须写在右侧的json区再点击解析)一样从目标楼层搜索,因此请确保该图块在目标楼层中存在且唯一。
3. **朝向:**有八种写法,可以直接填写改变后的朝向(`up, down, left, right`),也可以填写转身的角度(`:left, :right, :back`)或不变。
4. **动画时间:**指黑屏的毫秒数,可以填0或不小于100的整数,不填则使用玩家设定值。
+ * V2.8起,楼层切换的音效被延迟到了“屏幕完全变黑”的瞬间(脚本编辑——切换楼层中)才播放,以方便作者根据条件设置不同音效,因此上下楼时间建议尽量缩短。
5. **穿透性:**见[系统开关](start)允许穿透楼梯。
值得注意的是,绑定了楼层转换事件的门、怪物、道具、箱子,其系统行为(开门、战斗、拾取、推行)将不再发生(阻激夹域等地图属性不受影响),而是被覆盖为上下楼。
@@ -61,19 +63,30 @@
## 普通事件(红)
普通事件在启用后可以被勇士碰触而触发,它们都有着这样的开头:
-
-`覆盖触发器(Y/N) 启用(Y/N) 通行状态(Y/N?) 显伤(Y/N)`
-
-1. **覆盖触发器:**如前所述,门、怪物、道具、箱子都已经被绑定了系统触发器。如果您需要让地图上的个别这类图块在被勇士碰触时不发生系统行为(开门、战斗、拾取、推行),而是执行您在下面自定义的事件(比如触碰boss先进行一段对话再强制战斗),请勾选此项。(阻激夹域等地图属性不受影响)
+```
+覆盖触发器(Y/N) 启用(Y/N) 通行状态(Y/N?) 显伤(Y/N)
+V2.8新增:不透明度(0~1) 虚化 色相(0~359) 灰度(0~1) 反色(Y/N) 阴影
+```
+1. **覆盖触发器:**如前所述,门、怪物、道具、箱子都已经被绑定了系统触发器。如果您需要让地图上的个别这类图块在被勇士碰触时不发生系统行为(开门、战斗、拾取、推行),而是执行您在下面自定义的事件(比如需要制作一个“怪物中的叛徒”,它虽然有显伤但其实是个npc),请勾选此项。(阻激夹域捕捉支援等地图属性不受影响)
2. **启用:**如果不勾选此项,则此事件初始时是隐藏的。
- * 如前所述,非常不推荐仅仅为了初始隐藏一些图块(如战利品、陷阱门墙、埋伏怪等)就去绑定一堆没有指令的普通事件。
+ * 非常不推荐仅仅为了初始隐藏一些图块(如战利品、陷阱门墙、埋伏怪等)就去绑定一堆没有指令的普通事件。
* 更安全的做法是“从0转变图块”(支持淡入效果)和“关门”(这样还有音效,多香)。
+ * 事实上,除“覆盖触发器”外,其余所有参数本不该作为“普通事件”的一部分而应该移出去放在表格中,这是样板的历史遗留问题。
+ * 如今V2.8加入了六项特效,可能导致无指令的普通事件越来越不可避免,请自行注意。
3. **通行状态:**除怪物和道具外,所有图块本身都具有“可通行性”属性。
* 您可以设置此项去覆盖地图中这一点的可通行性,譬如强行让一格空地不可通行,勇士撞击时出现一堵墙(51层魔塔第23层的效果)。
4. **显伤:**在对怪物使用覆盖触发器后,表面上看不出它和一般怪物的不同。
* 如有必要(比如触碰这怪物根本不战斗),可不勾选显伤以示区别。
* 如数量较多,可注册一个相同素材的NPC,比如样板中的仙子。
- * 如需在一段剧情中关闭所有显伤,可以简单移除怪物手册
+ * 如需在一段剧情中关闭所有显伤,可以简单地暂时移除怪物手册
+5. **不透明度:**如题,0表示完全不透明,1表示完全隐身。可以设为1用来配合楼层贴图实现大型怪物,或者设为半透明来表示灵魂等状态的角色。本属性可以在事件中用指令动态修改,支持渐变。
+6. **虚化:**必须为自然数,设定后图块会变模糊,可以用来配合快速移动/跳跃来表示幻影状态的角色。不建议对多帧图块长时间使用,因为会随着不断的抖动把周围越描越黑。
+7. **色相:**必须为0~359的整数,180表示互补色。常用于npc以避免过于单调,也可以在游戏的教学环节用此项高亮强调部分图块。
+8. **灰度:**如题,1表示完全变灰,必要时可以全图变灰来表示回忆/梦境/濒死等场合。
+9. **反色:**勾选后此图块将反色,必要时可以全图瞬间反色来表示惊吓。
+10. **阴影:**必须为自然数,设定后图块周围将出现阴影描边,在草地上效果更佳哦。
+
+可以使用`core.setBlockFilter`更改任何一点的最后五项特效。
## 自动事件(橙)
@@ -87,13 +100,16 @@
每个自动事件具有以下几个属性:
-1. **触发条件:**自动事件最重要的属性,为支持冒号缩写量的逻辑表达式。
+1. **触发条件:**自动事件最重要的属性,为支持“冒号缩写量”的逻辑表达式。
* 譬如上述两个例子中,触发条件就是“某两个点没有图块而某7个点图块为黄门”和“某四个点没有图块而某四个点图块为魔法警卫”。
- * 关于冒号缩写量,详见[只读块]值块和冒号缩写量。
+ * 关于冒号缩写量,详见下面的“值块和冒号缩写量”。
+ * V2.8起,自动事件的触发条件和“值块”支持多行编辑(eval时会忽略\n)。
+ * 因此高级作者可以将此条件写成无名函数,这样就可以在里面使用var进行复杂的多步计算了。
2. **优先级:**一般不需要改动。当多个自动事件的条件同时满足时,优先执行此级别较大的。
* 此级别也相等时,允许跨层触发则优先执行楼层较矮的。
* 同一楼层优先执行横坐标较小的,横坐标相等时优先执行纵坐标较小的,同一点处优先执行页码较小的。
3. **仅在本层检测:**如题,一般不需要改动。除非您要制作一些全局的效果,如“勇士生命低于上限的1/3时改变背景音乐”。
+ * V2.8起,即使不勾选此项,也不会在分区砍层模式下触发冻结状态楼层的自动事件!
4. **事件流中延迟执行:**勾选此项后,在执行其他事件时触发此自动事件则会将其内容追加到待执行事件的末尾,否则插队到待执行事件的开头。
5. **允许多次执行:**如果不勾选,则此事件最多只会被触发一次。即使勾选了,每次执行的过程中也会暂时禁止自己被触发。勾选后,请记得在此事件的指令中将条件变得不满足。
@@ -103,21 +119,21 @@
有几个事件,如战后加点、回收钥匙商店,会在战后脚本或全局商店等处频繁用到。于是它们被整理成了公共事件,您也可以追加自己的。
-公共事件在内容上和其他事件并无不同,只是在插入公共事件时(如`core.insertCommonEvent("回收钥匙商店")`)可以提供一个`参数列表`。
+公共事件在内容上和其他事件并无不同,只是在插入公共事件时(如`core.insertCommonEvent("回收钥匙商店",[...])`)可以提供一个`参数列表`。
参数列表是一个一维数组,其每项会被依次代入`core.status.hero.flags.arg1、arg2、……`,而`arg0`则会记录公共事件的中文名。
-在整个事件流结束后(即勇士恢复行动,请注意不是公共事件结束后),这些以arg加纯数字命名的变量、以及以@temp开头的临时变量都会被清空。
+在整个事件流结束后(即勇士恢复行动,请注意不是公共事件结束后),这些以arg加纯数字命名的变量、以及以@temp@开头的临时变量都会被清空。
## 滑冰事件
滑冰(ski)是一个非常特殊的触发器,使用此触发器的图块需要画在背景层。
-冰上可以画门、怪物、道具等任何图块,您还可以在前景层画上四种单向通行箭头(样板1层右下方那些),把三个图层的游戏性都发挥出来。
+冰上可以画门、怪物、道具等任何图块,您还可以在前景层画上四种单向通行箭头(样板1层右下方那些)或红线薄墙(素材区第一列最下方那些),把三个图层的游戏性都发挥出来。
勇士走上冰面后,将一直“前进一格或撞击”。直到滑出冰面或无法再前进,如撞到墙或事件。
-比如撞到怪物会强制战斗,打不过直接游戏失败。走到道具上会捡起来,撞到门则要看有没有钥匙,有的话会把门打开。
+比如撞到怪物会强制战斗,打不过直接游戏失败。走到道具上会捡起来,撞到门则要看有没有钥匙,有的话会把门打开。V2.7.3起,踩到致命领域会死亡而不是停在前一格。
默认情况下,触发事件后勇士会停下来。如果要继续滑冰,可以在这些点的战后事件、开门后事件、(拾获)道具后事件(这里最好勾选“轻按时不触发”)中判断勇士还在不在冰上(`core.onSki()`函数),在冰上的话就命令“勇士前进一格或撞击”。
@@ -127,40 +143,40 @@
当您从数据区单击任何一个事件类属性的“编辑”按钮时,就会呼出事件编辑器,上图给出了事件编辑器的全貌。
-左下角为指令类别,可以点击它们呼出各类指令菜单,如左上方的值块菜单。
+图中左下角为指令类别,可以点击它们呼出各类指令菜单,如左上方的值块菜单。
中央为指令区,被一个标识事件类型的紫色块包覆(即左下角的“入口方块”,图中为开门后事件),所有的指令都塞在里面。
右上角为json区,会随着指令区的编辑而自动变化。`core.insertAction()`函数的自变量就是它们,所以学有余力的话也建议您经常左右对照去了解每个指令对应的json写法。
-右下角为调色器,当您单击指令块中的颜色按钮时(如图中“画面闪烁”指令的白块)就会自动呼出,可以进行诸如十进制和十六进制颜色格式互转等操作。
+右下角为调色器,当您单击指令块中的颜色按钮时(如图中“画面闪烁”指令的白块)就会自动呼出,可以进行诸如十进制和十六进制颜色格式互转并预览等操作。
左上角为功能区,各功能的含义和用法如下:
1. **确认(Ctrl+S):**将指令区的指令组翻译为json写回表格和文件,并关闭事件编辑器。如果手动修改了json区却没有点击变黄的解析按钮,或指令区存在异步事件没有用“等待所有异步事件执行完毕”(图中第二条褐色指令)去等待,则单击确认按钮会弹窗警告。此时如果想放弃对json区的修改,请随便点一下指令区的一个块即可。
-2. **解析:**将手动修改后的json区翻译回指令组同步到指令区,一般用于跨作品复制事件,或长距离批量挪动和复制指令。因为blockly使用Ctrl+V粘贴出的块总是出现在原块的旁边,而拖动块时块又跟不上滚轮。
+2. **解析:**将手动修改后的json区翻译回指令组同步到指令区,一般用于跨作品复制事件,或长距离批量挪动和复制指令。此外,由于下拉框不支持任意输入(如新增的怪物属性、楼层切换的任意目标图块ID),所以也必须这样做。
3. **取消:**放弃本次编辑,关闭事件编辑器,表格和文件会停留在打开事件编辑器前的状态。
4. **搜索事件块:**当您想不起来需要的指令在哪个类别时,请使用此项,如输入“勇”字就会列出所有带有“勇士”一词的指令。
5. **地图选点:**在编辑事件尤其是大篇幅事件的过程中,如果需要频繁保存并退出事件编辑器去浏览地图尤其是浏览别的楼层就很不方便。单击此按钮,您可以浏览所有楼层及其全景。通过点击地图去确认一个点的坐标,并复制任何一个楼层ID以填入需要的地方。需要填坐标的指令也可以直接双击其指令块从地图选点填入坐标和楼层,从而避免了肉眼数格子和手敲的麻烦和出错的隐患。
-6. **变量出现位置搜索:**您可以搜索所有以“变量:xxx”形式出现在事件中的变量的出现位置,请注意“形式”和“事件”。以下形式都是无法被搜索到的(比如仇恨值、阻激夹域捕的禁用开关):
-7. **开启中文名替换:**勾选此项后,“flag、status、item、switch、temp、global、enemy”等冒号缩写量的前缀以及怪物和道具的ID才会允许用中文在指令块中书写,如“变量、状态、物品、独立开关、临时变量、全局存储、怪物”。当然,json中还是只能用英文的。此外,如果您需要使用中文名相同的道具或怪物,或在`${}`以外的文本中将上述几个词和冒号连用,则也需要关闭此功能以避免blockly和json互译出错。
-8. **展开值块逻辑运算:**在值块菜单中我们可以看到第一个就是二元运算块,但是它并不完整。比如没有位运算(包括逻辑异或)和取余,因此如果解析的优先级与js的优先级不一致,请在表达式中适当的位置添加圆括弧,或取消勾选此项。
+6. **变量出现位置搜索:**您可以搜索所有以“变量:xxx”形式出现在事件中的变量的出现位置,形式必须是冒号缩写量,位置必须是事件而不是脚本。也就是说,`flags.xxx`和`core.insertAction([...])`中的变量都是搜索不到的。
+7. **开启中文名替换:**勾选此项后,“flag、status、item、switch、temp、global、enemy”等冒号缩写量的前缀以及怪物和道具的ID才会允许用中文在指令块中书写,如“变量、状态、物品、独立开关、临时变量、全局存储、怪物”。当然,json中还是只能用英文的。此外,如果您需要使用名称相同的道具或怪物,或在`${}`以外的文本中将上述几个词和冒号连用,则也可能需要关闭此功能以避免blockly和json互译出错。
+8. **展开值块逻辑运算:**在值块菜单中我们可以看到第一个就是二元运算块,但是它并不完整,比如没有位运算。因此如果解析的优先级与js的优先级不一致,请在表达式中适当的位置添加圆括弧,或取消勾选此项。
## 值块和冒号缩写量
-
+
值块并不能单独构成指令,但它们可以被嵌入数值操作、设置怪物属性和很多事件控制类指令。而冒号缩写量的用法就更多了,比如用于`${表达式计算}`和其他任何支持填表达式的地方。
值块大体上分为三种:勾选框与运算块、只读块、可读写块,其中后两类对应着冒号缩写量。
### 勾选框与运算块(附js比较运算大图鉴)
-包括勾选框块(true和false两个逻辑常量)、否定运算块和二元运算块。
+包括勾选框块(`true`和`false`两个逻辑常量)、否定运算块和二元运算块。
-否定运算块(一个“非”字,脚本中写作一个叹号)会把“false、0、null、undefined、NaN和空字符串”(以下简称广义false)变为true,而把别的量都变为false.
+否定运算块(一个“非”字,脚本中写作一个叹号)会把`false、0、null、undefined、NaN`和空字符串”(以下简称广义`false`)变为`true`,而把别的量都变为`false`.
二元运算块包括四则运算、取余、乘方、比较运算和三种逻辑运算。
-四则运算中,两个整数相除会得到小数。两个0的乘方会得到1(数学上无意义)
+四则运算中,两个整数相除会得到小数,两个0的乘方会得到1(数学上无意义)。
八种比较运算中,四种比大小的运算如果两项中有一项是数字,就会把另一项也转换成数字去比,所以会出现这些:
@@ -170,7 +186,7 @@
弱(不)等于(==和!=)非常难用,建议放弃,统一使用(不)等于(===和!==)。
-NaN一般是0/0或字符串瞎做减乘除得到的,它跟谁都没有可比性,包括自己。
+`NaN`一般是`0/0`或字符串瞎做减乘除得到的,它跟谁都没有可比性,包括自己。
纯数字字符串(包括十六进制)和对应的数字,都是弱相等关系。如`'0x10' == 16`
@@ -178,51 +194,134 @@ NaN一般是0/0或字符串瞎做减乘除得到的,它跟谁都没有可比
单个数字(或什么都没有)用方括号还是引号括起来,对外的比较行为都一致。
-undefined倒是不用担心,它除了和null弱相等外,和其他值都没有可比性。
+`undefined`倒是不用担心,它除了和`null`弱相等外,和其他值都没有可比性。
三种逻辑运算的原则是,“且”的优先级高于“或”,它俩都不满足交换律。
-若干个由“且”连起来的量中,取第一个广义false(没有则取最后一个量),
+若干个由“且”(&&)连起来的量中,取第一个广义`false`(没有则取最后一个量),
-若干个由“或”连起来的量中,取第一个不是广义false的量(没有则同上),
+若干个由“或”(||)连起来的量中,取第一个不是广义`false`的量(没有则同上),
-所以样板中充斥着形如x=x||y和z=x||y的代码,y算是x的默认值。
+若干个由“异或”(^)连起来的`true`或`false`,总结果取决于其中`true`的个数的奇偶,奇数个`true`则总结果为1,偶数个`true`则总结果为0.
-若干个由“异或”连起来的true或false,总结果取决于其中true的个数的奇偶,奇数个true则总结果为1,偶数个true则总结果为0.
+所以样板中充斥着形如`x=x||y`和`z=x||y`的代码,y算是x的默认值。
+这种做法并不安全,如果您的作品不打算发布到我们的`h5mota.com`,则更建议使用`x??y`,它只会在“x为`null`或`undefined`时”才用y代替x。
+
+双问号运算在早期浏览器并不被支持,因此如需在我们的站点发布则需要写`if(x==null){x=y;}`。
+
+再次强调,广义`false`不一定和`false`弱相等(比如`null`),而和`false`弱相等的也不一定是广义`false`(如`[]==![]`)。
+
+V2.7.3起,一元运算块追加了一些数学函数,如四种取整、开平方、绝对值。还追加了“变量类型”(typeof),只有两个类型相同的变量才有可能满足“相等”(===)。
+
+V2.8起,二元运算块追加了一些js函数,如“取较大/较小”(`Math.max`和`Math.min`)、“开始于/结束于”(字符串的`startsWith`和`endsWith`)、“包含”(数组和字符串的`includes`),进阶作者可以学习使用。
### 只读块(怪物属性、图块ID、图块类别、装备孔)
尽管这几个值块是只读的,但您仍然可以使用“设置怪物属性”、“穿脱装备”和“转变图块”等指令去改变它们。
-1. **怪物属性:**冒号缩写量写作`怪物:绿头怪:生命`,json代码中写作`enemy:greenSlime:hp`。怪物中文名有重复的话请在事件编辑器顶部关闭中文替换功能,道具中文名同理。
+1. **怪物属性:**冒号缩写量写作`怪物:绿头怪:生命`,json代码中写作`enemy:greenSlime:hp`。怪物名称有重复的话可以在事件编辑器顶部关闭中文替换功能,道具名称同理。
* 常见的怪物属性都提供在了下拉框中,如果下拉框里没有(如通过配置表格新增的属性),可以修改`_server\MotaAction.g4`文件最后的那些表来追加其中文简称,也可以放弃解析回中文块而是就用缩写量。
+ * V2.8起,怪物支持“行走图朝向”绑定,此值块将始终获取脸朝下的怪物属性。
2. **图块ID:**冒号缩写量写作`图块ID:x,y`,json代码中写作`blockId:x,y`。请注意逗号始终要用英文的,此值块实际直接调用的API为`core.getBlockId(x,y)`,即本值块和对应的冒号缩写量只支持本层,可以获知本层某个点的图块ID.
-3. **图块类别:**冒号缩写量写作`图块类别:x,y`,json代码中写作`blockCls:x,y`。同上,实际调用`core.getBlockCls(x,y)`,可以获知本层某个点的图块类别。
-4. **装备孔:**冒号缩写量写作`装备孔:n`,json代码中写作`equip:n`。实际调用`core.getEquip(n)`,可以获知勇士第n个装备孔中的装备ID.
+3. **图块数字:**冒号缩写量写作`图块数字:x,y`,json代码中写作`blockNumber:x,y`。同上,实际调用`core.getBlockNumber(x,y)`,可以获知本层某个点的图块数字。
+4. **图块类别:**冒号缩写量写作`图块类别:x,y`,json代码中写作`blockCls:x,y`。同上,实际调用`core.getBlockCls(x,y)`,可以获知本层某个点的图块类别。
+ * V2.8起,这三个值块中的坐标支持填写表达式,会在json区直接翻译为API调用,但这样填写也意味着无法再解析回值块,而且本质上这已经不是冒号缩写量了,不能直接用于${表达式计算}等场合。
+5. **第n格装备孔:**冒号缩写量写作`装备孔:n`,json代码中写作`equip:n`。实际调用`core.getEquip(n)`,可以获知勇士第n个装备孔中的装备ID,n从0开始!
-### 可读写块(status、item、flag、switch、temp、global)
+### 可读写块(status、item、flag、switch、temp、global、buff)
比起只读块,可读写块允许作为“数值操作”指令的左块:
1. **状态:**冒号缩写量为`状态:生命`等,json代码中写作`status:hp`等。
* 作为左块时会调用`core.setStatus()`,其他时候会调用`core.getStatus()`
2. **物品:**冒号缩写量为`物品:炸弹`等,json代码中写作`item:bomb`等
* 作为左块时会调用`core.getItem()`或`core.setItem()`,其他时候会调用`core.itemCount()`来统计背包中的道具数量。
- * 此外,最常用的9个勇士状态和三色钥匙提供在了下拉框中。您可以修改`_server/MotaAction.g4`文件最后的`FixedId_List`来追加,向“楼层转换”、“门信息”和“装备属性”的下拉框追加新的楼梯ID、钥匙ID和勇士状态名也是一样的道理,当然不追加也不影响手写。
+ * 此外,最常用的一些勇士状态(包括坐标和朝向)、三色钥匙、三围增益都提供在了下拉框中。您可以修改`_server/MotaAction.g4`文件最后的`FixedId_List`来追加,向“楼层转换”、“门信息”和“装备属性”的下拉框追加新的楼梯ID、钥匙ID和勇士状态名也是一样的道理,当然不追加也不影响手写(如果指令只提供了下拉框版本,那就必须写在json区再解析)。
3. **变量:**冒号缩写量为`变量:hatred`等,json代码中写作`flag:hatred`等。
* 作为左块时会调用`core.setFlag()`,其他时候会调用`core.getFlag(’xxx’, 0)`
* 请注意:变量类型支持中文,如`变量:开门个数`
* 这两个API实际操作的就是前文多次提到的`core.status.hero.flags`,只不过在事件中未定义的变量都视为0,更为安全。
* 如果您忘记了自己在哪些事件用过哪些变量,请善用事件编辑器顶部的“搜索变量出现位置”。
4. **独立开关:**如果您有一大批NPC都具有“首次对话不同于之后各次对话”之类的特点,那么为他们设置一大批不重名的变量就很繁琐。独立开关(叫独立变量更准确)就是为这种场合而生的,它对每层楼(首次到达和每次到达中)和每个坐标都是独立的。
- * 冒号缩写量写作`独立开关:A—Z`,json代码中写作`switch:A—Z`
- * 每个坐标处的独立开关有26个,用大写拉丁字母A—Z表示。MTn层(x,y)点的独立开关A,本质上是一个flag变量——`flag:MTn@x@y@A`,如果需要在其他点访问,就需要用这样的写法
+ * 冒号缩写量写作`独立开关:A—Z`,json代码中写作`switch:A—Z`。
+ * 每个坐标处的独立开关有26个,用大写拉丁字母A—Z表示。MTn层(x,y)点的独立开关A,本质上是一个flag变量——`flag:MTn@x@y@A`,如果需要在其他点访问,就需要用这样的写法。
+ * 首次到达/每次到达楼层的事件中,上述x和y会保留小写字母而不代入任何数字。
+ * 标题事件/开场剧情中,前缀的“楼层ID”视为“`:f`”。
+ * 可以在事件编辑器左侧菜单的“常用事件模板”中看到一个仿51层/新新魔塔的一次性商人的例子。
5. **临时变量:**冒号缩写量写作“临时变量:A—Z”,json代码中写作`temp:A-Z`,
* 临时变量泛指所有以`@temp@`开头的flag变量,一共也有26个。
* 临时变量一般用于计数循环和数组迭代,每当事件流结束(勇士恢复行动)时,临时变量和参数变量(以arg+纯数字命名)都会被清空。
+ * 全局商店状态下,临时变量`@temp@shop`会被启用,从而实现长按连续购买等操作。
+ * 上面提到的“一次性商人”模板中多次出现出售数量和价格常数,如果使用临时变量就很方便,不需要修改多个地方了。
6. **全局存储:**冒号缩写量写作`全局存储:xxx`,json代码中写作`global:xxx`,
* 和变量一样,冒号右侧本身支持中文。全局存储一般用来保存一些跨存档的信息,如成就系统、回想和音像鉴赏的收集进度、多周目数据等。
- * 用于左块时会调用`core.setGlobal()`,其他时候会调用`core.getGlobal()`
-
+ * 用于左块时会调用`core.setGlobal()`,其他时候会调用`core.getGlobal()`。
+ * `core.setGlobal()`在录像中会被忽略,`core.getGlobal()`在正常游戏中会将读取到的值写进录像,而在录像播放中直接读取这个写进去的值,从而复原了那次游戏时的样子。
+ * 然而,由于`core.getGlobal()`的调用频率在正常游戏和录像播放中可能不一致,因而可能会导致录像中的记录次数过多、过少或位置不合适。
+ * V2.8对这个问题进行了一定的修复,请放心使用。
+7. **增益:**冒号缩写量写作`增益:生命上限`等,json代码中写作`buff:hpmax`等,冒号右侧支持自定义的勇士新属性英文名。
+ * 用于左块时会调用`core.setBuff()`,其他时候会调用`core.getBuff()`。
+ * 增益这个概念在前面讲解装备属性时提到过,所有的百分比装备和百分比衰弱都是靠它发挥作用。
+ * `buff:xxx`本质上就是`flag:__buff_xxx__`,但前者更安全(默认值为1)。
+
+## 随机数(扩展内容,了解即可)
+
+此外,V2.8还新增了几个样板API的值块,包括“当前是否身穿某装备”、“当前是否在录像播放中”、“是否到达过某楼层”、“是否开启了某全局商店”、“能否打败某怪物”、“勇士面前第n格的坐标(负数表示身后)”、“随机数”。
+
+样板包括两种随机数,一种是上面说的值块提供的`core.rand(n)`,会得到小于正整数n的随机自然数,n不填则会得到小于1的随机正小数。
+
+一种则是`core.rand2(n)`,同样会得到小于n的随机自然数,n必须填正整数,不要省略!
+
+rand本质上是`flag:__rand__`不断一步步推进的结果,初始值为`flag:__seed__`,初始值(又叫随机种子)和游戏难度可以在标题画面通过`core.startGame(hard,seed)`函数指定(如果开启了标题界面事件化,则该函数还必须作为游戏重启函数`core.hideStartAnimate()`的回调来使用,但这样只能指定种子),种子必须为正整数。
+
+rand2则是通过js自带的`Math.random()`函数得到的真随机小数经过整数化处理的结果,会被直接写入录像(`random:n`),因此多次调用会导致录像(和存档)变得很庞大。而且正因为是写入录像,所以玩家也可以直接编辑录像文件或`core.status.route`来控制随机的结果。
+
+直观地说,rand的结果只和它的调用次数有关,因此玩家不能通过简单的SL操作来优化结果,必须调整路线或干脆重开游戏。
+
+而rand2的结果可以通过SL来改变,如果需要连续大量使用“可被SL改变的随机数”(期间不能存档)但又不希望录像变得太庞大,可以先在存档后使用一次`n=core.rand2(114514)`,再使用n次`core.rand()`来推进,效果就能让人满意了。(新新魔塔1就是这样的思路,每次撞怪时先自动存档然后生成n值,战斗中只使用rand)。
+
+然而,如果rand和rand2的使用场合不当,那么其调用频率在正常游戏中和录像回放时可能不一致。rand会因为推进步数不一致而导致游戏流程发生变化,rand2则会导致录像中记录的随机数出现多余或缺失。
+
+V2.8对rand2(以及“全局存储”、“弹窗输入”、“选择项”、“确认框”)的此问题进行了一定的修复,如果录像中出现了多余的随机数记录,就会在播放时跳过并在控制台警告,如果需要rand2但未记录或记录越界则会现场重新随机生成并补录。在V2.8之前这两种情况都会直接报错,而在V2.8中会导致首次播放结果的二次记录不一致,请不要惊慌,按R键从头再次播放一遍即可。
+
+总之,不计入录像的纯观赏性的随机效果(如捡到某道具随机播放一个音效)建议直接用`Math.random()`实现(例如V2.8每次上下楼后会在楼层属性的背景音乐中随机播放一个)。
+
+## 录像回放(扩展内容,了解即可)
+
+魔塔具有时空离散性和完全可重复性,因此可以像棋类运动一样记录类似棋谱的东西,我们称之为【录像】。
+
+正常游戏中,已录制的内容被保存在一维数组`core.status.route`中并不断从尾部延长,录像回放时,即将播放的内容会保存在一维数组`core.status.replay.toReplay`中并不断从头部缩减。
+
+您可以在正常游戏中自由行动时随时按下R键进行回放,上述数组具体的内容含义如下:
+
+```
+up down left right 勇士向某个方向行走一步
+item:ID 打开背包使用某件道具,如item:bomb表示使用炸弹
+unEquip:n 卸掉身上第n件装备(n从0开始),如unEquip:1默认表示卸掉盾牌
+equip:ID 打开背包穿上一件装备,如equip:sword1表示装上铁剑
+saveEquip:n 将身上的当前套装保存到第n套快捷套装(n从0开始)
+loadEquip:n 快捷换上之前保存好的第n套套装
+fly:ID 使用楼传飞到某一层,如fly:MT10表示飞到主塔10层
+choices:none 确认框/选择项界面超时(作者未设置超时时间则此项视为缺失)
+choices:n 确认框/选择项界面选择第n项(选择项中n从0开始,确认框界面0表示确定,1表示取消),此项越界将报错。此项缺失的话,确认框将选择作者的默认项(初始光标位置),选择项将弹窗请求补选(后台录像验证中则选第一项)。
+shop:ID 打开某个全局商店,如shop:itemShop表示打开道具商店。因此连载塔千万不要中途修改商店ID!
+turn 单击勇士(Z键)转身
+turn:dir 勇士转向某个方向,dir可以为up down left right,注意此项在正常游戏中无法随意触发。
+getNext 轻按获得身边道具,优先获得面前的,身边如果没有道具则此项会导致报错
+input:none “等待用户操作事件”中超时(作者未设置超时时间则此项会导致报错)
+input:xxx 可能表示“等待用户操作事件”的一个操作,也可能表示一个“接受用户输入数字”的输入,后者的情况下xxx为输入的数字。此项缺失的话前者将直接报错,后者将用0代替
+input2:xxx 可能表示“读取全局存储(core.getGlobal)”读取到的值,也可能表示一个“接受用户输入文本”的输入,两种情况下xxx都为base64编码。此项缺失的话前者将重新现场读取,后者将用空字符串代替
+no 走到可穿透的楼梯上不触发楼层切换事件,注意正常游戏中勇士无法随意停在旁边没有障碍物的楼梯上。
+move:x:y 尝试瞬移到[x,y]点,注意正常游戏中勇士无法随意瞬移到相邻格,而回放时连续的瞬移操作将被合并。
+key:n 按下键值为n的键,如key:49表示按下大键盘数字键1,默认会触发使用破墙镐
+click:n:px:py 点击自绘状态栏,n为0表示横屏1表示竖屏,[px,py]为点击的像素坐标
+random:n 生成了随机数n,即core.rand2(num)的返回结果,n必须在[0,num-1]范围,num必须为正整数。此项缺失或越界将导致现场重新随机生成数值,可能导致回放结果不一致!
+作者自定义的新项(一般为js对象,可以先JSON.stringify()再core.encodeBase64()得到纯英文数字的内容)需要用(半角圆括弧)括起来。
+```
+
+[在线插件库](https://h5mota.com/plugins/)中提供了“录像自助精修”插件,手机也适用,可供研究。
+
+开门打怪前会先转身再自动存档,因此该存档被读取后,已录制内容的最后一步将变成转身,导致录像变长,请自行注意。
+
==========================================================================================
[继续阅读下一章:事件指令](instruction)
diff --git a/_docs/img/V2_8server.jpg b/_docs/img/V2_8server.jpg
new file mode 100644
index 00000000..24137528
Binary files /dev/null and b/_docs/img/V2_8server.jpg differ
diff --git a/_docs/img/bgm.jpg b/_docs/img/bgm.jpg
new file mode 100644
index 00000000..8942d270
Binary files /dev/null and b/_docs/img/bgm.jpg differ
diff --git a/_docs/img/blockly.jpg b/_docs/img/blockly.jpg
index 0ff70dd8..6923e60c 100644
Binary files a/_docs/img/blockly.jpg and b/_docs/img/blockly.jpg differ
diff --git a/_docs/img/console2.jpg b/_docs/img/console2.jpg
index 470e54ec..c8cad352 100644
Binary files a/_docs/img/console2.jpg and b/_docs/img/console2.jpg differ
diff --git a/_docs/img/elements.jpg b/_docs/img/elements.jpg
index 398389f7..6adc428a 100644
Binary files a/_docs/img/elements.jpg and b/_docs/img/elements.jpg differ
diff --git a/_docs/img/events.jpg b/_docs/img/events.jpg
new file mode 100644
index 00000000..8c96175a
Binary files /dev/null and b/_docs/img/events.jpg differ
diff --git a/_docs/img/eventsx.jpg b/_docs/img/eventsx.jpg
deleted file mode 100644
index 0527c32b..00000000
Binary files a/_docs/img/eventsx.jpg and /dev/null differ
diff --git a/_docs/img/floor.jpg b/_docs/img/floor.jpg
new file mode 100644
index 00000000..a493c909
Binary files /dev/null and b/_docs/img/floor.jpg differ
diff --git a/_docs/img/floorsv.jpg b/_docs/img/floorsv.jpg
deleted file mode 100644
index 5eef9466..00000000
Binary files a/_docs/img/floorsv.jpg and /dev/null differ
diff --git a/_docs/img/mapsc.jpg b/_docs/img/mapsc.jpg
index 362dc3cb..1762003f 100644
Binary files a/_docs/img/mapsc.jpg and b/_docs/img/mapsc.jpg differ
diff --git a/_docs/img/quickshops.jpg b/_docs/img/quickshops.jpg
index e6996a68..b30c26d9 100644
Binary files a/_docs/img/quickshops.jpg and b/_docs/img/quickshops.jpg differ
diff --git a/_docs/img/values.jpg b/_docs/img/values.jpg
new file mode 100644
index 00000000..1a095cb2
Binary files /dev/null and b/_docs/img/values.jpg differ
diff --git a/_docs/instruction.md b/_docs/instruction.md
index d9064df0..61c66b8b 100644
--- a/_docs/instruction.md
+++ b/_docs/instruction.md
@@ -8,9 +8,11 @@
json代码本身则可以作为`core.insertAction()`函数的自变量,去插入一段事件执行。
+下述提到的“当前点”坐标均指`core.status.event.data.x`和`core.status.event.data.y`。
+
## 指令的分类(注意区分块的颜色和地图的七彩点)
-尽管本章的标题暗示了事件指令和`core.events._action_xxx()`函数是一一对应的,但它们进一步调用的底层函数却分布在libs文件夹的不同文件中,大致上:
+尽管事件指令和`core.events._action_xxx()`函数是一一对应的,但它们进一步调用的底层函数却分布在libs文件夹的不同文件中,大致上:
* 显示文字类(严格来说需要玩家操作的事件还涉及到actions.js)和UI绘制类在ui.js
* 数据相关类(这类也有不少道具相关在items.js)和特效声音类在control.js
@@ -20,8 +22,8 @@ json代码本身则可以作为`core.insertAction()`函数的自变量,去插
另一种分类方法则是按照同步和异步,分成以下几类:
1. **瞬间就能执行完的:**如UI绘制、设置XX属性、显隐和转变图层块等。
2. **阻塞直到玩家操作的:**如显示文章/选择项/确认框、接受用户输入、等待用户操作、呼出xxx等。
-3. **阻塞一段固定时间的:**如开关门、显示动画、移动跳跃、淡入淡出等。
-4. **耗时但不阻塞的:**如播放音效、显示提示等,会和后面的指令同时执行。
+3. **阻塞一段固定时间的:**如开关门、显示动画(观赏性)、移动跳跃、淡入淡出等。
+4. **耗时但不阻塞的:**如播放音效(V2.8支持阻塞)、显示提示等,一般为纯观赏性指令,会和后面的指令同时执行。
上述第3类指令都可以勾选“不等待执行完毕”(即前面提到的异步事件)变为第4类,从而实现诸如同步开关多个门的效果。
@@ -30,7 +32,7 @@ json代码本身则可以作为`core.insertAction()`函数的自变量,去插
data为整个指令对象,x和y为当前点坐标,prefix为独立开关的楼层前缀。
-您可以自行在使用`core.registerEvent`注册一个新的事件。如果需要把新指令做成像已有的指令一样有类别、名称、取色器、勾选框、下拉框、输入框等部件,请查阅[修改编辑器](editor)。
+您可以自行使用`core.registerEvent`注册一个新的事件。如果需要把新指令做成像已有的指令一样有类别、名称、取色器、勾选框、下拉框、输入框等部件,请查阅[修改编辑器](editor)。
## 显示文字类(黄色)
@@ -48,25 +50,28 @@ data为整个指令对象,x和y为当前点坐标,prefix为独立开关的
写成一个字符串就是`\t[标题,图像]\b[对话框效果]\f[立绘]正文`。
-1. **标题:**可选,一般填说话人的名字。如果不填,则尝试根据图像取中文名(道具除外,如图像填hero但不填标题则以勇士名字作为标题)。还可以填null强制不显示标题。
+1. **标题:**可选,一般填说话人的名字。如果不填,则尝试根据图像取中文名(道具除外,道具不会说话所以只填图像不填标题就会没有标题)。如图像填hero但不填标题则以勇士名字作为标题,标题还可以填`null`强制不显示标题(如`\t[null,hero]`只显示勇士头像)。
2. **图像:**可选,可以填hero(勇士行走图,如果勇士开了帧动画则会取当前朝向,但朝上会视为朝下)或任何图块ID,或者填this来尝试取当前点图块。
- * 也可以填一个png格式的图片文件名(需要后缀),甚至还可以填null来避免以图块ID为标题被解释成图像。
-3. **对话框效果:**可选,填法非常灵活,如下。
- 1. `up,x,y`:对话框显示在点(x,y)上方,尖角朝下指着这个点(绝对坐标,具体指的高度取决于图像。没有图像则判断该点是32×32px还是32×48px的图块,该点没有图块则没有尖角)。
- 2. `down,x,y`:对话框显示在点(x,y)下方,尖角朝上指着这个点。比起上面,这个没有高度问题,不过该点没有图块的话则还是没有尖角。
- * 上述两种写法中,如果把坐标换成hero则显示在勇士上方或下方。
- 3. `this,x,y`:在大地图中,点(x,y)可能位于视野上半部分也可能位于下半部分,写this就能让对话框自动适配上下来防止越界。
- 4. `hero`:在大地图上下边缘或小地图,勇士可能在上半或下半场,只写hero也能自动适配。
- 5. `hero,n`:n为正整数,显示给勇士的第n名跟随者,自动适配上下。
+ * 也可以填一个png格式的图片文件名(需要后缀),图像甚至还可以填null来避免以图块ID为标题被解释成图像(如`\t[bomb,null]`会以英文单词bomb为标题而没有图像,但单独的`\t[bomb]`则会没有标题但以炸弹道具为图像)。
+ * 只填写图像而不填写标题时,会被优先解析到标题框中,请不要惊慌,这并不影响效果。
+3. **对话框效果:**可选,填法非常灵活,如下(坐标在大地图中均为绝对坐标,省略则取当前点)。
+ 1. `up,x,y`:对话框显示在点(x,y)上方,尖角朝下指着这个点(具体指的高度取决于图像。没有图像则判断该点是32×32px还是32×48px的图块,但是不管有无图像,若该点没有图块则都没有尖角)。
+ 2. `down,x,y`:对话框显示在点(x,y)下方,尖角朝上指着这个点。比起上面,这个没有高度问题,不过该点没有图块的话则还是没有尖角。
+ * 上述两种写法中,如果把坐标换成hero则显示在勇士上方或下方(尖角朝下的话,高度取决于勇士的行走图)。
+ 3. `this,x,y`:在大地图中,点(x,y)可能位于视野上半部分也可能位于下半部分,写this就能让对话框自动适配上下来防止越界。
+ 4. `hero`:在大地图上下边缘或小地图,勇士可能位于视野上半部分也可能位于下半部分,只写hero也能自动适配。
+ 5. `hero,n`:n为正整数,尖角指向勇士的第n名跟随者,自动适配上下,将hero改为up或down则手动指定上下。
6. `up,null`:显示在屏幕最上方,同理up换成down则为最下方。
7. `center`:强制显示在屏幕中央,宽度为视野宽度。
8. 除最后两种外,其余写法都会给对话框进行宽度自适配:
* 如果正文没有自动换行,则会先尝试取一个让文本总行数最接近“几行半”的宽度,可能会再适当加宽来防止标题出界。
* 如果正文有自动换行,则会尝试连同标题在内取最长的一行作为宽度。
+ * V2.7起,文本绘制一定程度上支持了排版标点禁则,成对符号的左半部分不会出现在行尾,右半部分和其他某些标点不会出现在行首。
9. 最终绘制时会尽量让尖角居中,除非尖角所指的点实在太靠左或太靠右。
- 10. 值得注意的是,使用`project/images/inskin.png`或类似的图片作为文章背景时,尖角的绘制用的是用图片右下角64×32的两格进行的,所以往往需要您自己准备好。
+ 10. 值得注意的是,使用`project/images/winskin.png`或类似的图片作为文章背景时,尖角的绘制用的是用图片右下角64×32px的两格进行的,所以往往需要您自己准备好。
+ * 技术群`959329661`的群文件“常用素材”提供了一些已经制作好的这样的图片,敬请取用。
4. **正文:**双击指令块,进入多行编辑。正文中允许使用很多转义序列,当您键入一个\字符时就会提示补全,后面逐一介绍。
-5. **立绘:**显示文章的同时可以绘制一张或多张立绘图,请双击预览各张图的效果。每张立绘由一大堆参数组成:`\f[name(:x/:y/:o,sx,sy,sw,sh,)x,y(,w,h,alpha,angle)]`
+5. **立绘:**显示文章的同时可以绘制一张或多张立绘图,请双击预览各张图的效果或右击整个指令预览所有立绘。每张立绘由一大堆参数组成:`\f[name(:x/:y/:o,sx,sy,sw,sh,)x,y(,w,h,alpha,angle)]`
1. **文件名:**需要放在project\images文件夹中并注册,这里需要带后缀。
2. **翻转:**和楼层贴图一样,支持三种翻转,在json代码中以文件的后缀名之后追加“:x、:y、:o”来表示。
3. **绘制坐标:**立绘在视野中的左上角像素坐标,后面的参数一旦省略其中一个则必须省略其后所有。
@@ -78,28 +83,38 @@ data为整个指令对象,x和y为当前点坐标,prefix为独立开关的
### 显示文章正文的转义序列
-1. **表达式计算:**使用`${}`可以计算一个js表达式,式子中允许使用所有的冒号缩写量和API,详见core.calValue()函数。
- * 此语法也可以用于“道具描述”和“即捡即用提示”,只不过那里就不支持中文替换了。
+1. **表达式计算:**使用`${}`可以计算一个js表达式,式子中允许使用所有的冒号缩写量和API,详见`core.calValue()`函数。
+ * 此语法也可以用于“道具名称”、“道具描述”和“即捡即用提示”,只不过那里就不支持中文替换了。
* 如`勇士当前的攻防相乘是\${状态:攻击\*状态:防御}`(中文替换),`持有三色钥匙共\${item:yellowKey+item:blueKey+item:redKey}把。`(json)
+ * 由于样板对`${}`的处理使用了(非贪心)正则匹配而不是栈匹配,因此`${}`内部不允许出现}字符,这导致您将无法使用代码块(如流程控制)、对象或函数定义,只能使用简单的运算符(包括?:三元运算)和函数调用。如有需要,可以将语法规则改为`${...$}`并自行适配。
2. **局部文字变色:**使用`\r[颜色英文名]`或`\r[\#RrGgBb]`(十六进制)来将这之后的文本变为另一种颜色。
* 最常用的17种颜色提供了自动补全,十六进制颜色可以随便找个有颜色参数的指令,呼出调色器去自己调配。只使用\r不带方括号则变回默认颜色。
3. **局部字号调节:**使用`\\c[正整数]`改变这之后文本的字号,只使用`\\c`不加方括号则恢复默认字号。
4. **手动换行、局部加粗和斜体:**退出多行编辑后,手动换行写作`\n`,另外可以使用`\\d`将局部文本加粗或取消加粗,使用`\\e`将局部文本变为斜体或取消斜体。
5. **32×32px图标的绘制:**使用`\\i[图标ID]`绘制一个32×32px的图块的第一帧或系统图标,您可以使用`core.statusBar.icons`查看所有的系统图标。
+ * 出于历史遗留问题,图块ID可以和系统图标ID重复,此时优先使用图块ID.
6. **打字速度调节:**开启打字机效果后,文本的打字速度总是匀速的。所以样板提供了名为“时间占位符”的转义序列,使用`\\z[正整数]`可以暂停相当于打这么多个字的时间。
+除`\n,\t,\b,\r,\f`外,其余转义序列的反斜杠在json中必须写两个!
+
### 其他文字类指令
1. **自动剧情文本:**和上面的显示文章基本相同,只不过不是由玩家按下确认键或点击屏幕,而是一定毫秒后自动消失,录像回放中则忽略。
* 比起那个,这个不能通过长按Ctrl键或长按屏幕快进,大量使用时一般用来搭配语音。否则对魔塔这种快餐游戏来说可能会非常不友好,建议统一塞进“显示确认框”指令的场合之一。
2. **滚动剧情文本:**将一段文字从屏幕最下方滚动到最上方,不支持自动换行,常用于op和ed.
-3. **显示提示:**即诸如打败怪物、捡到道具、打不开门时左上角的提示,只支持`${表达式计算}`。
+ * 该指令对应`core.drawScrollText(content, time, lineHeight, callback)`。
+3. **显示提示:**即诸如打败怪物、捡到道具、打不开门时左上角的提示,只支持`${表达式计算}`和`\r[变色]`。
* 可以填写一个图标ID显示在提示文本的左侧(支持32×48px但只画靠上的2/3,也可以使用系统图标)。
- * 此指令对应`core.drawTip(text, icon, frame)`函数。自然数`frame`表示绘制第几帧,默认为0表示第一帧。
+ * 此指令对应`core.drawTip(text, icon, frame)`函数。自然数`frame`表示绘制第几帧,默认为0表示第一帧(但没有在事件中提供)。
+ * 此指令看似显示出的提示会过一会才消失,但此指令本身依然是瞬间完成的,不属于异步事件!
+ * V2.6.4短暂提供了“同时显示多个tip”的功能,这在事件中连续获得多个道具时很友好,
+ * 但是玩家纷纷表示自由行动时此功能遮挡了太多的视野,因而在V2.6.5中就取消了。
+ * 如果需要此功能(包括自定义底色),请在本项目的[github](https://github.com/ckcz123/mota-js/archive/refs/tags/v2.6.4-release.zip)站点自行下载V2.6.4的发布版本并对照研究。
4. **游戏胜败和重启:**游戏胜败分别对应“脚本编辑”(快捷键N)的`win`和`lose`函数,在线游戏排行榜中每个结局的每个难度都有一张榜。
- * 但同一结局只有最高难度有效,您可以勾选“不计入榜单”来让这个本来有效的结局也无效。还可以勾选“不结束游戏”来先停止录制,再演出ed.
+ * 但同一结局只有最高难度有效,您可以勾选“不计入榜单”来让这个本来有效的结局也无效。还可以勾选“不结束游戏”来先停止录像的录制,再演出ed.
+ * win和lose函数最终都会调用`core.gameOver(ending)`函数,区别在于lose不填写ending. 但是,事件中使用gameOver这一异步函数需要额外的技巧,详见“原生脚本”。
* 重启游戏对应的函数为`core.showStartAnimate()`
-5. **设置剧情文本的属性:**可用`core.status.textAttribute`获取当前的剧情文本属性(只读)。各项含义:
+5. **设置剧情文本的属性:**可用`core.status.textAttribute`获取当前的剧情文本属性,各项含义:
1. **位置:**“显示文章”不使用`\b`对话框效果时文本的位置,默认为屏幕中央。如果您有大量集中的剧情文本都欲使用`up,null`的对话框效果,则可以直接将此项设置为“顶部”,而将剩余的个别剧情文本使用`center`或`down,null`的对话框效果,反之亦然。
2. **偏移像素:**上面的“位置”选择“顶部”或“底部”时和屏幕上下边缘的距离,也作为滚动剧情文本和左边缘的距离。
3. **对齐:**默认为左对齐,可以修改此项来让显示文章的标题和正文都居中或都右对齐。
@@ -110,22 +125,31 @@ data为整个指令对象,x和y为当前点坐标,prefix为独立开关的
8. **行距和字符间距:**如题,单位都是像素,行距推荐为正文字号的一倍半。
9. **粗体(Y/N):**文本是否默认加粗,推荐在大量粗体文本中穿插少量细体文本时使用,以免频繁的`\\d`切换。
10. **打字间隔:**0表示不启用打字机效果而是一次显示完,正整数表示每打一个字的毫秒数,也作为`\\z`暂停的单位时间。
+ 11. **淡入淡出时间:**V2.8新增,指定此项后,每个“显示文章”指令都会增加淡入淡出效果,建议用于大段的剧情层。
+
+可以使用`core.clone(core.status.textAttribute)`将文本属性备份到`hero.flags`中,从而做到临时使用另一套文本属性绘制部分内容。
### 图片类指令
1. **显示图片:**和立绘的语法基本类似,只不过多了编号(1—50)和淡入时间。
* 可以双击预览效果,还可以勾选“不等待执行完毕”来和后面的指令同时执行,比如同时淡入两张图片,或者淡入一张同时淡出/移动另一张。
- * 编号较大的图片会遮盖较小的,1—24号图片会被色调层遮盖,25—40号图片会遮盖UI层,41—50号图片会遮盖UI层。
+ * 编号较大的图片会遮盖较小的,1—24号图片会被色调层遮盖,25—40号图片会遮盖色调层但被UI层遮盖,41—50号图片会遮盖UI层。
* 此指令对应`core.showImage()`函数,编号真正的意义,详见[个性化](personalization)
2. **清除图片:**如题,需要指定要清除的图片编号和淡出时间。
* 此指令对应`core.hideImage(code, time, callback)`
3. **图片移动:**其实还包括了透明度渐变,“终点像素位置”指移动结束后的图片在视野中的左上角像素坐标(不填则表示单纯的透明度渐变),“不透明度”指渐变结束后的新的不透明度(不填表示单纯的移动)。对应`core.moveImage(code, to, opacityVal, moveMode, time, callback)`
-4. **显示或清除动图:**需要填写动图的文件名(带.gif后缀),“起点像素位置”含义如前且必须填写,可以双击指令块来预览第一帧的效果。
- * 动图不支持淡入淡出和伸缩移动,如果不填任何参数则清除所有动图。
+ * time不能填0,如果想实现瞬移或瞬间改变透明度,请填1
+ * V2.8起,图片和视野的移动支持加速度,分为“匀速、加速、减速、先加速再减速”四种,请任意选用。
+4. **图片旋转:**V2.8新增,同样支持加速度,旋转中心坐标不填则取图片中心。
+ * 此指令对应`core.rotateImage(code, center, angle, moveMode, time, callback)`函数。
+ * time同样不能填0,如果想瞬间得到旋转后的结果,请填1
+ * 比起移动,旋转本身不支持同时透明度渐变,您可以先写一个不指定终点的移动指令且“不等待执行完毕”来实现单纯的淡入淡出,然后再写一个耗时相同或略长的旋转指令,这样两个指令就会一起执行了。
+ * 当不指定旋转中心时,本指令可以和移动指令同时使用,从而得到“图片的中心做直线运动、同时图片还在绕着中心自转”的效果。
+5. **显示或清除动图:**需要填写动图的文件名(带.gif后缀),“起点像素位置”含义如前且必须填写,可以双击指令块来预览第一帧的效果。
+ * 动图不支持淡入淡出和伸缩移动,如果不填任何参数则清除所有动图(只支持全部清除)。
* 该指令对应`core.showGif(name, x, y)`函数。
-5. **显示图片化文本:**这是您唯一显示镜像文字或旋转180°文字的机会。
- * 显示出来后就会视为一张通常的图片,可以被清除和移动。
- * 该指令对应`core.drawScrollText(content, time, lineHeight, callback)`
+6. **显示图片化文本:**这是您唯一显示镜像文字的机会。
+ * 显示出来后就会视为一张通常的图片,可以被清除、移动、淡入淡出、旋转。
### 显示确认框,选择项,QTE与全局商店
@@ -133,13 +157,17 @@ QTE,即快速反应事件。一般表现为需要玩家在收到某信号后
样板同样支持这类事件,一共有三种,这里先介绍两种。
-一是**显示确认框**,它会显示一段支持`${表达式求值}`但不支持自动换行和其他转义序列的文字。然后要求玩家在一定毫秒数内选择“确定”或“取消”之一,如果超时就视为哪个都没选,直接继续执行后面的事件。
+一是**显示确认框**,它会显示一段支持`${表达式求值}`但不支持自动换行、淡入淡出和其他转义序列的文字。然后要求玩家在一定毫秒数内选择“确定”或“取消”之一,如果超时就视为哪个都没选,直接继续执行后面的事件。
您可以指定闪烁光标的初始停留位置是确定还是取消,还可以指定超时毫秒数为0表示不限时间但玩家必须做出二选一。
+当指定了超时时间并且及时做出选择时,剩余时间会被写入“变量:timeout”,可以用来做一些处理(音游?)。
+
此指令对应`core.drawConfirmBox(text, yesCallback, noCallback)`函数,其中两个Callback分别为选择确定和取消后的回调函数。
-二是**显示选择项**,和RPG Maker不同,我们的选择项不会和它之前的“显示文章”同时出现,可以直接配上除对话框和打字机外的所有文字效果。
+V2.8起,显示确认框在录像回放时如果录像中没有记录该选哪一项(或者明明此事件未设置超时时间但录像中记录了超时),就会选择默认项(也就是光标的默认位置),请注意。
+
+二是**显示选择项**,和RPG Maker不同,我们的选择项不会和它之前的“显示文章”同时出现,可以直接配上除对话框、打字机、淡入淡出外的所有文字效果。
此指令对应`core.drawChoices(content, choices)`函数,其中content为提示文字,choices为各子选项文字组成的字符串数组。是的,比起上面的函数,这个不直接支持回调。
@@ -149,9 +177,23 @@ QTE,即快速反应事件。一般表现为需要玩家在收到某信号后
每个子选项还可以指定“出现条件”(不指定则一定出现),条件的写法和自动事件的触发条件一样,从而做出形如“怒气值满才显示大招选项”的效果。
-如果实际执行时所有子选项都不满足出现条件,则直接跳过。当然,如果非要做出“显示但选了没反应”的禁用项也不是不可以,只不过往往需要套在一个死循环里并让其他子选项负责跳出这个循环。
+如果实际执行时所有子选项都不满足出现条件,则直接跳过。但是如果出现的项都不满足下面的“启用条件”就会导致所有项都不可选,然后游戏卡死,请务必注意这个问题。
-为了方便地做出这种效果,样板提供了“全局商店”。
+V2.7.2起,每个子选项还可以指定“启用条件”,当出现条件和启用条件都满足时才能真正选中这一项。
+
+如果只满足前者但不满足后者,该项会变灰,尝试选择时会播放“操作失败”系统音效并显示提示(超时倒计时不会重置)。
+
+当指定了超时时间并且及时做出有效选择时,剩余时间同样会被写入“变量:timeout”,可以用来做一些处理。
+
+您或许会疑惑提示文字为什么不做成随光标位置而变化(这在很多电脑/手柄游戏中很常见),这是因为触屏设备无法改变光标位置,如有需要,请自行在此界面提供虚拟方向键(不打算发布触屏版游戏的则无所谓),然后在提示文字中使用${}对`core.status.event.selection`进行判定,从而改变提示文字。
+
+V2.8起,显示选择项在录像回放时如果录像中没有记录该选哪一项(或者明明此事件未设置超时时间但录像中记录了超时),就会弹窗询问玩家是否补选一项,此时玩家可以输入某项的序号(从0起)来修复录像,当然也可以在弹窗时点取消来放弃修复。
+
+提交成绩后,站点后端的录像验证时如果发生了同样的问题,则因为无法询问玩家,会直接选择第一项(可以在`core.events._action_choices()`函数中自行配置上述修复策略,如选择最后一项)。
+
+如果录像回放中尝试选择不满足“启用条件”的灰项,V2.8起会直接报错。这种处理方式比上面的“弹窗请求补选”更为严厉,如您在造塔测试时遇到了这种问题,可以先“回退到上一个节点”,然后在控制台输入`core.status.replay.toReplay`查看接下来该播放的内容(可以按N键单步播放),并在这个一维数组中删除掉那个非法的选项值。
+
+而如果录像中记录了多余的确认框或选择项(`choices:n`),V2.8起就会在播放时跳过并警告。

@@ -171,10 +213,10 @@ QTE,即快速反应事件。一般表现为需要玩家在收到某信号后
* “快捷名称”为显示在V键快捷菜单的名称,请注意控制字数,最好也两两不同以免玩家混淆。
* 勾选“未开启不显示”则此商店在开启前或禁用后不会出现在V键菜单中,当商店总个数超过12或14个且随着游戏流程进度依次开新的关旧的时,这个勾选项就很有必要了。
* 其次,和其他两种商店不同,您可以允许玩家预览它(前提是V键菜单中显示了),这对魔塔这种倡导完全信息的游戏来说非常有意义。
- * 最后,比起常规的“显示选择项”,它不能指定超时毫秒数,每个子选项除“出现条件”外还多出一个“使用条件”。
- * 实际执行中在所有子选项的最后会自动追加一个“离开”选项,选择其他子选项并执行后商店并不会立即关闭而是停在那个界面。就像胖老鼠和两部新新魔塔一样,只不过不支持长按连续购买。
+ * 最后,比起常规的“显示选择项”,它不能指定超时毫秒数,但是(V2.8起)允许长按连续购买。
+ * 实际执行中在所有子选项的最后会自动追加一个“离开”选项,选择其他子选项并执行后商店并不会立即关闭而是停在那个界面。就像胖老鼠和两部新新魔塔一样。
* “出现条件”和“使用条件”相搭配,让您能够很轻松地做出形如“消耗金币和各种材料的装备合成路线”这样的设定。
- * 在预览模式下除“离开”外的子选项、以及交易模式下不满足“使用条件”的子选项,都会显示为灰色。
+ * 在预览模式下除“离开”外的子选项、以及交易模式下不满足“使用条件”的子选项,都会显示为灰色,尝试选择时会播放“操作失败”系统音效并提示失败原因。
* 子选项的执行内容中需要手动处理扣费等问题,此外,在制作像两部新新魔塔一样会涨价的商店时,您也需要自己准备变量(变量名不必与商店id相同)去记录已购次数或者直接记录价格,并手动处理涨价问题。
有关全局商店的详细实现,请参见“插件编写”(句号键,`project/plugin.js`)。
@@ -185,43 +227,62 @@ QTE,即快速反应事件。一般表现为需要玩家在收到某信号后
或使用“提前结束本轮循环”来打断未执行内容而强制重启商店。
-同理,公共事件(包括公共事件商店)和自动事件本质上是“一次性”的条件为false的后置条件循环,因此使用这两个指令都能跳出它们。
+同理,公共事件(包括公共事件商店)和自动事件本质上是“一次性”的条件为`false`的后置条件循环,因此使用这两个指令都能跳出它们。
## 数据相关类(绿色)

-这类的指令会设置各种数据(如怪物属性、楼层属性、全塔属性、六大可读写块),处理弹窗输入和开关全局商店,以及控制玩家最最关心的勇士的各种行为。
+这类的指令会设置各种数据(如怪物属性、楼层属性、全塔属性、七大可读写块),处理弹窗输入和开关全局商店,以及控制玩家最最关心的勇士的各种行为。
### 设置各种数据的指令
-1. **数值操作:**最简单的就是最灵活的,本指令能够修改六大可读写块(状态、物品、变量、独立开关、临时变量、全局存储)的值。
- * 修改的运算符有八种,“设为”会将右块的值代入左块,“增加、减少、乘以、除以”则是对左块的值进行增减和扩大缩小,除法如想只保留整数商(向零靠近)则改用“除以并取商”,如想要余数(例如想取勇士生命值的后两位)则使用“除以并取余”,“乘方”指的是将若干个(不一定是正整数)左块连乘起来的积代入左块。
+1. **数值操作:**最简单的就是最灵活的,本指令能够修改七大可读写块(状态、物品、变量、独立开关、临时变量、全局存储、增益)的值。
+ * 修改的运算符有十种,“设为”会将右块的值代入左块,“增加、减少、乘以、除以”则是对左块的值进行增减和扩大缩小。
+ * 除法如想只保留整数商(向零靠近)则改用“除以并取商”,如想要余数(例如想取勇士生命值的后两位)则使用“除以并取余”。
+ * “乘方”指的是将若干个(不一定是正整数)左块连乘起来的积代入左块。
+ * “设为不大于”和“设为不小于”是指在左块大于/小于右块的时候将右块代入左块,也就是“封顶”和“保底”的作用。
* 指令的右块为一表达式,可以使用任何值块和运算块,甚至直接使用API.
* 如果需要连续使用本指令,建议除最后一个外都勾选“不刷新状态栏”,以降低刷新状态栏的性能损耗,并且避免意外触发自动事件、生命和魔力溢出甚至死亡(生命小于等于0)。
2. **设置怪物属性:**可以设置怪物的任何一项属性并计入存档。
- * 怪物ID在blockly块中也可以填中文(要求没有重复,有的话请在事件编辑器顶部关闭“中文替换”功能),需要设置的属性项在下拉框中选取。通过配置表格自行新增的属性下拉框里没有,但可以写在json区再单击变黄的“解析”按钮,或修改`_server\MotaAction.g4`文件最后的部分去追加。
- * 本指令对应`core.setEnemy(id, name, value)`函数,完全等价。
- * 最后的“值”和“数值操作”的右块写法一致(只支持写变化后的结果值,下同),注意设置怪物名字、映射名等字符串类型需要加引号。
-3. **设置楼层属性:**除了贴图和两个到达事件,其他属性都可以方便地修改。
+ * 怪物ID在blockly块中也可以填中文(要求没有重复,有的话请在事件编辑器顶部关闭“中文替换”功能),需要设置的属性项在下拉框中选取。通过配置表格自行新增的属性在下拉框里没有,但可以写在json区再单击变黄的“解析”按钮,或修改`_server\MotaAction.g4`文件最后的部分去追加。
+ * 本指令对应`core.setEnemy(id, name, value, operator, prefix)`函数,完全等价。
+ * 最后的“值”和“数值操作”的右块写法一致,注意设置怪物名称需要加引号,设置逻辑值(是否)需要填写`true`或`false`,设置“特殊属性”需要填数组且只支持结果值。
+ * V2.8起,怪物支持“行走图朝向”功能,您在四个朝向的怪物中任意设置一个的属性都会强制同步到其他三个。
+3. **定点设置/移动或重置怪物属性:**V2.8新增,该指令主要是为了实现一些诸如“发动技能后指定某个点,该点怪物被削弱/增强,并计入存档”的功能。
+ * 该指令支持设置的属性有“名称、生命、攻击、防御、金币、经验、加点”,设置后,该属性会在“脚本编辑——怪物真实属性”中最先被使用,然后可以被光环等影响。
+ * 使用时,需要指定楼层和坐标,楼层不写则取当前层,坐标不填则取当前点,支持双击从地图选点,(除移动外)支持选多个点。
+ * “移动某点怪物属性”支持写增量(dx、dy),如写[4,-2]就会让某个点的怪物属性移动到向右4格、向上2格的位置。
+ * 发生战斗后,该点会被自动重置定点属性。但是怪物移动跳跃时(如阻击)定点属性并不会一起移动,因此才提供了移动该属性的指令。
+ * 该组指令实际调用的API为:
+ ```
+ core.setEnemyOnPoint(x, y, floorId, ...)
+ core.moveEnemyOnPoint(fromX, fromY, toX, toY, floorId)
+ core.resetEnemyOnPoint(x, y, floorId)
+ core.enemys.getEnemyValue(enemy, name, x, y, floorId) // 读取
+ ```
+4. **设置装备属性:**V2.8新增,该项可以制作一些“随剧情推进而强化装备”的效果并计入存档。
+ * 使用时,需要指定装备ID、要修改的是常数值还是增益、要修改的属性英文名等。
+5. **设置楼层属性:**除了贴图和两个到达事件,其他属性都可以方便地修改。
* 楼层ID不填则视为当前楼层,可以去“地图选点”浏览各楼层并复制ID.
- * 注意修改“楼层中文名”、“状态栏中名称”、“默认地面ID”、“背景音乐”(需要后缀名)这些字符串类型都需要加引号,几个“能否/是否”只支持修改为true或false,三个坐标和天气、色调这些数组类型都需要加方括弧。本指令对应`core.events.setFloorInfo(name, value, floorId, prefix)`
-4. **设置全局属性:**即全塔属性中的“主样式”(无需再加引号)和装备孔列表。
+ * 注意修改“楼层中文名”、“状态栏中名称”、“默认地面ID”、“背景音乐”(需要后缀名)这些字符串类型都需要加引号(V2.8起背景音乐支持一维数组),几个“能否/是否”只支持修改为`true`或`false`,三个坐标和天气、色调这些数组类型都需要加方括弧。本指令对应`core.events.setFloorInfo(name, value, floorId, prefix)`
+ * 修改当前层的天气/色调/背景音乐后不会立即生效,如需生效请补一个对应的特效指令(如“恢复画面色调”)并且不要勾选“持续”。
+6. **设置全局属性:**即全塔属性中的“主样式”(无需再加引号)和装备孔列表。
* 修改装备孔列表时请注意,如果装备的道具属性中填写的装备类型是自然数,则可以【在列表结尾】随着游戏流程的推进解锁新的装备孔或移除装备孔(请先将身上的此类装备脱下)。
* 而如果装备的道具属性中填写的装备类型是装备孔名称,则可以随着游戏流程的推进修改装备孔的类型组成,如本来是两把剑一块盾改成一把剑两块盾(同样需要注意已经穿上的装备问题)。
* 本指令对应`core.events.setGlobalAttribute(name, value)`函数。
-5. **设置全局数值:**如题,可以修改四种宝石和三种血瓶的基础值等。
- * 如需使用脚本,请直接修改`core.values`,完全等价。
-6. **设置系统开关:**如题,可以用来随着游戏流程的推进解锁/移除状态栏的显示项或改动其他开关。
+7. **设置全局数值:**如题,可以修改四种宝石和三种血瓶的基础值等,必要时也可以修改图块的每帧时间以及上下楼时间以得到一些演出效果。
+ * 如需使用脚本,请直接修改`core.values`,完全等价。但是竖屏状态栏的自绘行数如果动态修改有可能会出问题,请注意。
+8. **设置系统开关:**如题,可以用来随着游戏流程的推进解锁/移除状态栏的显示项或改动其他开关。
* 比如中途开关生命上限、加点和负伤,中途显隐魔力、技能、绿钥匙和破炸飞毒衰咒。
* 在游戏胜利时会将生命值作为分数上传到在线游戏排行榜,因此请在胜利前关闭生命上限再修改生命,比如根据钥匙等道具的持有情况进行加分。
* 请注意,即使您在游戏中途才将楼传变为平面塔模式,访问过的楼层依然已经记录了最后离开的位置。
- * 如果想制作万能铁门钥匙,可以在适当的时候修改“铁门是否需要钥匙”。
- * 本指令对应`core.setGlobalFlag(name, value)`函数,实际会修改`core.flags`(但请不要脚本直接修改它)
+ * 本指令对应`core.setGlobalFlag(name, value)`函数,实际会修改`core.flags`(但请不要用脚本直接修改它)
+9. **设置文件别名:**V2.8新增,您可以修改一个中文名实际指向的英文文件名,从而做到随剧情推进采用不同的系统音效(如上下楼)等效果,如果英文文件名不填则表示恢复到全塔属性中的默认值。
### 导致勇士位置变化的指令
-这类指令都支持填写负坐标、超出地图宽高的坐标或小数坐标,
+这类指令都支持填写负坐标、超出地图宽高的坐标或小数坐标(大地图中请慎用小数坐标),
当勇士在这些异常坐标时【除第一个指令外】都可以正常执行。
@@ -229,25 +290,29 @@ QTE,即快速反应事件。一般表现为需要玩家在收到某信号后
1. **勇士前进一格或撞击:**如题,会让勇士像自由行动时一样尝试前进一格。
* 如果可以前进但前方不可被踏入(如门、怪物、箱子、NPC)则会撞击并触发事件,走到道具、踩灯或路障或用普通事件制作的陷阱等也会触发。
- * 本指令可以正常触发跑毒和阻激夹域捕,滑冰事件就是在冰上执行了它。
+ * 本指令可以正常触发跑毒和阻激夹域捕捉(可以致死),滑冰事件就是在冰上执行了它。
* 本指令对应`core.moveAction(callback)`函数,但请勿直接调用它。
-2. **无视地形移动勇士:**“动画时间”为每步的时间,不填则取玩家设定值。
+2. **无视地形移动勇士:**“动画时间”为每步的时间,不填则取玩家设定值,该值从V2.8起允许在移动过程中修改(最少为16)。
* 可以勾选“不等待执行完毕”来和后面的指令同时执行,比如让勇士和一个NPC肩并肩走。
- * 本指令不会触发跑毒和阻激夹域捕,且会无视地形可进出性、可通行性,
+ * 本指令不会触发跑毒和阻激夹域捕捉,且会无视地形可进出性、可通行性。
* 移动过程中不会触发任何事件,就像开启调试模式时按住Ctrl键移动一样(与之不同的是,也可以移动出地图外)
- * 指令的最后一个参数为步伐口诀,支持`上下左右前后`六种移动方向。连续的相同字可以合并,如`上上`可以写作`上2`。
- * 勇士后退时,跟随者们会照常前进。
- * 数不清楚格子时记得善用地图选点功能浏览地图
+ * 勇士后退时,跟随者们会照常前进,数不清楚格子时记得善用地图选点功能浏览地图。
+ * V2.8起,支持斜向移动,支持移动过程中单纯转向(步数填0)。
+ * 斜向移动时行走图以左右为准,但“后退”依然以勇士朝向为准而不考虑上一步的行走方向(这点和图块的移动不同,勇士不可能斜向后退但图块可能)。
* 本指令对应`core.eventMoveHero(steps, time, callback)`函数,请注意不是`core.moveHero()`
-3. **跳跃勇士:**可以填写目标点坐标(支持双击从地图选点),
- * 可以用带有冒号缩写量甚至API的表达式,比如`["core.nextX(2)", "core.nextY(2)"]`(json)表示勇士越过面前一格,即道具“跳跃靴”的效果。
+ * 多说一句,您可能会发现勇士在移动时会在行走图的2、4两帧之间反复切换(尤其是在大地图中心时很明显),这和图块以及RPG Maker的行为很不一致而且观感较差,如需改成1234帧循环,请启用“勇士四帧行走动画”插件(V2.8该插件有更新,从V2.7.x接档的用户需要重新抄写一下)。
+3. **跳跃勇士:**可以填写目标点坐标(支持双击从地图选点),坐标允许使用带有冒号缩写量甚至API的表达式。
+ * 比如`["core.nextX(2)", "core.nextY(2)"]`(json)表示勇士越过面前一格,即道具“跳跃靴”的效果。
+ * V2.7.3起,跳跃的目标坐标支持写增量(dx、dy),如写[4,-2]就会让勇士跳到向右4格向上2格的位置。
* 跳跃高度和距离有关,原地跳跃的高度只有半格(可在下述函数中修改)。跳跃过程中跟随者消失,跳跃结束时跟随者聚集。
* 跳跃也支持异步效果(如和NPC一起跳),对应`core.jumpHero(ex, ey, time, callback)`函数,其中`callback`为异步跳跃完毕的回调函数。
- * 跳跃默认没有音效,您可以自行像支援怪和道具“跳跃靴”一样配上音效。
- * 和无视地形移动勇士一样,勇士跳跃也会无视目标点的地形和阻激击域捕,不会触发目标点的任何事件。
-4. **楼层切换:**和前面的“楼梯、传送门”事件用法完全一样,但不可穿透。
+ * 跳跃默认没有音效,您可以自行像支援怪和道具“跳跃靴”一样配上音效(具体方法在“插件复写”一节有讲)。
+ * 和“无视地形移动勇士”一样,勇士跳跃也会无视目标点的地形和阻激夹域捕捉,不会触发目标点的任何事件。
+ * “无视地形移动勇士”和“跳跃勇士”因为经常和图块的这两个行为一起使用进行演出且都没有碰撞效果,因此V2.7.3起移动到了“地图处理类”,请注意。
+4. **楼层切换:**和前面的“楼梯、传送门”绿点事件用法完全一样,但不可穿透。
* 此指令同样支持双击从地图选点(坐标支持表达式)和在json区填写传送的目标点图块ID(在目标层唯一)再点击变黄的“解析”按钮。
* 另外,正如本小节开头提到的,本指令比起“楼梯、传送门”事件更多地用于演出,因此您可以填写异常坐标。
+ * 楼层ID只能填写常量,如需使用变量,请使用“原生脚本”插入事件。
5. **位置朝向切换:**“跳跃勇士”不会改变勇士朝向,“楼层切换”又会导致重生怪复活。且这两个都会导致跟随者聚集,所以同楼层内改变勇士位置可以使用本指令(坐标和跳跃一样支持双击从地图选点以及表达式)。
* 本指令还可以用来让勇士原地转身(不填坐标,这样也不会聚集跟随者),支持4种绝对朝向和4种相对转向。
@@ -256,23 +321,31 @@ QTE,即快速反应事件。一般表现为需要玩家在收到某信号后
以下杂牌指令负责弹窗输入、显伤战斗、道具装备、全局商店、行走图和队伍:
1. **接受用户输入:**弹窗请求用户输入一个自然数或字符串,提示文字允许使用`${表达式计算}`。
- * 请求输入自然数(支持十六进制)时,负整数会被取绝对值。小数会被向0取整,其他非法输入会变为0.
+ * 请求输入自然数(支持十六进制)时,负整数会被取绝对值。小数会被向0取整,其他非法输入会变为0,“输入自然数”在录像中会记录为`input:n`。
* 请求输入字符串时,玩家点击取消则视为输入了空字符串。
- * 输入的结果会保存在值块`变量:input`(`flag:input`)中,可供后续处理。
+ * 输入的结果会保存在值块“`变量:input`(`flag:input`)”中,可供后续处理。
* 比如样板的生命魔杖就是一个例子,它允许玩家一次使用多个同种道具。
+ * 读取“全局存储”这一行为,在录像中和“输入字符串”的记录方式一致(`input2:base64`)。
+ * V2.8起,录像回放中如果出现了多余的`input:`或`input2:`,都会警告并跳过。反之,“接受用户输入”事件在录像中缺失了值则会使用0或空字符串并补录。
2. **更新状态栏和地图显伤:**如题,可以勾选“不检查自动事件”来不检查。
- * 本指令实际执行“脚本编辑——更新状态栏”,即`core.updateStatusBar()`
-3. **强制战斗(点名):**和天降怪物(指定ID,中文替换只支持不重复的中文名)强制战斗,不会从地图删除图块也不会触发各点的战后事件(黄点)。
- * 此指令一般用于覆盖触发器的boss,可以制作战前剧情,然后强制战斗。
- * 战后boss不立即消失,可以继续进行一些演出,如51层魔塔四区骑士队长的逃跑效果。
- * 值得注意的是,因为是天降怪物(没有坐标),所以对这只怪物在属性修正以及战损计算等处涉及到怪物坐标的代码一律不起作用(比如它不会受局部光环的加成,也不会被任何怪支援)。
+ * 本指令实际执行“脚本编辑——更新状态栏”,即`core.updateStatusBar(doNotCheckAutoEvents);`
+3. **强制战斗(点名):**和天降怪物(指定ID,中文替换只支持不重复的中文名)强制战斗。
+ * 此指令战后不会从地图删除图块也不会触发各点的战后事件(黄点),但可以触发战后脚本和怪物属性中的(批量)战后事件。
+ * 此指令的战斗是强制的,打不过直接死亡(V2.8可以用值块预先判定能否打过)。
+ * 此指令一般用于boss战(通过走到某个点或开启某个门来触发),可以制作战前剧情,然后强制战斗。
+ * 战后boss不立即消失(从而避免基于漏怪检测的自动事件被误触发),可以继续进行一些演出,如51层魔塔四区骑士队长的逃跑效果。
+ * 因为是天降怪物(没有坐标),所以对这只怪物在属性修正以及战损计算等处涉及到怪物坐标的代码一律不起作用。
+ * 比如它不会受局部光环的加成,也不会被任何怪支援,也无法被V2.8的“定点设置怪物属性”影响。
* 另一种强制战斗指令在“地图处理类”,指定的是坐标而不是怪物ID.
+ * V2.8新增了两种战前事件,两种强制战斗指令都不会触发它们,如需触发,请使用“触发系统事件”指令。
+ * 由于V2.8提供了战前事件,因此不再建议使用曾经的“覆盖触发器+天降强制战斗”方式实现战前剧情,因为这样做不会自动存档,对玩家不太友好。
4. **尝试使用道具和穿脱装备:**使用道具和穿戴装备需要指定ID(中文替换规则和强制战斗一样)。
- * 不能使用怪物手册(请使用`特效声音类`的`呼出怪物手册`指令)和楼层传送器(如果`覆盖楼传事件`则没有关系),使用中心对称飞行器则会跳过确认画面。实际对应`core.useItem(itemId)`函数。
+ * 不能使用怪物手册(请使用“特效声音类”的“呼出怪物手册”指令)和楼层传送器(如果“覆盖楼传事件”则没有关系),使用中心对称飞行器则会跳过确认画面。实际对应`core.useItem(itemId)`函数。
* 穿脱装备对应`core.loadEquip(equipId)`和`core.unloadEquip(type)`函数。脱下装备需要指定类型,这里只能写自然数不能写名称。
- * 道具使用失败或穿不上装备(比如没有或不满足条件)时会提示。
+ * 道具使用失败或穿不上装备(比如没有或不满足条件)时会播放音效并提示。
5. **开关全局商店:**本指令可以设置一个全局商店的启用和禁用状态,设为启用时也支持立即打开。
* 一般用于商店的实体NPC处,再配合独立开关可以让勇士首次接触时先进行一些对话,然后启用(并打开)全局商店。
+ * V2.8新增了值块可以用来判定一个全局商店是否是开启状态。
6. **更改角色行走图:**如题,文件名必须填写(支持双击选文件)。
* 文件必须放在`project/images`文件夹并注册,且规格必须符合要求(4帧总宽度至少128px,高度不限。宽高必须为4的倍数)。
* 如果勾选“不重绘”就不会立即刷新,从而避免大地图视角重置到以勇士为中心。本指令对应`core.setHeroIcon(image, noDraw)`函数。
@@ -289,7 +362,7 @@ QTE,即快速反应事件。一般表现为需要玩家在收到某信号后
开始介绍前,首先明确一点:改变地图数据不会立即影响事件的进程(自动事件除外)。
-比如因为踩灯、路障和阻激夹域捕怪的分布变化导致勇士行走被妨害的区域发生变化,但不会立即触发妨害效果,而是要等到勇士下次行走。
+比如因为踩灯、路障和阻激夹域捕捉怪的分布变化导致勇士行走被妨害的区域发生变化,但不会立即触发妨害效果,而是要等到勇士下次行走。
在勇士所在点转变成(显示)一个门/怪物/道具/箱子/楼梯什么的(包括在脚下转变成/显示冰面)都不会立即触发事件,把这些图块移动/跳跃到勇士身上也是。
@@ -297,106 +370,118 @@ QTE,即快速反应事件。一般表现为需要玩家在收到某信号后
1. **强制战斗(定点):**这是另一种强制战斗,它指定坐标而不是怪物ID.
* 可以双击从地图选点(只能选当前楼层的,不填则取当前点),也可以用表达式指定坐标,坐标一次只能写【一个点】。
- * 战斗后会自动从地图删除该点的怪物,并尝试插入该点的战后事件(黄点),成功触发时会改变当前点坐标到该点。
+ * 战斗后会自动从地图删除该点的怪物(重生怪则是隐藏),并尝试插入该点的战后事件(黄点)以及怪物属性的(批量)战后事件,成功插入前者时会改变当前点坐标到该点。
+ * V2.8新增了两种战前事件,它们无法被“强制战斗”指令触发,如需触发,请使用“触发系统事件”指令。
2. **开关门:**坐标写法同上(限1个点),同层开门时楼层ID可以略去不写。
* 关门的位置必须是空地,“需要钥匙”只对同层开门有效。跨层开门请自己加判定,本指令对应`core.openDoor(x, y, needKey, callback)`函数。
* 这对指令支持所有完整填写了“门信息”的四帧图块(自动元件除外),比如样板自带的三色墙和六色门。
* 可以勾选“不等待执行完毕”来实现异步效果(如同时开关多个门,具体速度取决于门信息)。
- * 和上面的强制战斗一样,开门后将尝试插入该点的开门后事件(紫点),成功触发时会改变当前点坐标到该点。
+ * 和上面的强制战斗一样,开门后将尝试插入该点的开门后事件(紫点),成功插入时会改变当前点坐标到该点。
3. **显隐事件和图层块:**这两对指令可以令三层地图矩阵的某些阵元在0与非0之间切换。
* 还以51层魔塔为例,二楼右下角的小偷在游戏开始时是不显示的,勇士进入四区后才出现。
* 也就是说这个小偷是一个“普通事件”(红),内容是一些对话和打开35层魔龙处的暗道,只不过没有勾选“启用”。
* 在适当的时候(这个例子中是和29楼小偷对话后),执行一个“显示MT2层(12,12)点处的事件”指令,就能显示出二楼的小偷。
- * 同理,勇士接触此小偷并处理事件,事件结束前执行一个`隐藏(同时删除)当前点事件,500毫秒`指令,小偷就会从画面中淡出,勇士可以任意在小偷存在过的位置走来走去而不会再触发什么。
+ * 同理,勇士接触此小偷并处理事件,事件结束前执行一个“隐藏(同时删除)当前点事件,500毫秒”指令,小偷就会从画面中淡出,勇士可以任意在小偷存在过的位置走来走去而不会再触发什么。
* 所以,一次性陷阱(走到某个地方关上墙/机关门、冒出埋伏怪)在触发后一定要及时隐藏。不然就会反复触发,样板1层有例子可供参考。
- * “显隐事件”都可以双击从地图选点,但是这样只能选一个点(只想要楼层ID的话可以点击“复制楼层ID”按钮)。在指令块中可以使用表达式作为坐标,甚至可以将若干个点的横坐标依次填在x处而纵坐标对应填在y处(json中写作多行两列的二维数组),从而同时显隐多个点。
+ * “显隐事件”都可以双击从地图选点,支持选多个点(只想要楼层ID的话可以点击“复制楼层ID”按钮)。在指令块中可以使用表达式作为坐标(但这样只能写一个点),多个点可以把横坐标依次填在x处而纵坐标对应填在y处(json中写作多行两列的二维数组,但只支持常数),从而同时显隐多个点。
* 楼层ID省略则取当前楼层,“动画时间”用于同层显隐,从而表现出淡入淡出的效果。
* “不等待执行完毕”的含义如前,您可以淡入一些点同时淡出另一些点。
- * 值得注意的是,“隐藏事件”还提供了一个“同时删除”勾选框,勾选后无法再用“显示事件”指令显示出来。
- * 请注意,隐藏或删除后不影响正在进行的事件流(不会立刻结束),您可以把该点安全地直接转变为别的图块或让别的图块移动/跳跃到此点,比如把箱子/阻击怪推过来。
- * 其他两个图层的图块也支持显隐,对游戏性的影响主要体现在显隐背景层的滑冰图块以及两个图层的单向通行箭头。坐标和楼层ID的填法同上,只不过这两个就没有淡入淡出效果了。因为其他两个图层的图块不支持什么初始隐藏,如有需要,可以在“开场剧情”中统一提前隐藏。
+ * 值得注意的是,“隐藏事件”还提供了一个“同时删除”勾选框,勾选后无法再用“显示事件”指令显示出来(例如永久移除一个重生怪)。
+ * 请注意,隐藏或删除后不影响正在进行的事件流(不会立刻结束),您可以把该点安全地直接转变为别的图块或让别的图块移动/跳跃到此点,比如把箱子/阻击怪推过来(根据该点是否覆盖触发器,推过来以后的行为可能有变化)。
+ * 其他两个图层的图块也支持显隐,对游戏性的影响主要体现在显隐背景层的滑冰图块以及两个图层的单向通行箭头/薄墙。坐标和楼层ID的填法同上,只不过这两个就没有淡入淡出效果了。因为其他两个图层的图块不支持什么初始隐藏,如有需要,可以在“开场剧情”中统一提前隐藏。
* 显隐事件对应`core.showBlock(x, y, floorId)`和`core.hideBlock(x, y, floorId)`,同时删除对应`core.removeBlock(x, y, floorId)`函数;显隐图层块对应`core.maps._triggerFloorImage(type, loc, floorId, callback)`
4. **转变图块和图层块、事件转向:**这组指令可以修改三层地图矩阵的阵元。
- * 先说图层块吧(前景、背景),坐标和楼层的填法同上,不支持淡入淡出。转变图层块后,块的显隐状态不变,原来是隐藏还是隐藏。
+ * 先说图层块吧(前景、背景),坐标和楼层的填法同上,不支持淡入淡出。转变图层块后,块的显隐状态不变,原来是显示/隐藏还是显示/隐藏。
* 接着说事件层,坐标和楼层的填法同上。有几个注意事项:
1. 新图块为0时“动画时间”全部用来淡出,用于没有普通事件和“楼梯、传送门”的点会视为删除。
- 2. 转变图块也不影响显隐状态,该点原来是隐藏还是隐藏。
- 3. 同层把一种非0图块转变为另一种非0图块,“动画时间”的前一半用来淡出原图块,后一半用来淡入新图块。
+ 2. 转变图块也不影响显隐状态,该点原来是显示/隐藏还是显示/隐藏。
+ 3. 同层把一种非0图块转变为另一种非0图块(空气墙`airwall`算非0),“动画时间”的前一半用来淡出原图块,后一半用来淡入新图块。
4. 同层把0图块转变为非0图块,“动画时间”全部用来淡入。
* 这对指令可以填写新图块的ID也可以填写数字(如17是空气墙,201起是怪物)。
- * 如需让绑定了“行走图朝向”的npc48转向,也可以直接使用“事件转向”指令(和勇士一样支持7种转法),从而避免一个个手写行走图ID的麻烦。
+ * 如需让绑定了“行走图朝向”的图块转向,也可以直接使用“事件转向”指令(和勇士一样支持7种转法),从而避免一个个手写行走图ID的麻烦。
* 转变图块和图层块对应`core.setBlock(number, x, y, floorId)`和`core.maps._triggerBgFgMap(type, name, loc, floorId, callback)`
-5. **显隐贴图:**这个指令可以用来显隐之前在“楼层属性”中介绍的楼层贴图。
- * 显隐贴图不支持淡入淡出,坐标为贴图左上角的【像素坐标】,楼层ID不填则取当前层。实际执行`core.maps._triggerFloorImage(type, loc, floorId, callback)`
-6. **移动和跳跃事件:**这两个指令可以将地图一点的图块转移到另一点。
- * 首先明确一点,这两个指令转移的**仅仅是图块**。起点的七彩事件不会被一同转移,终点的七彩事件也不会被覆盖。
+5. **设置图块不透明度和特效:**如题,V2.8新增。前者支持渐变效果,可以用来制作亡灵状态的角色或配合楼层贴图实现大型怪物。
+6. **显隐贴图:**这个指令可以用来显隐之前在“楼层属性”中介绍的楼层贴图。
+ * 显隐贴图不支持淡入淡出,坐标为贴图左上角的【像素坐标】因此不支持地图选点,楼层ID不填则取当前层。实际执行`core.maps._triggerFloorImage(type, loc, floorId, callback)`
+7. **移动和跳跃事件:**这两个指令可以将地图一点的图块转移到另一点。
+ * 首先明确一点,这两个指令转移的【仅仅是图块】。起点的七彩事件不会被一同转移,终点的七彩事件也不会被覆盖。
* 从游戏性上讲,最终的效果是起点被“隐藏事件+同时删除”,勾选“不消失”时终点被“转变图块+显示事件”(终点原来的图块被覆盖)。
* 比如,阻击怪是“移动后不消失”,捕捉怪是“移动后消失”,支援怪是“跳跃后消失”。
* 这两个指令一次只能转移一个图块,双击从地图选点选择的是移动的起点和跳跃的终点(跳跃的起点请右击选取)。
* 任何一个坐标不填都视为当前点,比如“跳跃事件”什么坐标都不填就会让当前点图块原地跳跃。
* 和无视地形移动勇士一样,“移动事件”也没有碰撞效果,移动过程中会穿过勇士和一切地形。
- * “动画时间”为每步移动的时间和跳跃的用时,以及不勾选“不消失”时淡出的时间。
+ * “动画时间”为每步移动的时间或跳跃的用时,以及不勾选“不消失”时淡出的时间。
* 和“跳跃勇士”一样,“跳跃事件”默认也没有音效,可以自己搭配。
+ * V2.7.3起,跳跃的目标坐标支持写增量(dx、dy),如写[4,-2]就会让某个图块跳到其原位置向右4格向上2格的位置。
* 移动和跳跃实际对应`core.moveBlock(x, y, steps, time, keep, callback)`和`core.jumpBlock(sx, sy, ex, ey, time, keep, callback)`函数。
- * “移动事件”的步伐口诀只支持“上下左右”四个方向,不支持“前后”,即使是绑定了行走图朝向的NPC48也一样。
+ * V2.8起,“移动事件”指令支持斜向移动(行走图仍取左右)、中途变速(速度不得小于16)、中途转向(步数填0),“后退”指令如果用在开头则必须是绑定了“行走图朝向”的图块,如果用在中途则会根据上一步移动/转向的方向后退(注意这一点和勇士不同,勇士是不可能斜向后退的)。
* “不等待执行完毕”的用法如前,但几个图块再加上勇士以各异的速度和总步数移动时安排起来很麻烦,需要用到下述的“等待三姐妹”。
## 等待三姐妹、注释和原生js/json
在讲解“事件控制”(流程控制)类指令之前,这里插播几个比较杂牌的指令。
-1. **等待固定时间:**如题,可以用来实现复杂的集体移动效果。
+1. **等待固定时间:**如题,可以用来实现复杂的集体移动、跳跃效果。
* 比如说51层魔塔一区结尾的骷髅埋伏圈,就是九只骷髅和四扇机关门组成的复杂演出。
- * 每只骷髅开始移动时都不等待执行完毕,但又需要等待一小段时间再让下一只骷髅开始移动。
- * 本指令还提供了一个勾选项“不可被Ctrl跳过”,如果不勾选此项且当前【没有】正在执行的异步事件(动画不算),则Ctrl可以跳过等待。
+ * 每只骷髅开始移动时都“不等待执行完毕”,但又需要“等待一小段时间”再让下一只骷髅开始移动。
+ * 本指令还提供了一个勾选项“不可被Ctrl跳过”,如果不勾选此项且当前【没有】正在执行的异步事件(动画、音效、气泡提示不算),则Ctrl可以跳过等待。
2. **等待所有异步事件执行完毕:**让我们来想象这样一个情景。
* 您使用了“移动事件”来移动一只怪物到勇士面前,并且“不等待执行完毕”。而下一条指令是“勇士前进一格或撞击”,以期触发战斗。然而因为怪物移动需要时间,两个指令同时执行,所以战斗没法触发。
* 类似地,如果您在一个异步事件执行完毕之前就结束了整个事件流,让勇士恢复行动,那么可能这些异步事件还没来得及在游戏性方面生效,导致接下来会发生的事取决于玩家操作的时机和勇士的移速。
* 考虑到录像系统,在录像回放时很多耗时的东西和所有需要用户响应的东西会被跳过,勇士的移速又可以很快(倍速播放),导致回放结果和原游戏不一致。
* 总之,当您希望确保一些异步事件完全生效后再开始执行新的指令或结束事件流,“等待所有异步事件执行完毕”就是您的不二之选了,事件编辑器也会在发现缺少本指令时弹窗警告。
-3. **等待用户操作并获得键鼠信息:**前面提到三种QTE指令,这是最后一种。
- * 此指令的下一条指令为“清除所有动图”的话,会先清除再开始等待。
- * 之前提到的“确认框”和“选择项”可以复现RPG Maker的回合制战斗,但没法做出更复杂的交互界面,比如技能/天赋树,以及样板的道具商店。
+ * “不等待执行完毕”的动画和V2.8中“等待播放完毕”的音效不会被本指令视为异步事件,所以也不会对它们进行等待,务请注意。
+3. **等待用户操作并获得键鼠/触屏信息:**前面提到三种QTE指令,这是最后一种。
+ * 之前提到的“确认框”和“选择项”可以复现RPG Maker的回合制战斗,但没法做出更复杂的交互界面,比如技能/天赋树,以及样板的道具商店,这就需要用到本指令了。
* 本指令会阻塞事件的执行,直到玩家按下键盘上的某个键(滚轮视为PageUp/PageDown键)、或点击【视野】中的某个点、或经过了超时毫秒数(不设置则不限时)。
* 解除阻塞后,下列值块可能发生变化:
1. `变量:type`(`flag:type`),解除的原因,0表示按键,1表示点击,-1表示超时。
- 2. `变量:keycode`(`flag:keycode`),按键情况下的键值,48—57为大键盘0—9,65—90为字母键A—Z,其他键自己搜一下。
- 3. `变量:x`和`变量:y`(`flag:x`,`flag:y`),点击情况下所点格子的相对坐标,一定在0—12或0—14范围。
- 4. `变量:px`和`变量:py`(`flag:px`,`flag:py`),点击情况下所点像素的相对坐标,一定在0—415或0—479范围。
+ 2. `变量:keycode`(`flag:keycode`),按键情况下的键值,48—57为大键盘0—9,65—90为字母键A—Z,其他键请右击该子块查询(查不到的自己百度)。
+ 3. `变量:timeout`(`flag:timeout`),进行有效操作后,距离超时的剩余倒计时,可以用来进行一些处理(音游?)。
+ 4. `变量:x`和`变量:y`(`flag:x`和`flag:y`),点击情况下所点格子在视野中的相对坐标,一定在0—12或0—14范围。
+ 5. `变量:px`和`变量:py`(`flag:px`和`flag:py`),点击情况下所点像素在视野中的相对坐标,一定在0—415或0—479范围。
+ * 上述后两项如需转换为大地图中的绝对坐标,请查阅“楼层属性——修改楼层宽高”一节。
* 您可以根据这些值块去做流程控制,较为简单的场合(如几个键执行同一段指令,或横平竖直的单个矩形点击区)也可直接使用图中的场合块。
* 其中点击的场合块还支持双击预览判定区,用半透明的红色标出。
+ * 默认情况下,一次操作同时满足多个场合块时会依次执行这几个块的内容,除非您使用了下面的“不进行剩余判定”。
+ * V2.7.3起,场合块支持“不进行剩余判定”,当满足勾选了此项的场合块时,它下面的其他场合块会全部视为不满足。这允许您实现“点击地图上某个小区域做某些事,点击其他地方做另一些事”而不需要在后者的场合中专门排除前者。
+ * V2.8起,提供了超时场合块和自定义条件的场合块,同时还支持“只检测子块”。
+ * 在“只检测子块”模式下,如果玩家进行了不符合任何子块的操作,那么会继续阻塞而不是进入下一个指令,超时倒计时也不会重置。
+ * 但是如果设置了超时时间,即使未提供超时场合,超时时依然会解除阻塞直接进入下面的指令。
+ * 此指令获取到的玩家操作,在录像中会像“接受用户输入数字”一样记录为`input:...`。例如不带超时的键盘按键,就会记录为`input:keycode`。
+ * 录像回放时,如果出现了多余的`input:...`,就会跳过并警告。如果遇到本指令但录像中未记录操作或记录了非法/无效操作,就会直接报错。
+ * 非法操作指“本指令没有设置超时时间但录像中记录为超时”,无效操作指“本指令设置为只检测子块,但录像中记录的是一个不满足任何子块的操作”。
4. **添加注释:**在上述的场合块里您还可以看到两个注释块。
* 注释块在游戏中会被忽略,一般用来帮您记住写的指令是用来做什么的。
+ * 极端情况下,样板某些场合会检测指令数组是否为空及其长度,此时您可能需要被迫用注释指令来占位。
5. **自定义事件:**自带的指令毕竟有限,但事件可以与脚本任意联动。
- * 原生脚本分为两种,原生js和原生json.其中后者会实际执行您通过`core.registerEvent`注册的事件处理函数,请注意这类函数在执行结束前务必调用`core.doAction()`函数去继续执行下一条指令。
+ * 原生脚本分为两种,原生js和原生json.其中后者会实际执行您通过`core.registerEvent`注册的事件处理函数(即`{"type":"xxx",...}`对应`core.events._action_xxx()`),请注意这类函数在执行结束前务必调用`core.doAction()`函数去继续执行下一条指令。
* 如果学有余力,还可根据[修改编辑器](editor)来代替原生json,就可以使用调色器、地图选点、选文件等功能啦。
-6. **原生JS脚本执行**:允许你执行任意JS脚本。
+6. **原生JS脚本执行**:允许您执行任意JS脚本,例如造塔测试时发现事件流程不符合预期,此时可以使用`console.log()`语句在控制台输出日志信息进行检查。
原生js的用法就更广了,首先它可以做一些事件做不到的事,比如:
-如果用事件增加道具的话就会有提示和音效,而这有时不是我们需要的,尤其是在设计新道具时将“能否使用”填“true”并在使用效果事件中使用失败的场合返还道具时;因此我们可以直接调用脚本:
+如果用事件增加道具的话就会有提示和音效,而这有时不是我们需要的,尤其是在设计新道具时将“能否使用”填`"true"`并在使用效果事件中使用失败的场合返还道具时;因此我们可以直接调用脚本:
```js
core.addItem(itemId, n); // 静默增加n个道具,n可为负数,不填视为1
```
-其次,受制于Antlr—blockly的数据类型,很多指令的参数只能写常数,比如楼层ID。这时我们就需要在原生js中使用万能的core.insertAction()大法,来突破这些限制。
+其次,受制于Antlr—blockly的数据类型,很多指令的参数只能写常数,比如楼层ID。这时我们就需要在原生js中使用万能的`core.insertAction()`大法,来突破这些限制。
比如说我们有一座20层高的塔,楼层ID为MT0—MT19,某个事件中我们想让勇士随机传送到某个楼层,坐标不变。那么就可以使用下列原生js:
```js
core.insertAction({"type": "changeFloor", "floorId": "MT" + core.rand2(20)})
```
-连续使用多条json指令时,请先声明一个空的指令数组(`var todo = [];`)然后将需要的指令逐条追加到其末尾(`todo.push({"type": "xxx", ...});`),最后再一次性`core.insertAction(todo)`
+连续使用多条json指令时,请先声明一个空的指令数组(`var todo = [];`)然后将需要的指令分批追加到其末尾(`core.push(todo, [...]);`),最后再一次性`core.insertAction(todo);`插入执行,可以选择插入到剩余事件的开头或结尾。
-上述`core.rand2(20)`表示随机获取一个小于20的自然数。
+另外您可能会问:既然都用js了,为什么不直接用之前提到的`core.changeFloor()`函数呢?
-另外您可能会问:既然都用js了,为什么不直接用之前提到的core.changeFloor()函数呢?
+这是因为,原生js在不勾选“不自动执行下一个事件”的情况下,**只能使用瞬间完成的函数(或者drawTip、动画和音效这种虽然耗时但不影响游戏性的),不能使用任何异步函数(包括阻塞直到玩家操作的)**!
-这是因为,原生js在不勾选`不自动执行下一个事件`的情况下,**只能使用瞬间完成的函数(或者drawTip、动画和音效这种虽然耗时但不影响游戏性的),不能使用任何异步函数(包括阻塞直到玩家操作的)**!
+系统常见可能会被造塔用到的API都在[API列表](api)中给出,一般而言异步API的最后一个自变量都叫`callback`(回调)。在勾选“不自动执行下一个事件”的情况下,原生js可以使用一个异步API,只需将其`callback`参数填`core.doAction`,请谨慎使用。
-系统常见可能会被造塔用到的API都在[API列表](api)中给出,一般而言异步API的最后一个自变量都叫callback(回调)。在勾选`不自动执行下一个事件`的情况下,原生js可以使用一个异步API,只需将其`callback`参数填`core.doAction`,请谨慎使用。
-
-比如说,我们知道天降强制战斗没有坐标所以不受光环等影响也无法触发战后事件,那捕捉怪的战斗是怎么实现的呢?答案是在原生js中使用了异步的`core.battle(id, x, y, force, callback)`函数,这里`force`填`true`表示强制战斗,`callback`填`core.doAction`表示战斗结束后继续处理事件。
+比如说,我们知道天降强制战斗没有坐标所以不受光环等影响也无法触发(单点)战后事件,那捕捉怪的战斗是怎么实现的呢?答案是在原生js中使用了异步的`core.battle(id, x, y, force, callback)`函数,这里`force`填`true`表示强制战斗,`callback`填`core.doAction`表示战斗结束后继续处理事件。
熟练运用后,还可以使用多个异步API,每个以下一个作为回调。
@@ -408,16 +493,17 @@ core.insertAction({"type": "changeFloor", "floorId": "MT" + core.rand2(20)})
1. **条件分歧:**和“显示确认框”很相似,只不过这个是自动的。
* 和js的`if (...) {...;} else {...;}`完全等价,本指令需要内嵌一个值块(可以填逻辑表达式,常常是两个值块的比较,比如某道具是否足够)。
- * 当此值块的值不为`false、0、null、undefined、NaN和空字符串`时,执行“如果:”和“否则:”之间的指令,当此值块的值为这六个值之一时,执行“否则:”后面的指令。
-2. **多重分歧:**本指令和js的switch语句有一定差别,即使您有js基础也请仔细阅读接下来的说明。
- * 事件执行到多重分歧指令时,会先计算一次“判别值”,结果记作key.然后准备一个空的指令数组,记作list;
- * 接下来从上到下扫描每个场合块,如果一个场合块的“值”为default或计算结果和key相等,就把这个场合的指令组追加到list的末尾,`core.push(list, [...])`
+ * 当此值块的值不为`false、0、null、undefined、NaN和空字符串`(即之前提到的六大广义`false`)时,执行“如果:”和“否则:”之间的指令,当此值块的值为这六个值之一时,执行“否则:”后面的指令。
+2. **多重分歧:**本指令和js的`switch`语句有一定差别,即使您有js或其他编程语言基础,也请务必仔细阅读接下来的说明。
+ * 事件执行到多重分歧指令时,会先计算一次“判别值”,结果记作`key`.然后准备一个空的指令数组,记作`list`;
+ * 接下来从上到下扫描每个场合块,如果一个场合块的“值”为`default`或计算结果和`key`相等,就把这个场合的指令组追加到`list`的末尾,即`core.push(list, [...]);`。
* 每次成功追加后,如果被追加的此场合块未勾选“不跳出”,则无视下面的所有场合块直接结束扫描,否则继续扫描下一个场合块。
- * 扫描完全结束后,调用core.insertAction(list)付诸执行。
- * 所以各场合块的顺序一定要安排好,比如default(可以没有此场合)如果不勾选“不跳出”则一定要放在最后。
- * 多重分歧常见的用法是,判别值填常量,各场合块填未知量且都勾选“不跳出”。把所有相等的场合筛选出来依次执行,类似js的filter语法。
- * 或者,判别值填未知量,所有场合块都不勾选“不跳出”且“值”填写为两两不同的常量(如果有相同的则只有第一个有效)。从而执行唯一的相等场合,没有的话还可以补一个default场合,类似js的else
- if语法。
+ * 扫描完全结束后,调用`core.insertAction(list);`付诸执行。
+ * 所以各场合块的顺序一定要安排好,比如`default`(可以没有此场合)如果不勾选“不跳出”则一定要放在最后。
+ * 多重分歧常见的用法是,判别值填未知量,所有场合块都不勾选“不跳出”且“值”填写为两两不同的常量(如果有相同的则只有第一个有效)。从而执行唯一的相等场合,没有的话还可以补一个`default`场合,类似js的`else if`语法。
+ * 或者,判别值填常量,各场合块填未知量且都勾选“不跳出”。把所有相等的场合筛选出来依次执行,类似js的`filter`语法。
+ * 第二种用法中,最常见的是判别值填`true`,各场合块填逻辑表达式。此时如果都勾选“不跳出”并且不提供`default`场合,就相当于一堆没有`else`的if语句。
+ * 而如果在这个基础上改成都不勾选“不跳出”就相当于正常的`else if`语句(可以把`default`场合提供在最后或不提供),而且比起上面的“条件分歧”指令不需要嵌套了。
3. **循环遍历(计数):**使用临时变量A—Z(事件流结束时会和arg+纯数字的变量一起被清空)可以进行循环遍历,它们都属于前置条件循环。
* 循环遍历有两种,第一种是计数型。`从`和`到`之间的框填写临时变量的初始值,`到`和`步增`之间的框填写临时变量允许的边界值。
* 每轮循环开始前会【重新计算】边界值和步增,如果临时变量位于界外(减去边界值后和步增同号)则跳出循环。
@@ -427,40 +513,45 @@ core.insertAction({"type": "changeFloor", "floorId": "MT" + core.rand2(20)})
* 使用此项时请注意,列表中的字符串不会被自动解释为冒号缩写量。显示文章等处如有需求,请使用`${core.calValue(temp:A)}`来计算。
* 分歧和循环都可以嵌套,嵌套循环遍历请给内外层使用不同的临时变量。
5. **前/后置条件循环:**
- * 客观上,前置条件循环和一个没有“否则”分支的条件分歧很相似,区别仅仅在于每次执行完分支内容后都会【跳转】回到条件检测之前,从而再次检测条件,还满足就再执行,如此往复。
+ * 前置条件循环和一个没有“否则”分支的条件分歧很相似,区别仅仅在于每次执行完分支内容后都会【跳转】回到条件检测之前,从而再次检测条件,还满足就再执行,如此往复。
* 而后置条件循环比起前置,区别在于第一轮循环是无视条件强制执行的。
- * 它们对应的js语法分别为`while (...) {...;}和do {...;} while(...);`
-6. **跳出当前循环:**如题,遇到此指令时,将检测当前是否在某个循环中(还包括自动事件、公共事件、全局商店),并跳出所在的【最内层】循环。如果不在任何循环中,则什么也不做。大致相当于js的`break;`
-7. **提前结束本轮循环:**生效范围同上,不过是结束最内层的【本轮】循环。换言之,对一般的前/后置条件循环会立刻跳转到下次检测条件前,
- * 对循环遍历(计数)会立刻跳转到下次计算边界和步增并累加前,
+ * 它们对应的js语法分别为`while (...) {...;}`和`do {...;} while(...);`
+6. **跳出当前循环:**如题,遇到此指令时,将检测当前是否在某个循环中(还包括自动事件、公共事件、全局商店),并跳出所在的【最内层】循环(V2.7.3起支持指定跳出层数)。如果不在任何循环中,则什么也不做。大致相当于js的`break;`
+7. **提前结束本轮循环:**生效范围同上,不过是结束最内层的【本轮】循环。换言之:
+ * 对一般的前/后置条件循环会立刻跳转到下次检测条件前;
+ * 对循环遍历(计数)会立刻跳转到下次计算边界和步增并累加前;
* 对循环遍历(迭代)会立刻跳转到下次检查列表是否为空前。
* 还可用来“重启新版商店或道具商店”。若不在任何循环中,则什么也不做。
- * 大致等价于js的`continue;`
+ * 大致相当于js的`continue;`,V2.7.3起支持指定层数。
8. **立刻结束当前事件:**此指令将清空临时变量(以`@temp@`开头)和参数变量(`arg+纯数字`),清空事件列表,中断一切事件处理,恢复勇士行动。
-9. **触发系统事件:**模拟勇士撞击/踩踏本楼层的某个点,把触发的事件(包括图块属性的`script`,不包括阻激夹域捕和血网)插队到当前事件列表中。支持双击地图选点。
- * 譬如该点是道具则会捡起来,是怪物则会强制战斗,是门则会尝试开门,
- * 还会连带触发对应的`afterXxx`事件。实际执行`core.trigger(x, y, callback)`
- * 如果该点是楼梯则会直接触发传送(目标点是“保持不变”或三种对称点也以勇士位置而不是楼梯位置计算),是路障则会触发对应的毒衰咒(血网除外)。是踩灯则会把勇士脚下变成踩过的灯,是普通事件(红)则会触发。滑冰在背景层,所以无法触发。至于推箱子...请自行探索。
+ * V2.8起,您可以在两种“战前事件”中使用它取消战斗。
+9. **触发系统事件:**模拟勇士撞击/踩踏本楼层的某个点(实际执行`core.trigger(x, y, callback)`),支持双击从地图选点。
+ * 该指令把触发的事件(包括图块属性的“碰触脚本/碰触事件”,不包括阻激夹域捕捉和血网)插队到当前事件列表中。
+ * 譬如该点是道具则会捡起来,是怪物则会触发战前事件然后战斗,是门则会尝试开门,还会连带触发对应的`afterXxx`事件。
+ * 如果该点是普通事件(红)则会触发之,是楼梯事件(绿)则会直接触发传送(目标点是“保持不变”或三种对称点也以勇士位置而不是楼梯位置计算)。
+ * 该点是路障则会触发对应的毒衰咒(血网除外),是踩灯则会把勇士脚下变成踩过的灯。滑冰在背景层,所以无法触发。至于推箱子,请自行探索。
+ * V2.8起,您可以使用“强制战斗(定点)”指令跳过战前事件强制与地图上某个点的怪物战斗,也可以用“触发系统事件”指令指定某个有怪物的点然后先触发战前事件再战斗,请注意区分。
10. **插入公共事件:**如题,“参数列表”为一数组,其各项会被依次代入值块`变量:arg1`、`变量:arg2`...而`变量:arg0`会记录公共事件的名称。
* 实际执行`core.insertCommonEvent(name, args, x, y, callback, addToLast)`
-11. **插入事件:**此指令可以无视目标点启用与否,跨楼层插入任何点的普通事件或afterXxx事件执行。支持双击地图选点。
+11. **插入事件:**此指令可以无视目标点启用与否,跨楼层插入任何点的普通事件(不需要覆盖触发器)、战前事件、afterXxx事件执行。支持双击从地图选点。
## 特效声音类(褐色)

-这个类别的指令会负责动画、视角、色调、天气、音频等其他一些细节。
+这个类别的指令会负责动画、视角、色调、天气、音频、存读档等其他一些细节。
-1. **画面震动:**会让画面左右震动。
- * 实际执行`core.vibrate(direction, time, speed, pwoer, callback)`函数。
+1. **画面震动:**会让画面震动,可以选择四种振动方向,可以指定总时间、震动速度和振幅。
+ * 实际执行`core.vibrate(direction, time, speed, power, callback)`函数。
2. **显示动画:**如题,可以双击选文件并预览(预览的坐标锁定为视野中心)和试听/修改音效。
- * 如需从地图选点请右击指令块,坐标也可写hero令动画跟随勇士移动。
+ * 如需从地图选点请右击指令块,也可用另一个指令让动画跟随勇士移动。
* 坐标不写则取当前点,如果勾选“相对窗口坐标”则坐标应填写为0—12或0—14表示视野中的相对坐标(如13×13样板填两个6表示视野中心)。
- * 另外,即使勾选了“不等待执行完毕”,此指令也不会被视为通常意义上的异步事件,换言之没有其他异步事件的风险。
- * 如果不勾选“不等待执行完毕”,则等待的实际时长只取决于动画,和音效无关(同时开播)。
+ * 另外,即使勾选了“不等待执行完毕”,此指令(以及V2.8起“等待播放完毕”的音效)也不会被视为通常意义上的异步事件,换言之没有其他异步事件的风险(当然,也就不会被“等待所有异步事件执行完毕”所等待)。
+ * 如果不勾选“不等待执行完毕”,则等待的实际时长只取决于动画,和音效无关。
* 实际调用`core.drawAnimate(name, x, y, alignWindow, callback)`和`core.drawHeroAnimate(name, callback)`
-3. **设置和移动视角:**设置视角支持双击从地图选点,不填坐标则重置视角。
- * 移动视角的动画时间为每动一格的时间,步伐数组只支持“上下左右”。
+3. **设置视角:**设置视角支持双击从地图选点,不填坐标则重置视角。动画时间指移动的总时间,支持四种变速移动。
+ * 勇士的`status:animate`为`true`(原地抖动开启)时,禁止使用本指令!
+ * V2.7.3起,坐标支持写增量,如[4,-2]表示视角直线移动到向右4格、向上2格的位置。
* 请注意,勇士重绘时(`core.drawHero()`函数)视角也会随之重置。所以视角变化后勇士的坐标、朝向、显隐、行走图(事件和API都提供了不重绘参数)和跟随者情况暂时都不要动。
* 实际调用`core.setViewport(x, y)`和`core.moveViewport(x, y, moveMode, time, callback)`,其中前者的自变量为【像素坐标】且不必为32的倍数,必要时可作为原生js使用来实现特殊的演出。
4. **显隐状态栏:**如题,如果隐藏状态栏期间勇士需要恢复行动,则建议不隐藏竖屏工具栏以方便手机玩家。
@@ -468,37 +559,40 @@ core.insertAction({"type": "changeFloor", "floorId": "MT" + core.rand2(20)})
5. **显隐勇士:**如题,动画时间为淡入淡出时间,异步勾选框用法如前。
* 实际调用`core.triggerHero(type, time, callback)`
6. **更改画面色调:**色调可以用调色器调配,“动画时间”为渐变的总时间。
- * 请注意渐变是在RGBA颜色空间中匀速直线运动,因此效果可能不好,画面闪烁同理。
-7. **恢复画面色调:**指将更改后的色调恢复到楼层的默认色调。
+ * 请注意渐变是在RGBA颜色空间中匀速直线运动(V2.8.1可能加入加速度),因此效果可能不好,画面闪烁同理。
+7. **恢复画面色调:**指将更改后的色调恢复到楼层的默认色调,更改当前层的默认色调后您可以使用此指令刷新。
8. **画面闪烁:**“单次时间”必须为3的倍数,前1/3时间用于将画面色调转变为目标色调,后2/3时间用于恢复当前色调,执行次数如题。
* 实际调用`screenFlash(color, time, times, callback)`
-9. **更改天气:**如题,可以选择“无、雨、雪、雾”之一,强度需填小于等于10的正整数。
-10. **播放背景音乐:**如题,可以双击选文件并试听,并指定开始播放的秒数。
- * 如前所述,当在游戏中触发楼层切换时(包括读档),如果`flag:__color__、flag:__weather__、flag:__bgm__`这三个值块没有值,游戏当时的画面色调、天气、背景音乐就会变为楼层属性中的这三个设置项。
+9. **更改天气:**如题,可以选择“无、雨、雪、雾、晴”之一,强度需填小于等于10的正整数。
+10. **播放背景音乐:**如题,可以双击选文件并试听(支持别名),并指定开始播放的秒数。
+ * 当在游戏中触发楼层切换时(包括读档),如果`flag:__color__、flag:__weather__、flag:__bgm__`这三个值块没有值,游戏当时的画面色调、天气、背景音乐就会变为楼层属性中的这三个设置项。
* 以上几个指令都提供了“持续到下个本事件”勾选框,勾选后,本次设置的值将会计入这三个值块。它们的拦截行为在“脚本编辑——切换楼层中”。
* 若不勾选,或恢复画面色调、设置天气为无(晴),就会清除对应的值块。您也可以随时对这三个值块进行手动干预。
11. **暂停和恢复背景音乐:**如题,暂停时会记录暂停在了第几秒,恢复时可以选择从这个秒数继续或从头重播。
12. **预加载背景音乐和释放其缓存:**在线游戏使用,前者的原理是静音播放。
- * 最多同时缓存四首背景音乐(由`libs/core.js`控制),会自动释放最久未使用的,但您也可以手动释放。
-13. **播放音效和停止所有音效:**如题,开播一个音效的同时可以停止其他的。
+ * 最多同时缓存8首背景音乐(由`libs/core.js`控制),会自动释放最久未使用的,但您也可以手动释放。
+13. **播放音效和停止所有音效:**如题,开播一个音效的同时可以停止其他的。V2.8播放系统音效可以从下拉框选取,其他音效也支持使用别名。
+ * V2.8起,播放音效支持同时“变调且变速”,100表示正常速度和音调,可以填30到300之间的值。
+ * V2.8起,音效支持“等待播放完毕”,但它仍然不算异步事件,所以可以被Ctrl跳过,不会被“等待所有异步事件执行完毕”所等待。
14. **设置音量:**只对背景音乐有效,音量为小于等于100的自然数(玩家设置值其实被开了平方),渐变时间如题。
-15. **呼出怪物手册和SL界面:**
+15. **设置背景音乐播放速度和音调:**V2.8新增,需要填30到300之间的值。100表示正常速度和音调,可以只改变速度(RPG Maker做不到哦),也可以同时改变速度和音调。
+16. **呼出怪物手册和SL界面:**
* 呼出手册只在勇士持有手册时生效,关闭手册后事件继续。
- * 呼出存档界面最多只能存一个档然后事件继续(读档后事件现场会恢复)
- * 呼出读档界面如果不读档则事件继续,录像回放中这组指令被忽略。
-16. **自动存档:**读档后也会恢复事件现场,录像回放中会照常存档。
- * 如不勾选“不提示”则会core.drawTip(“已自动存档”),此指令一般用于选择项/确认框之前。
+ * 呼出存档界面最多只能存一个档然后事件继续(读档后事件现场会恢复)。
+ * 呼出读档界面如果不读档则事件继续,录像回放中这三条指令都被忽略。
+17. **自动存档:**读档后也会恢复事件现场,录像回放中会照常存档。
+ * 如不勾选“不提示”则会`core.drawTip(“已自动存档”)`(即使在下面禁止的情况下!),此指令一般用于选择项/确认框之前。
+18. **是否禁止存档:**该项允许暂时禁止玩家存档(包括任何自动存档,不包括上面的呼出存档界面),从而做出RPG中常见的“迷宫中只有特定位置可以存档,或者必须消耗道具进行存档”的效果。
## UI绘制类(瞬间)

-这个类别的指令全部是瞬间完成的,有一一对应的API,请放心使用,除“绘制多行文本”外都可以逐个双击预览。游戏中,这些指令都是画在uievent层的。
+这个类别的指令全部是瞬间完成的,有一一对应的API,请放心使用,除“绘制多行文本”外都可以逐个双击预览(多行文本需要右击预览)。游戏中,这些指令都是画在`uievent`层的。
-1. **UI绘制并预览:**您可以把一堆UI绘制类指令塞进去然后双击黄框整体预览
- * 请注意,“绘制多行文本”双击是多行编辑,必须塞到这里才能预览。
-2. **清除画布:**擦除uievent层的一部分,x和y为左上角坐标。
- * 四个参数都支持使用表达式,任何一个参数不填都会删除整个uievent层。
+1. **UI绘制并预览:**您可以把一堆UI绘制类指令塞进去然后双击黄框整体预览。
+2. **清除画布:**擦除`uievent`层的一部分,x和y为左上角坐标。
+ * 四个参数都支持使用表达式,任何一个参数不填都会删除整个`uievent`层。
* 实际调用`core.clearMap("uievent",x,y,width,height)`和`core.deleteCanvas("uievent")`,熟练后对其他画布使用也是可以的。
3. **设置画布属性:**
1. 字体:`italic和bold`表示斜体和加粗,可省略,字号和字体用于绘制文本。
@@ -510,24 +604,25 @@ core.insertAction({"type": "changeFloor", "floorId": "MT" + core.rand2(20)})
7. 基准线:绘制单行文本的基准线,有六种写法。绘制单行文本的坐标其实是文本的基准点,
8. z值:初始为135,z值较大的画布将覆盖较小的,详见“个性化”。闪烁光标的z值总是比上述的值大1,即默认为136.
4. **绘制文本:**
- * 这里仅绘制单行文化单行,坐标为基准点的像素坐标,需配合上述“对齐”和“基准线”使用。
+ * 这里仅绘制单行文本,坐标为基准点的像素坐标,需配合上述“对齐”和“基准线”使用。
* 如果设置了最大宽度,那么在超出此宽度时就会保持比例压缩到这个宽度。
- * 正文只支持`${js表达式求值}`,不支持其他一切转义序列,更不能手动换行。
+ * 正文只支持`${js表达式求值}`和`\r[变色]`,不支持其他一切转义序列,更不能手动换行。
* 实际执行`core.fillText("uievent", text, x, y, style, font, maxWidth)`
5. **绘制描边文本:**同上,但不支持限宽,描边效果同状态栏数字的黑边。
- * 实际原理是向四个方向各偏移1px以描边色绘制了四份一样的文本,中央再以文本色覆盖一份。
- * 本指令对应的`js函数为core.ui.fillBoldText('uievent', text, x, y, style, font)`
-6. **绘制多行文本:**双击进入多行编辑,预览请塞进黄框。
+ * 底层实现为`ctx.strokeText()`,描边颜色可以自己指定。
+ * 本指令对应的js函数为`core.ui.fillBoldText('uievent', text, x, y, style, font)`
+6. **绘制多行文本:**双击进入多行编辑,预览请右击。
* 起点像素为左上角,只有设置了最大行宽才会对齐、居中和自动换行。
* 如果不设置颜色和字号,就会采用“设置剧情文本的属性”中的正文设置。
* 不设置行距就会采用字体大小的1.3倍,建议采用偶数字号和1.5倍行距。
* 多行文本不支持字体样式的设置,使用的是全塔属性中的全局字体`Verdana`,
* 如有需要,请使用“设置全局属性”指令来设置字体样式。
-7. **绘制几何图形:**对应的`js函数为core.ui.fillXxx()和core.ui.strokeXxx()`
-8. **绘制图片:**同“显示图片”指令但功能有出入,比如这个支持旋转。实际执行`core.drawImage('uievent',img,x,y,w,h,x1,y1,w1,h1)`
+7. **绘制几何图形:**对应的js函数为`core.ui.fillXxx()`和`core.ui.strokeXxx()`
+8. **绘制图片:**同“显示图片”指令但功能有出入,实际执行`core.drawImage('uievent',img,x,y,w,h,x1,y1,w1,h1)`
9. **绘制图标:**支持图块id和系统图标,支持伸缩和选择哪一帧。支持32×32和32×48两种尺寸,实际执行`core.drawIcon(name, id, x, y, w, h, frame)`
-10. **绘制背景图:**背景色支持颜色数组,也支持类似`winskin.png`的图片名。使用图片时不透明度,纯色背景时的边框颜色,由“设置画布属性”指定。本指令对应的`js函数为core.ui.drawBackground(left, top, right, bottom, posInfo)`
+10. **绘制背景图:**背景色支持颜色数组,也支持类似`winskin.png`的图片名。使用图片时的不透明度以及纯色背景时的边框颜色,由“设置画布属性”指定。本指令对应的js函数为`core.ui.drawBackground(left, top, right, bottom, posInfo)`
11. **绘制和清除闪烁光标:**如题,光标的z值总是比`uievent`层大1.
+12. **设置画布特效:**V2.8新增,允许给画布设置像图块一样的“虚化、色相、灰度、反色、阴影”属性。
==========================================================================================
diff --git a/_docs/personalization.md b/_docs/personalization.md
index 2a552e91..8618a56c 100644
--- a/_docs/personalization.md
+++ b/_docs/personalization.md
@@ -57,21 +57,21 @@ core.fillText('test', '这是一段文字', 10, 30, '#FF0000', '16px Verdana');
## 单点多事件
-带有独立开关的商人算是一个最为简单的单点多事件的例子了,单点多事件最常用的指令就是“转变图块”(或关门)和“条件分歧”。下面以几个具体例子来进行详细说明:
+带有独立开关的商人算是一个最为简单的单点多事件的例子了(提供在了事件编辑器左侧的“常用事件模板”),单点多事件最常用的指令就是“转变图块”(或关门)和“条件分歧”。下面以几个具体例子来进行详细说明:
1. 打怪变成门或道具、开门变成怪或道具:怪物、门、道具都是系统触发器,直接利用afterXxx事件。如:
* 战后事件:关门`yellowDoor`(原地关上了一扇黄门)
* 战后事件:转变图块为`yellowKey`(怪物掉落了黄钥匙)
* 开门后事件:转变图块为`greenSlime`或`yellowKey`(开门变成了史莱姆或黄钥匙)
* 打怪变成别的怪、开门关上别的门、门和怪来回变的,用独立开关计数。
- * 如有批量需求,请使用“脚本编辑 - `afterXxx`函数。
+ * 如有批量需求,请使用“脚本编辑 - `afterXxx`函数或怪物的(批量)战前/战后事件。
2. 打怪/开门/捡道具后变成传送点或npc:
* 这时的传送点就不能用“楼梯、传送门”事件了,而应该用只有一条“场景切换”指令的普通事件。
* 此事件不勾选“覆盖触发器”,这样怪物、门和道具的系统触发器会触发。
- * 在对应的afterXxx事件中“转变图块为”传送点或npc,淡入效果更佳哦。
+ * 在对应的`afterXxx`事件中“转变图块为”传送点或npc,淡入效果更佳哦。
* 请注意,因为道具是可通行的,如果勇士走到道具上,就会和npc重合。
3. (懒人的选择)利用`图块类别:x,y`和`图块ID:x,y`等值块集中处理:
* 如果您实在搞不清楚“覆盖触发器”和“通行状态”这两项,那就干脆勾选前者并把后者设为不可通行,本希望可以通行的场合就得用“无视地形移动勇士”指令前进一步。
- * 用自动事件去转变图块,然后利用上述两个值块判定当前图块的状态等,再用`强制战斗`、`开门(需要钥匙)`和`增加道具`分别处理吧。
+ * 用自动事件去转变图块,然后利用上述两个值块判定当前图块的状态等,再用“强制战斗”、“开门(需要钥匙)”和“增加道具”分别处理吧。
## 并行脚本:即时制的希望?
@@ -83,7 +83,7 @@ core.fillText('test', '这是一段文字', 10, 30, '#FF0000', '16px Verdana');
js语言其实是没有多线程的,但我们可以写一些浏览器帧刷新时执行的脚本,也就是“并行脚本”。
-并行脚本分为两种,全塔并行和楼层并行。前者在“脚本编辑—并行脚本”,后者在楼层属性。一般来说,当您有多个楼层需要执行相同的并行脚本时,建议写在前者并通过对core.status.floorId的范围进行判定来决定具体执行的内容。
+并行脚本分为两种,全塔并行和楼层并行。前者在“脚本编辑—并行脚本”,后者在楼层属性。一般来说,当您有多个楼层需要执行相同的并行脚本时,建议写在前者并通过对`core.status.floorId`的范围进行判定(注意判空!)来决定具体执行的内容。
并行脚本将被系统反复执行,执行的时机是“浏览器帧刷新”,换言之相邻两次执行的间隔取决于浏览器或设备的性能,上限为60fps即每秒60次。
@@ -94,7 +94,7 @@ if (core.hasFlag('frame')) {
// 剧情事件中将“变量:frame”设为正整数来开启bgs,设为0来关闭
core.status.hero.flags.frame %= 60000; // 防止挂机太久导致溢出
if (core.getFlag('frame', 0) % 60 === 0)
- core.playSound('heartBeat.wav'); // 每60帧即1秒播放一次
+ core.playSound('heartBeat.mp3'); // 每60帧即1秒播放一次,还可以指定音调。
core.status.hero.flags.frame++; // 帧数加1
} // 其他特效也是一样的用法。
```
@@ -147,7 +147,11 @@ case 89: // 使用该按键的keyCode,比如Y键就是89
!> 如果记录了按键,且使用道具的话,需要将useItem的第二个参数设为true,避免重复记录!
-可以使用altKey来判断Alt键是否被同时按下。
+可以使用`altKey`来判断Alt键是否被同时按下(V2.8起,手机端的Alt键以粘滞键方式提供)。
+
+## 左手模式
+
+V2.7.3起,样板面向玩家提供了“左手模式”,可在ESC菜单中开启。开启后,wsad将用于勇士移动,ijkl将代替原本wsad的功能(存读档等)。
## 插件系统
@@ -180,13 +184,15 @@ this.myfunc = function(x) {
从V2.5.3以后,我们可以给手机端增加按键了,这样将非常有利于技能的释放。
-用户在菜单栏打开“拓展键盘”后,在竖屏模式下点击工具栏,就会在工具栏按钮和快捷键模式之间进行切换。
+用户在竖屏模式下点击难度标签,就会在工具栏按钮和快捷键模式之间进行切换。
-切换到快捷键模式后,可以点1-8,分别等价于在电脑端按键1-8。
+切换到快捷键模式后,可以点1-7,分别等价于在电脑端按键1-7。
-可以在脚本编辑的onKeyUp中定义每个快捷键的使用效果,比如使用道具或释放技能等。
+V2.8起,点击最后的A键则相当于电脑端按下/松开Alt键(即粘滞键),可以用来快捷换装。
-默认值下,1使用破,2使用炸,3使用飞,4使用其他存在的道具,5读取上一个自动存档,6读取下一个自动存档,7轻按,8未定义。可以相应修改成自己的效果。
+可以在脚本编辑的`onKeyUp`中定义每个快捷键的使用效果,比如使用道具或释放技能等。
+
+默认值下,1使用破,2使用炸,3使用飞,4使用其他存在的道具,5读取上一个自动存档,6读取下一个自动存档,7轻按。可以相应修改成自己的效果。
也可以替换icons.png中的对应图标,以及修改main.js中`main.statusBar.image.btn1~8`中的onclick事件来自定义按钮和对应按键。
@@ -196,7 +202,7 @@ this.myfunc = function(x) {
从V2.5.3开始允许自绘状态栏。要自绘状态栏,则应该打开全塔属性中的`statusCanvas`开关。
-自绘模式下,全塔属性中的`statusCanvasRowsOnMobile`将控制竖屏模式下的状态栏行数。
+自绘模式下,全塔属性中的`statusCanvasRowsOnMobile`将控制竖屏模式下的状态栏行数(下面的`rows`)。
开启自绘模式后,可以在脚本编辑的`drawStatusBar`中自行进行绘制。
@@ -208,7 +214,7 @@ this.myfunc = function(x) {
## 自定义状态栏的显示项
-在V2.2以后,我们可以自定义状态栏背景图(全塔属性 - statusLeftBackground)等等。
+在V2.2以后,我们可以自定义状态栏背景图(全塔属性 - 主样式)等等。
但是,如果我们还想新增其他项目的显示,比如攻速或者暴击,该怎么办?
@@ -264,7 +270,7 @@ core.setStatusBarInnerHTML('speed', core.getStatus('speed'));
// 设置其显示内容为flag:speed值,无需额外进行定义。
core.setStatusBarInnerHTML('speed', core.getFlag('speed', 0));
```
-总的来说不建议这样做,因为 `main.js` 和 `html` 文件不在 `project` 文件夹,会导致随样板更新迁移接档变得困难。
+总的来说不建议这样做,因为`main.js`和各种html文件不在`project`文件夹,会导致随样板更新迁移接档变得困难。
## 技能塔的支持
@@ -289,7 +295,7 @@ core.setStatusBarInnerHTML('speed', core.getFlag('speed', 0));
从V2.5开始,魔力值和技能名的状态栏项目已经被添加,可以直接使用。
-在脚本编辑-updateStatusBar中,可以对状态栏显示内容进行修改。
+在脚本编辑-updateStatusBar中,可以对状态栏显示内容进行修改。带有上限时如果一行放不下,可以想办法像生命一样拆成两行。
``` js
// 设置魔力值; status:manamax 只有在非负时才生效。
@@ -337,6 +343,8 @@ else { // 关闭技能
该(技能)道具任何时候都可被使用;使用时,判断当前是否开启了技能,如果开启则关闭,没开则再判断是否允许开启(魔力值够不够等)。
+V2.6.6起,道具提供了`useItemEvent`项,建议使用它而不是上面的脚本。'-
+
#### 快捷键触发技能
在PC端,我们还可以按键触发技能。
@@ -355,7 +363,7 @@ case 70: // F:开启技能“二倍斩”
```
在勇士处于停止的条件下,按下 `F` 键时,判断技能的道具是否存在,如果存在再使用它。
-!> 由于现在手机端存在拓展键盘,也强烈建议直接覆盖1-8的使用效果,这样手机端使用也非常方便。
+!> 由于现在手机端存在拓展键盘,也强烈建议直接覆盖1-7的使用效果,这样手机端使用也非常方便。
### 技能的效果
@@ -397,7 +405,7 @@ if (core.flags.statusBarItems.indexOf('enableSkill')>=0) {
}
```
-!> 开启技能后,建议将全塔属性的useLoop置为true,即改用循环计算临界值,这样临界计算才不会出问题!
+!> 开启技能后,建议将全塔属性的`useLoop`置为`true`,即改用循环计算临界值,这样临界计算才不会出问题!
diff --git a/_docs/script.md b/_docs/script.md
index fe42f408..3ba53acd 100644
--- a/_docs/script.md
+++ b/_docs/script.md
@@ -571,7 +571,7 @@ func: 可以是一个函数,或者是插件中的函数名;可以接受obj
- 不方便能整理成新的插件在别的塔使用(总不能让别的塔也去修改libs吧)
- ……
-好消息的是,从V2.6开始,我们再也不需要开文件了,而是可以直接在插件中对原始函数进行复写。
+好消息是,从V2.6开始,我们再也不需要开文件了,而是可以直接在插件中对原始函数进行复写。
函数复写的好处如下:
diff --git a/_docs/start.md b/_docs/start.md
index 2cf79ce3..c42c260c 100644
--- a/_docs/start.md
+++ b/_docs/start.md
@@ -8,7 +8,7 @@
- Win8或更高版本,Win7则需要安装 .Net Framework
4.0(能打开根目录的“启动服务.exe”即可)
- 其他电脑则需安装[python
- 3.8.3](https://www.python.org/downloads/)或更高版本,能运行根目录的server.py即可(Windows也可以这样做)。
+ 3.9.6](https://www.python.org/downloads/)或更高版本,能运行根目录的server.py即可(Windows也可以这样做)。
- 安卓手机需要安装[HTML5安卓造塔器](http://h5mota.com/games/_client/H5motaMaker.apk),推荐搭配ES文件浏览器。
2. [chrome浏览器](http://google.cn/chrome):其他浏览器可能导致本地服务闪退。
3. (强烈推荐)[VScode](http://code.visualstudio.com/download):最适合HTML5项目的文本编辑器,能进行跨文件的正则搜索和替换,也能完整发挥根目录的runtime.d.ts文件的作用。
@@ -28,7 +28,7 @@
以下为Windows专用的一些辅助工具(位于“辅助工具”文件夹),由C#编写:
-* 便捷PS工具:能方便地替换和新增素材。
+* 便捷PS工具:能方便地替换和新增32*32、32*48素材。
* 地图生成器:识别RPG Maker魔塔的地图截图,生成HTML5魔塔的地图数据。
* 怪物数据导出:从RPG Maker XP 1.03游戏导出怪物数据,用于HTML5魔塔或使用excel查看。
* RM动画导出:从RPG Maker XP 1.03游戏导出动画,用于HTML5魔塔。
@@ -39,6 +39,12 @@
!> **整个造塔过程中,启动服务必须全程处于开启状态!切不可手滑关闭,否则做的都是无用功!**
+
+
+V2.7.x中,“地图生成器”因为图片文件被拆分到两个文件夹的缘故而无法再使用,该问题已在V2.8中修复,同时该工具更名为“截图识别器”。
+
+V2.8中,“额外素材合并”不再在本地进行而是改在作品发布时在服务器端用python实现,并把实现原理改为“将未用到的图块透明化后,全图裁剪到可能的最小尺寸”,以避免图块id错乱的问题。
+
## 编辑器页面的结构

@@ -61,7 +67,7 @@
针对红海塔作者,这里给出一个极简版的造塔流程,您可以据此造出一座没有任何事件(包括但不限于难度分歧、老人、木牌、商人和商店等)的塔:
1. 编辑勇士的出生点和初始属性:
1. 滚轮切换到主塔0层,右击地图任意位置,绑定出生点为此点(会有一个大大的白色S字母显示出来)。
- 2. 按下B键切换到“全塔属性”,填写core.firstData.hero中勇士的各项初始属性,以及一些全局的数值(如四种血瓶和三种宝石的效果、破甲反击净化的比例等,注意“唯一英文标识符”一定要修改!)。
+ 2. 按下B键切换到“全塔属性”,填写core.firstData.hero中勇士的各项初始属性,以及一些全局的数值(如四种血瓶和三种宝石的效果、破甲反击净化的比例等,注意“唯一英文标识符”name一定要修改!)。
3. 在数据区使用滚轮向下翻(您可以随时折叠全塔属性的几大部分),按需编辑下面的大量勾选框(主要就是状态栏的那些显示项)。
2. 从素材区选择各种各样的非NPC图块绘制在地图上,如门、怪物、道具、楼梯、路障、箭头、踩灯、箱子等。每当选中一个素材时,数据区就进入了“图块属性”模式,您可以去填写道具的一些说明、以及修改其他一些图块的可通行性等。注意滑冰(触发器为ski)要画在背景层。如果您需要制作机关门,请简单地将机关门和守卫(不支持阻击怪和炸弹)画在地图上,再右击机关门快速绑定即可。(看到机关门左下角出现橙色小方块、守卫们左下角出现黄色小方块即说明绑定成功)
3. 如果您需要制作多个楼层,只需按下Z键将数据区切换到“地图编辑”模式,然后“新建空白地图”即可,不同楼层之间简单地通过楼梯来往返,您可以将楼梯画在地图上再右击快速绑定即可。(看到楼梯左下角出现绿色小方块即说明绑定成功)各个楼层的属性可以通过按下V键将数据区切换到“楼层属性”模式来填写,如能否使用楼传、是否为地下层、画面色调、宝石血瓶倍率等。