C++ best way to create a timer for my game

Started by
7 comments, last by NightCreature83 11 years, 8 months ago
Been looking into the time timer and ctime doodad, do i really need this if I am coding a game? Can I just create a counter for the current number of seconds and increment an int, will this allow me to slow time easily or am I going to end up shooting myself in the foot!?

I'm thinking something along the lines of (roughly):

m_gameSpeed = 1000;
m_gameTime = 0;

bool secondsUp = Some code based on seconds - pulled from system time!

if(secondsUp)
m_gameTime += gameSpeed;
If you get near a point, make it!
Advertisement
Okay GetTickCount() seems to be quite good, but isn't that going to affect my game if i'm checking the time every millisecond?
If you get near a point, make it!
It will affect your game by giving you the ability to measure the passage of time. This is a desirable quality.

One idea for correctness and performance is to only measure the elapsed time once per frame. If you call GetTickCount() all over the place, you could end up measuring the time between two different timestamps by accident. GetTickCount() called at the start of the frame will likely return a different value then GetTickCount() called just before updating the screen.

One way of writing your game is so that your game logic always uses a fixed time step. So you run a game logic step every time an accumulator exceeds a given value:

# 60 updates a second
GAME_STEP_TIME_MSS = 1000.0 / 60.0

running = true
accumulator = 0
previous = currentTimeMilliseconds()
while running
now = currentTimeMilliseconds()
elapsed = now - previous
accumulator += elapsed
# while loop here to "catch up" if we fall multiple game steps behind
while accumulator >= GAME_STEP_TIME_MS
gameLogic()
accumulator -= GAME_STEP_TIME_MS

drawGame(elapsed)

The animation etc can use an interpolated value between two game logic steps.
Awesome, that's perfect.
If you get near a point, make it!

while running


Did you just negate the {} from here or is that valid code? I've only used it without {}, on 'if' conditions!
If you get near a point, make it!
Did you just negate the {} from here or is that valid code?

It's also missing semicolons, parenthesis, and is using pound and not double-slash for comments -- in other words, it's psuedocode.
I would use a timeGetTime() function though as 10ms-16ms resolution in a timer is not enough for a gameloop you should use timeGetTime() as that will have the ms resolution you are looking for.

If you need more precise timing you will have to go with QueryPerformanceTimer, it's resolution is the same as that of the CPU speed.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, theHunter, theHunter: Primal, Mad Max, Watch Dogs: Legion

GetTickCount() is a low resolution timer. Here, I have a class that uses HIGH RESOLUTION TIMER.

[source lang="cpp"]// -- timer.h

/**
* A high resolution timer class.
*/
class Timer
{
private:
LARGE_INTEGER mFreq;
LARGE_INTEGER mStart;
LARGE_INTEGER mEnd;
double mElapsedTime;

public:
/**
* Constructor.
*/
Timer();

/**
* Destructor.
*/
virtual ~Timer();

/**
* Marks the timer.
*/
void StartTimer();

/**
* Gets the elapsed time in milliseconds.
* @return Time in milliseconds.
*/
double GetTimeInMillis();

};


// -- timer.cpp

Timer::Timer()
{
QueryPerformanceFrequency ( &mFreq );
}

Timer::~Timer()
{
}

void Timer::StartTimer()
{
QueryPerformanceCounter ( &mStart );
}

double Timer::GetTimeInMillis()
{
QueryPerformanceCounter ( &mEnd );
mElapsedTime = ((mEnd.QuadPart - mStart.QuadPart) * 1000.0f / mFreq.QuadPart);

return mElapsedTime;
}[/source]

GetTickCount() is a low resolution timer. Here, I have a class that uses HIGH RESOLUTION TIMER.

[source lang="cpp"]// -- timer.h

/**
* A high resolution timer class.
*/
class Timer
{
private:
LARGE_INTEGER mFreq;
LARGE_INTEGER mStart;
LARGE_INTEGER mEnd;
double mElapsedTime;

public:
/**
* Constructor.
*/
Timer();

/**
* Destructor.
*/
virtual ~Timer();

/**
* Marks the timer.
*/
void StartTimer();

/**
* Gets the elapsed time in milliseconds.
* @return Time in milliseconds.
*/
double GetTimeInMillis();

};


// -- timer.cpp

Timer::Timer()
{
QueryPerformanceFrequency ( &mFreq );
}

Timer::~Timer()
{
}

void Timer::StartTimer()
{
QueryPerformanceCounter ( &mStart );
}

double Timer::GetTimeInMillis()
{
QueryPerformanceCounter ( &mEnd );
mElapsedTime = ((mEnd.QuadPart - mStart.QuadPart) * 1000.0f / mFreq.QuadPart);

return mElapsedTime;
}[/source]

Be aware that on multithreaded CPU's you have to bind this timer to a thread otherwise you can get inconsistancies in the sampling as it might happen on another physical core.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, theHunter, theHunter: Primal, Mad Max, Watch Dogs: Legion

This topic is closed to new replies.

Advertisement