时间跨度逻辑错误

时间:2010-11-26 15:14:32

标签: c#

我的逻辑错误,无法弄清楚它是什么。基本上,我不断计算游戏循环的每次迭代的时间跨度,并将该持续时间添加到之前的持续时间。我正在尝试计算游戏的总时间。当然,它不会产生正确的结果。我究竟做错了什么?非常感谢任何指导。

        private TimeSpan totalDuration = TimeSpan.FromSeconds(1);
        private int score = 0;

        public void Stop()
        {
            IsGameOver = true;
            //MessageBox.Show(String.Format("Game Over\n\nScore = {0}", score));
            MessageBox.Show(String.Format("Game Over\n\nScore = {0}\n\nTime
            Duration={1}", score, totalDuration));
            Application.Exit();
        }

        public void Start()
        {

            score = 0;
            IsGameOver = false;

            currentRedLightX = 0;
            currentRedLightY = 0;

            currentGreenLightX = width / 2;
            currentGreenLightY = height / 2;


            double minIterationDuration = SPEED; // 50 frames / sec

            //game loop
            while (!IsGameOver)
        {
            if (IsCollision())
            {
                score += 10;
            }

            DateTime startIterationTime = System.DateTime.UtcNow;
            UpdateGameState();
            Render();
            DateTime endIterationTime = System.DateTime.UtcNow;
            TimeSpan iterationDuration = endIterationTime - startIterationTime;
            totalDuration += iterationDuration;
            //totalDuration += iterationDuration.Duration();                
            if (iterationDuration.TotalMilliseconds < minIterationDuration)
                Thread.Sleep(Convert.ToInt32(minIterationDuration - 
                iterationDuration.TotalMilliseconds));

            Application.DoEvents();
        }

4 个答案:

答案 0 :(得分:5)

使用StopWatch类来计算已用时间,而不是时间跨度:

Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
// Do stuff ...
stopWatch.Stop();

答案 1 :(得分:1)

DateTime.UtcNow的准确度相对较低。假设你的循环速度相当快,我发现大多数时候iterationDuration实际上是零,我都不会感到惊讶 - 导致错误的结果。这就是为什么使用Stopwatch(反复使用同一个,适当地调用Start / Stop而不是Reset)是一种更好的方法。 Stopwatch将使用高分辨率系统计时器(如果有的话)。

顺便说一下,在UI线程中睡觉并使用Application.DoEvents在UI编程方面非常讨厌。我想知道你真的想要一个Timer而不是......

答案 2 :(得分:1)

我猜你逻辑中缺少的东西是考虑你将线程发送到睡眠状态的时间。您可能希望在将其发送到睡眠之前或之后添加该时间。

答案 3 :(得分:1)

你没有在你的DoEvents电话中包含任何发生的事情 - 所以你不会捕捉到游戏运行的所有时间。

如果您所做的只是显示总持续时间,为什么不仅仅使用游戏的开始和结束时间,而不是将中间的所有微小间隔相加?