2014年4月3日星期四

Cocos2dx 半透明遮罩 ,UI震动效果,渐变场景过度

 

    在《三勇者传说》(暂定名)的开发过程中,我遇到了一些小问题,这里记录下来,以便之后查阅以及他人分享建议。

    首先是最常见的场景渐变,cocos2dx自身有一定数量的场景渐变效果,原本无需做太多说明,不过既然算是一种小伎俩,这里也备注一下。
  1. CCScene* pLoginScene = CLoginScene::scene(); 
  2. if( pLoginScene ) 
  3. {
  4.     float fTime = 1.5f; 
  5.     CCTransitionScene * pTransScene = CCTransitionFade ::create( fTime , pLoginScene ); 
  6.     CCDirector::sharedDirector()->replaceScene( pTransScene ); 
  7. }
    然后是半透明遮罩,这在游戏需要进行暂停时,以及弹出信息窗口时非常常用。


ShadeLayer.h

  1. #pragma once
  2. //--------------------------------------------------------------------
  3. #include "CommonHead.h"
  4. //--------------------------------------------------------------------
  5. class CShadeLayer : public CCLayer 
  6. {
  7. public:
  8. static CShadeLayer* create( CCLayer* p_pUILayer );
  9. bool init( CCLayer* p_pUILayer );
  10. private:
  11. void MenuCallback(CCObject* pSender){}
  12. };
ShadeLayer.cpp

  1. #include "ShadeLayer.h"

  2. //--------------------------------------------------------------------
  3. CShadeLayer* CShadeLayer::create( CCLayer* p_pUILayer )
  4. {
  5. CShadeLayer* pLayer = new CShadeLayer;
  6. if( pLayer && pLayer->init( p_pUILayer ) )
  7. {
  8. pLayer->autorelease();
  9. return pLayer;
  10. }
  11. else
  12. {
  13. delete pLayer;
  14. pLayer = NULL;
  15. return NULL;
  16. }
  17. }
  18. //--------------------------------------------------------------------
  19. bool CShadeLayer::init( CCLayer* p_pUILayer )
  20. {
  21. bool bRet = false;

  22. do 
  23. {
  24. CC_BREAK_IF(!CCLayer::init());
  25. CCAssert( p_pUILayer, "p_pUILayer == NULL!");

  26. CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
  27. CCLayerColor* layerColor = CCLayerColor::create();
  28. layerColor->setColor(ccc3(0, 0, 0));
  29. layerColor->setOpacity(150);
  30. layerColor->setContentSize(CCSizeMake(visibleSize.width, visibleSize.height));
  31. this->addChild(layerColor);

  32. CCMenuItemImage* item = CCMenuItemImage::create();
  33. item->setContentSize(CCSizeMake(visibleSize.width, visibleSize.height));
  34. item->initWithTarget(this, menu_selector(CShadeLayer::MenuCallback));
  35. CCMenu* menu = CCMenu::create(item, NULL);
  36. menu->setTouchPriority( SHADER_LAYER_TOUCH_PRIORITY );
  37. this->addChild(menu);

  38. this->setTag( SHADE_LAYER_TAG );

  39. bRet = true;
  40. } while (0);

  41. return bRet;
  42. }
  43. //--------------------------------------------------------------------
    我们上面的代码是使用一个巨大的CCMenu去截获消息,虽然方法不传统,但是的确高效。如果使用传统的建议方式,Layer设置接收消息并重载消息回调四个函数,这个方法也行的通,但是代价较高,性能上也无优化,并不划算。注意的是,里面的宏 SHADER_LAYER_TOUCH_PRIORITY 必须小于UI默认的消息级别 -128,建议为-129.那么我们假如在这个遮罩层上放置新的UI或者Layer一定注意将新的UI消息级别高于这个 SHADER_LAYER_TOUCH_PRIORITY,即建议为-130以下。
    它的调用方式如下:
    1. // 在某个Scene中添加遮罩层
    2. this->addChild( CShadeLayer::create(this), 100 );
        最后,记录一下UI显示时的震动效果。我们通常显示一个UI,并不希望它突然就出现在屏幕上,而是经过一个极短的动画过程再显示。我这里介绍一种震动效果。代码如下:

      1. CCAction* shakeAction = CCSequence::create(CCScaleTo::create(0.0, 0.0),
      2. CCScaleTo::create(0.12, 1.08),
      3. CCScaleTo::create(0.10, 0.92),
      4. CCScaleTo::create(0.10, 1.04),
      5. CCScaleTo::create(0.10, 0.96),
      6. CCScaleTo::create(0.10, 1.0), NULL);

      7. // 增加UI层
      8. CUIPanelLayer* pLayer = CUIPanelLayer::create();
      9. if( pLayer )
      10. {
      11. pLayer ->runAction( shakeAction );
      12. this->addChild( pLayer );
      13. }
          这样就模拟形成了一个震动显示的UI效果。
          今天就记录到这里,欢迎讨论~

      没有评论:

      发表评论