2

如果“自行车”列表中的一个对象包含布尔值 isBoosting,我正在尝试更快地绘制线()。当列表包含两辆自行车时,结果是两辆自行车似乎都在加速,而其中只有一辆自行车“正在加速”。有谁知道为什么?如果对象不包含 isBoosting 的 true 值,线程不应该“移动”更慢吗?

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());

}
4

2 回答 2

5

这有几个问题。

首先,因为它是一个单线程,所以当您休眠一段时间时,线程会被取消调度 - 不会进行渲染(在您的情况下,这意味着既不会绘制“增压”自行车也不会绘制其他自行车)。实际绘制的线总是从 b.location 到 b.getNextLocation(),这对于增压和未增压的自行车(我假设)是相等的。

其次,您将逻辑与渲染代码混合在一起......

确实,您应该将自行车实现为某种模型,并区分模型中的自行车速度和渲染,将其排除在渲染代码之外。

理想情况下,该模型将包含每辆自行车的速度矢量(由一个滴答计数的加速度矢量修改,与渲染周期无关),并且所有渲染都会绘制适当的线。

因此,基本上将您的提升代码放入 b.getNextLocation() 而不是 Draw(),并从绘图代码中删除条件语句。

于 2012-04-15T00:35:30.243 回答
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。

这只是向您展示了您所观察到的事情发生的原因:每辆自行车都在等待每个人的延迟,而不仅仅是他们自己的。

解决这个问题的唯一方法是有一个“屏幕刷新”延迟,并通过更改对象移动的距离而不是时间延迟来控制速度。

于 2012-04-15T00:39:29.727 回答