コンテナを運ぶ船を表示するiPhoneアプリのサンプルコードを描いてみます。
import UIKit
import SceneKit
class ViewController: UIViewController {
weak var sceneView : SCNView?
override func viewDidLoad() {
super.viewDidLoad()
setupScene()
createPort()
createShip()
createContainers()
createCamera()
}
func setupScene() {
let sv = SCNView(frame: view.bounds)
sv.backgroundColor = UIColor(hue: 0.5, saturation: 0.1, brightness: 1, alpha: 1)
sv.scene = SCNScene()
sv.allowsCameraControl = true
sv.autoenablesDefaultLighting = true
view.addSubview(sv)
self.sceneView = sv
}
func createPort() {
for i in 0…1 {
let port = SCNBox(width: 10, height: 5, length: 5, chamferRadius: 0)
port.firstMaterial?.diffuse.contents = UIColor(hue: 0.1, saturation: 0.8, brightness: 0.6, alpha: 1)
let portNode = SCNNode(geometry: port)
portNode.position = SCNVector3(x: i==0 ? –15 : 15, y: –5, z: 0)
self.sceneView?.scene?.rootNode.addChildNode(portNode)
portNode.physicsBody = SCNPhysicsBody.staticBody()
}
let sea = SCNBox(width: 40, height: 2, length: 40, chamferRadius: 0)
sea.firstMaterial?.diffuse.contents = UIColor(hue: 0.5, saturation: 0.6, brightness: 1, alpha: 1)
let seaNode = SCNNode(geometry: sea)
seaNode.position = SCNVector3(x: 0, y: –7, z: 0)
sceneView?.scene?.rootNode.addChildNode(seaNode)
seaNode.runAction(SCNAction.repeatActionForever(SCNAction.sequence([SCNAction.moveByX(0, y: –0.5, z: 0, duration: 2), SCNAction.moveByX(0, y: 0.5, z: 0, duration: 2)])))
}
func createShip() {
let ship = SCNCone(topRadius: 8, bottomRadius: 6.5, height: 2)
ship.firstMaterial?.diffuse.contents = UIColor(hue: 0, saturation: 1, brightness: 0.5, alpha: 1)
let shipNode = SCNNode(geometry: ship)
shipNode.name = “ship”
shipNode.scale = SCNVector3(x: 1, y: 1, z: 0.3)
shipNode.position = SCNVector3(x: –10, y: –5, z: 6)
sceneView?.scene?.rootNode.addChildNode(shipNode)
}
func createContainers() {
for i in 0…8 {
let x = (i % 3) * 2 – 17
let y = (i / 3) * 2 – 2
let box = SCNBox(width: 2, height: 2, length: 2, chamferRadius: 0.1)
box.firstMaterial?.diffuse.contents = UIColor(hue: 0.1 * CGFloat(i), saturation: 0.4, brightness: 0.9, alpha: 1)
let boxNode = SCNNode(geometry: box)
boxNode.name = “container \(i)”
boxNode.position = SCNVector3(x: Float(x), y: Float(y), z: 0)
sceneView?.scene?.rootNode.addChildNode(boxNode)
}
}
func createCamera() {
let camera = SCNNode()
camera.camera = SCNCamera()
camera.position = SCNVector3(x: 0, y: 0, z: 20)
sceneView?.scene?.rootNode.addChildNode(camera)
}
var count = 0
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
var containerOn = {() -> Void in
self.sceneView?.scene?.rootNode.childNodes
.filter { ($0 as! SCNNode).name?.componentsSeparatedByString(” “)[0] == “container” }
.reduce(0) { (cnt, n) -> Int in
let x = Float(cnt % 5) * 2 – 15
let y = Float(cnt / 5) * 2 – 2.9
n.runAction(SCNAction.moveTo(SCNVector3(x: Float(x), y: Float(y), z: 6), duration: 0.5), completionHandler: { () -> Void in
if let ship = self.sceneView?.scene?.rootNode.childNodeWithName(“ship”, recursively: false) {
ship.addChildNode(n as! SCNNode)
(n as! SCNNode).position = ship.convertPosition(n.position, fromNode: self.sceneView?.scene?.rootNode)
}
})
return cnt+1
}
};
var moveShip = {() -> Void in
if let ship = self.sceneView?.scene?.rootNode.childNodeWithName(“ship”, recursively: false) {
ship.runAction(SCNAction.moveByX(20, y: 0, z: 0, duration: 5.0))
}
};
if count == 0 {
containerOn();
}
else if count == 1 {
moveShip();
}
++count
}
}