0
\$\begingroup\$

I'm trying to rotate an object (shield) around another object (player) like this question.

My use-case is this: I have players moving around a field. Their respective shield is orbiting in a constant velocity around them. If a "ball"-object (red) touches a player, he's dead. A player can use his shield to deflect a "ball". When a shield collides with the "ball", I want the player and shield be affected by the collision; thus the player should bounce back, keeping the shield at the same distance. Alternatively, on colliding with the "ball" the shield could act like a static object, either way would be okay with me.

I tried connecting the player to the shield via a b2DistanceJoint and

  • applying a force to the shield (orthogonal to the line between center of player and center of shield i.e. if the shield is right of the player, the force acts downwards; if the shield is below the player, the force acts to the left). This made the shield rotate, but the player's position was affected by the rotation, which resulted in wobbling. Then, I tried changing the density of the shield to turn down the effect on the player, but then the collision with the "ball" was faulty as the ball had way more mass.

  • "teleporting" the shield to the right position, but the collision with the "ball" was faulty afterwards (the ball "stuck" to the shield)

I know my whole setup is not a realistic physics model, so is there a way to achieve this behaviour in Box2D?

b2Body* body;
{
    b2BodyDef bodyDef;
    bodyDef.type = b2_dynamicBody;
    bodyDef.position.Set(gameToWorld * x, gameToWorld * y);

    body = world.CreateBody(&bodyDef);

    // Define another box shape for our dynamic body.
    b2CircleShape circle;
    circle.m_p.Set(0, 0);
    circle.m_radius = gameToWorld * bodyRadius;

    // Define the dynamic body fixture.
    b2FixtureDef fixtureDef;
    fixtureDef.shape = &circle;

    // Set the box density to be non-zero, so it will be dynamic.
    fixtureDef.density = 1;

    // Override the default friction.
    fixtureDef.friction = 0.0f;

    fixtureDef.restitution = 1.0f;

    // Add the shape to the body.
    body->CreateFixture(&fixtureDef);
}

b2Body* shield;
{
    b2BodyDef bodyDef;
    bodyDef.type = b2_dynamicBody;
    bodyDef.position.Set(gameToWorld * x, gameToWorld * y);

    shield = world.CreateBody(&bodyDef);

    // Define another box shape for our dynamic body.
    b2PolygonShape rect;
    // HERE:
    rect.SetAsBox(1, 1, b2Vec2(0, 0), 45);

    // Define the dynamic body fixture.
    b2FixtureDef fixtureDef;
    fixtureDef.shape = ▭

    // Set the box density to be non-zero, so it will be dynamic.
    fixtureDef.density = 1;

    // Override the default friction.
    fixtureDef.friction = 0.0f;

    fixtureDef.restitution = 1.0f;

    // Add the shape to the body.
    shield->CreateFixture(&fixtureDef);
}

{
    b2DistanceJointDef def;
    def.bodyA = body;
    def.bodyB = shield;
    def.length = 0;

    world.CreateJoint(&def);
}
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Ah... easiest solution: have centre of mass for the shield lie outside it's shape, and have it coincide with the c.o.m. of the player body.

So in other words: model the shield shape away from (0,0,0).

\$\endgroup\$
3
  • \$\begingroup\$ How do I set the center of mass for a body? As far as I understood the center of mass is dynamically computes in a fixture's shape ComputeMass-function. But by changing this, I'd mess with the fixture and therefore collision detection \$\endgroup\$ Commented Dec 22, 2018 at 20:14
  • \$\begingroup\$ The C.o.M. is at the body's position. Just place your shield shape away from the origin. Then use a joint that keeps the shield body and player body at the exact same spot. \$\endgroup\$
    – Bram
    Commented Dec 22, 2018 at 20:34
  • \$\begingroup\$ I've updated my original question to include my source code. Both bodies are at the same position (gameToWorldx, gameToWorldy) and are connected via a DistanceJoint. If I now change the position of the shape ("HERE"); the player begins to "wobble" as the shape rotates around him. Additionally, I currently can not control how the shape rotates around the player Could you elaborate your answer (via code)? \$\endgroup\$ Commented Dec 28, 2018 at 11:00

You must log in to answer this question.

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