我现在已经使用Farseer了很长一段时间,从事物理教学平台项目。关于我大脑中的发动机有一些问题很长一段时间没有得到解决,其中很多都与发动机的碰撞处理有关。
许多人似乎在理解引擎的工作方面存在问题,部分原因是因为Farseer缺少适当的API。对于那些知道确认以下概念而 KILL 任何错误的概念,这可能是一个好主意。
Farseer中的碰撞分为两个阶段:
使用广泛相位碰撞的Farseer将在场景中发现潜在的碰撞。所述宽相碰撞试验由......完成。
如果我们发现需要知道哪一对灯具有可能发生碰撞,我们可能会这样做......
/* 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
有哪些常见情况对我们了解哪些灯具可能会发生碰撞有用?
两个关键字的定义:
BeforeCollision 表示两个对象不碰撞且不接触。
OnCollision 表示两个对象碰撞,但触摸不会触发此事件。
AfterCollision 表示两个对象发生碰撞,但现在仅触及。
OnSeparation 表示两个对象,但现在不是。
广泛的碰撞测试和精确的碰撞测试始终。
可以通过在事件 OnCollision 中返回false或使用IgnoreCollision方法来禁用精确碰撞。
我听过不止一次人们说"只是让OnCollision空了并且返回真实"。究竟是什么意思?使用这些事件意味着我们希望在上述事件发生时应用其他效果(例如杀死敌人,得分,播放声音等)。
答案 0 :(得分:3)
此答案适用于Farseer Physics 3.3.1 (当前稳定版本,撰写时)
广泛阶段只是一种性能优化。它可以快速确定可以碰撞的内容,以便无法碰撞的东西不会有更昂贵的窄相位碰撞检测运行。
根据我的经验,Farseer中的事件的设计并不尽如人意。我发现我必须为自己的游戏修改它们 - 但幸运的是,这段代码实际上并不难以阅读和修改。此外,文档在一些地方也不准确。
BeforeCollision
在广泛阶段注册新的潜在冲突时,在为两个灯具创建Contact
对象之前发生。您可以通过在事件处理程序中返回Contact
来阻止false
的创建。
Contact
的存在并不一定意味着两个灯具实际接触 - 只是宽广的阶段成功了。 Contact
可以触摸/不触摸,可以启用/禁用它们(它们开始启用且不触摸)。
OnCollision
从不接触变为触摸时,会发生 Contact
。您可以通过返回false来禁用联系人。奇怪的是,如果你返回true,你可以重新启用另一个事件处理程序在该步骤上禁用的联系人(这是我为自己的游戏改变的事情之一)。
只有启用的触摸式触点才会对物理模拟产生任何影响。
OnSeparation
与OnCollision
相反:当联系人从触摸变为不触摸时触发。这里没有办法禁用/启用联系人。
AfterCollision
都会调用 Contact
(所以:那些已启用,触摸,而不是在一个睡着的岛屿中)。它是在物理模拟步骤之后调用的,但在清理之前 - 最明显的是在清除Body.Force
和Body.Torque
之前(方便声音效果等)。
通常你只是使用这些事件来触发你的效果 - 粒子,声音,游戏机制,比如摧毁物体等等。在这种情况下,您订阅任何您想要的,做您喜欢的任何事情,然后返回true(不禁用/覆盖联系人)。
如果你想搞乱物理引擎或禁用联系人(特别是当你不小心重新启用它们时,使用另一个事件处理程序,如前面提到的那样)会变得更加复杂。如果Farseer的内置事件对您不起作用,那么进入其代码并添加自己的代码是完全合理的。在这个先进的水平上,从源代码构建实际上是必要的,这样你就可以确切地检查究竟发生了什么。