wassimulator; I make stuff
Next article ► AV-Racer Devlog (1): Getting a functional car model est. reading time: 10 minutes
The first question revolving around the interest of making a car game was figuring out the methods used by car games in simulating a car body. My modest lacunary conglamurate of car facts was all I had to start with, the general idea was to simulate car and tire forces that would move the thing through the might of physics. The right approach to this problem became a matter of discussion and debate between me and my close friend Said Al Attrach, we came across a very interesting website that provided useful information to start our project with. I setup a very basic project pipeline, using SDL2 to handle windows, events and rendering (later switching to my own renderer with OpenGL), made a quick couple of drawings on Aseprite and rendered a car in the center of the screen, a generic map behind it, and moved the car in a virtual sim space, moving the camera to follow its position as the car moves Camera.P = Car.P; I set up ImGui in the game to streamline any changes or input we needed to use, it was and still is a great decision, very useful for debug. The car had a 2D space position P and velocity V, we used input from the keyboard to add a constant force to a local acceleration value that we added to the car's velocity through the loops, the velocity adds to the position. We also had an angular velocity aV that adds to the car's Angle which rotates the sprite. We didn't have a good understanding of car physics and our attempts at a somewhat realistic simulation failed, so we resorted to an arcade-like model, which I will describe in the next section.
Settling for a simpler model I started from scratch. By that time the car already had an RPM system and a dysfunctional traction calculation, I started by simplifying the car into a single object, not four tires. One tire, or closer to a rolling ball. Acceleration To move the car we need to add some sort of force proportionate to “Gas” input to the total velocity of the car over time, i.e. acceleration. We need a 2D vector that adds to the 2D vector V to modify it. The acceleration vector should always point in the direction the car's pointing in, that's the direction the accelerating force would be applied. We therefore need the normalized car's longitudinal vector which we can derive from the car's angle (Angle), we can also get the lateral vector from it which we would need later. Then all we need to do to construct the acceleration vector is to multiply the vector with a modifier that is dependent on the gas input (Gas), a float from 0.0 to 1.0 that represents how much the gas was pressed, then multiply all of that with a coefficient we eyeball through testing to adjust how intensive the throttle input is:
v2 Lon = v2(cos(Angle)), sin(Angle)); v2 Lat = v2(-Lon.y, Lon.x); v2 Acceleration = Lon * Gas * TorqueCoeff;
Braking Next we need can construct a vector that represents brake power. When hitting the brakes, the forces acting on the car causing it to slow down can be represented in a single simple force that acts in the opposite direction of the car's velocity vector; however way the car is headed, the braking force acts in the opposite direction. This force would be proportionate to the input of the brake pedal (0.0 to 1.0) and is scaled by a brake coefficient.
Note how we need to normalize the velocity vector to use it as a direction. Next we need can construct a vector that represents brake power. When hitting the brakes, the forces acting on the car causing it to slow down can be represented in a single simple force that acts in the opposite direction of the car's velocity vector; however way the car is headed, the braking force acts in the opposite direction. This force would be proportionate to the input of the brake pedal (0.0 to 1.0) and is scaled by a brake coefficient.Note how we need to normalize the velocity vector to use it as a direction.
v2 Braking = -Brake * BrakeCoeff * Car.V.normalize();
Friction Putting these together the car might oscillate when braking as it overshoots at low speeds. There are two ways to fix the problem and I implement both: interpolation, and simulating friction forces.
... continue reading