グリーンの状態でリファクタリング
衝突判定のユニットテストはグリーンになりましたが、テストコードにdeleteが抜けているのでメモリリークを起こしてしまいます。
以前Objective-Cで書いていたコードを持ってきたので、ついdeleteを忘れてしまっていました。
単純にdeleteを追加すれば修正が終了しますが、テストコードをよく見るとCollisionDetection::isCollide関数の引数はポインタではなく参照の方が良い気がしてきました。
ですので、引数の型を参照にするようにリファクタリングを行う事にします。
テストファーストなので、先ずはテストコードの修正から。
TEST(Collision, isCollide) { CollisionArea area1(0.0f, 0.0f, 10.0f, 10.0f); CollisionArea area2(5.0f, 5.0f, 10.0f, 10.0f); CollisionArea area3(-15.0f, -5.0f, 10.0f, 10.0f); CollisionArea area4(-15.0f, -5.0f, 10.0f, 10.0f); CollisionArea area5(10.0f, 10.0f, 20.0f, 20.0f); CollisionArea area6(12.0f, 12.0f, 10.0f, 10.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)); // 小さな範囲が大きな範囲の内側に入っている }
単純にコンパイルエラーになるので、プロダクションコードも修正します。
bool CollisionDetection::isCollide(CollisionArea &lhs, CollisionArea &rhs) { const float selfLeft = lhs.x; const float selfTop = lhs.y; const float selfRight = selfLeft + lhs.w; const float selfBottom = selfTop + lhs.h; const float otherLeft = rhs.x; const float otherTop = rhs.y; const float otherRight = otherLeft + rhs.w; const float otherBottom = otherTop + rhs.h; if(selfLeft > otherRight) { return false; } // 判定対象の範囲は自分の範囲よりも左側にある if(selfTop > otherBottom) { return false; } // 判定対象の範囲は自分の範囲よりも上側にある if(selfRight < otherLeft) { return false; } // 判定対象の範囲は自分の範囲よりも右側にある if(selfBottom < otherTop) { return false; } // 判定対象の範囲は自分の範囲よりも下側にある // 判定対象の範囲は自分と重なっている部分がある return true; }
簡単な修正なので、問題なく終了してテストも通りました。
これでテスト駆動開発のレッド→グリーン→リファクタリングのサイクルが一度終了しました。
このテストはユニットのサンプルでよく見る、引数の値を処理して結果を戻り値として返す関数のシンプルなテストでした。
次はコリジョン判定を呼び出す処理周りを作っていこうかと思います。
今回のリビジョンのタグはこちらです。
blog_20140129