安卓重力小球demo
要过年了,最近在公司也没事。于是就在研究android的一些SDK。看到sensor时,突然想到大学里面刚出现android的时候,还没有钱买android手机,那时候想要是有个android手机能测试什么的岂不是很牛逼啊。记得那时候同学有款重力小球的游戏。
今天就开发了一款简单的demo重力小球。在网上也借鉴了一些别人的代码。测试是用的我爸以前的联想200元安卓机,但运行起来还是比较流畅的,所以就把帧数定在30帧。
运行画面
之后增加个碰撞时速度的检测,有没有发现游戏也就这样不难的
开始正题
首先在activity中定义我的MyView显示:
@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);
}
然后定义Myview:
@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{
/**TIME_IN_FRAME帧刷新一次屏幕*/
public static final int TIME_IN_FRAME = 30;
/** 游戏画笔 **/
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;
/**重力感应X,Y轴的重力*/
private float mGX = 0;
private float mGY = 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);
/**获得震动服务**/
vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
/**得到SensorManager对象**/
// 注册listener,第三个参数是检测的精确
//SENSOR_DELAY_FASTEST 太快了没必要使用
//SENSOR_DELAY_GAME 游戏中使用 //SENSOR_DELAY_NORMAL 正常速度
//SENSOR_DELAY_UI 延迟
mSensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
mSensor = mSensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorMgr.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_GAME);
}
public class MyView extends SurfaceView implements Callback,Runnable ,SensorEventListener{
/**TIME_IN_FRAME帧刷新一次屏幕*/
public static final int TIME_IN_FRAME = 30;
/** 游戏画笔 **/
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;
/**重力感应X,Y轴的重力*/
private float mGX = 0;
private float mGY = 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);
/**获得震动服务**/
vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
/**得到SensorManager对象**/
// 注册listener,第三个参数是检测的精确
//SENSOR_DELAY_FASTEST 太快了没必要使用
//SENSOR_DELAY_GAME 游戏中使用 //SENSOR_DELAY_NORMAL 正常速度
//SENSOR_DELAY_UI 延迟
mSensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
mSensor = mSensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorMgr.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_GAME);
}
最重要的是监听sensor事件:
@Override
public void onSensorChanged(SensorEvent event) {
mGX = Kg*event.values[SensorManager.DATA_Y];
mGY= Kg*event.values[SensorManager.DATA_X];
}
以及onDraw方法:
private void Draw() {
/**绘制游戏背景**/
mCanvas.drawBitmap(mbitmapBg,0,0, mPaint);
/**获取速度方向**/
Dx=getOrientation(Vx);
Dy=getOrientation(Vy);
/**获取合加速度 **/
float Ax=(float) (mGX-Dx*Kf*Math.pow(Vx, 2));
float Ay=(float) (mGY-Dy*Kf*Math.pow(Vy, 2));
/**获取速度**/
Vx=(float) (Vx+Ax*0.02);
Vy=(float) (Vy+Ay*0.02);
/**获取位移**/
Sx=(float) (Sx+Vx);
Sy=(float) (Sy+Vy);
//判断小球是否超出边界
if (Sx < 0) {
Sx = 0;
Vx=impactSpeed(Vx);
} else if (Sx > mScreenBallWidth) {
Sx = mScreenBallWidth;
Vx=impactSpeed(Vx);
}
if (Sy < 0) {
Sy= 0;
Vy=impactSpeed(Vy);
} else if (Sy > mScreenBallHeight) {
Sy = mScreenBallHeight;
Vy=impactSpeed(Vy);
}
/**绘制小球**/
mCanvas.drawBitmap(mbitmapBall, Sx,Sy, mPaint);
mCanvas.drawText("Gx "+ mGX, 0, 20, mPaint);
mCanvas.drawText("Gy "+ mGY, 0, 40, mPaint);
mCanvas.drawText("Vx " + Vx, 100, 20, mPaint);
mCanvas.drawText("Vy " + Vy, 100, 40, mPaint);
mCanvas.drawText("Sx " + Sx, 200, 20, mPaint);
mCanvas.drawText("Sy " + Sy, 200, 40, mPaint);
}
最后附上我的代码:下载地址