Giving a character a field of view (that can be obstructed)

Started by JD, Wed 25/08/2010 19:39:23

Previous topic - Next topic

JD

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.


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

Calin Leafshade

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.

GarageGothic

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. 

JD

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!

JD

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.

Calin Leafshade

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.

JD

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.

GarageGothic

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)

Calin Leafshade

well instead of GetPixel you could use a region instead.

thats probably a better plan for a mask.

JD

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.  :-\

Dualnames

OR WOW, USE REGIONS? A better way would be getting angle, getting position, and do a tracing algorithm.
Worked on Strangeland, Primordia, Hob's Barrow, The Cat Lady, Mage's Initiation, Until I Have You, Downfall, Hunie Pop, and every game in the Wadjet Eye Games catalogue (porting)

Wonkyth

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.
"But with a ninja on your face, you live longer!"

JD

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

SMF spam blocked by CleanTalk