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

2017/4/2

Help with removing Actors of the same class

1
2
Asiantree Asiantree

2017/4/2

#
public class Ant extends Actor
{
    private double xSpeed;
    private double ySpeed;
    
    private int goodCalorie;
    private int badCalorie;
    
    private double exactX;
    private double exactY;
    
    private boolean dead;
    
    public Ant (double xSpeed, double ySpeed)
    {
        goodCalorie = 200;
        badCalorie = 100;
        this.xSpeed = xSpeed;
        this.ySpeed = ySpeed;
        dead = false;
    }
    protected void addedToWorld (World myWorld)
    {
        exactX = getX();
        exactY = getY();
    }
    /**
     * Act - do whatever the Ant wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        exactX += xSpeed;
        exactY += ySpeed;
        setLocation ( (int) exactX, (int) exactY );
        
        if ((xSpeed < 0 && getX() <= getImage().getWidth() / 2) || (xSpeed > 0 && getX() >= getWorld().getWidth() - (getImage().getWidth() / 2))) 
        {
            xSpeed = -xSpeed;
        }
        if ((ySpeed < 0 && getY() <= getImage().getHeight() / 2) || (ySpeed > 0 && getY() >= getWorld().getHeight() - (getImage().getHeight() / 2))) 
        {
            ySpeed = -ySpeed;
        }
        
       int closeness = 10000;
       Actor closest = null;
       for (Object obj : getWorld().getObjects(Fries.class))
       {
           Actor actor = (Actor) obj;
           int dist = (int)Math.hypot(getX() - actor.getX(), getY() - actor.getY());
           if (closest == null || dist < closeness)
           {
               closest = actor;
               closeness = dist;
            }
        }
       if (closest != null) {
           if (intersects(closest))
           {
               getWorld().removeObject(closest);
               return;
           }
           turnTowards(closest.getX(), closest.getY());
           double rads = Math.atan2((double)(closest.getY()-getY()), (double)(closest.getX()-getX()));;
           xSpeed = Math.cos(rads);
           ySpeed = Math.sin(rads);
        }
        
       /**int closeness2 = 10000;
       Actor closest2 = null;
       for (Object obj : getWorld().getObjects(Ant.class))
       {
           Actor actor = (Actor) obj;
           int dist = (int)Math.hypot(getX() - actor.getX(), getY() - actor.getY());
           if (closest2 == null || dist < closeness)
           {
               closest2 = actor;
               closeness2 = dist;
            }
        }
       if (closest2 != null) {
           if (intersects(closest2))
           {
               getWorld().removeObject(closest2);
               return;
           }
           turnTowards(closest2.getX(), closest2.getY());
           double rads = Math.atan2((double)(closest2.getY()-getY()), (double)(closest2.getX()-getX()));;
           xSpeed = Math.cos(rads);
           ySpeed = Math.sin(rads);
        }
        **/
       if (badCalorie == 0 || goodCalorie == 0)
       {
           dead = true;
       }
       }
    }
How can I use the code that is commented out to get rid of actors of the same class? Or what can I add in that will accomplish this task?
danpost danpost

2017/4/2

#
Asiantree wrote...
< Code Omitted > How can I use the code that is commented out to get rid of actors of the same class? Or what can I add in that will accomplish this task?
I do not really know what you are trying to accomplish here -- especially after you have found and turned toward to closest one. Do you want to remove all the others except the closest?
Asiantree Asiantree

2017/4/2

#
I want to find the closest Ant and then remove that one. So if there were multiple Ants, the Ants would seek out the closest Ant and move towards that one until there are no more Ants left in the world.
danpost danpost

2017/4/3

#
Asiantree wrote...
I want to find the closest Ant and then remove that one. So if there were multiple Ants, the Ants would seek out the closest Ant and move towards that one until there are no more Ants left in the world.
Did I not see somewhere, where the food would shrink and disappear when ants were touching it? is that what you want?
Asiantree Asiantree

2017/4/3

#
Yes. Food shrinks and other Ants disappear when an Ant touches it.
danpost danpost

2017/4/3

#
Asiantree wrote...
Yes. Food shrinks and other Ants disappear when an Ant touches it.
I was actually referring to the food disappearing -- not the ants. The ants should not disappear for no apparent reason. What reason is given for the other ants to be removed from the world? I think you want some control over the 'goodCalorie' and 'badCalorie' fields and remove ants when one or the other reach zero. Currently, they are not being decremented for moving around or incremented for eating food. Lines 94 through 97 above should probably be replaced with something like this:
if (goodCalorie <= 0 || badCalorie <= 0)
{
    getWorld().removeObject(this);
}
Asiantree Asiantree

2017/4/3

#
Yes, but instead I need to change the image of the Ant dying to an image of a skull. But what I am trying to figure out is how to get Ants (multiple, like 5 or 6) to find the nearest Ant, move towards it, and then change both Ants to a skull image and stop, not so much remove them from the world. Then, if there are any Ants still alive, they continue moving until their calorie (good or bad) count runs out, in which then they also turn into a skull image and stop moving.
danpost danpost

2017/4/3

#
Use a separate Actor type for the dead ants. Just add a DeadAnt object at the location of the ant before removing the ant from the world. As far as getting them to move toward each other, I would suggest yet another class for suicidal ants. Have the world act method randomly pick an ant currently in the world to be SuicidalAnt object. Add the object at the ant's location and then remove the ant. You can add an int field to count the number of ants that are changed to commit suicide. Only create one at a time and do not create the next one until the one currently in the world has been killed. The World subclass act method would require code something like this:
if (suiciders < 6 && getObjects(SuicidalAnt.class).isEmpty())
as the condition for creating another SuicidalAnt object.
Asiantree Asiantree

2017/4/3

#
How would I get an Ant to randomly become a SuicidalAnt? I have managed to get the code for the SuicidalAnt to move towards another Ant, but how can I choose the already existing Ants to become a SuicidalAnt? And then, how can I add a DeadAnt to an Ant's last location when it has been touched by a SuicidalAnt?
danpost danpost

2017/4/3

#
Asiantree wrote...
How would I get an Ant to randomly become a SuicidalAnt? I have managed to get the code for the SuicidalAnt to move towards another Ant, but how can I choose the already existing Ants to become a SuicidalAnt?
// in Ant class
public void becomeSuicidal()
{
    getWorld().addObject(new SuicidalAnt(), getX(), getY());
    getWorld().removeObject(this);
}
and
// in world act method
if (suicidalAntCount < 6 && getObjects(SuicidalAnt.class).isEmpty())
{
    int antCount = getObjects(Ant.class).size();
    Ant ant = (Ant) getObjects(Ant.class).get(GreenfootRandomNumber(antCount));
    ant.becomeSuicidal();
}
how can I add a DeadAnt to an Ant's last location when it has been touched by a SuicidalAnt?
// in Ant act method
if (isTouching(SuicidalAnt.class))
{
    getWorld().addObject(new DeadAnt(), getX(), getY());
    removeTouching(SuicidalAnt.class);
    getWorld().removeObject(this);
}
Asiantree Asiantree

2017/4/3

#
Where can I initialize the suicidalAntCount in the world act method? The amount of Ants may vary so how can I use how many Ants were spawned in as the initial value for suicidalAntCount? For example: three Ants may spawn in from one file, but eight Ants may spawn in from another file.
danpost danpost

2017/4/3

#
Asiantree wrote...
Where can I initialize the suicidalAntCount in the world act method? The amount of Ants may vary so how can I use how many Ants were spawned in as the initial value for suicidalAntCount? For example: three Ants may spawn in from one file, but eight Ants may spawn in from another file.
You can get the current number of ants in the world with:
int antCount = getObjects(Ant.class).size();
Asiantree Asiantree

2017/4/3

#
For some reason, all of my Ants are being converted into suicidalAnts, and not one by one. Here's what I added to the World act method:
int suicidalAntCount = getObjects(Ant.class).size();
        if (suicidalAntCount < 6 && getObjects(SeekerAnt.class).isEmpty())
        {
            int antCount = getObjects(Ant.class).size();
            Ant ant = (Ant) getObjects(Ant.class).get(Greenfoot.getRandomNumber(antCount));
            ant.becomeSeeker();
        }
And this to the Ant's act method:
if (isTouching(SeekerAnt.class))
       {
           getWorld().addObject(new DeadAnt(), getX(), getY());
           removeTouching(SeekerAnt.class);
           getWorld().removeObject(this);
       }
(I changed the suicidalAnt class to seekerAnts because it seems more appropriate).
Super_Hippo Super_Hippo

2017/4/3

#
I think the 'Ant' in line 1 should be 'SeekerAnt'.
Asiantree Asiantree

2017/4/3

#
Yes, that worked. Now, how can I have the Ants seek out other Ants, while not being converted to a SeekerAnt (or find a way that all the Ants, whether an Ant or SeekerAnt, to turn towards the other Ants and chase them)? And also, the only SeekerAnt that touches an Ant will not always convert it into a DeadAnt, it usually changes into a DeadAnt after touching one or two Ants.
There are more replies on the next page.
1
2