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)
相關文章
相關標籤/搜索