「シーンの基本構造」の編集履歴(バックアップ)一覧に戻る

シーンの基本構造 - (2009/04/10 (金) 08:36:53) のソース

入門編・4
*シーンの基本構造
**クラスの派生
さて、Scene_Titleのmainを見ればいいということになったのですが。
あれ?
ないじゃありませんか。
そうです。スクリプトエディタのScene_Titleの項目を見ると、mainは無いのです。
じゃあ、Scene_Titleのmainって何だ?
Scene_Titleの7行目を見てみましょう。
>class Scene_Title < Scene_Base
Scene_Titleの後に、Scene_Baseというものがついていますね。
実はこの記述、Scene_Titleは、Scene_Baseというクラスから派生している、という意味なのです。
では、派生とは何なのでしょうか?
派生を使うと、派生元のクラスから派生先のクラスに、&bold(){変数とメソッドが受け継がれます}。
変数というのは、パラメータのようなもの。
メソッドというのは、コマンドのようなものです。そして、探していたmainは、メソッドです。
Scene_Baseを見てみましょう。
Scene_Baseには、mainメソッドがあります。このmainがScene_Titleに受け継がれています。だから、&bold(){Scene_Titleクラスにmainの記述が無くても、mainメソッドを持っていることになる}のです。
ではScene_Titleクラスのmainメソッドの内容は? これも引き継がれたもの、すなわち、&bold(){Scene_Baseのmainの内容と全く同じです}。
ちなみに、全てのシーンクラスは、このScene_Baseのmainを引き継いでいます。
&bold(){どのシーンクラスのmainも、見かけ上は同じ内容}ということになります。しかし、もちろん実際はそうではありません。どういうことなのかは、これから分かるようになります。
**mainの構造を見る
下に、Scene_Baseのmainの内容を示します。
>  def main
>    start                         # 開始処理
>    perform_transition            # トランジション実行
>    post_start                    # 開始後処理
>    Input.update                  # 入力情報を更新
>    loop do
>      Graphics.update             # ゲーム画面を更新
>      Input.update                # 入力情報を更新
>      update                      # フレーム更新
>      break if $scene != self     # 画面が切り替わったらループを中断
>    end
>    Graphics.update
>    pre_terminate                 # 終了前処理
>    Graphics.freeze               # トランジション準備
>    terminate                     # 終了処理
>  end
最初の行のdef main ~ endまでで、mainというメソッドを定義しています。実行されるのはdef mainの次の行から。
最初の三行、start,perform_transition,post_startは、シーンが開始する前の処理で、コマンド名です(四行目はとりあえず無視)。
では、Scene_Baseのこれらのコマンドの定義を見てみましょう。例えばstartは、
>  def start
>  end
あれ? 何もありません。どういうことでしょうか。
実は、&bold(){startコマンドは、Scene_Titleのstartコマンドを行うのです}。
クラスが継承されると、継承先のクラスに変数とメソッドを受け継ぎます。
しかし、&bold(){継承先で同じ名前のメソッドが再定義された場合、継承先のクラスでそのメソッドを実行する時は、継承先で再定義した方のメソッドを実行する}のです。
ややこしい文章ですが、要するに、本来は今Scene_Titleの話なので、Scene_Titleで定められていれば、そっちで定めた方を使うのです。&bold(){mainは定めてないので継承元のクラスScene_Baseのmainを実行、startは定めているのでScene_Titleのstartを実行するのです}。
では、Scene_Titleのstartメソッドはどうなっているでしょうか。
>  def start
>    super
>    load_database                     # データベースをロード
>    create_game_objects               # ゲームオブジェクトを作成
>    check_continue                    # コンティニュー有効判定
>    create_title_graphic              # タイトルグラフィックを作成
>    create_command_window             # コマンドウィンドウを作成
>    play_title_music                  # タイトル画面の音楽を演奏
>  end
ちゃんと、タイトル画面を作るのに必要そうなことをやっていますね。具体的な内容は今は飛ばします。
一つ注意しておきたいのが、superというものです。
&bold(){superは、継承元のクラスの同名のメソッドを実行する}という意味です。
ここでは、Scene_Baseのstartを実行しています(しかし前述のように中身は無いので、実際には何も実行されません)

同様に、perform_transition,pre_startも継承先のScene_Titleで再定義されているので、そっちを使います。
そして、この三行で、&bold(){メインループ}に入る前に必要な処理を全て行っています。
**メインループを見る
メインループというのは、6~11行目の、
>    loop do
>      Graphics.update             # ゲーム画面を更新
>      Input.update                # 入力情報を更新
>      update                      # フレーム更新
>      break if $scene != self     # 画面が切り替わったらループを中断
>    end
の部分のことです。6行目のloop doから11行目のendをひたすら繰り返し、
10行目に書かれるように、$sceneという変数の値が、自身と異なる場合、ループを抜けます。
そして、$sceneで定められた次のシーンに行くのですが、この詳しい意味は後述します。
なので、&bold(){メインループの重要な部分は実質三行です}。
>      Graphics.update             # ゲーム画面を更新
>      Input.update                # 入力情報を更新
>      update                      # フレーム更新
コメントにあるとおり、1行目はゲーム画面を更新、
2行目は入力情報(コントローラやキーボードからの入力)の更新(入力を受け取るということ)
そして、3行目がフレーム更新。フレーム更新って何でしょう?
ゲームを進めるために、画面を変えて入力を受け取る以外にするべきこと。

いっぱいありますね。
マップ画面で言えば、主人公を動かす、他のイベントを動かす、画面のスクロール、戦闘が始まらないかのチェック、背景のアニメーション、メニュー画面を開くべきかのチェック……。
要するに、&bold(){莫大な量の計算と、その結果に応じて得られるゲームへの反映、全てです。これがフレーム更新です}。
だから、表示して、入力を受け取って、計算して反映する。これがメインループの中身です。
実にシンプルですが、&bold(){RPGに限らず、(ほぼ)全てのゲームはこのメインループの構造の元に作られています}。

さて、とりあえず先に行きましょう。
メインループを抜けた後は、次のシーンに移るための終了処理です。
これは開始処理と同じく、継承先のクラスで定義されたのが中身です。
終了処理ののち、シーンが変更になり、シーンが続く限り別のシーンへ行って、また開始処理、メインループ、終了処理、の繰り返し……ということになります。

さて、次回はシーンを作ってみます。
Scene_Titleの解析ではなく、いきなりシーンを作るなんてことをするのは、&bold(){Scene_Titleの中身が難しいから}です。
教材として、次回からシューティングゲームもどきを作ります。
何でシューティングゲームなんていきなりRPGと関係の無いものを作るか、と言われれば。
画像表示、入力、反映、その関係が非常にシンプルだからです。騙されたと思ってちょっと一緒に作ってみて下さい。
----
[[前へ>Mainの中身を見る]]・[[次へ>シーンを作ってみる]]
----
#comment_num2(size=40,vsize=4,num=20,logpage=コメント一覧)
目安箱バナー