Cocos 3.x Tween 缓动

参考
cocos学习笔记 cc.tween
Cocos 3.0 缓动系统

一、基本用法

cc.tween 在调用 start 时会将之前生成的 action 队列重新组合生成一个 cc.sequence 队列,依次执行。

  • to改变到某个值
  • by 变化值
 cc.tween(this.node)
//to,在第一秒的时候放大为2倍,位置为(100,100),角度变化到120
.to(1,{scale:2,position:cc.v2(100,100),rotation:120})
//by,在第二秒时,缩放变化1.5倍,即最终放大为原始大小的3倍,位置变化了(100,100),即现在位置为(200,200)
.by(1,{scale:1.5,position:cc.v2(100,100)})
//在第三秒时缩放为原来的大小,位置设置为(0,0),然后加了一个缓动效果backOut
.to(1,{scale:1,position:cc.v2(0,0)},{easing:"backOut"})
.start();

cc.tween还可以缓动任意对象的任意属性,如

var obj = { a: 0 }
cc.tween(obj)
.to(1, { a: 100 })
.start()
二、可选属性

以to为例,参考cc.d.ts

        /**
         * @en
         * Add an action which calculate with absolute value.
         * @zh
         * 添加一个对属性进行绝对值计算的 action。
         * @method to
         * @param {number} duration 缓动时间,单位为秒
         * @param {Object} props 缓动的属性列表
         * @param {Object} [opts] 可选的缓动功能
         * @param {Function} [opts.progress]
         * @param {Function|String} [opts.easing]
         */
        to(duration: number, props: __private.cocos_tween_tween_ConstructorType, opts?: ITweenOption): Tween;

可选属性定义如下:

interface ITweenOption {
    easing?: TweenEasing | ((k: number) => number);
    progress?: (start: number, end: number, current: number, ratio: number) => number;
    onStart?: (target: object) => {};
    onUpdate?: (target: object, ratio: number) => {};
    onComplete?: (target: object) => {};
}

与 Creator v2.x 不同的是新增了 onStart、onUpdate、onComplete 等属性,这些属性是回调函数,调用时会传入缓动的目标。

另外,onUpdate 调用时还会多传入一个目前缓动的进行值,范围为 (0-1]。

以 onUpdate 为例,以下代码缓动一个位置,然后在 onUpdate 中将其设置到多个对象上,这样就像是缓动的合批。

import { Node, tween, Vec3 } from 'cc';
const nodeArray: Node[] = []; // 此处替换成你的节点数组
const tweenTargetVec3 = new Vec3();
tween(tweenTargetVec3)
    .by(1, new Vec3(1, 1, 1), {
        'onUpdate': (target: Vec3, ratio: number) => {
            for (let i = 0; i < nodeArray.length; i++)
                nodeArray[i].worldPosition = target;
        }
    }).start();
三、示例

具体的使用方法,详情请参考范例 Tween(GitHub | Gitee)。

1.repeat和repeatForever
 * 添加一个重复 action,这个 action 会将前一个动作作为他的参数。
 * @param {number} repeatTimes 重复次数
 * @param {Tween} embedTween 可选,嵌入 Tween
 */
repeat(repeatTimes: number, embedTween?: Tween): Tween;

 * 添加一个永久重复 action,这个 action 会将前一个动作作为他的参数。
 * @method repeatForever
 * @param {Tween} embedTween 可选,嵌入 Tween
 */
repeatForever(embedTween?: Tween): Tween;

下面两种写法效果一样的:

onLoad () {
    this.tweenRepeat = tween(this.node)
        .by(1, { scale: new Vec3(2, 2, 2) })
        // 对前一个 by 重复执行 3次
        .repeat(3)
        .call(() => { console.log('All tweens finished.') })
    //另外一种写法,repeat 重复的是嵌入的 Tween
    this.tweenRepeat = tween(this.node)
        .repeat(3, tween().by(1, { scale: new Vec3(2, 2, 2) }))

    // 一直重复执行下去
    this.tweenRF = tween(this.node)
        .by(1, { scale: new Vec3(2, 2, 2) })
        .repeatForever()
}

onEnable () {
    this.tweenRepeat.start();
}

onDisable () {
    this.tweenRepeat.stop();
}
2.delay

效果:方块会变大两次,第二次会等待1秒再变大

this.tweenDelay = tween(this.node)
    // 延迟 1s
    .delay(1)
    .to(1, { scale: new Vec3(2, 2, 2) })
    // 再延迟 1s
    .delay(1)
    .to(1, { scale: new Vec3(3, 3, 3) })

效果:方块在一秒后消失

/**
 * 注意 target 需要是 Node 的,才可以使用 removeSelf
 */
this.tweenRemoveSelf = tween(this.node)
    .delay(1)
    .removeSelf()

效果:方块会不断的显示和隐藏

/**
 * 注意 target 需要是 Node 的,才可以使用 show 和 hide
 */
this.tweenSH = tween(this.node)
    .delay(0.1)
    .hide()
    .delay(0.1)
    .show()
    .union()
    .repeatForever()

注:

         * 将之前所有的 action 整合为一个 action。
         */
        union(): Tween;
3.parallel
this.tweenParallel = tween(this.node)
    // 同时执行两个 Tween
    .parallel(
        tween().to(2, { scale: new Vec3(1, 2, 3) }),
        tween().to(2, { position: new Vec3(3, 0, 3) })
    )
    .call(() => {
        console.log('All tweens finished.')
    })

也可以传一个数组,参考:

         * 添加一个并行 action。
         */
        parallel(...args: Tween[]): Tween;
4.then

效果:方块会先缩放,再旋转,再移动

let scale = tween().to(1, { scale: new Vec3(2, 2, 2) })
let rotate = tween().to(1, { eulerAngles: new Vec3(45, 45, 45) })
let move = tween().to(1, { position: new Vec3(0, 5, 0) })

// 先缩放,再旋转,再移动
this.tweenThen = tween(this.node)
    .then(scale)
    .then(rotate)
    .then(move)
5.stop

效果:方块缩放后,就会停止运动

let scale = tween().to(1, { scale: new Vec3(3, 3, 3) })
let rotate = tween().to(1, { rotation: new Quat(Math.sin(60), Math.sin(60), Math.sin(60), Math.cos(60)) })

this.tweenStop = tween(this.node)
    .then(scale)
    .call(() => {
        // 停止缓动
        this.tweenStop.stop();
    })
    .then(rotate)

注:还有其它停止方法

 * 停止所有缓动
 */
static stopAll(): void;
/**
 * @zh
 * 停止所有指定标签的缓动
 */
static stopAllByTag(tag: number, target?: object): void;
/**
 * @zh
 * 停止所有指定对象的缓动
 */
static stopAllByTarget(target?: object): void;
6.progress

相对于 easing,自定义 progress 函数可以更自由的控制缓动的过程。

效果:方块会移动,然后瞬间变大,再变小

// 对所有属性自定义 progress
const scaleTween = tween(this.node)
    .to(2, { scale: new Vec3(3, 2, 1) }, {
        progress: (start: number, end: number, current: number, ratio: number) => {
            return start + (end - start) * ratio;
        }
    })

// 对单个属性自定义 progress
this.tweenCP = tween(this.node)
    .to(2, { position: new Vec3(2, 2, -2) }, {
        progress: (start: number, end: number, current: number, ratio: number) => {
            return start + (end - start) * ratio * ratio * ratio;
        }
    }).reverseTime(scaleTween)
7.回调

效果:方块会变大,一秒后会瞬移,
接着继续变大,然后瞬间旋转

private tween!: Tween;
private _scale = new Vec3(1, 1, 1);
onLoad () {
    const that = this;
    let times = 0;
    this.tween = tween(this._scale)
        // 延迟 1s
        .delay(1)
        .by(1, new Vec3(1, 1, 1), {
            'onStart': () => {
                // 第二遍开始的时候,移动node
                if (times == 1) that.node.translate(new Vec3(0, 10, 0));
            },
            'onUpdate': () => {
                that.node.scale = that._scale;
            },
            'onComplete': () => {
                // 第三遍完成的时候, 旋转Node
                if (times == 2) that.node.rotate(Quat.fromEuler(new Quat(), 0, 45, 0));
                times++;
            }
        })
        .repeat(3)
}
8.clone
         * 克隆当前 tween。
         */
        clone(target: T): Tween;

效果:两个方块会变大,然后停止

private tweenClone0!: Tween<{}>;
private tweenClone1!: Tween<{}>;

onLoad () {
    // 先创建一个缓动作为模板
    let tweenTemplate = tween({}).to(4, { scale: new Vec3(3, 3, 3) })

    // 复制 tween,并使用节点 cocos 作为 target
    this.tweenClone0 = tweenTemplate.clone(find('TweenClone/cocos')!);

    // 复制 tween,并使用节点 cocos2 作为 target
    this.tweenClone1 = tweenTemplate.clone(find('TweenClone/cocos2')!);
}

onEnable () {
    this.tweenClone0.start()
    this.tweenClone1.start()
}

onDisable () {
    this.tweenClone0.stop()
    this.tweenClone1.stop()
}
9.cc.tween,我想要缓动cc.blink,闪烁动作,可是cc.blick并没有to和by缓动属性,请问下该怎么设置

你可能感兴趣的:(Cocos 3.x Tween 缓动)