Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

2D All the way! / Line of sight

Author
Message
Agent
20
Years of Service
User Offline
Joined: 7th Sep 2004
Location: Sydney, Australia
Posted: 27th Sep 2004 04:16 Edited at: 29th Sep 2004 11:41
I'm currently working on a 2D tilebased game. A tile is either passable or not (ie, it's either floor or it's wall). I need to find a way to determine whether there is line of sight between two tiles, assuming that you can't see through impassibles?

Can anybody else help with the line of sight logic/algorithm/concept?

I'll provide some more details, for anyone who wants to help: I'm using arrays to hold the 2D location of each object (which includes both structures and units). The arrays are named marinex(index) and mariney(index), and represent the coordinates (in pixels) starting from the extreme top left of the tilemap. Every so often, I'll be performing a check that runs through the entire array of objects in existance. If the object belongs to the current player, it'll be displayed. If it doesn't, the line of sight rule applies. If an object that DOES belong to the player is in line of sight with the object being tested, that object will be displayed. Otherwise, it'll be hidden.

That said, I don't think the location of objects is relevant for this particular requirement. I need to test for line of sight between two tiles.

In determining line of sight, it's simply a matter of whether or not there's an impassable tile between the object being tested and the player-owned object. The tileset is stored in a single array, called map(x,y). There's a simple check to test if a tile at any given coordinate is passable or not.

So, what I need is an algorithm to check whether there's an impassable tile between any two given tiles.

Can anybody help?
Cybermind
Valued Member
22
Years of Service
User Offline
Joined: 28th Nov 2002
Location: Denmark
Posted: 27th Sep 2004 05:24
how about making a line, or shoot an object somehow, and if it touches impasable object then no line of sight. I need such a code myself, so I can write the code tonight or tomorrow and share it with you, if you want. Do you want DBC or DBPRO?
Agent
20
Years of Service
User Offline
Joined: 7th Sep 2004
Location: Sydney, Australia
Posted: 27th Sep 2004 15:23 Edited at: 27th Sep 2004 15:25
I'm DB Pro. I don't quite understand the concept you're suggesting, so guve me some pseudocode or a functional snippet that I can work with

I can draw a line alright, but how do I test to see if it crosses an impassable?!

I'll give you some code specifics:
I'm using an array called map(x, y) to store the tile information. The value stored is the tile type (which is merely the image number to display for that tile). I use a function called ispassable(x, y) to return a 1 if the specified tile is passable or a 0 if it's not. I need a new function lineofsight(x1, y1, x2, y2) that will return a 1 if there is line of sight between the two specified map tiles or a 0 if there's not.

I'd appreciate any help here. Please share your code with me.
Cybermind
Valued Member
22
Years of Service
User Offline
Joined: 28th Nov 2002
Location: Denmark
Posted: 27th Sep 2004 20:03
I will look in too it today
Cybermind
Valued Member
22
Years of Service
User Offline
Joined: 28th Nov 2002
Location: Denmark
Posted: 27th Sep 2004 22:52 Edited at: 27th Sep 2004 22:53
can you mail me the code? stefanchristensen[a]gmail.com with an ordinary @ of course, it is just to keep off those damn spam and junk mailers
Cybermind
Valued Member
22
Years of Service
User Offline
Joined: 28th Nov 2002
Location: Denmark
Posted: 27th Sep 2004 23:37
to be honest, I don't know much about how to make a line of sight function, but I will try hard, as I said, I need one myself.
Agent
20
Years of Service
User Offline
Joined: 7th Sep 2004
Location: Sydney, Australia
Posted: 28th Sep 2004 21:33
Part of my agreement with my supporters is to keep the code under wraps, so I can't just send you the source. I can give you specific details though, like I did above. What more will you need, besides what I've already given?

Just have a go at it for your own purposes and show me your logic so I can create code for my own project. I'm in the habit of crediting anybody who contributes in some way or another, so you'll get your name in the credits of my game when it's done
Cybermind
Valued Member
22
Years of Service
User Offline
Joined: 28th Nov 2002
Location: Denmark
Posted: 28th Sep 2004 22:34
ok, then I will start from scratch, and write in detail what I do in the code, no worry, but give me a week or something, I got a lot of things to do, near full-time work, doom 3 demo, my 2d level editor, watching my new season of futurama, and a little social life, so if you can start on something else while you wait for my code to be done then it would be fine what kind of game are you making? I am experienced in game concepts, so I can give you couple of ideas you can ditch or use, by the way, I build a multiple choice dialog engine, it is easy to fill in with new dialog, do you want it?
Agent
20
Years of Service
User Offline
Joined: 7th Sep 2004
Location: Sydney, Australia
Posted: 29th Sep 2004 11:28 Edited at: 29th Sep 2004 11:43
My game is an RTS. The website is at http://members.optushome.com.au/sektor/ihw/index.htm.

I don't really have need for a dialog engine in this game, but thanks for the offer. At the moment I'm concerned mostly with the line of sight code. It's probably the last thing I need help with before I can finish the game engine. After that I will need artists to make the final graphics.

Can anybody else help with the line of sight logic/algorithm/concept in the meantime?

I need an algorithm to check whether there's an impassable tile between any two specified tiles.

Can anybody help?
Flashing Blade
22
Years of Service
User Offline
Joined: 19th Oct 2002
Location: United Kingdom
Posted: 29th Sep 2004 20:10
Try this page:

http://www.gamedev.net/reference/articles/article729.asp


The word "Gullible" cannot be found in any English Dictionary.
the_winch
22
Years of Service
User Offline
Joined: 1st Feb 2003
Location: Oxford, UK
Posted: 30th Sep 2004 02:16
Here is a quick example.
Use the left mouse button to toggle wall pieces.
Use the right mouse button to position object a
Use the middle mouse button to position object b
Use space to toggle drawing the line that is used to see if they can see each other.

Click source button.

it's cool to hate
Agent
20
Years of Service
User Offline
Joined: 7th Sep 2004
Location: Sydney, Australia
Posted: 3rd Oct 2004 08:09
Thanks Winch, but your method is very inefficient for the system I am using. I will be calling the line of sight function (which will check between two points) up to 300 times per main loop cycle. Your code reduces my game to less than one frame per second. This seems to be because the further the two points are apart, the more calculations are performed. I will be checking objects at distances of up to around a thousand pixels. To check a distance of 1000 pixels your code would perform 1000 calculations. At maximum distance, your code would therefore perform up to 300,000 calculations per main loop cycle. Obviously, I can't use your code for that.

I require code which will determine the line of sight with a calculation which will take the same amount of time regardless of the distance between the two points. Efficiency is paramount - I cannot use anything that wastes time. I need to keep the number of calculations to a minimum in order to maintain efficiency.

In other words, I require code which can determine whether there is line of sight between two points in a constant number of calculations, irrespective of the distance between those two points.

Anyone up for the challenge?
PowerFang
21
Years of Service
User Offline
Joined: 6th Feb 2004
Location: Australia (But currently in the USA)
Posted: 4th Oct 2004 20:11 Edited at: 4th Oct 2004 20:13
** Edit : soz havent read all the posts when i first posted....the following code is not efficient and would need some work.


HEh just the thing i have just finished......This was something that was bugging me so after a bit of work i've got this:



There is alot of junk in there as i have just finished it and i have yet to implement it into storing the non viewables into an array.
PowerFang
21
Years of Service
User Offline
Joined: 6th Feb 2004
Location: Australia (But currently in the USA)
Posted: 4th Oct 2004 20:27
To make it better i recommend using this type of thing:

work out the gradient of the line between the 2 points:

Gradient = Rise / Run
Gradient = y1-y / x1-x

if Gradient < 1

xSquare = 1 / Gradient

The above line works out how many x squares to go across to go up 1 y square.....i.e. the next grid square that could block line of sight.

While x < goalx

count = count + 1
blocked = impassable(count*xSquare,count)
if blocked = 0 then LOS is blocked

x = count * xSquare

endwhile

Something along those lines is what i would try.......i'll try code this later on,. not up for it now
Peter H
21
Years of Service
User Offline
Joined: 20th Feb 2004
Location: Witness Protection Program
Posted: 7th Oct 2004 23:27 Edited at: 7th Oct 2004 23:28
so we can use the "impassable" function in our code?

and also...with the x and y positions the function is fed...is that the pixel pos...or the tile pos?

"We make the worst games in the universe."

Agent
20
Years of Service
User Offline
Joined: 7th Sep 2004
Location: Sydney, Australia
Posted: 9th Oct 2004 20:23
It's a pixel position. The function automatically converts that pixel position into a tile position by dividing by 50 and subtracting 1 from each param (x and y). Note that the function is called ispassable not impassable as people have been suggesting. You can use the ispassable function in your code in the format

dummy = ispassable(x,y)

The function returns a 1 if the specified tile is a floor (passable) or a 0 if the tile is a wall (not passable).

Line of sight is blocked by walls. In other words, if any of the tiles checked by your code return a 0 by ispassable, LOS is blocked.

If you are interested in helping, please create a function for me called lineofsight(x1,y1,x2,y2) that accepts the tile coordinates of the two tiles to be checked, and then performs a line of sight operation between those two tiles.

The simple logic I've come up with should keep calculations to a minumum: Your function should fill an array (or two arrays) with the coordinates of each tile that lies in a straight line between the source tile and the target tile. Then simply run an ispassable(x,y) on each coordinate in the array. If you get a 0 anywhere, then LOS is blocked and your function should return a zero. Otherwise, if they are all 1's, return a 1 yourself.
Oneka
21
Years of Service
User Offline
Joined: 24th Apr 2004
Location: Hampton,VA
Posted: 10th Oct 2004 05:59 Edited at: 10th Oct 2004 05:59
note* I didnt read the whole thread before saying this.
Ok you could just make a variable thats used for all tiles like named opacity or Viewable and if its one then check if player is facing north or something and tile is infront of him then you cant see a area...
P is player
1 is a tile that has a viewable variable set to 1 and D is the line of sight that is blocked..



Making better games everday!
Oh yeah and just so you know its Oh-nek-a not One-ka!
Peter H
21
Years of Service
User Offline
Joined: 20th Feb 2004
Location: Witness Protection Program
Posted: 10th Oct 2004 11:05 Edited at: 10th Oct 2004 11:09
@Agent...okey dokey, will get working

Quote: "The simple logic I've come up with should keep calculations to a minumum: Your function should fill an array (or two arrays) with the coordinates of each tile that lies in a straight line between the source tile and the target tile. Then simply run an ispassable(x,y) on each coordinate in the array. If you get a 0 anywhere, then LOS is blocked and your function should return a zero. Otherwise, if they are all 1's, return a 1 yourself."

so i guess the hard part is going to be finding the all the tiles inbetween your tile and the other tile


so with the "ispassable" function we have to feed it a pixel pos?? be kind of inconvenient if we start out with tile positions

"We make the worst games in the universe."

Agent
20
Years of Service
User Offline
Joined: 7th Sep 2004
Location: Sydney, Australia
Posted: 11th Oct 2004 15:49
@Oneka:
The ispassable function acheives exactly the result your suggested array would. You then suggest I should check to see if a blocked tile is in front of the player; The problem I had in the first place was, how exactly do you do that?

I need pseudocode, people, so that I can see the logic behind the solution. Actual code would be even betterif you feel you properly comprehend my code as I've described.

@Peter_X:
Yes, the hard part is determining which tiles lie between those specified. Those tiles have to be in as straight a line as possible. Tile sizes are 50x50, so if you want to convert a tile location to a pixel location, subtract one and then multiply by fifty The function automatically determines which tile that pixel location is in, and perform the appropriate check.

Bear in mind that efficiency is paramount - as few calculations as possible please! I will be calling this line of sight function up to several hundred times per main loop cycle.
Peter H
21
Years of Service
User Offline
Joined: 20th Feb 2004
Location: Witness Protection Program
Posted: 12th Oct 2004 00:50
ok...i've already started with a little thing that checks to see if the positions are on the same axis..and if they are then just do it the easy way

so it will optomize same axis checking

"We make the worst games in the universe."

Agent
20
Years of Service
User Offline
Joined: 7th Sep 2004
Location: Sydney, Australia
Posted: 15th Oct 2004 00:34
How are we going with that one, Pete?
Agent
20
Years of Service
User Offline
Joined: 7th Sep 2004
Location: Sydney, Australia
Posted: 22nd Oct 2004 18:33
Well, I guess my help has fallen through this time around. Anybody else able to help?
Peter H
21
Years of Service
User Offline
Joined: 20th Feb 2004
Location: Witness Protection Program
Posted: 22nd Oct 2004 21:40
i'm so busy with my compo game i completely forgot about this

maybe i'll be able to help after teh compo

"We make the worst games in the universe."

pizzaman
21
Years of Service
User Offline
Joined: 18th Feb 2004
Location: Gateshead, UK
Posted: 23rd Oct 2004 05:50
Hi

(Note: haven't read all of post)
All you need to do is give each tile a number, for example the top-left most tile is number 1, then the next tile to right is number 2 and so on.
Next you check the tile the player is on, then his orientation (left, right, up, down, etc), then which tile you want to see to; and now that you know which tile the player's on and which direction their facing, do the following :

Note: the followong is based on a straight line of sight, not a triangular or segmented line of sight but the same principle applies you will have to find out where the player sees, which can be done via floodfill algorithms to find out which tiles to check.

1. Check to see if the player is facing the right direction, if so goto 2 else end.
2. Check whether the next tile in between the player and the goal tile (*see below on how to do this) is passable or not, if its passable repeat this step until you get to the goal tile else end.

*If you know which tile the player is on and what direction their facing then you can work out where the next tile is, for example if tile map is a 10 by 10 grid, and the player is on tile 45, if the player is facing left then you minus one tile to get the next tile which is 44, then it would be 43, 42, 41, 40. If the player was facing up down then plus 10 tiles (the tile map's width), there the next tile would be 55 then 65, 75, 85 etc.

Sorry for the long winded answer, hope it helps
pizzaman
Agent
20
Years of Service
User Offline
Joined: 7th Sep 2004
Location: Sydney, Australia
Posted: 23rd Oct 2004 21:47
A note to all future posters in this thread:

Everyone who has mentioned that they didn't read everything has given useless answers. Please, please do not post in this thread unless you have read every word. You will not understand my problems unless you have read every single post.

Determining line of sight left, right, up and down is an elementary problem I might give a beginner. I need to determine line of sight along any given angle, from 0 degrees to 360 degrees, and this is problem a programmer with twenty years experience (me) can't get my head around.

I expect this is a problem that only a programmer with a similar degree of experience, or someone with university qualifications in mathematics is going to be able to help me with.

I need someone to post who is 100% sure they are giving me a correct answer, or at least pointing towards the right direction. If you want to speculate or guess, please leave my thread alone. My most significant project of all time depends upon this thread - please keep responses useful. Read every post before making your own.
Peter H
21
Years of Service
User Offline
Joined: 20th Feb 2004
Location: Witness Protection Program
Posted: 26th Oct 2004 08:54
as soon as this compo is over i will dive into this

but for the next 4 days i'm going to be very busy

"We make the worst games in the universe."

Agent
20
Years of Service
User Offline
Joined: 7th Sep 2004
Location: Sydney, Australia
Posted: 1st Nov 2004 14:09
Well, it's been four days How are we going with this?
DeepBlue
21
Years of Service
User Offline
Joined: 17th May 2003
Location: A little box in the UK
Posted: 9th Nov 2004 01:06 Edited at: 11th Nov 2004 10:08
Here ya go I think this is most of what you are after.

All calculations are done in memory using a mapArray that designates the tile type i.e. wall or floor, & the losTest function to determine if a tile is visible by an incrementally increasing vector & detecting if a wall is present. Note, the step is 25 units/pixels in the demo which will give the fastest speed but less accuracy.

For demo purposes the FOV function that uses the losTest function just goes through all the tiles to see what is visible to the player. The loop time to check 192 objects on my system takes around 10ms so speed shouldnt really be an issue.



DeepBlue

The coder formerly known as Twynklet.
DeepBlue
21
Years of Service
User Offline
Joined: 17th May 2003
Location: A little box in the UK
Posted: 11th Nov 2004 09:56
Amended above code as I accidently left a sprite command in that was slowing the whole thing down 10 fold.

The coder formerly known as Twynklet.

Login to post a reply

Server time is: 2025-05-15 22:35:40
Your offset time is: 2025-05-15 22:35:40