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

2016/4/5

Actor not in world error?

khoalabear khoalabear

2016/4/5

#
In my game there are fish that spawn on the left and right sides of the screen. When I I touch fish coming from the right, I get this error. 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:695) at greenfoot.Actor.getOneObjectAtOffset(Actor.java:897) at User_fish.checkRight(User_fish.java:84) at User_fish.act(User_fish.java:24) 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) my code looks like this:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
public class User_fish extends Actor
{
    private int movementspeed = 6;
    
    public User_fish()
    {
        int percentage = 80;
        GreenfootImage image = getImage();
        image.scale(image.getWidth()*percentage/100, image.getHeight()*percentage/100);
    }
    
    public void User_fish()
    {
        int percentage = 80;
        GreenfootImage image = getImage();
        image.scale(image.getWidth()*percentage/100, image.getHeight()*percentage/100);
    }

    public void act() 
    {
        checkKeys();
        checkLeft();
        checkRight();
    }    

    public void checkKeys()
    {
        if (Greenfoot.isKeyDown("left") )
        {
            moveLeft();
            User_fish();
        }
        if (Greenfoot.isKeyDown("Up"))
        {
            moveUp();
        }
        if (Greenfoot.isKeyDown("Down"))
        {
            moveDown();
        }
        if (Greenfoot.isKeyDown("Right"))
        {
            moveRight();
            User_fish();
        }
    }
    
    public void moveRight()
    {
            setImage("User_fish-right.png");
            int worldWidth = getWorld().getWidth();
            int x = (getX()+movementspeed)%worldWidth;
            setLocation(x, getY());
            
    }
    
    public void moveUp()
    {
        setLocation(getX(), getY() - movementspeed);
    }
        
    public void moveDown()
    {
        setLocation(getX(), getY() + movementspeed);
    }
        
    public void moveLeft()
    {
        setImage ("User_fish-left.png");
        int worldWidth = getWorld().getWidth();
        int x = (getX()-movementspeed+worldWidth)%worldWidth;
        setLocation(x, getY());
    }
    
    public void checkLeft()
    {
        Actor AI_left = getOneObjectAtOffset(0, 0, AI_left.class);
        if (AI_left != null)getWorld().removeObject(this);
    }
    
    public void checkRight()
    {
        Actor AI_right = getOneObjectAtOffset(0, 0, AI_right.class);
        if (AI_right != null) getWorld().removeObject(this);
    }
}
danpost danpost

2016/4/5

#
You are calling 'checkRight' after calling 'checkLeft'. Both of these methods could cause the actor to be removed from the world. If the first one called does, then the code in the second one cannot properly execute because you cannot get an offset from a place that is not in the world. Make sure the actor is in the world before calling the second one of the two methods:
// in act method
checkLeft();
if (getWorld() != null) checkRight();
or
checkLeft();
if (getWorld() == null) return;
checkRight();
which is even better (so if you add more code, it will not be executed either when removed from the world). Another way to do the entire process is to have the two methods return a true/false value depending on whether the actor should be removed from the world or not:
// in act
if (checkLeft() || checkRight())
{
    getWorld().removeObject(this);
    return;
}

// with the two methods being
private boolean checkLeft()
{
    return getOneObjectAtOffset(0, 0, AI_left.class) != null;
}
// and
private boolean checkRight()
{
    return getOneObjectAtOffset(0, 0, AI_right.class) != null;
}
You need to login to post a reply.