1. 成员变量
Repeat:
unsigned int _times; //create参数 unsigned int _total; //执行的次数 float _nextDt; //startWithTarget计算,当前所有action已执行的时间占总时间占比,轮到下次Repeat需要的时间进度 bool _actionInstant; //create中对action是否瞬时的判断 FiniteTimeAction *_innerAction; //create参数
RepeatForever:
ActionInterval *_innerAction; //create参数
2. create
Repeat::create(FiniteTimeAction *action, unsigned int times) RepeatForever::create(ActionInterval *action)
Repeat:
用参数赋值两个成员变量后,判断action是否为瞬时动作:
ActionInterval::initWithDuration(d) // 动作次数*一个动作时长
_actionInstant = dynamic_cast<ActionInstant*>(action) ? true : false;
_total = 0;
RepeatForever:用参数设置变量action。
3. startWithTarget
Repeat:
_total = 0; _nextDt = _innerAction->getDuration()/_duration; //一个action时间占总时间的占比 ActionInterval::startWithTarget(target); _innerAction->startWithTarget(target);
RepeatForever:
ActionInterval::startWithTarget(target);
_innerAction->startWithTarget(target);
4. update
RepeatForever没有update方法。每一帧,RepeatForever step方法调用action的step。
Repeat:
简要的说,如果当前进度没到触发下次Repeat的进度时,继续执行本次未完成的update。到了触发下次Repeat进度时,先对本次Repeat执行完成,为下次Repeat的action进行初始化,并为触发下下次Repeat的进度进行计算。如果到了总次数,停止当前action,否则执行action update。
void Repeat::update(float dt) { if (dt >= _nextDt) // 当前进度到达下次Repeat触发进度 { while (dt >= _nextDt && _total < _times) //到达下次Repeat触发进度且执行次数没到要求,进入循环 { if (!(sendUpdateEventToScript(1.0f, _innerAction))) _innerAction->update(1.0f); //执行action _total++; //执行好了,次数+1 _innerAction->stop(); _innerAction->startWithTarget(_target); //重新初始化action _nextDt = _innerAction->getDuration()/_duration * (_total+1); //设置新的触发一次Repeat的进度 } //... if (!_actionInstant) //不能是瞬时动作 { if (_total == _times) //到达总次数限制 { _innerAction->stop(); } else { if (!(sendUpdateEventToScript(dt - (_nextDt - _innerAction->getDuration()/_duration), _innerAction))) _innerAction->update(dt - (_nextDt - _innerAction->getDuration()/_duration)); //执行 } } } else //没到触发下一次Repeat的进度,继续执行本次Repeat的action { if (!(sendUpdateEventToScript(fmodf(dt * _times,1.0f), _innerAction))) _innerAction->update(fmodf(dt * _times,1.0f)); //参数为当前Repeat的进度 } }