cocos2d-x 座標轉換總結

首先腦補下基礎知識吧:
1、OpenGL座標系:該座標系原點在屏幕左下角,x軸向右,y軸向上。這也就是cocos2dx中用到的座標系所以沒啥好說的。
2、屏幕座標系:該座標系的原點在屏幕左上角,x軸向右,y軸向下,其實和OpenGL座標系的差別也就是y軸的方向拉。假設遊戲場景的分辨率爲(500,500),其中一個點的座標爲(200,200),那麼它在OpenGL座標系中的座標還是(200,200),在屏幕座標系中則要倒過來,則爲(200,500-200)。其實也就是6和9的差別啦,呵呵,六九式...
3、世界座標系:又名絕對座標系,概念啥的就不多說了,我們只要知道世界座標系和OpenGL座標系方向一致,原點在屏幕左下角,x軸向右,y軸向上。
4、節點座標系:又名相對座標系,和OpenGL座標系方向一致,不同的是原點在父節點左下角。

下面舉下例子:
1、先說OpenGL座標系與屏幕座標系吧

前面不是提到onTouchBegan(Touch* touch,Event* event)麼,參數touch傳來的觸點座標便是屏幕座標系,獲得該座標系的方法如下:
  1. auto point = touch->getLocationInView();//獲得屏幕座標系  
當然了,我們一般使用時都應該將屏幕座標系轉成OpenGL座標系,方法有兩種:
  1. auto point = touch->getLocation();//直接從touch中獲取,在getLocation()源碼裏會將座標轉成OpenGL座標系  
  2.   
  3. auto point = touch->getLocationInView();  
  4. point = Director::getInstance()->convertToGL(point);//先獲得屏幕座標,在調用convertToGL轉成OpenGl座標系  
下面看下完整的代碼:
  1. bool HelloWorld::onTouchBegan(Touch* touch,Event* event)  
  2. {  
  3.     auto point = touch->getLocation();//獲得OpenGl座標系  
  4.     CCLOG("Location point x=%f , y=%f",point.x,point.y);  
  5.   
  6.     auto point2 = touch->getLocationInView();//獲得屏幕座標  
  7.     CCLOG("LocationInView point x=%f , y=%f",point2.x,point2.y);  
  8.   
  9.     point2 = Director::getInstance()->convertToGL(point2);//將屏幕座標轉成OpenGL座標  
  10.     CCLOG("convertToGL1 point x=%f , y=%f",point2.x,point2.y);  
  11.   
  12.     point2 = Director::getInstance()->convertToGL(point2);//注意這個  
  13.     CCLOG("convertToGL2 point x=%f , y=%f",point2.x,point2.y);  
  14.   
  15.     return true;  
  16. }  

我當前屏幕的分辨率爲:960x640。輸出結果如下:



有沒有發現一個有趣的現象,convertToGL將point屏幕座標轉成OpenGL座標後,再對point使用一次convertToGL後,point又從OpenGL座標轉成了屏幕座標,哈哈。

2、接下來說節點座標吧,世界座標不打算詳細介紹,因爲自己也沒怎麼去用過...
節點座標的一個比較典型的用法應該就是scrollView了
吧,例如在scrollView的層上有一個精靈sp,你想獲取sp在scrollView中的哪個位置,可是每次獲取的座標都不一樣。原因就在於你每次獲得的座標都是OpenGL座標,上面有說道了,OpenGL的座標原點是在屏幕的左下角,而scrolView是一直在拖動的,每拖動一次sp的OpenGL座標當然也跟着改變。解決辦法就是將OpenGl座標轉成節點座標,方法如下:
  1. point = scroll_layer->convertToNodeSpace(point);//假設scrollView中的層是scroll_layer  
說到scrollView,下一篇要不要講點scrollView的技巧呢?

恩,先這樣吧,每次寫博客到這個點都好睏。其實也才十一點多~

尊重原創,轉載請註明來源:http://blog.csdn.net/star530/article/details/25250031


在開發cocos2d-x程序時一定要注意座標輪換問題,屏幕與openGL座標轉換有相應的函數。


  • convertToNodeSpace(const CCPoint& worldPoint): 這個函數把世界座標轉換爲對象窗口內的座標。

  • convertToWorldSpace(const CCPoint& nodePoint): 這個函數把對象窗口內的座標轉換爲世界座標。

  •  convertToNodeSpaceAR(const CCPoint& worldPoint):這個函數把世界座標轉換爲基於錨點的窗口內的座標。

  •  convertToWorldSpaceAR(const CCPoint& nodePoint):這個函數把基於錨點的對象窗口內的座標轉換爲世界座標。


用到cocos2dX的座標轉換,一般兩種情況:


1)從當前座標點獲取世界座標點(屏幕座標點,opengl的座標系)


2)從當前座標點獲取相對於某個CCNode的座標點;


第一種情況,直接用:nodeParent->convertToWorldSpace(node->getPosition());
這裏一定是需要轉換座標對象的父類調用convertToWorldSpace,參數是對象的座標點(相對於父類的座標點);
返回的是屏幕座標點;


第二種情況,直接用:node2->convertToNodeSpace(node1->getPosition);
node2並不是node1的父類,現在的情況就是:node1想得到相對於node2座標系的座標點;
返回的是相對於node2座標系的座標點。


注意:以上的調用,是沒有考慮nodeParent和node2的anchorPoint的(就是使用了0,0的錨點);考慮到錨點就使用:

convertToWorldSpaceAR()和convertToNodeSpaceAR();


PS:AR的意思是不是Anchor Relative???


nodeParent->convertToWorldSpaceAR(node->getPosition()); //因爲默認是0,0的錨點,

所以其得到的座標點是 ccpAdd(nodeParent->convertToWorldSpace(node->getPosition()),ccp(nodeParent->getContentSize.width*0.5,nodeParent->getContentSize.height*0.5))
node2->convertToNodeSpaceAR(node1->getPosition); //因爲默認是0,0的錨點,

所以其得到的座標點是 ccpSub(nodeParent->convertToWorldSpace(node->getPosition()),ccp(node2->getContentSize.width*0.5,node2->getContentSize.height*0.5))


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