SHOEISHA iD

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

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

特集記事

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

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

  • X ポスト
  • このエントリーをはてなブックマークに追加

ボールを動かす

Timerを使ってボールを動かす

 次はボールを動かします。ボールは、Timerコンポーネントを用いて一定間隔で移動させます。FireMonkeyにはアニメーション機能もありますので、いろいろな動作を織り込むこともできるかもしれませんね。

 ツールパレットの「System」カテゴリから、TTimerコンポーネントをフォーム上に配置します。

図3 TTimerの配置
図2 図3 TTimerの配置

 プロパティを次のように設定します。

Timer1
プロパティ
Enabled False
Interval 10

 TTimerは、Intervalプロパティで指定した間隔(ミリ秒)で、OnTimerイベントを呼び出します。ここにボールを移動させるコードを記述します。

void __fastcall TGameForm::Timer1Timer(TObject *Sender)
{
    MoveBall();  // 一定間隔でボールを動かします
}

 MoveBall関数は、TGameFormのメンバ関数として作成します。GameUnit.hのTGameFormクラスの宣言にMoveBall関数の定義を追加します。

private:  // ユーザー宣言
    void __fastcall MoveBall();

ボールを動かす関数

 MoveBall関数は、GameUnit.cppへ次のように記述します。

void __fastcall TGameForm::MoveBall()
{
    // 移動後のボールの位置を計算します
    int x = Ball->Position->X + DeltaX;
    int y = Ball->Position->Y + DeltaY;

    // 壁に当たったかの判定
    if (y + Ball->Height >= Court->Height) {  // 下の壁
        // 壁に当たった
        // 以下のコードはテスト用です
        // ラケットにあたった判定などを後ほど作成します

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

 この関数を実行するためには、いくつかのメンバ変数を定義する必要があります。

メンバ変数と関数を定義する

 まず、ボールの角度を表すAng、移動速度を表すSpeed、そして一回の移動量を表すDeltaX、DeltaYです。これらの変数は、TGameForm のメンバ変数として、GameUnit.hのTGameFormクラス宣言に追加します。また、DeltaX、DeltaYを再計算するCalcNewDelta関数の宣言も追加します。

private:	// ユーザー宣言
    int Ang, DeltaX, DeltaY;
    double Speed;
    void __fastcall MoveBall();
    void __fastcall CalcNewDelta();

 設定された角度によって新しい移動量を計算するCalcNewDeltaは、次のようになります。ボールの角度をもとに三角関数によって縦横の移動量を求めています。 

void __fastcall TGameForm::CalcNewDelta()
{
    // 新しい角度のラジアンを求める
    double rad = ((double)Ang / 180.0) * M_PI;
    DeltaX = (int)(cos(rad) * Speed);  // Xの移動量
    DeltaY = (int)(sin(rad) * Speed);  // Yの移動量
}

 この関数では、cos、sin関数と円周率を表す M_PIを用いています。これらの関数や定数は、math.hで定義されています。これらの関数や定数を使用するために、GameUnit.cppに math.hをインクルードするための一文を追加します。

#include <fmx.h>
#include <math.h>
#pragma hdrstop

#include "GameUnit.h"

次のページ
ラケットの当たり判定

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

  • X ポスト
  • このエントリーをはてなブックマークに追加
特集記事連載記事一覧

もっと読む

この記事の著者

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

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

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

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

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/6635 2012/06/28 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

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

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

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

メールバックナンバー

アクセスランキング

アクセスランキング