說明
本系列文章是對<3D Apple Games by Tutorials>一書的學習記錄和體會
相機約束
// 1.拿到相機節點
cameraNode = scnScene.rootNode.childNodeWithName("camera", recursively:
true)!
// 2.新增lookAt約束,讓相機始終朝向ballNode小球節點
let constraint = SCNLookAtConstraint(target: ballNode)
cameraNode.constraints = [constraint]
複製程式碼
Gimbal locking萬向節鎖
當使用SCNLookAtConstraint時,Scene Kit不管被朝向的物件如何移動,旋轉都會讓相機對著他.但是有些時候會轉到一些奇怪的角度,導致相機發生向左或向右的傾斜,對於燈光是沒問題的,但相機就不可以,我們總是希望相機保持水平方向. 因此用到萬向節鎖
constraint.gimbalLockEnabled = true
複製程式碼
更改物體的運動狀態和位置
//根據手機加速度感測器資料,移動小球
func updateMotionControl() {
// 1.每0.1秒更新感測器引數,構造為向量
if game.state == GameStateType.Playing {
motion.getAccelerometerData(0.1) { (x,y,z) in
self.motionForce = SCNVector3(x: Float(x) * 0.05, y:0, z: Float(y+0.8) * -0.05)
}
// 2.小球的速度改變
ballNode.physicsBody!.velocity += motionForce
}
}
//讓相機跟著小球平滑移動
func updateCameraAndLights() {
// 1.小球呈現位置與相機當前位置的差,每次移動0.01
let lerpX = (ballNode.presentationNode.position.x - cameraFollowNode.position.x) * 0.01
let lerpY = (ballNode.presentationNode.position.y - cameraFollowNode.position.y) * 0.01
let lerpZ = (ballNode.presentationNode.position.z - cameraFollowNode.position.z) * 0.01
cameraFollowNode.position.x += lerpX
cameraFollowNode.position.y += lerpY
cameraFollowNode.position.z += lerpZ
// 2.燈光位置也跟隨相機位置變化
lightFollowNode.position = cameraFollowNode.position
// 3.進入暫停狀態時,相機尤拉角沿y軸旋轉0.005
if game.state == GameStateType.TapToPlay {
cameraFollowNode.eulerAngles.y += 0.005
}
}
複製程式碼
感測器工具類程式碼
import Foundation
import CoreMotion
class CoreMotionHelper {
let motionManager = CMMotionManager()
init() {
}
func getAccelerometerData(interval: NSTimeInterval = 0.1, closure: ((x: Double, y: Double, z: Double) -> ())? ){
if motionManager.accelerometerAvailable {
motionManager.accelerometerUpdateInterval = interval
motionManager.startAccelerometerUpdatesToQueue(NSOperationQueue()) {
(data: CMAccelerometerData?, error: NSError?) -> Void in
if closure != nil{
closure!(x: data!.acceleration.x,y: data!.acceleration.y,z: data!.acceleration.z)
}
}
}
}
}
複製程式碼