0
votes

I'm learning the basics of Box2D using LibGDX. I come to you guys today because I have some trouble to understand how Velocity works. I actually use two bodies : one DynamicBody (for the player) and one StaticBody (the ground). It looks like this in image : game_screen For now nothing wrong, I next added a ControlSystem which allow player to use directionals arrows to move (up, left and right obviously). The issue comes when I want to go on left/right, whenever is use Body.setLinearVelocity(somevalue, 0) it moves well but I still have a small amout of Y velocity that I don't want. I highly think it's caused by the ground (somehow with friction or something like this) but I really know nothing about physics in general so I can't really say. I want to know if there is a way to move the player on left and right with an Y Linearvelocity to 0. By the way I want this Y LinearVelocity to 0 because I use a "StateComponent" which it sets the state to "JUMPING" if Y LinearVelocity is over 0. The code looks like this :

@Override
protected void processEntity(Entity entity, float deltaTime) {
    BodyComponent bodyComp = bodm.get(entity);
    StateCompent state = sm.get(entity);
    TextureComponent texComp = texm.get(entity);

    if(bodyComp.body.getLinearVelocity().y > 0){
        state.set(StateCompent.STATE_FALLING);
    }

    if(bodyComp.body.getLinearVelocity().y == 0){
        if(state.get() == StateCompent.STATE_FALLING){
            state.set(StateCompent.STATE_NORMAL);
        }
        if(bodyComp.body.getLinearVelocity().x != 0){
            state.set(StateCompent.STATE_MOVING);
        }
    }
    if(controller.left){
        bodyComp.body.setLinearVelocity(MathUtils.lerp(bodyComp.body.getLinearVelocity().x, -2f, 0.2f),bodyComp.body.getLinearVelocity().y);
        if(!texComp.region.isFlipX()){
            texComp.region.flip(true, false);
        }
    }
    if(controller.right){
        bodyComp.body.setLinearVelocity(MathUtils.lerp(bodyComp.body.getLinearVelocity().x, 2f, 0.2f),bodyComp.body.getLinearVelocity().y);
        if(texComp.region.isFlipX()){
            texComp.region.flip(true, false);
        }
    }
    if(!controller.left && ! controller.right){
        bodyComp.body.setLinearVelocity(MathUtils.lerp(bodyComp.body.getLinearVelocity().x, 0, 0.1f),bodyComp.body.getLinearVelocity().y);
    }

    if(controller.up && (state.get() == StateCompent.STATE_NORMAL || state.get() == StateCompent.STATE_MOVING)){
        bodyComp.body.applyLinearImpulse(0,10f, bodyComp.body.getWorldCenter().x, bodyComp.body.getWorldCenter().y, true);
        state.set(StateCompent.STATE_JUMPING);
    }

    // Hud to delete later
    hudBatch.begin();
    layout.setText(font, " X velocity : " + Float.toString(bodyComp.body.getLinearVelocity().x));
    font.draw(hudBatch, " X velocity : " + Float.toString(bodyComp.body.getLinearVelocity().x), Gdx.graphics.getWidth() - (layout.width + 20), Gdx.graphics.getHeight() - layout.height);
    layout.setText(font, " Y velocity : " + Float.toString(bodyComp.body.getLinearVelocity().y));
    font.draw(hudBatch, " Y velocity : " + Float.toString(bodyComp.body.getLinearVelocity().y), Gdx.graphics.getWidth() - (layout.width + 20), Gdx.graphics.getHeight() - (layout.height + 20));
    font.draw(hudBatch, "State : " + Integer.toString(state.get()), 20, Gdx.graphics.getHeight() - 20 );
    hudBatch.end();

And maybe if needed the FixtureDef of my two bodies :

  fixtureDef.density = 1f;
  fixtureDef.friction = 0.2f;
  fixtureDef.restitution = 0.01f;

I also uploaded a video, you can see on this video that when I use my left or right arrow key to move the Velocity Y is up to something like 0,000000001. Any idea why ?

2
Try to set restitution = 0 so the object should not re-jump after hitting the groundMorchul
I'll try it. But can you explain me what restitution is exactly ? As I said I really know nothing about physics basics.SamHel
This is a good tutorial to understand Fixtures: iforce2d.net/b2dtut/fixtures at the beginning it says: restitution - how bouncy the fixture is / friction - how slippery it is / density - how heavy it is in relation to its area. Hope this will help you. It is written in c++ but you can easy convert to javaMorchul

2 Answers

0
votes

Most physics engines naturally have a little bit of velocity on both directions, especially during collisions. Just factor this into your jump checking, e.g. make the threshold a little bit higher than 0.

0
votes

Ok guys I found something pretty interesting. I was surprised because of this issue because I first followed this tutorial and it worked well in it. I just noticed that in this tutorial we use a Circle shape for the player, so I tried this and it worked well as I wanted. Maybe because there is less point of contact or something like that.