[SceneKit專題]9-Basic-Collision-Detection碰撞檢測基礎

蘋果API搬運工發表於2017-12-25

說明

本系列文章是對<3D Apple Games by Tutorials>一書的學習記錄和體會

此書對應的程式碼地址

SceneKit系列文章目錄

設定node屬性

對一個小球節點設定屬性:

QQ20170405-235240@2x.png

  • Physics Body(物理形體):設定為Dynamic時,Scene Kit將會全面接管小球的運動
  • Settings(設定):Mass(質量),Friction(摩擦),Restitution(彈性),Rolling friction(滾動摩擦),Damping(阻尼),Angular damping(角阻尼),Charge(充值).
  • Velocity(速度): Linear velocity(線速度),Angular velocity(角速度),Linear factor(線性因子),Angular factor(角因子).Linear factor線性因子設定為 (x:1, y:0, z:1)時,作用在y軸的物理力將歸零,不受y軸方向影響.
  • Bit Masks(位掩碼):Category mask(分類掩碼)決定自己屬於哪一類,Collision mask(碰撞掩碼)決定自己能和哪一類物體碰撞,iOS9後新增Contact mask(接觸掩碼)決定和哪類物體的碰撞會呼叫代理.
  • Physics Shape(物理形狀):iOS9新增Collision Margin(碰撞邊距) iOS9以後新增屬性:
    QQ20170408-232555@2x.png

位掩碼的解釋

Scene Kit的位掩碼設計其實和cocos2d-x3.0是類似的. 每次碰撞時,用自己的Collision mask(碰撞掩碼)和別人的Category mask(分類掩碼)做按位與運算,運算結果為零則不能碰撞,運算結果不為零則會碰撞. 同理Contact mask(接觸掩碼)也是和別人的Category mask(分類掩碼)做按位與運算,運算結果為零則不會通知,運算結果不為零則會通知.

//設定各節點的Category mask(分類掩碼)
//Ball:          1 (Decimal) = 00000001 (Binary)
//Barrier:    2 (Decimal) = 00000010 (Binary)
//Brick:       4 (Decimal) = 00000100 (Binary)
//Paddle:    8 (Decimal) = 00001000 (Binary)

enum ColliderType: Int {
  case Ball = 0b1
  case Barrier = 0b10
  case Brick = 0b100
  case Paddle = 0b1000
}
//設定小球與哪些型別碰撞時呼叫代理通知
ballNode.physicsBody?.contactTestBitMask = ColliderType.Barrier.rawValue
|  ColliderType.Brick.rawValue | ColliderType.Paddle.rawValue
複製程式碼

碰撞代理

scnScene.physicsWorld.contactDelegate = self 設定SCNPhysicsContactDelegate,會有三個代理方法:

  • physicsWorld(_:didBeginContact:):該方法只在兩個物體接觸時呼叫一次.預設不呼叫,需要設定位掩碼決定後才會呼叫.
  • physicsWorld(_:didUpdateContact:):該方法在碰撞發生後呼叫,能提供碰撞進行過程中附加資訊.
  • physicsWorld(_:didEndContact:):該方法只在兩個物體脫離接觸時呼叫一次.

相關文章