Cocos2d-x 座標研究

    無論是搞2d還是3d開發,最需要搞清楚的就是座標系。網上很多講解座標系的文章,要麼寫得很模糊,要麼純粹是轉載,此文章是在參考了各位大神的博客之後,根據自己的理解寫的,在後面也分析了幾個例子。菜鳥入門,不喜勿噴!

部分轉載自:http://blog.163.com/zjf_to/blog/static/201429061201292193855498/


Cocos2d-x在CCNode中提供了一下四個座標轉換函數:

CCPoint convertToNodeSpace(constCCPoint& worldPoint);

CCPoint convertToWorldSpace(constCCPoint& nodePoint);

CCPoint convertToNodeSpaceAR(constCCPoint& worldPoint);

CCPoint convertToWorldSpaceAR(constCCPoint& nodePoint);

 

在理解這個之前,先了解一下世界座標和本地座標:

1、  GL座標系:

Cocos2D以OpenglES爲圖形庫,所以它使用OpenglES座標系。GL座標系原點在屏幕左下角,x軸向右,y軸向上。

 

2、  屏幕座標系:

蘋果的Quarze2D使用的是不同的座標系統,原點在屏幕左上角,x軸向右,y軸向下。ios的屏幕觸摸事件CCTouch傳入的位置信息使用的是該座標系。因此在cocos2d中對觸摸事件做出響應前需要首先把觸摸點轉化到GL座標系。可以使用CCDirector的convertToGL來完成這一轉化。

 

3、  世界座標系:

也叫做絕對座標系,cocos2d中的元素是有父子關係的層級結構,我們通過CCNode的position設定元素的位置使用的是相對與其父節點的本地座標系而非世界座標系。最後在繪製屏幕的時候cocos2d會把這些元素的本地座標映射成世界座標系座標。世界座標系和GL座標系一致,原點在屏幕左下角。

 

4、  本地座標系:

本地座標系也叫做物體座標系,是和特定物體相關聯的座標系。每個物體都有它們獨立的座標系,當物體移動或改變方向時,和該物體關聯的座標系將隨之移動或改變方向。比如用cocos2d-x創建了個矩形colorLayer:CCRect(10,10,100,100),這是的本地座標系爲以(10,10)爲座標原點,x軸向右,y軸向上。如果創建了一個CCSprite,錨點爲(0.5,0.5),位置爲(100,100),size爲(40,40),這時的本地座標系爲以(80,80)爲座標原點,x軸向右,y軸向上。總之,本地座標系原點爲node的左下角座標。

 

 

接下來,詳細解析一下上述的四個函數:

1、  convertToNodeSpace:

調用CCPoint point =node1->convertToNodeSpace(node2->getPosition());

將node2的座標轉化成相對於node1的本地座標。


如上圖所示:node1的錨點爲(0,0),所以node1的座標爲(20,40),node2的錨點爲(1,1),所以node2的座標爲(-5, -20)。轉換的時候,以node1(20,40)原點建立座標系,此時node2(-5,-20)相對於新座標系,轉換之後就是(-25,-60)。

 

2、  convertToWorldSpace:

調用CCPoint point =node1->convertToWorldSpace(node2->getPosition());

將node2的座標轉化成相對於node1的世界座標。


如上圖所示:node1(20,40),node2(-5,-20)。以node1(20,40)爲原點建立世界座標系,此時node2(-5,-20)在新的世界座標系中需往左(x軸)偏移5個單位,往下(y軸)偏移20個單位。所以node2(-5,-20)相對於node1世界座標系爲(-5,-20),而相對於原來的世界座標系(0,0),其座標則爲(20-5,40-20),即(15,20)。

 

3、  convertToNodeSpaceAR:

上面的兩個是忽略錨點的,所以講座標系原點設置在左下角。convertToNodeSpaceAR就是把node1的座標系原點設置在錨點的位置,node1的錨點是(0,0),所以轉化之後的座標系位置和上面的convertToNodeSpace一樣,結果也是一樣的。

 

4、  convertToWorldSpaceAR:

跟convertToNodeSpaceAR同理。


測試:

    CCSprite *sprite1 = CCSprite::create("HelloWorld.png",CCRect(0, 0, 40, 40));//從HelloWorld.png截取40x40的矩形區域

    sprite1->setPosition(ccp(20,40));

    sprite1->setAnchorPoint(ccp(0,0));

    this->addChild(sprite1);

    CCSprite *sprite2 = CCSprite::create("HelloWorld.png",CCRect(0, 0, 40, 40));

    sprite2->setPosition(ccp(-5,-20));

    sprite2->setAnchorPoint(ccp(1,1));

    this->addChild(sprite2);

    CCPoint point1 = sprite1->convertToNodeSpace(sprite2->getPosition());

    CCPoint point2 =sprite1->convertToNodeSpaceAR(sprite2->getPosition());

    CCPoint point3 =sprite1->convertToWorldSpace(sprite2->getPosition());

    CCPoint point4 =sprite1->convertToWorldSpaceAR(sprite2->getPosition());

    CCLog("position = (%f,%f)",point1.x,point1.y);

    CCLog("position = (%f,%f)",point2.x,point2.y);

    CCLog("position = (%f,%f)",point3.x,point3.y);

    CCLog("position = (%f,%f)",point4.x,point4.y);

結果:

    position = (-25.000000,-60.000000)

    position = (-25.000000,-60.000000)

    position = (15.000000,20.000000)

    position = (15.000000,20.000000)

 

 

測試:

    CCPoint point1 =sprite2->convertToNodeSpace(sprite1->getPosition());

    CCPoint point2 =sprite2->convertToNodeSpaceAR(sprite1->getPosition());

    CCPoint point3 = sprite2->convertToWorldSpace(sprite1->getPosition());

    CCPoint point4 =sprite2->convertToWorldSpaceAR(sprite1->getPosition());

結果:

    position = (65.000000,100.000000)

    position = (25.000000,60.000000)

    position = (-25.000000,-20.000000)

    position = (15.000000,20.000000)

這裏由於sprite2的錨點爲(1,1),所以convertToNodeSpace和convertToNodeSpaceAR結果不一樣。

 

解析:

sprite1座標(20,40),sprite2座標(-5,-20)。

 

convertToNodeSpace:以sprite2左下角建立節點座標系,原點(-5-40,-20-40)即(-45,-60),node1(20,40)相對於(-45,-60),轉換之後爲(45+20,60+40)即(65,100)。

convertToNodeSpaceAR:以sprite2錨點的位置建立節點座標系,原點(-5,-20),node1(20,40)相對於(-5,-20),轉換之後爲(5+20,20+40)即(25,60)。

convertToWorldSpace:以sprite2左下角建立世界座標系,原點(-5-40,-20-40)即(-45,-60),node1(20,40)相對於(-45,-60),轉換之後爲(-45+20,-60+40)即(-25,-20)。

convertToWorldSpaceAR:以sprite2錨點的位置建立世界座標系,原點(-5,-20),node1(20,40)相對於(-5,-20),轉換之後爲(-5+20,-20+40)即(15,20)。

 


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