【D3D11遊戲程式設計】學習筆記六:定時器的實現

Brother灬Nam發表於2012-12-13

      

       (注:【D3D11遊戲程式設計】學習筆記系列由CSDN作者BonChoix所寫,轉載請註明出處:http://blog.csdn.net/BonChoix,謝謝~)

 

       無論在遊戲還是簡單的動畫程式當中,定時器是一個必不可少的元素,用來正確地控制遊戲幀數、動畫的播放。最簡單的實現定時器的方法通過在主迴圈中定義兩個靜態計時用的變數即可實現。但在學習過程中,定時器的使用相當頻繁,因此設計一個具備基本功能的方便使用的定時器類很有必要。這次就來建立一個簡單但精度很高的定時器。

       這個定時器支援暫時、開始、重置等基本操作,程式中每一幀呼叫一次計數,並隨時返回距離上一次計數之間的差值。這個差值就是控制遊戲、動畫更新的最重要的資料。

       這個定時器用到了Windows中高精度的計時函式:QueryPerformanceCounter和QueryPerformanceFrequency,原型如下:

BOOL QueryPerformanceCounter(  LARGE_INTEGER* lpPerformanceCount );
BOOL QueryPerformanceFrequency(  LARGE_INTEGER* lpFrequency );

       這個定時函式以計數為單位,不同的機器兩次計數之間的時間差可能不一樣,因此有了第二個函式,返回一秒內計數的個數,求倒數即是兩次計數之間的時間差(秒)。第個函式返回一個長整型數,通過傳遞引數地址來獲得。詳細說明參見MSDN,參考該定時器類的實現也可以很好的理解它們的使用。

       下面是這個定時器的類定義:

class Timer
{
public:
	Timer();

	float TotalTime() const;	//返回定時器從開始計時到現在的總時間(不包含暫停時間),單位:秒
	float DeltaTime() const;	//返回本次計時與上次計時之間的時間差,單位:秒

	void Start();			//暫停後恢復計時
	void Stop();			//暫停
	void Reset();			//重置,開始計時,定時器開始工作時呼叫
	void Tick();			//計時一次,每一幀呼叫一次

private:
	float	m_secsPerCount;		//系統有關,兩個系統計數器之間的時間差值,單位:秒
					//這個變數是定時器把時間單位轉換為“秒”的基準
	float	m_deltaTime;		//距離上次計時之間的時間差,單位:秒

	__int64 m_baseTime;		//定時器開始工作的起始時間點
	__int64 m_stopTime;		//如果當前為暫停狀態,即指暫時的起始時刻
	__int64 m_pausedTime;		//暫停的總時間累計
	__int64	m_currTime;		//本次計時的時間點
	__int64	m_prevTime;		//上次計時的時間點

	bool	m_stopped;		//是否暫停
};

       註釋已經十分詳細,應該很容易明白各成員函式及變數的作用。

       在建構函式中,主要任務是獲得跟機器相關的變數,及m_secsPerCount,相臨兩次計數之間的時間差,以秒為單位。

       在定時器開始工作前,需要先呼叫Reset,重置定時器,使定時器處於相應的工作狀態,且設定好起始的引數。

       其次,在程式每一幀中呼叫Tick來計時,更新定時器。

       然後可以通過呼叫如TotalTime、DeltaTime函式來獲得相關的時間值。其中DeltaTime()是最重要的函式,其返回的時間值是更新遊戲每一幀及動畫的核心引數。

       通過呼叫Stop和Start來暫停和恢復定時器。

 

       該定時器設計設計就這麼簡單,各成員函式的定義及詳細的註釋見原始碼,通過原始碼也可以更深入地理解用到的兩個Windows定時函式。

       定時器原始碼

相關文章