C++ 如何调整游戏循环帧速率?
我现在正试图用SFML编程我的第一个游戏(和我的第一个整体),但我遇到了一个问题,我大约每秒会口吃一次。在这种口吃的情况下,帧时间比正常值高3到4倍,这是非常明显的,只要我不运行非常高的FPS(300+) 没有问题(至少atm),因为性能不是问题,但: 当我这样做的时候,我的移动方式真的很奇怪,而且移动速度比它应该做的要慢 我的移动方式:C++ 如何调整游戏循环帧速率?,c++,sfml,frame-rate,C++,Sfml,Frame Rate,我现在正试图用SFML编程我的第一个游戏(和我的第一个整体),但我遇到了一个问题,我大约每秒会口吃一次。在这种口吃的情况下,帧时间比正常值高3到4倍,这是非常明显的,只要我不运行非常高的FPS(300+) 没有问题(至少atm),因为性能不是问题,但: 当我这样做的时候,我的移动方式真的很奇怪,而且移动速度比它应该做的要慢 我的移动方式: void Player::Update(float frametime){ mMovementSpeedTimefactor = frametime
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();
}
在使用inbuild framelimiter时(尝试编写我自己的,但我得到了非常相同的结果,只要我使用sf:sleep来调节FPS,以避免cpu核心在100%负载下运行),将其设置为300 FPS
所以是的,我可以把我的标准速度设置为1而不是5,但是
setframeratelimit不是很精确,所以我得到了一些移动速度的变化,我真的不喜欢
谁有主意,我能做的最好?也许我没有看到森林里所有的树(我真的不知道你是否用英语说:P),但由于这是我的第一场比赛,我没有任何经验可以回顾 当
frametime
非常高或非常低时,由于浮点精度问题,您的计算可能无法正常工作。我建议将标准速度设置为,500
和mMovementSpeedTimeFactor
设置为frametime*60/10.0f
,并检查问题是否仍然存在。类似问题:
你真正需要的是固定的时间步长。
看看SFML游戏开发手册。以下是有趣的片段:
编辑:如果这不是您真正想要的,请参阅Laurent Gomila本人在SFML论坛中链接的“” 非常感谢,我会试试的。嗯,没用。我想我必须为“帧时间”设置一个最大值,否则我将始终获得这些跳跃它仍然比简单地将速度设置为1.0慢得多,即使它应该得到相同的值。。。嗯,现在我想我一直在使用内部帧限制器,并将我的速度设置为“应该”帧速率。我想我总是可以改变的,但我真的很沮丧。但不管怎样,谢谢你的建议:)试着偶尔写
mMovementSpeedTimeFactor
到控制台,检查它是否接近0来确认/取消确认我的原始想法。哦,我刚想到创建一个小日志,这真的很奇怪:我想你在FP精度或某种方面是对的。。。正如我所见,在简单计算时无法获得这些值:setMovementVector(sf::Vector2f(mMovementVector.x*mMovementSpeedTimefactor,mMovementVector.y*mMovementSpeedTimefactor))代码>“正常”值在这些fps应该是0.6到1.2为给定的帧时间…我爱你!!!!!!工作,谢谢,我想如果你没有要求的价值观,我永远不会记录我需要的一切。很抱歉没有看到这个较早(因为我没有时间为我的游戏atm我没有检查),但这不会导致100%的核心负载?你为什么不想采取所有的果汁为当前运行的游戏应用程序?还是你在做一个被动的游戏?(热座椅,回合制)还是一款电池寿命非常重要的手机游戏?但正如我所看到的,在您提供的示例中,您已经使用了100%的CPU。是否使用100%的CPU本身就是一个完全不同的问题。我在回答中添加了一个链接到这篇文章。
while(mMainWindow->isOpen()){
HandleEvents();
Update();
Render();
}
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();
}