Question

I have started a small project to help me learn scene2D in libGDX and keep running into a nullPointerException. My goal is to get the player to jump by using and actions sequence. My issue is that the player does jump up, but once it falls back down the game crashes. I have included the bits of my code that I belive are causing the problems. As I am still fairly new to libGDX and scene2d, I am unfamiliar with the differences between setX() setY() and the setPosition(x,y) methods that might be causing problems.

I would also like to know a little more about what exactly delta and parentAlpha are and how to use them correctly

The error I get

    Exception in thread "LWJGL Application" java.lang.NullPointerException
at com.badlogic.gdx.scenes.scene2d.actions.MoveToAction.begin(MoveToAction.java:26)
at com.badlogic.gdx.scenes.scene2d.actions.TemporalAction.act(TemporalAction.java:48)
at com.badlogic.gdx.scenes.scene2d.actions.SequenceAction.act(SequenceAction.java:65)
at com.badlogic.gdx.scenes.scene2d.Actor.act(Actor.java:85)
at com.chiefpeanut.noodle.Tony.act(Tony.java:48)
at com.badlogic.gdx.scenes.scene2d.Group.act(Group.java:48)
at com.badlogic.gdx.scenes.scene2d.Stage.act(Stage.java:225)
at com.chiefpeanut.noodle.GameScreen.render(GameScreen.java:54)
at com.badlogic.gdx.Game.render(Game.java:46)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:207)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:114)

The important part of my player class

public class Tony extends Actor{

public Rectangle bounds;
public float posX;
public float posY;
MoveToAction jumpUp;
MoveToAction jumpDown;
public Tony() {     
    posX = 10f;
    posY = 10f;
        
    bounds = new Rectangle();
    setHeight(100);
    setWidth(100);
    //scale(1, 1);
    setPosition(10, 10);
    
    
    setX(10f);
    setY(10f);
    setPosition(10, 10);
    jumpUp = new MoveToAction();
    jumpUp.setPosition(10, 80);
    jumpUp.setDuration(2f);
    
    jumpDown = new MoveToAction();
    jumpDown.setPosition(10, 10);
    jumpDown.setDuration(2f);
    
}


public void act(float delta){
    super.act(delta);<<--------SHOWS ERROR OCCURRING HERE------
    updateBounds();
    }
public void jump() {
    addAction(Actions.sequence(jumpUp, jumpDown));

}

public void draw(SpriteBatch batch, float parentAlpha){
    batch.draw(Assets.textureTony, getX(), getY(), getWidth(), getHeight());
    
}


}

As for important part of my GameScreen class, I have

public class GameScreen implements Screen, GestureListener {

MyGame game;
OrthographicCamera camera;
static SpriteBatch batch;
Stage stage;
Tony player;
Array<Block> blocks;

public GameScreen(MyGame game) {
    this.game = game;
    camera = new OrthographicCamera();
    camera.setToOrtho(false, 1920, 1080);
    camera.update();
    
    player = new Tony();
    
    batch = new SpriteBatch();
    stage = new Stage(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    
    stage.addActor(player);     
    
}

@Override
public void render(float delta) {
    Gdx.gl.glClearColor(1F, 1F, 1F, 1F);
    Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
    batch.setProjectionMatrix(camera.combined);
    
    stage.act(delta);//<<----SHOWS ANOTHER ERROR OCCURRING HERE-------
    stage.draw();
    System.out.println("rendered");
    

    if(Gdx.input.isKeyPressed(Keys.W)){
        player.jump();
    }
    if(Gdx.input.isKeyPressed(Keys.D)){
        //player.testMove();
        System.out.println(player.getX());
    }
    
    
}

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

}

@Override
public void show() {
    Gdx.input.setInputProcessor(new GestureDetector(this));

}

@Override
public void hide() {
    Gdx.input.setInputProcessor(null);

}

}

I began to assume I was using my rendering incorrectly--Which is probably right as I am going off of 5 different tutorials--but after clicking on the MoveToAction.java:26 error in the stack trace, it shows me line 26 on This document (on github) where the error is on the line that says "startX = actor.getX();" I have been very confused and trying different things for days and am desperate to find out what I am doing wrong.

Thank you very much for your help

Was it helpful?

Solution

I don't know the exact error. For this you have to use the debug wiht breakpoints. The error itself occures inside the MoveToAction.begin() method, in line 26. You have to look at this line to know which variable is null at this point. As soon as you know it it is easier to debug your code.
Looking at the code, it seens like your Actor is null. Are you seting him to null somewhere?
Anyways i would suggest to use the Actions class. It returns you a pooled action and is easy to use. In your jump() method you could use it like this:

public void jump() {
    this.addAction(Actions.sequenze(Actions.moveTo(10, 80, 2f), Actions.moveTo(10, 10, 2f)));
}

If the jump() method gets called, if you are pressing a key for example, you should hold a boolean, which says if you are allready jumping or not.

To your second question:

  1. float delta is the elapsed time, since the last call of your render() method, in seconds. The FPS (frames per second) are calculated using that alpha: FPS = 1/delta. The act(delta) method of the Actor uses this delta to update position, rotation... depending on the time. IF for example a Actor should move 10 units per second the act(delta) says setX(getX()+10*delta).
  2. The float parentAlpha describes the alpha value (opacity) of the group the Actor is in. Every stage has a root group, to which your Actor is added on stage.addActor(myActor). You can of course also add your own Group to the stage. If you want that group to be half transparent, set the alpha to 0.5f. All the Actors in that group will then get this as the parentAlpha in their draw method. You can let your ActorClass (in your case the Tony class) ignore this alpha, but you can also let him be influenced by this alpha:

    public void draw (SpriteBatch batch, float parentAlpha) { Color color = getColor(); // The Actors tint color batch.setColor(color.r, color.g, color.b, color.a*parentAlpha); // draw }

Something to read: Scene2D wiki article

OTHER TIPS

Try using Scene2d actions from a pool. "Actions" class has static methods that creates or re-uses actions from a pool. This is more readable and more memory efficient.

addAction( Actions.sequence( Actions.moveTo(x1, y1, t1), Actions.moveBy(x2, y2, t2)));

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top