UI座標就是Android和iOS等應用開發的時候使用的二維座標系。它的原點是在左上角的。html
UI座標原點是在左上角,x軸向右爲正,y軸向下爲正。咱們在Android和iOS等平臺使用的視圖、控件等都是遵照這個座標系。然而在Cocos2d-x默認不是採用UI座標,可是有的時候也會用到UI座標,例如在觸摸事件發生的時候,咱們會得到一個觸摸對象(Touch),觸摸對象(Touch)提供了不少得到位置信息的函數,以下面代碼所示:node
Point touchLocation = touch->getLocationInView();編程
使用getLocationInView()函數得到觸摸點座標事實上就是UI座標,它的座標原點在左上角。而不是Cocos2d-x默認座標,咱們能夠採用下面的語句進行轉換:函數
Point touchLocation2 = Director::getInstance()->convertToGL(touchLocation);this
經過上面的語句就能夠將觸摸點位置從UI座標轉換爲OpenGL座標,OpenGL座標就是Cocos2d-x默認座標。spa
咱們在上面提到了OpenGL座標,OpenGL座標是種三維座標。因爲Cocos2d-x底層採用OpenGL渲染,所以的默認座標就是OpenGL座標,只不過只採用兩維(x和y軸)。若是不考慮z軸,OpenGL座標的原點在左下角。操作系統
提示: 三維座標根據z軸的指向不一樣分爲:左手座標和右手座標。右手座標是z軸指向屏幕外。左手座標是z軸指向屏幕裏.OpenGL座標是右手座標,而微軟平臺的Direct3D[1]是左手座標。.net
因爲OpenGL座標有能夠分爲:世界座標和模型座標,因此Cocos2d-x的座標也有世界座標和模型座標。code
你是否有過這樣的問路經歷:張三會告訴你向南走一千米,再向東走500米。而李四會告訴你向右走一千米,再向左走500米。這裏兩種說法或許均可以找到你要尋找的地點。張三採用的座標是世界座標,他把地球做爲參照物,表述位置使用地理的東、南、西和北。而李四採用的座標是模型座標,他讓你本身做爲參照物,表述位置使用你的左邊、你的前邊、你的右邊和你的後邊。orm
咱們看看圖3-21,從圖中能夠看到A的座標是(5,5),B的座標是(4,6),事實上這些座標值就是世界座標。若是採用A的模型座標來描述B的位置,則B的座標是(1,-1)。
有的時候咱們須要將世界座標與模型座標互相轉換。咱們能夠經過Node對象以下函數實現:
Point convertToNodeSpace ( const Point & worldPoint )。將世界座標轉換爲模型座標。
Point convertToNodeSpaceAR ( const Point & worldPoint )。將世界座標轉換爲模型座標。AR表示相對於錨點。
Point convertTouchToNodeSpace ( Touch * touch )。將世界座標中觸摸點轉換爲模型座標。
Point convertTouchToNodeSpaceAR ( Touch * touch )。將世界座標中觸摸點轉換爲模型座標。AR表示相對於錨點。
Point convertToWorldSpace ( const Point & nodePoint )。將模型座標中觸摸點轉換爲世界座標。
Point convertToWorldSpaceAR ( const Point & nodePoint )。將模型座標中觸摸點轉換爲世界座標。AR表示相對於錨點。
下面咱們經過兩個例子瞭解一下世界座標與模型座標互相轉換。
一、世界座標轉換爲模型座標
下面是世界座標轉換爲模型座標實例運行結果。
在遊戲場景中有兩個Node對象,其中Node1的座標是(400, 500),大小是300 x 100像素。Node2的座標是(200, 300),大小也是300 x 100像素。這裏的座標事實上就是世界座標,它的座標原點是屏幕的左下角。
編寫代碼以下:
[html] view plaincopy
bool HelloWorld::init()
{
if( !Layer::init() )
{
returnfalse;
}
SizevisibleSize = Director::getInstance()->getVisibleSize();
Pointorigin = Director::getInstance()->getVisibleOrigin();
autocloseItem = MenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
CC_CALLBACK_1(HelloWorld::menuCloseCallback,this));
closeItem->setPosition(Point(origin.x+ visibleSize.width - closeItem->getContentSize().width/2 ,
origin.y+ closeItem->getContentSize().height/2));
automenu = Menu::create(closeItem, NULL);
menu->setPosition(Point::ZERO);
this->addChild(menu,1);
//建立背景
autobg = Sprite::create("bg.png"); ①
bg->setPosition(Point(origin.x+ visibleSize.width/2,
origin.y+ visibleSize.height/2));
this->addChild(bg,0); ②
//建立Node1
autonode1 = Sprite::create("node1.png"); ③
node1->setPosition(Point(400,500));
node1->setAnchorPoint(Point(1.0,1.0));
this->addChild(node1,0); ④
//建立Node2
autonode2 = Sprite::create("node2.png"); ⑤
node2->setPosition(Point(200,300));
node2->setAnchorPoint(Point(0.5,0.5));
this->addChild(node2,0); ⑥
PointPoint1 = node1->convertToNodeSpace(node2->getPosition()); ⑦
PointPoint3 = node1->convertToNodeSpaceAR(node2->getPosition()); ⑧
log("Node2NodeSpace = (%f,%f)",Point1.x,Point1.y);
log("Node2NodeSpaceAR = (%f,%f)",Point3.x,Point3.y);
returntrue;
}
代碼①~②行是建立背景精靈對象,這個背景是一個白色900 x 640像素的圖片。代碼第③~④行是建立Node1對象,並設置了位置和錨點屬性。代碼第⑤~⑥行是建立Node2對象,並設置了位置和錨點屬性。第⑦行代碼將Node2的世界座標轉換爲相對於Node1的模型座標。而第⑧行代碼是相似的,它是相對於錨點的位置。
運行結果以下:
Node2 NodeSpace = (100.000000,-100.000000)
Node2 NodeSpaceAR =(-200.000000,-200.000000)
Node2的世界座標轉換爲相對於Node1的模型座標,就是將Node1的左下角做爲座標原點(圖3-22中的A點),咱們不難計算出A點的世界座標是(100,400),那麼convertToNodeSpace函數就是A點座標減去C點座標,結果是(-100,100)。而convertToNodeSpaceAR函數要考慮錨點,所以座標原點是B點,B點座標減去C點座標,結果是(-200, -200)。
二、模型座標轉換爲世界座標
下面是模型座標轉換爲世界座標實例運行結果。
在遊戲場景中有兩個Node對象,其中Node1的座標是(400, 500),大小是300 x 100像素。Node2是放置在Node1中的,它對於Node1的模型座標是(0, 0),大小也是150 x 50像素。
編寫代碼以下:
[html] view plaincopy
bool HelloWorld::init()
{
if( !Layer::init() )
{
returnfalse;
}
SizevisibleSize = Director::getInstance()->getVisibleSize();
Pointorigin = Director::getInstance()->getVisibleOrigin();
autocloseItem = MenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
CC_CALLBACK_1(HelloWorld::menuCloseCallback,this));
closeItem->setPosition(Point(origin.x+ visibleSize.width - closeItem->getContentSize().width/2 ,
origin.y+ closeItem->getContentSize().height/2));
automenu = Menu::create(closeItem, NULL);
menu->setPosition(Point::ZERO);
this->addChild(menu,1);
//建立背景
autobg = Sprite::create("bg.png");
bg->setPosition(Point(origin.x+ visibleSize.width/2,
origin.y+ visibleSize.height/2));
this->addChild(bg,0);
//建立Node1
autonode1 = Sprite::create("node1.png");
node1->setPosition(Point(400,500));
this->addChild(node1,0);
//建立Node2
autonode2 = Sprite::create("node2.png");
node2->setPosition(Point(0.0,0.0)); ①
node2->setAnchorPoint(Point(0.0,0.0)); ②
node1->addChild(node2,0); ③
PointPoint2 = node1->convertToWorldSpace(node2->getPosition()); ④
Point Point4 =node1->convertToWorldSpaceAR(node2->getPosition()); ⑤
log("Node2WorldSpace = (%f,%f)",Point2.x,Point2.y);
log("Node2WorldSpaceAR = (%f,%f)",Point4.x,Point4.y);
returntrue;
}
上述代碼咱們主要關注第③行,它是將Node2放到Node1中,這是與以前的代碼的區別。這樣第①行設置的座標就變成了相對於Node1的模型座標了。
第④行代碼將Node2的模型座標轉換爲世界座標。而第⑤行代碼是相似的,它是相對於錨點的位置。
運行結果以下:
Node2 WorldSpace =(250.000000,450.000000)
Node2 WorldSpaceAR =(400.000000,500.000000)
所示的位置,能夠用世界座標描述。代碼①~③行修改以下:
node2->setPosition(Point(250, 450));
node2->setAnchorPoint(Point(0.0,0.0));
this->addChild(node2, 0);
[1] Direct3D(簡稱:D3D)是微軟公司在Microsoft Windows操做系統上所開發的一套3D繪圖編程接口,是DirectX的一部份,目前廣爲各家顯卡所支持。與OpenGL同爲計算機繪圖軟件和計算機遊戲最常使用的兩套繪圖編程接口之一。—— 引自於維基百科 http://zh.wikipedia.org/wiki/Direct3D