基本方法:
to:对属性进行绝对值计算,最终的运行结果即是设置的属性值,即改变到某个值
by:对属性进行相对值计算,最终的运行结果是设置的属性值加上开始运行时节点的属性值,即变化值
cc.tween(this.node) .to(1, { position: cc.v2(100, 100), angle: -90 }) .by(1, { scale: 2 }) .start();
贝塞尔曲线:
cc.tween(this.node)
.bezierTo(3, cc.v2(0, cc.winSize.height / 2), cc.v2(300, -cc.winSize.height / 2), cc.v2(300, 100)) .start();
· 支持缓动任意对象的任意属性
let obj = { a: 0 }cc.tween(obj) .to(1, { a: 100 }) .start();
· 变速 easing
cc.tween(this.node) .to(1, { scale: 2, position: cc.v2(100, 100), angle: -90 }, cc.easeIn(3.0)) .start();
· 自定义 progress
// 对所有属性自定义 progresscc.tween().to(1, { scale: 2, rotation: 90 }, { progress: (start, end, current, ratio) => { return start + (end - start) * ratio; }})
// 对单个属性自定义 progresscc.tween().to(1, { scale: 2, position: { value: cc.v3(), progress: (start, end, current, t) => { // 注意,传入的属性为 cc.Vec3,所以需要使用 Vec3.lerp 进行插值计算 return start.lerp(end, t, current); } }})
· 插入其他的缓动到队列中
let scale = cc.tween().to(1, { scale: 2 });let rotate = cc.tween().to(1, { angle: -90 });let move = cc.tween().to(1, { position: cc.v3(100, 100, 100) });
// 先缩放再旋转cc.tween(this.node).then(scale).then(rotate);// 先缩放再移动cc.tween(this.node).then(scale).then(move);
then 不仅可以插入 tween,还可以插入 action,比如跳跃(jumpTo)等
let jumpTo = cc.jumpTo(2, cc.v2(300, 300), 50, 4);cc.tween(this.node) .then(jumpTo) .start();
· 并行执行缓动
let t = cc.tween;t(this.node) // 同时执行两个 cc.tween .parallel( t().to(1, { scale: 2 }), t().to(2, { position: cc.v2(100, 100) }) ) .call(() => { console.log('All tweens finished.'); }) .start();
· 回调
cc.tween(this.node) .to(2, { angle: -90 }) .to(1, { scale: 2 }) // 当前面的动作都执行完毕后才会调用这个回调函数 .call(() => { cc.log('This is a callback'); }) .start();
· 重复执行
repeat:重复指定次数
cc.tween(this.node) .by(1, { scale: 1 }) // 对前一个 by 重复执行 10次 .repeat(10) // 最后 node.scale === 11 .start();
repeatForever:无限重复
cc.tween(this.node) .by(1, { scale: 1 }) .repeatForever() .start();
union:
repeat/repeatForever 函数只会将前一个 action 作为作用对象,如果希望重复多个 action 话,可是使用 union(将之前所有的 action 整合为一个 action)
cc.tween(this.node) .by(2, { angle: -90 }) .by(1, { scale: 2 }) .union() .repeat(10) .start();
· 延迟执行
cc.tween(this.node) // 延迟 1s .delay(1) .to(1, { scale: 2 }) // 再延迟 1s .delay(1) .to(1, { scale: 3 }) .start();
· 暂停/恢复/停止
暂停本节点上所有正在运行的动作
this.node.pauseAllActions();
恢复运行本节点上所有暂停的动作
this.node.resumeAllActions();
停止当前 tween
tween.stop();
停止所有指定对象的缓动
cc.Tween.stopAllByTarget(this.node);
停止所有指定标签的缓动cc.Tween.stopAllByTag(100);
tween扩展中途暂停、播放速率
cocos 提供的暂停/恢复只能控制节点上所有的动作,所以这里通过对 tween 扩展,实现单个 tween 的控制
tween 在 start 后,会返回的是一个 _finalAction,通过对其属性的读写,可以实现一些想要的功能
下面的代码中扩展了 tween 的暂停、恢复、倍速播放、总时长、已进行时长、跳转到指定时间、根据标签暂停、恢复
cc.ActionInterval.prototype.step = function (dt) { if (this.paused) { return; }
if (this._firstTick && !this._goto) { this._firstTick = false; this._elapsed = 0; } else { this._elapsed += dt; }
let t = this._elapsed / (this._duration > 0.0000001192092896 ? this._duration : 0.0000001192092896); t = (1 > t ? t : 1); this.update(t > 0 ? t : 0);
//Compatible with repeat class, Discard after can be deleted (this._repeatMethod) if (this._repeatMethod && this._timesForRepeat > 1 && this.isDone()) { if (!this._repeatForever) { this._timesForRepeat--; } this.startWithTarget(this.target); this.step(this._elapsed - this._duration); }};
cc.Tween.prototype.pause = function () { this._finalAction.paused = true;};
cc.Tween.prototype.resume = function () { this._finalAction.paused = false;};
cc.Tween.prototype.speed = function (speed) { this._finalAction._speedMethod = true; this._finalAction._speed = speed;}
cc.Tween.prototype.duration = function () { return this._finalAction._duration;}
cc.Tween.prototype.elapsed = function () { return this._finalAction._elapsed;}
cc.Tween.prototype.goto = function (time) { this._finalAction._goto = true; this._finalAction._elapsed = time;}
cc.ActionManager.prototype.pauseByTag = function (tag, pause) { if (tag === cc.Action.TAG_INVALID) { cc.logID(1002); }
let hashTargets = this._hashTargets; for (let name in hashTargets) { let element = hashTargets[name]; for (let i = 0, l = element.actions.length; i < l; ++i) { let action = element.actions[i]; if (action && action.getTag() === tag) { action.paused = pause; break; } } }}
cc.Tween.pauseByTag = function (tag) { cc.director.getActionManager().pauseByTag(tag, true);}
cc.Tween.resumeByTag = function (tag) { cc.director.getActionManager().pauseByTag(tag, false);}
因为是自己扩展的方法,creator.d.ts 中没有相关声明,可以利用 vs code 来自动添加相关声明



