2014-04-12 51 views
5

所以我在LibGDX中制作了一个游戏,在这里我使用AssetManager加载所有资产。 我只是不确定哪个是正确的方式来使用它。正确处理LibGDX AssetManager

目前我在第一个屏幕之前加载所有游戏资产。 然后我清除处理方法中的管理器。但这意味着我有一堆纹理 等,我不需要所有的屏幕。这可能导致内存泄漏?

我想到的另一种方法是只为每个屏幕加载我需要的资源,然后将它们卸载到每个屏幕的hide()方法中。

所以我想知道哪两种方法是最好的方法,或者如果有更好的方法来解决这个问题呢?

感谢

回答

7

首先:如果您在Android上开发,hide()都会被调用用户接听他们的电话或切换到另一个应用程序的时间。这意味着您必须重新分配show()中的资源。对于资源密集型游戏(如RPG游戏)来说,这可能会导致令人讨厌的黑屏,而游戏重新分配图形等。不好玩。

第二个请注意尽早优化您的游戏。如果您遇到内存不足错误,您忘记处理的一些菜单图形可能不是瓶颈。

随着这些点的出路,我已经发现,为了实现资产装载机的最简单方法是有一个单独的Assets类,看起来像这样:

public static AssetManager manager; 
public static TextureAtlas myGraphics; 
public static TextureAtlas myOtherGraphics; 

public static void create() { 
    manager = new AssetManager(); 
    load(); 
} 

private static void load() { 
    manager.load("mygraphics.pack", TextureAtlas.class); 
    manager.load("myothergraphics.pack", TextureAtlas.class); 
} 

public static void done() { 
    myGraphics = manager.get("mygraphics.pack", TextureAtlas.class); 
    myOtherGraphics = manager.get("myothergraphics.pack", TextureAtlas.class); 
} 

public static void dispose() { 
    manager.dispose(); 
} 

然后,在你载入画面的render()方法,您只需拨打Assets.manager.update() - 如果它返回true,请致电Assets.done(),然后转到您的游戏。

这种方法有几个好处。首先,它允许您将所有资产加载逻辑保存在一个类中。其次,如果您必须手动处理资源,则可以简单地拨打Assets.myGraphics.dispose()

如果您发现启动过程中需要加载太多的图形数据(例如Android上的10 MB精灵),您也可以尝试将图形数据拆分为离散块。在我的游戏中,每个精灵都有一个单独的TextureAtlas,每个TextureAtlas在加载时都缓存到一个数组中。

经常使用的精灵,如主角,始终保存在内存中,而较老的精灵会随着时间的推移而被卸载。使用这种方法,我不使用精灵上的10 MB内存,而是使用小于0.5 MB的内存。

+0

谢谢你的回答!我在我的游戏中有类似的设置,但不是让所有东西都是静态的,我有一个单例类。不知道哪种方式更好。我在Assets类中完成所有纹理的加载和卸载,但是我没有在我的资产类中调用manager.dispose()。只有manager.clear()。我知道这是错误的,但是当我使用dispose()方法时,我的应用程序会在我恢复时遇到错误。你知道这是为什么吗?无论如何感谢您的回答! – Johan

+1

manager.dispose()处理* manager本身*,所以你应该使用管理器。清除()。请记住,“内存中的资产”并不等于“内存泄漏”,特别是对于Java的GC策略。除非其他应用程序因为内存问题,否则在hide()期间不需要处理资源。 – user3525774

+5

我对此有疑问。在wiki中提到,“除非你正确地管理它们,否则不要让你的AssetManager或任何其他资源(如纹理等)为静态”。如果我在我的'Game'类中定义资产管理器对象并在整个屏幕中调用它,那不是更容易吗? – WeirdElfB0y