
てるてる坊主で雨をなんとかするiPhoneアプリのサンプルコードを描いてみます。
import UIKit
import SceneKit
class ViewController: UIViewController, SCNSceneRendererDelegate {
weak var sceneView : SCNView?
var rain = false
override func viewDidLoad() {
super.viewDidLoad()
setupScene()
createSky()
createTeruTeruBouzu()
createLight()
createCamera()
}
func setupScene() {
let sv = SCNView(frame: view.bounds)
sv.scene = SCNScene()
sv.allowsCameraControl = true
sv.delegate = self
view.addSubview(sv)
sceneView = sv
}
func createSky() {
let sky = SCNCylinder(radius: 20, height: 0.2)
sky.firstMaterial?.diffuse.contents = UIColor(hue: 0.5, saturation: 0.4, brightness: 1, alpha: 1)
let skyNode = SCNNode(geometry: sky)
skyNode.name = “sky”
skyNode.rotation = SCNVector4(x: 1, y: 0, z: 0, w: Float(M_PI) * 0.5)
skyNode.scale = SCNVector3(x: 1.4, y: 1, z: 1)
skyNode.position = SCNVector3(x: 0, y: 0, z: –20)
sceneView?.scene?.rootNode.addChildNode(skyNode)
let graysky = SCNCylinder(radius: 20, height: 0.2)
graysky.firstMaterial?.diffuse.contents = UIColor(hue: 0.5, saturation: 0.4, brightness: 0.3, alpha: 1)
let grayskyNode = SCNNode(geometry: graysky)
grayskyNode.position = SCNVector3(x: 0, y: –0.2, z: 0)
skyNode.addChildNode(grayskyNode)
}
func createTeruTeruBouzu() {
let bouzu = SCNNode()
bouzu.name = “bouzu”
bouzu.position = SCNVector3(x: 8, y: 4, z: 2)
sceneView?.scene?.rootNode.addChildNode(bouzu)
let head = SCNSphere(radius: 1)
head.firstMaterial?.diffuse.contents = UIColor(white: 1, alpha: 1)
let headNode = SCNNode(geometry: head)
headNode.position = SCNVector3(x: 0, y: 0.7, z: 0)
bouzu.addChildNode(headNode)
let body = SCNCone(topRadius: 0.5, bottomRadius: 1.5, height: 2)
body.firstMaterial?.diffuse.contents = UIColor(white: 1, alpha: 1)
let bodyNode = SCNNode(geometry: body)
bodyNode.position = SCNVector3(x: 0, y: –1, z: 0)
bouzu.addChildNode(bodyNode)
for i in 0…1 {
let eye = SCNSphere(radius: 0.15)
eye.firstMaterial?.diffuse.contents = UIColor.blackColor()
let eyeNode = SCNNode(geometry: eye)
eyeNode.position = SCNVector3(x: i==0 ? 0.5 : –0.5, y:0, z:1)
headNode.addChildNode(eyeNode)
}
let mouth = SCNSphere(radius: 0.25)
mouth.firstMaterial?.diffuse.contents = UIColor(hue: 0, saturation: 0.4, brightness: 0.7, alpha: 1)
let mouthNode = SCNNode(geometry: mouth)
mouthNode.position = SCNVector3(x: 0, y: –0.5, z: 1)
mouthNode.scale = SCNVector3(x: 0.6, y: 1, z: 0.2)
headNode.addChildNode(mouthNode)
}
func createLight() {
let light0 = SCNLight()
light0.type = SCNLightTypeAmbient
light0.color = UIColor(white: 0.4, alpha: 1)
let light0Node = SCNNode()
light0Node.position = SCNVector3(x: 0, y: 30, z: 30)
light0Node.light = light0
sceneView?.scene?.rootNode.addChildNode(light0Node)
let light = SCNLight()
light.type = SCNLightTypeDirectional
light.color = UIColor(white: 0.6, alpha: 1)
let lightNode = SCNNode()
lightNode.position = SCNVector3(x: 0, y: 0, z: 80)
lightNode.light = light
sceneView?.scene?.rootNode.addChildNode(lightNode)
}
func createCamera() {
let camera = SCNNode()
camera.camera = SCNCamera()
camera.position = SCNVector3(x: 0, y: 0, z: 25)
sceneView?.scene?.rootNode.addChildNode(camera)
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
if let bouzu = sceneView?.scene?.rootNode.childNodeWithName(“bouzu”, recursively: false) {
if let sky = sceneView?.scene?.rootNode.childNodeWithName(“sky”, recursively: false) {
bouzu.runAction(SCNAction.rotateByAngle(CGFloat(M_PI), aroundAxis: SCNVector3(x: 0, y: 0, z: 1), duration: 1.0))
sky.runAction(SCNAction.rotateByAngle(CGFloat(M_PI), aroundAxis: SCNVector3(x: 1, y: 0, z: 0), duration: 1.0))
self.rain = !self.rain
self.sceneView?.playing = true
}}
}
func renderer(aRenderer: SCNSceneRenderer, updateAtTime time: NSTimeInterval) {
if (self.rain) {
let x = arc4random() % 20
let rain = SCNSphere(radius: 0.15)
rain.firstMaterial?.diffuse.contents = UIColor(hue: 0.5, saturation: 0.3, brightness: 1, alpha: 0.7)
let rainNode = SCNNode(geometry: rain)
rainNode.name = “rain”
rainNode.position = SCNVector3(x: Float(x) – 10, y: 8, z: 4)
sceneView?.scene?.rootNode.addChildNode(rainNode)
rainNode.physicsBody = SCNPhysicsBody.dynamicBody()
}
sceneView?.scene?.rootNode.childNodes
.filter {($0 as! SCNNode).name == “rain” && ($0 as! SCNNode).position.y < –10}
.map{ ($0 as! SCNNode).removeFromParentNode() }
}
}