How to make timer for a game loop?

前端 未结 5 1743
别跟我提以往
别跟我提以往 2021-02-06 16:21

I want to time fps count, and set it\'s limit to 60 and however i\'ve been looking throught some code via google, I completly don\'t get it.

相关标签:
5条回答
  • 2021-02-06 17:03

    There are many good reasons why you should not limit your frame rate in such a way. One reason being as stijn pointed out, not every monitor may run at exactly 60fps, another reason being that the resolution of timers is not sufficient, yet another reason being that even given sufficient resolutions, two separate timers (monitor refresh and yours) running in parallel will always get out of sync with time (they must!) due to random inaccuracies, and the most important reason being that it is not necessary at all.

    Note that the default timer resolution under Windows is 15ms, and the best possible resolution you can get (by using timeBeginPeriod) is 1ms. Thus, you can (at best) wait 16ms or 17ms. One frame at 60fps is 16.6666ms How do you wait 16.6666ms?

    If you want to limit your game's speed to the monitor's refresh rate, enable vertical sync. This will do what you want, precisely, and without sync issues. Vertical sync does have its pecularities too (such as the funny surprise you get when a frame takes 16.67ms), but it is by far the best available solution.

    If the reason why you wanted to do this was to fit your simulation into the render loop, this is a must read for you.

    0 讨论(0)
  • 2021-02-06 17:13

    You shouldn't try to limit the fps. The only reason to do so is if you are not using delta time and you expect each frame to be the same length. Even the simplest game cannot guarantee that.

    You can however take your delta time and slice it into fixed sizes and then hold onto the remainder.

    Here's some code I wrote recently. It's not thoroughly tested.

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

    The member objects are Boost slots so different code can register with different timing methods. The Independent slot is for things like key mapping or changing music Things that don't need to be so precise. SingTick is good for physics where it is easier if you know every tick will be the same but you don't want to run through a wall. Render takes the delta so animations run smooth, but must remember to account for it on the next SingTick.

    Hope that helps.

    0 讨论(0)
  • 2021-02-06 17:13

    delta time is the final time, minus the original time.

    dt= t-t0
    

    This delta time, though, is simply the amount of time that passes while the velocity is changing.

    The derivative of a function represents an infinitesimal change in the function with respect to one of its variables. The derivative of a function with respect to the variable is defined as

                    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;
    
    }
    
    0 讨论(0)
  • 2021-02-06 17:21

    check this one out:

    //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++;
    }
    
    }
    
    0 讨论(0)
  • 2021-02-06 17:26

    If you want 60 FPS, you need to figure out how much time you have on each frame. In this case, 16.67 milliseconds. So you want a loop that completes every 16.67 milliseconds.

    Usually it goes (simply put): Get input, do physics stuff, render, pause until 16.67ms has passed.

    Its usually done by saving the time at the top of the loop and then calculating the difference at the end and sleeping or looping doing nothing for that duration.

    This article describes a few different ways of doing game loops, including the one you want, although I'd use one of the more advanced alternatives in this article.

    0 讨论(0)
提交回复
热议问题