PIXI 精灵表和精灵动画
本文介绍了精灵表(spirte sheet)和精灵动画的原理,利用TexturePacker来制作精灵表的方法还有如何在PIXI JS引擎中加载和使用。
1. 制作
1.1 原理和基础做法
动画和电影的原理很简单,就是把一系列图片顺序播放快速切换,快到人眼难以分辨单张图片时,就变成动画了。
所以制作PIXI动画最基本的做法就是把动画的每一帧都做成一张单独的图片,然后逐一加载,使用时用一个个数组写明每一帧的图片是什么,但是这样加载和使用起来都很麻烦。懒是人们前进的动力,所以我们会用下面提到的精灵表。
1.2 精灵表
1.2.1 简介
精灵表的英文原名是Sprite sheet,直接翻译过来就是精灵表,也有翻译成“雪碧图”的,个人认为还不如叫精灵表更贴切。
精灵表就是把许多图片放在一起打包成一张大图,或许还有辅助的json文件记录里面原来每张图片的信息,比如位置大小什么的,方便程序到时候再复原回去。
1.2.2 优势
精灵表的主要作用加速加载,在HTTP版本2之前,浏览器和服务器之间每传送一次就要建立一次TCP连接,大家都知道,3次握手4次挥手麻烦得很。所以如果要传输游戏动画这样有大量小图片的场景就特别慢。(HTTP2以后专门做了优化,所以好一些了)如果我们把这些动画都集合到一张图片里面就可以一次加载,省去了很多建立/断开TCP连接的时间。
不仅如此,精灵表还可以去除原来图片边缘空白的部分,让他们紧密地排列在一起,这样的话就可以缩小最终的文件体积。打包以后可以统一做图片压缩。很多时候,我们如果允许一点点图像损失(用户几乎看不出来那种)就可以减小几倍图片文件的大小。
精灵表还可以节省内存,这是因为显存里面存放的图片大小数值都是2的n次方,比如512 X 1024 即使不够也要加空白凑成2的n次方。可是我们图片制作的时候并没有这样的限制,可能有大量的大大小小的图片比如一个图标大小的动画,可能有几十张29 X 26的图片,这些图片单独加载的话,每个都在内存中占32 X 32大小的地方。但使用精灵表可以大大减少这种浪费,很多图片拼在一起,最终接近2的n次方大小可以避免浪费内存。这就是我们往往要求导出的精灵表大小符合2的n次方的规格的原因。
精灵表的另一个作用是在逻辑上把图片文件按类别聚集在一起。同类的文件放一起。同一个动画的每一帧图片也都放一起,如果有json描述文件的话你还能直接定义某些图片就是某个动画的帧。
1.3 PIXI 精灵表和精灵动画的json文件格式
{
"frames": { //记录每张图片的信息
"xx.png": {
"frame": {"x":0,"y":0,"w":154,"h":89}, //图片在精灵表中位置和大小
"rotated": false, //是否旋转过
"trimmed": false, //是否剪裁了边缘
"spriteSourceSize": {"x":0,"y":0,"w":154,"h":89},
"sourceSize": {"w":154,"h":89} //原图大小
},
"a_1.png":{}
"a_2.png":{}
//...
},
"animations": { //记录包含的所有动画信息
"a": ["a_1.png","a_2.png"] //例如,动画名字叫"a", 动画包含a_1, a_2两帧
},
"meta": { // 文件相关信息
"image": "youwon.png", //spirte sheet 图片文件路径
"format": "RGBA8888", //颜色格式
"size": {"w":1000,"h":388}, // 大小
"scale": "1", //缩放
...
}
}
1.4 使用Texture Packer导出精灵表和精灵动画
Texture Packer是一款专注于精灵表打包和压缩的工具。网址: https://www.codeandweb.com/texturepacker 使用起来挺方便,功能强,压缩比也不错。但注意是有付费版和免费版的区别,现在好像1年许可是35刀终生是99刀。
1.4.1 加入图片
只要将图片或图片文件夹拖入Texture Packer 窗口即可
1.4.2 设置导出格式
导出格式设定为你期望的格式,比如我们用PIXI就选PIXI
此外还有很多其他选项,比如图片颜色格式,8位的还是32位的,要不要透明通道。图片大小是随意还是2的n次方等等。
注意选择好要导出的目标文件夹。
1.4.3 识别和预览动画
如果你的动画里的每一帧图片应使用如下命名格式:“_.png”
Texture Packer 就可以自动识别精灵动画(sprite animation)
在左边精灵列表中选择要预览的动画帧然后点击上面的“预览动画”按钮,就会弹出动画预览窗口。拖动下面的速度条可以调整帧率(播放速度)。右下角还有个下拉框可以选择背景,真是贴心的设计。
1.4.4 导出
点击上面的“发布精灵表”按钮就可以导出了。
2. PIXI中的加载和使用
2.1 加载
2.1.1 Loader对象
一般来说无需自己构造Loader对象。如果你使用PIXI.Application来构造PIXI APP,那么它已经帮你准备好了一个loader 对象“app.loader”。你也可以使用PIXI默认的共享Loader对象“PIXI.Loader.shared”
2.1.2 加载图片
Loader.add('xxx/xxx.png')
###2.1.3 加载精灵表
Loader.add('xxx/xxx.json')
注意json文件中的meta中精灵表图片的相对路径要正确,能让程序找到。
2.1.4 加载事件
PIXI loader 可以触发如下事件:
loader.load((loader, resources) => {}) //加载完成
loader.onProgress.add(() => {}); // 加载进度,某个文件加载成功/失败
loader.onError.add(() => {}); // 某个文件加载失败
loader.onLoad.add(() => {}); // 某个文件加载成功
loader.onComplete.add(() => {}); // 队列中所有文件加载完成
2.2 使用
加载完成后我们就可以使用相应的图片和动画资源来构造PIXI精灵了。
2.2.1 PIXI Sprite
PIXI精灵(Sprite) 使用一张图片(缓存里的一个texture)来构造。可以直接构造在在load回调函数里
loader.load((loader, resources) => {
const sp = new PIXI.Sprite(resources.xxx.texture);
});
或者在任何地方通过缓存来找到图片然后构造
const sp = new PIXI.Sprite(PIXI.utils.TextureCache['assets/xxx.png']);
2.2.2 PIXI AnimatedSprite
PIXI动画精灵(AnimatedSprite) 通过一个图片数组来构造,比如
const asp = new PIXI.AnimatedSprite([
PIXI.utils.TextureCache['assets/aaa_1.png'],
PIXI.utils.TextureCache['assets/aaa_2.png'],
PIXI.utils.TextureCache['assets/aaa_3.png'],
// ...
]);
或者
PIXI.AnimatedSprite.fromFrames([
'assets/aaa_1.png',
'assets/aaa_2.png',
'assets/aaa_3.png',
//...
])
另外如果你的精灵表里已经定义好精灵动画,那就简单多了,不用列出每一帧的文件名
const sheet = loader.resources["assets/spritesheet.json"].spritesheet;
const asp = new PIXI.AnimatedSprite(sheet.animations["aaa"]);
动画精灵的相关方法:
asp.gotoAndPlay(frameNumber) //从指定帧开始播放
asp.gotoAndStop(frameNumber) //停止在指定帧
asp.play() //播放
asp.stop() //停止
附录
相关链接
PIXI JS: https://www.pixijs.com/
PIXI JS API: http://pixijs.download/release/docs/index.html
Texture Packer: https://www.codeandweb.com/texturepacker
更多推荐
所有评论(0)