【问题标题】:Box2d - shoot ball with high velocityBox2d - 高速射球
【发布时间】:2014-02-24 12:54:57
【问题描述】:

我的问题是,无论调整如何,我都无法实现快速移动的球。它漂浮在空气中,而不是从空气中射出。

在下面的方法中,我创建了一个半径为5 单位的球。将半径设置为0.01 不会产生结果差异。

创建后,我应用了一个比例荒谬的LinearImpulse,但球只会漂浮。 (另外,我正在使用 DebugRender。这不应该负责单位转换吗?)

Ball class

public Body createBody(float x, float y, float w, float h) {
    BodyDef bodyDef = new BodyDef();
    bodyDef.type = BodyDef.BodyType.DynamicBody;
    bodyDef.position.set(x,y);
    Body body = this.getWorld().createBody(bodyDef);

    CircleShape shape = new CircleShape();
    shape.setRadius(5);
    shape.setPosition(new Vector2(0, 0));  // relative to body position

    FixtureDef fixtureDef = new FixtureDef();
    fixtureDef.shape = shape;
    fixtureDef.density = 3f;
    fixtureDef.friction = 0.1f;
    fixtureDef.restitution = 0.8f;
    body.createFixture(fixtureDef);

    shape.dispose();
    // note the massive impulse vector
    body.applyLinearImpulse(new Vector2(10000, 100000), body.getWorldCenter(), true);

    return body;
}

render method in Game class

@Override
public void render(){

    Gdx.gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
    debugRenderer.render(world, camera.combined);

    // time step, velocityIterations, positionIterations
    world.step(1/40.0f, 6, 2);

    // scheduler takes care of creating game objects on the fly
}

【问题讨论】:

  • 这可能是因为 Box2D 的最大速度受到更新率的限制。你有多少FPS?也许尝试类似 world.step(Gdx.graphics.getDeltaTime()) 的东西。
  • 按照建议更改 world.step() 确实确实增加了经验速度。但我有一种感觉,这不是解决方案。由于我使用的是 debugrenderer,所有对象不应该自动正确缩放吗?

标签: libgdx box2d


【解决方案1】:

好的,连同我对这个问题的回答Is there an upper limit on velocity when using box2d?我会尽力解释你的问题。

Box2D 对速度有硬性限制,即每个时间步长 2 米。这意味着您每秒执行的时间步长越多,您的身体移动的速度就越快。但是,由于您实际上希望每秒有固定数量的时间步,因此通常不能选择更多的时间步。

应该做的是引入米与像素的比率,该比率可能在 1:16 到 1:128 之间。这意味着 box2d 中的 1 米应转换为屏幕单位中的 16 或 128 像素。这将提高整体精度,因为 Box2D 在较小的范围内更精确。如果您的比例为 1:1,则意味着如今的标准屏幕将跨越 1980 米 x 1080 米的范围,这绝对是太多了。您还可以看到,在 60fps = 60 个时间步长 = 60*2m 每秒最大距离的情况下,在最大速度下每秒只有 120 像素。这就是你目前作为浮体所体验到的。

例如,如果您将 1m 转换为 16px,则您的最大速度将增加到每秒 120px*16 = 7200px。我猜你的情况已经足够了。

此外,您还应该将body.bullet 设置为true 以提高快速移动物体的碰撞精度。

【讨论】:

  • 很好的答案!我认为让我有点难过的一件事是调试渲染器。我曾假设调试渲染器负责所有世界到像素的转换。我会接受你实施米/像素比的建议。
  • 不,米与像素的比例是您必须自己关心的事情。但是,有一个非常简单的解决方案。制作一个额外的相机,其视口按比例缩放。这意味着类似于Camera cam = new OrthographicCamera(Gdx.graphics.getWidth() * PIXEL_TO_METER, Gdx.graphics.getHeight() * PIXEL_TO_METER) 并将其提供给您的 DebugRenderer
【解决方案2】:

其中一个原因是世界比例尺,如果世界比例尺很大,您可能有一个非常大的世界比例尺。

它建议为了更好的准确性使用 set bullet to true 但是它需要更多的计算

body.bullet = true;

【讨论】:

  • 这样做对速度没有帮助。它只会改善碰撞。
  • 确实,它对我所看到的实际速度没有影响。
  • 关于世界比例,我没有在任何地方定义任何比例,我只是使用shape.setRadius(5) 设置大小。假设我将半径设置为 1 并使用调试器,这不应该是一个合适的值吗?
  • 这很奇怪,注意 setRadius 就像有多少脂肪的皮肤,所以在任何形状上你都可以将它设置为你想要的任何值甚至是负值,它只是一个偏移量,但对于圆形它是半径。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多