SpriteKitで衝突判定(Swift)

botman_blue iOS

Xcode-13.1

はじめに

SpriteKit でノードを衝突させる方法についてです。

SKPhysicsBody

とりあえずまずはノードに SKPhysicsBody を設定してやる必要があります。

SKPhysicsBody:ドキュメント

body

skView.showsPhysics = true により physicsBody を青線で表示してくれます。

イニシャライザは下記があるようです。

下記のプロパティとメソッドがあります。

衝突判定で重要なのは下記。

衝突判定

ScneKit の話ですが bitMask の考え方は同じです。
SceneKitの衝突判定(Swift)

衝突させる

物体が衝突するかどうかは下記2つの値が関係しています。

categoryBitMaskcollisionBitMask の AND(論理積)が 0 以外の場合に衝突が起きます。

こんな感じで実装して applyImpulse で動かしてみるとこうなります。

重要なのはここ!

■red を動かした場合

  • red の categoryBitMask(0b000001)と blue の collisionBitMask(0b000100)の論理積は 0
  • blue の categoryBitMask(0b000010)と red の collisionBitMask(0b000011)の論理積は 10

結果 red と blue は衝突はしますが blue は動きません。

■blue を動かした場合

  • blue の categoryBitMask(0b000010)と red の collisionBitMask(0b000011)の論理積は 10

結果 red と blue は衝突し red も動きます。

■yellow を動かした場合

  • yellow の categoryBitMask(0b001000)と red の collisionBitMask(0b000011)の論理積は 0
  • yellow の categoryBitMask(0b001000)と blue の collisionBitMask(0b000100)の論理積は 0
  • yellow の collisionBitMask(0b001000)と red の categoryBitMask(0b000001)の論理積は 0
  • yellow の collisionBitMask(0b001000)と blue の categoryBitMask(0b000010)の論理積は 0

結果 yellow は red, blue ともに衝突しません。

衝突判定

物体が衝突を通知するかどうかは下記2つの値が関係しています。

categoryBitMaskcontactTestBitMask の AND(論理積)が 0 以外の場合に衝突が通知されます。

上記のように実装すると red, blue どちらから衝突させた場合も didBegin, didEnd ともに呼ばれました。

  • red の categoryBitMask(0b000001)と blue の contactTestBitMask(0b000100)の論理積は 0
  • blue の categoryBitMask(0b000010)と red の contactTestBitMask(0b000011)の論理積は 10

上記の結果どちらの場合も衝突通知が発生するものと思われます。

yellow も置いて下記のように bitMask を設定するとこうなります。

  • red と blue
    衝突しますが通知はされません。
  • blue と yellow
    衝突しないし通知もされません。
  • red と yellow
    衝突しないですが通知はされます。

おわりに

これでノードの衝突もできるようになりました!ビットマスクがややこしいですがこれで衝突させ放題です!

参考

SpriteKitの衝突処理について(categoryBitMask collisionBitMask contactTestBitMask 使い方)

コメント

タイトルとURLをコピーしました