iPhone跳ぶ人

観客で飛び跳ねている感じのiPhoneアプリのサンプルコードを描いてみます。

import UIKit

import SceneKit

class ViewController: UIViewController, SCNSceneRendererDelegate {

    weak var sceneView : SCNView?

    

    override func viewDidLoad() {

        super.viewDidLoad()

        

        setupScene()

        createGround()

        createJumpers()

    }

    func setupScene() {

        let sv = SCNView(frame: self.view.bounds)

        sv.scene = SCNScene()

        sv.backgroundColor = UIColor(hue: 0.3, saturation: 0.1, brightness: 1, alpha: 1)

        sv.delegate = self

        self.view.addSubview(sv)

        

        sv.autoenablesDefaultLighting = true

        sv.allowsCameraControl = true

        

        sceneView = sv

    }

    func createGround() {

        let ground = SCNBox(width: 50, height: 1, length: 40, chamferRadius: 0)

        ground.firstMaterial?.diffuse.contents = UIColor(hue: 0.3, saturation: 0.2, brightness: 1, alpha: 1)

        let groundNode = SCNNode(geometry: ground)

        groundNode.physicsBody = SCNPhysicsBody.staticBody()

        

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

    }

    

    func createJumpers() {

        for i in 0..<60 {

            let x = Float(i % 10) * 4.018

            let z = Float(i / 10) * 4.010

            createPapaerJumper(UIColor(hue: 0.1 * CGFloat(arc4random_uniform(10)), saturation: 0.7, brightness: 1, alpha: 1), p: SCNVector3(x: x, y: 2.0, z: z))

        }

    }

    

    func createPapaerJumper(color: UIColor, p : SCNVector3) {

        let jumperNode = SCNNode()

        jumperNode.name = “jumper”

        jumperNode.position = p

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

        let head = SCNCylinder(radius: 1, height: 0.1)

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

        for g in [head, body] {

            g.firstMaterial?.diffuse.contents = color

            let n = SCNNode(geometry: g)

            if g === head {

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

                n.rotation = SCNVector4(x: 1, y: 0, z: 0, w: Float(M_PI) * 0.5)

            }

            jumperNode.addChildNode(n)

        }

        

        jumperNode.physicsBody = SCNPhysicsBody.dynamicBody()

        jumperNode.physicsBody?.angularVelocityFactor = SCNVector3(x: 0, y: 0, z: 0);

    }

    

    func renderer(aRenderer: SCNSceneRenderer, willRenderScene scene: SCNScene, atTime time: NSTimeInterval) {

        scene.rootNode.childNodes

            .filter {($0 as SCNNode).name == “jumper” && arc4random_uniform(40) == 0 }

            .map { ($0 as SCNNode).physicsBody?.applyForce(SCNVector3(x: 0, y: 2, z: 0), impulse: true) }

    }

    

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {

        let p = touches.anyObject()!.locationInView(self.sceneView)

        self.sceneView?.hitTest(p, options: [SCNHitTestSortResultsKey : true])?

            .filter {

                ($0 as SCNHitTestResult).node.parentNode?.name == “jumper”

            }

            .map {

                ($0 as SCNHitTestResult).node.parentNode?.physicsBody?.applyForce(SCNVector3(x: 0, y: 10, z: –20), impulse: true)

            }

    }

}