锚点的定义
锚点是指节点在进行形状变换、位置变动时依据的基准点。可以想象为钉在墙上用于固定纸张的小图钉,或者公告栏上用于固定纸张用的围棋状的小磁粒。当对某个节点调用setPosition时,cocos2d-x即会将其锚点移动到相应位置;当对节点进行rotate操作时,节点也是以锚点所在位置为轴心进行旋转的。具体的定义看CCNode.h中的setAnchorPoint说明:* anchorPoint is the point around which all transformations and positioning manipulations take place.
* It's like a pin in the node where it is "attached" to its parent.
锚点的特征
在cocos2d-x中,锚点是向量化后的点,比如某个480x320的节点,锚点(0,0)在其左下角,锚点(1,1)在其右上角即(480,320)的位置,锚点(0.5,0.5)位于其中点处。注意,锚点可以大于(1,1)或者小于(0,0),这在后面将会给出演示。* The anchorPoint is normalized, like a percentage. (0,0) means the bottom-left corner and (1,1) means the top-right corner.
* But you can use values higher than (1,1) and lower than (0,0) too.
锚点的默认值
CCNode:- anchorPoint: (x=0,y=0) -m_bIgnoreAnchorPointForPosition(false)CCScene/CCLayer/CCSprite:-setAnchorPoint( ccp(0.5f, 0.5f) ) -ignoreAnchorPointForPosition(true) (在相应的构造函数中可以看到)
注意:上面提到,设置节点位置时其实是将其锚点移动到指定位置,这有个前提,就是CCNode的m_bIgnoreAnchorPointForPosition成员必须为false,它是告诉标志节点移动时是否忽略锚点的标志。在cocos2d-x中,CCNode/CCSprite将其默认为false,而CCScene/CCLayer则默认为true,因此,若要使CCScene或者CCLayer根据锚点来移动,则要首先调用CCNode::ignoreAnchorPointForPosition(false)
锚点实例一:精灵的锚点
以下分别演示对精灵进行变换操作(transformation/position)时,锚点起到的作用
设置位置
// on "init" you need to initialize your instance
bool HelloWorld::init()
{
//
// 1. super init first
if ( !CCLayer::init() )
{
return false;
}
CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
CCSprite* sprite1 = CCSprite::create("CloseNormal.png");
sprite1->setAnchorPoint( ccp(0,0) );
sprite1->setPosition(ccp(origin.x+visibleSize.width/2, origin.y+visibleSize.height/2));
this->addChild(sprite1);
CCSprite* sprite2 = CCSprite::create("CloseNormal.png");
sprite2->setAnchorPoint( ccp(1,0) );
sprite2->setPosition(ccp(origin.x+visibleSize.width/2, origin.y+visibleSize.height/2));
this->addChild(sprite2);
CCSprite* sprite3 = CCSprite::create("CloseNormal.png");
sprite3->setAnchorPoint( ccp(1,1) );
sprite3->setPosition(ccp(origin.x+visibleSize.width/2, origin.y+visibleSize.height/2));
this->addChild(sprite3);
CCSprite* sprite4 = CCSprite::create("CloseNormal.png");
sprite4->setAnchorPoint( ccp(0,1) );
sprite4->setPosition(ccp(origin.x+visibleSize.width/2, origin.y+visibleSize.height/2));
this->addChild(sprite4);
CCSprite* sprite5 = CCSprite::create("CloseNormal.png");
sprite5->setAnchorPoint( ccp(0.5,0.5) );
sprite5->setPosition(ccp(origin.x+visibleSize.width/2, origin.y+visibleSize.height/2));
this->addChild(sprite5);
return true;
}
运行结果:
设置伸缩
bool HelloWorld::init()
{
//
// 1. super init first
if ( !CCLayer::init() )
{
return false;
}
CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
// 锚点(1,1)
CCSprite* sprite1 = CCSprite::create("CloseNormal.png");
sprite1->setAnchorPoint( ccp(1,1) );
sprite1->setPosition(ccp(origin.x+visibleSize.width/2, origin.y+visibleSize.height/2));
this->addChild(sprite1);
// 锚点、位置与sprite1相同,X轴以锚点为基点伸缩5.0倍
CCSprite* sprite2 = CCSprite::create("CloseNormal.png");
sprite2->setAnchorPoint( ccp(1,1) );
sprite2->setPosition(ccp(origin.x+visibleSize.width/2, origin.y+visibleSize.height/2));
this->addChild(sprite2);
sprite2->setScaleX(5.0f);
// 锚点(0,0)
CCSprite* sprite3 = CCSprite::create("CloseNormal.png");
sprite3->setAnchorPoint( ccp(0,0) );
sprite3->setPosition(ccp(origin.x+visibleSize.width/2, origin.y+visibleSize.height/2));
this->addChild(sprite3);
// 锚点、位置与sprite3相同,X轴以锚点为基点伸缩5.0倍
CCSprite* sprite4 = CCSprite::create("CloseNormal.png");
sprite4->setAnchorPoint( ccp(0,0) );
sprite4->setPosition(ccp(origin.x+visibleSize.width/2, origin.y+visibleSize.height/2));
this->addChild(sprite4);
sprite4->setScaleX(5.0f);
return true;
}
运行结果
设置旋转
bool HelloWorld::init()
{
//
// 1. super init first
if ( !CCLayer::init() )
{
return false;
}
CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
// 锚点(0,0)
CCSprite* sprite3 = CCSprite::create("CloseNormal.png");
sprite3->setAnchorPoint( ccp(0,0) );
sprite3->setPosition(ccp(origin.x+visibleSize.width/2, origin.y+visibleSize.height/2));
this->addChild(sprite3);
// 锚点、位置与sprite3相同,X轴以锚点为轴顺时针旋转90°
CCSprite* sprite4 = CCSprite::create("CloseNormal.png");
sprite4->setAnchorPoint( ccp(0,0) );
sprite4->setPosition(ccp(origin.x+visibleSize.width/2, origin.y+visibleSize.height/2));
this->addChild(sprite4);
sprite4->setRotation(90); // 顺时针旋转90°
return true;
}
运行结果
设置弯曲
bool HelloWorld::init()
{
//
// 1. super init first
if ( !CCLayer::init() )
{
return false;
}
CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
// 锚点(0,0)
CCSprite* sprite3 = CCSprite::create("CloseNormal.png");
sprite3->setAnchorPoint( ccp(0,0) );
sprite3->setPosition(ccp(origin.x+visibleSize.width/2, origin.y+visibleSize.height/2));
this->addChild(sprite3);
// 锚点、位置与sprite3相同,以锚点为固定点,X轴向右弯曲45°
CCSprite* sprite4 = CCSprite::create("CloseNormal.png");
sprite4->setAnchorPoint( ccp(0,0) );
sprite4->setPosition(ccp(origin.x+visibleSize.width/2, origin.y+visibleSize.height/2));
this->addChild(sprite4);
sprite4->setSkewX(45);
return true;
}
运行结果
锚点实例二:层的锚点
cocos2d-x中对CCLayer对象setPosition时,若希望以锚点为基点,则需要开启bIgnoreAnchorPointForPosition标志,否则setPosition时不考虑锚点因素。
设置位置
bool HelloWorld::init()
{
//
// 1. super init first
if ( !CCLayer::init() )
{
return false;
}
CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
// 创建一个绿色层
CCLayerColor* layer1 = CCLayerColor::create(ccc4(0,255,0,255), 100, 50);
layer1->setAnchorPoint( ccp(0.5,0.5) ); // 设置锚点为中点
// layer->ignoreAnchorPointForPosition(false);
layer1->setPosition(origin.x+visibleSize.width/2, origin.y+visibleSize.height/2); // 移动到窗口中点
this->addChild(layer1);
// 创建一个黄色层
CCLayerColor* layer2 = CCLayerColor::create(ccc4(255,255,0,255), 100, 50);
layer2->setAnchorPoint( ccp(0.5,0.5) ); // 设置锚点为中点
layer2->ignoreAnchorPointForPosition(false);
layer2->setPosition(origin.x+visibleSize.width/2, origin.y+visibleSize.height/2); // 移动到窗口中点
this->addChild(layer2);
return true;
}
运行结果
参考资料