【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特性添加到自定义类中了。
【cocos2dx开发技巧8】自定义控件-使自定义控件具有RGBA特性的更多相关文章
- 【cocos2dx开发技巧10】cocosStudio的集成以及c++11的新特性
转发.请保持地址:http://blog.csdn.net/stalendp/article/details/38880997 非常长时间没有碰cocos2dx了,近期又用起来了.花了好几个小时又一次 ...
- Android开发技巧——自定义控件之组合控件
Android开发技巧--自定义控件之组合控件 我准备在接下来一段时间,写一系列有关Android自定义控件的博客,包括如何进行各种自定义,并分享一下我所知道的其中的技巧,注意点等. 还是那句老话,尽 ...
- Android开发技巧——自定义控件之增加状态
Android开发技巧--自定义控件之增加状态 题外话 这篇本该是上周四或上周五写的,无奈太久没写博客,前几段把我的兴头都用完了,就一拖再拖,直到今天.不想把这篇拖到下个月,所以还是先硬着头皮写了. ...
- Android开发技巧——自定义控件之使用style
Android开发技巧--自定义控件之使用style 回顾 在上一篇<Android开发技巧--自定义控件之自定义属性>中,我讲到了如何定义属性以及在自定义控件中获取这些属性的值,也提到了 ...
- Android开发技巧——自定义控件之自定义属性
Android开发技巧--自定义控件之自定义属性 掌握自定义控件是很重要的,因为通过自定义控件,能够:解决UI问题,优化布局性能,简化布局代码. 上一篇讲了如何通过xml把几个控件组织起来,并继承某个 ...
- Android开发技巧——写一个StepView
在我们的应用开发中,有些业务流程会涉及到多个步骤,或者是多个状态的转化,因此,会需要有相关的设计来展示该业务流程.比如<停车王>应用里的添加车牌的步骤. 通常,我们会把这类控件称为&quo ...
- 【转】几点 iOS 开发技巧
[译] 几点 iOS 开发技巧 原文:iOS Programming Architecture and Design Guidelines 原文来自破船的分享 原文作者是开发界中知晓度相当高的 Mug ...
- Android开发技巧——实现可复用的ActionSheet菜单
在上一篇<Android开发技巧--使用Dialog实现仿QQ的ActionSheet菜单>中,讲了这种菜单的实现过程,接下来将把它改成一个可复用的控件库. 本文原创,转载请注明出处: h ...
- Android开发技巧——高亮的用户操作指南
Android开发技巧--高亮的用户操作指南 2015-12-15补记: 发现使用PopupWindow进行遮罩层的显示,在华为P7上会有问题.具体表现为:画出来的高亮部分会偏下.原因为:通过view ...
随机推荐
- 使用Python发送HTML格式的邮件(收到的邮件有发送方才是正解)
发送html格式的和普通文本格式差不多,只是MIMEText(content,"html","utf-8"))与MIMEText(content,"p ...
- Centos7下shell脚本添加开机自启动
添加开机自启脚本,注意都需要用绝对路径 psubscribe.sh脚本中的内容: nohup /usr/bin/php -f /data/aliyun51015cn/redisChannel/psub ...
- (Nginx) URL REWRITE
URL重写的基础介绍 把URI地址用作参数传递:URL REWRITE 最简单的是基于各种WEB服务器中的URL重写转向(Rewrite)模块的URL转换: 这样几乎可以不修改程序的实现将 news. ...
- hdu 4548 初始化+二分 *
题意:小明对数的研究比较热爱,一谈到数,脑子里就涌现出好多数的问题,今天,小明想考考你对素数的认识.问题是这样的:一个十进制数,如果是素数,而且它的各位数字和也是素数,则称之为“美素数”,如29,本身 ...
- [java][jboss]改变jboss部署目录(虚拟目录)
原文: [java][jboss]改变jboss部署目录(虚拟目录) 在开发过程中,有时候我们希望将程序放在我们的源代码目录中,比如d:\code下,而不是放在jboss的deploy下,怎么办? 我 ...
- hihocoder #1299 : 打折机票 线段树
#1299 : 打折机票 题目连接: http://hihocoder.com/problemset/problem/1299 Description 因为思念新宿的"小姐姐"们, ...
- 通过maven-war-plugin插件对war包分环境打包
针对多环节,从源头打包入手,当然这些都可以在运维阶段用脚本进行替换来代替 resources/environment/下有四个环境,local本地.dev开发.test测试.pre预上线.prod生产 ...
- oracle的dump理解
http://blog.csdn.net/notbaron/article/details/51228444 http://blog.csdn.net/lqx0405/article/details/ ...
- java对mongodb的and, in, or 经常使用操作
DBCollection dbcon = null; DBObject query = new BasicDBObject(); BasicDBList values = new BasicDBLis ...
- Delphi7下使用FastMM4
1> 将文件Replacement BorlndMM DLL/Precompiled/for Delphi IDE/Performance/BorlndMM.dll,替换掉Delphi/Bin下 ...