避免同时下载多个资源
下载一个资源,就需要建立一个连接,而建立连接的过程是需要消耗性能的。像下面这种做法是不推荐的:
//需要加载的资源列表 var assetList:Array = ["1.jpg", "2.jpg", "3.jpg", ......]; var loader:Loader; for each(var asset:String in assetList) { loader = new Loader(); loader.load(new URLRequest(asset)); }
这种做法会一次性同时加载过多资源,由于在短期内造成巨大的性能消耗,这有可能会导致Flash Player卡死,影响用户体验不说,也不见得加载速度会快多少。
使用队列加载方式是一种两全其美的办法,即可以保证不影响性能又能方便监测加载进度。实现思路就是将所有要加载的资源路径放在一个数组中,加载完一个就将该项目从数组中剔除并开始加载数组中下一个资源直到数组中不再存在元素为止。为了方便使用,网上存在很多实现了队列加载的第三方类库。比较有名的一个叫做BulkLoader(类库地址:http://code.google.com/p/bulk-loader/)。这个类库在我的项目中被使用,该类功能强大且使用方式比较简单,还带了对象池,确保了在多次使用同一个资源时不会被反复加载。
名词解释——对象池:所谓对象池,就是在要使用一个对象o时,会从一个Object或者Dictionary对象cache中取出o的缓存,若o不存在于cache中,则想办法创造一个o对象(可以从外部加载或者实例化)。
private var cache:Object = {}; private var asset:String = "1.jpg"; public function Test() { var bmd:BitmapData = getBMD(asset); if( !bmd ) generateBMD(asset); else addBitmap(bmd); } private function generateBMD(assetName:String):void { var loader:Loader = new Loader(); loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComp); loader.load(new URLRequest(assetName)); //将加载的资源名称保存在Loader的name属性中,这样在onComp方法中就能获知我加载得是哪个资源 loader.name = assetName; } private function onComp( e:Event ):void { var loaderInfo:LoaderInfo = e.currentTarget as LoaderInfo; loaderInfo.removeEventListener(Event.COMPLETE, onComp); var assetName:String = loaderInfo.loader.name; var bmp:Bitmap = loaderInfo.content as Bitmap; var bmd:BitmapData = bmp.bitmapData; //将加载得到的BitmapData缓存起来 if( !cache[assetName] ) { cache[assetName] = bmd; } //得到BitmapData就可以往舞台上添加图片了 addBitmap(bmd); //若要再次往舞台上添加同样的图片,则直接就可以从缓存中拿出被缓存的BitmapData,而不需要再次加载 addBitmap( getBMD(asset) ); } private function getBMD(bmdName:String):BitmapData { //若缓存中存在该资源则直接从缓存中取出.否则返回null if( cache[bmdName] ) { return ( cache[bmdName] as BitmapData ).clone(); } return null; } private function addBitmap(bmd:BitmapData):void { var bmp:Bitmap = new Bitmap(bmd); addChild(bmp); }
对于BitmapData对象来说,它可以通过clone方法来不断复制自己,所以可以缓存起来进行重用,但是对于Sprite、MovieClip、Sound这类的对象就不能够这么做了,它们可没有clone方法可以复制自己。因此,对于这些对象,我们可以缓存它们的类定义。那么何谓类定义呢?创建类定义的方法有两种,一,就是我们最熟悉的,创建一个as文件,像这样:
package { import flash.display.MovieClip; public class A extends MovieClip { } }
就创建了一个名为“A”的类定义。二,在fla的库中设置一个元件的属性,让其导出为ActionScript:
这样同样也创建了一个名为“A”的类定义。
有了类定义我们能干嘛呢?类定义就像一个印钞机,我们可以用它无限创建对象
var clz:Class = A; for(var i:int=0; i<5; i++) { var ins:MovieClip = new clz(); }
如果是在同一项目目录下的类,我们可以直接直接拿到其类定义并import进来。那么对于外部加载进来的类定义,我们需要访问其应用域(ApplicationDomain)并使用getDefinition方法来获取到。比如之前我们在lib.fla的库中创建了一个名字叫做A的元件并设置其为ActionScript导出,且导出的ActionScript类名为A。此时我们在我们的项目中若要使用到这个类A,那么我们首先要加载lib.fla发布出来的lib.swf文件,加载完毕后可以拿到它的应用域:
public class Test extends Sprite { public function Test() { var loader:Loader = new Loader(); loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComp); loader.load(new URLRequest("lib.swf")); } private function onComp(e:Event):void { var loaderInfo:LoaderInfo = e.currentTarget as LoaderInfo; var appDomain:ApplicationDomain = loaderInfo.applicationDomain; } }
在得到应用域后,我们需要把应用域中我们需要用到的类取出来并缓存到我们的项目中,这样就方便以后多次使用了
public class Test extends Sprite { private var cache:Object = {}; private var mcName:String = "A"; public function Test() { var clz:Class = getDef(mcName); if( clz ) { addMovie( new clz() as MovieClip ); } else { generateDef(); } } private function generateDef():void { var loader:Loader = new Loader(); loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComp); loader.load(new URLRequest("lib.swf")); } private function onComp(e:Event):void { var loaderInfo:LoaderInfo = e.currentTarget as LoaderInfo; var appDomain:ApplicationDomain = loaderInfo.applicationDomain; cache[mcName] = appDomain.getDefinition(mcName) as Class; //有了类定义之后就可以无限次地往舞台上添加MovieClip对象了 var clz:Class = getDef(mcName); addMovie( new clz() as MovieClip ); addMovie( new clz() as MovieClip ); } private function getDef(name:String):Class { if( cache[name] ) { return cache[name] as Class; } return null; } private function addMovie(mc:MovieClip):void { addChild(mc); } }
在一个大项目中往往需要加载多个swf文件作为外部资源库,那么此时为了知道我某个swf文件中包含哪些类定义,我需要写一张资源配置表,格式类似于:
<assetConfig> <s id='ui' group='ui' type='swf' path='assets/ui.swf'> <i id='WorldPanel' classes='WorldPanel'/> <i id='IslandPanel' classes='IslandPanel'/> <i id='WaitPanel' classes='WaitPanel'/> </s> <s id='ui_friend' group='ui' type='swf' path='assets/ui_friend.swf'> <i id='HomePanel' classes='HomePanel'/> <i id='HomeFriendItem' classes='HomeFriendItem'/> </s> </assetConfig>
每加载完一个swf文件就把它应用域中存放的我们需要用到的类定义缓存起来,以便以后使用。注意,类定义不可重名哦,不然不方便缓存!
合并你的资源
正因为建立连接需要消耗性能,加长用户等待时间,所以我们需要尽可能地削减需要加载的资源数量。把所有相关的图片合并成一个,如下图:
假如进入一个场景后需要加载那么多NPC素材,那么把它们都集成在一张图片中会非常高效,即节省了总体资源尺寸,又减少了资源数量。这种图片资源往往需要配套一个xml配置表记录其中所包含资源的位置、尺寸以便加载完毕后对该图片进行切片使用。
<?xml version="1.0" encoding="UTF-8"?> <TextureAtlas imagePath="Actor1.png"> <SubTexture name="0_0" x="0" y="0" width="32" height="32"/> <SubTexture name="0_1" x="32" y="0" width="32" height="32"/> <SubTexture name="0_2" x="64" y="0" width="32" height="32"/> <SubTexture name="1_0" x="96" y="0" width="32" height="32"/> <SubTexture name="1_1" x="128" y="0" width="32" height="32"/> (省略若干条……) </TextureAtlas>
这种将多个图片素材合并成一个并配以xml配置表的资源形式被称为SpriteSheet,被广泛使用。在Flash CS Professional 6或以上版本中有SpriteSheet生成功能,非常方便。或者你可以选择下载TexturePacker工具来生成SpriteSheet。
如果你不愿意制作SpriteSheet,你可以把多个资源放在一个fla的库中,然后让你的项目来加载该fla生成的swf文件,这样也可以有效地把资源进行打包。
最后,如果你够牛逼,你完全可以用AS代码来进行绘图!
相关推荐
DOOM启示录 DOOM启示录 DOOM启示录
《DOOM启示录》是关于经典第一人称射击游戏DOOM系列的一份详细解析文档,主要探讨了游戏的开发历程、技术细节、游戏文化以及对后续游戏产业的影响。DOOM作为1993年由id Software制作并发行的一款里程碑式游戏,它的...
《Doom启示录》这本书是游戏开发领域的一部重要文献,它揭示了经典第一人称射击游戏Doom的诞生过程,以及其背后的故事和技术细节。这本书对于任何对游戏开发、编程或者电子游戏历史感兴趣的人来说,都是一份珍贵的...
介绍了大量关于现代启示录详细内容现代启示录详细内容现代启示录详细内容
《DOOM启示录》:重塑流行文化的游戏帝国 在IT行业和游戏开发的历史长河中,《DOOM启示录》不仅是一部记录了两位游戏开发者如何创建一个帝国并彻底改变流行文化的书籍,它更是一段传奇故事的见证。由David Kushner...
20210301-方正证券-航空行业全球航空巨头启示录之欧洲篇(一)汉莎航空集团:欧洲第一大航司,低集中度市场下的强垄断.pdf
根据提供的文件信息,“Windows编程启示录.pdf”似乎是一本深入探讨Windows操作系统内部工作原理和技术细节的书籍。本书作者Raymond Chen是微软公司的资深员工,在Windows操作系统的发展历程中扮演了重要角色。下面...
《程序员启示录》这篇文章主要探讨了程序员在职业生涯中应该具备的一些关键态度和技能,结合了技术与职业发展的角度。文章中可能涵盖了多个IT领域的知识,包括编程语言、框架和数据库等。以下是对这些领域的详细解释...
《DOOM启示录》是一部揭示了游戏开发史上里程碑之作——DOOM背后故事的著作。它不仅讲述了这款游戏如何从一个简单的设想发展成为全球现象的过程,也深入探讨了开发者们的创新精神和坚韧不拔的决心。对于那些对游戏...
《Windows编程启示录》是微软资深工程师Raymond Chen所著的一部经典著作,中文版由聂雪军翻译。这本书深入浅出地揭示了Windows操作系统内部的工作原理,为开发者提供了宝贵的编程经验和洞见。中英文版合集的提供,...
技术团队启示录:TOP100实践案例 技术团队启示录:TOP100实践案例
人生启示录.doc
《软件沉思启示录》是ThoughtWorks公司员工智慧的结晶,它揭示了软件开发领域中的深邃思考与实践经验。这份资料不仅涵盖了软件工程的核心理念,还包含个人简历和面试准备的相关内容,对于软件开发者和求职者来说,都...
6. **编程技巧与优化**:书中可能包含了关于C语言编程和游戏性能优化的技巧,如内存管理、代码效率提升等,对于程序员来说具有很高的学习价值。 7. **游戏行业影响**:DOOM的成功推动了游戏行业的快速发展,促进了...
报告标题:“航空行业深度报告:全球航空巨头启示录之美国篇(一)——达美航空集团,全球航空龙头,航空业格局投资成功的典型案例” 报告内容概述: 本深度报告聚焦于全球航空业,特别是美国市场的领导者——达美...
本书首先是为众多的游戏玩家,尤其是John Carmack和id software 的忠实拥趸们准备的,而对更多的人,无论你是否玩DOOM游戏,无论你是否崇拜John Carmack,都会从John Carmack和id software的成功中获得启示。
赛道投资是一种投资理念,它认为投资者应该关注那些在政策推动、消费习惯变化、产品创新或技术进步等因素影响下,具有长期发展前景但当前渗透率仍然较低的领域。在赛道投资中,投资者通过选择正确的行业、产业或技术...
A股投资启示录(十九):A股历史大底是如何炼成的?.pdf