At some levels of my game I would like to darken all the elements but with some exceptions. I have added a top layer with a dark transparent color, but I dont know how to avoid some elements to get this color without changing all my z-order.
Changing z-order is the best choice but if you want another way:
-You can use clipper for the layer
or
-addchild the objects you want to keep to the dark layer
I want to darken everything except some element (lets say the moon) that will appear behind all the darken elements, so I chaning the z-order is not an option.
I didnt know about clippingNode, I am going to look for information about it, I think It will work. Thank you very much.
Ok, after some thinking, the ClippingNode solution will not work , because the elements that go thought the “cropped” area of the layer will lost the darkness.
Yes, I have done that (and I glad to learnt this feature ) . But maybe I havent explained myself very well or maybe I dont understand something.
This is a very simplified hierarchy of the layers:
-Background layer (with the Moon)
-Game Layer
-Darken layer (Layer with transparency above all layers, to darken all the elements)
I want to darken all the elements except the moon, but the moon has to be behind all the elements.
If I crop the “darken layer” to see the moon, it will also affect the game layer and its elements (Sometimes the moon hides behind elements.)
Now I am reading about the shader solution, lets see.
@saraguatox i am not sure if i understand your requirement, but Node::setColor() can make node darker. And Node::setCascadeColorEnabled() can change its children’s color.
Thank you very much, @zhangxm and @b12345 , for your answers.
I had thought already in this solution, but in the game sometimes some elements change already its colors and opacities under some circumstances with this method (sometimes tinted to red, sometimes tinted to blue…) so I supposed that this kind of solution will affect the other setcolors. Am i wrong?
Yep, you are right. May be you can render Game Layer to a rendertexture, and make it darker. Of course, it will slow down the app, but it works if it is just use it not frequently.
I tested your moon scene idea by having a background, a “moon” and something obscuring part of the moon, and used a LayerColor to cover the entire screen to darken it. Using blending functions, I was able to have the moon remain undarkened, while part of it is covered by a darkened sprite in front of it. Here’s how I did it:
Give your moon a blending function of (GL_ZERO, GL_ONE_MINUS_SRC_ALPHA).
Add a LayerColor in front of everything you want darkened and give it a blending function of (GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA).
Add a second copy of the moon in the same location as your first one and above the LayerColor. Give it a blending function of (GL_ONE_MINUS_DST_ALPHA, GL_ONE).
And that should work. Just set the colour of the LayerColor to black and adjust the opacity to darken/lighten the scene. (The higher the opacity, the darker the scene.) Here’s an explanation of what is happening:
The blending function of the first moon means it is “cutting a hole” in the scene, i.e. setting the alpha value to 0 of each pixel covered by the non-transparent pixels of the moon.
The blending function of the LayerColor means that it will only draw where the alpha value of a pixel is not 0, e.g. the hole cut in the first step.
The blending function of the second moon means it will draw where the alpha value of a sprite is 0, e.g. the hole. Because the second moon is in front of the darkening layer, it will fill in the hole with the undarkened moon.