使用不同的Thread.sleep()持续时间来控制播放器的速度?

时间:2012-04-15 00:24:54

标签: c# .net multithreading drawing

如果“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());

}

2 个答案:

答案 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之间的时间。

这只是告诉你为什么你所观察到的事情:每辆自行车等待每个人的延迟,而不仅仅是他们自己。

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