C++ 如何在Box2D和SFML中设置固定的绘图速度和世界步长?

C++ 如何在Box2D和SFML中设置固定的绘图速度和世界步长?,c++,box2d,sfml,game-development,C++,Box2d,Sfml,Game Development,有一个简单的项目,Box2D从事物理,SFML绘图。在不同的机器上,具有不同性能的程序速度各不相同。如何设置固定速度?因此,在一台功能强大、性能一般和性能较差的计算机上,程序的速度(物体的运动)是相同的吗? 我们需要让Box2D在不同的计算机上以相同的速度工作。 它还提供坐标,SFML在给定坐标处绘制一个正方形。如何解决这个问题?恒定帧速率是您需要的。这是一个众所周知的问题 正如您所说,不同的机器将具有不同的处理器速度。这可能需要一台硬件处理更好的计算机,使游戏每秒循环更多次 如果您想设置固定的

有一个简单的项目,Box2D从事物理,SFML绘图。在不同的机器上,具有不同性能的程序速度各不相同。如何设置固定速度?因此,在一台功能强大、性能一般和性能较差的计算机上,程序的速度(物体的运动)是相同的吗?
我们需要让Box2D在不同的计算机上以相同的速度工作。
它还提供坐标,SFML在给定坐标处绘制一个正方形。如何解决这个问题?

恒定帧速率是您需要的。这是一个众所周知的问题

正如您所说,不同的机器将具有不同的处理器速度。这可能需要一台硬件处理更好的计算机,使游戏每秒循环更多次

如果您想设置固定的帧速率,比如说60 FPS,那么您所要做的就是(如上所述)限制您的更新每1/60秒执行一次更新

这是一个常见的实现:

const sf::Time TimePerFrame = sf::seconds(1.f / 60.f);    // 60 FPS

void run(){
        sf::Clock clk;
        sf::Time timeSinceLastUpdate = sf::Time::Zero;
        while (_window.isOpen())
        {

            sf::Time dt = clk.restart();
            timeSinceLastUpdate += dt;
            while (timeSinceLastUpdate > TimePerFrame)
            {
                timeSinceLastUpdate -= TimePerFrame;

                processInput();
                update(TimePerFrame);
            }
            render();
        }
    }
}
这样,如果一台机器运行得更快,你只需要每1/60秒更新一次你的世界状态


TL;博士 当您的程序启动时,
TimesInclastUpdate
获取值
0
,您在
期间检查
,并获取自创建(或重新启动
clk
以来经过的时间,假设数字t1小于1/60秒。程序将其添加到
timeSinceLastUpdate
,并在创建场景时绘制场景(游戏的初始状态)

的第二个循环当
时,您再次获得经过的时间(自上次循环以来经过的时间,因为您重新启动了时钟)。这次我们叫t2。同样,这个数字小于1/60秒,但是当您将它添加到
timeSinceLastUpdate
时,两者加起来都大于1/60(因此
timeSinceLastUpdate=t1+t2>TimePerFrame
)。这一次,您将进入第二个循环,并更新您的世界,就像1/60秒已经过去一样。从
timeSinceLastUpdate
中减去这1/60秒,然后再次检查。如果剩余时间超过1/60秒,您将再次更新,直到您保持最新状态

如果你仔细观察,你只会调用
update(TimePerFrame)
,所以你总是会以1/60秒的时间段来更新你的世界


从。第1章:让游戏成功

固定时间步长 到目前为止,我们提出的解决方案对许多情况都是足够的。但这并不是一个完美的解决方案[…],因为每个帧都是唯一的,并且不能保证增量时间保持不变 一样。考虑到帧有时需要三倍的平均值。 增量时间。例如,这可能导致游戏逻辑中的严重错误 例如,当一名球员移动三倍的距离并传球时 穿过一堵他通常会碰到的墙。这就是物理学的原因 引擎期望增量时间是固定的

下图描述了我们所指的问题:

我们现在要做的是使用一种叫做固定时间步长的技术。我们 编写代码,保证在任何情况下,我们总是 无论发生什么情况,更新函数的增量时间都相同。如果 你会发现这听起来很难,和你想的没什么大区别 我们已经有了。我们只需要在代码中做一些簿记就可以了 自从上次调用
update()
函数以来,已经过去了多少时间

代码与上面的代码类似,内部带有while(timeSinceLastUpdate>TimePerFrame)

这种变化的实际效果是我们积累了多少时间 已在变量
TimesInclastUpdate
中运行。当我们过马路的时候 一帧所需的数量,我们减去该帧所需的长度 帧(即
TimePerFrame
),并更新游戏。我们这样做直到 我们再次低于要求的金额。这就解决了这个问题 可变增量时间,因为我们保证相同数量的 帧始终处于运行状态。在您可以下载的应用程序中,逻辑 帧速率将设置为每秒60帧
TimePerFrame
常数等于
sf::秒(1.f/60.f)


你必须让它不要工作得那么快。例如,每20毫秒只运行一次物理。@ÖöTiib,如何运行?你能通过Sleep()延迟世界的脚步吗?例如,std::this\u thread::Sleep\u直到(你想要它醒来的时间);Delta time或
dt
是一个常见的定义(我认为它来自数学和物理),可以看作是计算机更新世界/游戏/场景所需的最短时间,这对我很有帮助。但是物体运动的速度有什么慢呢?如何提高呢?只增加每秒的帧数?不,物体的速度应该是它们固有的。您有一个每秒移动600像素的框,如果您每1/60秒更新一次该框,则每次更新将移动10像素。如果你想让它移动得更快,请在内部提高它的速度。谢谢。祝你好运