iPhone箱パンチャー

箱がパンチするiPhoneアプリのサンプルコードを描いてみます。

import UIKit

import SceneKit

class ViewController: UIViewController {

    

    weak var sceneView : SCNView?

    override func viewDidLoad() {

        super.viewDidLoad()

        setupScene()

        createGround()

        createPunch()

        createButton()

    }

    func setupScene() {

        let sv = SCNView(frame: view.bounds)

        sv.backgroundColor = UIColor.lightGrayColor()

        sv.scene = SCNScene()

        sv.allowsCameraControl = true

        sv.autoenablesDefaultLighting = true

        view.addSubview(sv)

        

        sceneView = sv

    }

    

    func createGround() {

        let ground = SCNCylinder(radius: 6, height: 0.2)

        ground.firstMaterial?.diffuse.contents = UIColor.lightGrayColor()

        let groundNode = SCNNode(geometry: ground)

        sceneView?.scene?.rootNode.addChildNode(groundNode)

        groundNode.physicsBody = SCNPhysicsBody.staticBody()

    }

    

    func createPunch() {

        let box = SCNBox(width: 1, height: 1, length: 1, chamferRadius: 0)

        box.firstMaterial?.diffuse.contents = UIColor.yellowColor()

        let boxNode = SCNNode(geometry: box)

        boxNode.name = “box”

        boxNode.position = SCNVector3(x: 0, y: 1, z: 0)

        sceneView?.scene?.rootNode.addChildNode(boxNode)

        

        for var i=0; i<2; i++ {

            let eye = SCNBox(width: 0.1, height: 0.2, length: 0.1, chamferRadius: 0.1)

            eye.firstMaterial?.diffuse.contents = UIColor.blackColor()

            let eyeNode = SCNNode(geometry: eye)

            eyeNode.position = SCNVector3(x: i==0 ? –0.35 : 0.35, y: 0.3, z: –0.5)

            boxNode.addChildNode(eyeNode)

            

            let glove = SCNSphere(radius: 0.3)

            glove.firstMaterial?.diffuse.contents = UIColor.redColor()

            let gloveNode = SCNNode(geometry: glove)

            gloveNode.name = “glove”

            gloveNode.position = SCNVector3(x: i==0 ? –0.3 : 0.3, y: –0.2, z: –0.7)

            boxNode.addChildNode(gloveNode)

        }

        

        boxNode.physicsBody = SCNPhysicsBody.dynamicBody()

    }

    

    func createButton() {

        let button = UIButton.buttonWithType(.System) as! UIButton

        button.setTitle(“punch”, forState: .Normal)

        button.tintColor = UIColor.whiteColor()

        button.sizeToFit()

        button.center = CGPoint(x: CGRectGetMidX(view.bounds), y: 400)

        view.addSubview(button)

        button.addTarget(self, action: “tap”, forControlEvents: .TouchUpInside)

    }

    

    func tap() {

        sceneView?.scene?.rootNode.childNodes

            .filter { ($0 as! SCNNode).name == “box” }

            .each { i in

                let num = Int(arc4random() % 2)

                var count = 0

                i.childNodes.filter{ ($0 as! SCNNode).name == “glove” }.each {glove in

                    if count++ == num {

                        glove.runAction(

                            SCNAction.sequence([

                                SCNAction.moveByX(0, y: 0, z: –0.3, duration: 0.1),

                                SCNAction.moveByX(0, y: 0, z: 0.3, duration: 0.2)

                            ]))

                        

                    }

                }

            }

    }

}

extension Array {

    func each(doit:T -> Void) { for i in self { doit(i) }}

}