Game Engine Basic:Clock(查询时钟)

游戏运行机制和时间通常密切相关,通常我们需要一个更高精度的时钟。

这里提供一个Window环境下高精度的Clock类。

它仅提供查询当前时间的功能。

(当前时间指,从它被构造函数初始化以来,到调用time()函数时,经过的时间)。

 

它的用法很简单,导入Clock.h头文件,

double nowTime = Clock::get()->time();

即将当前时间保存到nowTime变量里。

 

以下代码通过该函数测试系统提供的Sleep()函数精度

main.cpp

#include <iostream>
#include "Clock.h"

int main() {

    double nowTime = 0;

    do {
        nowTime = Clock::get()->time();
        printf("当前时间为%lf\n",nowTime);
        Sleep(1000);
    } while (nowTime<3);

    return 0;
}

每次运行的结果都有较大差别,可以看到系统提供的时间相关的函数精度并不是很高。

由于游戏循环等各种机制依赖于高精度的计时,因此我们有必要尝试自己实现一个Timer(计时器),而Timer的基础就是Clock。

Clock的原理是通过硬件相关的函数来实现的:

QueryPerformanceFrequecy函数可以保存CPU运行频率。

QueryPerformanceCounter函数可以保存CPU当前计数。

将开始记录计数的时间定义为0,当前时间可以通过公式算得:

当前时间  =(当前计数-开始时计数)/运行频率

 

Clock.h

#ifndef __CLOCK_H__
#define __CLOCK_H__

#include <Windows.h>

class Clock {
public:
    //获取时钟单例
    static Clock* get();
    //获取当前时间
    double time();
private:
    //创建同时,自动记录开始计数以及机器频率
    Clock();
    //销毁同时,处理instance指针
    ~Clock();

private:
    //时钟单例
    static Clock* instance;
    //本机频率(和CPU相关)
    LARGE_INTEGER machineFrequency;
    //开始时的计数
    LARGE_INTEGER countStart;
};

#endif

Clock.cpp

#include "Clock.h"

Clock* Clock::instance = nullptr;

Clock::Clock() {
    //获取机器频率
    QueryPerformanceFrequency(&machineFrequency);
    //获取开始时的计数
    QueryPerformanceCounter(&countStart);
}

Clock* Clock::get() {
    if (!instance) {
        instance = new Clock();
    }
    return instance;
}

double Clock::time(){
    LARGE_INTEGER countNow;
    QueryPerformanceCounter(&countNow);
    return (((double)countNow.QuadPart) - ((double)countStart.QuadPart)) / ((double)machineFrequency.QuadPart);
}

Clock::~Clock() {
    if (instance) {
        delete instance;
        instance = nullptr;
    }
}

 

posted on 2018-08-18 16:19  jyunlon  阅读(320)  评论(0编辑  收藏  举报

导航