【解決済み】スクリプトに関する質問です

アバター
にゃたま
記事: 782
登録日時: 2016年1月13日(水) 23:53
お住まい: 床下の猫王国
連絡を取る:

【解決済み】スクリプトに関する質問です

投稿記事by にゃたま » 2020年3月22日(日) 10:32

今回はスクリプトに関する質問です。

別プラグインの関数からオブジェクトを生成する方法が知りたいです。

通常以下のようにすればnew演算子でWindow_Hogeを生成できるかと思います。

コード: 全て選択

(function() {
   function Window_Hoge() {
      this.initialize.apply(this, arguments);
   }
   
   Window_Hoge.prototype = Object.create(Window_Base.prototype);
   Window_Hoge.prototype.constructor = Window_Hoge;
   
   Window_Hoge.prototype.initialize = function(x, y, w, h) {
      Window_Base.prototype.initialize.call(this, x, y, w, h);
   };
   
   Scene_Hoge.prototype.createHogeWindow = function() {
      this._hogeWindow = new Window_Hoge(x, y, w, h);
      this.addWindow(this._hogeWindow);
   };
})();


しかし以下のようにこれを分けて別プラグインとした場合Window_Hoge関数を参照して
生成できません。ブロックが分かれてしまうということはわかります。

コード: 全て選択

(function() {
   function Window_Hoge() {
      this.initialize.apply(this, arguments);
   }
   
   Window_Hoge.prototype = Object.create(Window_Base.prototype);
   Window_Hoge.prototype.constructor = Window_Hoge;
   
   Window_Hoge.prototype.initialize = function(x, y, w, h) {
      Window_Base.prototype.initialize.call(this, x, y, w, h);
   };
})();



コード: 全て選択

(function() {
   Scene_Hoge.prototype.createHogeWindow = function() {
      this._hogeWindow = new Window_Hoge(x, y, w, h);
      this.addWindow(this._hogeWindow);
   };
})();


これの解決策として以下のようにfunction Window_Hoge()を(function() { })();の外に出せば
(つまりはグローバル化?)他のプラグインから参照して生成できますが
function Window_Hoge()関数を外に出さずに別プラグインからこの関数を生成することは可能なのでしょうか?

コード: 全て選択

function Window_Hoge() {
   this.initialize.apply(this, arguments);
}

(function() {
   Window_Hoge.prototype = Object.create(Window_Base.prototype);
   Window_Hoge.prototype.constructor = Window_Hoge;
   
   Window_Hoge.prototype.initialize = function(x, y, w, h) {
      Window_Base.prototype.initialize.call(this, x, y, w, h);
   };
})();
最後に編集したユーザー にゃたま on 2020年3月23日(月) 03:26 [ 編集 1 回目 ]

アバター
Plasma Dark
記事: 235
登録日時: 2020年2月08日(土) 02:29
連絡を取る:

Re: スクリプトに関する質問です

投稿記事by Plasma Dark » 2020年3月22日(日) 11:11

別のローカルスコープのシンボルを参照しようとする場合、スコープそのものに名前がついている必要があります。

行儀の良いプラグインは、作法で以下のようにスコープを切っています。

コード: 全て選択

(function() {
...プラグインの処理
})();


これは別のローカルスコープ(別のプラグイン)から中で定義されたシンボルを参照されないためです。
参照できないシンボルのクラスをnewすることはできません。
アバター
トリアコンタン
記事: 1969
登録日時: 2015年11月10日(火) 21:13
お住まい: きのこ王国
連絡を取る:

Re: スクリプトに関する質問です

投稿記事by トリアコンタン » 2020年3月22日(日) 11:19

こんにちは!

グローバル変数化するという点に変わりはないのでアレですが、影響を最小限に留める方策として、クラスを格納するグローバルオブジェクトをひとつだけ作成して、そこに外部から参照させたいクラスを格納していく……という方法ならあると思います。

プラグインA

コード: 全て選択

var classObj = classObj || {};

(function() {
    function Window_Hoge() {
        this.initialize.apply(this, arguments);
    }

    Window_Hoge.prototype = Object.create(Window_Base.prototype);
    Window_Hoge.prototype.constructor = Window_Hoge;

    Window_Hoge.prototype.initialize = function(x, y, w, h) {
        Window_Base.prototype.initialize.call(this, x, y, w, h);
    };

    classObj.Window_Hoge = Window_Hoge;
})();


プラグインB(Scene_Titleになっているのは動作確認のためです)

コード: 全て選択

var classObj = classObj || {};
(function() {
    var Window_Hoge = classObj.Window_Hoge;

    Scene_Title.prototype.createHogeWindow = function() {
        this._hogeWindow = new Window_Hoge(0, 0, 100, 100);
        this.addWindow(this._hogeWindow);
    };

    var _Scene_Title_create = Scene_Title.prototype.create;
    Scene_Title.prototype.create = function() {
        _Scene_Title_create.apply(this, arguments);
        this.createHogeWindow();
    };
})();
プラグイン関連のトラブルが発生した際の切り分けと報告の方法です。
http://qiita.com/triacontane/items/2e227e5b5ce9503a2c30

[Blog] : http://triacontane.blogspot.jp/
[Twitter]: https://twitter.com/triacontane/
[GitHub] : https://github.com/triacontane/
アバター
しぐれん
記事: 741
登録日時: 2017年3月28日(火) 22:22
連絡を取る:

Re: スクリプトに関する質問です

投稿記事by しぐれん » 2020年3月22日(日) 11:52

Mano_InputConfigで使っている方法ですが、外から参照できるオブジェクトを即時間数の戻り値で送り出す方法があります。
この方法ならどういうクラスがあるかをVScodeで検出できるのでオススメです。
JavaScriptにおいては型の定義も変数なので、それを利用することでこういうことができます。

外部からシーンを切り替える時にSceneManager.push(Mano_InputConfig.Scene_GamepadConfig)で切り替える仕組みを入れてますが、この機能の応用です。
関係ないシーンでnew Mano_InputConfig.Window_GamepadConfig()すると普通に画面に出せたりします。
(あくまで例というだけで、保証外ですが)

コード: 全て選択

var Mano_InputConfig=( function(){
    'use strict'
//中略
const exportClass ={

    Scene_ConfigBase:Scene_InputConfigBase_MA,
    Scene_KeyConfig:Scene_KeyConfig_MA,
    Scene_GamepadConfig: Scene_GamepadConfigMA,
    Window_InputSymbolList:Window_InputSymbolList,
    Window_GamepadConfig:Window_GamepadConfig_MA,
    Window_KeyConfig:Window_KeyConfig_MA,
    symbolToButtonName:symbolToButtonName,
    symbolToButtonNumber:symbolToButtonNumber,
    gotoKey:function(){
        SceneManager.push(Mano_InputConfig.Scene_KeyConfig );
    },
    gotoGamepad:function(){
        SceneManager.push(Mano_InputConfig.Scene_GamepadConfig  );
    },
    unknowButtons:function(){
        return unknowSymbols(Input.gamepadMapper,setting.symbolList);
    },
    unknowKeys:function(){
        return unknowSymbols(Input.keyMapper,setting.symbolList);
    }
};

return exportClass;
})();
有償でプラグイン作成リクエストに対応します。
(4月28日から依頼受付再開しました)
アバター
にゃたま
記事: 782
登録日時: 2016年1月13日(水) 23:53
お住まい: 床下の猫王国
連絡を取る:

Re: スクリプトに関する質問です

投稿記事by にゃたま » 2020年3月23日(月) 03:26

Plasma Dark様
前回も回答いただきありがとうございます。
ホームページ(ブログ?)のほうも見させていただいたりしましたが
プログラマの如く詳しくって尊敬するしかないです。
一応(function() {で囲うとブロック化してそこから外を参照できないことは
解ってましたがそこをなんとか別のブロックにアクセスする方法を探ってました。


しぐれん様
インプットコンフィグでは大変お世話になっています。
そうでしたか…こちらのプラグインでも同様の手法を取り入れられているのですね…
ただ私にはちょっと難解すぎるようですorz
これでもできるということは参考になりますので勉強してみます(^^
今後の課題ということで…


トリアコンタン様
様々なプラグインでいつも大変お世話になっています。
結局トリアコンタン様の方法が一番わかりやすく実装しやすいものでした。
おかげさまで完成して実装したものが公開できました。
本当にありがとうございます。やはり師匠というほかありませんorz
これでこのトピックは解決済みとさせていただきます。

このトピックを見てくださった方もありがとうございました。

“MV:質問” へ戻る