我有一个游戏 Bullet Physics作为物理引擎,该游戏是在线多人游戏,所以我想试试 Source Engine approach处理网络上的物理同步。所以在客户端我使用 GLFW所以默认情况下 fps 限制在那里工作。 (至少我认为这是因为 GLFW)。但是在服务器端没有图形库,所以我需要“锁定”模拟世界并将物理引擎步进到每秒 60 个“滴答”的循环。
这是将循环锁定为每秒运行 60 次的正确方法吗? (又名 60“fps”)。
void World::Run()
{
m_IsRunning = true;
long limit = (1 / 60.0f) * 1000;
long previous = milliseconds_now();
while (m_IsRunning)
{
long start = milliseconds_now();
long deltaTime = start - previous;
previous = start;
std::cout << m_Objects[0]->GetObjectState().position[1] << std::endl;
m_DynamicsWorld->stepSimulation(1 / 60.0f, 10);
long end = milliseconds_now();
long dt = end - start;
if (dt < limit)
{
std::this_thread::sleep_for(std::chrono::milliseconds(limit - dt));
}
}
}
可以使用 std::thread 来完成这个任务吗?
这种方式是否足够高效?
物理模拟会每秒步进 60 次吗?
附言
milliseconds_now()
看起来像这样:
long long milliseconds_now()
{
static LARGE_INTEGER s_frequency;
static BOOL s_use_qpc = QueryPerformanceFrequency(&s_frequency);
if (s_use_qpc) {
LARGE_INTEGER now;
QueryPerformanceCounter(&now);
return (1000LL * now.QuadPart) / s_frequency.QuadPart;
}
else {
return GetTickCount();
}
}
最佳答案
如果要将渲染限制在最大 FPS 60,非常简单:
每一帧,只是检查游戏是否运行得太快,如果是就等待,例如:
while ( timeLimitedLoop )
{
float framedelta = ( timeNow - timeLast )
timeLast = timeNow;
for each ( ObjectOrCalculation myObjectOrCalculation in allItemsToProcess )
{
myObjectOrCalculation->processThisIn60thOfSecond(framedelta);
}
render(); // if display needed
}
请注意,如果启用了垂直同步,渲染将被限制为垂直刷新频率,可能是 50 或 60 Hz。
但是,如果您希望逻辑锁定在 60fps,那就另当别论了:您必须隔离显示和逻辑代码,使逻辑以最大 60fps 运行,并修改代码,以便你可以有一个固定的时间间隔循环和一个可变的时间间隔循环(如上所述)。值得关注的好来源是“固定时间步长”和“可变时间步长”(Link 1 Link 2 和旧的可信赖的 Google 搜索)。
请注意您的代码: 因为您在 1/60 秒的整个持续时间内都在使用 sleep - 已经过去的时间,您很容易错过正确的时间,请将 sleep 更改为循环运行,如下所示:
代替
if (dt < limit)
{
std::this_thread::sleep_for(std::chrono::milliseconds(limit - dt));
}
改为
while(dt < limit)
{
std::this_thread::sleep_for(std::chrono::milliseconds(limit - (dt/10.0)));
// or 100.0 or whatever fine-grained step you desire
}
希望这对您有所帮助,但如果您需要更多信息,请告诉我:)
关于c++ - 这是将循环锁定为每秒 60 个循环的好方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22613245/