• 【传感器】重力感应X轴 Y轴 Z轴 SensorManager


    效果图:

    切图:

    编码:

    main.xml

    View Code
    <?xml version="1.0" encoding="utf-8"?>
    <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" 
        android:id="@+id/screen"
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent"
        android:orientation="vertical">
        <LinearLayout
            android:layout_width="fill_parent" 
            android:layout_height="fill_parent"
            android:orientation="vertical">
            <ImageView
             android:src="@drawable/jay"
             android:layout_width="fill_parent" 
             android:layout_height="fill_parent" />
        
        </LinearLayout>
    </ScrollView>

    SurfaceViewAcitvity.java

    View Code
    package cn.m15.xys;
    
    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 {
    
            /** 每10帧刷新一次屏幕 **/
            public static final int TIME_IN_FRAME = 10;
    
            /** 游戏画笔 **/
            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);
            }
    
            private void Draw() {
                /** 绘制游戏背景 **/
                mCanvas.drawBitmap(mbitmapBg, 0, 0, mPaint);
                /** 绘制小球 **/
                mCanvas.drawBitmap(mbitmapBall, mPosX, mPosY, mPaint);
                /** X轴 Y轴 Z轴的重力值 **/
                mCanvas.drawText("X轴重力值 :" + mGX, 0, 20, mPaint);
                mCanvas.drawText("Y轴重力值 :" + mGY, 0, 40, mPaint);
                mCanvas.drawText("Z轴重力值 :" + mGZ, 0, 60, mPaint);
            }
    
            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width,
                    int height) {
    
            }
    
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                /** 开始游戏主循环线程 **/
                mIsRunning = true;
                new Thread(this).start();
                /** 得到当前屏幕宽高 **/
                mScreenWidth = this.getWidth();
                mScreenHeight = this.getHeight();
    
                /** 得到小球越界区域 **/
                mScreenBallWidth = mScreenWidth - mbitmapBall.getWidth();
                mScreenBallHeight = mScreenHeight - mbitmapBall.getHeight();
            }
    
            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                mIsRunning = false;
            }
    
            @Override
            public void run() {
                while (mIsRunning) {
                    /** 取得更新游戏之前的时间 **/
                    long startTime = System.currentTimeMillis();
                    /** 在这里加上线程安全锁 **/
                    synchronized (mSurfaceHolder) {
                        /** 拿到当前画布 然后锁定 **/
                        mCanvas = mSurfaceHolder.lockCanvas();
                        Draw();
                        /** 绘制结束后解锁显示在屏幕上 **/
                        mSurfaceHolder.unlockCanvasAndPost(mCanvas);
                    }
    
                    /** 取得更新游戏结束的时间 **/
                    long endTime = System.currentTimeMillis();
    
                    /** 计算出游戏一次更新的毫秒数 **/
                    int diffTime = (int) (endTime - startTime);
    
                    /** 确保每次更新时间为50帧 **/
                    while (diffTime <= TIME_IN_FRAME) {
                        diffTime = (int) (System.currentTimeMillis() - startTime);
                        /** 线程等待 **/
                        Thread.yield();
                    }
    
                }
    
            }
    
            @Override
            public void onAccuracyChanged(Sensor arg0, int arg1) {
                // TODO Auto-generated method stub
    
            }
    
            @Override
            public void onSensorChanged(SensorEvent event) {
                mGX = event.values[SensorManager.DATA_X];
                mGY = event.values[SensorManager.DATA_Y];
                mGZ = event.values[SensorManager.DATA_Z];
    
                // 这里乘以2是为了让小球移动的更快
                mPosX -= mGX * 2;
                mPosY += mGY * 2;
    
                // 检测小球是否超出边界
                if (mPosX < 0) {
                    mPosX = 0;
                } else if (mPosX > mScreenBallWidth) {
                    mPosX = mScreenBallWidth;
                }
                if (mPosY < 0) {
                    mPosY = 0;
                } else if (mPosY > mScreenBallHeight) {
                    mPosY = mScreenBallHeight;
                }
            }
        }
    }

     配置文件

    View Code
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="cn.m15.xys"
          android:versionCode="1"
          android:versionName="1.0">
        <application android:icon="@drawable/icon" android:label="@string/app_name">
            
            <activity android:name=".SurfaceViewAcitvity"
                        android:configChanges="orientation|keyboardHidden"
                      android:label="@string/app_name">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            
        </application>
    </manifest> 
  • 相关阅读:
    Android客户端消息推送原理简介
    优秀程序员的十个习惯
    能让你成为更优秀程序员的10个C语言资源
    成大事必备9种能力、9种手段、9种心态
    33个优秀的HTML5应用演示 (转)
    Maven学习:Eclipse使用maven构建web项目(转)
    使用fiddler模拟http get
    TLS握手
    风暴英雄 http 302重定向 正在等待游戏模式下载完成
    page template in kentico
  • 原文地址:https://www.cnblogs.com/androidsj/p/2987009.html
Copyright © 2020-2023  润新知