テスト駆動でゲーム開発はできるのか?

ゲームの開発にテスト駆動開発を取り入れてみる検証のブログです

衝突判定のテストコードを書く

アクションゲームなので、先ずはシンプルな衝突判定処理を作成する所から始める事にします。

テストファーストで開発する流れは、簡単に説明すると以下のようになります。

  1. テストコードを書いて失敗させる → レッド
  2. テストコードが通るように実装する → グリーン
  3. ソースコードを整理する → リファクタリング

ですので、まず衝突判定のテストコードを書いて失敗させます。

TEST(Collision, isCollide) {
	CollisionArea *area1 = new CollisionArea(0.0f, 0.0f, 10.0f, 10.0f);
	CollisionArea *area2 = new CollisionArea(5.0f, 5.0f, 10.0f, 10.0f);
	CollisionArea *area3 = new CollisionArea(10.0f, 10.0f, -15.0f, -5.0f);
	CollisionArea *area4 = new CollisionArea(10.0f, 10.0f, -15.0f, -5.0f);
	CollisionArea *area5 = new CollisionArea(20.0f, 20.0f, 10.0f, 10.0f);
	CollisionArea *area6 = new CollisionArea(10.0f, 10.0f, 12.0f, 12.0f);

	ASSERT_TRUE(CollisionDetection::isCollide(area1, area2));	// 一部が重なっている
	ASSERT_FALSE(CollisionDetection::isCollide(area1, area3));	// 重なっていない
	ASSERT_TRUE(CollisionDetection::isCollide(area3, area4));	// 同じ位置と大きさの範囲が重なっている
	ASSERT_TRUE(CollisionDetection::isCollide(area5, area6));	// 大きな範囲の内側に小さな範囲が入っている
	ASSERT_TRUE(CollisionDetection::isCollide(area6, area5));	// 小さな範囲が大きな範囲の内側に入っている
}

テストコードだけではコンパイルが通らないので、レッドの状態です。
次にコンパイルを通すため必要なクラスと空の関数を書きます。

/**
 * @brief 衝突範囲
 */
class CollisionArea {
private:
	float _x, _y, _w, _h;
public:
	CollisionArea(float x, float y, float w, float h);
};

/**
 * @brief 衝突判定クラス
 */
class CollisionDetection {
public:
	static bool isCollide(CollisionArea *lhs, CollisionArea *rhs);
};

クラスの関数の内容は未実装なので、テストはまだ通りません。
この状態もまだレッドのままです。
ですが、コンパイルは通るのでここで一度区切りをつけてコミットをする事にします。

テストが通らないままコミットをするのは良くないので、以下のようにテストケースに DISABLED_ 設定を追加して、通らないテストを無視させます。

TEST(Collision, DISABLED_isCollide)

これで、コンパイルもテストも(実行されませんが)通るようになったのでコミットします。

実際はレッドのままですが、コミットをした事で一息つく事ができました。

今回のリビジョンのタグはこちらです。
blog_20140127