cocos2dx中经常会用到节点的旋转,一旦涉及到物体的旋转则会涉及到旋转所相对的中心点的位置,对于CCNode而言,其提供了设置锚点的接口,用来设置锚点的相对位置。
见CCNode源代码中CCNode.cpp
/// anchorPoint getter
const CCPoint& CCNode::getAnchorPoint()
{
return m_obAnchorPoint;
}
void CCNode::setAnchorPoint(const CCPoint& point)
{
if( ! point.equals(m_obAnchorPoint))
{
m_obAnchorPoint = point;
m_obAnchorPointInPoints = ccp(m_obContentSize.width * m_obAnchorPoint.x, m_obContentSize.height * m_obAnchorPoint.y );
m_bTransformDirty = m_bInverseDirty = true;
}
}
其锚点的坐标值是一个相对值0~1,其中m_obAnchorPoint表示的是相对锚点坐标,m_obAnchorPointInPoints表示的是锚点在屏幕中的像素坐标,所以对于CCNode的坐标系转换会涉及到多种转换方式。
我们也可以通过设置ignoreAnchorPointForPosition来忽略锚点的作用。
对于图层而言其ignoreAnchorPointForPosition的默认值为false,CCSprite默认值为true,但是有时候大家会发现,即便咱们设置了图层的ignoreAnchorPointForPosition为false,但是图层的旋转仍然没有按照预定的结果来进行,原因是因为默认CCLayer的图层的大小为CCSize(0,0),所以不管你怎么设置图层的大小始终为(0,0),经过锚点比例进行计算之后其锚点的坐标仍然是(0,0),如下图所示:
但是设置了CCLayer的大小之后,就会发现,咱们设置的锚点就能起到作用了
void LayerIgnoreAnchorPointPos::onEnter()
{
LayerTest::onEnter();
bool ignore = this->isIgnoreAnchorPointForPosition();
//this->ignoreAnchorPointForPosition(false);
//CCSize layerSize = this->getContentSize();
setContentSize(CCDirector::sharedDirector()->getWinSize());
setAnchorPoint(ccp(0.5, 1));
//CCSize layerSize2 = this->getContentSize();
//CCPoint pt = this->getPosition();
//setPosition(ccp(layerSize2.width/2, layerSize2.height/2));
CCSize s = CCDirector::sharedDirector()->getWinSize();
CCLayerColor *l = CCLayerColor::create(ccc4(255, 0, 0, 255), 150, 150);
l->setAnchorPoint(ccp(0.5f, 0.5f));
l->setPosition(ccp( s.width/2, s.height/2));
CCMoveBy *move = CCMoveBy::create(2, ccp(100,2));
CCMoveBy * back = (CCMoveBy *)move->reverse();
CCSequence *seq = CCSequence::create(move, back, NULL);
l->runAction(CCRepeatForever::create(seq));
this->addChild(l, 0, kLayerIgnoreAnchorPoint);
CCSprite *child = CCSprite::create("Images/grossini.png");
l->addChild(child);
CCSize lsize = l->getContentSize();
child->setPosition(ccp(lsize.width/2, lsize.height/2));
CCMenuItemFont *item = CCMenuItemFont::create("Toggle ignore anchor point", this, menu_selector(LayerIgnoreAnchorPointPos::onToggle));
CCMenu *menu = CCMenu::create(item, NULL);
this->addChild(menu);
menu->setPosition(ccp(s.width/2, s.height/2));
//this->setAnchorPoint(ccp(0.5, 0.5));
CCDirector::sharedDirector()->getActionManager()->addAction(
CCRepeatForever::create(
CCSequence::create(CCRotateBy::create(2, 360),
CCRotateBy::create(2, -360),
0)
),
this,
false);
}