基础概念
关于动画
动画作为数字媒体中最生动的视觉效果,在游戏中当然也必不可少,界面,交互操作的反馈,操作行为,这些看似死板的东西,也能在动画的加持下变的不那么僵硬,所以动画是非常重要的部分。
关于动作
这个动作并不是单纯的指现实动作片的那种帅气的动作。而是指通过一些手段,给某个节点下达一系列行为和操作,最简单动作的比如移动,放大,缩小,换颜色等等,这些操作(动作)通常会通过动画的效果直接呈现出来,换句话说,动作系统是为了实现动画。
动画原理和帧循环
这里动画是通过把很多张图片通过以眼睛无法察觉到的速度播放,形成的效果,游戏里要实现动画,肯定也绕不开这个原理,所以游戏引擎里都自带了一个大循环,只要没关闭游戏,那么这个循环就会一直循环下去,这个循环就是帧循环,帧循环通常以秒为单位,比如1秒循环60次,那么就称为60帧,就是说1秒钟内,游戏中所有的资源刷新了60次,动画就是通过在这60帧内插入关键的图片帧,在游戏自动帧循环进行刷新的时候自动刷新播放出来的效果,就是人眼中的动画
使用引擎界面动画编辑器实现简单的动画
这个动画编辑器就在控制台的右边一栏里
![295375dcffd001d9231298afd8256aae.png](https://i-blog.csdnimg.cn/blog_migrate/6ea59372115a945254d8be89f54412be.jpeg)
如图片中的位置,当然一个普通的节点是无法使用动画编辑器的,必须为它添加上Animation组件,翻译过来就是动画组件,可以直接点击图片中的添加Animation组件进行添加,也可以在节点的属性检查器中点击添加组件,其它组件中找到Animation添加,如图,一个组件可以拥有多个单独的动画剪辑Clip文件,这些动画会被存放在Animation组件的Clips的容器里,方便管理使用。
![10477f3311fa9461593aeb5e0050690b.png](https://i-blog.csdnimg.cn/blog_migrate/8e1bf58df34668c30f677f2ca259890a.png)
如图有了Animation组件后,就应该为动画组件,添加画剪辑文件(Clip)了,可以在资源管理器下新建一个Animation文件夹专门存放Clip文件,可以直接点击新建Clip文件,也可以在资源管理器中右键新建Animation Clip文件,完成了添加动画组件,添加动画剪辑后,就可以正式使用动画编辑器了。这里新添加一个test动画剪辑演示
注意:还要把资源管理器里对应的动画剪辑Clip拖拽到Animation组件下的Clips相应的节点才能读取和使用!
![3339335dd57fda08e938b2dc63044ecb.png](https://i-blog.csdnimg.cn/blog_migrate/a42cc700ef70fcedf9d4edf324a6ca2b.jpeg)
然后就可以点击最左上角开始编辑动画。
注意:一旦进入了编辑模式,一定要记住任何对节点的操作都会被记作到当前的动画剪辑当中,到时候会产生无法预估的错误,所以在动画编辑模式下不要随意修改当前节点的状态属性,只进行对自己想要动画效果的属性编辑,而且编辑完成之后一定要ctrl+s保存编辑好的动画剪辑在点击左上角进入时的位置退出动画编辑模式。
如图:动画编辑模式下会自动把除当前挂载动画组件的节点和它的子节点以外的节点设置为禁用,就是为了防止误操作被保存到动画剪辑当中。
![5376fcc77e7a877fdde7fdffde23e9a4.png](https://i-blog.csdnimg.cn/blog_migrate/b74f0d2ed403ee4203e269b8a5cacdbc.png)
![a971a06f3f7c69f30d19f55dc43e0e3f.png](https://i-blog.csdnimg.cn/blog_migrate/8eee5099d2ae2461946c9637c0963eb3.jpeg)
这个动画编辑器分为4个部分,先看左上角,这里列出来当前动画组件map节点下的所有子节点,表示可以对当前动画组件节点下的所有子节点进行操作,然后左下角Add property的部分可以添加需要修改节点的属性,在往下看可以看到Clip: test,之前说到了一个动画组件可以拥有多个动画剪辑来呈现不同的动画,这里是用来切换当前动画组件中Clips下的其他其它剪辑进行编辑,那么右边这根红线的区域就是用来决定什么时间就行修改节点的属性。
下面展示一个让节点懂放大到消失的操作
1.先点击Add property属性区添加一个scale(缩放倍速属性),然后右侧红线在在0秒的时候点击,scale右边三杠的属性条,点击插入关键帧,这样当前原来大小的节点scale属性就会被记录,显示蓝色菱形标记为记录成功
![8531a823fd4ea2fd4e601b1df621e725.png](https://i-blog.csdnimg.cn/blog_migrate/b920b27ec88ca6ded9dc81eee0ad84e1.jpeg)
2.把红线拖动到任意位置,直接在资源管理器把当前的节点的scale修改为0,这里会再次记录下一个关键帧,出现蓝色菱形标记。
![633864f55109e33722c6d88ef9e97c43.png](https://i-blog.csdnimg.cn/blog_migrate/4005bc1c4f2b01ea4f590cf13d3c88e7.jpeg)
按下ctrl之后可以点击动画编辑器字样下面的播放查看这段动画剪辑
就能看到Animation组件下拥有test动画的节点会播放一段从原来大小逐渐缩小到0倍大小,也就是逐步缩小到消失的动画效果,动画的时间就是红线从0:00到被拖动到的位置,当然也可以通过右下角的Sample才行采样帧,和Speed播放速度设置。
这样一个最基础修改属性的动画剪辑就编辑完成了。
当然动画不仅仅是修改节点的属性,还能进行其它操作,比如让一个游戏角色做出一套连贯动作的动画效果,那么就要像之前说的,在关键帧位置把角色的精灵帧切换为对应的动作的图片,那么在播放动画时就能看到想要的动作效果
![d6d4f2143dcb8b869931ca393ebe2820.png](https://i-blog.csdnimg.cn/blog_migrate/ab16377f6955170c087eb4dd25d8fbc0.png)
现在属性列加一个cc.spriteFrame精灵帧属性,下面准备的是一个角色向右走的逐帧图片,当这些图片一秒钟之内全部播放完,就会形成向右移动的动画效果,按住shift点击第一帧在点击最后一帧,顺序不能错,播放的动作是按照点击的顺序,然后直接拖拽到动画编辑器右下cc.spriteFrame同行的区域,那么动画编辑器就会自动分配好每一次精灵帧切换的时间,并记为蓝色菱形标记的关键帧,这时候把下面的Sample采样帧设置为这组动作的帧数14,这样播放时就能看到这个怪兽比较流畅的向右移动。
![c31b9941bff9d5554000bbce0c7ad031.png](https://i-blog.csdnimg.cn/blog_migrate/33295f7283106d9ddef9d923f370f79b.jpeg)
最后提一下中间的WrapMode表示播放的方法,其中有来回播放,倒放,循环播放等等,开始的Loop表示默认。
这些就是引擎界面自带的动画编辑器基础操作,依靠这些基础操作就能实现更复杂的效果。
代码中调用动画
@ccclass
export default class NewClass extends cc.Component {
// 用于挂载拥有动画组件的节点
@property(cc.Node)
monster:cc.Node = null;
// 用于获取动画组件
monsterAnim = null;
onLoad () {
// 先通过挂载拥有动画组件的节点获取到动画组件
this.monsterAnim = this.monster.getComponent(cc.Animation);
// 调用Animation自带的APi方法getClips()获取到Clips里所有的动画剪辑
var cilps = this.monsterAnim.getClips();
// 先用directionAnim(0)通过下标访问到刚刚取到的clips动画剪辑集合的第一个动画剪辑,在获取名字播放
this.monsterAnim.play(cilps[this.directionAnim(0)].name);
// 直接通过名字播放
this.monsterAnim.play("test");
}
}
动作系统(action)
动作和动画是相辅相成的,动作可以使得动画展示的流程更加丝滑流畅,上面实现了一个角色向右走动的动画,那么它只是在展示原地踏步的动画,那真正让它移动起来,这时候就可以借助动作系统
// 创建一个2秒钟移动到x = -148,y = 182的动作
var move = cc.moveTo(2, -148, 182);
// 调用runAction执行move
this.monster.runAction(move);
在上面播放动画的时候边执行这个动作,那么就能让monster真正产生在行走的动作
当然这是最简单动作,还有特殊的动作,比如动作队列,并行动作等等…
队列动作sequence:依次执行队列容器中的动作
并行动作spawn:同时执行这些动作
// 移动
var move1 = cc.moveTo(2, -148, 182);
var move2 = cc.moveTo(2, 41, 188);
var move3 = cc.moveTo(2, 104, 63);
// fadeOut隐藏
var out = cc.fadeOut(1.0);
// fadeOut显示
var In = cc.fadeIn(1.0);
// 创建一个队列动作sequence,把制作好的隐藏和显示动作放入队列中
var fadesq = cc.sequence(out, In);
// scaleTo缩放倍数,第一个参数是缩放时间
var scaleBig = cc.scaleTo(1, 2.0);
var scaleSmall = cc.scaleTo(1, 1.0);
// 把放大缩小放入一个动作队列中
var scalesq = cc.sequence(scaleBig, scaleSmall);
// 创建三个并行动作,表示move1移动位置,fadesq先隐藏在显示的动作队列,fadesq先放大在缩小的动作队列,这三个动作会同时执行
var sp1 = cc.spawn(move1, fadesq, scalesq);
var sp2 = cc.spawn(move2, fadesq, scalesq);
var sp3 = cc.spawn(move3, fadesq, scalesq);
// 创建一个函数动作,函数动作:当作动作执行的特殊函数
var call = cc.callFunc(function() {
cc.log("cocos");
});
// 最后创建一个动作队列,让sp1, sp2, call, sp3依次执行
var sq = cc.sequence(sp1, sp2, call, sp3);
// 调用runAction执行
this.monster.runAction(sq);
tweenAction
当使用Action的时候编译器可能会提示你,不要用Action,建议使用tweenAction(缓动系统)
Cocos Creator 在 v2.0.9 提供了一套新的 API —— cc.tween。cc.tween 能够对对象的任意属性进行缓动,功能类似于 cc.Action(动作系统)。但是 cc.tween 会比 cc.Action 更加简洁易用,因为 cc.tween 提供了链式创建的方法,可以对任何对象进行操作,并且可以对对象的任意属性进行缓动。
动作系统 是从 Cocos2d-x 迁移到 Cocos Creator 的,提供的 API 比较繁琐,只支持在节点属性上使用,并且如果要支持新的属性就需要再添加一个新的动作。为了提供更好的 API,cc.tween 在 动作系统 的基础上做了一层 API 封装。下面是 cc.Action 与 cc.tween 在使用上的对比:
// cc.Action:
this.node.runAction(
cc.sequence(
cc.spawn(
cc.moveTo(1, 100, 100),
cc.rotateTo(1, 360),
),
cc.scale(1, 2)
)
)
// cc.tween:
cc.tween(this.node)
.to(1, { position: cc.v2(100, 100), rotation: 360 })
.to(1, { scale: 2 })
.start()
链式 API
cc.tween 的每一个 API 都会在内部生成一个 action,并将这个 action 添加到内部队列中,在 API 调用完后会再返回自身实例,这样就可以通过链式调用的方式来组织代码。
cc.tween 在调用 start 时会将之前生成的 action 队列重新组合生成一个 cc.sequence 队列,所以 cc.tween 的链式结构是依次执行每一个 API 的,也就是会执行完一个 API 再执行下一个 API。
设置缓动属性
cc.tween 提供了两个设置属性的 API:
to:对属性进行绝对值计算,最终的运行结果即是设置的属性值
by:对属性进行相对值计算,最终的运行结果是设置的属性值加上开始运行时节点的属性值
下面用tween重新实现上面的多次移动效果
cc.tween(this.monster).to(2, {position:cc.v3(-148, 182), scale: 2.0})
.to(2, {position:cc.v3(41, 188), scale: 1.0})
.call(()=>cc.log("cocos"))
.to(2, {position:cc.v3(104, 63),scale: 2.0})
.start()