hmm. I'm not sure how much of my system you want to see. Could get lengthy here, but I'll try and post most of it. For the timing system, I rely on these classes whcih I have in a file I named eventtimer.h
Code: Select all
#ifndef eventtimer_h
#define eventtimer_h
class CEventTimerBase
{
public:
virtual bool isTimeout(long time)=0;
};
//I'm testing speed optimizations with template programming here
template< typename returntype,typename T, returntype(T::*func)()>
class CEventTimer : public CEventTimerBase
{
public:
CEventTimer(long _timeout, T *_instance)
{
instance=_instance;
timeout=_timeout;
}
virtual bool isTimeout(long time)
{
if(time >= timeout)
{
(*instance.*func)();
return true;
}
return false;
}
protected:
T *instance;
long timeout;
};
template< typename returntype,typename T,typename T1, returntype(T::*func)(T1)>
class CEventTimer1Param : public CEventTimerBase
{
public:
CEventTimer1Param(long _timeout,T *_instance,T1 _param1)
{
instance=_instance;
param1=_param1;
timeout=_timeout;
}
virtual bool isTimeout(long time)
{
if(time >= timeout)
{
(*instance.*func)(param1);
return true;
}
return false;
}
protected:
T *instance;
T1 param1;
long timeout;
};
template<typename returntype,typename T,typename T1,typename T2, returntype(T::*func)(T1,T2)>
class CEventTimer2Param : public CEventTimerBase
{
public:
CEventTimer2Param(long _timeout,T *_instance,T1 _param1,T2 _param2)
{
instance=_instance;
param1=_param1;
param2=_param2;
timeout=_timeout;
}
virtual bool isTimeout(long time)
{
if(time >= timeout)
{
(*instance.*func)(param1,param2);
return true;
}
return false;
}
protected:
T *instance;
T1 param1;
T2 param2;
long timeout;
};
#endif
My main game class keeps a list CEventTimerBase and updates them all with isTimeout every frame. Each one is checked every frame, but it's an inexpensive test. My main game class has the list as a member like this
Code: Select all
static core::list<CEventTimerBase*> timedEvents;
in my main game loop I do this
Code: Select all
//now check event timers
core::list<CEventTimerBase*>::Iterator iterate=timedEvents.begin();
time=getGameTime();
while(iterate!= timedEvents.end())
{
if((*iterate)->isTimeout(time))
{
delete *iterate;
iterate=timedEvents.erase(iterate);
}
else
{
iterate++;
}
}
use any other timing function in place of my getGameTime(). Internally that just calls the irrlicht timer anyway.
So that's my timing system. Now how to use it specifically with weapons. . .
each weapon maintains a triggerState enumeration variable. I was going to show you my enumeration, but I just realized a sligt problem with it that I need to tweak. The general method still works, however.
When the player presses the fire button or lets it up the triggerState is set differently. In my fire function I have something like this
Code: Select all
if(triggerState & TRIGGER_PRESSED)
{
//do other firing stuff
//here we add the code to make this gun repeat
CEventTimer<void, CWeaponProjectile, &CWeaponProjectile::fire> *event=new CEventTimer<void, CWeaponProjectile, &CWeaponProjectile::fire>(CGame::getGameTime() + rate,this);
CGame::addTimedEvent(event);
}
//test for any other important trigger states we may have
note that the fire function will always set a timed callback to itself, but if the TRIGGER_PRESSED bit of triggerState is no longer set the loop will end. In a way it's similar toa recursive function, except that the recursion is delayed
CGame::addTimedEvent is a function I forgot to show you. It simply adds a an event to our list to be processed
Code: Select all
static void addTimedEvent(CEventTimerBase* event){timedEvents.push_back(event);}
I know that was very long, so it may not be that helpful, but it's there if anyone wants to look at it. Please not that that event timer system is a core component of my game, it's a bit too complicated to put in merely for shooting and there are probably easier ways to get a similar effect for shooting if that's the only thing you need that sort of timed function calling for. I find it a useful and flexible system, however.