convertToNodeSpace和convertToWorldSpace的终极用法总结

有些接口吧,一段时间不用,再捡起来的时候,总害怕哪里用出问题。

然而百度相关技术文章,越查越来气。故弄玄虚的东西太多,浪费时间。

遂写一点自己的总结好了。

 

大致用法举例:

ptNode = node.convertToNodeSpace(ptWorld);

一个在世界坐标系(原点为屏幕左下角)中坐标值为ptWorld的点,通过这个接口,

得到这个点在节点坐标系(原点为节点左下角)的坐标ptNode

 

一张图说明问题:

convertToNodeSpace和convertToWorldSpace的终极用法总结

node直接放在世界坐标系中,position为(10, 10),anchorPoint为(0.5, 0.5),size为(10, 10),即为图中的红色正方形。

传入ptWorld为(20, 20),那么通过ptNode = node.convertToNodeSpace(ptWorld);就是得到世界坐标系中的点(20, 20),在红色坐标系中的坐标值。因此接口输出ptNode为(15, 15)。

这里这个例子很简单,用眼睛和心算就能从图中得到结果。然而这里节点坐标系相对于世界坐标系只有平移,也就是说节点相对于世界原点只有平移。当节点同时还有缩放和旋转属性时,节点坐标系也会有相应变化。此外多层节点嵌套时,节点坐标系和世界坐标系将变得很复杂。

这个接口的妙处就是一步到位,完全不用考虑这些事情。

 

convertToWorldSpace则是convertToNodeSpace的逆运算,因此大致用法如下:

ptWorld = node.convertToNodeSpace(ptNode);

一个在节点左下坐标系(原点为节点左下角)中坐标值为ptNode的点,通过这个接口,

得到这个点在世界坐标系(原点为屏幕左下角)的坐标ptWorld

还是用上面的例子,当传入ptNode为(15,15)时,接口输出ptWorld为(20, 20)。

 

这两个函数还有AR版本,convertToNodeSpaceAR和convertToWorldSpaceAR,和原版相比,唯一的区别是节点坐标系的原点不为节点左下角,而是节点的锚点。以convertToNodeSpaceAR为例,红色的坐标系发生了改变:

convertToNodeSpace和convertToWorldSpace的终极用法总结

因此通过ptNode = node.convertToNodeSpaceAR(ptWorld);输出的ptNode为(10, 10)。

 

 

最后,说一下Cocos Creator中相关的坑

这个坑源于两点:

1. Cocos Creator中的position/getPosition()取得的子节点位置,是以父节点锚点为原点的。

2. 这四个接口的性质在Cocos Creator和Cocos2dx中一样

有很多场合,需要计算某个节点node(的锚点)在世界坐标系中的位置,因此,这种用法很常见:

node.getParent().convertToWorldSpace(node.getPosition());

这种写法在Cocos2dx中没有问题,但是在CocosCreator中则不行,例如这样的节点嵌套结构:

convertToNodeSpace和convertToWorldSpace的终极用法总结

相关数据如下图:

convertToNodeSpace和convertToWorldSpace的终极用法总结

则相关调用如下:

var pos2node2.position;  //pos2为(0, 0)

var wPos = node1.convertToWorldSpace(pos2); //wPos为(10, 10),并非我们想得到的(30, 30)

注意:世界坐标系依然是以左下角为原点,Canvas只是加在场景根节点上的一个有尺寸的节点而已。世界坐标与其无关。

 

如果想实现和过去性质相同的逻辑,请改用

convertToWorldSpaceARconvertToNodeSpaceAR。