0

i'm creating a 2D platform game with Android Studio and LibGDX. Right now, I'm implementing an on-screen controller to move the character, but when I start the launcher, it closes automatically.

When I run the launcher, this is what the console shows:

Exception in thread "LWJGL Application" java.lang.IllegalArgumentException: batch cannot be null.
    at com.badlogic.gdx.scenes.scene2d.Stage.<init>(Stage.java:108)
    at com.globapps.supermarioclon.Tools.Controles.<init>(Controles.java:30)
    at com.globapps.supermarioclon.Screens.PantallaJuego.<init>(PantallaJuego.java:57)
    at com.globapps.supermarioclon.MarioBros.create(MarioBros.java:34)
    at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:147)
    at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:124)

This is the code from the controller class:

    public class Controles {
        Viewport viewport;
        Stage stage;
        boolean salto, izquierda, derecha;
        OrthographicCamera cam;

public Controles() {
    cam = new OrthographicCamera();
    viewport = new FitViewport(800, 480, cam);
    stage = new Stage(viewport, PantallaJuego.batch);

Gdx.input.setInputProcessor(stage);

Table table1 = new Table();
Table table2 = new Table();
table1.left().bottom();
table2.right().bottom();

Image flechaizquierda = new Image(new Texture("flechaIzquierda.png"));
flechaizquierda.setSize(50, 50);
flechaizquierda.addListener(new InputListener() {
    @Override
    public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
        izquierda = true;
        return true;
    }

    @Override
    public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
        izquierda = false;
    }
});

final Image flechaderecha = new Image(new Texture("flechaDerecha.png"));
flechaderecha.setSize(50, 50);
flechaderecha.addListener(new InputListener() {
    @Override
    public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
        derecha = true;
        return true;
    }

    @Override
    public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
        derecha = false;
    }
});

Image flechasalto = new Image(new Texture("flechaIzquierda.png"));
flechasalto.setSize(50, 50);
flechasalto.addListener(new InputListener() {
    @Override
    public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
        salto = true;
        return true;
    }

    @Override
    public void touchUp(InputEvent event, float x, float y, int pointer, int button) {

    }
});

table1.add();
table1.add(flechaizquierda).size(flechaizquierda.getWidth(), flechaizquierda.getHeight());
table1.add();
table1.row().pad(0, 5, 0, 5);
table1.add();
table1.add(flechaderecha).size(flechaderecha.getWidth(), flechaderecha.getHeight());
table2.add();
table2.add(flechasalto).size(flechasalto.getWidth(), flechasalto.getHeight());
table2.row().padRight(5);
table2.add();

stage.addActor(table1);
stage.addActor(table2);
}

public void draw() {
    stage.draw();
}


public boolean isDerecha() {
    return derecha;
}

public boolean isIzquierda() {
    return izquierda;
}

public boolean isSalto() {
    return salto;
}

public void resize(int ancho, int alto) {
    viewport.update(ancho, alto);
}
} 

And this is the PlayScreen class:

public class PantallaJuego extends ApplicationAdapter implements Screen  {
    private MarioBros game;
    public static SpriteBatch batch;
    private TextureAtlas atlas;
private OrthographicCamera gamecam, cam;
private Viewport gamePort, viewport;
private HUD hud;

private TmxMapLoader maploader;
private TiledMap map;
private OrthogonalTiledMapRenderer renderer;
private World world;
private Box2DDebugRenderer b2dr;
Controles controles;


private Mario player;

private Music musica;

public PantallaJuego(MarioBros game) {

    atlas = new TextureAtlas("MarioyEnemigos.pack");
    this.game = game;
    gamecam = new OrthographicCamera();
    gamePort = new FitViewport(MarioBros.V_WIDTH / MarioBros.PPM, MarioBros.V_HEIGHT / MarioBros.PPM, gamecam);
    hud = new HUD(game.batch);
    controles = new Controles();

    batch = new SpriteBatch();


    maploader = new TmxMapLoader();
    map = maploader.load("nivel1mario.tmx");
    renderer = new OrthogonalTiledMapRenderer(map, 1/MarioBros.PPM);

    gamecam.position.set(gamePort.getWorldWidth()/2, gamePort.getWorldHeight()/2, 0);


    world = new World(new Vector2(0,-10), true);
    b2dr = new Box2DDebugRenderer();
    player = new Mario(world, this);

    new B2WorldCreator(world, map);



    world.setContactListener(new WorldContactListener());

    musica = MarioBros.manager.get("Audio/Música/Super Mario World - Overworld Theme Music (FULL VERSION).mp3", Music.class);
    musica.setLooping(true);
    musica.play();

}

public TextureAtlas getAtlas() {
    return atlas;
}

@Override
public void show() {
}


public void handleInput(float dt) {

    if(controles.isDerecha())
        player.b2body.applyLinearImpulse(new Vector2(0.1f, 0), player.b2body.getWorldCenter(), true);

    if(controles.isSalto())
        MarioBros.manager.get("Audio/Sonidos/Super Mario Bros- Mario Jump Sound Effect.mp3", Sound.class).play();
    player.b2body.applyLinearImpulse(new Vector2(0, 4f), player.b2body.getWorldCenter(), true);

    if(controles.isIzquierda())
        player.b2body.applyLinearImpulse(new Vector2(-0.1f, 0), player.b2body.getWorldCenter(), true);



}

public void update(float dt) {
    handleInput(dt);

    world.step(1 / 60f, 6, 2);
    gamecam.position.x = player.b2body.getPosition().x;
    cam.position.set(viewport.getWorldWidth() / 2, viewport.getWorldHeight() / 2, 0);

    player.update(dt);
    hud.update(dt);


    if(Gdx.app.getType() == Application.ApplicationType.Android)
        controles.draw();

    gamecam.update();
    cam.update();
    renderer.setView(gamecam);


}

@Override
public void render(float delta) {
    update(delta);

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

    renderer.render();
    b2dr.render(world, cam.combined);
    b2dr.render(world, gamecam.combined);

    game.batch.setProjectionMatrix(gamecam.combined);
    game.batch.begin();
    player.draw(game.batch);
    game.batch.end();

    game.batch.setProjectionMatrix(hud.stage.getCamera().combined);
    hud.stage.draw();


}

If someone could help me, I'd be very grateful. Thank you.

Diego
  • 33
  • 2

2 Answers2

1

I think you should instantiate your batch in PantallaJueago class before instantiating controles field.

public PantallaJuego(MarioBros game) {

    atlas = new TextureAtlas("MarioyEnemigos.pack");
    this.game = game;
    gamecam = new OrthographicCamera();
    gamePort = new FitViewport(MarioBros.V_WIDTH / MarioBros.PPM, MarioBros.V_HEIGHT / MarioBros.PPM, gamecam);
    hud = new HUD(game.batch);
    batch = new SpriteBatch();
    controles = new Controles();

Because it is null while you instantiating your "controles". You are getting this error for your line

stage = new Stage(viewport, PantallaJuego.batch);

PantallaJuego.batch is null.

Fuat Coşkun
  • 1,045
  • 8
  • 18
  • Solved my problem, thank you. But now I get this int the console: Exception in thread "LWJGL Application" java.lang.NullPointerException at com.globapps.supermarioclon.Screens.PantallaJuego.update(PantallaJuego.java:117) at com.globapps.supermarioclon.Screens.PantallaJuego.render(PantallaJuego.java:136) at com.badlogic.gdx.Game.render(Game.java:46) at com.globapps.supermarioclon.MarioBros.render(MarioBros.java:41) at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:223) at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:124) – Diego Feb 24 '16 at 15:40
  • What is in your PantallaJuego.java line number 117 which stacktrace says? – Fuat Coşkun Feb 24 '16 at 15:41
  • I think you cam variable is null. You are using two different cams in PantallaJuego as "gamecam, cam" but cam is not instantiated. – Fuat Coşkun Feb 24 '16 at 16:01
  • That's it. Thank you so much! – Diego Feb 24 '16 at 16:31
0

Well you should learn some more of the basics before you continue. This is related to a a NullPointerException and is usually very easy to fix. It tells you that you are trying to access a method or variable in nothing since you did not initialize it. Let's take your stack and find whats wrong.

Exception in thread "LWJGL Application" java.lang.IllegalArgumentException: batch cannot be null.
//Great! So let's fix this.
    at com.badlogic.gdx.scenes.scene2d.Stage.<init>(Stage.java:108)
    //This is a LibGDX class so there is probably nothing wrong with this
    at com.globapps.supermarioclon.Tools.Controles.<init>(Controles.java:30)
    //This is your class so let's go to this specific line, you can double click it.


stage = new Stage(viewport, PantallaJuego.batch);
//So either viewport or batch is null in this line.
//You can put a breakpoint here and run a debug,
//your program will stop on this line and you can hover
//to see what is in the variables. You will see that batch
// is null. Why, you may ask.

In the constructor of your main class you first set new Controles()

controles = new Controles();

Now the constructor of Controles will run and comes to this line:

stage = new Stage(viewport, PantallaJuego.batch);

And since your code did not reach batch = new SpriteBatch(); in PantallaJuego batch is still null and since stage does not accept that it will throw a NullPointer. A quick fix is to turn around new SpriteBatch() and new Controles().

The reason I say you should start learning the basics first is because your code is very poorly formed. You should format your code in a neat way and use much smaller methods since right now certain methods and constructors do all kind of stuff and it is very hard to read. Apart from this you are picking up very bad habits like making a global from that SpriteBatch (public static). There is really no need for this and it is partly responsible for your failure here.

Have a look at What is a NullPointerException, and how do I fix it? although your error is not a NullPointerException it is very related. Stage() does a check of it's own for it to be null and throws another exception before it tries to access it and get a nullpointer then.

Community
  • 1
  • 1
Madmenyo
  • 8,389
  • 7
  • 52
  • 99
  • Ok, I'll learn much more because, now I'm just a beginner in games programming. Thank you very much. – Diego Feb 24 '16 at 19:34
  • @Diego You are a beginner in programming so first learn those fundamental basics and don't bite more then you can chew. – Madmenyo Feb 25 '16 at 07:31