Line of sight

Hi to all. This is my first attempt at AS Artificial Intelligence Programming that’s better than just adjusting the enemie’s _y coordinate relative to the player’s position.

Short intro, skip this paragraph to get on with the brass tacks. Now, what I want to do, is a top-down game where the player has free 360º movement and aiming capabilities. The player character(let’s call him James)'s direction, and _rotation, is always pointing towards the mouse pointer. Pressing forward and backwards means the player walks or backpedals towards the mouse and left and right is sidestepping, relative to the pointer (so if you want to sidestep in a straight line you have to move the mouse so that James keeps facing the same direction). You have to imagine a FPS without the Z coordinate and you can get the feel of it.

Now, my AI is patrolling around a “tile-generated” universe, using the main four possible directions, 0(360), 90, 180 and 270. So the little guards about to be shot by James (I’ll leave it to you to guess our Double Oh agent’s family name) would patrol around vertically and horizontally UNTIL THEY SEE THE PLAYER. Then, once they see they player, the guards would be in their “agressive mode”: they’d stop moving and concentrate on shooting in the direction of James. Agressive mode is a boolean checked at every frame. If James moves out of the line of sight, the guard resumes patrolling. This whole line of sight thing is the hard part. I’m able to calculate the hypothenuse of the two coordinates (the guard’s and Jame’s) in real time and to show/trace a boolean which dictates if James is in range of the guard. But I don’t know how to trace a line and see if there’s any obstacles between the guard and James, such as walls or crates.

Finally, my question: Suppose these obstacles are all instances of duplicated movie clips, how do I determine if an object is in the way (thus blocks line of sight) of the guard?

[font=Arial]Supplementary: I tried to have a small mc that’s like a pixel large and wide and that travels along the hypothenuse of the aforementionned points (guard’s and Jame’s coordinates) and thus that could see if it hits an obstacle along the way, turning a boolean false and thus proving the guard cannot see James. But I cannot make that because the checks have to be made every frame, and the movement of that little reticule has to be done onEnterFrame. So we have to be more creative…and I still haven’t found how![/font]

Line of sight should be pretty simple. Range of sight is a whole different story.

First of all, to make your life easier, put all your duplicated clips within a parent so that you only have to check hitTest against one clip. Then put something along the lines of the following in the onEnterFrame event of the guard:

var distance = 200; // how far you want to guard to see
for (var i = 0; i < distance; i++)
{
var radians = _rotation * Math.PI / 180;
var sightX = _x + Math.cos(radians) * i;
var sightY = _y + Math.sin(radians) * i;
if (james.hitTest(sightX, sightY, true))
{
iSeeJames();
break;
}
else if (mystuff.hitTest(sightX, sightY, true))
{
break;
}
}

I was going to suggest using a tile system, but I see that you already have :wink:

Anyway, that eases my response a bit. Since you are working in the four cardinal directions this should be simple:

Given the range of sight for the guard, have him look that number of blocks, or tiles ahead of him. You can handle this with a simple for-loop and break. Keep looking down until it comes across an object. If the object so happens to be James, go into aggressive mode, if not, be on your merry way.

Now this implementation requires a little setup:
You’re going to have to have some sort of matrix representing the actual tiles, and thus, position of every object, which gets updated whenever anything moves. With it, checking for objects in line of sight should be facilitated. The matrix can simply hold the names of each object which you can use for querying position later on.

EDIT: you mentioned that the checks are made every frame? You might want to consider using a setInterval for the checks so you can override the movie’s FPS.

That guard’s MOVEMENT is based on tiles, as is the whole level generation, but I want him to be able to see in front of him and to the side, thus a total of 180º (0 being to his left, then going by the front, then finishing at 180 to his right).

Opiate, I don’t understand what you said about putting “stuff” in a “different level”. I understand the for()… loop, it tests if the _x and _y coordinates of this line of sight intersects with James. I don’t think I’m gonna do a for loop on an enterframe event for every guard (even though thats basically what I did, which lagged like hell).

Thoriphes, I agree with doing a setInterval on the checks, thus reducing the “weight” of sight checks and, benefically, representing a “reaction time” to the guards.

Still, I need just a few specifications, perhaps it is I who does not understand/graps the concept fully enough…?

Instead of putting your objects on the stage, put them inside of another clip. That way you don’t need to keep track of all the duplicated clips, since you only have to call hitTest with the movie clip that contains them. Thats basically what I said the first time though, isn’t it? Oh well… (EDIT: To explain the code a bit, mystuff represents the name of a movie clip that contains anything that can block the guard’s view of James.)

What I think made what you did not work, is that a movieclip can only physically move once per frame. Thats probably why it appeared to lag.

I see what you’re saying with setInterval though, using that seems like a good idea.

I also thought of a more “physical” approach (don’t read “physics”, read "tangible): to have independant line of sight MovieClips follow and rotate, each one according to a guard. Independant, because else the bouding box of the guard would include his line of sight and, well, that would be bad.

So the guards would roam around and have their lines of sight follow them and rotate along as they scour the land. Difficulty setting could actually make these line of sights visible on easy mode, just like Metal Gear. However I wanted to find a more mathematical approach, hence the thread.

Calculating if James is in the tiles which are within a guard’s line of sight (what I think Thoriphes suggested) is touchy because James can move around with much more agility than the npc’s, so he can be within 1 to 4 tiles at a time. Updating an array with such information (when one of these many tiles could well be a wall) is REALLY touchy.

I’d rather have ONE formula which decides if agressive mode is on or off, and if it’s on, shoot in the direction of James(or the last “noted” direction, if we use setInterval, so that the guard doesn’t shoot exactly AT James), and if *agressive mode * is off, then the guard patrols.

Just to add something, I’ve been reading a couple of topics in here, and my game is similar to the one in this thread: http://www.kirupaforum.com/forums/showthread.php?t=60439, only it has a MAP and not just a blank white landscape, thus it’s the reason I need some line of sight!

would enjoy some reply on this touchy subject…if I’m not using tile-placement to calculate distance