简体   繁体   English

2D瓷砖照明

[英]2D Tile Lighting

I'm adding lighting to my XNA 2D tile based game. 我正在为我的基于XNA 2D磁贴的游戏添加照明。

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) 我一直在寻找相当长的一段时间但没有运气(我确实找到了Catalin的教程,但它对我来说似乎有点先进,并且由于重新绘制了每个点的整个游戏而不适用于瓷砖)

I'll share my method for applying a smooth lighting effect to a 2D tile grid. 我将分享我的方法,将平滑的光照效果应用于2D平铺网格。 ClassicThunder's answer provides a nice link for shadows. ClassicThunder的答案为阴影提供了一个很好的链接。

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 . 基本上我们所做的是循环遍历所有图块,从顶部开始,如果图块为空白,则将CurrentLight变量设置为最大亮度,如果我们找到实心图块,将其设置为CurrentLight变量并减去“吸收”量来自CurrentLight This way, on our next solid tile, when we set the tile to the CurrentLight value, it will be slightly less. 这样,在我们的下一个实体图块上,当我们将图块设置为CurrentLight值时,它会略微减少。 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. 我们必须再重复这个过程3次,从下到上,从左到右,从右到左。 And it can be repeated more times for better quality. 它可以重复多次以获得更好的质量。

Basically running this code on every tile in the loop 基本上在循环中的每个tile上运行此代码

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. 但是,如果你想要一个较少的“像素化”外观,你可以在gamedev上查看我的问题

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. 在SpriteBatch.draw中,一些重载方法采用了一种颜色。 When you use Color.White, the sprite that the SpriteBatch draws is normal colored. 当您使用Color.White时,SpriteBatch绘制的精灵是正常颜色。

Use Color multiplication by creating a new Color(Color.yourcolor.r*float, Color.yourcolor.y*float, Color.yourcolor.z*float, 255) 通过创建新颜色使用颜色乘法(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. 由于2D游戏不需要法线,因此这个公式应该相对容易。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM