C# 使用不同的Thread.sleep()持续时间来控制播放器速度?
如果“bikes”列表中的一个对象包含布尔值,我将尝试更快地绘制line()。当列表中包含两辆自行车时,结果是当只有一辆自行车“加速”时,两辆自行车似乎都加速了。有人知道为什么吗?如果对象不包含isBoosting的值true,线程是否应该“移动”较慢C# 使用不同的Thread.sleep()持续时间来控制播放器速度?,c#,.net,multithreading,drawing,C#,.net,Multithreading,Drawing,如果“bikes”列表中的一个对象包含布尔值,我将尝试更快地绘制line()。当列表中包含两辆自行车时,结果是当只有一辆自行车“加速”时,两辆自行车似乎都加速了。有人知道为什么吗?如果对象不包含isBoosting的值true,线程是否应该“移动”较慢 foreach (LightBike b in bikes) //draw bikes { if (b.isBoosting && b.boostCounter > 0) //player is boosting
foreach (LightBike b in bikes) //draw bikes
{
if (b.isBoosting && b.boostCounter > 0) //player is boosting
{
Thread.Sleep(GAME_SPEED - 5);
b.boostCounter--;
if (b.boostCounter == 0)
{
b.isBoosting = false;
b.boostCounter = 20;
}
}
else
{
Thread.Sleep(GAME_SPEED);
}
canvas.DrawLine(new Pen(b.color, BIKE_SIZE) { EndCap = System.Drawing.Drawing2D.LineCap.Square }, b.location, b.getNextLocation());
}
这有几个问题 首先,由于它是一个单线程,当您睡眠一段时间时,线程被重新调度——不会进行渲染(在您的情况下,这意味着既不会绘制“增强”的自行车,也不会绘制其他自行车)。实际绘制的线总是从b.location到b.getNextLocation(),这(我假设)对于助力自行车和非助力自行车都是相等的 其次,您正在将逻辑与呈现代码混合在一起 实际上,您应该将自行车作为某种模型来实现,并区分模型中的自行车速度和渲染中的自行车速度,将其排除在渲染代码之外 理想情况下,该模型将包含每辆自行车的速度向量(在滴答声计数时由加速度向量修改,与渲染周期无关),渲染所要做的就是绘制适当的线
因此,基本上将增强代码放入b.getNextLocation()而不是Draw(),并从绘图代码中删除条件语句。假设有两个自行车,A和b(不是增强)。让我们经历几个周期:
A -- wait GAME_SPEED
Redraw A
B -- wait GAME_SPEED
Redraw B
A -- wait GAME_SPEED
Redraw A
B -- wait GAME_SPEED
Redraw B
A的重画间隔时间=B的重画间隔时间=游戏速度*2
现在假设B是增压的:
A -- wait GAME_SPEED
Redraw A
B -- wait GAME_SPEED - 5
Redraw B
A -- wait GAME_SPEED
Redraw A
B -- wait GAME_SPEED - 5
Redraw B
B的重画间隔时间=A的重画间隔时间=游戏速度*2-5
这只是告诉你为什么你所观察到的事情会发生:每辆自行车都会等待每个人的延迟,而不仅仅是他们自己的延迟
解决这个问题的唯一方法是有一个“屏幕刷新”延迟,并通过改变对象移动的距离而不是时间延迟来控制速度。这种方法无法可靠地工作。不要控制延迟:它只是一个近似值,可以被其他因素控制并影响一切。控制每个时间增量的移动量(时间增量不是完全恒定的,一旦正确处理时间增量,就可以改变)。这种简单形式的“时间增量移动”在任何[好的]基础游戏教程中都有介绍。此外,更新逻辑应该与绘制逻辑分开:绘制只是世界上对象的视觉表现,在大多数情况下应该是独立的。