当TextureAtlas中存在太多Sprite时,游戏会挂起

时间:2014-06-21 04:45:46

标签: libgdx texturepacker

为了使用精灵渲染清晰的图形,我决定为每个分辨率提供专用的精灵文件夹。我有 55个这样的文件夹,每个文件夹包含 57 .png个文件(这意味着总数为57 * 55 = 3135个文件 )。我将所有55个文件夹放在一个文件夹中,然后在该文件夹上运行Texture Packer。在输出文件夹中,我得到1 pack.atlas个文件和212 packX.png个文件(X从1到212运行)

在我的代码中,我在Assets

中创建了这些字段
private static TextureAtlas atlas;
private static Sprite logo;
// ... total of 57 Sprite fields....

Assets类的初始化方法中,在游戏开始时调用:

atlas = new TextureAtlas(Gdx.files.internal("pack.atlas"));
logo = atlas.createSprite(getWidthPath() + "logo");   //getWidthPath() returns the appropriate folder path based on the resolution size. As stated above, there are 55 such folder
//...atlas.createSprite 57 times for 57 fields....

我已经为少量文件夹(3个文件夹)做了这个,游戏运行良好。但是,当我决定支持所有55个分辨率文件夹时,游戏无法在Android上加载并且可以在桌面上加载但在开始时确实很慢。

pack.atlas文件引用的大量精灵导致挂起,这是真的吗?

我想如果我只是在每个分辨率文件夹上运行TexturePacker,我将获得55个pack.atlas个文件(而不是1个),每个pack.atlas文件现在将引用57个精灵(而不是3135个文件),游戏应该运行良好,但它太费力了

2 个答案:

答案 0 :(得分:2)

正如@noone所说,将不同分辨率大小的所有精灵打包成一个TextureAtlas会破坏地图集的含义。我必须为每个分辨率打包一张地图集。但问题是如何自动完成?

在看到TexturePacker设置不允许这样后,最后我必须稍微修改类TexturePacker的源代码,并从指令here构建我自己的自定义Libgdx构建

我只更改main函数以接受另一个参数(true或false)来指定是否应该打包到输入文件夹的子文件夹中。它不是指定选项的传统方式,但对我的情况来说已经足够了。

这是类main

中修改后的TexturePacker.java函数
static public void main (String[] args) throws Exception {
    String input = null, output = null, packFileName = "pack.atlas";
    boolean optionSeparateFolder = false;

    switch (args.length) {
    case 4:
        packFileName = args[3];
    case 3:
        optionSeparateFolder = Boolean.parseBoolean(args[2]);
    case 2:
        output = args[1];
    case 1:
        input = args[0];
        break;
    default:
        System.out.println("Usage: inputDir [outputDir] [packToSeparateFolder] [packFileName]");
        System.exit(0);
    }
    File inputFile = new File(input);
    if (!optionSeparateFolder) {
        if (output == null) {
            output = new File(inputFile.getParentFile(), inputFile.getName() + "-packed").getAbsolutePath();
        }
        process(input, output, packFileName);
    }
    else{
        String[] childrenOfInput = inputFile.list();
        File outputFile = new File(output);
        for (int i=0; i<childrenOfInput.length; i++){
            process(inputFile.getAbsolutePath()+"/"+childrenOfInput[i],outputFile.getAbsolutePath()+"/"+childrenOfInput[i],packFileName);
        }
    }

}

答案 1 :(得分:1)

  

我想如果我只是在每个分辨率文件夹上运行TexturePacker,我将获得55个pack.atlas个文件(而不是1个),每个pack.atlas文件现在将引用57个精灵(而不是3135个文件),游戏应该运行良好,但它太费力了。

运行封隔器55次太费力了,但是创建55种不同变体的每个精灵不是吗?

你应该想出一个不同的方法,因为这个方法不会有效。我假设你的一个图册页面是1024x1024。所以大概1MB。拥有212个这样的页面将导致仅精灵的212MB。并且用户只会使用 ONE 这样的精灵集合,积极使用1MB,但仍然携带211MB无用的其他精灵集。

此外,如果不以任何理智的方式对资产进行分组(例如每张分辨率为1张图册),则会完全破坏图集的目的。 TextureAtlas用于减少降低性能的OpenGL纹理绑定量。但在您的情况下,由此产生的地图集在这212个页面中具有所有随处所需的资产。这意味着在渲染时,在幕后你仍然会有很多纹理绑定,因为那些212页和分散的精灵。

您可以查看Viewport。它可以帮助您处理不同的分辨率,并实施了许多策略。您应该使用这种方法,而不是为每种可能的分辨率提供一组精灵。如果你想为每个分辨率提供像素完美的精灵渲染,你仍然需要55种不同的变体,但是你需要重新打包55个版本的应用,而不是在一个应用程序中打包55个版本。