【Android遊戲開發十八】解放手指,利用傳感器開發遊戲!(本文講解在SurfaceView中用重力傳感器控制圓球的各方向移動)

 李華明Himi 原創,轉載務必在明顯處註明:
轉載自 【黑米GameDev街區】 原文連接:  http://www.himigame.com/android-game/344.html

 

不少童鞋說個人代碼運行後,點擊home或者back後會程序異常,若是你也這樣遇到過,那麼你確定沒有仔細讀完Himi的博文,第十九篇Himi專門寫了關於這些錯誤的緣由和解決方法,這裏我在博客都補充說明下,省的童鞋們總疑惑這一塊;請點擊下面聯繫進入閱讀:css

【Android遊戲開發十九】(必看篇)SurfaceView運行機制詳解—剖析Back與Home按鍵及切入後臺等異常處理!html


       前兩篇都是向你們介紹了頗有意思的兩種手勢操做,嵌入咱們遊戲中,不得不說讓遊戲的自由度、可玩性和趣味性都增色很多!那麼今天繼續給你們介紹一亮點!傳感器java

 

一:什麼是傳感器:android

     所謂傳感器可以探測如光、熱、溫度、重力、方向 等等的功能!canvas

 

二:Android中提供傳感器有哪些:api

     1.  加速度傳感器(重力傳感器)數組

     2.  陀螺儀傳感器ide

     3.  光傳感器函數

     5.  恆定磁場傳感器測試

     6.  方向傳感器

     7.  恆定的壓力傳感器

     8.  接近傳感器

     9.  溫度傳感器

 

今天咱們給你們介紹的是遊戲開發中最最多見的,用到的頻率最高的一種傳感器,加速度傳感器(重力傳感器)!


由於模擬器沒法測試,因此我用手機調試的~,先上兩張截圖;


         

 

/**
 *@author Himi
 *@Sensor 加速度傳感器 ,也稱爲重力傳感器 
 *@SDK 1.5(api 3)就支持傳感器了
 *@解釋:此傳感器不只對玩家反轉手機的動做能夠檢測到,並且會根據反轉手機的程度,獲得傳感器的值也會不一樣!
 */
public class MySurfaceView extends SurfaceView implements Callback, Runnable {
	private Thread th = new Thread(this);
	private SurfaceHolder sfh;
	private Canvas canvas;
	private Paint paint;
	private SensorManager sm;
	private Sensor sensor;
	private SensorEventListener mySensorListener;
	private int arc_x, arc_y;// 圓形的x,y位置
	private float x = 0, y = 0, z = 0;
	public MySurfaceView(Context context) {
		super(context);
		this.setKeepScreenOn(true);
		sfh = this.getHolder();
		sfh.addCallback(this);
		paint = new Paint();
		paint.setAntiAlias(true);
		setFocusable(true);
		setFocusableInTouchMode(true);
		//經過服務獲得傳感器管理對象 
		sm = (SensorManager) MainActivity.ma.getSystemService(Service.SENSOR_SERVICE);
		sensor = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);//獲得一個重力傳感器實例
		//TYPE_ACCELEROMETER    加速度傳感器(重力傳感器)類型。
		//TYPE_ALL              描述全部類型的傳感器。
		//TYPE_GYROSCOPE        陀螺儀傳感器類型
		//TYPE_LIGHT            光傳感器類型
		//TYPE_MAGNETIC_FIELD   恆定磁場傳感器類型。
		//TYPE_ORIENTATION      方向傳感器類型。
		//TYPE_PRESSURE         描述一個恆定的壓力傳感器類型
		//TYPE_PROXIMITY        常量描述型接近傳感器
		//TYPE_TEMPERATURE      溫度傳感器類型描述
		mySensorListener = new SensorEventListener() {
			@Override
			//傳感器獲取值發生改變時在響應此函數
			public void onSensorChanged(SensorEvent event) {//備註1 
				//傳感器獲取值發生改變,在此處理 
				x = event.values[0]; //手機橫向翻滾
				//x>0 說明當前手機左翻 x<0右翻     
				y = event.values[1]; //手機縱向翻滾
				//y>0 說明當前手機下翻 y<0上翻
				z = event.values[2]; //屏幕的朝向
				//z>0 手機屏幕朝上 z<0 手機屏幕朝下
				arc_x -= x;//備註2
				arc_y += y;
			}
			@Override
			//傳感器的精度發生改變時響應此函數
			public void onAccuracyChanged(Sensor sensor, int accuracy) {
				// TODO Auto-generated method stub
			}
		};
		sm.registerListener(mySensorListener, sensor, SensorManager.SENSOR_DELAY_GAME);
		//第一個參數是傳感器監聽器,第二個是須要監聽的傳感實例
		//最後一個參數是監聽的傳感器速率類型: 一共一下四種形式
		//SENSOR_DELAY_NORMAL  正常
		//SENSOR_DELAY_UI  適合界面
		//SENSOR_DELAY_GAME  適合遊戲  (咱們必須選這個呀 哇哈哈~)
		//SENSOR_DELAY_FASTEST  最快
	}
	public void surfaceCreated(SurfaceHolder holder) {
		arc_x = this.getWidth() / 2 - 25;
		arc_y = this.getHeight() / 2 - 25;
		th.start();
	}
	public void draw() {
		try {
			canvas = sfh.lockCanvas();
			if (canvas != null) {
				canvas.drawColor(Color.BLACK);
				paint.setColor(Color.RED);
				canvas.drawArc(new RectF(arc_x, arc_y, arc_x + 50,
						arc_y + 50), 0, 360, true, paint);
				paint.setColor(Color.YELLOW);
				canvas.drawText("當前重力傳感器的值:", arc_x - 50, arc_y-30, paint);
				canvas.drawText("x=" + x + ",y=" + y + ",z=" + z,
						arc_x - 50, arc_y, paint);
				String temp_str = "Himi提示: ";
				String temp_str2 = "";
				String temp_str3 = "";
				if (x < 1 && x > -1 && y < 1 && y > -1) {
					temp_str += "當前手機處於水平放置的狀態";
					if (z > 0) {
						temp_str2 += "而且屏幕朝上";
					} else {
						temp_str2 += "而且屏幕朝下,提示別躺着玩手機,對眼睛很差喲~";
					}
				} else {
					if (x > 1) {
						temp_str2 += "當前手機處於向左翻的狀態";
					} else if (x < -1) {
						temp_str2 += "當前手機處於向右翻的狀態";
					}
					if (y > 1) {
						temp_str2 += "當前手機處於向下翻的狀態";
					} else if (y < -1) {
						temp_str2 += "當前手機處於向上翻的狀態";
					}
					if (z > 0) {
						temp_str3 += "而且屏幕朝上";
					} else {
						temp_str3 += "而且屏幕朝下,提示別躺着玩手機,對眼睛很差喲~";
					}
				}
				paint.setTextSize(20);
				canvas.drawText(temp_str, 0, 50, paint);
				canvas.drawText(temp_str2, 0, 80, paint);
				canvas.drawText(temp_str3, 0, 110, paint);
			}
		} catch (Exception e) {
			Log.v("Himi", "draw is Error!");
		} finally {
			sfh.unlockCanvasAndPost(canvas);
		}
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while (true) {
			draw();
			try {
				Thread.sleep(100);
			} catch (Exception ex) {
			}
		}
	}
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
	}
	public void surfaceDestroyed(SurfaceHolder holder) {
	}
}
 

 

 

 

備註1:

      SensorEventListener的onSensorChanged事件將返回SensorEvent對象,包含Sensor的最新數據,經過event.values得到一個float[]數組!對於不一樣的傳感器類型,其數組包含的元素個數是不一樣的,重力傳感器老是返回一個長度爲3的數組,分別表明X、Y和Z方向的數值。Z軸表示了手機是屏幕朝上仍是屏幕朝下;

 

這裏還要注意你當前手機處於 縱向, 仍是橫向,由於這個會影響咱們的X,Y表示的意思!

     若是當前手機是縱向屏幕:  

              x>0 說明當前手機左翻 x<0右翻     

              y>0 說明當前手機下翻 y<0上翻 

     若是當前手機是橫向屏幕: 

             x>0 說明當前手機下翻 x<0上翻     

             y>0 說明當前手機右翻 y<0左翻  

 

我要提醒各位童鞋:

     1.要考慮玩家當前拿手機的姿式,例如豎屏,橫屏

      2.根據橫豎屏幕的不一樣,雖然屏幕座標系會自動改變,可是傳感器的值不會自動改變座標系!因此爲何會橫屏豎屏改變的時候咱們從傳感器中取出的值表示的動做不同的緣由!!!所以你們遊戲開發的時候對於人物移動、圖片移動等等操做的時候,手勢X,Y的正負值表明什麼必定要想清楚!不然玩家會玩着玩着吐的 (太暈了!)- -、

 

備註2 :

      這裏本應該arc_x+=x;可是由於當前我屏幕是縱向!形成x>0的手勢表示玩家將手機左翻了,可是咱們屏幕的圓形應該根據人的反轉相對應的移動,那麼這裏玩家將手機左翻,咱們就應該讓原型的X座標減小!因此這裏寫成了arc_x-=x;!

 

 

總結一下: 對於傳感器的雖然本章只是講了一個重力傳感器,可是一個足夠了,由於若是你想使用其餘的傳感器,那麼你只要如下步驟就OK:

1. 利用 SensorManager.getDefaultSensor();傳入一個你想要的傳感器的參數獲得其實例!

2.註冊!

3.在監聽器裏處理事件!

OK!就是這麼簡單、 

 

                                                           

源碼下載地址http://www.himigame.com/android-game/344.html

 

 



原文連接: http://blog.csdn.net/xiaominghimi/article/details/6143520
相關文章
相關標籤/搜索