[cocos2dx] 让UIButton支持disable状态
摘要: 主要解决cocos2dx-2.2.2版本中, UIButton显示不了disable状态图的问题. 顺便, 理解了一下cocos2dx中UIWidget的渲染原理.
- 博客: http://www.cnblogs.com/jhzhu
- 邮箱: jhzhuustc@gmail.com
- 作者: 知明所以
- 时间: 2014-03-23
发现问题
在cocostudio中添加一个UIButton组件, 我们可以看到通常以一下按钮的三态:normal,pressed,disable. 但是,当我们设置了disable状态之后, 在我们的游戏项目中, 对某个按钮执行button->setEnable(false)后, 按钮居然完全不见了?!
解决方法
修改
Widget::visit()方法, 改为:void Widget::visit()
{
CCNodeRGBA::visit();
}即, 删除
if判断.修改
Widget::setEnable()方法, 改为:void Widget::setEnabled(bool enabled)
{
_enabled = enabled;
if(_widgetChildren && _widgetChildren->count() > 0)
{
CCObject* child;
CCARRAY_FOREACH(_widgetChildren, child)
{
((Widget*)child)->setEnabled(enabled);
}
}
setBright( enabled );//增加此行
}即, 增加
setBright( enabled );行.
如果想知其所以然的, 下面是解释.
解释
Widget的诡异渲染
Widget::visit()的实现如下:
void Widget::visit()
{
if (_enabled)
{
CCNodeRGBA::visit();
}
}
如果您没时间仔细看过cocos2dx的源码, 这里可以有一个简单的解释:
1. visit()方法最初是从CCNode继承过来的. 也就是说任何显示对象都有这个方法.
2. CCNode::visit()就是CCNode的渲染函数, 是视图渲染中最重要的一个函数, 跟IOS开发中的UIView::draw()功能类似. 框架在每一帧都会调用这个方法, 而这个方法负责当前组件的openGL绘制. 我们可以看下CCNode::visit()的实现来作为验证:
void CCNode::visit()
{
...
this->draw();
...
}
//算了, 这段代码有点长, 有些人时间比较宝贵可能没兴趣看. 我就放在***附录***了.(*^__^*)
看到这里, 你肯定一经发现问题了: 为什么只有在_enabled为true的时候才渲染?难道不是坑爹么?disable状态就不理了么?
可能cocos2dx另有打算, 我没理解清楚. 不过这个功能既然不符合我的要求, 我就果断的把那个if去掉了. (谁让咱们是程序员呢?).
但是, 问题并没有完全结束. 还是没有显示disable状态.
Widget的enable?
UIButton::setEnable()方法比较短, 贴出来看看.
void Widget::setEnabled(bool enabled)
{
_enabled = enabled;
if(_widgetChildren && _widgetChildren->count() > 0)
{
CCObject* child;
CCARRAY_FOREACH(_widgetChildren, child)
{
((Widget*)child)->setEnabled(enabled);
}
}
}
发现这段代码除了把_enable和所有孩子的_enable状态设为false, 没做任何事情. 通过查看widget的代码, 很容易看到, widget的三态是通过下面的是三个函数实现的:
void Widget::onPressStateChangedToNormal(){}
void Widget::onPressStateChangedToPressed(){}
void Widget::onPressStateChangedToDisabled(){}
不错,他们都是空函数.子类根据需要来实现这三个函数.
下面是setBright的实现:
void Widget::setBright(bool bright)
{
_bright = bright;
if (_bright)
{
_brightStyle = BRIGHT_NONE;
setBrightStyle(BRIGHT_NORMAL);
}
else
{
onPressStateChangedToDisabled();
}
}
由上代码可以看出. 而我们调用setBright(false), 即可根据widget当前的状态, 渲染不同的图像.
附录
代码片段一CCNode::visit()
void CCNode::visit()
{
// quick return if not visible. children won't be drawn.
if (!m_bVisible)
{
return;
}
kmGLPushMatrix();
if (m_pGrid && m_pGrid->isActive())
{
m_pGrid->beforeDraw();
}
this->transform();
CCNode* pNode = NULL;
unsigned int i = 0;
if(m_pChildren && m_pChildren->count() > 0)
{
sortAllChildren();
// draw children zOrder < 0
ccArray *arrayData = m_pChildren->data;
for( ; i < arrayData->num; i++ )
{
pNode = (CCNode*) arrayData->arr[i];
if ( pNode && pNode->m_nZOrder < 0 )
{
pNode->visit();
}
else
{
break;
}
}
// self draw
this->draw();
for( ; i < arrayData->num; i++ )
{
pNode = (CCNode*) arrayData->arr[i];
if (pNode)
{
pNode->visit();
}
}
}
else
{
this->draw();
}
// reset for next frame
m_uOrderOfArrival = 0;
if (m_pGrid && m_pGrid->isActive())
{
m_pGrid->afterDraw(this);
}
kmGLPopMatrix();
}
Written with StackEdit.
[cocos2dx] 让UIButton支持disable状态的更多相关文章
- [cocos2dx]让CCScrollView支持分页
[cocos2dx]让CCScrollView支持分页 做过IOS开发的朋友, 肯定知道UIScrollView有一个isPaged属性. 当设置其为true的时候, 滑动会自动分页. 即, 每次滑动 ...
- UICollectionViewCell选中高亮状态和UIButton的高亮状态和选中状态
UICollectionViewCell选中高亮状态 //设置点击高亮和非高亮效果! - (BOOL)collectionView:(UICollectionView *)collectionView ...
- AndroidTips:selector的disable状态为什么无效?
正确的姿势: <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android=& ...
- UIButton在Disabled状态下标题混乱的问题
最近开发中遇到的问题汇总 有段时间没有归纳开发中遇到的一些问题了,今天就写一下之前开发中遇到的几个问题.希望这 篇文章能让读者在以后的开发中少走弯路.本文将依次介绍<UIButton在Disab ...
- 移动开发之浅析cocos2d-x的中文支持问题
题记:这阵子一直在学习cocos2d-x,其跨平台的特性确实让人舒爽,引擎的框架概念也很成熟,虽然相应的第三方工具略显单薄,但也无愧是一件移动开发的利器啊,有兴趣的朋友有时间就多了解吧. 使用引擎的过 ...
- 求解: Windows Phone XAML Controls 为什么是disable状态?
问题 : 我在做一个windows phone 的App,显示一个web 返回来的data,现在想用控件ListView 去绑定这个Data,但是 为何我的VS2012 中的 ToolBox 的XAM ...
- js判断元素是否是disable状态
js判断元素是否是disable状态 jquery判断元素状态用$(select).prop(属性值) == true js判断button是否可以点击: //判断button是否为不可点击状态 if ...
- 我的Android进阶之旅------>Android中StateListDrawable支持的状态
Android中StateListDrawable支持的状态 android:state_active 代表是否处于激活状态 android:state_checked 代表是否处于已勾选状态 an ...
- UIButton在不同状态下显示不同背景色
参考自:原文地址(内容与原文并无区别,只是自己以后方便使用整理了一下) 1.UIButton的background是不支持在针对不同的状态显示不同的颜色. 2.UIButton的backgroundI ...
随机推荐
- 从零开始学习Linux(ls命令)
学习Linux已经两年了,可是仍然是小白一个.用过很多命令,可是很多都没记住,基础不扎实,很大程度上是不记笔记,得过且过. 从今天起,开始整理Linux笔记. Linux每个命令都有--help这个选 ...
- j2ee分布式缓存同步实现方案dlcache v1.0.0
现成的分布式K/V缓存已经有很多的实现,最主要的比如redis,memcached,couchbase.那为什么我们还要自己去实现呢,在我们解决了分布式系统下大量rpc调用导致的高延时后,我们发现很多 ...
- postgresql 9.6 rc1发布
postgresql 9.6 rc1发布了,意味着postgresql 9.6正式版将会越来越近了. 对于dss来说,postgresql远优于mysql,尤其是9.6新引入的并行执行,将大大提高性能 ...
- JavaScript的prototype(原型)
JavaScript的每一个对象都有prototype属性哦 对象方法.类方法.原型方法 1.对象方法:理解就很简单了,主要是如果类生成一个实例,那么该实例就能使用该方法2.类方法:不需要通过生成实例 ...
- andriod 图片选择器
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="ht ...
- Creating a SharePoint BCS .NET Connectivity Assembly to Crawl RSS Data in Visual Studio 2010
from:http://blog.tallan.com/2012/07/18/creating-a-sharepoint-bcs-net-assembly-connector-to-crawl-rss ...
- Android用路径api在内部存储读写文件
复制并修改原有项目 复制之前创建的项目CC+CV操作 需要改动的地方: * 项目名字 * 应用包名 * R文件重新导包 接着修改件/AndroidManifest.xml中的包名:package=&q ...
- HDFS主要特性和体系结构
引言 Hadoop分布式文件系统(HDFS)被设计成适合运行在通用硬件(commodity hardware)上的分布式文件系统.它和现有的分布式文件系统有很多共同点.但同时,它和其他的分布式文件系统 ...
- JAVA基础学习day18--常用工具类
一.System 1.1.概述 System 类包含一些有用的类字段和方法.它不能被实例化. 在 System 类提供的设施中,有标准输入.标准输出和错误输出流:对外部定义的属性和环境变量的访问:加载 ...
- Spring(二)Bean入门
一.BeanFactory介绍 1.1.Bean: 在Spring技术中是基于组件的 最基本了是最常用的单元 其实实例保存在Spring的容器当中 Bean通常被定义在配置文件当中,Bean实例化由S ...