SpriteKit当たり判定
SpriteKitの当たり判定はオブジェクトごとに保持しているカテゴリーと当たり判定が相手と一致した時に当たったと見なされます。
サンプルコード
実行時の画像
ソースと解説
画像のようなシンプルなサンプルを作成しました。tapしたポジションからNodeを発生させ円との当たり判定をとっています。
class GameScene: SKScene, SKPhysicsContactDelegate {
private var label : SKLabelNode?
private var spinnyNode : SKShapeNode?
override func didMove(to view: SKView) {
//重力の設定
self.physicsWorld.gravity = CGVector(dx: 0, dy: -3)
let floor = SKShapeNode(circleOfRadius: 400)
floor.position = CGPoint(x: 0, y: -(view.frame.maxY))
floor.fillColor = .red
//当たり判定の大きさ
floor.physicsBody = SKPhysicsBody(circleOfRadius: 400)
//重力を無効にする
floor.physicsBody?.affectedByGravity = false
//カテゴリ
floor.physicsBody?.categoryBitMask = 0x1 << 0
//衝突
floor.physicsBody?.collisionBitMask = 0x1 << 2
self.addChild(floor)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touchPos = touches.first?.previousLocation(in: self){
let rect = SKShapeNode(rectOf: CGSize(width: 50.0, height: 50.0))
rect.position = touchPos
rect.fillColor = .blue
//当たり判定の大きさ
rect.physicsBody = SKPhysicsBody(rectangleOf: rect.frame.size)
//カテゴリ
rect.physicsBody?.categoryBitMask = 0x1 << 1
//衝突
rect.physicsBody?.collisionBitMask = 0x1 << 0
self.addChild(rect)
}
}
}
コード一覧を載せました。コメントを入れたのである程度はわかると思うのですが、つまづきやすいカテゴリとマスクの部分を解説します。
categoryBitMaskとcollisionBitMask
コードだけだとわかりにくいので画像の中にカテゴリと衝突のビットマスクがどうなっているのかを書き込んでみました。
注目して欲しいのは四角の衝突と、円のカテゴリーが0で一致しているという部分です。
0x1 << 1, 0x1 << 2などこれはなんだ?という話なのですが、ビット演算というものを行なっています。詳しくは調べればたくさん出てきます。がここを詳しくやるとこんがらがってしまいそうなので割愛します。
ようするに、物体Aのカテゴリと物体Bの衝突が等しければBはAに衝突します。
今回の例でいうと物体Aは円にあたり、物体Bは四角です。
//四角---------------------
//カテゴリ
rect.physicsBody?.categoryBitMask = 0x1 << 1
//衝突
rect.physicsBody?.collisionBitMask = 0x1 << 0
//円----------------------
//カテゴリ
floor.physicsBody?.categoryBitMask = 0x1 << 0
//衝突
floor.physicsBody?.collisionBitMask = 0x1 << 2
円が四角に当たっても落下していかないのは円の衝突が2であり、四角のカテゴリは1で異なっている為、実は円は衝突していないことになっている為四角だけが衝突して落下していくことになります。