Stephen
Stephen

Reputation: 499

How to fade a CCLayerColor and it's children to a given opacity? Cocos2d

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?

Upvotes: 0

Views: 3470

Answers (3)

PeqNP
PeqNP

Reputation: 1361

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))

Upvotes: 4

sdabet
sdabet

Reputation: 18670

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

Upvotes: 3

YvesLeBorg
YvesLeBorg

Reputation: 9089

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];
}

Upvotes: 2

Related Questions