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

2019/5/2

Line of Sight

LobsterL LobsterL

2019/5/2

#
Good Day fellow coders, i have occurred a bump in the road working towards the completion of my major project that requires some expert help. I have created a line of sight actor that draws a line between two actors in the world, this is done so that it can check if any obstacles are in the way.
Actor Army1;
    Actor Army2;
    int army1X;
    int army1Y;
    int army2X;
    int army2Y;
    GreenfootImage myImage;
    public LineOfSight (Actor a1, Actor a2)
    {
        Army1 = a1;
        Army2 = a2;
        setImage(new GreenfootImage(1,1));
    }
    /**
     * Act - do whatever the LineOfSight wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        if(Army1.getWorld()!=null && Army2.getWorld()!=null)
        {
            army1X = Army1.getX();
            army1Y = Army1.getY();
            army2X = Army2.getX();
            army2Y = Army2.getY();
            int myX = (army2X + army1X)/2; 
            int myY = (army2Y + army1Y)/2;
            setLocation(myX, myY);
            turnTowards(army1X, army1Y);
            int d =(int)Math.sqrt(Math.pow((army2X-army1X),2)+Math.pow((army2Y-army1Y),2));
            setImage(new GreenfootImage(d,1));
            myImage = getImage();
            myImage.setColor(Color.BLACK);
            myImage.drawLine(0,0,d,0);
        }
    }    
    public boolean clearLineOfSight()
    {
        return(getOneIntersectingObject(Barriers.class)==null);
    }
    
}
Army2 code:
public class Army2 extends West
{
    Army1 army1OnScreen;
    LineOfSight los;
    boolean found = false;
    public List<Army1> army1List;
    public Army1 targetedArmyObject;
    public void addedToWorld(World myWorld)
    {
        if(myWorld instanceof BattleGround)
        {
            BattleGround battleground = (BattleGround)myWorld;
            los = battleground.getLOS();
            army1OnScreen = battleground.getArmy1();
        }
    }
    /**
     * Act - do whatever the Army2 wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        Army1Found();
        if(los!=null)
        {
            if(los.clearLineOfSight())
            {
                if(army1OnScreen.getWorld()!=null && found ==true)
                {
                    turnTowards(army1OnScreen.getX(), army1OnScreen.getY());
                    move(3);
                }
            }
        }
        if( isTouching(Army1.class))
        {
            removeTouching(Army1.class);
        }
        
    }    
    public void Army1Found()
    {
         army1List = getWorld().getObjects(Army1.class);
         int i = 0;
         while (i < army1List.size() && !found)
         {
             if (army1List.get(i).targeted)
             {
                 i ++;
             }
             else
             {
                 found = true;
                 army1List.get(i).targeted = true;
                 targetedArmyObject = army1List.get(i);
                }
         }
        
    }
    public Army2()
    {
    }
}
As you can see here i have implemented a list system that allows my to get the multiple Army2 actors in the world in an attempt to assign a corresponding Army1 actor for the Army2 actor to turn towards if their is a clear line of sight.
public class Army1 extends East
{   private int frameCounterMove = 0;
    private int reload;
    int damage;
    public boolean targeted;
    private String[] womanleft = {"eastarmywomen3.png", "eastarmywomen4.png"};
    /**
     * Act - do whatever the Army1 wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        
        animate();
        // move(-2);
        // if (Research = 1)
        // {
            // damage = 1;
        // }
    }    
    public Army1()
    {
         
    }
    public void animate()
    {
        reload++;
        if(reload==7)
       {
        setImage(womanleft[frameCounterMove]);
        frameCounterMove++;
        if(frameCounterMove >= womanleft.length)
          frameCounterMove=0; 
        reload = 0;
      }
        
    }
    
    public void turnTowards()
    {
        
        
    }
}
What i want to happen is once the Army2 is in the world it will look for an Army1 and lock onto it then return a Boolean statement to allow for other Army2 actors to know that that specific Army1 is found and they should continue searching for another. Thanks
danpost danpost

2019/5/2

#
LobsterL wrote...
i have occurred a bump in the road
No explanation or anything resembling a bump in the entirety of the remaining post. Please provide specific issue. If any type of error message is involved, provide it as well (in its entirety).
LobsterL LobsterL

2019/5/3

#
My Issue is that i don't know how to implement the line of sight class for each individual Army2 and Army1 actor so that the Army2 turns towards a different Army1 instead of only locking onto one Army1
danpost danpost

2019/5/3

#
LobsterL wrote...
My Issue is that i don't know how to implement the line of sight class for each individual Army2 and Army1 actor so that the Army2 turns towards a different Army1 instead of only locking onto one Army1
Well, your LineOfSight class is coded to check between two object given it upon its creation; but, you seem to want to use the same LineOfSight object over and over again. You cannot have it both ways; its either one or the other. I think it better to use just one for all checks; however,I would not give it any auto-behavior -- that is, there should not be an act method in the LineOfSight class. You should give the two actors to check between at the time you check between them. Something like this:
import greenfoot.*;

public class LineOfSight extends Actor
{
    public LineOfSight()
    {
        setImage(new GreenfootImage(1, 1);
    }
    
    public boolean clearLineOfSight(Actor actor1, Actor actor2)
    {
        int dx = actor2.getX()-actor1.getX();
        int dy = actor2.getY()-actor1.getY();
        int dist = (int)Math.hypot(dx, dy);
        setLocation(actor1.getX()+dx/2, actor1.getY()+dy/2);
        turnTowards(actor2.getX(), actor2.getY());
        setImage(new GreenffootImage(dist, 2);
        // getImage().fill(); // use this to see line
        return getOneIntersectingObject(Barrriers.class) == null;
    }
}
The world should create one object from the class and add it to the world; and it should keep a reference to it along with having a "getter" method for it (you appear to have this part implemented already). For iterating through the Army1 type object, I would use a for-each loop, as follows:
for (Object obj : getWorld().getObjects(Army1.class))
{
    Army1 army1 = (Army1)obj;
    if (army1.targeted || !los.clearLineOfSight(this, army1)) continue;
    army1.targeted = true;
    targetedArmyObject = army1;
    turnTowards(army1.getX(), army1.getY());
    break;
}
In the Army2 class, you only need the two fields, targetedArmyObject and los. You can use:
if (targetedArmyObject == null)
to determine whether an Army1 object has been targeted or not (with the for-each loop in its block of code).
LobsterL LobsterL

2019/5/4

#
Thanks a lot Danpost. You truly are a Savoir.
You need to login to post a reply.