如何在libgdx/box2d中为特定物体强制执行最大速度?

3
我正在使用Libgdx通过Box2D创建场景。我有一个场景,希望使用applyForce不断推进一个特定的物体(方向会不时改变),但只能达到一定的速度。
想象一下一个在零重力环境下由火箭发动机(各侧均有喷嘴)推进的圆形物体,以进行说明。 是否有一种方法可以在不重新计算施加的力或每次更新时执行重复计算的情况下实现这一点?我只知道如何为所有对象设置最大速度。目前我最好的选择是以某种方式使用linearDamping,但我希望有更简单的解决方案。
1个回答

11

你可以使用SetLinearVelocity来覆盖当前的速度。

b2Vec2 vel = body->GetLinearVelocity();
float speed = vel.Normalize();//normalizes vector and returns length
if ( speed > maxSpeed ) 
    body->SetLinearVelocity( maxSpeed * vel );

===============

编辑: 简单的空气阻力可以通过在旅行方向相反的方向上施加小的阻力力,尺度与旅行速度成比例来建模。

b2Vec2 vel = body->GetLinearVelocity();
body->ApplyForce( 0.05 * -vel, body->GetWorldCenter() );

在这个例子中,拖动的比例值(为0.05)决定了拖动力和火箭发动机施加的力相等并且两个力相互抵消从而达到顶速的速度。

maxSpeed = thrustForce.Length() / 0.05;

纯理论派会指出,阻力实际上与速度的平方成正比,因此为了更准确,你可以这样做:

b2Vec2 vel = body->GetLinearVelocity();
float speed = vel.Normalize(); //normalizes vector and returns length
body->ApplyForce( 0.05 * speed * speed * -vel, body->GetWorldCenter() );

我认为这将使您达到最高速度

maxSpeed = sqrtf( thrustForce.Length() / 0.05 );

这种方法可能是可行的,但在我看来甚至更不理想,因为它会在每次更新时引入额外的计算。此外,像setVelocity这样的方法调用应该避免用于动态物体吧? - mikołak
它一定会起作用的,因为这正是Box2d强制实施你在问题中提到的最大速度限制的方法。也许这些计算并不像你想象的那么麻烦... 是的,如果您想要逼真的物理效果,直接设置速度通常是不推荐的,但这并不是您在这里要做的事情。 - iforce2d
关于真实性,嗯,我正在尝试模拟空气阻力;)但你可能是对的,我可能想太多了。我会检查这个解决方案。 - mikołak
我看到我忘了添加后续。不幸的是,这个解决方案对我来说不合适,因为我希望对象保持它们的惯性,而使用这个答案将强制我手动重新计算它。 - mikołak
我明白了,所以你不想让速度突然受到硬性限制。我添加了一些关于空气阻力的想法。 - iforce2d

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接