我的逻辑错误,无法弄清楚它是什么。基本上,我不断计算游戏循环的每次迭代的时间跨度,并将该持续时间添加到之前的持续时间。我正在尝试计算游戏的总时间。当然,它不会产生正确的结果。我究竟做错了什么?非常感谢任何指导。
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();
}
答案 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
电话中包含任何发生的事情 - 所以你不会捕捉到游戏运行的所有时间。
如果您所做的只是显示总持续时间,为什么不仅仅使用游戏的开始和结束时间,而不是将中间的所有微小间隔相加?