我想时间fps计数,并设置为60的限制,但我一直在寻找通过谷歌的一些代码,我完全没有得到它。
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; }
emeijp432#
如果你想要60帧每秒,你需要计算每一帧的时间,在这个例子中是16.67毫秒,所以你想要一个每16.67毫秒完成一次的循环。通常它是这样的(简单地说):获取输入,做物理的东西,渲染,暂停,直到16.67ms已经过去。它通常是通过在循环的顶部保存时间,然后在结束时计算差异,并在该持续时间内休眠或循环。This article描述了几种不同的游戏循环方法,包括您想要的方法,不过在本文中我将使用其中一种更高级的方法。
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上说明它。希望能有所帮助。
ikfrs5lh4#
有很多很好的理由说明你不应该以这样的方式限制你的帧率,一个原因是正如stijn指出的,并不是每个显示器都可能精确地运行在60 fps,另一个原因是计时器的分辨率不够,还有一个原因是即使给出了足够的分辨率,两个独立的计时器(显示器刷新和您的)并行运行将始终与时间不同步(他们必须!)由于随机的不准确,而最重要的原因是根本没有必要。注意Windows下默认的计时器分辨率是15 ms,而你能得到的最佳分辨率(通过timeBeginPeriod)是1 ms,因此,你最多只能等待16 ms或17 ms,一帧60 fps是16.6666ms你怎么能等待16.6666ms呢?如果你想限制你的游戏速度到显示器的刷新率,启用垂直同步。这将做你想要的,精确,没有同步问题。垂直同步也有它的特殊性(如有趣的惊喜,你会得到一帧需要16.67毫秒),但它是迄今为止最好的解决方案。如果您想这样做的原因是为了使您的模拟适合渲染循环,那么this是您的必读书目。
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++; } }
5条答案
按热度按时间brgchamk1#
增量时间是最终时间减去原始时间。
然而,这个时间差只是速度变化时所经过的时间量。
函数的导数表示函数相对于其中一个变量的无穷小变化。函数相对于该变量的导数定义为
http://mathworld.wolfram.com/Derivative.html
emeijp432#
如果你想要60帧每秒,你需要计算每一帧的时间,在这个例子中是16.67毫秒,所以你想要一个每16.67毫秒完成一次的循环。
通常它是这样的(简单地说):获取输入,做物理的东西,渲染,暂停,直到16.67ms已经过去。
它通常是通过在循环的顶部保存时间,然后在结束时计算差异,并在该持续时间内休眠或循环。
This article描述了几种不同的游戏循环方法,包括您想要的方法,不过在本文中我将使用其中一种更高级的方法。
xghobddn3#
你不应该尝试限制fps。这样做的唯一原因是如果你不使用delta时间,你希望每一帧都是相同的长度。即使是最简单的游戏也不能保证这一点。
但是,您可以将增量时间分割为固定大小,然后保留剩余部分。
这是我最近写的一些代码,还没有经过彻底的测试。
成员对象是Boost槽,因此不同的代码可以注册不同的计时方法。Independent槽用于键Map或改变音乐等不需要如此精确的事情。SingTick适用于物理学,如果你知道每个滴答都是相同的,但你不想穿过墙壁,那么它会更容易。Render使用delta,因此动画运行流畅。但一定要记得在下一次的SingTick上说明它。
希望能有所帮助。
ikfrs5lh4#
有很多很好的理由说明你不应该以这样的方式限制你的帧率,一个原因是正如stijn指出的,并不是每个显示器都可能精确地运行在60 fps,另一个原因是计时器的分辨率不够,还有一个原因是即使给出了足够的分辨率,两个独立的计时器(显示器刷新和您的)并行运行将始终与时间不同步(他们必须!)由于随机的不准确,而最重要的原因是根本没有必要。
注意Windows下默认的计时器分辨率是15 ms,而你能得到的最佳分辨率(通过timeBeginPeriod)是1 ms,因此,你最多只能等待16 ms或17 ms,一帧60 fps是16.6666ms你怎么能等待16.6666ms呢?
如果你想限制你的游戏速度到显示器的刷新率,启用垂直同步。这将做你想要的,精确,没有同步问题。垂直同步也有它的特殊性(如有趣的惊喜,你会得到一帧需要16.67毫秒),但它是迄今为止最好的解决方案。
如果您想这样做的原因是为了使您的模拟适合渲染循环,那么this是您的必读书目。
3ks5zfa05#
看看这个: