A闪的 BLOG 技术与人文
从1.5.3版本开始,Egret中对MovieClip架构进行了重新设计,在前一段时间发布的1.6版本中,Egret彻底稳定了新的MovieCilp架构设计。
相信很多开发这还没有实际使用过,或者对新的MovieClip还不太了解。这里介绍一下。
在旧版本的MovieClip中,需要处理逐帧动画的数据,已经位图资源,并且在MovieClip中进行播放暂定等操作。这个类,耦合度非常高,没有对数据与业务逻辑进行分离。使用起来灵活度收到一定限制。
在新版本的MovieClip架构设计中,Egret将数据与逐帧动画业务功能进行了分离。从而大家能看到两个新的类,MovieClipData与MovieClipDataFactory。
MovieClipData中专门用来存储逐帧动画中的数据,而MovieClipDataFactory则用于存储MovieClipData与Texture。仅仅是负责存储数据与纹理,由于数据为json格式,不涉及到数据解析的问题。
MovieClip的功能则进行了简化,其实也是去数据化,将原有和数据存储,纹理存储相关的操作移除,只保留和动画相关逻辑。
这样做的优势有两个
1、数据与逻辑彻底分离。对功能扩展有相当大的帮助。 2、数据被分离后,我们可以通过MovieClipDataFactory单独管理数据,进行操作,或者进行缓存控制。
我们通过几个demo来展示一下全新的MovieClip用法以及技巧。
为了方便,我们做了一个仅仅有5帧的逐帧动画,内容非常简单,都是100×100像素的正方形,只不过每帧颜色不同。
动画制作完成后,使用新的MovieClip Plug-in,来导出Egret所支持的格式以及贴图,json数据和图片在下面。
{ "mc": { "mcdemo": { "frameRate":24, "labels": [ ], "frames": [ {"res":"mcdemo0000","x":0,"y":0}, {"res":"mcdemo0001","x":0,"y":0}, {"res":"mcdemo0002","x":0,"y":0}, {"res":"mcdemo0003","x":0,"y":0}, {"res":"mcdemo0004","x":0,"y":0} ] } }, "res": { "mcdemo0000":{"x":0,"y":0,"w":100,"h":100}, "mcdemo0001":{"x":0,"y":100,"w":100,"h":100}, "mcdemo0002":{"x":0,"y":200,"w":100,"h":100}, "mcdemo0003":{"x":0,"y":300,"w":100,"h":100}, "mcdemo0004":{"x":0,"y":400,"w":100,"h":100} } }理论上来说,清晰的了解MovieClip的动画数据格式是非常重要的,但鉴于这篇文章中不会对高级用法做太多介绍,所以这部分内容放到下一篇中介绍。
下面要编写的代码很简单(只提供核心代码)
var data = RES.getRes("mcdemo_json"); var tex = RES.getRes("mcdemo_png"); var mcf:egret.MovieClipDataFactory = new egret.MovieClipDataFactory(data,tex); var mc:egret.MovieClip = new egret.MovieClip( mcf.generateMovieClipData("mcdemo")); this.addChild(mc); mc.play();完成这段代码后,build并且startserver一下,查看你动画的效果。如果你看到了一个快速的,一闪而过的动画,那么恭喜你,成功了第一步。
如果你查看过MovieClipDataFactory的API,你会发现,方法仅仅有3个,属性也仅仅有4个。
我们再来略微修改一下代码,看看效果。
var data = RES.getRes("mcdemo_json"); var tex = RES.getRes("mcdemo_png"); var mcf:egret.MovieClipDataFactory = new egret.MovieClipDataFactory(data,tex); var mc:egret.MovieClip = new egret.MovieClip( mcf.generateMovieClipData("mcdemo")); this.addChild(mc); mc.play();console.log(mcf.mcDataSet); var bit:egret.Bitmap = new egret.Bitmap(); bit.texture = mcf.spriteSheet.getTexture("mcdemo0003"); bit.x = 130; bit.y = 130; this.addChild(bit);
如果你看到这样的图,那么证明你是对的。不要怀疑,我们的代码没有错误。你可能会有疑问,为什么舞台上看不到我们新创建的Bitmap,而console我们的MC数据是正常的。
这是一个非常好玩的问题。现在你把 bit.texture = mcf.spriteSheet.getTexture(“mcdemo0003”); 中的”mcdemo0003”改为”mcdemo0000”,再测试一下试试。
如果你看到了上面这样的效果,证明你正确了。为什么会这样,只有”mcdemo0000”能够正常显示,而其他的不可以。 我们要来了解一下MovieClip的运作机制。当你使用MovieClipDataFactory来创建数据的时候,MovieClip既包含json数据,也包含一个SpriteSheet对象,也就是我们的纹理集。
但是请注意,此时SpriteSheet中仅仅只有一张纹理集图片,没有单独的纹理,这是因为还没有调用SpriteSheet中的createTexture方法来创建单独纹理。所以你获取mcdemo0003肯定是返回空值的。我们在新代码中先创建了MovieClip,虽然执行了play操作,但是,MovieClip第一帧此时已被创建。所以,mcdemo0000是存在的。
通过修改刚才的错误代码,你可以看到效果。
我们通过MovieClip来获取其中的MovieClipData数据,并且打印出一些基本数据。
var data = RES.getRes("mcdemo_json"); var tex = RES.getRes("mcdemo_png"); var mcf:egret.MovieClipDataFactory = new egret.MovieClipDataFactory(data,tex); var mc:egret.MovieClip = new egret.MovieClip( mcf.generateMovieClipData("mcdemo")); this.addChild(mc); mc.play();效果如图:console.log("frameRate:"+mc.movieClipData.frameRate+"\nnumFrames:"+mc.movieClipData.numFrames);
这篇简单的介绍先写到这里,后面再追加一个高级篇。