MoveBallの改造
Scoreプロパティと RacketCountプロパティが用意できたところで、これらの値を変更するコードが抽象化できます。MoveBall関数を変更して、ラケットを失うコードを追加してみましょう。
void __fastcall TGameForm::MoveBall() { // 移動後のボールの位置を計算します int x = Ball->Position->X + DeltaX; int y = Ball->Position->Y + DeltaY; // ラケットにヒットしたかどうかを判定 TPosition *pos = Racket->Position; // ラケットの座標 if (CheckHit(Ball->Position->X, Ball->Position->Y, x, y, pos)) { if (x < pos->X + 2 || x + Ball->Width > pos->X + pos Width - 2) Ang = 360 - Ang + (random(60) - 30); // 角で引っかけた else Ang = 360 - Ang; // 正しくヒット Ball->Position->X = x; Ball->Position->Y = y; CalcNewDelta(); MessageBeep(-1); return; } // 壁に当たったかの判定 if (y + Ball->Height >= Court->Height) { // 下の壁 // 壁に当たった LostRacket(); // ラケットを消す RacketCount = RacketCount - 1; if (RacketCount == 0) GameOver(); // ゲームオーバー else { // 次のラケットを使ったゲームの準備 Speed += 0.4; Ball->Position->X = Court->Width / 2; Ball->Position->Y = Court->Height / 3; Ang = random(45) + 90; CalcNewDelta(); } return; // 以下の3行はコメントにします。 //Ang = 360 - Ang; // 跳ね返った角度を計算 //CalcNewDelta(); // 新しい移動量を計算 //y = Court->Height - Ball->Height; } else if (y < 0) { // 上の壁 Ang = 360 - Ang; //跳ね返った角度を計算 Speed += 0.1; // 上の壁に当たると少し早くなります CalcNewDelta(); // 新しい移動量を計算 y = 0; } if (x + Ball->Width >= Court->Width) { // 右の壁 Ang = 180 - Ang; // 跳ね返った角度を計算 CalcNewDelta(); // 新しい移動量を計算 x = Court->Width - Ball->Width; } else if (x < 0) { // 左の壁 Ang = 180 - Ang; //跳ね返った角度を計算 CalcNewDelta(); // 新しい移動量を計算 x = 0; } // ボールの位置を変更 Ball->Position->X = x; Ball->Position->Y = y; }
この関数内で使用しているLostRacket関数とGameOver関数を定義します。GameUnit.hに関数の宣言を追加します(太字部分)。
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);
void __fastcall LostRacket();
void __fastcall GameOver();
GameUnit.cppに記述するLostRacket関数とGameOver関数の定義は次のとおりです。
void __fastcall TGameForm::LostRacket() { // ラケットの大きさを保管 int orgWidth = Racket->Width, orgHeight = Racket->Height; // ラケットを少しずつ消す for (int i = 0, w = orgWidth/2; i < w; i++) { Racket->Width = Racket->Width - 2; Racket->Height = (orgHeight * (w - i))/ w; Racket->Position->X = Racket->Position->X + 1; Racket->UpdateStyle(); // ラケットの表示更新 Sleep(20); // 20msec待つ } Sleep(100); // 100msec待つ // ラケットを元の大きさに戻す Racket->Width = orgWidth; Racket->Height = orgHeight; // ラケットを中央に配置 Racket->Position->X = (Court->Width - orgWidth) / 2; MessageBeep(-1); } void __fastcall TGameForm::GameOver() { // タイマーの停止 Timer1->Enabled = false; // ボールを非表示にする Ball->Visible = false; // ボタンの状態変更 StartButton->Enabled = true; StopButton->Enabled = false; // ゲームオーバーのメッセージ ShowMessage("Game Over"); }
