使用CCNode作为容器容易踩的坑
Cocos2dx中CCNode经常作为一个父容器,里面装一些UI控件,最后组成一个复杂的自定义的UI控件,但是在使用别人的自定义控件和自己写自定义问题的时候会踩一些坑。
首先拿到一个自定义的UI控件一定要明确他的position是在控件的什么位置,即锚点位置,这样才能知道改如何取设置position。
其次知道父容器区域是不是全包含子容器的,因为ccnode里面的子节点的范围是可以超出你设定的ccnode的区域的。原因在于ccnode可以没有区域,这个跟winform桌面编程的Panel有差别,用到区域的时候才设置区域。
所以最需要知道的是子节点如何排列,所有子节点排列完毕后,父容器的锚点是在子节点的什么位置。
比如用一个node中加入一个cclabelTTF,cclabelTTF的锚点是0.5,0.5如果不做调整,node->setpositon(0,0)的话只有cclabel的第二象限会显示出来。
所以如果自定义UI组件自己用或者给别人用的话最好能有一个美术的示意图,子节点的构成和位置,设置父容器坐标的时候坐标该如何偏移,默认的父容器锚点的位置在哪里,是否可以更改,否则真心是大坑!
CCNode* n1 = CCNode::create();
StrokeLabel* l1 = StrokeLabel::create(40);
l1->setString("11111111");
n1->addChild(l1);
n1->setAnchorPoint(ccp(0.5,0.5));
n1->setContentSize(CCSizeMake(400,400));
n1->setPosition(480,320);
addChild(n1);
这段代码,strokeLabel可以换成cclabelTTF,去掉setContentSize和有会造成2种不同的效果
原因
void CCNode::setContentSize(const CCSize & size)
{
if ( ! size.equals(m_obContentSize))
{ m_obContentSize = size;
m_obAnchorPointInPoints = ccp(m_obContentSize.width * m_obAnchorPoint.x, m_obContentSize.height * m_obAnchorPoint.y );
}
}
个人认为对于ccnode来说只有设置了contentsize后锚点才是有意义的。
其次setContentsize和setAnchorpoint的顺序是无关紧要的,在setAnchorPoint中会重新设置 m_obAnchorPointInPoints。这引发了我的一些思考,自己写的东西给他人用的时候如果提供的方法有调用顺序应该详细的说明写上一个示例,
同时这种public的接口调用之间有顺序这种设计应该尽量规避