1全面的定时器与多个定时器,每个对象的定时器

1全面的定时器与多个定时器,每个对象的定时器

问题描述:

我有一个关于良好实践的问题。我正在做一个简单的游戏,我正在搞一些精灵。1全面的定时器与多个定时器,每个对象的定时器

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

现在,我有一个List<Creatures>和“生物”的每个人,都有一个Sprite对象来运行动画。这意味着每个生物都有一个计时器来完成同样的事情。

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

什么是好习惯?

  1. 给每个“生物”自己的计时器。
  2. 在迭代列表的Form中创建一个“大”定时器,并调用每个对象创建动画的函数。
  3. 一种不同的方式

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

不幸的是,它并没有在现实中。您受限于(非高性能)系统时钟的分辨率,该时钟在〜15  毫秒附近。所以,如果你喜欢,你可以设置1的间隔,但这不是你实际得到的。

回到主题,对于游戏,所有内容都应该在同一个时钟上运行。对于每个勾号,您将有一个循环来更新游戏的逻辑状态(位置和内容),然后显示(动画帧,屏幕上的blit等)。如果您在不同的定时器上使用它们,您将很可能遇到问题,因为在并行更新对象时协调对象的状态会变得非常困难。

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

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

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

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

+0

即时通讯使用System.Windows.Forms.Timer – samy 2012-04-10 21:18:19

+0

@samy:意识到此计时器在UI线程上运行'Tick'事件委托。 – 2012-04-10 21:19:18

最好的办法是实现一个游戏循环,记录自上次循环迭代以来已经过了多少时间,然后将经过的时间量传递给所有需要更新自身的实体。

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

这些事件的

每个传递FrameEventArgs类型的参数,它具有时间的一个属性:

/// <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; 
    } 
} 

基于经过的时间,你就可以找出动画帧在精灵渲染。

增加的好处是,通过查看这段时间,您可以计算出您当前正在运行的每秒多少帧,并基于此决定(跳过帧的渲染,降低渲染复杂度等) 。