【问题标题】:How to adjust a game loop frame rate?如何调整游戏循环帧率?
【发布时间】:2013-08-06 13:32:08
【问题描述】:

我目前正在尝试用 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,因为我的移动速度设置为像素/秒而不是每帧的值。

movementspeed 是 5,所以角色应该每秒移动 5 px,不管我有什么 FPS(以及帧时间)。

但是:这给了我非常跳跃的动作,因为那些“stutterframes”会导致跳跃,并且在 nto stuttering 帧上,palyer 的移动速度比它应该的要慢得多。

我的主循环真的很简单,就

while(mMainWindow->isOpen()){

        HandleEvents();
        Update();
        Render();
    }

在使用内置帧限制器时(尝试编写我自己的,但我得到了完全相同的结果,只要我使用 sf:sleep 来调节 FPS 以使 cpu 核心不以 100% 负载运行)到 300 FPS。

所以是的,我可以将标准速度设置为 1 而不是 5,但是 setframeratelimit 不是很准确,所以我的移动速度有一些变化,我真的不喜欢。

任何人都有一个想法,我能做什么最好?也许我没有看到所有树木的森林(我实际上不知道你是否用英语说:P)但由于这是我的第一场比赛,我没有经验可以回顾。

【问题讨论】:

    标签: c++ sfml frame-rate


    【解决方案1】:

    类似问题:Movement Without Framerate Limit C++ SFML.

    您真正需要的是固定时间步长。 看看 SFML 游戏开发书籍source code。这是来自Application.cpp的有趣的sn-p:

        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!”。

    【讨论】:

    • 很抱歉没有早点看到这个(因为我没有时间玩我的游戏 atm 我没有检查)但这不会导致 100% 的核心负载吗?
    • 您为什么不想为当前正在运行的游戏应用程序使用所有剩余的汁液?或者你正在做一个被动游戏? (热坐,回合制)或者它是一款电池寿命真的很重要的手机游戏?但正如我所见,在您提供的示例中,您已经使用了 100% 的 CPU。而是否使用 100% 的 CPU 本身就是另一个问题。
    • 我在回答中添加了指向Fix your Timestep 文章的链接。
    【解决方案2】:

    frametime 非常高或非常低时,由于浮点精度问题,您的计算可能无法正常工作。我建议将标准速度设置为 500mMovementSpeedTimeFactorframetime * 60 / 10.0f 并检查问题是否仍然存在。

    【讨论】:

    • 非常感谢,我会试试看。
    • 嗯,没用。我想我必须为'frametime'设置一个最大值,否则我总是会得到那些跳跃。 + 它仍然比简单地将速度设置为 1.0 慢很多,即使它应该产生相同的值......好吧,现在我想我继续使用内部帧限制器并将我的速度设置为“应该是”帧率。我想我总是可以改变这一点,但我真的很沮丧。但是无论哪种方式都感谢您的建议:)
    • 尝试偶尔将mMovementSpeedTimeFactor 写入控制台并检查它是否接近 0 以确认/取消确认我的原始想法
    • 嗯,我只是想创建一个小日志,这真的很奇怪:link 我猜你对 FP 精度或某种类型是正确的......因为我看不出有什么办法简单计算时的那些值:setMovementVector(sf::Vector2f( mMovementVector.x * mMovementSpeedTimefactor, mMovementVector.y * mMovementSpeedTimefactor)); 那些 fps 的“正常”值对于给定的帧时间应该是 0.6 到 1.2...
    • 我爱你!!!!!!工作,谢谢,我想如果你不要求我永远不会记录我需要的所有值。
    猜你喜欢
    • 2012-06-08
    • 1970-01-01
    • 1970-01-01
    • 2016-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-21
    相关资源
    最近更新 更多