2016-10-30 16 views
10

SpriteKitの機能をテストしていて、問題が発生しました。私はビットマスク、衝突、カテゴリ、連絡先を読み込んでいました。ほとんどの場合、カテゴリビットマスクのポイントは得られませんが、問題を解決するために必要なビットマスクが衝突します。SpriteKitを使用してオブジェクトが衝突するのを防ぐ

私の問題は2種類あります:オブジェクト秒です。名前は実際にはあまり意味がありませんが、テストのためだけです。私は2番目に衝動があることを望み、オブジェクトに力を与えたい。私はスプライトにそれぞれのベクトルを適用することができましたが、私はそれらを互いに衝突させたくありません。私は彼らが右を通過し、お互いの存在を無視してほしい。

Iは、互いに異なる衝突ビットマスクを割り当てることによって、その問題を解決しようとした:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 
    let texture = SKTexture(imageNamed: "pokeball") 
    let object = SKSpriteNode(texture: texture) 

    object.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: object.size.width,height: object.size.height)) 
    object.physicsBody?.affectedByGravity = false 
    object.yScale = 0.5 
    object.xScale = 0.5 

    for t in touches { 
     object.position = t.location(in: self) 
    } 
    self.addChild(object) 
    object.physicsBody?.collisionBitMask = UInt32(4) 
    object.physicsBody?.applyForce(CGVector(dx: 0, dy: 10)) 

} 

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { 
    let texture = SKTexture(imageNamed: "purple") 
    let second = SKSpriteNode(texture: texture) 
    let impulse : Double = 20 
    let x = (impulse * Double(cosf(45))) 
    let y = Double(impulse * Double(sinf(45))) 
    let vector = CGVector(dx: x, dy: y) 
    second.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: second.size.width,height: second.size.height)) 

    second.yScale = 1.5 
    second.xScale = 1.5 
    second.physicsBody?.isDynamic = true 

    for t in touches { 
     second.position = t.location(in: self) 
    } 
    self.addChild(second) 
    second.physicsBody?.collisionBitMask = UInt32(1) 
    second.physicsBody?.applyImpulse(vector) 
} 

ようにオブジェクトが4のビットマスクを有する:

object.physicsBody?.collisionBitMask = UInt32(4) 

そして第1のビットマスクを有する。

second.physicsBody?.collisionBitMask = UInt32(1) 

私はシミュレータを使いましたが、まだ衝突していましたので、私はオンラインになり、いくつかの回答のためのk:私は数字のように使用する必要があると言うものを見つけました:

これらはビットマスクです、あなたは任意の数字1,2,3,4,5を使用することはできません - 4,8,16など -

誰かが理由を説明できますか?しかし、1と4を使用していたのでそれは問題ではなかった

次の質問私は二進数(0100)と(0010)を使用しなければならなかったと言いました。

私は衝突の絵を残します: Collisions

なぜこれが起こっている誰もが知っていますか?もしこれが本当にダムなミスやすでに尋ねられていることであれば、私はそれを見つけることができませんでした。

+0

これを見てください:http://stackoverflow.com/a/39064710/3402095カテゴリービットマスクのデフォルト値を探します。それはすべてそこに説明されています。 – Whirlwind

+0

物理ボディにcollisionBitMAskが4であることを指定すると、categoryBitMaskが4のphysicsBodyと衝突します(実際には '4'ビットがオンになっていますが、最も簡単な例から始めます)。あなたがcategoryBitMasksを見たことが気にならないなら、物事はうまくいかないでしょう。 –

答えて

7

これらのトピックについては多くのドキュメントがありますが、実際の例があります。

categoryBitMasks

のパワーは、あなたが3つのノード poolbasketballbowlingballのコレクションを持っているふり。明らかに、我々は basketballbowlingballがお互いに衝突することを望んでいます。したがって、collisionBitMasksを次のように設定します。

basketball.physicsBody?.collisionBitMask = UInt32(2) 
bowlingball.physicsBody?.collisionBitMask = UInt32(2) 

素晴らしいです。今度は、bowlingballpoolの底に沈めて、basketballpoolと衝突させたいと思っています。どうすればこのことができますか?私たちは試みることができる:

pool.physicsBody?.collisionBitMask = UInt32(2) // ? 

しかし、待って、それはbasketballになるだろうとbowlingballpoolと衝突します。 basketballはプールに衝突するだけですが、bowlingballpoolを無視して、衝突なしで真っ直ぐ下に沈んだりします。

let basketballBitMask  = UInt32(1) 
let bowlingballBitMask = UInt32(2) 
let poolBitMask   = UInt32(4) // Why 4? See next section 

basketball.physicsBody?.categoryBitMask = basketballBitMask 
bowlingball.physicsBody?.categoryBitMask = bowlingballBitMask 
pool.physicsBody?.categoryBitMask   = poolBitMask 

各オブジェクトは、それに割り当てられた固有の番号を持っているので、あなたが今選んで、あなたはと衝突することを目的とするたいオブジェクトを選択できます:

// basketball physics body collides with bowlingball(2) OR pool(4) 
basketball.physicsBody?.collisionBitMask = bowlingballBitMask | poolBitMask 
// ('|' = logical OR operator) 

// bowlingball physics body only collides with basketball(1) 
bowlingball.physicsBody?.collisionBitMask = basketballBitMask 

// pool physics body only collides with basketball(1) 
pool.physicsBody?.collisionBitMask   = basketballBitmask 
categoryBitMaskが便利になるsの場所です

奇妙な '|'あなたがここで何が起こっているのかを理解するのを助けるために高度な演算子にswift documentationを強くお勧めします。

なぜcollisionBitMasksを使用しないのですか?

これで、ビットマスクをいくつか設定しました。しかし、彼らはどのように使われていますか?私たちが2つのオブジェクトしか持っていない場合、なぜcollisionBitMasksを比較できないのですか?

簡単に言えば、それはどのように動作するかではありません。

;(結果は同じであるか、またはその逆) bowlingballpool、SpriteKitベースの物理エンジンし、(「&」)と共に bowlingballpoolとcategoryBitMaskのcollisionBitMaskと接触したときに

bowlingballcategoryBitMaskpoolcollisionBitMaskの共通のゼロ・ビットを有するので

objectsShouldCollide = (bowlingball.physicsBody?.categoryBitMask & 
         pool.physicsBody?.collisionBitMask) 
// objectsShouldCollide = (ob010 & 0b100) = 0b000 
は、 objectsShouldCollideはゼロに等しく、SpriteKitベースが衝突からオブジェクトを停止します。

しかし、あなたの場合は、オブジェクトのcategoryBitMaskを設定していません。そのため、デフォルト値は2^32、0xFFFFFFFF(hexadecimal representation)、バイナリは0b11111111111111111111111111111111です。 「オブジェクト」は、「第二」のオブジェクトに当たったのでとき、SpriteKitベースはこの行います。あなたが定義されていないので、

objectsShouldCollide = (0b11111111111111111111111111111111 & // Default categoryBitMask for "object" 
         0b00000000000000000000000000000001) // collisionBitMask for "second" object 
//     = 0b00000000000000000000000000000001 

objectのcategoryBitMask、どんなにあなたがsecondオブジェクトのcollisionBitMaskとして設定したもの、objectsShouldCollideはなります絶対にゼロにならず、常に衝突します。

注:オブジェクトのcollisionBitMaskを0に設定できます。そのオブジェクトは決して何にも衝突することができません。 categoryBitMasks

2(0,1,2,4,8など)の力を利用し

は、今の私たちはお互いに衝突し、複数のbowlingball秒を含めるしたいとしましょう。簡単:

ここ
bowlingball.physicsBody?.collisionBitMask = basketballBitMask | bowlingballBitMask 
// bowlingball collision bit mask (in binary) = 0b10 | 0b01 = 0b11 
// bowlingball collision bit mask (in decimal) = 2 | 1 = 3 

あなたは私たちがするUInt32へpoolのphysicsCategoryを設定していた場合(3)、それはもはやbowlingballまたはbasketballと区別しないであろうことがわかります。

さらに提案

は(偶然、「objectsecondオブジェクトは」非常によく働いていた、が)あなただけのテストのためにそれらを使用している場合でも、目的とname変数をご覧ください。

はあなたのコードを簡素化し、読みやすさを改善するために、ビットマスクのための構造体を使用してください:

struct PhysicsCategory { 
    static let Obj1   : UInt32 = 0b1 << 0 
    static let Obj2   : UInt32 = 0b1 << 1 
    static let Obj3   : UInt32 = 0b1 << 2 
    static let Obj4   : UInt32 = 0b1 << 3 
} 

obj1.physicsBody?.categoryBitmask = PhysicsCategory.Obj1 // etc 
+0

私はコリジョンビットマスクにまっすぐ行くことができるときにカテゴリビットマスクが必要な理由はありませんか?どうか説明していただけますか?私が衝突ビットマスクを変更したときのデフォルト値は上書きされませんか? – Pablo

+0

いいえカテゴリビットマスクは、衝突ビットマスクと同じものではありません。私の更新された答えを読んでください。 – Ralph

2

あなたがダウンロードして、この単純なスプライト・キットのプロジェクトに再生されないのはなぜ?さまざまな幾何学的図形を作成し、それらのいくつかを衝突させ、いくつかは接触させ、checkPhysics()関数を使用して何が起きるかを表示し、図形をフリックさせます。

Attack button in SpriteKit

それについてどのような質問が働きだと私は試してみて、説明するよりも幸せになります。

+1

文書内のリンクされたプロジェクトのアップヴォートよりも完全に報酬を与える方法が必要です。とても良い! – Confused

関連する問題