欢迎关注公众号:“Cocos Creator 源码讲解”,一起学习。
/*
* Repeats an action a number of times.
* To repeat an action forever use the CCRepeatForever action.
* @class Repeat
* @extends ActionInterval
* @param {FiniteTimeAction} action
* @param {Number} times
* @example
* var rep = new cc.Repeat(cc.sequence(jump2, jump1), 5);
*/
/* 多次重复某个动作。
*/
cc.Repeat = cc.Class({
name: 'cc.Repeat',
extends: cc.ActionInterval,
ctor: function (action, times) {
this._times = 0;
this._total = 0;
this._nextDt = 0;
this._actionInstant = false;
this._innerAction = null;
/* tims不为空的时候,直接进行初始化,把action和times初始化到里面 */
times !== undefined && this.initWithAction(action, times);
},
/*
* @param {FiniteTimeAction} action
* @param {Number} times
* @return {Boolean}
*/
initWithAction: function (action, times) {
/* 初始化参数,总共时间=单个耗时*次数 */
var duration = action._duration * times;
/* 重置一些参数,一定返回true,不知道为啥要添加个if,后面逻辑添加个 return */
if (this.initWithDuration(duration)) {
/* repeat次数 */
this._times = times;
/* repeat的内置action */
this._innerAction = action;
/* 判断action类型为 cc.ActionInstant 这种类型立刻会执行,总次数减一,设置flag-_actionInstant为true*/
if (action instanceof cc.ActionInstant) {
this._actionInstant = true;
this._times -= 1;
}
this._total = 0;
return true;
}
return false;
},
/* 复制Action cc.Repeat */
clone: function () {
var action = new cc.Repeat();
this._cloneDecoration(action);
action.initWithAction(this._innerAction.clone(), this._times);
return action;
},
/* 设置target */
startWithTarget: function (target) {
this._total = 0;
/* 因为是多次 重复,所以,当前action的时间 除以总时间,获取所占总时间百分比 */
this._nextDt = this._innerAction._duration / this._duration;
cc.ActionInterval.prototype.startWithTarget.call(this, target);
this._innerAction.startWithTarget(target);
},
stop: function () {
/* 正在run的Action,执行stop */
this._innerAction.stop();
cc.Action.prototype.stop.call(this);
},
update: function (dt) {
dt = this._computeEaseTime(dt);
/* 重新赋值,设置局部变量 */
var locInnerAction = this._innerAction;
var locDuration = this._duration;
var locTimes = this._times;
var locNextDt = this._nextDt;
/* _total 执行了的次数 */
if (dt >= locNextDt) {
while (dt > locNextDt && this._total < locTimes) {
locInnerAction.update(1);
this._total++;
locInnerAction.stop();
locInnerAction.startWithTarget(this.target);
locNextDt += locInnerAction._duration / locDuration;
this._nextDt = locNextDt > 1 ? 1 : locNextDt;
}
// fix for issue #1288, incorrect end value of repeat 修复问题 #1288,重复的最终值不正确
if (dt >= 1.0 && this._total < locTimes) {
// fix for cocos-creator/fireball/issues/4310
locInnerAction.update(1);
this._total++;
}
// don't set a instant action back or update it, it has no use because it has no duration
/* // 不要设置或更新即时操作,它没有任何用处,因为它没有持续时间 */
if (!this._actionInstant) {
if (this._total === locTimes) {
locInnerAction.stop();
} else {
// issue #390 prevent jerk, use right update
locInnerAction.update(dt - (locNextDt - locInnerAction._duration / locDuration));
}
}
} else {
locInnerAction.update((dt * locTimes) % 1.0);
}
},
isDone: function () {
/* 根据当前已经执行的次数是否和总次数相等判断是否已经done */
return this._total === this._times;
},
/* 创建一个action的reverse */
reverse: function () {
var action = new cc.Repeat(this._innerAction.reverse(), this._times);
this._cloneDecoration(action);
this._reverseEaseList(action);
return action;
},
/*
* Set inner Action.
* @param {FiniteTimeAction} action
*/
/* 设置当前的Action */
setInnerAction: function (action) {
if (this._innerAction !== action) {
this._innerAction = action;
}
},
/*
* Get inner Action.
* @return {FiniteTimeAction}
*/
getInnerAction: function () {
return this._innerAction;
}
});
/**
* !#en Creates a Repeat action. Times is an unsigned integer between 1 and pow(2,30)
* !#zh 重复动作,可以按一定次数重复一个动,如果想永远重复一个动作请使用 repeatForever 动作来完成。
* @method repeat
* @param {FiniteTimeAction} action
* @param {Number} times
* @return {ActionInterval}
* @example
* // example
* var rep = cc.repeat(cc.sequence(jump2, jump1), 5);
*/
cc.repeat = function (action, times) {
return new cc.Repeat(action, times);
};