我正在设计一个时间类,它只会在预定义的时间后执行一个操作,但我仍然无法找到重置时间的方法。无论如何,是将时间重置为零还是暂时停止并恢复时间?
因此,我的目标是在每次满足条件 A 时重置时间,这样它就不会搞砸 delayTime 函数,它仍然保持以前的时间并最终导致错误的时间计算。
if ( condition A )
{
if ( time.delayTime( 5.0f ) )
{
doActionA();
}
}
时间类.h
#ifndef _TIMECLASS_H_
#define _TIMECLASS_H_
#include <windows.h>
class TimeClass
{
public:
TimeClass();
~TimeClass();
bool delayTime( float second );
float getSecond();
void reset();
private:
float getGameTime();
float currentTime;
UINT64 ticks;
float time;
float timeAtGameStart;
UINT64 ticksPerSecond;
};
#endif
时间类.cpp
#include "TimeClass.h"
TimeClass::TimeClass()
{
// We need to know how often the clock is updated
if( !QueryPerformanceFrequency((LARGE_INTEGER *)&ticksPerSecond) )
ticksPerSecond = 1000;
// If timeAtGameStart is 0 then we get the time since
// the start of the computer when we call GetGameTime()
timeAtGameStart = 0;
timeAtGameStart = getGameTime();
}
float TimeClass::getGameTime()
{
// This is the number of clock ticks since start
if( !QueryPerformanceCounter((LARGE_INTEGER *)&ticks) )
ticks = (UINT64)timeGetTime();
// Divide by frequency to get the time in seconds
time = (float)(__int64)ticks/(float)(__int64)ticksPerSecond;
// Subtract the time at game start to get
// the time since the game started
time -= timeAtGameStart;
return time;
}
bool TimeClass::delayTime( float second )
{
currentTime = getGameTime();
static float totalTime = second + getGameTime();
if ( currentTime >= totalTime )
{
totalTime = second + getGameTime();
return true;
}
else
{
return false;
}
}
float TimeClass::getSecond()
{
currentTime = getGameTime();
static float totalTime = 1 + getGameTime();
if ( currentTime >= totalTime )
{
totalTime = 1 + getGameTime();
return currentTime;
}
else
{
return currentTime;
}
}
void TimeClass::reset()
{
timeAtGameStart = 0;
timeAtGameStart = getGameTime();
}
TimeClass::~TimeClass()
{
}
最佳答案
标准库
如前所述,只需使用 std::chrono::high_resolution_clock .如果您使用 Visual C++ 编译器,则会有一个实际的 bug report关于 high_resolution_clock 的分辨率,它与 QueryPerformanceCounter 不相同。
示例
auto t1 = std::chrono::high_resolution_clock::now();
// Do something
auto t2 = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::duration<double>>(t2 - t1);
double dt = duration.count();
时间类
您现在面临的主要问题是您使用的是静态变量。您正在寻找一种方法来从 delayTime 之外的另一个函数重置静态变量。如果你会引入成员变量来摆脱静态变量,它会让事情变得容易得多(注意:函数中的静态变量是不好的做法,因为它们持有状态 => 不利于多线程)。那么像这样的事情呢:
class Event {
std::chrono::high_resolution_clock::time_point lastEventOccurred;
double timeBetweenEvents;
public:
Event(double timeBetweenEvents)
: timeBetweenEvents(timeBetweenEvents)
, lastEventOccurred(std::chrono::high_resolution_clock::now()) { }
bool ready() {
auto currentTime = std::chrono::high_resolution_clock::now();
auto elapsedTime = std::chrono::duration_cast<std::chrono::duration<double>>(currentTime - lastEventOccurred).count();
if(elapsedTime > timeBetweenEvents) {
reset();
return true;
} else
return false;
}
void reset() {
lastEventOccurred = std::chrono::high_resolution_clock::now();
}
};
用法:
Event evtDelay = Event(5.0);
if(condition A) {
if(evtDelay.ready()) {
doActionA();
}
} else if(condition B) {
evtDelay.reset();
}
另一种方法是使用捕获状态和更新方法。如我所见,您正在将其用于游戏,因此可以在游戏的更新方法中完成更新。假设事件有一个类似 {Active, Inactive} 的状态和一个耗时的成员,每次调用更新时,如果状态为事件,则添加自上次更新调用以来耗时。因此,就绪函数只会检查耗时是否大于定义的阈值。
class Event {
std::chrono::high_resolution_clock::time_point lastUpdateCall;
double timeBetweenEvents;
double elapsedTime;
bool active;
public:
Event(double timeBetweenEvents)
: timeBetweenEvents(timeBetweenEvents)
, lastUpdateCall(std::chrono::high_resolution_clock::now())
, elapsedTime(0.0)
, active(true) { }
bool ready() {
return elapsedTime >= timeBetweenEvents;
}
void reset() {
elapsedTime = 0.0;
}
void setActive(bool state) {
active = state;
}
void update() {
auto currentTime = std::chrono::high_resolution_clock::now();
if(active) {
auto dt = std::chrono::duration_cast<std::chrono::duration<double>>(currentTime - lastUpdateCall).count();
elapsedTime += dt;
}
lastUpdateCall = currentTime;
}
};
关于c++ - 时间类问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19180218/