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精灵动画引擎的更多相关文章

  1. 网页小实验——用canvas生成精灵动画图片

    实验目标:借助canvas把一张国际象棋棋子图片转换为一组适用于WebGL渲染的精灵动画图片,不借助其他图片处理工具,不引用其他库只使用原生js实现. 初始图片如下: 一.图片分割 将初始图片分割为六 ...

  2. 3D网页小实验-基于多线程和精灵动画实现RTS式单位行为

    一.实验目的: 1.在上一篇的"RTS式单位控制"的基础上添加逻辑线程,为每个单位实现ai计算: 2.用精灵动画为单位的行为显示对应的动作效果. 二.运行效果: 1.场景中的单位分 ...

  3. 原创:CSS3技术-雪碧图自适应缩放与精灵动画方案

    花了一个礼拜完成了慕课网定制的七夕主题效果,其中有一个没实现好的功能,就是雪碧图的自适应缩放 ps: 以下实现都是基于移动端的处理 原图如下: 人物是采用的是雪碧图,通过坐标绝对数据取值 问题很明显, ...

  4. 利用pixi.js制作精灵动画

    CSS Sprites 技术对于广大的前端工程师来说应该是一点也不陌生.国内开发者昵称为CSS精灵,通过一定的技术手段,让精灵动起来,我称其为精灵动画,那么目前有哪些实现方式 呢?下面让我们详细的聊聊 ...

  5. css精灵动画

    精灵动画的实现 CSS Sprites在国内很多人叫CSS精灵,其实这个技术不新鲜,原理就是:靠不断的切换图片让人感觉视觉上不断在变化,例如gif动画之类的效果 那么前端如何实现精灵效果? 传统的就是 ...

  6. 第四十二课:基于CSS的动画引擎

    由于低版本浏览器不支持css3 animation,因此我们需要根据浏览器来选择不同的动画引擎.如果浏览器支持css3 animation,那么就使用此动画引擎,如果不支持,就使用javascript ...

  7. 精灵动画Animation对话框组成Idle动画的各精灵

    精灵动画Animation对话框组成Idle动画的各精灵 1.3  精灵动画 场景中已经添加了精灵,现在是时候让让它动起来了.读者也许已经从精灵图集中,各精灵的命名中看出来了,这个精灵一共有两种动画状 ...

  8. [Unity2D]精灵动画

    通常我们在游戏里面创建的精灵比如玩家主角,它在移动的过程中一般会带有一些动画的效果,比如两只脚前后地移动,那么这种动画效果的实现和控制就可以通过Unity2D的动画系统来实现. 要添加这样的动画,首先 ...

  9. Unity3D ShaderLab 模拟精灵动画

    Unity3D ShaderLab 模拟精灵动画 在上一篇,介绍了通过Shader 模拟纹理运动,那么更深一步讲,我们也可以把帧动画的精灵纹理运动通过shader实现. 虽然大家都是在游戏脚本中做更高 ...

随机推荐

  1. Spring Boot + Bootstrap 出现"Failed to decode downloaded font"和"OTS parsing error: Failed to convert WOFF 2.0 font to SFNT"

    准确来讲,应该是maven项目使用Bootstrap时,出现 "Failed to decode downloaded font"和"OTS parsing error: ...

  2. R in a nutshell(连载)

    data(cars)dim(cars)names(cars)summary(cars)plot(cars, xlab = "Speed (mph)", ylab = "S ...

  3. Mvc 简单分页代码

    ) { string userid = EndUserLoginManage.Instance.loginUserID; ICommentInfoBLL c_bll = new CommentInfo ...

  4. nodejs前端跨域访问

    XMLHttpRequest cannot load http://localhost:3000/. No 'Access-Control-Allow-Origin' header is presen ...

  5. MySQL的安装配置

    安装配置 MySQL1.官方下载 MySQL2.用 tar 解压.tar.bz 或.tar.gz3.解压后有三个目录,分别为 usr etc var4.进入 usr,进入 bin5.在主机上建个目录( ...

  6. ruby日记1

    1.irb参数配置 ~/.irbrc IRB.conf[:PROMPT_MODE] = :SIMPLE #简化 irb 提示符,以及禁用一些烦人的自动缩进行为 IRB.conf[:AUTO_INDEN ...

  7. NOI 4976:硬币

    描述 宇航员Bob有一天来到火星上,他有收集硬币的习惯.于是他将火星上所有面值的硬币都收集起来了,一共有n种,每种只有一个:面值分别为a1,a2- an. Bob在机场看到了一个特别喜欢的礼物,想买来 ...

  8. How to create Web Deployment Package and install the package

    Create Web Deployment Package To configure settings on the Connection tab In the Publish method drop ...

  9. css居中解决方案

    水平居中 行内或者具有行内元素性质的元素(比如文字或者链接)? 让一个父元素为块级元素的行内元素水平居中,可以:CSS: 1 2 3 .center-children { text-align: ce ...

  10. 用Yaml文件进行元素管理【转】

    原文:http://www.cnblogs.com/milanmi/p/4636503.html 如界面有一个按钮,id号是test.如果进行对象化的话,就是test.click就可以了.不用每次都要 ...