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.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);
总结
是十分值得学习,以后还要更新的!!!