4

私はかなり長い間Farseerを使用しており、物理教育プラットフォームプロジェクトに取り組んでいます。私の脳内のエンジンについては、かなり長い間答えられていない質問がいくつかあります。その多くは、エンジンの衝突処理に関するものです。

Farseerに適切なAPIがないこともあり、多くの人がエンジンの動作を理解するのに問題があるようです。知っている人は、次の概念を確認し、間違っている概念をすべて削除することをお勧めします。

コンセプト0:2つの段階

Farseerでの衝突は、次の2つの段階に分けられます。

  1. ブロードフェーズ衝突
  2. 正確な衝突(別の正式な名前がある場合は、私の用語の使用を修正してください...)

コンセプト1:ブロードフェーズ

Farseerは、広い位相の衝突を使用して、シーン内の潜在的な衝突を検出します。上記の広相衝突試験は、以下によって行われる。

  1. パッケージ「Farseer.Collision」にある四分木を使用します。

  2. クラス「Farseer.Dynamics.World」には、「Farseer.Collision.QuadTreeBroadphase」への参照があります。

  3. 「Farseer.Collision.QuadTreeBroadphase」には「Farseer.Collision.QuadTree」への参照があります。

  4. さらにバウンディングボックステストも行われます。

  5. フィクスチャのどのペアが衝突する可能性があるかを知る必要がある場合は、これを行うことができます...

    /* Game.Initialize */
    public override void Initialize() {
        OtherIrrelevantInitCode();
        _world.OnBroadphaseCollision += BroadphaseHandler;
        base.Initialize();
    }
    public void BroadphaseHandler(ref FixtureProxy fp1, ref FixtureProxy fp2) {
        // code to read about fp1 and fp2
    }
    

しかしその後...

小さな質問1

どのフィクスチャのペアが衝突する可能性があるかを知ることが役立つ一般的な状況のいくつかは何ですか?

コンセプト2:イベントの意味

2つのキーワードの定義:

  1. 触れる:2つのオブジェクトが接触しています。配列Manifold.Pointsは空ではありません
  2. 衝突:2つのオブジェクトが初めて接触します。

BeforeCollisionは、2つのオブジェクトが衝突しておらず、接触していないことを意味します。

OnCollisionは、2つのオブジェクトが衝突していることを意味しますが、触れてもこのイベントは発生しません。

AfterCollisionは、2つのオブジェクトが衝突していたことを意味しますが、現在は接触しているだけです。

OnSeparationは、2つのオブジェクトが接触していたことを意味しますが、現在は接触していません。

コンセプト3:イベントの使用

ブロードフェーズ衝突試験と精密衝突試験は常に実施されます。

OnCollisionイベントでfalseを返すか、IgnoreCollisionメソッドを使用すると、正確な衝突を無効にできます。

人々が「OnCollisionを空のままにしてtrueに戻すだけ」と言うのを何度も聞いたことがあります。一体どういう意味ですか?イベントを使用するということは、上記のイベントが発生したときに、追加の効果(たとえば、敵を倒す、スコアを付ける、サウンドを再生するなど)を適用したいということです。

4

1 に答える 1

3

この回答は、Farseer Physics 3.3.1(執筆時点での現在の安定バージョン)に適用されます。


ブロードフェーズは、パフォーマンスの最適化にすぎません。何が衝突する可能性があるかをすばやく判断するため、衝突できないものは、より高価な狭位相衝突検出を実行しません。


私の経験では、Farseerのイベントは期待どおりに設計されていません。私は自分のゲームのためにそれらを変更しなければならなかったことに気づきました-しかし幸いなことに、このコードは実際に読んだり変更したりするのはそれほど難しくありません。また、ドキュメントはいくつかの場所で正確ではありません。

FarseerPhysicsのイベントが実際に行うことは次のとおりです。

BeforeCollisionブロードフェーズが2つのフィクスチャのオブジェクトを作成する前に、新しい潜在的な衝突を登録するときに発生します。イベントハンドラーに戻るContactことで、の作成をブロックできます。Contactfalse

aの存在は、Contact必ずしも2つのフィクスチャが実際に接触していることを意味するわけではありません。つまり、広範なフェーズが成功したということです。AContactはタッチ/非タッチにすることができ、有効/無効にすることができます(最初は有効で非タッチです)。

OnCollisionContact非接触から接触に変化したときに発生します。falseを返すことにより、連絡先を無効にできます。奇妙なことに、trueを返すと、そのステップで別のイベントハンドラーが無効にした連絡先を再度有効にすることができます(これは、私が自分のゲーム用に変更したものの1つです)。

有効な接触接触のみが物理シミュレーションに影響を及ぼします。

OnSeparationの反対ですOnCollision:接触が接触から非接触に変化したときにトリガーされます。ここで連絡先を無効/有効にする方法はありません。

AfterCollisionそのフレームでの物理シミュレーションに関係するすべての人に呼び出されますContact(つまり、眠っている島ではなく、有効になっていて、触れている人)。これは、物理シミュレーションのステップの後、クリーンアップの前に呼び出されます。特に、前に呼び出され、Body.ForceクリアBody.Torqueされます(効果音などに便利です)。


通常、これらのイベントを使用して、エフェクト(パーティクル、サウンド、オブジェクトの破壊などのゲームの仕組みなど)をトリガーします。その場合、あなたはあなたが望むものを購読し、あなたが好きなことをして、そしてtrueを返します(連絡先を無効にしたり上書きしたりしないでください)。

物理エンジンをいじったり、連絡先を無効にしたりする場合(特に、前述のように、別のイベントハンドラーを使用して、誤って連絡先を再度有効にできる場合)、さらに複雑になります。Farseerの組み込みイベントが機能しない場合は、そのコードにアクセスして独自のイベントを追加するのが完全に合理的です。この高度なレベルでは、とにかく何が起こっているのかを正確に調べることができるように、実際にはソースから構築する必要があります。

于 2012-11-16T11:17:38.663 に答える