gpt4 book ai didi

ios - Swift 使用 CMMotionManager 配置加速度计跟踪

转载 作者:可可西里 更新时间:2023-11-01 01:37:50 27 4
gpt4 key购买 nike

我一直在寻找一种方法来为加速度计在我的游戏中跟踪玩家移动的方式添加偏移量。在我的游戏中,您通过前后倾斜手机来控制玩家角色。这由加速度计转换为屏幕上的 x 和 y 坐标。不幸的是,这意味着为了阻止角色一直位于屏幕底部,您必须将手机放平。这对玩家来说不是很舒服。

所以我正在尝试实现一种方法,无论手机在开始游戏时的角度如何,这都是默认角度,然后倾斜由该角度的增量而不是原始数据决定我猜这将反对 0,0...

这是我试图弄清楚的:

func instantiateAcceleration() {
if motionManager.accelerometerAvailable{
let queue = NSOperationQueue()


motionManager.startAccelerometerUpdatesToQueue(queue) { data, error in
let currentX = self.player.position.x
let currentY = self.player.position.y

if(!self.hasCapturedOffset){

/* So the first time we enter this loop. we'll cature the offset */

self.offsetY = data!.acceleration.y;
self.offsetX = data!.acceleration.x;

print("captured offset : x - \(self.offsetX) y - \(self.offsetY)")
self.hasCapturedOffset = true;
}

/* x coords */
if data!.acceleration.y < (0 - self.offsetY) {
self.destX = currentX + CGFloat(data!.acceleration.y * 100)
}

else if data!.acceleration.y > (0 + self.offsetY) {
self.destX = currentX + CGFloat(data!.acceleration.y * 100)
}

/* y coords */
if data!.acceleration.x > (0.1 - self.offsetX){
self.destY = currentY - CGFloat(data!.acceleration.x * 100)
}

else if data!.acceleration.x < (0.1 + self.offsetX) {
self.destY = currentY - CGFloat(data!.acceleration.x * 100)
}

/* keep it in bounds */
if(self.destY > self.size.height){
self.destY = self.size.height;

}else if(self.destY < 0){
self.destY = 0;
}

if(self.destX > self.size.width){
self.destX = self.size.width;

}else if(self.destX < 0){
self.destX = 0;
}

}

} else {
print("Accelerometer is not available")
}

}

上面的函数是在viewDidLoad上调用的,self.DestX, self.DestY用于在更新方法中更新播放器:

override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
/* Accelerometer data */
let action = SKAction.moveTo(CGPoint(x:destX, y:destY), duration: 0.1)
self.player.runAction(action)

}

我真的很想学习如何正确地做到这一点,我知道这背后肯定有一些我不熟悉的数学。如果有人能指出我正确的方向,我将不胜感激 :)

最佳答案

您可以将起始方向存储为 referenceAttitude 并使用

 currentattitude.multiplyByInverseOfAttitude(referenceAttitude) 

计算运动。

这是我前一段时间做的代码示例:

import Foundation
import CoreMotion

// Damping factor
let cLowPassFactor: Float = 0.95

class MotionManagerSingletonSwift: NSObject {


var motionManager: CMMotionManager
var referenceAttitude:CMAttitude?=nil
var bActive = false
var lastVector:[Float] = [0.0, 0.0, 0.0]


override init() {
motionManager=CMMotionManager()
motionManager.deviceMotionUpdateInterval = 0.25
motionManager.startDeviceMotionUpdates()
bActive=true;
}

// only one instance of CMMotionManager can be used in your project.
// => Implement as Singleton which can be used in the whole application
class var sharedInstance: MotionManagerSingletonSwift {
struct Singleton {
static let instance = MotionManagerSingletonSwift()
}
return Singleton.instance
}

class func getMotionManager()->CMMotionManager {
if (sharedInstance.bActive==false) {
sharedInstance.motionManager.startDeviceMotionUpdates()
sharedInstance.bActive=true;

}
return sharedInstance.motionManager
}

// Returns an array with the movements
// At the first time a reference orientation is saved to ensure the motion detection works
// for multiple device positions
class func getMotionVectorWithLowPass() -> [Float] {
// Motion
var attitude: CMAttitude? = getMotionManager().deviceMotion?.attitude

if sharedInstance.referenceAttitude==nil {
// Cache Start Orientation to calibrate the device. Wait for a short time to give MotionManager enough time to initialize
dispatch_after(250, dispatch_get_main_queue(), {
MotionManagerSingletonSwift.calibrate()
})
} else if attitude != nil {
// Use start orientation to calibrate
attitude!.multiplyByInverseOfAttitude(sharedInstance.referenceAttitude)
}

if attitude != nil {
return lowPassWithVector([Float(attitude!.yaw), Float(attitude!.roll), Float(attitude!.pitch)])
} else {
return [0.0, 0.0, 0.0]
}
}

// Stop collection motion data to save energy
class func stop() {
sharedInstance.motionManager.stopDeviceMotionUpdates()
sharedInstance.referenceAttitude=nil
sharedInstance.bActive=false
}

// Calibrate motion manager with a ne reference attitude
class func calibrate() {
sharedInstance.referenceAttitude = getMotionManager().deviceMotion?.attitude?.copy() as? CMAttitude
}


// Damp the jitter caused by hand movement
class func lowPassWithVector(var vector:[Float]) -> [Float]
{
vector[0] = vector[0] * cLowPassFactor + sharedInstance.lastVector[0] * (1.0 - cLowPassFactor)
vector[1] = vector[1] * cLowPassFactor + sharedInstance.lastVector[1] * (1.0 - cLowPassFactor)
vector[2] = vector[2] * cLowPassFactor + sharedInstance.lastVector[2] * (1.0 - cLowPassFactor)

sharedInstance.lastVector = vector
return sharedInstance.lastVector
}
}

完整教程:http://developerplayground.net/?p=19

关于ios - Swift 使用 CMMotionManager 配置加速度计跟踪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34077518/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com