Game Engine Basic:Timer(计时器)

之前已经实现了一个简单的查询时钟Clock,这里借助Clock来实现一个Timer

以达到和Sleep等函数相同功能,但更高精度的效果。

 

它的用法也比较简单,以下为测试代码:

main.cpp

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

int main() {
    
    Timer timer;
    double nowTime;
    timer.setTickInterval(1);
    timer.start();

    do {
        nowTime = timer.getRunTime();
        printf("当前时间为%lf\n",nowTime);
        timer.tick();
    } while (timer.getRunTime()<4);

    return 0;
}

对比前文Clock中测试Sleep函数的数据,可以看到我们自制的计时器精度有了显著提高。

由此我们可以更精细地控制游戏循环等各种涉及时间的部分。

 

翻到后文代码部分,我们看到Timer类里有许多函数,

诸如:

start()  //初次开启计时

pause()  //暂停

resume()  //从暂停中恢复

以及许多get类函数,但这并非重点。

 

真正最核心的函数还是滴答

tick()  //滴答一次

可能一下子不好理解这个滴答,

但是如果联系之前类比的Sleep延时函数就容易理解了。

 

延时函数:

 

一般情况下,延时函数实现的原理就是让其一直调用无意义的循环,直到超过设定的时间。

我们这里的滴答就像真正的时钟滴答一下,表面已经走过了一个时间片段,如一秒。

这个时间片段也称滴答间隔可以自由设置,在没超过滴答间隔的时间内,应该继续等待(做无意义循环),直到超过后,

作一些数据处理。

 

Timer.h

#ifndef  __TIMER_H__
#define __TIMER_H__

#include "Clock.h"

class Timer {
public:
    Timer();
    //开始计时
    void start();
    //暂停计时
    void pause();
    //恢复计时
    void resume();
    //时钟滴答
    void tick();
    //设置滴答时间间隔
    void setTickInterval(double _tickInterval);
    //获取开始时间点
    double getStartPoint();
    //获取运行时间
    double getRunTime();
    //获取是否暂停
    bool IsPause();
private:
    bool isPause;
    //当前时间点
    double nowPoint;
    //开启计时器时间点
    double startPoint;
    //上次滴答时间点
    double preTickPoint;
    //上次暂停时间点
    double prePausePoint;
    //恢复时间点
    double resumePoint;
    //已暂停时间
    double pausedTime;
    //已运行时间
    double runTime;
    //滴答间隔
    double tickInterval;
};

#endif // ! __TIMER_H__

Timer.cpp

#include "Timer.h"

Timer::Timer():isPause(false),tickInterval(0.001),
    startPoint(0),preTickPoint(0),prePausePoint(0),resumePoint(0),
    pausedTime(0),runTime(0){

}

void Timer::start() {
    nowPoint = Clock::get()->time();
    startPoint = nowPoint;
    resumePoint = nowPoint;
}

void Timer::pause() {
    if (!isPause) {
        nowPoint = Clock::get()->time();
        prePausePoint = nowPoint;
        isPause = true;
    }
}

void Timer::resume() {
    if (isPause) {
        nowPoint = Clock::get()->time();
        resumePoint = nowPoint;
        pausedTime += resumePoint - prePausePoint;
        isPause = false;
    }
}

void Timer::tick() {
    if (isPause) {
        return;
    }

    do {
        nowPoint = Clock::get()->time();
    } while ((nowPoint-preTickPoint)<tickInterval);

    preTickPoint = nowPoint;
}

void Timer::setTickInterval(double _tickInterval) {
    tickInterval = _tickInterval;
}

bool Timer::IsPause() {
    return isPause;
}

double Timer::getStartPoint() {
    return startPoint;
}

double Timer::getRunTime() {
    nowPoint = Clock::get()->time();
    return nowPoint - startPoint - pausedTime;
}

 

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

导航