`
263229365
  • 浏览: 472258 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Android 小球重力感应实现

 
阅读更多

重力感应主要是依靠手机的加速度传感器(accelerometer)来实现
       在Android的开发中一共有八种传感器但是不一定每一款真机都支持这些传感器。因为很多功能用户根本不care的所以可能开发商会把某些功能屏蔽掉。还是得根据真机的实际情况来做开发,今天我们主要来讨论加速度传感器的具体实现方式。

       传感器名称如下:
       加速度传感器(accelerometer)
       陀螺仪传感器(gyroscope)
       环境光照传感器(light)
       磁力传感器(magnetic field)
       方向传感器(orientation)
       压力传感器(pressure)
       距离传感器(proximity)
       温度传感器(temperature)


       1.SensorMannager传感器管理对象
       手机中的所有传感器都须要通过SensorMannager来访问,调用getSystemService(SENSOR_SERVICE)方法就可以拿到当前手机的传感器管理对象。

java代码:

  1. SensorManager mSensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
复制代码

       2.实现SensorEventListener接口
       说道SensorEventListener接口就不得不说SensorListener接口。在Android1.5一下是通过实现SensorListener接口来捕获 手机传感器状态,但是在1.5以上如果实现这个接口系统会提示你这行代码已经过期。今天我们不讨论SensorListener因为它已经是过时的东西了。主要讨论一下SensorEventListener接口。我们须要实现SensorEventListener这个接口 onSensorChanged(SensorEvent event)方法来捕获手机传感器的状态,拿到手机 X轴Y轴Z轴三个方向的重力分量,有了这三个方向的数据重力感应的原理我们就已经学会了。

java代码:
  1. public void onSensorChanged(SensorEvent e) { 
  2. float x = e.values[SensorManager.DATA_X]; 
  3. float y = e.values[SensorManager.DATA_Y]; 
  4. float z = e.values[SensorManager.DATA_Z]; 
  5. }
复制代码

       手机屏幕向左侧方当X轴就朝向天空,垂直放置 这时候 Y 轴 与 Z轴没有重力分量,因为X轴朝向天空所以它的重力分量则最大 。这时候X轴 Y轴 Z轴的重力分量的值分别为(10,0,0)
       手机屏幕向右侧方当X轴就朝向地面,垂直放置 这时候 Y 轴 与 Z轴没有重力分量,因为X轴朝向地面所以它的重力分量则最小 。这时候X轴 Y轴 Z轴的重力分量的值分别为(-10,0,0)
       手机屏幕垂直竖立放置方当Y轴就朝向天空,垂直放置 这时候 X 轴 与 Z轴没有重力分量,因为Y轴朝向天空所以它的重力分量则最大 。这时候X轴 Y轴 Z轴的重力分量的值分别为(0,10,0)
       手机屏幕垂直竖立放置方当Y轴就朝向地面,垂直放置 这时候 X 轴 与 Z轴没有重力分量,因为Y轴朝向地面所以它的重力分量则最小 。这时候X轴 Y轴 Z轴的重力分量的值分别为(0,-10,0)

       手机屏幕向上当Z轴就朝向天空,水平放置 这时候 X 轴与Y轴没有重力分量,因为Z轴朝向天空所以它的重力分量则最大 。这时候X轴 Y轴 Z轴的重力分量的值分别为(0,0,10)
       手机屏幕向上当Z轴就朝向地面,水平放置 这时候 X 轴与Y轴没有重力分量,因为Z轴朝向地面所以它的重力分量则最小 。这时候X轴 Y轴 Z轴的重力分量的值分别为(0,0,-10)

       因为这张图片是在模拟器上截得,所以没有重力感应它的三个方向的的重力分量都为0。

 3.注册SensorEventListener

       使用SensorMannager调用getDefaultSensor(Sensor.TYPE_ACCELEROMETER)方法拿到加速重力感应的Sensor对象。因为本章我们讨论重力加速度传感器所以参数为Sensor.TYPE_ACCELEROMETER,如果须要拿到其它的传感器须要传入对应的名称。使用SensorMannager调用registerListener()方法来注册,第三个参数是检测的灵敏精确度根据不同的需求来选择精准度,游戏开发建议使用  SensorManager.SENSOR_DELAY_GAME。

java代码:

  1. mSensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE); 
  2. mSensor = mSensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 
  3. // 注册listener,第三个参数是检测的精确度 
  4. //SENSOR_DELAY_FASTEST 最灵敏 因为太快了没必要使用 
  5. //SENSOR_DELAY_GAME 游戏开发中使用 
  6. //SENSOR_DELAY_NORMAL 正常速度 
  7. //SENSOR_DELAY_UI 最慢的速度 
  8. mSensorMgr.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_GAME);
复制代码

       重力感应简单速度计算的方式。 每次摇晃手机计算出 X轴 Y轴 Z轴的重力分量可以将它们记录下来 然后每次摇晃的重力分量和之前的重力分量可以做一个对比 利用差值和时间就可以计算出他们的移动速度。

java代码:
  1. private SensorManager sensorMgr; 
  2. Sensor sensor = sensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 
  3. //保存上一次 x y z 的坐标 
  4. float bx = 0; 
  5. float by = 0; 
  6. float bz = 0; 
  7. long btime = 0;//这一次的时间 
  8. sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE); 
  9. SensorEventListener lsn = new SensorEventListener() { 
  10. public void onSensorChanged(SensorEvent e) { 
  11. float x = e.values[SensorManager.DATA_X]; 
  12. float y = e.values[SensorManager.DATA_Y]; 
  13. float z = e.values[SensorManager.DATA_Z]; 
  14. //在这里我们可以计算出 X Y Z的数值 下面我们就可以根据这个数值来计算摇晃的速度了 
  15. //我想大家应该都知道计算速度的公事 速度 = 路程/时间 
  16. //X轴的速度 
  17. float speadX = (x - bx) / (System.currentTimeMillis() - btime); 
  18. //y轴的速度 
  19. float speadY = (y - by) / (System.currentTimeMillis() - btime); 
  20. //z轴的速度 
  21. float speadZ = (z - bz) / (System.currentTimeMillis() - btime); 
  22. //这样简单的速度就可以计算出来 如果你想计算加速度 也可以 在运动学里,加速度a与速度, 
  23. //位移都有关系:Vt=V0+at,S=V0*t+1/2at^2, S=(Vt^2-V0^2)/(2a),根据这些信息也可以求解a。 
  24. //这里就不详细介绍了 公事 应该初中物理课老师就教了呵呵~~ 
  25. bx = x; 
  26. by = y; 
  27. bz = z; 
  28. btime = System.currentTimeMillis(); 

  29. public void onAccuracyChanged(Sensor s, int accuracy) { 

  30. }; 
  31. // 注册listener,第三个参数是检测的精确度 
  32. sensorMgr.registerListener(lsn, sensor, SensorManager.SENSOR_DELAY_GAME);
复制代码
java代码:
  1. import android.app.Activity; 
  2. import android.content.Context; 
  3. import android.content.pm.ActivityInfo; 
  4. import android.graphics.Bitmap; 
  5. import android.graphics.BitmapFactory; 
  6. import android.graphics.Canvas; 
  7. import android.graphics.Color; 
  8. import android.graphics.Paint; 
  9. import android.hardware.Sensor; 
  10. import android.hardware.SensorEvent; 
  11. import android.hardware.SensorEventListener; 
  12. import android.hardware.SensorManager; 
  13. import android.os.Bundle; 
  14. import android.view.SurfaceHolder; 
  15. import android.view.SurfaceView; 
  16. import android.view.Window; 
  17. import android.view.WindowManager; 
  18. import android.view.SurfaceHolder.Callback; 


  19. public class SurfaceViewAcitvity extends Activity { 
  20. MyView mAnimView = null; 


  21. @Override 
  22. public void onCreate(Bundle savedInstanceState) { 
  23. super.onCreate(savedInstanceState); 
  24. // 全屏显示窗口 
  25. requestWindowFeature(Window.FEATURE_NO_TITLE); 
  26. getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
  27. WindowManager.LayoutParams.FLAG_FULLSCREEN); 
  28. //强制横屏 
  29. setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 
  30. // 显示自定义的游戏View 
  31. mAnimView = new MyView(this); 
  32. setContentView(mAnimView); 

  33. public class MyView extends SurfaceView implements Callback,Runnable ,SensorEventListener{ 
  34. /**每50帧刷新一次屏幕**/ 
  35. public static final int TIME_IN_FRAME = 50; 
  36. /** 游戏画笔 **/ 
  37. Paint mPaint = null; 
  38. Paint mTextPaint = null; 
  39. SurfaceHolder mSurfaceHolder = null; 
  40. /** 控制游戏更新循环 **/ 
  41. boolean mRunning = false; 
  42. /** 游戏画布 **/ 
  43. Canvas mCanvas = null; 
  44. /**控制游戏循环**/ 
  45. boolean mIsRunning = false; 
  46. /**SensorManager管理器**/ 
  47. private SensorManager mSensorMgr = null; 
  48. Sensor mSensor = null; 
  49. /**手机屏幕宽高**/ 
  50. int mScreenWidth = 0; 
  51. int mScreenHeight = 0; 
  52. /**小球资源文件越界区域**/ 
  53. private int mScreenBallWidth = 0; 
  54. private int mScreenBallHeight = 0; 
  55. /**游戏背景文件**/ 
  56. private Bitmap mbitmapBg; 
  57. /**小球资源文件**/ 
  58. private Bitmap mbitmapBall; 
  59. /**小球的坐标位置**/ 
  60. private float mPosX = 200; 
  61. private float mPosY = 0; 
  62. /**重力感应X轴 Y轴 Z轴的重力值**/ 
  63. private float mGX = 0; 
  64. private float mGY = 0; 
  65. private float mGZ = 0; 
  66. public MyView(Context context) { 
  67. super(context); 
  68. /** 设置当前View拥有控制焦点 **/ 
  69. this.setFocusable(true); 
  70. /** 设置当前View拥有触摸事件 **/ 
  71. this.setFocusableInTouchMode(true); 
  72. /** 拿到SurfaceHolder对象 **/ 
  73. mSurfaceHolder = this.getHolder(); 
  74. /** 将mSurfaceHolder添加到Callback回调函数中 **/ 
  75. mSurfaceHolder.addCallback(this); 
  76. /** 创建画布 **/ 
  77. mCanvas = new Canvas(); 
  78. /** 创建曲线画笔 **/ 
  79. mPaint = new Paint(); 
  80. mPaint.setColor(Color.WHITE); 
  81. /**加载小球资源**/ 
  82. mbitmapBall = BitmapFactory.decodeResource(this.getResources(), R.drawable.ball); 
  83. /**加载游戏背景**/ 
  84. mbitmapBg = BitmapFactory.decodeResource(this.getResources(), R.drawable.bg); 
  85. /**得到SensorManager对象**/ 
  86. mSensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE); 
  87. mSensor = mSensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
  88. // 注册listener,第三个参数是检测的精确度 
  89. //SENSOR_DELAY_FASTEST 最灵敏 因为太快了没必要使用 
  90. //SENSOR_DELAY_GAME 游戏开发中使用 
  91. //SENSOR_DELAY_NORMAL 正常速度 
  92. //SENSOR_DELAY_UI 最慢的速度 
  93. mSensorMgr.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_GAME); 



  94. private void Draw() { 
  95. /**绘制游戏背景**/ 
  96. mCanvas.drawBitmap(mbitmapBg,0,0, mPaint); 
  97. /**绘制小球**/ 
  98. mCanvas.drawBitmap(mbitmapBall, mPosX,mPosY, mPaint); 
  99. /**X轴 Y轴 Z轴的重力值**/ 
  100. mCanvas.drawText("X轴重力值 :" + mGX, 0, 20, mPaint); 
  101. mCanvas.drawText("Y轴重力值 :" + mGY, 0, 40, mPaint); 
  102. mCanvas.drawText("Z轴重力值 :" + mGZ, 0, 60, mPaint); 



  103. @Override 
  104. public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) { 



  105. @Override 
  106. public void surfaceCreated(SurfaceHolder holder) { 
  107. /**开始游戏主循环线程**/ 
  108. mIsRunning = true; 
  109. new Thread(this).start(); 
  110. /**得到当前屏幕宽高**/ 
  111. mScreenWidth = this.getWidth(); 
  112. mScreenHeight = this.getHeight(); 
  113. /**得到小球越界区域**/ 
  114. mScreenBallWidth = mScreenWidth - mbitmapBall.getWidth(); 
  115. mScreenBallHeight = mScreenHeight - mbitmapBall.getHeight(); 

  116. @Override 
  117. public void surfaceDestroyed(SurfaceHolder holder) { 
  118. mIsRunning = false; 

  119. @Override 
  120. public void run() { 
  121. while (mIsRunning) { 
  122. /** 取得更新游戏之前的时间 **/ 
  123. long startTime = System.currentTimeMillis(); 
  124. /** 在这里加上线程安全锁 **/ 
  125. synchronized (mSurfaceHolder) { 
  126. /** 拿到当前画布 然后锁定 **/ 
  127. mCanvas = mSurfaceHolder.lockCanvas(); 
  128. Draw(); 
  129. /** 绘制结束后解锁显示在屏幕上 **/ 
  130. mSurfaceHolder.unlockCanvasAndPost(mCanvas); 

  131. /** 取得更新游戏结束的时间 **/ 
  132. long endTime = System.currentTimeMillis(); 
  133. /** 计算出游戏一次更新的毫秒数 **/ 
  134. int diffTime = (int) (endTime - startTime); 
  135. /** 确保每次更新时间为50帧 **/ 
  136. while (diffTime <= TIME_IN_FRAME) { 
  137. diffTime = (int) (System.currentTimeMillis() - startTime); 
  138. /** 线程等待 **/ 
  139. Thread.yield(); 





  140. @Override 
  141. public void onAccuracyChanged(Sensor arg0, int arg1) { 
  142. // TODO Auto-generated method stub 

  143. @Override 
  144. public void onSensorChanged(SensorEvent event) { 
  145. mGX = event.values[SensorManager.DATA_X]; 
  146. mGY= event.values[SensorManager.DATA_Y]; 
  147. mGZ = event.values[SensorManager.DATA_Z]; 
  148. //这里乘以2是为了让小球移动的更快 
  149. mPosX -= mGX * 2; 
  150. mPosY += mGY * 2; 
  151. //检测小球是否超出边界 
  152. if (mPosX < 0) { 
  153. mPosX = 0; 
  154. } else if (mPosX > mScreenBallWidth) { 
  155. mPosX = mScreenBallWidth; 

  156. if (mPosY < 0) { 
  157. mPosY = 0; 
  158. } else if (mPosY > mScreenBallHeight) { 
  159. mPosY = mScreenBallHeight; 



  160. }

<!--EndFragment-->
分享到:
评论

相关推荐

    Android小球重力感应运动有碰撞声源码.rar

    Android小球重力感应运动有碰撞声源码.rar,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。

    Android 小球重力感应 代码

    在Android平台上,开发一款利用重力感应功能的小球...总之,Android小球重力感应代码示例是一个实用的实践项目,它涵盖了Android传感器API、事件处理、物理运动模拟等多个知识点,对于提升Android开发技能十分有益。

    Android小球重力感应源码

    这个"Android小球重力感应源码"项目很可能是为了帮助开发者理解如何将手机的重力感应数据应用到游戏或者动态效果中。 首先,我们要了解Android的Sensor API。Android系统提供了SensorManager服务,用于管理设备上的...

    Android小球重力感应运动(有碰撞声)源码

    本项目“Android小球重力感应运动(有碰撞声)源码”提供了一个完整的示例,展示了如何利用Android的传感器API来捕捉设备的重力变化,使屏幕上的小球模拟真实世界的物理运动,并在碰撞时产生声音反馈。 首先,我们...

    Android 重力感应游戏-疯狂的小球源码程序

    Android 重力感应游戏-疯狂的小球源码程序,基于Android 平台的重力感应游戏-疯狂的小球。

    Unity Android版重力感应小球

    在"Unity Android版重力感应小球"项目中,开发者利用Unity3D的特性构建了一个移动设备上的游戏,玩家可以通过设备的重力感应器来控制小球的移动。以下是对该项目涉及的关键技术点的详细解释: 1. **Unity3D**:...

    Android小球重力感应运动有碰撞声源码的冲突文件2017-08-0410-24-13-524.rar

    该压缩包文件“Android小球重力感应运动有碰撞声源码的冲突文件2017-08-0410-24-13-524.rar”包含了Android平台上的一个特殊项目,该项目旨在实现一个基于重力感应的小球运动模拟,并在小球与边界或其它物体碰撞时...

    Android重力感应Demo

    在Android平台上,重力感应是通过传感器服务(Sensor Service)来实现的,它允许开发者获取设备的各种物理状态信息,如重力、加速度、陀螺仪等。在本"Android重力感应Demo"中,我们将深入探讨如何利用Android SDK中的...

    Android游戏开发之小球重力感应源码

    本项目“Android游戏开发之小球重力感应源码”提供了实现这一功能的详细代码,帮助开发者了解如何将手机的重力感应数据应用到游戏逻辑中。 首先,我们需要了解Android系统是如何获取重力感应数据的。Android系统...

    Android 重力感应游戏-疯狂的小球

    "疯狂的小球"作为一款这样的游戏,它充分展现了Android平台上的重力感应技术。下面将详细介绍重力感应游戏的设计原理、实现方式以及与"疯狂的小球"相关的技术要点。 1. 重力感应原理: Android设备中的加速度计是...

    android重力感应小球

    一个很独特的重力游戏,控制你的小球不断的转动重力以达到终点。

    Android手机平台重力感应Demo

    在Android平台上,重力感应功能是通过传感器系统服务来实现的,这允许应用程序接收设备的动态运动数据,如重力、加速度等。这个"Android手机平台重力感应Demo"是一个示例项目,用于演示如何在Android应用中利用重力...

    android 重力感应 小球测试源码.rar

    android 重力感应测试项目源代码,作者:雨松MOMO。利用一个小球下落来模拟重力感应,进入游戏世界 - 强制横屏 -小球移动,显示自定义的游戏View,每50帧刷新一次屏幕,重力感应X轴 Y轴 Z轴的重力值,设置当前View...

    Android 弹力小球实例

    首先,"小球重力感应源码"是这个实例的核心部分。Android系统提供了一个名为SensorManager的服务,用于获取设备的各种传感器数据,包括加速度传感器。加速度传感器可以捕捉到设备的移动和倾斜,这正是实现重力感应...

    Android 2D游戏开发小案例设计重力感应

    在Android平台上进行2D游戏开发是一项充满挑战和乐趣的任务,特别是在设计涉及物理模拟的游戏时,如本案例中的“重力感应足球”。这个小案例提供了一个实际应用,它利用了Android设备内置的加速度传感器,让玩家通过...

    Android_重力感应和屏幕旋转关系.docx

    在Android平台中,重力感应主要是通过内置的三轴加速度传感器来实现的。该传感器可以检测设备在三维空间内的加速度变化,具体包括X、Y、Z三个方向上的加速度分量。这三个方向上的加速度可以被看作是一个位于三维坐标...

    android简单的重力感应游戏

    用unity3D简单的重力感应游戏,做的很粗糙,供大家参考吧,呵呵

    flash重力感应实例

    这个名为“Flash重力感应实例”的项目,就是专门针对Android系统设计的一个演示程序,它利用设备的加速度传感器来捕捉用户的移动和倾斜,进而控制界面上的小球移动。下面我们将详细探讨这个实例涉及到的几个关键知识...

Global site tag (gtag.js) - Google Analytics