精灵通过DeltaTime进行序列控制

时间:2017-01-29 03:58:44

标签: c++ algorithm sprite sdl-2 timedelta

以前在我的游戏主循环中,时间以60 FPS和延迟时间延迟管理。

Sprite序列的动画如下:

from app import db


class User(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    username = db.Column(db.String(35), index = True, unique = True)
    email = db.Column(db.String(255), index = True, unique = True)
    password = db.Column(db.String(255), index = False, unique = False)
    posts = db.relationship('Post', backref='author', lazy='dynamic')

    def __repr__(self):
        return '< User %r>' % (self.username)

class Post(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    body = db.Column(db.String(140))
    timestamp = db.Column(db.DateTime)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))

    def __repr__(self):
        return '<Post %r>' % (self.body)

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

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

1 个答案:

答案 0 :(得分:2)

主循环中的

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是一个全局变量持有&#34;最后&#34;测量时间os精灵变化。 t1是实际时间,animation_T是动画更改之间的时间常数。要测量时间,您需要在Windows上使用操作系统 api,例如PerformanceCounter,或者在asm中使用RDTSC,或者使用其他任何其他人,但分辨率足够小。

    < / LI>
  2. 操作系统计时器

    只需在siguienteSprite间隔的某个计时器中递增animation_T。这很简单,但OS定时器不精确,通常大约1ms或更多+ OS粒度(类似于Sleep精度)。

  3. 主题计时器

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

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

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

    您也可以增加一些时间变量,并将其用作应用中的实际时间,并使用您想要的任何分辨率。但请注意,如果delay未将 CPU 控制权返回操作系统,则此方法会将 CPU 用于100%/CPU_cores。对此有一些补救措施,即用{:1}替换你的delay

    Sleep(0.9*animation_T);
    for (;;)
     {
     t1=get_actual_time();
     if (t1-t0>=animation_T)
      {
      siguienteSprite++;
      t0=t1;
      break;
      }
    
  4. 如果您正在使用测量时间,那么您应该处理溢出(t1<t0),因为任何计数器都会在一段时间后溢出。例如,在3.2 GHz CPU核心上使用 RDTSC 的32位部分将每2^32/3.2e9 = 1.342 sec个溢出,因此这是真的可能。如果我的内存运行良好,那么Windows中的性能计数器通常在较旧的 OS 系统上运行3.5 MHz,在较新的60-120 MHz周围运行(至少在上次检查时)并且是64位所以溢出不是一个大问题(除非你全天候运行)。此外,在使用 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作为替代计时源