3
\$\begingroup\$

I am trying a box2d body to rotate following the mouse. Here's an image to clarify what I mean. enter image description here

The red and blue circles are current point of the mouse and the body (of corresponding color) moving/rotating to follow it. Basically the rectangle should rotate with its one end pointed towards where the mouse pointer is.

Here's my code so far,

 World world;
    Body body, bullet;
    Box2DDebugRenderer debugRenderer;
    OrthographicCamera camera;

    @Override
    public void create() {

        world = new World(new Vector2(0, 0f), true);
        debugRenderer = new Box2DDebugRenderer();
        float w = Gdx.graphics.getWidth();
        float h = Gdx.graphics.getHeight();

        BodyDef bodyDef = new BodyDef();
        bodyDef.type = BodyDef.BodyType.DynamicBody;
        bodyDef.position.set(10, 10);
        body = world.createBody(bodyDef);

        PolygonShape shape = new PolygonShape();
        shape.setAsBox(2, 5);
        FixtureDef fixtureDef = new FixtureDef();
        fixtureDef.shape = shape;
        fixtureDef.density = 1f;
        Fixture fixture = body.createFixture(fixtureDef);

        shape.dispose();

        Gdx.input.setInputProcessor(this);

        camera = new OrthographicCamera(200, 100 * (h / w));
        camera.position.set(camera.viewportWidth / 2f, camera.viewportHeight / 2f, 0);
        camera.update();

    }
 @Override
    public void render() {

        Gdx.gl.glClearColor(1, 1, 1, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        world.step(Gdx.graphics.getDeltaTime(), 6, 2);
        camera.update();
        debugRenderer.render(world, camera.combined);
    }

  @Override
    public boolean mouseMoved(int screenX, int screenY) {
        int mouseX = screenX;
        int mouseY = Gdx.graphics.getHeight() - screenY;
        float rotateAngle = MathUtils.radiansToDegrees * MathUtils.atan2((float) mouseY - (float) body.getPosition().y, (float) mouseX - (float) body.getPosition().x);
        body.setTransform(body.getPosition(), rotateAngle / 57.2957795f);
        return true;
    }

And here's a gif of how it appears now. enter image description here

as you can see the body gets skewed and also doesn't rotate properly. What am I missing?

\$\endgroup\$
1
  • 2
    \$\begingroup\$ Is this your full code by the way ? From some research I did I'm pretty sure the rotation code (degrees aside) is correct and it should not be skewing. Maybe something could be wrong with the drawing or creating the body itself ? Try to let the mouse out of this and try to see if the rotation alone works (for example 1.5f), to narrow down the problem. \$\endgroup\$
    – dimitris93
    Jun 21, 2015 at 14:33

1 Answer 1

2
\$\begingroup\$

The skewing is because of how the viewport is setup, try changing it to something like this;

@Override
public void create() {
  ...

  bodyDef.position.set(0, 0); // Let this be at origin for now, it's easier to debug

  ...

  camera = new OrthographicCamera(200, 200 * ((float)Gdx.graphics.getHeight()/(float)Gdx.graphics.getWidth());
  camera.position.set(0, 0, 0); // easier to just center on origin for now

  ...
}

Also, the rotation is wrong because you're trying to use screen coordinates, you need to unporject them from screen space into camera space;

@Override
public boolean mouseMoved(int screenX, int screenY) {
  Vector3 sp3 = camera.unproject(new Vector3(screenX, screenY, 0));
  Vector2 sp2 = new Vector2(sp3.x, sp3.y);

  // Take the vector that goes from body origin to mouse in camera space
  Vector2 a = body.getPosition();
  Vector2 d = sp.sub(a);

  // Now you can set the angle;
  body.setTransform(body.getPosition(), d.angleRad());

  // You might have to do some work on d.angleRad if you find your angles are flipping as the appraoch PI/2.
}

As a side note, be careful about rotating bodies like this, setTransform on Body is intended for body setup, not during the simulation and I think you might run into some interesting behavior when this body collides with other bodies.

\$\endgroup\$

You must log in to answer this question.

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