1
\$\begingroup\$

I want to rotate kinematic body around a specific point (I already done this part using

shape.setAsBox(1.8f / PPM, 0.2f / PPM, new Vector2(5.2f, 0), 0); 

What I try is this:

PolygonShape shape = new PolygonShape();
shape.setAsBox(1.8f / PPM, 0.2f / PPM, new Vector2(5.2f, 0), 0); // !!!!

FixtureDef fdef = new FixtureDef();
fdef.shape = shape;
fdef.filter.categoryBits = categoryBits;
fdef.filter.maskBits = Constants.PLAYER;

bDef.position.set(((V_WIDTH / 32 - 3) / 2) / PPM, y / PPM);

body = world.createBody(bDef).createFixture(fdef).getBody();
body.setAngularVelocity(1f);
body.setUserData(new BodyUserData(categoryBits, colorArray[0]));

sprite.setOrigin(sprite.getWidth() / 2, sprite.getHeight() / 2);
sprite.setPosition(
    body.getPosition().x * 32 - sprite.getWidth() / 2, 
    body.getPosition().y * 32 - sprite.getHeight() / 2
);

and here how I draw sprite

public void draw(SpriteBatch sb){
    sprite.setRotation(body.getAngle() * MathUtils.radiansToDegrees);
    sprite.draw(sb);
}

Unfortunately my sprite position is not the same as my body. It seems that sprite is rotating around it's center, not my point. Is it possible to fix that?

\$\endgroup\$
2
+50
\$\begingroup\$

Just setting your bodys angular velocity means that it rotates around its center. You never definded the point it should rotate around.

Sadly in Box2d you can't define a rotation origin, but you could try this:

  1. Define a static body for your fixed point
  2. Define your rotating body
  3. Use a Joint to link these 2 bodies
  4. Apply a force to your rotating body
  5. Update your sprites position to the bodys position each time you draw it

Or you could calculate the circle of rotation by yourself and set the sprites position before each draw, like @Hamza Hasan described in his answer


If you want your sprite to rotate around a specific point, change its origin relative to that point:

// This sets the sprites origin to its center, letting it rotate around its center
sprite.setOrigin(sprite.getWidth() / 2, sprite.getHeight() / 2);
// If you want it to rotate around a point (e.g. 50 pixels to the left) you could try
sprite.setOrigin(-50, sprite.getHeight() / 2);

You just have to calculate the distance of your sprite to the point:

Vector2 specificPoint = new Vector2(200, 400);
Vector2 position = sprite.getPosition();
Vector2 distance = new Vector2(position.x + sprite.getWidth() / 2 - specificPoint.x, 
                              position.y + sprite.getHeight() / 2 - specificPoint.y);
sprite.setOrigin(distance);
\$\endgroup\$
3
\$\begingroup\$

I don't know libgdx, but I know something that might help you, in fact some trigonometry will help you at this point.

Normally I use parametric equation of circle for this purpose if I am unable to do it by all the other ways.

Here is the parametric equation of circle

x = r * Cos(theta) + displacementX
y = r * Sin(theta) + displacementY

where,

  • r = radius
  • theta = angle that will change upon time. (in gameloop)
  • displacementX and displacementY would be the center point of the body in center. ( if displacementX and displacementY both are zero then this equation will rotate the body around origin )

Lets say, you have a box as centre point and a circle as the sprite or object that will rotate around the box.

pseudo-code:

r = 5; // radius or distance from the box
theta = 0; // could be any, up to you
rotationSpeed = 0.5; // Change in angle, also represents the rotation speed

// public void draw(SpriteBatch sb) in your case
Gameloop()
{
    displacementX = box.x
    displacementY = box.y

    circle.x = r * Cos(theta) + displacementX
    circle.y = r * Sin(theta) + displacementY

    theta += rotationSpeed // from this you can control the rotation speed

    if (theta >= 360)
        theta = 0;
} 
\$\endgroup\$
  • 1
    \$\begingroup\$ if (theta >= 360) theta -= 360; \$\endgroup\$ – Jon Mar 8 '16 at 14:48
-3
\$\begingroup\$

You need to set sprite position to body's position each render frame, not only in initialization method.

\$\endgroup\$
  • \$\begingroup\$ I already tried this, unfortunately this doesn't worked for mr. \$\endgroup\$ – user3334375 Mar 8 '16 at 7:52

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.