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;
}