C++ 在游戏循环中使用sleep()会使增量时间不稳定
我正在用sfml编写一个游戏循环。当我不让它休眠时,每次循环迭代所用的时间约为1ms。但当我加上睡眠(睡眠时间)时,dt突然升高。我在循环开始时重新启动dt,但它似乎增加了最后的睡眠时间。是什么原因造成的C++ 在游戏循环中使用sleep()会使增量时间不稳定,c++,sfml,game-loop,C++,Sfml,Game Loop,我正在用sfml编写一个游戏循环。当我不让它休眠时,每次循环迭代所用的时间约为1ms。但当我加上睡眠(睡眠时间)时,dt突然升高。我在循环开始时重新启动dt,但它似乎增加了最后的睡眠时间。是什么原因造成的 sf::Clock clock; float dt; sf::Time sleepTime = sf::milliseconds(0); while(m_Window.isOpen()) { sf::Time elapsed = clock.restart(); dt = e
sf::Clock clock;
float dt;
sf::Time sleepTime = sf::milliseconds(0);
while(m_Window.isOpen())
{
sf::Time elapsed = clock.restart();
dt = elapsed.asMilliseconds();
cout << "Elapsed: " << dt;
sf::Event event;
while(m_Window.pollEvent(event))
{
switch(event.type)
{
case sf::Event::Closed:
m_Window.close();
break;
}
}
sleepTime = sf::milliseconds(16 - dt);
float time = sleepTime.asMilliseconds();
cout << "\tSleep time: " << time << endl;
if(sleepTime >= sf::Time::Zero)
{
sf::sleep(sleepTime);
}
else
{
cout << "Shit." << endl;
}
sf::时钟;
浮动dt;
sf::Time sleepTime=sf::毫秒(0);
while(m_Window.isOpen())
{
sf::经过的时间=clock.restart();
dt=经过的时间。asmillseconds();
SFML中已经内置了您试图执行的操作–将游戏限制在特定的帧速率内。只需使用您想要的帧速率作为参数调用sf::Window::setFrameRateLimit()
,您就可以进行设置。还可以使用垂直同步(通过使用sf::Window::setVerticalSyncEnabled()
)限制帧数/更新,尽管这通常被认为是一个坏主意,因为如果目标机器不能以所需的帧率渲染(或在120或140Hz的高端屏幕上加速),游戏也会变慢
但是,您通常希望断开游戏更新与帧速率的连接,这样即使当前机器无法足够快地更新屏幕,游戏也不会减速
使用SFML的基本方法通常如下所示(这是从内存中获取的,因此可能包括bug或打字错误):
sf::Clock UpdateTime;//用于监视所经过时间的时钟
sf::Time passedTime;//累计游戏时间
const sf::Time frameTime(sf::毫秒(10));//每帧的预期时间;此处:10ms
while(window.isOpen()){
sf::事件;
while(window.pollEvent(事件)){
//事件处理
}
//首先加上经过的时间
passedTime+=UpdateLock.restart();
unsigned int numUpdates=0;//计算完成的更新
//只要经过足够的时间,就进行更新
//达到特定的最大值以避免出现问题,例如。
//主线程被阻塞或无法跟上
while(passedTime>=帧时间){
if(numUpdates++<10){
//在这里更新你的游戏吗
}
//减去我们“处理”的时间
passedTime-=帧时间;
}
window.clear();
//在这里画你的游戏
window.display();
}
numUpdates
的用法一开始可能不太清楚,但想象一下,在这种情况下,机器每秒几乎无法运行所需的100次更新。如果您落后20次更新(一些故障或其他情况)机器将永远无法正常追赶,导致严重口吃或游戏变得无反应。睡眠导致它。你为什么要睡觉?因为我想建立恒定的游戏速度。我使用:作为向导。我知道睡眠()不是非常精确。但我在循环开始时重新启动dt,为什么要将睡眠时间添加到dt中?睡眠不会建立任何类似于恒定游戏速度的东西。这就是分时操作系统的本质。我不清楚-你期望什么样的输出?你每次迭代都要轮询一次时钟,其中包括睡眠。为什么睡眠时间不应该包括在这个读数中吗?也许你的意思是在计算睡眠时间之前再次轮询时钟?@Glamhoth不要第二次重新启动计时器(在最后)。否则你就失去了绘制所有内容所花费的时间。
sf::Clock updateTimer; // Clock to monitor the time passed
sf::Time passedTime; // Accumulated game time
const sf::Time frameTime(sf::milliseconds(10)); // intended time per frame; here: 10ms
while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
// Event handling
}
// First add the time passed
passedTime += updateClock.restart();
unsigned int numUpdates = 0; // Count the updates done
// As long as enough time passed, do an update
// Up to a specific maximum to avoid problems, e.g.
// the main thread was blocked or can't catch up
while (passedTime >= frameTime) {
if (numUpdates++ < 10) {
// Do your game update here
}
// Subtract the time we've "handled"
passedTime -= frameTime;
}
window.clear();
// Draw your game here
window.display();
}