【问题标题】:libGDX: Box2D velocity not increasing enoughlibGDX:Box2D 速度没有增加足够
【发布时间】:2017-07-04 04:14:11
【问题描述】:

如果有一个我正在使用 box2d 的游戏项目。现在在我的运动系统中(我正在使用基于实体组件的方法),我希望 Box2D 根据控件设置的所需速度来移动我的对象。

不幸的是,速度似乎永远不够高。例如,即使在每个轴的速度矢量(所需速度)为245044.23 的情况下进行applyLinearImpulse 时,所得到的身体速度也只是大约为90.0。我在做什么错?有什么限制吗?

这是我运行速度更新和世界步骤的代码:

//************************
// physics-system
//************************
public void update(float deltaTime) {

        float frameTime = Math.min(deltaTime, 0.25f);
        accumulator += frameTime;
        if (accumulator >= MAX_STEP_TIME) {

            world.step(MAX_STEP_TIME, 6, 2);
            accumulator -= MAX_STEP_TIME;

            for (Entity entity : entities) {
                TransformComponent transform = tim.get(entity);
                BodyComponent bodyComp = bod.get(entity);
                VelocityComponent velocity = vel.get(entity);

                Vector2 bodyVelocity = bodyComp.body.getLinearVelocity();
                float velChangeX = velocity.horizontalVelocity - bodyVelocity.x;
                float velChangeY = velocity.verticalVelocity - bodyVelocity.y;

                float impulseX = bodyComp.body.getMass() * velChangeX;
                float impulseY = bodyComp.body.getMass() * velChangeY;

                bodyComp.body.applyLinearImpulse(new Vector2(impulseX, impulseY), bodyComp.body.getWorldCenter(),
                        false);

                // update transform
                Vector2 position = bodyComp.body.getPosition();
                transform.x = (int) position.x;
                transform.y = (int) position.y;

                // slowingdownVelocitys(velocity);

            }
        }

    }

这里是我目前唯一一个带有 box2D-Component(称为 BodyComponent)的实体的定义:

        Entity entity = new Entity();
        //...
        BodyComponent bodyComponent = new BodyComponent();
        BodyDef bodyDef = new BodyDef();

        bodyDef.type = BodyDef.BodyType.DynamicBody;

        bodyDef.position.set(transformComponent.getX(), transformComponent.getY());

        bodyComponent.body = GameManager.getB2dWorld().createBody(bodyDef);
        bodyComponent.body.applyAngularImpulse(50f, true);

        CircleShape circle = new CircleShape();
        circle.setRadius(2f);

        FixtureDef fixtureDef = new FixtureDef();
        fixtureDef.shape = circle;
        fixtureDef.density = 10f;
        fixtureDef.friction = 0.4f;
        fixtureDef.restitution = 0.6f; // Make it bounce a little bit

        bodyComponent.body.createFixture(fixtureDef);

        circle.dispose();

        entity.add(bodyComponent);
        //... 

【问题讨论】:

  • this线程
  • Marc M,如果它解决了您的问题,请考虑接受我的回答,否则请留下评论,解释您仍然没有回答的问题。谢谢!

标签: java libgdx box2d


【解决方案1】:

Box2D 确实限制了速度。限制基本上是为了避免floating point arithmetic 的不准确性。正如您所发现的,245044.23 的速度和 1/60 秒的步进时间远高于此限制。如果你可以将你的步数降低到 1/200000 秒,你可以模拟每秒 245044.23 米,但我认为我们大多数人都很难让它实时运行。以每秒 60 步的步速(每步仅为模拟秒的 1/60),您所说的速度约为每步 4084 米,因为 Box2D 单位基本上是 MKS 单位(米、千克、秒)。同时,速度限制被限制为每步 2 米(b2_maxTranslation)。这个限制可以提高,但随着它的提高,您更有可能看到更少的类似物理的行为,例如隧道。

至于你做错了什么,除了尝试使用高于 Box2D 可以处理的速度方式之外,通常像你描述的问题是使用视觉缩放的结果。请记住,Box2D 的位置以米为单位,而我们的大多数显示器(在水平或垂直方向上)都比米小得多。 Box2D 常见问题解答中有这样的说法about scaling in terms of pixels

假设您有一个 100x100 像素的角色精灵。你 决定使用比例因子 0.01。这将使 角色物理框 1m x 1m。所以去做一个1x1的物理盒子。 现在假设字符从像素坐标 (345,679) 开始。所以 将物理框定位在 (3.45,6.79)。现在模拟物理 世界。假设角色物理框移动到(2.31,4.98),所以移动 你的角色精灵到像素坐标(231,498)。现在唯一 棘手的部分是选择比例因子。这真的取决于你的 游戏。你应该试着让你的移动物体在 0.1 - 10 范围内 米,1 米是最佳位置。

您要回答的问题是使用什么缩放比例,以便 Box2D 可以处理的物理速度可以以仍然可以看到的方式转化为视觉效果。在 1/60 秒(每步)的步模拟中,Box2D 将处理的速度限制为每秒 +/- 120 米。但是通过巧妙地使用世界坐标和图形坐标之间的缩放比例,可以达到每秒 120 个距离单位,您可以将距离单位设置为公里或太米等。

请注意,速度过慢也会带来问题 - 例如遇到碰撞响应的速度阈值 (b2_velocityThreshold)。

希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-06
    • 2011-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多