Game loop and time tracking
- by David Brown
Maybe I'm just an idiot, but I've been trying to implement a game loop all day and it's just not clicking. I've read literally every article I could find on Google, but the problem is that they all use different timing mechanisms, which makes them difficult to apply to my particular situation (some use milliseconds, other use ticks, etc).
Basically, I have a Clock object that updates each time the game loop executes.
internal class Clock {
public static long Timestamp {
get { return Stopwatch.GetTimestamp(); }
}
public static long Frequency {
get { return Stopwatch.Frequency; }
}
private long _startTime;
private long _lastTime;
private TimeSpan _totalTime;
private TimeSpan _elapsedTime;
/// <summary>
/// The amount of time that has passed since the first step.
/// </summary>
public TimeSpan TotalTime {
get { return _totalTime; }
}
/// <summary>
/// The amount of time that has passed since the last step.
/// </summary>
public TimeSpan ElapsedTime {
get { return _elapsedTime; }
}
public Clock() {
Reset();
}
public void Reset() {
_startTime = Timestamp;
_lastTime = 0;
_totalTime = TimeSpan.Zero;
_elapsedTime = TimeSpan.Zero;
}
public void Tick() {
long currentTime = Timestamp;
if (_lastTime == 0)
_lastTime = currentTime;
_totalTime = TimestampToTimeSpan(currentTime - _startTime);
_elapsedTime = TimestampToTimeSpan(currentTime - _lastTime);
_lastTime = currentTime;
}
public static TimeSpan TimestampToTimeSpan(long timestamp) {
return TimeSpan.FromTicks(
(timestamp * TimeSpan.TicksPerSecond) / Frequency);
}
}
I based most of that on the XNA GameClock, but it's greatly simplified. Then, I have a Time class which holds various times that the Update and Draw methods need to know.
public class Time {
public TimeSpan ElapsedVirtualTime { get; internal set; }
public TimeSpan ElapsedRealTime { get; internal set; }
public TimeSpan TotalVirtualTime { get; internal set; }
public TimeSpan TotalRealTime { get; internal set; }
internal Time() { }
internal Time(TimeSpan elapsedVirtualTime, TimeSpan elapsedRealTime,
TimeSpan totalVirutalTime, TimeSpan totalRealTime) {
ElapsedVirtualTime = elapsedVirtualTime;
ElapsedRealTime = elapsedRealTime;
TotalVirtualTime = totalVirutalTime;
TotalRealTime = totalRealTime;
}
}
My main class keeps a single instance of Time, which it should constantly update during the game loop. So far, I have this:
private static void Loop() {
do {
Clock.Tick();
Time.TotalRealTime = Clock.TotalTime;
Time.ElapsedRealTime = Clock.ElapsedTime;
InternalUpdate(Time);
InternalDraw(Time);
} while (!_exitRequested);
}
The real time properties of the time class turn out great. Now I'd like to get a proper update/draw loop working so that the state is updated a variable number of times per frame, but at a fixed timestep. At the same time, the Time.TotalVirtualTime and Time.ElapsedVirtualTime should be updated accordingly. In addition, I intend for this to support multiplayer in the future, in case that makes any difference to the design of the game loop.
Any tips or examples on how I could go about implementing this (aside from links to articles)?