LibGDX circle object keep rolling

337 Views Asked by At

Basically i have a circle object which acts as the player, and it can only jump. What I want to do is make the circle object keep rolling while having a constant gravity or force act on the circle object to make it keep rolling to the right on the ground. I have tried making a constant gravity by setting the vector2 x value to 0.5f:

World world = new World(new Vector2(0.5f, -9.8f), true); 

When i do this the ball rapidly keeps moving faster as time goes on.

Is there way I can achieve my desired effect?

Play class code:

public class Play implements Screen,ContactListener{

World world = new World(new Vector2(0f, -9.8f), true);  
Box2DDebugRenderer debugRenderer;  
OrthographicCamera camera;  
static final int PPM = 100;
static float height,width;
Body player;
RayHandler handler;
PointLight l1;
Body groundBody;
float tileSize;
boolean playerOnGround = false;
int footContact;
ShapeRenderer shapeRenderer;
PointLight light;
TiledMap tileMap;
OrthogonalTiledMapRenderer tmr;
BallJump game;
int level;

Color lightColor = new Color();

public Play(int level,BallJump game ) { 
    this.level = level;
    this.game = game;
}


@Override
public void show() {
    shapeRenderer = new ShapeRenderer();

    height = Gdx.graphics.getHeight();
    width = Gdx.graphics.getWidth();

    //set camera
     camera = new OrthographicCamera();  


     new FitViewport(width/PPM/2, height/PPM/2, camera);
    if((height + width) > 1500 && (height + width) < 2000) { 
        camera.zoom = 0.5f;
    } else if ((height + width) > 2000) { 
        camera.zoom = 0.75f;
    }
     camera.update();  




     //player Body  
     BodyDef bodyDef = new BodyDef();  
     bodyDef.type = BodyType.DynamicBody;  
     bodyDef.position.set((width/PPM)/2/2, (height / PPM)/2/2);  
     player = world.createBody(bodyDef);  
     CircleShape dynamicCircle = new CircleShape();  
     dynamicCircle.setRadius(5f/PPM);  
     FixtureDef fixtureDef = new FixtureDef();  
     fixtureDef.shape = dynamicCircle;  
     fixtureDef.density = 0.4f;  
     fixtureDef.friction = 1f;  
     fixtureDef.restitution = 0f;  











     player.createFixture(fixtureDef).setUserData("player");;  
     debugRenderer = new Box2DDebugRenderer();  

     //Lighting

     handler = new RayHandler(world);

     light = new PointLight(handler,500,Color.MAGENTA,4f,width/PPM/2/2/2,height/PPM/2/2);
     light.attachToBody(player);



     // tile map

     tileMap = new TmxMapLoader().load("test2.tmx");
     tmr = new OrthogonalTiledMapRenderer(tileMap,0.01f);

     TiledMapTileLayer layer = (TiledMapTileLayer) tileMap.getLayers().get("block");
     tileSize = layer.getTileHeight()*2;

     for(int row = 0; row < layer.getHeight(); row++) { 
         for(int col = 0; col < layer.getWidth(); col++) { 
             Cell cell =  layer.getCell(col, row);
             if(cell == null) { continue;}
             if(cell.getTile() == null) { continue;}

             BodyDef bdef = new BodyDef();
             bdef.type = BodyType.StaticBody;
             bdef.position.set((col + 0.5f) * tileSize /PPM/2, (row + 0.5f) * tileSize /PPM/2);

             PolygonShape cs = new PolygonShape();
             cs.setAsBox(tileSize/2/PPM/2, tileSize/2/PPM/2);




             FixtureDef fdef = new FixtureDef();
             fdef.friction = 0f;
             fdef.shape = cs;
             world.createBody(bdef).createFixture(fdef).setUserData("ground");;

             world.setContactListener(this);



         }
     }


}


public void update() { 

     playerOnGround = footContact > 0;





    if(Gdx.input.isKeyJustPressed(Keys.UP) || (Gdx.input.isTouched())) { 
        if(playerOnGround)
        player.applyForceToCenter(0, 0.75f, true);
    }
     else if (Gdx.input.isKeyPressed(Keys.SPACE)) { 
        player.setTransform((width/PPM)/2/2, (height / PPM)/2/2, 0);
    }




}




@Override  
public void pause() {  
}  

@Override  
public void resume() {  
}


@Override
public void beginContact(Contact contact) {

    Fixture a = contact.getFixtureA();
    Fixture b = contact.getFixtureB();


    if(b.getUserData().equals("player") && b.getUserData() != null) { 
        footContact++;
        player.setAngularDamping(5f);
    } 
    if(a.getUserData().equals("player") && a.getUserData() != null) { 
        footContact++;
        player.setAngularDamping(5f);
    } 





}


@Override
public void endContact(Contact contact) {
    Fixture a = contact.getFixtureA();
    Fixture b = contact.getFixtureB();

    if(b.getUserData().equals("player") && b.getUserData() != null) { 
        footContact--;
    } 
    if(a.getUserData().equals("player") && a.getUserData() != null) { 
        footContact--;
    } 


}


@Override
public void preSolve(Contact contact, Manifold oldManifold) {}


@Override
public void postSolve(Contact contact, ContactImpulse impulse) {}


@Override
public void render(float delta) {

    camera.position.set(player.getPosition().x, player.getPosition().y, 0); 
    update();
    camera.update();

    shapeRenderer.setProjectionMatrix(camera.combined);




     Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);  

     world.step(1/60f, 6, 2); 
     handler.updateAndRender();
     handler.setCombinedMatrix(camera.combined);






     debugRenderer.render(world, camera.combined);  






}
}
1

There are 1 best solutions below

0
On BEST ANSWER

The gravity is a force, which is applied to every (dynamic) body in the world in every step.
That means, that the velocity of those affected object increases every frame.
Thats just the expected result, think about the reality:
If you jump from a high place, you get faster and faster, until you hit the ground (or air resistance limits your speed).

If you want to move with a constant speed (in Box2D), you should do something like that:

Vector2 vel = this.player.body.getLinearVelocity();
if (vel.x < MAX_VELOCITY) {
     circle.applyLinearImpulse(impulse.x, impulse.y, pos.x, pos.y, wake);

Where impulse.x is a float, defining the impulse strength applyed in x-direction, impulse.y is the same for y-direction, pos.x and pos.y is the position, to which you want to apply the impulse (if not the center, the body will get some torque-effect) and the boolean wake defines, if the body should wake up.