Adventure Game Studio

AGS Support => Advanced Technical Forum => Topic started by: JD on Wed 25/08/2010 19:39:23

Title: Giving a character a field of view (that can be obstructed)
Post by: JD on Wed 25/08/2010 19:39:23
Greetings!

I am wondering if anyone can help me with this. This thing I'm working on has a top-down view, and enemies you can try to avoid. I thought I'd use a transparent character to give an enemy (red dot in the image below) a field-of-view (the yellow cone), and when it collides with the player (the green dot) the enemy will go after you. No problem in a rectangular room. But when walls come into play it gives some trouble as you can see in the image below.
(http://members.quicknet.nl/jjj.dekker/example.png)

Does anyone know a better way to approach this? I thought of using regions to check both the player and the enemy's position but I am not sure if that is a better/working solution (especially on more complex rooms).

Thanks in advance!

-Def
Title: Re: Giving a character a field of view (that can be obstructed)
Post by: Calin Leafshade on Wed 25/08/2010 19:48:31
try a kind of ray-tracing approach.

Draw an imaginary line between the player and the enemy.

If the line is not obstructed (use a mask and getpixel for this) THEN check if the player is in the characters field of view.
Title: Re: Giving a character a field of view (that can be obstructed)
Post by: GarageGothic on Wed 25/08/2010 20:05:42
I'd actually suggest *first* checking whether the character is in the field of view, but instead of collision detection using algebra (he's between the two lines? Ok, then is the distance to the enemy near enough to be seen?) - and *then* checking for walls with GetPixel as Calin suggests. Possibly you could use AGS' pathfinder to check for walls - if you have an invisible dummy character WalkStraight from the enemy position to the player, with a speed setting that makes the movement instant (speed -1? Not sure, but I did make use of it before). Then check the dummy's actual coordinates after walking. Is he at the player x,y? Then there's no wall.

Edit: I suck at algebra, always have to look up the equations - when I mention "two lines" above I was imagining the FOV as a triangle, but probably it would make more sense to treat it as a wedge of a circle. You already know the NPC's facing angle, so you'd just calculate the angle of the line between the player and the NPC and see if it was between NPC facing angle +/- half of whatever the FOV angle is. 
Title: Re: Giving a character a field of view (that can be obstructed)
Post by: JD on Wed 25/08/2010 20:12:41
Thank you for the quick response Calin. I understand your solution and it sounds like it's just what I need. I looked up GetPixel and I think I sort of know how to use a mask here. It's been a while since I used the DrawingSurface functions (back when you used RawDraw) so I could very well be wrong here. Do I:

1. Add another background frame to each room showing a mask of the walls
2. Use DrawingSurface *surface = Room.GetDrawingSurfaceForBackground(1); to be able to detect walls with GetPixel
3. Draw the imaginary line and use GetPixel to detect walls

Step 3 has me a bit puzzled though. Well if step 1 and 2 are incorrect then I am completely puzzled :D I hope you (or someone) can poke me in the right direction.

Thanks again!
Title: Re: Giving a character a field of view (that can be obstructed)
Post by: JD on Wed 25/08/2010 20:18:33
Quote from: GarageGothic on Wed 25/08/2010 20:05:42
Possibly you could use AGS' pathfinder to check for walls - if you have an invisible dummy character WalkStraight from the enemy position to the player, with a speed setting that makes the movement instant (speed -1? Not sure, but I did make use of it before). Then check the dummy's actual coordinates after walking. Is he at the player x,y? Then there's no wall.

This sounds like a great solution as well GG! Though I think negative speed settings just make a character move slower than 1. Using 0 seems to make movement instant though. I'll play around with this a bit, thanks again.
Title: Re: Giving a character a field of view (that can be obstructed)
Post by: Calin Leafshade on Wed 25/08/2010 20:43:36
I dislike solutions like that which rely on some internal AGS feature because it can be unpredictable and often inefficient but if it works then it works i guess.
Title: Re: Giving a character a field of view (that can be obstructed)
Post by: JD on Wed 25/08/2010 20:49:51
I've been fooling around with it a bit and it seems to work. Though I would love to see how I can implement Calin's suggestion because I'm not sure if using several hidden characters that move around checking for walls (ie. multiple enemies) would slow things down or not or whatever.
Title: Re: Giving a character a field of view (that can be obstructed)
Post by: GarageGothic on Wed 25/08/2010 20:51:17
Quote from: Calin Leafshade on Wed 25/08/2010 20:43:36I dislike solutions like that which rely on some internal AGS feature because it can be unpredictable and often inefficient but if it works then it works i guess.

Hardly inefficient compared to GetPixel, I would like to think (or hope). But I agree with you in general.

Quote from: Def on Wed 25/08/2010 20:12:41I hope you (or someone) can poke me in the right direction.

If the poking in question should involve some sort of stick... let's say a broom handle, you may want to reconsider -  or at least, Calin, have the decency to clean that nasty thing beforehand ;)

(sorry, inter-threadal joke (http://www.adventuregamestudio.co.uk/yabb/index.php?topic=41689.msg551803#msg551803))
Title: Re: Giving a character a field of view (that can be obstructed)
Post by: Calin Leafshade on Wed 25/08/2010 21:06:26
well instead of GetPixel you could use a region instead.

thats probably a better plan for a mask.
Title: Re: Giving a character a field of view (that can be obstructed)
Post by: JD on Wed 25/08/2010 21:21:15
Comparing the player's coordinates with the wall-checking character's coordinates (that moves between the enemy and the player) works. Until I decide to make that checking-character transparent. The .Transparency command doesn't affect it at all, and nothing happens when the player is within reach of the enemy. Until I remove the .Transparency command; after that it works fine. Blargh this is headache inducing! Especially if I want to have multiple enemies roaming about. :( I think I'll give the regions method another try and perhaps use less complex rooms.  :-\
Title: Re: Giving a character a field of view (that can be obstructed)
Post by: Dualnames on Wed 25/08/2010 21:22:21
OR WOW, USE REGIONS? A better way would be getting angle, getting position, and do a tracing algorithm.
Title: Re: Giving a character a field of view (that can be obstructed)
Post by: Wonkyth on Thu 26/08/2010 02:33:14
I've done this in AGS, complete with moving enemies and changing size/shape of field of view.
I just defined everything physical as vectors and used a few simple coordinate geometry equations to check for collisions and intersections.
This can also be useful if you want to change fields of view(or another related sensory thingimo) to dynamically change around the players(or another enemies) position, which is fantastic if you want squads or complex AI.
Title: Re: Giving a character a field of view (that can be obstructed)
Post by: JD on Thu 26/08/2010 16:25:16
Quote from: wonkyth on Thu 26/08/2010 02:33:14
I just defined everything physical as vectors and used a few simple coordinate geometry equations to check for collisions and intersections.

This sounds interesting. As does the 'draw imaginary line between characters and see if there is a wall(region) between them'. How would I go about doing this? I'm not trying to push anyone into giving me a bit of script that I can copy n paste and be done with it, but I would love to see an example and learn from that.

Thanks again everyone,

-Def