キャラクタ周りを調べてみた

タイルの向こうとこっちを組み合わせて判定するのだ

 今回は、マップ上でプレイヤーが操作するキャラクタを中心に調べてみようと思います。

マップキャラクタ

 例によって、RPGMV-CoreScript-Referenceを中心に追いかけていきます。
 キャラクタ関連のクラスは以下の通り。

 キャラクタの表示を担当するのは以下。

 あと、JSONデータ。

 イベント(Game_Event)に関してはイベントコマンド周りを調べてみたで調べたので、多少わかってるつもり。
 操作対象でもないので、今回は Game_Event については原則無視の方針でいきます。

 これまで散々調べた後に、同じこと書いてるページを見つけて「あら?」みたいな事が多かったので、まず、Web上の参考になりそうなサイトを検索します。
 成長したねっ!!

 …見つけきれないとゆーね。
 多分色々あるんだろうけど、自分の検索に使える語彙が不足してる感じというかなんというか。

キャラの基本 Game_CharacterBase

 Game_CharacterBase で、ほとんどの機能は完成している。

 自分の位置のマップ状態を調べるメソッドがいくつもあるが、基本 $gameMap の同名のメソッドに丸投げしているだけ。
 表示に関するプロパティをたくさん持っているが、実際の表示周りを受け持っているのは Sprite_Character の方だ。

プレイヤーキャラ

 プレイヤーキャラは大域変数が用意されているので、座標は$gamePlayer.x(なお[read-only])という感じで簡単に取れる。
 これを知っていれば、プラグインを作るまでもなく[スクリプト]でかなり解決できそう。

 実際表示を担当している Sprite_Character は、Spriteset_Map の _characterSprites に入っている。
 ただ、こちらのプロパティを変更しても、アップデートによって Game_CharacterBase の値が反映されるので、あまり操作しても意味がない。

隊列

 隊列(ドラクエっぽくゾロゾロ歩くやつ)に関係あるのは、Game_Followers と Game_Follower。
 Game_Followers で隊列全体を管理して、Game_Follower が個々のメンバー。

マップ上の扱い

 画像をどう制御しているかの基本的なところは、Map関連クラスを調べてみたで調べた。
 それによると、SceneManager._scene._spriteset._tilesetと辿っていくと、マップタイルにたどり着いた。
 ここではキャラを調べたいので、各オブジェクトを追っていくと、_spritesetClass: Spriteset_Map に当たるんだけど、ここに _characterSprites というプロパティがある。
 ここに[アクター]と[イベント]がぶら下がっているみたいだ。

SceneManager._scene._spriteset._characterSprites
(12) [Sprite_Character, Sprite_Character, Sprite_Character, ...]

 とまぁこんな感じで、Class: Sprite_Character がたくさん出てきた。
 これらが表示を担当してるようだ。

キャラの移動について

 正面に進むメソッド Game_CharacterBase.moveStraight() が呼ばれるのは以下のパターン。

  • [移動ルート]から4方向に移動する場合
  • パーティメンバー の場合は Game_Follower.Follow() から
  • プレイヤーの入力で動く場合は Game_Player.moveByInput()から Game_Player.executeMove() を経て

 そしてmoveStraight() から canPass() が呼ばれる。

 もうひとつの canPass() が呼ばれるルートとしては、イベントやプレイヤーが[移動ルート]で8方向に動く場合。
 Game_Character.processMoveCommand()Game_CharacterBase.moveDiagonally()canPassDiagonally()canPass() の順に呼ばれる。

 Game_CharacterBaseクラス では canPass() から、マップの衝突判定を行うisMapPassable() と イベントとの衝突判定を行うisCollidedWithCharacters() を呼んでいる。
 また、[すりぬけON] の場合の isThrough() と、デバッグ中の通過キー押し状態を判定する isDebugThrough()も呼ばれている。

 isMapPassable()$gameMap.isPassable() を現在地から移動先への通過判定と、移動先での現在地からの通過判定の2回呼んでいる。
 ここから判定の中心は Game_Mapクラスへ移行。

 isPassable() から checkPassage() が呼ばれている。
 両者はほぼ似た感じの関数だが、 checkPassage()は方向だけでなく、船の通行判定などフラグのビットチェック全般を受け持っている。
 当然、isPassable() からは方向のチェックのみの目的で checkPassage() が呼ばれる。

 moveStraight()canPass()が trueなら、目標地点である_x、_y を設定し、現在地に _realX、_realYを設定する。

 Game_CharacterBaseupdate() から updateMove()が呼ばれて、そこで distancePerFrame()(ダッシュなどの状況に応じた移動距離を返す)の分だけ、目標地点に向かって移動する。
 という感じ。

 Game_CharacterBase.shiftY() がファイル名の ! の有無でキャラをずらす数値を返してるので、ここを操作すると高さ制御が行える。
 またジャンプ時の動作は updateJump() が担っている。

まとめ

 キャラの挙動は移動以外にも色々とあるが、Game_CharacterBase をしっかり把握しておけば、だいたい操作できそうだ。
 まだ、頭の中はごちゃごちゃしてるものの、ざっとした仕組みは想像できるようになったように思う。

 なお、この辺を色々いじって階段などを表現するプラグイン TF_Undulation.js を作ったので、試してみてほしい。

 そこで結論。

キャラが一歩進むのも、結構複雑!