I've been meaning to try this out for a while, but haven't really had the time or the project for it. Basically what you need is to be able to simulate the friction of the tank sitting on the ground to be able to make your tank move and spin.
Chipmunk currently doesn't have constraints that help you do this, but you can do it well enough using a bit of a hack. It should work well enough for a tank game. Essentially, what you need to do is to create a static body that you joint your tank to, then you control your tank by changing the static body.
So here's what I would try:
- Create a static body (infinite mass and moment of inertia, don't add it to the space)
- Add a pivot joint between the tank's body and the static body using cpPivotJointNew2(), use cpvzero for both joint anchors.
- Add a gear joint between the tanks' body and the static body. Use 1.0 for the ration and 0.0 for the phase.
- Set the biasCoef of both joints 0.0. Setting the maxForce of the joints will control the amount of friction. The pivot controls the sliding, and the gear joint controls the rotation.
With all this set up, setting the velocity of the static body will control the movement of the tank and setting the rotational velocity will control the tank's rotation. No need to move the static body around, just modify the velocities. It works by using the joints to lock the velocity of the tank to the velocity of the static body. By setting the
biasCoef to 0.0, you are disabling the position correction the joint would normally do to keep the joints from stretching. The
maxForce is acting like friction by limiting how much force can be used to match their velocities.
It's also possible to control the angle of the tank directly if you don't really care about directly controlling the rotation speed. Instead of setting the gear joint's
biasCoef value, set the
maxBias value to whatever speed you want the tank to rotate at. This way the angular correction of the gear joint will be active, but limited to the rate defined by
maxBias. You can now set the angle of the static body using
cpBodySetAngle() and the the tank body will rotate to match it.
Lastly, if you want to define the tank's velocity relative to the tank's rotation (presumably you do), do something like this:
- Code: Select all
staticTankBody-> = cpvrotate(tankBody->rot, cpv(speed, 0.0))
Cheers.