对于cocos2dx 获取 子节点相对于父节点的坐标,我们首先要分清什么是父节点,什么是子节点,只要这些概念清楚了,才可以去实施操作。    

Cocos2d-x 采用了场景、层、精灵的层次结构来组织游戏元素,

与此同时,这个层次结构还对应了游戏的渲染层次,因此游戏元素可以组织成树形结构,称作渲染树。
 
Cocos2d-x 把渲染树上的每一个游戏元素抽象为一个节点,即 Node。
一切游戏元素都继承自 Node,因此它们 都具有 Node 所提供的特性。
 
Node 定义了一个可绘制对象的通用特性,包括位置、缩放、是否可见、旋转角度等。
节点的最基本的功能包括:
1、包含其他 Node 对象;
2、接受各种事件与回调函数,如定时器事件;
3、运行动作。
 
渲染树中包含着许多子节点的 Node,类似一张画布,允许其他画布以不同的顺序叠加覆盖在自己上面,
一旦改变该节点的缩放和旋转等特性,就会影响该节点(包括它的子节点)的显示效果。
例如,把节点的旋转角度设置为 90 度,则它旋转 了 90 度,但它的子节点仍然保持相对位置和角度不变。
绘图的顺序通过 localZOrder属性描述,这与 addChild 中的 localZOrder参数是相同的。
 
Cocos2d-x 中的坐标系
绘图坐标系。它是最常见的坐标系,与 OpenGL 采用的坐标系相同,以左下角为原点,向右为 x 轴正方向,向上为 y 轴正方向,在 Cocos2d-x 中,一切绘图相关的操作都使用绘图坐标系,如游戏元素中的 Position 和 AnchorPoint 等属性。
纹理坐标系。纹理坐标系以左上角为原点,向右为 x 轴正方向,向下为 y 轴正方向。在 Cocos2d-x 中,只
有从纹理中截取部分矩形时才使用这个坐标系,如 Sprite 的 TextureRect 属性。
 
绘图属性
Sprite 所拥有的绘图相关属性。利用这些属性,我们可以对精灵呈现的方式进行精确的控制。
Size _contentSize:获取或设置此节点的内容大小。任何一个节点都需要确定它的内容大小,以便进行图形变换。对于精灵来说,_contentSize是它的纹理显示部分的大小;
对于层或场景等全屏的大型节点来说,_contentSize则是屏幕大小。
Point _anchorPoint与 Point _position: _anchorPoint 用于设置一个锚点,以便精确地控制节点的位置和变换。
 
_anchorPoint的两个参量 x 和 y 的取值通常都是 0 到 1 之间的实数,表示锚点相对于节点长宽的位置。
例如,把节点左下角作为锚点,值为(0,0);
把节点的中心作为锚点,值为(0.5,0.5);
把节点右下角作为锚点,值为(1,0)。
精灵的 _anchorPoint默认值为(0.5,0.5),其他节点的默认值为(0,0)。
_position用于设置节点的位置。
由于 _position指的是锚点在父节点中的坐标值,节点显示的位置通常与锚点有关。
因此,如果层与场景保持默认的位置,只需把层中精灵位置设为窗口长宽的一半即可让它显示在屏幕中央;
当多个节点嵌套时,每个节点的坐标系原点位于其内容的左下角。
因此,锚点在父节点中的坐标实际上是它相对于父节点左下角的坐标值。
对于场景或层等大型节点, 它们的_ignoreAnchorPointForPosition属性为 true, 
此时引擎会认为_anchorPoint 永远为(0,0);
而其他节点的该属性为 flase,它们的锚点不会被忽略。
 
float Rotation:获取或设置节点的旋转角度。
节点以自己的锚点为中心顺时针旋转一定量,单位是角度。旋转角度可以是任意实数。
 
float _scaleX(以及 float _scaleY与 float _scaleZ):Scale 用于获取或设置节点的缩放比例。
节点以锚点为中心缩放该比例。
Scale 的值代表整体缩放比例,而 _scaleX与 _scaleY分别代表 X 方向与 Y 方向的缩放比例。
默认情况下,这三个属性的值都是 1,表示节点不被缩放。
如果设置 Scale 属性,则 _scaleX和 _scaleY都会随之变为相同的值。
当然,我们也可以给_scaleX与 _scaleY设置不同的值,那样 Scale 属性的值就没有意义了。
 
bool _visible:获取或设置节点的可见性。
当 _visible为 true 时,节点会被显示,反之节点不会被显示。
在节点不被显示的时候,也不会被调用绘图方法(visit 与 draw)。
这个属性与众不同的是,它的访问器没有遵循属性的命名规范。
以下为它的访问器方法:
/**
 * Sets whether the node is visible
 *
 * The default value is true, a node is default to visible
 *
 * @param visible true if the node is visible, false if the node is hidden.
 */
virtual void setVisible(bool visible);
/**
 * Determines if the node is visible
 *
 * @see `setVisible(bool)`
 *
 * @return true if the node is visible, false if the node is hidden.
 */
virtual bool isVisible() const;

float _skewX与 float _skewY:获取或设置斜切角度。

节点以锚点为中心,平行 x 轴或 y 轴方向作一定角度的变形。
_skewX为平行 x 轴顺时针的变形,_skewY为平行 y 轴逆时针的变形,单位为角度。
_skewX与 _skewY的默认值为 0,表示节点没有斜切变形。

int _tag:获取或设置节点的标号。
在 Cocos2d-x 中,_tag的作用类似于标识符,以便快速地从节点的所有子节点中找出所需节点。
_tag可以用于定位子节点,因此添加到同一节点的所有 Node 之中,不能有两个节点的 _tag相同,否则就给定位
带来了麻烦。与 _tag相关的方法有 getTag、removeChildByTag等。
 
void *_userData; ///< A user assingned void pointer, Can be point to any cpp object
void *_userData;:获取或设置与节点相关的额外信息。
_userData为 void*类型,我们可以利用这个属性来保存任何数据。
 
Node的其他属性表

管理组织节点相关的方法

定时器事件

利用场景、层和精灵等游戏元素,我们可以构建游戏的框架,但是此时的游戏仍然是静止不动的。
在一切游戏中,游戏的状态都会随着时间的流逝而改变,同时我们还需要定时进行一些逻辑判断;
为了解决以上问题, 引入了定时器的概念。
定时器是以一定时间间隔连续引发游戏事件的工具。很显然,定时器就是使游戏动态变化所需的工具。
Cocos2d-x 为我们提供了两种方式实现定时机制--使用 update 方法以及使用 schedule 方法;
下面简要介绍这两种方式。
 
update 定时器
第一种定时机制是 Node 的刷新事件 update 方法,该方法在每帧绘制之前都会被触发一次。
由于绘图帧率有限,而每次更新最终会反映到画面上,
所以在每帧之间刷新一次已经足够应付大部分游戏逻辑处理的要求了。
<找小三>的碰撞检测机制就完全可以通过 update 事件来实现。
 
Node 默认并没有启用 update 事件,为了启用定时器,我们需要调用 scheduleUpdate 方法,并重载 update 以执行自己的代码。对应地,我们可以使用 unscheduleUpdate 方法停止定时器。
 
schedule 定时器
另一种定时机制是 Node 提供的 schedule 方法,可以实现以一定的时间间隔连续调用某个函数。
由于引擎的调度机制,这里的时间间隔必须大于两帧的间隔,否则两帧期间的多次调用会被合并成一次调用。
所以 schedule 定时器通常用在间隔较长的定时调用中,一般来说,事件间隔应在 0.1 秒以上。
实际开发中,许多定时操作都通过 schedule 定时器实现;
 
例如找小三中时间条的定时刷新等。
下面我们将以《找小三》为例来讲解如何使用 schedule 定时器。
游戏中有时钟表的跳动,构造timeRunning方法,初始化方法中添加以下代码来启用定时器:
this->schedule(schedule_selector(PlayGame::timeRunning),1.0f);

而在timeRunning方法中更新逻辑,以及时钟表的显示:

void PlayGame::timeRunning(float dt)
{
 if(second <= 0)
 {
  second = 0;
  pLabelTime->setString(toTimeMode(second));
  this->unschedule(schedule_selector(PlayGame::timeRunning));
  return;
 }
 second --;
 pLabelTime->setString(toTimeMode(second));
}

Node的schedule方法接受一个函数指针并启动一个定时器,利用schedule方法不同的重载可以指定触发间隔与延时。

schedule_selector 则是一个把指定函数转换为函数指针的宏,用于创建 schedule 方法所需的函数指针。

传入这个宏的函数应该包含一个 float 参数,表示距离前一次触发事件的时间间隔。

定时器相关方法

定时器机制是 Cocos2d-x 调度机制的基础,cocos2d-x的动作机制实际上也依赖定时器实现。

由于 Cocos2d-x 的调度是纯粹的串行机制,因此所有函数都运行在同一个线程,不会存在并行程序的种种麻烦,这大大简化了编程的复杂性。

其他与流程控制相关的事件

这些事件的默认实现通常负责处理定时器和动作的启用与暂停,因此必须在重载方法中调用父类的方法;

例如,我们可以 在游戏层开始时设置事件监听器: