BREW ブロック崩しゲーム 〜 BREW C++ ゲームプログラミング 〜
アプリケーションの初期化
ライセンス コードの記述
今回のアプリケーションでは、Block.cpp に次のように記述します。
- Block.cpp - ... // ブート ローダ SFCApplet::FactorySPP SFCApplet::Boot(AEECLSID id, SFXAnsiStringPtr license) { *license = "heap://" "Z9UHROLXIRNW7U9XKSNX2LX4RFR0TMWKCW7R0Z5RPXJR3Z4XDV" "2TCSGVPV1WOYJS5XQ9W9YCAX2VFZ2VPTPV1U1RLXCXNYAVNWNU" "GUQZ4TQR4VKS0FRDUGUBS1THSGSOR0R3W4SLY87SHLT0YLSAVH" "ES3TJWBTPSCS4THZ0S42TCSJX0VMZ6UNT8TLWBGVOR2V6WPS3S" "IYLUFVKWFVNVIR5TMTGY2U1Z6RCREV3RPUEYHWQV0VFUNWQLS3" "XBVLRNSGZ2S9R6Z8RFYGXD2UCT7WGXLXHY3XBVMTG8VNAUBXQZ" "9TQR3RAVEREYIYDU3YFXDX9WJW5FTASNTJTAR7TCXHXPU1UCXA" "0VISOTFY1WQW7VQVJ"; return (id == AEECLSID_BLOCK) ? (&Block::Factory) : (null); } ...
ライセンス コードを記述し忘れると実機でアプリケーションを実行することは出来ませんので、忘れないようにしましょう。
アプリケーションの初期化
それではアプリケーションの初期化処理の記述に取り掛かりましょう。
アプリケーションの初期化処理を記述する場所としては、
- アプリケーション クラスのコンストラクタ
- アプリ開始ハンドラ (OnAppStart 関数)
の 2 箇所があります。
今回は、
- Block.cpp -...// コンストラクタBlock::Block(Void) : _status(APP_STATUS_NOTHING), _drawInterval(1000 / DRAW_RATE){ // ラケットの色を設定_racket.color.Set(RACKET_COLOR); // ボールの色を設定_usingBall.color.Set(BALL_COLOR);return;}... // アプリ開始ハンドラVoid Block::OnAppStart(AEEAppStartPtr environment){ // 未使用変数のワーニングを回避します。unused(environment); // ここにアプリ開始時の処理を記述します。Initialize();return;}...
として、Block::Initialize 関数の中でエミュレータや実機での画面の大きさの違いを吸収するための処理を行っています。
初期化処理1 : グラフィック・インターフェイスの取得
それでは Block::Initialize 関数の中身に移りましょう。この関数内では変数の初期化を行っていますが、煩雑なためここには挙げません。詳細は Block.cpp をご覧ください。
ポイントは、
_pgraphics = SFXGraphics::GetInstance();
として、グラフィック・インターフェイスを取得しておくことです。
何でもそうですが、ハードウェアに対して何か処理を行う場合、まずはそのインターフェイスを取得することから始まります。
今、グラフィック・インターフェイスが取得できたので、忘れないうちに背景色を設定しておきましょう。
_pgraphics->SetBackColor(BGCOLOR);
ここで BGCOLOR の定義が
#define BGCOLOR SFXRGBColor(0, 0, 0, 0)
であったことを思い出してください。SFXGraphics::SetBackColor 関数の引数は SFXRGBColor オブジェクトへの参照ですので、このようにする必要があります。
初期化処理2 : 画面に関する情報の取得
このブロック崩しの画面構成は、次のようになっています。
画面上部 (_gameArea) を実際のゲームに使用し、画面下部 (_messageArea) を得点などを表示するのに使用します。これを実現するためには、画面の表示領域の大きさと文字の高さとを取得する必要があります。
まず画面の表示領域の大きさについては、
SFXRectangle deviceRect = _pgraphics->GetDeviceRectangle();
とすることによって、表示領域が長方形として取得できます。
一方、文字の高さについては、
SInt16 fontHeight = _pgraphics->GetFontHeight(AEE_FONT_NORMAL);
とすることで取得できます。
あとはこの情報に基づいて _gameArea と _messageArea の座標計算を行えば良いのです。
初期化処理3 : SFXRectangle について
_gameArea と _messageArea は共に SFXRectangle 型のオブジェクトです。今回の場合、両者の高さを計算すれば必要な画面構成が実現できるはずです。そこで、幅については画面の幅そのままなので、一旦
_gameArea = _messageArea = deviceRect;
としておきます。
まず、_gameArea の高さを計算しましょう。これは画面の高さから文字の高さを引いたものに等しくなります。そこで、
_gameArea.SetHeight(deviceRect.GetHeight() - fontHeight);
となります。
一方、_messageArea の高さは文字の高さに等しいので、
_messageArea.SetHeight(fontHeight);
となります。
あとはこれら 2 つの長方形を移動すれば完了です。
その前に、SFXRectangle のメンバ関数のうち、
- Set* (例 : SetLeft、SetRight)
- Snap* (例 : SnapLeft、SnapRight)
の違いについて知っておく必要があります。
Set* 関数は、指定された頂点あるいは辺を指定された場所に移動するだけの関数です。言い換えると、この関数を使用することで長方形の大きさが変わります。
対して Snap* 関数は、指定された頂点あるいは辺が指定された場所に来るように長方形を移動する関数です。つまり、この関数を使用しても長方形の大きさは変わりません。
SFXRectangle クラスの内部では、長方形の左上端の座標と幅と高さを保持しています。今回の場合、_gameArea に関しては左上端の座標が画面の左上端の座標と一致するため、SetHeight 関数を呼び出すだけで済みます。
一方、_messageArea については下辺が画面の下端に一致するように長方形を移動する必要があります。そこで、SnapBottom 関数を、
_messageArea.SnapBottom(deviceRect.GetBottom());
のように使用することで、目的を達することができます。
Initialize 関数の中では他にもブロックやラケット、ボールの大きさを計算したり、それぞれの速さを計算したりしていますが、それらの処理は以上のことの応用に過ぎないので、実装の詳細についてはここでは割愛します。詳細は Block.cpp を参照してください。
初期化処理4 : 各ステージの生成
このブロック崩しは 4 つのステージから構成されています。
ステージ 1 は 1 種類のブロックが、ステージ 2 は 2 種類のブロックが配置されます。ブロックそのものはステージ 1 と 3、2 と 4 で同じですが、ステージ 3 と 4 ではゲーム開始後 10 秒後にブロックも動き出します。
こういった各ブロックごとの性質は Void Block::CreateStage(SInt16 n) で定義しています。そしてこの関数は、Block::Initialize 関数の最後で呼び出されます。
この CreateStage 関数の中身は冗長なので、ここには挙げません。Block.cpp をご覧ください。