RPGツクールMV

Window_Selectableで選択している項目におうじて表示を切り替えるウィンドウを作る

Window_SelectableのsetHelpWindowメソッドを使うと、選択している項目におうじて表示を切り替えるウィンドウを作ることができます。

↓こんなウィンドウが作れます。
RPGツクールMV Window_Selectableで選択した項目におうじて表示を切り替えるウィンドウを作る サンプルコード3実行結果

この記事では、setHelpWindowメソッドを使って選択している項目におうじて表示を切り替えるウィンドウを作る方法を解説します。

このブログの記事は厳密な正確さよりも、わかりやすさを重視して書いてあるので、あらかじめご了承ください。

武器を選択できる一覧を作る

とりあえず、てきとうにデータベース「武器」に登録されている項目を表示するウィンドウを作ってみます。

サンプルコード1

(function(){
    'use strict';

    var pluginName = "SelectableHelpWindowSample";
    
    // ----------プラグインコマンドの定義 ここから ----------
    var _Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
    
    Game_Interpreter.prototype.pluginCommand = function(command, args){
	_Game_Interpreter_pluginCommand.call(this, command, args);

	if(command === pluginName){
	    switch(args[0]){
	    case 'open':
                SceneManager.push(Scene_SelectableHelpWindowSample);
                break;
	    }
	}
    };
    // ----------プラグインコマンドの定義 ここまで ----------

    
    // ----------シーンの定義 ここから ----------    
    function Scene_SelectableHelpWindowSample(){
	this.initialize.apply(this, arguments);
    }

    Scene_SelectableHelpWindowSample.prototype = Object.create(Scene_MenuBase.prototype);
    Scene_SelectableHelpWindowSample.prototype.constructor = Scene_SelectableHelpWindowSample;

    Scene_SelectableHelpWindowSample.prototype.initialize = function(){
	Scene_MenuBase.prototype.initialize.call(this);
    };

    // ウィンドウの生成・追加
    Scene_SelectableHelpWindowSample.prototype.create = function(){
	Scene_MenuBase.prototype.create.call(this);
	
	this.createIndexWindow();
    };

    // 一覧ウィンドウ(Window_Selectable)生成
    Scene_SelectableHelpWindowSample.prototype.createIndexWindow = function(){
	var x = 0;
	var y = 120;
	var width = 300;
	var height = 500;
	
	this._indexWindow = new Window_MyIndexList(x, y, width, height);
	this.addWindow(this._indexWindow);
    };
    // ----------シーンの定義 ここまで ----------
    
    
    // ----------一覧ウィンドウの定義 ここから ----------
    function Window_MyIndexList (){
	this.initialize.apply(this, arguments);
    };

    Window_MyIndexList.prototype = Object.create(Window_Selectable.prototype);
    Window_MyIndexList.prototype.constructor = Window_MyIndexList;

    Window_MyIndexList.prototype.initialize = function(x, y, width, height){
	Window_Selectable.prototype.initialize.call(this, x, y, width, height);	
	this.createListItem();

	this.select(0);
	this.activate();
	this.refresh();
    };

    // 一覧のリストの設定
    Window_MyIndexList.prototype.createListItem = function(){
	this._data = [];

	// データベース:武器のインデックス0はnullなので、インデックス1から取得
	for(var i = 1; i < $dataWeapons.length; i++ ){
	    this._data.push($dataWeapons[i]);
	}
    };

    // ===Window_Selectableのメソッドをオーバーライド===    
    // これがないとdrawItemが実行されない
    Window_MyIndexList.prototype.maxItems = function(){
	return this._data  ? this._data.length : 0;
    };

    // 項目表示
    Window_MyIndexList.prototype.drawItem = function(index){
	if(this._data){
	    var item = this._data[index];
	    var rect = this.itemRect(index);
	    
	    this.drawText(item.name, rect.x, rect.y, this.width);
	}
    };
    // ----------一覧ウィンドウの定義 ここまで ----------
})();

サンプルコード1の実行結果

RPGツクールMV Window_Selectableで選択した項目におうじて表示を切り替えるウィンドウを作る プラグインコマンド呼び出し RPGツクールMV Window_Selectableで選択した項目におうじて表示を切り替えるウィンドウを作る サンプルコード1実行結果

Scene_MenuBaseから派生させた自作クラスScene_SelectableHelpWindowSampleと、Window_Selectableから派生させた自作クラスWindow_MyIndexListを定義し、ウィンドウを表示しています。

ここらへんはRPGツクールMVのプラグインで一覧から項目を選択するウィンドウを作るでも解説しているので、もしよければそちらも参考にしてください。

ヘルプウィンドウを表示する

つぎに、ヘルプウィンドウを作って説明を表示させてみます。

シーンの定義と一覧ウィンドウの定義にすこし追加しています。

サンプルコード2

    // ----------シーンの定義 ここから ----------    
    function Scene_SelectableHelpWindowSample(){
	this.initialize.apply(this, arguments);
    }

    Scene_SelectableHelpWindowSample.prototype = Object.create(Scene_MenuBase.prototype);
    Scene_SelectableHelpWindowSample.prototype.constructor = Scene_SelectableHelpWindowSample;

    Scene_SelectableHelpWindowSample.prototype.initialize = function(){
	Scene_MenuBase.prototype.initialize.call(this);
    };

    // ウィンドウの生成・追加
    Scene_SelectableHelpWindowSample.prototype.create = function(){
	Scene_MenuBase.prototype.create.call(this);
	
	this.createIndexWindow();
	this.createHelpWindow();
    };

    // 一覧ウィンドウ(Window_Selectable)生成
    Scene_SelectableHelpWindowSample.prototype.createIndexWindow = function(){
	var x = 0;
	var y = 120;
	var width = 300;
	var height = 500;
	
	this._indexWindow = new Window_MyIndexList(x, y, width, height);
	this.addWindow(this._indexWindow);
    };

    // ヘルプウィンドウ(Window_Help)生成
    Scene_SelectableHelpWindowSample.prototype.createHelpWindow = function(){
	this._helpWindow = new Window_Help();
	this._indexWindow.setHelpWindow(this._helpWindow);
	this.addWindow(this._helpWindow);
    };
    
    // ----------シーンの定義 ここまで ----------
    
    // ----------一覧ウィンドウの定義 ここから ----------
    function Window_MyIndexList (){
	this.initialize.apply(this, arguments);
    };

    Window_MyIndexList.prototype = Object.create(Window_Selectable.prototype);
    Window_MyIndexList.prototype.constructor = Window_MyIndexList;

    Window_MyIndexList.prototype.initialize = function(x, y, width, height){
	Window_Selectable.prototype.initialize.call(this, x, y, width, height);	
	this.createListItem();

	this.select(0);
	this.activate();
	this.refresh();
    };

    // 一覧のリストの設定
    Window_MyIndexList.prototype.createListItem = function(){
	this._data = [];

	// データベース:武器のインデックス0はnullなので、インデックス1から取得
	for(var i = 1; i < $dataWeapons.length; i++ ){
	    this._data.push($dataWeapons[i]);
	}
    };


    // 選択しているアイテム
    Window_MyIndexList.prototype.item = function(){
	return this._data ? this._data[this.index()] : null;
    }; 


    // ===Window_Selectableのメソッドをオーバーライド===    
    // これがないとdrawItemが実行されない
    Window_MyIndexList.prototype.maxItems = function(){
	return this._data  ? this._data.length : 0;
    };

    // 項目表示
    Window_MyIndexList.prototype.drawItem = function(index){
	if(this._data){
	    var item = this._data[index];
	    var rect = this.itemRect(index);
	    
	    this.drawText(item.name, rect.x, rect.y, this.width);
	}
    };

    // ヘルプウィンドウを更新
    Window_MyIndexList.prototype.updateHelp = function(){
	this.setHelpWindowItem(this.item());
    };
    // ----------一覧ウィンドウの定義 ここまで ----------

サンプルコード2の実行結果

RPGツクールMV Window_Selectableで選択した項目におうじて表示を切り替えるウィンドウを作る サンプルコード2実行結果

サンプルコード2の解説

Window_SelectableはhelpWindowという子ウィンドウを持っています。

Window_Selectableの setHelpWindow メソッドで、ヘルプウィンドウを設定できます。

setHelpWindow メソッドで設定するウィンドウは、RPGツクールMV内部(rpg_windows.js)で定義されているWindow_Helpか、Window_Helpから継承した(派生させた)ウィンドウを指定します。

つぎに、ヘルプウィンドウの更新処理を作ります。

Window_SelectableにはupdateHelpというメソッドが定義されています。

Window_Selectableではselectメソッドが実行されると、callUpdateHelpメソッドを経由してupdateHelpメソッドが呼ばれます。

Window_Selectableで定義されている元々のupdateHelpメソッドは、helpWindow.clearをしているだけで更新処理が書かれていないため、そのままではヘルプウィンドウが更新されません。

自作したWindow_MyIndexListに同名のメソッドを定義し、メソッドを上書き(オーバーライド)します。

Window_Selectableには引数で指定したオブジェクトをヘルプウィンドウに渡すsetHelpWindowItemメソッドがあるので、updateHelpメソッドの中で呼び出しています。

Window_Helpは、setHelpWindowItemメソッドで渡されたアイテムのdescriptionプロパティの値をウィンドウに表示します。

文字以外も表示できるヘルプウィンドウを作る

Window_Helpをそのまま使うと、ちょっと不便なところもあります。

  • ウィンドウの位置やサイズをインスタンス生成時に指定できない
  • descriptionプロパティを持ったオブジェクトしか渡せない
  • テキストしか表示できない

そこで、HelpWindowから派生させたWindow_HelpExを作って便利にしてみます。

サンプルコード3

    // ----------シーンの定義 ここから ----------    
    function Scene_SelectableHelpWindowSample(){
	this.initialize.apply(this, arguments);
    }

    Scene_SelectableHelpWindowSample.prototype = Object.create(Scene_MenuBase.prototype);
    Scene_SelectableHelpWindowSample.prototype.constructor = Scene_SelectableHelpWindowSample;

    Scene_SelectableHelpWindowSample.prototype.initialize = function(){
	Scene_MenuBase.prototype.initialize.call(this);
    };

    // ウィンドウの生成・追加
    Scene_SelectableHelpWindowSample.prototype.create = function(){
	Scene_MenuBase.prototype.create.call(this);
	
	this.createIndexWindow();
	this.createHelpWindow();
    };

    // 一覧ウィンドウ(Window_Selectable)生成
    Scene_SelectableHelpWindowSample.prototype.createIndexWindow = function(){
	var x = 0;
	var y = 120;
	var width = 300;
	var height = 500;
	
	this._indexWindow = new Window_MyIndexList(x, y, width, height);
	this.addWindow(this._indexWindow);
    };

    // ヘルプウィンドウ(Window_Help)生成
    Scene_SelectableHelpWindowSample.prototype.createHelpWindow = function(){
	var x = this._indexWindow.x + this._indexWindow.width + 20;
	var y = this._indexWindow.y;
	var width = 480;
	var height = this._indexWindow.height;
	
	this._helpWindow = new Window_HelpEx(x, y, width, height);
	
	this._indexWindow.setHelpWindow(this._helpWindow);
	this.addWindow(this._helpWindow);
    };
    
    // ----------シーンの定義 ここまで ----------    
  
    // ----------ヘルプウィンドウの定義 ここから ----------
    function Window_HelpEx(){
	this.initialize.apply(this, arguments);
    };

    Window_HelpEx.prototype = Object.create(Window_Help.prototype);
    Window_HelpEx.prototype.constructor = Window_HelpEx;

    Window_HelpEx.prototype.initialize = function(x, y, width, height){
	this._item = null;
	Window_Base.prototype.initialize.call(this, x, y, width, height);
    };

    Window_HelpEx.prototype.setItem = function(item){
	this._item = item;
	this.refresh();
    };

    Window_HelpEx.prototype.refresh = function(){
	this.contents.clear();
	this.createContents();
	this.drawContent();
    };
    
    Window_HelpEx.prototype.drawContent = function(){
	if(this._item){
	    this.drawItemName(this._item, 0, 0, this.width);	    
	    this.drawText("<" + this._item.name + "の詳細説明>", 0, this.lineHeight() * 2, this.width);
	}    
    };
    // ----------ヘルプウィンドウの定義 ここまで ----------

※一覧ウィンドウの定義のあとに、ヘルプウィンドウの定義を追加。

サンプルコード3実行結果

RPGツクールMV Window_Selectableで選択した項目におうじて表示を切り替えるウィンドウを作る サンプルコード3実行結果

サンプルコード3解説

Window_SelectableとWindow_Helpの処理をみて、どこをオーバーライドするかを考えます。

rpg_window.jsのコードを追っていくと、

  1. Window_SelectableのsetHelpWindowItemメソッドからWindow_HelpのsetItemメソッドが呼ばれる
  2. Window_Helpは引数で渡されたオブジェクトのdescriptionプロパティを引数にして、自身のsetTextメソッドを呼び出す
  3. setTextメソッド内で、内部プロパティにdescriptionの値を代入し、refreshメソッドを呼び出す
  4. refreshメソッド内でdrawTextExでテキストを書きだす

という処理をしていることがわかりました。

2番めのdescriptionを渡してsetTextメソッドを呼び出すところと、最後のrefreshメソッドの描画内容を変更したのが変更後のコードになります。
(3番めのsetTextメソッドは使わないように変更)

ウィンドウの内容を描画する処理は個別にわけた方が見やすいので、新しくdrawContentメソッドを作ってrefreshメソッドから呼び出すことにしました。

setItemメソッドでdescriptionの値ではなく渡されたオブジェクトをそのまま使うようにしたので、description以外のプロパティの値も使えます。

選択している項目におうじて表示を切り替えるウィンドウを作るまとめ

まとめ
  • Window_Selectableを元にしたウィンドウクラスを作る
  • setHelpWindowメソッドを使って、Window_Helpを設定
  • Window_SelectableのupdateHelpをオーバーライドする
  • descriptionプロパティ以外の値を表示させたい時はWindow_Helpを元にしたウィンドウクラスを作る
(function(){
    'use strict';

    var pluginName = "SelectableHelpWindowSample";
    
    // ----------プラグインコマンドの定義 ここから ----------
    var _Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
    
    Game_Interpreter.prototype.pluginCommand = function(command, args){
	_Game_Interpreter_pluginCommand.call(this, command, args);

	if(command === pluginName){
	    switch(args[0]){
	    case 'open':
                SceneManager.push(Scene_SelectableHelpWindowSample);
                break;
	    }
	}
    };
    // ----------プラグインコマンドの定義 ここまで ----------

    
    // ----------シーンの定義 ここから ----------    
    function Scene_SelectableHelpWindowSample(){
	this.initialize.apply(this, arguments);
    }

    Scene_SelectableHelpWindowSample.prototype = Object.create(Scene_MenuBase.prototype);
    Scene_SelectableHelpWindowSample.prototype.constructor = Scene_SelectableHelpWindowSample;

    Scene_SelectableHelpWindowSample.prototype.initialize = function(){
	Scene_MenuBase.prototype.initialize.call(this);
    };

    // ウィンドウの生成・追加
    Scene_SelectableHelpWindowSample.prototype.create = function(){
	Scene_MenuBase.prototype.create.call(this);
	
	this.createIndexWindow();
	this.createHelpWindow();
    };

    // 一覧ウィンドウ(Window_Selectable)生成
    Scene_SelectableHelpWindowSample.prototype.createIndexWindow = function(){
	var x = 0;
	var y = 120;
	var width = 300;
	var height = 500;
	
	this._indexWindow = new Window_MyIndexList(x, y, width, height);
	this.addWindow(this._indexWindow);
    };

    // ヘルプウィンドウ(Window_Help)生成
    Scene_SelectableHelpWindowSample.prototype.createHelpWindow = function(){
	var x = this._indexWindow.x + this._indexWindow.width + 20;
	var y = this._indexWindow.y;
	var width = 480;
	var height = this._indexWindow.height;
	
	this._helpWindow = new Window_HelpEx(x, y, width, height);
	
	this._indexWindow.setHelpWindow(this._helpWindow);
	this.addWindow(this._helpWindow);
    };
    
    // ----------シーンの定義 ここまで ----------    
    
    // ----------一覧ウィンドウの定義 ここから ----------
    function Window_MyIndexList (){
	this.initialize.apply(this, arguments);
    };

    Window_MyIndexList.prototype = Object.create(Window_Selectable.prototype);
    Window_MyIndexList.prototype.constructor = Window_MyIndexList;

    Window_MyIndexList.prototype.initialize = function(x, y, width, height){
	Window_Selectable.prototype.initialize.call(this, x, y, width, height);	
	this.createListItem();

	this.select(0);
	this.activate();
	this.refresh();
    };

    // 一覧のリストの設定
    Window_MyIndexList.prototype.createListItem = function(){
	this._data = [];

	// データベース:武器のインデックス0はnullなので、インデックス1から取得
	for(var i = 1; i < $dataWeapons.length; i++ ){
	    this._data.push($dataWeapons[i]);
	}
    };


    // 選択しているアイテム
    Window_MyIndexList.prototype.item = function(){
	return this._data ? this._data[this.index()] : null;
    }; 


    // ===Window_Selectableのメソッドをオーバーライド===    
    // これがないとdrawItemが実行されない
    Window_MyIndexList.prototype.maxItems = function(){
	return this._data  ? this._data.length : 0;
    };

    // 項目表示
    Window_MyIndexList.prototype.drawItem = function(index){
	if(this._data){
	    var item = this._data[index];
	    var rect = this.itemRect(index);
	    
	    this.drawText(item.name, rect.x, rect.y, this.width);
	}
    };

    // ヘルプウィンドウを更新
    Window_MyIndexList.prototype.updateHelp = function(){
	this.setHelpWindowItem(this.item());
    };
    // ----------一覧ウィンドウの定義 ここまで ----------

    
    // ----------ヘルプウィンドウの定義 ここから ----------
    function Window_HelpEx(){
	this.initialize.apply(this, arguments);
    };

    Window_HelpEx.prototype = Object.create(Window_Help.prototype);
    Window_HelpEx.prototype.constructor = Window_HelpEx;

    Window_HelpEx.prototype.initialize = function(x, y, width, height){
	this._item = null;
	Window_Base.prototype.initialize.call(this, x, y, width, height);
    };

    Window_HelpEx.prototype.setItem = function(item){
	this._item = item;
	this.refresh();
    };

    Window_HelpEx.prototype.refresh = function(){
	this.contents.clear();
	this.createContents();
	this.drawContent();
    };
    
    Window_HelpEx.prototype.drawContent = function(){
	console.log('drawContent');
	
	if(this._item){
	    this.drawItemName(this._item, 0, 0, this.width);	    
	    this.drawText("<" + this._item.name + "の詳細説明>", 0, this.lineHeight() * 2, this.width);
	}    
    };
    // ----------ヘルプウィンドウの定義 ここまで ----------
})();

setHelpWindowItemメソッドで渡すitemはどんな値でもいいので、オブジェクトを自作して、独自のメニューを作ってみてもよいかと思います。

RPGツクールMV Window_Selectableで選択した項目におうじて表示を切り替えるウィンドウを作る おまけ実行結果独自オブジェクトを使って行先選択システムっぽいのを作ってみた