RPGツクールMVのプラグインでウィンドウを表示する方法の解説記事です。
このブログの記事は厳密な正確さよりも、わかりやすさを重視して書いてあるので、あらかじめご了承ください。
自作ウィンドウにはSceneクラスとWindowクラスが必要
自作ウィンドウを表示するには、プラグインの中で
- Sceneクラス
- Windowクラス
を定義してあげる必要があります。
Sceneクラスでは、ウィンドウの生成の処理とボタンが押された時の処理などを定義します。
Windowクラスでは、実際にウィンドウに表示する内容などを定義します。
- クラスとは?
-
オブジェクトにどんなメソッドやプロパティがあるか定義するフォーマットのこと。
オブジェクトはクラスを元に作られています。
ウィンドウとか作るときに、1回1回ゼロから作るのは大変だからあらかじめウィンドウのフォーマットを決めておいて、フォーマットからコピーしてウィンドウを作る的な感じです。
作ったクラス(フォーマット)を元に、別のクラスを作ることもあります。(継承という)
クラスから作られたオブジェクトは、フォーマットとなったクラスがもつメソッドとプロパティを持ちます。
クラスからオブジェクトを作ったあとで、独自のメソッドやプロパティを追加することも可能です。
クラスから作られたオブジェクトのことをインスタンスともいいます。
また、クラスからオブジェクトを作ることをインスタンス化といいます。
クラスからオブジェクトを作ったとき(インスタンス化したとき)、オブジェクトのinitializeメソッドが自動で実行されます。
元になるSceneとWindowを決める
RPGツクールMVではメニューやステータス画面など、すでにいくつかのSceneクラスとWindowクラスが定義されています。
すでにあるクラスと同じ処理でいい場合は、すでにあるクラスからオブジェクトを作ればいいです。
処理を変えたければ、すでにあるクラスで処理内容が近いものをベースにして自作クラスを作り、自作クラスからオブジェクトを作ります。
近いものがない場合は、Scene_BaseやWindow_Baseを元にクラスを作っていきます。
RPGツクールMVのシーンクラス一覧
Scene名 | 内容 |
---|---|
Scene_Base | すべてのSceneの親クラス |
Scene_Boot | ゲーム起動時のシーン |
Scene_Title | タイトル画面 |
Scene_Map | マップ画面 |
Scene_MenuBase | すべてのメニューシーンの親クラス |
Scene_Menu | メニュー画面 |
Scene_ItemBase | アイテム画面(Scene_Item)、 スキル画面(Scene_Skill)の親クラス |
Scene_Item | アイテム画面 |
Scene_Skill | スキル画面 |
Scene_Equip | 装備画面 |
Scene_Status | ステータス画面 |
Scene_Option | オプション画面 |
Scene_File | セーブ画面(Scene_Save)、 ロード画面(Scene_Load)の親クラス |
Scene_Save | セーブ画面 |
Scene_Load | ロード画面 |
Scene_GameEnd | ゲーム終了画面 (メニューからゲーム終了を選んだ時の画面) |
Scene_Shop | ショップ画面 |
Scene_Name | 名前入力画面 |
Scene_Debug | デバッグ画面 |
Scene_Battle | 戦闘画面 |
Scene_Gameover | ゲームオーバー画面 |
RPGツクールMVのウィンドウ一覧
クラス名 | 説明 |
---|---|
Window_Base | すべてのウィンドウの親クラス |
Window_Selectable | 一覧から項目を選択できるウィンドウ |
Window_ItemList | パーティが持っているアイテムの一覧を表示するウィンドウ |
Window_EquipItem | 装備画面で装備を選択するウィンドウ |
Window_EventItem | イベントコマンド「アイテム選択の処理」でアイテムを選択するウィンドウ |
Window_BattleItem | 戦闘画面でアイテムを選択するウィンドウ |
Window_ShopSell | ショップ画面でアイテムを売る時にアイテムを選択するウィンドウ |
Window_ShopBuy | ショップ画面でアイテムを買う時のウィンドウ |
Window_ShopNumber | ショップ画面で買う・売る時の個数を入力するウィンドウ |
Window_SkillList | スキルの一覧を表示するウィンドウ |
Window_BattleSkill | 戦闘画面でスキルを選択するウィンドウ |
Window_EquipSlot | 装備部位を選択するウィンドウ |
Window_Status | ステータス画面のウィンドウ |
Window_MenuStatus | メニュー画面でパーティーメンバーのステータスを表示するウィンドウ |
Window_MenuActor | メニュー画面でアクターを表示するウィンドウ |
Window_NumberInput | イベント「数値入力の処理」で数値を入力するウィンドウ |
Window_BattleLog | 戦闘画面のログを表示させるウィンドウ |
Window_BattleStatus | 戦闘画面のステータスを表示させるウィンドウ |
Window_BattleActor | 戦闘画面で味方を選択するためのウィンドウ |
Window_BattleEnemy | 戦闘画面で敵を選択するためのウィンドウ |
Window_SavefileList | セーブ・ロード画面でファイルを選択するウィンドウ |
Window_Command | コマンドを持つウィンドウ |
Window_HorzCommand | 横に並んだコマンドを持つウィンドウ |
Window_ItemCategory | アイテム画面とショップ画面でアイテムの種類を選択するウィンドウ |
Window_EquipCommand | 装備画面で装備コマンドを表示するウィンドウ |
Window_ShopCommand | ショップ画面で買う・売るを表示するコマンド |
Window_MenuCommand | メニューコマンドを表示するウィンドウ |
Window_SkillType | スキル画面でスキルの種類を選択するウィンドウ |
Window_GameEnd | ゲーム終了画面のコマンドを表示するウィンドウ |
Window_ChoiceList | イベント「選択肢の表示」で選択肢を表示するウィンドウ |
Window_PartyCommand | 戦闘画面でパーティ全体コマンド(逃げるなど)を表示するウィンドウ |
Window_ActorCommand | 戦闘画面でキャラごとのコマンドを表示するウィンドウ |
Window_Options | オプション画面で設定を表示するウィンドウ |
Window_TitleCommand | タイトル画面でコマンドを表示するウィンドウ |
Window_NameInput | イベント「名前入力の処理」で入力する文字を選択するウィンドウ |
Window_DebugRange | デバッグ画面でスイッチと変数を表示するウィンドウ |
Window_DebugEdit | デバッグ画面でスイッチと変数を表示するウィンドウ |
Window_Message | テキストを表示するウィンドウ |
Window_ScrollText | スクロールするテキストを表示するウィンドウ |
Window_MapName | マップ名を表示するウィンドウ |
Window_SkillStatus | スキル画面でステータスを表示するウィンドウ |
Window_EquipStatus | 装備画面でステータスを表示するウィンドウ |
Window_ShopStatus | ショップ画面でステータスを表示するウィンドウ |
Window_Help | アイテムやスキルの説明テキストを表示させるウィンドウ |
Window_Gold | 所持金を表示するウィンドウ |
Window_NameEdit | イベント「名前入力の処理」でアクター名を表示するウィンドウ |
ただウィンドウを表示するだけのプラグインを作ってみる
ただウィンドウを表示するだけのプラグイン、MyWindowTest.jsを作ってみます。
SceneクラスはScene_Baseを元にScene_MyWindowクラスを作ります。
Windowクラスはテキストをそのまま表示するだけなので、自作クラスは作らずにWindow_Baseクラスからオブジェクトを作ります。
プラグインコマンドshowでウィンドウを呼び出すようにしています。
サンプルコード1
// ====================== // MyWindowTest.js // ====================== /*: * @plugindesc Test Create Window * @author Moooty * * @help * Plugin Command: * MyWindowTest show #Open window. */ /*:ja * @plugindesc ウィンドウ作成テスト * @author むーてぃ * * @help * プラグインコマンド: * MyWindowTest show #ウィンドウを開く */ (function(){ 'use strict'; var pluginName = "MyWindowTest"; // ----------プラグインコマンドの定義 ここから ---------- 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 'show': SceneManager.push(Scene_MyWindow); break; } } }; // ----------プラグインコマンドの定義 ここまで ---------- // ----------Sceneの定義 ここから ---------- function Scene_MyWindow(){ this.initialize.apply(this, arguments); } // 自作Sceneの元になるSceneを定義 Scene_MyWindow.prototype = Object.create(Scene_Base.prototype); Scene_MyWindow.prototype.constructor = Scene_MyWindow; // Sceneを生成した時の処理(親クラスのinitializeメソッドに自分を渡して呼びだし) Scene_MyWindow.prototype.initialize = function(){ Scene_Base.prototype.initialize.call(this); }; // ウィンドウの作成 Scene_MyWindow.prototype.create = function(){ Scene_Base.prototype.create.call(this); this.createWindowLayer(); this.createMainWindow(); this._mainWindow.drawText('Hello, World!', 0, 0, this._mainWindow.width); }; // メインウィンドウ作成処理 Scene_MyWindow.prototype.createMainWindow = function(){ var ww = 350; var wh = 100; var wx = (Graphics.width - ww) / 2; var wy = (Graphics.height - wh) / 2; this._mainWindow = new Window_Base(wx, wy, ww, wh); this.addWindow(this._mainWindow); }; // ----------Sceneの定義 ここまで ---------- })();
実行結果


サンプルコード解説
RPGツクールMVにはSceneManagerというSceneを管理するためのクラスがあり、SceneManagerにSceneを追加(push)するとSceneの内容が実行されます。
SceneManagerはシーンが変わる時にchangeSceneという自身のメソッドを呼び出し、その中でSceneのcreateメソッドを実行します。
Sceneのcreateメソッドの中にウィンドウの生成処理を書いておけば、シーンが変わったと同時にcreateメソッドが実行され、ウィンドウが表示されます。
サンプルコードではcreateMainWindowというメソッドを定義しておいて、createメソッドから呼び出しています。
1つのシーンに複数のウィンドウがある場合が多いので、createメソッドのなかに直接ウィンドウ生成の処理を書くよりは、ウィンドウごとに生成するメソッドを別に作っておいてcreateメソッドの中で呼び出すとコードがスッキリして読みやすくなります。
Window_Baseクラスからオブジェクトを作っているのは this._mainWindow = new Window_Base(wx, wy, ww, wh); の部分です。
new クラス名(引数) で、オブジェクトを作った時に実行されるinitializeメソッドに引数を渡し、クラスからオブジェクトを作ります。
Window_BaseのinitializeメソッドではウィンドウのX座標、Y座標、ウィンドウの幅、ウィンドウの高さの引数を受け取るので、それぞれ変数を渡しています。
このプラグインコマンドを実行すると、真っ黒の画面にウィンドウだけ表示されます。
Scene_MyWindowのベースにしたScene_Baseは、すべてのシーンの元になるクラスです。
それまで表示されていたマップやキャラクターの描画も見えなくなるので、1から画面を作ることができます。
マップやキャラクターはそのままでウィンドウを表示させたいという場合はScene_MenuBaseなどを元にすればよいです。
コード中のScene_Baseと書いてあるところ(3ヶ所あります)をScene_MenuBaseにすると、画面がすこしボケて前面にウィンドウが表示されるようにます。
Scene_Statusをベースにすればステータス画面が表示されてその上にウィンドウが表示されますし、元となるシーンクラスを変えるといろいろ変わるので試してみてください。
Window_Baseはすべてのウィンドウの元になるクラスで、まあ普通のウィンドウです。
drawTextはウィンドウに文字を表示するためのメソッドです。
drawText(表示させる文字, X座標, Y座標, 表示幅);
ウィンドウの左上を起点として、X座標、Y座標で指定した位置に文字を表示します。
表示幅は設定しておくと、文字が長すぎるときに文字のサイズを縮小して表示幅の範囲に収まるようにしてくれます。
プラグインコマンドの引数をSceneに渡す
文章が固定だとおもしろくないので、プラグインコマンドの引数で任意のメッセージを表示できるようにしてみます。
黄色でハイライトした行を追加しています。
サンプルコード2
(function(){ 'use strict'; var pluginName = "MyWindowTest"; // ----------プラグインコマンドの定義 ここから ---------- 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 'show': SceneManager.push(Scene_MyWindow); SceneManager.prepareNextScene(args[1]); break; } } }; // ----------プラグインコマンドの定義 ここまで ---------- // ----------Sceneの定義 ここから ---------- function Scene_MyWindow(){ this.initialize.apply(this, arguments); } // 自作Sceneの元になるSceneを定義 Scene_MyWindow.prototype = Object.create(Scene_Base.prototype); Scene_MyWindow.prototype.constructor = Scene_MyWindow; // Sceneを生成した時の処理(親クラスのinitializeメソッドに自分を渡して呼びだし) Scene_MyWindow.prototype.initialize = function(){ Scene_Base.prototype.initialize.call(this); }; // Sceneに引数を渡したい場合、 // SceneManager.prepareNextSceneメソッドで引数を指定し、 // Sceneのprepareメソッドで受け取る Scene_MyWindow.prototype.prepare = function(description){ this._description = description; }; // ウィンドウの作成 Scene_MyWindow.prototype.create = function(){ Scene_Base.prototype.create.call(this); this.createWindowLayer(); this.createMainWindow(); this._mainWindow.drawText(this._description, 0, 0, this._mainWindow.width); }; // メインウィンドウ作成処理 Scene_MyWindow.prototype.createMainWindow = function(){ var ww = 350; var wh = 100; var wx = (Graphics.width - ww) / 2; var wy = (Graphics.height - wh) / 2; this._mainWindow = new Window_Base(wx, wy, ww, wh); this.addWindow(this._mainWindow); }; // ----------Sceneの定義 ここまで ---------- })();
実行結果


サンプルコード解説
Sceneに引数を渡すには、SceneManagerのprepareNextSceneメソッドとSceneのprepareメソッドを使います。
SceneManagerのprepareNextSceneメソッドは、受け取った引数をSceneのprepareメソッドに渡して呼び出します。
自作Sceneクラスにprepareメソッドを用意してあげれば、SceneManagerから引数を受け取ることができます。
コマンドウィンドウを追加する
今のままだと、シーンを呼び出したはいいけど元の画面に戻れない状態なので、元に戻れるようにしてあげます。
しかし、テキストを表示しているWindow_Baseにはキー入力を受け取る用のメソッドがありません。
そこで、Sceneにもう1つウィンドウを追加します。
コマンドを表示するためのWindow_MyCommandWindowを定義し、そのウィンドウに表示されたコマンドから操作をするようにします。
Window_MyCommandWindowの元となるクラスはWindow_Commandです。
サンプルコード3
(function(){ 'use strict'; var pluginName = "MyWindowTest"; // ----------プラグインコマンドの定義 ここから ---------- 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 'show': SceneManager.push(Scene_MyWindow); SceneManager.prepareNextScene(args[1]); break; } } }; // ----------プラグインコマンドの定義 ここまで ---------- // ----------Sceneの定義 ここから ---------- function Scene_MyWindow(){ this.initialize.apply(this, arguments); } // 自作Sceneの元になるSceneを定義 Scene_MyWindow.prototype = Object.create(Scene_Base.prototype); Scene_MyWindow.prototype.constructor = Scene_MyWindow; // Sceneを生成した時の処理(親クラスのinitializeメソッドに自分を渡して呼びだし) Scene_MyWindow.prototype.initialize = function(){ Scene_Base.prototype.initialize.call(this); }; // Sceneに引数を渡したい場合、 // SceneManager.prepareNextSceneメソッドで引数を指定し、 // Sceneのprepareメソッドで受け取る Scene_MyWindow.prototype.prepare = function(description){ this._description = description; }; // ウィンドウの作成 Scene_MyWindow.prototype.create = function(){ Scene_Base.prototype.create.call(this); this.createWindowLayer(); this.createMainWindow(); this._mainWindow.drawText(this._description, 0, 0, this._mainWindow.width); this.createCommandWindow(); }; // メインウィンドウ作成処理 Scene_MyWindow.prototype.createMainWindow = function(){ var ww = 350; var wh = 100; var wx = (Graphics.width - ww) / 2; var wy = (Graphics.height - wh) / 2; this._mainWindow = new Window_Base(wx, wy, ww, wh); this.addWindow(this._mainWindow); }; // コマンドウィンドウ作成処理 Scene_MyWindow.prototype.createCommandWindow = function(){ var wx = this._mainWindow.x; var wy = this._mainWindow.y + this._mainWindow.height + 50; this._commandWindow = new Window_MyCommandWindow(wx, wy); this._commandWindow.setHandler('ok', this.onCommandOk.bind(this)); this.addWindow(this._commandWindow); }; // コマンドウィンドウで決定ボタンを押したときの処理 Scene_MyWindow.prototype.onCommandOk = function(){ this.popScene(); }; // ----------Sceneの定義 ここまで ---------- // ----------コマンドウィンドウの定義 ここから ---------- function Window_MyCommandWindow(){ this.initialize.apply(this, arguments); } Window_MyCommandWindow.prototype = Object.create(Window_Command.prototype); Window_MyCommandWindow.prototype.constructor = Window_MyCommandWindow; Window_MyCommandWindow.prototype.initialize = function(x, y){ Window_Command.prototype.initialize.call(this, x, y); }; // コマンドを設定 Window_MyCommandWindow.prototype.makeCommandList = function(){ this.addCommand('戻る', 'back', true); }; // ----------コマンドウィンドウの定義 ここまで ---------- })();
実行結果

サンプルコード解説
コマンドウィンドウにコマンドを追加する
コマンドウィンドウを生成するcreateCommandWindowメソッドを作り、createメソッドから呼び出しました。
createCommandWindowの中でWindow_Commandをベースに作ったWindow_MyCommandWindowクラスからオブジェクトを作っています。
this._commandWindow = new Window_MyCommandWindow(wx, wy);
Window_Commandはインスタンスが生成されると、makeCommandListメソッドを実行します。
Window_Commandを元に作ったWindow_MyCommandWindowも同じですので、Window_MyCommandWindowにmakeCommandListメソッドを作ります。
その中でコマンドを追加するaddCommandメソッドを実行してコマンドを追加しています。
addCommandメソッドはWindow_MyCommandWindowの元になったWindow_Commandで定義されているメソッドです。
元にしたクラスのメソッドは自分で定義をしなくてもぜんぶ使えます。
自分で定義していない場合は、ベースにしたクラスのメソッドが呼ばれます。
addCommand(コマンドの表示名, シンボル, 使用可能か);
シンボルは後述しますが、どんな操作をしたかを判定するための文字列で、好きな文字を指定します。
使用可能かどうかはtrueまたはfalseを指定します。
falseにした場合、コマンドがグレーアウトして押せなくなります。
makeCommandListは自分で定義しているのでWindow_MyCommandWindowで定義したmakeCommandListメソッドが呼ばれ、addCommandは自分で定義していないので元にしたWindow_CommandのaddCommandメソッドが呼ばれています。
ボタンを押した時の処理を設定する
ボタン操作した時の処理は this._commandWindow.setHandler(‘ok’, this.onCommandOk.bind(this)); です。
setHandlerメソッドで、実行するメソッドを設定します。
setHandler(シンボル, メソッド)
シンボルはどんな操作がされたのかを表す文字です。
決定ボタンを押した時はok、キャンセルボタンならcancelというシンボルを指定します。
addCommandでコマンドを追加したときにも、コマンドごとにシンボルを指定しているので、そっちのシンボルを指定してもいいです。
サンプルコードだと戻るボタンはbackというシンボルを設定しているので、
this._commandWindow.setHandler(‘ok’, this.onCommandOk.bind(this)); は
this._commandWindow.setHandler(‘back’, this.onCommandOk.bind(this));でも動きます。
前者は「決定ボタンが押された時」、後者はaddCommandメソッドで追加した「戻るボタンが押された時」に引数で指定したメソッドが呼び出されます。
コマンドが1つの場合はどちらも変わりませんが、コマンドが複数ある場合は「決定ボタンが押された時」にすると、どのコマンドが選ばれたかどうかは関係なく実行されます。
メソッドはonCommandOkメソッドを作って、引数に指定しています。
onCommandOkメソッドの中でpopSceneメソッドを実行し、SceneManagerから自身を取り除き(popし)、シーンを終了しています。
まとめ
- ウィンドウを表示させるにはSceneクラスとWindowクラスが必要
- すでにある処理と同じでいい場合は、すでにあるクラスからオブジェクトを作る
- 処理を変えたい部分があれば、すでにあるクラスを元にして自作クラスを作り、自作クラスからオブジェクトを作る
- Sceneを実行するにはSceneManagerにpushする。
Sceneを終了するにはSceneManagerからpopする。
自作ウィンドウを作る時はすでにあるクラスを元に作るので、ベースにしたクラスがどんなメソッドを持っていて、どこで呼び出しているのか? というRPGツクールMVの内部処理の理解が必要です。
RPGツクールMVで定義されているクラスは、プロジェクトフォルダ配下のjsフォルダ(自分のプラグインを置くフォルダの1階層上のフォルダ)にあるファイルに書かれています。
Sceneクラスだったら「rpg_scenes.js」、Windowクラスだったら「rpg_windows.js」です。
これらのファイルはプラグインと同じJavaScriptで書かれていますが、オブジェクト指向というプラグラムの設計するときの考え方にもとづいているため、JavaScriptだけではなくオブジェクト指向についても知らないと理解がしづらいかと思います。
オブジェクト指向については本がいろいろと出ているので、図書館や本屋などで探してみるとよいかと思います。
概念を完全に理解するには難しいですが、「クラス」「オブジェクト」「継承」「オーバーライド」ぐらいが理解できれば、RPGツクールMVの内部処理をわりと読めるようになります。