redGREENblue
redGREENblue

Reputation: 3126

Static body bridging two other static bodies

I have two box2d bodies like below, enter image description here

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). enter image description here

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

Answers (1)

Hllink
Hllink

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:

Testing the bridge

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

Related Questions