(注:【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定時函數。