Android实现重力小球

很简单的实现,作为软件专业大二在校生,接触安卓还没两个月,没事写着玩练练手,请大神们莫要嘲讽

重力小球主要参考了http://www.xuanyusong.com/archives/337这篇文章,我写出来的代码风格都完全一样,惭愧惭愧

(我的第一篇CSDN博客,值得纪念一手,蛤蛤蛤

package com.example.a29205.myapp10;



import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;

import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;



import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;


public class MainActivity extends AppCompatActivity {





final static  String TAG="MainActivity";


    @Override
    protected void onResume() {
        super.onResume();

    }

    @Override
    protected 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



        mysuferView mysuferView=new mysuferView(this);
        setContentView(mysuferView);

    }

    @Override
    protected void onPause() {
        super.onPause();

    }

}


然后就是自定义的suferView

package com.example.a29205.myapp10;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;

import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;

import android.os.Vibrator;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import static android.content.Context.SENSOR_SERVICE;

/**
 * Created by 29205 on 2018/4/29.
 */

public class mysuferView extends SurfaceView implements SurfaceHolder.Callback,Runnable,SensorEventListener{



    final static  String TAG="mysuferView";
    SensorManager mSensorManager;//SensorManager 是系统所有传感器的管理器,获得一个sensormanager的实例
    Sensor mSensor_of_orientation;//传感器sensor实例
    //永远记得确保当你不需要的时候,特别是Activity暂定的时候,要关闭感应器。
    SensorEventListener mSensorEventListener;//对传感器输出的信号进行监听
    float GX=0;
    float GY=0;
    float GZ;
    //重力加速度g在设备的x,y,z轴三个方向的分量
    double AX;
    double AY=0;////大地垂直坐标系与设备Y轴之间的弧度,由该弧度的大小决定赋予小球加速度的大小
    double AZ;
    //设备的x,y,z轴与大地方向(即重力加速度方向)的夹角
    double g;
    //重力加速度
    double acceleation;//小球被赋予的加速度,由屏幕旋转的角度赋予
    double weiyi;
    /**每30帧刷新一次屏幕**/
    public static final int TIME_IN_FRAME = 30;


    Paint mPaint = null;
    Paint mLinePaint = null;
    /**小球资源文件**/
    private Bitmap mbitmapBall;
    /**游戏背景文件**/
    private Bitmap mbitmapBackground;




    SurfaceHolder mSurfaceHolder = null;
    /** 控制游戏更新循环 **/
    boolean mRunning = false; // 子线程标志位

    private Canvas mCanvas=null;// 用于绘图的Canvas

    /**手机屏幕宽高**/
    int mphoneScreenWidth = 0;
    int mphoneScreenHeight = 0;

    /**小球越界区域**/
    private int mBallWidth_zuo = 0;
    private int mBallHeight_shang = 0;
    private int mBallWidth_you=0;
    private int mBallHeight_xia= 0;
    private int r_of_bianjie=500;
//    在屏幕内,坐标都是正值,屏幕范围内最小是0
    /**小球的坐标位置**/
    private float mPosX =500;
    private float mPosY =300;
/*   不管横屏是由竖屏顺时针旋转90度,或者 逆时针旋转90度得到,
 都是以左上角为原点。是视觉上的左上角 ,不是空间上的左上角。

*/
boolean is_chujie=false;


    public void initView(Context context){//自定义的初始化方法

//        所谓焦点就是被选中的意思,或者说是“当前正在操作的组件”的意思。
//        如果一个组件被选中,或者正在被操作者,就是得到了焦点,而相反的,
// 一个组件没有被选中或者失去操作,就是被转移了焦点,焦点已经到别的组件上去了。
        this.setFocusable(true);
        //设置当前View可以拥有控制焦点

        /** 设置当前View拥有触摸事件 **/
        this.setFocusableInTouchMode(true);
        /** 拿到SurfaceHolder对象 **/
        mSurfaceHolder = this.getHolder();
        /** 将mSurfaceHolder添加到Callback回调函数中 **/
        mSurfaceHolder.addCallback(this);
        /** 创建画布 **/
        mCanvas = new Canvas();
        mCanvas.drawColor(Color.YELLOW);

        /** 创建画笔 ,分别用来画小球和杆**/
        mPaint = new Paint();
        mPaint.setColor(Color.BLACK);
        mPaint.setAntiAlias(true);
        mLinePaint=new Paint();
        mLinePaint.setColor(Color.WHITE);
        mLinePaint.setTextSize(30);
        /**加载游戏背景**/
        mbitmapBackground = BitmapFactory.decodeResource(this.getResources(), R.drawable.bg);
        /**加载小球资源**/
        mbitmapBall = BitmapFactory.decodeResource(this.getResources(), R.drawable.ball);


        mSensorManager= (SensorManager)context.getSystemService(SENSOR_SERVICE);//获取到 SensorManager 的实例
        mSensor_of_orientation=mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);//获取重力传感器
        mSensorManager.registerListener(this, mSensor_of_orientation, SensorManager.SENSOR_DELAY_GAME);//注册传感器

}
    private void Draw() {//绘制方法



        Log.e(TAG,mPosX+"mPosX ");
        Log.e(TAG,mPosY+" mPosY");
        Paint paint = new Paint();
          paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
        mCanvas.drawPaint(paint);
       paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));

        mPosX+=0.5*GY*(TIME_IN_FRAME*TIME_IN_FRAME/80);
        mPosY+=0.5*GX*(TIME_IN_FRAME*TIME_IN_FRAME/80);
        /**绘制游戏背景**/
        mCanvas.drawBitmap(mbitmapBackground,0,0, mPaint);
        Paint linshipaint=new Paint();
        linshipaint.setColor(Color.RED);
        linshipaint.setTextSize(50);
        if(is_chujie==true){

            mCanvas.drawText("小球已出界",0,140,linshipaint);}
        else{
            mCanvas.drawText("小球未出界",0,140,linshipaint);}


        mCanvas.drawText(GX+"  X轴上的重力加速度",0,30,mLinePaint);
        mCanvas.drawText(GY+"  Y轴上的重力加速度",0,80,mLinePaint);
        mCanvas.drawCircle(mphoneScreenWidth/2,mphoneScreenHeight/2 ,r_of_bianjie,mPaint);


        /**绘制小球**/
        mCanvas.drawBitmap(mbitmapBall, mPosX,mPosY, mPaint);
    }


    public mysuferView(Context context) {
        super(context);
        initView(context);
    }

    public mysuferView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView(context);
    }

    public mysuferView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context);
    }

//对于SurfaceHolder.Callback方法,需要实现如下方法,其实就是SurfaceView的生命周期:
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        /**开始游戏主循环线程**/
        mRunning = true;
        /**得到当前屏幕宽高**/
        mphoneScreenWidth = this.getWidth();
        mphoneScreenHeight = this.getHeight();
      Log.e(TAG,mphoneScreenWidth+"当前屏幕宽");
       Log.e(TAG,mphoneScreenHeight+"当前屏幕的高");

        /**得到小球越界区域**/
        mBallWidth_you = (mphoneScreenWidth/2) +r_of_bianjie;
        mBallWidth_zuo=(mphoneScreenWidth/2)-r_of_bianjie;
        mBallHeight_shang=mphoneScreenHeight/2+r_of_bianjie;
        mBallHeight_xia=mphoneScreenHeight/2-r_of_bianjie;

        new Thread(this).start();

    }

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

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        mRunning = false;
        mSensorManager.unregisterListener(mSensorEventListener);//要调用 unregisterListener ()方法将使用的资源释放掉

    }
//对于Runnable接口,需要实现run()方法
    @Override
    public void run() {
        while (mRunning) {

            /** 取得更新游戏之前的时间 **/
            long startTime = System.currentTimeMillis();

            /** 在这里加上线程安全锁 **/
            synchronized (mSurfaceHolder) {
                /** 拿到当前画布 然后锁定 **/

                mCanvas = mSurfaceHolder.lockCanvas();

                Draw();
                /** 绘制结束后解锁显示在屏幕上 **/
                mSurfaceHolder.unlockCanvasAndPost(mCanvas);
            }

            /** 取得更新游戏结束的时间 **/
            long endTime = System.currentTimeMillis();

            /** 计算出游戏一次更新的毫秒数 **/
        int    diffTime = (int) (endTime - startTime);

            /** 确保每次更新时间为30帧 **/
            while (diffTime <= TIME_IN_FRAME) {
                diffTime = (int) (System.currentTimeMillis() - startTime);
                /** 线程等待 **/
                Thread.yield();
            }

        }

    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        //              onSensorChanged()方法中传入了一个 SensorEvent 参数,
//              这个参数里又包含了一个 values 数组,所有传感器输出的信息都是存放在这里的
//                //获取传感器的数据
        GZ=event.values[SensorManager.DATA_Z];
        GX=event.values[SensorManager.DATA_X];
        GY=event.values[SensorManager.DATA_Y];

//        g=  Math.sqrt(GX*GX+GY*GY+GZ*GZ);//重力加速度,约为9.8
//
//        AX= Math.acos((GX/g));
//        AY= Math.acos((GY/g));//大地垂直坐标系与设备Y轴之间的弧度
//        AZ= Math.acos((GZ/g));
////        Log.e(TAG,g+" "+AY+"  想要的Y弧度");
////        Log.d(TAG,g+" "+AX+"  X的弧度");
////        Log.d(TAG,g+" "+AZ+"  Z的弧度");
//        double shuzhi_chuizhi;
//        if(AY>Math.PI/2.0) {
//            shuzhi_chuizhi=(Math.PI / 2.0 )- (Math.PI - AY);
//            Log.d(TAG,shuzhi_chuizhi+"数值垂直夹角");
//            acceleation=g*Math.sin(shuzhi_chuizhi)*5;
//            Log.e(TAG,acceleation+"看一下加速度");
//
//
//
//
//        }else{
//            acceleation=g*Math.sin(AY)*5;
//            Log.e(TAG,acceleation+"看一下加速度");
//
//        }

       Log.d(TAG," "+GX+"  X轴上的重力加速度");
      Log.d(TAG," "+GY+" Y轴上的重力加速度 ");
        is_chujie=false;



        //检测小球是否超出边界
        if (mPosX <520) {

            is_chujie=true;


        } else if (mPosX > 1200) {

            is_chujie=true;


        }
        if (mPosY <=0 ) {
            mPosY = 0;
            is_chujie=true;


        } else if (mPosY > (mphoneScreenHeight-20)) {
            mPosY = mphoneScreenHeight;

            is_chujie=true;


        }







    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }
}



猜你喜欢

转载自blog.csdn.net/hrwy2920566283/article/details/80152786