坐标笔记

UI坐标

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

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

CCPoint touchLocation = touch->getLocationInView();

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

CCPoint touchLocation2 = CCDirector::sharedDirector()->convertToGL(touchLocation);

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

OpenGL坐标

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

世界坐标和模型坐标

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

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

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

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

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

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

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

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

 

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

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

在游戏场景中有两个Node对象,其中Node1的坐标是B(240, 160),大小是120 x 40像素。Node2的坐标是C(80, 80),大小也是120 x 40像素。这里的坐标事实上就是世界坐标,它的坐标原点是屏幕的左下角。

编写代码如下:

bool HelloWorld::init()
{
    bool bRet = false;
    do 
    {

        CC_BREAK_IF(! CCLayerColor::initWithColor(ccc4(255, 255, 255, 255)));

        CCSprite* pNode1 = CCSprite::create("node1.jpg");
        pNode1->setPosition(ccp(240, 160));
        pNode1->setAnchorPoint(ccp(1, 1));
        this->addChild(pNode1, 0);

        CCSprite* pNode2 = CCSprite::create("node2.jpg");
        pNode2->setPosition(ccp(80, 80));
        pNode2->setAnchorPoint(ccp(0.5, 0.5));
        this->addChild(pNode2, 0);

        CCPoint ponit1 = pNode1->convertToNodeSpace(pNode2->getPosition());
        CCPoint ponit2 = pNode1->convertToNodeSpaceAR(pNode2->getPosition());  
     
        CCLog("Node2 NodeSpace = (%f,%f)",ponit1.x,ponit1.y);  
        CCLog("Node2 NodeSpaceAR = (%f,%f)",ponit2.x,ponit2.y);  

        bRet = true;
    } while (0);

    return bRet;
}

运行结果如下:

Node2 NodeSpace = (-40.000000,-40.000000)
Node2 NodeSpaceAR = (-160.000000,-80.000000)

Node2的世界坐标转换为相对于Node1的模型坐标,就是将Node1的左下角作为坐标原点(图中的A点),A点的世界坐标是(240-120,160-40),那么convertToNodeSpace函数就是C(80, 80)点坐标减去A(120,120)点坐标,结果是(-40,-40)。而convertToNodeSpaceAR函数要考虑锚点,因此坐标原点是B点,C(80, 80)点坐标减去B(240, 160)点坐标,结果是(-160, -80)。

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

在游戏场景中有两个Node对象,其中Node1的坐标是B(240, 160),大小是120 x 40像素。Node2是放置在Node1中的,它对于Node1的模型坐标是C(0, 0),大小60 x 20像素。

编写代码如下:

bool HelloWorld::init()
{
    bool bRet = false;
    do 
    {

        CC_BREAK_IF(! CCLayerColor::initWithColor(ccc4(255, 255, 255, 255)));

        CCSprite* pNode1 = CCSprite::create("node1.jpg");
        pNode1->setPosition(ccp(240, 160));
        pNode1->setAnchorPoint(ccp(1, 1));
        this->addChild(pNode1, 0);

        CCSprite* pNode2 = CCSprite::create("node2.jpg");
        pNode2->setPosition(ccp(0, 0));
        pNode2->setAnchorPoint(ccp(0, 0));
        pNode1->addChild(pNode2, 0);

        CCPoint ponit1 = pNode1->convertToWorldSpace(pNode2->getPosition());
        CCPoint ponit2 = pNode1->convertToWorldSpaceAR(pNode2->getPosition());  
     
        CCLog("Node2 WorldSpace = (%f,%f)",ponit1.x,ponit1.y);  
        CCLog("Node2 WorldSpaceAR = (%f,%f)",ponit2.x,ponit2.y);  

        bRet = true;
    } while (0);

    return bRet;
}

运行结果如下:

Node2 WorldSpace = (120.000000,120.000000)
Node2 WorldSpaceAR = (240.000000,160.000000)

Node2的模型坐标转换为相对于Node1的世界坐标,就是将Node1的左下角作为坐标原点(图中的A点),A世界坐标是(240-120,160-40),那么convertToWorldSpace函数就是C(0,0)点坐标加上A(120,120)点坐标,结果是(120,120)。而convertToWorldSpaceAR函数要考虑锚点,因此坐标原点是B点,C(0,0)点坐标加上B(240,160)点坐标,结果是(240,160)。

posted @ 2015-01-20 00:13  百里抱木  阅读(345)  评论(0编辑  收藏  举报