java - Android Studio/LibGDX 游戏内存不足

标签 java android memory libgdx dispose

我正在尝试开发一个简单的游戏来学习基本的 Java 知识。一切似乎都运行良好,但过了一段时间我就会开始崩溃。我认为发生的情况是我创建了太多对象并且内存不足,但我不知道如何防止这种情况。我想知道是否有人有任何提示或可以看到我在哪里犯了错误,我很高兴听到建议。

package com.colordash.game;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.InputListener;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Button;
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
import com.badlogic.gdx.utils.viewport.ScreenViewport;

import java.util.Random;

class GameScreen implements Screen {
    private final ColorDash game;
    private Texture backgroundTexture;

    private OrthographicCamera camera;

    // rby ryb yrb ybr bry byr

    private float screenWidth;
    private float screenHeight;
    private int leftPressedValue;
    private int rightPressedValue;
    private int measuredValue;
    private int neededValue;

    private float redHeight;
    private float blueHeight;
    private float yellowHeight;

    private Stage stage;

    private Texture centerDisplayTexture;
    Texture buttonLRed;

    private float time;

    int randomNum;

    public GameScreen(final ColorDash gam) {
        this.game = gam;
        time = 0;

        backgroundTexture = new Texture(Gdx.files.internal("background2.png"));
        backgroundTexture.setWrap(Texture.TextureWrap.Repeat, Texture.TextureWrap.Repeat);

        // create the camera and the SpriteBatch

        stage = new Stage(new ScreenViewport()); //Set up a stage for the ui
        screenWidth = stage.getWidth();
        screenHeight = stage.getHeight();

        float buttonWidth = 3 * (screenWidth / 12);
        float buttonHeight = 4 * (screenHeight / 12);

        float buttonLower = 1 * (screenHeight / 3) - buttonHeight;
        float buttonMid = 2 * (screenHeight / 3) - buttonHeight;
        float buttonHigher = 3 * (screenHeight / 3) - buttonHeight;

        float col1 = screenWidth - 23 * (screenWidth / 24);
        float col2 = screenWidth - 1 * (screenWidth / 24) - buttonWidth;

        Random randomButtons = new Random();
        int buttonLocations = randomButtons.nextInt(6);
        if (buttonLocations == 0) {
            redHeight = buttonLower;
            blueHeight = buttonMid;
            yellowHeight = buttonHigher;
        } else if (buttonLocations == 1) {
            redHeight = buttonLower;
            blueHeight = buttonHigher;
            yellowHeight = buttonMid;
        } else if (buttonLocations == 2) {
            redHeight = buttonMid;
            blueHeight = buttonLower;
            yellowHeight = buttonHigher;
        } else if (buttonLocations == 3) {
            redHeight = buttonHigher;
            blueHeight = buttonLower;
            yellowHeight = buttonMid;
        } else if (buttonLocations == 4) {
            redHeight = buttonHigher;
            blueHeight = buttonMid;
            yellowHeight = buttonLower;
        } else if (buttonLocations == 5) {
            redHeight = buttonMid;
            blueHeight = buttonHigher;
            yellowHeight = buttonLower;
        }

        // red 1
        // blue 2
        // yellow 4

        int[] combinations = new int[6];
        combinations[0] = 2; // red red
        combinations[1] = 3; // red blue
        combinations[2] = 4; // blue blue
        combinations[3] = 5; // yellow red
        combinations[4] = 6; // yellow blue
        combinations[5] = 8; // yellow yellow

        leftPressedValue = 0;
        rightPressedValue = 0;
        measuredValue = 0;

        Random rn = new Random();
        int randomNum = rn.nextInt(6);
        if (ColorDash.lastRandomNumber == randomNum) {
            randomNum = rn.nextInt(6);

        }
        neededValue = combinations[randomNum];

        if (neededValue == 2) {
            centerDisplayTexture = new Texture(Gdx.files.internal("redBig.png"));
        } else if (neededValue == 3) {
            centerDisplayTexture = new Texture(Gdx.files.internal("purple.png"));
        } else if (neededValue == 4) {
            centerDisplayTexture = new Texture(Gdx.files.internal("blueBig.png"));
        } else if (neededValue == 5) {
            centerDisplayTexture = new Texture(Gdx.files.internal("orange.png"));
        } else if (neededValue == 6) {
            centerDisplayTexture = new Texture(Gdx.files.internal("green.png"));
        } else if (neededValue == 8) {
            centerDisplayTexture = new Texture(Gdx.files.internal("bigyellow.png"));
        }

        // center display
        TextureRegion centerDisplayTextureRegion = new TextureRegion(centerDisplayTexture);
        TextureRegionDrawable centerDisplayTexRegionDrawable = new TextureRegionDrawable(centerDisplayTextureRegion);

        Button centerDisplay = new Button(centerDisplayTexRegionDrawable);
        centerDisplay.setSize(screenHeight / 2, screenHeight / 2);
        centerDisplay.setPosition(screenWidth / 2 - (screenHeight / 2) / 2, screenHeight / 2 - (screenHeight / 2) / 2);
        stage.addActor(centerDisplay);

        // red buttons
        Texture redButtonTexture = new Texture(Gdx.files.internal("redright.png"));
        TextureRegion redButtonTextureRegion = new TextureRegion(redButtonTexture);
        TextureRegionDrawable redButtonTexRegionDrawable = new TextureRegionDrawable(redButtonTextureRegion);

        Button buttonLRed = new Button(redButtonTexRegionDrawable);
        buttonLRed.setSize(buttonWidth, buttonHeight);
        buttonLRed.getStyle().up = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("redleft.png"))));
        //buttonLRed.getStyle().down = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("redleft.png"))));
        buttonLRed.setPosition(col1, redHeight);

        Button buttonRRed = new Button(redButtonTexRegionDrawable);
        buttonRRed.setSize(buttonWidth, buttonHeight);
        buttonRRed.getStyle().up = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("redright.png"))));
        //buttonRRed.getStyle().down = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("redright.png"))));
        buttonRRed.setPosition(col2, redHeight);

        buttonLRed.addListener(new InputListener() {@Override
        public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
            leftPressedValue = 1;
        }@Override
        public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
            leftPressedValue = 1;
            return true;
        }
        });
        buttonRRed.addListener(new InputListener() {@Override
        public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
            rightPressedValue = 1;
        }@Override
        public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
            rightPressedValue = 1;
            return true;
        }
        });

        stage.addActor(buttonLRed);
        stage.addActor(buttonRRed); //Add the button to the stage to perform rendering and take input.

        // blue buttons
        Texture blueButtonTexture = new Texture(Gdx.files.internal("blue.png"));
        TextureRegion blueButtonTextureRegion = new TextureRegion(blueButtonTexture);
        TextureRegionDrawable blueButtonTexRegionDrawable = new TextureRegionDrawable(blueButtonTextureRegion);

        Button buttonLBlue = new Button(blueButtonTexRegionDrawable);
        buttonLBlue.setSize(buttonWidth, buttonHeight);
        buttonLBlue.getStyle().up = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("blueleft.png"))));
        //buttonLBlue.getStyle().down = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("blueleft.png"))));
        buttonLBlue.setPosition(col1, blueHeight);

        Button buttonRBlue = new Button(blueButtonTexRegionDrawable);
        buttonRBlue.setSize(buttonWidth, buttonHeight);
        buttonRBlue.getStyle().up = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("blueright.png"))));
        //buttonRBlue.getStyle().down = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("right.png"))));
        buttonRBlue.setPosition(col2, blueHeight);

        buttonLBlue.addListener(new InputListener() {@Override
        public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
            leftPressedValue = 2;
        }@Override
        public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
            leftPressedValue = 2;
            return true;
        }
        });
        buttonRBlue.addListener(new InputListener() {@Override
        public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
            rightPressedValue = 2;
        }@Override
        public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
            rightPressedValue = 2;
            return true;
        }

        });

        stage.addActor(buttonLBlue);
        stage.addActor(buttonRBlue); //Add the button to the stage to perform rendering and take input.

        // yellow buttons
        Texture yellowButtonTexture = new Texture(Gdx.files.internal("yellow.png"));
        TextureRegion yellowButtonTextureRegion = new TextureRegion(yellowButtonTexture);
        TextureRegionDrawable yellowButtonTexRegionDrawable = new TextureRegionDrawable(yellowButtonTextureRegion);

        Button buttonLYellow = new Button(yellowButtonTexRegionDrawable);
        buttonLYellow.setSize(buttonWidth, buttonHeight);
        buttonLYellow.getStyle().up = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("yellowleft.png"))));
        //buttonLYellow.getStyle().down = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("yellowleft.png"))));
        buttonLYellow.setPosition(col1, yellowHeight);

        Button buttonRYellow = new Button(redButtonTexRegionDrawable);
        buttonRYellow.setSize(buttonWidth, buttonHeight);
        buttonRYellow.getStyle().up = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("yellowright.png"))));
        //buttonRYellow.getStyle().down = new TextureRegionDrawable(new TextureRegion(new Texture(Gdx.files.internal("yellowright.png"))));
        buttonRYellow.setPosition(col2, yellowHeight);

        buttonLYellow.addListener(new InputListener() {@Override
        public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
            leftPressedValue = 4;
        }@Override
        public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
            leftPressedValue = 4;
            return true;
        }
        });
        buttonRYellow.addListener(new InputListener() {@Override
        public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
            rightPressedValue = 4;
        }@Override
        public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
            rightPressedValue = 4;
            return true;
        }
        });

        stage.addActor(buttonLYellow);
        stage.addActor(buttonRYellow); //Add the button to the stage to perform rendering and take input.

        Gdx.input.setInputProcessor(stage);

        //Start taking input from the ui
        camera = new OrthographicCamera();
        camera.setToOrtho(false, stage.getWidth(), stage.getHeight());
        ColorDash.lastRandomNumber = randomNum;

    }

    @Override
    public void render(float delta) {

        Gdx.gl.glClearColor(0, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        game.batch.begin();
        game.batch.draw(backgroundTexture, 0, 0, 0, 0, Math.round(screenWidth), Math.round(screenHeight));
        //game.font.draw(game.batch,toString().valueOf(randomNum),400,350);
        //game.font.draw(game.batch,toString().valueOf(ColorDash.lastRandomNumber),400,400);
        game.batch.end();

        // tell the camera to update its matrices.
        camera.update();

        float deltaTime = Gdx.graphics.getDeltaTime();
        time += deltaTime;

        double timeSpeeedMultiplier = ColorDash.counter * 0.005;

        // tell the SpriteBatch to render in the
        // coordinate system specified by the camera.
        game.batch.setProjectionMatrix(camera.combined);

        game.batch.begin();
        stage.act(Gdx.graphics.getDeltaTime()); //Perform ui logic
        stage.draw(); //Draw the ui
        game.batch.end();

        measuredValue = leftPressedValue + rightPressedValue;
        if (measuredValue > 20) {
            measuredValue = 0;
        }

        if (time > (2 - 2 * timeSpeeedMultiplier)) {
            game.setScreen(new GameOverScreen(game));
            ColorDash.scoreFinal = ColorDash.counter;

        }

        if (Gdx.input.isTouched()) {
            if (leftPressedValue > 0 && rightPressedValue > 0 && measuredValue != neededValue) {
                game.setScreen(new GameOverScreen(game));
                ColorDash.scoreFinal = ColorDash.counter;
            }
            if ((leftPressedValue > 0 && rightPressedValue > 0 && measuredValue == neededValue)) {
                ColorDash.counter++;
                if (ColorDash.counter == 15) {
                    game.setScreen(new GameScreenLevel2(game));
                } else {
                    game.setScreen(new GameScreen(game));
                }
                leftPressedValue = 0;
                rightPressedValue = 0;
                measuredValue = 0;
                ColorDash.scoreFinal = +((2 - 2 * timeSpeeedMultiplier) - deltaTime);

            }
        } else {
            leftPressedValue = 0;
            rightPressedValue = 0;
            measuredValue = 0;
        }

    }

    @Override
    public void resize(int width, int height) {}

    @Override
    public void show() {
        // start the playback of the background music
        // when the screen is shown
    }

    @Override
    public void hide() {}

    @Override
    public void pause() {}

    @Override
    public void resume() {}

    @Override
    public void dispose() {
        backgroundTexture.dispose();
        Gdx.input.setInputProcessor(null);
    }
}

最佳答案

在构造函数或 create() 中初始化的每个 Disposable 对象都必须在对此屏幕的引用丢失之前被释放。您可以将所有 dispose() 调用放入屏幕的 dispose() 方法中,并从其 调用屏幕的 dispose() 方法>hide() 方法,因为您没有重用屏幕。

纹理、SpriteBatches 和阶段都是一次性的。

但是,丢弃屏幕并加载同一屏幕的另一个实例对您来说是一种浪费,因为它会重新加载所有相同的资源。制作一种重置游戏相关内容状态的方法并使用它而不是创建和设置新屏幕会更有意义。

顺便说一句,stage.act() 在其自己的内部 SpriteBatch 上调用 begin()end()。即使让它拥有自己的 SpriteBatch 也是浪费的,因此您应该将 esixitng 实例传递到 Stage 构造函数中。

关于java - Android Studio/LibGDX 游戏内存不足,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46324939/

相关文章:

java - Google Cloud Talent API - Java : Library Missing or example outdated?

java - 可从带有蜂窝的 url 中绘制

java - 如何在将数据发送到 Firebase 数据库之前对其进行加密?

java - For循环将信息发送到Java中的构造函数

java - 在 Spring Boot 应用程序中从 mongo db 获取数据,其中要获取的集合名称和字段在运行时已知

android - Google TTS 中的俄语和德语支持

C - 了解结构的值设置模式

BeautifulSoup 的 Python 高内存使用率

go - Golang中的指针地址

java - 使用 arrayList 中的字符串