在引擎中提供了几个有关透明度变化的动作:CCFadeIn,CCFadeOut,CCFadeTo

CCFadeIn:the opacity from 0 to 255

CCFadeOut:the opacity from 255 to 0

CCFadeTo: from the current value to a custom one

   下面简单记录一下我所遇到的一些问题:


问题一:父Sprite执行fade动作,子Sprite不执行问题

看到下面的代码:


1. CCSize winSize = CCDirector::sharedDirector()->getWinSize();  
2. "HelloWorld.png");  
3.     bgSprite->setPosition(ccp(winSize.width/2, winSize.height/2));  
4. this->addChild(bgSprite);  
5.       
6. "Icon.png");  
7.     sprite->setPosition(ccp(200, 200));  
8.     bgSprite->addChild(sprite);  
9.       
10.     CCFadeOut* fadeout = CCFadeOut::create(1);  
11.     bgSprite->runAction(fadeout);


分析:这里面的父sprite添加了一个子sprite,那么当父sprite执行fade out的动作,子sprite也是要一样执行fade out这个动作的,但是实际运行结果是,只有父sprite执行了这个动作,子sprite并没有执行。

那么这个问题如何解决呢? ---  一个最笨的方法就是 去getChildren() 然后每一个子sprite再去执行这个动作。


那么,还有其他方法吗?

--有的。我们可以用 setCascadeOpacityEnabled 这个方法。

在 CCRGBAProtocol 类定义了这个方法:






1. /** 
2.      *  whether or not opacity should be propagated to its children.
3.      */  
4. virtual bool isCascadeOpacityEnabled(void) = 0;  
5. virtual void setCascadeOpacityEnabled(bool cascadeOpacityEnabled) = 0;



看到注释就知道是神马作用了,当设置为true的时候,父sprite执行opacity的变化,子sprite也同样会执行到这个变化。

再具体看看:




1. void CCNodeRGBA::setCascadeOpacityEnabled(bool cascadeOpacityEnabled)  
2. {  
3.     _cascadeOpacityEnabled = cascadeOpacityEnabled;  
4. }




    1. virtual void updateDisplayedOpacity(GLubyte opacity) = 0;




      1. void CCNodeRGBA::updateDisplayedOpacity(GLubyte parentOpacity)  
      2. {  
      3.     _displayedOpacity = _realOpacity * parentOpacity/255.0;  
      4.       
      5. if (_cascadeOpacityEnabled)  
      6.     {  
      7.         CCObject* pObj;  
      8.         CCARRAY_FOREACH(m_pChildren, pObj)  
      9.         {  
      10. dynamic_cast<CCRGBAProtocol*>(pObj);  
      11. if (item)  
      12.             {  
      13.                 item->updateDisplayedOpacity(_displayedOpacity);  
      14.             }  
      15.         }  
      16.     }  
      17. }



      同样的,在这个类中还有这个方法:



      1. /**
      2.      *  whether or not color should be propagated to its children.
      3.      */  
      4. virtual bool isCascadeColorEnabled(void) = 0;  
      5. virtual void setCascadeColorEnabled(bool cascadeColorEnabled) = 0;

      显然就是为了在父sprite执行颜色变化的时候,子sprite也可以执行到这个变化。


      回到上面的代码例子,添加: bgSprite->setCascadeOpacityEnabled(true);  这条语句就没有问题了。


      问题二:自定义的sprite执行 CCFade~ 的问题

      我自定义了一个sprite类:在这个自定义的精灵内部又添加了两个子sprite。



      1. SelectedBoxSprite* SelectedBoxSprite::createWithPic(const char *name)  
      2. {  
      3. new SelectedBoxSprite();  
      4. if (pobView && pobView->initWithFile(name) && pobView->setUpdateView()) {  
      5.         pobView->autorelease();  
      6. return pobView;  
      7.     }  
      8.     CC_SAFE_DELETE(pobView);  
      9. return NULL;  
      10. }  
      11.   
      12. bool SelectedBoxSprite::setUpdateView()  
      13. {  
      14. bool isRet = false;  
      15. do {  
      16. this->setCascadeOpacityEnabled(true);  
      17.           
      18. "yellow.png");  
      19.         spr1->setAnchorPoint(CCPointZero);  
      20.         spr1->setTag(1);  
      21.         spr1->setPosition(ccp(0, 4));  
      22. this->addChild(spr1);  
      23.           
      24.         listSpriteArray->addObject(spr1);  
      25.   
      26. "yellow_1.png");  
      27.         spr2->setAnchorPoint(CCPointZero);  
      28.         spr2->setTag(2);  
      29.         spr2->setPosition(ccp(0, 30));  
      30. this->addChild(spr2);  
      31.           
      32.         listSpriteArray->addObject(spr2);  
      33.           
      34. true;  
      35. while (0);  
      36. return isRet;  
      37. }




      我创建了这样的一个实例,想要执行CCFadeIn这个动作



      1. SelectedBoxSprite* selectBoxSprite = SelectedBoxSprite::createWithPic("list_box.png");  
      2.     selectBoxSprite->setAnchorPoint(ccp(0.5, 0.5));  
      3.     selectBoxSprite->setPosition(ccp(300, 305));  
      4.     selectBoxSprite->setTag(2);  
      5. this->addChild(selectBoxSprite,1);  
      6.       
      7.     CCFadeIn* fadein = CCFadeIn::create(1);  
      8.     selectBoxSprite->runAction(fadein);



      但是,发现有问题,就是这个自定义sprite里面的两个子sprite不会执行这个fade in动作



      那么这么办呢?

      那我就想 CCFadeOut 也会不会有这个问题呢


      1. CCFadeOut* fadeout = CCFadeOut::create(1);  
      2. selectBoxSprite->runAction(fadeout);

      发现没有问题,这个自定义的sprite会fade out;


      同样我又试了一下 CCFadeTo ,同样也是没有问题



      1. CCFadeTo* fadeto = CCFadeTo::create(1, 0);  
      2. selectBoxSprite->runAction(fadeto);

      这个时候,我冷静下来看看代码,发现原来 在fade in之前没有 将这个精灵的opacity设置为 0 



      1. //这个很重要,不要忘了  
      2.     selectBoxSprite->setOpacity(0);  
      3.       
      4.     CCFadeIn* fadein = CCFadeIn::create(1);  
      5.     selectBoxSprite->runAction(fadein);


      这样发现运行就正常了,里面的两个子sprite也会运行了。