【RPGツクールMZ】マップ内に宝箱がいくつ残っているか判定する


はじめに

経緯

RPGツクールMZで、DQの「とうぞくのはな」のような仕組みをシンプルで楽に実装できないかを考えていました。
すると「メタデータ」という概念がツクールMZにあることを知り、これを利用して実装できるのではと考えつき、やってみたら変数すら使わずに出来ました。
(実装に協力下さったあわやまたなさん、ありがとうございました)

メタデータとはなんぞや

こういうやつです→ <data:123>
プラグインを使ったことのある人なら見たことあると思います。
これをメタデータと言います。

詳しい解説はこちらの記事を参考にして下さい。

https://forum.tkool.jp/index.php?threads/%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3%E4%B8%8D%E8%A6%81%EF%BC%81%E6%84%8F%E5%A4%96%E3%81%A8%E7%9F%A5%E3%82%89%E3%82%8C%E3%81%A6%E3%81%84%E3%81%AA%E3%81%84%E3%80%8C%E3%83%A1%E3%82%BF%E3%83%87%E3%83%BC%E3%82%BF%E3%80%8D%E3%81%AE%E6%B4%BB%E7%94%A8%E6%B3%95.4638/

実装方法

前提

セルフスイッチで処理する宝箱イベントであること。
(宝箱を取得したら、セルフスイッチをONにして、宝箱を空にするタイプ)

手順

1.宝箱のイベントのメモ欄にメタデータを埋め込む

2ページ目は空白で、出現条件はセルフスイッチAがONにしています

2.メタデータを埋め込んだイベントのスイッチ状況を条件分岐で判定する
下記スクリプトを、「条件分岐」のスクリプトにコピペして下さい。

$gameMap.events().filter((event) => (event.findMeta('treasure') && !$gameSelfSwitches.value([event._mapId, event._eventId, "A"]))).length > 0

3.判定に応じたイベントを作る

コモンイベントとかに書いとくと便利です

4.終わり!

解説

1.宝箱のイベントのメモ欄にメタデータを埋め込む
宝箱の残り個数を判定する為には、宝箱イベントである「目印」を作る必要があります。
その目印として利用するのが「メタデータ」です。
これを埋め込むことで、スクリプト側で「これは宝箱である」と判定出来るようになります。

文字はtreasureじゃなくてもいいです

2.メタデータを埋め込んだイベントのスイッチ状況を条件分岐で判定する
下記スクリプトで何をやっているのかを解説します。


$gameMap.events().filter((event) => (event.findMeta('treasure') && !$gameSelfSwitches.value([event._mapId, event._eventId, "A"]))).length > 0

これは
「現在いるマップの中で、メモ欄に『treasure』が入っているイベントのうち、セルフスイッチがOFFになっているものが1つ以上あるか」 を判定しています。

更に分解して解説しますと
$gameMap.events()
で、現在いるマップのイベントの情報を全て取得しています。
(公式のスクリプトリファレンス参考)

続いて
.filter()
を使って条件を満たすイベントを絞り込んでいます。

具体的な条件の定義は
(event) => (event.findMeta('treasure') && !$gameSelfSwitches.value([event._mapId, event._eventId, "A"]))
です。
これが「メモ欄に『treasure』が入っているイベントのうち、セルフスイッチAがOFFになっているものがあるか」の判定となっています。

event.findMeta('treasure')
で、メモ欄に『treasure』が入っているかを判定しています。

!$gameSelfSwitches.value([event._mapId, event._eventId, "A"])
で、セルフスイッチAがOFFかどうかを判定しています。
頭にある「!」を消せば、セルフスイッチAがON(開封済み)かどうかの条件になります。
セルフスイッチA以外を判定させたい場合は、Aの文字をBやCに変えればいいです。

&&
をつけることで、and条件(両方を満たす場合)にしています。

(event) =>
は深く考えなくていいです。そういう書き方のルールがあります。
詳しく知りたい方は、jsのドキュメントを参考にして下さい。

条件の解説から戻りまして
.length
で、条件にマッチするイベントがいくつあるかを取得しています。

最後に
> 0
で、条件にマッチするイベントが0より大きい(1件以上ある)かの判定を入れています。
これはツクールMZのデフォルトの条件分岐でも見る形だと思います。

このスクリプトを入れることで、デフォルトの条件分岐1つで判定を行う事ができます。
後は好きな処理を入れるだけでオッケーです。

おまけ

DQの「とうぞくのはな」を作る

下記スクリプト、変数の代入のスクリプト欄にコピペしてください。
上記で解説した条件を満たすイベント件数を取得するスクリプトです。

$gameMap.events().filter((event) => (event.findMeta('treasure') && !$gameSelfSwitches.value([event._mapId, event._eventId, "A"]))).length
こんな感じでコピペすればオッケーです

あとは、代入した変数の値を制御文字で表示させればオッケーです。
制御文字がわからない人はこちら。

もし、代入した変数をツクールのデフォルトの条件式で使うのであれば、変数のデータ型に注意して下さい。
詳しくは下記記事を参考。

DQの「レミラーマ」を作る

イベントコマンドのスクリプトに、下記スクリプトをコピペしてください。

const treasureList = $gameMap.events().filter((event) => (event.findMeta('treasure') && !$gameSelfSwitches.value([event._mapId, event._eventId, "A"])));

let character = '';

for (let i = 0; i < treasureList.length; i++) {
    character = '';
    character = this.character(treasureList[i]._eventId);
    $gameTemp.requestAnimation([character], アニメーションID)
}
こんな感じ

これは
「現在いるマップの中で、メモ欄に『treasure』が入っているイベントのうち、セルフスイッチがOFFになっているイベントに対して、イベントコマンド『アニメーションの表示』を実施する」
スクリプトです。
サンプルの「アニメーションID」を再生したいアニメーションIDに差し替えれば、好きなアニメーションを適用する事ができます。

え?
アニメーションの再生順を変えたり、ウェイトを入れたい?
…頑張ってください。

おわりに

ツクールMZって、慣れれば何でも出来るんだなと思いました。
メタデータを上手く活用すると、保守性の高い自作システムがかなり組めそうな気がします。

いいなと思ったら応援しよう!