iOS - 加速计(重力感应)

先上效果图
iOS - 加速计(重力感应)_第1张图片
iOS - 加速计(重力感应)_第2张图片

小球根据重力感应 然后降落 并且有弹起效果

一、原理
重力感应的三维空间 xyz的坐标系如图 (注意:和frame的坐标的y不同)

  • x
    向左: 负数 向右:正数
  • y
    向上: 正数 向下:负数
  • z
    屏幕朝上:负数 屏幕朝下:正数

二、代码
注:以下代码只适用于iOS4.0之后
移动的方法都封装在了CoreMotion.framework 这个库中
在工程里加入库 并且在所需控制器中添加头文件CoreMotion/CoreMotion.h

1.引用库
CoreMotion/CoreMotion.h
2.创建运动管理者
@property (nonatomic,strong) CMMotionManager * mgr;
self.mgr = [[CMMotionManager alloc]init];
3.判断加速计是否可以用
if (!self.mgr.isAccelerometerAvailable) {
//表示不可以使用
NSLog(@”加速计不可用”);
return;
}
4.设置采样间隔 (push采样需要 pull采样不需要)
self.mgr.accelerometerUpdateInterval = 1.0/30.0; //一秒钟采样30次
注:push方式是系统主动推过来的 所以需要设置采样时间间隔,对于数据要求较高的app试用,此处的重力感应需要
pull方式是在有需要的时候,自己主动去拿数据,所以不需要设置时间间隔

5.开始采样
push方式
[self.mgr startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMAccelerometerData * _Nullable accelerometerData, NSError * _Nullable error) {
}];
pull方式
[self.mgr startAccelerometerUpdates];

最后提上全部代码

//
// ViewController.m
// 160412重力加速
//
// Created by Momo on 16/4/12.
// Copyright © 2016年 Momo. All rights reserved.
//

#import "ViewController.h"
#import <CoreMotion/CoreMotion.h>
@interface ViewController ()<UIAccelerometerDelegate>

/** 小球*/
@property (weak, nonatomic) IBOutlet UIImageView *ball;

/** 运动管理者*/
@property (nonatomic,strong) CMMotionManager * mgr;

/** 小球运动速度*/
@property (nonatomic,assign) CGPoint velocity;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // 1.创建运动管理对象
    self.mgr = [[CMMotionManager alloc]init];

    // 2.判断加速器是否可以使用(最好判断一下)
    if (!self.mgr.isAccelerometerAvailable) {
        //表示不可以使用
        NSLog(@"加速计不可用");
        return;
    }

    //push方式
    [self push];

    //pull方式
    //[self pull];

}

-(void)push{


    // 3.设置采样间隔 (push采样需要 pull采样不需要)
    self.mgr.accelerometerUpdateInterval = 1.0/30.0; //一秒钟采样30次


    // 4.1 开始采样 (push 时时采样)
    [self.mgr startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMAccelerometerData * _Nullable accelerometerData, NSError * _Nullable error) {

        if (error) {
            return ;
        }

        // 5.获取加速计信息
        CMAcceleration acceleration = accelerometerData.acceleration;
        NSLog(@"x:%f y:%f z:%f",acceleration.x,acceleration.y,acceleration.z);


        // 处理小球
        // v = a * t = a1 + a2 + a3 + ... + at
        // 1.累加加速度 = 速度
        _velocity.x += acceleration.x;
        _velocity.y -= acceleration.y; //y的加速度是相反的 所以就是减

        // 2.累加速度 = 位移
        // s = v * t = v1 + v2 + v3 + ... + vt
        CGRect rect = self.ball.frame;
        rect.origin.x += _velocity.x;
        rect.origin.y += _velocity.y;
        self.ball.frame = rect;

        // 3.边界处理
        if (self.ball.frame.origin.x <= 0) {
            // x超出左边界
            rect.origin.x = 0;
            self.ball.frame = rect;

            //速度取反 削弱速度
            _velocity.x *= -0.5;
        }

        if (CGRectGetMaxX(self.ball.frame) >= self.view.frame.size.width) {
            // x超出右边界
            rect.origin.x = self.view.frame.size.width - self.ball.frame.size.width;
            self.ball.frame = rect;

            //速度取反 削弱速度
            _velocity.x *= -0.5;
        }

        if (self.ball.frame.origin.y <= 0) {
            // y超出上边界
            rect.origin.y = 0;
            self.ball.frame = rect;

            //速度取反 削弱速度
            _velocity.y *= -0.5;

        }

        if (CGRectGetMaxY(self.ball.frame) >= self.view.frame.size.height) {
            // y超出下边界
            rect.origin.y = self.view.frame.size.height - self.ball.frame.size.height;
            self.ball.frame = rect;

            //速度取反 削弱速度
            _velocity.y *= -0.5;
        }

    }];


}

-(void)pull{

    // 4.2 开始采样 (pull 有需要时采样)
    [self.mgr startAccelerometerUpdates];

}

// 4.2 开始采样 (pull 有需要时采样)
 //在需要时获取数据 此处为点击屏幕时需要采样
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

    //获取加速计信息
    CMAcceleration acc = self.mgr.accelerometerData.acceleration;
    NSLog(@"%f,%f, %f", acc.x,acc.y,acc.z);
}




@end

你可能感兴趣的:(ios)