使用CMMotionManager swift iOS sdk滚动球

时间:2018-04-09 09:48:02

标签: ios swift core-motion

我正在尝试使用CMMotionManager制作一个滚球应用程序。 这是我的代码:

import UIKit
import CoreMotion


class ViewController: UIViewController {

    @IBOutlet weak var circleView: UIView!
    @IBOutlet weak var accelX: UILabel!

    let motionManager = CMMotionManager()

    var circleCentre : CGPoint!
    var newCircleCentre : CGPoint!

    override func viewDidAppear(_ animated: Bool) {

        motionManager.accelerometerUpdateInterval = 0.01 //1.0 / 60.0

        motionManager.startAccelerometerUpdates(to: OperationQueue.current!) { (data, error) in
            if let myData = data
            {

                self.newCircleCentre.x = (CGFloat(myData.acceleration.x) * 10)
                self.newCircleCentre.y = (CGFloat(myData.acceleration.y) * 10)
                self.circleCentre = CGPoint(x: self.circleCentre.x + self.newCircleCentre.x, y: self.circleCentre.y + self.newCircleCentre.y)

                self.accelX.text = String(format: "X == %.2f  Y == %.2f", self.circleCentre.x, self.circleCentre.y)

                if self.circleCentre.x < 20 {
                    self.circleCentre = CGPoint(x: 20, y: self.circleCentre.y)
                }

                if self.circleCentre.x > 256 {
                    self.circleCentre = CGPoint(x: 256, y: self.circleCentre.y)
                }

                if self.circleCentre.y < 20 {
                    self.circleCentre = CGPoint(x: self.circleCentre.x, y: 20)
                }

                if self.circleCentre.y > 256 {
                    self.circleCentre = CGPoint(x: self.circleCentre.x, y: 256)
                }

                self.circleView.center = self.circleCentre

            }
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        circleCentre = self.circleView.center
        newCircleCentre = self.circleView.center
    }


}

但当我的设备保持在水面上时,它的表现不正常并且不会在中心停止。谁能帮我。提前致谢

2 个答案:

答案 0 :(得分:1)

首先,您需要考虑一些事实:

  • 你的表面永远不会完全笔直
  • 你的表面不断运动(即使颜色不明显)
  • 测量方向时,手机的设计无限制

如果你把一个球放在桌子上,它会留在原处还是会有点滚动?表面越硬,球越完美,你就会有更多的滚动。在你的模拟中,表面是完美的,球是完美的。这意味着它没有摩擦,没有理由保持静止。

但是你可以设置一个阈值,这样如果力量相对较小,球就会停止。请考虑以下事项:

import CoreMotion


class ViewController: UIViewController {

    lazy var circleView: UIView = {
        let view = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 50.0, height: 50.0))
        view.backgroundColor = UIColor.green
        view.layer.cornerRadius = 25.0
        self.view.addSubview(view)
        return view
    }()

    let motionManager = CMMotionManager()

    var circleCentre : CGPoint!
    var newCircleCentre : CGPoint!

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        motionManager.accelerometerUpdateInterval = 0.01 //1.0 / 60.0

        motionManager.startAccelerometerUpdates(to: OperationQueue.current!) { (data, error) in
            if let myData = data
            {

                self.newCircleCentre.x = (CGFloat(myData.acceleration.x) * 10)
                self.newCircleCentre.y = (CGFloat(myData.acceleration.y) * -10)

                if abs(self.newCircleCentre.x) + abs(self.newCircleCentre.y) < 1.0 {
                    self.newCircleCentre = .zero
                }

                self.circleCentre = CGPoint(x: self.circleCentre.x + self.newCircleCentre.x, y: self.circleCentre.y + self.newCircleCentre.y)

                self.circleCentre.x = max(self.circleView.frame.size.width*0.5, min(self.circleCentre.x, self.view.bounds.width - self.circleView.frame.size.width*0.5))
                self.circleCentre.y = max(self.circleView.frame.size.height*0.5, min(self.circleCentre.y, self.view.bounds.height - self.circleView.frame.size.height*0.5))


                self.circleView.center = self.circleCentre

            }
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        circleCentre = self.circleView.center
        newCircleCentre = self.circleView.center
    }


}

答案 1 :(得分:0)

这就是我实现所需输出的方式。谢谢大家

    motionManager.accelerometerUpdateInterval = 1.0 / 60.0

    motionManager.startAccelerometerUpdates(to: OperationQueue.current!) { (data, error) in
        if let myData = data {

            let xG = CGFloat(myData.acceleration.x) * 100
            let yG = -CGFloat(myData.acceleration.y) * 100

            let xPos = grillageCenter.x + xG
            let yPos = grillageCenter.y + yG

            print("x pos === \(xPos)")
            print("y pos === \(yPos)")

            self.circleView.center = CGPoint(x: xPos, y: yPos)
        }
    }