PhysicsBody相關API說明

PhysicsBody相關API說明

  • void setGroup(int group);

PhysicsBody的Group

1.優先級比bit masks的優先級高(CategoryBitmask,ContactTestBitmask,CollisionBitmask)

2.group是正數且相等的話,就一定碰撞

3.group是負數且相等的話,就一定不會碰撞

4.group其他情況沒說,應該是取決於bit masks了


  • void setCategoryBitmask(int bitmask);

PhysicsBody的CategoryBitmask

1.CategoryBitmask用來標記這個PhysicsBody的所屬類別

2.每個PhysicsBody最多可以屬於32個類別,一個bit代表一個類別,0代表不是對應類別,1代表是對應類別

3.和另外兩個屬性(collisionBitMask and contactTestBitMask)配合着用

4.默認值0xFFFFFFFF,即這個PhysicsBody分別屬於所有的32個類別


  • void setContactTestBitmask(int bitmask);

PhysicsBody的ContactTestBitmask

1.ContactTestBitmask用來定義哪個類別的PhysicsBody可以和這個PhysicsBody產生相交通知

2.舉個例子:有PhysicsBody A B佔了同樣的空間了。如何判斷A B要產生相交通知呢,

if((A.CategoryBitmask & B.ContactTestBitmask) != 0 || (A.ContactTestBitmask & B.CategoryBitmask) != 0)

    {/*條件成立,執行相交通知*/}

else{/*沒有相交通知*/}

3.爲了性能考慮,相交通知只應該設置給我們感興趣的物體

4.默認值0x00000000 (all bits cleared),沒有哪個類別的PhysicsBody可以產生相交通知


  • void setCollisionBitmask(int bitmask);

PhysicsBody的CollisionBitmask

1.CollisionBitmask是用來定義哪個類別的PhysicsBody可以和這個PhysicsBody產生碰撞

2.舉個例子:有PhysicsBody A B彼此接觸了,那碰撞就可能發生。

A受不受這個碰撞的影響(體現爲物理效果)表達爲:

1
2
3
4
5
6
7
8
if((A.CollisionBitmask & B.CategoryBitmask) != 0 )
{
    /*A產生碰撞的物理效果*/
else
{    
    /*A沒效果*/
 }

3.至於B受不受這個碰撞的影響,則採用同樣的表達式單獨計算即可

1
2
3
4
5
6
7
if((B.CollisionBitmask & A.CategoryBitmask) != 0 )
{
    /*B產生碰撞的物理效果*/
 
else{
    /*B沒效果*/
 }

4.默認值0xFFFFFFFF (all bits set),所有類別的PhysicsBody都能對this body產生碰撞效果


DEMO及源碼

  • 基於Cocos2d-x 3.4 Final,源碼下載:https://github.com/cheyiliu/CollisionDetection

  • DEMO功能:註冊了物理碰撞事件的監聽,用來查看是否有事件回調;註冊了touch事件監聽,在touch的結束事件裏回在觸摸點創建一個帶物理效果的精靈。精靈有兩種,用來測試PhysicsBody的設置造成的影響。具體看代碼,不復雜。


驗證對API的理解

所有參數保持默認

  • 屬性值:

group = 0

CategoryBitmask = 0xFFFFFFFF

ContactTestBitmask = 0x00000000

CollisionBitmask = 0xFFFFFFFF

  • 現象和分析:

  • a、b爲同一類物品,有碰撞現象【group未設置; 那就套上面的API的分析, (a.CategoryBitmask & b.CollisionBitmask) != 0 true; 反過來也是; 故a b都有碰撞效果。】

  • a、b爲同一類物品,無碰撞回調【套公式 ((a.CategoryBitmask & b.ContactTestBitmask) != 0 || (a.ContactTestBitmask & b.CategoryBitmask) != 0)等於false,故沒回調。】


確認group優先級

  • 屬性值:

group = 需要設置<-----

CategoryBitmask = 0xFFFFFFFF

ContactTestBitmask = 0x00000000

CollisionBitmask = 0xFFFFFFFF

  • 現象和分析:

  • a、b爲同一類物品,group都取1。有碰撞現象,無回調【跟group不設置時現象一樣,還不能說明什麼】

  • a、b爲同一類物品,group都取-1。無碰撞現象,無回調,物體a b分別從同一個位置落下後,a b重疊【其他bitmask的默認值設置是有碰撞現象的,但設置group取相同的負數後沒碰撞了,group優先級高!】

  • a、b爲同一類物品,group都取1,但設置CollisionBitmask=0x00(試圖不要碰撞效果)。現象1自由落體到世界外面去了,現象2快速touch在同一個位置產生兩個精靈會有擠開的現象(若group取-1則不會擠開,疊在一起了)。【說明group的優先級最高!】

  • a、b爲同一類物品,group都取1,但設置CollisionBitmask=0x00(試圖不要碰撞效果),設置ContactTestBitmask=0x01(試圖獲取回調)。現象1自由落體到世界外面去了;現象2快速touch在同一個位置產生兩個精靈會有擠開的現象(若group取-1則不會擠開,疊在一起了);現象3有回調。【說明group的優先級最高!】


想要回調

  • 屬性值:

group = 0

CategoryBitmask = 0xFFFFFFFF

ContactTestBitmask = 0x00000001<-----change to this

CollisionBitmask = 0xFFFFFFFF

  • 現象和分析:

  • a、b爲同一類物品,有碰撞現象,有回調【碰撞的理由是(a.CollisionBitmask & b.CategoryBitmask) != 0非0, true;有回調的理由是((a.CategoryBitmask & b.ContactTestBitmask) != 0 || (a.ContactTestBitmask & b.CategoryBitmask) != 0) 等於true】


想要回調但不要碰撞效果

  • 屬性值:

group = 0

CategoryBitmask = 0xFFFFFFFF

ContactTestBitmask = 0x00000001<-----change to this

CollisionBitmask = 0x00000000<-----change to this

  • 現象和分析:

  • a、b爲同一類物品,無碰撞現象,無回調【不碰撞的理由是(a.CollisionBitmask & b.CategoryBitmask) != 0 等於0,false,;無回調的理由是雖然((a.CategoryBitmask & b.ContactTestBitmask) != 0|| (a.ContactTestBitmask & b.CategoryBitmask) != 0) 等於true,但是沒有碰撞的前提】


想要A類和B類碰撞,A類之間不碰撞,B類之間不碰撞-法1

  • 屬性值:

group = 0【A的group取-1;B的group取-2】

CategoryBitmask = 0xFFFFFFFF

ContactTestBitmask = 0xFFFFFFFF【AB都取這個值】

CollisionBitmask = 0xFFFFFFFF

  • 現象和分析:

  • 同類之間不碰撞,a b爲同一類物品【group決定的,相同的負的group值的對象不會碰撞;雖然((a.CategoryBitmask & b.ContactTestBitmask) != 0 || (a.ContactTestBitmask & b.CategoryBitmask) != 0)等於true,但沒碰撞的前提,故無回調】

  • 不同類可以碰撞,a b爲不同類的物品【group的值不一樣,取決於bitmask了;碰撞的理由是(a.CollisionBitmask & b.CategoryBitmask) != 0非0,true,b也是;回調理由是有碰撞且((a.CategoryBitmask & b.ContactTestBitmask) != 0 || (a.ContactTestBitmask & b.CategoryBitmask) != 0) 等於true】


想要A類和B類碰撞,A類之間不碰撞,B類之間不碰撞-法2

  • 屬性值:

group = 0【AB都保持默認0】

CategoryBitmask = 【A的CategoryBitmask=0x01;B的CategoryBitmask=0x02】

ContactTestBitmask = 【A的ContactTestBitmask=0x02;B的ContactTestBitmask=0x01】

CollisionBitmask = 【A的CollisionBitmask=0x02;B的CollisionBitmask=0x01】

  • 現象和分析:

  • 同類之間無碰撞,a b爲同一類物品【無碰撞的理由是(a.CollisionBitmask & b.CategoryBitmask) != 0false; 無回調是((a.CategoryBitmask & b.CollisionBitmask) != 0 || (a.CollisionBitmask & b.CategoryBitmask) != 0)等於false故無回調】

  • 不同類可以碰撞,a b爲不同類的物品【碰撞的理由是(a.CollisionBitmask & b.CategoryBitmask) != 0true,b也是;回調理由是有碰撞且((a.CategoryBitmask & b.ContactTestBitmask) != 0 || (a.ContactTestBitmask & b.CategoryBitmask) != 0)等於true】


效果圖

想要A類和B類碰撞,A類之間不碰撞,B類之間不碰撞(NOTE: gif中,相同的圖片是同一類,不同圖片類型不同) 

1423627494843807.gif


總結

  • 能碰撞,不能碰撞以及碰撞事件通知的大致邏輯

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
PhysicsBody a;
PhysicsBody b;
if ((a.group == b.group) && a.group > 0) {
    /*能碰撞,有碰撞的物理效果*/
    if (((a.CategoryBitmask & b.ContactTestBitmask) != 0)
            || ((a.ContactTestBitmask & b.CategoryBitmask) != 0)) {
        /*條件成立,執行相交通知*/
    }
else if ((a.group == b.group) && a.group < 0) {
    /*不能碰撞,沒有碰撞的物理效果*/
else {
    if ((a.CollisionBitmask & b.CategoryBitmask) != 0) {
        /*a能碰撞,a有碰撞的物理效果*/
        if (((a.CategoryBitmask & b.ContactTestBitmask) != 0)
                || ((a.ContactTestBitmask & b.CategoryBitmask) != 0)) {
            /*條件成立,執行相交通知*/
        }
    else {
        /*a不能碰撞,a沒有碰撞的物理效果*/
    }
    if ((b.CollisionBitmask & a.CategoryBitmask) != 0) {
        /*b能碰撞,b有碰撞的物理效果*/
        if (((a.CategoryBitmask & b.ContactTestBitmask) != 0)
                || ((a.ContactTestBitmask & b.CategoryBitmask) != 0)) {
            /*條件成立,執行相交通知*/
        }
    else {
        /*b不能碰撞,b沒有碰撞的物理效果*/
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章