C#游戏开发定时器

时间:2011-02-26 14:38:27

标签: c# .net timer

我想找出在游戏中创建基于时间的事件的最佳方式。 让我们谈谈德州扑克的例子。服务器可以处理数千个表,在每个表中我们都有定时器:转动计时器,保持座位计时器等等。

为此目的实现计时器的最佳方法是什么?

System.Timers.Timer类是否可以处理这个问题,或者创建一个带有排序时间队列的单独线程更合理(例如,一个升序排序列表,其中int值代表以ms为单位的时间)?

提前致谢, 的Valentin

3 个答案:

答案 0 :(得分:2)

我建议使用System.Timers.TimerSystem.Threading.Timer。您使用排序队列的想法正是System.Threading.Timer的实现方式,因此您只是浪费时间并增加不必要的开销。 System.Timers.TimerSystem.Threading.Timer的包装。

我不建议使用当前时间(即DateTime.Now或类似的)来提供超时,因为时钟可能会以不可预测的方式在不可预测的时间发生变化。

如果您希望以“当前时间”为基础,则在程序开头添加Stopwatch,并使用Elapsed属性作为游戏中的“当前时间”。所以从当前时间开始的五秒钟时间是:

var FiveSecondsFromNow = GameTimer.Elapsed + TimeSpan.FromSeconds(5);

评论中提出的问题是我是否会建议使用多个带有Elapsed事件的计时器,或者按时间顺序维护并定期检查的动作列表(即在计时器或主游戏循环中)。

我的立即回应是为每个需要发生的事件使用单独的计时器对象。这样做可以在多个核心可用时利用它们(并发事件可以同时发生),并且可以防止我必须维护该待处理操作列表。我知道定时器队列实现可以毫无困难地处理数千个单独的定时器,并且几乎可以肯定它们的定时器队列的实现将比我的更有效。

使用计时器可以简化代码,除非您遇到多线程问题。我一切都很简单。如果我遇到计时器的性能问题,我只会去手动维护的待处理操作列表。而且我非常肯定在我努力消除它们之前,定时器是罪魁祸首。

答案 1 :(得分:1)

我经常发现在最好的方法中不使用计时器。只需存储时间戳,当您进行处理时,请检查当前时间与存储时间戳的差异。

当其他简单的解决方案可用时,尽量减少使用线程。

您应该能够经常“处理”所有表以处理所有逻辑。除非我们说的是非常大的数字,否则这应该不是问题。

除非你的游戏中有一些非常重的逻辑需要大量的处理,很可能不是德州扑克,你不应该使用线程,它们只会使事情复杂化。当完全有可能在一次简短的更新中更新整个游戏状态时,为什么还要运行'同步'?

答案 2 :(得分:0)

我会保留一个已排序的队列,但会将System.Timers.Timer安排到队列中第一个事件的时间。当事件触发时,我从队列中一次选择一个元素,处理元素,在下一个峰值处查看时间是否已经过去。如果时间已过,请处理该事件,否则为剩余时间安排计时器。

当新事件到达时,您将它们插入已排序的队列中。如果它们恰好是队列中的第一个,请重置计时器并以新的第一个元素的间隔重新启动它。

这一切都假设您需要触发某些事情。如果你只是想知道有人询问是否有新事件,你不需要定时器,也不需要额外的线程来处理队列。当有人问起时,只需检查你的事件队列。