先說下世界座標跟本地:
// 把世界座標轉換到當前節點的本地座標系中
point converttonodespace(constpoint& worldpoint) const;
// 把基於當前節點的本地座標系下的座標轉換到世界座標系中
point converttoworldspace(constpoint& nodepoint) const;
// 基於anchor point把基於當前節點的本地座標系下的座標轉換到世界座標系中
point converttonodespacear(constpoint& worldpoint) const;
// 基於anchor point把世界座標轉換到當前節點的本地座標系中
point converttoworldspacear(constpoint& nodepoint) const;
下面通過乙個例子來說明這四個方法的理解和作用:
auto *sprite1 = sprite::create("helloworld.png");
sprite1->setposition(ccp(20,40));
sprite1->setanchorpoint(ccp(0,0));
this->addchild(sprite1); //此時新增到的是世界座標系,也就是opengl座標系
auto *sprite2 = sprite::create("helloworld.png");
sprite2->setposition(ccp(-5,-20));
sprite2->setanchorpoint(ccp(1,1));
this->addchild(sprite2);//此時新增到的是世界座標系,也就是opengl座標系
//將 sprite2 這個節點的座標ccp(-5,-20) 轉換為 sprite1節點 下的本地(節點)座標系統的 位置座標
point point1 = sprite1->converttonodespace(sprite2->getposition());
//將 sprite2 這個節點的座標ccp(-5,-20) 轉換為 sprite1節點 下的世界座標系統的 位置座標
point point2 = sprite1->converttoworldspace(sprite2->getposition());
log("position = (%f,%f)",point1.x,point1.y);
log("position = (%f,%f)",point2.x,point2.y);
執行結果:
cocos2d: position = (-25.000000,-60.000000)
cocos2d: position = (15.000000,20.000000)
其中:point point1 = sprite1->converttonodespace(sprite2->getposition());
相當於sprite2
這個節點新增到(實際沒有新增,只是這樣理解)sprite1
這個節點上,那麼就需要使用sprite1
這個節點的節點座標系統,這個節點的節點座標系統的原點在(20,40),而sprite1
的座標是(-5,-20),那麼經過變換之後,sprite1
的座標就是(-25,-60)。
其中:point point2 = sprite1->converttoworldspace(sprite2->getposition());
此時的變換是將sprite2
的座標轉換到sprite1
的世界座標系下,而其中世界座標系是沒有變化的,始終都是和opengl等同,只不過sprite2
在變換的時候將sprite1
作為了」參照「而已。所以變換之後sprite2
的座標為:(15,20)。
以上只是泛泛的簡單的轉換了下,但是工作中往往會稍微複雜些。
比如說:
判斷子彈是否飛出了螢幕,但是子彈是在地圖層的,地圖又在gamelayer層上,gamelayer上又有層,這一層套一層到底該怎麼判斷子彈的絕對位置呢?
bullet->getposition() 查了下資料得到的位置是相對父結點的,即地圖層下的區域性座標,我希望得到是子彈相對於螢幕左下角的位置,這也就是著名的絕對座標。顯然bullet->getposition()在地圖一移動的情況下就不再是世界座標了,那可怎麼辦呢?
網上很多網友給出的解決辦法是座標系轉換,即本地座標轉為世界座標系,就一句**就行:
posbullet = (bullet->getparent())->converttoworldspace(bullet->getposition());
經試驗是可行的,但我對此深深的懷疑:bullet的父結點是一層套一層的,那converttoworldspace裡的引數是什麼意思,(bullet->getparent())又是什麼,為什麼不能是(bullet->getparent()->getparent())
看了很多官方說法,再查源**:終於理解了這方法的含義:我們是要求的是bullet的世界座標系,即相對於螢幕左下角的座標,所以converttoworldspace的引數是 bullet->getposition(),那什麼執行主體是bullet->getparent()而不用考慮更深層次的父結點呢,原因很簡單,bullet的position是相對於它的父結點的,也就是bullet->getparent(),所以執行主體也就是bullet->getparent(),那怎麼保證此函式求到的是最上層的世界座標而不是相對於他的父結點的座標呢,看源**:
vec2 node::converttoworldspace(const vec2& nodepoint) const
裡面有個重要的矩陣變換 getnodetoworldtransform() ,估且不要理解其中複雜的數學變換,它的原始碼:
mat4 node::getnodetoworldtransform() const
return t;
}
可看出它是一層一層向上回溯找其父結點的變換矩陣的,所以最後能求到最上層父結點的變換矩陣,也就求得了世界座標系。所以
posbullet = (bullet->getparent())->converttoworldspace(bullet->getposition()); 此方法是正確的,就是子彈的世界座標。然後要是要是再將子彈的這個座標轉換成相對於其他節點的本地座標,就要用到剛才的posbullet ,比如說轉換成非該子彈父節點的node的相對座標:pos = node->converttonodespace(posbullet);這樣就可以將不在同一層級中的節點轉換成其他層級的本地座標了,用到最多的比如每個傳奇專案中的 每個主角總是在螢幕的中心處。
cocos2d 座標系的轉換
許久之後遇到問題,立馬又來發了一篇。這次的內容跟c 無關,是有關cocos2d的乙個小技術點 本地座標與世界座標 在cocos中有兩種座標系 本地座標系和世界座標系。本地座標系 這個座標系是基於節點以及層的座標系,例如有兩個節點 node1和node2,node1在layer中,node2在node...
Cocos2d中各種座標位置關係
先看一段 cpp view plain copy id init return self 1 載入地圖 cpp view plain copy cctmxtiledmap gameworld cctmxtiledmap tiledmapwithtmxfile positiontext.tmx 2 獲...
Cocos2d中各種座標位置關係
接觸cocos2d有段時間了,今天特意研究了下cocos2d座標系中各種位置關係,anchor屬性,ccnode座標和地圖座標轉換。先看一段 id init return self 1 載入地圖 cctmxtiledmap gameworld cctmxtiledmap tiledmapwithtm...