【问题标题】:proper handling of LibGDX AssetManager正确处理 LibGDX AssetManager
【发布时间】:2014-04-12 17:50:34
【问题描述】:

所以我在 LibGDX 中制作游戏,我使用 AssetManager 加载我的所有资产。 我只是不确定哪个是正确的使用方法。

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

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

所以我想知道这两种方法中哪一种是最好的方法,或者是否有 有更好的处理方法吗?

谢谢

【问题讨论】:

    标签: libgdx


    【解决方案1】:

    首先:如果您在 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 的 sprite),您也可以尝试将图形数据分解为离散的块。在我的游戏中,每个精灵都有一个单独的TextureAtlas,每个TextureAtlas在加载时都会缓存到一个数组中。

    经常使用的精灵,例如主角,总是保存在内存中,而较旧的精灵会随着时间的推移而被卸载。使用这种方法,我现在使用的内存不到 0.5 MB,而不是在 sprite 上使用 10 MB 内存。

    【讨论】:

    • 感谢您的回答!我的游戏中有类似的设置,但我没有让所有东西都是静态的,而是有一个单例类。真的不知道哪种方式更好。我在我的资产类中执行所有纹理的加载和卸载,但我没有在我的资产类中调用 manager.dispose()。只有 manager.clear()。我知道这是错误的,但是当我使用 dispose() 方法时,我的应用程序在恢复时会出错。你知道为什么会这样吗?无论如何感谢您的回答!
    • manager.dispose() 处理 manager 本身,因此您应该改用 manager.clear()。请记住,“内存中的资产”不等于“内存泄漏”,尤其是在 Java 的 GC 策略中。除非其他应用程序因此出现内存问题,否则您确实不需要在 hide() 期间处理资产。
    • 我对此有疑问。在 wiki 中,提到“不要让您的 AssetManager 或任何其他资源(如纹理等)静态,除非您正确管理它们”。如果我在 Game 类中定义资产管理器对象并在整个 Screens 中调用它会不会更容易?
    猜你喜欢
    • 1970-01-01
    • 2017-12-20
    • 1970-01-01
    • 2017-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多