Может быть, я просто идиот, но я целый день пытаюсь реализовать игровой цикл, и он просто не щелкает. Я прочитал буквально каждую статью, которую смог найти в Google, но проблема в том, что все они используют разные механизмы синхронизации, что затрудняет их применение в моей конкретной ситуации (некоторые используют миллисекунды, другие используют тики и т. Д.).
По сути, у меня есть объект Clock
, который обновляется при каждом выполнении игрового цикла.
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);
}
}
Я основал большую часть этого на XNA GameClock
, но он значительно упрощен. Затем у меня есть класс Time
, который содержит различные времена, которые должны знать методы Update
и Draw
.
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;
}
}
Мой основной класс содержит один экземпляр Time
, который он должен постоянно обновлять в течение игрового цикла. Пока у меня есть это:
private static void Loop() {
do {
Clock.Tick();
Time.TotalRealTime = Clock.TotalTime;
Time.ElapsedRealTime = Clock.ElapsedTime;
InternalUpdate(Time);
InternalDraw(Time);
} while (!_exitRequested);
}
Свойства временного класса в реальном времени получаются великолепными. Теперь я хотел бы получить правильный цикл обновления / отрисовки, чтобы состояние обновлялось переменное число раз за кадр, но с фиксированным временным шагом. В то же время, Time.TotalVirtualTime
и Time.ElapsedVirtualTime
должны быть обновлены соответственно. Кроме того, я намерен в будущем поддерживать многопользовательскую игру на случай, если это повлияет на дизайн игрового цикла.
Какие-нибудь советы или примеры того, как я мог бы реализовать это (кроме ссылок на статьи)?