首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >FPS口吃-游戏运行在双FPS指定?

FPS口吃-游戏运行在双FPS指定?
EN

Stack Overflow用户
提问于 2013-09-03 13:23:37
回答 2查看 339关注 0票数 0

我已经创建了一个系统,允许游戏对象根据时间的变化(而不是帧数的变化)移动。为了练习的缘故,我现在正试图强加FPS限制器。

我遇到的问题是,是游戏循环数量的两倍,比我预期的要多。例如,如果我试图将帧数限制为1个FPS,那么在这一秒内就会有两个帧--一个非常长的帧(~1秒)和一个非常短的帧(~15毫秒)。这可以通过输出每个游戏循环之间的时间差(毫秒)来显示--例如输出可能是993,17,993,16.

我尝试过更改代码,以便在有限的FPS之前计算增量时间,但没有效果。

计时器班:

代码语言:javascript
复制
#include "Timer.h"
#include <SDL.h>

Timer::Timer(void)
{
    _currentTicks = 0;
    _previousTicks = 0;
    _deltaTicks = 0;

    _numberOfLoops = 0;
}

void Timer::LoopStart()
{
    //Store the previous and current number of ticks and calculate the
    //difference. If this is the first loop, then no time has passed (thus
    //previous ticks == current ticks).
    if (_numberOfLoops == 0)
        _previousTicks = SDL_GetTicks();
    else
        _previousTicks = _currentTicks;

    _currentTicks = SDL_GetTicks();

    //Calculate the difference in time.
    _deltaTicks = _currentTicks - _previousTicks;

    //Increment the number of loops.
    _numberOfLoops++;
}

void Timer::LimitFPS(int targetFps)
{ 
    //If the framerate is too high, compute the amount of delay needed and
    //delay.
    if (_deltaTicks < (unsigned)(1000 / targetFps))
        SDL_Delay((unsigned)(1000 / targetFps) - _deltaTicks);
}

(部分)游戏循环:

代码语言:javascript
复制
//The timer object.
Timer* _timer = new Timer();

//Start the game loop and continue.
while (true)
{
    //Restart the timer.
    _timer->LoopStart();

    //Game logic omitted

    //Limit the frames per second.
    _timer->LimitFPS(1);
}

注意:我正在使用SMA计算FPS;这段代码被省略了。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-09-03 14:36:34

这个问题是如何设置计时器结构的一部分。

代码语言:javascript
复制
_deltaTicks = _currentTicks - _previousTicks;

我看了几遍代码,根据您如何设置计时器,这似乎是问题所在。

在代码开始时遍历它,_currentTicks将等于0,而_previousTicks将等于0,所以对于第一个循环,_deltaTicks将是0。这意味着,不管您的游戏逻辑如何,LimitFPS都会行为不检。

代码语言:javascript
复制
void Timer::LimitFPS(int targetFps)
{ 
    if (_deltaTicks < (unsigned)(1000 / targetFps))
        SDL_Delay((unsigned)(1000 / targetFps) - _deltaTicks);
}

我们刚刚计算出_deltaTicks在循环开始时为0,因此我们等待完整的1000 at,而不管游戏逻辑中发生了什么。

在下一个框架中,_previousTicks将等于0,而_currentTicks现在将大约等于1000 On。这意味着_deltaTicks将等于1000。

我们再次命中了LimitFPS函数,但这次的_deltaTicks值为1000,这使得我们等待0ms。

这种行为会像这样不停地翻转。

代码语言:javascript
复制
wait 1000ms
wait 0ms
wait 1000ms
wait 0ms
...

那些等待的基本上是你的FPS的两倍。

您需要在游戏逻辑的开始和结束时测试时间。

代码语言:javascript
复制
//The timer object.
Timer* _timer = new Timer();

//Start the game loop and continue.
while (true)
{
    //Restart the timer.
    _timer->LoopStart();

    //Game logic omitted

    //Obtain the end time
    _timer->LoopEnd();

    //Now you can calculate the delta based on your start and end times.
    _timer->CaculateDelta();

    //Limit the frames per second.
    _timer->LimitFPS(1);
}

希望这能有所帮助。

票数 1
EN

Stack Overflow用户

发布于 2013-09-03 13:44:42

假设只有在SDL_Delay()过期时才触发gameloop,那么只编写以下内容是不够的:

代码语言:javascript
复制
void Timer::LimitFPS(int targetFps)
{
    SDL_Delay((unsigned)(1000 / targetFps));
}

要根据请求的目标FPS将游戏延迟正确的毫秒数吗?

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18593506

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档