I recommend learning how to use a time lapse variable in your main loop, like tau
. I actually have a write-up I made for it, which I can post for you. Note that this comes from a technical report on the process of making my game Agent: 00PK, and is meant for the layman. As such, some of this might be completely obvious.
Any “continuous” video game is controlled via what is called a game loop, or sometimes
a main loop. This is a place in the code that constantly cycles over and over again – in a long
loop. Every time the loop cycles, it performs the same game actions. These might be to draw, to
calculate physics, to update positions, to run the AI, or more. Any actions that must happen
“constantly” are actually called within the game loop in extremely rapid intervals. This gives the
appearance of constancy and a continuous function.
A good analogy to this would be a runner going around a track. The track is surrounded
by other events, like shot put and the high jump. On this particular track, however, the runner is
being followed by a cameraman. The people in the other events only want to perform when they
have camera exposure. So, as the runner passes the shot put, the strong man throws the ball. As
soon as the runner leaves, the shot putter stops. As the runner passes the high jump, the
contestant hurdles himself up over his goal, but he doesn’t make another attempt until the runner
comes back. The track meet will ﬁnish eventually, but will only continue as the runner passes by
each contest. Now imagine that the runner and cameraman are incredibly fast – so quick that the
shot putter and the high jumper can’t even tell when they’re being ﬁlmed or not. As a result, they
will appear never to stop – even though they are actively waiting for the camera; it comes around
so often they go as fast as they can.
The game loop is more than similar to this situation – it is practically the same. The only
difference is that in the game loop the cameraman stops and waits at each event before he goes to
the next one. If the contestants are incredibly fast, then the observers can’t even tell that any
waiting is happening; they assume that everything is happening all at once. The game loop is run
by a computer, and so naturally is this fast. The result is that, although all actions are called
incrementally, they appear to be happening simultaneously.
But what happens if the shot putter takes too long and forces the cameraman to wait? The
answer, of course, is that every other contestant can’t go until the shot putter ﬁnishes. To the
game, this circumstance would either result in a temporary freeze or a permanent one. But, these
circumstances are only caused by errors or poor code, so there’s not much that can be done about
them. What we are concerned with, however, is when one shot putter is faster than the contestant
before him. In this case, the cameraman will be going around the track at seemingly random
speeds, which will deﬁnitely confuse the observers.
In the game loop, some operations may take signiﬁcantly longer in one time step than
they did in the previous one. This gives a non-constant rate of change, so the gravity can’t simply
say to apply 9.8 meters per loop, because the span will be different every time. Without
constancy, there needs to be some way of measuring the irregularity, and then adjusting
The result is a variable called tau. Despite having a greek name, its value is quite simple:
it records the amount of time since the last time step by measuring the system clock. If tau is
very large (meaning that the cameraman had to wait an extra long time), then gravity needs to
work extra in order to account for the longer “second.” If tau is very small, then everything
happens at a smaller fraction of the rate it would normally.
Think of tau like a ratio that controls observable time. It’s analogy in the track and ﬁeld
world would be the cameraman’s feed to the television. He wants the audience to see exactly 100
respective events per hour, regardless how long each event actually takes. So, if each loop
around the track, all events considered, takes him 36 seconds, that means that the audience will
see the targeted 100 events in an hour. This golden number, which we’ll call our normal time, is
the exact number of milliseconds we want every lap to take. The cameraman can’t control how
fast the shot putters and the high jumpers are, but he can control how fast he is. So if the shot
putter takes 10 seconds and the high jumper takes 5, that makes the tau 15. The cameraman
therefore has 21 seconds to ﬁnish the lap. If the tau increases up to 30, then the cameraman needs
to put on the juice and run around the lap in just 6 seconds. If tau is only 2, then the cameraman
needs to slow down, ﬁnishing his lap in a snail’s pace 34 seconds.
Although it might not be completely obvious, what’s really being changed is the
cameraman’s velocity. If the track is 100 meters around, then with a 15 second tau the
cameraman needs to run at 4.76 meters per second. With a tau of 30, the camerman must run at
16.66 meters per second. With a tau of 2, the cameraman will be moving at only 2.94 meters per
Agent: 00PK’s game loop is just like the cameraman, except it’s signiﬁcantly faster, and
instead of changing the cameraman’s speed, we’re changing all applied velocities. Someone’s
downward velocity, for example, might be 5 meters per second with a tau of 1, and 10 meters per
second with a tau of 2. This means that, no matter how slow or fast a computer might get, the
resulting physical changes will always happen at a steady rate. This concept is detailed more
speciﬁcally in the physics below.
Basically what you do is make your thread yield when it's going too fast, ( Thread.yield() ), and move everything a certain amount times tau each timestep. The bigger tau is (the longer the wait), the more you move each object. The opposite is naturally also true.