坐标系详解

Cocos2d-x坐标系和OpenGL坐标系相同,都是起源于笛卡尔坐标系。原点为屏幕左下角,x向右,y向上。

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

世界坐标系也叫做绝对坐标系,本地坐标系也叫相对坐标系,是和节点相关联的坐标系。每个节点都有独立的坐标系,当节点移动或改变方向时,和该节点关联的坐标系将随之移动或改变方向。我们通过Node的setPosition设定元素的位置使用的是相对与其父节点的本地坐标系而非世界坐标系。最后在绘制屏幕的时候cocos2d会把这些元素的本地坐标映射成世界坐标系坐标。

锚点(Anchor Point)

锚点是子节点相对于父节点设置位置时候的,一个基准参考点。设置这个参考点对应父节点上的位置。

  • Anchor Point的两个参数都在0~1之间。它们表示相对百分比位置。(0.5, 0.5)表示Anchor Point位于节点长度乘0.5和宽度乘0.5的地方,即节点的中心
  • 在Cocos2d-x中Layer的Anchor Point为默认值(0, 0),其他Node的默认值为(0.5, 0.5)。
  • 因为Layer比较特殊,它默认忽略锚点,所以要调用ignoreAnchorPointForPosition()接口来改变锚点,关于ignoreAnchorPointForPosition()接口的使用说明,请看一下示例。
  1. auto red = LayerColor::create(Color4B(, , , ), visibleSize.width/, visibleSize.height/);
  2. red->ignoreAnchorPointForPosition(false);
  3. red->setAnchorPoint(Point(0.5, 0.5));
  4. red->setPosition(Point(visibleSize.width/ + origin.x, visibleSize.height/ + origin.y));
  5.  
  6. auto green = LayerColor::create(Color4B(, , , ), visibleSize.width/, visibleSize.height/);
  7. green->ignoreAnchorPointForPosition(false);
  8. green->setAnchorPoint(Point(, ));
  9. red->addChild(green);
  10.  
  11. this->addChild(red, );

gnore Anchor Point全称是ignoreAnchorPointForPosition,开启锚点自由定位的方法。

  • 如果设置其值为true,则图片资源的Anchor Pont固定为左下角,否则即为所设置的位置。
  • 如果设置其值为false,则可以通过setAnchorPoint重新设置锚点的位置。

VertexZ,PositionZ和zOrder

  • VerextZ是OpenGL坐标系中的Z值
  • PositionZ是Cocos2d-x坐标系中Z值
  • zOrder是Cocos2d-x本地坐标系中Z值

在实际开发中我们只需关注zOrder,可以通过setPositionZ接口来设置PositionZ。

  • PositionZ是全局渲染顺序即在根节点上的渲染顺序。
  • zOrder则是局部渲染顺序,即该节点在其父节点上的渲染顺序,与Node的层级有关。

实例代码:

  1. auto red = LayerColor::create(Color4B(, , , ), visibleSize.width/, visibleSize.height/);
  2. red->ignoreAnchorPointForPosition(false);
  3. red->setPosition(Point(visibleSize.width / , visibleSize.height / ));
  4.  
  5. auto green = LayerColor::create(Color4B(, , , ), visibleSize.width/, visibleSize.height/);
  6. green->ignoreAnchorPointForPosition(false);
  7. green->setPosition(Point(visibleSize.width / , visibleSize.height / - ));
  8. red->setPositionZ();
  9. green->setPositionZ();
  10. this->addChild(red, );
  11. this->addChild(green, );

虽然green的zOrder大于red的zOder,但是因为red的PositionZ较大,所以red还是在green上面显示。

触摸点(Touch position)

处理触摸事件时需要用重写以下四个函数:

  1. virtual bool onTouchBegan(Touch *touch, Event * event);
  2. virtual void onTouchEnded(Touch *touch, Event * event);
  3. virtual void onTouchCancelled(Touch *touch, Event * event);
  4. virtual void onTouchMoved(Touch *touch, Event * event);

在函数中获取到touch,我们在设计游戏逻辑时需要用到触摸点在Cocos2d坐标系中的位置,就需要将touch的坐标转换成OpenGL坐标系中的点坐标。

Touch position是屏幕坐标系中的点,OpenGL position是Cocos2d-x用到的OpenGL坐标系上的点坐标。通常我们在开发中会使用两个接口getLocation()getLocationInView()来进行相应坐标转换工作。

此外,关于世界坐标系和本地坐标系的相互转换,在Node中定义了以下四个常用的坐标变换的相关方法。

  1. // 把世界坐标转换到当前节点的本地坐标系中
  2. Point convertToNodeSpace(const Point& worldPoint) const;
  3.  
  4. // 把基于当前节点的本地坐标系下的坐标转换到世界坐标系中
  5. Point convertToWorldSpace(const Point& nodePoint) const;
  6.  
  7. // 基于Anchor Point把基于当前节点的本地坐标系下的坐标转换到世界坐标系中
  8. Point convertToNodeSpaceAR(const Point& worldPoint) const;
  9.  
  10. // 基于Anchor Point把世界坐标转换到当前节点的本地坐标系中
  11. Point convertToWorldSpaceAR(const Point& nodePoint) const;

下面通过一个例子来说明这四个方法的理解和作用:

  1. auto *sprite1 = Sprite::create("HelloWorld.png");
  2. sprite1->setPosition(ccp(,));
  3. sprite1->setAnchorPoint(ccp(,));
  4. this->addChild(sprite1); //此时添加到的是世界坐标系,也就是OpenGL坐标系
  5.  
  6. auto *sprite2 = Sprite::create("HelloWorld.png");
  7. sprite2->setPosition(ccp(-,-));
  8. sprite2->setAnchorPoint(ccp(,));
  9. this->addChild(sprite2); //此时添加到的是世界坐标系,也就是OpenGL坐标系
  10.  
  11. //将 sprite2 这个节点的坐标ccp(-5,-20) 转换为 sprite1节点 下的本地(节点)坐标系统的 位置坐标
  12. Point point1 = sprite1->convertToNodeSpace(sprite2->getPosition());
  13.  
  14. //将 sprite2 这个节点的坐标ccp(-5,-20) 转换为 sprite1节点 下的世界坐标系统的 位置坐标
  15. Point point2 = sprite1->convertToWorldSpace(sprite2->getPosition());
  16.  
  17. log("position = (%f,%f)",point1.x,point1.y);
  18. log("position = (%f,%f)",point2.x,point2.y);
  1. 运行结果:
  2.  
  3. Cocos2d: position = (-25.000000,-60.000000)
  4. Cocos2d: position = (15.000000,20.000000)

其中:Point point1 = sprite1->convertToNodeSpace(sprite2->getPosition());

相当于sprite2 这个节点添加到了sprite1这个节点上(实际并没有),sprite2在世界坐标系中位置不变的,以sprite1作为假象父节点,来算出sprite2锚点相对于sprite1的本地坐标。

其中:Point point2 = sprite1->convertToWorldSpace(sprite2->getPosition());

相当于sprite2 这个节点添加到了sprite1这个节点上(实际并没有),把sprite2目前的世界坐标作为相当于sprite1的本地坐标值后,这个时候sprite2的实际位置将会发生变化,算出sprite2变化后的世界坐标。

cocos基础教程(6)坐标与锚点讲解的更多相关文章

  1. cocos基础教程(1)Mac环境下搭建

    下面主要介绍cocos2d-x环境的设置以及android的环境搭建 1.下载cocos2d-x 3.0正式版      http://www.cocos2d-x.org/download 2.下载a ...

  2. cocos基础教程(8)粒子效果

    简介 粒子系统是指计算机图形学中模拟特定现象的技术,它在模仿自然现象.物理现象及空间扭曲上具备得天独厚的优势,为我们实现一些真实自然而又带有随机性的特效(如爆炸.烟花.水流)提供了方便. 粒子属性 一 ...

  3. cocos基础教程(4)基础概念介绍

    在Cocos2d-x-3.x引擎中,采用节点树形结构来管理游戏对象,一个游戏可以划分为不同的场景,一个场景又可以分为不同的层,一个层又可以拥有任意个可见的游戏节点(即对象,游戏中基本上所有的类都派生于 ...

  4. cocos基础教程(3)cocos3.x版本目录结构介绍

    简介 cocos2d-x-3.x版本进行了很多优化,比如:将TTF字体用Atlas缓存,节点重排序官方声称提升了10倍速度,查找.移除节点方面也提高了10%,拆分渲染层到独立的线程运行: 另外,coc ...

  5. cocos基础教程(2)Window环境下搭建(补充)

    一.环境搭建 1.JDK.Eclipse与SDK 我用的JDK是1.7 Eclipse用的是Luna版的 这些之前都已经设好了,相关下载自己网上找吧 2. 下载最新的Cocos2d-x,我下的是3.5 ...

  6. cocos基础教程(2)Window环境下搭建

    第一步:开始安装VS2012  第二步:下载Cocos2d-x 3.4源码  配置环境变量 COCOS_CONTROL = E:\cocos2d-x-3.4\tools\cocos2d-console ...

  7. cocos基础教程(13)使用Physicals代替Box2D和chipmunk

    1.   概述 游戏中模拟真实的世界是个比较麻烦的事情,通常这种事情都是交给物理引擎来做.首屈一指的是Box2D了,它几乎能模拟所有的物理效果.而chipmunk则是个更轻量的引擎,能够满足简单的物理 ...

  8. cocos基础教程(12)点击交互的三种处理

    1.概述 游戏也好,程序也好,只有能与用户交互才有意义.手机上的交互大致可以分为两部分:点击和输入.其中点击更为重要,几乎是游戏中全部的交互.在Cocos2d-x 3.0中,更改了dispatch机制 ...

  9. cocos基础教程(9)声音和音效

    使用音效引擎 我们可以使用Cocos2d-x自带的CocosDension库来使用声音引擎.CocosDesion实现了简单易用的SimpleAudioEngine类,为了使用它,我们只需引入他的头文 ...

随机推荐

  1. Chrome扩展开发之三——Chrome扩展中的数据本地存储和下载

    目录: 0.Chrome扩展开发(Gmail附件管理助手)系列之〇——概述 1.Chrome扩展开发之一——Chrome扩展的文件结构 2.Chrome扩展开发之二——Chrome扩展中脚本的运行机制 ...

  2. .NET领域最为流行的IOC框架之一Autofac

    一.前言 Autofac是.NET领域最为流行的IOC框架之一,微软的Orchad开源程序使用的就是Autofac,Nopcommerce开源程序也是用的Autofac. Orchad和Nopcomm ...

  3. 慢牛APP相关截图

    慢牛APP相关截图 第一和第二个版本都是基于Sencha Touch+Cordova开发,公众号是采用Angularjs+D3开发,第三个版本是采用React Native开发. 第一个版本 第二个版 ...

  4. EventBus框架在Android多Pane(Fragment)中的应用

    通常多pane的设计中,比如Fragment A是个Headline,Fragement B是detail,那么B通常需要实现A的点击事件的接口,这样子的话,两个fragment就高耦合了,而且需要在 ...

  5. [C++基础]一个比较常用的配置文件/初始化文件读取程序

    在编程中,我们经常会遇到一些配置文件或初始化文件.这些文件通常后缀名为.ini或者.conf,可以直接用记事本打开.里面会存储一些程序参数,在程序中直接读取使用.例如,计算机与服务器通信,服务器的ip ...

  6. 开放封闭原则(OCP,Open Closed Principle)

    tks:http://www.cnblogs.com/Benjamin/p/3251987.html

  7. [工具类]泛型集合转换为DataTable

    写在前面 在实际项目中,用到了将集合转换为DataTable,就试着封装了一个方法,记录一下. 代码 using System; using System.Collections.Generic; u ...

  8. PHP时间日期比较

    若要使用PHP来比较日期,最好用DateTime::diff 但是这个是5.3才支持的,如果没有这样的环境,可以使用<.>来比较 如下例子,会输出right $date1=strtotim ...

  9. Cellphone Typing 字典树

    Cellphone Typing Time Limit: 5000ms Memory Limit: 131072KB   This problem will be judged on UVA. Ori ...

  10. Nginx简单实现网站的负载均衡

    在大型网站搭建时,都会考虑如果用户量每日不断增加,大量的并发访问,会不会给网站.数据库带来崩盘的灾难.今天我们就讨论一下,现实中如何解决这些问题的一套最为容易实现的方案. 控制并发,大家都会首先考虑的 ...