いよいよ完成に向かって
ラケットゲームの作成もいよいよ佳境です。C++Builderの開発手順の特長として、見えるところから作り、徐々に内部の実装を進めるという方法をとることができます。このやり方を用いれば、ソフトウェアの外観や雰囲気を先に見せ、フィードバックを受けながら改善したり、機能を追加していくことができます。
今回のゲームの完成形を改めてご覧いただきましょう。
今回実装するスコアやラケット数の管理機能がなくても、このような外観を見てもらうことはできます。
ゲームの要素を追加する
スコアの管理
では、ゲームの勝敗を左右するスコアや予備ラケットの管理機能を実装していきましょう。
スコアは、ScorePanel上に表示されるラベルですが、コード上では、変数の設定とラベル更新の処理が伴います。これらをカプセル化して簡単なコーディングを可能にする方法を紹介します。
コンポーネントのプロパティは、参照によって値を取得し、代入によって何らかの結果を引き起こします。プロパティは、予約語__propertyによって作成できます。独自のプロパティを作成し、参照と代入のそれぞれの処理を変数や関数に対応させることができます。
GemeUnit.hのTGameFormクラスの宣言にプロパティの定義を追加します(太字部分)。
class TGameForm : public TForm { __published: // IDE で管理されるコンポーネント TPanel *Panel1; TPanel *Court; : : : private: // ユーザー宣言 int Ang, DeltaX, DeltaY; double Speed; void __fastcall MoveBall(); void __fastcall CalcNewDelta(); bool __fastcall CheckHit(int ox, int oy, int &nx, int &ny, TPosition *r); protected: int FScore; void __fastcall SetScore(int NewScore); public: // ユーザー宣言 __fastcall TGameForm(TComponent* Owner); __property int Score = { read = FScore, write = SetScore }; };
プロパティScoreはスコアを管理します。現在のスコアはScoreプロパティによって分かりますが、実際にはFScoreを参照します。Scoreプロパティに値を設定すると、SetScore関数が呼ばれ適切な処理が行われます。
GameUnit.cppにScore関数を定義します。
void __fastcall TGameForm::SetScore(int NewScore) { if ((FScore = NewScore) < 0) FScore = 0; ScoreLabel->Text = FScore; }
ラケット数の管理
スコアと同じ手法でラケット数も管理します。ラケット数を表すプロパティはRacketCountにします。GameUnit.hを変更します(太字部分)。
class TGameForm : public TForm { __published: // IDE で管理されるコンポーネント TPanel *Panel1; TPanel *Court; : : private: // ユーザー宣言 int Ang, DeltaX, DeltaY; double Speed; void __fastcall MoveBall(); void __fastcall CalcNewDelta(); bool __fastcall CheckHit(int ox, int oy, int &nx, int &ny, TPosition *r); protected: int FScore, FRacket; void __fastcall SetScore(int NewScore); void __fastcall SetRacketCount(int NewRacket); public: // ユーザー宣言 __fastcall TGameForm(TComponent* Owner); __property int Score = { read = FScore, write = SetScore }; __property int RacketCount = { read = FRacket, write = SetRacketCount }; };
RacketCountを設定するSetRacketCount関数を、GameUnit.cppに記述します。
void __fastcall TGameForm::SetRacketCount(int NewRacket) { if (FRacket != NewRacket) { FRacket = NewRacket; if (FRacket > 5) FRacket = 5; else if (FRacket < 0) FRacket = 0; int i; for (i = 1; i < FRacket; i++) dynamic_cast<TLabel *>( FindComponent("Racket" + IntToStr(i)))->Visible = true; for (; i < 5; i++) dynamic_cast<TLabel *>( FindComponent("Racket" + IntToStr(i)))->Visible = false; } }
FindComponentメソッドは、フォームに配置されたコンポーネントを名前によって探す関数です。Racket1~Racket4の表示状態を変更する処理をforループで記述するために、この関数を使用しています。