小桑博客

如果渡不过这不可渡的海,将成为这海中捞不起的沙

[Cocos2d-x wiki翻译]Coordinate System(ok)

Coordinate System·坐标系

  • Introduction of Different Coordinate Systems
    • Cartesian Coordinate System
    • UI Coordinate System
    • Direct3D Coordinate System
    • OpenGL and Cocos2d Coordinate System
  • Parent and Childrens
  • Anchor Point
  • getVisibleSize, getVisibleOrigin vs getWinSize
  • How to convert co-ordinates
    • convertToNodeSpace:
    • convertToWorldSpace:
    • convertToWorldSpaceAR,
    • Sample code:
  • References
  • Comment
## Cartesian Coordinate System

笛卡尔坐标系

### Introduction of Different Coordinate Systems·

不同坐标系简介

#### Cartesian Coordinate System·

笛卡尔坐标系

You probably have known “Cartesian Coordinate System” from school where it’s heavily used in geometry lessons. If you have forgotten, these image will remind you quickly:

你可能上学的时候就已经知道“笛卡尔坐标系”了,它在几何课本里经常用到。如果你已经忘得差不多了,下面这些图片可以很快唤起你的记忆:

There’re 3 types of coordinate system that you will meet in mobile games development.

在移动游戏开发过程中,你可能会遇到三种类型的坐标系:

#### UI Coordinate System·

UI坐标系

In common UI Coordinates on iOS/Android/Windows SDK: - The origin (x=0, y=0) is at the top-left corner. - X axis starts at the left side of the screen and increase to the right; - Y coordinates start at the top of the screen and increase downward,

iOS/Android/Windows SDK中的通用UI坐标系:

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

详见下图

#### Direct3D Coordinate System·

Direct3D坐标系

DirectX uses Left-handed Cartesian Coordinate.

DirectX 使用Left-handed Cartesian Coordinate(左手笛卡尔坐标系)。

#### OpenGL and Cocos2d Coordinate System

OpenGL和Cocos2d坐标系

Cocos2d-x/-html5/-iphone uses the same coordinate system as OpenGL, which is so called “Right-handed Cartesian Coordinate System”.

Cocos2d-x/-html5/-iphone使用的坐标系和OpenGL的坐标系一样,名为“Right-handed Cartesian Coordinate System”(右手笛卡尔坐标系)。

We only use x-axis & y-axis in 2D world. So in your cocos2d games: - The origin (x=0, y=0) is in the bottom-left corner of screen, which means the screen is in the first quartile of right-handed cartesian coordinate system, - X axis starts at the left side of the screen and increase to the right; - Y axis starts at the bottom of the screen and increase upwards.

在2D世界中,我们仅会使用x轴和y轴。所以在你的cocos2d游戏中:

  • 起点坐标(x=0, y=0)位于右下角,这意味着屏幕位于右手笛卡尔坐标系的第一象限
  • X轴从屏幕最左边开始,由左向右渐增
  • Y轴坐标从屏幕最下方开始,由下向上渐增
And here’s a picture that helps illustrate Cocos2d-x Coordinates a bit better:

下面这张图片有助于更好的阐述Cocos2d-x坐标:

Note that it’s different from common UI coordinate systems and DirectX coordinate systems.

一定要注意:通用UI坐标系和DirectX坐标系是不一样的。

Parent and Childrens

Every class derived from CCNode (Ultimate cocos2d-x class) will have a anchorPoint property. When determining where to draw the object (sprite, layer, whatever), cocos2d-x will combine both properties position and anchorPoint. Also, when rotating an object, cocos2d-x will rotate it around its anchorPoint.

由于每个类都继承自CCNode(cocos2d-x的最顶层类),所以每个类都会默认有anchorPoint属性。 当我们决定在一个位置画一个对象的时候,cocos2d-x会结合属性位置和anchorPoint。还有,当旋转一个对象时,cocos2d-x会绕anchorPoint旋转这个对象。

We create a sprite as a gray parent and another sprite as blue child.Set parent’s position to ccp(100,100),child’s anchor point in the center of circle .

我们创建一个灰色父对象和一个蓝色子对象。设置父对象位置是ccp(100,100),子对象的anchor point位于圆心。

1
2
3
4
5
6
7
8
9
10
11
CCSprite* parent = CCSprite::create("parent.png");
parent->setAnchorPoint(ccp(0, 0));// Anchor Point
parent->setPosition(ccp(100, 100));
parent->setAnchorPoint(ccp(0, 0));
addChild(parent);

//create child 
CCSprite* child = CCSprite::create("child.png");
child->setAnchorPoint(ccp(0.5, 0.5));
child->setPosition(ccp(0, 0));
parent->addChild(child);//add child sprite into parent sprite.
Although we set child’s position of ccp(0,0),parent’s position is ccp(100,100).Therefore,child’s position is :

由于我们设置子对象的位置是ccp(0,0),父对象位置是ccp(100,100)。所以,子对象位置如图:

### Anchor Point·

锚点

As a example, this sprite has an anchorPoint of ccp(0,0) and a position of ccp(0,0).

举个例子,下面这个精灵的锚点位于 ccp(0,0),位置位于ccp(0,0)。

This rectangle sprite will be placed at the bottom left corner of its parent, the layer. example:

这个矩形精灵将被放到它的父对象(layer)的左下角。

示例:

1
2
3
4
5
// create sprite
CCSprite* sprite = CCSprite::create("bottomleft.png");
sprite->setAnchorPoint(ccp(0, 0));// Anchor Point
sprite->setPosition(ccp(0,0));
addChild(sprite);

In another example, we will assign a anchorPoint of ccp(0.5,0.5) to better understand the relative value of the anchor point.

在另一个例子中,我们会摆放一个anchorPoint坐标为ccp(0.5,0.5)的对象,以便您更好地理解锚点的相对值。

1
2
3
4
5
// create sprite
CCSprite* sprite = CCSprite::create("center.png");
sprite->setAnchorPoint(ccp(0.5, 0.5));// Anchor Point
sprite->setPosition(ccp(0,0));
addChild(sprite);

As you can see in the image, the anchor point is not a pixel value. The value of X and Y are relative to the size of the node.

正如你从图中所见,锚点取的不是像素值,此值的X和Y是相对于此节点的大小而言。

### getVisibleSize, getVisibleOrigin vs getWinSize

获取可视区域大小, 获取可视区域起点 vs 获取窗口大小

VisibleSize returns visible size of the OpenGL view in points.The value is equal to getWinSize if don’t invoke CCEGLView::setDesignResolutionSize(). getVisibleOrigin returns visible origin of the OpenGL view in points. Please refer to [Multi resolution support](Multi resolution support) for more details

VisibleSize(可视区域大小)会返回此点OpenGL视图的可视区域大小。如果没有调用CCEGLView::setDesignResolutionSize()的话,此值等于getWinSize的大小。
getVisibleOrigin(获取可视区域起点)会返回此点OpenGL视图的可视区域起点。请移步更多支持方案查看详情。

### How to convert co-ordinates·

如何转换坐标

convertToNodeSpace:

convertToNodeSpace will be used in, for example, tile-based games, where you have a big map. convertToNodeSpace will convert your openGL touch co-ordinates to the co-ordinates of the .tmx map or anything similar. Example: The following picture shows that we have node1 with anchor point (0,0) and node2 with anchor point (1,1). We invoke CCPoint point = node1->convertToNodeSpace(node2->getPosition()); convert node2’s SCREEN coords to node1’s local.As the result,node2 with the position of (-25,-60).

举例来说,convertToNodeSpace用于tile-based的游戏,即有一个大地图。convertToNodeSpace会将openGL触摸点坐标转换成.tmx 地图或者其他近似的坐标。

例子:

下面的图片会展现,node1的锚点(0,0),node2的锚点是(1,1)。

我们调用CCPoint point = node1->convertToNodeSpace(node2->getPosition()); 相对node1的本地位置转换node2的屏幕坐标。结果node2的位置是(-25,-60).

convertToWorldSpace:

convertToWorldSpace(const CCPoint& nodePoint) converts on-node coords to SCREEN coordinates.convertToWorldSpace will always return SCREEN position of our sprite, might be very useful if you want to capture taps on your sprite but need to move/scale your layer Example:

convertToWorldSpace(常量 CCPoint& nodePoint) 转换node坐标为屏幕坐标。convertToWorldSpace通常返回精灵的屏幕位置,如果你想捕获精灵上的触摸事件却需要移动/缩放layer的时候,这可能非常有帮助。

1
CCPoint point = node1->convertToWorldSpace(node2->getPosition()); 
the above code will convert the node2‘s coordinates to the coordinates on the screen. For example if the position of node2 is (0, 0) which will be the bottom left corner of the node1, but not necessarily on the screen. This will convert (0, 0) of the node2 to the position of the screen(in this case is (15,20)). The result shows in the following picture:

上述的代码会将node2坐标转换为node2在屏幕上对应的坐标。

举个例子,如果node2的位置是(0,0),这个位置是node1的左下角,但不见得屏幕上也如此。上述代码会把(0,0)位置的node2转换到屏幕上的位置(这个例子中是(15,20))。结果如下图所示:

convertToWorldSpaceAR

convertToWorldSpaceAR will return the position relatevely to anchor point: so if our scene - root layer has Anchor Point of ccp(0.5f, 0.5f) - default, convertToWorldSpaceAR should return position relatively to screen center. convertToNodeSpaceAR - the same logic as for .convertToWorldSpaceAR

convertToWorldSpaceAR返回相对锚点的位置:所以如果你的场景 - 根layer有一个锚点位于ccp(0.5f, 0.5f)。- 默认的,convertToWorldSpaceAR应返回相对于屏幕中心的位置。

convertToNodeSpaceAR - 和convertToWorldSpaceAR是一样的逻辑。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
CCSprite *sprite1 = CCSprite::create("CloseNormal.png");

sprite1->setPosition(ccp(20,40));

sprite1->setAnchorPoint(ccp(0,0));

this->addChild(sprite1);

CCSprite *sprite2 = CCSprite::cteate("CloseNormal.png");

sprite2->setPosition(ccp(-5,-20));

sprite2->setAnchorPoint(ccp(1,1));

this->addChild(sprite2);

CCPoint point1 = sprite1->convertToNodeSpace(sprite2->getPosition());

CCPoint point2 = sprite1->convertToWorldSpace(sprite2->getPosition());

CCPoint point3 = sprite1->convertToNodeSpaceAR(sprite2->getPosition());

CCPoint point4 = sprite1->convertToWorldSpaceAR(sprite2->getPosition());

CCLog("position = (%f,%f)",point1.x,point1.y);

CCLog("position = (%f,%f)",point2.x,point2.y);

CCLog("position = (%f,%f)",point3.x,point3.y);

CCLog("position = (%f,%f)",point4.x,point4.y);

结果:

position = (-25.000000,-60.000000)
position = (15.000000,20.000000)
position = (-25.000000,-60.000000)
position = (15.000000,20.000000)

参考

Comment

Comments