坐标系

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];
相关文章
相关标签/搜索