Window_Selectableでボタンを押したときの処理を作るには、以下のように setHandler メソッドを使って、実行したいメソッドを指定する必要があります。
Scene_IndexMenuBase.prototype.create = function(){ Scene_MenuBase.prototype.create.call(this); // ウィンドウの生成 this.createIndexWindow(); }; // 一覧ウィンドウの生成 Scene_IndexMenuBase.prototype.createIndexWindow = function(){ //ボタンを押した時に呼び出すメソッドの設定 this._indexWindow.setHandler('ok', this.onIndexOk.bind(this)); this._indexWindow.setHandler('cancel', this.onIndexCancel.bind(this)); this.addWindow(this._indexWindow); }; // 一覧で決定した時の処理 Scene_IndexMenuBase.prototype.onIndexOk = function(){ //ボタンを押した時の処理 }; // 一覧でキャンセルした時の処理 Scene_IndexMenuBase.prototype.onIndexCancel = function(){ this.popScene(); };
ボタンが1つならまだいいですが、確認ボタンなども作ったりするとボタン処理を書くのが面倒です。
そこでキャンセルした時などの共通処理をまとめるSceneを定義したIndexMenuBase.jsを作ってみました。
Window_Selectableの共通処理をまとめるScene
//============================================================================= // IndexMenuBase.js // 一覧ウィンドウのボタン処理を共通化 //============================================================================= // ----------シーンの定義 ここから ---------- function Scene_IndexMenuBase(){ this.initialize.apply(this, arguments); } Scene_IndexMenuBase.prototype = Object.create(Scene_MenuBase.prototype); Scene_IndexMenuBase.prototype.constructor = Scene_IndexMenuBase; Scene_IndexMenuBase.prototype.initialize = function(indexWindow){ this._confirm = true; this._indexWindow = indexWindow; Scene_MenuBase.prototype.initialize.call(this); }; // =============================================== // 1.ウィンドウの生成・追加 // =============================================== Scene_IndexMenuBase.prototype.create = function(){ Scene_MenuBase.prototype.create.call(this); // ウィンドウの生成・追加 this.addIndexWindow(); this.createConfirmWindow(); // 確認ウィンドウは非表示 this.hideConfirmWindow(); }; // 一覧ウィンドウの追加 Scene_IndexMenuBase.prototype.addIndexWindow = function(){ //ボタンを押した時の設定 this._indexWindow.setHandler('ok', this.onIndexOk.bind(this)); this._indexWindow.setHandler('cancel', this.onIndexCancel.bind(this)); this.addWindow(this._indexWindow); }; // 確認メッセージウィンドウの生成と追加 Scene_IndexMenuBase.prototype.createConfirmWindow = function(){ this._confirmWindow = new Window_Confirm(); this._confirmCommand = new Window_CommandYesNo(); // ボタンを押した時の設定 this._confirmCommand.setHandler('commandYes', this.onConfirmYes.bind(this)); this._confirmCommand.setHandler('commandNo', this.onConfirmNo.bind(this)); this._confirmCommand.setHandler('cancel', this.onConfirmCancel.bind(this)); this.addWindow(this._confirmWindow); this.addWindow(this._confirmCommand); }; // =============================================== // 2.ボタン処理 // =============================================== // =============================================== // 2-1. 一覧ウィンドウのボタン処理 // =============================================== // 一覧で決定ボタンを押した時の処理 Scene_IndexMenuBase.prototype.onIndexOk = function(){ if(this._confirm){ // 確認メッセージをセットして呼びだす this._confirmWindow.setMessage(this.confirmMessage()); this.showConfirmWindow(); } else { this.execute(); } }; // 一覧でキャンセルした時の処理 Scene_IndexMenuBase.prototype.onIndexCancel = function(){ this.popScene(); }; // =============================================== // 2-2. 確認コマンドウィンドウのボタン処理 // =============================================== // 確認コマンドで「はい」を押した時の処理 Scene_IndexMenuBase.prototype.onConfirmYes = function(){ this.execute(); }; // 確認コマンドで「いいえ」を押した時の処理 Scene_IndexMenuBase.prototype.onConfirmNo = function(){ this.hideConfirmWindow(); }; // 確認コマンドでキャンセルした時の処理 Scene_IndexMenuBase.prototype.onConfirmCancel = function(){ this.hideConfirmWindow(); }; // =============================================== // 3.ウィンドウ制御 // =============================================== // 確認ウィンドウを表示する Scene_IndexMenuBase.prototype.showConfirmWindow = function(){ this._confirmWindow.show(); this._confirmCommand.show(); this._confirmCommand.activate(); }; // 確認ウィンドウを非表示にする Scene_IndexMenuBase.prototype.hideConfirmWindow = function(){ this._confirmWindow.hide(); this._confirmCommand.hide(); this._confirmCommand.deactivate(); this._indexWindow.activate(); }; // =============================================== // 4.設定 // =============================================== // 一覧で決定ボタンを押した時に確認メッセージを表示するか? // デフォルトはtrue Scene_IndexMenuBase.prototype.setConfirm = function(confirm){ this._confirm = confirm; }; // =============================================== // 5.オーバーライド用メソッド // =============================================== // 確認用メッセージ Scene_IndexMenuBase.prototype.confirmMessage = function(){ return this._confirmWindow.message(); }; // 実行する時の処理(確認で「はい」を押したか、確認がオフの時に実行) Scene_IndexMenuBase.prototype.execute = function(){ this.hideConfirmWindow(); }; // ----------シーンの定義 ここまで ---------- // ----------確認メッセージウィンドウの定義 ここから ---------- function Window_Confirm(){ this.initialize.apply(this, arguments); } Window_Confirm.prototype = Object.create(Window_Base.prototype); Window_Confirm.prototype.constructor = Window_Confirm; Window_Confirm.prototype.initialize = function(x, y, width, height){ this._message = "本当に実行しますか?"; Window_Base.prototype.initialize.call(this, x, y, width, height); }; // 確認メッセージ設定 Window_Confirm.prototype.setMessage = function(message){ this._message = message; this.refresh(); }; Window_Confirm.prototype.message = function(){ return this._message; }; // 更新処理 Window_Confirm.prototype.refresh = function(){ this.contents.clear(); this.createContents(); this.drawText(this._message, 0, 0, this.width); }; // ----------確認メッセージウィンドウの定義 ここまで ---------- // ----------確認コマンドウィンドウの定義 ここから ---------- function Window_CommandYesNo(){ this.initialize.apply(this, arguments); }; Window_CommandYesNo.prototype = Object.create(Window_Command.prototype); Window_CommandYesNo.prototype.constructor = Window_CommandYesNo; Window_CommandYesNo.prototype.initialize = function(x, y){ this._yesLabel = "はい"; this._noLabel = "いいえ"; this._defaultCommandIndex = 0; Window_Command.prototype.initialize.call(this, x, y); }; Window_CommandYesNo.prototype.makeCommandList = function(){ this.addCommand(this._yesLabel, 'commandYes', true); this.addCommand(this._noLabel, 'commandNo', true); }; Window_CommandYesNo.prototype.setYesLabel = function(label){ this._yesLabel = label; this.refresh(); }; Window_CommandYesNo.prototype.setNoLabel = function(label){ this._noLabel = label; this.refresh(); }; Window_CommandYesNo.prototype.setDefaultCommandIndex = function(index){ this._defaultCommandIndex = index; }; Window_CommandYesNo.prototype.activate = function(){ Window_Command.prototype.activate.call(this); this.select(this._defaultCommandIndex); }; // ----------確認コマンドウィンドウの定義 ここまで ----------
IndexMenuBase.jsを再利用して建設メニューっぽいものを作る
IndexMenuBase.jsを利用して、建設メニューを表示するBuildMenu.jsを作ってみました。
サンプルコード
//============================================================================= // BuildMenu.js // IndexMenuBase.jsを使って建設メニューを作るサンプル //============================================================================= (function(){ 'use strict'; var pluginName = "BuildMenu"; // ----------プラグインコマンドの定義 ここから ---------- 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_BuildMenu); break; } } }; // ----------プラグインコマンドの定義 ここまで ---------- // ----------シーンの定義 ここから ---------- // Scene_IndexMenuBaseを再利用 function Scene_BuildMenu(){ this.initialize.apply(this, arguments); } Scene_BuildMenu.prototype = Object.create(Scene_IndexMenuBase.prototype); Scene_BuildMenu.prototype.constructor = Scene_BuildMenu; Scene_BuildMenu.prototype.initialize = function(){ this._indexWindow = new Window_BuildMenu(0, 100, 300, 400); Scene_IndexMenuBase.prototype.initialize.call(this, this._indexWindow); }; // =============================================== // 1.ウィンドウの生成・追加 // =============================================== Scene_BuildMenu.prototype.create = function(){ Scene_IndexMenuBase.prototype.create.call(this); // ウィンドウの生成・追加 this.createTitleWindow(); this.createGoldWindow(); this.createHelpWindow(); this._indexWindow.setMoney(this._goldWindow.value()); // 確認ウィンドウの位置調整 this.setConfirmWindowPosition(); }; // タイトルウィンドウ(Window_Help)の生成 Scene_BuildMenu.prototype.createTitleWindow = function(){ this._titleWindow = new Window_Help(1); this._titleWindow.width = this._indexWindow.width; this._titleWindow.setText("建設メニュー"); this.addWindow(this._titleWindow); }; // ゴールドウィンドウ(Window_Gold)の生成 Scene_BuildMenu.prototype.createGoldWindow = function(){ this._goldWindow = new Window_Gold(0, 0); this._goldWindow.x = Graphics.width - this._goldWindow.width; this.addWindow(this._goldWindow); }; // ヘルプウィンドウ(Window_BuildHelp)の生成 Scene_BuildMenu.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_BuildHelp(x, y, width, height); this._indexWindow.setHelpWindow(this._helpWindow); this.addWindow(this._helpWindow); }; // 確認ウィンドウの位置調整 Scene_BuildMenu.prototype.setConfirmWindowPosition = function(){ // 確認メッセージウィンドウ this._confirmWindow.x = 0; this._confirmWindow.y = this._indexWindow.y + this._indexWindow.height + 10; this._confirmWindow.width = Graphics.width - 280; this._confirmWindow.height = 110; // 確認コマンドの位置 this._confirmCommand.x = this._confirmWindow.x + this._confirmWindow.width + 20; this._confirmCommand.y = this._confirmWindow.y; this._confirmWindow.refresh(); }; // 確認メッセージのオーバーライド Scene_BuildMenu.prototype.confirmMessage = function(){ return this._indexWindow.item().name() + "を作成しますか?"; }; // 一覧実行処理のオーバーライド Scene_BuildMenu.prototype.execute = function(){ console.log("-----ここに実行した時の処理を書く-----"); var buildItem = this._indexWindow.item(); $gameSwitches.setValue(buildItem.id(), true); $gameParty.loseGold(buildItem.price()); this._goldWindow.refresh(); this._indexWindow.setMoney(this._goldWindow.value()); Scene_IndexMenuBase.prototype.execute.call(this); }; // ----------シーンの定義 ここまで ---------- // ----------一覧ウィンドウの定義 ここから ---------- function Window_BuildMenu (){ this.initialize.apply(this, arguments); }; Window_BuildMenu.prototype = Object.create(Window_Selectable.prototype); Window_BuildMenu.prototype.constructor = Window_BuildMenu; Window_BuildMenu.prototype.initialize = function(x, y, width, height){ this._money = 0; this.createListItem(); Window_Selectable.prototype.initialize.call(this, x, y, width, height); this.select(0); this.activate(); this.refresh(); }; Window_BuildMenu.prototype.maxItems = function(){ return this._data ? this._data.length : 0; }; // 選択しているアイテム // this._dataが設定されていない時はnullが返る Window_BuildMenu.prototype.item = function(){ return this._data ? this._data[this.index()]: null; }; Window_BuildMenu.prototype.isCurrentItemEnabled = function() { return this.isEnabled(this.item()); }; Window_BuildMenu.prototype.isEnabled = function(item){ return this._money >= item.price(); }; Window_BuildMenu.prototype.setMoney = function(money){ this._money = money; this.refresh(); }; Window_BuildMenu.prototype.createListItem = function(){ this._data = []; this._data.push(new BuildItem(1, '木の家', 1000, '住民が増える')); this._data.push(new BuildItem(2, '農場', 5000, '家畜が飼える')); this._data.push(new BuildItem(3, '診療所', 8000, 'HPの回復ができる')); }; // 一覧の表示をオーバーライド Window_BuildMenu.prototype.drawItem = function(index){ var buildItem = this._data[index]; var rect = this.itemRect(index); this.changePaintOpacity(this.isEnabled(buildItem)); this.drawText(buildItem.name(), rect.x, rect.y, 100); }; Window_BuildMenu.prototype.updateHelp = function(){ this.setHelpWindowItem(this.item()); }; // ----------一覧ウィンドウの定義 ここまで ---------- // ----------ヘルプウィンドウの定義 ここから ---------- function Window_BuildHelp(){ this.initialize.apply(this, arguments); }; Window_BuildHelp.prototype = Object.create(Window_Help.prototype); Window_BuildHelp.prototype.constructor = Window_BuildHelp; Window_BuildHelp.prototype.initialize = function(x, y, width, height){ this._item = null; Window_Base.prototype.initialize.call(this, x, y, width, height); }; Window_BuildHelp.prototype.setItem = function(item){ this._item = item; this.refresh(); }; Window_BuildHelp.prototype.refresh = function(){ this.contents.clear(); this.drawContent(); }; Window_BuildHelp.prototype.drawContent = function(){ if(this._item){ var buildItem = this._item; var units = TextManager.currencyUnit; this.drawText(buildItem.name(), 0, 0, this.width); this.drawText("費用: " + this._item.price() + units, 0, this.lineHeight() * 2, this.width); this.drawText("効果: ", 0, this.lineHeight() * 4, this.width); this.drawText(buildItem.description(), 20, this.lineHeight() * 5, this.width); } }; // ----------ヘルプウィンドウの定義 ここから ---------- // ----------建物オブジェクトの定義 ここから ---------- function BuildItem(id, name, price, description){ this._id = id; this._name = name; this._price = price; this._description = description; }; BuildItem.prototype.id = function(){ return this._id; }; BuildItem.prototype.name = function(){ return this._name; }; BuildItem.prototype.price = function(){ return this._price; }; BuildItem.prototype.description = function(){ return this._description; }; // ----------建物オブジェクトの定義 ここまで ---------- })();
サンプルコード実行結果


確認ウィンドウの生成やボタンを押したときの処理をIndexMenuBase.jsにまとめたおかげで、BuildMenu.jsの記述がすこし短くなりました。
プラグインを追加するときは、IndexMenuBase.jsをBuildMenu.jsの前に読み込む必要があります。
ツール→プラグイン管理のリストの上から順番に読み込まれるので、IndexMenuBase→BuildMenuの順番にしておきます。
確認ウィンドウで「はい」を押した時にはScene_IndexMenuBaseの execute メソッドが実行されるので、呼び出し側(Scene_BuildMenu)でexecuteメソッドを上書き(オーバーライド)してやればいいです。
確認ウィンドウに表示されるメッセージは、confirmMessageメソッドで定義しています。
こちらもオーバーライドすることで、好きなメッセージを表示することができます。
選択している項目はthis._indexWindow.item()で取得できます。
サンプルコードでは、BuildItemという独自のクラス(オブジェクト)を作っています。
確認ウィンドウを表示するかしないかはsetConfirmメソッドを使って切り替えることができます。
// =============================================== // 1.ウィンドウの生成・追加 // =============================================== Scene_BuildMenu.prototype.create = function(){ Scene_IndexMenuBase.prototype.create.call(this); // ウィンドウの生成・追加 this.createTitleWindow(); this.createGoldWindow(); this.createHelpWindow(); this._indexWindow.setMoney(this._goldWindow.value()); // 確認ウィンドウの位置調整 // this.setConfirmWindowPosition(); // 一覧で決定した時に確認をしない this.setConfirm(false); };
確認コマンドは、はい/いいえの文言と、デフォルトの選択肢を変更できます。
Scene_BuildMenu.prototype.create = function(){ Scene_IndexMenuBase.prototype.create.call(this); // ウィンドウの生成・追加 this.createTitleWindow(); this.createGoldWindow(); this.createHelpWindow(); this._indexWindow.setMoney(this._goldWindow.value()); // 確認ウィンドウの位置調整 this.setConfirmWindowPosition(); // 確認コマンドの表示文字を変更 this._confirmCommand.setYesLabel('OK!'); this._confirmCommand.setNoLabel('ダメ!'); this._confirmCommand.setDefaultCommandIndex(1); };

データを変えれば、いろいろなメニューを作ることができます。