• 【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特性添加到自定义类中了。

  • 相关阅读:
    四则运算
    自我介绍
    代练第七天
    代练第六天
    代练第五天
    代练第四天
    补充总结
    对软件工程课程的总结
    作业4:结对编程项目四则运算
    psp记录个人项目花费时间
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3255895.html
Copyright © 2020-2023  润新知