Cocos2d-x 3.0的新物理系統我就不必多說了,接觸一段時間,感覺還是不錯的。對于那些基本概念,網上的教程已經泛濫了,就不多說了,不過對于創建多邊形物體的教程,還真不多,很多都是創建圓形和矩形,這兩個很簡單,傳入圖片的大小數據基本就可以搞定了。多邊形的麻煩之處在于每個點的位置,Mac下有VertexHelper可以很輕松獲取到多邊形的每個點,然后創建出來,但Windows下,呃,確實我沒找到什么好的工具,PhysicsEditor在以前使用Box2d原生的代碼創建多邊形還是挺好用的,現在就不太適合了,所以本篇的用法也是建立在它的之上做出來的,如果有好的辦法,歡迎提出分享哈。
話不多說,看看如何利用PhysicsEditor來創建一個多邊形。
打開PhysicsEditor,導入一張多邊形,姑且咱們先拿個三角形開刀說,導入圖片之后,選擇上方的add polygon
<img src="http://www.2cto.com/uploadfile/Collfiles/20140823/201408230920218.png" alt="" http:="" www.2cto.com="" kf="" ware="" vc="" "="" target="_blank" class="keylink" style="box-sizing: border-box; border: medium none; vertical-align: middle; display: block; margin: 0px auto; max-width: 100%; width: 2090.67px; height: auto;">vcfQzsf40/LArbP2wLSjrM/x1eLR+aOsPC9wPgo8cD48aW1nIHNyYz0="http://www.2cto.com/uploadfile/Collfiles/20140823/2014082309202110.png" alt="\">
這樣多邊形的幾個點位置就算完成了,下面的步驟很關鍵,
在右邊Exporter選擇“Chipmunk generic”,因為cocos封裝的多邊形頂點是按照順時針的方向來的,和box2d不一樣,box2d是反方向的。
當你選擇之后,會看到圖中多了一個點,那個是錨點的位置,所以接下來是設置錨點的位置,新版的物理系統在setPhysicsBody的時候是將Body綁定在圖片的中心點位置,所以我們在PhysicsEditor中繪制的Body區域也需要將錨點設置在中心點,不然回過頭在創建Body的時候還要設置偏移量offset。
如下圖,將關鍵的地方設置成(0.5, 0.5)就可以了。
接下來,保存一下這個文件,是一個plist格式的,用個Notepad++打開下,找到下面有個點數組的位置,
我們就是需要這一組點數據,我想后面的事大家應該就很清楚了,打開VS,創建一個多邊形咯。
auto triangle = Sprite::create("CyanTriangle.png"); triangle->setPosition(Point(size.width/2, size.height*0.8)); Point points[3] = { Point(-50.00000, -43.50000), Point(0.00000, 43.50000), Point(51.00000, -43.50000) }; auto polygonBody = PhysicsBody::createPolygon(points, 3); triangle->setPhysicsBody(polygonBody); addChild(triangle);
PhysicsBody::createPolygon的參數第一個是點數組,第二個是數組的大小,也就是邊的個數。
運行看一下效果,
由于打開了debug模式,所以紅色的區域非常貼切,可以用啦。
當然咯,PhysicsEditor也可以做凹多邊形的,不過這個步驟要麻煩不少,但過程基本一樣,簡單過一遍,
拿個logo圖片做一下,可以右鍵添加點哦,然后簡單拉出這樣的效果。然后還是保存我們的plist文件。
對于凹多邊形,我們的策略基本就是采用addShape的方式,將其分割成多個凸多邊形,然后組合在一起,他們的碰撞區域是組合起來的,所以沒問題。
這個時候打開plist文件,可以看到是這樣的點數組,
它的策略也是這樣的,所以符合我們的要求,只是這么多點,咱們要一個一個添加,確實略顯麻煩,沒辦法,繼續來吧。。。。
一個數組點創建一個多邊形Shape,所以代碼是這樣的。
auto logo = Sprite::create("powered.png"); auto logoBody = PhysicsBody::create(); Point vert1[4] = { Point(1.00000, 134.50000), Point(24.00000, 111.50000), Point(-16.00000, 126.50000), Point(-22.00000, 149.50000) }; logoBody->addShape(PhysicsShapePolygon::create(vert1, 4)); Point vert2[4] = { Point(-100.00000, -149.50000), Point(24.00000, 111.50000), Point(101.00000, 111.50000), Point(101.00000, -149.50000) }; logoBody->addShape(PhysicsShapePolygon::create(vert2, 4)); Point vert3[4] = { Point(24.00000, 111.50000), Point(-100.00000, -149.50000), Point(-32.00000, 112.50000), Point(-16.00000, 126.50000) }; logoBody->addShape(PhysicsShapePolygon::create(vert3, 4)); Point vert4[3] = { Point(-32.00000, 112.50000), Point(-100.00000, -149.50000), Point(-100.00000, 112.50000) }; logoBody->addShape(PhysicsShapePolygon::create(vert4, 3)); logo->setPhysicsBody(logoBody); logo->setPosition(Point(size.width*0.8, size.height*0.7)); addChild(logo); logo->setRotation(180);
好了,這樣就可以了,我還旋轉了一下,為了測試一下上面那一撮頭發的碰撞區域,哈哈~