DotMoveSystemとSRD_CameraCoreの競合を解消したい

返信する
アバター
BumbleB
記事: 28
登録日時: 2017年2月27日(月) 05:28

DotMoveSystemとSRD_CameraCoreの競合を解消したい

投稿記事 by BumbleB »

度々恐れ入ります。うなぎおおとろ氏のDotMoveSystemとSumRndmDde氏のSRD_CameraCoreを使用した時の問題を解消したいのですが
わからない点がありアドバイスをいただけると嬉しいです。

●問題点
SRD_CameraCoreはフォーカス対象を指定すると自動でその対象を中心としてカメラを移動し、そのキャラクターが移動したとき自動でカメラが追従してくれる機能があります。
ところがDotMoveSystemを導入した時、「フォロワーのみ機能しなくなる」という症状があり、これを解決したいと考えています。
内容としては、エラーなどが出るわけではありませんが、カメラが固定され一切スクロールしなくなってしまいます。

●わかっていること
まずSRD_CameraCoreは
555行目

コード: 全て選択

Game_Character.prototype.updateScroll = Game_Player.prototype.updateScroll;
でイベントやフォロワーにupdateScrollの機能を追加し

589行目~

コード: 全て選択

	const _Game_Follower_update = Game_Follower.prototype.update;
	Game_Follower.prototype.update = function () {
		var lastScrolledX = this.scrolledX();
		var lastScrolledY = this.scrolledY();
		_Game_Follower_update.apply(this, arguments); 
		//ここで this.scrolledX()、this.scrolledY();が更新されていない?
		this.updateScroll(lastScrolledX, lastScrolledY);
	};

	Game_Follower.prototype.updateScroll = function (lastScrolledX, lastScrolledY) {
		if ($gameScreen.focusEvent === this._memberIndex * (-1)) {
			Game_Character.prototype.updateScroll.apply(this, arguments);
		}
	};
上記の処理でプラグインコマンドが実行されたとき、$gameScreen.focusEventに該当するイベントや
フォロワーをカメラスクロールの対象にする(そのときはGame_PlayerのupdateScrollが行われないようにしておく)というやり方をとっているようです。

そのupdateScrollの処理は
コアスクリプトrpg_object7701行目~

コード: 全て選択

Game_Player.prototype.updateScroll = function(lastScrolledX, lastScrolledY) {
    var x1 = lastScrolledX;
    var y1 = lastScrolledY;
    var x2 = this.scrolledX();
    var y2 = this.scrolledY();
    if (y2 > y1 && y2 > this.centerY()) {
        $gameMap.scrollDown(y2 - y1);
    }
    if (x2 < x1 && x2 < this.centerX()) {
        $gameMap.scrollLeft(x1 - x2);
    }
    if (x2 > x1 && x2 > this.centerX()) {    
        $gameMap.scrollRight(x2 - x1);
    }
    if (y2 < y1 && y2 < this.centerY()) {
        $gameMap.scrollUp(y1 - y2);
    }
};
が実行されていると思うのですが、どうやらDotMoveSystemを導入しているとき、カメラをフォロワーを対象にして実行内容をみると
lastScrolledXとthis.scrolledX()、lastScrolledYとthis.scrolledY()が常に同じ値になってしまっているということがわかりました。
それによって$gameMap.scroll~が実行されないので、カメラスクロールが行われないというのが理由のようでした。
SRD_CameraCoreにコメントした通り
var lastScrolledX = this.scrolledX();
var lastScrolledY = this.scrolledY();で代入した後
_Game_Follower_update.apply(this, arguments);が呼ばれているわけですが
ここでthis.scrolledX()、this.scrolledY()が更新されないといけない?のかと思いましたが
処理の追い方がいまいちわからず、詰まってしまいました。

DotMoveSystemはかなり色々と処理を書き換えていて、しばしば競合するので手放そうかとも考えたのですが
結局イベントにもドット単位移動を行わせることができるプラグインが他に見つからず、また
イベントの当たり判定の調整なども欲しい機能なので、できればこのプラグインを使いたいと思っています。


https://plugin.fungamemake.com/archives ... e_vignette
https://plugin.fungamemake.com/archives/26500
プラグインのリンク(ツクプラ)は上記です。よろしくお願いします。
アバター
Plasma Dark
記事: 731
登録日時: 2020年2月08日(土) 02:29
連絡する:

Re: DotMoveSystemとSRD_CameraCoreの競合を解消したい

投稿記事 by Plasma Dark »

特にDotMoveSystem.jsはコードが複雑なので、処理が追いにくいですね。
全容を把握しようとすると、 Game_Player.prototype.update から順番に処理を追っていく必要があります。

おっしゃるとおり、SRD_CameraCore.jsは Game_Follower.prototype.update の処理の中で this.scrolledX(), this.scrolledY() の結果が変動したことを検知して、画面をスクロールしています。
this.scrolledX(), this.scrolledY() の結果はそれぞれ処理を見ていただければわかりますが、 this._realX, this._realY によって計算されます。

Game_Follower.prototype.update の処理の中で、 this._realX, this._realY が更新されるタイミングはどこか、というところから追っていくのが正攻法かなと思います。

結論から言ってしまえば、MVデフォルトでは Game_CharacterBase.prototype.updateMove が呼び出されるとその一連の処理で this._realX, this._realY が更新されます。

DotMoveSystem.jsではどうかというと、updateMove含め、移動に関する処理の少なくない部分を独自の処理に置き換えており、これを読んでいかないといけません。
updateMoveから追っていくと、毎フレーム、キャラクターの移動先との距離を見て、それが0より大きければキャラクターを移動する(_realX, _realYを更新する)という処理をしています。
ところが、フォロワーについてはこの移動先との距離が必ず0になるようです。

おそらく、 Game_Followers.prototype.update の中で先にフォロワーの _realX, _realY を更新してしまっているがために、 Game_Follower.prototype.update の呼び出し時点ですでにそのフレーム内でフォロワーを移動させる必要がなくなっているのだと思われます。

解決のアプローチとしては、 SRD_CameraCore.js か DotMoveSystem.js どちらかを編集することになるかと思います。

解決のアプローチ1: lastScrolledX, lastScrolledYの算出時点を変更する (SRD_CameraCore.js を編集する)
$gamePlayer.update() の先頭(あるいは呼び出し直前)で算出するように変更してしまえば、this.scrolledX(), this.scrolledY() との差分が出てupdateScrollが効力を発揮します。
https://gist.github.com/elleonard/dbae0 ... f105dc0250

解決のアプローチ2: chaseCharacterの呼び出し時点を変更する (DotMoveSystem.js を編集する)
Game_Follower.prototype.update の先頭で呼び出すように変更すれば、lastScrolledX, lastScrolledY と this.scrolledX(), this.scrolledY() の差分が出てupdateScrollが効力を発揮します。
https://gist.github.com/elleonard/81218 ... 4e14a8391b
アバター
BumbleB
記事: 28
登録日時: 2017年2月27日(月) 05:28

Re: DotMoveSystemとSRD_CameraCoreの競合を解消したい

投稿記事 by BumbleB »

DarkPlasmaさん 
いつもありがとうございます
(御作のプラグインにもいつもお世話になっております……この場を借りて感謝申し上げます)
コードまで書いていただき本当に助かります。
どちらを使うのがいいか迷ったのですが、アプローチ1のほうをパッチにするかたちで
独立したプラグインにして、ゲームに取り込むことにしました。ありがとうございます。

もしよろしければ後学のためお聞きしたいのですが
こうしたマップ上でのキャラクターやイベントの移動の処理の流れについて解説してくれているサイトなどご存知でしょうか?
例えば戦闘の処理についてはツクールMV Advent Calendar 2015などで詳しく解説してくれた記事などがあるのですが
マップ上の移動については、プレイヤー(マウス・キーボード)の移動、フォロワーの移動、イベントの移動とあるのを
今までなんとなくで理解した気になっていたので、今回のように他のプラグインが絡んでくると
「そもそもどういう処理になっているのか」がわかってないことが多いんですよね…。
できるだけ自分で解決できるようになるためにも勉強し直したいと考えています。
アバター
Plasma Dark
記事: 731
登録日時: 2020年2月08日(土) 02:29
連絡する:

Re: DotMoveSystemとSRD_CameraCoreの競合を解消したい

投稿記事 by Plasma Dark »

もしよろしければ後学のためお聞きしたいのですが
こうしたマップ上でのキャラクターやイベントの移動の処理の流れについて解説してくれているサイトなどご存知でしょうか?
残念ながら、そこまで詳しく処理のフローを解説しているサイトに心当たりはありません。

マップ上におけるキャラクターの移動を含む毎フレームの更新処理は、 Scene_Map.prototype.updateMain から追うことができます。
特にキャラクターの移動に絞って見たい場合は、 Game_CharacterBase.prototype.update から追っていくのでも良いですが、キャラクターにはイベント、プレイヤー、フォロワー、乗り物などいくつか種類があります。
今回のケースのようにフォロワーのみ他と挙動が異なる、といった際に全体を見通すには、 Scene_Map.prototype.updateMain から根気よくコードを読んでいく他なさそうです。
アバター
BumbleB
記事: 28
登録日時: 2017年2月27日(月) 05:28

Re: DotMoveSystemとSRD_CameraCoreの競合を解消したい

投稿記事 by BumbleB »

ありがとうございます
マップ上におけるキャラクターの移動を含む毎フレームの更新処理は、 Scene_Map.prototype.updateMain から追うことができます。
sceneの更新の処理から少しずつたどっていくということですね…時間のある時にじっくり取り組んでみたいと思います。ありがとうございます!
返信する

“MV:質問”に戻る