
円をカットして観覧車が周っているように見せるiPhoneアプリのサンプルコード
import UIKit
import SceneKit
class ViewController: UIViewController {
weak var sceneView : SCNView?
override func viewDidLoad() {
super.viewDidLoad()
setupScene()
[SCNVector3(x: 0, y: 0, z: 0), SCNVector3(x: –5, y: 5, z: 0), SCNVector3(x: 5, y: –5, z: 0)].each{ position in
self.createWheel(position)
}
createCamera()
}
func setupScene() {
let sv = SCNView(frame: view.bounds)
sv.scene = SCNScene()
sv.allowsCameraControl = true
sv.backgroundColor = UIColor(hue: 0.2, saturation: 0.1, brightness: 1, alpha: 1)
view.addSubview(sv)
sceneView = sv
}
func createWheel(p : SCNVector3) {
let wheel = SCNNode()
wheel.name = “wheel”
wheel.position = p
self.sceneView?.scene?.rootNode.addChildNode(wheel)
let stand = SCNBox (width: 1, height: 2, length: 1.2, chamferRadius: 0)
stand.firstMaterial?.diffuse.contents = UIColor(hue: 0.3, saturation: 0.6, brightness: 1, alpha: 1)
let standNode = SCNNode(geometry: stand)
standNode.position = SCNVector3(x: p.x, y: p.y–1.4, z: p.z)
self.sceneView?.scene?.rootNode.addChildNode(standNode)
let w = M_PI / 4.0
let arcpath = UIBezierPath(arcCenter: CGPointZero, radius: 2, startAngle: 0, endAngle: CGFloat(w), clockwise: true)
arcpath.addLineToPoint(CGPointZero)
arcpath.closePath()
arcpath.flatness = 0.01
[Int](0…7).each {i in
let piece = SCNShape(path: arcpath, extrusionDepth: 0.2)
piece.firstMaterial?.diffuse.contents = UIColor(hue: 0.03, saturation: 0.6, brightness: 1, alpha: 1)
let pieceNode = SCNNode(geometry: piece)
pieceNode.name = “piece”
pieceNode.rotation = SCNVector4(x: 0, y: 0, z: 1, w: Float(w) * Float(i))
wheel.addChildNode(pieceNode)
}
}
func createCamera() {
let camera = SCNNode()
camera.camera = SCNCamera()
camera.position = SCNVector3(x: –13, y: 0, z: 30)
camera.rotation = SCNVector4(x: 0, y: 1, z: 0, w: –0.4)
sceneView?.scene?.rootNode.addChildNode(camera)
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
self.sceneView?.scene?.rootNode.childNodes
.filter { ($0 as SCNNode).name == “wheel” }
.each{ wheel in
wheel.childNodes
.filter {($0 as SCNNode).name == “piece” }
.each {piece in
let x = 0.3 * CGFloat(cos(piece.rotation.w + Float(M_PI/8.0)))
let y = 0.3 * CGFloat(sin(piece.rotation.w + Float(M_PI/8.0)))
piece.runAction(SCNAction.sequence([SCNAction.moveByX(x, y: y, z: 0, duration: 0.5), SCNAction.waitForDuration(2.5)]), completionHandler: {
piece.runAction(SCNAction.moveTo(SCNVector3Zero, duration: 0.25))
return;
})
}
wheel.runAction(SCNAction.rotateByAngle(CGFloat(M_PI), aroundAxis: SCNVector3(x: 0, y: 0, z: 1), duration: 3.0))
}
}
}
extension Array {
func each(doit:T -> Void) { for i in self {doit(i)} }
}