長方形の境界ボックスが衝突した後、壁に引っかかる


7

XNAの組み込みのIntersects()を2つの長方形で使用して、衝突を検出し、速度をゼロに設定できます。しかし、オブジェクトはそこに引っかかって出られません!この衝突を適切に解決するにはどうすればよいですか?

回答:


12

これは、オブジェクトが壁に入り込んで衝突が見つかったら、速度をゼロに設定してオブジェクトの動きを停止するだけで、オブジェクトはまだその壁内にあるためです。

これを修正するには、オブジェクトを移動して衝突を解決する必要があります。ここには2つのオプションがあります。

  • 衝突を検出したらすぐに移動をキャンセルする速度の反対を適用して、オブジェクトを元の位置に戻します。長所:実装が非常に簡単です。ゲームのプレイに影響がない場合は、このオプションを使用してください。短所:これにより、オブジェクトが衝突を引き起こす方向に移動することが防止されます(たとえば、壁に沿ってスライドすることができなくなります)。
  • オブジェクトがどこにあるかを見つけ、それに応じて衝突を解決します。たとえば、オブジェクトが左から来て壁の左側で衝突した場合、オブジェクトを壁のすぐ左に移動するだけです。これを四角形のすべての辺で繰り返すことにより、オブジェクトは目的の速度に向かって移動し続けることができますが、衝突は回避されます。

2番目のオプションの実装

ここでは、速度がオブジェクトの移動方向を表していると仮定します(基本的に、オブジェクトの位置変更と衝突チェックの間の速度変更しないことに注意してください)。また、原点が画像の左上にあると仮定します(したがって、オブジェクトを移動して衝突を解決する場合は、左上隅を配置します)。

ここに私がする方法があります:

if (objRect.Intersects(wallRect)) // If there is a collision
{
    Vector2 newPos = obj.Position;

    if (obj.Velocity.X > 0) // object came from the left
        newPos.X = wallRect.Left - objRect.Width;
    else if (obj.Velocity.X < 0) // object came from the right
        newPos.X = wallRect.Right;
    if (obj.Velocity.Y > 0) // object came from the top
        newPos.Y = wallRect.Top - objRect.Height;
    else if (obj.Velocity.Y < 0) // object came from the bottom
        newPos.Y = wallRect.Bottom;

    obj.Position = newPos;
}

古いオブジェクトの位置を使用してオブジェクトがどこから来たかを見つけることもできますが、この場合は速度を使用する方が簡単です。


はい、基本的には壁に引っかかって衝突が続いています。これを解決するにはどうすればよいですか?
Jopo

あなたが尋ねたようにそれを編集していました。いくつかのコードサンプルで、両方のオプションがどのように実装されるかを示しますか?
ジェシーエモンド2011年

最初に最初に実装したのは、方向と呼ばれるベクトルを実装することです。これは、押されたキーに応じて左または右で正規化されたベクトルです。これに、衝突が検出されたときの速度を掛けます。これはほとんどの部分で機能しましたが、長方形の片側(右側?)でのみ機能するようです。2番目の例については、これについて多くのことを聞いたが、具体的な実装を見たことがないので、コードサンプルに感謝します。
Jopo

1
最初のオプションは、してはいけないことの例です。そのタイプの衝突検出を備えたゲームであれば、私は欠陥があると考えます。
AttackingHobo

1
あなたが与えられた方法を実装することができ、それがうまくいったなら、なぜこの答えは受け入れられないのですか?
ジョナサンコネル

1

これはさまざまな方法で行うことができます。

1つの方法は、四角形の以前の位置をフレームごとに保存することです。したがって、長方形が交差する場合は、オブジェクトの位置を衝突していない古いものに設定するだけです。この方法は最適ではありません。四角形の速度が高い場合、コードを介して行った再配置が表示される場合があるためです。

別の方法は、レイキャストとの衝突をテストすることです。これにより、衝突が発生する前にプレビューできます。

レイキャストの衝突に関するドキュメントについては、msdnを参照してください。そうすれば、それを実行できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.