Skip to main content
3 of 4
added 174 characters in body
David Gouveia
  • 25k
  • 5
  • 88
  • 127

Your definition of visible is the following:

tile is visible when at least a part (e.g. corner) of the tile can be connected to center of player tile with a straight line which does not intersect any of obstacles

You can implement this concept quite literally by tracing rays from your player tile and intersecting them with your scene. You break from each iteration once the ray hits an obstacle (or exceeds a certain distance threshold) since you're only interested on the tiles the player can see directly. I'll break up the process for you:

  1. Specify the level of precision you'd like to give the algorithm. This will be the number of rays you will be tracing.
  2. Divide the full 360 degrees circle by the chosen precision to know how many degrees to rotate between each ray.
  3. Starting at 0 degrees and incrementing by the amount determined in step 2, create a ray with the origin at the center of the player tile, and the direction determined by the current angle.
  4. For each ray, starting from the player tile, walk along the direction of the ray until you hit an obstacle tile. Add that tile to the visible tile list and proceed to the next ray. You might also want to add a maximum distance to "give up" in case no collision is found.

Here's a picture showing 3 example rays. The darked colored tiles are the "result" of each ray, i.e where the collision happened. You'd need to repeat this all around the circle though:

enter image description here

Tweak the maximum distance and number of rays for performance. Too little and you'll miss a few tiles, too much and your performance will suffer. Also, the furthest the rays have to travel, the larger the "error" will get, and the more precision you'll need.

Edit

Check the following tutorial on raycasting, in particular Step 3 and Step 4, to help you implement the intersection bit of the algorithm:

http://www.permadi.com/tutorial/raycast/rayc7.html

David Gouveia
  • 25k
  • 5
  • 88
  • 127