Nabati 2016-08-17 12:05 采纳率: 6.3%
浏览 1151
已采纳

重力感应控制画布小球问题

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);    
}  

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;  
    }  
}  
}  

}

这时用重力感应器控制小球移动的一个demo,但是现在我想自己画一个圆充当小球,而不是用图片替代,我该怎么改这段代码?求指教!

  • 写回答

1条回答 默认 最新

  • FFZ2009 2016-08-18 02:09
    关注

    主要是修改Draw()方法,drawBitmap(...)需要改为drawCircle(...)
    以下是修改的代码,仅供参考:

    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 int mCircleRadius = 48;
    
            private int mCircleColor = Color.CYAN;
            private Paint mCirclePaint = new Paint();
    
            private int mBackgroundColor = Color.DKGRAY;
    
            /**小球资源文件**/
           // 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);
    
                mCirclePaint.setColor(mCircleColor);
                /**加载小球资源**/
                //mbitmapBall = BitmapFactory.decodeResource(this.getResources(), R.mipmap.ic_launcher);
                /**加载游戏背景**/
               // mbitmapBg = BitmapFactory.decodeResource(this.getResources(),  R.drawable.switch_thumb_pressed_holo_light);
    
                /**得到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.drawColor(mBackgroundColor);
                /**绘制小球**/
                mCanvas.drawCircle(mPosX,mPosY,mCircleRadius,mCirclePaint);
                //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();*/
    mScreenBallWidth = mScreenWidth - mCircleRadius;
    mScreenBallHeight = mScreenHeight - mCircleRadius;
    }

            @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 < mCircleRadius) {
                    mPosX = mCircleRadius;
                } else if (mPosX > mScreenBallWidth) {
                    mPosX = mScreenBallWidth;
                }
                if (mPosY < mCircleRadius) {
                    mPosY = mCircleRadius;
                } else if (mPosY > mScreenBallHeight) {
                    mPosY = mScreenBallHeight;
                }
            }
        }
    }
    
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 Mac虚拟机安装Windows,Windows中用idea跑项目,报错process finished with exit code -1073741819(0xc0000005) 如何解决?
  • ¥15 关于python爬虫返回js数据结构的处理
  • ¥15 ubuntu所用stm32标准库开发烧录没反映
  • ¥15 运维工程师(在职人员回答)
  • ¥15 python 爬虫问题
  • ¥15 Kmeans的趋势分析有会的吗
  • ¥20 R语言单细胞测序 对seurat对象进行标准化时出现问题
  • ¥15 Anaconda navigator updateor一直更新
  • ¥15 请问如何在matlab里使用raven工具?
  • ¥100 关于ios手游充值到一定金额,再点充值提示公众号的问题。