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

2015/4/21

Null Pointer Exception Error?

Tommy99 Tommy99

2015/4/21

#
Hello. My game is essentially a maze game, with an elephant being controlled by the player. When I run the game though, a null pointer exception error message pops up. Any help is greatly appreciated. Here is my code for the Elephant class:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.List;
import java.awt.Color;
public class Elephant extends Actor
{
    protected final int NORTH = 270;
    protected final int EAST = 0;
    protected final int SOUTH = 90;
    protected final int WEST = 180;
    protected int counter = 0;
    protected final static int OFFSET = 20;
    public int opaque = 255;

    public Elephant()
    {

        getImage().scale(20,20);

    }

    public void act() 
    {

        if(canMove()==true){
            counter++;
            if(counter==11){
                move(OFFSET);
                counter=0;
            }
        }
        moveWithArrowKeys();
        touchingPortal();
        makeWallsGlow();

        
    }    
    public void makeWallsGlow()
    {
        List <Wall> walls = getWorld().getObjects(Wall.class);
        Color color = getTouchWall().getImage().getColor();
        for(Wall wall: walls){
            if(wall.getImage().getColor().equals( wall.getImage().getColor())) {  
                wall.glow();
            }
        }

    }
    
    public Wall getTouchWall()
    {
        int xOffset=0, yOffset=0;

        switch(getRotation()){
            case EAST: xOffset=OFFSET; break;
            case SOUTH: yOffset=OFFSET; break;
            case WEST: xOffset=-OFFSET; break;
            case NORTH: yOffset=-OFFSET; break;
        }
        return (Wall) getOneObjectAtOffset(xOffset, yOffset, Wall.class);

    }
    
    

    public void moveWithArrowKeys()
    {

        if(Greenfoot.isKeyDown("up")){
            setRotation(NORTH);
        }
        if(Greenfoot.isKeyDown("down")){
            setRotation(SOUTH);
        }
        if(Greenfoot.isKeyDown("left")){
            setRotation(WEST);

        }
        if(Greenfoot.isKeyDown("right")){
            setRotation(EAST);
        }
    }

    public boolean isFacingWall()
    {
        int xOffset=0, yOffset=0;

        switch(getRotation()){
            case EAST: xOffset=OFFSET; break;
            case SOUTH: yOffset=OFFSET; break;
            case WEST: xOffset=-OFFSET; break;
            case NORTH: yOffset=-OFFSET; break;
        }
        return getOneObjectAtOffset(xOffset, yOffset, Wall.class)!=null;

    }

    public boolean isFacingEdge()
    {
        switch(getRotation()){
            case EAST: return getX()>=getWorld().getWidth()-OFFSET; 
            case SOUTH: return getY()>=getWorld().getHeight()-OFFSET;
            case WEST: return getX()<=OFFSET;
            case NORTH: return getY()<=OFFSET;
        }
        return false;
    }

    public boolean canMove()
    {
        return !(isFacingWall() || isFacingEdge());
    }

    public void touchingPortal()
    {
        Actor target = getOneIntersectingObject(Portal.class);
        if(target!=null){
            getWorld().addObject(new GameOver(), 300, 300);
            Greenfoot.stop(); 

        } 
    }

}
Here is the error message:
java.lang.NullPointerException
	at Elephant.makeWallsGlow(Elephant.java:40)
	at Elephant.act(Elephant.java:33)
	at greenfoot.core.Simulation.actActor(Simulation.java:594)
	at greenfoot.core.Simulation.runOneLoop(Simulation.java:552)
	at greenfoot.core.Simulation.runContent(Simulation.java:215)
	at greenfoot.core.Simulation.run(Simulation.java:205)
danpost danpost

2015/4/21

#
If your elephant is not touching a wall, 'getTouchWall' will return 'null'. So, you must make sure it is not 'null' before you can call 'getImage' on it. Also, there is no 'getColor' method in the GreenfootImage class. At any rate, with what you have:
// change this line
Color color = getTouchWall().getImage().getColor();
// to these
Wall wall = getTouchWall();
if (wall != null)
{
    Color color = wall.getImage().getColor();
    for (...
}
Tommy99 Tommy99

2015/4/21

#
I changed my code, but now it says that variable wall was already defined in method makeWallsGlow(). Here's the new code:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.List;
import java.awt.Color;
public class Elephant extends Actor
{
    protected final int NORTH = 270;
    protected final int EAST = 0;
    protected final int SOUTH = 90;
    protected final int WEST = 180;
    protected int counter = 0;
    protected final static int OFFSET = 20;
    public int opaque = 255;

    public Elephant()
    {

        getImage().scale(20,20);

    }

    public void act() 
    {

        if(canMove()==true){
            counter++;
            if(counter==11){
                move(OFFSET);
                counter=0;
            }
        }
        moveWithArrowKeys();
        touchingPortal();
        makeWallsGlow();

    }    

    public void makeWallsGlow()
    {
        List <Wall> walls = getWorld().getObjects(Wall.class);
        Wall wall = getTouchWall();
        if (wall != null)
        {
            Color color = wall.getImage().getColor();
            for(Wall wall: walls){
                if(wall.getImage().getColor().equals( wall.getImage().getColor())) {  
                    wall.glow();
                }
            }
        }

    }
    public Wall getTouchWall()
    {
        int xOffset=0, yOffset=0;

        switch(getRotation()){
            case EAST: xOffset=OFFSET; break;
            case SOUTH: yOffset=OFFSET; break;
            case WEST: xOffset=-OFFSET; break;
            case NORTH: yOffset=-OFFSET; break;
        }
        return (Wall) getOneObjectAtOffset(xOffset, yOffset, Wall.class);

    }

    public void moveWithArrowKeys()
    {

        if(Greenfoot.isKeyDown("up")){
            setRotation(NORTH);
        }
        if(Greenfoot.isKeyDown("down")){
            setRotation(SOUTH);
        }
        if(Greenfoot.isKeyDown("left")){
            setRotation(WEST);

        }
        if(Greenfoot.isKeyDown("right")){
            setRotation(EAST);
        }
    }

    public boolean isFacingWall()
    {
        int xOffset=0, yOffset=0;

        switch(getRotation()){
            case EAST: xOffset=OFFSET; break;
            case SOUTH: yOffset=OFFSET; break;
            case WEST: xOffset=-OFFSET; break;
            case NORTH: yOffset=-OFFSET; break;
        }
        return getOneObjectAtOffset(xOffset, yOffset, Wall.class)!=null;

    }

    public boolean isFacingEdge()
    {
        switch(getRotation()){
            case EAST: return getX()>=getWorld().getWidth()-OFFSET; 
            case SOUTH: return getY()>=getWorld().getHeight()-OFFSET;
            case WEST: return getX()<=OFFSET;
            case NORTH: return getY()<=OFFSET;
        }
        return false;
    }

    public boolean canMove()
    {
        return !(isFacingWall() || isFacingEdge());
    }

    public void touchingPortal()
    {
        Actor target = getOneIntersectingObject(Portal.class);
        if(target!=null){
            getWorld().addObject(new GameOver(), 300, 300);
            Greenfoot.stop(); 

        } 
    }

}
danpost danpost

2015/4/21

#
Change your 'makeWallsGlow' method to this:
public void makeWallsGlow()
{
    Wall touchWall = getTouchWall();
    if (touchWall != null)
    {
        Color color = touchWall.getImage().getColor();
        List <Wall> walls = getWorld().getObjects(Wall.class);
        for(Wall wall: walls){
            if (wall.getImage().getColor().equals(color) {  
                wall.glow();
            }
        }
    }
}
I did three things: * renamed one of the 'wall' variables (to 'touchWall') * moved where the list of walls was created to a more appropriate location * changed your 'equals' comparison so that you were not comparing a color to itself
Tommy99 Tommy99

2015/4/21

#
It worked perfectly! Thank you very much for your help! The 'equals' comparison change was really useful.
You need to login to post a reply.