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

2013/9/24

Life Scenario Help

1
2
3
JasonZhu JasonZhu

2013/9/24

#
An error occurs when one of my Ladybugs disappear. It has to do with these methods:
    public void act() 
    {
        moveAround();
        growOlder();
        becomingPregnant();
    }  

    private void becomingPregnant()
    {
        Ladybug bug = (Ladybug)getOneIntersectingObject(Ladybug.class);
        if(bug != null && !isOld() && isAdult() && Greenfoot.getRandomNumber(100)==30){
            if(bug.isFemale() && bug.isMale()){
                gestationPeriod();
            }
        }
    }
Can anyone tell me why that is? Here's 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.getOneIntersectingObject(Actor.java:912) at Ladybug.becomingPregnant(Ladybug.java:91) at Ladybug.act(Ladybug.java:37) 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)
JasonZhu JasonZhu

2013/9/24

#
To reword: I know why this is, but I want to know how to fix it. I could provide more code if needed. Thanks
Zamoht Zamoht

2013/9/24

#
Because the actor is not in the world when Ladybug bug = (Ladybug)getOneIntersectingObject(Ladybug.class); gets called. I would like to see the two other methods moveAround(); and growOlder(); since I believe one of them contains code which removes the actor from the world.
JasonZhu JasonZhu

2013/9/24

#
I believe this is what you mean:
    private void growOlder()
    {
        cycles++;
        if( cycles == MONTH ) {
            cycles = 0;
            age++;
            if( age == LIFE_SPAN ) {
                getWorld().removeObject(this);
            }            
        }
    }
Zamoht Zamoht

2013/9/24

#
Yes exactly. The problem is that when getWorld().removeObject(this); gets called the actor is removed from the world, but the act method is not done yet. Therefore becomingPregnant(); gets called after the actor is removed and the program crashes. What you can do is that you can either move growOlder(); to the bottom of the act method so it's the last method that gets called or you can make it a boolean and return false if the object is removed (true otherwise) and then you can stop the act method if growOlder(); returns false. I hope this makes sense.
JasonZhu JasonZhu

2013/9/24

#
That makes great sense! Thanks for all your help. I sort of cant believe it was a simple error like this.
Zamoht Zamoht

2013/9/24

#
I'm glad I could help. No problem. I have made that mistake a few times myself haha.
JasonZhu JasonZhu

2013/9/24

#
I have another problem now... My scenario isn't spawning new Ladybugs. My code seems fine, but its not doing what I want. Can anyone tell me where I went wrong? Thanks!
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

public class Ladybug extends Actor
{
    private static final int LIFE_SPAN = 12; // in months
    private static final int MONTH = 100;
    private static final int BIRTH_TIME = 2; // in months
    private int age; // in months
    private int gestation; // in months
    private boolean female;
    private boolean male;
    private boolean gestated;
    private int cycles = 0;
    private int gestationcycles = 0;

    // Overloading constructors
    public Ladybug()
    {
        this(0);
    }
    
    public Ladybug(int age)
    {
        setRotation( Greenfoot.getRandomNumber(360) );
        this.age = age;
        if( Greenfoot.getRandomNumber(2)==0 ) {
            female = true;
        } else {
            male = true;
        }
    }
    
    public void act() 
    {
        moveAround();
        becomingPregnant();
        growOlder();
    }  
    
    public boolean isFemale()
    {
        return female;
    }
    
    public boolean isMale()
    {
        return male;
    }
    
    public boolean isOld()
    {
        return age>10;
    }
    
    public boolean isAdult()
    {
        return age>2;
    }
    
    public boolean isPregnant()
    {
        return gestated;
    }
    
    private void growOlder()
    {
        cycles++;
        if( cycles == MONTH ) {
            cycles = 0;
            age++;
            if( age == LIFE_SPAN ) {
                getWorld().removeObject(this);
            }            
        }
    }
    
    private void gestationPeriod()
    {
        gestationcycles++;
        if( gestationcycles == MONTH ) {
            gestationcycles = 0;
            gestation++;
            if( gestation == BIRTH_TIME ) {
                getWorld().addObject(this,getX(),getY()); // replace this with new Ladybug at age 0
            }            
        }        
    }
    
    private void becomingPregnant()
    {
        Ladybug bug = (Ladybug)getOneIntersectingObject(Ladybug.class);
        if(bug != null && !isOld() && isAdult() && Greenfoot.getRandomNumber(100)==30){
            if(bug.isFemale() && bug.isMale()){
                gestationPeriod();
            }
        }
    }
    
    private void moveAround()
    {
        move(5);
        if( Greenfoot.getRandomNumber(100)<60 ) {
            if(Greenfoot.getRandomNumber(2)==0) {
                turn(10);
            } else {
                turn(-10);
            }
        }      
        if( nearEdge() ) {
            turn(20);
        }
    }
    
    private boolean nearEdge()
    {
        return getX()<5 || getY()<5 ||
            getX()>getWorld().getWidth()-5 ||
            getY()>getWorld().getHeight()-5;
    }
}
JasonZhu JasonZhu

2013/9/24

#
Where I wrote: "// replace this with new Ladybug at age 0 ", I'm not sure how to do this step either. That, and my Boolean of isPregnant I'm having trouble writing. Thanks!
Zamoht Zamoht

2013/9/24

#
Yeah I think the code you commented out is your problem. When you add an actor which is already in the world the only effect you will notice is that the object moves so it has the same visible effet as setLocation(int x, int y); in this case. What you want to do is to add a new Ladybug. So instead of "this" you should write "new LadyBug(0)". Lastly you should remove the old ladybug after the new one is added.
JasonZhu JasonZhu

2013/9/24

#
Wow, I did yet another stupid thing... Anyway I did as you said, but still no new bugs are spawning. I feel there is no need to remove the old bug as it removes itself after its LIFE_SPAN is over.
Zamoht Zamoht

2013/9/24

#
Oh another problem in your becomingPregnant() method:
            if(bug.isFemale() && bug.isMale()){  
                gestationPeriod();  
            }  
Here you want the other ladybug you find to be both male and female at the same time. You should change the if statement to if(isFemale() && bug.isMale())
JasonZhu JasonZhu

2013/9/24

#
I see what you mean there, however, with the change, still nothing spawns.. Getting frustrated haha.
Zamoht Zamoht

2013/9/24

#
I looked at your code and it's a bit messy :) The gestationPeriod() method only gets called if the female ladybug finds a male ladybug and the 1% chance you get from if (Greenfoot.getRandomNumber(100)==30). This will never make a baby. So first of all you should change that if statement to if(bug != null && !isOld() && isAdult() && Greenfoot.getRandomNumber(100)<30) to get a 30% chance. Also you may want to check if the ladybug you find is !isOld() and isAdult(). So the final if statement would look like this: if(bug != null && !bug.isOld() && bug.isAdult() && !isOld() && isAdult() && Greenfoot.getRandomNumber(100)<30) Now that this is done you got a problem with the gestationPeriod() method. Instead of this I think you should make a isPregnant boolean and change it to true when it gets pregnant:
    private void becomingPregnant()  
    {  
        Ladybug bug = (Ladybug)getOneIntersectingObject(Ladybug.class);  
        if(bug != null && !bug.isOld() && bug.isAdult() && !isOld() && isAdult() && isFemale() && bug.isMale() && Greenfoot.getRandomNumber(100)==30){  
            isPregnant = true;
        }  
    } 
Now put in the act method that if isPregnant is true the "birth counter" should count up. When the "birth counter" gets over a value you decide the child is born, "birth counter" is set to 0 and isPregnant is set to false.
JasonZhu JasonZhu

2013/9/24

#
Ill try fixing it up. I am busy right now and Ill have to do it later. I will post a result asap. Thanks a lot.
There are more replies on the next page.
1
2
3