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

2013/11/5

Actor Not In World

cruelrabbit cruelrabbit

2013/11/5

#
Hey all, have a problem that's driving me nuts. When I try to remove a bullet when it hits the worlds edge, I get the following 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:663) at greenfoot.Actor.getX(Actor.java:157) at EnemyBullet.hitEdges(EnemyBullet.java:26) at EnemyBullet.act(EnemyBullet.java:11) My bullet code is as follows -
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

public class EnemyBullet extends Mover
{
    //int counter = 0;
    
    public void act() 
    {
        move(1.0);
        hitPlayer();
        hitEdges();
        if(getWorld() == null) return; 
    }
    private void hitPlayer()
    {
        Actor player = getOneIntersectingObject(Turret.class);
        if (player !=null)
        {
            getWorld().removeObject(player);
            getWorld().removeObject(this);
            return;
        }
    }
    private void hitEdges()
    {
        if((this.getX() < 10 || this.getX() > this.getWorld().getWidth() - 10) && (this != null))
        {
            this.getWorld().removeObject(this);
            return;
        }
        if((getY() < 10 || getY() > getWorld().getWidth() - 10)  && (this != null))
        {
            getWorld().removeObject(this);
            return;
        }
    }
}

I've read the solutions already posted but nothing seems to work. What have I missed?
davmac davmac

2013/11/5

#
In your act() method, you call hitPlayer() which potentially removes 'this' object from the world before it returns. Your act() method then calls hitEdges() which calls this.getX(), which isn't valid if the object has been removed from the world. Your line 12 seems to be an attempt to fix this, but for some reason you have put it after the call to hitEdges() instead of before, so it really has no effect.
JetLennit JetLennit

2013/11/5

#
Try changing hitEdges() to this
private void hitEdges()  
    {  
        if((this.getX() < 10 || this.getX() > this.getWorld().getWidth() - 10) && (this != null))  
        {  
            this.getWorld().removeObject(this);  
            return;  
        }  
        else if((getY() < 10 || getY() > getWorld().getWidth() - 10)  && (this != null))  
        {  
            getWorld().removeObject(this);  
            return;  
        }  
    }  
This should work (added while he was posting)
cruelrabbit cruelrabbit

2013/11/5

#
Thanks, guys. I tried moving line 12 so that it is the first line in 'act' but to no avail. And Jet, your code threw up the same error as mine. To be honest, I'm not 100% sure how to proceed from here.
danpost danpost

2013/11/5

#
You only needed switch the last two lines of the act method (not move the last to the first).
cruelrabbit cruelrabbit

2013/11/5

#
D'OH! I feel a little foolish:) Thanks guys, you da bestest!
davmac davmac

2013/11/5

#
I tried moving line 12 so that it is the first line in 'act' but to no avail.
Well of course not! Look at your code:
        hitPlayer();   // <-- this is what removes the object from the world
        hitEdges();  // <-- this is what fails because the object is no longer in the world
You need to check if the object has been removed between those two method calls. If you check before the hitPlayer method, the object is always still in the world and so the check has no effect. If you check after the hitEdges method, it's too late.
You need to login to post a reply.