參考了《cocos2d-x權威指南》,有一些說法改爲了我本身比較理解的話。node
錨點的出現就是爲sprite圖片精靈的服務的,錨點指定了精靈上和其在父節點座標系中設置的位置重合的點的位置(原話是:錨點指定了精靈上和所在節點原點(也就是設置位置的點)重合的點。),所以只有在Node節點類使用貼圖的狀況下,錨點纔有意義。c++
在Cocos2d - x中CCLayer的Anchor Point爲默認值(0, 0),其餘Node的默認值爲(0.5, 0.5),表示的是一個乘數因子。其表示錨點位於貼圖長度乘0.5和寬度乘0.5即貼圖中心。函數
改變錨點的值並不會改變節點的位置,變化的只是貼圖相對於設置的相對位置,至關於在移動節點裏的貼圖,而非節點自己。測試
注意!!再理解一次:子節點添加到父節點時,參考的是父節點左下角的座標原點而非錨點,改變某個節點中的錨點並不影響此節點的原點位置。但子節點在父節點中的位置與子節點的錨點有關,即子節點錨點與父節點原點重合。還沒理解的話必定要寫程序!!將一個節點添加到父節點裏時,須要設置其在父節點上的位置,本質上是設置節點的錨點在父座標系上的位置。this
Vec2 convertToWorldSpace(const Vec2 &nodePoint) const
Converts a Vec2 to world space coordinates.
The result is in Points.
Parameters
nodePoint A given coordinate.
Returns
:A point in world space coordinates.spa
cocos的文檔說明寫得太簡潔了,看完後腦子還很糊。
首先得弄明白究竟是對節點對象的座標仍是對函數傳入參數表明的座標進行轉化。通常用此成員函數將傳入的座標經過某個節點座標轉化到世界座標系中。假設已經清楚了錨點的做用了(好吧,不清楚再回過頭看一下上面)。下面用4組測試對這個函數進行詳細分析。code
準備工做,建立兩個圖片精靈A、B,初始的尺寸,位置和錨點以下設置對象
auto A = Sprite::create("red.png"); auto B = Sprite::create("green.png"); A->setContentSize(Size(300,200)); B->setContentSize(Size(200,100)); A->setAnchorPoint(Vec2(0,0)); B->setAnchorPoint(Vec2(1,1)); A->setPosition(300,300); B->setPosition(200,200);
這裏沒用到節點A),傳入Vec2(10,10)進行轉換.blog
Vec2 position1 = B->convertToWorldSpace(Vec2(10,10)); log("World Position = (%f,%f)",position1.x,position1.y);
將B的錨點設置爲(1,1)的狀況:
輸出World Position = (10.000000,110.000000)
將B的錨點設置爲(0,0)的狀況:
輸出World Position = (210.000000,210.000000)圖片
第一種狀況,(再次強調節點座標系原點座標一直在左下角,不會變!),B節點原點在世界座標系中是(0,100),(0,100)+(10,10)=(10,110)。第二種狀況,B的原點在世界座標系中是(200,200),與上述同理相加便可獲得結果。
爲什麼是相加呢?把這個函數作個分解:①傳入想轉變的座標,②藉助某個節點座標系,把傳入座標放到B的節點座標系中,就是以B左下角爲原點的座標系。③轉換到世界座標系中,傳入的座標在B的節點座標系就是他本身傳入的座標,在放大到世界座標系,那就是這個座標再加上B原點在世界座標系中的座標就是傳入座標在世界座標系中的座標,把這個過程畫個圖就明白了!
第一步傳入的座標能夠像上述直接一個點,也能夠是經過某個節點獲得的座標,例如A-->getPosition()返回的座標(我看到不少博主在說明經過傳入這種座標時都要將兩個節點揉在一塊兒,並且各有解釋。好比A的錨點相對於B的原點進行轉化;A經過B來平移等,看得頭都大了,最終我仍是準備本身解釋,請看下面)。
Vec2 position1 = B->convertToWorldSpace(A->getPosition());
B錨點設置(1,1),A錨點設置(0,0)的狀況:
輸出World Position = (300.000000,400.000000)
B錨點不變,A錨點改爲(1,1)的狀況:
輸出World Position = (300.000000,400.000000)
B錨點改爲(0,0),A錨點仍然爲(0,0)的狀況:
輸出World Position = (500.000000,500.000000)
舉的例子中,A、B節點的父節點就是場景節點,其座標系與世界座標系重合。
咱們看到改變參照節點A的錨點並無影響,而改變B的錨點結果出現了變化。因爲咱們傳入的只是一個Vec2類型的量,雖然是經過A節點獲取到的,但其實和A節點的關係並不大。由於A節點在其父節點中的位置一開始就已肯定:(200,200),而咱們以前說過錨點是與在父節點中設置的位置重合的點,不管怎樣改變錨點,也不可能改變這個位置。
別人的說法①:能夠把這個變換看做是A的錨點相對於B的原點在世界座標系中的位置。這個說法欠妥,若是轉換的關係是這樣的話,結果應該是B節點的原點與A節點錨點的相對位置,那麼就是A節點錨點所在位置的座標減去B節點原點所在位置的結果。上述狀況,B的原點在(0,100),A節點錨點在(300,300),輸出結果是(300,400),顯然是相減而非相加。第2、三種狀況同理。
別人的說法②:點能夠當作向量,B節點座標系是其父節點座標系位移那麼多量得來。而A參照了B節點,進行一樣的位移,也就是在A向量+B位置。結果就是位移後的結果。這個解釋能夠。不過咱們不妨就把傳入的參數當作一個點吧,而不要聯繫到兩個節點上(若是這樣的理解有問題的話,歡迎指正!)。
auto A = Sprite::create("red.png"); auto B = Sprite::create("green.png"); A->setContentSize(Size(300,200)); B->setContentSize(Size(200,100)); A->setAnchorPoint(Vec2(0,0)); B->setAnchorPoint(Vec2(1,1)); A->setPosition(300,300); B->setPosition(200,200); this->addChild(A, 0); A->addChild(B); Vec2 position1 = B->convertToWorldSpace(Vec2(0,0)); log("World Position = (%f,%f)",position1.x,position1.y);
結果: World Position = (300.000000,400.000000)
由於B是A的子節點,以A左下角原點(300,300)設置B的位置(200,200),B錨點設置是(1,1),因此相對於節點A的節點座標系B的原點座標在(0,100),但在世界座標系是即(300,300)+(0,100)=(300,400),傳入點是(0,0),至關於沒加,因此最後結果(0,0)+(300,400)=(300,400)
Vec2 position1 = B->convertToWorldSpace(A->getPosition());
結果:B Node World Position = (600.000000,700.000000)
上面計算過了,B原點位置在世界座標系中是(300,400),因爲獲取的AgetPosition()獲得的座標就是剛開始相對於其父節點所設置的座標(300,300),那麼結果就是這兩個的和。
改變錨點的狀況與測試2同理,只要照着測試1中說的那樣去思考,不管是A仍是B的錨點改變都能很容易計算。
this->addChild(B, 0); B->addChild(A, 0); Vec2 position1 = B->convertToWorldSpace(origin); log("World Position = (%f,%f)",position1.x,position1.y);
結果World Position = (0.000000,100.000000)
B是A的父節點,B的原點在世界座標系中座標爲(0,100),後面再也不贅述。
Vec2 position1 = B->convertToWorldSpace(A->getPosition());
結果B Node World Position = (300.000000,400.000000)
B的原點在世界座標系中爲(0,100),A是B的子節點,以B的節點座標系設置座標(300,300),且B的錨點設置是(0,0),那麼B的錨點座標和其原點重合,AgetPosition()獲得的位置就是相對於其父節點所設置的座標(300,300),最後結果在世界座標系中A的原點的座標(0,100)+(300,300)= (400,400)
改變錨點的狀況再也不贅述。
Vec2 convertToNodeSpace(const Vec2 &worldPoint) const
Converts a Vec2 to node (local) space coordinates.
The result is in Points.
Parameters
worldPoint A given coordinate.
Returns
:A point in node (local) space coordinates.
這個函數是將傳入的座標轉化到某個節點的節點座標系。理解這個函數就是以參考的節點座標左下角爲原點畫座標系,觀察傳入點的相對位置,就能知道是傳入點座標減去節點原點世界座標系座標。仍然能夠分步理解。①傳入一個節點,怎麼傳入都行,只要是Vec2類型的,②經過世界座標系比較傳入點和節點原點座標的相對位置。③轉化到節點座標系,以節點原點畫座標,獲得傳入點在節點座標系中的位置。
auto A = Sprite::create("red.png"); auto B = Sprite::create("green.png"); A->setContentSize(Size(300,200)); B->setContentSize(Size(200,100)); A->setAnchorPoint(Vec2(0,0)); B->setAnchorPoint(Vec2(1,1)); A->setPosition(300,300); B->setPosition(200,200); this->addChild(B, 0); this->addChild(A, 0); Vec2 position1 = B->convertToNodeSpace(Vec2(10,10)); log("Node Position = (%f,%f)",position1.x,position1.y);
結果:Node Position = (10.000000,-90.000000)
這裏沒有涉及A節點,忽略A。
B的原點座標在世界座標系中的位置是(0,100),傳入座標(10,10),(10,10)-(0,100)=(10,-90),相減的緣由按照上述分解畫個圖就能明白。
改變錨點和父子節點只要理解了爲何相減,過程都與convertToWorldSpace同樣。
只是把參考節點原點改爲了節點錨點,若是真的理解了上面的內容,理解這兩個易如反掌。故再也不贅述。