【问题标题】:libgdx game process dies on loading texture atlaseslibgdx 游戏进程在加载纹理图集时终止
【发布时间】:2015-03-21 03:54:43
【问题描述】:

我尝试加载很多纹理图集 (10),每个图集大约有 5 个 (~2048x~2048)(不使用 PoT).png。我正在使用 AssetManager,它在我的电脑上没有问题,但是当我在平板电脑上尝试它时,应用程序就死了,没有任何错误消息或崩溃报告,也没有任何 outOfMemoryExceptions。

这是我的日志:

DropBox link

最大内存:67是

Runtime().getRuntime().maxMemory() / 1000000

我已经不知道该做什么了。也许我不完全理解手机游戏的工作方式:是不是很多图集(除了这些图集,我还有其他纹理而不是图集)?因为据我所知,内存段中的一切看起来都很好。无论如何,我愿意接受建议,也许还有一些提示。 而且我真的很想在我的游戏中保留这些地图集。

编辑:当我每个图集使用 1 个 png (8192x8192) 但我的平板电脑由于某种原因没有显示大于 2048x2048 的图像时,游戏会在我的平板电脑上而不是手机上加载,哦,图集中的图像甚至不是 1024x1024所以我知道为什么它不显示它们一定是因为图集是 8192x8192。

编辑#2:我现在只加载地图集,没有单独的 .png 文件,我现在使用 PoT (2048x2048)。 17 个图集,有些有 2 个 png,有些甚至有 1 个 png,但有些有 5 个以上,这是我的关卡加上播放器动画,加上我为我的整个关卡使用了一个渐变,总宽度约为 10000 像素,我使用 FBO 来做关卡上的 Lighten 着色器,我的关卡有动画。是不是太多了? 无论如何,这次游戏在我的手机(Galaxy S2)上死了@ 94%,在我的平板电脑上死了@ 58%(Lenovo IdeaTab A2109) 这是我的新日志,但这次来自我的手机:

DropBox link log_new

我很困惑,因为没有任何 outOfMemory 异常,我正在处理所有可能要处理的东西。 顺便说一句,我在日志中的应用是 com.comraz.slashem

【问题讨论】:

  • 您是否尝试过调试(在手机仍连接到计算机时在手机上运行该应用)以确保您没有遗漏打印到日志的错误?
  • 你说你没有使用两个png的力量。我会先尝试一下——我有过模拟器不关心但真正的设备关心的经验。设备使用各种图形驱动程序,坚持使用 PoT 始终是一个好主意。
  • @NigelK 我知道 PoT,它是我的第一选择,但问题仍然存在,游戏只加载了 10 个地图集中的 4 个,但现在它加载了 10 个地图集中的 8 个。
  • @KevinWorkman 当然,这就是我发布日志的方式
  • 认为发生了内存泄漏......一旦检查此链接github.com/libgdx/libgdx/wiki/Memory-management

标签: java android opengl-es libgdx texture-atlas


【解决方案1】:

您应该考虑根据需要加载游戏资源,并且应该很好地管理您的资源。在游戏过程中加载和卸载资产。这将有助于防止因内存不足而导致的痛苦崩溃。使用类似这样的东西作为屏幕的入口点,以防您使用舞台更简单。

public class LoadingScreen extends MyAbstractScreen {

    private static final String TAG = "ASSETLOAD";
    public static final int TYPE_UI_MENU = 0;
    public static final int TYPE_UI_LEVEL = 1;
    public static final int TYPE_UI_HIGHSCORE = 2;
    public static final int TYPE_UI_CREDIT = 3;
    public static final int TYPE_UI_INSTRUCTION = 4;
    public static final int TYPE_GAME = 5;

    public static final  String BASE_ATLAS ="data/base/base_atlas.pack";
    public static final  String UI_MENU_ATLAS ="data/ui_menu/menu_atlas.pack";
    public static final  String UI_LEVEL_ATLAS ="data/ui_level/level_atlas.pack";
    public static final  String UI_HIGHSCORE_ATLAS ="data/ui_highscore/highscore_atlas.pack";
    public static final  String UI_CREDIT_ATLAS ="data/ui_credit/credit_atlas.pack";
    public static final  String UI_INSTRUCTION ="data/ui_instruction/instruction_atlas.pack";
    public static final  String GAME_ATLAS ="data/game_screen/game_atlas.pack";

    private int type;
    private Texture background_loading, logo, progressBarImg, progressBarBaseImg;
    private SpriteBatch batch;
    private boolean loaded = false;
    private Vector2 logoPos, pbPos;
    public TableModel menuTable;
    public EmptyActorLight btnLogo;

    public LoadingScreen(Game game, String screenName, int type)
    {
        super(game, screenName);
        this.type = type;
    }

    @Override
    public void show()
    {
        batch = new SpriteBatch();

        // Load assets needed for loading screen
        getMyGame().getManager().loadGroup("loading_screen");
        getMyGame().getManager().loadGroup("base");
        getMyGame().getManager().finishLoading(); //Blocks until all resources are loaded into memory

        Gdx.app.log(TAG, "Assets loaded");

        // Get Assets
        background_loading = getMyGame().getManager().get("data/loading_screen/background_loading.png");
        logo = getMyGame().getManager().get("data/loading_screen/logo.png");

        //progressBarImg = getMyGame().getManager().get("data/loading_screen/progress_bar.png");
        //progressBarBaseImg = getMyGame().getManager().get("data/loading_screen/progress_bar_base.png");

        // Get logo position
        //logoPos = new Vector2();
        // Centre the log in the screen
        //logoPos.set(Gdx.graphics.getWidth()/2 - logo.getWidth()/2, Gdx.graphics.getHeight()/2 - logo.getHeight()/2);

        // ProgressBar position
        //pbPos = new Vector2();
        //pbPos.set(logoPos.x, logoPos.y - (logo.getHeight()));

        //Depending on screen type load appropriate assets
        switch (type)
        {
        case TYPE_UI_MENU:
            if(getMyGame().getManager().isLoaded(GAME_ATLAS, TextureAtlas.class))
            {
               getMyGame().getManager().unloadGroup("game_screen");
            }
            getMyGame().getManager().loadGroup("ui_menu");
            break;
        case TYPE_UI_LEVEL:
            getMyGame().getManager().loadGroup("ui_level");
            break;
        case TYPE_UI_HIGHSCORE:
            getMyGame().getManager().loadGroup("ui_highscore");
            break;
        case TYPE_UI_CREDIT:
            getMyGame().getManager().loadGroup("ui_credit");
            break;
        case TYPE_UI_INSTRUCTION:
            getMyGame().getManager().loadGroup("ui_instruction");
            break;
        case TYPE_GAME:
            getMyGame().getManager().unloadGroup("ui_menu");
            getMyGame().getManager().unloadGroup("ui_level");
            getMyGame().getManager().unloadGroup("ui_instruction");
            getMyGame().getManager().loadGroup("ui_game");
            break;
        }
    }

    @Override
    public void render(float delta)
    {
        Gdx.gl.glClearColor(0, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        //Render background image
        //batch.begin();
       //batch.draw(background_loading, 0, 0);
        //batch.end();

        // Check if async load is done
        if (!loaded)
        {
            // Render Logo and Loading Bar
            batch.begin();
            batch.draw(logo, Gdx.graphics.getWidth()/2 - logo.getWidth()/2, Gdx.graphics.getHeight()/2 - logo.getHeight()/2);
            //batch.draw(progressBarBaseImg, pbPos.x, pbPos.y);
            //batch.draw(progressBarImg, pbPos.x, pbPos.y,progressBarImg.getWidth() * getMyGame().getManager().getProgress(),progressBarImg.getHeight());
            batch.end();


            if (getMyGame().getManager().update())
            {
                loaded = true;

                switch (type)
                {
                case TYPE_UI_MENU:
                    ((Game) Gdx.app.getApplicationListener()).setScreen(new MenuScreen(getMyGame(), "MainMenu Screen"));
                    break;
                case TYPE_UI_LEVEL:
                    ((Game) Gdx.app.getApplicationListener()).setScreen(new LevelSelectScreen(getMyGame(),"LevelSelect Screen"));
                    break;
                case TYPE_UI_HIGHSCORE:
                    ((Game) Gdx.app.getApplicationListener()).setScreen(new HighScoresScreen(getMyGame(),"Highscore Screen"));
                    break;
                case TYPE_UI_CREDIT:
                    ((Game) Gdx.app.getApplicationListener()).setScreen(new CreditsScreen(getMyGame(),"Credit Screen"));
                    break;
                case TYPE_UI_INSTRUCTION:
                    ((Game) Gdx.app.getApplicationListener()).setScreen(new PreGameScreen(getMyGame(), "Tutorial Screen"));
                    break;
                case TYPE_GAME:
                    ((Game) Gdx.app.getApplicationListener()).setScreen(new GameScreen(getMyGame(), "Game Screen"));
                    break;
                }
            }
        }
        else
        {

        }

    }

    @Override
    public void hide()
    {
        getMyGame().getManager().unloadGroup("loading_screen");
    }




    }

【讨论】:

  • 谢谢。我已经以类似的方式弄清楚了。也使用 AssetManager。我只是忘记发布答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-13
  • 1970-01-01
  • 2015-02-18
  • 1970-01-01
  • 1970-01-01
  • 2020-04-01
  • 1970-01-01
相关资源
最近更新 更多