Best way to handle entity loading!

Hi there,

EDIT* - Whenever I add “handler = new Handler();” in the MenuState class it works. Oddly enough. This is fine… I just don’t understand it. I still want a better system though!

I am looking for the best way to load map objects (entitys, gameobjects (coins, players, enemies, blocks, etc.)). Currently, I am using this type of system:

Main Class > GameStateManager > 1. STATE 1 > Render > Handler Render > GameObject
2. STATE 2 > Render > Handler Render > GameObject

Hopefully, this isn’t confusing. Lets break it down. First, I am using a “gameStateManager” class to cycle through the selected state (ex: menu, intro, playstate, etc.) and render/tick that state.

GameStateManager Class


package net.austinh.dot.gears;

import java.awt.Graphics;

import net.austinh.dot.states.AboutState;
import net.austinh.dot.states.MenuState;
import net.austinh.dot.states.PlayState;

public class GameStateManager {
	
	
	@SuppressWarnings("unused")
	private boolean paused;
	
	public GameState[] gameStates;
	public int currentState;
	public int previousState;
	
	public static final int NUM_STATES = 3;
	public static final int MENU = 0;
	public static final int PLAY = 1;
	public static final int ABOUT = 2;
	
	public GameStateManager() {
		
		paused = false;
		
		gameStates = new GameState[NUM_STATES];
		setState(MENU);
		
		
	}
	
	public void setState(int i) {
		previousState = currentState;
		unloadState(previousState);
		currentState = i;
		if(i == MENU) {
			gameStates[i] = new MenuState(this);
			gameStates[i].init();
		}
		else if(i == PLAY) {
			gameStates[i] = new PlayState(this);
			gameStates[i].init();
		}
		else if(i == ABOUT) {
			gameStates[i] = new AboutState(this);
			gameStates[i].init();
		}
	}
	
	public void unloadState(int i) {
		gameStates[i] = null;
	}
	
	public void setPaused(boolean b) {
		paused = b;
	}
	
	public void tick() {
		if(gameStates[currentState] != null) {
			gameStates[currentState].tick();
		}
	}
	
	public void render(Graphics g) {
		if(gameStates[currentState] != null) {
			gameStates[currentState].render(g);
		}
	}

	public int getCurrentState() {
		return currentState;
	}

	public void setCurrentState(int currentState) {
		this.currentState = currentState;
	}
	
}

Next, on the selected state, it renders everything needed:

PlayState Class

package net.austinh.dot.states;

import java.awt.Graphics;

import net.austinh.dot.gears.GameState;
import net.austinh.dot.gears.GameStateManager;
import net.austinh.dot.main.Game;
import net.austinh.dot.main.Handler;
import net.austinh.dot.objects.ObjectId;
import net.austinh.dot.objects.Player;

public class PlayState extends GameState{

	Game game;
	Handler handler;
	
	public PlayState(GameStateManager gsm) {
		super(gsm);
	}

	public void init() {
		
		game = new Game();
		handler = new Handler();
		
		handler.addObject(new Player(50, 50, ObjectId.Player));
		
		
	}

	public void tick() {
		handler.tick();
	}

	public void render(Graphics g) {
	
		g.fillRect(0, 0, 650, 450);
		
		handler.render(g);
		
	}

}

After that, it renders an object through the handler class:

Handler Class:

package net.austinh.dot.main;

import java.awt.Graphics;
import java.util.LinkedList;

import net.austinh.dot.objects.GameObject;

public class Handler {

	public LinkedList<GameObject> object = new LinkedList<GameObject>();
	private GameObject tempObject;
	
	public void tick(){
		
		for(int i = 0; i < object.size(); i++){
			tempObject = object.get(i);
			tempObject.tick(object);
		}
	}
	
	public void render(Graphics g){
		
		for(int i = 0; i < object.size(); i++){
			tempObject = object.get(i);
			tempObject.render(g);
		}
	}
	
	public void addObject(GameObject object){
		this.object.add(object);
	}
	
	public void removeObject(GameObject object){
		this.object.remove(object);
	}
	
}

(Here is the gameobject super class):

package net.austinh.dot.objects;

import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.LinkedList;

public abstract class GameObject {

	protected float x, y;
	protected static float velX = 0, velY = 0;
	protected ObjectId id;

	public GameObject(float x, float y, ObjectId id){
		this.x = x;
		this.y = y;
		this.id = id;
	}
	
	public abstract void tick(LinkedList<GameObject> object);
	public abstract void render(Graphics g);
	public abstract Rectangle getBounds();

	public float getX() {
		return x;
	}

	public void setX(float x) {
		this.x = x;
	}

	public float getY() {
		return y;
	}

	public void setY(float y) {
		this.y = y;
	}

	public ObjectId getId() {
		return id;
	}

	public void setId(ObjectId id) {
		this.id = id;
	}
	
	
	
}

Then, through the handler class… it displays the object through
handler.addObject(new Player(50, 50, ObjectId.Player));

Player Class

package net.austinh.dot.objects;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.LinkedList;

import net.austinh.dot.main.Handler;

public class Player extends GameObject{

	public int w = 32, h = 32;
	
	
	public Player(float x, float y, ObjectId id) {
		super(x, y, id);
	}

	public void tick(LinkedList<GameObject> object) {
		x+=velX;
		y+=velY;
	}

	public void render(Graphics g) {
		
		g.setColor(Color.white);
		g.drawRect((int)x, (int)y, w, h);
		
	}

	public Rectangle getBounds() {
		return new Rectangle((int)x, (int)y, w, h);
	}

}

The error I am having is in the playstate class.
This is the error:

What in the world is wrong with my system??

& What would be a similar, yet better, system for handling objects. (This includes locations, collisions, etc.)

Thanks!

  • A

Oh and within the Game class (main class)… in the render and tick methods… we have “gsm.tick();” and “gsm.render(g);”. We also have the GameStateManager initialized as gsm.

Read the error by yourself, please.

Null pointer exception happens when you try to access a pointer that isn’t pointing anywhere (null), or you pass a null as a parameter somewhere, and that method you passed null in, does:

if(parameter == null) throw new NullPointerException("Parameter cannot be null!");

I don’t know how much you know about errors, but I will explain as much as I can.

By reading the exception’s stack trace from top to bottom, you can see what your program was calling before the error happened. So the top most line tells you that the error happened at PlayState class line 39. You can go to that line, and what you can see is that you are doing:

handler.render(g)

This probably means that handler is equal to null. If you look at your code, you would see that when you create ‘handler’ object, you don’t initialize it. The only place you initialize it is in your init() method. Since handler is null, that means your init() method is not called anywhere.

Looking back at the stack trace, if you keep reading it down, you can see how your program got to that error.
You could write your stack likes this:
Thread.run called from unknown source -> line 53 in Game.run called -> line 78 at Game.render called -> and so on

Yes, and based on the stack trace I couldn’t find the error. Surprisingly, the problem was that the handler wasn’t initialized in another states init(); method. Which doesn’t make sense… but the stack trace mentioned nothing about it being in another state. I was initializing the handler in the PlayState, but not the MenuState.

Thanks!