quick-cocos2d-x物理引擎之chipmunk(二)

上一篇讲了quick-cocos2d-x使用chipmunk的使用流程,介绍了World,Body,Shape的创建,这一篇将讲解如何处理物体之间的碰撞。

1、监听事件
quick-cocos2d-x中的chipmunk碰撞处理是经过监听事件来实现的。 函数

-- 设置物体的碰撞类别,默认全部物体都是类别0
Body:setCollisionType(type)
-- handle是一个回调函数,碰撞处理将在这个函数中执行
-- collisionTypeA和collisionTypeB是两个int值,表示要监听的是哪两种物体
-- 这两个值在body中设置(上面所示的方法),两个值相同时为监听同种物体之间的碰撞
World:addCollisionScriptListener(handler, collisionTypeA, collisionTypeB)
-- handler回调函数,这个函数必定要返回true,否则碰撞后两个物体将会重合,即像是不碰撞同样
-- eventType为碰撞的类别,有四种值:
--   begin 开始碰撞
--   preSolve 持续碰撞(相交),能够设置相交时独自的摩擦,弹力等
--   postSolve 调用完preSolve后,作后期处理,好比计算破坏等等
--   separate 分开,当删除一个shape时也会调用
-- event为CCPhysicsCollisionEvent实例
onCollisionListener(eventType, event)
示例:
body:setCollisionType(1)
self.world:addCollisionScriptListener(handler(self, self.onCollisionListener), 1, 2)
function PhysicsScene:onCollisionListener(eventType, event)
    print(eventType)
    return true
end

2、 CCPhysicsCollisionEvent
在回调函数中,有个重要的参数就是event了,CCPhysicsCollisionEvent中包含不少碰撞时的信息
-- 获取CCPhysicsWorld
event:getWorld()
-- 获取两个碰撞的body
event:getBody1()
event:getBody2()
-- 是不是两种物体第一次接触
event:isFirstContact()
-- 弹性系数,在preSolve以前设置可改变当前值
event:setElasticity(elasticity)
event:getElasticity()
-- 摩擦系数,在preSolve以前设置可改变当前值
event:setFriction(friction)
event:getFriction()
-- 碰撞时两物体的接触点数
event:getCount()
-- 获取接触点
event:getPoint(index)

3、分组碰撞
咱们在作一款游戏的时候,可能里面有不少的物体类型,咱们但愿某一物体只与特定的其它物体碰撞,而不是所有都碰撞,这种状况下就须要对物体进行分组了,在quick-cocos2d-x中可经过如下方法来实现
-- body所在的碰撞层,默认值为0,同层的物体才会发生碰撞
-- layers能够表示多个层,具体怎么达到的呢
-- 当咱们对一个物体分层时,所用的数字应该为[1,2,4,8,16,32,...]这样形式(倍增)来分
-- 如A为1,B为2,C为4,即为基本层(layer),若是要求C可与A碰撞,则C的layers为1+4=5
Body:setCollisionLayers(layers)
-- body所在组,默认值为0,同个组的将不发生碰撞(除了0组)
-- 优先级高于layer,当group不同的时候才会考虑layers
Body:setCollisionGroup(group)
从上面咱们能够得出:
两个物体要想发生碰撞,就要
一、group不同或都为0。
二、至少有一个layer(注意,非layers)是同样的

下面将经过一个具体的案例来说解。

假如咱们设计一个游戏,内容为上古部落之间的战争,有A,B,C,D四个部落,A和B为结盟关系,C,D则是各自独立的,这是一个三角混战的关系,那么就有如下的规则:
1)A和B分别与C,D碰撞
2)A和B之间不发生碰撞
3)C与A,B,D之间都碰撞
4)D与A,B,C之间都碰撞
5)A,B,C,D之间各自(即A与A,B与B,...)不碰撞
咱们设计的基本层为:A=1,B=2,C=4,D=8

可由上图得出它们各自的layers为
A.layers=1
B.layers=2
C.layers=1+2+4+8
D.layers=1+2+4+8
上面有一些是重复的层,能够进行简化
A.layers=1
B.layers=2
C.layers=1+2+4+8
D.layers=1+2 +8
还能够把C,D放在同一层4进行简化
A.layers=1
B.layers=2
C.layers=1+2+4
D.layers=1+2+4
具体的分法并无一个统一的方法,只要合乎上面的原则便可,并且物体多时会比较麻烦,你们要多加注意。
设置layers只解决了1)——4)而已,5)仍是没有解决,这就用到了group这一属性,咱们把A,B,C,D设为不一样的group便可
A. group =1
B. group =2
C. group =3
D. group =4
最后的代码以下:
-- 为了程序清晰,layers不用求和
A:setCollisionLayers(1)
B:setCollisionLayers(2)
C:setCollisionLayers(1+2+4+8)
D:setCollisionLayers(1+2+4+8)
A:setCollisionGroup(1)
B:setCollisionGroup(2)
C:setCollisionGroup(3)
D:setCollisionGroup(4)
相关文章
相关标签/搜索