1综合计时器与多个计时器,每个对象的计时器

时间:2012-04-10 21:13:18

标签: c# winforms timer

我有一个关于良好做法的问题。我正在做一个简单的游戏,我正在搞乱一些精灵。

我有一个精灵类。在该类中,有一个每隔几毫秒运行一次的计时器。

现在,我有一个List<Creatures>和“生物”的每个人,都有一个Sprite对象来运行动画。所以这意味着每个生物都有一个同样的东西。

我决定更改它,并制作一个只在列表上迭代的计时器,并调用为每个“Creature”创建动画的函数。

什么是好习惯?

  1. 为每个“生物”提供自己的计时器。
  2. 在表单中创建一个“大”计时器,迭代列表,并从每个对象调用正在创建动画的函数。
  3. 另一种方式

3 个答案:

答案 0 :(得分:5)

如果它们都以相同的间隔运行,那么一个大计时器肯定是要走的路。

即使它们以不同的间隔运行,一个大的计时器(用逻辑确定哪些子处理程序触发)通常仍然是最好的。

某些库将在内部添加此逻辑,并且仅从OS请求单个计时器。你还没有确切地说你正在使用哪个计时器(.NET至少有四个),所以我建议你自己使用一个集中计时器。

答案 1 :(得分:5)

  

我有一个精灵类。在该类中,有一个每隔几毫秒运行一次的计时器。

不幸的是,它实际上并不存在。您受到(非高性能)系统时钟的分辨率的限制,该时钟约为15 ms。因此,如果您愿意,可以将间隔设置为1,但这不是您实际获得的间隔。

回到主题,对于游戏,一切都应该在同一个时钟上运行。对于每个刻度,你将有一个循环,它更新游戏的逻辑状态(位置和诸如此类),然后是显示(动画帧,blit到屏幕等)。如果你将它们放在不同的计时器上,你可能会遇到问题,因为当它们并行更新时协调对象的状态变得非常困难。

还要意识到您需要规范化更新速率,以确保事情不会更快或太慢(取决于渲染帧所需的时间)。您需要检查上次更新和新更新之间的差异并采取相应措施。

答案 2 :(得分:1)

你最好的选择是实现一个游戏循环,它跟踪自上次循环迭代以来经过了多长时间,然后将经过的时间量传递给需要自我更新的所有实体。 / p>

例如,OpenTk实现了每次通过游戏循环时发生的several events(例如OnUpdateFrame,OnRenderFrame)。

每个事件都传递一个FrameEventArgs类型的参数,该参数具有单个属性Time:

/// <summary>
/// Gets a <see cref="System.Double"/> that indicates how many seconds of time elapsed since the previous event.
/// </summary>
public double Time 
{
    get { return elapsed; }
    internal set
    {
        if (value <= 0)
            throw new ArgumentOutOfRangeException();
        elapsed = value;
    }
}

根据经过的时间,您可以找出要在精灵中渲染的动画帧。

额外的优势在于,通过查看此时间过去,您可以计算出当前运行的每秒帧数并根据它做出决策(跳过帧的渲染,降低渲染复杂性等)。