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:
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?