[iOS 8] SpriteKit でミニゲームをつくる #14 物理エンジン ジョイント
物理エンジン ジョイント
今回は、ペンギンが隣り合わせになったら、手をつなぐ処理を作ります。
コードは前回からの続きです。
まず、ペンギンを生成するときに、手の領域のノードを追加します。今回は、動かしたときに見分けやすいように白くしています。
func addPenguinBlock() -> SKSpriteNode! { .................... .................... .................... // 手を追加する。 let handRight = SKSpriteNode(color: UIColor(white: 1, alpha: 0.5) , size: CGSizeMake(40, 40)) handRight.position = CGPointMake(-46, 0) handRight.name = "hand" handRight.zPosition = 1 penguin.addChild(handRight) let handLeft = SKSpriteNode(color: UIColor(white: 1, alpha: 0.5) , size: CGSizeMake(40, 40)) handLeft.position = CGPointMake(46, 0) handLeft.name = "hand" handLeft.zPosition = 1 penguin.addChild(handLeft) // ペンギンをレイヤーに追加する。 isLandLayer?.addChild(penguin) return penguin }
次に、フレームごとの物理演算の後に呼ばれる didSimulatePhysics メソッドで、手が他のペンギンの手と重なっているかどうかを判別して、重なっている手(接続可能な手)がある場合は星印を追加して、手を削除します。
override func didSimulatePhysics() { let isLandLayer = childNodeWithName("scrollLayer")?.childNodeWithName("isLandLayer") for child in isLandLayer!.children { jointHand(child as SKNode) } } func jointHand(penguin:SKNode) { for child in penguin.children { let penguinHand:SKNode = child as SKNode let penguinHandPoint:CGPoint = penguin.convertPoint(penguinHand.position, toNode: self) // 接続可能な手を取得する。 let jointHand = jointHandFromHand(penguinHand, penguinHandPoint:penguinHandPoint) // 接続する手がある場合は接続する。 if jointHand != nil { addJoint(penguinHand, jointHand: jointHand) } } } func jointHandFromHand(penguinHand:SKNode, penguinHandPoint:CGPoint) ->SKNode! { var jointHand:SKNode! var nodes = nodesAtPoint(penguinHandPoint) for node in nodes { let childNode:SKNode! = node as? SKNode if childNode != nil { if penguinHand.parent != childNode.parent { if childNode.name? == "hand" { jointHand = childNode break } } } } return jointHand } func addJoint(penguinHand:SKNode, jointHand:SKNode) { let penguinHandPoint:CGPoint = penguinHand.parent!.convertPoint(penguinHand.position, toNode: self) let jointHandPoint:CGPoint = jointHand.parent!.convertPoint(jointHand.position, toNode: self) // 2点の中点を取得する。 let jointPoint:CGPoint = CGPointMake((penguinHandPoint.x + jointHandPoint.x) / 2.0, (penguinHandPoint.y + jointHandPoint.y) / 2.0) // 中点でジョイントする。 let jointPin = SKPhysicsJointPin .jointWithBodyA(penguinHand.parent!.physicsBody, bodyB: jointHand.parent!.physicsBody, anchor: jointPoint) physicsWorld.addJoint(jointPin) // ジョイントの星印を追加する。 var joint:SKSpriteNode = SKSpriteNode(texture:atlas.textureNamed("link")) joint.position = convertPoint(jointPoint, toNode: penguinHand.parent!) joint.xScale = 0.0 joint.yScale = 0.0 joint.zPosition = penguinHand.parent!.zPosition + 1 penguinHand.parent!.addChild(joint) joint.runAction(SKAction.scaleTo(1.0, duration: 0.2)) // 接続したら手を削除する。 jointHand.removeFromParent() penguinHand.removeFromParent() }
手を接続しているところでは、SKPhysicsJointPin を使っています。
では、動かしてみます。
白い四角の部分が手の領域で、星印のところが手をつないでいるところです。
いまさらだけど、ペンギンって「手」じゃなくて「翼」だったかな?まあいいか。。
動きを見たい方は、ぜひ「つみペンギン」をダウンロードしてみてください。
次回へ続く。ではでは。