Last time, I wrote:
My brother probably expected the cart to make a turn if it was pushed on one side. Instead, it would spin around its axis, but keep moving in more or less the same direction! […] I will need to consider carefully whether this is going to be a real problem, though.
In the classic Asteroids game, the feeling of being slightly out of control is not so much of an issue, because there is no goal to move towards, and most of the world is empty. You just have to worry about not slamming into an asteroid, but otherwise you’re free to go wherever you want.
A racing game is different. There’s a set track to follow, and there are many more obstacles. Having more control over your cart, I decided, is necessary. This came about in several stages.
A major problem is that the cart easily starts spinning. Some extra friction purely on rotation (‘angular damping’) helped a lot here.
But it wasn’t enough: the cart still felt more like a spaceship than like a car. I asked myself what made that difference, and quickly realized: wheels! The swivel wheels of a shopping cart will happily roll in any direction, but the fixed wheels of cars force them into the direction in which they – actually, their wheels – are facing.
Since the cart’s motion is entirely driven by the Box2D physics engine, I had to find a way to represent the wheels physically. A simple solution, that works very well, is this:
- Measure the velocity of the wheel relative to the ground.
- Decompose this velocity into a part in the ‘rolling’ direction, in line with the wheel, and a part in the ‘sliding’ direction, perpendicular to the wheel.
- Apply a friction force in the sliding direction, proportional to the sliding velocity, but opposite in direction. Optionally, apply a much smaller force in the rolling direction.
Unwilling to completely abandon my new control scheme, I started by giving the cart fixed rear wheels, that would not swivel but always point forwards. I read somewhere that most American shopping carts work this way. I hoped that the rear wheels would help the cart move in the direction the player wanted, by making a mere rotation affect the sideways motion. This worked – to some extent. However, at high velocities the wheels made it nearly impossible to steer at all. Have a look at the above algorithm to see why: when going faster, the sideways ‘sliding’ force on the wheels becomes proportionally larger, and even a small deviation from the straight path will apply a big force that immediately pushes the cart back onto an almost straight path. It’s actually realistic, I think: such carts are hard to steer.
But not being able to spin at all is even worse than being able to spin, but not to make a corner. So as a next step, I added steering front wheels. They would steer based on the force applied to the cart’s handle: if you push on the left, the wheels steer to the right to help you make that turn. This worked incredibly well, and even I (the worst driver in history) could now turn around corners with greater ease than ever before!
Unfortunately, this control scheme made my original idea of left/right pushing somewhat redundant. The initial motivation was that it allowed for manoeuvres that normal racing games don’t allow, such as spinning around but still keeping on track. The wheels made these manoeuvres all but impossible. At some point, you have to admit that you’re fighting a lost battle. I ended up removing the left/right push altogether, and replaced it by a single throttle slider.
Another reason to abandon the original scheme was that it required multi-touch. This isn’t much of an issue per se, except that my only development phone is a Nexus One. And the Nexus One touch sensor simply sucks with multi-touch. Watch the video below (not mine) to see what I mean (skip to 1:00 for the Nexus One test).
You can imagine that this makes an already difficult control scheme nearly impossible to use. Often, when trying to make a turn, the cart ends up turning in the opposite direction. Not much fun for the player. The number of Nexus One users is, fortunately, quite small, but being unable to test my own game properly was definitely a handicap. One that I’m now rid of.