我现在在我的游戏中有这个工作正常(ish),但我在数学方面并不出色.当两个原发性物质发生碰撞时,如果施加于原色的力超过设定的阈值,我希望它们粉碎成微小的碎片.我目前的碰撞事件处理程序看起来像这样.
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;
}
Run Code Online (Sandbox Code Playgroud)
我是在很久以前刚刚玩的时候把它放的.这在某些情况下会引起一些问题.例如,如果一个灵长类动物是在地板上固定,另一个灵长类动物从一个体面的高度落到它几乎总是落箱炸毁和休息盒生存.此外,如果两个箱子并排下落侧给对方触摸的tinyest,那么这两个箱子炸掉半空中.嗯,不是那么完美.有谁知道如何改进我的碰撞处理程序?提前致谢.
好的,所以我的另一个答案是可行的.但是我更仔细地研究了Farseer 3.0(当前的SVN版本)并发现它已经完全实现了你想要做的事情.
寻找" BreakableBody.cs ".您可以直接使用它 - 但是否则您可以复制出您想要的功能.
具体来说:OnCollision您不想将功能附加到您的灯具上,而是将其附加到PostSolve.它需要ContactConstraint你可以潜入并找到碰撞的冲动.
这是由BreakableBody以下函数使用的函数的实现:
private void PostSolve(ContactConstraint contactConstraint)
{
if (!Broken)
{
float maxImpulse = 0.0f;
for (int i = 0; i < contactConstraint.manifold.PointCount; ++i)
{
maxImpulse = Math.Max(maxImpulse,
contactConstraint.manifold.Points[0].NormalImpulse);
maxImpulse = Math.Max(maxImpulse,
contactConstraint.manifold.Points[1].NormalImpulse);
}
if (maxImpulse > Strength)
{
// Flag the body for breaking.
_break = true;
}
}
}
Run Code Online (Sandbox Code Playgroud)
显然,流形中的脉冲数据只能正确设置PostSolve,而不是在OnCollision.
(虽然这是目前接受的答案 - 我会指示任何人找到我的另一个答案,以获得潜在的优越方法.)
你对冲击力的计算是完全错误的.你需要在接触点获得相对速度 - 你得到的东西很奇怪......
您的代码看起来像是使用Farseer 3.0(您应该指定,因为它更像是Box2DX的分支而不是Farseer 2.1).我在Farseer 2.1(你得到的ContactList contacts而不是a 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
}
Run Code Online (Sandbox Code Playgroud)
从简短的Farseer 3.0源代码看,似乎Manifold有一个成员:
public FixedArray2<ManifoldPoint> Points;
Run Code Online (Sandbox Code Playgroud)
两者Manifold并ManifoldPoint有成员:
public Vector2 LocalPoint;
Run Code Online (Sandbox Code Playgroud)
修改我的Farseer 2.1代码以使用它们应该相当简单.
另外:我建议简单地将两个对象标记为需要中断,然后在物理更新完成运行后实际打破它们(而不是在碰撞处理程序中).
| 归档时间: |
|
| 查看次数: |
3752 次 |
| 最近记录: |