c++ - 通过 DeltaTime 控制 Sprite 序列

标签 c++ algorithm sprite sdl-2 timedelta

之前在我的游戏主循环中,时间被管理在 60 FPS 和相应的 Delay 时间延迟。

Sprite 序列动画如下:

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

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

有人可以帮我一把,只有这个问题的逻辑,先谢谢你。 :)

最佳答案

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

  • 操作系统粒度
  • 与 gfx 卡/驱动同步
  • 处理时间不固定

有更多的方法来处理这个问题:

  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 Sprite 变化的全局变量。 t1是实际时间,animation_T是动画变化之间的时间常数。要测量时间,您需要使用 OS api,如 PerformanceCounter在 Windows 或 RDTSC在 asm 或你手边的任何其他语言中,但分辨率足够小。

  2. 操作系统计时器

    简单地增加 siguienteSprite在一些带有 animation_T 的计时器中间隔。这很简单,但操作系统计时器并不精确,通常约为 1 毫秒或更多 + 操作系统粒度(类似于 Sleep 精度)。

  3. 线程定时器

    您可以出于计时目的创建单线程,例如:

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

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

    您还可以增加一些时间变量,并将其用作您应用中的实际时间,并具有您想要的任何分辨率。但要注意如果 delay没有将 CPU 控制权返回给 OS 那么这种方法将利用您的 CPU100%/CPU_cores .对此有补救措施,那就是更换您的 delay有了这个:

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

如果您使用的是测量时间,那么您应该处理溢出 (t1<t0)因为任何计数器都会在时间过后溢出。例如,在 3.2 GHz 上使用 RDTSC 的 32 位部分CPU 核心 每隔2^32/3.2e9 = 1.342 sec 就会溢出所以这是真正的可能性。如果我没记错的话,Windows 中的性能计数器通常运行在 3.5 MHz 左右。在较旧的 OS 系统和 60-120 MHz 附近在较新的(至少我上次检查时)并且是 64 位的,所以溢出不是什么大问题(除非你运行 24/7)。此外,在使用 RDTSC 的情况下,您应该将进程/线程关联设置为单个 CPU 核心,以避免在多核 CPU 上出现计时问题。

多年来,我在低水平上参与了基准测试和高级高分辨率计时,因此这里有一些相关的QA我的:


wrong clock cycle measurements with rdtsc - 操作系统粒度
Measuring Cache Latencies - 测量 CPU 频率
Cache size estimation on your system? - PerformanceCounter例子
Questions on Measuring Time Using the CPU Clock - PIT 作为替代定时源

关于c++ - 通过 DeltaTime 控制 Sprite 序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41917471/

相关文章:

c - Sprite Packing C 应用程序中的 Sprite 对齐

c++ - 在我的主窗体之外使用 QtScript

c++ - 来自另一个类的对象的类 vector

c++ - 依赖循环

c - 从数组中获取最大排序子数组的算法

java - 使用 java 8 的设计模式建议/实现

android - 获取二值图像中非几何线的坐标

CSS 可以用 Sprite 图像的 1px 区域填充元素的背景吗?

android - iOS和Android通用随机数生成器

ios - 如何找到两个 Sprite 之间接触点的法向量