Reputation: 11
I'm trying to develop a simple game to learn a basic amount of 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);
}
}
Upvotes: 1
Views: 332
Reputation: 93922
Every Disposable object you initialize in the constructor or create()
must be disposed before the reference to this screen is lost. 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.
Textures, SpriteBatches, and Stages are all Disposables.
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. It's wasteful to even let it have its own SpriteBatch, so you should pass your esixitng instance into the Stage constructor.
Upvotes: 2