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

代码

定时器代码

#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;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值