I programed a basic Box2d-"Game": No textures and suchlike, Only a player(body), who jumps from one static groundbody to another.
The problem is that the ground respectively the playerbody, which is followed by the camera, stutters every few seconds.
(https://www.dropbox.com/s/llsg2q65lz828t6/stuttering.avi) (download this video, please, otherwise your flashplayer will show much more stuttering)
If you look between the groundelements, you can see this very good.
Binded textures stutters too.
Curiously: There aren't any stucks in fullscreen mode (config.fullscreen = true); Only on Android-Phones and in window mode.
Although it is only a small game, I have tried to use Interpolation and analysed the GC-actions: No result :\
Thanks in advance!
Some peaces of my code (I turned off the Interpolation):
private float step = 1.0f / 60.0f;
public void show()
{
//...
bodyDef.type = BodyType.StaticBody;
bodyDef.position.set(0, 0);
//...
ChainShape groundShape = new ChainShape();
float width = 20;
float height = 0.25f;
fixtureDef.restitution = 0.0f;
fixtureDef.friction = 0.5f;
fixtureDef.shape = groundShape;
fixtureDef.friction = .5f;
fixtureDef.restitution = 0;
groundShape.createChain(new Vector2[] { new Vector2(0, 0), new Vector2(width, 0), new Vector2(width, -height), new Vector2(0, -height), new Vector2(0, 0) });
fixtureDef.shape = groundShape;
world.createBody(bodyDef).createFixture(fixtureDef);
groundShape.dispose();
groundShape = new ChainShape();
bodyDef.position.set(25, 0);
groundShape.createChain(new Vector2[] { new Vector2(0, 0), new Vector2(width, 0), new Vector2(width, -height), new Vector2(0, -height), new Vector2(0, 0) });
fixtureDef.shape = groundShape;
world.createBody(bodyDef).createFixture(fixtureDef);
groundShape.dispose();
//...
}
public void render(float delta)
{
world.step(step, 8, 3);
input.update();
playCam.position.set(player.getBody().getPosition().x + 6.5f, 3.5f, 0);
playCam.update();
player.move();
debugRenderer.render(world, playCam.combined);
}
Player-Class:
move()
{
playerbody.setLinearVelocity(20f, 0);
}
Related
I wanted to try out Box2d and wrote similar code to one that is in tutorial, everything renders properly, but nothing updates and there are no exceptions. Please help me i think i am going insane.
#Override
public void create () {
world = new World(new Vector2(0, -10f), true);
r = new Box2DDebugRenderer();
camera = new OrthographicCamera(100, 100);
camera.translate(50, 50, 0);
BodyDef bd = new BodyDef();
bd.type = BodyType.DynamicBody;
bd.position.set(50, 50);
Body body = world.createBody(bd);
CircleShape cs = new CircleShape();
cs.setRadius(1);
FixtureDef fd = new FixtureDef();
fd.shape = cs;
body.createFixture(fd);
cs.dispose();
BodyDef b = new BodyDef();
b.type = BodyType.StaticBody;
b.position.set(30, 30);
Body bo = world.createBody(b);
PolygonShape ps = new PolygonShape();
ps.setAsBox(10, 3);
FixtureDef f = new FixtureDef();
f.shape = ps;
bo.createFixture(f);
ps.dispose();
}
#Override
public void render () {
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
r.render(world, camera.combined);
camera.update();
world.step(1/60, 6, 2);
}
of course box2D still work with Libgdx
your problem is this line
world.step(1/60, 6, 2);
try do this
world.step(1/60f, 6, 2);
your time step was considerer 0 cause 1/60 interger is 0
I have testedd your code it will work !
Good luck
I am trying to build a lever in an android game using box2d and libgdx. When the game starts, the 2 platforms of the lever are balancing perfectly and when I move a box on one platform of the lever, it goes down as expected but when I move the body out, the 2 platforms doesn't balance again as before.
I am using this code to create the 2 platforms:
private Body setupShape(World world, float cx, float cy, float cw, float ch){
Body ptf;
PolygonShape shape = new PolygonShape();
shape.setAsBox(cw / 2, ch / 2);
FixtureDef fdef = new FixtureDef();
fdef.shape = shape;
fdef.density = 1.0f;
fdef.friction = 1.0f;
fdef.restitution = 0.0f;
BodyDef bd = new BodyDef();
//bd.allowSleep = false;
bd.position.set(cx, cy);
bd.fixedRotation = true;
ptf = world.createBody(bd);
//lever.setGravityScale(10);
ptf.createFixture(fdef);
ptf.setType(BodyDef.BodyType.DynamicBody);
ptf.setUserData("Lever");
shape.dispose();
return ptf;
}
And this code for creating the lever using "PulleyJoint":
PulleyJointDef pulleyDef = new PulleyJointDef();
Vector2 bodyoneanchor = new Vector2(Constants.Pixel2SIf(360), Constants.Pixel2SIf(400));
Vector2 bodytwoanchor = new Vector2(Constants.Pixel2SIf(660), Constants.Pixel2SIf(400));
pulleyDef.initialize(bodyA, bodyB, bodyoneanchor, bodytwoanchor, bodyA.getWorldCenter(), bodyB.getWorldCenter(), 1);
world.createJoint(pulleyDef);
I would like to know what's wrong with my code and how to make the lever re-balance again after moving out objects from it.
Here's a drawing to demonstrate my problem more clearly:
http://costheta.net/quest.png
It will be very much appreciated if you could help me fixing that problem.
Best regards!
UPDATE:
Here's my new code after adding Prismatic joints:
PulleyJointDef pulleyDef = new PulleyJointDef();
Vector2 bodyoneanchor = new Vector2(Constants.Pixel2SIf(360), Constants.Pixel2SIf(400));
Vector2 bodytwoanchor = new Vector2(Constants.Pixel2SIf(660), Constants.Pixel2SIf(400));
pulleyDef.initialize(bodyA, bodyB, bodyoneanchor, bodytwoanchor, bodyA.getWorldCenter(), bodyB.getWorldCenter(), 1);
world.createJoint(pulleyDef);
BodyDef bd0 = new BodyDef();
bd0.position.set(bodyoneanchor.x, bodyoneanchor.y);
Body ptf0 = world.createBody(bd0);
PrismaticJointDef pjd0 = new PrismaticJointDef();
pjd0.initialize(ptf0, bodyA, ptf0.getWorldCenter(), new Vector2(0, 1));
pjd0.motorSpeed = 200f;
pjd0.maxMotorForce = 30.0f;
pjd0.enableMotor = true;
pjd0.lowerTranslation = -Math.abs(bodyA.getWorldCenter().y - bodyoneanchor.y);
pjd0.upperTranslation = 0;//Math.abs(bodyA.getWorldCenter().y - bodyoneanchor.y);
pjd0.enableLimit = true;
world.createJoint(pjd0);
BodyDef bd1 = new BodyDef();
bd1.position.set(bodytwoanchor.x, bodytwoanchor.y);
Body ptf1 = world.createBody(bd1);
PrismaticJointDef pjd1 = new PrismaticJointDef();
pjd1.initialize(ptf1, bodyB, ptf1.getWorldCenter(), new Vector2(0, 1));
pjd1.motorSpeed = 200f;
pjd1.maxMotorForce = 30.0f;
pjd1.enableMotor = true;
pjd1.lowerTranslation = -Math.abs(bodyB.getWorldCenter().y - bodytwoanchor.y);
pjd1.upperTranslation = 0;//Math.abs(bodyB.getWorldCenter().y - bodytwoanchor.y);
pjd1.enableLimit = true;
world.createJoint(pjd1);
They shouldn't re-balance because the weight of each side is the same and the tensions cancel each other out, resulting in no movement (get some string and build the setup in real life).
If you want it to re-balance, add a spring on each platform with a length of zero placed on the initial position and center of the box.
I'm making an endless runner on LibGDX with Box2d. I want to make the camera and player move at the same speed so while everything's fine, the player is in the center of the screen. I don't want it to just always make the player the center though, since I want the player to be left behind by the camera if the player gets stuck (ex. behind a crate). With that, I was thinking that I could translate the camera with the same default velocity that the player has. Doesn't work though. Help?
render() (with the camera update):
dx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
//stage.getCamera().translate(Constants.DEFAULT_VELOCITY / Constants.PIXELS_TO_BOX, 0, 0);
//the commented function call above was what I was thinking; doesnt work
stage.getCamera().position.x = player.getX();
batcher.begin();
batcher.draw(AssetLoader.background, 0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
batcher.end();
stage.draw();
batcher.begin();
debugRenderer.render(gameWorld.getWorld(), debugMatrix);
batcher.end();
part of Player:
public Player(Texture texture, float x, float y, World world) {
this.texture = texture;
setWidth(texture.getWidth()); //pixels
setHeight(texture.getHeight()); //pixels
setPosition((x + getWidth()/2), y + (getHeight()/2)); //pixels
setName("player");
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyType.DynamicBody;
bodyDef.position.set(x / Constants.PIXELS_TO_BOX, y / Constants.PIXELS_TO_BOX); //meters
body = world.createBody(bodyDef);
PolygonShape shape = new PolygonShape();
shape.setAsBox(texture.getWidth()/2 / Constants.PIXELS_TO_BOX , texture.getHeight()/2 / Constants.PIXELS_TO_BOX); //meters
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = shape;
fixtureDef.density = 1.0f;
fixtureDef.friction = 0.0f;
fixtureDef.restitution = 0.0f;
body.createFixture(fixtureDef);
body.setFixedRotation(true);
shape.dispose();
body.setUserData(this);
}
#Override
public void act(float delta) {
body.setLinearVelocity(new Vector2(Constants.DEFAULT_VELOCITY, body.getLinearVelocity().y));
//what I use to set velocity
if (hasJumped) {
jump();
hasJumped = false;
Gdx.app.log("player", "jumped");
}
}
I created a rope in box2d with RevoluteJoint and a RopeJoint but I have several problems with it:
From time to time, the last segment rotates and it looks like it was disconnected from the rope.
How to draw this thing? I create a texture with the size of each link. If the rope isn't moving it looks good, but as soon as the rope moves and the different links start to rotate slightly, you see gaps between the links.
Code:
private void createChain(World world, Body anchorBody) {
Body previousBody = anchorBody;
FixtureDef fixtureDef = new FixtureDef();
PolygonShape robeLinkShape = new PolygonShape();
robeLinkShape.setAsBox(4 / PPM, 8 / PPM);
fixtureDef.shape = robeLinkShape;
fixtureDef.density = 0.1f;
// fixtureDef.friction = 1.0f;
fixtureDef.restitution = 0.1f;
fixtureDef.filter.maskBits = Box2DConst.BIT_PLAYER;
fixtureDef.filter.categoryBits = Box2DConst.BIT_GROUND;
float mapX = anchorBody.getPosition().x * PPM;
float mapY = anchorBody.getPosition().y * PPM;
BodyDef bodyDef = new BodyDef();
bodyDef.angularDamping = 1.0f;
bodyDef.linearDamping = 1.0f;
//create rope
for (int i = 0; i < 10; i++) {
Float robeX = mapX / PPM;
Float robeY = (mapY - (i * 16)) / PPM;
bodyDef.type = BodyDef.BodyType.DynamicBody;
bodyDef.position.set(robeX, robeY);
final Body link = world.createBody(bodyDef);
link.createFixture(fixtureDef);
RevoluteJointDef jointDef = new RevoluteJointDef();
jointDef.initialize(previousBody, link, new Vector2(robeX, robeY));
//don't need the rope to collide itself
jointDef.collideConnected = false;
jointDef.enableLimit = false;
// because we don't collide with other bodies in the rope, limit rotation to keep the rope bodies from rotating too much.
jointDef.lowerAngle = -5.0f * MathUtils.degreesToRadians;
jointDef.upperAngle = 5.0f * MathUtils.degreesToRadians;
world.createJoint(jointDef);
links.add(link);
previousBody = link;
}
RopeJointDef ropeJointDef = new RopeJointDef();
ropeJointDef.localAnchorB.set(0, 0);
ropeJointDef.maxLength = 90.0f;
ropeJointDef.bodyB = previousBody;
ropeJointDef.bodyA = links.get(0);
ropeJointDef.collideConnected = false;
world.createJoint(ropeJointDef);
}
public void draw(final SpriteBatch batch) {
Texture texture = FipiGame.res.get("rope");
batch.begin();
for (Body link : links) {
float x = (link.getPosition().x * PPM) - 4;
float y = (link.getPosition().y * PPM) - 8;
float angleDeg = MathUtils.radiansToDegrees * link.getAngle();
batch.draw(texture, x, y, 0, 0, texture.getWidth(), texture.getHeight(), 1f, 1f, angleDeg, 0, 0,
texture.getWidth(), texture.getHeight(), false, false);
}
batch.end();
}
Instead of drawing based on body positions and rotations: Create a set of points by looping through the revolute joint positions (midpoint of anchorA and anchorB in world space). Then draw your sprites so they connect those positions. This will be somewhat inaccurate in that it won't perfectly line up with the positions of the rigid bodies, but it should look all right.
I'm trying to make a movable car in java, using libgdx and box2d;
I made a car, m_car, with position set in middle of the car.
In every step, i take take the current position of the m_car, decrese that values with the cars width/height, so i have the left bottom corner. When is on a straight ground, it shows well, the texture is where is should be, but when the ground have an angle, the texture position its under, or upper the car.
I don't understand how TextureRegion works, i think that when the angle is not 0, i dont take the point of drawing well, and i dont know how to solve it. help me pls :)
Ty.
Edit:
my code is a mess, its not an actual project, its an ideea, and i took pieces, and put them down to see how they work, so when il start the project, i would know what to do, this is my car declaration:
private void car2(){
m_hz = 5.0f;
m_zeta = 0.7f;
m_speed = 50.0f;
BodyDef bd = new BodyDef();
bd.type = BodyType.DynamicBody;
part1(bd);
part2(bd);
part3(bd);
wheels(bd);
m_car.setAwake(true);
}
private void part3(BodyDef bd) {
PolygonShape shape = new PolygonShape();
shape.setAsBox(0.01f, 0.35f,new Vector2(1.01f - 3, 4.85f - 4), 0);
m_car.createFixture(shape, 1.0f);
}
private void part1(BodyDef bd){
PolygonShape chassis = new PolygonShape();
Vector2 vertices[] = new Vector2[6];
vertices[0] = new Vector2(-2, -0.5f);
vertices[1] = new Vector2(-2, 0.5f);
vertices[2] = new Vector2(1.25f, 0.5f);
vertices[3] = new Vector2(2.5f, 0.15f);
vertices[4] = new Vector2(2.5f, -0.5f);
vertices[5] = new Vector2(-2, -0.5f);
chassis.set(vertices);
bd.position.set(new Vector2(3, 4));
m_car = m_world.createBody(bd);
m_car.createFixture(chassis, 1.0f);
}
private void part2(BodyDef bd){
PolygonShape chassis = new PolygonShape();
Vector2 vertices[] = new Vector2[5];
vertices[0] = new Vector2(3, 4.5f);
vertices[1] = new Vector2(3, 5.25f);
vertices[2] = new Vector2(3.80f, 5.25f);
vertices[3] = new Vector2(4.25f, 4.5f);
vertices[4] = new Vector2(3, 4.5f);
for (int i = 0; i < 5; ++ i){
vertices[i].x -= 3;
vertices[i].y -= 4;
}
chassis.set(vertices);
//m_car = m_world.createBody(bd);
m_car.createFixture(chassis, 1.0f);
}
private void wheels(BodyDef bd){
CircleShape circle = new CircleShape();
circle.setRadius(0.4f);
FixtureDef fd = new FixtureDef();
fd.shape = circle;
fd.density = 1.0f;
fd.friction = 0.9f;
bd.position.set(2f, 3.5f);
m_wheel1 = m_world.createBody(bd);
m_wheel1.createFixture(fd);
bd.position.set(4.5f, 3.5f);
m_wheel2 = m_world.createBody(bd);
m_wheel2.createFixture(fd);
WheelJointDef jd = new WheelJointDef();
Vector2 axis = new Vector2(1.0f, 0.5f);
jd.initialize(m_car, m_wheel1, m_wheel1.getPosition(), axis);
jd.motorSpeed = 0.0f;
jd.maxMotorTorque = 20.0f;
jd.enableMotor = true;
jd.frequencyHz = m_hz;
jd.dampingRatio = m_zeta;
m_spring1 = (WheelJoint) m_world.createJoint(jd);
jd.initialize(m_car, m_wheel2, m_wheel2.getPosition(), axis);
jd.motorSpeed = 0.0f;
jd.maxMotorTorque = 10.0f;
jd.enableMotor = false;
jd.frequencyHz = m_hz;
jd.dampingRatio = m_zeta;
m_spring2 = (WheelJoint) m_world.createJoint(jd);
}
some explenation: why i have for for vertices to decreese 3 and 4 ? i didnt know that if i set position to the bodydef, the vertices consider that point to be 0, 0, when i found out, was easyer to me to just decrese (cuz its just for test, to see how it works)
and this is how i draw:
float angle = (float) Math.toDegrees(m_car.getAngle());
batch.draw(textureRegion, x, y, 3f, 4f,
4.5f, 2.75f, 1f, 0.61f, angle);
For a realistic car in Box2D you might find this useful: http://www.iforce2d.net/b2dtut/top-down-car
About your problem with the angle: You need to supply the angle of the car to the spriteBatch. TextureRegion doesn't know ANYTHING about where or how it is supposed to be rendered. You need to tell the spriteBatch about those informations.
You can use a Sprite for that. A Sprite can be manipulated with setRotation(), setPosition() etc and then being draw with Sprite.draw(spriteBatch) instead of `spriteBatch.draw(sprite)
Furthermore, be careful with your PIXEL_TO_METER conversion and remember to update your Cameras properly.