Cocos Creator-3.缓冲系统,动作系统,计时器

前言

官网官网!!!
cc.tween 能够对对象的任意属性进行缓动,功能类似于 cc.Action(动作系统)。但是 cc.tween 会比 cc.Action 更加简洁易用,因为 cc.tween 提供了链式创建的方法,可以对任何对象进行操作,并且可以对对象的任意属性进行缓动。

一、缓冲系统

Easing_API
Easing函数效果演示
下面是官方的案例(其实还是很好理解的!!)

//同时执行多个属性
cc.tween(this.node)
    // 同时对 scale, position, rotation 三个属性缓动
    .to(1, { scale: 2, position: cc.v2(100, 100), rotation: 90 })
    .start()

//支持缓动任意对象的任意属性
let obj = { a: 0 }
cc.tween(obj)
  .to(1, { a: 100 })
  .start()

//cc.tween 提供了两个设置属性的 API:to//by
cc.tween(node)
  .to(1, {scale: 2})      //duration:1s, node.scale === 2
  .by(1, {scale: 2})      // node.scale === 4 (2 + 2)
  .by(1, {scale: 1})      // node.scale === 5
  .to(1, {scale: 2})      // node.scale === 2
  .start()

//easing使用 easing 来使缓动更生动(就是行动的方式)
// 传入 easing 名字,直接使用内置 easing 函数
cc.tween().to(1, { scale: 2 }, { easing: 'sineOutIn'})

// 使用自定义 easing 函数
cc.tween().to(1, { scale: 2 }, { easing: t => t*t; })

// 只对单个属性使用 easing 函数
// value 必须与 easing 或者 progress 配合使用
cc.tween().to(1, { scale: 2, position: { value: cc.v3(100, 100, 100), easing: 'sineOutIn' } })

// 对所有属性自定义 progress
cc.tween().to(1, { scale: 2, rotation: 90 }, {
  progress: (start, end, current, ratio) => {
    return start + (end - start) * ratio;
  }
})

// 对单个属性自定义 progress
cc.tween().to(1, {
  scale: 2,
  position: {
    value: cc.v3(),
    progress: (start, end, current, t) => {
      // 注意,传入的属性为 cc.Vec3,所以需要使用 Vec3.lerp 进行插值计算
      return start.lerp(end, t, current);
    }
  }
})

//clone 函数会克隆一个当前的缓动,并接受一个 target 作为参数。
// 先创建一个缓动作为模板
let tween = cc.tween().to(4, { scale: 2 })

// 复制 tween,并使用节点 Canvas/cocos 作为 target
tween.clone(cc.find('Canvas/cocos')).start()
// 复制 tween,并使用节点 Canvas/cocos2 作为 target
tween.clone(cc.find('Canvas/cocos2')).start()

//*******重点********
//插入其他的缓动到队列中
let scale = cc.tween().to(1, { scale: 2 })
let rotate = cc.tween().to(1, { rotation: 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)

//并行执行缓动
//cc.tween 在链式执行时是按照 sequence 的方式来执行的,但是在编写复杂缓动的时候可能会需要同时并行执行多个队列,cc.tween 提供了 parallel 接口来满足这个需求。
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()

//重复执行
//repeat/repeatForever 函数会将前一个 action 作为作用对象。但是如果有参数提供了其他的 action 或者 tween,则 repeat/repeatForever 函数会将传入的 action 或者 tween 作为作用对象。
cc.tween(this.node)
    .by(1, { scale: 1 })
    // 对前一个 by 重复执行 10次
    .repeat(10)
    // 最后 node.scale === 11
    .start()

// 也可以这样用
cc.tween(this.node)
    .repeat(10,
        cc.tween().by(1, { scale: 1 })
    )
    .start()

// 一直重复执行下去
cc.tween(this.node)
    .by(1, { scale: 1 })
    .repeatForever()
    .start()
    
//延迟执行
cc.tween(this.node)
    // 延迟 1s
    .delay(1)
    .to(1, { scale: 2 })
    // 再延迟 1s
    .delay(1)
    .to(1, { scale: 3 })
    .start()

二、动作系统

动作系统 API 列表
(动作系统目前已不推荐使用,未来将逐步移除,建议使用 缓动系统 做为替代。)
动作系统可以在一定时间内对节点完成位移,缩放,旋转等各种动作。

//动作系统的使用方式也很简单,在 cc.Node 中支持如下 API:
// 创建一个移动动作
var action = cc.moveTo(2, 100, 100);
// 执行动作
node.runAction(action);
// 停止一个动作
node.stopAction(action);
// 停止所有动作
node.stopAllActions();

//开发者还可以给动作设置 tag,并通过 tag 来控制动作。
// 给 action 设置 tag
var ACTION_TAG = 1;
action.setTag(ACTION_TAG);
// 通过 tag 获取 action
node.getActionByTag(ACTION_TAG);
// 通过 tag 停止一个动作
node.stopActionByTag(ACTION_TAG);

//容器动作
//1.顺序动作 cc.sequence 顺序动作可以让一系列子动作按顺序一个个执行。示例:
 // 让节点左右来回移动
 var seq = cc.sequence(cc.moveBy(0.5, 200, 0), cc.moveBy(0.5, -200, 0));
 node.runAction(seq);
 //2.同步动作 cc.spawn 同步动作可以同步执行对一系列子动作,子动作的执行结果会叠加起来修改节点的属性。示例:
  // 让节点在向上移动的同时缩放
 var spawn = cc.spawn(cc.moveBy(0.5, 0, 50), cc.scaleTo(0.5, 0.8, 1.4));
 node.runAction(spawn);
 //3.重复动作 cc.repeat 重复动作用来多次重复一个动作。示例:
 // 让节点左右来回移动,并重复 5 次
 var seq = cc.repeat(
             cc.sequence(
                 cc.moveBy(2, 200, 0),
                 cc.moveBy(2, -200, 0)
             ), 5);
 node.runAction(seq);
 //4.永远重复动作 cc.repeatForever 顾名思义,这个动作容器可以让目标动作一直重复,直到手动停止。
  // 让节点左右来回移动并一直重复
 var seq = cc.repeatForever(
             cc.sequence(
                 cc.moveBy(2, 200, 0),
                 cc.moveBy(2, -200, 0)
             ));
 //5.速度动作 cc.speed 速度动作可以改变目标动作的执行速率,让动作更快或者更慢完成。
  // 让目标动作速度加快一倍,相当于原本 2 秒的动作在 1 秒内完成
 var action = cc.speed(
                 cc.spawn(
                     cc.moveBy(2, 0, 50),
                     cc.scaleTo(2, 0.8, 1.4)
                 ), 2);
 node.runAction(action);
 //6.我们给容器类型动作提供了更为方便的链式 API,动作对象支持以下三个 API:repeat、repeatForever、speed,这些 API 都会返回动作对象本身,支持继续链式调用。我们来看一个更复杂的动作示例:
 // 一个复杂的跳跃动画
this.jumpAction = cc.sequence(
    cc.spawn(
        cc.scaleTo(0.1, 0.8, 1.2),
        cc.moveTo(0.1, 0, 10)
    ),
    cc.spawn(
        cc.scaleTo(0.2, 1, 1),
        cc.moveTo(0.2, 0, 0)
    ),
    cc.delayTime(0.5),
    cc.spawn(
        cc.scaleTo(0.1, 1.2, 0.8),
        cc.moveTo(0.1, 0, -10)
    ),
    cc.spawn(
        cc.scaleTo(0.2, 1, 1),
        cc.moveTo(0.2, 0, 0)
    )
// 以 1/2 的速度慢放动画,并重复 5 次
).speed(2).repeat(5);


//动作回调(得好好理解)
//动作回调可以用以下的方式声明:
//第一个参数是处理回调的方法,第二个参数指定了处理回调方法的 context(也就是绑定 this),第三个参数是向处理回调方法的传参
var finished = cc.callFunc(this.myMethod, this, opt);
//可以这样使用传参:
var finished = cc.callFunc(function(target, score) {
    this.score += score;
}, this, 100); //动作完成后会给玩家加 100 分

//在声明了回调动作 finished 后,您可以配合 cc.sequence 来执行一整串动作并触发回调:
var myAction = cc.sequence(cc.moveBy(1, cc.v2(0, 100)), cc.fadeOut(1), finished);
///***注意:在 cc.callFunc 中不应该停止自身动作,由于动作是不能被立即删除,如果在动作回调中暂停自身动作会引发一系列遍历问题,导致更严重的 bug。

//缓动动作
var action = cc.scaleTo(0.5, 2, 2);
action.easing(cc.easeIn(3.0));

基础的缓动动作类cc.ActionEase

三,计时器

cc.Scheduler,主要的API!!
注意:cc.Node 不包含计时器相关
Component API
关于计时器的函数:

  • schedule:开始一个计时器
  • scheduleOnce:开始一个只执行一次的计时器
  • unschedule:取消一个计时器
  • unscheduleAllCallbacks:取消这个组件的所有计时器
//首先,先创建一个指向某个组件的变量,变量名为 component。
//1.开始一个计时器,,首先,先创建一个指向某个组件的变量,变量名为 component。计时器将每隔 5s 执行一次。
 component.schedule(function() {
     // 这里的 this 指向 component
     this.doSomething();
 }, 5);
 
 //2.更灵活的计时器计时器将在 10 秒后开始计时,每 5 秒执行一次回调,执行 3 + 1 次。
 // 以秒为单位的时间间隔
 var interval = 5;
 // 重复次数
 var repeat = 3;
 // 开始延时
 var delay = 10;
 component.schedule(function() {
     // 这里的 this 指向 component
     this.doSomething();
 }, interval, repeat, delay);
 
 //3.只执行一次的计时器(快捷方式),上面的计时器将在两秒后执行一次回调函数,之后就停止计时。
 component.scheduleOnce(function() {
     // 这里的 this 指向 component
     this.doSomething();
 }, 2);
 
 //4.取消计时器
 this.count = 0;
 this.callback = function () {
     if (this.count === 5) {
         // 在第六次执行回调时取消这个计时器
         this.unschedule(this.callback);
     }
     this.doSomething();
     this.count++;
 }
 component.schedule(this.callback, 1);
 

总结

是十分值得学习,以后还要更新的!!!

posted @ 2021-12-17 00:00  cactus9  阅读(215)  评论(0编辑  收藏  举报