我想時間fps計數,並將其限制爲60,但是我一直在通過谷歌瀏覽一些代碼,我完全不明白。如何爲遊戲循環制作計時器?
回答
你不應該試圖限制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槽,所以不同的代碼可以用不同的定時方法註冊。獨立插槽用於諸如鍵映射或改變音樂之類的事物,不需要如此精確。 SingTick適用於物理學,如果您知道每個嘀嗒將是相同的,但您不想穿過牆壁,則它更容易。渲染需要三角洲,所以動畫運行平穩,但必須記住在下一個SingTick上進行說明。
希望有所幫助。
如果你想要60 FPS,你需要弄清楚每幀有多少時間。在這種情況下,16.67毫秒。所以你需要一個循環,每16.67毫秒完成一次。
通常情況下(簡單地說):獲取輸入,做物理材料,渲染,暫停直到16.67ms過去。
它通常通過保存循環頂部的時間,然後計算結束時的差異以及睡眠或循環在該持續時間內無所事事來完成。
This article描述了幾種不同的遊戲循環方式,包括你想要的,但我會用這篇文章中更高級的選擇之一。
有很多很好的理由你爲什麼不應該以這種方式限制你的幀速率。原因之一就是指出,並非每個顯示器都可以以60fps的速度運行,另一個原因是定時器的分辨率不足,另一個原因是即使分辨率足夠高,兩個獨立的定時器(顯示器刷新和您的)由於隨機誤差,並行將總是與時間不同步(他們必須!),最重要的原因是它根本沒有必要。
請注意,Windows下的默認計時器分辨率是15ms,並且您可以獲得的最佳分辨率(通過使用timeBeginPeriod)爲1ms。因此,你可以(最好)等待16ms或17ms。一幀60fps是16.6666ms你如何等待16.6666ms?
如果要限制遊戲速度到顯示器的刷新率,請啓用垂直同步。這將完全符合你的要求,而且沒有同步問題。垂直同步也有它的一貫性(例如,當一幀需要16.67毫秒時有趣的驚喜),但它是迄今爲止最好的解決方案。
如果你想這樣做的原因是爲了讓你的模擬進入渲染循環,this是你必讀的。
+1鏈接http://gafferongames.com/game-physics/fix-your-timestep/ – 2012-10-24 07:41:30
delta時間是最後一次減去原來的時間。
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;
}
檢查這一個:
//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++;
}
}
跆拳道是這樣的...... – 2014-08-14 15:04:51
看起來像一個程序,將精確運行24小時,並將打印小時:分鐘:每秒秒鐘。這對遊戲循環有什麼好處? – mchiasson 2015-04-08 18:09:47
- 1. 回合制遊戲的遊戲循環
- 2. 回合制遊戲設計:事件驅動vs.遊戲循環
- 3. C#GDI遊戲循環(FPS計數器)
- 4. 遊戲循環控制
- 5. C#簡單的2D遊戲 - 製作基本的遊戲循環
- 6. 使用定時器和遊戲循環
- 7. 用於渲染和遊戲邏輯的獨立計時器的遊戲循環
- 8. 如何在spritekit遊戲中製作計時器?
- 9. 通過計時器或遊戲循環創建新的敵人?
- 10. Android的倒計時器與遊戲循環問題
- 11. 如何製作一個穩定的遊戲循環
- 12. JAVA遊戲循環?
- 13. Win32遊戲循環
- 14. Javascript遊戲循環
- 15. 在遊戲循環
- 16. BlackJack遊戲循環
- 17. 遊戲渲染類/遊戲循環內的Android倒計時時間
- 18. Lua,遊戲狀態和遊戲循環
- 19. 文字遊戲 - 遊戲循環
- 20. 遊戲循環中游戲對象的設計模式
- 21. 如何破解Flash遊戲計時器?
- 22. 如何爲幸運7(vb遊戲)製作一個實時比分計數器
- 23. 開發遊戲 - 如何執行多個遊戲循環?
- 24. 如何在遊戲中添加循環
- 25. 如何使Java Canvas遊戲循環
- 26. 如何調整遊戲循環幀率?
- 27. 遊戲計時器Javascript
- 28. C++ OpenGL遊戲計時器
- 29. 設置遊戲計時器
- 30. php計時器facebook遊戲
出於興趣,假設fps的限制爲60,它在75Hz屏幕上看起來像什麼? – stijn 2011-03-26 09:39:26
您可能想要在DirectX中啓用VSync,這會將渲染限制爲多倍的屏幕刷新率。從上一幀開始花時間並且通過這個(獨立於FPS的世界)增加遊戲狀態通常要簡單得多。 – ssube 2011-03-26 16:30:56