跳到主要内容

RMMZ的脚本基础

原文:『RPGツクールMZ』スクリプトの使い方基礎

RMMZ是使用JavaScript开发的。

通常情况下,不用在意这点,只要使用编辑器中的事件指令就能开发游戏。

但总有些细节,是事件命令无法顾及的,而且也找不到能解决这些问题的插件。

这种时候,使用脚本,写一点js,就能解决很多问题。

另外……在移动路线设置中没有插件指令,所以有时候不得已也会使用脚本,唉唉。

官方帮助的功能说明中,只说到了“将文本作为js进行求值(执行)”。

但光这么写谁懂啊!!

因此,这里来写一些使用脚本的基础知识。

既然要写js,按理说学习js本身就好了,但要到这一步就有点……毕竟有些人“并不是想当程序员”。

面向这类读者,跳过那些js入门书里的内容,希望能达到“直接复制粘贴,然后修改一下看起来差不多的数字”这种程度。

想学习js本身的人,请参考以下教程!

信息

介绍脚本的页面上写着“可以轻松扩展事件指令”“比插件更轻便”之类的话,本文开头也写了这些,但实际上使用脚本的门槛相当高。

虽然可以在什么都不懂的情况下复制粘贴来使用,但即使如此,什么都不知道的话也还是会有些心里没底。

为了能在使用脚本的时候更有底气,让大家达到”复制粘贴+改造“的程度,接下来我会写出在使用脚本时会遇到的难点。

参考的脚本集

由于不少地方都公开了许多方便的脚本示例,所以脚本就从示例集拿来用吧。

这篇文章针对rmmz,不过也姑且准备了指向写有rmmv脚本的页面链接。

敬称略

关于著作权

别人写的程序,复制过来用真的可以吗?真的不会在意吗。

在意这一点的人,好眼光!请珍视这份心态,不要随意使用他人作品!

那么来说说脚本。

俳句都能被认可拥有著作权,所以你会感到不安。但仅仅几行的程序就能主张著作权的例子,目前我还没有听说过。

通常,它们会被认为“只是一段信息,而不是表达思想情感之类的创作”。

特别是先前链接的页面,它们就是以“前提就是复制使用”的方式公开的,所以请大胆地复制粘贴吧。

发布游戏时,不标注著作权信息也可以,不过如果在特别致谢加上脚本集作者名,感觉会更有面子,我也觉得这样不错。

毕竟一个人开发的话,结尾的制作人员名单会显得很冷清呢。(笑)

顺带一提,即使是范例集,如果把整个页面复制下来公开,果然也还是不行的。

另外,像插件那样公开脚本时,如果被人提问却答不上来会急得冒汗,所以参考别人的代码时,也要好好理解后再去做!

此外,明明是自己写的脚本,却答不上别人的提问,这种事也相当常见(笑)

脚本集的使用方法

复制脚本,粘贴,然后改一下。

最开始的时候,就算看不懂什么意思,抱着“能跑起来就算成功”的心态去用,我觉得也没问题。

能贴脚本的地方意外的多,大致可以分为“有返回值”和“无返回值”两种类型。

返回值有时也可以直接写成“结果”。

那么基于以上前提,我来介绍一下可以写脚本的地方。

事件命令

首先在地图事件,或者公共事件的执行内容中,或者从敌群的战斗事件中打开的事件命令窗口中,有一个直截了当就叫脚本的按钮。

img

[3]-[进阶]-[脚本]

img

这里就是按下脚本后出现的窗口,在这里写js,或者直接把代码贴进去。

顺带一提,里面的alert("Hello World");是我随便写的js代码,窗口中央所显示的是右键菜单。

之后我会把它写作[脚本]事件指令。

这个指令没有返回值。

设定移动路线

接下来是地图事件或公共事件中的移动路线设定,这里面也有脚本命令。

img

[2]-[移动]-[设定移动路线]

img

[移动命令]-[脚本]

img

虽然看起来很小,但功能和脚本时间命令基本一样,也能打开右键菜单。

之后我会把它写作[脚本]移动命令。

没有返回值。

自定义移动路线

接下来是地图事件的自主移动的脚本。

img选择[自主移动]-[类型]-[自定义]出现[路线]

img

和设置移动路线事件命令里的脚本基本一样,最大的区别就是不能指定左上角的目标角色。

之后我会称其为[脚本]移动指令。

咦,这不是和之前那个一样吗?

确实。

只在必要时候我会写成自主移动的脚本。

没有返回值。

变量操作

接下来在地图事件、公共事件或战斗事件里打开事件命令,找到变量操作,里面也有脚本。

img

[1]-[游戏进程]-[变量操作]

img

[操作数]-[脚本]

之后,我会称其为变量的脚本。

它有返回值,会把返回值设置到你指定的变量里。

条件分岐

最后在地图事件、公共事件或战斗事件打开事件指令窗口,里面也有脚本

img

[1]-[流程控制]-[条件分岐]

img

[4]-[脚本] 之后我会称其为条件的脚本。

它有返回值,会根据返回值来进行条件分歧。

计算公式

好吧,其实还有一个!

实际上,伤害公式那里就是js。

可以直接用已经自带值的a和b。另外,虽然不是js功能,但作为计算公式特有的功能,还可以把v[n]当变量来用。

它有返回值,会作为伤害数值来使用。

那么到此结束!

去逛逛我介绍的那些网站,然后找些有趣的脚本复制粘贴玩玩吧!

话虽如此,虽然在这可以结束了,但这次的文章,从这里开始才是重头戏。


为了为今后进一步扩大适用范围做个铺垫,我会适当加上rmmz 非官方js参考的链接,不过没必要一个个去翻看。

等你把这页从头到尾读一遍,对写脚本有了一定程度的习惯后,再去看那个参考手册比较好。

另外,我觉得很多地方不达到一定的熟练度是看不懂的,所以跳着读就行了。

关于脚本写法中那些让人在意的细节

看各个地方的脚本时,会发现虽然说明差不多,但写法上却有微妙的差别。

我觉得如果不讲清楚,有些人可能会不安,所以我来解释一下几个典型的地方。

字母的大小写

js是严格区分字母大小写的! 所以 aA 是两个不同的东西。 虽然标识符的大小写不同不会带来功能上的差异,但在js里,作为一种书写惯例,大致有以下几种:

标识符示例说明用途
SampleValue首字母大写,后面用大写字母分隔单词类(class)
sampleValue首字母小写,后面用大写字母分隔单词变量、函数、属性、方法、以及会被赋予可变值的常量
SAMPLE_VALUE全部大写,用下划线分隔单词被赋予固定值(字面量)的常量

这些“用途”是什么意思看不懂也没关系,总之它们全都是不同的东西,所以要注意别打错大小写。

果然最安心的办法还是“复制 & 粘贴”!

なおjs的にはとくにパターンというわけではないですが『RPGツクールMZ』では次のようなパターンがあります。

另外虽然从js本身来说并非固定的格式,但在rmmz中有如下写法:

标识符示例说明用途
Sample_Value首字母大写,用下划线分隔单词核心脚本里的类
_sampleValue下划线开头,后面首字母小写并用大写分隔单词类内部使用的属性
$sampleValue$ 符号开头,后面首字母小写并用大写分隔单词全局变量

关于这些的详细内容,我会在别的地方再解释。

关于脚本末尾的 ;

看各处介绍的脚本时,会发现有的末尾有 ;,有的没有。

你可能会担心“到底需不需要?没有行不行?”,但基本上是不需要的!

那么 ; 是什么呢?它是“用来分隔脚本的东西”。

而且写在脚本里的js都很短,所以大部分情况下没有分隔符也能正常运行。

反过来,像移动路线、条件分歧、计算式这些地方,通常只能写一行,但加上 ; 之后,就可以把多行“叠”在一起写。

如果有返回值的话,会返回最后一个分隔的结果。

比如在变量操作的脚本里写下下面这样,就会按 ; 的每个分隔顺序执行,并返回最后一个分隔的结果 20

const a = 4;a * a + a;

我个人经常写比较长的脚本,所以在那种情况下我都会加上 ;

写短脚本的时候我也会习惯性地加上,所以在这个页面里基本上都会带着 ; 来写!

结论:加上分号的话,看起来会比较像专业人士啦 ;(分号)

关于引号

首先,“クォーテーション”这玩意儿是啥啊!——话说回来,就是引号啦。就是用来括住台词之类的符号。

在js中,被引号括起来的部分会被解释为与程序代码不同的字符串数据。

而在脚本里出现的引号有三种。

值与操作功能
'单引号'用来括住字符串
"双引号"用来括住字符串
`反引号`用来括住字符串

……功能不是一样的嘛!好啦,你先冷静一下。

"想在文本中使用'单引号'"
'反过来"双引号"也想用'

就像这样,在遇到同一个引号之前,都会被认为是处于被括住的状态,所以就可以把另一种引号写在里面。

……为了这个而存在两种引号,是不是有点傻?你可能会这么想,但js它就是这样的设计啦!!

从编程的角度来说,想把程序代码本身当作字符串来写的情况也时有发生,这时候就方便了。

那么,rmmz游戏本体的脚本,我们称之为核心脚本

核心脚本中基本上使用的是 "(双引号),所以这里我也用 "

尽量把书写格式和核心脚本统一起来,这样在读核心脚本的时候就能没有违和感地读下去(很重要)。

话说回来,你是不是想问“那反引号呢?”!

厉害,你还真记住了。这是在js中后来才引入的方式,可以在字符串中间嵌入js的处理,也可以换行,是一种稍微高性能一点的引号。

`就像这样,可以嵌入编号 ${id},
也可以直接换行写出来。`

所以,如果把反引号改成双引号或单引号,可能会导致程序无法运行,请注意这一点。

反过来说,双引号和单引号是不能直接换行的,必须用 \n 这个特殊符号来表示换行。

顺便一提,你可能会问:truefalse 或者数字之类的,没有被引号括起来,这样没问题吗?

这些是和字符串不同类型的值,所以就直接写。就是这么回事。

反过来,如果像 "true" 这样用引号括起来,它就会被判断为字符串,然后导致程序无法运行……如果能立刻出问题倒还好,但它往往看起来好像还在正常运作,然后突然就出毛病。所以,没带引号的裸值就直接留着别动,绝对不要加引号!别好心办坏事,千万别加引号!!

关于注释

在js中,// 之后直到行末的字符都会被忽略。

这部分可以用来写各种注解,这就叫做注释。

还有用 /**/ 括起来的注释形式,不过我觉得在脚本示例中不太常用。

let a = 0;// 这部分是注释
console.log( a );/* 这部分也是注释
这里还可以换行! */

注释在执行时会被忽略,所以可以不复制,或者复制之后删掉也没关系。

当然,既然会被忽略,就那么留着也行,或者按自己的喜好随便改写里面的文字也可以。

关于脚本中的空白(空格)

脚本里各处都会出现空格,看起来好像有某种规律,但实际上每个脚本的写法都有微妙的不同。

其实并没有什么规律,全凭个人喜好加的!

大家通常都以为编程必须写得很严谨,所以这还挺让人吃惊的吧。

不过,单词(也就是所谓的标识符)中间是不能插入空格的。

func ( 12 + 1 , "文本" ) ;

即使把这里的空格去掉,写成下面这样,意思也是一样的。

func(12+1,"文字");

另外,全角空格不能用在脚本代码中。但可以用在字符串数据或者注释里面。

闲谈

就我个人而言,大概是这样的风格:「单词前后、逗号等分隔符号的后面、括号内侧、数学符号前后加空格」,以及「函数、方法、控制语句和 ( 之间不加空格」。

func( 12 + 1, "文本" );

说实话,这些地方其实都无所谓,但如果不事先定好,每次写的时候都会纠结“到底要不要加空格呢”,白白浪费时间,真的是纯属浪费。

程序员通常都会定好规则再写,多人协作的时候更是会统一规则(有时甚至是整个公司统一)。

在最近的开发环境中,大多都可以在设置里详细指定空格的添加方式,然后自动帮你格式化代码。真方便!

即使看不懂js,如果看一个插件的内容发现空格的用法没有一致性,那基本上可以断定它的js写法也很随意。

请用这个标准去判断插件的质量。至于我的插件嘛,“因为开发环境会自动整理,所以很整洁!”(笑)

关于方法、属性、数组和对象

……什么鬼?你肯定会这么想。

用脚本的时候,有时候会遇到明明在做类似的事情,写法却微妙地不一样的情况

$gameMessage._positionType = 2;
$gameMessage.setPositionType( 2 );

看起来这两行都想给 positionType 设置成 2,那这个区别使用到底是怎么回事呢?

另外括号也是,有用 [] 的,有用 () 的…完全搞不懂对吧。

这个解释起来非常麻烦,主要原因大概有两个:

  • 强行使用了没有设想会让用户去用的部分。
  • 本来就没有什么特别的理由,就是用了不同的写法。

我觉得rmmz在区分使用上算是比较没有条理的(个人感想)。

因为编程嘛,这方面不统一也能跑啊!它就是能跑起来!!

要说细节的话,也有那种“不这么写就不行”的场景,但解释起来又琐碎又长,我觉得也听不懂。

所以,这里的结论就是:“就当是那么回事吧,别太纠结了!” —— 就这么定了!!

因为存在叫做“方法”、“属性”、“数组”、“对象”的机制,各自的写法都不一样。

关于这些术语,你暂时先理解到“哦,有这种东西啊”这个程度就可以了。

等你想认真学js的时候,再去查吧。

关于 this

脚本里经常会出现 this 这个词,但要解释它到底是什么,还挺麻烦的。

净是些麻烦事儿呢。

仅限在rmmz的脚本里来说,它是一个根据你写脚本的位置不同,内容也会跟着变的变量。

脚本位置this 的值
事件指令Game_Interpreter
移动指令Game_PlayerGame_Event
变量操作Game_Interpreter
条件分支Game_Interpreter

Game_Interpreter 是处理事件指令的机制。

Game_Player 是 [玩家] 角色。

Game_Event 顾名思义就是 [事件]。

所以,即便是同一个 this,在不同位置也拥有完全不同的性质。

参考: Game_Interpreter

参考: Game_Player

参考: Game_Event

信息

具体来说就是,含有 this 的脚本如果写在别的位置,大概率是没法运行的。

因为会出现 “明明写的内容完全没错,可就是跑不起来” 的情况,所以很难找到原因。

请确认好脚本是给事件指令用的,还是给移动指令用的,然后再使用!

如果没有特别说明,基本上可以认为是给事件指令用的,基本不会错。

另外,如果是给 [变量操作] 或 [条件分支] 用的脚本,我觉得应该会有所说明(不会不写的)。

RPG Maker MZ 中常见的模式

虽然从js本身来说没什么特别的意思,但我会介绍一些rmmz特有的、知道了就能加深理解的信息。

小键盘对应

在rmmz中,指定角色的朝向或移动方向等时,会使用数字。

小键盘 | 方向

789↖︎↗️
456
123↙︎↘︎

就是这样对应的,比如数字 4 就是 ← 方向。顺便一提,数字 5 基本上会被忽略。

这个知道了的话还挺好懂的,但如果不知道,我觉得就很难消除“为什么 4 是左?”这样的疑问了。

以 $ 开头的标识符

看脚本的时候,会时不时碰到以 $ 开头的标识符。

这在js本身中并没有什么特殊含义,是核心脚本独有的一个规则,用来表示这是一个全局变量。

全局变量无论是在 [脚本] 事件指令、移动路线设置里的 [脚本]、变量的 [脚本],还是条件的 [脚本] 中,都可以同样地使用。

另外,在测试游戏时按 [F8] 键调出的 [开发者工具] 的 [控制台] 里,也可以使用它们。

参考:全局变量一览

以大写字母开头的标识符

除了以 $ 开头的标识符之外,还有一些全局可用的东西是以大写字母开头的标识符。 这在js本身中也没什么特别的意思,但几乎所有人都在遵守,所以可以说是事实上的标准。 rmmz主要有以下这些

标识符说明
AudioManager音频环境的管理
BattleManager战斗的管理
ColorManager颜色数据的管理
ConfigManager设置的管理
DataManager数据输入的管理
EffectManager特效的管理
FontManager字体的管理
ImageManager图像数据的管理
PluginManager插件的管理
SceneManager场景的管理
SoundManager声音数据的管理
StorageManager存档数据的管理
TextManager文本的管理
Graphics图像的处理
Input手柄・键盘输入的处理
TouchInput鼠标・触摸输入的处理
Utils其他处理
Video视频的处理
信息

除此之外,还有其他以大写字母开头的全局可用标识符,不过主要的应该就是这些了。

以 _ 开头的标识符

看脚本的时候,会时不时碰到以 _ 开头的标识符。

这在js本身中并没有什么特殊含义,是核心脚本独有的一个规则,用来表示这是一个局部性质的值。

虽然说是“局部”,但实际上并不是只能局部使用,它的意思大概只是比较宽松地提醒一下:“带 _ 的,大家尽量别用哦”,仅此而已。

(顺便一提,带 $ 的全局变量确实可以全局使用,但并不是因为带了 $ 所以就能全局用,只是核心脚本采用了给全局变量加上 $ 这个规则而已。)

这是因为js缺乏把东西真正局部隐藏起来的手段,所以只能用“提个请求”这种方式来凑合,是个挺悲伤的理由。

实际上,大家并没有太在意,还是用得很欢的(笑)。

但是,如果同时存在 _namename() 并且都能取到相同的值,那么使用后者 name() 才是正规方法,而且两者的行为有时也会不一样。

比如,取到的值可能会被转换成整数之类的,就是这样的区别。

反过来,如果不需要那种额外的处理,有时也会故意直接用 _name

另外,有时候虽然有 _name,但核心脚本里并没有准备 name(),这种情况下就只能用 _name 了。

真是够复杂的呢。

顺便一提,标识符末尾如果带有表示复数的 s,手抄的时候也容易漏掉,所以这点也要注意。

结论就是:如果你用复制粘贴的方式使用,就不需要在意这些;但如果你要手抄,小心别漏掉那个 _

话说回来……标识符这种东西,总之还是尽量用复制粘贴吧![⌘C] 和 [⌘V] 走起!

##js控制台

在测试游戏时,按 [F8](或者 [F12])键,就会打开[开发者工具]窗口。

使用这个工具,可以进行各种开发方面的调查。

其中特别重要的是js控制台。

打开控制台

在[帮助] - [辅助工具的使用方法] - [测试游戏]里,只写了一句话“开发者工具的功能与 Google Chrome 内置的工具相同”,就这么甩锅给 Chrome 的帮助文档了!

去看 Google 官方帮助网站就行了,说没问题倒也没问题……哇哦!This is English!

所以呢,我推荐JAVASICIPT.INFO 开发者控制台这个网站。

另外,在实际的 Chrome 浏览器中,可以用 [⌥⌘I] 打开开发者工具。用 [⌥⌘J] 的话,可以直接打开js控制台。

[开发者工具] 的功能非常强大,如果要正经地用js进行开发,它是绕不开的,而且用起来会非常方便!

不过因为它能做的事情太多了,所以这里我先只挑一些在写[脚本]时知道会比较有用的部分,摘出来介绍给大家。

用 [F8] 打开的[开发者工具]中,写着 [Console] 的那个标签页就是js控制台。

img

DevTools failed to load SourceMap: Could not load content for chrome-extension://njgcanhfjdabfmnlmpmdedalocpafnhl/js/libs/pixi.js.map: System error: net::ERR_FILE_NOT_FOUND

会显示这样一条信息对吧。

这个信息根据环境(OS 或 NW.js 的版本)不同,显示上可能会有些差异,但总之就是告诉你 “pixi.js.map” 这个文件不存在。

<Bad!> 要说这个文件是否需要,其实是不需要的,但就因为能正常运行就把这种错误信息放着不管,我觉得作为产品来说有点不太好。

信息

NW.js 是一种应用,为了让rmmz的游戏能以应用程序的形式运行,而提供接近浏览器环境的运行环境。

小知识

"pixi.js.map" 这个文件,里面装的是在发布时不需要、但在开发时需要的信息,也就是用于关联相关信息的东西。

rmmz使用了名为 "pixi.js" 的js库(一个集合了可供程序调用的功能的程序),但在用 RPG Maker 开发游戏时,虽然会看到核心脚本,但作为其基础的 pixi.js 库本身的开发是不需要的,所以没有附带 "pixi.js.map" 这个文件。

如果在 "pixi.js.map" 文件里写下以下内容,然后把它放到 "js/libs/" 文件夹中,上面的错误就不会再出现了。

{
"sources": []
}

正如你所见,这是一个没什么实际内容的虚拟文件。

或者,删除 "js/libs/" 文件夹中 "pixi.js" 文件末尾的注释,错误也不会再出现。

//# sourceMappingURL=pixi.js.map

另外,对于进行此更改后可能出现的任何问题,我不提供任何保证。

话说回来,这篇文章整体都是这样。出了问题我也不管哦!请自行承担责任,please!

运行 JavaScript

点击控制台中显示 > 的地方,就可以输入并执行 JavaScript。

试着做一下最基本的计算。

1+1

对于输入的内容,结果会实时显示出来。哦哦,高科技!

如果是像计算这样只要知道答案就好,那没问题;但如果需要让什么东西动起来,就按 [回车] 键执行。

注意,图像等画面如果不选中游戏窗口,显示是不会更新的。

在控制台中,this 里面是(浏览器的)Window。粗略来说,它处于“最外层”的位置。

在 [脚本] 中不会出现这种状态,所以无法测试含有 this 的脚本。

这么一来,你可能会觉得没法测试脚本了,但请回想一下:带 $ 的全局变量等是可以随处使用的。

没错,如果是全局变量,就可以在控制台中执行。

没必要每次都在 [脚本] 事件指令里写好,然后测试游戏,再去触发 [执行内容]!

如果示例代码是以 $ 开头的,那基本上肯定可以在 [控制台] 中执行,所以请灵活运用,多多尝试。

$gamePlayer.setDirection(6);

在地图上显示着玩家的时候,试着把这个脚本复制粘贴,然后按 [回车] 键执行。

正如之前所说,别忘了选中游戏窗口!

怎么样?是不是感觉js离自己近了不少?

输入过的脚本可以用 [↑] 键调出来,而且js自带的标识符以及《RPG Maker MZ》中定义的标识符都会有自动补全。用 [↑] [↓] 键选择,按 [Tab] 键确定。也可以用鼠标来选。

<Nice!> 超级方便!!

感觉你已经可以自己批量生产脚本了呢!

……虽然可能还到不了那个程度吧(笑),但我觉得只是改造一下的话,应该会变得相当轻松。

开发者工具里还准备了各种用于处理错误的功能……但如果要说明这些,就不是这篇文章的量能搞定的了,所以请自己去搜索讲解这些功能的网站吧!

老实说,我自己也没有完全掌握这些功能!!

另外,在rmmz中,开发者工具不能正常工作,所以这里写的步骤可能无法执行。但这一页毕竟只是rmmz的解说,敬请谅解。

最后

说实话,从“事件指令”到“脚本(JavaScript)”之间的这个过渡部分,对于从 RPG Maker 入门的人来说,几乎完全没有人引导,感觉就像一道相当陡峭的悬崖绝壁。

它看起来好像近在咫尺,但实际上甚至会让人忍不住想:是不是先好好研究一下插件反而更是一条捷径呢?

话虽如此,既然它好不容易就在眼前,那还是想直接爬上去看看。

这篇文章虽然还谈不上装了个电梯……但至少楼梯……可能也还算不上,大概也就是在悬崖上敲了个岩钉的程度吧?没敲上?结果拴上绳子一拉,岩钉就掉了?

嘛……有时候也可能会这样吧。

当你习惯了脚本的复制粘贴后,请继续阅读RMMZ的脚本应用