在循环中实现Delta时序

时间:2014-05-04 06:54:02

标签: c++ sfml game-loop timedelta

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

float delta = .06 

放在我的循环之前,但是当维基百科描述delta时间时:

  

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

以下是我正在做的 WRONG 目前,我似乎无法将逻辑转换为语法:

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

4 个答案:

答案 0 :(得分:2)

不应该是:

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

(我假设你不需要时间和last_time)

答案 1 :(得分:1)

您的循环运行速度非常快,以秒为单位的增量非常小。为什么不用毫秒来衡量呢?

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

答案 2 :(得分:1)

你的方法几乎是正确的。但是,如果您自己计算时差(减去上一次),则不得重置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个对象。这不是真正的重大变化。但是,它允许我稍后检索不同单位的差异(只需检索秒或毫秒即可)。
  • 我等了很短的时间。这可以基于在循环的一次迭代期间经过的时间产生显着差异。否则 - 在一台非常非常快的计算机上 - 你可能最终得到delta为0.虽然只要你使用原始时间跟踪微秒这是不太可能的,但如果你使用原始时间跟踪微秒,这可能是个问题。你只评估毫秒(在这种情况下你甚至可能想睡一整秒)。根据系统的计时器粒度/功率(保存)设置,与完全不睡觉相比,这可能会慢一点,但它不应该引人注目(因为SFML也试图解决这个问题,因为孔)。

答案 3 :(得分:0)

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

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

对于Mario提到的sf::sleep,您应该只使用sf::RenderWindow::setFramerateLimit(unsigned int)来限制fps,SFML将负责让您的应用程序在正确的时间内保持睡眠状态每个循环。