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

2014/9/21

greenfoot java.lang.IllegalStateException: Actor not in world.

dottiestar dottiestar

2014/9/21

#
I am getting this error when my game ends and I can't figure out how to fix it.
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:681) at greenfoot.Actor.getOneIntersectingObject(Actor.java:930) at Crab.heartCollisions(Crab.java:163) at Crab.act(Crab.java:41) at greenfoot.core.Simulation.actActor(Simulation.java:583) at greenfoot.core.Simulation.runOneLoop(Simulation.java:541) at greenfoot.core.Simulation.runContent(Simulation.java:215) at greenfoot.core.Simulation.run(Simulation.java:205)
This happens when my crab object in the game runs into another object or loses all of it's health. I have code in there that I thought would stop the game, so I don't know why it's still looking for an actor at this point. This is part of the code where the game ends if the crab touches a pelican object. All objects are removed and it shows my game over image, and also returns the error above.
 healthbar.loseHealth();
                touchingPelican = true;
                World world = getWorld();  
                world.removeObjects(world.getObjects(null)); 
                world.setBackground("gameover.jpg");
                Greenfoot.stop();
I'm not sure what other code you need to see to help, but here is the act method for my crab.
public void act()
    {
        checkKeypress();
        lookForWorm();
        lobsterCollisions();
        pelicanCollisions();
        heartCollisions();
        scoreKeeper();
    }
NikZ NikZ

2014/9/21

#
Is healthbar in the World?
Super_Hippo Super_Hippo

2014/9/21

#
The problem is that in the 'pelicanCollisions' method, you are (probably) remove the crab from the world (if it touches a pelican) but it still wants to end this act cycle. For 'heartCollisions', the crab needs to be in the world. If the crab is only killed by the pelican, just move the 'pelicanCollisions' method to the end of the act method.
dottiestar dottiestar

2014/9/21

#
Yes, the healthbar is in the World. I moved scoreKeeper method to the bottom because I had the same issue when winning the game and it fixed that, so if I move pelicanCollisions to the bottom then I still have a problem. I'm sure there is another way for me to do this, but I am just beginning and trying to figure this out, so I might be going about it all wrong. My goal is to move the crab using arrow keys to eat all of the worms on the screen to win. If crab collides with lobster it loses one health(has max of 3.) If crab's health is drained, game ends. If crab collides with a pelican, game ends. Crab can collide with a heart and regain 1 health. I have 2 backgrounds to display when game ends, either youwin.jpg or gameover.jpg. Here is some of my code
public void lobsterCollisions()
    {
        Actor getLobster = getOneIntersectingObject(Lobster.class);
        if (getLobster != null)
        {
            World World = getWorld();
            CrabWorld crabworld = (CrabWorld)World;
            HealthBar healthbar = crabworld.getHealthBar();
            if(touchingLobster == false)
            {
                healthbar.loseHealth();
                touchingLobster = true;
                if(healthbar.health <=0)
                {
                    World world = getWorld();  
                    world.removeObjects(world.getObjects(null)); 
                    world.setBackground("gameover.jpg");
                    Greenfoot.stop();
                   
                }
            }
        }
        else
        {
            touchingLobster = false;
        }
    }

    /**
     * If the crab collides with a heart, it gains 1 health point.  
     */
    public void heartCollisions()
    {
        Actor getHeart = getOneIntersectingObject(Heart.class);
        if (getHeart != null)
        {
            World World = getWorld();
            CrabWorld crabworld = (CrabWorld)World;
            HealthBar healthbar = crabworld.getHealthBar();
            if(healthbar.health <3)
                if(touchingHeart == false)
                {
                    {
                        getWorld().removeObject(getHeart);
                        Greenfoot.playSound("hooray.wav");
                        healthbar.gainHealth();
                    }
                    touchingHeart = true;
            }
        }
    }

    /**
     * If the crab collides with a pelican, the game is over and the pelican now has lunch!
     */
    public void pelicanCollisions()
    {
        Actor getPelican = getOneIntersectingObject(Pelican.class);
        if (getPelican != null)
        {
            World World = getWorld();
            CrabWorld crabworld = (CrabWorld)World;
            HealthBar healthbar = crabworld.getHealthBar();
            if(touchingPelican == false)
            {
                healthbar.loseHealth();
                touchingPelican = true;
                World world = getWorld();  
                world.removeObjects(world.getObjects(null)); 
                world.setBackground("gameover.jpg");
                Greenfoot.stop();
            
            }

        }
        else
        {
            touchingPelican = false;
        }

    }

    /**
     * This method keeps score of the game.  If the crab eats 10 worms, the player wins.
     */
    public void scoreKeeper()
    {
        if(countWormsEaten == 10)
        {
            World world = getWorld();  
            world.removeObjects(world.getObjects(null));
            Greenfoot.playSound("fanfare.wav");
            world.setBackground("youwin.jpg");
            Greenfoot.stop();
        }
dottiestar dottiestar

2014/9/21

#
I moved pelicanCollisions like you suggested, and I moved lobsterCollisions. Now I only get the error when the crab dies from lobsterCollisions! One more down, but I don't know if there is another way to stop it.
 public void act()
    {
        checkKeypress();
        lookForWorm();
        heartCollisions();
        lobsterCollisions();
        pelicanCollisions();
        scoreKeeper();
danpost danpost

2014/9/22

#
Your act method calls several methods that may remove all objects, including the player, from the world. However, once the player is removed from the world, you must not call any method that requires the actor be in the world (anything dealing with the location of the actor in a world, which includes coordinates, intersectors, neighbors or in-range methods). You can add a condition to making a call to a method by using this:
if (getWorld() != null)
As an alternative, you can place the following line at the beginning of any of your methods that requires the actor be in the world:
if (getWorld() == null) return;
dottiestar dottiestar

2014/9/22

#
Thank you so much! I used the if condition before the method and it worked!
You need to login to post a reply.