cocos2d-x-3.3——碰撞检测3-物理引擎碰撞过滤
发表于2015-12-19
PhysicsBody相关API说明
- void setGroup(int group);
- void setCategoryBitmask(int bitmask);
- void setContactTestBitmask(int bitmask);
- void setCollisionBitmask(int bitmask);
DEMO及源码
- 基于cocos 3.4final
- DEMO功能:注册了物理碰撞事件的监听,用来查看是否有事件回调;注册了touch事件监听,在touch的结束事件里回在触摸点创建一个带物理效果的精灵。精灵有两种,用来测试PhysicsBody的设置造成的影响。具体看代码,不复杂。
- https://github.com/cheyiliu/CollisionDetection
验证对API的理解
所有参数保持默认
属性值:group =0CategoryBitmask =0xFFFFFFFFContactTestBitmask=0x00000000CollisionBitmask =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 =0xFFFFFFFFContactTestBitmask=0x00000000CollisionBitmask =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 =0CategoryBitmask =0xFFFFFFFFContactTestBitmask=0x00000001<-----change to thisCollisionBitmask =0xFFFFFFFF- 现象和分析:
- a b为同一类物品,有碰撞现象,有回调【碰撞的理由是(a.CollisionBitmask & b.CategoryBitmask) != 0非0, true;有回调的理由是((a.CategoryBitmask & b.ContactTestBitmask) != 0 || (a.ContactTestBitmask & b.CategoryBitmask) != 0) 等于true】
想要回调但不要碰撞效果
属性值:group =0CategoryBitmask =0xFFFFFFFFContactTestBitmask=0x00000001<-----change to thisCollisionBitmask =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 =0xFFFFFFFFContactTestBitmask=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中,相同的图片是同一类,不同图片类型不同)
- https://github.com/cheyiliu/All-in-One/raw/master/res/cocos2d/CollisionDetection-way3-use-physics-engine-filter.gif
总结
- 能碰撞,不能碰撞以及碰撞事件通知的大致逻辑