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

2015/2/24

Null Pointer Exception

Zapp Zapp

2015/2/24

#
Hi guys, please help me find the error in my code. I get a null pointer exception error every time the bomb reaches the left edge.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*
*each time a bomb approaches the left edge of the World it disappears, a new bomb is added to the right edge of the World
*and the counter is raised by 1
*/
     
    public void removeBomb()
    {
        TurtleWorld turtleWorld = (TurtleWorld) getWorld();
        
        if ( getX() <= turtleWorld.getWidth() -turtleWorld.getWidth() +10 )
        {   
            turtleWorld.removeObject(this);
            turtleWorld.addObject( new Bomb(), turtleWorld.getWidth() -10, Greenfoot.getRandomNumber( turtleWorld.getHeight() ) );
            turtleWorld.getCounter().add(1);           
        }       
    }
Thanks!
danpost danpost

2015/2/24

#
The most probably cause of the NullPointerException is that the 'turtleWorld' reference variable is assign a 'null' value by way of the 'getWorld' call. This can happen if a method called prior to the 'act' method calling the 'removeBomb' method removes the bomb first. Post your 'act' method and any other methods in the class that uses 'removeObject(this)' if you cannot resolve the issue.
Zapp Zapp

2015/2/24

#
Thank you for your help so far. I've managed to locate the problem which lies in the gameOver() method. If I don't invoke it in my act() method everything works as expected., I just fail to understand why there would be a problem with eating Pac objects when seeing Pac objects. Because although the original bomb had been removed there already existes a new one... Here's the code of the whole Bomb class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
 
/**
 *Bombs travel from right to left in a straight line and disappear at the left edge of the World.
 *Then a new bomb spawns at the right edge. For every evaded bomb the counter's add method is invoked.
 *Upon touching Pac the bomb explodes ending the game.
 */
public class Bomb extends Actor
{
 
    public void act()
    {              
        bombMovement();
        bombSpawn();
        removeBomb();
        gameOver();
    }
 
    /*
     *right to left movement by the amount specified by the variable bombSpeed
     */
 
    public void bombMovement()
    {
        setLocation( getX()-10, getY() );       
    }
 
    /*
     *adds a new bomb at the left edge of the World at a random y coordinate with a chance of 1/1000
     */
 
    public void bombSpawn()
    {
        TurtleWorld turtleWorld = (TurtleWorld) getWorld();
 
        if ( Greenfoot.getRandomNumber (1000) == 666 )
        {
            turtleWorld.addObject(new Bomb(), turtleWorld.getWidth() -10, Greenfoot.getRandomNumber( turtleWorld.getHeight() ) );
        }
    }
 
    /*
     *each time a bomb approaches the left edge of the World it disappears, a new bomb is added to the right edge of the World
     *and the counter is raised by 1
     */
 
    public void removeBomb()
    {
        TurtleWorld turtleWorld = (TurtleWorld) getWorld();
 
        if ( getX() <= turtleWorld.getWidth() -turtleWorld.getWidth() +10 )
        {   
            turtleWorld.addObject( new Bomb(), turtleWorld.getWidth() -10, Greenfoot.getRandomNumber( turtleWorld.getHeight() ) );
            turtleWorld.removeObject(this);            
            turtleWorld.getCounter().add(1);           
        }       
    }
 
    /*
     * upon touching Pac the bomb removes it, changes it's own image to explosion_transp.png and stops the execution
     */
 
    public void gameOver()
    {
        if ( canSee(Pac.class) )
        {
            eat(Pac.class);
            setImage("explosion_transp.png");
            Greenfoot.stop();
        }
    }
 
    public boolean canSee(Class clss)
    {
        Actor actor = getOneObjectAtOffset(0, 0, clss);
        return actor != null;       
    }
 
    public void eat(Class clss)
    {
        Actor actor = getOneObjectAtOffset(0, 0, clss);
        if(actor != null) {
            getWorld().removeObject(actor);
        }
    }
}
danpost danpost

2015/2/24

#
If 'removeBomb' does remove the bomb from the world, then your code will fail when 'gameOver' calls 'canSee' which uses 'getOneObjectAtOffset'. It requires the actor be in a world. You can avoid the error by adding a condition to the 'if' on line 65 in the 'gameOver' method:
1
if (getWorld() != null && canSee(Pac.class))
This ensures the actor is still in the world before 'canSee' is executed.
Zapp Zapp

2015/2/24

#
Ah, OK, I canSee. Many thanks!!!
You need to login to post a reply.