C# 游戏循环与时间跟踪

C# 游戏循环与时间跟踪,c#,timing,game-loop,C#,Timing,Game Loop,也许我只是个白痴,但我整天都在尝试实现一个游戏循环,只是没有点击。我读过谷歌上的每一篇文章,但问题是它们都使用不同的计时机制,这使得它们很难适用于我的特定情况(一些使用毫秒,另一些使用滴答声,等等) 基本上,我有一个时钟对象,它在每次执行游戏循环时都会更新 internal class Clock { public static long Timestamp { get { return Stopwatch.GetTimestamp(); } } pub

也许我只是个白痴,但我整天都在尝试实现一个游戏循环,只是没有点击。我读过谷歌上的每一篇文章,但问题是它们都使用不同的计时机制,这使得它们很难适用于我的特定情况(一些使用毫秒,另一些使用滴答声,等等)

基本上,我有一个
时钟
对象,它在每次执行游戏循环时都会更新

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);
    }
}
我的主类保留一个
时间的实例,它应该在游戏循环期间不断更新。到目前为止,我有:

private static void Loop() {
    do {
        Clock.Tick();

        Time.TotalRealTime = Clock.TotalTime;
        Time.ElapsedRealTime = Clock.ElapsedTime;

        InternalUpdate(Time);
        InternalDraw(Time);
    } while (!_exitRequested);
}
time类的实时属性非常好。现在,我想让一个适当的更新/绘制循环正常工作,以便每个帧的状态更新次数可变,但时间步长固定。同时,应相应地更新
time.TotalVirtualTime
time.ElapsedVirtualTime
。此外,我打算在将来支持多人游戏,以防对游戏循环的设计产生任何影响


关于如何实现这一点(除了文章链接之外)有什么提示或示例吗?

XNA中主要使用的方法是以固定速率调用
Update()
,并尽可能多地调用
Draw()
,直到达到某个限制。在
Update()
方法中,您只需更新变量以反映新时刻的世界,当调用
Draw()
时,您只需将其绘制到屏幕上

要使
Update()
以固定速率运行,您可能需要使用计时器或更精确的计时,使用:

[DllImport("kernel32.dll")]
public static extern long GetTickCount();

然后,您可以使用另一个(较慢的)计时器,该计时器对用于绘制游戏的对象(画布)调用
Invalidate()
。在画布的绘制事件中,调用
Draw()
。这样,每当系统认为有必要时(当它使画布失效时),或者当你调用
Invalidate()

时,只要它有机会这样做,你的世界就会被绘制出来。对不起,我忘了提到我只关心在Xbox 360上运行,这意味着我将无法访问P/Invoke,也不需要担心系统何时需要我绘制,因为我可以随时绘制。通过使用Stopwatch.GetTimestamp()
,类已具有准确的计时。我的问题实际上是关于我需要如何构造固定更新循环,以及如何跟踪经过的“游戏/虚拟时间”。我想我有一个相当好的理解,但我想一些建议,以防有更好的方法来做。不过,谢谢你的回答!
[DllImport("kernel32.dll")]
public static extern long GetTickCount();