[libGDX] Error with Actor

Hey,

I’m trying to figure out how to use actors now and due to google not giving me any good tutorials except for this github code ( https://github.com/minimaldevelop/libgdx-scene2d-demo-game/blob/master/Libgdx-Scene2d-Game/src/com/minimaldevelop/libgdxgame/actors/FallingMan.java ) I’ve had to guess most of this.

The error I’m getting is…

Exception in thread "LWJGL Application" java.lang.NullPointerException
	at screens.Screen_Game2.render(Screen_Game2.java:83)
	at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:204)
	at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:112)

…which doesn’t tell me anythingother than that there is something wrong somewhere in the code below.

package actors;

import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.scenes.scene2d.Actor;

import core.Core_Resources;

public class Player extends Actor
{
	private Body actorBody;
	private int keyFrameTimer = 0;
	private int keyFrame = 0;
	private int direction = 0; // Down(0), Left(1), Right(2), Up(3), Down-Left(4), Down-Right(5), Up-Left(6), Up-Right(7)
	
	public Player()
	{
		setX(20);
		setY(20);
	}
	
	public void draw(SpriteBatch batch)
	{
		setPosition(actorBody.getPosition().x, actorBody.getPosition().y);
		
		keyFrameTimer++;
		
		if(keyFrameTimer >= 30)
		{
			batch.draw(Core_Resources.entities[0][direction][keyFrame], getX(), getY(), Core_Resources.entities[0][direction][keyFrame].getWidth(), Core_Resources.entities[0][direction][keyFrame].getHeight());
			keyFrameTimer = 0;
		}
	}
}

Can anyone see what I’m doing wrong in this?

Here is the main class in case that somehow has anything to do with it:

package screens;

import actors.Player;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TiledMapRenderer;
import com.badlogic.gdx.maps.tiled.TmxMapLoader;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;

public class Screen_Game2 implements ApplicationListener
{
	private TiledMap map;
	private TiledMapRenderer renderer;
	private OrthographicCamera camera;
	private BitmapFont font;
	private SpriteBatch batch;
	private Player player;
	
	@Override
	public void create() 
	{		
		float w = Gdx.graphics.getWidth();
		float h = Gdx.graphics.getHeight();

		camera = new OrthographicCamera();
		camera.setToOrtho(false, (w/h) * 10, 10);
		
		//Set the starting view location. (0,0) is in the bottom left corner.
		camera.position.x = 0;
		camera.position.y = 125;
		
		camera.update();

		font = new BitmapFont();
		batch = new SpriteBatch();

		map = new TmxMapLoader().load("assets/Maps/Map_01.tmx");
		renderer = new OrthogonalTiledMapRenderer(map, 1f / 32f);
	}

	@Override
	public void render() 
	{
		//Sets the background color and then clears the screen.
		Gdx.graphics.getGL20().glClearColor(0f, 0f, 0f, 0f);
		Gdx.graphics.getGL20().glClear( GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT );
		
		//This will exit fullscreen mode.
		if(Gdx.input.isKeyPressed(Keys.ESCAPE))
		{
			System.exit(0);
		}
		//Movement Controls
		if(Gdx.input.isKeyPressed(Keys.LEFT) || Gdx.input.isKeyPressed(Keys.A))
		{
			camera.position.x -= 0.05;
		}
		if(Gdx.input.isKeyPressed(Keys.RIGHT) || Gdx.input.isKeyPressed(Keys.D))
		{
			camera.position.x += 0.05;
		}
		if(Gdx.input.isKeyPressed(Keys.UP) || Gdx.input.isKeyPressed(Keys.W))
		{
			camera.position.y += 0.05;
		}
		if(Gdx.input.isKeyPressed(Keys.DOWN) || Gdx.input.isKeyPressed(Keys.S))
		{
			camera.position.y -= 0.05;
		}

		camera.update();
		renderer.setView(camera);
		renderer.render();
		batch.begin();
		font.draw(batch, "FPS: " + Gdx.graphics.getFramesPerSecond(), 10, 20); 
		player.draw(batch);
		batch.end();
	}

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

	@Override
	public void pause() 
	{
		//Called just before dispose() on desktop.
	}

	@Override
	public void resize(int arg0, int arg1) 
	{
		//Called once after the create() method and every time the game screen is resized.
	}

	@Override
	public void resume() 
	{
		//Not used on desktop.
	}
}

You should look into understanding stack traces, this is a simple error


Exception in thread "LWJGL Application" java.lang.NullPointerException
   at screens.Screen_Game2.render(Screen_Game2.java:83)

we can see its a null pointer exception.
the next line says exactly where it is, inside Screen_Game2 inside the render method and the error is at line 83

we can tell one of the variables is null as if the crash was caused by something in the player class you would get this instead


//What thread the exception was located in, and what type of error
Exception in thread "LWJGL Application" java.lang.NullPointerException

//this line would say it is inside the render method IF IT WAS THE CAUSE
  at pathToPlayer.Player.render(Player.java:someLineNumberHere)

//player.render is called within this class at line 83
   at screens.Screen_Game2.render(Screen_Game2.java:83)

//more sub classes that it went through to get to the Screen_Game2 loop
   at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:204)
   at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:112)

skipping to your problem:

line 83 is


player.draw(batch);

either player or batch is not initialized, I can see the player is not initialized.

read up on stack traces so you can solve simple errors like this without assistance.

EDIT: more detail explanation

also, as a side note: correct me if wrong, I really have not used LibGDX, only played around with it for a hour or 2, So I’m not sure if the spritebatcher sets the font to be rendered after images or anything, but I am doubting that.


      batch.begin();
      font.draw(batch, "FPS: " + Gdx.graphics.getFramesPerSecond(), 10, 20); 
      player.draw(batch);
      batch.end();

you probably want the FPS drawn infront of the player instead of behind the player, so re order the render.


      batch.begin();
      player.draw(batch);
      font.draw(batch, "FPS: " + Gdx.graphics.getFramesPerSecond(), 10, 20); 
      batch.end();

Phased right. You never initialize the Player instance.

Also fix your naming convention.

Yeah… I feel completely retarded for missing that. >.<

Huh? What’s wrong with it?

Underscore and number. Google for Java camel convention.