cocos 坐标系的转换

  1. //实现点击屏幕背景玩家移动到该位置  
  2.     moveToClicked : function(eventString){  
  3.         var self = this;  
  4.         self.bg.on(eventString,function(event){  
  5.             //获取当前点击的全局坐标  
  6.             var temp = event.getLocation();  
  7.             cc.log("点击全局坐标:",temp.x,temp.y);  
  8.             //获取当前点击的局部坐标  
  9.             var tempPlayer = self.node.parent.convertToNodeSpaceAR(temp);  
  10.             cc.log("点击局部坐标:",tempPlayer.x,tempPlayer.y);  
  11.             //获取当前的玩家的局部坐标  
  12.             var po1 = self.node.getPosition();  
  13.             cc.log("玩家坐标:",po1.x,po1.y);  
  14.             //对玩家的行走进行左右交换  
  15.             if(po1.x < tempPlayer.x){  
  16.                 self.scaleX = -1;  
  17.             }else{  
  18.                 self.scaleY = 1;  
  19.             }  
  20.             //计算玩家移动的时间  
  21.             var playerTime = 1;  
  22.             //让玩家移动到点击位置  
  23.             var action = cc.moveTo(playerTime,  
  24.             self.node.stopAllActions();  
  25.             //进行移动  
  26.             self.node.runAction(action);  
  27.         })  
  28.     },  

知识点:1:通过点击事件获得点击的全局坐标位置

              event.getLocation(); 返回一个Vec2类型的数据

注意这里的全局坐标系是在Canvas的左下角的

            2:将全局坐标转换为节点坐标系:

            

[javascript]  view plain  copy
  1. <span style="font-size:18px;">convertToNodeSpaceAR(temp)</span>  
       
  • convertToNodeSpace 将一个点转换到节点 (局部) 坐标系。结果以 Vec2 为单位。
  • convertToWorldSpace 将一个点转换到世界空间坐标系。结果以 Vec2 为单位。
  • convertToNodeSpaceAR 将一个点转换到节点 (局部) 空间坐标系。结果以 Vec2 为单位。
    返回值将基于节点坐标。
  • convertToWorldSpaceAR 将一个点转换到世界空间坐标系。结果以 Vec2 为单位。
    返回值将基于世界坐标。
  • convertTouchToNodeSpace 将触摸点转换成本地坐标系中位置。
  • convertTouchToNodeSpaceAR 转换一个 cc.Touch(世界坐标)到一个局部坐标,该方法基于节点坐标。

         3:cc.moveTo(time,Number,y);返回一个ActionInterval 动作对象

/**
  * !#en
  * Moves a Node object to the position x,y. x and y are absolute coordinates by modifying its position property. <br/>
  * Several MoveTo actions can be concurrently called, and the resulting <br/>
  * movement will be the sum of individual movements.
  * !#zh 移动到目标位置。
  * @method moveTo
  * @param {Number} duration duration in seconds
  * @param {Vec2|Number} position
  * @param {Number} [y]
  * @return {ActionInterval}
  * @example
  * // example
  * var actionBy = cc.moveTo(2, cc.p(80, 80));
  */
  cc.moveTo = function (duration, position, y) {
  return new cc.MoveTo(duration, position, y);
  };
 
       4:Node.runAction(action);运行动作方法

笛卡尔坐标系

Cocos Creator 的坐标系和 cocos2d-x 引擎坐标系完全一致,而 cocos2d-x 和 OpenGL 坐标系相同,都是起源于笛卡尔坐标系。笛卡尔坐标系中定义右手系原点在左下角,x 向右,y 向上,z 向外,我们使用的坐标系就是笛卡尔右手系。

right hand

屏幕坐标系和 cocos2d-x 坐标系

标准屏幕坐标系使用和 OpenGL 不同的坐标系,和 cocos2d-x 坐标系有很大区别。

在 iOS, Android, Windows Phone 等平台用原生 SDK 开发应用时使用的是标准屏幕坐标系,原点为屏幕左上角,x 向右,y 向下。

Cocos2d-x 坐标系和 OpenGL 坐标系一样,原点为屏幕左下角,x 向右,y 向上。

screen vs cocos

世界坐标系(World Coordinate)和本地坐标系(Local Coordinate)

世界坐标系也叫做绝对坐标系,在 Cocos Creator 游戏开发中表示场景空间内的统一坐标体系,「世界」就用来表示我们的游戏场景。

本地坐标系也叫相对坐标系,是和节点相关联的坐标系。每个节点都有独立的坐标系,当节点移动或改变方向时,和该节点关联的坐标系将随之移动或改变方向。

Cocos Creator 中的  节点(Node)  之间可以有父子关系的层级结构,我们修改节点的  位置(Position)  属性设定的节点位置是该节点相对于父节点的  本地坐标系  而非世界坐标系。最后在绘制整个场景时 Cocos Creator 会把这些节点的本地坐标映射成世界坐标系坐标。

锚点(Anchor)

锚点(Anchor) 是节点的另一个重要属性,它决定了节点以自身约束框中的哪一个点作为整个节点的位置。我们选中节点后看到变换工具出现的位置就是节点的锚点位置。

锚点由 anchorX 和 anchorY 两个值表示,他们是通过节点尺寸计算锚点位置的乘数因子,范围都是 0 ~ 1 之间。(0.5, 0.5) 表示锚点位于节点长度乘 0.5 和宽度乘 0.5 的地方,即节点的中心。

anchor center

锚点属性设为 (0, 0) 时,锚点位于节点本地坐标系的初始原点位置,也就是节点约束框的左下角。

anchor left bottom

子节点的本地坐标系

锚点位置确定后,所有子节点就会以 锚点所在位置 作为坐标系原点,注意这个行为和 cocos2d-x 引擎中的默认行为不同,是 Cocos Creator 坐标系的特色!

假设场景中节点的结构如下图所示:

node tree

当我们的场景中包含不同层级的节点时,我们按照以下的流程确定每个节点在世界坐标系下的位置:

  1. 从场景根级别开始处理每个节点,上图中 NodeA 就是一个根级别节点。首先根据 NodeA 的 位置(Position) 属性和 锚点(Anchor) 属性,在世界坐标系中确定 NodeA 的显示位置和坐标系原点位置(和锚点位置一致)。
  2. 接下来处理 NodeA 的所有直接子节点,也就是上图中 NodeB 以及和 NodeB 平级的节点。根据 NodeB 的位置和锚点属性,在 NodeA 的本地坐标系中确定 NodeB 在场景空间中的位置和坐标系原点位置。
  3. 之后不管有多少级节点,都继续按照层级高低依次处理,每个节点都使用父节点的坐标系和自身位置锚点属性来确定在场景空间中的位置。

变换属性

除了上面介绍过的 锚点(Anchor) 之外,节点还包括四个主要的变换属性,下面我们依次介绍。

transform properties

位置(Position)

位置(Position) 由 x 和 y 两个属性组成,分别规定了节点在当前坐标系 x 轴和 y 轴上的坐标。

position

上图中节点 NodeA 位于场景根级别,他的位置是 (507, 354)(可以参考 场景编辑器 背景的刻度显示),其子节点 NodeC 的位置是 (345, 0),可以看到子节点的位置是以父节点锚点为基准来偏移的。

位置属性的默认值是 (0, 0),也就是说,新添加节点时,节点总会出现在父节点的坐标系原点位置。Cocos Creator 中节点的默认位置为 (0, 0),默认锚点设为 (0.5, 0.5)。这样子节点会默认出现在父节点的中心位置,在制作 UI 或组合玩家角色时都能够对所有内容一览无余。

在场景编辑器中,可以随时使用 移动变换工具 来修改节点位置。

旋转(Rotation)

旋转(Rotation) 是另外一个会对节点本地坐标系产生影响的重要属性,旋转属性只有一个值,表示节点当前的旋转角度。角度值为正时,节点顺时针旋转,角度值为负时,节点逆时针旋转。

rotation

上图所示的节点层级关系和前一张图相同,只是节点 NodeA 的 旋转(Rotation) 属性设为了 30 度,可以看到除了 NodeA 本身顺时针旋转了 30 度之外,其子节点 NodeC 也以 NodeA 的锚点为中心,顺时针旋转了 30 度。

在场景编辑器中,可以随时使用 旋转变换工具 来修改节点旋转。

缩放(Scale)

缩放(Scale) 属性也是一组乘数因子,由 scaleX 和 scaleY 两个值组成,分别表示节点在 x 轴和 y 轴的缩放倍率。

scale

上图中节点 NodeA 的缩放属性设为 (0.5, 1.0),也就是将该节点在 x 轴方向缩小到原来的 0.5 倍,y 轴保持不变。可以看到子节点 NodeC 图像也在 x 轴方向上进行了压缩,所以缩放属性会影响所有子节点。

子节点上设置的缩放属性会和父节点叠加作用,子节点的子节点会将每一层级的缩放属性全部相乘来获得在世界坐标系下显示的缩放倍率,这一点和位置、旋转其实是一致的,只不过位置和旋转属性是相加作用,只有缩放属性是相乘,作用表现的更明显。

缩放属性是叠加在位置、尺寸等属性上作用的,修改缩放属性时,节点的位置和尺寸不会变化,但显示节点图像时会先将位置和尺寸等属性和缩放相乘,得出的数值才是节点显示的真实位置和大小。

在场景编辑器中,可以随时使用 缩放变换工具 来修改节点缩放。

尺寸(Size)

尺寸(Size) 属性由 Width(宽度)和 Height (高度)两个值组成,用来规定节点的约束框大小。对于 Sprite 节点来说,约束框的大小也就相当于显示图像的大小。

因此尺寸属性很容易和缩放属性混淆,两者都会影响 Sprite 图像的大小,但他们是通过不同的方式来影响图像实际显示大小的。尺寸属性和位置、锚点一起,规定了节点四个顶点所在位置,并由此决定由四个顶点约束的图像显示的范围。尺寸属性在渲染 九宫格图像(Sliced Sprite) 时有至关重要的作用。

而缩放属性是在尺寸数值的基础上进行相乘,得到节点经过缩放后的宽度和高度。可以说在决定图像大小时,尺寸是基础,缩放是变量。另外尺寸属性不会直接影响子节点的尺寸(但可以通过 对齐挂件(Widget)间接影响),这一点和缩放属性有很大区别。

在场景编辑器中,可以随时使用 矩形变换工具 来修改节点尺寸。

猜你喜欢

转载自blog.csdn.net/lck8989/article/details/80214052