动画
像素动画画面帧率间隔脚本大脑游戏游戏引擎
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 = '';
@property
label:cc.label = null;
@property
text: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 秒的残留,大脑认为这个画面就是一个连续的画面。