ものだねっと

■衝撃により作業>>>>ゲームと化した。 ■FGO:ネロちゃまは万病に効くどころの話じゃなかった。

アクションゲームでありがちな勝手に動いてる床を作りたい(フリゲ制作5)

どうも、ものだねです。
ツクール意欲が湧いたのでガンガン骨組みを作っています。

 

ツール:RPGツクールMV
現在導入中のプラグイン

 

ジャンル:アクション寄り
探索要素は未定

 

アクツクも検討しましたが
どうにも難しそうという結論に至り、
半歩移動で通常のツクールゲーより拡張性を求める方針にしました。


幸いなことに、アクション要素に適したプラグインを見つけることができ、
現在は実装案と比較して使用を検討している段階です。

 

画面外イベント動作については
昔1週間くらいでツクった二次創作ゲーでお世話になり、
続投を検討しています。

 

同じようなプラグインを見つけましたが、
今回は全てのマップでイベント動作しても問題ないアクションということで見送りました。
プラグインを作ってくださる方々には感謝しかありません。

 

さて、勝手に動いて乗れる床ですが、
一応こちらでスイッチを押すと現れる床について書かれています。

【解決】スイッチで移動する床を作成したい - ツクマテ

また、こちらではタイミングを合わせて移動する床について書かれています。

YADOT 穴の上に移動床を設定

(ツクール2000のようですが活用できると思います)

 

ただ、移動床というワードがツクールMV公式で強制移動を意味しており、
なかなか目当ての情報に辿り着けない、
もしくはそもそも情報が存在しないという状況のようです。
公式ワードとの混同を防ぐため、以下移動足場と呼称します。

 

また、ただ移動足場を配置しても通常のアクションゲームのような

  • 勝手に移動してくれる
  • その上で自由に行動できる

という2つの要素を同居させることはできません。
ここは妥協しましょう。
というわけで上記2000の解説を参考に

タイミングよく移動して進む必要がある床

を作っていきましょう。

 

2000ではコモンイベントでプレイヤーの移動が指定できないようですが、
MVでは問題なく移動できるのでコモンイベントで流用しやすくします。

 

導入中の半歩移動ですが、

仕様上イベントID(変数7)がこの位置で読み込めないので
スクリプトコマンドを用いてOFFにします。
まあ読み込めたら読み込めたでありがたいですが、
プレイヤーが中間に立った場合どちらのイベントに乗った判定にするか
といった問題が出てくるので今のところなしでいいでしょう…。

 

 

①リージョンIDで穴を指定する

上記解説では地形IDを読み込ませていましたが、
MVにはリージョン機能があるのでリージョンIDで穴を指定します。

こんな感じです。

橋のマップチップを利用して作っていきます。
テスト用マップなのでこんなものでいいでしょう。

 

犬は橋の挙動に関与してません。
左上のイベントの自動実行により、
以下で作り上げるコモンイベントに必要な各種変数を設定しています。

 

②穴の判定をコモンイベントで作る

2000の「定期的に並列処理をする」の仕様が不明なため、
ラベルジャンプを使用してループを設定しています。

また、プレイヤー位置を利用して変数を代入するコマンドが見つからなかったため
スクリプトを利用しています。
(※のちにスクリプトを利用して変数操作なくリージョンIDを取得できたため、
スクリプトに置き換えました)

 

③足場の判定を作る

コモンイベントとして使い回すことを想定しているため、
移動足場IDは可変となるよう変数を指定しました。
各マップで並列処理イベントを作るのとどちらがいいかは悩みどころです。

こちらはマップごとに自動実行で指定させます。
ちなみにイベントIDを個別に指定するよりもまとめた方が
このように条件指定が簡潔になります。

 

④移動する足場に乗る判定を作る

2000での解説では
移動する足場イベント全ての画面XYを取得しているようですが、
コモンイベントでそんなこと指定したくないので、
足元にあるイベントの画面XYのみを取得します。

この時、イベントが存在しないと
存在しないイベントのXY座標を取得できずにエラーが発生してしまうため、
イベントID≠0で条件分岐を設定します。

9~10、11~12でプレイヤーの画面座標を取得し、
スクリプトで取得した足元のイベントの画面座標で減算で処理します。
Yで-6を指定しているのはデフォルトで6pxプレイヤーが浮いてるからですね。

 

⑤プレイヤーが移動しているか確認する

イベントID≠0の条件分岐の中に格納します。
そうしなければせっかくのギミックが
単に歩いているだけでスルーされてしまいます。

こんなの放置してたらひどいバグですね。

 

(場所移動はリトライ用の変数を用意してあります)
2000の解説ではこのイベント自体をマップに設置しているので
「このイベントの画面XY」を使用していますが、
これはコモンイベントなのでそういうわけにはいきません。

代わりにイベントIDの指定をできるようにしました。
指定したIDのイベントが画面内に収まっていれば大丈夫です。

 

結局のところ、

  • 専用イベントを画面内に収まるようワープさせながら追従させる
  • 専用イベントに並列処理させてプレイヤーの位置ごとにIDを切り替えさせる

くらいしかぼくには思い浮かびませんでした。
もっといいアイデアがあれば教えてください。

 

13と14で再度プレイヤーの画面座標を取得した後、
変数15で指定するIDのイベントの画面座標を取得させて減算処理します。
その後13~14は剰余処理で48で割った余りを求めさせます。

48はマップの1マスあたりのpxですね。
0であれば移動していないということになります。

 

ひとまず完成?

これで最低限の処理が完成しました。

 

ですが、移動足場を作るにはまだ足りません。
更に要素を足していく必要があります。
今の時点で完成しているのは、
橋から落ちることができる
という内容だけです。


時間経過で落ちる足場とかだったらこれだけでも平気ですが、
あいにくやりたいのは足場を動かすこと。

 

というわけで解説に従って、
更に付け足していきましょう。

 

追加①足元のイベントID(変数7)を複製した変数18を初期化する処理を加える

ぼくが先に作ってしまった足元のイベントIDを判定する処理ですが、
なんと追加範囲で使いました…。
しかし、実際の処理を追っていくと、
複製した変数を使用して移動するかチェックするようです。
変数の複製(代入)は後ほど処理を追加していくので、
今は新たな変数18を初期化することだけ考えましょう。

まずは②のリージョンID≠1だった場合に変数18を初期化(0を代入)します。
この後にも初期化処理は出てきますが、初期化を付け足すのはここだけです。

 

追加②プレイヤーが移動しているか確認する処理を加える

これは変数1つにプレイヤーのX座標とY座標を格納する処理ですね。
移動した場合に複製ID(変数18)を初期化します。

 

追加③乗っている移動足場のイベントIDを複製する処理を加える

解説の「変数7≧1」に当たる部分はつまるところ「変数7≠0」ですが、
新しく追加しても意味がないのでまとめてしまいます。
「変数7≠0」の中に③で作った移動しない足場の判定をカットペーストで移します。

 

移したらこの条件分岐にも条件を満たさない時の分岐を作り、
移動しない足場に乗っている時は複製IDを初期化する処理を加えます。
そして移動している足場に乗っている時にはIDを複製します。

これで、複製したIDを参照して移動するか決める処理の下準備が完了です。
解説にあるスイッチですが、コモンイベントの仕様上
マップイベントを呼び出してもコモンイベントが優先されるため
コモンイベント内で動作を完結させた結果、そもそも不要となりました。

 

追加④移動足場に乗っていたらプレイヤーが勝手に移動する処理を加える

条件分岐「変数7≠0」で条件を満たさない時の分岐を作成にチェックを入れます。
ここに条件分岐「複製ID≠0」を作ります。

 

先ほどいらないといったスイッチですが、
コモンイベントの拡張性を高めるために追加しました。
移動足場を作るというだけなら不要です。


スクリプトですが、指定したIDのイベントの向きを確認する
というコマンドが見つからなかったため利用しました。
あとは移動ルートの設定でプレイヤーの移動をさせるだけです。


ちなみにこれは足場の移動頻度が最高(5)だと追い付かずに落ちますので、
別のイベントを作ってあげる必要があると思われます。
また、MVの仕様上仕方ないことだと思いますが、
移動足場とプレイヤーの動きが完全に同期することはありません。
プレイヤーが必ず1テンポ遅れます。
これは割り切るしかないでしょう。

 

※追記:
改善に成功して移動足場とプレイヤーの動きが完全に同期できましたが、
移動足場の数だけ並行処理が増えるため重くなる可能性があります。

方法としてはイベントの並行処理の中にイベントの移動ルートを設定し、
イベントが移動する直前にプレイヤーの各種設定変更を入れるだけです。

 

最後に複製ID≠0の分岐の中の一番後ろに

  • 複製IDの初期化処理
  • ラベルジャンプで最初に戻る処理

を加えて完成です。

 

実装に使用した変数

  • 変数1:プレイヤーのX座標を取得スクリプトで直接指定できたため削除)
  • 変数2:プレイヤーのY座標を取得(同上)
  • 変数6:足元のリージョンIDを取得(同上)
  • 変数7:足元のイベントIDを取得
  • 変数8:現在のマップで移動足場イベントのIDを指定
  • 変数9:プレイヤーの画面Xを取得
  • 変数10:変数7で指定するイベントの画面Xを変数9から減算
  • 変数11:プレイヤーの画面Yを取得
  • 変数12:変数7で指定するイベントの画面Yを変数11から減算
  • 変数13~14:プレイヤーが移動しているかを画面XYから計算で算出
  • 変数15:変数13と変数14の計算に必要なイベントIDを指定
  • 変数16:現在のプレイヤーのXY座標を1つの変数で管理
  • 変数17:変数16が更新された時、変数17にコピー
  • 変数18:変数7をコピーし、足元にイベントがなくなった時に使用される

 

使用したスクリプト一覧

  1. プレイヤー座標からリージョンIDを取得
    $gameMap.regionId($gameVariables.value(1),$gameVariables.value(2))
    プレイヤーの現在位置のリージョンIDが1以外か確認
    $gameMap.regionId($gamePlayer.x, $gamePlayer.y) !== 1
  2. プレイヤー座標からイベントIDを取得
    $gameMap.eventIdXy($gamePlayer.x, $gamePlayer.y)
  3. 足元のイベントID(変数7)の画面座標を取得

    $gameMap.event($gameVariables.value(7)).screenX()

    $gameMap.event($gameVariables.value(7)).screenY()

  4. 指定したイベントID(変数15)の画面座標を取得

    $gameMap.event($gameVariables.value(15)).screenX()

    $gameMap.event($gameVariables.value(15)).screenY()

  5. 指定したイベントID(変数18)の向きを取得して確認

    $gameMap.event($gameVariables.value(18)).direction() == 2;

    $gameMap.event($gameVariables.value(18)).direction() == 4;

    $gameMap.event($gameVariables.value(18)).direction() == 6;

    $gameMap.event($gameVariables.value(18)).direction() == 8;
    指定したイベントID(変数18)の向きを取得して移動(移動ルート内)
    $gamePlayer.moveStraight($gameMap.event($gameVariables.value(18)).direction())

  6. プレイヤーのXY座標を変数16に格納する処理

    $gamePlayer.x * 1000 + $gamePlayer.y

 

おわり。

ツクールは久しぶりに触るので調べものも多く、実装に丸1日はかかりました。
これを1から編み出したYADO様に感謝です。

 

なお、スクリプトの生成にはchatGPTを使用しており、
ぼく本人はド素人です。
AIによるスクリプト生成のため、スクリプト著作権はありません。
スクリプトの使用・改変はご自由にどうぞ。

 

 

ノシ