【问题标题】:Implementing Delta timing in my loop在我的循环中实现 Delta 计时
【发布时间】:2014-05-04 06:54:02
【问题描述】:

我想在我的 SFML 循环中实现增量计时,以补偿选择运行我的应用程序的其他计算机,现在我只有

float delta = .06 

放置在我的循环之前,但正如维基百科描述的增量时间:

这是通过每秒每帧调用一个计时器来完成的 现在和最后一次通话之间的时间,以毫秒为单位。[2]此后 结果数字(Delta Time)用于计算快多少 例如,游戏角色必须移动以弥补 首先引起的滞后峰值。[3]

这是我目前正在做的错误,我似乎无法将逻辑转换为语法:

bool running=true;                                      //set up bool to run SFML loop
    double lastTime = clock.getElapsedTime().asSeconds();
    sf::Clock clock;                                        //clock for delta and controls
    while( running )
    {
        clock.restart();
        double time= clock.getElapsedTime().asSeconds();
        double delta = time - lastTime; //not working... values are near 0.0001
        time = lastTime;
        //rest of loop

【问题讨论】:

标签: c++ sfml game-loop timedelta


【解决方案1】:

不应该是:

sf::Clock clock;
while( running )
{
    double delta =  clock.restart().asSeconds(); // asMilliseconds()
    //rest of loop
}

(我假设您不需要 time 和 last_time)

【讨论】:

    【解决方案2】:

    您的循环运行得如此之快,以至于以秒为单位的增量非常小。为什么不用毫秒来衡量呢?

    .asSeconds() 切换为.asMilliseconds()。查看 here 获取文档。

    【讨论】:

    • 我现在看到甚至维基百科的文章都指定了毫秒,哎呀!
    【解决方案3】:

    您的方法几乎是正确的。但是,如果您自己计算时差(减去之前的时间),则不能重置您的sf::Clock

    对于可变时间步长,您基本上可以使用 Dieter 的解决方案。不过,我建议做一个小小的修改:

    sf::Clock clock
    while (running) {
        // do event processing here
    
        const sf::Time delta = clock.restart();
    
        // do your updates here        
    
        sf::sleep(sf::microseconds(1));
    }
    

    我所做的不同之处在于两件事:

    • 我将delta 时间存储为sf::Time 对象。这并不是真正的重大变化。但是,它允许我稍后检索不同单位的差异(尽管检索秒或毫秒就可以了)。
    • 我等待的时间很短。根据循环的一次迭代期间经过的时间,这可能会产生显着差异。否则 - 在一台非常非常快的计算机上 - 你可能会得到一个 0 的delta。虽然这不太可能,只要你使用原始时间跟踪微秒,如果你只是评估毫秒(在这种情况下,您甚至可能想睡一整毫秒)。根据系统的计时器粒度/电源(节能)设置,与完全不睡觉相比,这可能会慢一点,但应该不会很明显(因为 SFML 也试图解决这个问题)。

    【讨论】:

      【解决方案4】:

      你想要的基本上是这样的:

      while(running)
      {
          sf::Time now = clock.getElapsedTime();
          deltaTime = now - lastTime;
          lastTime = now;
      }
      

      至于马里奥提到的sf::sleep,您应该只使用sf::RenderWindow::setFramerateLimit(unsigned int) 来根据需要限制fps,SFML 将负责让您的应用程序在每个循环中休眠正确的时间。

      【讨论】:

        猜你喜欢
        • 2014-08-05
        • 1970-01-01
        • 2014-02-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多