今天有个同事使用cc.tween的时候出了个问题,
cc.tween(node)
.delay(0.5)
.call(()=>{
cc.log(‘test’);
})
.repeat(5)
.start()
会打印几个‘test’,答案是4次并且瞬间打印4次,这里是用错了repeat,因为repeat是把上一个链式动作当成需要的参数传入并重复
正确的写法有两种:
cc.tween(node)
.delay(0.5)
.call(()=>{
cc.log(‘test’);
})
.union()
.repeat(5)
.start()
或
cc.tween(node)
.repeat(
5,
cc.tween()
.delay(0.5)
.call(()=>{
cc.log(‘test’);
})
)
.start()
union 函数是将之前所有的 action 整合为一个 action这样就可以实现想要的需求
抛开用法上的错误,还有个问题就是为什么call不能执行5次而是4次呢,于是就找到了Repeat的实现
initWithAction:function (action, times) {
var duration = action._duration * times;
if (this.initWithDuration(duration)) {
this._times = times;
this._innerAction = action;
if (action instanceof cc.ActionInstant){
this._actionInstant = true;
this._times -= 1;
}
this._total = 0;
return true;
}
return false;
},
update:function (dt) {
dt = this._computeEaseTime(dt);
var locInnerAction = this._innerAction;
var locDuration = this._duration;
var locTimes = this._times;
var locNextDt = this._nextDt;
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
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);
}
},
通过这两个函数可以很清楚的知道当传入动作是瞬时动作时会直接把 this._times -1,然后update执行时只有当this._total < this._times时才会重复动作,所以比如你传入重复次数为1,那么根本就不会执行
虽然正常开发过程中很少会直接把瞬时动作进行重复,因为没有意义,但是这个减一的设计。。。