Page 1 of 1

A "real" timer

Posted: Wed May 10, 2006 4:11 pm
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?

Posted: Wed May 10, 2006 4:18 pm
by Xharock
SDL, has a great timer system. Just in case you want to try it.

Posted: Wed May 10, 2006 4:21 pm
by mR.haHN
ehehe...what is SDL?

Posted: Wed May 10, 2006 4:27 pm
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

Posted: Wed May 10, 2006 4:49 pm
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
   }

Posted: Wed May 10, 2006 6:40 pm
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();
  }
}

Posted: Sun Jul 16, 2006 9:02 am
by mR.haHN
Thx Acki, it works fine :wink:

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