gpt4 book ai didi

c# - 概念检查器 : Collision situations in Farseer

转载 作者:行者123 更新时间:2023-11-30 12:12:34 27 4
gpt4 key购买 nike

我使用 Farseer 已经有一段时间了,从事物理教学平台项目。我脑子里有几个关于引擎的问题很长一段时间都没有得到解答,其中很多是关于引擎的碰撞处理。

许多人似乎无法理解引擎的工作原理,部分原因是 Farseer 缺少合适的 API。对于知情人士来说,确认以下概念并杀死任何错误的概念可能是个好主意。

概念0:两个阶段

Farseer 中的碰撞分为两个阶段:

  1. 广义相碰撞
  2. 精确碰撞(请更正我对术语的使用,如果它有另一个更正式的名称...)

概念 1:Broadphase

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:事件的意义

两个关键字的定义:

  1. 接触:两个物体接触。数组 Manifold.Points 不为空
  2. 碰撞:两个物体第一次相互接触。

BeforeCollision 表示两个对象没有碰撞并且没有接触

OnCollision 表示两个对象正在碰撞,但接触不会触发此事件。

AfterCollision 表示两个对象正在碰撞,但现在它们只是接触

OnSeparation 表示两个对象接触,但现在它们没有接触。

概念 3:使用事件

宽相碰撞测试和精确碰撞测试始终进行。

可以通过在事件 OnCollision 中返回 false 或使用 IgnoreCollision 方法来禁用精确碰撞。

我不止一次听到人们说“让 OnCollision 为空并返回 true”。这到底是什么意思?使用事件意味着我们希望在上述事件发生时应用额外的效果(例如杀死敌人、得分、播放声音等)。

最佳答案

此答案适用于 Farseer Physics 3.3.1(撰写本文时的当前稳定版本)


Broad-phase 只是一种性能优化。它可以快速确定什么可以碰撞,这样不能碰撞的东西就不会运行更昂贵的窄相碰撞检测。


根据我的经验,Farseer 中的事件 设计得并不尽如人意。我发现我不得不为我自己的游戏修改它们 - 但幸运的是这段代码实际上并不难阅读和修改。此外,该文档在一些地方并不准确。

以下是 Farseer Physics 中的事件实际上所做的:

BeforeCollision 发生在 broad-phase 注册一个新的潜在碰撞时,在它创建一个Contact对象之前两个固定装置。您可以通过在事件处理程序中返回 false 来阻止创建 Contact

Contact 的存在并不一定意味着这两个 fixture 实际上 处于接触状态 - 只是 broad phase 成功了。 Contact 可以触摸/不触摸,也可以启用/禁用(它们开始时启用但不触摸)。

OnCollisionContact 从不接触变为接触时发生。您可以通过返回 false 来禁用联系人。奇怪的是,如果您返回 true,您可以重新启用另一个事件处理程序在该步骤中禁用的联系人(这是我为自己的游戏所做的更改之一)。

只有启用的触摸接触才会对物理模拟产生任何影响。

OnSeparationOnCollision 相反:当接触从接触变为非接触时触发。无法在此处禁用/启用联系人。

AfterCollision 为该帧物理模拟中涉及的每个 Contact 调用(因此:启用、触摸、而不是在一个沉睡的岛上)。它在物理模拟步骤之后,但在清理之前调用 - 最值得注意的是在 Body.ForceBody.Torque 被清除之前(方便声音效果等) .


通常,您只需使用这些事件来触发您的效果 - 粒子、声音、游戏机制(如摧毁物体)等等。在这种情况下,您可以订阅任何一个您想要的,做任何您喜欢的事情,然后返回 true(而不是禁用/覆盖联系人)。

如果您想扰乱物理引擎或禁用触点(特别是当您可能不小心重新启用它们时,使用另一个事件处理程序,如前所述),事情会变得更加复杂。如果 Farseer 的内置事件对您不起作用,那么进入其代码并添加您自己的事件是完全合理的。在这个高级级别,实际上有必要从源代码构建,这样您就可以准确地检查到底发生了什么。

关于c# - 概念检查器 : Collision situations in Farseer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13393945/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com