线性脉冲值

时间:2014-01-16 22:08:53

标签: java box2d

我正在使用Box2D创建自己的游戏应用程序,我遇到了一些问题。我设法渲染我想要的每一个身体,移动它们但我必须高价值才能正确移动它们。例如,这是我的玩家身体定义:

    bodyDefPlayer = new BodyDef();
    bodyDefPlayer.type = BodyType.DynamicBody;
    bodyDefPlayer.position.set(positionX, (positionY * tileHeight) + 50);
    playerBody = world.createBody(bodyDefPlayer);
    polygonPlayer = new PolygonShape();
    polygonPlayer.setAsBox(50, 50);
    fixturePlayer = new FixtureDef();
    fixturePlayer.shape = polygonPlayer;
    fixturePlayer.density = 0.8f;
    fixturePlayer.friction = 0.5f;
    fixturePlayer.restitution = 0.0f;
    playerBody.createFixture(fixturePlayer);
    playerBody.setFixedRotation(true);

以下是我如何运用我的冲动来推动他:

    Vector2 vel = this.player.playerBody.getLinearVelocity();
    Vector2 pos = this.player.playerBody.getWorldCenter();
    player.playerBody.applyLinearImpulse(new Vector2(vel.x + 20000000, vel.y * 1000000), pos, true);

正如你所看到的,我的价值非常高,而且当他下降时球员没有做曲线但是当他可以的时候更多的是直接下降。

我想请一些帮助:)

谢谢!

2 个答案:

答案 0 :(得分:2)

当您应该施加力时,似乎您正在使用线性脉冲。线性冲动" smacks"一个有很大力量的身体,使它具有很大的瞬时速度。如果你打高尔夫球(大力,小时间)或模拟发射的子弹,这是很好的,但它对于真实身体的运动看起来不太好。

这是我在我的实体上使用的一个函数,它是一个用于容纳box2D主体并将控制力施加到主体的类。在这种情况下,此函数ApplyThrust使身体向目标移动(寻找行为):

   void ApplyThrust()
   {
      // Get the distance to the target.
      b2Vec2 toTarget = GetTargetPos() - GetBody()->GetWorldCenter();
      toTarget.Normalize();
      b2Vec2 desiredVel = GetMaxSpeed()*toTarget;
      b2Vec2 currentVel = GetBody()->GetLinearVelocity();
      b2Vec2 thrust = desiredVel - currentVel;
      GetBody()->ApplyForceToCenter(GetMaxLinearAcceleration()*thrust);
   }

在这种情况下,实体已被赋予移动到目标位置的命令,该位置在内部缓存并可使用GetTargetPos()恢复。该函数通过在期望的最大速度(朝向目标)和当前速度之间生成差矢量来对身体施加力。如果身体已经以最大速度朝向目标,则此函数的贡献实际上为0(相同向量)。

请注意,这不会改变身体的方向。实际上有一个单独的功能。

注意原始问题似乎是在Java(libgdx?)中。这是在C ++中,但是一般的想法是适用的,并且应该在任何Box2d实现中使用引用而不是指针等。

samples of doing this located here的代码库。 You can read more about this code base in this post。观看视频......我怀疑它会立即告诉您这是否是您要查找的信息。

Normalize函数应该是b2Vec2类的成员:

/// Convert this vector into a unit vector. Returns the length.
float32 b2Vec2::Normalize()
{
    float32 length = Length();
    if (length < b2_epsilon)
    {
        return 0.0f;
    }
    float32 invLength = 1.0f / length;
    x *= invLength;
    y *= invLength;

    return length;
}

这将矢量转换为指向相同方向的单位矢量(长度= 1)。 注意这是就地操作。它改变了实际的b2Vec2对象,它不会返回一个新对象。根据需要适应Java。

这有用吗?

答案 1 :(得分:2)

您使用相同的图形和物理单位(像素)。这种方法很糟糕有两个原因:

  1. 它会在不同的分辨率下缩放
  2. Box2D被调整为使用某些范围的值(由于浮点数精度)。您可以在Box2D手册中找到值的范围。它们以米为单位,但是你如何命名单位实际上并不重要,因为Box2D不跟踪单位,而是操作值。例如,您可以说身体的速度是每秒10米或每秒10英尺。对于计算,这并不重要。当您解释计算结果时,这将变得很重要。例如,随着时间的推移行进距离:在第一种情况下,它将是米,在第二种情况下是一英尺。但这不是Box2D的业务。您只需将值传递给它(例如,body.pos.set(2, 3) //no info about units here
  3. 克服这些问题的常用技术是使用不同的单位与Box2D和图形一起使用,只是在它们之间重新缩放(在cocos示例中查找PTM_RATIO