1. 程式人生 > >Box2d中剛體的紋理的幾種實現方式

Box2d中剛體的紋理的幾種實現方式



Box2d中建立完剛體並將裝置(fixture)附加到剛體上以後,還需要對剛體應用紋理才能夠讓剛體看起來像一個真正的物體,而不是一個個多邊形或者圓形線框。因此,總結了下面幾種為剛體新增紋理的思路。

1.最簡單的方式就是使用CCPhysicsSprite類,CCPhysicsSpritecocos2d 2.1之後引入的,支援ChipmunkBox2d兩個框架,類中定義了b2Body成員用來儲存其對應的剛體,該類重寫了nodeToParentTransformpositionrotationget/set等方法,獲取對應剛體的座標和轉角,然後使用座標和轉角來更新其紋理的位置和旋轉,從而使紋理和剛體能夠同步移動和旋轉。

使用CCPhysicsSprite的方式很簡單:

CCPhysicsSprite*sprite = [CCPhysicsSprite spriteWithTexture:texture rect:CGRectMake(x, y,width, height)];

[parentaddChild:sprite];

[spritesetPTMRatio:PTM_RATIO];

[spritesetB2Body:body];

[spritesetPosition: ccp( p.x, p.y)];

首先通過初始化方法初始化紋理texture和紋理的繪製區域(矩形區域),接著將該精靈物件新增到場景中(與一般的CCSprite物件用法相同),接著設定單位轉換的比例(Box2d中的“米”與畫素之間的轉換比例,即PTM_RATIO),然後指定對應的剛體(body),最後設定其初始的位置即可。

不需要做額外的操作,精靈的紋理便會隨著剛體的運動而運動。

有興趣的朋友可以在cocos2d類庫中找到CCPhysicsSprite.h和CCPhysicsSprite.mm檔案看一下具體的實現方法。

2.上面第一種方式,我們使用了cocos2d中為我們提供的類庫來實現剛體和紋理的同步運動。同樣,我們也可以自己定義一個類(暫且就叫它MyB2Body),MyB2Body中包含CCSPriteb2Body這兩個成員(除了這兩個成員,其它成員根據需求而定,不在我們的討論範圍內),然後在MyB2Body中定義自己的更新方法(就叫updateBodyAndSprite吧),接著在我們需要更新剛體位置的地方呼叫

updateBodyAndSprite就可以了。

這種方式和第一種方式的區別在於,它為我們提供了更多的靈活性,當然你也可以說,因為cocos2d是開源的,所以我們也可以修改CCPhysicsSprite類,所以其同樣具有靈活性,但是如果我們修改CCPhysicsSprite類,則會影響到你機器上其他使用cocos2d框架的應用程式。而且這裡我們並不是重寫position或者rotation的get/set方法,而是實現自定義的方法供手動呼叫。

具體的例子可以看一下另一篇博文手把手教你製作一款Box2D小遊戲(一)中StepBlock類的實現(該類中使用CCPhysicsSprite,其實使用CCSprite即可滿足需求)。

3.上面兩種方法我們通過定義類或者使用庫中定義的類來完成,實際上,b2Body物件為我們提供了一個很好的屬性來儲存其對應的精靈,即userData這個屬性。b2BodyuserData屬性用來存放任何我們想存放的資料,那麼我們乾脆就在userData中存放其對應的精靈物件就好了(這裡說是存放,其實是userData指向剛體對應的精靈物件)。PhysicsEditor附帶的例子中實際上就用的是這種方法。在update方法中,首先通過world->Step(dt,velocityIterations, positionIterations)來計算並更新所有剛體的位置,接著通過下面的迴圈來更新所有剛體對應的精靈的紋理:

for(b2Body* b = world->GetBodyList(); b; b = b->GetNext())

  {

          if (b->GetUserData() != NULL)

          {

                   CCSprite *myActor = (CCSprite*)b->GetUserData();

                   myActor.position = CGPointMake(

b->GetPosition().x* PTM_RATIO, b->GetPosition().y * PTM_RATIO);

                   myActor.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());

          }      

  }

這種方式與我們第二種方式有些類似,都需要在其他方法中手動更新精靈的位置。

好了,以上就是關於剛體紋理的一點點心得,如果有說的不清楚的地方,歡迎留言指正~