Search code examples
javaandroidnullpointerexceptionlibgdxspritebatch

"[AppName] has stopped" in my physical device. ERROR in logcat: java.lang.NullPointerException


I have been working on a game in android studio and libgdx and whenever I run it on my physical device it says "[AppName] has stopped".

I have checked for the names of the images that i used (spelling, capitalization), other than that I have no idea what the problem is.

This is the error that I received in logcat:

10-06 12:01:51.055 21591-21627/com.jpfalmazan.ninjaassault E/AndroidRuntime: FATAL EXCEPTION: GLThread 2891
                                                                             java.lang.NullPointerException
                                                                                 at com.jpfalmazan.ninjaassault.GameScreens.MenuScreen.<init>(MenuScreen.java:23)
                                                                                 at com.jpfalmazan.ninjaassault.NinjaAssault.create(NinjaAssault.java:19)
                                                                                 at com.badlogic.gdx.backends.android.AndroidGraphics.onSurfaceChanged(AndroidGraphics.java:275)
                                                                                 at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1505)
                                                                                 at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)

Here is my code for the game:

package com.jpfalmazan.ninjaassault;

import com.badlogic.gdx.Game;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.jpfalmazan.ninjaassault.GameScreens.MenuScreen;


public class NinjaAssault extends Game {
    public SpriteBatch batch;
    Texture img;

    @Override
    public void create () {
        batch = new SpriteBatch();
        this.setScreen(new MenuScreen(this));   ////This is the "NinjaAssault.java:19 " error shown in logcat 
    }

    @Override
    public void render () {
        super.render();
        Gdx.gl.glClearColor(1,0,0,1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        batch.begin();
    }

    @Override
    public void dispose () {
        batch.dispose();
        img.dispose();
    }
}

And here is my code in the MenuScreen class:

package com.jpfalmazan.ninjaassault.GameScreens;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.jpfalmazan.ninjaassault.NinjaAssault;

public class MenuScreen implements Screen{
    NinjaAssault game;
    public MenuScreen (NinjaAssault game){
        this.game = game;
    }
    public SpriteBatch batch;
    public Texture background;
    public Texture title;
    public Texture playButtonINACTIVE;
    public Texture playButtonACTIVE;

    public float screenWidth = Gdx.graphics.getWidth();
    public float screenHeight = Gdx.graphics.getHeight();
    public float titleWidth = title.getWidth();  //This is the "MenuScreen.java:23" error shown in logcat 
    public float titleHeight = title.getHeight();
    public float xLimit1 = (float) ((screenWidth/2)-(titleWidth/2));
    public float xLimit2 = (float) ((screenWidth/2)+(titleWidth/2));
    public float yLimit1 = (float) ((screenHeight*.35));
    public float yLimit2 = (float) ((screenHeight*.35)+titleHeight);



    @Override
    public void show() {
        batch = new SpriteBatch();
        background = new Texture("BGYELL.png");
        title = new Texture ("BGASTRO.png");
        playButtonINACTIVE = new Texture("BTPLAY.png");
        playButtonACTIVE = new Texture("BTPLAYON.png");

    }

    @Override
    public void render(float delta) {
        Gdx.gl.glClearColor(1,0,0,1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        game.batch.begin();
        game.batch.draw(background,0,0,screenWidth,screenHeight);
        if((Gdx.input.getX()> xLimit1 && Gdx.input.getX() < xLimit2) && (Gdx.input.getY() < yLimit2 && Gdx.input.getY() > yLimit1 ) ){
            game.batch.draw(playButtonACTIVE,(screenWidth/2)-(playButtonACTIVE.getWidth()/2), (float) (screenHeight*.35));
        }else  game.batch.draw(playButtonINACTIVE,(screenWidth/2)-(playButtonINACTIVE.getWidth()/2), (float) (screenHeight*.35));
        game.batch.draw(title,(screenWidth/2)-((float)(screenWidth*.8)/2), (float) (screenHeight*.65),(float)(screenWidth*.8) , (float) ((screenWidth*.8)*(titleHeight/titleWidth)));




        game.batch.end();
    }

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

    }

    @Override
    public void pause() {

    }

    @Override
    public void resume() {

    }

    @Override
    public void hide() {

    }

    @Override
    public void dispose() {

    }
}

Solution

  • You have not set "title" to anything yet. You have only declared it to exist. title is set in show() which is called after the constructor. You need to do

    title = new Texture ("BGASTRO.png");
    

    BEFORE you try to get the height of the texture. This goes for all other variables too, make sure they are set to something before using them.

    Also, you should remove

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

    from you render() in NinjaAssault class. It is unnecessary and if you call

    batch.begin()
    

    you need to call

    batch.end()
    

    too, but in this case its never used anyway so no need for it at all.