I just started creating a game using libgdx. It is a top down 2d shooter using scene2d ui. Now i thought, that i could add darkness and light to some levels, but i don't want to rewrite everything using box2d. I don't need realistic shadows just some kind of ambient light and a lightcircle arround my character, which is not affected by walls and other obstacles arround him. So i wanted to know if there is any kind of lightsystem in libgdx? Or can i use box2dlights without using box2d bodies/world...? Thanks
问题:
回答1:
Unfortunately there is nothing like this already provided by LibGDX.
But you can easily do it yourself if you do not want shadows.
Here is a little video of someone who has done it via LibGDX. Here is the article to this video, with code and descriptions and everything provided.
You can do it this way with shaders, but you could also do the same by just rendering a lightmap to an FBO (in the given links you can see how to do that) and then just render it the usual way with blending activated on top of your screen. The standard SpriteBatch
can do that and you don't need any custom shaders.
If you still want to have real shadows with obstacles, you will probably find this article very useful. But this is a lot slower and needs special shaders.
There is also no way to use Box2dLights without Box2D btw.
回答2:
In my opinion the marked answer is wrong.
Its actually pretty simple to use box2dLights without using box2d if u dont want any shadows. The question was, if its possible to add some kind of circle light around a character.
I used two different approaches, only one using box2dlights.
The article in the marked answer discripes a method using FBO. U dont really need that if u just want to lighten an area. U just need a sprite, like this. Now place it somewhere on ur screen, and when rendering , do the following:
batch.setBlendFunction(GL20.GL_DST_COLOR, GL20.GL_SRC_ALPHA);
theLightSprite.draw(batch, parentAlpha);
batch.setBlendFunction(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
First the blend function is changed, so we dont just render the sprite, but blend it in a lighting way on the background. After drawing it, reset the blend function to normal, so everything else after this is rendered normally again. Thats it.
Second approach uses box2dlights. Yes, we do need a box2d world object, but we dont need to do something with it. So what we do is:
world = new World(new Vector2(0,0),false);
rayHandler = new RayHandler(world);
rayHandler.setCombinedMatrix(stage.getCamera().combined);
new PointLight(rayHandler,1000, Color.BLUE,radius,x_position,y_position);
First we create our world, thats just doing nothing. We only need it for the second statement, where we create our RayHandler, that calculates our lights. In the third statement we set the matrix of the rayHandler. In this case i use scene2d, and thus using the stages camera combined matrix for it. If u use another camera just use its combined matrix here. The last statement creates a pointlight with the rayHandler, and discribe the number of rays, the lights color, its radius, and its position.
All we have to do now, is draw our stage or sprites in our render() method and call
rayHandler.updateAndRender();
after that in the render method. Pretty easy.