我正在研究太空飞船射击游戏。在游戏中有一些缓慢移动的导弹,我在不同的任务上运行。
Task t4 = new Task(() => fireShipCannons());
他们做得不多;只需在屏幕上移动一个小位图。通常它是一个包含30次迭代的for循环。问题是时间关闭,一些任务似乎优先于其他任务。我还有许多人要注意,为了控制导弹的速度,我正在使用Thread.Sleep(100)。由于这种减速,该方法将运行几秒钟。
我正在使用c#,。net,Windows Form Application
我花了好几个小时思考如何改写这个,我认为它措辞正确。我遇到的问题很广泛;是的,这个问题可能有点宽泛。我得到了一个很好的答案!这不表示问题被正确提出了吗?
答案 0 :(得分:2)
由于您已经在使用Task
(好),因此您可以简单地使用async Tasks并使用await Task.Delay(time)
。
async Task fireShipCannons(CancellationToken ct)
{
for (int i = 0; i < distance; i++) {
await Task.Delay(100, ct);
drawBitmap(i);
}
}
这样你就不会为每个子弹占用1个线程。很可能你的任务目前很慢,因为你达到了你的线程池的限制,所以这应该快得多。但另外,您还应该检查Task.Delay
是否超过了您建议的100毫秒。如果确实如此,则将子弹画2个点而不是1个,并相应地重新安排。
async Task fireShipCannons(CancellationToken ct)
{
var start = DateTime.Now;
while (bullet.isOnscreen) {
drawBitmap(bullet);
var sleep = (start.Add(TimeSpan.FromMilliseconds(100.0)) - DateTime.Now);
if (sleep.Milliseconds > 0) {
Task.Delay(sleep, ct);
}
iter = (int)((DateTime.Now - start).TotalMilliseconds / 100 + 0.5);
bullet.moveSteps(iter); // move it iter steps.
var start = start.AddMilliseconds(100 * it);
}
}
最后,最好不要用每个子弹的新调用来敲击你的绘制函数,而是将所有项目符号/更改组合到一个渲染函数中,该函数计算所有更改并一次性将它们发送出去。但这取决于你的绘制函数本身是如何实现的。
答案 1 :(得分:-1)
这取决于机器及其可支持的线程数。另一方面,我不认为使用Thread.Sleep这是一个很好的做法,为什么不改变对象每毫秒移动的距离(以像素为单位)?