Search code examples
androideclipseuser-interfacelibgdxscreens

Libgdx Screen NullPointerException when referencing another class


I have clicked every Google result I could find that might help me with no success.

I have built a game that I would like to implement a full UI with. In my game I have separate classes for my sprites, so while doing several tutorials for making screens I tried to implement something where I could use those separate classes for getting textures, current frames, etc.

I have gotten to the point where I can switch between two screens if they are not referring to anything outside themselves, but whenever I try to reference my sprite class on the game screen, it crashes, pointing me to this in the game class:

if (screen != null) screen.render(Gdx.graphics.getDeltaTime());

So here is the code I am using (minus any implemented methods or other stuff that is default for a class).

Tutorial.java:

public class Tutorial extends Game {
    MainMenuScreen mainMenuScreen ;
    AnotherScreen anotherScreen;
    Player player ;

    @Override
    public void create() {
        mainMenuScreen = new MainMenuScreen(this);
        anotherScreen = new AnotherScreen(this);
        setScreen(mainMenuScreen);
    }
}

MainMenuScreen.java (problem is here in the batch):

public class MainMenuScreen implements Screen {
    Tutorial game ;
    SpriteBatch batch ;
    Player player ;
    Texture test ;

    public MainMenuScreen(Tutorial game){
        this.game = game;
    }

    @Override
    public void render(float delta) {
        Gdx.gl.glClearColor(1, 1, 1, 1);
        Gdx.gl.glClear(GL30.GL_COLOR_BUFFER_BIT);

        batch.begin();
        batch.draw(player.playerTexture, 200, 200); // error points to here
        batch.end();
    }
}

AnotherScreen.java (runs fine):

public class AnotherScreen implements Screen {
    Tutorial game ;
    SpriteBatch batch ;
    Texture test ;

    public AnotherScreen(Tutorial game){
        this.game = game;
    }

    @Override
    public void render(float delta) {
        Gdx.gl.glClearColor(1, 1, 1, 1);
        Gdx.gl.glClear(GL30.GL_COLOR_BUFFER_BIT);

        batch.begin();
        batch.draw(test, 0, 200);
        batch.end();
    }

    @Override
    public void show() {
        batch = new SpriteBatch();
        test = new Texture(Gdx.files.internal("badlogic.jpg")); 
    }
}

Player.java:

public class Player {
    Texture playerTexture ;
    Vector2 position;
    String textureLoc;

    public Player(Vector2 position, String textureLoc){
    //What I am trying to get from AnotherScreen.java
        playerTexture = new Texture(Gdx.files.internal("badlogic.jpg")); 
    }
    public Texture getPlayerTexture() {
        return playerTexture;
    }
    public void setPlayerTexture(Texture playerTexture) {
        this.playerTexture = playerTexture;
    }
}

The exact error in the console is:

Exception in thread "LWJGL Application" java.lang.NullPointerException
    at com.tutorial.MainMenuScreen.render(MainMenuScreen.java:25)
    at com.badlogic.gdx.Game.render(Game.java:46)
    at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:206)
    at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:114)

what am I doing wrong? I have rearranged the code putting everything in different places but I just can't get it to work. Thank you for your time!

I have discovered that if I open MainMenuScreen, then go to AnotherScreen and try to get a texture from Main to show in Another, it works if I have Tutorial get the texture before passing it to Another. This does not work with Player though...


Solution

  • AnotherScreen works because you've instantiated batch before using it. However, in MainMenuScreen, you didn't instantiate both batch and the player object, ergo, the NPEs. Make sure you've instantiated the batch and player texture as follows:

    public class MainMenuScreen implements Screen {
        Tutorial game ;
        SpriteBatch batch ;
        Player player ;
        Texture test ;
    
        public MainMenuScreen(Tutorial game){
            this.game = game;
        batch = new SpriteBatch();
        player = new Player(position, textureLoc); //modify arguments
        }
    
        @Override
        public void render(float delta) {
            Gdx.gl.glClearColor(1, 1, 1, 1);
            Gdx.gl.glClear(GL30.GL_COLOR_BUFFER_BIT);
    
            batch.begin();
            batch.draw(player.playerTexture, 200, 200); // error points to here
            batch.end();
        }
    }