1

I'm building my first game in Java, from scratch. I've decided that the GameWorld class, that centralizes the main operations of the game (handling input, etc), would be best implemented as a singleton (using an enum). The relevant code for the enum is below.

public enum GameWorld {
    INSTANCE;
    private static InputController input = InputController.getInput();
    public EntityPlayer player = new EntityPlayer(10, 10, 5, 5);

    public static GameWorld getWorld() {
        return INSTANCE;
    }

    public InputController getInputController() {
        return input;
    }
}

The exception occurs in the constructor of EntityPlayer. The code and stack trace are below.

public class EntityPlayer implements Entity, InputListener {
    private int xPos;
    private int yPos;
    private int width;
    private int height;

    // Velocity of object
    // Determines where it sets itself on update
    private int xVel;
    private int yVel;
    private GameWorld world;

    private InputController input;

    private boolean solid;

    public EntityPlayer(int x, int y, int width, int height) {
        xPos = x;
        yPos = y;
        this.width = width;
        this.height = height;
        solid = true;
        xVel = 0;
        yVel = 0;
        world = getWorld();
        input = world.getInputController();
        input.registerKeyListener(this);
    }

    @Override
    public Graphics draw(Graphics g) {
        g.setColor(Color.yellow);
        g.fillRect(xPos, yPos - height, width, height);
        return g;
    }

    @Override
    public void update() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public int getXPos() {
        return xPos;
    }

    @Override
    public int getYPos() {
        return yPos;
    }

    @Override
    public Rectangle getRect() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public boolean isSolid() {
        return solid;
    }

    @Override
    public void kill() {

    }

    @Override
    public GameWorld getWorld() {
        return GameWorld.getWorld();
    }

    @Override
    public void sendKeyPress(KeyEvent ke) {
        System.out.println(ke.getKeyChar());
    }

    @Override
    public void sendMouseMove(MouseEvent me) {

    }

}

The stack trace:

Exception in thread "main" java.lang.ExceptionInInitializerError
    at com.pvminecraft.gameworld.Main.<clinit>(Main.java:14)
Caused by: java.lang.NullPointerException
at com.pvminecraft.gameworld.entities.EntityPlayer.<init>(EntityPlayer.java:45)
at com.pvminecraft.gameworld.GameWorld.<init>(GameWorld.java:15)
at com.pvminecraft.gameworld.GameWorld.<clinit>(GameWorld.java:13)
... 1 more

Line 14 of Main.java is me getting another instance of GameWorld for testing. I'm not sure why this is throwing an Exception. If I remove references to GameWorld in EntityPlayer, it goes away. If you need the code for Main.java, tell me in the comments and I will post it. Thanks!

EDIT: Line 45 in EntityPlayer is "input = world.getInputController();" I'm pretty sure that world is null, though I have no idea why.

Michael Smith
  • 1,847
  • 2
  • 19
  • 19

2 Answers2

2

You are turning yourself in circles.

You want to initialize the GameWorld.INSTANCE variable. Before you can do that, you have to initialize all the fields of the GameWorld class. After initializing all the field, the variable INSTANCE will be assigned. Before that happens, it still has the default value of null.

During the initialization, the field player is initialized. And in that initialization, you already access the INSTANCE field. So you have a circular dependency.

You really must decouple your classes, so that they become more independent of each other.

Roland Illig
  • 40,703
  • 10
  • 88
  • 121
0

I didn't see any guarantee that the expression

InputController.getInput()

returns non-null. And since your code is very debugging-friendly (at least one NullPointerException per line) it should be trivial to see which variable is null.

As I said, I suspect input.

Roland Illig
  • 40,703
  • 10
  • 88
  • 121