溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Cocos2d-x坐標(biāo)系介紹

發(fā)布時(shí)間:2020-07-14 08:49:05 來(lái)源:網(wǎng)絡(luò) 閱讀:419 作者:tony關(guān)東升 欄目:游戲開(kāi)發(fā)

Cocos2d-x坐標(biāo)系介紹

在圖形圖像和游戲應(yīng)用開(kāi)發(fā)中坐標(biāo)系是非常重要的,我們?cè)贏ndroid和iOS等平臺(tái)應(yīng)用開(kāi)發(fā)的時(shí)候使用的二維坐標(biāo)系它的原點(diǎn)是在左上角的。而在Cocos2d-x坐標(biāo)系中它原點(diǎn)是在左下角的,而且Cocos2d-x坐標(biāo)系又可以分為:世界坐標(biāo)和模型坐標(biāo)。

UI坐標(biāo)

UI坐標(biāo)就是Android和iOS等應(yīng)用開(kāi)發(fā)的時(shí)候使用的二維坐標(biāo)系。它的原點(diǎn)是在左上角的。

Cocos2d-x坐標(biāo)系介紹


UI坐標(biāo)原點(diǎn)是在左上角,x軸向右為正,y軸向下為正。我們?cè)贏ndroid和iOS等平臺(tái)使用的視圖、控件等都是遵守這個(gè)坐標(biāo)系。然而在Cocos2d-x默認(rèn)不是采用UI坐標(biāo),但是有的時(shí)候也會(huì)用到UI坐標(biāo),例如在觸摸事件發(fā)生的時(shí)候,我們會(huì)獲得一個(gè)觸摸對(duì)象(Touch),觸摸對(duì)象(Touch)提供了很多獲得位置信息的函數(shù),如下面代碼所示:

Point touchLocation = touch->getLocationInView();

使用getLocationInView()函數(shù)獲得觸摸點(diǎn)坐標(biāo)事實(shí)上就是UI坐標(biāo),它的坐標(biāo)原點(diǎn)在左上角。而不是Cocos2d-x默認(rèn)坐標(biāo),我們可以采用下面的語(yǔ)句進(jìn)行轉(zhuǎn)換:

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

通過(guò)上面的語(yǔ)句就可以將觸摸點(diǎn)位置從UI坐標(biāo)轉(zhuǎn)換為OpenGL坐標(biāo),OpenGL坐標(biāo)就是Cocos2d-x默認(rèn)坐標(biāo)。

OpenGL坐標(biāo)

我們?cè)谏厦嫣岬搅薕penGL坐標(biāo),OpenGL坐標(biāo)是種三維坐標(biāo)。由于Cocos2d-x底層采用OpenGL渲染,因此的默認(rèn)坐標(biāo)就是OpenGL坐標(biāo),只不過(guò)只采用兩維(x和y軸)。如果不考慮z軸,OpenGL坐標(biāo)的原點(diǎn)在左下角。

Cocos2d-x坐標(biāo)系介紹


 

提示:  三維坐標(biāo)根據(jù)z軸的指向不同分為:左手坐標(biāo)和右手坐標(biāo)。右手坐標(biāo)是z軸指向屏幕外。左手坐標(biāo)是z軸指向屏幕里.OpenGL坐標(biāo)是右手坐標(biāo),而微軟平臺(tái)的Direct3D[1]是左手坐標(biāo)。

Cocos2d-x坐標(biāo)系介紹

世界坐標(biāo)和模型坐標(biāo)

由于OpenGL坐標(biāo)有可以分為:世界坐標(biāo)和模型坐標(biāo),所以Cocos2d-x的坐標(biāo)也有世界坐標(biāo)和模型坐標(biāo)。

你是否有過(guò)這樣的問(wèn)路經(jīng)歷:張三會(huì)告訴你向南走一公里,再向東走500米。而李四會(huì)告訴你向右走一公里,再向左走500米。這里兩種說(shuō)法或許都可以找到你要尋找的地點(diǎn)。張三采用的坐標(biāo)是世界坐標(biāo),他把地球作為參照物,表述位置使用地理的東、南、西和北。而李四采用的坐標(biāo)是模型坐標(biāo),他讓你自己作為參照物,表述位置使用你的左邊、你的前邊、你的右邊和你的后邊。

我們看看圖3-21,從圖中可以看到A的坐標(biāo)是(5,5),B的坐標(biāo)是(4,6),事實(shí)上這些坐標(biāo)值就是世界坐標(biāo)。如果采用A的模型坐標(biāo)來(lái)描述B的位置,則B的坐標(biāo)是(1,-1)。

Cocos2d-x坐標(biāo)系介紹


有的時(shí)候我們需要將世界坐標(biāo)與模型坐標(biāo)互相轉(zhuǎn)換。我們可以通過(guò)Node對(duì)象如下函數(shù)實(shí)現(xiàn):

Point convertToNodeSpace ( const Point & worldPoint )。將世界坐標(biāo)轉(zhuǎn)換為模型坐標(biāo)。

Point convertToNodeSpaceAR ( const Point & worldPoint )。將世界坐標(biāo)轉(zhuǎn)換為模型坐標(biāo)。AR表示相對(duì)于錨點(diǎn)。

Point convertTouchToNodeSpace ( Touch * touch )。將世界坐標(biāo)中觸摸點(diǎn)轉(zhuǎn)換為模型坐標(biāo)。

Point convertTouchToNodeSpaceAR ( Touch * touch )。將世界坐標(biāo)中觸摸點(diǎn)轉(zhuǎn)換為模型坐標(biāo)。AR表示相對(duì)于錨點(diǎn)。

Point convertToWorldSpace ( const Point & nodePoint )。將模型坐標(biāo)中觸摸點(diǎn)轉(zhuǎn)換為世界坐標(biāo)。

Point convertToWorldSpaceAR ( const Point & nodePoint )。將模型坐標(biāo)中觸摸點(diǎn)轉(zhuǎn)換為世界坐標(biāo)。AR表示相對(duì)于錨點(diǎn)。

 

下面我們通過(guò)兩個(gè)例子了解一下世界坐標(biāo)與模型坐標(biāo)互相轉(zhuǎn)換。

1、世界坐標(biāo)轉(zhuǎn)換為模型坐標(biāo)

下面是世界坐標(biāo)轉(zhuǎn)換為模型坐標(biāo)實(shí)例運(yùn)行結(jié)果。

Cocos2d-x坐標(biāo)系介紹


在游戲場(chǎng)景中有兩個(gè)Node對(duì)象,其中Node1的坐標(biāo)是(400, 500),大小是300 x 100像素。Node2的坐標(biāo)是(200, 300),大小也是300 x 100像素。這里的坐標(biāo)事實(shí)上就是世界坐標(biāo),它的坐標(biāo)原點(diǎn)是屏幕的左下角。

編寫(xiě)代碼如下:

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);
    //創(chuàng)建背景
    autobg = Sprite::create("bg.png");                                                                                         ①
    bg->setPosition(Point(origin.x+ visibleSize.width/2,
         origin.y+ visibleSize.height/2));
 
    this->addChild(bg,0);                                                                                                                      ②
    //創(chuàng)建Node1
    autonode1 = Sprite::create("node1.png");                                                                           ③
    node1->setPosition(Point(400,500));
    node1->setAnchorPoint(Point(1.0,1.0));
 
    this->addChild(node1,0);                                                                                                               ④
    //創(chuàng)建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;
}

代碼①~②行是創(chuàng)建背景精靈對(duì)象,這個(gè)背景是一個(gè)白色900 x 640像素的圖片。代碼第③~④行是創(chuàng)建Node1對(duì)象,并設(shè)置了位置和錨點(diǎn)屬性。代碼第⑤~⑥行是創(chuàng)建Node2對(duì)象,并設(shè)置了位置和錨點(diǎn)屬性。第⑦行代碼將Node2的世界坐標(biāo)轉(zhuǎn)換為相對(duì)于Node1的模型坐標(biāo)。而第⑧行代碼是類似的,它是相對(duì)于錨點(diǎn)的位置。

運(yùn)行結(jié)果如下:

Node2 NodeSpace = (100.000000,-100.000000)

Node2 NodeSpaceAR =(-200.000000,-200.000000)

Node2的世界坐標(biāo)轉(zhuǎn)換為相對(duì)于Node1的模型坐標(biāo),就是將Node1的左下角作為坐標(biāo)原點(diǎn)(圖3-22中的A點(diǎn)),我們不難計(jì)算出A點(diǎn)的世界坐標(biāo)是(100,400),那么convertToNodeSpace函數(shù)就是A點(diǎn)坐標(biāo)減去C點(diǎn)坐標(biāo),結(jié)果是(-100,100)。而convertToNodeSpaceAR函數(shù)要考慮錨點(diǎn),因此坐標(biāo)原點(diǎn)是B點(diǎn),B點(diǎn)坐標(biāo)減去C點(diǎn)坐標(biāo),結(jié)果是(-200, -200)。

2、模型坐標(biāo)轉(zhuǎn)換為世界坐標(biāo)

下面是模型坐標(biāo)轉(zhuǎn)換為世界坐標(biāo)實(shí)例運(yùn)行結(jié)果。

Cocos2d-x坐標(biāo)系介紹


在游戲場(chǎng)景中有兩個(gè)Node對(duì)象,其中Node1的坐標(biāo)是(400, 500),大小是300 x 100像素。Node2是放置在Node1中的,它對(duì)于Node1的模型坐標(biāo)是(0, 0),大小也是150 x 50像素。

編寫(xiě)代碼如下:

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);
 
    //創(chuàng)建背景
    autobg = Sprite::create("bg.png");
    bg->setPosition(Point(origin.x+ visibleSize.width/2,
         origin.y+ visibleSize.height/2));
    this->addChild(bg,0);
 
    //創(chuàng)建Node1
    autonode1 = Sprite::create("node1.png");
    node1->setPosition(Point(400,500));
    this->addChild(node1,0);
 
    //創(chuàng)建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;
}


上述代碼我們主要關(guān)注第③行,它是將Node2放到Node1中,這是與之前的代碼的區(qū)別。這樣第①行設(shè)置的坐標(biāo)就變成了相對(duì)于Node1的模型坐標(biāo)了。

第④行代碼將Node2的模型坐標(biāo)轉(zhuǎn)換為世界坐標(biāo)。而第⑤行代碼是類似的,它是相對(duì)于錨點(diǎn)的位置。

運(yùn)行結(jié)果如下:

Node2 WorldSpace =(250.000000,450.000000)

Node2 WorldSpaceAR =(400.000000,500.000000)

所示的位置,可以用世界坐標(biāo)描述。代碼①~③行修改如下:

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

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

this->addChild(node2, 0);

 

更多精彩內(nèi)容請(qǐng)關(guān)注史上最牛的cocos2d-x課程

cocos2d-x手機(jī)游戲開(kāi)發(fā)實(shí)戰(zhàn)》直播課程第一期

報(bào)名Cocos2d-x直播課程還送關(guān)東升老師iOS終身會(huì)員。

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

會(huì)員鏈接:http://edu.51cto.com/member/id-3.html



向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI