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

2013/1/15

Actor not in World problem.

MrBunni MrBunni

2013/1/15

#
Hi, Recently I saw a scenario about a ball which you could pull and when you'd release it the ball bounced very far and high, when the ball would go above the screen, it would place a counter so you'd know how high the ball was. I haven't been able to find it since then, but luckily I had saved the scenario. I then used the code to display the same counter for my helicopter, if it would go above the screen. And this worked ever since. Sadly it has been getting an error lately because I've been using a rope which is placed under my helicopter, so people are able to hang on to them for them to be saved. The Rope class isn't using anything from the counter class or the other way around. This is the code the counter uses:
public class counter extends Helikoptergame
{
    helicopter heli;
    
    public counter(helicopter heli)
    {
        this.heli = heli;
    }   
    
    public void addedToWorld(World w)
    {
        setImage(new GreenfootImage(1, 1));
    }
    
   public void act() 
    {   
        int heliY = heli.getY();
         makeImage(heliY);
         int x = heli.getX();
        if(x < getImage().getWidth()/2) x = getImage().getWidth()/2;
        if(x > getWorld().getWidth() - getImage().getWidth()/2) x = getWorld().getWidth() - getImage().getWidth()/2;
        setLocation(x, getImage().getHeight()/2);
    }
    
     private void makeImage(int y)
    {
        y = -y/10;
        if(y > 0) setImage(new GreenfootImage("+" + y + "m", 30, Color.GREEN, new Color(0, 0, 0, 0)));
        else      setImage(new GreenfootImage(1, 1));
    }
}
The error never happens when I'm just flying with the helicopter, it doesn't happen when I'm placing the rope under my helicopter. It only happens when I'm removing the rope. The 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.getY(Actor.java:170)
	at counter.act(counter.java:26)
	at greenfoot.core.Simulation.actActor(Simulation.java:565)
	at greenfoot.core.Simulation.runOneLoop(Simulation.java:523)
	at greenfoot.core.Simulation.runContent(Simulation.java:213)
	at greenfoot.core.Simulation.run(Simulation.java:203)

This would mean that either the helicopter dissappears when I'm trying to delete my rope or that the counter.act:26 code which is : int heliY = heli.getY(); is actually trying to get the Y from the rope, which no longer exists. When I remove the counter.class from the game, it gives no Actor not in World errors with other classes, this would mean the helicopter doesn't dissappear from the game, because I would get alot of Actor not in World errors. This is the code for the Touw, which is Dutch for Rope, commented in English.
public class Touw extends helicopter
{
    
    private int frame = 2; // Makes the rope drop and go back accordingly
    private int dropRopeCount = 0; // Makes the rope drop slowly
    private boolean civilOnRope = false; // Returns wheter a civilion is hanging on the rope.
    Actor ropeCivilIntersect = null;
    
    public void act() 
    {
       if(exploded == false){
            setRopeLocation();
            setHelicopterRotation();
            setRopeImage();
            checkCivilIntersect();
            checkSpacePressed();
            
            System.out.println(frame);
        }
    }   
    
    public void setRopeLocation(){
    
        if(getRotationHeli == 0 && rechts == true){
            setLocation(heliX+37, heliY+75);
        }
        else if(getRotationHeli == 4 && rechts == true){
            setLocation(heliX+30, heliY+76);
        }
        else if(getRotationHeli == 8 && rechts == true){
            setLocation(heliX+28, heliY+79);
        }
        else if(getRotationHeli == 12 && rechts == true){
            setLocation(heliX+23, heliY+82);
        }
        else if(getRotationHeli == 16 && rechts == true){
            setLocation(heliX+17, heliY+82);
        }
        else if(getRotationHeli == 20 && rechts == true){
            setLocation(heliX+11, heliY+82);
        }
        else if(getRotationHeli == 24 && rechts == true){
            setLocation(heliX+5, heliY+82);
        }
        else if(getRotationHeli == 18 && rechts == true){
            setLocation(heliX+14, heliY+82);
        }
        else if(getRotationHeli == 10 && rechts == true){
            setLocation(heliX+26, heliY+79);
        }
        else if(getRotationHeli == 345 && rechts == true){
            setLocation(heliX+49, heliY+65);
        }
        else if(getRotationHeli == 350 && rechts == true){
            setLocation(heliX+45, heliY+70);
        }
        
        if(getRotationHeli == 0 && links == true){
            setLocation(heliX-37, heliY+75);
        }
        else if(getRotationHeli == 356 && links == true){
            setLocation(heliX-30, heliY+76);
        }
        else if(getRotationHeli == 352 && links == true){
            setLocation(heliX-28, heliY+79);
        }
        else if(getRotationHeli == 348 && links == true){
            setLocation(heliX-23, heliY+82);
        }
        else if(getRotationHeli == 344 && links == true){
            setLocation(heliX-17, heliY+82);
        }
        else if(getRotationHeli == 340 && links == true){
            setLocation(heliX-11, heliY+82);
        }
        else if(getRotationHeli == 336 && links == true){
            setLocation(heliX-5, heliY+82);
        }
        else if(getRotationHeli == 342 && links == true){
            setLocation(heliX-14, heliY+82);
        }
        else if(getRotationHeli == 350 && links == true){
            setLocation(heliX-26, heliY+79);
        }
        else if(getRotationHeli == 15 && links == true){
            setLocation(heliX-49, heliY+65);
        }
        else if(getRotationHeli == 10 && links == true){
            setLocation(heliX-45, heliY+70);
        }
    
    }
    
    private void setRopeImage(){
        dropRopeCount++;
        
        if(civilOnRope == true){// If civilian is on the rope, show right picture
            
            // if space is pressed, drop rope
            if(Greenfoot.isKeyDown("space") && frame < 42 && dropRopeCount == 3){
        
                setImage("touwburger("+frame+").png");
                frame ++;
                dropRopeCount = 0;
        
            }
            else if(frame==42 && Greenfoot.isKeyDown("space") && dropRopeCount == 3){ //removes bug that stops the rope from going up after it has dropped completely
                setImage("touwburger("+frame+").png");
                dropRopeCount = 0;
            }
            //
            else if(frame>0 && dropRopeCount == 3){
        
                setImage("touwburger("+frame+").png");
                frame --;
                dropRopeCount = 0;
            
                //Remove rope if it is entirely back in the heli
                if(frame == 1){
            
                    getWorld().removeObjects(getWorld().getObjects(Touw.class));  
                    ropeCount = 0;
                
                }
        
            }
        
        }
        
        else{//If there is no civilian on the rope, display normal picture
            // If space is pressed, drop rope
            if(Greenfoot.isKeyDown("space") && frame < 42 && dropRopeCount == 3){
        
                setImage("touw("+frame+").png");
                frame ++;
                dropRopeCount = 0;
        
            }
            else if(frame==42 && Greenfoot.isKeyDown("space") && dropRopeCount == 3){ //removes bug that stops the rope from going up after it has dropped completely
                setImage("touw("+frame+").png");
                dropRopeCount = 0;
            }
            //Drops rope even when space is not pressed
            else if(frame>0 && dropRopeCount == 3){
        
                setImage("touw("+frame+").png");
                frame --;
                dropRopeCount = 0;
                
                //Remove rope if it is entirely back in the heli
                if(frame == 1){
            
                    getWorld().removeObjects(getWorld().getObjects(Touw.class));  
                    ropeCount = 0;
                
                }
        
            }
        }
        
    }
    
    private void checkCivilIntersect(){
    
        if(checkSpacePressed() == true){// removes error "Actor not in World"
            Actor ropeCivilIntersect = getOneIntersectingObject(Burger.class);
        
            if(ropeCivilIntersect != null && frame ==42){ // Only lets civilians on rope when it has dropped at least 35 frames 
                civilOnRope = true;            
                
                getWorld().removeObject(ropeCivilIntersect);
            }

        }
        
    }
    
    private boolean checkSpacePressed(){ //Makes sure pressing space doesn't cause a bug in repeating setRopeImage()      
    
        if(Greenfoot.isKeyDown("space")){
            return true;
        }
        else{
            return false;
        }
        
    }
}
I don't mind uploading the scenario if you want to see the entire game. Help would be appreciated, thanks in advance!
danpost danpost

2013/1/15

#
The error message tells you that the error occurred on line 26 of the 'counter' class. I cannot be sure because you did not post the entire class code (missing the 'import' statements and probably some comments as well), but I am guessing it would be on line 17 as it is listed above. Just because you have a helicopter in the world does not mean that the field that hold the helicopter object has been set to it. Check to ensure that the helicopter that is in the world has been successfully passed to the 'counter' constructor (it cannot be an object that was created seperately from the one that was placed in the world; it must be the same one).
MrBunni MrBunni

2013/1/15

#
Hi, thank you for the quick response. You are correct, I forgot to post the import statements and comments, which are 9 lines, so the 26th line in my Counter.class would be the 17th here. As for the actual problem, I've logged the 'heli' variable in the counter class. It works fine when I'm just flying outputting the following: helicopter@20c3b85a. Which I think is the name of the class, and the place in memory it uses. When I spawn the rope, it says this: helicopter@20c3b85a Touw@5ebe901 And after I remove the Rope/Touw It is obviously no longer in the world therefor the 'Actor not in World' error. Could this be because rope is a subclass of helicopter? Is there a way I can modify the counter class so that it does not log the place of the rope and only the helicopter?
davmac davmac

2013/1/15

#
You have in the Touw class: public class Touw extends helicopter This seems wrong. A rope is not a helicopter; Touw should not extend helicopter. If it's your helicopter constructor that creates the counter, this is the problem; you are getting two counters, one for the helicopter and one for the rope.
jrlowe jrlowe

2013/1/15

#
All you have to do is on the world contructor, super (x,y,cellsize) put false at the end so the objects can leave the screen, then you dont have to keep track of any of that
MrBunni MrBunni

2013/1/15

#
davmac wrote...
You have in the Touw class: public class Touw extends helicopter This seems wrong. A rope is not a helicopter; Touw should not extend helicopter. If it's your helicopter constructor that creates the counter, this is the problem; you are getting two counters, one for the helicopter and one for the rope.
I checked and you are correct, when I go above the screen, it makes 2 counters because the helicopter creates the counter. But while Touw/rope is indeed not a helicopter, it is part of the helicopter, it shares certain variables with the helicopter so it moves exactly the same as the helicopter, when used ofcourse. Would you suggest creating the counter elsewhere or rather removing the rope as extending the helicopter and find other ways to share the variables?
jrlowe wrote...
All you have to do is on the world contructor, super (x,y,cellsize) put false at the end so the objects can leave the screen, then you dont have to keep track of any of that
The object is already leaving the screen, I simply want to add a counter to see how high because it looks nice.
danpost danpost

2013/1/15

#
Being a 'rope' is NOT a 'helicopter', it should not extend it. You can either make it a seperate actor object or have the helicopter object you already have adjust its image to include the rope with an instance variable to track the length of the rope.
MrBunni MrBunni

2013/1/15

#
Understood. I didn't realize the rules for extending were so strict. I'll make sure the rope won't extend the helicopter anymore. Thanks for all the help!
davmac davmac

2013/1/15

#
I didn't realize the rules for extending were so strict
The rules aren't really strict, but if you extend a class then you inherit things from it - constructors, methods, and variables - which you don't necessarily want. The general rule of thumb is, if A "is a" B, then class A extends B.
SomeRandomStuff SomeRandomStuff

2015/1/5

#
I am having a similar problem. I keep getting this message
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.getY(Actor.java:170)
	at BritishShip.act(BritishShip.java:19)
	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)
Here is my code
    public void act() 
    {
      setLocation(getX(), getY()+1);
      checkColision();
      if( getY()>=getWorld().getHeight()-0)
      {
          getWorld().removeObject(this);
      }
    }        
    private void checkColision()
    {
        Actor a = getOneIntersectingObject(CannonBall.class);
        if (a != null)
        {
            Scene world = (Scene) getWorld();
            world.removeObject(this);
        }
    }
       
if you can help me I will be very grateful of your help
SomeRandomStuff SomeRandomStuff

2015/1/5

#
wait i will move this to another discussion please ignore
You need to login to post a reply.