SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

C++Builder XE2+FireMonkeyで昔のラケットゲームを再構築してみる(4)

15年前の入門書の課題を、最新の開発環境を使って再挑戦

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");
}

次のページ
START/STOPボタンの設定

この記事は参考になりましたか?

特集記事連載記事一覧

もっと読む

この記事の著者

EDN編集部(イーディーエヌ編集部)

エンバカデロ・デベロッパーネットワーク(EDN)は、ソフトウェア開発者とデータベース技術者のための技術情報サイトです。Delphi、C++Builderをはじめとする開発ツールやER/Studioなどのデータベースツールに関連する技術記事、ビデオなどを提供しています。EDN編集部は、EDN記事と連携...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/6651 2012/07/12 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー