Android 小球重力感应实现(一)
重力感应主要是依靠手机的加速度传感器(accelerometer)来实现
在Android的开发中一共有八种传感器但是不一定每一款真机都支持这些传感器。因为很多功能用户根本不care的所以可能开发商会把某些功能屏蔽掉。还是得根据真机的实际情况来做开发,今天我们主要来讨论加速度传感器的具体实现方式。
传感器名称如下:
加速度传感器(accelerometer) 陀螺仪传感器(gyroscope) 环境光照传感器(light)
磁力传感器(magnetic field) 方向传感器(orientation) 压力传感器(pressure) 距离传感器(proximity) 温度传感器(temperature)
1.SensorMannager传感器管理对象
手机中的所有传感器都须要通过SensorMannager来访问,调用getSystemService(SENSOR_SERVICE)方法就可以拿到当前手机的传感器管理对象。
java代码:
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代码:
public void onSensorChanged(SensorEvent e) { float x = e.values[SensorManager.DATA_X]; float y = e.values[SensorManager.DATA_Y]; float z = e.values[SensorManager.DATA_Z]; }
手机屏幕向左侧方当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代码:
mSensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE); mSensor = mSensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
// 注册listener,第三个参数是检测的精确度
//SENSOR_DELAY_FASTEST 最灵敏因为太快了没必要使用 //SENSOR_DELAY_GAME 游戏开发中使用 //SENSOR_DELAY_NORMAL 正常速度 //SENSOR_DELAY_UI 最慢的速度
mSensorMgr.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_GAME);
重力感应简单速度计算的方式。每次摇晃手机计算出 X轴 Y轴 Z轴的重力分量可以将它们记录下来然后每次摇晃的重力分量和之前的重力分量可以做一个对比利用差值和时间就可以计算出他们的移动速度。
java代码:
private SensorManager sensorMgr;
Sensor sensor = sensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); //保存上一次 x y z 的坐标 float bx = 0; float by = 0; float bz = 0;
long btime = 0;//这一次的时间
sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
SensorEventListener lsn = new SensorEventListener() { public void onSensorChanged(SensorEvent e) { float x = e.values[SensorManager.DATA_X]; float y = e.values[SensorManager.DATA_Y]; float z = e.values[SensorManager.DATA_Z];
//在这里我们可以计算出 X Y Z的数值下面我们就可以根据这个数值来计算摇晃的速度了 //我想大家应该都知道计算速度的公事速度 = 路程/时间 //X轴的速度
float speadX = (x - bx) / (System.currentTimeMillis() - btime); //y轴的速度
float speadY = (y - by) / (System.currentTimeMillis() - btime); //z轴的速度
float speadZ = (z - bz) / (System.currentTimeMillis() - btime);
//这样简单的速度就可以计算出来如果你想计算加速度也可以在运动学里,加速度a与速度, //位移都有关系:Vt=V0+at,S=V0*t+1/2at^2, S=(Vt^2-V0^2)/(2a),根据这些信息也可以求解a。
//这里就不详细介绍了公事应该初中物理课老师就教了呵呵~~ bx = x; by = y; bz = z;
btime = System.currentTimeMillis(); }
public void onAccuracyChanged(Sensor s, int accuracy) { } };
// 注册listener,第三个参数是检测的精确度
sensorMgr.registerListener(lsn, sensor, SensorManager.SENSOR_DELAY_GAME);
java代码:
import android.app.Activity; import android.content.Context;
import android.content.pm.ActivityInfo; import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.Bundle;
import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.Window;
import android.view.WindowManager;
import android.view.SurfaceHolder.Callback;
public class SurfaceViewAcitvity extends Activity { MyView mAnimView = null;
@Override
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
// 全屏显示窗口
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); //强制横屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
// 显示自定义的游戏View mAnimView = new MyView(this); setContentView(mAnimView); }
public class MyView extends SurfaceView implements Callback,Runnable ,SensorEventListener{ /**每50帧刷新一次屏幕**/
public static final int TIME_IN_FRAME = 50; /** 游戏画笔 **/ Paint mPaint = null; Paint mTextPaint = null;
SurfaceHolder mSurfaceHolder = null; /** 控制游戏更新循环 **/ boolean mRunning = false; /** 游戏画布 **/ Canvas mCanvas = null;
/**控制游戏循环**/
boolean mIsRunning = false; /**SensorManager管理器**/
private SensorManager mSensorMgr = null; Sensor mSensor = null; /**手机屏幕宽高**/ int mScreenWidth = 0; int mScreenHeight = 0;
/**小球资源文件越界区域**/
private int mScreenBallWidth = 0; private int mScreenBallHeight = 0; /**游戏背景文件**/
private Bitmap mbitmapBg; /**小球资源文件**/
private Bitmap mbitmapBall; /**小球的坐标位置**/ private float mPosX = 200; private float mPosY = 0;
/**重力感应X轴 Y轴 Z轴的重力值**/ private float mGX = 0; private float mGY = 0; private float mGZ = 0;
public MyView(Context context) { super(context);
/** 设置当前View拥有控制焦点 **/ this.setFocusable(true);
/** 设置当前View拥有触摸事件 **/ this.setFocusableInTouchMode(true); /** 拿到SurfaceHolder对象 **/ mSurfaceHolder = this.getHolder();
/** 将mSurfaceHolder添加到Callback回调函数中 **/ mSurfaceHolder.addCallback(this); /** 创建画布 **/
mCanvas = new Canvas();
/** 创建曲线画笔 **/ mPaint = new Paint();
mPaint.setColor(Color.WHITE); /**加载小球资源**/
mbitmapBall = BitmapFactory.decodeResource(this.getResources(), R.drawable.ball); /**加载游戏背景**/
mbitmapBg = BitmapFactory.decodeResource(this.getResources(), R.drawable.bg); /**得到SensorManager对象**/
mSensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE); mSensor = mSensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
// 注册listener,第三个参数是检测的精确度
//SENSOR_DELAY_FASTEST 最灵敏因为太快了没必要使用 //SENSOR_DELAY_GAME 游戏开发中使用 //SENSOR_DELAY_NORMAL 正常速度 //SENSOR_DELAY_UI 最慢的速度
mSensorMgr.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_GAME); }
百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说教育文库Android 小球重力感应实现在线全文阅读。
相关推荐: