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

2015/11/7

Null Pointer Exception Error when I Try to add Actor

Sammi Sammi

2015/11/7

#
Hey~ I'm very new to coding, and my scenario is pretty simple, just a polar bear moving around trying to eat dolphins, but when I tried to make another dolphin appear when the last one's eaten, the error kept popping out and I don't know how to fix it... My Dolphin code's this:
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
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
 
 
public class ToothedWhale extends Animal
{
     
    public void act()
    {
        doWhatever();
        WorldEdge();
        duplicateDolphin();
    }   
    World world= getWorld();
    public void doWhatever()
    { turn( Greenfoot.getRandomNumber(10)-5);
        move(5);
 
    }  
 
    public void WorldEdge()
    {if(atWorldEdge())
        { turn(30);
        }
 
    }
 
    public void duplicateDolphin()
    {if(world.getObjects(ToothedWhale.class).isEmpty())
        {   ToothedWhale toothedwhale = new ToothedWhale();
            world.addObject( toothedwhale ,1,1);
        }
 
    }
 
}
Thanks a lot!
davmac davmac

2015/11/7

#
When you get an exception (error) and a stack trace, it's important to copy the entire stack trace (all the lines in red that appear in the terminal) and paste the error here when you want help in resolving it. However, in this case I can see the problem. On line 13 you save the return from getWorld() into a variable called 'world'. However, this code is outside any method and so is an initialiser that runs when the object it is created. When the object is created, it isn't in a world (yet) so 'getWorld()' returns 'null' (meaning, no object, and in this case, no world). You then try to add an object to the world in the 'world' variable on line 30. This is why you get an exception - you're trying to add an object into (no world). The simplest fix is probably to remove the 'world' variable from your class and instead have a parameter to the duplicateDolphin() method:
1
2
3
public void duplicateDolphin(World world)
{
     // the rest is unchanged
You will have to pass in a world when you call the method. Probably you can use getWorld() at that time, so instead of writing just:
1
whale.duplicateDolphin();
you would write:
1
whale.duplicateDolphin(getWorld());
(Which does bring me to the next point: if the method creates a ToothedWhale then it probably should not be called duplicateDolphin() ...).
danpost danpost

2015/11/7

#
Line 13 of your code is outside any method and will be treated as an instance field. As such, its value, returned from 'getWorld()', will be set to 'null' because it is assigned when you create the object -- long before (in computer time) the actor is placed into a world. Sorry, I did not see that this was mentioned within the previous post by davmac.
Sammi Sammi

2015/11/7

#
Thanks for the help! But while it didn't error and it compiled successfully, when I ate all the dolphins I originally placed, nothing happened. I have no idea why. And another question(probably a stupid one, sorry...): why is it " whale.duplicateDolphin(); "?(I've changed it to duplicateToothedWhale() now) But where does the "whale" come from? (When I try to put that in, it doesn't let me compile so I just left it off) My Dolphin code now looks like:
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
import greenfoot.*; 
 
 
public class ToothedWhale extends Animal
{
 
    public void act()
    {
        doWhatever();
        WorldEdge();
        duplicateToothedWhale(getWorld());
    }   
 
    public void doWhatever()
    { turn( Greenfoot.getRandomNumber(10)-5);
        move(5);
 
    }  
 
    public void WorldEdge()
    {if(atWorldEdge())
        { turn(30);
        }
 
    }
 
    public void duplicateToothedWhale( World world)
    {if(getWorld().getObjects(ToothedWhale.class).isEmpty())
        {   ToothedWhale toothedwhale = new ToothedWhale();
            getWorld().addObject( toothedwhale ,20,20);
        }
 
    }
 
}
Thank you so much for the help!!
danpost danpost

2015/11/7

#
As the code is now, there will never be a chance that the 'duplicateToothedWhale' method will be executed without any ToothedWhale objects in the world because the actor that causes the method to execute, which is a ToothedWhale object, is in the world. If you wish to add one into the world when the one in it is removed, code it in your World subclass act method (or a method it calls).
davmac davmac

2015/11/7

#
why is it " whale.duplicateDolphin(); "?(I've changed it to duplicateToothedWhale() now) But where does the "whale" come from?
I had missed that you actually call the method from your act() method - I had assumed that you instead called it from whatever ate it. In that case, 'whale' would need to be reference to the eaten whale. As danpost says, you need to ensure that the duplicate...() method gets called when it will actually have an effect! :)
Sammi Sammi

2015/11/11

#
I finally get it now~ Thank you so much!!
You need to login to post a reply.