天天看點

2dx-Box2d

1.開啟實體引擎

Android  

projects/pojectName/proj.android/jni/Application.mk

DCC_ENABLE_CHIPMUNK_INTEGRATION=1

DCC_ENABLE_BOX2D_INTEGRATION=1

ios

CC_ENABLE_CHIPMUNK_INTEGRATION=1

CC_ENABLE_BOX2D_INTEGRATION=1

代碼

createWithPhysics 建立scene時候開啟,必須在 Layer:onEnter 後才能調用 scene->getPhysicsWorld()

2.實體世界

1.世界:PhysicsWorld和2dx的scene關聯,控制整個世界裡的物體。

關聯兩個物體 addJoint

設重力                         setGravity

得到世界裡所有剛體    getAllBodies

通過tag确定剛體 getBody(1)

檢測射線運動              rayCast

是否顯示剛體 setDebugDrawMask

判斷是否觸摸到剛體   getShapes

振頻率 setUpdateRate

3.剛體

基礎

offset:           重心點

velocity:        速度 

dadamping: 阻尼 

rerestitution:彈力 

material:      材質(密度,摩擦力,恢複力) 

mass:          品質

moment:     力矩,當他碰到另一個剛體時候 ,會産生一股扭轉力,做旋轉運動

body:          剛體,表示實體世界中的抽象實體,附帶有實體屬性

shape:        剛體的形狀,同一個body可以附加多個shape 該shape們不會發生碰撞

joint:           關節,可以連接配接>=2個剛體 

剛體

PhysicsBody和2dx的node及其子類關聯,通過形狀确定剛體的大小以及碰撞的範圍

剛體的類型大概有三種:靜态剛體(static body)、棱柱剛體(Prismatic body)、動态剛體(Dynamic Body)。

其中棱柱剛體沒有品質,但是可以有速度,引擎會根據熟讀計算并更新它的位置。

建立剛體時指定形狀

實體矩形 PhysicsBody::createBox

空體              box PhysicsBody::createEdgeBox           EdgeBox預設不受重力影像(靜态剛體)

空體矩形       PhysicsBody::createEdgeSegment

圓                 PhysicsBody::createCircle

多邊形 PhysicsBody::createPolygon

。。。

PhysicsBody::create() 可以放多個剛體形狀

addShape 繪制剛體形狀

剛體方法

靜态剛體 setDynamic(false)

不受重力影響   setGravityEnable(false)

品質 setMass

等等                 setMoment

加速度 setVelocity

角速度             setAngularVelocity

唯一标示 setTag

setCategoryBitmask(0x01) 設定掩碼

setCollisionBitmask

setContactTestBitmask

local2World 坐标轉換

getVelocityAtWorldPoint

setPositionOffset                 位置

setRotationOffset 角度

4.剛體碰撞

set / get方法來設定和擷取

CategoryBitmask: 碰撞掩碼 category   (0xFFFFFFFF)

ContactTestBitmask: 觸發碰撞事件掩碼contact    (0x00000000)

CollisionBitmask: 是否發生碰撞掩碼collision  (0xFFFFFFFF)

body1 和 body2

觸發碰撞事件(預設不觸發)

(category1 & contact2)!=0 并且 (category2 & contact1)!=0

發生碰撞(預設)

(category1 & collision2)!=0 并且 (category2 & collision1)!=0

碰撞事件

EventListenerPhysicsContact                         多個剛體碰撞

EventListenerPhysicsContactWithBodies 兩個剛體碰撞

EventListenerPhysicsContactWithShapes

EventListenerPhysicsContactWithGroup

onContactBegin      在接觸開始時被調用,僅調用一次,通過放回true或者false來決定兩個物體是否有碰撞。同時可以使用PhysicsContact::setData()來設定接觸操作的使用者資料。當傳回false時,onContactPreSolve和onContactPostSolve将不會被調用,但是onContactSeperate将被調用一次。

onContactPreSlove   會在每一次被調用,通過放回true或者false來決定兩個物體是否有碰撞,同樣可以用ignore()來跳過後續的onContactPreSolve和onContactPostSolve回調函數。(預設傳回true)

onContactPostSolve  在兩個物體碰撞反應中的每個步驟中被處理調用。可以在裡面做一些後續的接觸操作。如銷毀body

onContactSeperate   在兩個物體分開時被調用,在每次接觸時隻調用一次,和onContactBegin配對使用。

兩個body碰撞

auto contactListener = EventListenerPhysicsContactWithBodies::create(body1, body2);
contactListener->onContactBegin = CC_CALLBACK_1(PhysicsDemoOneWayPlatform::onContactBegin, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(contactListener, this);
bool PhysicsDemoOneWayPlatform::onContactBegin(PhysicsContact& contact)								//獲得剛體的一些資訊 contact
{
    return contact.getContactData()->normal.y < 0;
}
           

多個body碰撞

auto contactListener = EventListenerPhysicsContact::create();
contactListener->onContactBegin = CC_CALLBACK_1(PhysicsContactTest::onContactBegin, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(contactListener, this);
bool PhysicsContactTest::onContactBegin(PhysicsContact& contact)
{
    PhysicsBody* a = contact.getShapeA()->getBody();
    PhysicsBody* b = contact.getShapeB()->getBody();
    PhysicsBody* body = (a->getCategoryBitmask() == 0x04 || a->getCategoryBitmask() == 0x08) ? a : b;
    CC_UNUSED_PARAM(body);
    CC_ASSERT(body->getCategoryBitmask() == 0x04 || body->getCategoryBitmask() == 0x08);
    
    return true;
}
           

工具:

PhysicsEditor:比較麻煩

VertexHelper:代碼形式工具

不規則圖像碰撞檢測,先用工具描剛體邊,确定繪制多邊形剛體的坐标點,之後在代碼裡繪制此剛體

總結:

世界關聯的

  剛體

剛體關聯的

  形狀

  碰撞

  關節

繼續閱讀