2.ウィンドウ
1.ウィンドウの表示
ウィンドウを表示するには Window_Base を使用します。
イベントコマンド「スクリプト」に次の1行を記述してください。
テストプレイで確認してみましょう。
引数の値は、(x, y, width, height) となっていて、
最初の2つが表示位置の座標、後ろの2つがウィンドウのサイズです。
(x座標, y座標, 横幅, 縦幅)ですね。
パソコンでの座標は、画面の左上が(0, 0)です。
vxの解像度は、544 x 416 ですので、右下が(543 x 415)となります。
先ほどの引数のx,yの値が表示するウィンドウの左上に位置します。
そこから width, height のサイズのウィンドウを表示するわけです。
さて、ウィンドウを表示することはできましたが、いつまでも画面上に残っていると思います。
このウィンドウを消すには、dispose というメソッドを使用します。
先ほどのスクリプトに2行を加えて次のようにしてください。
今度は2秒後にウィンドウが消えると思います。
2行目に入れた処理は、2秒間待つという処理です。
120 という数値が2秒をあらわします。
これは、フレーム数です。
デフォルトでは、1秒間に60回、画面を更新しています。
ですので、120回画面を更新させれば2秒という事になります。
イベントコマンド「スクリプト」に次の1行を記述してください。
win = Window_Base.new(112, 88, 320, 240)これだけでウィンドウを表示することができます。
テストプレイで確認してみましょう。
引数の値は、(x, y, width, height) となっていて、
最初の2つが表示位置の座標、後ろの2つがウィンドウのサイズです。
(x座標, y座標, 横幅, 縦幅)ですね。
パソコンでの座標は、画面の左上が(0, 0)です。
vxの解像度は、544 x 416 ですので、右下が(543 x 415)となります。
先ほどの引数のx,yの値が表示するウィンドウの左上に位置します。
そこから width, height のサイズのウィンドウを表示するわけです。
さて、ウィンドウを表示することはできましたが、いつまでも画面上に残っていると思います。
このウィンドウを消すには、dispose というメソッドを使用します。
先ほどのスクリプトに2行を加えて次のようにしてください。
win = Window_Base.new(112, 88, 320, 240) Graphics.wait(120) win.disposeテストプレイで確認してみてください。
今度は2秒後にウィンドウが消えると思います。
2行目に入れた処理は、2秒間待つという処理です。
120 という数値が2秒をあらわします。
これは、フレーム数です。
デフォルトでは、1秒間に60回、画面を更新しています。
ですので、120回画面を更新させれば2秒という事になります。
◆ 今回のポイント
・ new メソッドで作成して、dispose メソッドで削除する。
・ ウェイト(待ち時間)は、フレーム数で指定する。
・ 通常、1秒間=60フレーム
・ new メソッドで作成して、dispose メソッドで削除する。
・ ウェイト(待ち時間)は、フレーム数で指定する。
・ 通常、1秒間=60フレーム
2.文字の描画
ウィンドウに文字を表示するには、contents メソッドを使用します。
これは、ウィンドウ内容として表示するビットマップ (Bitmap) への参照をするものです。
そして、文字の描画は Bitmap クラスの draw_text を使用します。
つまり、文字は画像だということですね。
では、前回と同じようにイベントコマンドのスクリプトへ記述してください。
あ、スクリプトはコピペするよりも自分で打ち込んだ方が上達が早いですよ。
いや、ホントに。
では、説明していきたいと思います。
win.contents には、ウィンドウ内容の画像が入っています。
この画像に、文字やら画像やらを描画するわけです。
注意点は、ウィンドウのサイズよりも 32px 小さいと言うことです。
これは、仕様ですのでどうすることもできません。
今回の場合は、ウィンドウサイズが 320 x 240 ですので、
ウィンドウ内容は 288 x 208 という事になりますね。
このウィンドウ内容は、画像のような位置になりますので描画位置などを調節する必要はありません。
そして、描画処理は draw_text メソッドですね。
このメソッドは、Bitmap クラスに定義してあります。
引数は(x座標, y座標, 横幅, 縦幅, 描画文字)となっています。
座標は、ウィンドウの時と同じです。ただ、ウィンドウ内容での座標だということに注意してください。
横幅は、文字を表示する範囲ですが文章がこの幅より大きくなってしまった場合は、
ある程度まで1文字の横幅を小さくして、指定された幅内に納めようとします。
縦幅も文字を表示する範囲ですが、この範囲内で中央に揃えます。
例えば、サイズが20の文字を縦幅100で表示しようとすると、
上や下に寄せて表示するのではなく、真ん中に表示されます。
横の表示位置も変更することができます。
6つ目のパラメータは、文字の位置を指しています。
0:左揃え、1:中央揃え、2:右揃え。省略するとすべて左揃えです。
ウィンドウの内容を消したい場合は、clear メソッドを使用します。
これは、ウィンドウ内容として表示するビットマップ (Bitmap) への参照をするものです。
そして、文字の描画は Bitmap クラスの draw_text を使用します。
つまり、文字は画像だということですね。
では、前回と同じようにイベントコマンドのスクリプトへ記述してください。
# ウィンドウを作成 win = Window_Base.new(112, 88, 320, 240) # 文字を描画 win.contents.draw_text(0, 0, 288, 24, "文字") # 2秒間待つ Graphics.wait(120) # ウィンドウを消去 win.disposeでは、テストプレイで実行してみてください。
あ、スクリプトはコピペするよりも自分で打ち込んだ方が上達が早いですよ。
いや、ホントに。
では、説明していきたいと思います。
win.contents には、ウィンドウ内容の画像が入っています。
この画像に、文字やら画像やらを描画するわけです。
注意点は、ウィンドウのサイズよりも 32px 小さいと言うことです。
これは、仕様ですのでどうすることもできません。
今回の場合は、ウィンドウサイズが 320 x 240 ですので、
ウィンドウ内容は 288 x 208 という事になりますね。
このウィンドウ内容は、画像のような位置になりますので描画位置などを調節する必要はありません。
そして、描画処理は draw_text メソッドですね。
このメソッドは、Bitmap クラスに定義してあります。
引数は(x座標, y座標, 横幅, 縦幅, 描画文字)となっています。
座標は、ウィンドウの時と同じです。ただ、ウィンドウ内容での座標だということに注意してください。
横幅は、文字を表示する範囲ですが文章がこの幅より大きくなってしまった場合は、
ある程度まで1文字の横幅を小さくして、指定された幅内に納めようとします。
縦幅も文字を表示する範囲ですが、この範囲内で中央に揃えます。
例えば、サイズが20の文字を縦幅100で表示しようとすると、
上や下に寄せて表示するのではなく、真ん中に表示されます。
横の表示位置も変更することができます。
# ウィンドウを作成 win = Window_Base.new(112, 88, 320, 240) # 文字を描画 win.contents.draw_text(0, 0, 288, 208, "文字", 1) # 2秒間待つ Graphics.wait(120) # ウィンドウを消去 win.dispose文字がウィンドウのど真ん中に表示されたでしょうか?
6つ目のパラメータは、文字の位置を指しています。
0:左揃え、1:中央揃え、2:右揃え。省略するとすべて左揃えです。
ウィンドウの内容を消したい場合は、clear メソッドを使用します。
# ウィンドウを作成 win = Window_Base.new(112, 88, 320, 240) # 文字を描画 win.contents.draw_text(0, 0, 288, 208, "文字", 1) # 2秒後、描画内容を消去 Graphics.wait(120) win.contents.clear # 2秒後、ウィンドウを消去 Graphics.wait(120) win.dispose
◆ 今回のポイント
・ ウィンドウ内の描画可能範囲は、ウィンドウの横・縦幅を -32 したサイズである。
・ 文字を描画する座標の指定は、描画域のものである。
・ デフォルトでは水平位置は、左揃えである。
・ 垂直位置は、常に中央揃えである。
・ ウィンドウ内の描画可能範囲は、ウィンドウの横・縦幅を -32 したサイズである。
・ 文字を描画する座標の指定は、描画域のものである。
・ デフォルトでは水平位置は、左揃えである。
・ 垂直位置は、常に中央揃えである。
3.文字の色を変更
文字の色はFontクラスですね。
このクラスを使えば、色だけではなく大きさやスタイル、種類なども変更できます。
色を扱っているのがColorクラスです。
文字の色を変えるときは、この2つを使用します。
では、下記の例をイベントコマンドで実行してみてください。
色の指定方法ですけど、Color.new(赤, 緑, 青)こんな感じで指定します。
ペイントソフトとかで見たことがあるんじゃないかな?
3色を混ぜるあわせる感じかな?あっ、でも光の3原色だから重ねるかな?
数値は0〜255で指定します。
一度指定すると以後その色で表示されるので注意してね。
文字を表示するときは、一緒に色も指定したほうがいいかも。
どんな色で表示されるかわからないからねb
色の指定方法はColorクラスを使わない方法もあります。
デフォルトの文字色というものがあります。
たとえば、文字の色などは白で表示されるでしょう。
ステータスなどの名称は青で表示されるでしょう。
このように、あらかじめ決められている色を使用することもできます。
これの説明をするとちょっと長くなりそうなので、今回は省きます。
下記のスクリプトは今回のスクリプトと組み合わせて見てください。
normal_colorの部分をsystem_colorにすれば、青に変わると思います。
これらの色は、Window_Baseクラスに定義されています。
このクラスを使えば、色だけではなく大きさやスタイル、種類なども変更できます。
色を扱っているのがColorクラスです。
文字の色を変えるときは、この2つを使用します。
では、下記の例をイベントコマンドで実行してみてください。
# ウィンドウを作成 win = Window_Base.new(150, 100, 244, 216) # 文字を赤くする。 win.contents.font.color = Color.new(255, 0, 0) # 文字を描画(中央揃え) win.contents.draw_text(0, 0, 212, 184, "文字", 1) # 2秒間待つ Graphics.wait(120) # ウィンドウを消去 win.dispose
色の指定方法ですけど、Color.new(赤, 緑, 青)こんな感じで指定します。
ペイントソフトとかで見たことがあるんじゃないかな?
3色を混ぜるあわせる感じかな?あっ、でも光の3原色だから重ねるかな?
数値は0〜255で指定します。
一度指定すると以後その色で表示されるので注意してね。
文字を表示するときは、一緒に色も指定したほうがいいかも。
どんな色で表示されるかわからないからねb
色の指定方法はColorクラスを使わない方法もあります。
デフォルトの文字色というものがあります。
たとえば、文字の色などは白で表示されるでしょう。
ステータスなどの名称は青で表示されるでしょう。
このように、あらかじめ決められている色を使用することもできます。
self.contents.font.color = normal_colorこのように記述します。
これの説明をするとちょっと長くなりそうなので、今回は省きます。
下記のスクリプトは今回のスクリプトと組み合わせて見てください。
win.contents.font.color = win.normal_colorあ、例が悪かったですね。
normal_colorの部分をsystem_colorにすれば、青に変わると思います。
これらの色は、Window_Baseクラスに定義されています。
normal_color # 通常文字色 system_color # システム文字色 crisis_color # ピンチ文字色 knockout_color # 戦闘不能文字色 power_up_color # パワーアップ色 power_down_color # パワーダウン色※ これらは、変数ではなくメソッドです。
◆ 今回のポイント
・ 色の指定には、0~255の数値を用いて光の三原色で指定する。
・ 文字の色を変更後は、すべてその色になる。
・ 文字を表示する場合は、文字の色もセットで記述する。
・ 色の指定には、0~255の数値を用いて光の三原色で指定する。
・ 文字の色を変更後は、すべてその色になる。
・ 文字を表示する場合は、文字の色もセットで記述する。
4.アクターの情報を描画
さて、お次はアクターの情報の描画ですね。
アクターの情報を保持している変数は、2種類あります。
$data_actorsと$game_actorsです。
この違いは、$data_actors の方がデータベースの情報をそのまま格納しています。
この変数の値は、絶対に変更しないようにしましょう。
$game_actors の方は、$data_actors の情報に加えて
現在のアクターの情報などを保持しています。
現在のHPやレベル、装備などです。
詳細は、ヘルプの[RGSS リファレンス] - [RPGVX データ構造] を参照してください。
$data_actors:RPG::Actor(ヘルプ)
$game_actors:Game_Actor(エディタ)
ということで、描画方法は「文字の描画」と同じですね。
文字のところに、$game_actors[アクターのID].表示する情報みたいな?
それを使えば、わざわざ定義しなくても良いので楽かもです。
アクターの情報を保持している変数は、2種類あります。
$data_actorsと$game_actorsです。
この違いは、$data_actors の方がデータベースの情報をそのまま格納しています。
この変数の値は、絶対に変更しないようにしましょう。
$game_actors の方は、$data_actors の情報に加えて
現在のアクターの情報などを保持しています。
現在のHPやレベル、装備などです。
詳細は、ヘルプの[RGSS リファレンス] - [RPGVX データ構造] を参照してください。
$data_actors:RPG::Actor(ヘルプ)
$game_actors:Game_Actor(エディタ)
ということで、描画方法は「文字の描画」と同じですね。
文字のところに、$game_actors[アクターのID].表示する情報みたいな?
actor = $game_actors[1] # 1番のアクターの名前 win.contents.draw_text(0, 0, 288, 24, actor.name) # ラルフの 現在のHP/最大HP text = "#{actor.hp}/#{actor.maxhp}" win.contents.draw_text(0, 0, 288, 24, text) # パーティの名前を順番に描画 for actor in $game_party.members win.contents.draw_text( 0, 24 * actor.index, 288, 24, actor.name) end名前や現在のHPを表示する処理は、Window_Baseに定義済みだったりします。
それを使えば、わざわざ定義しなくても良いので楽かもです。
actor = $game_actors[1] # ラルフの名前 win.draw_actor_name(actor, 0, 0) # ラルフのHP (ゲージ付) win.draw_actor_hp(actor, 0, 24) # ラルフの顔グラ win.draw_actor_face(actor, 0, 48)
◆ 今回のポイント
・$data_actors は、データベースの情報なので書き換えない。
・ゲーム内のアクターの情報は、$game_actors を参照する。
・メニューなどで表示されている情報は、大抵 Window_Base に定義されている。
・$data_actors は、データベースの情報なので書き換えない。
・ゲーム内のアクターの情報は、$game_actors を参照する。
・メニューなどで表示されている情報は、大抵 Window_Base に定義されている。
5.オープンとクローズ
今回は、オープンとクローズ処理についてです。
メッセージウィンドウなんかがこの処理を使っていますね。
開いたり閉じたりする動作があるやつです。
では、そのようなウィンドウを定義してみます。
イベントコマンドよりエディタでの定義のほうがわかりやすいかな?
ということで、ウィンドウの基本 Window_Base を継承したクラスを定義します。
@test_window.updateというので、ウィンドウを更新しています。
openもしくは、closeでフラグたてをして、閉じたり開いたりしているわけです。
ですので、もしこの update を行わなければ、ウィンドウは表示されません。
Bボタンが押されたら、ウィンドウを閉じます。
その上にある@test_window.openness == 0で、ウィンドウが完全に閉じているのかを判断しています。
ちなみに、このopenとcloseメソッドは、Window_Baseに定義してあります。
メッセージウィンドウなんかがこの処理を使っていますね。
開いたり閉じたりする動作があるやつです。
では、そのようなウィンドウを定義してみます。
イベントコマンドよりエディタでの定義のほうがわかりやすいかな?
ということで、ウィンドウの基本 Window_Base を継承したクラスを定義します。
class Window_Test < Window_Base
#--------------------------------------------------------------------------
# ● オブジェクト初期化
#--------------------------------------------------------------------------
def initialize
super(150, 100, 244, 216)
self.openness = 0 # ウィンドウを閉じる
end
end
次にシーンも定義しておきましょう。class Scene_Test < Scene_Base #-------------------------------------------------------------------------- # ● 開始処理 #-------------------------------------------------------------------------- def start create_menu_background @test_window = Window_Test.new @test_window.open # ウィンドウを開く end #-------------------------------------------------------------------------- # ● 終了処理 #-------------------------------------------------------------------------- def terminate @test_window.dispose end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def update @test_window.update # ウィンドウが閉じている状態ならマップヘ戻る $scene = Scene_Map.new if @test_window.openness == 0 # キャンセルボタンが押されたら、ウィンドウを閉じる if Input.trigger?(Input::B) Sound.play_cancel @test_window.close # ウィンドウを閉じる end end endウィンドウは、最初閉じた状態で生成されるので、インスタンスを作った後にopenで開いています。
@test_window.updateというので、ウィンドウを更新しています。
openもしくは、closeでフラグたてをして、閉じたり開いたりしているわけです。
ですので、もしこの update を行わなければ、ウィンドウは表示されません。
Bボタンが押されたら、ウィンドウを閉じます。
その上にある@test_window.openness == 0で、ウィンドウが完全に閉じているのかを判断しています。
ちなみに、このopenとcloseメソッドは、Window_Baseに定義してあります。
6.ウィンドウ枠に文字
ウィンドウに文字を描画する際 16px の余白があり、この部分には、文字を描画できません。
今回は、その余白部分に文字を表示したいと思います。
ではでは、クラスを定義してみます。
ウィンドウと同じ大きさのスプライトを生成して、上に重ねただけです。
これで、ウィンドウの枠を無視して、文字を描画することが出来ます。
引数の*の意味がわからないかな?
詳しい説明は省きますが、仮引数で使用した場合は、以降の引数の値を配列にするという処理で、
実引数で使用した場合は、変数の配列を展開するという処理になります。
んで、描画するには他にメソッドを定義します。
先ほどのクラスの中に定義してください。
おっと、忘れるとこだった。
スプライトを使用した後は、必ず解放してあげないといけないよ
一応、Bitmapも解放しておくよ。
ウィンドウを消しても描画文字は表示されたままになってしまいます。
ビットマップは画像そのものなんで解放しなくても見かけは変わりませんが、
メモリに画像は残ったままなので、解放しておきます。
Rubyは、自動でメモリ管理してくれるので、放っておいてもいつか解放されます。
イベントで確認してください。
今回は、その余白部分に文字を表示したいと思います。
ではでは、クラスを定義してみます。
class Window_ExtendedBase < Window_Base #-------------------------------------------------------------------------- # ● オブジェクト初期化 (引数は Window_Base#initialize と同じ) #-------------------------------------------------------------------------- def initialize(*arg) super(*arg) create_sprite_contents end #-------------------------------------------------------------------------- # ● スプライト生成 #-------------------------------------------------------------------------- def create_sprite_contents @contents_sprite = Sprite.new @contents_sprite.bitmap = Bitmap.new(self.width - 32, self.height - 32) @contents_sprite.x = self.x @contents_sprite.y = self.y @contents_sprite.z = self.z end endこんな感じでしょうか?難しいことは一切していません。
ウィンドウと同じ大きさのスプライトを生成して、上に重ねただけです。
これで、ウィンドウの枠を無視して、文字を描画することが出来ます。
引数の*の意味がわからないかな?
詳しい説明は省きますが、仮引数で使用した場合は、以降の引数の値を配列にするという処理で、
実引数で使用した場合は、変数の配列を展開するという処理になります。
んで、描画するには他にメソッドを定義します。
先ほどのクラスの中に定義してください。
#-------------------------------------------------------------------------- # ● スプライトに描画 (引数は Bitmap#draw_text と同じ) #-------------------------------------------------------------------------- def draw_frame_text(*arg) @contents_sprite.bitmap.draw_text(*arg) end #-------------------------------------------------------------------------- # ● スプライトをクリア (引数は Bitmap#clear or Bitmap#clear_rect と同じ) #-------------------------------------------------------------------------- def clear_frame_text(*rect) # 配列の要素がないなら if rect.empty? @contents_sprite.bitmap.clear # 全体をクリア else @contents_sprite.bitmap.clear_rect(*rect) # 矩形でクリア end endちょっと、クリアの処理に凝っちゃった
おっと、忘れるとこだった。
スプライトを使用した後は、必ず解放してあげないといけないよ
一応、Bitmapも解放しておくよ。
#--------------------------------------------------------------------------
# ● 解放
#--------------------------------------------------------------------------
def dispose
@contents_sprite.bitmap.dispose
@contents_sprite.dispose
super
end
ここで、スプライトを解放しないと、ウィンドウを消しても描画文字は表示されたままになってしまいます。
ビットマップは画像そのものなんで解放しなくても見かけは変わりませんが、
メモリに画像は残ったままなので、解放しておきます。
Rubyは、自動でメモリ管理してくれるので、放っておいてもいつか解放されます。
イベントで確認してください。
win = Window_ExtendedBase.new(61, 54, 150, 100) win.draw_frame_text(0, 0, 150, 24, "TestMessage.") Graphics.wait(60) win.clear_frame_text(0, 0, 150, 12) Graphics.wait(60) win.dispose
7.描画機能
Window_Base クラスには、様々な描画機能がデフォルト用意されています。
このメソッドは、左上ではなく中央下の座標を渡す必要があります。
これは、サイズの異なる画像でも同じ位置に表示するためだと思います。
アクターの歩行グラフィック描画
アクターの顔グラフィック描画
名前の描画
クラスの描画
レベルの描画
ステートの描画
HP の描画
MP の描画
能力値の描画
アクターの顔グラフィック描画
名前の描画
クラスの描画
レベルの描画
ステートの描画
HP の描画
MP の描画
能力値の描画
:draw_actor_graphic(actor, x, y)
:draw_actor_face(actor, x, y, size = 96)
:draw_actor_name(actor, x, y)
:draw_actor_class(actor, x, y)
:draw_actor_level(actor, x, y)
:draw_actor_state(actor, x, y, width = 96)
:draw_actor_hp(actor, x, y, width = 120)
:draw_actor_mp(actor, x, y, width = 120)
:draw_actor_parameter(actor, x, y, type)
各引数は次のようなものになります。:draw_actor_face(actor, x, y, size = 96)
:draw_actor_name(actor, x, y)
:draw_actor_class(actor, x, y)
:draw_actor_level(actor, x, y)
:draw_actor_state(actor, x, y, width = 96)
:draw_actor_hp(actor, x, y, width = 120)
:draw_actor_mp(actor, x, y, width = 120)
:draw_actor_parameter(actor, x, y, type)
actor : アクター (Game_Actor オブジェクト) x : 描画先 X 座標 y : 描画先 Y 座標 size : 表示サイズ width : 描画先の幅 type : 能力値の種類 (0〜3)ここで、注意するのは draw_actor_graphic の描画先の座標です。
このメソッドは、左上ではなく中央下の座標を渡す必要があります。
これは、サイズの異なる画像でも同じ位置に表示するためだと思います。