4

fpsカウントの時間を計り、制限を60に設定したいのですが、Google経由でいくつかのコードを見てきましたが、完全にはわかりません。

4

5 に答える 5

3

デルタ時間は、最終時間から元の時間を引いたものです。

dt= t-t0

ただし、このデルタ時間は、単に速度が変化している間に経過する時間です。

関数の導関数は、その変数の 1 つに関する関数の微小変化を表します。変数に関する関数の導関数は、次のように定義されます。

                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;

}
于 2012-11-24T15:51:30.243 に答える
3

60 FPS が必要な場合は、各フレームにどれくらいの時間があるかを把握する必要があります。この場合、16.67 ミリ秒です。したがって、16.67 ミリ秒ごとに完了するループが必要です。

通常は (簡単に言えば)、入力を取得し、物理処理を行い、レンダリングし、16.67ms が経過するまで一時停止します。

これは通常、ループの先頭で時間を保存し、最後に差を計算し、その間何もせずにスリープまたはループすることによって行われます。

この記事では、必要な方法を含め、ゲーム ループを実行するいくつかの異なる方法について説明しますが、この記事ではより高度な方法の 1 つを使用します。

于 2011-03-26T10:03:05.593 に答える
2

fpsを制限しようとしないでください。これを行う唯一の理由は、デルタ時間を使用しておらず、各フレームが同じ長さであると予想する場合です。最も単純なゲームでさえ、それを保証することはできません。

ただし、デルタ時間を取り、それを固定サイズにスライスして、残りを保持することができます。

これが私が最近書いたコードです。徹底的にテストされていません。

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

メンバーオブジェクトはブーストスロットであるため、さまざまなコードをさまざまなタイミングメソッドで登録できます。独立したスロットは、キーのマッピングや音楽の変更など、それほど正確である必要はないもののためのものです。SingTickは、すべての目盛りが同じであることがわかっていても、壁を突き抜けたくない場合に簡単な物理学に適しています。レンダリングはデルタを取得するため、アニメーションはスムーズに実行されますが、次のSingTickでそれを考慮する必要があります。

お役に立てば幸いです。

于 2011-03-26T11:43:24.727 に答える
1

このような方法でフレーム レートを制限してはならない理由はたくさんあります。stijn が指摘したように、1 つの理由は、すべてのモニターが正確に 60 fps で実行されるわけではないことです。別の理由は、タイマーの解像度が十分でないことです。さらに別の理由は、十分な解像度が与えられたとしても、2 つの別個のタイマー (モニターの更新とあなたのもの) が実行されていることです。 parallel は、ランダムな不正確さのために常に時間と同期しなくなります (そうしなければなりません!)。最も重要な理由は、それがまったく必要ないことです。

Windows での既定のタイマーの解像度は 15 ミリ秒であり、(timeBeginPeriod を使用して) 取得できる最高の解像度は 1 ミリ秒であることに注意してください。したがって、(せいぜい) 16ms または 17ms 待つことができます。60fps での 1 フレームは 16.6666ms 16.6666ms をどのように待ちますか?

ゲームの速度をモニターのリフレッシュ レートに制限する場合は、垂直同期を有効にします。これにより、必要なことが正確に同期の問題なしで実行されます。垂直同期にも特殊性がありますが (フレームが 16.67 ミリ秒かかると驚くような驚きが得られるなど)、利用可能なソリューションとしては群を抜いて優れています。

これを行う理由が、シミュレーションをレンダー ループに適合させるためだった場合、これは必読です。

于 2011-03-26T16:27:38.590 に答える
-3

これをチェックしてください:

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

}
于 2013-12-11T14:26:54.717 に答える