上一次借着实现一个随屏幕旋转的小玩意,了解了iPhone内置的加速计。今天咱们继续搞点好玩的东东。按照计划这次要看看陀螺仪了。

最终咱们会完成一个小球撞壁的小游戏,一个超级贱的利用陀螺仪的APP。小球可以感受到重力,从而能够随着手机的运动来一起运动。为了增加一点点趣味性,对小球的运动范围做了限制。当小球碰到屏幕的边缘的时候,会进行反弹,相反方向运动。咱们一起来看看实现后的实况录像:

今天的代码比起上次的加速计稍微多了一点点,所以就提供了源码供大家批评。同时由于这部分Swfit和Objective-C略微有不太一样的地方,所以源码提供了两版。

其实不管是加速计还是今天的陀螺仪,都是用到了上次说的iOS当中的那个核心运动框架CoreMotion。

1. 陀螺仪介绍

陀螺仪主要是用来测量沿着某个特定的坐标轴旋转速度的。在使用中,陀螺仪始终指向一个固定的方向,当运动物体的运动方向偏离预定方向时,陀螺仪就可以感受出来。

在手机上,仅用加速度计没办法测量或重构出完整的3D动作,测不到转动的动作的,加速计只能检测轴向的线性动作。但陀螺仪则可以对转动、偏转的动作做很好的测量,这样就可以精确分析判断出使用者的实际动作。而后根据动作,可以对手机做相应的操作。

1.1 陀螺仪的应用场景

各位童鞋相比都玩过Wii,那个体感手柄肯定就用到了陀螺仪。玩家通过挥动运动手柄,来控制游戏。例如乒乓球、网球、赛车等等。有一些酷炫的APP会通过小幅度的倾斜,偏转手机,实现彩蛋功能,例如放大缩小之类的。或者把手机屏幕翻转,就可以拒接电话或者静音啥的。 拍照类的APP也会通过陀螺仪把拍照时候手的抖动反馈交给图像处理器,以便抓到更清晰稳定的图片。

还有一些是最近刚刚看到的好贱好贱的APP。例如Send Me To Heaven,游戏的玩法超级简单,只需向天空抛掷手机,扔得越高,分数也就越高。

Throw Me App 另外一个贱不拉几的APP。这是一个相机APP,使用时打开APP并将手机抛向空中,当手机在空中时,使用陀螺仪和加速计探测手机是否达到了最高点,且摄像头是否向下。随后,该应用将激活摄像头快门进行拍照。

1.2 陀螺仪在iOS中的使用

iPhone、iPad、iWatch都有内置的陀螺仪,也都可以让开发者进行调用。同样,用一张图展现一下:

2. 陀螺仪的使用

2.1 使用步骤

陀螺仪同样也是通过CoreMotion这个框架来管理的,所以和加速计一样,四个标准步骤:

  1. 初始化CMMotionManager管理对象;

  2. 调用管理对象的对象方法获取数据;

  3. 处理数据;

  4. 当不需要使用的时候,停止获取数据。

2.2 陀螺仪数据获取的两种方法

CoreMotion中有2种获取数据方式,一种叫做PUSH的方式,一种叫做PULL的方式。顾名思义,PUSH就是被动的获取。设定完了之后,线程定时把获取到的数据推送回来。可想而知,对于资源的消耗是会稍微大一点的。 PULL,就是要去索取。拉一下才会获取到数据。不要不给。上一次加速计咱们给出的代码是OC的,今天咱们就用Swift的。

2.2.1 PULL的方式

1
2
3
4
5
6
7
8
9
10
11
12
     private   func useGyroPull() {
          //判断陀螺仪可不可用
          if   manager.isGyroAvailable {
              //设置陀螺仪多久采样一次
              manager.gyroUpdateInterval =  0.1
              //开始更新,后台线程开始运行。这是Pull方式。
              manager.startGyroUpdates()
                   
           }
          //获取并处理陀螺仪数据。这里我们就只是简单的做了打印。
          print( "X = \(manager.gyroData?.rotationRate.x ?? 0)" , "Y = \(manager.gyroData?.rotationRate.y ?? 0)" , "Z = \(manager.gyroData?.rotationRate.z ?? 0)" )
      }

2.2.2 PUSH的方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
     private   func useGyroPush() {
          //判断陀螺仪可不可用
          if   manager.isGyroAvailable {
              //设置陀螺仪多久采样一次
              manager.gyroUpdateInterval =  0.1
              //Push方式获取和处理数据,这里我们一样只是做了简单的打印。把采样的工作放在了主线程中。                     manager.startGyroUpdates(to: OperationQueue.main, withHandler: { (gyroData, error) in
             print( "X = \(self.manager.gyroData?.rotationRate.x ?? 0)" , "Y = \(self.manager.gyroData?.rotationRate.y ?? 0)" , "Z = \(self.manager.gyroData?.rotationRate.z ?? 0)" )           
                  
             }) 
          else   {
             print( "陀螺仪不可用" )
          }
 
     
    }

3. 开始我们的小游戏

3.1 思维导图

3.2 实现

3.2.1 以X轴边界值处理及碰壁后速度处理为例

1
2
3
4
5
6
//            对球在X轴碰壁进行处理
              if   currentPoint.x = bounds.size.width - imageWidth /  2   {
                  currentPoint.x = bounds.size.width - imageWidth /  2
                  ballXVelocity = -ballXVelocity *  0.8
   
             }

3.2.2 开启陀螺仪并更新

1
2
3
4
5
6
7
8
9
10
         manager.deviceMotionUpdateInterval =  1   60
          //注意一下,在Swift没有了NSOperation。被OperationQueue取代了。
          manager.startDeviceMotionUpdates(to: OperationQueue.main) { (motion, error)  in
           
                  self.ballView!.accelleration = (motion?.gravity)!
              //开启主队列异步线程,更新球的位置。
              DispatchQueue.main.async {
                  self.ballView!.updateLocation(multiplier:  5000 )
   
             }

3.2.3 更新小球的位置

1
2
3
4
5
6
7
8
9
10
11
12
13
     func updateLocation(multiplier : Double) {
          if   (lastUpdateTime != nil) {
              let updatePeriod : Double =  Date .init().timeIntervalSince(lastUpdateTime!)
                            
               ballXVelocity = ballXVelocity + accelleration.x * updatePeriod
               ballYVelocity = ballYVelocity + accelleration.y * updatePeriod
                            
              let coefficient = updatePeriod * multiplier
              currentPoint = CGPoint(x: currentPoint.x + (CGFloat)(ballXVelocity * coefficient), y: currentPoint.y - (CGFloat)(ballYVelocity * coefficient))
           }
          lastUpdateTime =  Date ()
      
      }

3.3 关于Swift中重写set/get

其实写到这里的时候才突然想起来,咱们从来没有说过Swift怎么重写Set/Get方法。而且貌似也没有分享过iOS开发中多线程的东东。下个系列非典型技术宅就可以写写多线程相关的玩意儿吧,如果多线程这部分不太明白的话,对不住对不住对不住,马上补上。

在swift中其实重写set不太常见,但这都是OC留下来的臭毛病,就非要重新咋办?请自行搜索,就不提供链接到*书了。

这个不是重点,咱们在写小球的时候用到的是didSet这个方法。这是啥呐?这是swift当中的观察者,用来监视属性除了初始化之外的属性变化。

  • didSet:在属性值改变后触发,didSet可以带一个oldName的参数,表示旧的属性,不带的话默认命名为oldValue。

  • willSet:在属性值改变前触发,可以带一个newName的参数,没有的话,该参数默认命名为newValue。

iOS传感器:使用陀螺仪完成一个小球撞壁的小游戏相关推荐

  1. 用python3写一个小球转动的抽奖小游戏

    最近老师在讲 tkinter,所以我做了一个抽奖小游戏 一.效果图 先上效果图.红色的小球会围绕蓝色小球做环形运动.我设置的四个角是奖品,其余的都是再接再厉. 二.方法 基于tkinter中的butt ...

  2. 用c++做一个简单的打飞机小游戏(详细说明与注释)

    用c++做一个简单的打飞机小游戏(详细说明与注释) 说明: 代码长度5k多,行数200多行. 不仅没有压行,反而为了条理清晰一点所以很多中间加空换行,把很多可以写在一起的分割成了几个函数. 为了不会忘 ...

  3. Py之pygame:有趣好玩——利用pygame库实现一个移动底座弹球的小游戏

    Py之pygame:有趣好玩--利用pygame库实现一个移动底座弹球的小游戏 目录 输出结果 实现代码 输出结果 实现代码 # -*- coding: utf-8 -*-#Py之pygame:有趣好 ...

  4. main java game,playgame 一个JAVA编写的飞行小游戏,有基本完整的 框架,适合初学者参照学习 Other s 其他 238万源代码下载- www.pudn.com...

    文件名称: playgame下载 收藏√  [ 5  4  3  2  1 ] 开发工具: Java 文件大小: 7050 KB 上传时间: 2013-06-06 下载次数: 3 提 供 者: Lyq ...

  5. c语言小游戏 精简_一个简易的贪吃蛇小游戏C语言源码

    /* *程序名称:贪吃蛇v2.1 *程序描述:一个简易的贪吃蛇小游戏 *版本信息:v2.1 *v1.1版本更新:1:加入菜单选择项 *v1.2版本更新:1:修复菜单选择bug *v1.3班本更新:1: ...

  6. pygame小游戏代码_Py之pygame:有趣好玩——利用pygame库实现一个移动底座弹球的小游戏...

    Py之pygame:有趣好玩--利用pygame库实现一个移动底座弹球的小游戏 目录 输出结果 实现代码 输出结果 ​ 实现代码 # -*- coding: utf-8 -*-#Py之pygame:有 ...

  7. 写一个简单的实时互动小游戏

    在写之前,我们先回顾上一篇文章,从需求.架构.设计.开发上讲述并演示了搭建一个实时通信客户端的过程,并附了图片与视频. 写这篇文章的之前,第一个互动的游戏DEMO已经写好了,先附上截图 很奇怪的一张图 ...

  8. 教你如何用C语言设计一个有趣的猜数字小游戏

    目录 前言 猜数字游戏 打印菜单 处理玩家选择的操作 编写猜数字游戏函数 游戏中要猜数字从哪来?(配置随机数生成器) 时间戳 开始生成随机数 game函数内部编写 完整代码 总结 前言 好久不见,今天 ...

  9. 使用Qt写一个简单的五子棋单机小游戏

    使用Qt写一个简单的五子棋单机小游戏 刚学,不够专业请勿喷,有不对的地方还请指出,我渴望进步!现在贴出这个游戏我原创的所有代码.希望可以帮到有需要的人. 游戏界面: 因为后面添加了.wav的音频文件, ...

最新文章

  1. linux系统中删除文件夹
  2. VMware 滴滴声解决
  3. python 定时执行 爬虫 模块_【Python】定时执行网站爬虫
  4. Oracle 11gR2 RAC Service-Side TAF 配置示例
  5. 汇编jnl_汇编指令集
  6. android xml 列表展示,Android中ListView实现展示列表数据
  7. epson彩色打印机加墨水_爱普生打印机墨盒如何加墨?
  8. java switch中if_详解java中if语句和switch的使用
  9. linux磁盘划分注意,划分磁盘阵列注意问题
  10. php简单生成缩略图方法
  11. 十二、十三天总结笔记
  12. IntelliJ IDEA提示忽略大小写
  13. 当卷积层后跟batch normalization层时为什么不要偏置b
  14. adb修改什么文件获取root权限_Android获取ROOT权限的通用方法
  15. Java 序列化与主流编解码技术框架介绍
  16. 八十九、Java内置函数(常用函数)
  17. Android 健康饮食软件详解
  18. depends的使用教程
  19. 计算机网络(24)——轮转访问MAC协议
  20. 轻松实现Word在线编辑

热门文章

  1. nvm的下载管理不同版本的node
  2. 性价比最高的百元蓝牙耳机排行,学生党蓝牙耳机推荐
  3. Spark:DataFrame使用
  4. 如何使用onyx for mac显示更多系统硬件信息
  5. 投资理财__读懂利润表
  6. 指纹辨识将被破解?最新研究出人工智能可以绘制假指纹
  7. tv.twitch.android,Twitchapp_Twitch最新免费安卓版 - 系统家园
  8. 如何在 Label 控件内容改变后自动向左伸缩而不是向右
  9. 数据结构复习之顺序表
  10. vmware 虚拟机三种网络模式 桥接 NAT 仅主机区别 是什么意思