libGDX:Box2D速度不够增加

时间:2017-07-01 22:53:49

标签: java libgdx box2d

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

不幸的是,速度似乎永远不会变得足够高。例如,即使为每个轴执行applyLinearImpulse的{​​{1}}速度矢量(所需速度)245044.23,身体的最终速度也会变成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);
        //... 

1 个答案:

答案 0 :(得分:1)

Box2D确实限制了速度。限制基本上是为了避免floating point arithmetic的不准确。如您所发现的,步速为1/60秒的245044.23速度远高于此极限。如果你可以将你的步骤时间缩短到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)。

希望这有帮助!