座標系

Cocos2d 中 分有大體4個座標系html

1. World space coordinate 世界座標系
2. Opengl es coordinate Op 座標系
 
世界座標系和 Opengl es 座標系 是 同樣的  , 都是以x y( 0, 0) 原地在屏幕的 左下角 , x 軸 朝上, y軸朝右 主要照顧遊戲時候 常常爲 橫屏 使用。
關於世界座標系轉換的 理解 我在stackoverflow 老外這麼解釋的
convertToWorldSpace: method converts one node space to parent node space ... until it gets to world space.
轉換座標系 到 世界座標系的方法是 轉換一個節點的座標系到它的父節點座標系 直到世界座標系 就是屏幕的座標系。
那麼能夠理解爲converToWorldSpace 這個方法就是把節點的座標系轉換到父節點的座標系
Cocos2d <wbr>座標系 <wbr>淺析

 
下面用2個精靈圖片, 圖片直接取自cocos2d 自帶的圖片 一個 72*72 一個 50*50
而後把 小的精靈 插入到 大的精靈的 座標系中
 

player1 = [CCSprite spriteWithFile:@"Icon-72.png" rect:CGRectMake(0072,72)];node

player1.position = ccp(winWidth/2, winHeight/2);ios

[self addChild:player1 z:0];ide

player2 = [CCSprite spriteWithFile:@"Icon-Small-50.png" rect:CGRectMake(00,5050)];測試

[player1 addChild:player2 z:0];ui

而後獲得觸摸的點的 本地Node space 座標系
 

CGPoint touchLocation = [touch locationInView:touch.view];this

touchLocation = [[CCDirector sharedDirectorconvertToGL:touchLocation];url

touchLocation = [player1 convertToNodeSpace:touchLocation];spa

Cocos2d <wbr>座標系 <wbr>淺析

能夠看到 點擊 72*72圖片的時候座標是 13,12 那就說明 座標系的原點是在 圖片的 左下角 而不是 屏幕的 左下角, 說明咱們如今是在 local Node space coordinate 中。
 
那麼如今轉換到世界座標系中呢? 或者轉換到父級 座標系 就是 opengl es coordinate 中
 
添加如下代碼
 

 CCSprite *player = (CCSprite*)[self getChildByTag:77];3d

 touchLocation = [player1 convertToWorldSpace:touchLocation];

 NSLog(@"%f, %f", touchLocation.x, touchLocation.y);

而後點擊圖片後獲得的座標是 223,122

這就說明如今所在的座標系是world space 或者說 opengl es 座標系中 也就是 圖片的 父級座標系

Cocos2d <wbr>座標系 <wbr>淺析

 
3. Node space coordinate 座標系
 
Node space coordinate 是本地座標系 也就是 圖片或者精靈自己的座標系 通常都是 以圖片左下角 爲原點(0,0)
4. UIkit coordinate uikit 座標系
 
這是 ios view 的座標系 和 opengl es 座標系不一樣的是 這個座標系 是以 左上角 爲 原點 x 軸 向右 , y 軸向下 延生, 主要是大多數 應用 除了 遊戲以外 用戶都是習慣豎着 拿 設備。
 
Cocos2d <wbr>座標系 <wbr>淺析

 
 通常來講 咱們獲得的 觸摸點的  座標都是 UIKit 座標系的 因此通常在觸摸方法好比 cctouchbegan 中
首先把 UIKit 座標轉化成 opengl es 的 

 CGPoint touchLocation = [touch locationInView:touch.view];

 touchLocation = [[CCDirector sharedDirectorconvertToGL:touchLocation];

若是直接想獲得 用戶是否點擊到 精靈 或者圖片上面的 本地座標

再添加這條

 

touchLocation = [player1 convertToNodeSpace:touchLocation];

固然 用 一條代碼 能夠代替上面的 2條 省事的話

touchLocation = [player1 convertTouchToNodeSpace: touch];

 ——————————————————————————————————————————————————

// converting local node coordinates to world space
-(CGPoint) convertToWorldSpace:(CGPoint)nodePoint;
-(CGPoint) convertToWorldSpaceAR:(CGPoint)nodePoint;
 
// converting world coordinates to local node space
-(CGPoint) convertToNodeSpace:(CGPoint)worldPoint;
-(CGPoint) convertToNodeSpaceAR:(CGPoint)worldPoint;
 
// converting touch (world) coordinates to local node space
-(CGPoint) convertTouchToNodeSpace:(UITouch*)touch;
-(CGPoint) convertTouchToNodeSpaceAR:(UITouch*)touch;

發現convertToGL 是 CCDirector 類的方法 返回 CGPoint
 
[[CCDirector sharedDirector] convertToGL: CGPoint]
 
先大致放在這
 
爲何要進行 座標系 之間的轉換 能夠看看 老外這麼說的
A common case is the node's boundingBox.origin point, which is in local node coordinates. You may need to convert this boundingBox.origin to another node's local coordinate space in order to test for collision between nodes, or you may want to convert it to world coordinate space in order to perform collision tests with a bunch of nodes at once.

通常的狀況 節點的 boundingBox 原點 在本地的節點座標系當中。 那麼你也許須要把這個節點的 boundingBox 原點 轉換到另一個 節點的本地座標系當中 來判斷 2個 節點是否是碰撞了。或者把這個節點的 boundingBox 轉換到 世界座標系當中來測試一個節點和一羣節點的碰撞。

如今來試試第一種狀況 把 一個節點 加入到 另一個節點的座標系當中
 
// convert a world point to node coordinate space
CGPoint localPoint = [someNode convertToNodeSpace:worldPoint];

如今 我用player1 和 player2 , 把player2 的座標系 換成 player1 的 再判斷點擊是否是在座標系內
touchLocation = [player2 convertToNodeSpace:player1.position];

if(CGRectContainsPoint([player2 textureRect], touchLocation)) {

NSLog(@"Inside");

}else {

NSLog(@"Outside");

}

Cocos2d <wbr>座標系 <wbr>淺析-2 <wbr>座標轉換

能夠看到 player2 的 圖片位於靠近原點的位置 可是它的座標系已經轉換爲player1 的 local Node space coordinate。

而後點擊控制檯獲得
Cocos2d <wbr>座標系 <wbr>淺析-2 <wbr>座標轉換
能夠看到 無論你怎麼點都是 215, 135 的座標 應爲 player1的position 座標 位於 player2 的本地節點座標系(Local Node space coordinate)當中, 原點是 player2 的 原點 而不是屏幕左下角的原點
 
先在把player1 移動位置放到 player2 上面 看看 發生什麼
 
Cocos2d <wbr>座標系 <wbr>淺析-2 <wbr>座標轉換
再點擊player1 和 player2 控制檯輸出

Cocos2d <wbr>座標系 <wbr>淺析-2 <wbr>座標轉換

能夠看到 座標原點已經改變了 

下面給出了幾個經常使用的座標系轉換的狀況
把本地座標系轉換爲世界座標系(父)
// convert a local node point to world coordinate space
CGPoint worldPoint = [someNode convertToWorldSpace:localPoint];
本地座標系相對另一個座標系錨點的偏移量, 這個還不太清楚 等會研究
// same as above, but localPoint is offset to be relative to anchorPoint of someNode
CGPoint worldPointAR = [someNode convertToWorldSpaceAR:localPoint];
本地座標系轉換到另一個節點的座標系當中(這裏是父座標系)
// convert a local node point to another node's coordinate space
CGPoint targetNodeLocalPoint = [targetNode convertToWorldSpace:otherNodeLocalPoint];
 和上面同樣只不過變成了錨地的偏移量
// same as above, but otherNodeLocalPoint is offset to be relative to anchorPoint of targetNode
CGPoint targetNodeLocalPointAR = [targetNode convertToWorldSpaceAR:otherNodeLocalPoint];
 
接下來研究下什麼是描點之間座標系的轉換 Anchor relative coordinate conversion

Normally (and unfortunately) cocos2d places child nodes relative to the parent's lower left contentSize corner. In the case of a sprite using a 100x100 image, and the sprite positioned at 400x300, a child node with a position of 0x0 will be centered on the coordinate 400-(100/2)x300-(100/2) = 350x250. This is odd but that's the way cocos2d works. The non-AR conversion coordinates convert coordinates relative to this origin point 350x250 whereas the AR variants convert coordinates relative to the node's anchorPoint, in this case relative to 400x300.

通常或者不幸的是 cocos2d 放置 子節點的位置 是相對 父節點的 左下角的位置這樣的方式。 在這個例子裏 使用100*100的圖片, 精靈位置是 400,300, 一個子節點的位置是 0,0 應該是位於400-100/2 = 350,和300-100/2 = 250中心的地方. 這比較奇怪, 但這就是cocos2d 的方式。(按照通常思惟 應該在原點 就是 400, 300 的地方 可是 父節點的錨點不是 0.5 , 0.5 而是 0,0)

The difference between non-AR and AR coordinate conversion methods is merely the distance between the node's lower left origin point and the anchorPointInPoints property. Should the anchorPoint of the node and all of its parents be set to 0x0 (not recommended btw) then both coordinate conversion methods would give you the same results.

這樣錨地和 無錨點的座標系之間轉換 將出現很微小的偏差, 應該把節點的錨點和全部它的父節點都設置爲0,0 ,你將獲得正確的結果.

 

最後是 UIKit coordinate 轉換  UIKit coordinate conversion
CGPoint cocosPoint = [[CCDirector sharedDirector] convertToGL:uikitPoint];
CGPoint uikitPoint = [[CCDirector sharedDirector] convertToUI:cocosPoint];
 
可是節點本地座標系轉換到UIkit 座標系 以下
CGPoint cocosPoint = [someNode convertToWorldSpace:localPoint];
CGPoint uikitPoint = [[CCDirector sharedDirector] convertToUI:cocosPoint];

反之

CGPoint cocosPoint = [[CCDirector sharedDirector] convertToGL:uikitPoint];
CGPoint localPoint = [someNode convertToNodeSpace:cocosPoint];
相關文章
相關標籤/搜索