RPGツクールMZ応用編 イベントの位置を初期化する方法3選

当ページのリンクには広告が含まれています。

今回は、イベントの位置を初期化する方法を3つ紹介します。以前リクエストをいただいた内容です。

イベントの初期化が必要になる例として、石を押して色の違うタイルに乗せるパズルイベントがあります。石を誤った場所に移動すると、タイルの上に乗せられなくなり、詰んでしまうことがあります。

石を誤った場所へ移動してパズルが詰んだ場面

このような場合は、石の位置を初期化する必要があります。

もう1つの例は、敵に追いかけられて捕まるとミスになるイベントです。捕まったあとにプレイヤーと敵イベントの位置を初期化すれば、スタート位置からやり直せます。

敵に捕まるとスタートからやり直す追いかけっこイベント

どの方法が優れているというわけではありません。制作しているゲームや用途に合わせて選んでください。

チャプター

1. 場所移動を使う方法

場所移動を使ってイベント位置を初期化する方法

最も簡単なのは、場所移動を使う方法です。

RPGツクールMZには、一度別のマップに移動してから元のマップへ戻ると、イベントの位置が初期化されるという性質があります。

たとえば、街のマップでモブキャラが動いていても、一度建物に入ってから街へ戻ると、モブキャラは最初の位置に戻っています。この挙動を利用します。

基本的な手順

  1. 「リセット用」などの名前で、新しいマップを作成します。中身は空で問題ありません。
  2. イベントコマンドの「場所移動」を設定します。
  • 最初にリセット用マップのどこかへ移動します。
  • そのあと、元のマップのスタート位置へ移動します。向きは下などに設定します。
  1. 場所移動の前後に「画面のフェードアウト」と「画面のフェードイン」を挟みます。プレイヤーが一瞬見えてしまうのを防ぐためです。

注意点: 同じマップ内で場所移動しただけでは、イベントの位置はリセットされません。必ず一度別のマップへ移動してから戻す必要があります。

場所移動では一度別のマップを経由する必要があるという注意点

変数で移動先を指定する

場所移動の座標を直接指定すると、同じイベントを別のマップで使い回すときに手間がかかります。

たとえば、テスト1のマップ用に作ったイベントをテスト2へコピーすると、移動先はテスト1のままです。この問題は、変数で移動先を指定することで解消できます。

  1. マップID、X、Yの3つの変数を用意します。
  2. マップに入ったとき、自動実行で初期位置を取得するイベントを作ります。
  • マップIDに「ゲームデータ → マップID」を代入します。
  • Xに「キャラクター → プレイヤーのマップX」を代入します。
  • Yに「キャラクター → プレイヤーのマップY」を代入します。
  • 最後に「イベントの一時消去」で自身を消します。
  1. 位置をリセットするときの場所移動先に、これらの変数を指定します。

イベントの一時消去には、一度マップを出てから戻るとイベントが復活する性質があります。そのため、マップに入るたびに初期位置が上書きされます

イベントの一時消去を使って初期位置を取得する設定

この仕組みを利用すると、ステージ1・2・3があるミニゲームで、ステージ2でミスした場合はステージ1ではなくステージ2から再開する、といった簡易的なオートセーブも実現できます。

2. イベント位置の設定を使う方法

2つ目は、イベントコマンド2ページ目の「イベント位置の設定」を使い、イベントを直接動かす方法です。

場所移動ではプレイヤーを別の場所へ移動させます。一方、イベント位置の設定では、指定したイベントを同じマップ内の別の座標へ移動できます

プレイヤーは移動しないため、リセット用マップも必要ありません。

場所移動とイベント位置の設定の違い

座標を直接指定する

戻したいイベントごとに「イベント位置の設定」を使い、元の座標を直接指定します。

変数で座標を指定する

イベントごとにX・Yの変数を用意し、初期位置を取得するイベントで、各イベントのマップXとマップYを変数へ代入しておきます。リセット時は、その変数を参照してイベントを移動させます。

この方法の弱点は、各イベントのX・Y座標を取得するために、多くの変数が必要になることです。イベントが3つだけでも、X・Y × 3で合計6つの変数を使います。石が4つ、5つと増えると管理が大変です。

イベントごとにX座標とY座標の変数が必要になる弱点

解決策として、セルフ変数を使えるプラグインを利用する方法もあります。ただし、余計なバグやメンテナンスの手間を減らすためにも、できればプラグインの数は増やしたくないところです。

3. スクリプトで位置を初期化する方法

3つ目は、変数やイベント位置の設定を使わず、スクリプトでイベントを一括初期化する方法です。

メモ欄で対象イベントを指定する

イベントのメモ欄に `<ターゲット>` と書きます。これにより、メモ欄に「ターゲット」と書かれたイベントだけを元の位置へ戻し、それ以外のイベントは動かさないように制御できます。

メモ欄へ任意の文字を入れるときは、`<>`という不等号の中に文字を入れることを覚えておいてください。

イベントのメモ欄にターゲットと記入して初期化対象を指定する設定

スクリプトの内容

イベントコマンド3ページ目にある、上級の「スクリプト」へ以下を入力します。

Jaavscript
for (let i = 1; i < $gameMap._events.length; i++) {
  if (!!$gameMap._events[i]) {
    if ($gameMap._events[i].event().note.match(/<target>/)) {
      $gameMap._events[i].locate(
        $gameMap._events[i].event().x,
        $gameMap._events[i].event().y
      );
    }
  }
}

スクリプトの仕組み

コードを見るだけで頭が痛くなる方もいるかもしれません。僕も頭が痛くなりますが、処理を分けて見れば理解しやすくなります。

for文でイベントを順番に処理する

  • `let i = 1`:変数iに1を代入し、イベントID 1から開始します。
  • `i <= $gameMap._events.length`:iがマップ内のイベント最大数以下である間、ループします。
  • `i++`:ループを1周するたびに、iへ1を加えます。

つまり、イベントID 1から最大番号まで、順番に処理を実行しています。

1つ目のif文でイベントの存在を確認する

`!!$gameMap._events[i]`では、イベントID iのイベントがマップに存在するかを確認します。

RPGツクールでイベントを作っていると、ID 5を削除してID 7だけが残るようなことがあります。存在しないイベントを処理するとエラーになるため、ここでスキップします。

2つ目のif文でメモ欄を確認する

`$gameMap._events[i].event().note.match(‘target’)`では、メモ欄に「target」という文字があるかを判定します。

スクリプト内で文字列を参照するときは、シングルクォーテーション(’)またはダブルクォーテーション(”)で囲みます

locateで初期位置へ移動する

  • `$gameMap._events[i].event().x`:イベントの初期X座標を自動参照します。
  • `$gameMap._events[i].event().y`:イベントの初期Y座標を自動参照します。

イベントの初期位置を変更すると、参照する座標も自動的に変わります。そのため、イベントを増やしたり別の場所へ移動したりしても、このスクリプト1つで初期化できることが最大の利点です。

locateとイベントデータのx・yで初期位置を取得するコード

4. セルフスイッチも一緒にリセットする

イベントによっては、位置だけでなくセルフスイッチもリセットする必要があります。

たとえば、ゴールのリージョンに到達するとセルフスイッチAがオンになり、イベントが2ページ目へ移行して動かなくなる仕様を考えてみます。この場合、位置だけを初期化しても、イベントは2ページ目のままなので、押しても動きません

このような場合は、イベントの位置を初期化するときに、セルフスイッチAも同時にオフにします。

セルフスイッチAをオフにする

スクリプトのターゲット判定のあとに、以下を追加します。

Jaavscript
$gameSelfSwitches.setValue([this._mapId, i, 'A'], false);
  • `this._mapId`:現在のマップIDです。
  • `i`:ループ中のイベントIDです。
  • `’A’`:オフにするスイッチのアルファベットです。
  • `false`:オフを表します。オンにする場合は `true`です。
セルフスイッチAをfalseにしてオフにするスクリプト

A〜Dをまとめてオフにする

セルフスイッチA・B・C・Dを複数使っている場合、1つずつ書くとコードが長くなります。そこで、配列とfor…of文を使います。

Jaavscript
const arr = ['D', 'C', 'B', 'A'];
for (let i = 1; i <= $gameMap._events.length; i++) {
if (!!$gameMap._events[i]) {
if ($gameMap._events[i].event().note.match('ターゲット')) {
$gameMap._events[i].locate(
$gameMap._events[i].event().x,
$gameMap._events[i].event().y
);
for (const val of arr) {
$gameSelfSwitches.setValue([this._mapId, i, val], false);
}
}
}
}
  • `const arr = [‘D’, ‘C’, ‘B’, ‘A’]`:配列にD・C・B・Aを格納します。
  • `for (const val of arr)`:配列の中身を順番にvalへ入れてループします。
  • この処理だけで、セルフスイッチD・C・B・Aをすべてオフにできます。
配列を使ってセルフスイッチAからDをまとめて処理するコード

慣れていないと少し難しく感じるかもしれません。必要になったときは、このコードをそのままコピーして貼り付けても問題ありません。

まとめ

方法特徴向いている場面
場所移動最も簡単。別マップを1つ用意するだけシンプルなリセットが必要な場面
イベント位置の設定プレイヤーは移動しない。変数が増えやすいイベント数が少ない場合
スクリプトメモ欄で対象を指定。変数が不要で拡張性が高いイベント数が多い場合や、使い回したい場合
  • 場所移動で位置をリセットする場合は、必ず別のマップを経由します。同じマップ内の移動ではリセットされません。
  • 変数で移動先を指定すると、コピーしやすく、メンテナンスも楽になります
  • スクリプトでは `$gameMap._events[i].event().x`と`$gameMap._events[i].event().y`で、初期座標を自動参照できます
  • 必要な場合は、セルフスイッチのリセットも忘れずに行います。

変数を使った場所移動やメモ欄の参照方法は、ドラクエのルーラ・リレミト再現の回でも解説しています。スクリプトの基礎は、スクリプト入門の回で詳しく紹介しています。必要に応じて、そちらも試してみてください。

SNSのネタにどうぞ

作者

ゲーム作ってる人。主にRPGツクールでのゲーム制作に役立つスキルを発信している

座右の銘:インドカレー
将来の夢:インドカレーになること

チャプター