2
\$\begingroup\$

I am developing a small game with LibGDX and Box2D.

I want to move a body at a constant speed, lets say 2 m/s (meters per sec).
The body should accelerate to that speed immediately when pressing the respective key (e.g. Arrow Up) and also be able to stop or change direction instantly.

The code to start and stop such a movement should look like this: public void onKeyPress(key){ if(key == ArrowUp){ currentMovement = new Vector2(0, movementSpeed); body.addConstantMovement(currentMovement); } //TODO: Remaining directions }

public void onKeyRelease(key){ if(key == ArrowUp || key == ArrowLeft || key == ArrowRight || key == ArrowDown){ body.removeConstantMovement(currentMovement); } } The given Vector2 (movementSpeed) should be remebered and I should be able to remove it at any time.

However, he should still be affected by the physics of everything around him.
So if he moves towards a magnet that pulls him 1 m/s, he will move with 3 m/s, when moving away from it the speed should be down at 1 m/s.

Is it possible to do this in Box2D without manually moving it in every step of the world?
-If yes, how?
-If no, any libraries that can do this? I only need very simple physics, no density, friction etc.

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

When you want to modify a body in box2d you have 2 main choices use the physics or ignore the physics and modify things yourself.

The first option would be to use the bodie's applyForce or applyLinearImpulse methods to move the object. This will allow box 2d to perform physics on your body.

The other option is to ignore the physics from box2d and manually set the position/speed etc with setTransform, setLinearVelocity etc.

Each of these have their own pros and cons. For example, the first option will allow your body to react in a way that matches the real world but will be harder to control the speed. The second option will make it easy to control speed and position but will make it hard for you to make the body react in a natural way.

My opinion on this would be to go with option 2 as once you can move you body at your desired speed etc then you can use sensors to sense when a body is within range of said "Magnets" then have your own function to apply the physics you want, be it push or pull to a point with some simple trigonometry.

This example below shows how to control the body:

public void onKeyPress(key){
    if(key == ArrowUp){
        // box2d is in meters so 0,2 is 2 meters per second
        body.setLinearVelocity(new Vector2D(0, 2));
    }
    if(key == ArrowRight){
        body.setLinearVelocity(ew Vector2D(2, 0));
    }
    if(key == ArrowDown){
        body.setLinearVelocity(new Vector2D(0, -2));
    }
    if(key == ArrowLeft){
        body.setLinearVelocity(new Vector2D(-2, 0));
    }
   // this does not allow diagonals
}

Now to apply magnetism you will need a contact listener which listens to contacts and then checks if those came from a magnets sensor body. You woul then use something like this to apply a pull magnetism effect

        // get distance from moving object and magnet
        float velx = magnetBody.getPosition().x - movingBody.getPosition().x;
        float vely = magnetBody.getPosition().y - movingBody.getPosition().y;

        // get the euclidean length
        float length = (float) Math.sqrt(velx * velx + vely * vely);
        if (length != 0) {
            velx = velx / length;
            vely = vely / length;
        }

        // get current moving speed
        Vector2 current = movingBody.getLinearVelocity();

        // get speed magnet should add
        Vector2 magnets = new Vector2(velx * magnetStrength, vely
                        * magnetStrength)

        // add magnet speed to current speed to get modified speed
        Vector2 newSpeed = current.add(magnets);

        // apply it to the body
        movingBody.setLinearVelocity(newSpeed);

This should cover the basics of what you need to apply the speed and magnet power to a body. You will need to adjust this to match your world but this should help you get started.

\$\endgroup\$
1
  • \$\begingroup\$ Thank you, that made things much more clear for me. I will now try to add multiple forces (Vector2) to each GameObject (class that manages a body) and manually calculate a total force. \$\endgroup\$
    – Lahzey
    Commented Oct 10, 2017 at 14:30

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .