【问题标题】:How to enforce a maximum speed for a specific body in libgdx/box2d?如何为 libgdx/box2d 中的特定主体强制执行最大速度?
【发布时间】:2012-09-20 00:09:58
【问题描述】:

我通过 Libgdx 使用 Box2D 来创建场景。我有一个场景,我想使用applyForce 不断推动特定对象(方向会不时改变),但只能达到给定的速度。

想象一个由火箭发动机推动的圆形物体(四面都有喷嘴),重力为零,以作说明。

有没有办法在不重新计算施加的力或每次更新时重复计算的情况下做到这一点?我只知道如何为所有对象设置最大速度.目前我最好的选择是以某种方式使用linearDamping,但我希望有一个更简单的解决方案。

【问题讨论】:

    标签: java box2d libgdx


    【解决方案1】:

    您可以使用 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 之类的方法?
    • 它肯定会起作用,因为这与 Box2d 强制执行您在问题中提到的最大速度限制的方式相同。也许这些计算并没有您想象的那么严重……是的,如果您想要逼真的物理效果,通常不建议直接设置速度,但这不是您在这里要做的。
    • 关于现实主义,好吧,我试图模拟空气阻力;)...但你可能是对的,我可能想多了。我会检查这个解决方案。
    • 我看到我忘记添加后续内容了。不幸的是,这个解决方案不适合我,因为我希望对象保持它们的惯性,并且使用这个答案将迫使我手动重新计算它。
    • 我明白了,所以你不想突然硬限制速度。我添加了一些关于空气阻力的想法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-05
    • 1970-01-01
    • 2011-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多