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

2017/11/21

Actor can see another actor

NielsV5B NielsV5B

2017/11/21

#
I want to make an enemy shoot at the player if the enemy can 'see' it. I found this : https://www.greenfoot.org/topics/7436 But I want it possible to have more enemies in the world at the same time, but that isn't working... Is somebody got some ideas how to make it possible for an enemy to see the player?
danpost danpost

2017/11/21

#
NielsV5B wrote...
I want to make an enemy shoot at the player if the enemy can 'see' it.
This should work:
// with the following LineOfSight Actor subclass
import greenfoot.*;

public class LineOfSight extends Actor
{
    public LineOfSight()
    { // removes default image (new images are added when needed)
        setImage((GreenfootImage)null);
    }
    
    public boolean isClearBetween(Actor looker, Actor toSee)
    { // checks line of sight from first actor to second actor
        if (looker == null || toSee == null || looker == toSee) return false; // must have two distinct actors
        if (looker.getWorld() == null || looker.getWorld() != toSee.getWorld()) return false; // both actors must be in same world
        if (getWorld() != looker.getWorld()) looker.getWorld().addObject(this, 0, 0); // this actor must be in same world
        setLocation(looker.getX(), looker.getY()); // set at location of first actor
        int dist = (int)Math.hypot(toSee.getX()-looker.getX(), toSee.getY()-looker.getY()); // get distance between actors
        setImage(new GreenfootImage(dist, 2)); // create and set image for this actor
        turnTowards(toSee.getX(), toSee.getY()); // look toward second actor
        move(dist/2); // move in-between the actors
        return getIntersectingObjects(Actor.class).size() == 2; // only the two actors should intersect
    }
}
you can then add the following to the class of the enemy:
// class field
private static LineOfSight lineOfSight = new LineOfSight(); // all enemies use the same 'lineOfSight' actor

// in act of enemy class (or in a method called via the act method)
// (after determining if it is time for enemy to shoot)
Actor player = null;
if ( ! getWorld().getObjects(Player.class).isEmpty()) // ensure player is in world
{
    player = (Actor)getWorld().getObjects(Player.class).get(0); // get reference to player
    if (lineOfSight.isClearBetween(this, player)) // check view to player
    {
        // shooting code here
    }
}
NielsV5B NielsV5B

2017/11/27

#
Thank you very much, that's finally working! (sorry for late reaction)
You need to login to post a reply.