說明
本系列文章是對<3D Apple Games by Tutorials>一書的學(xué)習(xí)記錄和體會此書對應(yīng)的代碼地址
相機(jī)約束
// 1.拿到相機(jī)節(jié)點(diǎn)
cameraNode = scnScene.rootNode.childNodeWithName("camera", recursively:
true)!
// 2.添加lookAt約束,讓相機(jī)始終朝向ballNode小球節(jié)點(diǎn)
let constraint = SCNLookAtConstraint(target: ballNode)
cameraNode.constraints = [constraint]
Gimbal locking萬向節(jié)鎖
當(dāng)使用SCNLookAtConstraint時,Scene Kit不管被朝向的對象如何移動,旋轉(zhuǎn)都會讓相機(jī)對著他.但是有些時候會轉(zhuǎn)到一些奇怪的角度,導(dǎo)致相機(jī)發(fā)生向左或向右的傾斜,對于燈光是沒問題的,但相機(jī)就不可以,我們總是希望相機(jī)保持水平方向.
因此用到萬向節(jié)鎖
constraint.gimbalLockEnabled = true
更改物體的運(yùn)動狀態(tài)和位置
//根據(jù)手機(jī)加速度傳感器數(shù)據(jù),移動小球
func updateMotionControl() {
// 1.每0.1秒更新傳感器參數(shù),構(gòu)造為向量
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
}
}
//讓相機(jī)跟著小球平滑移動
func updateCameraAndLights() {
// 1.小球呈現(xiàn)位置與相機(jī)當(dāng)前位置的差,每次移動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.燈光位置也跟隨相機(jī)位置變化
lightFollowNode.position = cameraFollowNode.position
// 3.進(jìn)入暫停狀態(tài)時,相機(jī)歐拉角沿y軸旋轉(zhuǎn)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)
}
}
}
}
}