c++ 如何制作游戏循环计时器?

xggvc2p6  于 2023-03-09  发布在  其他
关注(0)|答案(5)|浏览(184)

我想时间fps计数,并设置为60的限制,但我一直在寻找通过谷歌的一些代码,我完全没有得到它。

brgchamk

brgchamk1#

增量时间是最终时间减去原始时间。

dt= t-t0

然而,这个时间差只是速度变化时所经过的时间量。
函数的导数表示函数相对于其中一个变量的无穷小变化。函数相对于该变量的导数定义为

f(x + h) - f(x)
f'(x) = lim    -----------------
        h->0           h

http://mathworld.wolfram.com/Derivative.html

#include<time.h>
#include<stdlib.h>
#include<stdio.h>
#include<windows.h>
#pragma comment(lib,"winmm.lib")

void gotoxy(int x, int y);
void StepSimulation(float dt);

int main(){

  int NewTime = 0;
  int OldTime = 0;
  float dt = 0;
  float TotalTime = 0;
  int FrameCounter = 0;
  int RENDER_FRAME_COUNT = 60;

  while(true){

        NewTime = timeGetTime();    
        dt = (float) (NewTime - OldTime)/1000; //delta time
        OldTime = NewTime;

        if (dt > (0.016f)) dt = (0.016f);  //delta time
        if (dt < 0.001f) dt = 0.001f;

        TotalTime += dt;

        if(TotalTime > 1.1f){ 
            TotalTime=0;
            StepSimulation(dt);
            }

        if(FrameCounter >= RENDER_FRAME_COUNT){           
            // draw stuff
            //Render(); 

            gotoxy(1,2);
            printf(" \n");
            printf("OldTime      = %d \n",OldTime);
            printf("NewTime      = %d \n",NewTime);
            printf("dt           = %f  \n",dt);
            printf("TotalTime    = %f  \n",TotalTime);
            printf("FrameCounter = %d fps\n",FrameCounter);
            printf("   \n");
            FrameCounter = 0;

        } 
        else{
            gotoxy(22,7);
            printf("%d  ",FrameCounter);
            FrameCounter++;

        }

    }

    return 0;
}

void gotoxy(int x, int y){
    COORD coord;
    coord.X = x; coord.Y = y;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
    return;
}

void StepSimulation(float dt){
    // calculate stuff
   //vVelocity += Ae * dt;

}
emeijp43

emeijp432#

如果你想要60帧每秒,你需要计算每一帧的时间,在这个例子中是16.67毫秒,所以你想要一个每16.67毫秒完成一次的循环。
通常它是这样的(简单地说):获取输入,做物理的东西,渲染,暂停,直到16.67ms已经过去。
它通常是通过在循环的顶部保存时间,然后在结束时计算差异,并在该持续时间内休眠或循环。
This article描述了几种不同的游戏循环方法,包括您想要的方法,不过在本文中我将使用其中一种更高级的方法。

xghobddn

xghobddn3#

你不应该尝试限制fps。这样做的唯一原因是如果你不使用delta时间,你希望每一帧都是相同的长度。即使是最简单的游戏也不能保证这一点。
但是,您可以将增量时间分割为固定大小,然后保留剩余部分。
这是我最近写的一些代码,还没有经过彻底的测试。

void GameLoop::Run()
{
    m_Timer.Reset();

    while(!m_Finished())
    {
        Time delta = m_Timer.GetDelta();
        Time frameTime(0);
        unsigned int loopCount = 0;

        while (delta > m_TickTime && loopCount < m_MaxLoops)
        {
            m_SingTick();
            delta -= m_TickTime;
            frameTime += m_TickTime;
            ++loopCount;
        }
        m_Independent(frameTime);

        // add an exception flag later.
        // This is if the game hangs
        if(loopCount >= m_MaxLoops)
        {
            delta %= m_TickTime;
        }

        m_Render(delta);
        m_Timer.Unused(delta);
    }
}

成员对象是Boost槽,因此不同的代码可以注册不同的计时方法。Independent槽用于键Map或改变音乐等不需要如此精确的事情。SingTick适用于物理学,如果你知道每个滴答都是相同的,但你不想穿过墙壁,那么它会更容易。Render使用delta,因此动画运行流畅。但一定要记得在下一次的SingTick上说明它。
希望能有所帮助。

ikfrs5lh

ikfrs5lh4#

有很多很好的理由说明你不应该以这样的方式限制你的帧率,一个原因是正如stijn指出的,并不是每个显示器都可能精确地运行在60 fps,另一个原因是计时器的分辨率不够,还有一个原因是即使给出了足够的分辨率,两个独立的计时器(显示器刷新和您的)并行运行将始终与时间不同步(他们必须!)由于随机的不准确,而最重要的原因是根本没有必要。
注意Windows下默认的计时器分辨率是15 ms,而你能得到的最佳分辨率(通过timeBeginPeriod)是1 ms,因此,你最多只能等待16 ms或17 ms,一帧60 fps是16.6666ms你怎么能等待16.6666ms呢?
如果你想限制你的游戏速度到显示器的刷新率,启用垂直同步。这将做你想要的,精确,没有同步问题。垂直同步也有它的特殊性(如有趣的惊喜,你会得到一帧需要16.67毫秒),但它是迄今为止最好的解决方案。
如果您想这样做的原因是为了使您的模拟适合渲染循环,那么this是您的必读书目。

3ks5zfa0

3ks5zfa05#

看看这个:

//Creating Digital Watch in C++
#include<iostream>
#include<Windows.h>
using namespace std;

struct time{

int hr,min,sec;
};
int main()
{
time a;
a.hr = 0;
a.min = 0;
a.sec = 0;

for(int i = 0; i<24; i++)
{
    if(a.hr == 23)
    {
        a.hr = 0;
    }

    for(int j = 0; j<60; j++)
    {
        if(a.min == 59)
        {
            a.min = 0;
        }

        for(int k = 0; k<60; k++)
        {
            if(a.sec == 59)
            {
                a.sec = 0;
            }

            cout<<a.hr<<" : "<<a.min<<" : "<<a.sec<<endl;
            a.sec++;
            Sleep(1000);
            system("Cls");
        }
    a.min++;

}

    a.hr++;
}

}

相关问题