『RPGツクールMZ』で始めるJavaScript入門
以上の二本の記事で、とりあえず[スクリプト]イベントコマンドを使えるようにはなったと思います(以降、その前提で書きます)
しかし、なんでそれで動いているのか、JavaScript の基本的なところがわからず気持ち悪いという人もいると思います。
紹介してあった上記のサイトを読んだけど、今ひとつ良くわからないというかとっかかりさえつかめない。
てゆーか、別に HTML とかどーでもいいんだよ!なんでそこから勉強しなきゃいけないんだよ!アホか!と思った人もいるかと思います。
この紹介した先は割と HTML と絡めずに JavaScript の部分だけ書いてある方なんですけど、それが逆にわからないということもあったりしそうです。
(なお、これらのサイトそのものは情報に信頼性があり、かなりわかりやすく書かれているので、JavaScript を勉強する際は、大いに活用できます。『RPGツクールMZ』のことが考慮されてないだけです)
そんなわけで、ツクールから JavaScript に入門するための記事を書くことにしました。
[スクリプト]イベントコマンドからの使い方を中心に『RPGツクールMZ』エディタ上での説明をします。
プラグインを作るときもほぼ同じスクリプトが使えるので、プラグインを作りたい場合も参考になると思いますが、ここではプラグインでの JavaScript については記述しません。
ところでRPGツクールMZ公式の最速JavaScript講座はプラグイン入門の一環として書かれていますが、JavaScript と『RPGツクールMZ』をつなげる部分として比較的短くわかりやすいですのでオススメです。
それはそれとして、本記事では以下にリンクしているリファレンスを読めるようになる、というのを目標にやります。
「使えるようになる」のは簡単なやつだけを目標にします。
全部使えるにようになるにはコアスクリプトを直接読んで理解する必要があるからです。
後、僕も全部は使えませんから説明できません(笑)
なお、以降で紹介するサイトの作者名は敬称略です。
用語
以下、『RPGツクールMZ』[スクリプト]の応用にも書いたものですが、最後にいくつか付け加えてます。
知らない単語が出てきたときに読んでみてください。
配列…値に番号をつけて並べた値。例:[ 10, 4, 6 ]
(これは値として数字を並べていますが他の値も並べられます)
添字…「そえじ」配列(を保持している変数)から値を取り出す際に使う数字。例:array[ 0 ]
( JavaScript の配列の添字は 0 から始まります)
文字列…文字を並べた値です。JavaScript 的には String
です。値が文字1つに固定された配列と考えてもいいです。例: "文字列でーす"
真偽値…真(正・ON)と偽(負・OFF)の2つを取る値です。JavaScript 的には Boolean
で2つの値は true
と false
で表されます。
論理演算…計算の結果として真偽値を返す演算です。値の多少を判定する条件式などが含まれます。
変数…値を保持しています。JavaScript の変数も『RPGツクールMZ』の変数とだいたい同じです。定義例:let variable;
以前は定義に let
ではなく var
を使っていましたが問題が多く、今(2022年現在)はあまり使われていません。逆に var
が使われていると素人でも簡単に古いコードだと分かります。なお『RPGツクールMZ』になってコアスクリプトは var
を廃止してます。
定数…変数とだいたい同じですが、一度値を設定したら変更できません。一見不便に感じますが、実は変数より便利で、実際のプログラミングでは、ほとんど変数を使う必要はありません。定義例:const constant = 1;
関数…処理をまとめたものです。『RPGツクールMZ』の[コモンイベント]とだいたい同じですが、引数と返り値があるので使い勝手が格段に良いです。また[スクリプト]イベントコマンドも複数の処理が書けるので一種の関数といえ、[変数の操作]にある[スクリプト]などには返り値があります。JavaScript は歴史的経緯があって関数の定義方法がたくさんあるのが困ったところです。定義例:function addOne( arg ) { return arg +1; };
、const addOne = arg => arg + 1;
引数…「ひきすう」は関数の実行の際に ()
内に書いて渡す値。関数には引数がない場合も複数ある場合もあります。
返り値…「かえりち」関数が返す値です。関数によってあったりなかったりします。
オブジェクト…関係する値(プロパティ)と機能(メソッド)をまとめたもの。JavaScript のプログラムはこれを組み合わせてできてます。
プロパティ…オブジェクトに付随した変数です。ただし変数と違ってオブジェクトの状態で値が変わるものもあります。逆に設定することでオブジェクトの他のプロパティなどの状態が変わる場合もあります。オブジェクトに .
をつけた後に指定します。例:object.property
リードオンリープロパティ…オブジェクトに付随した読み取り専用の値です。ただし定数と違ってオブジェクトの状態で値が変わるものもあります。read only は ro とか r/o とか略されます。
メソッド…オブジェクトに付随した関数です。だいたいはプロパティを加工します。オブジェクトに .
をつけた後に指定し、()
の中で引数を指定します。例:object.method()
追加用語
クラス…オブジェクトの設計図とか型とか説明される、プログラムのひとまとまり。
インスタンス…クラスから生成(new)されたオブジェクトのことです。大体は単にオブジェクトと呼ぶので滅多に使われない用語です。
コアスクリプト…『RPGツクールMZ』で作ったゲームに必要なクラスを定義しているスクリプトです。事実上、これを操作するのが『RPGツクールMZ』での JavaScript です。逆に一般の JavaScript プログラマは知らないので、質問しても「なにそれ」って言われる確率が高いです。
ライブラリ…特定の目的のプログラムを作る際に必要な機能をまとめたプログラム。プログラムから使われるためのプログラム。ライブラリを利用することでいちからプログラムを構築する必要がなく、比較的簡単に機能を拡張できます。
局所変数…プログラムは細かくクラスや関数で領域を分割されて、別の領域から変数を扱えないようにすることで、複雑化を防いでいます。そのような領域に閉じ込められた変数が局所(ローカル)変数です。
大域変数…大域(グローバル)変数は例外で、プログラムのどの領域からでも扱えます。
静的クラス…クラスからオブジェクトを生成することなく、直接クラス名を指定して使えるクラス。大域変数と同様にプログラムのどの領域からでも扱えます。
静的プロパティ…静的クラスに付随するプロパティ。リファレンスでは[static]がついています。
静的メソッド…静的クラスに付随するメソッド。リファレンスでは(static)がついています。
コアスクリプトのクラスツリー
さて JavaScript の歴史とかは知りたい人だけ本とかWebで調べてもらうとして、ツクールです。
とりあえず、次のリンク先をざっと見て帰ってきてください。
RPGツクールMZ 非公式JavaScriptリファレンス - クラスツリー
英単語がぐわーーーッと並んでいたと思います。
階層化された様子が木に似ているということでクラスツリー(class tree)なんて言ったりします。
これがコアスクリプトで定義されているクラス(オブジェクト)です。
…え、こんなにたくさんあるの!?って思ったでしょうが、あるんですよ。
ただこれ全部把握するのは大変ですし、なんなら僕も把握してません。
ま、とにかく。これらのオブジェクトを操作するのが『RPGツクールMZ』における JavaScript というわけです。
コアスクリプト外のJavaScript
まず『RPGツクールMZ』は『アツマール』のようにWebブラウザ上で実行できることからもわかるように、Webブラウザの機能の上で動いています。
なのでWebブラウザの持っている JavaScriptオブジェクトも使えるんですが、基本的には無視して構いません。
次に『RPGツクールMZ』には PixiJS(ぴくしーじぇいえす)という描画ライブラリと Effekseer(えふぇくしあー)というエフェクトアニメーションライブラリが使われています。
あとローカルで動かす場合(Mac なら .app、Windows なら .exe の形式)には NW.js というローカルでブラウザと近い HTML+JavaScript を動かす環境が使われています。
ややこしいですが NW.js はその環境の中に Node.js というファイルなどが扱えるライブラリを持っています。
[テストプレイ]を行った時に『nwjs』というアプリケーションが立ち上がっているのにお気づきでしょうか?アレです。
これらのライブラリは先ほど見たクラスツリーの中のオブジェクトから使われているので、あえて直接使う必要はありません。
ただし JavaScript そのものが持っている基礎的なクラスは、[スクリプト]イベントコマンドからも割と使います。
コアスクリプトの3つの構成要素
先ほど見たクラスツリーはいわば材料で、動作させるにはそれを組み立てなければいけません。
『RPGツクールMZ』の場合は[テストプレイ]などをおこなってプレイを開始した時点で組み上がっています。
なのでツクラーそれぞれが、どうやってオブジェクトを組み上げるか考える必要はありません。楽!
なので、ツクラーに必要なのは『RPGツクールMZ』がどのようにオブジェクトを組み上げているのかを理解することです。
その構成要素は大きく分けて データベース、ゲームオブジェクト、マネージャの3つです。
データベース
$data
から始まる大域変数です。エディタで設定する[データベース]の内容そのものなので、すでに把握しているようなものです。
データベースは "data/ファイル名.json" ファイルに保存されているので、JSONデータと言われたりします。
リファレンス:Global#データベースでも確認できますが、一覧表にしました。
説明 | 変数名 | 配列 |
---|---|---|
アクター | $dataActors | ⚪︎ |
アニメーション | $dataAnimations | ⚪︎ |
防具 | $dataArmors | ⚪︎ |
職業 | $dataClasses | ⚪︎ |
コモンイベント | $dataCommonEvents | ⚪︎ |
敵キャラ | $dataEnemies | ⚪︎ |
アイテム | $dataItems | ⚪︎ |
現在のマップ | $dataMap | - |
マップ一覧 | $dataMapInfos | ⚪︎ |
スキル | $dataSkills | ⚪︎ |
ステート | $dataStates | ⚪︎ |
システム | $dataSystem | - |
タイルセット | $dataTilesets | ⚪︎ |
敵グループ | $dataTroops | ⚪︎ |
武器 | $dataWeapons | ⚪︎ |
配列が ⚪︎ の場合、たとえば$dataActors
はリファレンス:Global#データベースの最初の方を見てみると、次のような記述があります。
Array.<RPG.Actor>
$dataActors :[アクター]用JSON( Actors.json )。
Array
というのは配列のことで RPG.Actor
というデータが番号をつけて順に記録されているということを示しています。
なので変数の後ろに [添字]
と書いて指定すると添字に書いた番号に応じたデータが返ってきます。
$dataActors[ 1 ]
この場合はエディタの[データベース]-[アクター]のアクターID1のデータです。
.<RPG.Actor>
と書いてある部分のリンクをクリックして詳細ページをみるとプロパティのところに英単語が並んでいて[データベース]のウィンドウで見たラベルとの対応が書かれています。
それを .
に続けて書くとそれぞれの値が取得できます。
たとえば次のようにすればアクターID1の[名前]が取得できます。
$dataActors[ 1 ].name
[テストプレイ]の際に[F8](または[F12])で開く[コンソール]にコピーすると値が表示されます。
数字を変えてみたり .name
の部分を削除したり、別のプロパティに書き換えてみたりしてみましょう。
まとめると、『RPGツクールMZ』には大域変数 $dataActors
が用意されていて、それは配列なので [ 1 ]
と書くとアクターID1の RPG.Actor
の情報が得られ、続けて .name
と書くことでアクターID1の[名前]情報が得られる、という流れです。
[アクター]以外の[データベース]の項目も同様の指定方法で取得できます。
プロパティが配列の場合や、さらにプロパティを持っている場合もあります。
その場合も配列なら [添字]
、プロパティなら .プロパティ
という形で後ろにつなげていけば OK です。
$dataActors[ 1 ].equips[ 2 ]
$dataActors[ 1 ].traits[ 3 ].code
なお $dataMap
や $dataSystem
は配列(Array
)ではないので添字は必要ありません。
たとえば次のようにすれば[表示名]が取得できます。
$dataMap.displayName
具体的な記述方法は、トリアコンタンさんが書かれた RPGツクールMZ スクリプトリファレンス#データベース を値の名前で検索して「取得スクリプト」のスクリプトを確認するといいです。
メモ(メタデータ)
データベースに含まれるメモ(メタデータ)を扱えるようになると、標準の機能ではむずかい処理ができるようになります。
詳しくは『RPGツクールMZ』[スクリプト]の応用#メタデータを参照してください。
ゲームデータ
$game
から始まる大域変数はゲームで使われるオブジェクトです。
ゲームのさまざまな挙動を制御できます。また多くのものはセーブデータを兼ねていて、セーブファイルに保存されます。
リファレンス:Global#ゲームデータでも確認できますが、一覧表にしました。
説明 | 変数名 | セーブ |
---|---|---|
アクター | $gameActors | ⚪︎ |
マップ | $gameMap | ⚪︎ |
メッセージ | $gameMessage | - |
パーティー | $gameParty | ⚪︎ |
プレイヤー | $gamePlayer | ⚪︎ |
画面管理 | $gameScreen | ⚪︎ |
セルフスイッチ | $gameSelfSwitches | ⚪︎ |
スイッチ | $gameSwitches | ⚪︎ |
システム | $gameSystem | ⚪︎ |
一時保存 | $gameTemp | - |
タイマー | $gameTimer | ⚪︎ |
敵グループ | $gameTroop | - |
変数 | $gameVariables | ⚪︎ |
ゲームデータの取得サンプルは、トリアコンタンさんが書かれたRPGツクールMZ スクリプトリファレンス#ゲームデータを見ると、ここの記述方法がわかります。
プロパティの指定方法はデータベースと一緒なので省略します。
ゲームデータはメソッドがあるのが、データベースとの大きな違いです。
またプロパティは値を取得するだけではなく、値の代入が多いのも違いです。
マネージャ
Manager
がついた静的クラスはゲームで使うデータなどを管理します。
マネージャの機能は名前を見ればわかる感じですが、期待した機能が入ってないこともそれなりにあります。
クラスツリー
そういえばクラスツリーってなんで樹木のような枝分かれになっているのか、説明していませんでした。
クラスは継承という仕組みを使って、1つのクラスをベースにして複数の別のクラスを作ることができます。
『RPGツクールMZ』ではたとえば window
クラスをベースにたくさんの関連クラスが作られています。
『RPGツクールMZ』で作ったゲームには色々なウィンドウがありますが、どれも基本的な「枠があって文字が書かれる」という部分は一緒なので共通化したクラスを作って、それを継承したクラスで違う部分だけを定義して楽をしている、というわけです。
継承元のクラスをスーパークラス、継承先のクラスをサブクラスと言います。これらの単語をリファレンスの説明で見かけたかもしれません。
前述の説明のように継承元の機能を使いまわしているわけですからスーパークラスで使えたプロパティとメソッドもそのまま使えるのです。
リファレンスでは「スーパークラスから継承されたメソッド」は一覧にしていますが、プロパティについては一覧化していません。
ですがスーパークラスのプロパティも実際は使えます。リファレンスでは _
付きのプロパティは極力使わない方がいいというのもあって、あんまり見えやすくするのもなー、あと面倒臭いし(笑)というわけでスーパークラスから継承されたプロパティは一覧化していません。
座標を示す x
とか y
みたいな定番のプロパティがないなーと思ったときは、スーパークラスの方をたどっていくと、どこかで定義されています。
ちなみにコアスクリプトには前述の PixiJS のオブジェクトから継承したクラスも多いので、主要なものはリファレンスに引き写しています。
PixiJS公式サイトにもリファレンスはありますが英語なので、頑張って訳しました。
継承によって機能が共通化され全体としてはわかりやすくはなるのですが、1つのクラスだけ調べようとしても継承元のスーパークラスを追っていかねばならないので、その点では把握しづらくなっています。
プラグインを作るぐらい使い込むつもりなら、クラスツリーを眺めて大枠を把握しておいた方が良いと思います。
オブジェクトの生成
[スクリプト]に JavaScript を書く場合、大抵はすでに生成してあるオブジェクトを使います。
$data
、$game
系の大域変数がそうでした。
あるいは Manager
系の静的クラスを直接使ったり、静的クラスのオブジェクトが入っているプロパティを使うとか。
そんなわけで、大抵のオブジェクトは生成してあるので、新たにオブジェクトを生成して使うということは少ないと思いますが、いちおう説明しておきます。
new クラス名()
クラスの説明のところに「new クラス名()」と書いてある場合があります。
それはインスタンスを生成する場合の書式と引数の説明です。
こんな感じで新しいオブジェクトを生成し、定数に入れて使います。
const rect = new Rectangle( 360, 8, 100, 400 );
Rectangle
の引数の詳細は以下リファレンスをご覧ください。
定数に入れずにメソッドの引数に直接書くこともできますが、読みにくくなるのでオススメしません。
RPG と MV について
リファレンスを見ていると RPG.
とか MV.
がついたクラスをちらほら見かけるかと思います。
これらは以下のリンク先にも書いてありますが、非公式リファレンスで勝手に名付けたものです。
リファレンス的には名前がないと、なんとも扱いづらかったので。
リファレンス:ネームスペース:RPG
リファレンス:ネームスペース:MV
RPG.
はデータベース用に作られるものです。そういう意味ではJSONファイルを覗けば、そこにフォーマットの定義はあります。$data
系の大域変数に記録されています。
MV.
は各種メソッドの引数や返り値に一定の形式のものがあり、その形式を説明したものです。あえていえばメソッドのコード(プログラム)が定義です。
これらは JavaScript 上は単なる Object
というデータの一種です。なんちゃってオブジェクトと言いますか。
ここでなんちゃってオブジェクトのクラス名が Object
というのが非常にややこしいのですが…これ JavaScript を説明づらくする仕様の筆頭だと思います。
それはそうとして、なんちゃってなので作るときは new
ではなく、たとえば MV.Size
なら次のように書きます。
const size = { width:10, height:8 };
見ればわかるとは思いますが、言葉で説明すると全体を {}
で囲い、プロパティ名と値を :
で区切って、プロパティ毎に ,
で区切る、ということです。
MV.Size
という名前は便宜上つけただけなので、実際はそんな名前のクラスはなく、こんなふうにデータを記号で区切って並べるだけです。
プロパティの詳細はリファレンスをご覧ください。
こういう値をプロパティ名でまとめたものを「Object型の値」とか言ったりします。単にオブジェクトということもあるので、まーややこしいです。
さて、この例では定数に代入していますが引数に直接書くこともあります。
またメソッドの返り値が、これらの形式の値なこともあります。
以上がオブジェクトと、なんちゃってオブジェクトこと Object型の値の生成方法でした。
豆知識
JavaScript のクラスの継承をたどっていくと Object
クラスに行き着きます。
「なんちゃってオブジェクト」とか書いてますが、実は同時に「すべてのオブジェクトの親」だったりします。
とはいえデータ型として使うことが多いので、クラス名は Object
じゃなくて Record
とかにして欲しかったです。全 JavaScript プログラマがそう思ってると思います(笑)
なお ES6 と言われる JavaScript のバージョンから、Object型をデータ型として使う場合の問題が解消された Map
というデータ型が用意されています。
Map型は『RPGツクールMZ』でも使えますが、ゲームとしてマップ表示があるんでややこしいですね。
thisについて
[スクリプト]イベントコマンド用のサンプルスクリプトを見ていると、頻繁に this
という単語を目にしたと思います。
ざっくりいうとthis
には現在のスクリプトを含んでいるオブジェクトが入っています。
[スクリプト]イベントコマンドの場合は Game_Interpreter
です。
なので this
に続けて以下リファレンスにあるプロパティやメソッドが書けます。
たとえば次のような感じです。
this.setWaitMode( "message" );
[スクリプト]移動コマンドの場合this
には移動ルートの実行対象である[イベント]か[プレイヤー]が入ります。
なので this
に続けて以下リファレンスにあるプロパティやメソッドが書けます。
リファレンス:Game_Event
リファレンス:Game_Player
たとえば次のような感じです。
this.setDirection( 8 );
この辺りになると、コアスクリプトの中身を把握していないと便利に使うのは難しいと思います。
コピーするスクリプトに this
が入っているときに「なるほど、前読んだアレか」ぐらいに思っておけばいいでしょう。
最後に
以上でRPGツクールMZ 非公式JavaScriptリファレンスがなんとか読めるようになってもらえれば幸いです。
最初に書いたように、コアスクリプト全部を使えるようになるのは難しいと思います。
とはいえこれで「やりたい処理があった場合にリファレンス内を探して、うまくいけば使い方のわかるプロパティやメソッドを発見できる」というぐらいにはなれるとは思います。
あるいは「スクリプトをコピーしてきた後に、メソッドの引数をリファレンスで調べて引数を書き換える」とか。
そもそも『RPGツクールMZ』で作品を作るのが目的なのですから、あまり JavaScript に深入りするのは本末転倒だと思います。
僕なんか、深入りしすぎて全然作品が作れてません(笑)
ただ、これを機会に JavaScript にズッポリハマってしまうのも、それはそれで楽しいかもしれません。
レッツエンジョイ ツクールライフ!
変数に数値以外を入れる使い方を解説しました。
『RPGツクールMZ』で文字列・配列を使う
Discussion