动画
像素动画画面帧率间隔脚本大脑游戏游戏引擎
import { _decorator, Component, Node, CCObject } from 'cc';const { ccclass, property } = _decorator;/*** Predefined variables* Name = NewComponent* DateTime = Sat Apr 16 2022 14:10:06 GMT+0800 (中国标准时间)* Author = gycarver127* FileBasename = NewComponent.ts* FileBasenameNoExtension = NewComponent* URL = db://assets/NewComponent.ts* ManualUrl = https://docs.cocos.com/creator/3.4/manual/zh/**/@ccclass('NewComponent')export class NewComponent extends Component {// [1]// dummy = '';@propertylabel:cc.label = null;@propertytext:string = "hello";// [2]// @property// serializableDummy = 0;start () {// [3]}update (deltaTime: number) {if(this.node.x > 200) return;this.node.x += 5; //将节点移动5像素}}/*** [1] Class member could be defined like this.* [2] Use `property` decorator if your want the member to be serializable.* [3] Your initialization goes here.* [4] Your update function goes here.** Learn more about scripting: https://docs.cocos.com/creator/3.4/manual/zh/scripting/* Learn more about CCClass: https://docs.cocos.com/creator/3.4/manual/zh/scripting/decorator.html* Learn more about life-cycle callbacks: https://docs.cocos.com/creator/3.4/manual/zh/scripting/life-cycle-callbacks.html*/
文字记录
这章里边我们讲一下动画的实现,这章的内容主要是讲以程序的方式来编写动画效果,这个比上一章的内容要高级一些,比上一章的cc.tween应该说是更本质一些。加载我们的游戏之后,会有一个小猪佩奇的这样的一个角色,它会自动从左侧默默的移动到了右侧,这个并不是使用 cc.tween 来实现的,而是我们使用的所谓帧动画来实现的。
我们先创建一个佩奇的节点,给它添加一个脚本,创建一个 TypeScript ,名字还是叫做 pigscript ,然后把这个脚本附加给佩奇节点,保存一下,再打开这个脚本,默认给我们创建的脚本是这个。
import { _decorator, Component, Node } from 'cc';const { ccclass, property } = _decorator;/*** Predefined variables* Name = NewComponent_001* DateTime = Sun Apr 17 2022 16:37:46 GMT+0800 (中国标准时间)* Author = gycarver127* FileBasename = NewComponent-001.ts* FileBasenameNoExtension = NewComponent-001* URL = db://assets/NewComponent-001.ts* ManualUrl = https://docs.cocos.com/creator/3.4/manual/zh/**/@ccclass('NewComponent_001')export class NewComponent_001 extends Component {// [1]// dummy = '';// [2]// @property// serializableDummy = 0;start () {// [3]}// update (deltaTime: number) {// // [4]// }}/*** [1] Class member could be defined like this.* [2] Use `property` decorator if your want the member to be serializable.* [3] Your initialization goes here.* [4] Your update function goes here.** Learn more about scripting: https://docs.cocos.com/creator/3.4/manual/zh/scripting/* Learn more about CCClass: https://docs.cocos.com/creator/3.4/manual/zh/scripting/decorator.html* Learn more about life-cycle callbacks: https://docs.cocos.com/creator/3.4/manual/zh/scripting/life-cycle-callbacks.html*/
以前我们已经用过了 onload 初始化加载的时候,start第一次启动的时候, update 我们还没有用过,这个就是我们这一章要关注的东西。
update()回调方法
这个回调方法是什么意思呢?就是帧动画的绘制。这个方法每秒钟会被这个游戏引擎调用 60 次,我们可以在这里边来加一些动画的逻辑。 
那你怎么知道它每秒钟会被这个游戏引擎调用 60 次, 我们可以先加一些日志来观测一下,比如说在这里边我加上一个日志,加上一个时间戳,把当前的时间给打印一下。当前时间怎么样来写呢?这样的话就能够把当前的时间的毫秒值给打印出来,把这个游戏运行一下,观察下这个日志输出。
update(){cc.log("update() is called,time=" + new Date().getTime());}
打开这个开发者工具,可以看到在这里边刷的是非常快的。
因为我们刚才已经告诉大家他是每秒钟刷大概六十次,也就是每 16 毫秒就有一句打印。所以这个打印实际上是非常多的,我们可以把它给暂停一下。可以看到这个它的打印的时间大概是每间隔 16 毫秒左右,会打印一次,我刚才说的是没有错误的。
帧率
刚才说告诉大家这个 update 的方法会被游戏引擎每秒钟大概调用是 60 次左右。这个 60 次我们就称之为这个帧率,对应的英文术语叫 frames for second ,每秒钟多少帧,那么默认情况下这个是 60 帧,简称FPS。
既然有了这样的一个方法,我们可以考虑把这个动画逻辑放在这个里边,因为它是每秒钟调用 60 次。那我每次向右移动一定距离。比如说我每次向右移动 5 个像素,那么一秒钟下来就移动了 60 次,60次乘以 5 个像素,一秒钟下来它会均匀的向右移动,大概是 300 个像素。好的,我们现在把这个逻辑给加上来直接拷贝一下,填写到update 方法里边。
看一下我们的update 里边的实现,因为我们想要的效果是让这个小猪从左边移动到右边,怎么移呢?我们让它每次 update 的时候都把它的坐标向右移动 5 个像素 ,x += 5,你可以想象每次移动一点点,那么一秒钟移动 60 次,那么整体上就是一种均匀的移动的效果了,当然在上面加上一个边界的控制,因为你不能让它一直向右移动。我们这里面加一个限制,如果这 X 的坐标大于等于 200 的话就停止运动。
update (deltaTime: number) {if(this.node.x > 200) return;this.node.x += 5; //将节点移动5像素}
这两行代码控制一下,把这个代码保存一下,再刷新一下,再运行游戏。这时候我们打开游戏会发现这个小猪就是自动往右移,直到它的坐标到达 200 像素为止。
那看起来其实是一个很连贯很连续的动作,你看不到中间有任何的间隔,正是因为这个移动的速度,它调用的速度实际上是非常快的,每秒钟调用 60 次,每次它移动这个五个像素。那对于人眼来说,基本上无法区分中间的这个抖动,它就是一个连续的画面。
要做一个动画,设置为 60 FPS 肯定是够的,实际上设为30,也就基本上无法区分了,这个就是所谓的帧动画,其实在做电影的时候,电影动画片也都是一个意思,它都是每秒钟连续的播放一些画面,这样的话对于我们观众而言是看不到中间这样的一个间隔的,因为这个画面在大脑里边实际上是有大概是 0.05 秒的残留,大脑认为这个画面就是一个连续的画面。
