[SceneKit专题]13-Intermediate-Collision-Detection碰撞检测中级

976 阅读2分钟

说明

本系列文章是对<3D Apple Games by Tutorials>一书的学习记录和体会

此书对应的代码地址

SceneKit系列文章目录

在迷宫类游戏中,小球需要和不同物体碰撞,和不同物体碰撞后又会有不同结果

QQ20170416-105051@2x.png

bit masks位掩码

就是二进制的值,可以用来做位运算,运算结果为0表示关,运算结果为其它值表示开

QQ20170412-223058@2x.png

Category masks分类掩码

用二进制数来代表不同物体的分类

QQ20170416-103707@2x.png

Collision masks碰撞掩码

表示自己能和哪些类别物体碰撞,如BALL(球)的值14=8+4+2,代表可以和2(STONE石头),4(PILLAR柱子),8(CRATE木箱)三类物体碰撞.而其他值都是1,代表只可以和1(BALL球)碰撞

QQ20170416-103745@2x.png

Contact masks接触掩码

表示和哪些物体碰撞时要触发代理事件.如BALL(球)的值14=8+4+2,代表和2(STONE石头),4(PILLAR柱子),8(CRATE木箱)三类物体碰撞时调用代理方法.而其他值都是0,代表碰撞时不通知代理.physicsWorld(world: SCNPhysicsWorld, didBeginContact contact:SCNPhysicsContact)

QQ20170416-103934@2x.png

小球的设置

动态形体,受重力影响,类掩码1,碰撞掩码14,物理形状默认,范围1

QQ20170416-105624@2x.png
QQ20170416-105635@2x.png
QQ20170416-105646@2x.png
QQ20170416-105656@2x.png

石头的设置

静态形体,不受重力,类掩码2,碰撞掩码1,物理形状默认

QQ20170416-105925@2x.png
QQ20170416-105936@2x.png
QQ20170416-105950@2x.png

##示例代码

//0.碰撞的代理方法
extension GameViewController : SCNPhysicsContactDelegate {
  func physicsWorld(world: SCNPhysicsWorld, didBeginContact contact:
SCNPhysicsContact) {
    // 1.确定小球是哪个节点
    var contactNode:SCNNode!
    if contact.nodeA.name == "ball" {
      contactNode = contact.nodeB
    } else {
      contactNode = contact.nodeA
    }
// 2.如果是和珍珠碰撞,则隐藏珍珠,30秒后重新显示
    if contactNode.physicsBody?.categoryBitMask == CollisionCategoryPearl
  {
      contactNode.hidden = true
      contactNode.runAction(SCNAction.waitForDurationThenRunBlock(30) { (node:SCNNode!) -> Void in
      node.hidden = false
    })
   }
// 3.如果是和柱子或木箱碰撞,可以在这里添加声音效果
  if contactNode.physicsBody?.categoryBitMask == CollisionCategoryPillar || ontactNode.physicsBody?.categoryBitMask == CollisionCategoryCrate {
  } }
}