今回は2Dゲーム用の当たり判定についてメモります。今回は、長方形と長方形、円と円の当たり判定についてだけメモります。他は、その内書くと思います。
まず、簡単なのが長方形と長方形の当たり判定のチェックです。XNAにあるRecangle型には当たり判定に使えるメソッドが備わっているので、ソレを使います。使うのはRectangle.Interset(Rectangle)メソッドです。このメソッドは、メソッドを呼んでいる長方形と、引数で送られた長方形が接触しているかどうかをbool型で返します(trueの場合接触あり)
Rectangle one = new Rectangle( 0, 0, 100, 100); Rectangle two = new Rectangle( 30, 50, 100, 100); if (one.Intersects(two)) { // ...当たった時の処理 }
次は、円と円の当たり判定です。二つの円の当たり判定を確かめるには、以下の式を使います:
円1の中心点と円2の中心点の距離 < 円1の半径 + 円2の半径
これは、図にすると以下の用になります:
そして当りがある場合はこうなります:
これをコードで表すとこうなります:
class Circle { public float Radius = 0.0f; public Vector2 Position = Vector2.Zero; } private bool CheckCollision(Circle one, Circle two) { // 二つの円の距離を測る float distance = Vector2.Distance(one.Position, two.Position); // 当たり判定、trueなら当たっている return (distance < one.Radius + two.Radius); }
これで当たり判定のチェックは終わりです。余談ですが、Vector2.Distance()メソッドは距離を計る際sqrt(スクウェアルート)を使っている可能性が高く、sqrtはかなり重い方の計算なので、速度を出来る限り切り詰めなくてはいけない場合は、.Distance()の代わりに、DistanceSquared()を使うことが出来ます。このメソッドは、距離の2乗を返します。なので、当たり判定をする際には、半径2乗で計算すればホンの少しだけ速く計算でき・・・るはずです(細かくチェックしていないので100%の確信はまだ無いです)。
[…] 今回は、前に書いた当たり判定の記事の続編で、円と長方形の当たり判定の実装方法をメモります(いつか書くと思ったまま忘れてました・・・)。 […]
当たり判定の仕組みは理解できたのですが、記述方法がよく分からなかったので質問です。
例えば、classAのオブジェクトとclassBのオブジェクトがある。
classAの座標は(100,100)でclassBの座標は(800,100)である。
classBのオブジェクトのX座標を-100ずつしていきclassAとclassBが衝突した時にゲームを終了したいとした場合どういう感じのソースコードになるのでしょうか?
よろしくお願いします。
ちなみに質問は円と円の当たり判定の場合のときのことです。
特殊な事を考えていないならその場合は、移動のコードを記載後に、上記のCheckCollision()メソッドを呼び出し、その結果しだいで終了処理を加えれば良いはずです。