iPhone人文字マル

人文字みたいに、合図で点を円周上に整列させるiPhoneアプリのサンプルコードを描いてみます。

import UIKit

import SceneKit

class ViewController: UIViewController, SCNSceneRendererDelegate {

    weak var sceneView : SCNView?

    var letter = false

    var last : NSTimeInterval = 0.0

    

    override func viewDidLoad() {

        super.viewDidLoad()

        setupScene()

        createGround()

        createDots()

        createCamera()

    }

    func setupScene() {

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

        sv.scene = SCNScene()

        sv.delegate = self

        sv.backgroundColor = UIColor(hue: 0.7, saturation: 0.2, brightness: 1, alpha: 1)

        sv.scene?.physicsWorld.speed = 0;

        view.addSubview(sv)

    

        sceneView = sv

    }

    

    func createGround() {

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

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

        let groundNode = SCNNode(geometry: ground)

        groundNode.physicsBody = SCNPhysicsBody.dynamicBody()

        groundNode.physicsBody?.velocityFactor = SCNVector3(x: 0, y: 0, z: 0)

        groundNode.physicsBody?.allowsResting = false

        

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

    }

    

    func createDots() {

        for i in 0..<25 {

            let x = Float(i % 5) * 10.020.0

            let z = Float(i / 5) * 10.020.0

            

            let dot = SCNSphere(radius: 0.5)

            dot.firstMaterial?.diffuse.contents = UIColor(hue: 0, saturation: 0.7, brightness: 1, alpha: 1)

            let node = SCNNode(geometry: dot)

            node.name = “dot”

            node.position = SCNVector3(x: x, y: 2, z: z)

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

        }

        

    }

    

    func createCamera() {

        let camera = SCNNode()

        camera.camera = SCNCamera()

        camera.camera?.zFar = 120

        camera.position = SCNVector3(x: 0, y: 20, z: 90)

        camera.rotation = SCNVector4(x: 1, y: 0, z: 0, w: –0.2)

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

    }

    

    func renderer(aRenderer: SCNSceneRenderer, updateAtTime time: NSTimeInterval) {

        

        if letter { return }

        

        if last == 0 {

            last = time

            return

        }

        

        let interval = time – last

        if interval >= 2.0 {

            last = time

            sceneView?.scene?.rootNode.childNodes

                .filter { return ($0 as SCNNode).name == “dot” }

                .map { (n : AnyObject) -> Void in

                    let x = Int(arc4random_uniform(50)) – 25

                    let z = Int(arc4random_uniform(50)) – 25

                    n.runAction(SCNAction.moveTo(SCNVector3(x: Float(x), y: 2, z: Float(z)), duration: 2.0))

                    return

                }

        }

    }

    

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

        

        sceneView?.scene?.physicsWorld.speed = 1.0

        

        letter = !letter

        if (letter) {

            letter = true

            let dots = sceneView?.scene?.rootNode.childNodes

                .filter { return ($0 as SCNNode).name == “dot” }

            

            let dAngle = 2.0 * M_PI / 25.0

            for (i, c) in enumerate(dots!) {

                let x = 20 * cos(dAngle * Double(i))

                let z = 20 * sin(dAngle * Double(i))

                c.runAction(SCNAction.moveTo(SCNVector3(x: Float(x), y: 2, z: Float(z)), duration: 2.0))

            }

        }

    }

}