Cocos2d-x坐标系介绍

Cocos2d-x坐标系介绍

在图形图像和游戏应用开发中坐标系是非常重要的,我们在Android和iOS等平台应用开发的时候使用的二维坐标系它的原点是在左上角的。而在Cocos2d-x坐标系中它原点是在左下角的,而且Cocos2d-x坐标系又可以分为:世界坐标和模型坐标。

UI坐标

UI坐标就是Android和iOS等应用开发的时候使用的二维坐标系。它的原点是在左上角的。

UI坐标原点是在左上角,x轴向右为正,y轴向下为正。我们在Android和iOS等平台使用的视图、控件等都是遵守这个坐标系。然而在Cocos2d-x默认不是采用UI坐标,但是有的时候也会用到UI坐标,例如在触摸事件发生的时候,我们会获得一个触摸对象(Touch),触摸对象(Touch)提供了很多获得位置信息的函数,如下面代码所示:

Point touchLocation = touch->getLocationInView();

使用getLocationInView()函数获得触摸点坐标事实上就是UI坐标,它的坐标原点在左上角。而不是Cocos2d-x默认坐标,我们可以采用下面的语句进行转换:

Point touchLocation2 = Director::getInstance()->convertToGL(touchLocation);

通过上面的语句就可以将触摸点位置从UI坐标转换为OpenGL坐标,OpenGL坐标就是Cocos2d-x默认坐标。

OpenGL坐标

我们在上面提到了OpenGL坐标,OpenGL坐标是种三维坐标。由于Cocos2d-x底层采用OpenGL渲染,因此的默认坐标就是OpenGL坐标,只不过只采用两维(x和y轴)。如果不考虑z轴,OpenGL坐标的原点在左下角。

提示:  三维坐标根据z轴的指向不同分为:左手坐标和右手坐标。右手坐标是z轴指向屏幕外。左手坐标是z轴指向屏幕里.OpenGL坐标是右手坐标,而微软平台的Direct3D[1]是左手坐标。

世界坐标和模型坐标

由于OpenGL坐标有可以分为:世界坐标和模型坐标,所以Cocos2d-x的坐标也有世界坐标和模型坐标。

你是否有过这样的问路经历:张三会告诉你向南走一公里,再向东走500米。而李四会告诉你向右走一公里,再向左走500米。这里两种说法或许都可以找到你要寻找的地点。张三采用的坐标是世界坐标,他把地球作为参照物,表述位置使用地理的东、南、西和北。而李四采用的坐标是模型坐标,他让你自己作为参照物,表述位置使用你的左边、你的前边、你的右边和你的后边。

我们看看图3-21,从图中可以看到A的坐标是(5,5),B的坐标是(4,6),事实上这些坐标值就是世界坐标。如果采用A的模型坐标来描述B的位置,则B的坐标是(1,-1)。

有的时候我们需要将世界坐标与模型坐标互相转换。我们可以通过Node对象如下函数实现:

Point convertToNodeSpace ( const Point & worldPoint )。将世界坐标转换为模型坐标。

Point convertToNodeSpaceAR ( const Point & worldPoint )。将世界坐标转换为模型坐标。AR表示相对于锚点。

Point convertTouchToNodeSpace ( Touch * touch )。将世界坐标中触摸点转换为模型坐标。

Point convertTouchToNodeSpaceAR ( Touch * touch )。将世界坐标中触摸点转换为模型坐标。AR表示相对于锚点。

Point convertToWorldSpace ( const Point & nodePoint )。将模型坐标中触摸点转换为世界坐标。

Point convertToWorldSpaceAR ( const Point & nodePoint )。将模型坐标中触摸点转换为世界坐标。AR表示相对于锚点。

下面我们通过两个例子了解一下世界坐标与模型坐标互相转换。

1、世界坐标转换为模型坐标

下面是世界坐标转换为模型坐标实例运行结果。

在游戏场景中有两个Node对象,其中Node1的坐标是(400, 500),大小是300 x 100像素。Node2的坐标是(200, 300),大小也是300 x 100像素。这里的坐标事实上就是世界坐标,它的坐标原点是屏幕的左下角。

编写代码如下:

bool HelloWorld::init()
{
   
    if( !Layer::init() )
    {
         returnfalse;
    }
 
    SizevisibleSize = Director::getInstance()->getVisibleSize();
    Pointorigin = Director::getInstance()->getVisibleOrigin();
    autocloseItem = MenuItemImage::create(
         "CloseNormal.png",
         "CloseSelected.png",
         CC_CALLBACK_1(HelloWorld::menuCloseCallback,this));
 
    closeItem->setPosition(Point(origin.x+ visibleSize.width - closeItem->getContentSize().width/2 ,
         origin.y+ closeItem->getContentSize().height/2));
 
    automenu = Menu::create(closeItem, NULL);
    menu->setPosition(Point::ZERO);
    this->addChild(menu,1);
    //创建背景
    autobg = Sprite::create("bg.png");                                                                                         ①
    bg->setPosition(Point(origin.x+ visibleSize.width/2,
         origin.y+ visibleSize.height/2));
 
    this->addChild(bg,0);                                                                                                                      ②
    //创建Node1
    autonode1 = Sprite::create("node1.png");                                                                           ③
    node1->setPosition(Point(400,500));
    node1->setAnchorPoint(Point(1.0,1.0));
 
    this->addChild(node1,0);                                                                                                               ④
    //创建Node2
    autonode2 = Sprite::create("node2.png");                                                                           ⑤
    node2->setPosition(Point(200,300));         
    node2->setAnchorPoint(Point(0.5,0.5));
 
    this->addChild(node2,0);                                                                                                               ⑥
 
    PointPoint1 = node1->convertToNodeSpace(node2->getPosition());                                      ⑦
    PointPoint3 = node1->convertToNodeSpaceAR(node2->getPosition());                                 ⑧
   
    log("Node2NodeSpace = (%f,%f)",Point1.x,Point1.y);
    log("Node2NodeSpaceAR = (%f,%f)",Point3.x,Point3.y);
 
    returntrue;
}

代码①~②行是创建背景精灵对象,这个背景是一个白色900 x 640像素的图片。代码第③~④行是创建Node1对象,并设置了位置和锚点属性。代码第⑤~⑥行是创建Node2对象,并设置了位置和锚点属性。第⑦行代码将Node2的世界坐标转换为相对于Node1的模型坐标。而第⑧行代码是类似的,它是相对于锚点的位置。

运行结果如下:

Node2 NodeSpace = (100.000000,-100.000000)

Node2 NodeSpaceAR =(-200.000000,-200.000000)

Node2的世界坐标转换为相对于Node1的模型坐标,就是将Node1的左下角作为坐标原点(图3-22中的A点),我们不难计算出A点的世界坐标是(100,400),那么convertToNodeSpace函数就是A点坐标减去C点坐标,结果是(-100,100)。而convertToNodeSpaceAR函数要考虑锚点,因此坐标原点是B点,B点坐标减去C点坐标,结果是(-200, -200)。

2、模型坐标转换为世界坐标

下面是模型坐标转换为世界坐标实例运行结果。

在游戏场景中有两个Node对象,其中Node1的坐标是(400, 500),大小是300 x 100像素。Node2是放置在Node1中的,它对于Node1的模型坐标是(0, 0),大小也是150 x 50像素。

编写代码如下:

bool HelloWorld::init()
{
    if( !Layer::init() )
    {
         returnfalse;
    }
 
    SizevisibleSize = Director::getInstance()->getVisibleSize();
    Pointorigin = Director::getInstance()->getVisibleOrigin();
 
    autocloseItem = MenuItemImage::create(
         "CloseNormal.png",
         "CloseSelected.png",
         CC_CALLBACK_1(HelloWorld::menuCloseCallback,this));
 
    closeItem->setPosition(Point(origin.x+ visibleSize.width - closeItem->getContentSize().width/2 ,
         origin.y+ closeItem->getContentSize().height/2));
 
    automenu = Menu::create(closeItem, NULL);
    menu->setPosition(Point::ZERO);
    this->addChild(menu,1);
 
    //创建背景
    autobg = Sprite::create("bg.png");
    bg->setPosition(Point(origin.x+ visibleSize.width/2,
         origin.y+ visibleSize.height/2));
    this->addChild(bg,0);
 
    //创建Node1
    autonode1 = Sprite::create("node1.png");
    node1->setPosition(Point(400,500));
    this->addChild(node1,0);
 
    //创建Node2
    autonode2 = Sprite::create("node2.png");
    node2->setPosition(Point(0.0,0.0));                                                                                              ①
    node2->setAnchorPoint(Point(0.0,0.0));                                                                              ②
    node1->addChild(node2,0);                                                                                                 ③
 
    PointPoint2 = node1->convertToWorldSpace(node2->getPosition());                                              ④
Point Point4 =node1->convertToWorldSpaceAR(node2->getPosition());                                  ⑤
 
 
    log("Node2WorldSpace = (%f,%f)",Point2.x,Point2.y);
    log("Node2WorldSpaceAR = (%f,%f)",Point4.x,Point4.y);
 
    returntrue;
}

上述代码我们主要关注第③行,它是将Node2放到Node1中,这是与之前的代码的区别。这样第①行设置的坐标就变成了相对于Node1的模型坐标了。

第④行代码将Node2的模型坐标转换为世界坐标。而第⑤行代码是类似的,它是相对于锚点的位置。

运行结果如下:

Node2 WorldSpace =(250.000000,450.000000)

Node2 WorldSpaceAR =(400.000000,500.000000)

所示的位置,可以用世界坐标描述。代码①~③行修改如下:

node2->setPosition(Point(250, 450));

node2->setAnchorPoint(Point(0.0,0.0));

this->addChild(node2, 0);

更多精彩内容请关注史上最牛的cocos2d-x课程

cocos2d-x手机游戏开发实战》直播课程第一期

报名Cocos2d-x直播课程还送关东升老师iOS终身会员

课程链接:http://edu.51cto.com/pack/view/id-13.html

会员链接:http://edu.51cto.com/member/id-3.html

Cocos2d-x坐标系介绍

时间: 2024-10-08 17:40:08

Cocos2d-x坐标系介绍的相关文章

OpenGL坐标系介绍

OpenGL坐标系介绍 OpenGL可以分成四种坐标系,分别是世界坐标系,模型坐标系,眼坐标系,设备坐标系. 数学的观点:向量空间和仿射空间 仿射空间(affine space)是向量空间的扩展,除了标量和向量,它还包含另外一种对象-点. 尽管在仿射空间中对两个点以及一个点和一个标量没有定义运算,但对一个向量和一个点定义了一种运算--向量-点加法,它的结果是一个点.也可以说有一种称为点-点减法的运算,这种运算由两个点得到一个向量. 计算机科学的观点 把标量.点和向量看做是集合中的元素,并且可以按

cocos2dx坐标系介绍

GL坐标系 Cocos2D以OpenglES为图形库,所以它使用OpenglES坐标系.GL坐标系原点在屏幕左下角,x轴向右,y轴向上. 屏幕坐标系 苹果的Quarze2D使用的是不同的坐标系统,原点在屏幕左上角,x轴向右,y轴向下.ios的屏幕触摸事件CCTouch传入的位置信息使用的是该坐标系.因此在cocos2d中对触摸事件做出响应前需要首先把触摸点转化到GL坐标系.可以使用CCDirector的convertToGL来完成这一转化. 世界坐标系 世界坐标系也叫做绝对坐标系,是游戏开发中的

转---视图动画和坐标系介绍!

Core Animation基础 Core Animation利用了硬件加速和架构上的优化来实现快速渲染和实时动画.当视图的drawRect:方法首次被调用时,层会将描画的结果捕捉到一个位图中,并在随后的重画中尽可能使用这个缓存的位图,以避免调用开销很大的drawRect:方法.这个过程使Core Animation得以优化合成操作,取得期望的性能. Core Animation把和视图对象相关联的层存储在一个被称为层树的层次结构中.和视图一 样,层树中的每个层都只有一个父亲,但可以嵌入任意数量

Cocos2d 官网介绍,新手必看!!!!!!!!!!!!!!!!!!!!!!!!!

1.之前一直没仔细看cocos2d官网,后来发现很坑 http://cocos2d-x.org/   官网分成英文,中文,还有日本语,建议大家用英语. 我之前给大家做教程,发现下载的一些东西你在中文网站是找不到的. 我们进入这个网站默认是英文的. 2.我们下一步点击Download       我给大家详细介绍一下这些都是什么东西.     ---DOWNLOAD V3.10这是目前官网上最新的框架里面包含了 lua javascript   c++ ---Html5 lite version 

典型坐标系-介绍

当你选中一个原点,定义好x,y,z三个坐标轴之后,那么世界位置中的任何一个地方都是可以定义的.但实际情况我们会这样做吗?例如你在布置一间房子的时候,你可能会描述我要把这个桌子放在墙角(2,3)米的地方.你能说我放在地球多少经纬度多少度,多少分,多少秒的地方吗?很显然其他的坐标系都有存在的价值,例如局部坐标系,世界坐标系,物体坐标系,摄像机坐标系,惯性坐标系.在具体的情况下,会有具体的坐标系适合这种情况. 世界坐标系.世界坐标系应该是大家最熟悉的坐标系,也就是我们所说的经纬度,然后再加上高程.世界

Cocos2d-x学习(3) - cocos2d坐标系,锚点

1.OpenGL的坐标系 Cocos2d是基于OpenGL开发的,所以Cocos2d的坐标系和OpenGL的坐标系是一致的,都是按照图示方向.和我们平时最常见到的坐标系也是一致的. 2.屏幕坐标系 屏幕坐标系是界面编程中很常见的坐标系.它规定的则是屏幕的左上角为坐标原点,向右为X轴正方向,向下为Y轴正方向.这个相比OpenGL坐标系,X轴方向其实是一致的,不同就在与Y轴方向. 3.元素的位置 每个元素的坐标系都是相对于其父节点的,也就是说如果父节点移动那么该父节点下的元素坐标也是相对移动的.就像

cocos2D(五岁以下儿童)---- CCNode

本将主要介绍下CCNode这个类.CCNode是全部节点的基类,当中包含我们经常使用的CCScene(场景).CCLayer(图层).CCSprite(精灵)等.它是一个不可以可视化显示的抽象类,仅仅是用来定义全部节点的公共属性和方法的.本讲纯粹是理论. 首先来看看CCNode的继承结构图,仅仅列举了经常使用的类 节点的处理 1.创建一个新的节点 [java] view plaincopy CCNode *node = [CCNode node]; 2.加入子节点 [java] view pla

Cocos2d之Texture2D类详解之将文件加载成Texture2D对象

一.声明 笔者以cocos2d框架cocos2d-x-3.3rc0版本的源码做分析.本文为笔者原创,允许转载和分享,只要注明文章出处即可. 二.简介 Texture2D类简介 Texture2D类允许开发者用图像.文本信息和简单的数据来创建OpenGL2D纹理.被创建的纹理拥有两个维度.根据开发者创建Texture2D对象方式的不同,实际图像的尺寸可能比生成的纹理的尺寸要小,而且纹理的内容是倒置的. 像素格式 在计算机图形学中,人们用每个像素在内存中的总位数以及分别存储红.蓝.绿和alpha(阿

五、CCNode

本将主要介绍下CCNode这个类,CCNode是所有节点的基类,其中包括我们常用的CCScene(场景).CCLayer(图层).CCSprite(精灵)等,它是一个不能够可视化显示的抽象类,只是用来定义所有节点的公共属性和方法的.本讲纯粹是理论. 首先来看看CCNode的继承结构图,只列举了常用的类 节点的处理 1.创建一个新的节点 [java] view plaincopy CCNode *node = [CCNode node]; 2.添加子节点 [java] view plaincopy