ウィンドウ表示関連を調べてみた
インプット周りを調べてみたでも有益な情報を公開してくれた yamachanさんがウィンドウ表示のコードの流れとショップ販売のカテゴリ化プラグインを作成してみるいう記事を公開してるので、乗っかっていきます!
ウィンドウクラスはアホほどある
とにかくウィンドウはクラスが多くて、へこたれます。
なんなんだ、この量は!! 殺女か! もとい殺す気か!
- Window
- Window_Base
- Window_EquipStatus 装備時のステータス
- Window_Gold 所持金
- Window_Help 項目が選択された際の解説
- Window_MapName マップの[表示名]を出す
- Window_Message [文章の表示]
- Window_NameEdit [名前入力の処理]名前表示・編集
- Window_ScrollText [文章のスクロール表示]
- Window_ShopStatus [ショップの処理]のステータス
- Window_SkillStatus スキル選択字のステータス
- Window_Selectable
- Window_BattleEnemy 敵の選択
- Window_BattleLog 戦闘ログ
- Window_DebugEdit デバッグ(F9)編集
- Window_DebugRange デバッグ(F9)範囲
- Window_EquipSlot 装備スロット
- Window_NameInput [名前入力の処理]文字入力表
- Window_NumberInput [数値入力の処理]数値入力表
- Window_SavefileList [セーブ画面を開く]ファイルリスト
- Window_ShopBuy [ショップの処理]購入
- Window_ShopNumber [ショップの処理]個数
- Window_Status ステータス
- Window_BattleStatus
- Window_BattleActor 戦闘シーンのアクター選択
- Window_MenuStatus
- Window_MenuActor アクター選択
- Window_SkillList
- Window_BattleSkill 戦闘シーンのスキル選択
- Window_ItemList
- Window_BattleItem 戦闘シーンのアイテム選択
- Window_EquipItem 装備アイテム選択
- Window_EventItem イベントアイテム選択
- Window_ShopSell [ショップの処理]売却
- Window_Command
- Window_ActorCommand アクターコマンド
- Window_ChoiceList [選択肢の表示]
- Window_GameEnd [ゲーム終了]
- Window_MenuCommand メニューコマンド
- Window_Options オプション
- Window_PartyCommand パーティコマンド
- Window_SkillType [スキルタイプ]
- Window_TitleCommand タイトルコマンド
- Window_HorzCommand
- Window_EquipCommand [装備]の種類選択
- Window_ItemCategory [アイテム]の種類選択
- Window_ShopCommand [ショップの処理]の売買選択
- Window_Base
自分が変更したい部分さえわかってりゃイイ、というスタンスで取り掛かっていこうと思います。
てな訳で、重要そうなクラスを強調しておきました。
標準の戦闘シーンやメニューはどうにも無駄なウィンドウが多く感じるので、削減を目指します。
Window
ウィンドウの基本クラスは Window
ということは上の表を見ればわかります。
この Window
も以下のように pixi.js のクラスを継承してます。
ウィンドウ関連のクラスは rpg_windows.js で定義されていますが、この Window
だけは rpg_core.js で定義されているので注意です。
PIXI.utils.EventEmitter
PIXI.DisplayObject
PIXI.Container
Window
x, y, width, height あたりの基本的なプロパティは pixi.js のクラスが定義しているので、「絶対このプロパティあるはずなんだけどなー」って時に確認すると良いかと思います。
意外な機能もってて継承先の Window でも普通に使えたりするので侮れません。
が、面倒臭いので pixi.js にはあんまり触れずに行きましょう。
pixi.js については pixi.js に詳しい誰かが書いてることでしょう(…個人的には日本語では入門記事しか見たことないですが)
さて、この Window
ですが、'img/Systems/Window.png' にあるスキン(UI用の入れ替え画像)を読み込んで表示するあたりを担当してます。
ウィンドウはたくさんのスプライトを組み合わせて作られています。
以下はそれらの構造を格納したプロパティを包含関係に沿って並べたものです。
レイヤー順に並べているので、ポーズサインが一番上、背景が一番下となるわけです。
_windowPauseSignSprite
ポーズサイン_upArrowSprite
上向き矢印_downArrowSprite
下向き矢印_windowContentsSprite
内容contents
_windowCursorSprite
カーソル_windowSpriteContainer
ウィンドウ_windowFrameSprite
枠_windowBackSprite
背景
Window.png
ヘルプを見ると、一切情報としての価値がない情報が載っています。
Window.png
ウィンドウを構成する画像をまとめた素材です。
ファイル名見りゃわかるんだよ!! そんなことはっ!!!!
なので、ここで調べたことを解説します。ほとんど、鈴華@PinkloverさんのPinklover - 素材置き場の解説の引き写しですけどっ!
img/system/Window.png 素材と、Window
のプロパティ対応は以下のようになっています。
_windowPauseSignSprite は、左上,右上,左下,右下の順にアニメーションします。
_windowFrameSprite と_windowCursorSprite は9スライスになっていて、枠の幅はそれぞれ24pxと4pxです。
_windowFrameSprite の方は真ん中の部分は、_upArrowSprite と _downArrowSprite に使われていますが、かなり枠に囲われてない何にも使われてない部分が残っています。
_windowBackSprite は赤い方(Window.png の左上)が背景の引き伸ばして使う方、青い方(Window.png の左下)がその上に重ねて繰り返しパターンとして使われるものです。
右下に並んでいる色はカラー番号に対応した色で、左上を0番として、右へそして下へ順に番号がついて31番まで並んでいます。
Window_Base
Window
を継承しているのは Window_Base
だけで、直接 new Window()
して使ってるところもないようなので、実質同じクラスです。
Window
がウィンドウ枠を担当しているのに対して、Window_Base
は概ねコンテンツの描画に関する部分を担当している感じです。
コンテンツは _windowContentsSprite.bitmap
に当たりますが、非常によく使うので contents
というプロパティが特に用意してあります。
この Bitmap
にウィンドウに含まれる画像や文字など描いて行きます。
実際は文字もRPGツクールMVでは画像として描いていくので、文字をブラウザでドラッグして選択してコピーとかできません。
内容を記述するために便利なメソッドがたくさん用意されています。
例えば、先ほどの Window.png で指定された色をCSSカラー文字列として取り出すメソッドが用意されています。
番号 | メソッド | 説明 |
---|---|---|
0 | normalColor() | 通常(文字) |
1〜15 | なし | |
16 | systemColor() | システム |
17 | crisisColor() | 瀕死 |
18 | deathColor() | 死亡 |
19 | gaugeBackColor() | ゲージの背景 |
20 | hpGaugeColor1() | [HP]ゲージ1 |
21 | hpGaugeColor2() | [HP]ゲージ2 |
22 | mpGaugeColor1() | [MP]ゲージ1 |
23 | mpGaugeColor2() | [MP]ゲージ2 |
23 | mpCostColor() | [消費MP] |
24 | powerUpColor() | 装備の値上昇 |
25 | powerDownColor() | 装備の値下降 |
26 | なし | |
27 | なし | |
28 | tpGaugeColor1() | [TP]ゲージ1 |
29 | tpGaugeColor2() | [TP]ゲージ2 |
29 | tpCostColor() | [消費TP] |
30 | なし | |
31 | なし |
0〜15までは、[メッセージ表示]コマンドで \C[n] 指定する際に使ってね。って感じで、16〜31は主にシステム用みたいです。
23番と29番がそれぞれ2つあるのは間違ってるんじゃなくて、指定できる色数に余裕あるのに、なぜか共有されてるんですよね。
なお、textColor() を使えば番号で色を取り出せます。
カラー番号と使用箇所の対応については、むーてぃさんのRPGツクールMV システムカラーの一覧に詳しいです。
Window_Base.contents.context
は CanvasRenderingContext2D なので、JavaScript標準の Canvas描画メソッドがフツーに使えます。
詳細はCanvas関連の書籍やリンク先のサイトなどを調べて見てください。
なお、_windowFrameSprite
などの Sprite
も bitmap
ひいては context
を持っていますので、Canvas関連メソッドによる描画が可能です。
ちなみに、それを使って作ったのがウィンドウをベクター描画する TF_VectorWindow.js です。
さらにちなみに、メッセージを表示する際の[暗くする]ってオプションを指定した場合に出てくる、黒くてグラデーションのついた背景、あれそもそもRPGツクールMVの標準でベクター描画してます。
WindowLayer
今まで戦闘やピクチャを調べた時に、ウィンドウはどうやらシーンにぶら下がってるぞ、というアタリをつけてます。
と言っても例によって SceneManager._scene
から辿っていくわけなんで、アタリも何もあったもんじゃないという気もします。
Scene_Base
には _windowLayer
というもう間違いないプロパティがあります。
_windowLayer
には WindowLayer
クラスが格納されていて、基本的にウィンドウはこの中に格納されてます。
ただ絶対ではなくて、シーン直下にウィンドウをぶら下げている場合もあります。
じゃあこれなんなんだよいらなくね?という話になりますが、これウィンドウを重ねたときに下のウィンドウにマスクをかける役割を持ってるんですよ。
半透明のウィンドウを重ねた時に下の情報が透けて見えると見辛くてしょうがないので、下のウィンドウをくり抜く処理をしてるんですね。
ただ、RPGツクールMVのウィンドウってデフォルトでは、基本的に重ならないんで…やっぱりこれ、いらんのでは? みたいな気もしてきます。
一応、戦闘シーンだと味方のパラメータとコマンドが重なるので、必要ですが。
ところで ver.1.6.1のrpg_core.js の 7167行、y座標の計算の中に間違ってthis.xが入ってる。
rect.y = this.x + shift.y + window.y + window.height / 2 * ( 1 - window._openness / 255 );
このバグに気づかずに、SceneManager._boxWidth
変えるとマスク位置がズレるなーと1週間ぐらい悩んだ。
まさかRPGツクールMV本体のバグだとは…。
ウィンドウのサイズについて
ウィンドウの大きさは PIXI.Container を継承しているんで、当然 width
と height
を持っています。
そこから、Window.padding * 2
を引いたのが contents
の大きさで、表示位置も padding
の分だけウィンドウの周囲から離れています。
これがちょっとわかりにくいのはCSSと表している範囲が違ってるんですよ。
CSSのボックスモデルでは padding
は枠の内側の文章本体までの距離なんですが、RPGツクールMVでの padding
はウィンドウの一番外から内容までの距離で、枠の外の間隔が含まれてる。
ここ、CSSに慣れてる人は気をつけてください。個人的には「なんでズレるかなー?」って割と長い時間引っかかりました。
まとめ
ということで結構頑張って色々調べましたが、まだまだウィンドウ関連の入り口だけという印象です。
冒頭で示した大量のクラスのうち、Window
と Window_Base
しか調べてないですからね(笑)
そこで結論。
ウィンドウを表示するだけでも、結構大変だ!