`

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像素。这里的坐标事实上就是世界坐标,它的坐标原点是屏幕的左下角。

编写代码如下:

 

[html] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. bool HelloWorld::init()  
  2. {  
  3.      
  4.     if( !Layer::init() )  
  5.     {  
  6.          returnfalse;  
  7.     }  
  8.    
  9.     SizevisibleSize = Director::getInstance()->getVisibleSize();  
  10.     Pointorigin = Director::getInstance()->getVisibleOrigin();  
  11.     autocloseItem = MenuItemImage::create(  
  12.          "CloseNormal.png",  
  13.          "CloseSelected.png",  
  14.          CC_CALLBACK_1(HelloWorld::menuCloseCallback,this));  
  15.    
  16.     closeItem->setPosition(Point(origin.x+ visibleSize.width - closeItem->getContentSize().width/2 ,  
  17.          origin.y+ closeItem->getContentSize().height/2));  
  18.    
  19.     automenu = Menu::create(closeItem, NULL);  
  20.     menu->setPosition(Point::ZERO);  
  21.     this->addChild(menu,1);  
  22.     //创建背景  
  23.     autobg = Sprite::create("bg.png");                                                                                         ①  
  24.     bg->setPosition(Point(origin.x+ visibleSize.width/2,  
  25.          origin.y+ visibleSize.height/2));  
  26.    
  27.     this->addChild(bg,0);                                                                                                                      ②  
  28.     //创建Node1  
  29.     autonode1 = Sprite::create("node1.png");                                                                           ③  
  30.     node1->setPosition(Point(400,500));  
  31.     node1->setAnchorPoint(Point(1.0,1.0));  
  32.    
  33.     this->addChild(node1,0);                                                                                                               ④  
  34.     //创建Node2  
  35.     autonode2 = Sprite::create("node2.png");                                                                           ⑤  
  36.     node2->setPosition(Point(200,300));           
  37.     node2->setAnchorPoint(Point(0.5,0.5));  
  38.    
  39.     this->addChild(node2,0);                                                                                                               ⑥  
  40.    
  41.     PointPoint1 = node1->convertToNodeSpace(node2->getPosition());                                      ⑦  
  42.     PointPoint3 = node1->convertToNodeSpaceAR(node2->getPosition());                                 ⑧  
  43.      
  44.     log("Node2NodeSpace = (%f,%f)",Point1.x,Point1.y);  
  45.     log("Node2NodeSpaceAR = (%f,%f)",Point3.x,Point3.y);  
  46.    
  47.     returntrue;  
  48. }  

 

 

代码①~②行是创建背景精灵对象,这个背景是一个白色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像素。

编写代码如下:

 

[html] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. bool HelloWorld::init()  
  2. {  
  3.     if( !Layer::init() )  
  4.     {  
  5.          returnfalse;  
  6.     }  
  7.    
  8.     SizevisibleSize = Director::getInstance()->getVisibleSize();  
  9.     Pointorigin = Director::getInstance()->getVisibleOrigin();  
  10.    
  11.     autocloseItem = MenuItemImage::create(  
  12.          "CloseNormal.png",  
  13.          "CloseSelected.png",  
  14.          CC_CALLBACK_1(HelloWorld::menuCloseCallback,this));  
  15.    
  16.     closeItem->setPosition(Point(origin.x+ visibleSize.width - closeItem->getContentSize().width/2 ,  
  17.          origin.y+ closeItem->getContentSize().height/2));  
  18.    
  19.     automenu = Menu::create(closeItem, NULL);  
  20.     menu->setPosition(Point::ZERO);  
  21.     this->addChild(menu,1);  
  22.    
  23.     //创建背景  
  24.     autobg = Sprite::create("bg.png");  
  25.     bg->setPosition(Point(origin.x+ visibleSize.width/2,  
  26.          origin.y+ visibleSize.height/2));  
  27.     this->addChild(bg,0);  
  28.    
  29.     //创建Node1  
  30.     autonode1 = Sprite::create("node1.png");  
  31.     node1->setPosition(Point(400,500));  
  32.     this->addChild(node1,0);  
  33.    
  34.     //创建Node2  
  35.     autonode2 = Sprite::create("node2.png");  
  36.     node2->setPosition(Point(0.0,0.0));                                                                                              ①  
  37.     node2->setAnchorPoint(Point(0.0,0.0));                                                                              ②  
  38.     node1->addChild(node2,0);                                                                                                 ③  
  39.    
  40.     PointPoint2 = node1->convertToWorldSpace(node2->getPosition());                                              ④  
  41. Point Point4 =node1->convertToWorldSpaceAR(node2->getPosition());                                  ⑤  
  42.    
  43.    
  44.     log("Node2WorldSpace = (%f,%f)",Point2.x,Point2.y);  
  45.     log("Node2WorldSpaceAR = (%f,%f)",Point4.x,Point4.y);  
  46.    
  47.     returntrue;  
  48. }  

 

 

上述代码我们主要关注第③行,它是将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);

 



[1] Direct3D(简称:D3D)是微软公司在Microsoft Windows操作系统上所开发的一套3D绘图编程接口,是DirectX的一部份,目前广为各家显卡所支持。与OpenGL同为计算机绘图软件和计算机游戏最常使用的两套绘图编程接口之一。—— 引自于维基百科 http://zh.wikipedia.org/wiki/Direct3D

分享到:
评论

相关推荐

    Cocos2d-x开发游戏的坐标系知识介绍

    本文将详细介绍在Cocos2d-x中使用到的三种坐标系:OpenGL坐标系、世界坐标系和节点坐标系,并结合锚点的概念和转换函数深入解析它们的应用。 首先,让我们从UI坐标系开始。UI坐标系是许多操作系统中通用的坐标系统...

    cocos2d-x 自学文档

    【cocos2d-x 自学文档】 cocos2d-x 是一个开源的游戏开发框架,它基于C++,广泛应用于移动游戏开发。以下是一些cocos2d-x的关键知识点: 一、运动中的加速度 在cocos2d-x中,我们可以利用Ease系列的方法来实现物体...

    cocos2d-x文字描边Demo

    《cocos2d-x文字描边技术详解及实践》 在游戏开发中,视觉效果的呈现至关重要,其中文字描边是一种常见的美化手段,能够提升游戏界面的清晰度和视觉冲击力。Cocos2d-x作为一款广泛使用的跨平台2D游戏引擎,提供了...

    Cocos2d-x学习笔记(三)—— 坐标系

    Cocos2d-x学习笔记(三)—— 坐标系

    【Cocos2d-x游戏引擎开发笔记(13)】Tiled Map Editor(一)

    Cocos2d-x是一款流行的开源游戏开发框架,广泛用于2D游戏的开发。在这个系列的开发笔记中,我们将深入探讨如何使用Cocos2d-x与Tiled Map Editor结合,创建和管理游戏地图。Tiled Map Editor是一款强大的2D地图编辑器...

    cocos2d-x-2.2.3安卓横竖屏自动切换

    《cocos2d-x-2.2.3在安卓平台上的横竖屏自动切换技术解析》 cocos2d-x是一款强大的2D游戏开发框架,它支持多平台,包括iOS、Android、Windows等。在cocos2d-x 2.2.3版本中,开发者可能会遇到如何在Android设备上...

    cocos2d-x obb 旋转碰撞 矩形

    在游戏开发领域,cocos2d-x是一款广泛使用的2D游戏引擎,它基于C++,并且支持多种平台,包括iOS、Android、Windows等。在cocos2d-x中,对象的碰撞检测是游戏物理系统的重要组成部分,对于创建交互式游戏至关重要。本...

    cocos2d-x面试题DOCX文档

    cocos2d-x面试题DOCX文档 cocos2d-x是一款popular的游戏引擎,它提供了丰富的API和工具来帮助开发者快速地创建游戏。本文档总结了cocos2d-x面试题,涵盖了CCScene、CCLayer、CCSprite、CCNode、CCAction、...

    Cocos2D-X开发学习笔记-渲染框架之摄像机类的使用示例

    Cocos2D-X是一款强大的跨平台2D游戏开发框架,被广泛应用于移动设备上的游戏开发。在Cocos2D-X中,渲染框架是构建游戏场景和交互的核心部分,而摄像机(Camera)作为渲染框架的一部分,它控制着游戏场景的视角和观察...

    知易 Cocos2D-iPhone 游戏开发教程002

    Cocos2D-iPhone使用的是屏幕坐标系,原点位于左下角,x轴向右,y轴向上。这种坐标系与传统的直角坐标系有所不同,因此在处理位置和布局时需要注意坐标方向。Cocos2D-iPhone还提供了`CCPoint`和`CGSize`等类型,用于...

    cocos2d-x的CCDirector类说明

    通过以上成员函数的介绍可以看出,`CCDirector`类在cocos2d-x中扮演着极其重要的角色,它几乎控制着游戏运行的各个方面,包括场景管理、渲染控制、性能监控等。掌握这些函数的使用方法对于开发高质量的游戏至关重要...

    Cocos2d-x学习笔记之世界坐标系、本地坐标系、opengl坐标系、屏幕坐标系

    在Cocos2d-x游戏中,理解各种坐标系的概念至关重要,因为它们定义了游戏对象在屏幕上的位置和相互关系。下面我们将详细探讨世界坐标系、本地坐标系、OpenGL坐标系以及屏幕坐标系。 1. **世界坐标系 (World ...

    魔塔cocos2dx3.x版本

    《Cocos2d-x 3.x 版本在魔塔游戏开发中的应用详解》 Cocos2d-x 是一个开源的、跨平台的游戏开发框架,它基于C++编写,广泛应用于2D游戏、UI和各种图形应用的开发。在本文中,我们将深入探讨如何在魔塔游戏开发中...

    CocosApp02.zip

    《Cocos2d-x开发环境搭建与设备坐标系解析》 Cocos2d-x是一款流行的开源游戏开发框架,尤其在2D游戏开发领域备受青睐。本文档将详细讲解如何使用"CocosApp02.zip"中的资源进行项目开发,并探讨设备坐标系在Cocos2d-...

Global site tag (gtag.js) - Google Analytics