Android重力感应飘树叶,晃动掉元宝

来源:互联网 发布:淘宝网有解封dnf的吗 编辑:程序博客网 时间:2024/03/28 17:56

图呢,,,,,自己想想吧、、、、、、、画面很美。

package com.example.propertyanimsecdemo;import android.content.Context;import android.hardware.Sensor;import android.hardware.SensorEvent;import android.hardware.SensorEventListener;import android.hardware.SensorManager;import android.provider.ContactsContract.CommonDataKinds.Event;import android.sax.StartElementListener;import android.util.Log;import android.widget.TextView;public class SensorManagerHelper implements SensorEventListener {/** * 上下文 */private Context mContext;/** * 传感器管理器 */private SensorManager mSensorManager;/** * 传感器 */private Sensor mSensor;/** * 手机上一个位置时重力感应坐标 */private float LX, LY, LZ;/** * 晃动监听 */private OnShakeListener mShakeListener;/** * 速度阈值,当摇晃速度达到这值后产生作用 */private static final int SPEED_SHRESHOLD = 5000;/** * 两次检测的时间间隔 */private static final int UPTATE_INTERVAL_TIME = 50;/** * 某轴上的速度s/t */private static final int SPEED_XYZ = 500;/** * 上次晃动检测时间 */private long lastShakeTime;public SensorManagerHelper(Context mContext) {super();this.mContext = mContext;start();}public void start() {// 获取传感器管理器mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);if (mSensorManager != null) {// 获取重力传感器mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);}if (mSensor != null) {// 注册listener,第三个参数是检测的精确度// SENSOR_DELAY_FASTEST 最灵敏 因为太快了没必要使用// SENSOR_DELAY_GAME 游戏开发中使用// SENSOR_DELAY_NORMAL 正常速度// SENSOR_DELAY_UI 最慢的速度mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_UI);}}public void stop() {mSensorManager.unregisterListener(this);}@Overridepublic void onSensorChanged(SensorEvent event) {long curShakeTime = System.currentTimeMillis();// 当前时间long deltaT = curShakeTime - lastShakeTime;// 两次时间差if (deltaT < UPTATE_INTERVAL_TIME) {return;}lastShakeTime = curShakeTime;// 获取当前x,y,z坐标float CX = event.values[0];float CY = event.values[1];float CZ = event.values[2];// 坐标差float deltaX = CX - LX;float deltaY = CY - LY;float deltaZ = CZ - LZ;LX = CX;LY = CY;LZ = CZ;double speed = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ) / deltaT * 10000;// 达到速度阀值,发出提示if (speed >= SPEED_SHRESHOLD)mShakeListener.onShake();if ((7<Math.abs(CX)&&Math.abs(CX)<10&&Math.abs(deltaX/deltaT*10000)>SPEED_XYZ)||(7<Math.abs(CY)&&Math.abs(CY)<10&&Math.abs(deltaY/deltaT*10000)>SPEED_XYZ)||(7<Math.abs(CZ)&&Math.abs(CZ)<10&&Math.abs(deltaZ/deltaT*10000)>SPEED_XYZ)) {mShakeListener.onSensor();}}@Overridepublic void onAccuracyChanged(Sensor sensor, int accuracy) {}// 摇晃监听接口public interface OnShakeListener {/** * 晃动监听回调 */public void onShake();/** * 重力监听回调 */public void onSensor();}/** * 设置晃动监听 *  * @param mShakeListener */public void setmShakeListener(OnShakeListener mShakeListener) {this.mShakeListener = mShakeListener;}}

1、取得重力感应器Sensor对象

mSensorManager= (SensorManager) getSystemService(Context.SENSOR_SERVICE);


mSensor = manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

2、创建监听器


mListener = new SensorEventListener() {
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}

public void onSensorChanged(SensorEvent event) {
float x = event.values[SensorManager.DATA_X];
float y = event.values[SensorManager.DATA_Y];
float z = event.values[SensorManager.DATA_Z];
doSomething(x, y, z);
}
};

 

3、注册监听器


mSensorManager.registerListener(mListener, mSensor, SensorManager.SENSOR_DELAY_GAME);

这里 SENSOR_DELAY_GAME 还可以是以下常量:
SENSOR_DELAY_FASTEST
SENSOR_DELAY_UI
SENSOR_DELAY_NORMAL

 

4、取消监听器


mSensorManager.unregisterListener(mListener);

5、添加当重力变化时的处理函数

    Android重力感应系统的坐标系

    以屏幕的左下方为原点(2d编程的时候,是以屏幕左上方为原点的,这个值得注意一下),箭头指向的方向为正。从-10到10,以浮点数为等级单位,想象一下以下情形:

    手机屏幕向上(z轴朝天)水平放置的时侯,(x,y,z)的值分别为(0,0,10);

    手机屏幕向下(z轴朝地)水平放置的时侯,(x,y,z)的值分别为(0,0,-10);

    手机屏幕向左侧放(x轴朝天)的时候,(x,y,z)的值分别为(10,0,0);

    手机竖直(y轴朝天)向上的时候,(x,y,z)的值分别为(0,10,0);

    其他的如此类推,规律就是:朝天的就是正数,朝地的就是负数。利用x,y,z三个值求三角函数,就可以精确检测手机     的运动状态了

       当手机倾斜方向改变时,监听器会调用该方法。
       我们要做的,就是填充该方法,用于在重力发生变化时进行我们自己的处理。
       当 x=y=0 时,手机处于水平放置状态。
       当 x=0 并且 y>0 时,手机顶部的水平位置要大于底部,也就是一般接听电话时手机所处的状态。
       当 x=0 并且 y<0 时,手机顶部的水平位置要小于底部。手机一般很少处于这种状态。
       当 y=0 并且 x>0 时,手机右侧的水平位置要大于左侧,也就是右侧被抬起。
       当 y=0 并且 x<0 时,手机右侧的水平位置要小于左侧,也就是左侧被抬起。
       当 z=0 时,手机平面与水平面垂直。
       当 z>0 时,手机屏幕朝上。
       当 z<0 时,手机屏幕朝下


package com.example.propertyanimsecdemo;import java.util.Random;import com.example.propertyanimsecdemo.SensorManagerHelper.OnShakeListener;import android.app.Activity;import android.graphics.Point;import android.os.Bundle;import android.util.DisplayMetrics;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.view.ViewGroup.LayoutParams;import android.widget.Button;import android.widget.FrameLayout;import android.widget.TextView;import android.widget.Toast;public class MainActivity extends Activity {private FrameLayout mFrameLayout;private LayoutParams mParams;/** * 贝尔曲线数 */private static final int BEZIER_COUNT = 20;/** * 4点决定三次贝尔曲线 */private static final int POINT_COUNT = 4;/** * 添加树叶 */private static final int LEAF = 1;/** * 添加元宝 */private static final int YUANBAO = -1;/** * 树叶数 */private static final int LEAF_COUNT = 6;/** * 移动物体元宝 */private Button[] mViews = new Button[BEZIER_COUNT];/** * 移动物体树叶 */private Button[] mLeafs= new Button[LEAF_COUNT];/** * 三次贝塞尔曲线起始点,2控制点,终点 */private Point[] mPoints = new Point[POINT_COUNT];/** * 屏幕宽 */private int w_screen;/** * 屏幕高 */private int h_screen;private SensorManagerHelper mHelper;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mFrameLayout = (FrameLayout) findViewById(R.id.frameLayout);DisplayMetrics dm = getResources().getDisplayMetrics();w_screen = dm.widthPixels;h_screen = dm.heightPixels;int[] leafs = { R.drawable.fengye1,R.drawable.fengye2, R.drawable.fengye3, R.drawable.fengye4, R.drawable.fengye3, R.drawable.fengye4};for (int i = 0; i < BEZIER_COUNT; i++) {addPointAndView(i, R.drawable.yuanbao,YUANBAO);}for (int i = 0; i < LEAF_COUNT; i++) {addPointAndView(i, leafs[i],LEAF);}mHelper = new SensorManagerHelper(MainActivity.this);mHelper.setmShakeListener(new OnShakeListener() {@Overridepublic void onShake() {for (int count = 0; count < BEZIER_COUNT; count++) {getFPoints();mViews[count].setX(mPoints[0].x);mViews[count].setY(mPoints[0].y);MyAnimator animator = new MyAnimator(mPoints, MainActivity.this, mViews[count],YUANBAO);animator.startAnimator();}}@Overridepublic void onSensor() {for (int count = 0; count < LEAF_COUNT; count++) {getFPoints();mLeafs[count].setX(mPoints[0].x);mLeafs[count].setY(mPoints[0].y);MyAnimator animator = new MyAnimator(mPoints, MainActivity.this, mLeafs[count],LEAF);animator.startAnimator();}}});}/** * 随机产生四点 */private void getFPoints() {for (int i = 0; i < POINT_COUNT; i++) {Point point = new Point();point.x = new Random().nextInt( w_screen - 20);if (i == 0) {point.y = 0 - Utils.dip2px(this, 60);// 控制起点在屏幕最上方} else if (i == 3) {point.y = h_screen;// 控制终点在屏幕最下方} else {point.y = new Random().nextInt( h_screen);}mPoints[i] = point;Log.d("ee", i + ":(" + point.x + "." + point.y);}}/** * 往布局上添加物体 *  * @param count * @param resource * @param type  */private void addPointAndView(int count, int resource, int type) {getFPoints();if (type==YUANBAO) {Button mView = new Button(MainActivity.this);mView.setBackgroundResource(resource);mParams = new LayoutParams(Utils.dip2px(this, 30), Utils.dip2px(this, 30));mFrameLayout.addView(mView, mParams);mView.setX(mPoints[0].x);mView.setY(mPoints[0].y);mViews[count] = mView;}else {Button mView = new Button(MainActivity.this);mView.setBackgroundResource(resource);mParams = new LayoutParams(Utils.dip2px(this, 60), Utils.dip2px(this, 60));mFrameLayout.addView(mView, mParams);mView.setX(mPoints[0].x);mView.setY(mPoints[0].y);mLeafs[count]=mView;}}@Overrideprotected void onDestroy() {super.onDestroy();mHelper.stop();}}

源码下载



0 0