问题
I'm adding lighting to my XNA 2D tile based game.
I found this article useful, but the way its done it does not support collision. What I'd like is a method to do the following
- Have always lit point
- Collision (If the light ray hits a block, then dim the next block by whatever amount until its dark to simulate shadows)
I've been searching around for quite a while but no luck (I did find Catalin's tutorial, but it seemed a bit advanced for me, and didn't apply to tiles well due to redrawing the entire game for each point)
回答1:
I'll share my method for applying a smooth lighting effect to a 2D tile grid. ClassicThunder's answer provides a nice link for shadows.
First off, we will need to calculate the lighting values of each tile which will be blurred later. Let me illustrate how this works before I get into the code.
Basicly what we do is loop through all the tiles, starting from the top, if a tile is blank, set the CurrentLight
variable to max brightness, if we find a solid tile, set it as the CurrentLight
variable and subtract an "absorbsion" amount from the CurrentLight
. This way, on our next solid tile, when we set the tile to the CurrentLight
value, it will be slightly less. This process is repeated until the array is iterated.
Now there will be a nice top to bottom lighting effect, but it isn't that great. We must repeat this process 3 more times, for bottom to top, left to right, and right to left. And it can be repeated more times for better quality.
Basically running this code on every tile in the loop
if (tile.Light > CurrentLight) //If this tile is brighter than the last, set the current light to the tiles light
CurrentLightR = tile.Light;
else if (CurrentLight != 0f) //If it is less, and isnt dark, then set the tile to the current light
tile.Light = CurLightR;
if (tile.Light == CurLightR) //If it is the same, subtract absorb values
CurrentLight -= tile.Absorb;
And there you go, nice tile lighting. However if you want a less "pixelized" look, you can check out my question on gamedev for that.
回答2:
For per-pixel lighting, you might have to look somewhere else, because I don't know about that. For per-tile lighting,
in SpriteBatch.draw, a few of the overloaded methods takes a color. When you use Color.White, the sprite that the SpriteBatch draws is normal colored.
Use Color multiplication by creating a new Color(Color.yourcolor.r*float, Color.yourcolor.y*float, Color.yourcolor.z*float, 255)
Basically, to get the float, try to find out a formula that calculates the brightness of the block due to nearby lights (stored in an array or list, probably). Since there's no normals needed for 2D games, this formula should be relatively easy.
来源:https://stackoverflow.com/questions/9864869/2d-tile-lighting