1. 程式人生 > >Android之感測器小遊戲

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