ページ 11

アイテムを何も持っていないときの処理

Posted: 2018年8月31日(金) 18:10
by aka0191
初めて質問します。

メニュー画面でアイテムやスキルを何ももっていない状態でアイテムを選んだときに、
アイテム画面にいかずに「何も持っていない」というようなメッセージを出したいと思っています。

いろいろ試行錯誤しながら、なんとか下記の形でメッセージウィンドウでメッセージを出すところまでは
できたのですが、テストプレイをするとメッセージを表示したところでフリーズしてしまいます。

メッセージウィンドウでメッセージを出し終えたあとにウィンドウを閉じて、メニュー画面に戻すためにはどのようにすればよいのでしょうか。

ご教授いただけますと幸いです。

Scene_Menu.prototype.commandItem = function() {
this._data = [];
this._data = $gameParty.allItems().filter(DataManager.isItem);
if ( this._data.length == 0){
$gameMessage.add('なにももっていない');
} else {
SceneManager.push(Scene_Item);
}
};

よろしくお願いいたします。

Re: アイテムを何も持っていないときの処理

Posted: 2018年9月02日(日) 22:21
by トリアコンタン
こんばんは!

ツクールMVのウィンドウの仕様で
「ウィンドウで決定ボタンを押すと一旦そのウィンドウからフォーカスが外れる」
というものがあります。
その後、全てのウィンドウからフォーカスが外れた状態になり操作不能になってしまいます。

「this._commandWindow.activate();」というコードにより、コマンドウィンドウを再度フォーカスすることが可能です。
以下が実装例です。

コード: 全て選択

    Scene_Menu.prototype.commandItem = function() {
        this._data = $gameParty.allItems().filter(DataManager.isItem);
        if ( this._data.length === 0){
            $gameMessage.add('なにももっていない');
            this._commandWindow.activate();
        } else {
            SceneManager.push(Scene_Item);
        }
    };
ただし、上記だけでは動作しません。
なぜならメニュー画面には、もともとメッセージウィンドウを表示するための仕組みが用意されていないからです。

この場合、メニュー画面でもメッセージウィンドウが表示できる何らかのプラグインを使うのがオススメです。
いいものが見付からない場合、多少変則的ですが以下でも代用可能です。

メニュー内コモンイベントプラグイン
https://raw.githubusercontent.com/triac ... onEvent.js

上記のプラグインを適用し、さらにメインメニュー画面で空のコモンイベントを指定するよう設定すれば、メニュー画面でもメッセージウィンドウが出せるようになります。

Re: アイテムを何も持っていないときの処理

Posted: 2018年9月02日(日) 22:51
by aka0191
ありがとうございます!

this._commandWindow.activate();を組み込んだら確かにフリーズはしなくなったのですが、
メッセージウィンドウが残ったままでメニュー操作ができる状態になり、
アイテムを何度か選択してから、メニューを閉じると
「なにももってない」メッセージが選択した回数だけ出るようになってしまいます。

ちなみにメッセージウィンドウについては、以下のように組み込んでいました。
Scene_Menu.prototype.create = function() {
Scene_MenuBase.prototype.create.call(this);
this.createCommandWindow();
this.createGoldWindow();
this.createStatusWindow();
this.createMessageWindow();
};

Scene_Menu.prototype.createMessageWindow(); = function() {
Scene_Map.prototype.createMessageWindow.call(this);
};

activateを実行する前にキー入力があったかなどを入れてみたりしたのですが、
私の書き方が悪いのかうまくいかなかったので、変にメニュー画面で条件分岐するよりは、
アイテム一覧を出すときに「なにももってない」と出したほうが実装が簡単な気がしています(苦笑

Re: アイテムを何も持っていないときの処理

Posted: 2018年9月02日(日) 23:53
by トリアコンタン
こんばんは!
メッセージウィンドウ表示中もフォーカスが当たっているウィンドウ(コマンドウィンドウ)は操作可能であるため問題が発生しています。

プラグイン等ではなく、独自にメッセージウィンドウを追加して対応したい場合、コマンドウィンドウにフォーカスを当てるタイミングを「メッセージが終了した場合」にするのが手っ取り早いと思います。

以下が実装例です。やや複雑になりますが、メッセージウィンドウが終了したときに実行される関数をシーンクラスから予め登録しておきます。

コード: 全て選択

    Scene_Menu.prototype.commandItem = function() {
        this._data = $gameParty.allItems().filter(DataManager.isItem);
        if ( this._data.length > 0){
            $gameMessage.add('なにももっていない');
        } else {
            SceneManager.push(Scene_Item);
        }
    };

    Scene_Menu.prototype.create = function() {
        Scene_MenuBase.prototype.create.call(this);
        this.createCommandWindow();
        this.createGoldWindow();
        this.createStatusWindow();
        this.createMessageWindow();
    };

    Scene_Menu.prototype.createMessageWindow = function() {
        Scene_Map.prototype.createMessageWindow.call(this);
        this._messageWindow.setTerminateHandler(this.onMessageTerminate.bind(this));
    };

    Scene_Menu.prototype.onMessageTerminate = function() {
        this._commandWindow.activate();
    };

    var _Window_Message_terminateMessage = Window_Message.prototype.terminateMessage;
    Window_Message.prototype.terminateMessage = function() {
        _Window_Message_terminateMessage.apply(this, arguments);
        if (this._terminateHandler) {
            this._terminateHandler();
        }
    };

    Window_Message.prototype.setTerminateHandler = function(handler) {
        this._terminateHandler = handler;
    };

Re: アイテムを何も持っていないときの処理

Posted: 2018年9月03日(月) 21:55
by aka0191
丁寧なご回答、ありがとうございます!

無事、解決いたしました!

今まではプラグインに割と頼っていたのですが、勉強のためにも自力でと思っていましたが、
やはり1からやっていくのは難しいですね。。。