对应源码位置:(1)cocos2d-x-3.3\cocos\base\Scheduler.*
Scheduler 一般译作 定时器,主要用于控制触发每帧都会需要的update以及用户自定义的更新操作。
Timer类的实现
这是一个 Light-weight timer,提供了指定delay延迟时间后,每次经过seconds时间间隔,触发trigger时间一次,执行次数为 _repeat+1,或者称为无限次。主要思想为通过 update(float dt)
每次累计dt时间,计算是否到达触发时机。
class CC_DLL Timer : public Ref
{
protected:
Timer();
public:
/** get interval in seconds */
inline float getInterval() const {
return _interval; };
/** set interval in seconds */
inline void setInterval(float interval) {
_interval = interval; };
void setupTimerWithInterval(float seconds, unsigned int repeat, float delay);
virtual void trigger() = 0;
virtual void cancel() = 0;
/** triggers the timer */
void update(float dt);
protected:
Scheduler* _scheduler; // weak ref
float _elapsed;//经过的时间
bool _runForever;
bool _useDelay;
unsigned int _timesExecuted;
unsigned int _repeat; //0 = once, 1 is 2 x executed
float _delay;
float _interval;
};
其具体实现代码为,内部有详细注释:
Timer::Timer()
: _scheduler(nullptr), _elapsed(-1), _runForever(false), _useDelay(false), _timesExecuted(0), _repeat(0), _delay(0.0f), _interval(0.0f)
{
}
void Timer::setupTimerWithInterval(float seconds, unsigned int repeat, float delay)
{
_elapsed = -1;
_interval = seconds;
_delay = delay;
_useDelay = (_delay > 0.0f) ? true : false;
_repeat = repeat;
_runForever = (_repeat == CC_REPEAT_FOREVER) ? true : false;
}
void Timer::update(float dt)
{
//若为第一次,则初始化 经过的时间为0,执行次数为0
if (_elapsed == -1)
{
_elapsed = 0;
_timesExecuted = 0;
}
else
{
//走到这里 显然不是第一次了
//如果无限循环以及没有使用延迟
if (_runForever && !_useDelay)
{
//standard timer usage
//直接累加时间 若到了间隔时长 则触发事件 经过时间置0 周而复始
_elapsed += dt;
if (_elapsed >= _interval)
{
trigger();
_elapsed = 0;
}
}
else
{
//advanced usage
//不满足上述假设 则非无限或者有些延迟
_elapsed += dt;
//有延迟
if (_useDelay)
{
//则 先消耗延迟时间 这里注意的是 延迟时间过了后 直接触发了一次 没有在等从零开始的 _interval
//接下来 不在考虑延迟 一视同仁
if( _elapsed >= _delay )
{
trigger();
_elapsed = _elapsed - _delay;
_timesExecuted += 1;
_useDelay = false;
}
}
//无延迟 有限次
else
{