Reputation: 3126
I have two box2d bodies like below,
What I need is to create another body that kind of bridges this two bodies. I am not looking for a box2d joint, but a body that will be like a bridge touching the rightmost point of the first body and the leftmost point in the second body, like in this image (excuse my paint skills).
Problem is, looks like I am not getting the co-ordinates and angles on how to create the third (bridge) body. Here's my code below,
Body body1, body2, bridge;
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.StaticBody;
bodyDef.position.set(350 / Constants.PIXELS_TO_METERS, 0 / Constants.PIXELS_TO_METERS);
body1 = world.createBody(bodyDef);
PolygonShape shape = new PolygonShape();
shape.setAsBox(300 / Constants.PIXELS_TO_METERS, 300 / Constants.PIXELS_TO_METERS);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = shape;
fixtureDef.density = 1f;
body1.createFixture(fixtureDef);
BodyDef bodyDef2 = new BodyDef();
bodyDef2.type = BodyDef.BodyType.StaticBody;
bodyDef2.position.set(1600 / Constants.PIXELS_TO_METERS, 0 / Constants.PIXELS_TO_METERS);
body2 = world.createBody(bodyDef2);
PolygonShape shape2 = new PolygonShape();
shape2.setAsBox(300 / Constants.PIXELS_TO_METERS, 500 / Constants.PIXELS_TO_METERS);
FixtureDef fixtureDef2 = new FixtureDef();
fixtureDef2.shape = shape2;
fixtureDef2.density = 1f;
body2.createFixture(fixtureDef2);
BodyDef bodyDef3 = new BodyDef();
bodyDef3.type = BodyDef.BodyType.StaticBody;
Vector2 a = new Vector2(body1.getPosition().x + 300 / Constants.PIXELS_TO_METERS, body1.getPosition().y + (300 + 50 / 2) / Constants.PIXELS_TO_METERS);
Vector2 b = new Vector2(body2.getPosition().x - 300 / Constants.PIXELS_TO_METERS, body2.getPosition().y + (300 + 50 / 2) / Constants.PIXELS_TO_METERS);
float distance = a.dst(b);
Vector2 bridgePos = new Vector2(a.x + distance / 2, a.y + 50 / 2 / Constants.PIXELS_TO_METERS);
bodyDef3.position.set(bridgePos);
float angle = (float) Math.atan2(a.y + 50 / Constants.PIXELS_TO_METERS, b.x);
bridge = world.createBody(bodyDef3);
PolygonShape shape3 = new PolygonShape();
shape3.setAsBox(distance / 2, 50 / Constants.PIXELS_TO_METERS);
FixtureDef fixtureDef3 = new FixtureDef();
fixtureDef3.shape = shape3;
fixtureDef3.density = 1f;
bridge.createFixture(fixtureDef3);
bridge.setTransform(bridgePos, angle);
This doesn't give the correct position or angle for the bridge, as it works for some body sizes and sometimes don't (yes, I have accounted for the hardcoded values for every change). I am not exactly sure what I am doing wrong. Any help?
Upvotes: 3
Views: 111
Reputation: 918
Dont do that! Just build the shape programatically with polygons vectors as you can see in the following example:
Create your 2 bodies, set it to the world and call the createBridge method:
private final Vector2 vecBodySize1 = new Vector2(100,50);
private final Vector2 vecBodySize2 = new Vector2(110,70);
private void createBodies(){
Body body1, body2;
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.StaticBody;
bodyDef.position.set(YOUR_POSITION.x, YOUR_POSITION.y);
body1 = world.createBody(bodyDef);
PolygonShape shape = new PolygonShape();
shape.setAsBox(vecBodySize1.x, vecBodySize1.y);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = shape;
fixtureDef.density = 1f;
body1.createFixture(fixtureDef);
BodyDef bodyDef2 = new BodyDef();
bodyDef2.type = BodyDef.BodyType.StaticBody;
bodyDef2.position.set(YOUR_POSITION2.x, YOUR_POSITION2.y);
body2 = world.createBody(bodyDef2);
PolygonShape shape2 = new PolygonShape();
shape2.setAsBox(vecBodySize2.x, vecBodySize2.y);
FixtureDef fixtureDef2 = new FixtureDef();
fixtureDef2.shape = shape2;
fixtureDef2.density = 1f;
body2.createFixture(fixtureDef2);
///
// The body object gonna take the center position as default, this way you can set where the bridge starts and ends with 2 simple vectors
// you can set the thickness variable as you want to be the size of the bridge, never leave this null or 0
///
Vector2 vecBridge1 = new Vector2(body1.getPosition().x+vecBodySize1.x,body1.getPosition().y+vecBodySize1.y);
Vector2 vecBridge2 = new Vector2(body2.getPosition().x-vecBodySize2.x,body2.getPosition().y+vecBodySize2.y);
createBridge(vecBridge1,vecBridge2, 10.0f);
}
createBridge method that creates the body with fixture that links the 2 objects:
private void createBridge(Vector2 vecFrom, Vector2 vecTo, Float thickness){
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.StaticBody;
bodyDef.position.set(vecFrom);
Body tmpBody = Box2dGameWorld.getInstance().getWorldBox2D().createBody(bodyDef);
PolygonShape shape = new PolygonShape();
shape.set( new Vector2[]{
new Vector2(0,0)
,new Vector2(vecTo.x-vecFrom.x,vecTo.y-vecFrom.y)
,new Vector2(vecTo.x-vecFrom.x,vecTo.y-vecFrom.y-thickness)
,new Vector2(0,0-thickness)});
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = shape;
fixtureDef.density = 1f;
tmpBody.createFixture(fixtureDef);
}
the result:
As you can see you now can create bridges giving 2 vectors and the thickness, you don't necessary need to attach 'em to the bodies, imagine if you now want a bridge in the middle of a body or even in the air, this method make things a lot easier..
Upvotes: 5