假设我有这个功能:
void changeMap(Player* player, int map) {
player->setMap(map);
}
我想要一个计时器类,让我能在一段时间后运行该函数,就像这样。
Player* chr;
int mapid = 300;
int milliseconds = 6000;
Timer.Schedule(changeMap(chr, 300), milliseconds);
提前致谢。
答案 0 :(得分:2)
如果这是游戏循环,那么一种方法是保留您希望在将来某个时间发生的事件列表,其中您存储时间和指向要调用的函数的指针。 (或者std :: function,或者其他)。保持列表按时间排序,以便最快的事件是列表的顶部。
然后在你的主游戏循环中,每个循环,检查列表顶部是否已经达到该事件的时间,以及是否已弹出事件并调用该函数。
答案 1 :(得分:0)
通过自由使用Functor委托对象和模板,您可以实现所需的效果:
CAlarm.h
#ifndef CALARM_H
#define CALARM_H
#include "ADTtime.h"
#include "CStopwatch.h"
template<class FunctionObject>
class Alarm : public StopWatch {
public:
Alarm(const FunctionObject& fn);
Alarm(double tickTime, const FunctionObject& fn);
virtual ~Alarm();
FunctionObject Tick();
protected:
FunctionObject _delegate;
double _tickTime;
private:
};
template<class FunctionObject>
Alarm<FunctionObject>::Alarm(const FunctionObject& fn)
: StopWatch(), _delegate(fn), _tickTime(1.0) { }
template<class FunctionObject>
Alarm<FunctionObject>::Alarm(double tickTime, const FunctionObject& fn)
: StopWatch(), _delegate(fn), _tickTime(tickTime) { }
template<class FunctionObject>
Alarm<FunctionObject>::~Alarm() {
if(_isRunning) Stop();
}
template<class FunctionObject>
FunctionObject Alarm<FunctionObject>::Tick() {
if(IsRunning() == false) return _delegate;
if(GetElapsedTimeInSeconds() >= _tickTime) {
Reset();
_delegate();
}
return _delegate;
}
#endif
CStopwatch.h
#ifndef CSTOPWATCH_H
#define CSTOPWATCH_H
#include "ADTtime.h"
class StopWatch : public ADTTime {
public:
StopWatch();
virtual ~StopWatch();
void Start();
void Restart();
void Stop();
void Reset();
virtual void CalculateElapsedTime();
virtual double GetElapsedTimeInSeconds();
virtual double GetElapsedTimeInMilliseconds();
protected:
private:
};
#endif
CStopwatch.cpp
#include "CStopwatch.h"
StopWatch::StopWatch() : ADTTime() {
/* DO NOTHING. ALL INITIALIZATION HAPPENS IN BASE CLASS */
}
StopWatch::~StopWatch() {
_startTime = -1;
_endTime = -1;
_deltaTime = -1.0;
_isRunning = false;
}
void StopWatch::Start() {
if(_isRunning == true) return;
_startTime = clock();
_isRunning = true;
}
void StopWatch::Stop() {
if(_isRunning == false) return;
_isRunning = false;
CalculateElapsedTime();
}
void StopWatch::Restart() {
Reset();
Start();
}
void StopWatch::Reset() {
Stop();
_startTime = 0;
_endTime = 0;
_deltaTime = 0.0;
}
void StopWatch::CalculateElapsedTime() {
_endTime = clock();
_deltaTime = difftime(_startTime, _endTime);
}
double StopWatch::GetElapsedTimeInSeconds() {
CalculateElapsedTime();
return -ADTTime::GetElapsedTimeInSeconds();
}
double StopWatch::GetElapsedTimeInMilliseconds() {
CalculateElapsedTime();
return -ADTTime::GetElapsedTimeInMilliseconds();
}
ADTTime.h
#ifndef ADTTIME_H
#define ADTTIME_H
#include <ctime>
class ADTTime {
public:
clock_t GetStartTime() const;
clock_t GetStartTime();
double GetStartTimeInSeconds() const;
double GetStartTimeInSeconds();
clock_t GetEndTime() const;
clock_t GetEndTime();
double GetEndTimeInSeconds() const;
double GetEndTimeInSeconds();
virtual double GetElapsedTimeInSeconds();
virtual double GetElapsedTimeInMilliseconds();
virtual void CalculateElapsedTime()=0;
bool IsRunning() const;
bool IsRunning();
virtual void Start()=0;
virtual void Restart()=0;
virtual void Stop()=0;
virtual void Reset()=0;
ADTTime();
virtual ~ADTTime();
protected:
bool _isRunning;
clock_t _startTime;
clock_t _endTime;
double _deltaTime;
private:
};
#endif
CADTTime.cpp
#include "ADTtime.h"
clock_t ADTTime::GetStartTime() const {
return _startTime;
}
clock_t ADTTime::GetStartTime() {
return static_cast<const ADTTime&>(*this).GetStartTime();
}
double ADTTime::GetStartTimeInSeconds() const {
return static_cast<double>((_startTime / CLOCKS_PER_SEC));
}
double ADTTime::GetStartTimeInSeconds() {
return static_cast<const ADTTime&>(*this).GetStartTimeInSeconds();
}
clock_t ADTTime::GetEndTime() const {
return _endTime;
}
clock_t ADTTime::GetEndTime() {
return static_cast<const ADTTime&>(*this).GetEndTime();
}
double ADTTime::GetEndTimeInSeconds() const {
return static_cast<double>((_endTime / CLOCKS_PER_SEC));
}
double ADTTime::GetEndTimeInSeconds() {
return static_cast<const ADTTime&>(*this).GetEndTimeInSeconds();
}
double ADTTime::GetElapsedTimeInSeconds() {
return _deltaTime / CLOCKS_PER_SEC;
}
double ADTTime::GetElapsedTimeInMilliseconds() {
return _deltaTime;
}
bool ADTTime::IsRunning() const {
return _isRunning;
}
bool ADTTime::IsRunning() {
return static_cast<const ADTTime&>(*this).IsRunning();
}
ADTTime::ADTTime() : _isRunning(false), _startTime(-1), _endTime(-1), _deltaTime(-1.0) { }
ADTTime::~ADTTime() {
_isRunning = false;
_startTime = -1;
_endTime = -1;
_deltaTime = -1.0;
}
答案 2 :(得分:0)
由于您在Windows操作系统上运行,我不明白您为什么要重新发明轮子?
CComPtr<IReferenceClock> pReferenceClock;
HRESULT hr = CoCreateInstance( CLSID_SystemClock, NULL, CLSCTX_INPROC_SERVER, IID_IReferenceClock, (void**)&pReferenceClock );
hr = pReferenceClock->AdviseTime( ... );
// or, hr = pReferenceClock->AdvisePeriodic( ... );
一旦你完成,
hr = pReferenceClock->Unadvise( adviseCookie );