zoukankan      html  css  js  c++  java
  • CoreMontion加速计

    描述:用CoreMontion加速计控制小球的运动,通过屏幕触摸,暂停和恢复。

    步骤

    1. 添加MontionManager和CADisplayLink

    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        // 添加小球
        UIImage *image = [UIImage imageNamed:@"black"];
        _ball = [[UIImageView alloc] initWithImage:image];
        _ball.center = self.view.center;
        
        [self.view addSubview:_ball];
        
        _ballVelocity = CGPointZero;
        
        _queue = [[NSOperationQueue alloc] init];
        
        // 运动管理器方法
        // 1) 实例化运动管理器
    MyMontionManager *montionManager = 
    [MyMontionManager sharedMyMontionManager];
        
        // 2) 判断加速计是否可用
        if (montionManager.isAccelerometerAvailable) {
            // 3) 设置采样数据的时间间隔
            montionManager.accelerometerUpdateInterval = 1 / 60.0;
            
            // 4)开始采样数据
            [self startAccelerometerUpdates];
        } else {
            NSLog(@"摔坏了");
        }
        
        // 实例化游戏时钟  防止小球虚化显示  montionManager负责采集,CADisplayLink 负责显示
    _gameTimer = [CADisplayLink displayLinkWithTarget:self 
    selector:@selector(updateLocation)];
        // 将时钟添加到主运行循环中
    [_gameTimer addToRunLoop:[NSRunLoop mainRunLoop] 
    forMode:NSDefaultRunLoopMode];
    }
    

    2. 设置MontionManager单例,方便使用

    static MyMontionManager *_instance;
    
    @implementation MyMontionManager
    
    + (id)allocWithZone:(struct _NSZone *)zone
    {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            _instance = [super allocWithZone:zone];
        });
        
        return _instance;
    }
    
    + (instancetype)sharedMyMontionManager
    {
        if (_instance == nil) {
            _instance = [[MyMontionManager alloc] init];
        }
        
        return _instance;
    }
    
    @end
    

    3. 采样方法

    - (void)startAccelerometerUpdates
    {
        // 操作队列是负责处理采样的数据
    [[MyMontionManager sharedMyMontionManager] 
    startAccelerometerUpdatesToQueue:_queue 
    withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) 
    {
            // 处理采样数据,修改小球速度
            _ballVelocity.x += accelerometerData.acceleration.x;
            _ballVelocity.y -= accelerometerData.acceleration.y;
            
            NSLog(@"%@", [NSThread currentThread]);
        }];
    }
    

    4. 更改小球位置、

    - (void)updateLocation
    {
        NSLog(@"==== %@", [NSThread currentThread]);
        
        // 设置小球的位置
        CGPoint center = _ball.center;
        CGSize size = self.view.bounds.size;
        
        // 解决小球出界问题,碰撞检测
        // 水平方向:左边,右边
        if (CGRectGetMinX(_ball.frame) <= 0 || CGRectGetMaxX(_ball.frame) >= size.width) {
            // 修改小球的速度方向
            _ballVelocity.x *= -1;
            
            // 修复位置 < 0
            if (CGRectGetMinX(_ball.frame) <= 0) {
                center.x = _ball.bounds.size.width / 2.0;
            } else {
                center.x = size.width - _ball.bounds.size.width / 2.0;
            }
        }
        
        // 垂直方向
        if (CGRectGetMinY(_ball.frame) <= 0 || CGRectGetMaxY(_ball.frame) >= size.height) {
            // 修改小球的速度方向
            _ballVelocity.y *= -1;
            
            // 修复位置 < 0
            if (CGRectGetMinY(_ball.frame) <= 0) {
                center.y = _ball.bounds.size.height / 2.0;
            } else {
                center.y = size.height - _ball.bounds.size.height / 2.0;
            }
        }
        
        center.x += _ballVelocity.x;
        center.y += _ballVelocity.y;
        
    
         _ball.center = center; //在mainloop中,所以不需要队列
    
    }
    

    5 触摸停止/启动

    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
        // 正在采样数据,说明游戏进行中,暂停
    if ([MyMontionManager sharedMyMontionManager].isAccelerometerActive)
     {
            // 定制采样数据
            [[MyMontionManager sharedMyMontionManager] stopAccelerometerUpdates];
            
            // 停止时钟
            // invalidate停止时钟
            //  1> 将时钟从主运行循环中撤销
            //  2> 将时钟销毁
    //        [_gameTimer invalidate];
            
            // 直接从主运行循环中将游戏时钟删除,而不会销毁时钟,等到需要时再次添加即可。
            [_gameTimer removeFromRunLoop:[NSRunLoop mainRunLoop] 
    forMode:NSDefaultRunLoopMode];
        } else {
            // 开始采样加速计数据
            [self startAccelerometerUpdates];
           
    
            [_gameTimer addToRunLoop:[NSRunLoop mainRunLoop] 
    forMode:NSDefaultRunLoopMode];
        }
        
    }
    
  • 相关阅读:
    洛谷 P2915 [USACO08NOV]奶牛混合起来Mixed Up Cows 题解
    洛谷 P2687 [USACO4.3]逢低吸纳Buy Low, Buy Lower/ACWing 314 低买 题解
    7、Python异常
    必须要调整心态,积极起来,不能再偷懒
    5、Python函数
    10、Python数据库支持
    8、Python方法、属性、迭代器
    9、Python模块和标准库
    6、Python抽象的类
    UDP Linux编程(客户端&服务器端)
  • 原文地址:https://www.cnblogs.com/dqxu/p/3595762.html
Copyright © 2011-2022 走看看