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