我目前正在尝试在 SFML 中编写我的第一个游戏(也是我的第一个整体游戏),但我遇到了一个问题,即我每秒都会出现一次口吃。在这样的卡顿期间,帧时间比正常情况高 3 到 4 倍,只要我不运行非常高的 FPS(300+),这一点就非常明显。
没问题(至少atm),因为性能不是问题,但是:
这样做时,我的运动方法真的很糟糕,而且运动速度比它应该做的要慢得多。
我的移动方法:
void Player::Update(float frametime){
mMovementSpeedTimefactor = frametime * 60 / 1000.0f;
setMovementVector(sf::Vector2f( mMovementVector.x * mMovementSpeedTimefactor, mMovementVector.y *mMovementSpeedTimefactor));
validateMovement();
//std::cout << mTestClock->restart().asMilliseconds() << std::endl;
moveObject();
this->updateAnimation();
}
frametime 是以毫秒为单位的帧时间,我乘以 60,因为我的移动速度设置为像素/秒而不是每帧的值。
移动速度为 5,因此角色应该每秒移动 5 像素,无论我有什么 FPS(以及帧时间)。
但是:这给了我真正的跳跃运动,因为那些“口吃帧”会导致跳跃,并且在nto口吃帧上,玩家的移动速度比应有的要慢得多。
我的主循环非常简单,只是
while(mMainWindow->isOpen()){
HandleEvents();
Update();
Render();
}
在使用内置帧限制器(尝试编写自己的帧限制器,但只要我使用 sf:sleep 来调节 FPS,避免 CPU 核心在 100% 负载下运行)时,我会得到完全相同的结果)到 300 FPS。
所以是的,我可以将标准速度设置为 1 而不是 5,但是 setframeratelimit 不是很准确,所以我的移动速度发生了一些变化,我真的不喜欢。
有人知道我能做什么吗?也许我没有看到所有树木的森林(我实际上不知道你是否用英语说这个:P),但因为这是我的第一个游戏,我没有经验可以回顾。
最佳答案
类似问题:Movement Without Framerate Limit C++ SFML .
你真正需要的是固定的时间步长。 看看SFML游戏开发书source code 。这是 Application.cpp 中的有趣片段:
const sf::Time Game::TimePerFrame = sf::seconds(1.f/60.f);
[...]
sf::Clock clock;
sf::Time timeSinceLastUpdate = sf::Time::Zero;
while (mWindow.isOpen())
{
sf::Time elapsedTime = clock.restart();
timeSinceLastUpdate += elapsedTime;
while (timeSinceLastUpdate > TimePerFrame)
{
timeSinceLastUpdate -= TimePerFrame;
processEvents();
update(TimePerFrame);
}
updateStatistics(elapsedTime);
render();
}
编辑:如果这不是您真正想要的,请参阅 Laurent Gomila 本人在 SFML 论坛中链接的“Fix your timestep!”。
关于c++ - 如何调整游戏循环帧率?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18065004/