在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的 源码, 这里可以有一个简单的解释:
visit()方法最初是从CCNode继承过来的. 也就是说任何显示对象都有这个方法.
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当前的状态, 渲染不同的图像.