在开始讲小游戏开发中会使用到的实现动画的方式,咱们先来回顾一下在H5开发中若是你想作一个动画能够会用到实现动画的方式。css
回顾完H5中的一些动画实现方式,咱们再来看看Laya游戏引擎给咱们提供了哪些实现动画的方式。html
图集 ≈ 雪碧图
,两者的区别就是图集还多了一份每一个图片对应位置关系的配置表;$(selector).animate()
或者 Tween.js的Tween.to()
、Tween.from()
,提供Laya.Tween.from()
、Laya.Tween.to()
函数控制元素从状态A逐步切换到状态B;Spine骨骼动画
、DragonBone龙骨动画
;目前,仅仅H5中的Gif动画没法在Laya游戏引擎中支持,其余动画方式均可以在Laya游戏中使用。下图为来自灵魂画师的动画对比图前端
介绍了游戏提供的实现动画的方式以后,咱们来看一下该如何使用这些动画css3
图集动画自己就是直接播放图集资源,咱们前面也提到了图集资源其实就是雪碧图搭配一个图片位置信息表,如今咱们来看一下真实的图集资源是什么样子的。git
下图为咱们具体用到的图集资源,blink.atlas
(每一个图片资源的位置信息),blink.png
(每一帧图片合成的雪碧图)github
blink.atlas:记录每一张图片在雪碧图中的位置,内容以下:typescript
{"frames":{"lz_01.png":{"frame":{"h":604,"idx":0,"w":650,"x":0,"y":0},"sourceSize":{"h":667,"w":720},"spriteSourceSize":{"x":15,"y":23}},"lz_03.png":{"frame":{"h":625,"idx":0,"w":667,"x":651,"y":0},"sourceSize":{"h":667,"w":720},"spriteSourceSize":{"x":42,"y":25}},"lz_05.png":{"frame":{"h":619,"idx":0,"w":623,"x":0,"y":605},"sourceSize":{"h":667,"w":720},"spriteSourceSize":{"x":63,"y":13}},"lz_07.png":{"frame":{"h":617,"idx":0,"w":670,"x":624,"y":626},"sourceSize":{"h":667,"w":720},"spriteSourceSize":{"x":20,"y":24}},"lz_09.png":{"frame":{"h":618,"idx":0,"w":688,"x":1295,"y":626},"sourceSize":{"h":667,"w":720},"spriteSourceSize":{"x":13,"y":30}},"lz_11.png":{"frame":{"h":617,"idx":0,"w":671,"x":0,"y":1244},"sourceSize":{"h":667,"w":720},"spriteSourceSize":{"x":35,"y":7}},"lz_13.png":{"frame":{"h":615,"idx":0,"w":676,"x":1319,"y":0},"sourceSize":{"h":667,"w":720},"spriteSourceSize":{"x":35,"y":13}},"lz_15.png":{"frame":{"h":642,"idx":0,"w":613,"x":672,"y":1244},"sourceSize":{"h":667,"w":720},"spriteSourceSize":{"x":71,"y":0}},"lz_17.png":{"frame":{"h":614,"idx":0,"w":702,"x":1286,"y":1245},"sourceSize":{"h":667,"w":720},"spriteSourceSize":{"x":10,"y":18}},"lz_19.png":{"frame":{"h":598,"idx":0,"w":614,"x":1984,"y":616},"sourceSize":{"h":667,"w":720},"spriteSourceSize":{"x":98,"y":24}},"lz_21.png":{"frame":{"h":613,"idx":0,"w":621,"x":1996,"y":0},"sourceSize":{"h":667,"w":720},"spriteSourceSize":{"x":79,"y":25}},"lz_23.png":{"frame":{"h":551,"idx":0,"w":602,"x":1989,"y":1215},"sourceSize":{"h":667,"w":720},"spriteSourceSize":{"x":53,"y":46}}},"meta":{"image":"blink.png","prefix":"lamp/blink/"}}
blink.png:全部帧对应的图片的合集(此处为原图,可自行下载做为demo使用),内容以下:json
总体的使用过程也很简单,加载图集资源以后,直接播放便可c#
/** * 使用图集动画流程: * 一、建立动画实例 * 二、加载图集资源 *.atlas * 三、添加到舞台 * 四、播放动画 */ // 建立动画实例 let animation = new Laya.Animation(); // 加载图集资源 blink.atlas,引擎会根据atlas文件自行查找到图片资源 blink.png animation.loadAtlas('animation/blink.atlas', new Laya.Handler(this, () => { // 加载完成后,将动画添加到舞台上,并开始播放 this.addChild(animation); // 无限循环播放 animation.play() }));
具体效果以下:微信
缓动动画是提升游戏体验的重要手段,Laya引擎将缓动动画封装的很不错,对外只暴露出2个类,缓动类Laya.Tween
、速度类Laya.Ease
,经过这2个类便可快速实现缓动动画。咱们来看一下如何实现一个方块移动且变色:
/** * 使用缓动动画流程: * 一、给须要移动的元素设置缓动后的样式属性便可 */ // 舞台中添加元素,并设置大小和位置 let $box = new Laya.Box(); $box.size(100, 100).pos(0, 0); $box.bgColor = 'red'; this.addChild($box) // 经过缓动动画控制 $box位置移动、大小变化;整个动画耗时2秒 Laya.Tween.to($box, { width: 200, height: 200, x: 300, y: 700 }, 2000, Laya.Ease.linearInOut, Laya.Handler.create(this, () => { // 缓动动画结束后的操做 Laya.Tween.to($box, { width: 100, height: 100, x: 0, y: 0 }, 2000); }));
具体效果以下:
Laya提供了2种方式实现时间轴动画,一是利用IDE的编辑模式建立时间轴动画,二是利用代码直接建立时间轴动画。咱们来看一下如何实现一个方块移动且改变大小:
一、 经过编辑模式建立时间轴动画的步骤以下:
(a) 右击左侧场景目录,新建时间轴动画文件
(b) 将图片拖入场景,点击“动画编辑模式”,设置关键帧属性,修图片大小和x
、y
属性
(c) 点击时间轴上对应的帧增长想要的属性,重复屡次,添加多个关键帧
(d) 将生成的时间轴动画*.ani
拖拽到场景中,从新编译便可看到效果
二、 经过代码建立时间轴动画的方式:
/** * 使用时间轴动画流程: * 一、给须要移动的元素设置每一帧的样式便可 */ // 舞台中添加元素,并设置大小和位置 let $box = new Laya.Box(); $box.size(100, 100).pos(0, 0); $box.bgColor = 'blue'; this.addChild($box) // 建立时间轴动画 let timeline = new Laya.TimeLine(); timeline // 时间轴动画第一个序列 .to($box, { width: 200, height: 200, x: 300, y: 700 }, 2000) // 时间轴动画第二个序列 .to($box, { width: 100, height: 100, x: 0, y: 0 }, 2000); timeline.play();
具体效果以下:
动效模板能够理解成是一个时间动画效果的抽象,相似于一个css3中定义一个@keyframes,只要给对应的dom添加上该keyframes便可执行相同的动画。目前动效模板只支持在IDE的编辑模式中建立。步骤以下:
(a) 右击左侧场景目录,建立动效模板
(b) 拖拽添加图片
(c) 经过鼠标控制组件的轴心点
(d) 编辑关键帧,添加摇动的动画效果,相似前面的编辑时间轴动画时的操做
(e) 在新的场景中新建图片组件,并将刚刚实现的动效模板 Shake.efc
添加到图片组件中
具体效果以下:
骨骼动画的使用相对其余动画较为复杂,由于他须要先利用Laya自带的ui资源转换工具把现有的设计资源转换成Laya引擎认识的资源(纹理集*.png
、龙骨资源信息*.sk
)。由于目前市面上主流的作龙骨动画的工具备2种:DragonBone、Spine。其中Spine是收费软件,DragonBone是免费的,为了方便你们本身操做,咱们就用DragonBones作演示工具。使用步骤:
(a) 下载DragonBones工具,官网地址
(b) 打开DragonBone工具后随便选择一个骨骼动画的示例,若是你有本身的龙骨动画资源也能够用本身的,这里为了方便就选了第一个资源。
(c) 导出laya引擎能够解析的资源,选择文件 -> 导出
,选择正确的格式
(d) 利用IDE建立一个新的Laya2D项目,并把上述导出的文件放到项目的根目录下面
(e) 经过IDE提供的工具将龙骨动画资源转换引擎可用的资源
(f) 转换完成后,会在目录中生成*.png
和*.sk
文件,将文件放到项目的资源文件中 laya/assets/dragonBone
(dragonBone文件为本身建立,取别的名字也能够)。
(g) 在编辑模式下,按F9,增长勾选类库laya.ani.js
(h) 直接修改初始化项目中的src/script/GameUI.ts
,修改成以下代码,从新编译便可看到效果
import { ui } from "./../ui/layaMaxUI"; export default class GameUI extends ui.test.TestSceneUI { onEnable(): void { /** * 使用龙骨动画的流程: * 一、建立动画模版 * 二、加载龙骨资源 * 三、经过模版建立龙骨动画实例 * 四、播放龙骨动画 */ // 建立动画模版,方便后续存在复用动画的场景 let templet = new Laya.Templet(); // 加载龙骨资源 templet.loadAni('dragonBone/Dragon_1.sk'); // 处理加载完成事件 templet.on(Laya.Event.COMPLETE, this, () => { // 经过模版建立动画实例 // 0,使用模板缓冲的数据,模板缓冲的数据,不容许修改 // 1,使用动画本身的缓冲区,每一个动画都会有本身的缓冲区,至关耗费内存 (内存开销大,计算开销小,支持换装) // 2,使用动态方式,去实时去画 (内存开销小,计算开销大,支持换装,不建议使用) let skeleton = templet.buildArmature(1); skeleton.pos(200, 500); this.addChild(skeleton); // 播放动画 skeleton.play(0, true); }); } }
具体效果以下:
基本上任何动画均可以经过时间轴动画或者图集动画来实现,只不过是实现的须要的图集大小的区别和是否适合的区别,咱们快游戏自己对包体大小都有严格的控制,快游戏主包限制为10MB,若是按照设计师提供的动画资源直接使用,大几率会致使游戏包体很快就超过限制,针对这一问题这里列举几个经常使用的动画优化策略:
上述优化策略主要仍是从如何减小动画资源大小方向上考虑。Laya引擎自身对动画作了不少本身的优化,保证了你们开箱即用便可,有兴趣了解Laya引擎,能够自行查看源码。
笔者19年5月开始深度参与了一个OPPO快游戏项目(相似微信小游戏),从零开始折腾到如今,终于算是入了H5游戏开发的门。目前关于Laya引擎开发快游戏的教程还很少,因而笔者决定把这几个月踩过的坑、解决的问题、总结的经验都记录下来,方便其余准备入坑的同窗提早规避。
Laya2.x游戏引擎入门系列预计会写如下文章,记录如何从零开始完成一个快游戏的开发和上架:
同时,Laya2目前将引擎代码经过TypeScript进行了重构,你们若是在写代码中遇到什么疑问均可以直接在GitHub源码中找到答案,后续笔者也会写一些关于Laya2源码解析的文章,有兴趣的朋友能够关注。
第一次尝试写完整的教学文章,若有错误或不严谨的地方,请务必给予指正,十分感谢!
我是一个莫得感情的代码搬运工,每周会更新1至2篇前端相关的文章,有兴趣的老铁能够扫描下面的二维码关注或者直接微信搜索前端补习班
关注。
精通前端很难,让咱们来一块儿补补课吧!