很久沒更新博客了,今天來談談android小遊戲———重力感應,通常在遊戲裏運用的比較多,比方這類遊戲有:神廟逃亡。極品飛車,平衡球。三圍重力迷宮,重力賽車等。css
首先什麼是重力感應。重力感應是指現在手機中常常使用的一個器件,及加速度傳感器。html
當手機精巧時。加速度就是重力。因此通常也叫作重力傳感器。這個硬件可以感應加速度的變化,轉化爲數據提供給系統。另外一種傳感器是陀螺儀,檢測環繞某軸的旋轉動做,是利用有質量的剛體的在作旋轉或震動時,假設發生垂直於旋轉或震動軸的旋轉,因爲慣性會產生垂直於旋轉或震動軸的柯氏力(G-sensor是加速度力)。陀螺儀必然會分x。y。z軸。二者的差異是前者,內部的測量對象是加速度力。後者,內部測量柯氏力。前者告訴你物體動沒動,往哪一個方向動了?後者告訴你動起來的物體轉了嗎?怎麼轉的,轉了多少度? 多軸的的G-Sensor也可以檢測到物體切向於豎直方向的轉動。但角度推斷起來很是困難。java
那麼手機重力感應的原理是什麼?(如下)android
——經過對力敏感的傳感器。感覺手機在變換姿式時,重心的變化。使手機光標變化位置從而實現選擇的功能。 手機重力感應技術:利用壓電效應實現,簡單來講是是測量內部一片重物(重物和壓電片作成一體)重力正交兩個方向的分力大小,來斷定水平方向。 手機重力感應指的是手機內置重力搖桿芯片。支持搖晃切換所需的界面和功能,甩歌甩屏,翻轉靜音,甩動切換視頻等,是一種很是具備使用樂趣的功能。安全
如下看一個簡單的小遊戲(範例)效果圖:APK下載地址:http://download.csdn.net/detail/liuyang1990i/7448211app
代碼例如如下:(下爲部分Java代碼)ide
startActivity.java文件
函數
package cn.m15.xys;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class startActivity extends Activity {
Context mContext = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mContext = this;
/**進入遊戲世界 - 小球移動**/
Button botton0 = (Button)findViewById(R.id.button0);
botton0.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Intent intent = new Intent(mContext,SurfaceViewAcitvity.class);
startActivity(intent);
}
});
}
}
post
SurfaceViewAcitvity.java文件
this
package cn.m15.xys; import android.app.Activity; import android.content.Context; import android.content.pm.ActivityInfo; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.Bundle; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.Window; import android.view.WindowManager; import android.view.SurfaceHolder.Callback; public class SurfaceViewAcitvity extends Activity { MyView mAnimView = null; @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);// 顯示本身定義的遊戲ViewmAnimView = new MyView(this);setContentView(mAnimView); } public class MyView extends SurfaceView implements Callback,Runnable ,SensorEventListener{/**每50幀刷新一次屏幕**/ 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;/**小球的座標位置**/private float mPosX = 200;private float mPosY = 0;/**重力感應X軸 Y軸 Z軸的重力值**/private float mGX = 0;private float mGY = 0;private float mGZ = 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); /**獲得Sens * orManager對象**/ mSensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE); mSensor = mSensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); // 註冊listener,第三個參數是檢測的準確度 //SENSOR_DELAY_FASTEST 最靈敏 因爲太快了不是必需使用 //SENSOR_DELAY_GAME 遊戲開發中使用 //SENSOR_DELAY_NORMAL 正常速度 //SENSOR_DELAY_UI 最慢的速度 mSensorMgr.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_GAME); } private void Draw() { /**繪製遊戲背景**/ mCanvas.drawBitmap(mbitmapBg,0,0, mPaint); /**繪製小球**/ mCanvas.drawBitmap(mbitmapBall, mPosX,mPosY, mPaint); /**X軸 Y軸 Z軸的重力值**/ mCanvas.drawText("X軸重力值 :" + mGX, 0, 20, mPaint); mCanvas.drawText("Y軸重力值 :" + mGY, 0, 40, mPaint); mCanvas.drawText("Z軸重力值 :" + mGZ, 0, 60, mPaint);}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {}@Overridepublic void surfaceCreated(SurfaceHolder holder) { /**開始遊戲主循環線程**/ mIsRunning = true; new Thread(this).start(); /**獲得當前屏幕寬高**/ mScreenWidth = this.getWidth(); mScreenHeight = this.getHeight(); /**獲得小球越界區域**/ mScreenBallWidth = mScreenWidth - mbitmapBall.getWidth(); mScreenBallHeight = mScreenHeight - mbitmapBall.getHeight();}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) { mIsRunning = false;}@Overridepublic void run() { while (mIsRunning) {/** 取得更新遊戲以前的時間 **/long startTime = System.currentTimeMillis();/** 在這裏加上線程安全鎖 **/synchronized (mSurfaceHolder) { /** 拿到當前畫布 而後鎖定 **/ mCanvas = mSurfaceHolder.lockCanvas(); Draw(); /** 繪製結束後解鎖顯示在屏幕上 **/ mSurfaceHolder.unlockCanvasAndPost(mCanvas);}/** 取得更新遊戲結束的時間 **/long endTime = System.currentTimeMillis();/** 計算出遊戲一次更新的毫秒數 **/int diffTime = (int) (endTime - startTime);/** 確保每次更新時間爲50幀 **/while (diffTime <= TIME_IN_FRAME) { diffTime = (int) (System.currentTimeMillis() - startTime); /** 線程等待 **/ Thread.yield();} }} @Overridepublic void onAccuracyChanged(Sensor arg0, int arg1) { // TODO Auto-generated method stub }@Overridepublic void onSensorChanged(SensorEvent event) { mGX = event.values[SensorManager.DATA_X]; mGY= event.values[SensorManager.DATA_Y]; mGZ = event.values[SensorManager.DATA_Z]; //這裏乘以2是爲了讓小球移動的更快 mPosX -= mGX * 2; mPosY += mGY * 2; //檢測小球是否超出邊界 if (mPosX < 0) {mPosX = 0; } else if (mPosX > mScreenBallWidth) {mPosX = mScreenBallWidth; } if (mPosY < 0) {mPosY = 0; } else if (mPosY > mScreenBallHeight) {mPosY = mScreenBallHeight; }} } }