2Dでのコーナーコリジョンの処理方法


22

トップダウンの2D XNAゲームを書いています。最初の頃から、物理学と衝突に関するものを自分で書いて、それを学習しようとしています。

プレーヤーのスプライトキャラクターが境界が壁の端と交差する位置に移動しようとするたびに、跳ね返り角度(入射角=反射の角度)を計算し、プレーヤーを壁から跳ね返して衝突を回避します。

角に当たったとしても、スプライトが2つの壁のエッジと同時に交差する状況をどのように処理するかを考えるのに苦労しています。

コーナー衝突

私のコードでは現在、2つの壁のエッジが交差しているが、どちらのエッジが最初にヒットしたか、したがってどのエッジが跳ね返ったかはわかりません。

どのエッジを跳ね返すかを選択する数学的テストは何ですか?見てみるとわかりやすいですが、数学テストを理解するのに苦労しています。



Tetradに感謝します。私はそれを見ましたが、ボールは私の長方形の問題とは異なる振る舞いをするように見えました。上記の例では、長方形のスプライトが壁の下端に当たって跳ね返っていました。壁の側端が方程式に入ることはなかったでしょう。コードでそれを表現し、その決定を下す方法がわかりません。
-TerryB

回答:


9

あなたはどのくらいに計算すると移動してきた、あなたはおそらく、交差しているコーナーのx、y座標のデルタでそれをベースにすることができます。それが理にかなっていることを願っています、私はそれを表現するより良い方法を考えることができない。WallPlayer Sprite

したがって、たとえば、図を見ると。テイクxの左上隅の値Player Sprite(移動後)を、および減算xの右下隅の値をWally値に対して同じことを行い、どちらが大きいかを確認します。重要なのは、一方が他方よりも大きい場合、Player Spriteおそらくその側で交差しているということです。

画像の例を次に示します(これは、独自の行を追加した画像のサブセクションです)。

交差点の例

ここで、青い線が緑の線よりも大きいことがわかります。この場合、青い線はPlayer Sprite、跳ね返ると予想される側にもあります。

2つの値が等しい場合、それらは右隅に当たります。

現在、この方法で行うには若干の問題があります。Player Spriteが非常に速く移動している場合、または衝突がコーナーの非常に近くにあるPlayer Sprite場合Wall、間違った方向にさらに進む可能性があります。その場合、おそらく移動するオブジェクトの速度を確認する必要があります。(Nathan Reedの回答を参照してください。)

注:私は本質的に@Blauが言及したSAT衝突検出について説明しようとしていると思いますが、これを書くのに長い時間を費やしてきたので、とにかく投稿します。うまくいけば、それがあなたを助けるでしょう。


Drackirに感謝します!そして、私の壁がスプライトに対して相対的に回転する場合、少し複雑ですが、同じ原理が当てはまります。スプライトが壁と衝突しないことを意味する最小長の変位ベクトルを探します。次に、そのベクトルに垂直な壁を、跳ね返る私の壁として使用します。
TerryB

@TerryB-回転により、さらに複雑さが増します。軸に沿った境界ボックス(AABB)を読み上げることができます。基本的に、回転したオブジェクトが収まる最小のボックスをテストすることで上記と同じ原理を使用しますが、そのボックスの軸はデカルト軸に揃えられます。正方形があり、それを45度回転してダイアモンドにする場合を想像してください。その上で衝突を計算するのは難しく、コストがかかるので、まず、ダイヤモンドの各ポイントが中央の各辺に接する正方形であるAABBを使用して、オブジェクトが近くにあるかどうかを確認します。
リチャードマースケル-Drackir 11年

次に、近くにあることがわかったら、より費用のかかる計算を実行して、角度で交差するかどうかを確認できます(おそらく別の質問になります:))。
リチャードマースケル-Drackir 11年

1
-1最小変位が「どのエッジが最初に衝突した」に対する正しい答えを常に与えるとは限らないため。私の答えをご覧ください。
ネイサンリード

@NathanReed-これが、「今、この方法で速度をチェックするのにわずかな問題がある」段落で速度のチェックに言及した理由です。
リチャードマースケル-ドラッカー

15

最小変位は、どのエッジが最初にヒットしたかについて常に正しい答えを与えるとは限りませ。この場合を考えてください:

最短変位アルゴリズムを破るケース

これは、1フレーム中にブロックがかなり遠くに移動するほど速度が高い場合に発生します。どのエッジが最初にヒットしたかを正しく検出するには、線形方程式を設定して、各エッジとの衝突時間を解く必要があります。OPの図で説明されているこの場合、関連する方程式は次のとおりです。

timeXCollision = (player.left - wall.right) / -player.velocity.x
timeYCollision = (wall.bottom - player.top) / player.velocity.y

(これは、X-right、Y-up座標系を前提としています。)一般に、player.velocityのXおよびYコンポーネントの兆候を使用して、テストする必要があるエッジのペアを決定する必要があります。とにかく、衝突時間が計算されると、2つのうち早い方が処理する必要のある衝突になります。


1
2つの変数を実装する方法の例を教えてください。
BjarkeCK

1

SAT衝突検出が必要です

基本的に、オブジェクトの1つに差し引かれて交差しない最小変位ベクトルを探す必要があります。

画像の最小変位はオレンジ色のセグメントです。

ここに画像の説明を入力してください


4
-1最小変位が「どのエッジが最初に衝突した」に対する正しい答えを常に与えるとは限らないため。私の答えをご覧ください。
ネイサンリード

誰がそれを求めているの?
ブラウ

質問はそれを求めています。「現在、私のコードでは、2つの壁のエッジが交差しているが、どちらのエッジが最初にヒットしたか、したがってどのエッジが跳ね返ったかはわかりません。」
ネイサンリード

最初?問題は最初のものではなく、2つのエッジに同時に衝突します。問題はどちらのエッジを跳ね返すかです。あなたに合った方法を1つ選択します。私にとっては、両方とも有効です
ブラウ

1
角を丸くしたり斜めにしたりするように、オブジェクトがそのようにすり抜けるように設計を決定する場合は、それがあなたの決定であり、ゲームプレイにとって正しいことです。しかし、質問が設計上の決定について尋ねているとは思わない。軸に沿って並んだ長方形を互いにバウンスする方法を数学的に求めています。これは解釈の問題ではありません。この数学の問題には、どのエッジを跳ね返すかに対する明確で正しい答えがあります。
ネイサンリード

0

ここで同様の質問に答えました

以前の位置を確認することを検討する必要があります-

たとえば、左側が以前に右側の右側にあり、衝突している場合、右側の衝突が発生しています。

これを行う場合は、y軸の衝突を解決し、何かと衝突しているかどうかを確認してから、x軸の衝突を解決します。

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