キャラクタ周りを調べてみた
今回は、マップ上でプレイヤーが操作するキャラクタを中心に調べてみようと思います。
マップキャラクタ
例によって、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
と辿っていくと、マップタイルにたどり着いた。
ここではキャラを調べたいので、各オブジェクトを追っていくと、_spriteset
が Class: 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_CharacterBase
の update()
から updateMove()
が呼ばれて、そこで distancePerFrame()
(ダッシュなどの状況に応じた移動距離を返す)の分だけ、目標地点に向かって移動する。
という感じ。
Game_CharacterBase.shiftY()
がファイル名の ! の有無でキャラをずらす数値を返してるので、ここを操作すると高さ制御が行える。
またジャンプ時の動作は updateJump()
が担っている。
まとめ
キャラの挙動は移動以外にも色々とあるが、Game_CharacterBase
をしっかり把握しておけば、だいたい操作できそうだ。
まだ、頭の中はごちゃごちゃしてるものの、ざっとした仕組みは想像できるようになったように思う。
なお、この辺を色々いじって階段などを表現するプラグイン TF_Undulation.js を作ったので、試してみてほしい。
そこで結論。
キャラが一歩進むのも、結構複雑!