cocos2d-x中的錨點(AnchorPoint)理解

錨點的定義

錨點是指節點在進行形狀變換、位置變動時依據的基準點。可以想象爲釘在牆上用於固定紙張的小圖釘,或者公告欄上用於固定紙張用的圍棋狀的小磁粒。當對某個節點調用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;
}

運行結果

參考資料

1. cocos2d-x AnchorPoint錨點

2. CSS3中的transform變形詳解


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章