Question

I am trying to figure out how to fade the layer and its children to a given opacity. This is what I am doing.

    - (id)init
    {

        if( (self=[super initWithColor:ccc4(0, 0, 255, 255)] )) {

            CCSprite *background = [CCSprite spriteWithFile:@"LevelsBackGround.png"];
            background.position = ccp([UIScreen mainScreen].bounds.size.height * .5f ,160);
            [self addChild:background];

            CCSprite *text = [CCSprite spriteWithFile:@"SwipeText.png"];
            text.position = ccp([UIScreen mainScreen].bounds.size.height *.5, 17);
            [self addChild:text];


            sceneText = [CCLabelTTF labelWithString:@"Yard" fontName:@"Baskerville-Bold" fontSize:20];
            sceneText.position = ccp([UIScreen mainScreen].bounds.size.height *.5, 300);
            sceneText.color = ccc3(172, 169, 164);
            [self addChild:sceneText];

        [self performSelector:@selector(LaunchLevel:) withObject:nil afterDelay:2.f];

}
    - (void ) LaunchLevel: (id) sender {

        [self runAction:[CCFadeTo actionWithDuration:.5 opacity:127]];
    }

But this doesn't seem to do anything. If I remove the background sprite in order to see the blue color that I have the layer set to and then build it, then the blue background gets faded exactly as it should. So my question is, why is it not working to fade out all of the layers children?

Was it helpful?

Solution 3

The opacity property does not get propagated to the children. If you want , you can override the setOpacity method :

// in your .h file, an iVar 

GLubyte _opacity;

// in you .m, the overrides

- (void)setOpacity:(GLubyte)opacity {

    for (id child in self.children) {
        id <CCRGBAProtocol> opaqueChild = (id <CCRGBAProtocol>) child;
        if ([opaqueChild respondsToSelector:@selector(setOpacity:)]) {
            opaqueChild.opacity = opacity;
        } else {
            // you must decide here what to do for your own situation
            // and the children you are likely to have in there
        }
    }
    _opacity = opacity;
}

- (GLubyte)opacity {
    return _opacity;
}

edit : extending a CCLayerColor (this compiles, have not actually tested it, but should work). Just add this in your .m file (the implementation for your class) :

- (void)setOpacity:(GLubyte)opacity {

    for (id child in self.children) {
        id <CCRGBAProtocol> opaqueChild = (id <CCRGBAProtocol>) child;
        if ([opaqueChild respondsToSelector:@selector(setOpacity:)]) {
            opaqueChild.opacity = opacity;
        } else {
            // you must decide here what to do for your own situation
            // and the children you are likely to have in there
        }
    }
    [super setOpacity:opacity];
}

OTHER TIPS

As of Cocos2d-x v3-ish (I'm using v3.4); If you're adding several Sprites to a Layer you can now set a flag on the layer to indicate that opacity should be cascaded down to its respective children with the following command:

local layer = cc.Layer:create()
layer:addChild(cc.Sprite("hero-dude.png"))
layer:setCascadeOpacityEnabled(true)
layer:runAction(cc.FadeTo:create(0.5, 127))

Setting recursively the opacity of the children does not render very well ("opacity overlapping" effect).

If you want to fade a whole hierarchy of nodes "as a whole", you can use CCRenderTexture (to render your node graph and fade it as a single image).

And if your children are somehow animated you need to update your CCRenderTexture frequently (quite CPU-costly).

More details here: http://2sa-studio.blogspot.com/2013/01/fading-node-hierarchy-with.html

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top