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中,相同的圖片是同一類,不同圖片類型不同)
總結
-
能碰撞,不能碰撞以及碰撞事件通知的大致邏輯
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沒有碰撞的物理效果*/ } }
|