当前位置: 首页 > 知识库问答 >
问题:

FPS口吃-游戏以指定的双FPS运行?

澹台宾白
2023-03-14

我已经成功创建了一个系统,允许游戏对象根据时间的变化(而不是帧数的变化)移动。为了练习起见,我现在正在尝试设置FPS限制。

我遇到的问题是,游戏循环的数量是我预期的两倍。例如,如果我尝试将帧数限制为1fps,则在一秒钟内会有2帧通过-一个非常长的帧(~1秒)和一个非常短的帧(~ 15毫秒)。这可以通过输出每个游戏循环之间的时间差(毫秒)来显示-示例输出可能是993、17993、16。。。

我尝试过更改代码,以便在FPS受到限制之前计算增量时间,但无济于事。

计时器类:

#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);
}

(部分)游戏循环:

//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;此代码已被省略。

共有2个答案

商茂勋
2023-03-14

假设你的游戏循环只有在SDL延迟()过期时才被触发,那么写下:

void Timer::LimitFPS(int targetFps)
{
    SDL_Delay((unsigned)(1000 / targetFps));
}

要根据请求的目标FPS将游戏循环延迟适当的毫秒数?

戚侯林
2023-03-14

这个问题是你的定时器结构设置的一部分。

_deltaTicks = _currentTicks - _previousTicks;

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

在代码开始时遍历它,currentTicks将等于0,previousTicks将等于0,因此对于第一个循环,您的_deltaTicks将为0。这意味着不管你的游戏逻辑限制,FPS都会行为不端。

void Timer::LimitFPS(int targetFps)
{ 
    if (_deltaTicks < (unsigned)(1000 / targetFps))
        SDL_Delay((unsigned)(1000 / targetFps) - _deltaTicks);
}

我们刚刚计算出_deltaTicks在循环开始时为0,因此无论您的游戏逻辑中发生了什么,我们都等待整整1000毫秒。

在下一帧中,_previousTicks将等于0,_currentTicks现在大约等于1000ms。这意味着_deltatick将等于1000。

我们再次使用LimitFPS函数,但这次使用了1000的_deltaTicks,因此我们等待0毫秒。

这种行为将不断地像这样翻转。

wait 1000ms
wait 0ms
wait 1000ms
wait 0ms
...

这些等待0毫秒的时间实质上是你FPS的两倍。

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

//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);
}

希望有所帮助。

 类似资料:
  • 我正在开发一个单人2d游戏。我用的发动机是我自己的。我很困惑如何适应不同的FPS游戏。我希望看到相同的游戏速度,而不管计算机可以处理的帧数。我的意思是,如果你的电脑足够强大,每秒可以画1000次,或者只有20帧,你的游戏速度应该是一样的。 我试图根据FPS自动更改移动参数,但似乎无法连接。 事实上,我有一些决定,但它们并不理想: 第一个是将FPS限制为30(例如),因此,即使性能不佳的计算机也可以

  • 我在玩Pygame,做一些简单的游戏只是为了学习它。然而,我很难按照我想要的方式实现fps。 据我所知,fps通常设置为: 然后在整个程序中,我确保每个循环/帧的写入时间为1/60秒,因此我可以,例如,使对象以我想要的速度移动。将滴答声增加到120 fps将使游戏运行过快,而降低滴答声将使游戏运行过慢。 然而,这不是我所熟悉的fps在其他游戏中的工作方式。在大多数游戏中,fps可以随您的需要而变化

  • 我目前正在制作一个游戏,我想限制每秒的帧数,但我对此有问题。这是我正在做的: 我通过每个帧执行的这个方法获取deltaTime: DeltaTime是有我所期望的值(大约0.012......到0.016...) 然后,我使用deltaTime通过睡眠窗口函数来延迟帧,如下所示: MAXFPS等于60,我乘以1000将秒转换为毫秒。虽然一切似乎都是正确的,但我的帧速率仍然超过了60帧(我的帧频约为

  • 在我的游戏中,我在中创建了许多循环和方法。我的笔记本电脑中的FPS范围从到不等,这是可以的。然而,当我在Galaxy Note 4的Android操作系统中运行它时,FPS的范围从到不等,这是不太好的。 现在我需要一个新的呈现线程,以同步呈现: 有人能帮我解决这个问题吗?

  • 问题内容: 现在看来似乎是事实上的动画方法。在大多数情况下,它对我来说效果很好,但是现在我正在尝试制作一些画布动画,我在想:是否有任何方法可以确保它以特定的fps运行?我了解到,rAF的目的是使动画始终保持平滑,并且可能冒使动画不稳定的风险,但是现在它似乎以任意大不相同的速度运行,我想知道是否有一种方法可以打击那不知何故。 我会用,但是我想要rAF提供的优化(特别是当标签页处于焦点时自动停止)。

  • 我是GLM新手,正在尝试编写fps风格的相机类 移动鼠标时是否需要重新计算上方向向量? 然而,在我改变向上向量后,一切看起来都很奇怪 但是当我保持向上向量时我的程序看起来有问题 文件:FPSCAMER。cpp公司 您可以在此处下载源代码和二进制文件 https://docs.google.com/file/d/0B9givuJvSet8ekRReWtRM29ldzg/edit?usp=sharin