Phaser3 ES6+ 入门教程(4)——动画

虽然,我们也可以在update()函数中,或使用其它方式写动画,但是Phaser中也提供了处理两类动画的方法。
Phaser3中,有补间动画(Tween)和逐帧动画(Animation)两种,使用这两类动画,我们可以很容地做出一些动态效果。

补间动画与逐帧动画的区别

我们知道,动画是由一段连续的静态图片快速播放组成的,其中的每一张图片叫做一帧。
补间动画,就是在一段时间内,将一个或者多个GameObject的某个属性(例如不透明度)从一个状态有一定规律地变成新的状态,例如从透明变成不透明,但是如果只有起始状态和结束状态两帧的话,那么看起来就是突然变化,没有过渡效果,会很突兀,而补间动画则是有过渡效果的,可以看成是两个状态之间有一些帧,在这些帧中,被改变的属性的值按照规律发生变化,例如一个Alpha从0变为1,中间可能会有0.1、0.2、0.3等值。所以叫做补间动画,自动补充中间的帧。
逐帧动画,就是每一帧都是不同的图片,没有规律可循。
简而言之,就是补间动画是在一段时间内动态调整显示物体的属性,从而形成动画的效果,逐帧动画就是每段时间显示一张静态的图片。

补间动画

补间动画,需要在场景类中使用Phaser.Scene.tweens属性中的方法进行添加,补间动画默认是会在添加后立刻播放的,不需要调用任何函数,当然也可以传入paused属性用来表示创建先不播放。
添加补间动画用的是add()方法,里面需要传入一个配置,大多数GameObject及其属性都可以成为补间动画的配置内容。
例如:

class Hello extends Phaser.GameObjects.Text{
  constructor(scene){
    super(scene);
    this.tweens.add({
      target:this,
      props:{
        alpha:0.5
      }
    })
  }
}

上面这个动画就是说每个Hello类的实例都会在1秒(为什么是1秒,因为默认是1秒,详见下文)中按照一定的算法将透明度从1慢慢地渐变到0.5.
在配置中,targets是必须传入的,其它都可选,该属性代表在该补间动画中要改变属性的GameObject(s),它可以是一个GameObject或者一个GameObject数组,也就是可以只改变一个GameObject,也可以改变多个GameObject。
其中,props属性设置在当前补间动画中,target需要改变的属性的状态,里面可以有多个属性,它们会同时发生变化。对于里面属性的键,就是target这个GameObject要改变的属性,它的值有多种写法,如果是一个数字,就代表在这个动画中,该属性从当前的最初状态,上述代码会将alpha从1变为0.5,过度到该属性这个值的这么一个状态,也可以写成:

alpha:{from:1,to:0.5}
// 或者
alpha:"-=0.5"

对于props中的属性,我们可以省略props,直接写在传入的大括号里面。
我们可以在配置中传入delay和duration属性,它们分别代表在动画开始前的延迟(也就是要等待多少毫秒之后再开始播放动画,默认是0,即不等待)和动画的时长(以毫秒为单位,默认是1000毫秒,即1秒)。
repeat属性代表动画是否要重复,默认是0,即不重复,也就是只播放1次,-1代表循环播放,1代表重复1次,即实际播放2次,2和以上同理。
然后,还有一个很重要的属性,ease代表过渡效果,也就是我们上面所说的补间动画的规律。默认值是Power0、除此之外,还有Linear、Cubic、Elastic、Bounce、Back等内置的规律可以选择,也可以自己写一个函数,各种效果自己查字典尝试吧。
另外,还有一个属性yoyo,默认是false,这个属性就是说动画要不要倒着来一遍,默认是动画结束后不会回到初始状态的,如果把该属性设置为true,则会动态地回到初始状态。至于为什么叫悠悠球呢?我估计大概是因为悠悠球它是会回到初始状态的。其它属性请看文档。
对于duration指的是播放一次的所用时间,所以如果设置为1000毫秒的话并且设置yoyo为true的话,可以视为播放2次,即1次是正着放,1次是倒着放,那么从最初状态回到最初状态应该是2000毫秒,即2秒。
补间动画可以设置paused属性,表示创建该动画后是否立刻播放,默认为true。

逐帧动画

逐帧动画,我们先要有一些图片,假设相对于HTML文件的路径分别是./images/img1.png./images/img2.png,那么我们在创建动画之前,需要先加载用到的图片,在场景类的相应方法中,

this.load.add("img1","./images/img1.png");
this.load.add("img2","./images/img2.png");

然后就可以通过使用Phaser.Scene.anims属性中的相关方法来进行动画的创建等处理。

this.anims.create({
key:"ani", // 动画名称
frames:[{frame:0,key:"img1",duration:1000},{"img2",duration:1000,frame:1}]
});

其中的key指的是动画的名称,不是需要用到的图片的名称,frames是该动画中的所有关键帧。
在每一个关键帧中,frame指的是关键帧位于第几帧,key是指该帧所用的图像的键,duration指该帧持续多少毫秒。
由于在创建动画时是不会设置显示坐标的,因此我们在播放动画时必须指定一个有动画属性的GameObject,它就会在该GameObject的位置进行播放,sprite是一个不错的选择,它也可以不传入纹理(下文就称之为空精灵了)。
一个例子,假设上面已经创建好了动画,在场景类中可以这么写:

let p=this.add.sprite(0,0).setOrigin(0,0); // 创建一个空精灵,其实setOrigin也不是必须的,只是为了看清楚效果可以这么设置一下
this.anims.play("ani",[p]);

相信大家已经猜到了,这样播放动画的话,动画中图片大小也会跟随空精灵缩放。
逐帧动画也有duration、delay等属性,不过逐帧动画默认是创建后不自动播放的。

精灵表

有时,一些动画的关键帧会按照一定的大小放在一张图片中,这样的图片就叫做精灵表(Sprite Sheet)(有时也称为纹理图集,但是在Phaser中这两个是不一样的)。
精灵表是指其中的每一张图片都具有相同的大小,这样我们就可以给其中的每一张图片一个从0开始算的唯一一个数字,这个数字就可以代表这张小图片;纹理图集是用帧名来代表一张小图片的。以下暂时只讲精灵表。
我们可以在场景类中通过类似于如下代码加载一张精灵表,

this.load.spritesheet("player","assets/player.png",{frameWidth:32,frameHeight:32});

这个函数共有4个参数,后面三个都是可选的。
上面的第一个参数就是随便取的一个键名,第二个参数是精灵表图片的路径,第三个参数就是帧的配置,第四个参数是xhr设置。
主要是第三个参数,精灵表中所谓的帧(Frame),其实也就是指里面的一张小图片,这里我们需要设置我们的精灵表图片中的每一张小图片的大小(也就是帧的宽度和高度,以px为单位)
一张精灵表就是一张图片,我们可以将其划分成若干张大小相同的图片,我们使用其中的帧就没有必要向上面那样写很多图片的键了,我们可以直接用一个函数去生成frames。
相关的函数有两个:this.anims.generateFrameNumbers和this.anims.generateFrameNames,顾名思义,精灵表是用数字来表示的,因此自然选择前者,而后者就是用于处理纹理图集的。
对于精灵表,我们只需要在frames属性中调用该函数即可,
该函数的第一个参数是精灵表的键名,第二个参数是一些配置,比如说start和end就是代表从第几帧到第几帧,默认是全部帧,帧是从0开始、从左往右、从上往下数的。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,204评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,091评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,548评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,657评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,689评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,554评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,302评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,216评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,661评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,851评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,977评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,697评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,306评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,898评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,019评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,138评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,927评论 2 355

推荐阅读更多精彩内容