1.シーンクラス
1.シーンクラス
シーンクラスでは、マップ画面や戦闘画面などの処理を行っています。
それぞれの画面は、別々のシーンであり、これを切り替えることで画面を表示しています。
シーンは、常に1つしか存在せず、メニュー画面の裏にマップ画面があるように見えますが、
実際は画像であって、マップ画面は消去されています。
マップ ⇒ メニュー ⇒ ステータス と切り替えるときは、
マップを消してメニューを作成し、メニューを消してステータスを作成というような処理を行っています。
それぞれの画面は、別々のシーンであり、これを切り替えることで画面を表示しています。
シーンは、常に1つしか存在せず、メニュー画面の裏にマップ画面があるように見えますが、
実際は画像であって、マップ画面は消去されています。
マップ ⇒ メニュー ⇒ ステータス と切り替えるときは、
マップを消してメニューを作成し、メニューを消してステータスを作成というような処理を行っています。
2.最小のシーンクラス
まずは最低限必要なものだけで、シーンクラスを作ってみます。
シーンクラスを作成するには、Scene_Base を継承しなければいけません。
これで、シーンクラスの完成です。
シーンを切り替えるには、グローバル変数の $scene にシーンクラスのインスタンスを代入します。
イベントコマンドで$scene = Scene_Test.newを実行してみてください。
真っ黒な画面になり、操作不能になると思います。これは、シーンクラスが空っぽだからです。
何もできませんが正常に動作していますので、いったんウィンドウを閉じてください。
操作不能では困るので、Bボタンを押すと元のマップへ戻る処理を加えます。
ボタンが押されたかどうかは、毎フレーム処理して判断しなければいけません。
そこで、毎フレーム呼び出される update メソッドを定義します。
マップへ戻るということは、シーン切り替えですので $scene = Scene_Map.new とします。
これで、マップへ戻ってくることができるようになりました。
次は、背景を表示したいと思います。
メニュー画面やステータス画面の背景は、マップ画像が表示されています。
このマップ画像の表示処理は、すでに Scene_Base で定義されています。
ですので、そのメソッドを呼び出すだけで簡単に表示させることができます。
create_menu_backgroundで、背景を作成します。
dispose_menu_backgroundで、背景を削除します。
update_menu_backgroundは、背景の更新です。
このメソッドには、何も定義されていませんが、再定義されることを考えて呼び出しておきます。
ここまでを最小のシーンクラスとしておきます。
シーンクラスを作成するには、Scene_Base を継承しなければいけません。
これで、シーンクラスの完成です。
シーンを切り替えるには、グローバル変数の $scene にシーンクラスのインスタンスを代入します。
イベントコマンドで$scene = Scene_Test.newを実行してみてください。
真っ黒な画面になり、操作不能になると思います。これは、シーンクラスが空っぽだからです。
何もできませんが正常に動作していますので、いったんウィンドウを閉じてください。
操作不能では困るので、Bボタンを押すと元のマップへ戻る処理を加えます。
ボタンが押されたかどうかは、毎フレーム処理して判断しなければいけません。
そこで、毎フレーム呼び出される update メソッドを定義します。
マップへ戻るということは、シーン切り替えですので $scene = Scene_Map.new とします。
これで、マップへ戻ってくることができるようになりました。
次は、背景を表示したいと思います。
メニュー画面やステータス画面の背景は、マップ画像が表示されています。
このマップ画像の表示処理は、すでに Scene_Base で定義されています。
ですので、そのメソッドを呼び出すだけで簡単に表示させることができます。
create_menu_backgroundで、背景を作成します。
dispose_menu_backgroundで、背景を削除します。
update_menu_backgroundは、背景の更新です。
このメソッドには、何も定義されていませんが、再定義されることを考えて呼び出しておきます。
ここまでを最小のシーンクラスとしておきます。
1.Scene_Base を継承したクラスを定義する。
2.開始処理として start メソッドを定義する。
3.終了処理として terminate メソッドを定義する。
4.フレーム更新として update メソッドを定義する。
2.開始処理として start メソッドを定義する。
3.終了処理として terminate メソッドを定義する。
4.フレーム更新として update メソッドを定義する。
3.ウィンドウを表示する
◆ 今回のポイント
・開始処理では、ウィンドウの生成などを行う。
・終了処理では、ウィンドウの消去などを行う。
・開始処理・終了処理は、シーンが切り替わる際に自動で呼び出される。
・フレーム更新では、ウィンドウの更新やキー入力の処理などを行う。
・開始処理では、ウィンドウの生成などを行う。
・終了処理では、ウィンドウの消去などを行う。
・開始処理・終了処理は、シーンが切り替わる際に自動で呼び出される。
・フレーム更新では、ウィンドウの更新やキー入力の処理などを行う。
4.シーンクラスの仕組み
最小のシーンクラスを作成しましたが、start や update メソッドがどのように処理されているのか、
変数 $scene への代入だけで、なぜ画面が切り替わるのかを見てみます。
シーンは、$scene というグローバル変数に保存されています。
この変数のシーンを変更することで画面が切り替わり、nil になるとゲームを終了します。
この仕組みは、2つのループ処理によって実装されています。
1つ目は、Main セクションの $scene.main while $scene != nil という処理です。
$scene が nil になるとループを抜けるためゲームが終了します。
ループ中には、$scene の main メソッドが呼ばれ続けます。
2つ目は、その main メソッド内にあります。
すべてのシーンクラスは、Scene_Base を継承していますので Scene_Base の定義を見ます。
まず、開始処理で start メソッドが呼ばれます。
この段階では、画面の書き換えが禁止されているので、
ウィンドウの作成や位置調整など見えない処理を行います。
post_start メソッドが実行されるときには、画面が更新されるので、
プレイヤーにもシーン移動が終わっていることがわかります。
ですので、画面の変化を表示したい開始処理を行います。
そして、2つ目のループに入ります。
このループでは update メソッドを呼び出して、フレームの更新を行っています。
break if $scene != self という処理は、シーンが変更されたかを判定しています。
シーンを切り替えるとき、$scene = Scene_Map.new のように変数のオブジェクトを変更しました。
現在実行しているオブジェクトと違うオブジェクトが代入されていれば、ループを抜けるわけです。
抜けた後は、終了処理を行って Main セクションのループへ戻ります。
ここで、$scene が nil でないかを調べ、また main メソッドの呼び出しというように繰り返すことで、
シーンを切り替えゲームを実行しています。
変数 $scene への代入だけで、なぜ画面が切り替わるのかを見てみます。
シーンは、$scene というグローバル変数に保存されています。
この変数のシーンを変更することで画面が切り替わり、nil になるとゲームを終了します。
この仕組みは、2つのループ処理によって実装されています。
1つ目は、Main セクションの $scene.main while $scene != nil という処理です。
$scene が nil になるとループを抜けるためゲームが終了します。
ループ中には、$scene の main メソッドが呼ばれ続けます。
2つ目は、その main メソッド内にあります。
すべてのシーンクラスは、Scene_Base を継承していますので Scene_Base の定義を見ます。
まず、開始処理で start メソッドが呼ばれます。
この段階では、画面の書き換えが禁止されているので、
ウィンドウの作成や位置調整など見えない処理を行います。
post_start メソッドが実行されるときには、画面が更新されるので、
プレイヤーにもシーン移動が終わっていることがわかります。
ですので、画面の変化を表示したい開始処理を行います。
そして、2つ目のループに入ります。
このループでは update メソッドを呼び出して、フレームの更新を行っています。
break if $scene != self という処理は、シーンが変更されたかを判定しています。
シーンを切り替えるとき、$scene = Scene_Map.new のように変数のオブジェクトを変更しました。
現在実行しているオブジェクトと違うオブジェクトが代入されていれば、ループを抜けるわけです。
抜けた後は、終了処理を行って Main セクションのループへ戻ります。
ここで、$scene が nil でないかを調べ、また main メソッドの呼び出しというように繰り返すことで、
シーンを切り替えゲームを実行しています。
◆ 今回のポイント
・ゲームは、メインセクションのループとシーンクラスのループで実行されている。
・メインのループは、シーンの呼び出しとゲームの終了を行う。
・開始処理と終了処理のときは、画面の更新が行われない。
・ゲームは、メインセクションのループとシーンクラスのループで実行されている。
・メインのループは、シーンの呼び出しとゲームの終了を行う。
・開始処理と終了処理のときは、画面の更新が行われない。
5.シーンの切り替え
シーンの切り替え方法は、すでにご存知ですね。
$scene = シーンクラス.new です。
ただし、これは強制的なもので有無を言わさず切り替えます。
次のようなイベントを作成して実行してみてください。
強制的な切り替えだと、メッセージウィンドウが表示されてしまいます。
これを回避するには、シーン切り替え予約の処理を追加します。
予約の処理は、Scene_Map#update_scene_change で行います。
予約を行う処理は、$game_temp.next_scene = "test"です。
$scene = シーンクラス.new です。
ただし、これは強制的なもので有無を言わさず切り替えます。
次のようなイベントを作成して実行してみてください。
強制的な切り替えだと、メッセージウィンドウが表示されてしまいます。
これを回避するには、シーン切り替え予約の処理を追加します。
予約の処理は、Scene_Map#update_scene_change で行います。
予約を行う処理は、$game_temp.next_scene = "test"です。
◆ 今回のポイント
・切り替え予約を使用すると、メッセージウィンドウなどが閉じた後に処理が実行される。
・$game_temp.next_scene = "識別名" で切り替え予約ができる。
・予約処理で切り替えた場合は、必ず $game_temp.next_scene = nil を実行する。
・Scene_Map#update_scene_change は alias を用いて再定義し、元の処理は最後に呼び出す。
・切り替え予約を使用すると、メッセージウィンドウなどが閉じた後に処理が実行される。
・$game_temp.next_scene = "識別名" で切り替え予約ができる。
・予約処理で切り替えた場合は、必ず $game_temp.next_scene = nil を実行する。
・Scene_Map#update_scene_change は alias を用いて再定義し、元の処理は最後に呼び出す。