キャラクタの当たり判定

当たり判定に関してリクエストが来たのでまとめてみました。

まずは、キャラクタ同士のあたり判定について。

キャラクタ同士があたっているかどうかは、それぞれの図形の頂点が開いての範囲に入っているかどうかを確認します。それぞれの図形はいくら複雑でも良いですが、、通常は四角ですね。重なっていると以下のようになるのでそれぞれの頂点を判定します。



青四角ABCDと、赤四角EFGHとの当たり判定の場合、まず、ABCDの各点がEFGHの中にあるか、調べます。それから赤四角が青四角にすっぽりと入っている場合のために今度はEFGHの各点がABCDの中に入っているか調べます。ひとつでも入っていると判断されれば二つの四角は重なっています。

具体的なコードでは、それぞれの位置をどのように持つかという事が重要ですが、この例では構造体とします。
ペンティアムマシンならクラスで持っても問題は無いでしょう。
 

 int CAtariDlg::AtariHantei(charab * a1, charab * a2)
 {
 // a2の左上点がa1の範囲内か
 if( (a2->x > a1->x) && (a2->x x+a1->w)){ // a2の左上点がa1のX軸範囲内か
 if( (a2->y > a1->y) && (a2->y y+a1->h)) // a2の左上点がa1のY軸範囲内か
  return 0; // 当たっている
 if( (a2->y+a2->h > a1->y) && (a2->y+a2->h y+a1->h))// a2の左下点がa1のY軸範囲内か
  return 0; // 当たっている
 }
 
 // a2の右上点がa1の範囲内か
 if( (a2->x+a2->w > a1->x) && (a2->x+a2->w x+a1->w)){ // a2の左上点がa1のX軸範囲内か
 if( (a2->y > a1->y) && (a2->y y+a1->h)) // a2の左上点がa1のY軸範囲内か
  return 0; // 当たっている
 if( (a2->y+a2->h > a1->y) && (a2->y+a2->h y+a1->h))// a2の左下点がa1のY軸範囲内か
  return 0; // 当たっている
 }
 
 // a1の左上点がa2の範囲内か
 if( (a1->x > a2->x) && (a1->x x+a2->w)){ // a1の左上点がa2のX軸範囲内か
 if( (a1->y > a2->y) && (a1->y y+a2->h)) // a1の左上点がa2のY軸範囲内か
  return 0; // 当たっている
 if( (a1->y+a1->h > a2->y) && (a1->y+a1->h y+a2->h))// a1の左下点がa2のY軸範囲内か
  return 0; // 当たっている
 }
 
 // a1の右上点がa2の範囲内か
 if( (a1->x+a1->w > a2->x) && (a1->x+a1->w x+a2->w)){ // a1の左上点がa2のX軸範囲内か
 if( (a1->y > a2->y) && (a1->y y+a2->h)) // a1の左上点がa2のY軸範囲内か
  return 0; // 当たっている
 if( (a1->y+a1->h > a2->y) && (a1->y+a1->h y+a2->h))// a1の左下点がa2のY軸範囲内か
  return 0; // 当たっている
 }
 
 return 1; // 当たってない
 }
 

これはもっともシンプルなあたり判定ですが、通常のアクションゲームやシューティングゲームでは十分実用的です。

壁や、道などの判定も基本的にはこれと同じです。データをどう持つか、比較するデータをどう作るかといったところに工夫が必要になります。

このプログラムの動作チェック用プロジェクト