頂上から山の周りをころころくるくるとボールをころがすiPhoneアプリのサンプルコードを描いてみます。
import UIKit
import SceneKit
class ViewController: UIViewController {
weak var scene : SCNScene?
override func viewDidLoad() {
super.viewDidLoad()
self.setupScene()
self.createMountain()
self.createSlope()
self.createCamera()
self.createLight()
}
func setupScene() {
var w = CGRectGetWidth(self.view.bounds)
var sceneView = SCNView(frame: CGRect(x:0, y:0, width: w, height: w))
sceneView.backgroundColor = UIColor(hue: 0.9, saturation: 0.1, brightness: 1, alpha: 1)
sceneView.center = CGPoint(x: CGRectGetMidX(self.view.bounds), y: CGRectGetMidY(self.view.bounds))
sceneView.scene = SCNScene()
self.view.addSubview(sceneView)
self.scene = sceneView.scene
}
func createMountain() {
var cone = SCNCone(topRadius: 0, bottomRadius: 50, height: 50)
cone.firstMaterial?.diffuse.contents = UIColor(hue: 0.4, saturation: 0.5, brightness: 0.8, alpha: 1)
var coneNode = SCNNode(geometry: cone)
coneNode.name = “mountain”
self.scene?.rootNode.addChildNode(coneNode)
coneNode.physicsBody = SCNPhysicsBody.staticBody()
coneNode.physicsBody?.physicsShape = SCNPhysicsShape(geometry: cone, options: [SCNPhysicsShapeTypeKey: SCNPhysicsShapeTypeConcavePolyhedron])
}
func createSlope() {
var dangle = M_PI / 20.0
for i in 0…60 {
var r = 50.0 – Double(i) * 0.6
var x = r * cos(dangle * Double(i))
var z = r * sin(dangle * Double(i))
var slope = SCNBox(width: 10, height: 1, length: 10, chamferRadius: 0)
slope.firstMaterial?.diffuse.contents = UIColor.lightGrayColor()
var slopeNode = SCNNode(geometry: slope)
slopeNode.position = SCNVector3(x: Float(x), y: Float(i) / 1.4 – 25.0, z: Float(z))
slopeNode.transform = SCNMatrix4Rotate(slopeNode.transform, –0.05, Float(x), 0, Float(z))
self.scene?.rootNode.addChildNode(slopeNode)
slopeNode.physicsBody = SCNPhysicsBody.staticBody()
slopeNode.physicsBody?.friction = 0
r = r + 7
x = r * cos(dangle * Double(i))
z = r * sin(dangle * Double(i))
var wall = SCNBox (width: 5, height: 8, length: 0.2, chamferRadius: 0)
wall.firstMaterial?.diffuse.contents = UIColor.brownColor().colorWithAlphaComponent(0.4)
var wallNode = SCNNode(geometry: wall)
wallNode.transform = SCNMatrix4Rotate(wallNode.transform, Float(M_PI) * 0.5 – Float(dangle) * Float(i), 0,1,0)
wallNode.position = SCNVector3(x: Float(x), y: slopeNode.position.y + 2.5, z: Float(z))
self.scene?.rootNode.addChildNode(wallNode)
wallNode.physicsBody = SCNPhysicsBody.staticBody()
wallNode.physicsBody?.friction = 0
wallNode.physicsBody?.restitution = 0.7
}
}
func createCamera() {
var camera = SCNNode()
camera.camera = SCNCamera()
camera.camera?.zFar = 300
camera.position = SCNVector3(x: 0, y: 40, z: 120)
self.scene?.rootNode.addChildNode(camera)
if let target = self.scene?.rootNode.childNodeWithName(“mountain”, recursively: false) {
camera.constraints = [SCNLookAtConstraint(target:target)]
}
}
func createLight() {
var light = SCNLight()
light.type = SCNLightTypeOmni
var lightNode = SCNNode()
lightNode.light = light
lightNode.position = SCNVector3(x: 0, y: 100, z: 100)
self.scene?.rootNode.addChildNode(lightNode)
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
var ball = SCNSphere(radius: 3)
ball.firstMaterial?.diffuse.contents = UIColor(hue: 0.1, saturation: 0.7, brightness: 1, alpha: 1)
var ballNode = SCNNode(geometry: ball)
ballNode.position = SCNVector3(x: –10, y: 40, z: 0)
self.scene?.rootNode.addChildNode(ballNode)
ballNode.physicsBody = SCNPhysicsBody.dynamicBody()
ballNode.physicsBody?.friction = 0
ballNode.physicsBody?.restitution = 0.7
ballNode.physicsBody?.damping = 0
ballNode.physicsBody?.angularDamping = 0
ballNode.physicsBody?.applyForce(SCNVector3(x: 0, y: 0, z: 7), impulse: true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}