2014-04-12 50 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