转发,请保持地址: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特性添加到自定义类中了。

【cocos2dx开发技巧8】自定义控件-使自定义控件具有RGBA特性的更多相关文章

  1. 【cocos2dx开发技巧10】cocosStudio的集成以及c++11的新特性

    转发.请保持地址:http://blog.csdn.net/stalendp/article/details/38880997 非常长时间没有碰cocos2dx了,近期又用起来了.花了好几个小时又一次 ...

  2. Android开发技巧——自定义控件之组合控件

    Android开发技巧--自定义控件之组合控件 我准备在接下来一段时间,写一系列有关Android自定义控件的博客,包括如何进行各种自定义,并分享一下我所知道的其中的技巧,注意点等. 还是那句老话,尽 ...

  3. Android开发技巧——自定义控件之增加状态

    Android开发技巧--自定义控件之增加状态 题外话 这篇本该是上周四或上周五写的,无奈太久没写博客,前几段把我的兴头都用完了,就一拖再拖,直到今天.不想把这篇拖到下个月,所以还是先硬着头皮写了. ...

  4. Android开发技巧——自定义控件之使用style

    Android开发技巧--自定义控件之使用style 回顾 在上一篇<Android开发技巧--自定义控件之自定义属性>中,我讲到了如何定义属性以及在自定义控件中获取这些属性的值,也提到了 ...

  5. Android开发技巧——自定义控件之自定义属性

    Android开发技巧--自定义控件之自定义属性 掌握自定义控件是很重要的,因为通过自定义控件,能够:解决UI问题,优化布局性能,简化布局代码. 上一篇讲了如何通过xml把几个控件组织起来,并继承某个 ...

  6. Android开发技巧——写一个StepView

    在我们的应用开发中,有些业务流程会涉及到多个步骤,或者是多个状态的转化,因此,会需要有相关的设计来展示该业务流程.比如<停车王>应用里的添加车牌的步骤. 通常,我们会把这类控件称为&quo ...

  7. 【转】几点 iOS 开发技巧

    [译] 几点 iOS 开发技巧 原文:iOS Programming Architecture and Design Guidelines 原文来自破船的分享 原文作者是开发界中知晓度相当高的 Mug ...

  8. Android开发技巧——实现可复用的ActionSheet菜单

    在上一篇<Android开发技巧--使用Dialog实现仿QQ的ActionSheet菜单>中,讲了这种菜单的实现过程,接下来将把它改成一个可复用的控件库. 本文原创,转载请注明出处: h ...

  9. Android开发技巧——高亮的用户操作指南

    Android开发技巧--高亮的用户操作指南 2015-12-15补记: 发现使用PopupWindow进行遮罩层的显示,在华为P7上会有问题.具体表现为:画出来的高亮部分会偏下.原因为:通过view ...

随机推荐

  1. C#中的特性 (Attribute) 入门 (一)

    C#中的特性 (Attribute) 入门 (一) 饮水思源 http://www.cnblogs.com/Wind-Eagle/archive/2008/12/10/1351746.html htt ...

  2. 1012 The Best Rank (25)(25 point(s))

    problem To evaluate the performance of our first year CS majored students, we consider their grades ...

  3. python opencv3 视频文件的读写

    git: https://github.com/linyi0604/Computer-Vision # coding:utf8 import cv2 """ 读取视频文件 ...

  4. 数据准备<4>:变量筛选-理论篇

    在上一篇文章<数据准备<3>:数据预处理>中,我们提到降维主要包括两种方式:基于特征选择的降维和基于维度转换的降维,其中基于特征选择的降维通俗的讲就是特征筛选或者变量筛选,是指 ...

  5. bzoj 3837 (随机过题法了解一下)

    3837: [Pa2013]Filary Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 395  Solved: 74[Submit][Status] ...

  6. Git_Bug分支

    软件开发中,bug就像家常便饭一样.有了bug就需要修复,在Git中,由于分支是如此的强大,所以,每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除. 当你接到一个修复一 ...

  7. 解决 git push Failed to connect to 127.0.0.1 port 45463: 拒绝连接

    使用Github pull 代码突然报错: Failed to connect to 127.0.0.1 port 43421: Connection refused 使用 lsof 发现端口未被占用 ...

  8. windows的磁盘操作之九——区分本地磁盘与移动硬盘

    http://cutebunny.blog.51cto.com/301216/674443 最近碰到了个新问题,记录下来作为windows的磁盘操作那个系列的续篇吧. 一些时候我们的程序需要区分本地存 ...

  9. vs2017与docker

    基本需求 系统 win10 vs2017 docker 步骤 1.开启系统的hyper-v 2. 重启电脑 3.安装docker 下载地址:https://docs.docker.com/docker ...

  10. Microsoft Composition (MEF 2)

    This packages provides a version of the Managed Extensibility Framework (MEF) that is lightweight an ...