Time-based movement

Instead of using frame-based movement, it is much better to base our movement on time. Time is guaranteed to be consistent throughout development and on all hardware, now and in the future. Whether our game is updating at three frames per second or 3,000 frames per second, one second will always be equal to one second.

Using time-based movement is great because it allows us to use equations that have existed for hundreds of years. We don't need to reinvent the wheel to simulate velocity and acceleration. As we said before, using a constant speed to move the player is OK for some games, but that isn't how real physics works. Cars and spaceships do not accelerate instantly. Gravity pulls you down faster and faster the longer you fall.

When you toss a ball to a ten year old child, they don't need to do complex calculations to catch the ball; they can just do it. Similarly, in a semi-realistic simulation, players will expect the physics to behave normally. To simulate realistic or semi-realistic physics in our game, we should understand how to incorporate velocity and physics into our movement.

We can calculate an object's velocity by subtracting the initial position of an object from the final position of an object, and dividing that by how long the displacement took. Another way to say this is that velocity is equal to the change in the position divided by the change in time. We can use this to create an equation that we can put in our code:

We can also calculate an object's acceleration by subtracting the initial velocity from the final velocity and dividing by the change in time. Acceleration is change in velocity over change in time:

We also know from Newton's second law of motion that force equals mass times acceleration. This also means that acceleration is equal to force divided by mass:

What this means is that, if we know the current position, velocity, and the forces acting on an object, we can find the position and velocity at some point in the future. In our games, we can use these three equations to simulate motion:

The first two of these three equations are called Euler (pronounced Oiler) Integration. Specifically, it is called explicit Euler. In code, it will look something like this:

float EulerIntegration(float pos, float vel, float accel, 
float totalTime, float dt)
{
float time = 0.0f;
while (time < totalTime)
{
pos += vel * dt;
vel += accel * dt;
time += dt;
}
return pos;
}

The inner loop of this code is a close example of how we will use this in a game. Every frame, we will update our position and velocity based on dt and the acceleration. The velocity calculated in this frame will be used to update the position of an object in the next frame. Outside of a loop, these equations make perfect sense. If we are traveling at 55 mph down the freeway, after one hour we expect to be 55 miles further down the road. Similarly, if we are accelerating at 8 miles per hour per second then after ten seconds we expect to have a velocity of 80 mph.

However, inside of the loop we will have some errors. Euler Integration is only accurate if acceleration and velocity are held constant. In the preceding code example, velocity is changing every time through the loop, so it is inaccurate proportional to the square of the step size. That means that the larger the step, the more error it has.

Let's compare Euler Integration with one of the Kinematics Equations of motion to see how this error effects our results. The Kinematics Equation that we will test with is:

Where p is our new position, p0 is our initial position, v0 is our initial velocity, a is our acceleration and t is our time.

Let's assume that our starting position is 0 and our starting velocity is 0. Typically, in physics equations, acceleration is in units of seconds per second instead of hours per second. So, let's say we are accelerating at 20 feet per second for 10 seconds. After 10 seconds, our car will have traveled 500 feet:

So, the Kinematics equations say we will be 1000 feet from where we started after 10 seconds. Using this same data, let plug it into our Euler Integration function. We will be integrating every second for 10 seconds:

  Time = 0  pos =    0.00 vel =   0.00 
Time = 1 pos = 0.00 vel = 20.00
Time = 2 pos = 20.00 vel = 40.00
Time = 3 pos = 60.00 vel = 60.00
Time = 4 pos = 120.00 vel = 80.00
Time = 5 pos = 200.00 vel = 100.00
Time = 6 pos = 300.00 vel = 120.00
Time = 7 pos = 420.00 vel = 140.00
Time = 8 pos = 560.00 vel = 160.00
Time = 9 pos = 720.00 vel = 180.00
Time = 10 pos = 900.00 vel = 200.00

Euler Integration says we will be 900 feet from where we started. The Kinematics Equation and Euler Integration are 100 feet off. This is after only 10 seconds. The longer we integrate for, the more the error. Of course, we already explained why we have this problem. The error is proportional to the time step. If we use a smaller time step, we will have a smaller error. Luckily our game will be updating more than one frame per second. Let's integrate again, but let's use some more realistic time steps. Let's choose values for 30 fps, 60 fps, and 120 fps. These give us time steps of .0333, .0167, and .008 respectively:

  dt = 1.000000   pos = 900.00 
dt = 0.033333 pos = 996.67
dt = 0.016667 pos = 998.33
dt = 0.008333 pos = 1000.83

As you can see, by using a smaller time step, we come closer to the matching result. At 120 fps, we are pretty accurate but, even at 60 fps, we have calculated a few feet off. Unfortunately, even the Kinematics equations are not accurate unless acceleration is held constant.

For many games, Euler Integration will be all you need. The errors are small enough that players may not notice. This of course depends on gameplay and the frame rate. Creating an extremely accurate physics integrator is beyond the scope of this book.

If your game requires very accurate physics, check out Verlet Integration or RK4 Integration at:
https://en.wikipedia.org/wiki/Verlet_integration,
https://en.wikipedia.org/wiki/Runge-Kutta_methods

Whichever integration method you choose, it will be better and more reliable than using frame-based movement. The important thing to remember is that anything that changes in the game must use time. This includes rotations, which can use similar rotational velocity and rotational acceleration if you want. It also includes scaling over time, animating a texture over time, and even changing color and transparency. This will give our game a very consistent look and feel, as well as making it easier to test and debug throughout development.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.113.55