2
\$\begingroup\$

I'm trying to make good suspension for my car game, but I'm getting nervous of some problems with it.

At the beginning, I've tried to make it out of one prismatic joint/revolute joint per one wheel only, but surprisingly prismatic joint that should only move in Y asix moves also in X axis, if car travels very fast, or even on low speeds if there's setContinuousPhysics = true. This causes wheels to "shift back", moving them away from axle.

Now I've tried to add some bodies that will keep it in place:

enter image description here

enter image description here

Suspension helper collides with spring only, wheel doesn't collide with spring&helper&vehicle body

This is how I create those elements:

rect = new Rectangle(1100, 1350, 200, 50, getVertexBufferObjectManager());
        rect.setColor(Color.RED);
        scene.attachChild(rect);
        //rect.setRotation(90);
        Rectangle miniRect1 = new Rectangle(1102, 1355, 30, 50, getVertexBufferObjectManager());
        miniRect1.setColor(0, 0, 1, 0.5f);
        miniRect1.setVisible(true);
        scene.attachChild(miniRect1);

        Rectangle miniRect2 = new Rectangle(1268, 1355, 30, 50, getVertexBufferObjectManager());
        miniRect2.setColor(0, 0, 1, 0.5f);
        miniRect1.setVisible(true);
        scene.attachChild(miniRect2);


        rectBody = PhysicsFactory.createBoxBody(
                physicsWorld, rect, BodyDef.BodyType.DynamicBody, PhysicsFactory.createFixtureDef(10.0f, 0.01f, 10.0f));
        rectBody.setUserData("car");

        Body miniRect1Body = PhysicsFactory.createBoxBody(
                physicsWorld, miniRect1, BodyDef.BodyType.DynamicBody, PhysicsFactory.createFixtureDef(10.0f, 0.01f, 10.0f));
        miniRect1Body.setUserData("suspension");

        Body miniRect2Body = PhysicsFactory.createBoxBody(
                physicsWorld, miniRect2, BodyDef.BodyType.DynamicBody, PhysicsFactory.createFixtureDef(10.0f, 0.01f, 10.0f));
        miniRect2Body.setUserData("suspension");


        physicsWorld.registerPhysicsConnector(new PhysicsConnector(rect, rectBody, true, true));
        physicsWorld.registerPhysicsConnector(new PhysicsConnector(miniRect1, miniRect1Body, true, true));
        physicsWorld.registerPhysicsConnector(new PhysicsConnector(miniRect2, miniRect2Body, true, true));

        PrismaticJointDef miniRect1JointDef = new PrismaticJointDef();
        miniRect1JointDef.initialize(rectBody, miniRect1Body,
                miniRect1Body.getWorldCenter(),
                new Vector2(0.0f, 0.3f));
        miniRect1JointDef.collideConnected = false;
        miniRect1JointDef.enableMotor= true;

        miniRect1JointDef.maxMotorForce = 15;
        miniRect1JointDef.motorSpeed = 5;
        miniRect1JointDef.enableLimit = true;
        physicsWorld.createJoint(miniRect1JointDef);

        PrismaticJointDef miniRect2JointDef = new PrismaticJointDef();
        miniRect2JointDef.initialize(rectBody, miniRect2Body,
                miniRect2Body.getWorldCenter(),
                new Vector2(0.0f, 0.3f));
        miniRect2JointDef.collideConnected = false;
        miniRect2JointDef.enableMotor= true;
        miniRect2JointDef.maxMotorForce = 15;
        miniRect2JointDef.motorSpeed = 5;
        miniRect2JointDef.enableLimit = true;
        physicsWorld.createJoint(miniRect2JointDef);

        scene.attachChild(karoseriaSprite);


        Rectangle r1 = new Rectangle(1050, 1300, 52, 150, getVertexBufferObjectManager());
        r1.setColor(0, 1, 0, 0.5f);
        r1.setVisible(true);
        scene.attachChild(r1);
        Body r1body = PhysicsFactory.createBoxBody(physicsWorld, r1, BodyDef.BodyType.DynamicBody, PhysicsFactory.createFixtureDef(10.0f, 0.001f, 0.01f));
        r1body.setUserData("suspensionHelper");
        physicsWorld.registerPhysicsConnector(new PhysicsConnector(r1, r1body, true, true));
        WeldJointDef r1jointDef = new WeldJointDef();
        r1jointDef.initialize(r1body, rectBody, r1body.getWorldCenter());
        physicsWorld.createJoint(r1jointDef);

        Rectangle r2 = new Rectangle(1132, 1300, 136, 150, getVertexBufferObjectManager());
        r2.setColor(0, 1, 0, 0.5f);
        r2.setVisible(true);
        scene.attachChild(r2);
        Body r2body = PhysicsFactory.createBoxBody(physicsWorld, r2, BodyDef.BodyType.DynamicBody, PhysicsFactory.createFixtureDef(10.0f, 0.001f, 0.01f));
        r2body.setUserData("suspensionHelper");
        physicsWorld.registerPhysicsConnector(new PhysicsConnector(r2, r2body, true, true));
        WeldJointDef r2jointDef = new WeldJointDef();
        r2jointDef.initialize(r2body, rectBody, r2body.getWorldCenter());
        physicsWorld.createJoint(r2jointDef);

        Rectangle r3 = new Rectangle(1298, 1300, 50, 150, getVertexBufferObjectManager());
        r3.setColor(0, 1, 0, 0.5f);
        r3.setVisible(true);
        scene.attachChild(r3);
        Body r3body = PhysicsFactory.createBoxBody(physicsWorld, r3, BodyDef.BodyType.DynamicBody, PhysicsFactory.createFixtureDef(1f, 0.01f, 0.01f));
        r3body.setUserData("suspensionHelper");
        physicsWorld.registerPhysicsConnector(new PhysicsConnector(r3, r3body, true, true));
        WeldJointDef r3jointDef = new WeldJointDef();
        r3jointDef.initialize(r3body, rectBody, r3body.getWorldCenter());
        physicsWorld.createJoint(r3jointDef);
        MouseJointDef md = new MouseJointDef();

        Sprite wheel1 = new Sprite(
                miniRect1.getX()+miniRect1.getWidth()/2-wheelTexture.getWidth()/2,
                miniRect1.getY()+miniRect1.getHeight()-wheelTexture.getHeight()/2,
                wheelTexture, engine.getVertexBufferObjectManager());
        scene.attachChild(wheel1);

        Body wheel1body = PhysicsFactory.createCircleBody(
                physicsWorld, wheel1, BodyDef.BodyType.DynamicBody, PhysicsFactory.createFixtureDef(10.0f, 0.01f, 5.0f));
        wheel1body.setUserData("wheel");
        Shape wheel1shape = wheel1body.getFixtureList().get(0).getShape();
        wheel1shape.setRadius(wheel1shape.getRadius()*(3.0f/4.0f));
        physicsWorld.registerPhysicsConnector(new PhysicsConnector(wheel1, wheel1body, true, true));

        Sprite wheel2 = new Sprite(
                miniRect2.getX()+miniRect2.getWidth()/2-wheelTexture.getWidth()/2,
                miniRect2.getY()+miniRect2.getHeight()-wheelTexture.getHeight()/2,
                wheelTexture, engine.getVertexBufferObjectManager());
        scene.attachChild(wheel2);

        Body wheel2body = PhysicsFactory.createCircleBody(
                physicsWorld, wheel2, BodyDef.BodyType.DynamicBody, PhysicsFactory.createFixtureDef(10.0f, 0.01f, 5.0f));
        wheel2body.setUserData("wheel");
        Shape wheel2shape = wheel2body.getFixtureList().get(0).getShape();
        wheel2shape.setRadius(wheel2shape.getRadius()*(3.0f/4.0f));
        physicsWorld.registerPhysicsConnector(new PhysicsConnector(wheel2, wheel2body, true, true));

        RevoluteJointDef frontWheelRevoluteJointDef = new RevoluteJointDef();
        frontWheelRevoluteJointDef.initialize(wheel1body, miniRect1Body, wheel1body.getWorldCenter());
        frontWheelRevoluteJointDef.collideConnected = false;

        RevoluteJointDef rearWheelRevoluteJointDef = new RevoluteJointDef();
        rearWheelRevoluteJointDef.initialize(wheel2body, miniRect2Body, wheel2body.getWorldCenter());
        rearWheelRevoluteJointDef.collideConnected = false;
        rearWheelRevoluteJointDef.motorSpeed = 2050;
        rearWheelRevoluteJointDef.maxMotorTorque= 3580;
        physicsWorld.createJoint(frontWheelRevoluteJointDef);
        Joint j = physicsWorld.createJoint(rearWheelRevoluteJointDef);

        rearWheelRevoluteJoint = (RevoluteJoint)j;


        r1body.setBullet(true);
        r2body.setBullet(true);
        r3body.setBullet(true);
        miniRect1Body.setBullet(true);
        miniRect2Body.setBullet(true);
        rectBody.setBullet(true);

at low speeds, it's OK, but on high speed vehicle can even flip around on flat ground..

Is there a way to make this work better?

\$\endgroup\$

1 Answer 1

1
+100
\$\begingroup\$

Simulation of joint in AndEngine is so much poor as per my experience also. You have to use wheel joint for designing any vehicle. I know your next question. you found wheel joint implementation in RealMayo's Box2d Extension

So you have to simulate single joint only so all over performance become good. Also you can apply suspension and all other attribute to you vehicle using wheel joint.

You have to implement following two steps also for better physics implementation.

  1. Use FixedStepPhysiscsWorld with allow sleep attribute value set to false. Render world with 60 fps.
  2. Use FixedStepEngine instead of normal engine. Render engine also with 60 fps.

Above all suggestions are important as per my review. I hope work for you also.

\$\endgroup\$

You must log in to answer this question.

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