今天中午针对3种知道的位图渲染角色动画的实现方法进行了性能测试,这三种方法分别是:
copyPixels,mask和scrollRect
测试素材:800*600位图文件一张
测试方法:对同屏100个对象不停进行渲染,观察CPU和内存的占用情况。渲染速度30FPS
先说下主要的渲染思路:
copyPixels
指定一个缓冲区变量buffer,将其设置为bitmap的bitmapData属性或者设置为Sprite的beginBitmapFill填充对象,之后,从源位图文件中复制对应的像素到buffer中。
类代码如下:
package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.geom.Point; import flash.geom.Rectangle; /** * ... * @author D5Power */ public class ShowObjectCP extends Bitmap implements Render { private var buffer:BitmapData; private var _source:BitmapData; public function ShowObjectCP(source:BitmapData) { buffer = new BitmapData(40, 40); _source = source; super(buffer); } public function render():void { buffer.copyPixels(_source, new Rectangle(int(760 * Math.random()), int(560 * Math.random()), 40, 40), new Point()); } } }
mask
将源位图作为bitmapData,定义一个Bitmap对象,然后在sprite绘制一个矢量区域,来做为遮罩,之后更改Bitmap的坐标,来实现动画。类代码如下:
package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Sprite; /** * ... * @author D5Power */ public class ShowObjectXY extends Sprite implements Render { private var masker:Sprite; private var b:Bitmap; public function ShowObjectXY(bitmap:BitmapData) { masker = new Sprite(); masker.graphics.beginFill(0); masker.graphics.drawRect(0, 0, 80, 120); addChild(masker); b = new Bitmap(bitmap); addChild(b); b.mask = masker; } public function render():void { b.x = -int(760*Math.random()); b.y = -int(560*Math.random()); } } }
scrollRect
创建一个Bitmap对象,通过修改其 scrollRect属性来更改当前的显示区域。类代码如下:
package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.geom.Rectangle; /** * ... * @author Howard.Ren */ public class ShowObjectSC extends Bitmap implements Render { private var rect:Rectangle; public function ShowObjectSC(bitmap:BitmapData) { super(bitmap); rect = new Rectangle(0, 0, 80, 120); scrollRect = rect; } public function render():void { rect.x= int(760*Math.random()); rect.y = int(560 * Math.random()); scrollRect = rect; } } }
最后,通过主函数在屏幕上同时渲染100个。
package { import flash.display.BitmapData; import flash.display.Sprite; import flash.events.Event; /** * ... * @author Howard.Ren */ public class Main extends Sprite { private var list:Array; public function Main() { list = new Array(); var source:BitmapData = new map(0,0); for (var i:uint = 0; i < 100; i++ ) { var obj:ShowObjectCP = new ShowObjectCP(source); obj.x = int(Math.random() * stage.stageWidth); obj.y = int(Math.random() * stage.stageHeight); addChild(obj); list.push(obj); } addEventListener(Event.ENTER_FRAME, doit ); } private function doit(e:Event):void { for each(var obj:Render in list) { obj.render(); } } } }
运行结果如下:
先来看scrollRect的
再来看mask的
最后来看copyPixels的
其实在运行前,我以为mask的速度会最快,因为只是改动了位图的XY坐标而已,比其他的多了一个mask出来。但是,实际上它的性能跟scrollRect不相上下,怀疑是不是底层是同一实现方法。而copyPixels则稳居第一。只有10%左右的CPU占有。
完毕,上源码。欢迎各路兄弟丢斧头。。。