0
votes

Hello I am currently programming a LibGDX game based on physics with a ball that must stay on a platform, I have set up the physics components for the ball, but when I try updating the sprite for the ball based on the physic body's position it is giving me a null pointer exception.

I have spent 1 whole day trying to fix the problem through researching and looking at other peoples' code but cannot find my error. Thank you for your time and any input that you can give. Below I have typed the code from my Render class, Ball GameObject class, Asset class, and Exception.

Ball GameObject Class:

public class Ball {

    public static World physicsWorld;

    public static BodyDef ballBodyDef;
    public static Body ballBody;

    public static CircleShape ballShape;

    public static FixtureDef ballFixtureDef;
    public static Fixture ballFixture;

    public Ball() {

        physicsWorld = new World(new Vector2(0, -9.8f), true);

        ballBodyDef = new BodyDef();
        ballBodyDef.position.set(Assets.ballSprite.getX(),
                Assets.ballSprite.getY());
        ballBodyDef.type = BodyDef.BodyType.DynamicBody;

        ballBody = physicsWorld.createBody(ballBodyDef);

        ballShape = new CircleShape();
        ballShape.setRadius(6f);

        ballFixtureDef = new FixtureDef();
        ballFixtureDef.density = 1.0f;
        ballFixtureDef.friction = 0.2f;
        ballFixtureDef.restitution = 0.4f;

        ballFixture = ballBody.createFixture(ballFixtureDef);

    }

    public void dispose() {

        physicsWorld.dispose();
        ballShape.dispose();

    }

    public BodyDef getBallBodyDef() {
        return ballBodyDef;
    }

    public void setBallBodyDef(BodyDef ballBodyDef) {
        this.ballBodyDef = ballBodyDef;
    }

    public Body getBallBody() {
        return ballBody;
    }

    public void setBallBody(Body ballBody) {
        this.ballBody = ballBody;
    }

    public CircleShape getBallShape() {
        return ballShape;
    }

    public void setBallShape(CircleShape ballShape) {
        this.ballShape = ballShape;
    }

    public FixtureDef getBallFixtureDef() {
        return ballFixtureDef;
    }

    public void setBallFixtureDef(FixtureDef ballFixtureDef) {
        this.ballFixtureDef = ballFixtureDef;
    }

    public Fixture getBallFixture() {
        return ballFixture;
    }

    public void setBallFixture(Fixture ballFixture) {
        this.ballFixture = ballFixture;
    }

}

Render Class:

public class GameRenderer {

    private GameWorld myWorld;
    private OrthographicCamera cam;

    int width = Gdx.graphics.getWidth();
    int height = Gdx.graphics.getHeight();

    private SpriteBatch batch;

    public GameRenderer(GameWorld world, int gameHeight, int midPointY) {
        myWorld = world;
        cam = new OrthographicCamera();
        cam.setToOrtho(true, width, height);

        batch = new SpriteBatch();
        batch.setProjectionMatrix(cam.combined);

    }

    public void render(float delta) {
        Gdx.app.log("GameRenderer", "render");

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

        Ball.physicsWorld.step(Gdx.graphics.getDeltaTime(), 6, 2);
        Assets.ballSprite.setPosition(Ball.ballBody.getPosition().x,
                Ball.ballBody.getPosition().y);

        batch.begin();

        batch.draw(Assets.skySprite, 0, 0, 1920, 1080);
        batch.draw(Assets.ballSprite, Assets.ballSprite.getX(),
                Assets.ballSprite.getY());
        batch.draw(Assets.platformSprite, Assets.platformSprite.getX(),
                Assets.platformSprite.getY());

        batch.end();

    }

}

Lastly my Assets Class:

public class Assets {

    public static Texture skyTexture;
    public static Sprite skySprite;

    public static Texture ballTexture;
    public static Sprite ballSprite;

    public static Texture platformTexture;
    public static Sprite platformSprite;

    public static Button rightTiltButton;
    public static TextureAtlas rightButtonAtlas;
    public static TextButtonStyle rightButtonStyle;
    public static Skin rightButtonSkin;

    public static void Load() {

        skyTexture = new Texture(Gdx.files.internal("Assets/skybackground.png"));
        skyTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
        skySprite = new Sprite(skyTexture);
        skySprite.flip(false, true);

        ballTexture = new Texture(
                Gdx.files.internal("Assets/ballcharacter.png"));
        ballTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
        ballSprite = new Sprite(ballTexture);
        ballSprite.flip(false, true);
        ballSprite.setPosition(
                Gdx.graphics.getWidth() / 2 - ballSprite.getWidth()/2,
                Gdx.graphics.getHeight() / 2 - ballSprite.getHeight()-4);

        platformTexture = new Texture(Gdx.files.internal("Assets/platform.png"));
        platformTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
        platformSprite = new Sprite(platformTexture);
        platformSprite.flip(false, true);
        platformSprite.setPosition(
                Gdx.graphics.getWidth() / 2 - platformSprite.getWidth()/2,
                Gdx.graphics.getHeight() / 2 - platformSprite.getHeight()/2);

        rightButtonSkin = new Skin();
        rightButtonAtlas = new TextureAtlas(
                Gdx.files.internal("Assets/right_tilt_button.pack"));
        rightButtonSkin.addRegions(rightButtonAtlas);
        rightButtonStyle = new TextButtonStyle();
        rightButtonStyle.up = rightButtonSkin.getDrawable("right_tilt_button");
        rightButtonStyle.up = rightButtonSkin
                .getDrawable("right_tilt_button_pressed");
        rightButtonStyle.up = rightButtonSkin.getDrawable("right_tilt_button");
        rightButtonStyle.over = rightButtonSkin
                .getDrawable("right_tilt_button_pressed");
        rightButtonStyle.down = rightButtonSkin
                .getDrawable("right_tilt_button_pressed");

        rightTiltButton = new Button(rightButtonStyle);

    }

    public static void dispose() {

        skyTexture.dispose();
        rightButtonAtlas.dispose();
        rightButtonSkin.dispose();
        ballTexture.dispose();

    }

}

NullPointerException:

Exception in thread "LWJGL Application" java.lang.NullPointerException
at com.manumade.tiltr.tiltrhelpers.GameRenderer.render         (GameRenderer.java:36)
at com.manumade.tiltr.screens.GameScreen.render(GameScreen.java:39)
at com.badlogic.gdx.Game.render(Game.java:46)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:208)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:114)
3

3 Answers

0
votes

Looking at your code and stack trace there seems to be a problem on one of this lines:

 batch.draw(Assets.skySprite, 0, 0, 1920, 1080);
 batch.draw(Assets.ballSprite, Assets.ballSprite.getX(),
            Assets.ballSprite.getY());
 batch.draw(Assets.platformSprite, Assets.platformSprite.getX(),
            Assets.platformSprite.getY());

From the stack trace that you provided we can see that the error is happening on line 36:

at com.manumade.tiltr.tiltrhelpers.GameRenderer.render         (GameRenderer.java:36)

Look at your GameRenderer class and see what object gets called on that line. When you receive a NullPointerException it means that you are trying to call a method or acess a variable on a object that does not point to anything (The object might never be created.)

I would assume that either:

  • The SpriteBatch is NULL
  • Assets.skySprite is NULL
  • Assets.ballSprite is NULL
  • Assets.platformerSprite is NULL

So look at the way those object get instantiated. Also make sure that you are actually initializing them before performing anything on those objects. Your render() method might be called before you actually initialize the Sprite objects in your Assets class.

0
votes

It looks like a problem with drawing one of your sprites (based on the exception line number). Try replacing the sprites you have used with other ones (obviously it will look silly), and see if any of them work.

Once you know which sprites work and which ones don't, you can try and narrow down what might be different about them. I have had similar problems caused by using non-power of two textures, for example.

0
votes

I see that you call:

Assets.ballSprite.setPosition(Ball.ballBody.getPosition().x,
                              Ball.ballBody.getPosition().y);

batch.begin();

batch.draw(Assets.skySprite, 0, 0, 1920, 1080);

batch.draw(Assets.ballSprite,
           Assets.ballSprite.getX(),
           Assets.ballSprite.getY());

batch.draw(Assets.platformSprite, 
           Assets.platformSprite.getX(),
           Assets.platformSprite.getY());

batch.end();

Assets.skySprite,
Assets.ballSprite,
Assets.platformSprite

but I can not see that you call Assets.load ();

before using the above why is null, because they are not initialized only declared or I think that's the error.

try calling Assets.Load (); before that used in render method, for example inside of the your public GameRenderer(...); method.

could try to read about it AssetsManager :

https://github.com/libgdx/libgdx/wiki/Managing-your-assets and create a loading of assets before entering the playing area.(but it's just an idea).

could look at, www some tutorial about it AssetManager.

P.S: which is the line: (GameRenderer.java:36), sure that the staticas variables used for example in Ball, are initialized before being used in render.