Libgdx external class error

Hi! I’m trying to create an external card class but I’m getting an error.
On my thoughts the problem is in myBatch, line 64

Main class

package com.mygdx.game;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;



public class Main extends ApplicationAdapter {

	SpriteBatch myBatch;
	ShapeRenderer sr;
	int tileSize = 32;
	Card card1;
	Texture tex;




	@Override
	public void create () {


		myBatch = new SpriteBatch();
		sr = new ShapeRenderer();
		tex = new Texture(Gdx.files.internal("ball.png"));
		card1 = new Card(tex);



		}

	public void grid(){

		int height = Gdx.app.getGraphics().getHeight();
		int width = Gdx.app.getGraphics().getWidth();

		for (int i = 0; i <= width; i = i + tileSize) {

			sr.rectLine(i, height, i, 0,2, Color.BLACK, Color.BLACK);
		}

		for (int j = 0; j <= width; j = j + tileSize){

			sr.rectLine(width, j, 0, j,2, Color.BLACK, Color.BLACK);
		}

	}

	@Override
	public void render () {

		Gdx.gl.glClearColor(20/255f, 40/255f, 100/255f, 1);
		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);




		myBatch.begin();
		card1.draw(myBatch);
		sr.begin(ShapeRenderer.ShapeType.Filled);
		grid();
		sr.end();
		myBatch.end();


	}



	@Override
	public void dispose () {

		sr.dispose();

	}
}

Card class

package com.mygdx.game;


import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;

public class Card extends Sprite {

    public Card(Texture myTexture) {

        //myTexture = new Texture(Gdx.files.internal("ball.png"));

    }
}

An error:

Exception in thread “LWJGL Application” java.lang.NullPointerException
at com.badlogic.gdx.graphics.g2d.SpriteBatch.flush(SpriteBatch.java:962)
at com.badlogic.gdx.graphics.g2d.SpriteBatch.end(SpriteBatch.java:183)
at com.mygdx.game.Main.render(Main.java:68)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:225)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:126)

Process finished with exit code 0

The sprite’s texture is never set. Let’s break this apart line by line.

The error is thrown here:


myBatch.end();

But like you, my suspicion is that it is really thrown because of this line:


card1.draw(myBatch);

Which means that either card1, myBatch, or something used in the end/draw methods is null.

Well, we can see from your create method that card1 and myBatch are not null.


@Override
public void create () {
     myBatch = new SpriteBatch();
     sr = new ShapeRenderer();
     tex = new Texture(Gdx.files.internal("ball.png"));
     card1 = new Card(tex);
}

My assumption (wtihout looking at the code) is that the end method (line 68) is trying to do all of the rendering at once, and so it’s simply catching what was null from the draw method. Let’s look at the draw method.

(Taken from the Sprite class)


public void draw (Batch batch) {
     batch.draw(texture, getVertices(), 0, SPRITE_SIZE);
}

it is drawing the texture of the sprite. The constructor for Sprite takes in a texture as a parameter, however in your card class, while you do take in a texture parameter, you don’t pass it to the Sprite.


package com.mygdx.game;


import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;

public class Card extends Sprite {

    public Card(Texture myTexture) {

        //myTexture = new Texture(Gdx.files.internal("ball.png"));

    }
}

The null pointer is being thrown because the texture is null. You take it, and literally do nothing with it. What you want to do, is to pass the texture you take in as a parameter in your Card class and use it by calling something like


    super(myTexture);

If you’re not familiar with what that does, I must urge you to pause your libGDX development and learn a bit more Java code before you go any further.

I would also ask, why exactly you are making a class that extends sprite, and then has nothing in it? It’s basically just a typealias at this point (which Java doesn’t technically have). Why not just have card1 be a type of sprite, and skip the unnecessary Card class (less files usually means less confusion, and always means less space taken up).

I just wanted to create an external class just for practice. Thank you.

Fair enough. Did that solution work for you?

Yes it did, it works without an error but draws a black texture.
I’ve found the reason: if I comment out the “grid()” method between sr.begin and sr.end, the texture shows up. But I have no idea how to fix it. May be it is because of frame buffer, opengl or something else.
I’ve solved it! Just used another myBatch.begin() and myBatch.end().

Cool. Glad you were able to fix it!

I’ve found another solution:

Just created another yet card class:

package com.mygdx.game;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.Texture;


public class CardTwo {

    public void DrawCardTwo(SpriteBatch sprBatch, Texture myTexture){

        sprBatch.draw(myTexture, 300, 300);

    }

}

Main:

package com.mygdx.game;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;



public class Main extends ApplicationAdapter {

	SpriteBatch myBatch;
	ShapeRenderer sr;
	int tileSize = 32;
	Card card1;
	Texture tex, tex2;
	CardTwo card2;





	@Override
	public void create () {


		myBatch = new SpriteBatch();
		sr = new ShapeRenderer();
		tex = new Texture(Gdx.files.internal("ball.png"));
		tex2 = new Texture(Gdx.files.internal("badlogic.jpg"));
		card1 = new Card(tex);
		card2 = new CardTwo();



		}

	public void grid(){

		int height = Gdx.app.getGraphics().getHeight();
		int width = Gdx.app.getGraphics().getWidth();

		for (int i = 0; i <= width; i = i + tileSize) {

			sr.rectLine(i, height, i, 0,2, Color.BLACK, Color.BLACK);
		}

		for (int j = 0; j <= width; j = j + tileSize){

			sr.rectLine(width, j, 0, j,2, Color.BLACK, Color.BLACK);
		}

	}

	@Override
	public void render () {

		Gdx.gl.glClearColor(20/255f, 40/255f, 100/255f, 1);
		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

		myBatch.begin();
		sr.begin(ShapeRenderer.ShapeType.Filled);
		grid();
		sr.end();
		myBatch.end();


		myBatch.begin();
		card1.draw(myBatch);
		card1.setPosition(100,100);
		myBatch.end();


		myBatch.begin();
		card2.DrawCardTwo(myBatch, tex2);
		myBatch.end();

	}



	@Override
	public void dispose () {

		sr.dispose();

	}
}

I’m excited). Thanks for help.

A little off topic but it would be better to keep an array of cards rather than creating a new variable for each new one.