衝突検出ロジックはどこに配置する必要がありますか?


19

私は小さな2Dゲームエンジンを開発しています。文字には、現在次のことを行うpaintメソッドがあります。

  1. 速度などに応じてキャラクターの新しい位置を計算します。
  2. コリジョングリッドセルを更新します**
  3. 新しい位置にキャラクターを描く

**交差点チェックの回数を減らすために衝突グリッドを作成しました

今、衝突を検出するために私が考えた基本的なアルゴリズムは次のとおりです。

For Each Character
    Check intersection with characters in surrounding 8 cells

このメソッドをpaintメソッドに配置するだけです。しかし、ここに私が予想する問題があります。

2つの文字AとBが衝突グリッドの隣接するセルにあるとします。これで、上記のアルゴリズムに従って、文字Aの反復でBと衝突したことが検出されます。文字Bの反復で、文字Aと衝突したことが検出されます。

しかし、AがBと衝突したことをAが検出すると、Aと衝突したことをBに通知する必要があるという考えがあります。これにより、衝突するアクタが2人以上いる場合に多くの比較を保存できます。しかし、私はこれをどのように扱うかわかりません。すべてのキャラクターが衝突をチェックする代わりに、ゲームループ内で衝突をチェックする必要があると思います。

このアプローチは正しいでしょうか?この種の問題をどのように処理しましたか?衝突グリッドのことは自分で考えました。コリジョングリッドロジックに代わるものはありますか?


nitpickには申し訳ありませんが、専門の2D物理ライブラリです。ゲーム物理学は通常非常に近似的であるため、ゲームをプレイ不可能にしない解決策は問題ありませんが、正しく解決したい場合は、Box2Dなどの特殊な物理学を使用してください...
-D

回答:


14

衝突検出の通常のアプローチは、AまたはBのどちらも単独で衝突を検出しないことです。

代わりに、最初にすべてのオブジェクトを移動し、別の衝突システムですべてのオブジェクトのペア間の衝突を探し、衝突したものについてすべてのオブジェクトに伝え、最後にすべてのオブジェクトをレンダリングします。

したがって、本質的には、Paint()関数内で「移動、衝突の確認、描画」を行う代わりに、「移動」と「描画」を別々に呼び出す別々の関数に分割します(最初にすべてのオブジェクトに対して「移動」、すべてのオブジェクトに対して「描画」)。そして、それらの間で、衝突をチェックします。

高度な注意:検出された衝突に反応してオブジェクトのいずれかが移動する場合、オブジェクトの衝突応答が別の衝突を引き起こす場合に備えて、「オブジェクトのすべてのペア間の衝突を探す」ステップを繰り返す必要があります。


これが適切な方法です。オブジェクトにその責任を任せ、衝突システムが障害に遭遇したときに何が起こるかを決定する必要があります。また、初期トリガーのようなものとして、キャラクターの周りに衝突長方形/シリンダー(2d / 3d)を持つことができます。
ジェームズP.

すばらしいです!高度なメモに関しては、衝突に反応して移動するオブジェクトと、新しい位置で衝突するオブジェクトについてのみ、衝突を再チェックするべきではありませんか?チェックのチェーンが存在しますが、すべてのオブジェクトの衝突チェックを回避します。
クラッカー


1

あなたが言うように、ゲームループ内のすべてのキャラクターに対してループを実行します。

私が行う方法は、各キャラクターの状態を使用することです。そのため、Aが衝突をチェックしているときにAとBが衝突すると、AとBはヒットするように設定されます。Bのループの先頭で、すでにヒットしているかどうかを確認します。ヒットしている場合、idはループを実行しません。

影響コードをループに入れたので、Bで実行されるアクションはAのループで発生したため、衝突の結果を台無しにするBがチェックする理由はないはずですが、これはあなたにとって異なるかもしれません。


ただし、この場合、AがBとの交差を検出すると、B.hitはtrueに設定されるため、Bは交差をチェックしません。しかし、別のキャラクターCがBと交差する場合、Bはそれを検出しませんか?
クラッカー

ごめんなさい AはCと交差しないため、C.hitは依然としてfalseです。Bは衝突をチェックしません。しかし、CはBとCの間に衝突があるという情報をチェックしてBに渡します。
クラッカー

しかし、A、B、Cがすべて交差すると問題が発生すると思います。AはB.hitとC.hitをtrueに設定します。BとCは、Aと衝突したことを認識します。しかし、ヒットプロパティがtrueであるため、衝突をチェックしません。BとCの衝突は見過ごされます。
クラッカー

すべての実行可能な衝突オブジェクトを何らかのコレクションに配置し、コレクション内のオブジェクトの後に来るものとの衝突のみをチェックすることで、同様の方法で忍び込むことができます。IE:Aチェックvs B、C、D。Bチェック対C、D; CはDをチェックします。後ろの人は、後ろの人のターンからすでにチェックされているので、チェックする必要はありません。要素の衝突を完全にスキップするほど高速ではありませんが、それでも便利です。
ルニン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.