Android之传感器小游戏
滚球小游戏–加速传感器的小应用
一个通过传感器的简单小游戏(明白逻辑就好)
关于如何使用传感器的代码我就不细说了 上篇博文已经谈过 套路都是一样的
SensorManager创建对象引用->获取对象->获取传感器
->给传感器弄监听->注册监听(onResume)->取消监听(onPause)
一丶SurfaceView的实现
主要谈画面的绘制
1.要想能够画出界面来 类必须继承SurfaceView
并且实现SurfaceHolder.Callback 生命周期回调接口
1.十分重要 :在surface子类的构造器中需要传入一个参数 即Activity
2.由于前面实现了生命周期回调接口 所以在构造器中必须要实现该接口
3.加载图片 然后获取图片的高度 然后创建画笔 打开抗锯齿
4.创建两个线程 一个小球运动的线程 一个画面的线程
下面开始画画了自定义的方法 onMyDraw(Canvas canvas) 调用此方法 传入参数Canvas(画布)
1.铺砖 canvas.drawBitmap(tableBM, tableBM.getWidth()*i, tableBM.getHeight()*j, paint);
四个参数->( 图片 坐标x 坐标y 画笔)
1.使用三个surface的方法 分别对应 改变,创建,销毁
当创建的时候就调用其创建的方法 (传入了SurfaceHolder对象)
并用该对象获取画布
2.给SurfaceHolder对象加锁synchronized(holder) 保证安全
3.if(canvas != null){
holder.unlockCanvasAndPost(canvas);
} 然后当画布创建完的时候 解锁
4.启动两个线程
public class MyGameView extends SurfaceView
implements SurfaceHolder.Callback //实现生命周期回调接口
{
SensorBallActivity activity;
BallGoThread bgt;
GameViewDrawThread gvdt;
Paint paint;//画笔
Bitmap tableBM;
Bitmap ballBM;
int ballSize;//球的尺寸
float dLength=2.5f;//小球的运动速度系数
int ballX=100;//当前小球的X坐标
int ballY=80;//当前小球的Y坐标
int dx=0;//当前小球的运动速度X分量
int dy=0;//当前小球的运动速度Y分量
public MyGameView(SensorBallActivity activity) {
super(activity);
this.activity = activity;
this.getHolder().addCallback(this);//设置生命周期回调接口的实现者
//加载图片
tableBM=BitmapFactory.decodeResource(activity.getResources(), R.drawable.table);
ballBM=BitmapFactory.decodeResource(activity.getResources(), R.drawable.ball);
ballSize=ballBM.getHeight();
paint = new Paint();//创建画笔
paint.setAntiAlias(true);//打开抗锯齿
bgt=new BallGoThread(this);
gvdt=new GameViewDrawThread(this);
}
public void onMyDraw(Canvas canvas)
{
//贴底纹3x3
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
canvas.drawBitmap(tableBM, tableBM.getWidth()*i, tableBM.getHeight()*j, paint);
}
}
//贴球
canvas.drawBitmap(ballBM, ballX, ballY, paint);
}
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
}
public void surfaceCreated(SurfaceHolder holder) {//创建时被调用
Canvas canvas = holder.lockCanvas();//获取画布
try{
synchronized(holder){
onMyDraw(canvas);//绘制
}
}
catch(Exception e){
e.printStackTrace();
}
finally{
if(canvas != null){
holder.unlockCanvasAndPost(canvas);
}
}
//启动球定时根据重力移动的线程
bgt.start();
//启动定时重新绘制画面的线程
gvdt.start();
}
public void surfaceDestroyed(SurfaceHolder arg0) {//销毁时被调用
}
}
=====================================================================
下面一起来看两个线程的具体实现
二丶小球运动线程Thread的实现
具体来说
主要是获取了surface的子类
然后无限循环启用线程 设定每30ms线程sleep一次
获取的数据主要由surface子类提供 而surface子类的数据则是Activity中的传感器来获取的
//球定时根据重力移动的线程
public class BallGoThread extends Thread
{
MyGameView mgv;
boolean flag=true;
public BallGoThread(MyGameView mgv)
{
this.mgv=mgv;
}
public void run()
{
while(flag)
{
//计算球的新位置
int dx=mgv.dx;
int dy=mgv.dy;
mgv.ballX=mgv.ballX+dx;
mgv.ballY=mgv.ballY+dy;
//判断X方向是否碰壁,若碰壁则恢复
if(mgv.ballX<0||mgv.ballX>mgv.getWidth()-mgv.ballSize)
{
mgv.ballX=mgv.ballX-dx;
}
//判断Y方向是否碰壁,若碰壁则恢复
if(mgv.ballY<0||mgv.ballY>mgv.getHeight()-mgv.ballSize)
{
mgv.ballY=mgv.ballY-dy;
}
try
{
Thread.sleep(30);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
}