1全面的定时器与多个定时器,每个对象的定时器
我有一个关于良好实践的问题。我正在做一个简单的游戏,我正在搞一些精灵。1全面的定时器与多个定时器,每个对象的定时器
我有一个精灵类。在那个类中,有一个计时器每隔几毫秒运行一次。
现在,我有一个List<Creatures>
和“生物”的每个人,都有一个Sprite对象来运行动画。这意味着每个生物都有一个计时器来完成同样的事情。
我决定改变它,并且创建一个只在列表上迭代的计时器,并调用为每个“Creature”创建动画的函数。
什么是好习惯?
- 给每个“生物”自己的计时器。
- 在迭代列表的Form中创建一个“大”定时器,并调用每个对象创建动画的函数。
- 一种不同的方式
我有一个精灵类。在那个类中,有一个计时器每隔几毫秒运行一次。
不幸的是,它并没有在现实中。您受限于(非高性能)系统时钟的分辨率,该时钟在〜15 毫秒附近。所以,如果你喜欢,你可以设置1的间隔,但这不是你实际得到的。
回到主题,对于游戏,所有内容都应该在同一个时钟上运行。对于每个勾号,您将有一个循环来更新游戏的逻辑状态(位置和内容),然后显示(动画帧,屏幕上的blit等)。如果您在不同的定时器上使用它们,您将很可能遇到问题,因为在并行更新对象时协调对象的状态会变得非常困难。
还意识到您需要规范化更新速率以确保事情不会更新得太快或太慢(取决于您渲染帧需要多长时间)。您需要检查上次更新和新更新之间的差异,并采取相应措施。
如果它们以相同的间隔都运行,一个大的定时器肯定是要走的路。
即使它们运行在不同的时间间隔,一个大计时器(具有确定哪些子处理程序触发的逻辑)通常仍然是最好的。
某些库会在内部添加此逻辑,并且只从操作系统请求一个定时器。你还没有确切地说过你正在使用哪个计时器(.NET至少有四个),所以我建议你自己使用一个集中计时器。
最好的办法是实现一个游戏循环,记录自上次循环迭代以来已经过了多少时间,然后将经过的时间量传递给所有需要更新自身的实体。
例如,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;
}
}
基于经过的时间,你就可以找出动画帧在精灵渲染。
增加的好处是,通过查看这段时间,您可以计算出您当前正在运行的每秒多少帧,并基于此决定(跳过帧的渲染,降低渲染复杂度等) 。
即时通讯使用System.Windows.Forms.Timer – samy 2012-04-10 21:18:19
@samy:意识到此计时器在UI线程上运行'Tick'事件委托。 – 2012-04-10 21:19:18