Clock幀計時器
-
目的
- 使用Qtime循環調用myUpdate來刷新幀畫面時,幀數非固定,若每兩幀之間的計算量相差較大,會出現兩幀之間卡頓,使得畫面停滯,需要利用幀計時來優化計算
-
原理
- 統計連續兩幀之間的時鐘週期數量,除以當前的每秒時鐘週期數,可獲得相鄰兩幀的差時
-
Clock類
#include <Windows.h>
namespace Time {
class __declspec(dllexport) Clock {
private:
LARGE_INTEGER lastFrameCounter;
LARGE_INTEGER deltaCounter;
float deltaTime;
public:
LARGE_INTEGER nowPerformanceFrequency;
bool clockInitialize();
bool clockGetNewFrame();
float clockTimeLastFrame();
bool clockShutdown();
};
}
-
API
- LARGE_INTEGER
- 大整數Union,64位整數,一位符號位
- LargeInteger.QuadPart:__int64
- bool QueryPerformanceFrequency(LARGE_INTEGER *frequncy)
- 查詢當前系統每秒週期數
- 成功返回1,系統無法查詢返回0,存在於frequncy
- bool QueryPerformanceCounter(LARGE_INTEGER *performanceCount)
- 查詢當前指令所在週期數
- 成功返回1,系統無法查詢返回0,存在於performanceCount
-
實現
#include "Clock.h"
namespace Time {
bool Clock::clockInitialize() {
bool errorCode = QueryPerformanceFrequency(&nowPerformanceFrequency);
deltaTime = 0;
lastFrameCounter.QuadPart = 0;
return errorCode;
}
bool Clock::clockGetNewFrame() {
LARGE_INTEGER nowFrameCounter;
bool errorCode = QueryPerformanceCounter(&nowFrameCounter);
if (!errorCode) return false;
deltaCounter.QuadPart = nowFrameCounter.QuadPart - lastFrameCounter.QuadPart;
if (lastFrameCounter.QuadPart != 0)
deltaTime = ((float)deltaCounter.QuadPart) / nowPerformanceFrequency.QuadPart;
lastFrameCounter.QuadPart = nowFrameCounter.QuadPart;
return true;
}
float Clock::clockTimeLastFrame() {
return deltaTime;
}
bool Clock::clockShutdown() {
return true;
}
}
void MyGlWindow::myUpdate() {
myClock.clockGetNewFrame();
float frameTime = myClock.clockTimeLastFrame();
Velocity = Vector2D(0.1f,0.1f);
shipPosition = shipPosition + frameTime*Velocity;
repaint();
}
DLL鏈接
-
目的
- Vector2D實現使用的是包含inl文件,實質上只有.h,不存在編譯問題
- Clock中使用了.cpp,需要對engine項目進行編譯生成,需要生成動態鏈接庫給其他項目
-
實現
- 解決方案屬性->設置項目依賴
- engine屬性->配置類型:dll
- sandbox屬性:配置lib與include目錄
- sandbox添加生成事件,將engine.dll拷貝到sandbox的debug目錄中
鍵盤按鍵事件
-
QT鍵盤事件
-
Windows鍵盤事件
-
API
- short GetAsyncKeyState(int vKey)
- 返回值非空爲按vKey鍵信號
- vKey爲VK_按鍵名
-
實現
void MyGlWindow::myCheckKeyState() {
const float ACCERALATION = 0.08f * myClock.clockTimeLastFrame();
if (GetAsyncKeyState(VK_UP))
shipVelocity.y += ACCERALATION;
if (GetAsyncKeyState(VK_DOWN))
shipVelocity.y -= ACCERALATION;
if (GetAsyncKeyState(VK_RIGHT))
shipVelocity.x += ACCERALATION;
if (GetAsyncKeyState(VK_LEFT))
shipVelocity.x -= ACCERALATION;
if (GetAsyncKeyState(VK_SPACE))
shipVelocity.x = 0, shipVelocity.y = 0;
}