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

2012/3/27

keep getting an error message

1
2
kiarocks kiarocks

2012/3/28

#
Post the line it happens on.
danpost danpost

2012/3/28

#
@michelman, where is 'theErm' set in your code? Is it possible that it has not been set and therefore a NullPointerExemption error was triggered?
michelman michelman

2012/3/29

#
thank you very much! I figured it out. The problem was (I think) that I did not have an erm yet. I fixed this and now it works. I'm now working on a way to fire a weapon and kill enemy's. I now get the following error message (sorry for posting it all in one discussion) java.lang.IllegalStateException: Actor not in world. An attempt was made to use the actor's location while it is not in the world. Either it has not yet been inserted, or it has been removed. at greenfoot.Actor.failIfNotInWorld(Actor.java:656) at greenfoot.Actor.getOneObjectAtOffset(Actor.java:860) at Bullet.kill(Bullet.java:81) at Bullet.act(Bullet.java:20) at greenfoot.core.Simulation.actActor(Simulation.java:507) at greenfoot.core.Simulation.runOneLoop(Simulation.java:470) at greenfoot.core.Simulation.runContent(Simulation.java:204) at greenfoot.core.Simulation.run(Simulation.java:194)
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Bullet here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Bullet extends Others
{
   
    /**
     * Act - do whatever the Bullet wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        scrollingMethods();
        fired();
        kill();
    }    
    
    public void fired()
    {
        move(50);
    }
    
    public int hits2=0;
    public int hits3=0;
    public int hits5=0;
    
    public boolean atWorldEdge()  
    {  
        if (getX() > getWorld().getWidth() - getImage().getWidth()  
        || getY() > getWorld().getHeight() - getImage().getHeight())  
  
        {  
            return true;  
        }  
        else  
        {  
            return false;  
        }  
    }  
   
         
    
    public void kill()
    {
        Actor Enemy2;
        Enemy2 = getOneObjectAtOffset(50, 50, Enemy2.class);
        if (Enemy2 != null)
        {
            hits2++;
            if(atWorldEdge())
            {
                getWorld().removeObject(this);
            }
            if(hits2>=2)
            {
                getWorld().removeObject(Enemy2);
            }
        }
        
        Actor Enemy3;
        Enemy3 = getOneObjectAtOffset(50, 50, Enemy3.class);
        if (Enemy3 != null)
        {
            hits3++;
            if(atWorldEdge())
            {
                getWorld().removeObject(this);
            }
            if(hits3>=5)
            {
                getWorld().removeObject(Enemy3);
            }
        }
       
        Actor Enemy5;
        Enemy5 = getOneObjectAtOffset(50, 50, Enemy5.class);
        if (Enemy5 != null)
        {
            hits5++;
            if(atWorldEdge())
            {
                getWorld().removeObject(this);
            }
            if(hits5>=15)
            {
                getWorld().removeObject(Enemy5);
            }
        }
    }
}
sp33dy sp33dy

2012/3/29

#
i've noticed this happens quite a lot with people beginning to use Greenfoot. You have to think about when you use getWorld().removeObject(this). This will remove the object immediately; however, if there is other code after that remove, then it will cause the exception above. If you note from above, I believe line 81 is where the error is occurring. If line 57 or 72 fire (are true in if's) then line 81 will always fail because it's not in the world any more! One way to fix this is set a variable flag to indicate the object(this) should be removed and then do the physical remove right at the end of the act method or in your case at the end of kill() because that's the last method called in your act method.
danpost danpost

2012/3/29

#
What is happening, is in your public void kill() method, you have several places where 'this' might be removed; and if it is removed in an earlier check, there would be no offset for the next check (because it is no longer in the world). Change your public void kill() method to the following:
public void kill()
{
    if (atWorldEdge())
    {
        getWorld().removeObject(this);
        return;
    }
    Actor Enemy2;
    Enemy2 = getOneObjectAtOffset(50, 50, Enemy2.class);
    if (Enemy2 != null)
    {
        hits2++;
        if(hits2>=2) getWorld().removeObject(Enemy2);
     }
    Actor Enemy3;
    Enemy3 = getOneObjectAtOffset(50, 50, Enemy3.class);
    if (Enemy3 != null)
    {
        hits3++;
        if(hits3>=5)  getWorld().removeObject(Enemy3);
    }
    Actor Enemy5;
    Enemy5 = getOneObjectAtOffset(50, 50, Enemy5.class);
    if (Enemy5 != null)
    {
        hits5++;
        if(hits5>=15)  getWorld().removeObject(Enemy5);
    }
}
This will at least get rid of this particular error. As a side-note: I think I would have only put the atWorldEdge() check in the Bullet class and put the Enemy hit check in the Enemy classes (which can track each enemies hits and remove both the bullet and, if neccessary, itself.
danpost danpost

2012/3/29

#
In fact, hits2, hits3, and hits5 need to be in the Enemy2, Enemy3, and Enemy5 classes, as here, they will be lost with the bullet. If Enemy2, Enemy3, and Enemy5 are all sub-classes of Enemy, then in the Enemy super-class add the variable 'hits', else add hits to each of the three classes. Also, in each of the three classes, you can add the variable 'maxHits' and set them appropriately for each class (2, 5, and 15). Then, again, if Enemy is a super-class of the three, add a method to check for bullets, and if present, action required; or, if not a super-class, add to each of the three classes.
michelman michelman

2012/3/30

#
@danpost thank you, I've got rid the error thanks to you! the only problem is that all the enemy's are killed by only one shot. this makes the game much too simple. I don't see why not :S
danpost danpost

2012/3/30

#
danpost wrote...
As a side-note: I think I would have only put the atWorldEdge() check in the Bullet class and put the Enemy hit check in the Enemy classes (which can track each enemies hits and remove both the bullet and, if neccessary, itself.
As soon as one enemy detects the bullet, the bullet needs to be removed from the world.
michelman michelman

2012/3/30

#
thanks! I did what you said and it now works. changed the getOneIntersectingObject method to the getOneObjectAtOffset method.
You need to login to post a reply.
1
2