Swiftで遊ぼう! - 757 - Sprite Kit ノードを作ればボディー
質問
今日の記事内で疑問を呈していますが、SKNodeのメソッド「addChild()」はどのオブジェクトから発動しているのでしょうか?
-
-
-
- -
-
-
少し複雑なSKSpriteKitのチュートリアルに取り組んでいます。
GameSceneにノードを設定するメソッドを書いています。
func newProjectile () { let beaker = SKSpriteNode(imageNamed: "beaker") beaker.name = "beaker" beaker.zPosition = 5 beaker.position = CGPoint(x: 120, y: 625)
ここまででSKSpriteNodeオブジェクト(インスタンス)が1つできました。
今日はノードに物理(physics)世界を組み込むのですが、それがSKPhsicsBodyの設定です。
// まずノード(ビーカー)の位置に四角(時に丸く)のボディを着せるような感じです。 let beakerBody = SKPhysicsBody(rectangleOf: CGSize(width: 40, height: 40)) // 重量と密度もプロパティとして持っています。「mass」は重量になります。 // CGFloat型で「kg」を意味します。 beakerBody.mass = 1.0 // ここから「カテゴリー」の設定です。カテゴリーはノードの「contact」を // 判定するために状態を設定します。「PhysicsType.beaker」は、 // グローバル定数としてStruct型で与えられています。 beakerBody.categoryBitMask = PhysicsType.beaker
GameSceneクラス宣言の前に次のグローバル定数を宣言します。前にも話しましたが、このようなカテゴリーを設定する場合、struct型よりenum型を使った方がいいと思うのですが、ベテランプログラマーの皆さん、どうでしょうか?
struct PhysicsType { static let none :UInt32 = 0 static let player :UInt32 = 1 static let wall :UInt32 = 2 static let beaker :UInt32 = 4 static let explosionRadius :UInt32 = 8 static let cat :UInt32 = 16 static let zombieCat :UInt32 = 32 }
このカテゴリー設定ですが、非常に重要な概念が「bitMask」です。この値は「UInt32」が設定されているんですが、基本的に2進法で表現するので32桁のパターン、要するに32通りの設定ができます。当然、10進法で見れば、2の倍数で表します。2進法を用いるのは、論理計算(ANDやOR)で結果を求める為です。
01 = 0b000001
02 = 0b000010
04 = 0b000100
08 = 0b001000
16 = 0b010000
32 = 0b100000
// ビーカーが衝突判定をしたいのは、ターゲットの猫と壁です。 // ということで「collisionBitMask」は「PhysicsType.cat」 // と「PhysicsType.wall」になります。 beakerBody.collisionBitMask = PhysicsType.wall | PhysicsType.cat // 単純ですが、ビーカーの物理世界ができあがったので // ビーカーに設定してからノードをシーンに追加します。 // 「addChild」はSKSceneのメソッドだと勘違いしていました。 // 実はSKNodeの持ているメソッドです。 // ちょっと疑問点があります。 // どのSKNodeのメソッドが発動しているのでしょうか? // たぶんGameScene.sksで設定しているSKNodeのどれかだと // 思います。1番ベースの階層に設定している「bk」 // でしょうか? どなたか教えてくださいm(_ _)m beaker.physicsBody = beakerBody addChild(beaker)
ここまでの話は、SpriteKitチュートリアルで説明した内容と同じなです。次のコードがノードの融合の話になりますが、明日説明します。
if let armBody = childNode( withName: "player")?.childNode( withName: "arm")?.physicsBody { pinBeakerToZombieArm = SKPhysicsJointFixed.joint(withBodyA: armBody, bodyB: beakerBody, anchor: CGPoint.zero) physicsWorld.add(pinBeakerToZombieArm!) beakerReady = true } }