Android Studio / LibGDX游戏内存耗尽

时间:2017-09-20 14:34:36

标签: 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);
    }
}

1 个答案:

答案 0 :(得分:1)

在构造函数或counter.js:190 failed to asynchronously prepare wasm: failed to load wasm binary file at 'counter.wasm'中初始化的每个Disposable对象必须在丢失对此屏幕的引用之前进行处理。您可以将所有create()来电置于屏幕的dispose()方法中,并从dispose()方法调用屏幕的dispose()方法,因为您没有重复使用屏幕。

Textures,SpriteBatches和Stages都是Disposables。

但是丢掉你的屏幕并加载同一个屏幕的另一个实例是浪费的,因为它会重新加载所有相同的资产。制作一种重置与游戏相关的东西的状态并使用它而不是创建和设置新屏幕的方法会更有意义。

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