
タッチするとニュッと三角が逃げるiPhoneアプリのサンプルコード
(※アイデアはAndrewさんからいただきました!ありがとうございます。)
import UIKit
import SceneKit
class ViewController: UIViewController {
weak var sceneView : SCNView?
override func viewDidLoad() {
super.viewDidLoad()
setupScene()
createTriangleShapes()
createCamera()
}
func setupScene() {
let sv = SCNView(frame: view.bounds)
sv.scene = SCNScene()
sv.backgroundColor = UIColor(white: 0.05, alpha: 1)
view.addSubview(sv)
sceneView = sv
}
func createTriangleShapes() {
let r = 5
// patten of animation ?
let points = [
[SCNVector3(x: 5, y: 0, z: 0), SCNVector3(x: –5, y: 5, z: 0), SCNVector3(x: –5, y: –5, z: 0)],
[SCNVector3(x: 5, y: 0, z: 0), SCNVector3(x: –5, y: 5, z: 0), SCNVector3(x: –15, y: –2, z: 0)],
[SCNVector3(x: 5, y: 0, z: 0), SCNVector3(x: –15, y: 8, z: 0), SCNVector3(x: –15, y: –2, z: 0)],
[SCNVector3(x: –5, y: 0, z: 0), SCNVector3(x: –15, y: 8, z: 0), SCNVector3(x: –15, y: –2, z: 0)]
]
let geometories = points.map { (var ps) -> SCNGeometry in
var verts : [SCNVector3] = ps
let indices : [Int32] = [0, 1, 2];
let vertexSource = SCNGeometrySource(vertices:UnsafePointer<SCNVector3>(verts), count:verts.count);
let indexData = NSData(bytes:indices, length:sizeof(Int32) * indices.count);
let element = SCNGeometryElement(data:indexData, primitiveType:.Triangles, primitiveCount:indices.count, bytesPerIndex:sizeof(Int32));
let triangle = SCNGeometry(sources:[vertexSource], elements:[element]);
triangle.firstMaterial?.diffuse.contents = UIColor(hue: 0.1, saturation: 0.4, brightness: 1, alpha: 1)
return triangle
}
let triangle = SCNNode(geometry: geometories[0])
triangle.name = “triangle”
triangle.morpher = SCNMorpher()
triangle.morpher?.targets = geometories
sceneView?.scene?.rootNode.addChildNode(triangle)
}
func createCamera() {
let camera = SCNNode()
camera.camera = SCNCamera()
camera.position = SCNVector3(x: 0, y: 0, z: 15)
sceneView?.scene?.rootNode.addChildNode(camera)
}
var lock = false
var frameNumber = 0
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
if frameNumber == 0 {
[Int](0…2).each { i in
self.delay(Double(i) * 0.2, doit: { () -> Void in
self.dodge()
})
}
} else {
dodge()
}
}
func dodge() {
let triangle = sceneView?.scene?.rootNode.childNodeWithName(“triangle”, recursively: false)
if let targets = triangle?.morpher?.targets as? [SCNGeometry] {
triangle?.geometry = targets[frameNumber]
frameNumber = (frameNumber + 1) % targets.count
let numMorpher = triangle!.morpher!.targets!.count
let a = CABasicAnimation(keyPath: “morpher.weights[\(frameNumber)]”)
a.fromValue = 0
a.toValue = 1
a.duration = 0.2
a.removedOnCompletion = false;
a.fillMode = kCAFillModeForwards;
a.delegate = self
[triangle?.addAnimation(a, forKey: “”)]
}
}
final func delay(delay:Double, doit:()->Void) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), doit)
}
}
extension Array {
func each(doit:T -> Void) { for i in self {doit(i)} }
}