忍者ブログ

しののめん

プログラミングを勉強中の人のあれこれなブログ

矩形同士の当たり判定(角もあるよ!)

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

コメント

ただいまコメントを受けつけておりません。

矩形同士の当たり判定(角もあるよ!)

ブロック崩しを作成している過程で教えてもらいながらやっとこさ出来たソースを公開してみる試み。
今回のソースは当たり判定の中でもメジャーな矩形同士の当たり判定。
結構ネット上とかにもソースはあるのだけど、角まで含んだのは珍しいのではないだろうか?

というわけで公開。

-----------------------------------------------------------------------------------------

BOOL HIT = FALSE; //当たったかどうかのフラグ。初期設定ではFALSE
BlockAYCenter;    //矩形Aの中心Y座標
BlockAXCenter;    //矩形Aの中心X座標
BlockBYCenter;    //矩形Bの中心Y座標
BlockBXCenter;    //矩形Bの中心X座標
BlockBYSpeed;     //矩形BのY速度
BlockBXSpeed;     //矩形BのX速度
BlockAWid;        //矩形Aの横幅
BlockAHei;        //矩形Aの縦幅
BlockBWid;        //矩形Bの横幅
BlockBHei;        //矩形Bの縦幅

void Hit()
{


 //当たり判定。ここらへんはいろんなところでソースが出ていると思う。
 //所謂、二つの座標の絶対値の距離を参照して一定の範囲内だったらTRUEを返すアルゴリズム。
 //ただ、今回の判定では未来予測を使用していることに注意。
 if (abs(BlockAYCenter - (BlockBYCenter + BlockBYSpeed)) <= (BlockAHei + BlockBHei) / 2)
 {
  if (abs(BlockAXCenter - (BlockBXCenter + BlockBXSpeed)) <= (BlockAWid + BlockBWid) / 2)
  {
   HIT = TRUE;
  }
 }

 if (HIT)
 {
  //角の当たり判定。問題はここ。
  //まず、現在位置においてどこにあるのかを判定する。
  //このif文は、現状矩形Aが矩形Bの角付近にいる場合を定義している。
  if (abs(BlockBXCenter - BlockAXCenter) > ((BlockAWid + BlockBWid) / 2) && abs(BlockBYCenter - BlockAYCenter) > ((BlockAHei + BlockBHei) / 2))
  {
   //そして判定。
   //角に当たって、接触している部分の形が正方形になるのなら、角に当たっているという判定。
   //そうでない場合(接触している部分の形が長方形の場合)は、XとYのどちらが長いかを場合分けして左右か上下どちらかにあたっているかを場合分けする。
   if (((BlockAWid + BlockBWid) / 2) - abs((BlockBXCenter + BlockBXSpeed) - BlockAXCenter) == ((BlockAHei + BlockBHei) / 2) - abs((BlockBYCenter + BlockBYSpeed) - BlockAYCenter))
   {
    //ここに角に当たった場合の処理を書く。
   }
   else if (((BlockAWid + BlockBWid) / 2) - abs((BlockBXCenter + BlockBXSpeed) - BlockAXCenter) > ((BlockAHei + BlockBHei) / 2) - abs((BlockBYCenter + BlockBYSpeed) - BlockAYCenter))
   {
    //ここに角には当たっているけど左右の辺よりな場合の処理を書く。
   }
   else if (((BlockAWid + BlockBWid) / 2) - abs((BlockBXCenter + BlockBXSpeed) - BlockAXCenter) < ((BlockAHei + BlockBHei) / 2) - abs((BlockBYCenter + BlockBYSpeed) - BlockAYCenter))
   {
    //ここに角には当たっているけど上下の辺よりな場合の処理を書く。
   }
  }
  //そして、角以外の当たり判定=各々の辺に当たっているなのでelseで処理を書く。
  else
  {
   //ここでは左右か上下かどちらかの場合分けをしている。
   //とりあえず、上下の場合をif文で定義。それ以外は左右なのでelseで分岐。
   if (((BlockAWid + BlockBWid) / 2) - abs((BlockBXCenter + BlockBXSpeed) - BlockAXCenter) > ((BlockAHei + BlockBHei) / 2) - abs((BlockBYCenter + BlockBYSpeed) - BlockAYCenter))
   {
    //ここに上下の辺にあたっている時の処理を書く。
   }
   else
   {
    //ここに左右の辺にあたっている時の処理を書く。
   }
  }
 }
}

-----------------------------------------------------------------------------------------

と、こんな感じのソースが出来上がりました。
今回、ブロック崩しを作成している過程でのソースなので、ブロック崩し専用のアルゴリズムになるのかな?
矩形が片方しか動いてなかったり、上下と左右の二つでしか場合分けしてないのがその証拠ですね(ブロック崩しは基本上下と左右は処理が同じ)。
あとこれ、矩形の動き方が斜め45度の時にしか上手く動いてくれないっぽいです。
ただ、角にも判定を作らなきゃいけないという場合には参考になるかと思います。

そしてちょっとだけソースの解説、いやソース内でも記述はしてあるけど。

まず、当たり判定には未来予測を使用しています。
次のフレームで当たる時に、現在のフレームの位置関係を調べてどの方向から当たるのかを調べているわけですね。

そして角付近に居る場合。接触したら角にぶつかったということになるのですが、角といってもちょっきり角に当たった場合と少し上にずれてるとかそういう場合があります。
それを調べるために、「接触している部分の形が正方形ならちょっきり角に当たったよー」という分岐を追加しているのですね、それ以外はずれているのでズレてる場合の処理。
そして角付近にいないということは辺の付近にいるということなのでelseを使用しているわけです。

ということで解説終了。
まぁ、ソースを見てもらって、使えそうならご自由に改変して使ってくださって問題ないです。
矩形同士の当たり判定にしか使えませんので、使う部分は限られてそうですが。

拍手[1回]

PR

コメント

プロフィール

HN:
東雲楓
性別:
男性
趣味:
特にない感じ

カレンダー

07 2025/08 09
S M T W T F S
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31

リンク

P R