سؤال

I try to load a lot of texture atlases (10) with approximately 5 (~2048x~2048)(not using PoT) .pngs each. I'm using AssetManager and there is no trouble with it on my pc but when I try it on my tablet the app just dies without any error messages or crash reports and there aren't any outOfMemoryExceptions.

Here's my log:

DropBox link

the max memory: 67 is

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

I'm running out of ideas of what to do. Maybe I don't fully understand the way mobile games work: is that a lot of atlases (I have other textures not atlases apart from these atlases)? because everything looks quite fine in the memory segment as much as I know. Anyway I'm open to suggestions and maybe some tips. And I'd really like to keep these atlases in my game.

EDIT: the game loads on my tablet but not phone when I use 1 png per atlas (8192x8192) but my tablet doesn't show images larger than 2048x2048 for some reason oh and the images in the atlas aren't even 1024x1024 so idk why it doesn't show them must be because the atlas is 8192x8192.

EDIT #2: I load only atlases now, no separate .png files and I am now using PoT (2048x2048). 17 atlases some have 2 pngs some even have 1 png but there are some that have 5+ and that's my level plus player animations plus I'm using a gradient for my whole level that is ~10000px in width combined and I use FBO to do a Lighten shader on the level and my level has animations. Is that too much? Anyway this time the game died @ 94% on my phone(Galaxy S2) and @ 58% on my tablet(Lenovo IdeaTab A2109) and here's my new log but this time from my phone:

DropBox link log_new

I'm confused because there aren't any outOfMemory exceptions and I'm disposing every possible thing there is to dispose. btw my app in the logs is com.comraz.slashem

هل كانت مفيدة؟

المحلول

You should consider loading your game assets according to what your needs, and you should manage your assets really well. Load and unload assets as you go through the game. This will help prevent painful crashes caused by low memories. Use something like this as an entry point for your screens, in case your using the stage its even simpler.

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");
    }




    }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top