问题描述
|
我正在利用Flash Builder 4 IDE构建一个Adobe AIR应用程序(二维平台冒险游戏),该软件包将打包在CD上进行安装。我将大多数游戏资产都嵌入到一个静态类中,以使其保持简单和有条理。这样,我可以重复使用资产并交换它们而无需进行过多挖掘。
例:
[Embed(source = \“ ../ data / gfx / spritesheets / boyHero.png \”)]公共静态var boyHero:Class;
在项目初期,一切都按计划进行。但是,随着项目的增长超过28MB,我开始遇到内存不足错误。这些发生在我添加新资产,重构一段时间或添加新类时。收到此错误后,我可以重新启动FB,然后再工作15-20分钟。
我已经修改了.ini文件,从而增加了Flash Builder 4的内存分配。当前设置为:
-xms512m
-Xmx1024m
在执行此操作时,以下是我已安装的规格/插件:
Flash Builder v 4.0(内部版本272416)
JNA库3.2.7
subclipse插件1.6.17
颠覆客户端适配器1.6.12
颠覆JavaHL Native Lib 1.6.15
SVNKit库1.3.5.7406
Mac OSx v 10.6.7
2.53 GHz Intel Core 2 Duo
4GB DDR
我的问题:
1)我在处理游戏中资产时选择的路径是否有问题?我正在流式传输某些资源,例如通过SWFLoader加载的教程swfs。我可以为所有资产走这条路...但是,我应该吗?这是处理磁盘游戏的正确方法吗? (将游戏安装在质量检查机器上后,运行顺利。)
2)前提是嵌入静态资产不是问题,这是FB4错误吗?我应该去哪里获取更多信息?
提前非常感谢!
-J
解决方法
在我看来,是时候将您的资产分解为单独的文件,并在运行时从磁盘加载它们了。这将在您编辑代码时释放一些空间,以使FB4不会发疯。我刚刚完成了一款拥有大量资产的Facebook游戏,最终将所有声音放入他们自己的SWF中,所有沉重的图形都放入他们自己的SWF中,然后在运行时加载它们。这是关键点的细分:
对我来说,我使用Flash CS5生成资产,并在第一帧中导出用于动作脚本的符号。我只导出电影,Flash会将我的资产SWF交给我,我很高兴。或者,您可以使用带有大量嵌入标签的简单AS文件,然后使用ant或FB4将其编译为它自己的SWF。归根结底,只要您将资产纳入SWF,这实际上是一回事。
这样,您将拥有一个充满符号名称的文件,而不是将充满Embed标签的文件包含在其余的游戏逻辑中,以便可以在需要它们时获取它们:
//GraphicalAssets.as
//the linkage for this asset in your asset swf would need to match \'hero_guy_graphic\'
public static var HERO_GUY_GRAPHIC:String = \"hero_guy_graphic\";
在某些地方,您还保留资产文件名:
//AssetFiles.as
public static var CHARACTER_ASSETS:String = \"thePathToTheCharacterAssetsFile.swf\";
在继续之前,最好将我要描述的功能放入某种AssetManager类中。您不想每次游戏都需要资产时都加载文件,因此AssetManager类为您提供了一个挂在资产上的位置,直到您确定它们已经完成。 (您可能已经知道)
无论如何,当您决定在游戏中需要这些资产时,可以使用Loader实例(大概在AssetManager类中的某个位置)加载它们:
var loader:Loader = new Loader();
var loader.contentLoaderInfo.addEventListener(Event.COMPLETE,handleAssetsLoaded);
//add some error event listeners here too...
var request:URLRequest = new URLRequest(pathToMyAssetsFile);
loader.load(request);
在handleAssetsLoaded
函数中,您将停留在已加载的SWF的applicationDomain
对象上。 applicationDomain是您对SWF中所有符号定义的访问点。
private function handleAssetsLoaded(evt:Event):void {
//hang on to this for later
var appDomain:ApplicationDomain = (evt.target as LoaderInfo).applicationDomain;
//a good way to do that would be have a private array where you hang on to them
//_appDomains[\"TheNameOfMyAssetFile.swf\"] = appDomain;
}
然后,当您要获取特定资产时,可以使用某种getAsset()方法:
public function getAsset(assetName:String,fileName:String):* {
var assetFileAppDomain:ApplicationDomain = _appDomains[fileName] as ApplicationDomain;
var assetClassDefinition:Class = assetFileAppDomain.getDefinition(assetName) as Class;
return new assetClassDefinition();
}
最后,当您想在游戏中加入HeroGuy时,您会看到一些如下所示的呼叫:
//assuming AssetManager is a singleton that we can get with AssetManager.instance ...
var heroGuyGraphic:MovieClip = AssetManager.instance.getAsset( GraphicalAssets.HERO_GUY_GRAPHIC,AssetFiles.CHARACTER_ASSETS ) as MovieClip;
希望这足以使您走上正确的道路。在大多数情况下,我在运行时加载资产文件时都是通过Web进行的,但是我不明白为什么应用相同的技术从磁盘获取资产不起作用的原因。如果您有任何疑问,请告诉我-很抱歉,如果我不清楚的话,我想您知道足够填补空白:)
祝你好运!