目前,我的游戏中此功能还可以,但我在数学上并不出色。当两个原始函数碰撞时,如果施加给原始函数的力超过设定的阈值,我希望它们粉碎成小块。目前我的碰撞事件处理程序看起来像这样。
public bool Collision(Fixture fixtureA, Fixture fixtureB, Manifold manifold)
{
Vector2 position = manifold.LocalNormal;
float angle = (float)Math.Atan2(position.Y, position.X);
Vector2 force = Vector2.Zero;
if (angle < 0)
force = new Vector2((float)(Math.Cos(angle) * fixtureA.Body.LinearVelocity.X), (float)Math.Sin(MathHelper.TwoPi + angle) * fixtureA.Body.LinearVelocity.Y);
else
force = new Vector2((float)(Math.Cos(angle) * fixtureA.Body.LinearVelocity.X), (float)Math.Sin(MathHelper.TwoPi - angle) * fixtureA.Body.LinearVelocity.Y);
double XForce = Math.Sqrt(force.X * force.X);
double YForce = Math.Sqrt(force.Y * force.Y);
double totalForce = XForce + YForce;
if ((Breakable) && (totalForce > BreakForce))
{
Breakable = false;
Active = false;
BreakUp(fixtureA, fixtureB);
}
return true;
}
我把它放在很久以前,当时我只是在玩耍。在某些情况下,这会引起一些问题。例如,如果一个灵长类动物在地板上静止不动,而另一个灵长类动物从一个体面的高度跌落到地板上,几乎总是这样,掉落的盒子会炸毁,而静止的盒子会幸存下来。同样,如果两个盒子并排掉落并且彼此碰触得最细,那么两个盒子都会吹起半空中。嗯,那不是很完美。有谁知道如何改进我的碰撞处理程序?提前致谢。
最佳答案
(虽然这是当前公认的答案-我会把任何人引导到我的other answer以寻求潜在的更优方法。)
您对冲击力的计算是完全错误的。您需要获得接触点的相对速度-您得到的东西很奇怪...
您的代码看起来像是在使用Farseer 3.0(您应该指定,因为与Farseer 2.1相比,它更像是Box2DX的分支)。我在Farseer 2.1(您使用ContactList contacts
而不是Manifold
)中所做的操作是:
foreach(Contact contact in contacts)
{
Vector2 position = contact.Position;
Vector2 v0;
me.Body.GetVelocityAtWorldPoint(ref position, out v0);
Vector2 v1 = new Vector2();
if(!hit.Body.IsStatic)
hit.Body.GetVelocityAtWorldPoint(ref position, out v1);
v0 -= v1;
float hitVelocity = v0.Length();
// To then get the force, you need the mass of the two objects
}
从Farseer 3.0的源代码中看,
Manifold
似乎有一个成员:public FixedArray2<ManifoldPoint> Points;
Manifold
和ManifoldPoint
都有成员:public Vector2 LocalPoint;
修改Farseer 2.1代码以使用这些代码应该相当简单。
另外:我建议您简单地将两个对象标记为需要中断,然后在物理更新完成运行之后(而不是在碰撞处理程序中)实际中断它们。
关于c# - 使用Farseer Physics的C#XNA中的OnCollision事件处理程序问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3308012/