我正在尝试使用C ++ 11线程为我的小游戏实现更新线程。我已经“尽可能快地”更新周期,但我想限制它说,每秒60次。如何剩下剩余时间?
Core::Core()
{
std::thread updateThread(update); // Start update thread
}
void Core::update()
{
// TODO Get start time
// Here happens the actual update stuff
// TODO Get end time
// double duration = ...; // Get the duration
// Sleep if necessary
if(duration < 1.0 / 60.0)
{
_sleep(1.0 / 60.0 - duration);
}
}
答案 0 :(得分:11)
这是Pete的正确答案(我已经投了票)但是有一些代码用来表示它比其他答案更容易完成:
// desired frame rate
typedef std::chrono::duration<int, std::ratio<1, 60>> frame_duration;
void Core::update()
{
// Get start time
auto start_time = std::chrono::steady_clock::now();
// Get end time
auto end_time = start_time + frame_duration(1);
// Here happens the actual update stuff
// Sleep if necessary
std::this_thread::sleep_until(end_time);
}
只要您使用<chrono>
,并且您发现自己正在手动转换单元,就可以立即或在将来的维护中为自己打开错误。让<chrono>
为您完成转化。
答案 1 :(得分:5)
如果您使用的是C ++ 11线程,则不限于_sleep
函数所做的任何事情。 C ++ 11线程具有sleep_for
,其持续时间(即,休眠10秒)和sleep_until
,其花费一个时间点(即,睡到下周四)。对于必须以固定间隔唤醒的线程,sleep_until
是可行的方法。睡到下一个叫醒时间。
答案 2 :(得分:4)
查看chrono标题中提供的功能和时钟。
例如:
using double_milliseconds = std::chrono::duration<double, std::chrono::milliseconds::period>;
auto t0 = std::chrono::high_resolution_clock::now();
/* do work here */
auto t1 = std::chrono::high_resolution_clock::now();
auto elapsed = std::chrono::duration_cast<double_milliseconds>(t1 - t0).count();
答案 3 :(得分:1)
限制帧速率的最简单方法是跟踪整个更新功能需要多长时间。之后你需要休息剩下的时间:
在此示例中,我使用timeGetTime来测量时间,但您可以使用任何其他具有高精度的函数
void Core::Update()
{
unsigned int start_time = timeGetTime();
ActualUpdate();
unsigned int end_time = timeGetTime();
unsigned int frame_time = end_time - start_time;
const unsigned int miliseconds_per_frame = 1000 / 60;
if(frame_time < miliseconds_per_frame)
{
Sleep(miliseconds_per_frame - frame_time);
}
}