欢迎关注公众号:“Cocos Creator 源码讲解”,一起学习。
/*
* Spawn a new action immediately
* @class Spawn
* @extends ActionInterval
*/
/* 叠加两个action,对某一个node执行生效。 */
cc.Spawn = cc.Class({
name: 'cc.Spawn',
extends: cc.ActionInterval,
ctor: function (tempArray) {
this._one = null;
this._two = null;
/* 判断参数类型为Array与否,是的话,直接用,不是的话,用arguments */
var paramArray = (tempArray instanceof Array) ? tempArray : arguments;
if (paramArray.length === 1) {
cc.errorID(1020);
return;
}
/* 下标最后一位 */
var last = paramArray.length - 1;
/* 最后一个参数不能为空 */
if ((last >= 0) && (paramArray[last] == null))
cc.logID(1015);
if (last >= 0) {
var prev = paramArray[0], action1;
for (var i = 1; i < last; i++) {
if (paramArray[i]) {
action1 = prev;
prev = cc.Spawn._actionOneTwo(action1, paramArray[i]);
}
}
this.initWithTwoActions(prev, paramArray[last]);
}
},
/* initializes the Spawn action with the 2 actions to spawn
* @param {FiniteTimeAction} action1
* @param {FiniteTimeAction} action2
* @return {Boolean}
*/
/* 使用 2 个要生成的操作来初始化 Spawn 操作 */
initWithTwoActions: function (action1, action2) {
if (!action1 || !action2) {
cc.errorID(1027);
return false;
}
var ret = false;
/* 两个action 分别的执行时间 */
var d1 = action1._duration;
var d2 = action2._duration;
/* 这个一定返回true,为啥做if条件处理呢?感觉多此一举 */
if (this.initWithDuration(Math.max(d1, d2))) {
this._one = action1;
this._two = action2;
/* 时间不一致,第一个时间大于第二个,设置一个delaytime的延时action 把第二个action重新赋值,目的是按照最长时间拉齐action */
if (d1 > d2) {
this._two = cc.Sequence._actionOneTwo(action2, cc.delayTime(d1 - d2));
} else if (d1 < d2) {
this._one = cc.Sequence._actionOneTwo(action1, cc.delayTime(d2 - d1));
}
ret = true;
}
return ret;
},
/* spawn 复制 */
clone: function () {
var action = new cc.Spawn();
this._cloneDecoration(action);
action.initWithTwoActions(this._one.clone(), this._two.clone());
return action;
},
/* 调用 cc.ActionInterval的startWithTarget方法,设置target */
startWithTarget: function (target) {
cc.ActionInterval.prototype.startWithTarget.call(this, target);
this._one.startWithTarget(target);
this._two.startWithTarget(target);
},
/* 两个action 同时执行stop,调用Actino的stop()方法 */
stop: function () {
this._one.stop();
this._two.stop();
cc.Action.prototype.stop.call(this);
},
/* 每一帧更新,两个actinon,分别执行update */
update: function (dt) {
dt = this._computeEaseTime(dt);
if (this._one)
this._one.update(dt);
if (this._two)
this._two.update(dt);
},
/* 动作翻转 */
reverse: function () {
var action = cc.Spawn._actionOneTwo(this._one.reverse(), this._two.reverse());
this._cloneDecoration(action);
this._reverseEaseList(action);
return action;
}
});
/**
* !#en Create a spawn action which runs several actions in parallel.
* !#zh 同步执行动作,同步执行一组动作。
* @method spawn
* @param {FiniteTimeAction|FiniteTimeAction[]} actionOrActionArray
* @param {FiniteTimeAction} ...tempArray
* @return {FiniteTimeAction}
* @example
* // example
* var action = cc.spawn(cc.jumpBy(2, cc.v2(300, 0), 50, 4), cc.rotateBy(2, 720));
* todo:It should be the direct use new
*/
cc.spawn = function (/*Multiple Arguments*/tempArray) {
var paramArray = (tempArray instanceof Array) ? tempArray : arguments;
if (paramArray.length === 1) {
cc.errorID(1020);
return null;
}
if ((paramArray.length > 0) && (paramArray[paramArray.length - 1] == null))
cc.logID(1015);
var prev = paramArray[0];
for (var i = 1; i < paramArray.length; i++) {
if (paramArray[i] != null)
prev = cc.Spawn._actionOneTwo(prev, paramArray[i]);
}
return prev;
};
cc.Spawn._actionOneTwo = function (action1, action2) {
var pSpawn = new cc.Spawn();
pSpawn.initWithTwoActions(action1, action2);
return pSpawn;
};