外部载入的图片和SWF中的显示对象重用方法

在游戏制作的过程中,经常需要将图片资源外置,因此我写了一个 VisualLoader 类用于批量载入皮肤。该类可以载入外部的图片文件或者swf文件,如果载入的是图片文件就将其转换为Bmp对象,如果载入的是swf文件,就利用反射获取库中导出的Symbol的Class,然后使用new操作符建立相应的对象。

实际上,如果载入的是swf,则获取的不仅仅限于显示对象,只要在Flash软件的库中可以“导出”的类型都可以获取。例如Font、MovieClip、Sound、SimpleButton等等。关于具体的实现方式,还可以参考这篇文章: 使用Loader/URLLoader/URLStream载入外部swf并获取类定义

这个类写好后,在实际使用的时候出了问题。地图配置中明明有18个使用了外部图片的对象,但显示出来却只有6个!一开始百思不得其解,做了许多调试工作。后来才想通,原来自己犯了个超级低级的错误!

在载入后,我保存的是对象而不是类,这样无论将该对象加入几次显示列表,对象还是原来的那个对象。对于swf中的显示对象来说很简单,只需要使用VisualLoader的getClass方法获取该显示对象的Class,每次建立一个Class的实例即可。

但是对于载入的外部图片,则无法通过反射获取图片的类。这就需要新建一个Bitmap对象,然后将外部载入的图像的bitmapData属性赋予它。看下面这个duplicateBMP方法:

1private function duplicateBMP($bmp:Bitmap):Bitmap
2{
3    return new Bitmap($bmp.bitmapData, PixelSnapping.AUTO, true);
4}

也可以使用BitmapData的draw方法来复制:

1private function duplicateBMP($bmp:Bitmap):Bitmap
2{
3    var __bmpData:BitmapData = new BitmapData($bmp.width, $bmp.height, true, 0x00FFFFFF);
4    __bmpData.draw($bmp);
5    return new Bitmap(__bmpData, PixelSnapping.AUTO, true);
6}

使用第二种方法要注意,如果复制的图片是支持Alpha透明的,那么BitmapData构造函数的第三个参数就必须填写。如果采用默认值,复制出来的图片就是不透明的。

第三个参数填写的值,应该是下面的格式,其中大写的X代表任意0-F的十六进制数:

10x00XXXXXX

这个格式与我们常用的6位的颜色格式不太相同,一共有8位。0x后面紧接的00就是代表Alpha透明度的。

当然,如果只是用 0x00 或者 0x000000 也可以实现被复制的位图的透明,但是0x后面的紧接着的两个数字一定不能是除了00之外的其它数字。