ページ 11

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

Posted: 2020年3月22日(日) 10:32
by にゃたま
今回はスクリプトに関する質問です。

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

通常以下のようにすれば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);
	};
})();

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

Posted: 2020年3月22日(日) 11:11
by Plasma Dark
別のローカルスコープのシンボルを参照しようとする場合、スコープそのものに名前がついている必要があります。

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

コード: 全て選択

(function() {
...プラグインの処理
})();
これは別のローカルスコープ(別のプラグイン)から中で定義されたシンボルを参照されないためです。
参照できないシンボルのクラスをnewすることはできません。

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

Posted: 2020年3月22日(日) 11:19
by トリアコンタン
こんにちは!

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

プラグイン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();
    };
})();

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

Posted: 2020年3月22日(日) 11:52
by しぐれん
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;
})();

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

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


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


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

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