zoukankan      html  css  js  c++  java
  • 【cocos2dx开发技巧8】自定义控件-使自定义控件具有RGBA特性

    转发,请保持地址:http://blog.csdn.net/stalendp/article/details/9948545

    虽然CCNodeRGBA,CCLayerRGBA,sprite等提供颜色和透明度的设置,但有时候要自定义控件,要自己去实现那些功能。比如,我要扩充一个CCSpriteBatchNode,同时要要具有颜色和透明度的设置,这个时候就需要自己动手了。

    其实为自己的控件添加RGBA特性并不是很难,只要继承CCRGBAProtocol,然后把CCNodeRGBA的实现方案贴到新加的类中就可以了。不过这样不便于代码的重用,所以我在改造代码的过程中使用了“适配器设计模式”。 这也是这片文章要介绍的一点。

    贴上我的设配器类:MyRGBAProtocolAdapter

    class MyRGBAProtocolAdapter: public CCRGBAProtocol {
    protected:
    	GLubyte		_displayedOpacity, _realOpacity;
    	ccColor3B	_displayedColor, _realColor;
    	bool		_cascadeOpacityEnabled, _cascadeColorEnabled;
    protected:
    	virtual CCArray* getRGBAChildren() = 0;
    	virtual CCNode* getRGBAParent() = 0;
    	
    public:
    	MyRGBAProtocolAdapter() :
    	_cascadeColorEnabled(true),
    	_cascadeOpacityEnabled(true),
    	_displayedOpacity(255),
    	_realOpacity(255),
    	_displayedColor(ccc3(255, 255, 255)),
    	_realColor(ccc3(255, 255, 255)) {
    		
    	}
    	
    	virtual void setColor(const ccColor3B& color) {
    		_displayedColor = _realColor = color;
    		
    		if (_cascadeColorEnabled)
    		{
    			ccColor3B parentColor = ccWHITE;
    			CCRGBAProtocol *parent = dynamic_cast<CCRGBAProtocol*>(getRGBAParent());
    			if (parent && parent->isCascadeColorEnabled())
    			{
    				parentColor = parent->getDisplayedColor();
    			}
    			
    			updateDisplayedColor(parentColor);
    		}
    	}
    	
        virtual const ccColor3B& getColor(void) {
    		return _realColor;
    	}
    	
        virtual const ccColor3B& getDisplayedColor(void) {
    		return _displayedColor;
    	}
    	
        virtual GLubyte getDisplayedOpacity(void) {
    		return _displayedOpacity;
    	}
    	
        virtual GLubyte getOpacity(void) {
    		return _realOpacity;
    	}
        
        virtual void setOpacity(GLubyte opacity) {
    		_displayedOpacity = _realOpacity = opacity;
    		
    		if (_cascadeOpacityEnabled)
    		{
    			GLubyte parentOpacity = 255;
    			CCRGBAProtocol* pParent = dynamic_cast<CCRGBAProtocol*>(getRGBAParent());
    			if (pParent && pParent->isCascadeOpacityEnabled())
    			{
    				parentOpacity = pParent->getDisplayedOpacity();
    			}
    			this->updateDisplayedOpacity(parentOpacity);
    		}
    	}
    	
        virtual void setOpacityModifyRGB(bool bValue) {
    	}
    	
        virtual bool isOpacityModifyRGB(void) {
    		return false;
    	}
    	
        virtual bool isCascadeColorEnabled(void) {
    		return _cascadeColorEnabled;
    	}
    	
        virtual void setCascadeColorEnabled(bool cascadeColorEnabled) {
    		_cascadeColorEnabled = cascadeColorEnabled;
    	}
        
        virtual void updateDisplayedColor(const ccColor3B& parentColor) {
    		_displayedColor.r = _realColor.r * parentColor.r/255.0;
    		_displayedColor.g = _realColor.g * parentColor.g/255.0;
    		_displayedColor.b = _realColor.b * parentColor.b/255.0;
    		
    		if (_cascadeColorEnabled)
    		{
    			CCObject *obj = NULL;
    			CCARRAY_FOREACH(getRGBAChildren(), obj)
    			{
    				CCRGBAProtocol *item = dynamic_cast<CCRGBAProtocol*>(obj);
    				if (item)
    				{
    					item->updateDisplayedColor(_displayedColor);
    				}
    			}
    		}
    	}
        
        virtual bool isCascadeOpacityEnabled(void) {
    		return _cascadeOpacityEnabled;
    	}
    	
        virtual void setCascadeOpacityEnabled(bool cascadeOpacityEnabled) {
    		_cascadeOpacityEnabled = cascadeOpacityEnabled;
    	}
    	
        virtual void updateDisplayedOpacity(GLubyte parentOpacity) {
    		_displayedOpacity = _realOpacity * parentOpacity/255.0;
    		
    		if (_cascadeOpacityEnabled)
    		{
    			CCObject* pObj;
    			CCARRAY_FOREACH(getRGBAChildren(), pObj)
    			{
    				CCRGBAProtocol* item = dynamic_cast<CCRGBAProtocol*>(pObj);
    				if (item)
    				{
    					item->updateDisplayedOpacity(_displayedOpacity);
    				}
    			}
    		}
    	}
    };
    


    注意到,其实MyRGBAProtocolAdapter类是一个抽象类,下面的两个方法是要被子类实现的:

    	virtual CCArray* getRGBAChildren() = 0;
    	virtual CCNode* getRGBAParent() = 0;


    虽然多继承不好,不过我这里还是使用了,下面是我的实现类:

    /**
     可以改变颜色和透明度的 Sprite batch Node
     **/
    
    #define BBB_AIM_DU 0.3
     
    class BBBatch : public CCSpriteBatchNode, public MyRGBAProtocolAdapter { // 1)继承MyRGBAProtocolAdapter
    public:
    	static BBBatch* create(const char* fileImage, unsigned int capacity) {
    		BBBatch *batchNode = new BBBatch();
    		if (batchNode && batchNode->initWithFile(fileImage, capacity)) {
    			batchNode->autorelease();
    			return batchNode;
    		}
    		CC_SAFE_DELETE(batchNode);
    		return NULL;
    	}
    	
    	void dark() {
    		runAction(CCTintTo::create(BBB_AIM_DU, 150, 150, 150));
    		runAction(CCFadeTo::create(BBB_AIM_DU, 255*0.6));
    	}
    	
    	void normal() {
    		runAction(CCTintTo::create(BBB_AIM_DU, 255, 255, 255));
    		runAction(CCFadeTo::create(BBB_AIM_DU, 255));
    	}
    	//2)下面将实现两个抽象类
    	// ========= MyRGBAProtocolAdapter begin ============ 
    	CCArray* getRGBAChildren() {
    		return getChildren();
    	}
    	CCNode* getRGBAParent() {
    		return getParent();
    	}
    	// ========= MyRGBAProtocolAdapter end ============
    };

    这样就可以简单方便地把RGBA特性添加到自定义类中了。

  • 相关阅读:
    【BZOJ 4151 The Cave】
    【POJ 3080 Blue Jeans】
    【ZBH选讲·树变环】
    【ZBH选讲·拍照】
    【ZBH选讲·模数和】
    【CF Edu 28 C. Four Segments】
    【CF Edu 28 A. Curriculum Vitae】
    【CF Edu 28 B. Math Show】
    【CF Round 439 E. The Untended Antiquity】
    【CF Round 439 C. The Intriguing Obsession】
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3255895.html
Copyright © 2011-2022 走看看