SpriteSheet精灵动画引擎
SpriteSheet精灵动画引擎
本文介绍Flash中SpriteSheet精灵序列图与其它渲染方式的性能对比、SpriteSheet的原理及注意实现,最后实现了一个精灵序列图的渲染引擎。本文的SpriteSheet引擎及demo可以在github上下载:https://github.com/saylorzhu/SpriteSheet
动画渲染性能对比
Flash中动画制作方式有多种,如矢量动画、位图帧动画、精灵序列图等等。针对不同的制作方式,对同一个角色动画进行如下测试:一个角色在屏幕上显示5个实例,对应呼吸、施法、行走、受伤、普攻状态。
测试运行的环境:
l Release version of Flash Player 12.0.159.1
l AMD Phenom(tm) II X4 830 Processor(2800 Mhz)
l Microsoft Windows 7 专业版 (32位)
得出测试结果如下表所示,为了节约大小资源中所用位图均为png8。
表1:不同动画渲染效率对比(具体测试数据与所使用资源有关)
|
渲染方式 |
描述 |
CPU |
内存(KB) |
文件大小(KB) |
|
时间轴 |
矢量 |
12 |
6m |
24 |
|
矢量+cacheAsBitmap |
12 |
6.2m |
24 |
|
|
位图 |
2 |
6.8m |
534 |
|
|
位图+导出类 |
2 |
13m |
537 |
|
|
位图渲染 |
SpriteSheet精灵序列图 |
1 |
11m |
220 png + 31 json/xml |
从上表可以得出,精灵序列图消耗CPU最少,并且文件大小适中,但内存消耗较大。对于游戏来说,CPU销毁越小,帧频可以越大,游戏越流畅。

图1:精灵序列图动画效果及帧频、内存信息
可以看出使用精灵序列图帧频和内存都非常稳定,内存没有频繁的gc,gc非常消耗cpu会造成游戏卡顿现象。反观其它渲染方式,会发现内存不稳定,这对游戏性能是一个风险。

图2:矢量动画

图3:矢量+cacheAsBitmap动画

图4:位图动画

图5:位图+导出类
下面详细介绍下精灵序列图的原理及注意事项。
精灵序列图
SpriteSheet精灵序列图是一种大的网格式位图,其中每一格都对应着一个动画截屏,每一动画截屏对应动画的一帧。精灵序列图通常采用PNG格式,这样可以使用Alpha通道。

图6:角色受伤动画序列图
除了大位图之后,还必须有一个对应的数据描述文件,常用的格式有json、json-array、xml。数据描述文件,用来指定每帧动画在大图中的位置(偏移位置、宽、高等等),如json格式如下:
|
JSON格式描述数据: |
|
{"frames": {
"呼吸0000": { "frame": {"x":0,"y":0,"w":110,"h":110}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":110,"h":110}, "sourceSize": {"w":110,"h":110} }, "呼吸0001": { "frame": {"x":110,"y":0,"w":110,"h":110}, "rotated": false, "trimmed": false, "spriteSourceSize": {"x":0,"y":0,"w":110,"h":110}, "sourceSize": {"w":110,"h":110} }, … }, "meta": { "app": "Adobe Flash CS6", "version": "12.0.0.481", "image": "jsonformat.png", "format": "RGB8", "size": {"w":1024,"h":1024}, "scale": "1" } } |
其中:
Key-"呼吸0000":表示帧的名字/对应图片文件名(json-array格式中,使用filename字段表示);
frame: 图片在大图中的偏移位置(左上角为原点)和大小(未旋转前) 需要注意这里的图片大小是图片未旋转前的大小;
rotated: 是否旋转(顺时针方向);
trimmed: 是否有去掉周围多余的透明部分;
spriteSourceSize: x,y表示图片未去掉周围透明部分的偏移量,这是如果需要还原图片原先的大小要用的;
sourceSize: 图片的原始大小,包含透明部分;
渲染机制
精灵序列图使用位块图像传输(bit-blitting,blit = Bit-Block Image Transfer)技术,它涉及到使用位图来渲染最终的显示效果。 将需要显示的效果,像素会绘制到一个已添加到舞台上的位图中。为了表现动画效果,会在一个循环中更新位图的像素。关键步骤如下:
1) 加载动画中需要的Sprite Sheet位图数据(.png文件)
2) 在displayList中添加一个BitmapData目标位图数据(画布)
3) 向画布复制或者擦除游戏(copyPixel vs draw)
4) 根据游戏显示层次顺序将Sprite Sheet复制到画布
5) 在游戏循环中重复第3、4步
copyPixel的效率比draw高,所以一般情况下,使用copyPixel复制图像到画布。
内存占用
在所有动画渲染方式中,精灵序列图对帧频的影响是最小的。因为精灵序列图会预先被缓存到BitmapData实例中,这就可以使渲染速度变得更快。一定要随时注意内存的占用,仔细把控,详尽规划。精灵序列图之所以效率高,是由于位图序列都缓存在内存中从而可被快速调取。但这样也可能会导致巨大的内存开销。
注意:一张图片占用多少内存只取决于图像的尺寸,而与图像文件的类型和图像压缩无关。
位图所占内存(字节)= 位图宽度 x 位图高度 x 4
假设一帧的图片的大小为200x400像素,占用内存312.5KB。如果一个动画18帧,则占用内存约5.5M。如果一个角色包含4个方向或4个动作的动画,则占用内存约22M。同屏在线10个角色,则占用内存约220M。
SpriteSheet工具
现在Flash cs6已经集成了将动画导出为SpriteSheet,如下图所示:

图7:Flash cs6导出SpriteSheet设置
TexturePacker也可以打包图片为SpriteSheet格式。
精灵序列图引擎
前面介绍了精灵序列图的原理及注意事项,下面实现一个精灵序列图动画的引擎,支持Flash Cs6/TexturePacker导出的JSON、JSON-Array、Starling(XML)3种数据格式。

图8:精灵序列图引擎类图
SpriteSheet类

图9:SpriteSheet类
SpriteSheet继承自flash.display.Sprite,包含一个bitmap成员用作画布。使用定时器Timer来驱动动画循环。
SpriteSheet使用类似Movieclip,提供play()、stop()、gotoAndPlay()、gotoAndStop()接口,并支持鼠标事件。
mAnimation成员(Animation实例)用于描述SpriteSheet当前表示的动作,如游戏中一个角色包含呼吸、行走、施法、受伤动作。
mTextureAltas成员(TexureAtlas实例)用于维护整个精灵序列图数据,并负责将特定帧位图复制到画布显示。
TexureAtlas类
TexureAtlas类保存了整个精灵序列图数据,并根据SpriteSheet的当前动作,生成构成动画的所有帧在精灵序列图中的偏移和大小。
Animation类
Animation动画信息类。
l seqName表示动画序列名(e.g. "walk")
l delay表示帧间隔
l loop表示动画是否循环播放
l arFrames:Vector.<SpriteFrame>;// 帧信息数据
SpriteFrame类
SpriteFrame类表示图片在大图中的偏移位置(左上角为原点)和大小(未旋转前)等等信息,根据数据描述文件生成。

图10:SpriteFra示意
JsonFormat、JsonArrayFormat、XmlFormat类
SpriteSheet序列图数据解析类,分别解析对应格式的描述数据。
Demo实例
SpriteSheet使用非常简单,与原生Movieclip差异不大。下面的例子分别加载JSON、JSON-Array、XML格式的数据及对应的PNG资源,然后创建SpriteSheet实例。
|
Demo: |
|
package { import com.as3game.asset.AssetManager; import com.as3game.spritesheet.SpriteSheet; import com.as3game.spritesheet.vos.DataFormat; import flash.display.BitmapData; import flash.display.Sprite; import flash.events.MouseEvent; import flash.filters.ColorMatrixFilter; import flash.text.TextField;
/** * ... * @author Tylerzhu */ public class TestSpriteSheet extends Sprite {
public function TestSpriteSheet() { SWFProfiler.init(stage, this); AssetManager.getInstance().getGroupAssets("spritesheets-json", ["data/json/jsonformat.json", "data/json/jsonformat.png"], onAnimLoaded); AssetManager.getInstance().getGroupAssets("spritesheets-xml", ["data/xml/xmlformat.xml", "data/xml/xmlformat.png"], onAnimLoadedXML); AssetManager.getInstance().getGroupAssets("spritesheets-jsonarray", ["data/json-array/jsonarrayformat.json", "data/json-array/jsonarrayformat.png"], onAnimLoadedJsonArray); }
private function onAnimLoaded():void { var bitmapData:BitmapData = AssetManager.getInstance().bulkLoader.getBitmapData("data/json/jsonformat.png"); var sheets:* = AssetManager.getInstance().getContent("data/json/jsonformat.json"); var sp:SpriteSheet = new SpriteSheet(bitmapData, sheets, DataFormat.FORMAT_JSON); sp.setAction("呼吸", 14); sp.play(); addChild(sp); }
private function onAnimLoadedXML():void { var bitmapData:BitmapData = AssetManager.getInstance().bulkLoader.getBitmapData("data/xml/xmlformat.png"); var sheets:* = AssetManager.getInstance().getContent("data/xml/xmlformat.xml"); var sp:SpriteSheet = new SpriteSheet(bitmapData, sheets, DataFormat.FORMAT_XML); sp.setAction("呼吸", 15); sp.play(); sp.y = 150; addChild(sp); }
private function onAnimLoadedJsonArray():void { var bitmapData:BitmapData = AssetManager.getInstance().bulkLoader.getBitmapData("data/json-array/jsonarrayformat.png"); var sheets:* = AssetManager.getInstance().getContent("data/json-array/jsonarrayformat.json"); var sp:SpriteSheet = new SpriteSheet(bitmapData, sheets, DataFormat.FORMAT_JSON_ARRAY); sp.setAction("呼吸", 15); sp.play(); sp.y = 300; addChild(sp); } } } |
SpriteSheet精灵动画引擎的更多相关文章
- 网页小实验——用canvas生成精灵动画图片
实验目标:借助canvas把一张国际象棋棋子图片转换为一组适用于WebGL渲染的精灵动画图片,不借助其他图片处理工具,不引用其他库只使用原生js实现. 初始图片如下: 一.图片分割 将初始图片分割为六 ...
- 3D网页小实验-基于多线程和精灵动画实现RTS式单位行为
一.实验目的: 1.在上一篇的"RTS式单位控制"的基础上添加逻辑线程,为每个单位实现ai计算: 2.用精灵动画为单位的行为显示对应的动作效果. 二.运行效果: 1.场景中的单位分 ...
- 原创:CSS3技术-雪碧图自适应缩放与精灵动画方案
花了一个礼拜完成了慕课网定制的七夕主题效果,其中有一个没实现好的功能,就是雪碧图的自适应缩放 ps: 以下实现都是基于移动端的处理 原图如下: 人物是采用的是雪碧图,通过坐标绝对数据取值 问题很明显, ...
- 利用pixi.js制作精灵动画
CSS Sprites 技术对于广大的前端工程师来说应该是一点也不陌生.国内开发者昵称为CSS精灵,通过一定的技术手段,让精灵动起来,我称其为精灵动画,那么目前有哪些实现方式 呢?下面让我们详细的聊聊 ...
- css精灵动画
精灵动画的实现 CSS Sprites在国内很多人叫CSS精灵,其实这个技术不新鲜,原理就是:靠不断的切换图片让人感觉视觉上不断在变化,例如gif动画之类的效果 那么前端如何实现精灵效果? 传统的就是 ...
- 第四十二课:基于CSS的动画引擎
由于低版本浏览器不支持css3 animation,因此我们需要根据浏览器来选择不同的动画引擎.如果浏览器支持css3 animation,那么就使用此动画引擎,如果不支持,就使用javascript ...
- 精灵动画Animation对话框组成Idle动画的各精灵
精灵动画Animation对话框组成Idle动画的各精灵 1.3 精灵动画 场景中已经添加了精灵,现在是时候让让它动起来了.读者也许已经从精灵图集中,各精灵的命名中看出来了,这个精灵一共有两种动画状 ...
- [Unity2D]精灵动画
通常我们在游戏里面创建的精灵比如玩家主角,它在移动的过程中一般会带有一些动画的效果,比如两只脚前后地移动,那么这种动画效果的实现和控制就可以通过Unity2D的动画系统来实现. 要添加这样的动画,首先 ...
- Unity3D ShaderLab 模拟精灵动画
Unity3D ShaderLab 模拟精灵动画 在上一篇,介绍了通过Shader 模拟纹理运动,那么更深一步讲,我们也可以把帧动画的精灵纹理运动通过shader实现. 虽然大家都是在游戏脚本中做更高 ...
随机推荐
- Thinkphp Exception捕获异常失败
try catch 比较坑,默认这样是走TP 的错误模板页面 自定义的话: try { } catch ( \Exception $e ) {}加个\
- Charles
1. charles使用教程指南+客户端弱网测试:http://blog.csdn.net/anualday/article/details/51423457 2.使用Charles对Https请求进 ...
- Java中抽象类和接口的区别
转载自:http://dev.yesky.com/436/7581936.shtml 在Java语言中, abstract class 和interface 是支持抽象类定义的两种机制.正是由于这两种 ...
- 从github上获取资源速度慢的解决办法
今天在github上clone一个仓库的时候,速度非常慢,只有3kb/s,开代理也没用,网上找到的各种git config的方法也没有用,最后想到设置hosts试试.于是在git的安装目录下找到了/e ...
- Hibernate+jsp+struts+spring做增删该查,
同样还是web项目,这里只做了一张表,做一个测试,例子.主要是建Hibernate 的时候要非常注意,有时间了整理一下建Hiberbnate 的时候需要注意的事项 这里我是建了5个包,其实只要四个就好 ...
- c++ 课堂作业(1)
一.题目 Create a program that asks for the radius of a circle and prints the area of that circle, using ...
- 数据类型安全验证都交给TryParse吧
C# 网站开发中 往往在编写后台代码中遇到从字符类型转换到其他类型.其实无需在单独验证字符串长度,是否为空等工作.直接用Tryparse转换,如果转换失败说明字符串的格式等有误.成功则再进一步验证转换 ...
- js判断手机浏览器是横屏or竖屏
移动端的浏览器一般都支持window.orientation这个参数,通过这个参数可以判断出手机是处在横屏还是竖屏状态. 从而根据实际需求而执行相应的程序.通过添加监听事件onorientationc ...
- Linux操作系统安装JDK
1.利用winSCP将要安装的jdk包传到Linux上. 2.命令 tar -zxvf [jdk的安装包],安装包须是tar的包才行. ep:tar -zxvf server-jre-7u80-lin ...
- Spring overview
引子 接触Java很多年了,各种framework,却从未系统的去了解过.最近突然想清楚一件事,就是当下的目标——Focus on Java-based RESTful WS & JS.而之于 ...