Instead of a question, I have an answer to a common question!
I've seen a number of people on the discussion board asking about a way to determine if one actor can "see" another with no obstacles blocking them. The usual solution to this is an "invisible projectile" which is stopped by obstacles. This isn't the ideal solution, because it doesn't happen instantaneously, and the faster the projectile goes the more likely it is to "skip over" the object to be seen. Below is a new solution. This is the entire code for an actor called LineOfSight that draws a line between two characters.
It has a boolean method called "clearLineOfSight" that returns "true" if the character can be seen. In the clearLineOfSight method you will want to change the class of the object from Wall.class to whatever class obstructs the actor's vision.
To use this, simple create a new actor with no image named LineOfSight and replace its code with the code below. When you create it in your world, pass the two actors it should connect, as in:
You'll need to make the code available to the object that wants to "see" by passing it as an argument or returning it through a method in the world.
Here is the complete code of the class:
1 | LineOfSight los = new LineOfSight (actor1, actor2) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo) import java.awt.Color; /** * Write a description of class LineOfSight here. * * @author (your name) * @version (a version number or a date) */ public class LineOfSight extends Actor { Actor mouse; Actor cat; int mouseX; int mouseY; int catX; int catY; GreenfootImage myImage; /** * Act - do whatever the LineOfSight wants to do. This method is called whenever * the 'Act' or 'Run' button gets pressed in the environment. */ public LineOfSight (Actor c, Actor m) { cat = c; mouse = m; setImage( new GreenfootImage( 1 , 1 )); } public void act() { if (mouse.getWorld()!= null && cat.getWorld()!= null ) { mouseX = mouse.getX(); mouseY = mouse.getY(); catX = cat.getX(); catY = cat.getY(); int myX = (catX + mouseX)/ 2 ; int myY = (catY + mouseY)/ 2 ; setLocation(myX, myY); turnTowards(mouseX, mouseY); int d = ( int )Math.sqrt(Math.pow((catX-mouseX), 2 )+Math.pow((catY-mouseY), 2 )); setImage( new GreenfootImage(d, 1 )); /* commented out section makes line of sight visible myImage = getImage(); myImage.setColor(Color.BLACK); myImage.drawLine(0,0,d,0); */ } } public boolean clearLineOfSight() { return (getOneIntersectingObject(Wall. class )== null ); } } |