高效的2D基础的瓷砖照明系统 [英] Efficient 2D Tile based lighting system

查看:180
本文介绍了高效的2D基础的瓷砖照明系统的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么是最有效的方式做照明的基于区块的引擎在Java中?
难道是把后面的瓷砖黑色背景和改变瓷砖阿尔法?
或者把一个黑色的前景和改变的阿尔法?还是别的什么?

What is the most efficient way to do lighting for a tile based engine in Java?
Would it be putting a black background behind the tiles and changing the tiles' alpha?
Or putting a black foreground and changing alpha of that? Or anything else?

这是我想要的那种照明的一个例子:

This is an example of the kind of lighting I want:

推荐答案

我觉得有很多很多很多的方式,以做到这一点。
所以要ppared花一些时间阅读本$ P $,
并请决定做什么
前阅读整个后 并且,我已经创造了一些code你到底:)

I think there are many many many ways to do that.
So be prepared to take some time reading this,
and please read the whole post before deciding what to do
and and the end i have created some code for you :)

我会'简单'综上所述,你可以去的方式,
因为有不同的方式要实现每一个不同的东西。

I will 'briefly' sum up the ways you could go,
because there is a different way for every different thing you want to achieve.

如果你想创建的不是很复杂硬边照明的效果是这样的:
(原谅我,如果我用你的形象,例如:D)

If you want to create not very complex hard edge lighting effects like this:
(forgive me if i used your image as example :D)

,那么你可以使用黑瓦图片

悠悠地过/后面您的砖和一个在前台设置为一个特定的 alpha值
这两个看起来完全一样,只是一个时间你添加透明的黑色瓷砖
和其他的时间到瓦片。
如果你是他创造了许多50%的α-黑瓦它看起来是这样的:

and lay it over / behind your tiles and set the one in foreground to a specific alpha value.
both will look exactly the same, just one time you add transparency to the black tile
and the other time to the tile.
if you maybe create many 50% alpha black tiles it will look like this:

,但这不是一个非常有效的方法,因为:

but this is not a very efficient way because:

    的Java
  1. alpha混合是不是很有效率可言,
    但我认为今天连smalles设备运行 Java 2D的应用
    可以处理这个轻松,所以这是不是在所有的主要问题

  1. alpha blending in java isn't very efficient at all,
    but i think today even the smalles device running java 2D applications
    can handle this with ease, so this is not the main problem at all

但如果你有加载额外的黑色瓷砖和油漆过来/每瓦暗淡下,
这会消耗额外的内存,是很缓慢的,因为你画两个真正的砖每一瓦日后可以看到

but if you have to load an extra black tile and paint it over / under each dimmed tile,
this consumes extra memory and is really slow because you paint two real tiles for each tile you can see afterwards

但更好的背景方式:
如果你的使用黑色背景图片在游戏中,无论如何,
你可以只设置你的瓷砖阿尔法以较低的数值,以使它们更暗,
如果该值为0(全黑),你甚至可以省略瓷砖和移交到下一个
所以你尽量少画的时间。

But the 'nicer' background way:
if you would use a black background image in your game anyway,
you could just set the alpha of your tiles to lower values to make them darker,
if the value is 0 (full black) you can even omit that tile and hand over to the next one
so you minimize the painting time.

这将导致相同的方式与上面所述的许多黑色瓷砖,
并且会更便宜(一个大的图像 VS 许多小图像
像这样的:

This would result in the same as the way above with the many black tiles,
and would be less expensive (one big image vs. many small images)
like this:

许多小黑瓦(见上图)

利用研究背景为黑色,与铺设在它
透明地砖
用GIMP它很难做到快,但程序code,你可以轻松地从100%的瓷砖阿尔法为0%瓷砖阿尔法梯度,使他们淡出从中间向外侧

using backgroud as black and laying tiles with transparency over it

with gimp its hard to do fast, but in program code, you can easily make a gradient from 100% tile alpha to 0% tile alpha so they fade out from middle to outer

但如果你有一个背景,你的游戏,是不黑
那么这个ins't真正有用的,因为它会导致许多黑瓦
paintet每瓦背后,我已经提到了同样的事情。

but if you have a background in your game that is not black
then this ins't really helpful, because it would result in many black tiles
paintet behind each tile, the same thing i have mentioned already.

在这一切的例子,你会得到一个硬边的光,只用每瓦一盏灯的水平

in all this examples you will get a hard edge light, with only one light level per tile

但是,如果我看看你的形象,
我能想象更具体的问题,更好的方式上悬而未决他们:

But if i have a look at your image,
i can imagine more specific problems and better ways to slove them:

  • 我想你想创建一个围绕你的角色的灯光和火把也许/不管

所以我有办法给你,那并不难实现,也具有高配置!
你可以之间甚至可以选择硬光柔和的光线,只有很少的改变:

Therefore i have a way for you, that isn't hard to implement and also high configurable!
You can even choose between hard light and soft light with only little changes:

您刚刚绘制所有砖为正常,完全不透明,打下一个大的图片在它
从阿尔法梯度(A 面膜(全亮)黑色(无灯光的全部)作为一个循环。
所以你可以得到动态柔和的光线,不会做太多!

you just draw all tiles as normal with full opacity, and lay one big image over it
(a mask) with a gradient from alpha (full light) to black (no light at all) as a circle.
so you could get dynamic soft light and wouldn't have to do much!

如果你想在硬光有太多,只是改变图片如下并将其放置在你的砖格(这样一个区块是面具瓷砖完全落后,
和中间瓷砖铺设在光源例如):

if you want the hard light there too, just change the image as follows and position it at your tile grid (so that one tile is exactly behind the mask tile,
and the middle tile lays over the light source for example):

新的面具看起来像(白色字母):

new mask would look like (white is alpha):

和结果:

通过这种方法,你甚至可以实现复杂的光形成一个圆圈容易
(试图从上方与黑瓦方法建立一个cirle出瓷砖在运行时,
比你现在想起来可能更难)
如果您 colorify 阿尔法一点,您的光会得到一个颜色

with this method you could even achieve complex light forms as a circle easy
(try to build a cirle out of tiles at runtime with the black tiles method from above,
might be harder than you think of it now)
and if you colorify the alpha a bit, your light would get a color!!

,但它有一个很大的缺点,这是不容易的一个光源相结合与另一
因为这两个口罩将取消themselfes出来,看起来丑陋的:

but it has one big disadvantage, it isn't easy to combine one light source with another
because the two masks would cancel themselfes out, that looks ugly:

所以你终于可以头到最复杂的方式,我能想到的砖出了现在我的脑海:
我们的颠倒面具
这意味着,在每一点上的面具由全alpha,
瓷砖背后绘制全黑
到处都全白,地砖被绘制完成。

so you could finally head over to the most complex way i can imagine for tiles out of my mind now:
we invert the mask!
that means that on every point the mask consists of full alpha,
the tiles behind are drawn fully black
and everywhere with full white, the tiles are drawn completely.

您可以想像,如果你敷个面膜
会发生什么 由白色,50%的α
瓷砖会得出同样的方式作为一个黑色背景的瓦(50%α)绘制了它
在这里,我用了2口罩,并结合它们,并将它们应用到地图:

you can imagine what would happen if you apply a mask
consisting of white with 50% alpha?
the tiles would drawn the same way as a black background with tile (50% alpha) drawn over it
here i used 2 masks, combined them and applied them to the map:

面膜1:

面膜2:

结果图像(增加两个面具,并将其应用到图像):

result image (add two masks and apply them to the image):

大致相同的掩模事情以上,但存在这样的优点:
你可以有许多光源(圈从白到阿尔法的口罩
即使是不同的尺寸/形状/颜色/等。,只是它们合并到一个图像
(躺着一个比下一个),你会得到一个最终的面膜可以应用到你的瓷砖。
所以你只要有一圆形或任何面具的每一个光源

roughly the same as the mask thing above but there is an advantage:
you can have many light sources (circles from white to alpha as a mask)
even with different sizes / shapes / color / etc. and just combine them to one image
(lay one over the next) and you will get a final mask you can apply to your tiles.
so you just have one circle or whatever mask for every light source

我想你呈现一个的BufferedImage 首先,如果你愿意,维基,瓷砖 我可以提供一点code的例子在这里你可以如何应用这样的Alpha遮罩
我已经在过去的方法证明一个的BufferedImage

i think you render the tiles in a BufferedImage first, if you so,
i can provide a little code example here how you can apply such a alpha mask
that i've shown to in the last method on a BufferedImage:

public void applyGrayscaleMaskToAlpha(BufferedImage image, BufferedImage mask)
{
    int width = image.getWidth();
    int height = image.getHeight();

    int[] imagePixels = image.getRGB(0, 0, width, height, null, 0, width);
    int[] maskPixels = mask.getRGB(0, 0, width, height, null, 0, width);

    for (int i = 0; i < imagePixels.length; i++)
    {
        int color = imagePixels[i] & 0x00ffffff; // Mask preexisting alpha

        // get alpha from color int
        // be careful, an alpha mask works the other way round, so we have to substrat this from 255
        int alpha = (maskPixels[i] >> 24) & 0xff;
        imagePixels[i] = color | alpha;
    }

    image.setRGB(0, 0, width, height, imagePixels, 0, width);
}

如果你现在创建了一个火把,也许,一个FPR玩家,
口罩 您可以将那些缓冲图像(或更多,然后2)是这样的:

if you now create a mask for a torch maybe and one fpr the player,
you can combine those to buffered images (or more then 2) this way:

public BufferedImage combineMasks(BufferedImage[] images)
{
    // create the new image, canvas size is the max. of all image sizes
    int w, h;

    for (BufferedImage img : images)
    {
        w = img.getWidth() > w ? img.getWidth() : w;
        h = img.getHeight() > h ? img.getHeight() : h;
    }

    BufferedImage combined = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);

    // paint all images, preserving the alpha channels
    Graphics g = combined.getGraphics();

    for (BufferedImage img : images)
        g.drawImage(img, 0, 0, null);

    return combined;
}

可以肯定这是可能的,有我在code,
一些小错误 因为我从我的脑海里写下来,所以请不要生气跟我看看 我肯定你自己看着办吧自己:)

for sure it's possible that there are some minor mistakes in my code,
because i've written it down from my mind, so please don't get mad with me
im sure you can figure it out yourself :)

你唯一的挑战是要在绘制时即时创建合适的面具,
但是我相信你很快就会得到它, 我是多么希望你一切顺利!
我希望我能帮助你远一点你的目标!

your only challenge now is to create the right mask on the fly when drawing,
but im sure you will get it soon, i'm wishing you all the best!
i hope i could help you a bit further to your goal!

这篇关于高效的2D基础的瓷砖照明系统的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆