玩技术,Geeker
一个原创技术文章分享网站

菜鸟学习Cocos2d-x 3.x——坐标系简介

稳扎稳打

目前的手游行业是一个浮躁的行业,大家天天就想着怎么去发财。去想发财,无可厚非,我也想,做梦都想。但是作为刚刚步入游戏行业的我,还是决定稳扎稳打,步步为营,先把基本的技术搞扎实了。这里就开始总结一下Cocos2d-x中的坐标系。

进行游戏开发,肯定离开不了坐标系。这个精灵放在什么位置?那个控件又放在什么位置?我们的原点是在哪里?屏幕的左上角,还是在屏幕的左下角?那么Cocos2d-x的坐标系又是什么样子的呢?这些看似很基础的知识点,在实际开发中,如果没有扎实的基本功,就很容易出现各种错误,浪费时间,降低开发效率。

UI坐标系

在进行iOS或者Android界面开发时,它的坐标系规则如下图所示:

alt

  • 原点坐标(x=0, y=0)位于左上角;
  • X轴从屏幕最左边开始,由左向右渐增;
  • Y轴坐标从屏幕最上方开始,由上向下渐增

Cocos2d-x坐标系

Cocos2d-x坐标系是这里的重点,也是我们开发时考虑的最多的。由于Cocos2d-x是基于OpenGL和OpenGL ES的。该坐标系的规则如下:

  • 原点坐标(x=0, y=0)位于左下角;
  • X轴从屏幕最左边开始,由左向右渐增;
  • Y轴从屏幕最下方开始,由下向上渐增;

在Cocos2d-x中的场景,就是使用的该坐标系。

世界坐标系

世界坐标系也叫绝对坐标系,是游戏开发中建立的概念。它建立了描述其它坐标系所需要的参考标准。我们都可以使用世界坐标系来描述其它坐标系的位置。

Cocos2d-x中元素是有父子关系的层次结构,通过Node设置位置使用的是相对其父节点的本地坐标系,而非世界坐标系,最后在绘制屏幕的时候,Cocos2d-x会把这些元素的本地节点坐标映射成世界坐标系坐标。世界坐标系和OpenGL坐标系方向一致,原点在屏幕左下角,X轴向右,Y轴向上。

节点坐标系

节点坐标系也叫相对坐标系,它是与特定节点相关联的坐标系。每个节点都有独立的坐标系,当节点移动或改变方向时,和该节点关联的坐标系(它的子节点)将随之移动或改变方向。比如一个Layer上面有10个精灵,当移动这个Layer的时候,这些精灵也会跟着一起移动的。

Node节点类中,我们可以对节点进行位置的操作,而这些设置位置使用的就是父节点的节点坐标系。它和OpenGL坐标系方向一致,原点在屏幕左下角,X轴向右,Y轴向上。有的时候,我们需要将节点坐标转换成世界坐标,或者将世界坐标转换成节点坐标。在Node节点类中,就提供了对应的转换函数,下面我们就使用一下这些函数,加深对Cocos2d-x坐标系、世界坐标系和节点坐标系的理解。

转换API

在Cocos2d-x中提供了以下的API用来进行坐标转换。

/**
* 将世界坐标转换成节点坐标,忽略锚点的影响;结果是以点为单位。
*/
Vec2 convertToNodeSpace(const Vec2& worldPoint) const;

/**
* 将节点坐标转换成世界坐标,忽略锚点的影响;结果是以点为单位。
*/
Vec2 convertToWorldSpace(const Vec2& nodePoint) const;

/**
* 将世界坐标转换成节点坐标;结果是以点为单位。
* 会考虑到锚点的影响
*/
Vec2 convertToNodeSpaceAR(const Vec2& worldPoint) const;

/**
* 将节点坐标转换成世界坐标;结果是以点为单位。
* 会考虑到锚点的影响。
*/
Vec2 convertToWorldSpaceAR(const Vec2& nodePoint) const;

/**
* 将Touch对应的点转换成节点坐标,忽略锚点的影响。
*/
Vec2 convertTouchToNodeSpace(Touch * touch) const;

/**
* 将Touch对应的点转换成节点坐标,考虑锚点的影响。
*/
Vec2 convertTouchToNodeSpaceAR(Touch * touch) const;

好了,世界坐标系转节点坐标系,节点坐标系转世界坐标系,就这么几个函数就能搞定了,剩下的就是实际的应用了。对了,在实际中,一定要考虑到锚点的影响,可能你得到的结果,就是因为锚点的影响,而完全不同的。

坐标系变换原理

上面总结了坐标系之间转换的一些API函数,下面就来看看它们之间到底是如何转换的。看了网上很多人的博客,写的转换原理,写的都不错,就是看的云里雾里的,很多人都配上了坐标图,搞笑的是那些坐标图都是“一副”,也不知道谁抄袭的谁的。

下面就做一些简单的原理,没有过的图来说明,就是一些简短的文字,按照这些文字说明,你肯定能看的懂的。

  • convertToNodeSpace
    Vec2 newPosition = node1->convertToNodeSpace(node2->getPosition());
    将node2的位置坐标转换成相对于node1左下角顶点的坐标。转换方法:node1和node2位置不变,将坐标轴原点设置为node1的左下角顶点,重新计算node2->getPosition()这个点的坐标即为newPosition。
    当调用以下代码时,返回的是相对于其父节点的节点坐标,当然了,以下代码的实际用处并不大。

    Vec2 newPosition = node1->convertToNodeSpace(node1->getPosition());
  • convertToNodeSpaceAR
    Vec2 newPosition=node1->convertToNodeSpaceAR(node2->getPosition());
    将node2的位置坐标转换成相对于node1锚点的坐标。转换方法:node1和node2位置不变,将坐标轴原点设置为node1的锚点,重新计算node2->getPosition()这个点的坐标即为newPosition。
  • convertToWorldSpace
    Vec2 newPosition=node1->convertToWorldSpace(node2->getPosition());
    将node2的位置坐标转换成世界坐标。转换方法:node1的位置不变,世界坐标的坐标轴也不变,以node1的左下角顶点再建立一个坐标系(其实就是本地坐标),将node2->getPosition()这个点设置到新建的坐标系中,以原来的世界坐标系为参考,重新计算node2->getPosition()这个点的坐标即为newPosition。
  • convertToWorldSpaceAR
    Vec2 newPosition=node1->convertToWorldSpaceAR(node2->getPosition());
    将node2的位置坐标转换成世界坐标。转换方法:node1的位置不变,世界坐标的坐标轴也不变,以node1的锚点再建立一个坐标系,将node2->getPosition()这个点设置到新建的坐标系中,以原来的世界坐标系为参考,重新计算node2->getPosition()这个点的坐标即为newPosition。

淡定的总结

哦哦哦~
总结完成了,我希望我以最简单的语句,让你明白了这些最绕人概念。我希望我做到了,也希望你明白了。

2014年11月9日 于深圳。

未经允许不得转载:果冻想 » 菜鸟学习Cocos2d-x 3.x——坐标系简介

分享到:更多 ()

评论 12

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
  1. #5

    不错,值得学习。

    王语双个人网站2年前 (2014-11-10)回复
  2. #4

    cocos2dx原点在左下角吧。
    在Windows界面编程的时候才是左上角。

    dzz2年前 (2015-08-06)回复
  3. #3

    比别人讲的好理解些。

    a2年前 (2015-10-10)回复
  4. #2

    UP, Layout是个什么类型?

    BOBI1年前 (2015-11-05)回复
    • 看看Cocos2d里面的概念。

      果冻想1年前 (2015-11-05)回复
      • 我又来。 COCOS这东西变的太快了。现在3.10版本了,有的东西介绍的不怼了~~

        BOBI1年前 (2016-02-03)回复
        • 恩,的确是这样,我那个时候用的是3.0版本吧,COCOS更新太快,很多概念都变了,很多的实现方法也变了。

          果冻想1年前 (2016-02-03)回复
          • 啊?? 概念都变了啊

            qwer231年前 (2016-03-03)
          • 恩,有些变了。主要是Cocos更新太快了。这种更新快的东西,你追它会很累,就要把握它的根,而它的根就是源码。

            果冻想1年前 (2016-03-03)
  5. #1

    在网上搜cocos2dx教程 , 这个真心不错

    qwer231年前 (2016-03-03)回复

在这里玩技术,享受技术带来的疯狂

捐赠名单关于果冻