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);
}
}
The gravity is a
force
, which is applied to every (dynamic)body
in theworld
in everystep
.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:Where
impulse.x
is afloat
, defining the impulse strength applyed in x-direction,impulse.y
is the same for y-direction,pos.x
andpos.y
is the position, to which you want to apply theimpulse
(if not the center, the body will get sometorque
-effect) and theboolean wake
defines, if thebody
should wake up.