bool HelloWorld::init() { bool bRet = false; do { CC_BREAK_IF(! CCLayer::init()); //opengl的座標系和世界座標系相同,都是以屏幕左下角爲原點,向右爲x軸的增長方向,向上爲y軸的增長方向 //這裏的世界指的是遊戲世界 //屏幕座標系是以左上角爲原點,是咱們熟悉的 //本地座標系也叫節點座標系,世界座標系是相對於總體而言的,而本地座標系是相對於父節點而言的,理解這點很重要 //CCDirector::sharedDirector()->convertToGL() 轉換到OPENGL座標系 //CCDirector::sharedDirector()->convertToUI() 轉換到屏幕座標系 //CCNode::convertToWorldSpace() 把本地座標系轉換到世界座標系 //CCNode::convertToNodeSpace() 把世界座標系轉換到本地座標系 //sprite一、sprite2的圖片大小是100,100 CCSprite * sprite1 = CCSprite::create("image1.png"); sprite1->setPosition(ccp(100,100)); //將sprite2添加到sprite1節點中,這時候是以sprite1的左下角爲原點,雖然sprite1的錨點是在它圖片的中間 CCSprite * sprite2 = CCSprite::create("image2.png"); //setPosition中設置的座標是sprite2的本地座標 sprite2->setPosition(ccp(100,100)); sprite1->addChild(sprite2); //getPosition中得到的座標也是sprite2的本地座標 CCPoint point = sprite2->getPosition(); CCLog("point.x=%f,point.y=%f",point.x,point.y); //得到sprite2的opengl座標系,屏幕座標系,世界座標系,本地座標系 //convertToWorldSpace的傳入參數是sprite2的節點座標系(本地座標),也就是setPosition中傳入的參數,而convertToNodeSpace的傳入參數是sprite2的世界座標系,看清誰是調用者,傳入的參數又是什麼 CCPoint worldSpace = sprite1->convertToWorldSpace(point); CCPoint nodeSpace = sprite1->convertToNodeSpace(worldSpace); //如下倆個函數完成一樣的功能,只不過此次的sprite2的座標是基於sprite1的錨點的,而不是左下角了,因此咱們傳入了ccp(50,50) CCPoint worldSpaceAR = sprite1->convertToWorldSpaceAR(ccp(50,50)); CCPoint nodeSpaceAR = sprite1->convertToNodeSpaceAR(worldSpaceAR); //convertToUI中傳入的是opengl座標系,由於opengl座標和世界座標系是相同的,因此咱們傳入世界座標 CCPoint ui = CCDirector::sharedDirector()->convertToUI(worldSpace); CCPoint opengl = CCDirector::sharedDirector()->convertToGL(ui); CCLog("opengl.x=%f,opengl.y=%f",opengl.x,opengl.y); CCLog("ui.x=%f,ui.y=%f",ui.x,ui.y); CCLog("worldspace.x=%f,worldspace.y=%f",worldSpace.x,worldSpace.y); CCLog("nodeSpace.x=%f,nodeSpace.y=%f",nodeSpace.x,nodeSpace.y); CCLog("worldspaceAR.x=%f,worldspaceAR.y=%f",worldSpaceAR.x,worldSpaceAR.y); CCLog("nodeSpaceAR.x=%f,nodeSpaceAR.y=%f",nodeSpaceAR.x,nodeSpaceAR.y); this->addChild(sprite1); bRet = true; } while (0); return bRet; }
補充:node
1.屏幕座標系 原點在左上角,X軸向右,Y軸向下。
2.GL座標系 原點在左下角,X軸向右,Y軸向上。
3.世界座標系 指相對於整個屏幕的座標系,(0,0)就是屏幕的左下角,(320,480)就是屏幕的右上角。
4.本地座標系 相對於父對象的座標。函數
[obj.parent convertToWorldSpace:[obj position]]; //得到obj的世界座標 [obj.parent convertToNodeSpace:[obj position]]; //得到obj的本地座標 [[CCDirector sharedDirector] convertToGL:*****(0,0)]; //得到GL座標 [[CCDirector sharedDirector] convertToUI:*****(0,0)]; //得到屏幕座標
在調用任何須要設置位置的函數,或從函數獲取位置信息前,必需要明確這個函數使用哪一個座標系。好比調用CCNode類的setPosition函數,它使用的就是GL座標系。好比在處理觸摸事件時CCTouch對象中的座標就是屏幕座標系。
另外一個重要的座標系就是和Node相關的本地座標系。這個結構和通常作3D用的場景樹的概念是同樣的。因此從Node拿到的位置是該節點的本地座標,須要經過特定的函數才能把本地座標轉換爲世界座標。並且這裏的座標都用的是GL座標系。在CCNode對象中有幾個方便的函數能夠作座標轉換。convertToWorldSpace方法能夠把基於當前node的本地座標系下的座標轉換到世界座標系中。convertToNodeSpace方法能夠把世界座標轉換到當前node的本地座標系中。
另外一個關鍵的問題就是在cocos2d裏面就是各類對象的大小問題。由於在cocos2d裏CCNode對象有縮放的方法setScaleX和setScaleY。因此在獲取對象大小的時候就必須根據狀況明確指定獲取對象原始大小,仍是縮放後的大小。固然cocos2d裏提供了對應的函數來完成這些操做。
getContentSize 函數用來得到節點原始的大小。
boundingBox 函數用來得到通過縮放和旋轉以後的外框盒大小。ui
pTouch對象中的座標是屏幕座標系,因此必須轉換到GL座標系,再轉換到父節點的本地座標下。好在convertTouchToNodeSpace這個函數一次完成了這兩個轉換,能夠參考該庫的源碼,其中有具體的計算過程。this