昼と夜でくるっと回る箱庭みたいなiPhoneアプリのサンプルコードを描いてみます。
import UIKit
import SceneKit
class ViewController: UIViewController {
weak var sceneView : SCNView?
override func viewDidLoad() {
super.viewDidLoad()
setupScene()
createStage()
createCover()
createCamera()
}
func setupScene() {
let sv = SCNView(frame: view.bounds)
sv.scene = SCNScene()
sv.backgroundColor = UIColor.lightGrayColor()
view.addSubview(sv)
sceneView = sv
}
func createStage() {
let stage = SCNCylinder(radius: 10, height: 1)
stage.firstMaterial?.diffuse.contents = UIColor.brownColor()
let stageNode = SCNNode(geometry: stage)
stageNode.name = “stage”
sceneView?.scene?.rootNode.addChildNode(stageNode)
// day
let halfCircle = UIBezierPath(arcCenter: CGPointZero, radius: 10, startAngle: 0, endAngle: CGFloat(M_PI), clockwise: true)
halfCircle.flatness = 0.1
let day = SCNShape(path: halfCircle, extrusionDepth: 0.1)
day.firstMaterial?.diffuse.contents = UIColor(hue: 0.5, saturation: 0.2, brightness: 1, alpha: 1)
let dayNode = SCNNode(geometry: day)
stageNode.addChildNode(dayNode)
// sun
let sun = SCNSphere(radius: 2)
sun.firstMaterial?.diffuse.contents = UIColor(hue: 0.02, saturation: 0.5, brightness: 1, alpha: 1)
let sunNode = SCNNode(geometry: sun)
sunNode.position = SCNVector3(x: –7, y: 7, z: 0)
stageNode.addChildNode(sunNode)
// building day
let building = SCNBox(width: 3, height: 5, length: 1, chamferRadius: 0)
building.firstMaterial?.diffuse.contents = UIColor(white: 0.8, alpha: 1)
let buildingNode = SCNNode(geometry: building)
buildingNode.position = SCNVector3(x: 5, y: 2.5, z: 0)
stageNode.addChildNode(buildingNode)
for i in 0..<4 {
let x = Float(i % 2) * 1.5 – 0.8
let y = Float(i / 2) * 1.5 + 0.2
let wind = SCNBox(width: 1, height: 1, length: 1, chamferRadius: 0)
wind.firstMaterial?.diffuse.contents = UIColor(hue: 0.5, saturation: 0.4, brightness: 1, alpha: 1)
let windNode = SCNNode(geometry: wind)
windNode.position = SCNVector3(x: x, y: y, z: 0.5)
buildingNode.addChildNode(windNode)
}
// night
halfCircle.applyTransform(CGAffineTransformMakeRotation(CGFloat(M_PI)))
let night = SCNShape(path: halfCircle, extrusionDepth: 0.1)
night.firstMaterial?.diffuse.contents = UIColor(hue: 0.5, saturation: 0.2, brightness: 0.1, alpha: 1)
let nightNode = SCNNode(geometry: night)
stageNode.addChildNode(nightNode)
// moon
let moon = SCNSphere(radius: 2)
moon.firstMaterial?.diffuse.contents = UIColor(hue: 0.15, saturation: 0.5, brightness: 0.9, alpha: 1)
let moonNode = SCNNode(geometry: moon)
moonNode.position = SCNVector3(x: 7, y: –7, z: 0)
stageNode.addChildNode(moonNode)
// building night
let buildingNight = SCNBox(width: 3, height: 5, length: 1, chamferRadius: 0)
buildingNight.firstMaterial?.diffuse.contents = UIColor(white: 0.5, alpha: 1)
let buildingNightNode = SCNNode(geometry: buildingNight)
buildingNightNode.position = SCNVector3(x: –5, y: –2.5, z: 0)
stageNode.addChildNode(buildingNightNode)
for i in 0..<4 {
let x = Float(i % 2) * 1.5 – 0.8
let y = Float(i / 2) * 1.5 + 0.2
let wind = SCNBox(width: 1, height: 1, length: 1, chamferRadius: 0)
wind.firstMaterial?.diffuse.contents = UIColor(hue: 0.5, saturation: 0.4, brightness: 0.4, alpha: 1)
let windNode = SCNNode(geometry: wind)
windNode.position = SCNVector3(x: -x, y: -y, z: 0.5)
buildingNightNode.addChildNode(windNode)
}
}
func createCover() {
let tube = SCNTube(innerRadius: 10, outerRadius: 11, height: 10)
tube.firstMaterial?.diffuse.contents = UIColor(hue: 0.3, saturation: 0.5, brightness: 0.5, alpha: 1)
let tubeNode = SCNNode(geometry: tube)
tubeNode.position = SCNVector3(x: 0, y: –5, z: 0)
sceneView?.scene?.rootNode.addChildNode(tubeNode)
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
let n = sceneView?.scene?.rootNode.childNodeWithName(“stage”, recursively: false)
n?.runAction(SCNAction.rotateByAngle(CGFloat(M_PI), aroundAxis: SCNVector3(x: 0, y: 0, z: 1), duration: 0.5))
}
func createCamera() {
let camera = SCNNode()
camera.camera = SCNCamera()
camera.position = SCNVector3(x: 0, y: 0, z: 40)
camera.transform = SCNMatrix4Rotate(camera.transform, –0.4, 1, 0, 0)
sceneView?.scene?.rootNode.addChildNode(camera)
}
}