iPhone滑り込み

スリットの間に弾を通すiPhoneアプリのサンプルコードを描いてみます。

import UIKit

import SceneKit

class ViewController: UIViewController {

    weak var sceneView : SCNView?

    

    override func viewDidLoad() {

        super.viewDidLoad()

        setupScene()

        createLine()

        createSlit()

        createPlayer()

        createCamera()

    }

    func setupScene() {

        let sv = SCNView(frame: view.bounds)

        sv.scene = SCNScene()

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

        sv.allowsCameraControl = true

        sv.autoenablesDefaultLighting = true

        view.addSubview(sv)

        

        sceneView = sv

    }

    func createLine() {

        let line = SCNBox(width: 150, height: 0.1, length: 5, chamferRadius: 0)

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

        let lineNode = SCNNode(geometry: line)

        

        lineNode.physicsBody = SCNPhysicsBody.staticBody()

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

    }

    

    func createSlit() {

        [Int](03).each {i in

            let slit = {() -> SCNNode in

                let s = SCNNode()

                [Int](03).each {j in

                    let box = SCNBox(width: 0.5, height: 4, length: 10, chamferRadius: 0)

                    box.firstMaterial?.diffuse.contents = UIColor(hue: 0.9, saturation: 0.5, brightness: 0.6, alpha: 1)

                    let boxNode = SCNNode(geometry: box)

                    boxNode.transform = SCNMatrix4Translate(boxNode.transform, 0, 5, 0)

                    boxNode.transform = SCNMatrix4Rotate(boxNode.transform, Float(j) * Float(M_PI) * 0.5, 1, 0, 0)

                    s.addChildNode(boxNode)

                }

                return s

            }()

            

            

            slit.position = SCNVector3(x: –5 + Float(i) * 20, y:0 , z: 0)

            slit.physicsBody = SCNPhysicsBody.staticBody()

            slit.physicsBody?.physicsShape = SCNPhysicsShape(node: slit, options: [SCNPhysicsShapeTypeKey : SCNPhysicsShapeTypeConvexHull])

            self.sceneView?.scene?.rootNode.addChildNode(slit)

            let (y, z) = (4 * cos(Float(M_PI) * 0.5 * Float(i)), 4 * sin(Float(M_PI) * 0.5 * Float(i)))

            slit.runAction(SCNAction.repeatActionForever(SCNAction.sequence([SCNAction.moveTo(SCNVector3(x:slit.position.x , y: y, z: z), duration: 1.0), SCNAction.moveTo(SCNVector3(x: slit.position.x, y: 0, z: 0), duration: 1)])))

        }

    }

    

    func createPlayer() {

        let player = SCNCylinder(radius: 2, height: 1)

        player.firstMaterial?.diffuse.contents = UIColor(hue: 0.7, saturation: 0.2, brightness: 0.5, alpha: 1)

        let playerNode = SCNNode(geometry: player)

        playerNode.name = “player”

        playerNode.position = SCNVector3(x: –15, y: 4, z: 0)

        playerNode.physicsBody = SCNPhysicsBody.dynamicBody()

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

    }

    

    func createCamera() {

        let camera = SCNNode()

        camera.camera = SCNCamera()

        camera.camera?.zFar = 300

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

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

    }

    

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

        let player = sceneView?.scene?.rootNode.childNodeWithName(“player”, recursively: false)

        player?.physicsBody?.friction = 0

        player?.physicsBody?.applyForce(SCNVector3(x: 70, y: 0, z: 0), impulse: true)

        

        player?.runAction(SCNAction.sequence([SCNAction.waitForDuration(3.0), SCNAction.runBlock { (n) -> Void in

            n.removeFromParentNode()

            self.createPlayer()

            }]))

    }

}

extension Array {

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

}