I wrote a system for my tilebased rpg which does the following:
First get a list of all the visible light sources in the scene. I have a max light distance somewhere, and if the light sources are further away than that from what is visible to the player, I can just ignore them.
Then loop through every tile I'm going to draw:
- Each tile starts out in darkness - I make an 'intensity' value of 0.
- I loop through every visible light source and do this stuff: (don't worry, there's only a couple of hundred tiles onscreen at a time and maybe a dozen light sources so it's not so bad)
* first, I calculate how much light the light source can shine onto the tile. Up to you how you want this to work - fixed value, dropping off based on distance, etc. I made mine shine less light onto the tile the further away you are.
* next, check to see if there actually is a line of sight between the tile and the light source position. I'll post my line of sight check below, because it's useful for other stuff, too. If there is a line of sight, the light value from the light source gets added to the tile. If not, that light source contributes no light and is not added. You can fool around a good deal with how you calculate adding two brightnesses together to get the effect you want.
- Draw some kind of representation of how "in shadow" the tile is on top of the tile. I used a 4x4 ordered dither to give nice pixely shadows but you can just as easily just use black with alpha values increasing with intensity.
Here's a video of how it looks in action - this one is a bit old, but you get the idea:
https://www.dropbox.com/s/34un702humfby ... 2.mp4?dl=0
Line of sight check uses the Bresenham Line algorithm to get all the tiles from position A to position B:
https://en.wikipedia.org/wiki/Bresenham ... _algorithm
Once I have a list of all the tiles in a line, I run through them and check if they have a "BlockLineOfSight"-property.