您的位置:首页 > 其它

win32一个好用的游戏循环定时器

2016-01-21 15:16 288 查看

代码

定时器代码

#ifndef __CTimer_H__
#define __CTimer_H__

#include <windows.h>
class CTimer{
private:
LONGLONG    m_CurrenntTime,
m_LastTime,
m_NextTime,
m_FrameTime,     //每帧有多少个时钟周期
m_PerfCountFreq; //定时器的时钟频率

double      m_TimeElapsed,
m_TimeScale;     //定时器的时钟周期

float       m_FPS;
public:
CTimer();
CTimer(float fps);

void        Start();
bool        ReadyForNextFrame();
double      GetTimeElapsed(){return m_TimeElapsed;}
double      TimeElapsed();
};

#endif

//CTimer.cpp
#include "CTimer.h"

CTimer::CTimer():m_FPS(0),
m_TimeElapsed(0.0f),
m_FrameTime(0),
m_LastTime(0),
m_PerfCountFreq(0)
{
//获得定时器的时钟频率
QueryPerformanceFrequency((LARGE_INTEGER*) &m_PerfCountFreq);
//时钟周期
m_TimeScale = 1.0f / m_PerfCountFreq;
}

CTimer::CTimer(float fps):m_FPS(fps),
m_TimeElapsed(0.0f),
m_LastTime(0),
m_PerfCountFreq(0)
{
QueryPerformanceFrequency((LARGE_INTEGER*) &m_PerfCountFreq);
m_TimeScale = 1.0f / m_PerfCountFreq;
m_FrameTime = (LONGLONG)(m_PerfCountFreq / m_FPS);
}

void CTimer::Start(){
QueryPerformanceCounter((LARGE_INTEGER*) &m_LastTime);
m_NextTime = m_LastTime + m_FrameTime;
return;
}

bool CTimer::ReadyForNextFrame(){
if(!m_FPS){
MessageBox(NULL, "No FPS set in timer", "Doh", 0);
return false;
}
QueryPerformanceCounter((LARGE_INTEGER*) &m_CurrentTime);
if(m_CurrentTime > m_NextTime){
m_TimeElapsed = (m_CurrentTime - m_LastTime) * m_TimeScale;
m_LastTime = m_CurrentTime;
m_NextTime = m_CurrentTime + m_FrameTime;
return true;
}
return false;
}

double CTimer::TimeElapsed(){
QueryPerformanceCounter((LARGE_INTEGER*) &m_CurrentTime);
m_TimeElapsed = (m_CurrentTime - m_LastTime) * m_TimeScale;
m_LastTime = m_CurrentTime;
return m_TimeElapsed;
}


定时器使用

int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow){
WNDCLASSEX  winclass;
HWND        hwnd;
MSG         msg;

winclass.cbSize         = sizeof(WNDCLASSEX);
winclass.style          = CS_HREDRAW | CS_VREDRAW;
winclass.lpfnWndProc    = WindowProc;
winclass.cbClsExtra     = 0;
winclass.cbWndExtra     = 0;
winclass.hInstance      = hinstance;
winclass.hIcon          = NULL;
winclass.hCursor        = LoadCursor(NULL, IDC_ARROW);
winclass.hbrBackground  = NULL;
winclass.lpszMenuName   = NULL;
winclass.lpszClassName  = szWindowClassName;
winclass.hIconSm        = NULL;

if(!RegisterClassEx(&winclass)){
MessageBox(NULL, "Error Registering Class!", "Error", 0);
return 0;
}

if(!(hwnd = CreateWindowEx(NULL,
szWindowClassName,
szApplicationName,
WS_OVERLAPPED | WS_VISIBLE | WS_CAPTION | WS_SYSMENU,
GetSystemMetrics(SM_CXSCREEN)/2 - CParams::WindowWidth/2,
GetSystemMetrics(SM_CYSCREEN)/2 - CParams::WindowHeight/2,
CParams::WindowWidth,
CParams::WindowHeight,
NULL,
NULL,
hinstance,
NULL)))
{
MessageBox(NULL, "Error Creating Window!", "Error", 0);
return 0;
}

ShowWindow(hwnd, SW_SHOWDEFAULT);
UpdateWindow(hwnd);

//============游戏循环=====================
//设置帧率
CTimer timer(CParams::iFramesPerSecond);

//开始计时
timer.Start();
bool bDone = false;

while(!bDone){
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
if(msg.message == WM_QUIT){
bDone = TRUE;
}else{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

//是否开始下一帧
if(timer.ReadyForNextFrame() || g_pController->FastRender()){
if(!g_pController->Update())
bDone = true;

InvalidateRect(hwnd, NULL, NULL);
UpdateWindow(hwnd);
}
}

Cleanup();
UnregisterClass(szWindowClassName, winclass.hInstance);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  win32