Android之传感器小游戏

滚球小游戏–加速传感器的小应用

Android之传感器小游戏
一个通过传感器的简单小游戏(明白逻辑就好)
关于如何使用传感器的代码我就不细说了 上篇博文已经谈过 套路都是一样的
SensorManager创建对象引用->获取对象->获取传感器
->给传感器弄监听->注册监听(onResume)->取消监听(onPause)

一丶SurfaceView的实现

主要谈画面的绘制
Android之传感器小游戏
1.要想能够画出界面来 类必须继承SurfaceView
并且实现SurfaceHolder.Callback 生命周期回调接口

Android之传感器小游戏
1.十分重要 :在surface子类的构造器中需要传入一个参数 即Activity
2.由于前面实现了生命周期回调接口 所以在构造器中必须要实现该接口
3.加载图片 然后获取图片的高度 然后创建画笔 打开抗锯齿
4.创建两个线程 一个小球运动的线程 一个画面的线程

Android之传感器小游戏
下面开始画画了自定义的方法 onMyDraw(Canvas canvas) 调用此方法 传入参数Canvas(画布)
1.铺砖 canvas.drawBitmap(tableBM, tableBM.getWidth()*i, tableBM.getHeight()*j, paint);
四个参数->( 图片 坐标x 坐标y 画笔)

Android之传感器小游戏
Android之传感器小游戏
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();
			}
		}
	}
}