在flash游戏开发中,很多时候需要在屏幕上面显示很多个MovieClip,如果在屏幕上面有过多的矢量图,相信会卡得飞起。因为在矢量图移动的时候会消耗很多CPU资源,所以为了可以让更多的MovieClip可以显示在屏幕上面而不影响效率,就采用了转换成位图的方式。用内存去换取CPU,就是说消耗多点内存,降低CPU的消耗。而且有些时候,可以作动态导图,就是说可以把MovieClip的每一帧在运行的时候都转换成位图,然后封装到一个类里面,模仿MovieClip的写法自己写一个类出来,里面存的都是位图,就算在屏幕上面显示几百个,也会相当的流畅。本人之前就自己写过一个模仿MovieClip的类,里面的每一帧都是一个位图,是把一个MovieClip传进去之后转换而成的。不过这个方法有两个弊端,一个是需要时间去加载,因为MovieClip是带有时间轴的,而且要获取每帧上面的图像,是需要时间的。另外一个弊端是如果MovieClip里面再嵌套MovieClip的话,这方法就不灵了,因为动画里面有动画,导出的位图达不到嵌套多层动画的效果。第二个弊端可以用一些动画的技巧去弥补,第一个弊端的话确实没办法,一次性大量的转换成位图的话还是相当消耗资源和时间的,这里或许会有优化的算法,不过无论怎么优化,一个游戏也得有成百上千的图要转换。
下面分享一下自己写的一个位图转换类,写得不好的地方请见谅
Display2Bitmap.as
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.DisplayObjectContainer;
import flash.display.Sprite;
import flash.geom.Matrix;
import flash.geom.Rectangle;
/**
* ...
* @author Gary
*/
public class Display2Bitmap
{
public function Display2Bitmap() {}
public static function Change(Dis:DisplayObjectContainer)
{
var tempBitmapData:BitmapData = new BitmapData(Dis.width / Dis.scaleX, Dis.height / Dis.scaleY, true, 0x00000000);
var rectangle:Rectangle = Dis.getBounds(Dis.stage);
var mix:Matrix = new Matrix;
mix.tx -= rectangle.x;
mix.ty -= rectangle.y;
tempBitmapData.draw(Dis,mix);
removeAllChildren(Dis);
var tempBitmap:Bitmap = new Bitmap(tempBitmapData);
tempBitmap.x += rectangle.x;
tempBitmap.y += rectangle.y;
Dis.addChild(tempBitmap);
}
//转成图片的内容超过2880*2880 在flash里面超过2880的图片要作特殊处理,不是的话不能正常显示
public static function BigBitmapChange(Dis:DisplayObjectContainer)
{
var wCount:int = 0;
var hCount:int = 0;
wCount = Math.ceil(Dis.width / 2880);
hCount = Math.ceil(Dis.height / 2880);
var w:Number = Dis.width;
var h:Number = Dis.height;
var bitmapCache:Array = new Array;
var rectangle:Rectangle = Dis.getBounds(Dis.stage);
if (wCount == 1 && hCount == 1)
{
Change(Dis);
return;
}
else
{
var tempW = w;
var tempw:Number = 0;
var temph:Number = 0;
for (var i:int = 0; i < hCount; i++)
{
w = tempW;
if (i + 1 == hCount)
{
temph = h;
if (temph < 2880)
{
temph = Math.ceil(temph);
}
}
else
{
h -= 2880;
temph = 2880;
}
for (var j:int = 0; j < wCount; j++)
{
if (j + 1 == wCount)
{
tempw = w;
if (tempw < 2880)
{
tempw = Math.ceil(tempw);
}
}
else
{
w -= 2880;
tempw = 2880;
}
var tempBitmapData:BitmapData = new BitmapData(tempw, temph, true, 0x00000000);
var mix:Matrix = new Matrix;
mix.tx -= rectangle.x;
mix.ty -= rectangle.y;
mix.tx -= 2880 * j;
mix.ty -= 2880 * i;
tempBitmapData.draw(Dis,mix);
var tempBitmap:Bitmap = new Bitmap(tempBitmapData);
tempBitmap.x += rectangle.x;
tempBitmap.y += rectangle.y;
tempBitmap.x += 2880 * j;
tempBitmap.y += 2880 * i;
bitmapCache.push(tempBitmap);
}
}
}
removeAllChildren(Dis);
var len:int = bitmapCache.length;
for (i = 0; i < len; i++)
{
Dis.addChild(bitmapCache[i] as Bitmap);
}
}
//返回的Bitmap的坐标位置与Dis容器的位置相对应
public static function Change2Bitmap(Dis:DisplayObjectContainer):Bitmap
{
var tempBitmapData:BitmapData = new BitmapData(Dis.width / Dis.scaleX, Dis.height / Dis.scaleY, true, 0x00000000);
var rectangle:Rectangle = Dis.getBounds(Dis.stage);
var mix:Matrix = new Matrix;
mix.tx -= rectangle.x;
mix.ty -= rectangle.y;
tempBitmapData.draw(Dis,mix);
var tempBitmap:Bitmap = new Bitmap(tempBitmapData);
tempBitmap.x += rectangle.x;
tempBitmap.y += rectangle.y;
return tempBitmap;
}
//转成图片的内容超过2880*2880;
public static function BigBitmapChange2(Dis:DisplayObjectContainer):Sprite
{
var wCount:int = 0;
var hCount:int = 0;
wCount = Math.ceil(Dis.width / 2880);
hCount = Math.ceil(Dis.height / 2880);
var w:Number = Dis.width;
var h:Number = Dis.height;
var bitmapCache:Array = new Array;
var rectangle:Rectangle = Dis.getBounds(Dis.stage);
var tempMySprite:Sprite = new Sprite;
if (wCount == 1 && hCount == 1)
{
tempMySprite = Change2BitMap2(Dis);
return tempMySprite;
}
else
{
var tempW = w;
var tempw:Number = 0;
var temph:Number = 0;
for (var i:int = 0; i < hCount; i++)
{
w = tempW;
if (i + 1 == hCount)
{
temph = h;
if (temph < 2880)
{
temph = Math.ceil(temph);
}
}
else
{
h -= 2880;
temph = 2880;
}
for (var j:int = 0; j < wCount; j++)
{
if (j + 1 == wCount)
{
tempw = w;
if (tempw < 2880)
{
tempw = Math.ceil(tempw);
}
}
else
{
w -= 2880;
tempw = 2880;
}
var tempBitmapData:BitmapData = new BitmapData(tempw, temph, true, 0x00000000);
var mix:Matrix = new Matrix;
mix.tx -= rectangle.x;
mix.ty -= rectangle.y;
mix.tx -= 2880 * j;
mix.ty -= 2880 * i;
tempBitmapData.draw(Dis,mix);
var tempBitmap:Bitmap = new Bitmap(tempBitmapData);
tempBitmap.x += rectangle.x;
tempBitmap.y += rectangle.y;
tempBitmap.x += 2880 * j;
tempBitmap.y += 2880 * i;
bitmapCache.push(tempBitmap);
}
}
}
var len:int = bitmapCache.length;
for (i = 0; i < len; i++)
{
tempMySprite.addChild(bitmapCache[i] as Bitmap);
}
return tempMySprite;
}
//返回的Bitmap的坐标位置与Dis容器的位置相对应
public static function Change2Bitmap2(Dis:DisplayObjectContainer):Sprite
{
var tempBitmapData:BitmapData = new BitmapData(Dis.width / Dis.scaleX, Dis.height / Dis.scaleY, true, 0x00000000);
var rectangle:Rectangle = Dis.getBounds(Dis.stage);
var mix:Matrix = new Matrix;
mix.tx -= rectangle.x;
mix.ty -= rectangle.y;
tempBitmapData.draw(Dis,mix);
var tempBitmap:Bitmap = new Bitmap(tempBitmapData);
tempBitmap.x += rectangle.x;
tempBitmap.y += rectangle.y;
var tempMySprite:Sprite = new Sprite;
tempMySprite.addChild(tempBitmap);
return tempMySprite;
}
/清楚所有子对象函数removeAllChildren()/
public static function removeAllChildren(container:DisplayObjectContainer):void
{//删除子对象,释放内存,container参数为子对象的父级
var count:int = container.numChildren;
for (var i:int = 0; i < count; i++)
{
container.removeChildAt(0);
}
}
}
}
根据需要去调用,需要注意的是有些方法是会清空传进去的容器,然后再填充位图进去的,所以要慎用,一般我都只会用有返回值的方法。在外面再用容器去存放,这样比较保险点,因为如果传进去的容器被清空了的话,可能会影响外面的操作。