XNA メモ – 円と長方形の当たり判定

Posted: 2012年2月17日 カテゴリー: プログラミングメモ, XNA, XNAメモ
タグ:, , , , , , , , ,

今回は、前に書いた当たり判定の記事の続編で、円と長方形の当たり判定の実装方法をメモります(いつか書くと思ったまま忘れてました・・・)。

今回は出来るだけ簡単で短い実装方法を目指します。まず、下準備として円を表すクラスを作ります。

class Circle
{
 public Vector2 Center;
 public float Radius;

 public Circle(Vector2 center, float radius)
 {
 Center = center;
 Radius = radius;
 }
}

そして、当たり判定の実装です。当たり判定の確認は、円の中心点から、長方形の一番近い点を獲得し、その距離を測る事で判定します。

private bool CheckCollision(Circle circle, Rectangle rect)
{
 // 円に一番近い位置を長方形から探す
 Vector2 closest = new Vector2(MathHelper.Clamp(circle.Center.X, rect.Left, rect.Right),
 MathHelper.Clamp(circle.Center.Y, rect.Top, rect.Bottom));

 // 計算した位置と、円の中心点との距離を測る
 float distanceSquared = Vector2.DistanceSquared(closest, circle.Center);

 // 距離が円の半径より長い場合は、当たっていない
 return (distanceSquared < (circle.Radius * circle.Radius));
}

後は、このメソッドを呼び、確認したい長方形と円を渡します。

if (CheckCollision(m_circle, m_bound))
{
// ... 当たった時の処理
}

こんな感じになります。

 

以上です。今回、距離の計算にVector2.DistanceSquared()を使ったのは、2乗のまま計算したほうが、sqrt()を使わずにすむ分速いからです。なので、距離を計算する時も半径の2乗を使っています。

今回の実装方法は多分速度としても悪くは無いですが、一つの問題は長方形を回転させたら位置がずれ、ちゃんと確認出来ないことです。それについては気が向いたら書きます(また忘れるフラグ)。

コメント
  1. araki より:

    後は、このメソッドを呼び、確認したい長方形と円を渡します。
    if (CheckCollision(m_circle, m_bound))
    {
    // … 当たった時の処理
    }

    これはどこに記述すればよいのでしょうか?

    • K1 より:

      何処に記載するかはゲーム内用や、実装方法によりますが、このサンプルは当たりがあるかどうかを確認したい時/箇所に記載するように紹介しました。

  2. araki より:

    private bool CheckCollision(Circle circle, Rectangle rect)
    {
    // 円に一番近い位置を長方形から探す
    Vector2 closest = new Vector2(MathHelper.Clamp(circle.Center.X, rect.Left, rect.Right),
    MathHelper.Clamp(circle.Center.Y, rect.Top, rect.Bottom));

    // 計算した位置と、円の中心点との距離を測る
    float distanceSquared = Vector2.DistanceSquared(closest, circle.Center);

    // 距離が円の半径より長い場合は、当たっていない
    return (distanceSquared < (circle.Radius * circle.Radius));
    }

    このメソッドはどこに記述すべきでしょうか?

    • K1 より:

      前回の質問同様、何処に実装するかはゲーム内容や、個人の好みで変わります。(実装方法もそれにより変化します)

      Circleクラス内、当たり判定のマネージャークラス内、等様々な選択肢があるので、自分がしっくり来る方法で実装してみてください。

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中