【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 opencv3 静态图片检测人脸
git:https://github.com/linyi0604/Computer-Vision # coding:utf-8 import cv2 filename = "../data/ ...
- 【转】高效率编辑器VIM
最近实习的时候需要在服务器上做Debug,不得不用到vim的相关操作.以前对vim这种被码农无数赞扬的神器望而却步,但今天试了之后感觉还是不错的.以后争取少用鼠标,少用insert模式. 这是从网上看 ...
- luoguP5108 仰望半月的夜空 [官方?]题解 后缀数组 / 后缀树 / 后缀自动机 + 线段树 / st表 + 二分
仰望半月的夜空 题解 可以的话,支持一下原作吧... 这道题数据很弱..... 因此各种乱搞估计都是能过的.... 算法一 暴力长度然后判断判断,复杂度\(O(n^3)\) 期望得分15分 算法二 通 ...
- CF893F Subtree Minimum Query 主席树
如果是求和就很好做了... 不是求和也无伤大雅.... 一维太难限制条件了,考虑二维限制 一维$dfs$序,一维$dep$序 询问$(x, k)$对应着在$dfs$上查$[dfn[x], dfn[x] ...
- [POI2000]病毒 --- AC自动机
[POI2000]病毒 题目描述: 二进制病毒审查委员会最近发现了如下的规律: 某些确定的二进制串是病毒的代码. 如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的. 现在委员会已经找 ...
- 【状压dp】Petrozavodsk Winter Training Camp 2018 Day 1: Jagiellonian U Contest, Tuesday, January 30, 2018 Problem E. Guessing Game
题意:给你n个两两不同的零一串,Alice在其中选定一个,Bob去猜,每次询问某一位是0 or 1.问你最坏情况下最少要猜几次. f(22...2)表示当前状态的最小步数,2表示这位没确定,1表示确定 ...
- N!(N的阶乘)最末位非0的求解方法
问题是求关于N!的最后一位非0位, 如3!=6,最后一位非0位为6, 5!=120, 最后一位非0位为2.怎么样快速的求出最后一位非0位呢? 最朴素的想法就是先求出N!的结果,再求出结果的最后一位非0 ...
- tsinsen A1333
可以用二维树状数组套值域线段树来做,复杂度:O( (n*n+q) * logn logn log10^9 ) 但作为作为整体二分的例题,还是用整体二分来写了一下.对整体二分有一点感觉了. 整体二分,顾 ...
- ZOJ 3235 Prototype
Prototype Time Limit: 1 Second Memory Limit: 32768 KB Prototype is a 3D game which allow you to ...
- 【bzoj2005】 [Noi2010]能量采集 数学结论(gcd)
[bzoj2005] [Noi2010]能量采集 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnli ...