[iOS 8] SpriteKit でミニゲームをつくる #13 物理エンジン 接触

2014.09.18

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

物理エンジン 接触

今回は、ペンギンが氷の島に接触した時と、ペンギン同士が接触した時に、目パチを入れます。

前回までのコードに処理を追加します。
まず、物理ボディーに、所属するカテゴリーと、接触を検知するカテゴリーをセットします。

    // 氷の島のビットマスク
    let categoryBitMaskIsLand:UInt32 = 0x1
    
    // ペンギンのビットマスク
    let categoryBitMaskPenguin:UInt32 = 0x1 << 1
    
    override func didMoveToView(view: SKView) {
        
        ....................
        ....................
        ....................
        
        // 氷の島に物理ボディーを追加する。
        let isLand = childNodeWithName("scrollLayer")?
            .childNodeWithName("isLandLayer")?
            .childNodeWithName("isLand") as SKSpriteNode
        
        // 物理ボディーを生成する。
        let physicsBody = SKPhysicsBody(rectangleOfSize: isLand.size,
            center: CGPointMake(0, -24))
        
        // 動的に動かないようにする。
        physicsBody.dynamic = false
        
        // 摩擦を最大にする。
        physicsBody.friction = 1.0
        
        // バウンドをしないようにする。
        physicsBody.restitution = 0.0
        
        physicsBody.categoryBitMask = categoryBitMaskIsLand
        
        physicsBody.contactTestBitMask = categoryBitMaskPenguin
        
        // 氷の島に物理ボディーをセットする。
        isLand.physicsBody = physicsBody
        
        // 物理ワールドのデリゲートにselfをセットする。
        physicsWorld.contactDelegate = self
    }
    
    func breakBalloon() {
        
        ....................
        ....................
        ....................
        
        
        // 物理ボディーを生成する。
        let physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(76.0, 76.0))
        
        // 摩擦を最大にする。
        physicsBody.friction = 1.0
        
        // バウンドをしないようにする。
        physicsBody.restitution = 0.0
        
        // カテゴリーをセットする。
        physicsBody.categoryBitMask = categoryBitMaskPenguin
        
        // コンタクトテストをセットする。
        physicsBody.contactTestBitMask = categoryBitMaskPenguin
        
        // ペンギンに物理ボディーをセットする。
        flyingPenguin.physicsBody = physicsBody
        
        // 風船を削除する。
        flyingPenguin.childNodeWithName("balloon")?.removeFromParent()
    }
[/swift]

<br>
<p>次に <strong>SKPhysicsContactDelegate</strong> を追加して、physicsWorldの<strong>contactDelegate</strong> にselfをセットします。</p>

class GameScene: SKScene, SKPhysicsContactDelegate {
    
    override func didMoveToView(view: SKView) {
        
        ....................
        ....................
        ....................
        
        
        // 物理ワールドのコンタクトデリゲートにselfをセットする。
        physicsWorld.contactDelegate = self
    }


最後に、didBeginContact メソッドを新たに作り、接触したときの処理を書きます。
今回は、ペンギンが他の物体と接触したときに目パチをするようにしました。

    func didBeginContact(contact: SKPhysicsContact!) {
        println("didBeginContact")
        
        if contact.bodyA.categoryBitMask == categoryBitMaskPenguin {
            actionPachi(contact.bodyA.node as SKSpriteNode)
        }
        
        if contact.bodyB.categoryBitMask == categoryBitMaskPenguin {
            actionPachi(contact.bodyB.node as SKSpriteNode)
        }
    }
    
    func actionPachi(penguin:SKSpriteNode) {
        penguin.texture = self.atlas.textureNamed("block_adelie_pachi")
        penguin.runAction(SKAction.waitForDuration(0.25), completion: { () -> Void in
            penguin.texture = self.atlas.textureNamed("block_adelie_normal")
        })
    }


では、動かしてみます。

stack_penguin_13_01

目パチしました。
動きを見たい方は、ぜひ「つみペンギン」をダウンロードしてみてください。

次回へ続く。ではでは。

完成品はこちら。つみペンギン
つみペンギン stack_penguin_qrcode

姉妹品はこちら。ペンギン陸上-スプリント-
ペンギン陸上-スプリント- athlete_penguin_sprint_qrcode