简体   繁体   English

Android Studio / LibGDX游戏内存不足

[英]Android Studio/LibGDX game running out of memory

I'm trying to develop a simple game to learn a basic amount of Java. 我正在尝试开发一个简单的游戏来学习基本的Java。 Everything seems to run great, but after a while I'll begin to start crashing. 一切似乎运行良好,但是一段时间后,我将开始崩溃。 I think what's happening is I'm creating too many objects and running out of memory, but I'm not sure how to prevent this. 我认为正在发生的事情是我创建了太多对象并且内存不足,但是我不确定如何防止这种情况发生。 I was wondering if anyone had any tips or could see where I'm making a mistake I would be glad to hear advice. 我想知道是否有人提出任何建议或可以看到我在哪里犯了错误,所以我很高兴听到建议。

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

Every Disposable object you initialize in the constructor or create() must be disposed before the reference to this screen is lost. 您必须先丢弃在构造函数或create()初始化的每个Disposable对象,然后再丢失对该屏幕的引用。 You can put all your dispose() calls into the screen's dispose() method, and call the screen's dispose() method from its hide() method, since you are not reusing screens. 您可以将所有dispose()调用放入屏幕的dispose()方法中,并从其hide()方法中调用屏幕的dispose() hide()方法,因为您不会重复使用屏幕。

Textures, SpriteBatches, and Stages are all Disposables. 纹理,SpriteBatches和Stage都是一次性的。

But it is wasteful for you to throw away your screen and load another instance of the same screen, since it is loading all the same assets all over again. 但是,由于您要重新加载所有相同的资产,因此放弃屏幕并加载同一屏幕的另一个实例对于您来说是浪费的。 It would make more sense to make a method that resets the state of the gameplay-related stuff and use that instead of creating and setting a new screen. 设置一种重置与游戏相关的东西的状态并使用它而不是创建和设置新屏幕的方法会更有意义。

By the way, stage.act() calls begin() and end() on its own internal SpriteBatch. 顺便说一句, stage.act() end()在其自己的内部SpriteBatch上调用begin()end() It's wasteful to even let it have its own SpriteBatch, so you should pass your esixitng instance into the Stage constructor. 甚至让它拥有自己的SpriteBatch是浪费的,因此您应该将esixitng实例传递到Stage构造函数中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM