cocos2d-x官方文檔
笛卡爾坐標系
不同坐標系簡介
笛卡爾坐標系
你可能上學的時候就已經知道“笛卡爾坐標系”了,它在幾何課本里經常用到。如果你已經忘得差不多了,下面這些圖片可以很快喚起你的記憶:
在移動游戲開發過程中,有三種類型的坐標系你可能遇到:
UI坐標系
iOS/Android/Windows SDK中的通用UI坐標系:
- 起點坐標(x=0, y=0)位於左上角
- X軸從屏幕最左邊開始,由左向右漸增
- Y軸坐標從屏幕最上方開始,由上向下漸增
詳見下圖
Direct3D坐標系
DirectX 使用Left-handed Cartesian Coordinate
OpenGL和Cocos2d坐標系
Cocos2d-x/-html5/-iphone使用的坐標系和OpenGL的坐標系一樣,名為“Right-handed Cartesian Coordinate Syste”。
在2D世界中,我們僅會使用x軸和y軸。所以在你的cocos2d游戲中:
- 起點坐標(x=0, y=0)位於左下角,這意味着屏幕位於
- X軸從屏幕最左邊開始,由左向右漸增
- Y軸坐標從屏幕最下方開始,由下向上漸增
下面這張圖片有助於更好的闡述Cocos2d-x坐標:
一定要注意:通用UI坐標系和DirectX坐標系是不一樣的。
Parent and Childrens
由於每個類都繼承自CCNode(cocos2d-x的最頂層類),所以每個類都會默認有anchorPoint屬性。 當我們在一個位置畫一個的對象的時候,cocos2d-x會合並屬性位置和anchorPoint。當然,當旋轉一個對象時,cocos2d-x會圍繞繞anchorPoint旋轉的。
我們創建一個灰色父對象和一個藍色子對象。設置父對象位置是ccp(100,100),子對象的anchor point位於圓心。
CCSprite* parent = CCSprite::create("parent.png"); parent->setAnchorPoint(ccp(0, 0));// Anchor Point parent->setPosition(ccp(100, 100)); parent->setAnchorPoint(ccp(0, 0)); addChild(parent); //create child CCSprite* child = CCSprite::create("child.png"); child->setAnchorPoint(ccp(0.5, 0.5)); child->setPosition(ccp(0, 0)); parent->addChild(child);//add child sprite into parent sprite.
由於我們設置子對象的位置是ccp(0,0),父對象位置是ccp(100,100)。所以,子對象位置是:

錨點
作為例子,下面這個精靈有的錨點位於 ccp(0,0),位置位於ccp(0,0)。
這個矩形精靈將被放到它的父對象(layer)的左下角。
示例:
// create sprite CCSprite* sprite = CCSprite::create("bottomleft.png"); sprite->setAnchorPoint(ccp(0, 0));// Anchor Point sprite->setPosition(ccp(0,0)); addChild(sprite);
在另一個例子中,我們會擺放一個坐標為ccp(0.5,0.5)的anchorPoint,以便您更好的理解錨點的相對值。
// create sprite CCSprite* sprite = CCSprite::create("center.png"); sprite->setAnchorPoint(ccp(0.5, 0.5));// Anchor Point sprite->setPosition(ccp(0,0)); addChild(sprite);
正如你從圖中看出的,錨點取的不是像素值,此值的X和Y是相對於此節點的大小的。
獲取可視區域大小, 獲取可視區域起點 vs 獲取窗口大小
VisibleSize(可視區域大小)會返回此點的OpenGL視圖的可視區域大小。如果沒有調用CCEGLView::setDesignResolutionSize()的話,此值等於getWinSize的大小。 getVisibleOrigin(獲取可視區域起點)會返回此點的OpenGL視圖的可視區域起點。請移步Multi resolution support查看詳情。
如何轉換坐標
convertToNodeSpace:
舉例,convertToNodeSpace用於tile-based的游戲,即有一個大地圖。convertToNodeSpace會轉換openGL觸摸點轉成.tmx 地圖或者其他近似的坐標。
例子:
下面的圖片會展現,node1的錨點(0,0),node2的錨點是(1,1)。
我們會調用CCPoint point = node1->convertToNodeSpace(node2->getPosition()); 轉換node2的屏幕坐標為node1的位置。結果是,node2的位置是(-25,-60).
convertToWorldSpace:
convertToWorldSpace(常量 CCPoint& nodePoint) 轉換node坐標為SCREEN坐標。convertToWorldSpace會經常返回你的精靈的SCREEN位置,如果你想捕獲精靈的taps而且需要移動/縮放layer的時候,這可能非常有幫助。
CCPoint point = node1->convertToWorldSpace(node2->getPosition());
上面的代碼會轉換node2坐標為node2在屏幕上對應的坐標。
convertToWorldSpaceAR
convertToWorldSpaceAR返回相對錨點的位置:所以如果你的場景 - 根layer有一個錨點位於ccp(0.5f, 0.5f)。- 默認的,convertToNodeSpaceAR應返回相對於屏幕中心的位置。
convertToNodeSpaceAR - 和convertToWorldSpaceAR是一樣的邏輯。
示例代碼:
CCSprite *sprite1 = CCSprite::create("CloseNormal.png"); sprite1->setPosition(ccp(20,40)); sprite1->setAnchorPoint(ccp(0,0)); this->addChild(sprite1); CCSprite *sprite2 = CCSprite::cteate("CloseNormal.png"); sprite2->setPosition(ccp(-5,-20)); sprite2->setAnchorPoint(ccp(1,1)); this->addChild(sprite2); CCPoint point1 = sprite1->convertToNodeSpace(sprite2->getPosition()); CCPoint point2 = sprite1->convertToWorldSpace(sprite2->getPosition()); CCPoint point3 = sprite1->convertToNodeSpaceAR(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 = (15.000000,20.000000) position = (-25.000000,-60.000000) position = (15.000000,20.000000)