This site requires JavaScript, please enable it in your browser!
Greenfoot back
jogit666
jogit666 wrote ...

2015/4/19

Don't know why the code throws a NullPointerException

jogit666 jogit666

2015/4/19

#
So I am making a game of 2048. The Game class (extends World) contains a 2D boolean array to indicate which cells are clear and which aren't. Here's some of the code of the Game class:
public class Game extends World
{
    private ArrayList<Tile> tiles = new ArrayList();
    private boolean[][] cells = new boolean[4][4];
    
    private int time = 0;
    
    public Game()
    {
        super(4, 4, 122);
        
        int newX = Greenfoot.getRandomNumber(4);
        int newY = Greenfoot.getRandomNumber(4);
        int newValue = Greenfoot.getRandomNumber(10)==0? 4:2;
        
        tiles.add(new Tile(newValue, newX, newY));
        addObject(tiles.get(0), newX, newY);
        cells[newY][newX] = true;
        
        while(cells[newY][newX])
        {
            newX = Greenfoot.getRandomNumber(4);
            newY = Greenfoot.getRandomNumber(4);
        }
        newValue = Greenfoot.getRandomNumber(10)==0? 4:2;
        
        tiles.add(new Tile(newValue, newX, newY));
        addObject(tiles.get(1), newX, newY);
        cells[newY][newX] = true;
    }

    public boolean[][] getCells()
    {
        return cells;
    }
}
And here's some of the code from the Tile class
    
    private Game game;
    private int value;
    
    public Tile(int value, int x, int y)
    {
        game = (Game)getWorld();
        this.value = value;
        setLocation(x, y);
    }

    public boolean topIsClear()
    {
        if(getY() == 0)
            return false;
        return !game.getCells()[getY()-1][getX()];
    }
    public boolean rightIsClear()
    {
        if(getX() == 3)
            return false;
        return !game.getCells()[getY()][getX()+1];
    }
    public boolean downIsClear()
    {
        if(getY() == 3)
            return false;
        return !game.getCells()[getY()+1][getX()];
    }
    public boolean leftIsClear()
    {
        if(getX() == 0)
            return false;
        return !game.getCells()[getY()][getX()-1];
    }
}
When one of the IsClear methods of the Tile class is called (precisely game.getCells()), a NullPointerException is thrown. This doesn't happen however when getCells() is called directly from the Game object. So what is wrong here? Thank you!
Super_Hippo Super_Hippo

2015/4/19

#
private Game game;
'game' is initialized to null here.
game = (Game)getWorld();
It is still null because the constructor is executed when the object is created, so before it is added to the world. Calling any method on null is throwing the error then. You can either change all instances of 'game' to '((Game)getWorld())'or you add this method to the class:
protected void addedToWord(Game g)
{
    game = g;
}
Well, I am not 100% sure if that works... if it doesn't, use this:
protected void addedToWord(World w)
{
    game = (Game)getWorld();
}
jogit666 jogit666

2015/4/19

#
Oh that makes sense, thanks! Yeah I just replaced game with ((Game)getWorld()) because I'm probably not going to use it anywhere else.
Super_Hippo Super_Hippo

2015/4/19

#
I am not sure how it works, but saving it in a field is probably not a bad idea so each time one of these methods is called, only the field is accessed and it doesn't need to call 'getWorld' and cast it to a Game object every time. As an alternative, you can also make 'cells' and 'getCells' static and simply use 'Game.getCells()' or make 'cells' public static and use 'Game.cells'.
jogit666 jogit666

2015/4/19

#
Static is a good idea, I did that. Sorry another question, hope you see it:
    public Tile tileOnTop()
    {
        return getOneObjectAtOffset(0, -1, Tile.class);
    }
This outputs "incompatible types". How do I use this method?
jogit666 jogit666

2015/4/19

#
Solved it return (Tile)getOneObjectAtOffset(0, -1, Tile.class);
You need to login to post a reply.