2
\$\begingroup\$

I have created below hexagon structure in Andengine with box2D physics extension. I want to rotate whole structure with respect to center when other ball collides with the structure using physics.

hex

I tried weld joint and revolute joint with the bodies but it is not performing proper motion as required. All bodies are attached with weld joint and vertices have revolute joint with center body which is static like,

RevoluteJointDef revoluteJointDef1 = new RevoluteJointDef();
revoluteJointDef1.initialize(centerB, movingBody[i], centerB.getWorldCenter());
revoluteJointDef1.enableMotor = true;
revoluteJointDef1.motorSpeed = 0;
revoluteJointDef1.maxMotorTorque = 1f;
this.mPhysicsWorld.createJoint(revoluteJointDef1);

I had refered these links: box2d manual and box2d joints tutorial

Is there any other way to perform smooth rotation of whole structure? Thanks.

\$\endgroup\$
  • \$\begingroup\$ Is there any way if i can add a big circle disc body and attach balls on top of it which will rotate all bodies? \$\endgroup\$ – Harry Jan 13 '15 at 8:51
  • \$\begingroup\$ Do the circles need to move independently of the hex structure sometimes, or will the entire hex structure always move as one? \$\endgroup\$ – NauticalMile Jan 15 '15 at 20:39
  • \$\begingroup\$ The whole hex structure should rotate not the particular ball. But it should be done with physics like when other ball collides with the hex, it should rotate accordingly. \$\endgroup\$ – Harry Jan 17 '15 at 5:00
2
\$\begingroup\$

If the circles never need to move independently, you can make one body. See here for an example of a hexagon body. I've extracted the relavent bits and pasted them here:

import static org.anddev.andengine.extension.physics.box2d.util.constants.PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;

/* ... */

public class PhysicsExample extends BaseExample implements IAccelerometerListener, IOnSceneTouchListener {

    /* ... */

    private static Body createHexagonBody(final PhysicsWorld pPhysicsWorld, final Shape pShape, final BodyType pBodyType, final FixtureDef pFixtureDef) {
    /* Remember that the vertices are relative to the center-coordinates of the Shape. */
        final float halfWidth = pShape.getWidthScaled() * 0.5f / PIXEL_TO_METER_RATIO_DEFAULT;
        final float halfHeight = pShape.getHeightScaled() * 0.5f / PIXEL_TO_METER_RATIO_DEFAULT;

    /* The top and bottom vertex of the hexagon are on the bottom and top of hexagon-sprite. */
        final float top = -halfHeight;
        final float bottom = halfHeight;

        final float centerX = 0;

        final float left = -halfWidth + 2.5f / PIXEL_TO_METER_RATIO_DEFAULT;
        final float right = halfWidth - 2.5f / PIXEL_TO_METER_RATIO_DEFAULT;
        final float higher = top + 8.25f / PIXEL_TO_METER_RATIO_DEFAULT;
        final float lower = bottom - 8.25f / PIXEL_TO_METER_RATIO_DEFAULT;

        final Vector2[] vertices = {
            new Vector2(centerX, top),
            new Vector2(right, higher),
            new Vector2(right, lower),
            new Vector2(centerX, bottom),
            new Vector2(left, lower),
            new Vector2(left, higher)
        };

        return PhysicsFactory.createPolygonBody(pPhysicsWorld, pShape, vertices, pBodyType, pFixtureDef);
    }
}

EDIT:

I know the OP has found a working solution to their problem, but I thought I would update my answer anyway. I think the best way is still to make just one body, but you can add multiple fixtures to it (Example done in RUBE):

enter image description here

When a collision happens, the fixture (e.g. ball) in contact is passed to all the collision callbacks, so you don't have to worry about implementing any fancy system to determine which ball was hit in a collision.

IMO this is a lot cleaner and faster than creating new bodies for every ball, and then joining every body to a central one using weld joints.

\$\endgroup\$
  • \$\begingroup\$ But if i throw a ball, how do i get which ball from the hexagon has collided with the thrown ball?! \$\endgroup\$ – Harry Jan 23 '15 at 9:56
  • \$\begingroup\$ Oh, so you're throwing balls at the hexagon and you need to know which ball was hit. That's an important piece of information! I am also curious now, do you delete the balls when they are struck? Kind of like the panels are deleted in breakout? \$\endgroup\$ – NauticalMile Jan 23 '15 at 17:20
  • \$\begingroup\$ It is also a good solution, but i dont know RUBE as this is my first experience with andengine, thanks for the effort but i cant vote up due to low reputation. \$\endgroup\$ – Harry Jan 28 '15 at 14:05
  • \$\begingroup\$ No worries, glad I could help. \$\endgroup\$ – NauticalMile Jan 28 '15 at 18:24
0
\$\begingroup\$

Oh! i got solution by myself... I did the same thing as i mentioned in first comment my question where I attached balls on a big circle body like,

Body circleBody ... ;// having large radius
//for all balls arranged in hexagon structure
foreach BallBody b
{ 
WeldJointDef def = new WeldJointDef();
def.initialize(b, circleBody, b.getWorldCenter());
mPhysicsWorld.createJoint(def);
}

and got the rotation by having revolute joint of circleBody with center. Thanks who put their efforts.

\$\endgroup\$

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.