如果“bikes”列表中的一个对象包含布尔值isBoosting,我试图更快地绘制Line()。当列表包含两辆自行车时,结果是当两辆自行车中只有一辆“isBoosting”时,两辆自行车似乎都加速了。有没有人知道为什么?如果对象不包含isBoosting的值,则线程不应该“移动”更慢吗?
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());
}
答案 0 :(得分:5)
这有几个问题。
首先,因为它是一个单独的线程,当你睡了一段时间线程被取消预定 - 不会进行渲染(在你的情况下,这意味着既不会“提升”自行车也不会绘制其他自行车)。实际绘制的线总是从b.location到b.getNextLocation(),对于增强和未增强的自行车,它们(我假设)是相等的。
其次,你将逻辑与渲染代码混合在一起......
你真的应该将自行车作为某种模型来实现,并区分模型中的自行车速度和渲染,从而将其保持在渲染代码之外。
理想情况下,该模型将包含每个自行车的速度矢量(由刻度线上的加速度矢量修改,与渲染周期无关),并且所有渲染都将绘制相应的线。
所以基本上将你的提升代码放入b.getNextLocation()而不是Draw()中,并从绘图代码中删除条件语句。
答案 1 :(得分:0)
假设有两辆自行车,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 = GAME_SPEED * 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 = GAME_SPEED * 2 - 5之间的时间。
这只是告诉你为什么你所观察到的事情:每辆自行车等待每个人的延迟,而不仅仅是他们自己。
解决这个问题的唯一方法就是有一个“屏幕刷新”延迟,并通过改变物体移动的距离来控制速度,而不是时间延迟。