プレイヤーとイベントの間の最短の移動距離を測定したい

アバター
にゃたま
記事: 837
登録日時: 2016年1月13日(水) 23:53
お住まい: 床下の猫王国-すみませんが体調悪いのでサポートはお休みさせていただきます
連絡を取る:

プレイヤーとイベントの間の最短の移動距離を測定したい

投稿記事by にゃたま » 2017年7月11日(火) 22:33

こんばんは。

今回はプレイヤーと指定したイベントとの間の移動距離が測定したいと思いました。
移動距離というのは直線上の距離ではなく障害物や他のイベントなどを避けた最短距離を表します。
スクリプトを使用した例でも構いませんので距離を取得して変数に入れる方法を教えて頂けないでしょうか?
ご存知の方いましたらアドバイスお願いします。

追記
「移動距離」=「到達までの歩数」になります。

アバター
こめかみ
記事: 104
登録日時: 2017年9月06日(水) 19:34
連絡を取る:

Re: プレイヤーとイベントの間の最短の移動距離を測定したい

投稿記事by こめかみ » 2020年1月08日(水) 06:06

>にゃたま様
回答でなく申し訳ございません。
私も最短移動距離を変数に格納したく、投稿を上げさせていただきました。

経路探索系のプラグイン内で計算される数値を代入すればと思いseea様の"SA_AnotherRouteSearch.js"を改変してみたのですが、自分の知識ではどうにもならず:|

※250行目あたりの経路バッファの項目がそれらしき数値かもと
"$gameVariables.setValue(n,this._activeRouteBuffer.length)"
を追記したところ実際に数値は出たのですが、経路探索を実行する全イベントがリアルタイムで数値を算出してしまいダメでした。

該当イベント⇔該当イベント(orプレイヤー)の最短移動距離を変数に代入できる方法やプラグインはないでしょうか?
アバター
ツミオ
記事: 83
登録日時: 2017年4月02日(日) 13:46
連絡を取る:

Re: プレイヤーとイベントの間の最短の移動距離を測定したい

投稿記事by ツミオ » 2020年1月08日(水) 10:41

注*
プラグインを作成したので、そちらをご利用ください。
https://raw.githubusercontent.com/Tsumio/rmmv-plugins/master/plugins/ShortestDistanceCalculator.js

以下そのまま。

こんにちは。
経路探索等のアルゴリズムを理解できるわけではないので、経路探索の方法自体はコアスクリプトの流用ですが、スクリプトを作成してみましたので、プラグインとして取り込んでみてください。
おおまかには想定通りになるかと思います。

ただコードのコメントでも書いています通り、無限ループするかもしれないのと(例えば絶対にたどり着けないところ。他にも(そいうことがあるのかどうかは不明ですが)経路探索が失敗して同じところをグルグル回った場合)、100%正しい最短経路を返すかどうかはわかりません。

上記を踏まえた上で、試作版としていったんお試しいただければなと思います。

コード: 全て選択

/**
 * targetへの最短距離を返す。
 * Note:100%最短経路を返すとは限らない。
 * WARNING:無限ループする可能性あり。例えば、絶対にたどり着けない場所。再帰の回数を制限できた方がよい?
 */
Game_Character.prototype.calcShortestDistance = function(target) {
    //現在のインスタンスを元に、画面上には存在しないダミーキャラクターを作成する
    const dummyCharacter = JsonEx.parse(JsonEx.stringify(this));

    //最短距離を計算する
    const calcShortestDistanceRecursive = function(count, x, y) {
        dummyCharacter.moveTowardCharacter2(target.x, target.y);
        const isMoved = dummyCharacter.x !== x || dummyCharacter.y !== y;
        const isArrived = dummyCharacter.existAround4(target);
        return isMoved && !isArrived ? calcShortestDistanceRecursive(count + 1) : count+1;
    };

    //最短距離を返す
    return calcShortestDistanceRecursive(0, dummyCharacter.x, dummyCharacter.y);
};

/**
 * moveTowardCharacterみたいなやつ。
 * Note:TouchInputによっておこる移動の処理を流用。
 * Note:次に移動すべき場所を計算するとき、moveTowardCharacterでは動きが止まる可能性が高過ぎる。
 */
Game_Character.prototype.moveTowardCharacter2 = function(x, y) {
    const direction = this.findDirectionTo(x, y);
    if (direction > 0) {
        this.executeMove(direction);
    }
};

/**
 * 周囲4方向に対象がいるかどうかを返す
 */
Game_Character.prototype.existAround4 = function(target) {
    const diffX = Math.abs(this.x - target.x);
    const diffY = Math.abs(this.y - target.y);
    return (diffX + diffY) <= 1;
};

/**
 * 周り(4方向ではなく8方向をチェック)に対象キャラクターがいたらtrueを返す。
 * 8方向プラグインに対応させるならこちら。
 */
Game_Character.prototype.existAround8 = function(target) {
    const fromX = Math.abs(this.deltaXFrom(target.x));
    const fromY = Math.abs(this.deltaYFrom(target.y));
    return fromX <= 1 && fromY <= 1;
};


使い方はイベントのスクリプトに例えば以下のように記述します。

コード: 全て選択

//プレイヤーからイベント12までの最短経路距離を計算
const dis = $gamePlayer.calcShortestDistance($gameMap.event(12));
console.log(dis);


追記:
まるでイベントに対しても使えるかのような書き方になってしまっていますが、executeMoveがイベントには実装されていないため、今のままだとイベントに対してはエラーが出ます。
ご了承ください。
最後に編集したユーザー ツミオ on 2020年1月08日(水) 18:20 [ 編集 1 回目 ]
【Twitter】https://twitter.com/TsumioNtGame/
【GitHub】https://github.com/Tsumio/rmmv-plugins

有償の依頼も募集中。
今まで有償で制作したものは実績をご覧ください。
アバター
こめかみ
記事: 104
登録日時: 2017年9月06日(水) 19:34
連絡を取る:

Re: プレイヤーとイベントの間の最短の移動距離を測定したい

投稿記事by こめかみ » 2020年1月08日(水) 17:11

>ツミオ様
ありがとうございます!
早速試しました!おおよその値が取得できればOKでしたので、活用させて頂こうと思います!
※記述されてるように、行き止まり状態で経路が探索できない場合はフリーズしてしまうようなので、気をつけたいと思います;
アバター
ツミオ
記事: 83
登録日時: 2017年4月02日(日) 13:46
連絡を取る:

Re: プレイヤーとイベントの間の最短の移動距離を測定したい

投稿記事by ツミオ » 2020年1月08日(水) 18:19

テストありがとうございます。
おおよそ問題ないとのことなのでプラグイン化しました。
同じように使えてかつ、挙げていた問題を解決しているため、以後はこちらをお使いください。

https://raw.githubusercontent.com/Tsumio/rmmv-plugins/master/plugins/ShortestDistanceCalculator.js
【Twitter】https://twitter.com/TsumioNtGame/
【GitHub】https://github.com/Tsumio/rmmv-plugins

有償の依頼も募集中。
今まで有償で制作したものは実績をご覧ください。
アバター
こめかみ
記事: 104
登録日時: 2017年9月06日(水) 19:34
連絡を取る:

Re: プレイヤーとイベントの間の最短の移動距離を測定したい

投稿記事by こめかみ » 2020年1月09日(木) 12:06

>ツミオ様
プラグイン化、大変お手数お掛けいたします。
使用法の間違いかも知れないのですが、変数に代入する為に変数の操作のスクリプトにて下記
[$gameMap.event(n).calcShortestDistance($gamePlayer);]
を実行したのですが、9007199254740991 と15桁の数値を取ってしまいます。
対象イベントがかなり近くにいる時には(1~3あたり)正確に算出される時もあるのですが、ほぼ上記の15桁が出てしまいます。
他のプラグインは切って試したのですが、使用法に問題ありでしょうか?
アバター
ツミオ
記事: 83
登録日時: 2017年4月02日(日) 13:46
連絡を取る:

Re: プレイヤーとイベントの間の最短の移動距離を測定したい

投稿記事by ツミオ » 2020年1月09日(木) 12:32

プラグインのヘルプに書いてあります通り、無限ループを避けるために再帰回数を制限しています。
その大きな値は再帰回数を超えた場合に返される値です。

距離が遠い場合、再帰回数を130より増やしてください。
提示されているコードですと、例えば以下のようにします。

コード: 全て選択

$gameMap.event(n).calcShortestDistance($gamePlayer, 250);


もしも最短距離が100や200ではなく、例えば3000程度離れている状況が頻出するということでしたら、別の実装方法を検討しなければならないかもしれません。
想定の範囲内では最大でどの程度離れているのでしょうか?

補足:
最大コールスタック数(環境によって異なります)を超えて再帰呼び出しをおこなうとエラーが発生します。
このエラーを抑制するために再帰回数を制限しています。
したがって、例えば3000などの値を設定すると、環境によってはエラーが発生する場合があります。
【Twitter】https://twitter.com/TsumioNtGame/
【GitHub】https://github.com/Tsumio/rmmv-plugins

有償の依頼も募集中。
今まで有償で制作したものは実績をご覧ください。
アバター
こめかみ
記事: 104
登録日時: 2017年9月06日(水) 19:34
連絡を取る:

Re: プレイヤーとイベントの間の最短の移動距離を測定したい

投稿記事by こめかみ » 2020年1月11日(土) 23:04

>ツミオ様
ありがとうございます。再帰回数の増加で値を取ることができました!
使用目的は80×50程の緩い迷路状のマップでの追跡型ゲームなのですが、対象への距離(実歩数)による追跡者の挙動の変化を想定しております。(並列処理ではなく、一定のタイミングで実行をさせます)
配置によっては500程の値が必要になるかも知れません(余りにも離れ過ぎている場合は"超遠距離"という括りで処理する予定です)

※仕様上、先述の経路探索プラグイン SA_CoreSpeedImprovement.js が必須なのですが、こちらを併用した際にほぼ確実に処理落ち及び15桁の再帰回数オーバーが出てしまいました。競合解消まで視野に入れると解決は難しいでしょうか・・・
アバター
にゃたま
記事: 837
登録日時: 2016年1月13日(水) 23:53
お住まい: 床下の猫王国-すみませんが体調悪いのでサポートはお休みさせていただきます
連絡を取る:

Re: プレイヤーとイベントの間の最短の移動距離を測定したい

投稿記事by にゃたま » 2020年1月11日(土) 23:15

ツミオ様

プラグインの制作ありがとうございます。
2年半も前に投稿した記事がこうして日の目を見ることになることは
予想だにしてなかったです。

当時どういった意図でこのような質問をしていたのか今となっては失念してしまい
思い出せないのですが、何かしらの別の方法にトライしていたのかもしれません。

今後このような機能を使いたいときに使わせていただくかもしれません。
この度は制作いただきありがとうございました。この場を借りてお礼申し上げます。

komekami様、掘り起こしていただきありがとうございました。
解決されたみたいですが文面からもう少し様子を見たほうがよいと判断しましたので
解決済みにするのはもう少し後にします。

“MV:質問” へ戻る