A "real" timer

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
mR.haHN
Posts: 49
Joined: Wed May 03, 2006 5:37 pm

A "real" timer

Post by mR.haHN »

Hi there,

I´ve got a big problem. I discovered it yesterday and failed to solve it since then :wink:

Well, just take a look at my code, you´ll see the problem:

Code: Select all

 if(attacking=1)
                        {
                        attacktimer += 1;
                        if(attacktimer==120)
                        {
                          
                          fader->setColor(video::SColor(0,255,0,0));
                          fader->fadeIn(200);
                          HPplayer -= 10;
                          attacktimer = 0;
                        }
                        }
This is only one example, I used this method for several more functions..

How can I use a real timer so that everything isnt depending on the framerate?
Xharock
Posts: 71
Joined: Wed May 10, 2006 3:50 pm

Post by Xharock »

SDL, has a great timer system. Just in case you want to try it.
mR.haHN
Posts: 49
Joined: Wed May 03, 2006 5:37 pm

Post by mR.haHN »

ehehe...what is SDL?
Xharock
Posts: 71
Joined: Wed May 10, 2006 3:50 pm

Post by Xharock »

SDL - Simple Direct Media Layer. Its a multi-platform set of game libraries. These libraries include some great functions for timers. You can find them here:

http://www.libsdl.org/index.php
CuteAlien
Admin
Posts: 9720
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

You can wrap the Irrlicht Timer in an own class for which you can create as many timer instances as you need.

I can give you my code as example how i did it - maybe it helps:

timer.h:

Code: Select all

#ifndef TIMER_H
#define TIMER_H

class Timer
{
public:
    Timer(irr::ITimer * irrlichtTimer_, bool startRunning_=false);
	virtual ~Timer();

    // in milliseconds
	virtual u32 GetTime();
	virtual void SetTime(u32 time_);

	virtual u32 GetLastTickInMs();
	virtual f32 GetLastTickInSeconds();

    // unlike irr::ITimer there's no reference counting for start/stop!
	virtual void Stop();
	virtual void Start();
	virtual bool IsStopped();

	virtual void SetSpeed(f32 speed_ = 1.0f);
	virtual f32 GetSpeed();


	virtual void Tick();

private:
    irr::ITimer  *  mIrrlichtTimer;

    u32     mTime;
    f32     mTimeRest;
    u32     mLastRealTime;
    f32     mSpeed;
    u32     mLastTick;
    int     mIsRunning;
};

#endif // TIMER_H
timer.cpp:

Code: Select all

#include "timer.h"

Timer::Timer(irr::ITimer * irrlichtTimer_, bool startRunning_)
    : mIrrlichtTimer(irrlichtTimer_)
    , mTime(0)
    , mTimeRest(0.f)
    , mLastRealTime(0)
    , mSpeed(1.f)
    , mLastTick(0)
    , mIsRunning(startRunning_)
{
}

Timer::~Timer()
{
}

u32 Timer::GetTime()
{
    return mTime;
}

void Timer::SetTime(u32 time_)
{
    mTime = time_;
    mTimeRest = 0.f;
}

u32 Timer::GetLastTickInMs()
{
    return mLastTick;
}

f32 Timer::GetLastTickInSeconds()
{
    return static_cast<f32>(mLastTick) / 1000.f;
}


void Timer::Stop()
{
    mIsRunning = 0;
    mLastTick = 0;
}

void Timer::Start()
{
    mIsRunning = 1;
    if ( mIrrlichtTimer )
    {
        mLastRealTime = mIrrlichtTimer->getRealTime();
    }
}

bool Timer::IsStopped()
{
    return mIsRunning ? false : true;
}

void Timer::SetSpeed(f32 speed_)
{
    mSpeed = speed_;
}

f32 Timer::GetSpeed()
{
    return mSpeed;
}

void Timer::Tick()
{
    if ( mLastRealTime == 0 )
    {
        if ( mIrrlichtTimer )
        {
            mLastRealTime = mIrrlichtTimer->getRealTime();
        }
    }

    if ( mIsRunning )
    {
        u32 timeNow = 0;
        if ( mIrrlichtTimer )
        {
            timeNow = mIrrlichtTimer->getRealTime();
            f32 timeAdd = static_cast<float>(timeNow-mLastRealTime) * mSpeed + mTimeRest;
            mLastTick = static_cast<int>(timeAdd);
            mTime += mLastTick;
            mTimeRest = timeAdd - mLastTick;
        }
    }
    if ( mIrrlichtTimer )
    {
        mLastRealTime = mIrrlichtTimer->getRealTime();
    }
}
Initialize it with the Irllicht timer and update it regularly with the Tick() function. Then you have a timer which can be independently be stopped, started, etc.

If you need to have something with fixed timesteps it can for example be done like following in the update (mGameTimer is an instance of Timer):

Code: Select all

    mGameTimer->Tick();
    f32 timeTickSec = mGameTimer->GetLastTickInSeconds();
    static float  timeRest = 0.f;
    timeRest += timeTickSec;

    int countSteps = 0;
    while ( timeRest > 0.1f ) // 0.1 is the fixed stepsize
    {
        ++countSteps;
        timeRest -= 0.1; // stepsize
   }
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

I would use something like this:

Code: Select all

{
  // initialisation
  static ITimer* tmr = device->getTimer();
  static long lastTick = tmr->getTime();

  if((tmr->getTime() - lastTick) >= 120){
    fader->setColor(video::SColor(0,255,0,0));
    fader->fadeIn(200);
    HPplayer -= 10;
    attacktimer = 0;
    lastTick = tmr->getTime();
  }
}
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
mR.haHN
Posts: 49
Joined: Wed May 03, 2006 5:37 pm

Post by mR.haHN »

Thx Acki, it works fine :wink:

Sorry for my late answer, I didn´t have time to code last month(s)
Post Reply