Cocos2d-x 详解坐标系统
这篇博文将介绍一下在cocos2dx中的一些坐标系统概念:
一、
(1)OpenGL坐标系
Cocos2D-x以OpenGL和OpenGL ES为基础,所以自然支持OpenGL坐标系。该坐标系原点在屏幕左下角,x轴向右,y轴向上。
(2)屏幕坐标系
屏幕坐标系使用的是不同的坐标系统,原点在屏幕左上角,x轴向右,y轴向下。iOS的屏幕触摸事件CCTouch传入的位置信息使用的是该坐标系。因此在Cocos2D-x中对触摸事件做出响应前,需要首先把触摸点转化到OpenGL坐标系。这一点在后面的触屏信息中会详细介绍,可以使用CCDirector的convertToGL方法来完成这一转化。
在处理触摸事件的回调方法中,我们会经常碰到这两者的坐标系统的转换处理问题。在CCTouch文件中已经为我们封装好了获取触摸点在OpenGL坐标系统和屏幕坐标系统中的坐标位置。
①从触摸点获取到在屏幕坐标系中的坐标
CCSprite *sprite1 = CCSprite::create("CloseNormal.png"); sprite1->setPosition(ccp(20,40)); sprite1->setAnchorPoint(ccp(0,0)); this->addChild(sprite1); //此时添加到的是世界坐标系,也就是OpenGL坐标系 CCSprite *sprite2 = CCSprite::create("CloseNormal.png"); sprite2->setPosition(ccp(-5,-20)); sprite2->setAnchorPoint(ccp(1,1)); this->addChild(sprite2); //此时添加到的是世界坐标系,也就是OpenGL坐标系 //将 sprite2 这个节点的坐标ccp(-5,-20) 转换为 sprite1节点 下的本地(节点)坐标系统的 位置坐标 CCPoint point1 = sprite1->convertToNodeSpace(sprite2->getPosition()); //将 sprite2 这个节点的坐标ccp(-5,-20) 转换为 sprite1节点 下的世界坐标系统的 位置坐标 CCPoint point2 = sprite1->convertToWorldSpace(sprite2->getPosition()); CCLog("position = (%f,%f)",point1.x,point1.y); CCLog("position = (%f,%f)",point2.x,point2.y);
运行结果:
下面解释一下:我们添加了两个节点sprite1(node1),sprite2(node2)。
其中 : CCPoint point1 = sprite1->convertToNodeSpace(sprite2->getPosition());
相当于我们将sprite2这个节点添加到(实际没有添加,只是这样理解)sprite1这个节点上,那么就需要使用sprite1这个节点的节点坐标系统,这个节点的节点坐标系统的原点在(20,40),而sprite1的坐标是(-5,-20),那么经过变换之后,sprite1的坐标就是(-25,-60)。
其中 : CCPoint point2 = sprite1->convertToWorldSpace(sprite2->getPosition());
此时的变换是将sprite2的坐标转换到sprite1的世界坐标系下,而其中世界坐标系是没有变化的,始终都是和OpenGL等同,只不过sprite2在变换的时候将sprite1作为了”参照“而已。所以变换之后sprite2的坐标为:(15,20)
通俗一点理解就是,sprite2的坐标在sprite1节点左下角(原点)坐标的基础上加上sprite2的坐标(也即基于sprite1原点的平移,平移坐标就是sprite1的ccp(-5,-20))就可以得到sprite2变换后的坐标:(15,20)=sprite1原点坐标(20,40)+ 平移(-5,-20)
2、convertToNodeSpaceAR 和 convertToWorldSpaceAR
注意到这两个方法只不过增加了AR的约束,也即锚点。其意思是:修改变换的基准。这样理解:
convertToNodeSpaceAR,就是将节点坐标系的坐标原点修改在其锚点位置。(convertToNodeSpace 节点坐标系的原点位置是其左下角)
convertToWorldSpaceAR,就是在变换的时候将参照坐标修改到其锚点位置。(convertToWorldSpace 参照坐标是在其左下角)
下面给出一个例子说明一下这两个方法:
CCSprite *sprite1 = CCSprite::create("CloseNormal.png"); sprite1->setPosition(ccp(100,100)); sprite1->setAnchorPoint(ccp(0.5,0.5)); this->addChild(sprite1); CCSprite *sprite2 = CCSprite::create("CloseNormal.png"); sprite2->setPosition(ccp(-5,-20)); sprite2->setAnchorPoint(ccp(1,1)); this->addChild(sprite2); CCPoint point3 = sprite1->convertToNodeSpaceAR(sprite2->getPosition()); CCPoint point4 = sprite1->convertToWorldSpaceAR(sprite2->getPosition()); CCLog("position = (%f,%f)",point3.x,point3.y); CCLog("position = (%f,%f)",point4.x,point4.y);
运行结果:Cocos2d: position = (-105.000000,-120.000000)Cocos2d: position = (95.000000,80.000000)首先关于 convertToNodeSpaceAR 我们可以用下面这个图来看。
sprite1节点的节点坐标系原点现在变成节点的锚点所在位置,在这个位置建立一个坐标系,那么就可以确定sprite2转换到这个节点坐标系所在的位置了。
而关于 convertToWorldSpaceAR 其实其变换和 convertToWorldSpace 是十分类似的,只不过其原点变成其节点的锚点,而不是左下角。
那么变换的过程: sprite2变换后的坐标(90,80) = sprite1的锚点(100,100) + 平移(-5,-20)。
这样介绍大概可以弄清楚了吧!
参考文章:http://blog.163.com/zjf_to/blog/static/201429061201292193855498/