通过DeltaTime进行精灵序列控制 [英] Sprites sequence control through DeltaTime

查看:154
本文介绍了通过DeltaTime进行精灵序列控制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以前,在我的游戏主循环中,时间以60 FPS和相应的Delay进行延时管理。

Previously in my main loop of the game, the time was managed at 60 FPS and the respective Delay for the time delay.

Sprite序列的动画设置如下:

The Sprite sequence was animated as follows:

<pre>
if(++ciclos > 10){
   siguienteSprite++;
   ciclos = 0;
}
</pre>

鉴于我在DeltaTime中使用了平滑运动,因此我从主循环中消除了Delay;使动画的精灵周期更快,不仅如此,而且每个序列之间的时间也有所不同。

Given that I am using Smooth Motion with DeltaTime, therefore I have eliminated Delay from the Main Cycle; Making this the sprites cycles of the animation are faster, and not only this, but also the time between each sequence varies.

只有在这个问题的逻辑,事先谢谢。 :)

Someone could give me a hand, only with the logic of this problem, beforehand thank you. :)

推荐答案

延迟并不是一个好方法为此(因为它没有考虑主循环中其他内容花费的时间)。当您删除延迟后,速度会更大,并且变化更大,因为主循环时序中的其他内容更为重要,并且由于许多原因通常是非恒定的,例如:

delay in main loop is not really a good way for this (as it is not accounting for the time other stuff in your main loop takes). When you removed delay then the speed is bigger and varying more because the other stuff in your main loop timing is more significant and usually non constant for many reasons like:


  • 操作系统粒度

  • 与gfx卡/驱动程序同步

  • 非恒定处理时间

  • OS granularity
  • synchronization with gfx card/driver
  • non constant processing times

还有更多处理方法:


  1. 测量时间

<pre>
t1=get_actual_time();
while (t1-t0>=animation_T)
 {
 siguienteSprite++;
 t0+=animation_T;
 }
// t0=t1; // this is optional and change the timing properties a bit
</pre>

其中 t0 是一些持有最后测量的时间os精灵变化。 t1 是实际时间, animation_T 是动画更改之间的时间常数。要测量时间,您需要在Windows上使用 OS API,例如 PerformanceCounter 或在asm中使用 RDTSC 或您手边的任何其他但分辨率都足够小的计算机。

where t0 is some global variable holding "last" measured time os sprite change. t1 is actual time and animation_T is time constant between animation changes. To measure time you need to use OS api like PerformanceCounter on windows or RDTSC in asm or any other you got at hand but with small enough resolution.

操作系统计时器

只需间隔 animation_T ,即可在某个计时器中递增 siguienteSprite 。这很简单,但OS计时器不精确,通常约为1毫秒或更长,并且带有OS粒度(类似于 Sleep 精度)。

simply increment the siguienteSprite in some timer with animation_T interval. This is simple but OS timers are not precise and usually of around 1ms or more + OS granularity (similar to Sleep accuracy).

线程计时器

您可以为计时目的创建单个线程例如这样的东西:

you can create single thread for timing purposes for example something like this:

for (;!threads_stop;)
 {
 Delay(animation_T); // or Sleep()
 siguienteSprite++;
 }

不要忘记 siguienteSprite 必须为 volatile 并在渲染期间进行缓冲,以避免闪烁和/或访问冲突错误。这种方法更加精确(除非您拥有单核 CPU )。

Do not forget that siguienteSprite must be volatile and buffered during rendering to avoid flickering and or access violation errors. This approach is a bit more precise (unless you got single core CPU).

您也可以增加一些时间变量,并将其用作应用程序中具有所需任何分辨率的实际时间。但是请注意,如果 delay 没有将 CPU 控制权返回给 OS ,则此方法将利用您的 CPU 设置为 100%/ CPU_cores 。对此有一种补救措施,那就是用以下命令替换您的 delay

You cam also increment some time variable instead and use that as actual time in your app with any resolution you want. But beware if delay is not returning CPU control to OS then this approach will utilize your CPU to 100%/CPU_cores. There is remedy for this and that is replacing your delay with this:

Sleep(0.9*animation_T);
for (;;)
 {
 t1=get_actual_time();
 if (t1-t0>=animation_T)
  {
  siguienteSprite++;
  t0=t1;
  break;
  }


如果使用测量的时间,则应处理(t1< t0)的溢出,因为任何计数器都会在时间后溢出。例如,在 3.2 GHz CPU内核上使用 RDTSC 的32位部分将每 2溢出一次^ 32 / 3.2e9 = 1.342秒,所以这确实是可能的。如果我的内存运行良好,则Windows上的性能计数器通常在较旧的 OS 系统上运行在 3.5 MHz 附近,并且在 60-120附近运行MHz 较新(至少我上次检查),并且是64位的,因此溢出并不是什么大问题(除非您以24/7运行)。同样,如果使用 RDTSC ,则应将进程/线程关联性设置为单个 CPU 内核,以避免在多核 CPU 上出现时序问题。

If you are using measured time then you should handle overflows (t1<t0) because any counter will overflow after time. For example using 32bit part of RDTSC on 3.2 GHz CPU core will overflow every 2^32/3.2e9 = 1.342 sec so it is real possibility. If my memory serves well then Performance counters in Windows usually runs around 3.5 MHz on older OS systems and around 60-120 MHz on newer (at least last time I check) and are 64 bit so the overflows are not that big of a problem (unless you run 24/7). Also in case of RDTSC use you should set process/thread affinity to single CPU core to avoid timing problems on multi core CPUs.

这些年来,我在低水平上完成了基准测试和高分辨率高分辨率定时测试,因此这里很少涉及到我的 QA

I did my share of benchmarking and advanced high resolution timing at low level over the years so here few related QAs of mine:


使用rdtsc进行错误的时钟周期测量-操作系统粒度

测量缓存延迟-测量CPU频率

系统上的缓存大小估计?- PerformanceCounter 示例

有关使用CPU时钟测量时间的问题-PIT作为备用计时源


wrong clock cycle measurements with rdtsc - OS Granularity
Measuring Cache Latencies - measuring CPU frequency
Cache size estimation on your system? - PerformanceCounter example
Questions on Measuring Time Using the CPU Clock - PIT as alternative timing source

这篇关于通过DeltaTime进行精灵序列控制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆