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没有碰撞的物理效果*/
}
}
|