1
\$\begingroup\$

At the moment I am trying to code a 2d game in java, where a jetski is riding on water. If you press on the screen the jetski should dive down and jump back up on release. How do I have to do this in Box2d? My idea was to put a rectangular body as the water and an other one as the jetski. Since I am new to box2d I don't really know how I should bring this into code. I hope one of you can help.

\$\endgroup\$
2
\$\begingroup\$

I spent a good while looking how to implement Box2D in Android studio, so for anyone else in the same boat, or just looking to implement Box2D - here goes.

For implementing Box2D into your java code/framework, Box2D is tuned to work with numbers between 0.1 and 10 (it works in meters), quoting from the Box2D manual:

http://box2d.org/manual.pdf

Box2D is tuned for MKS units. Keep the size of moving objects roughly between 0.1 and 10 meters. You'll need to use some scaling system when you render your environment and actors. The Box2D testbed does this by using an OpenGL viewport transform. DO NOT USE PIXELS.

I have no experience in libgdx, but I believe Box2D coordinate conversions and implementations can be general/universal (I have managed to implement Box2D in C++ and Java using the same ideas).

In the implementations that I do, there will usually be a standard base gameobject/sprite class, and in this class you could have the conversion variables and functions to convert from your local framework coordinates, to Box2D coordinates:

I am assuming you have the Box2D world all set up!

public class GameObject extends Sprite
{
    protected static float box2DFrameworkScale = 100.0f;    // How much you want to scale down from FRAMEWORK coordinates to BOX2D coordinates.
    protected static float box2DFrameworkOffsetX = 0.0f;    // How much of an offset there will be to map your Jetski sprite, to the body created in Box2D.
    protected static float box2DFrameworkOffsetY = 0.0f;    // Same as above for the y coordinate.
    protected static float box2DSizeOffset = 0.75f;         // How much does the size of the Box2D body need to be scaled down from the framework width and height in order for collisions to "look"/"be" correct; this value tends to work for me.

    //
    // Your GameObject class functions...
    //

    // Here are the functions to convert from your framework coordinates, to Box2D coordinates and vice versa.
    // You will need access to screen width and height if possible!

    // GETTERS.
    // Getting FRAMEWORK COORDINATES.
    // Convert Box2D coordinates into local framework coordinates.
    public float getFrameworkXPosition(float box2DX)   { return ((box2DX * box2DFrameworkScale) + box2DFrameworkOffsetX); }                   // Getting your local framework x coordinate FROM Box2D x coordinate.
    public float getFrameworkYPosition(float box2DY)   { return (screenHeight - (box2DY * box2DFrameworkScale + box2DFrameworkOffsetY)); }    // Getting your local framework y coordinate FROM Box2D y coordinate. 
    public float getFrameworkSize(float dimension)     { return (dimension * box2DFrameworkScale); }                                          // Getting your local framework width/height FROM Box2D width/height.

    // Getting BOX2D COORDINATES.
    // Convert local framework coordinates into Box2D coordinates.
    public float getBox2DXPosition(float frameworkX)   { return ((frameworkX - box2DFrameworkOffsetX) / box2DFrameworkScale); }                 // Getting the Box2D x coordinate FROM your framework x coordinate.
    public float getBox2DYPosition(float frameworkY)   { return ((frameworkY - screenHeight + box2DFrameworkOffsetY) / -box2DFrameworkScale); } // Getting the Box2D y coordinate FROM your framework y coordinate.
    public float getBox2DSize(float dimension)         { return (dimension / box2DFrameworkScale); }                                            // Getting the Box2D width/height FROM your framework width/height.
}

With these conversions you can then go and implement a Dynamic Body class, I used an outdated version of Box2D for my android project, but it should provide you with the basic understanding of implementing the conversion functions above!

Your Jetski will most likely be a dynamic body of sorts, you can find out how to create on in the manual I linked to you above, here is a basic implementation (angles aren't considered, feel free to look into that, bodyDef.angle and fixedRotation etc. that kind of thing - if it is a later version):

public class DynamicBody extends GameObject
{
    // Creating the dynamic body.
    public void init(World world, Vector2 positions, Vector2 dimensions)
    {
        // Initialising the game object here.
        init(positions, dimensions, angle);

        // Setting up the body definition.
        BodyDef bodyDef = new BodyDef();
        bodyDef.position.set(new Vec2(getBox2DXPosition(getSpriteLeft()), getBox2DYPosition(getSpriteTop())));    // Use conversion functions to place local framework coordinates into Box2D coordinates.
        body = new Body(bodyDef, world);
        body = world.createBody(bodyDef);
        body.setXForm(new Vec2(getBox2DXPosition(getSpriteLeft()), getBox2DYPosition(getSpriteTop())), 0.0f);

        // Here is where we create the actual box/rectangle in Box2D.
        PolygonDef box = new PolygonDef();
        box.setAsBox(getBox2DSize(dimensions.getX()) * box2DSizeOffset, getBox2DSize(dimensions.getY()) * box2DSizeOffset);    // This function MIGHT be different in newer versions of the Box2D library. Convert from your framework width and height into the Box2D width and height.
        box.density = 1.0f;    // Change these around to get your desired effect on the dynamic body properties and physics.
        box.friction = 0.5f;
        box.restitution = 0.65f;

        body.createShape(box);
        body.setMassFromShapes();

        // Setting the "connection" of data between sprites and the body.
        body.setUserData(this);
    }

    // You will want the body and sprite to be at the same place at the same time.
    // Call this every frame to keep the two aligned!
    public void update()
    {
        // New coordinates for the sprite x and y position given by the Box2D body position.
        float newX = body.getPosition().x;
        float newY = body.getPosition().y;

        // Convert the new coordinates into your local framework coordinates to correctly place your sprite on the screen in line with your Box2D body.
        setPosition(getFrameworkXPosition(newX), getFrameworkYPosition(newY));
    }
}

For the water you may want to create a static body class, similar to the dynamic body class above, hope this has helped you in some way! If not, sorry for the misunderstanding/unhelpful answer.

As for making the jetski go up/down, you can apply impulses to bodies in Box2D:

// Change body.getWorldCenter() for the front end of the jetski body.
// Two vector 2's, the impulse force AND the point where the impulse will be applied.
// This will apply an impulse of X/Y to the centre of the body.
body.applyImpulse(new Vec2(impulseX, impulseY), body.getWorldCenter());
\$\endgroup\$
  • \$\begingroup\$ fitst: thank you for taking that much time. second: I don't really know what these framework coordinates are... \$\endgroup\$ – jobr97 Aug 15 '15 at 18:15
  • \$\begingroup\$ No problem, I had quite a lot of slow progress with implementing Box2D myself, so I just thought I'd try and help out! Framework coordinates are just your own coordinates. So how would you normally display objects on the screen in libgdx? What are YOUR x and y coordinates. Hope this helps! \$\endgroup\$ – 101_son Aug 15 '15 at 18:46
  • \$\begingroup\$ oh so they are basically just pixel coordinates? \$\endgroup\$ – jobr97 Aug 15 '15 at 19:07
  • \$\begingroup\$ Yes, you got it, pixel coordinates. \$\endgroup\$ – 101_son Aug 15 '15 at 19:48
  • \$\begingroup\$ and what is the getSpriteLeft() ? \$\endgroup\$ – jobr97 Aug 16 '15 at 13:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.