花鬼の庵

開発とかゲームとか実況とか

【当たり判定】弾丸やボール等が速すぎて当たり判定をすり抜けてしまう場合の解決方法

弾丸やボールが目標に当たった瞬間に何かしらの処理を実行したい。(体力低下やスコア加算等)
だけど弾丸やボール等のスピードが速すぎて的をすり抜けてしまう…。
何故なんだ…orz
理由は簡単、スピードが速すぎると1F(フレーム)に動く距離が長くなるからです。

f:id:HanaoniEruni:20181211205326g:plain
図1:物体の速度によっては当たらない

このように1Fに動く距離が長くなると的を通り過ぎてしまう、つまりすり抜ける。

なら1F内で少しずつ当たり判定を繰り返してあげれば良い

void main()
{
    vector3 ballPos{0,0,0}; // ボールの初期位置は{0,0,0}と仮定
    float  Len = 10;     // まず1フレームで進む距離を取得(10と仮定)
    int    num = 10;       // 何回に分けて判定するか
    bool isHit = false;

    for( int i = 0; i < num; i++ )
    {
        // ここでは10回に分けているので1/10ずつボールを動かす
        ballPos.x += Len / num;
        
        // 動かすたびに当たり判定を行う
        // (ここでは当たり判定の関数に通している)
        if( CheckHit(ballPos) )
        {
           isHIt = true;   
         break;
        }
    }
}
bool ChackHit(vector3 pos)
{
  vector3 EnemyPos {8,0,0};  // 敵(的)の位置は{8,0,0}と仮定
    // ここでは敵と重なったら当たったとする
    if( EnemyPos == pos )
    {
      return true;
    }
}

ballPosは1フレームでLen(上記では10)ずつ動く。
Lenをnumで割った分をnumだけ動かしていく(上記では1/10ずつ動かすという処理を10回行っている)。
そのたびに当たり判定を通して当たったら処理から抜ける。
もし1/10でもすり抜けるなら、numの値を大きくしてさらに細かく動かして判定を取れば、速度が速すぎてすり抜けるということはなくなると思います。(ただしその分重くなる可能性はもちろんある)

締め

考え方はどの言語でも共通です。

上のソースは説明用のものなのでコピペしてもエラーを吐きます。ご注意を。
なにか質問等々ございましたらコメントいただければと思います。