How to add sprite to a Box2d Body? - java

I just made my character for the game which is a box2d dynamic body:
public Body createPlayer(){
Body body;
BodyDef def = new BodyDef();
def.type = BodyDef.BodyType.DynamicBody;
def.fixedRotation = true;
def.position.set(position.x, position.y);
body = world.createBody(def);
PolygonShape shape = new PolygonShape();
shape.setAsBox(1, 1);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = shape;
fixtureDef.density = 0.1f;
body.createFixture(fixtureDef).setUserData(this);
body.setLinearVelocity(20, 0);
shape.dispose();
return(body);
}
Is it possible to add texture or sprite to a body? or I'll just set the sprite position the same as the position of my body? so that it will cover the shape of the body and move like the actual box2d body.

The Box2D physics library is completely graphics API agnostic - It doesn't understand sprites at all. It is a none visual (just data) simulation of a physics world.
As you mentioned, you will have to create a Sprite and move/rotate it to keep in sync with the Box2D simulation.
Here is a good beginners guide to linking a sprite to a Box2D simulation

Related

Jbox2d Issues with positioning platforms

I am working on developing a platformer, and everything's working fine, except, I seem to be unable to position the bodies for the static platforms.
// creating all the bodies
BodyDef bdef = new BodyDef();
bdef.position.set(x, y);
bdef.type = BodyType.STATIC;
Body body = world.createBody(bdef);
PolygonShape shape = new PolygonShape();
shape.setAsBox(width, height);
FixtureDef fdef = new FixtureDef();
fdef.friction = 0.3f;
fdef.shape = shape;
body.createFixture(fdef);
This is general code that's used to create every body in the map. The bodies work fine, but they don't line up with the width nor the coordinates of the map that I've set. I've noticed that I must specify the bottom left point as starting point for it to make body, but what else I am missing? Why bodies tend to be bigger and go past the starting point of X and Y?
Bodies in box2d are made from their center points. When you define it's position, you are setting it's center and when you define it's width/height, you are actually setting half the width/height (i.e. the size ends up double what you intended).

How to create infinite Platform with Box2d?

I'm making a side scrolling game and I wan't to know how can I create an infinite terrain, do I need to use a static body that keeps on increasing its width? Also since its an infinite world, is it a good idea to just create a body to be used as an obstacle and then remove it when not in range?
public Body createPlatform(){
Body body;
BodyDef def = new BodyDef();
def.type = BodyDef.BodyType.StaticBody;
def.fixedRotation = true;
def.position.set(0.6f, 1.6f);
body = world.createBody(def);
PolygonShape shape = new PolygonShape();
shape.setAsBox(2f, 1.5f);//have no Idea how to increase width infinitely or should I even be using a Body as ground.
FixtureDef fDef = new FixtureDef();
fDef.shape = shape;
fDef.density = 1f;
body.createFixture(fDef);
shape.dispose();
return(body);
}
Also I'm using Libgdx library and java of course.
It's best to split the world into chunks: once the player exits one chunk, load in one or more. You do not need to have the chunks pre-loaded; you load them in on the fly depending on the player's location.

Box2D Polygon Bodies not rotating

I'm trying to create a game with "libGDX" and "Box2D".
I've several shapes in the game, so I created a BodyFactory class which creates my bodies using PolygonShape
The problem is, when I create a body, with Shape.setAsBox() method, everything works fine, but when I create bodies with PolygonShape.set(vertices), the position of bodies changes as I wish, but they won't rotate at all.
This is what I get (after stability) when I drop 3 bodies from the sky:
The square rotates and stays at the ground, bot the other shapes won't.
Also note that I tried adding
body.setFixedRotation(false);
to my code, but nothing changed.
Also friction, mass and density of shapes are at a reasonable amount.
This is the part of my code which creates a "PolygonShape" from a file:
...
Body body = world.createBody(bodyDef);
...
for (int i = 0; i < bodyConf.meshData.length; i++) {
PolygonShape polygonShape = new PolygonShape();
polygonShape.set(bodyConf.meshData[i]);
fixtureDef.shape = polygonShape;
body.createFixture(fixtureDef);
polygonShape.dispose();
}
I think the problem is that you are creating only one Body with three Fixtures attached to it.
What you actually want is three Bodys, with one Fixture attached to each of them. That way, each body can rotate independent from the others.
for (int i = 0; i < bodyConf.meshData.length; i++) {
BodyDef bodyDef = ...;
Body body = world.createBody(bodyDef);
PolygonShape polygonShape = new PolygonShape();
polygonShape.set(bodyConf.meshData[i]);
fixtureDef.shape = polygonShape;
body.createFixture(fixtureDef);
polygonShape.dispose();
}

How to prevent two objects in collisions from crossing both

I want to know how to prevent an object in crossing another. I have a ball and a square which I can move whith my mouse. When my ball is on my square I move it (in top for example) if I go very slowly the ball remains on the square if not it crosses it.
if both of your 2 object have a fixture defined they will not be able to crossing one another this is an exmple of how a dynamic object who will be affected by physics in the BOX2D world must be created , and also this object can't tunneling through a sensor :
public Ball (World world){
this.world = world;
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyType.DYNAMIC;
bodyDef.position.set(0.0f/RATE, 0.0f/RATE);
Ballbody = world.createBody(bodyDef);
CircleShape circle = new CircleShape();
radius = (int) (Math.random()*30+15); // you can set a non randum raduis
circle.m_radius = radius/RATE;
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = circle;
fixtureDef.restitution = 0.8f;
fixtureDef.density = 2.0f;
fixtureDef.friction = 0.3f;
fixtureDef.filter.groupIndex = -1;
Ballbody.createFixture(fixtureDef);
Ballbody.getFixtureList().setUserData("Ballounaton"); // optional
Vec2 ballVec = new Vec2((float) (Math.random()*8+2),0.0f);
Ballbody.setLinearVelocity(ballVec);
}
make sure to define a fixture to your box2d dynamic or static object to avoid tunneling through a sensor like in this exmple :
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = circle;
fixtureDef.restitution = 0.8f;
fixtureDef.density = 2.0f;
fixtureDef.friction = 0.3f;
fixtureDef.filter.groupIndex = -1;
Ballbody.createFixture(fixtureDef);
according to BOX2D official documentation :
Recall that shapes don’t know about bodies and may be used
independently of the physics simulation. Therefore Box2D provides the
b2Fixture class to attach shapes to bodies. Fixtures hold the
following:
a single shape
broad-phase proxies
density, friction, and restitution
collision filtering flags
back pointer to the parent body
user data
sensor flag

Box2D static body collision performance issue

I'm using JBox2d to perform collision detection in a game project I'm working on.
I represent obstacles in the world with static bodies. Whenever a dynamic body (i.e. a game character) collides with one of these obstacles, there is a very noticeable drop in performance. Fps will drop from ~120 to ~5. This seems to happen more frequently when the corners of the static body are collided with.
When I set the body type of the world obstacles to be dynamic instead of static, with very high density(to prevent the body from moving when it is collided with), this issue disappears... This solution is not ideal for my situation however......
Any ideas as to what could be causing this huge fps drop?
Here's the code I use to create the static bodies:
BodyDef def = new BodyDef();
def.type = BodyType.STATIC; // If this line is commented and the other
//commented lines are uncommented, the issue goes away.
//def.type = BodyType.DYNAMIC;
def.position.set(worldBounds.getCenterX(), worldBounds.getCenterY());
Body staticBody = b2World.createBody(def);
PolygonShape box = new PolygonShape();
box.setAsBox(worldBounds.getWidth() * 0.5f, worldBounds.getHeight() * 0.5f);
FixtureDef fixture = new FixtureDef();
fixture.shape = box;
fixture.friction = 0.3f;
//fixture.density = 1000000000;
staticBody.createFixture(fixture);
//staticBody.setSleepingAllowed(true);
//staticBody.setFixedRotation(true);
I've tried using a CircleShape instead of a PolygonShape, but that doesn't help anything.
Thank you!
this is the code from the game im working on at the moment which works fine. hopefully if you copy and paste, change a few variable names and stuff it might sort your problem. im new to box2d so cant tell you exactly where the problem lies. hope it helps.
//bodydef
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyType.StaticBody;
bodyDef.position.set(position);
body = world.createBody(bodyDef);
//shape
PolygonShape shape = new PolygonShape();
shape.setAsBox(dimension.x / 2, dimension.y / 2);
//fixture
FixtureDef fixture = new FixtureDef();
fixture.friction = 0.3f;
fixture.shape = shape;
body.createFixture(fixture);
shape.dispose();

Categories