Android 重力傳感器在游戲開發(fā)中的應(yīng)用
手勢操作可以說是智能手機(jī)的一種魅力所在,前兩節(jié)給大家講解了兩種有趣的手勢操作,將它們置于游戲當(dāng)中,大大提升了游戲的可玩性和趣味性。本節(jié)將繼續(xù)介紹智能手機(jī)的另一種神奇之處:傳感器。
一、何為傳感器
所謂傳感器就是能夠探測如光、熱、溫度、重力、方向等等的裝置。
二、Android提供了哪些傳感器
1、加速度傳感器(重力傳感器)
2、陀螺儀傳感器
3、光傳感器
4、恒定磁場傳感器
5、方向傳感器
6、恒定的壓力傳感器
7、接近傳感器
8、溫度傳感器
今天我們給大家介紹的是游戲開發(fā)中最最常見的,用到的頻率最高的一種傳感--加速度傳感器(重力傳感器)!
三、傳感器實(shí)例講解
因?yàn)槟M器無法測試,所以我用手機(jī)調(diào)試的,先上兩張截圖:

下面貼代碼:
Java代碼
/**
*@author Himi
*@Sensor 加速度傳感器 ,也稱為重力傳感器
*@SDK 1.5(api 3)就支持傳感器了
*@解釋:此傳感器不僅對(duì)玩家反轉(zhuǎn)手機(jī)的動(dòng)作可以檢測到,而且會(huì)根據(jù)反轉(zhuǎn)手機(jī)的程度,得到傳感器的值也會(huì)不同!
*/
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);
//通過服務(wù)得到傳感器管理對(duì)象
sm = (SensorManager) MainActivity.ma.getSystemService(Service.SENSOR_SERVICE);
sensor = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);//得到一個(gè)重力傳感器實(shí)例
//TYPE_ACCELEROMETER 加速度傳感器(重力傳感器)類型。
//TYPE_ALL 描述所有類型的傳感器。
//TYPE_GYROSCOPE 陀螺儀傳感器類型
//TYPE_LIGHT 光傳感器類型
//TYPE_MAGNETIC_FIELD 恒定磁場傳感器類型。
//TYPE_ORIENTATION 方向傳感器類型。
//TYPE_PRESSURE 描述一個(gè)恒定的壓力傳感器類型
//TYPE_PROXIMITY 常量描述型接近傳感器
//TYPE_TEMPERATURE 溫度傳感器類型描述
mySensorListener = new SensorEventListener() {
@Override
//傳感器獲取值發(fā)生改變時(shí)在響應(yīng)此函數(shù)
public void onSensorChanged(SensorEvent event) {//備注1
//傳感器獲取值發(fā)生改變,在此處理
x = event.values[0]; //手機(jī)橫向翻滾
//x>0 說明當(dāng)前手機(jī)左翻 x<0右翻
y = event.values[1]; //手機(jī)縱向翻滾
//y>0 說明當(dāng)前手機(jī)下翻 y<0上翻
z = event.values[2]; //屏幕的朝向
//z>0 手機(jī)屏幕朝上 z<0 手機(jī)屏幕朝下
arc_x -= x;//備注2
arc_y += y;
}
@Override
//傳感器的精度發(fā)生改變時(shí)響應(yīng)此函數(shù)
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
};
sm.registerListener(mySensorListener, sensor, SensorManager.SENSOR_DELAY_GAME);
//第一個(gè)參數(shù)是傳感器監(jiān)聽器,第二個(gè)是需要監(jiān)聽的傳感實(shí)例
//最后一個(gè)參數(shù)是監(jiān)聽的傳感器速率類型: 一共一下四種形式
//SENSOR_DELAY_NORMAL 正常
//SENSOR_DELAY_UI 適合界面
//SENSOR_DELAY_GAME 適合游戲 (我們必須選這個(gè)呀 哇哈哈~)
//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("當(dāng)前重力傳感器的值:", 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 += "當(dāng)前手機(jī)處于水平放置的狀態(tài)";
if (z > 0) {
temp_str2 += "并且屏幕朝上";
} else {
temp_str2 += "并且屏幕朝下,提示別躺著玩手機(jī),對(duì)眼睛不好喲~";
}
} else {
if (x > 1) {
temp_str2 += "當(dāng)前手機(jī)處于向左翻的狀態(tài)";
} else if (x < -1) {
temp_str2 += "當(dāng)前手機(jī)處于向右翻的狀態(tài)";
}
if (y > 1) {
temp_str2 += "當(dāng)前手機(jī)處于向下翻的狀態(tài)";
} else if (y < -1) {
temp_str2 += "當(dāng)前手機(jī)處于向上翻的狀態(tài)";
}
if (z > 0) {
temp_str3 += "并且屏幕朝上";
} else {
temp_str3 += "并且屏幕朝下,提示別躺著玩手機(jī),對(duì)眼睛不好喲~";
}
}
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對(duì)象,包含Sensor的最新數(shù)據(jù),通過event.values獲得一個(gè)float[]數(shù)組!對(duì)于不同的傳感器類型,其數(shù)組包含的元素個(gè)數(shù)是不同的,重力傳感器總是返回一個(gè)長度為3的數(shù)組,分別代表X、Y和Z方向的數(shù)值。Z軸表示了手機(jī)是屏幕朝上還是屏幕朝下。
這里還要注意你當(dāng)前手機(jī)處于縱向還是橫向,因?yàn)檫@個(gè)會(huì)影響我們的X,Y表示的意義!
如果當(dāng)前手機(jī)是縱向屏幕:
x>0 說明當(dāng)前手機(jī)左翻 x<0右翻;
y>0 說明當(dāng)前手機(jī)下翻 y<0上翻。
如果當(dāng)前手機(jī)是橫向屏幕:
x>0 說明當(dāng)前手機(jī)下翻 x<0上翻;
y>0 說明當(dāng)前手機(jī)右翻 y<0左翻。
我要提醒各位童鞋:
1、要考慮玩家當(dāng)前拿手機(jī)的姿勢,例如豎屏,橫屏。
2、根據(jù)橫豎屏幕的不同,雖然屏幕坐標(biāo)系會(huì)自動(dòng)改變,但是傳感器的值不會(huì)自動(dòng)改變坐標(biāo)系!所以為什么會(huì)橫屏豎屏改變的時(shí)候我們從傳感器中取出的值表示的動(dòng)作不一樣的原因!因此大家游戲開發(fā)的時(shí)候?qū)τ谌宋镆苿?dòng)、圖片移動(dòng)等等操作的時(shí)候,手勢X,Y的正負(fù)值代表什么一定要想清楚!否則玩家會(huì)玩著玩著吐的 (太暈了!)- -、
備注2:
這里本應(yīng)該arc_x+=x;但是因?yàn)楫?dāng)前我屏幕是縱向!造成x>0的手勢表示玩家將手機(jī)左翻了,但是我們屏幕的圓形應(yīng)該根據(jù)人的反轉(zhuǎn)相對(duì)應(yīng)的移動(dòng),那么這里玩家將手機(jī)左翻,我們就應(yīng)該讓原型的X坐標(biāo)減少!所以這里寫成了arc_x-=x;。
總結(jié)
雖然本節(jié)只講了重力傳感器這一種,但已經(jīng)足夠了,因?yàn)槿绻阆胧褂闷渌膫鞲衅?,只要按以下步驟操作就可以:
1、利用 SensorManager.getDefaultSensor();傳入一個(gè)你想要的傳感器的參數(shù)得到其實(shí)例;
2、注冊(cè);
3、在監(jiān)聽器里處理事件。
其實(shí)并不難,你也可以讓自己的游戲有各種感應(yīng)效果了。
以上就對(duì)Android 重力傳感器的資料整理,后續(xù)繼續(xù)補(bǔ)充相關(guān)知識(shí),謝謝大家對(duì)本站的支持!
相關(guān)文章
Android實(shí)現(xiàn)常見的驗(yàn)證碼輸入框?qū)嵗a
我們?cè)陂_發(fā)APP的時(shí)候經(jīng)常要遇到輸入框,下面這篇文章主要給大家介紹了關(guān)于利用Android如何實(shí)現(xiàn)常見的驗(yàn)證碼輸入框的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)下吧。2017-09-09
Android通過Service實(shí)現(xiàn)簡單的音樂播放
這篇文章主要介紹了Android通過Service實(shí)現(xiàn)簡單的音樂播放,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-05-05
Android開發(fā)之關(guān)于項(xiàng)目
本文是此系列文章的第二篇,給大家介紹的是項(xiàng)目相關(guān)的內(nèi)容,非常的細(xì)致全面,有需要的小伙伴可以參考下2016-02-02
AndroidStduio3.0 使用gradle將module打包jar文件的方法
這篇文章主要介紹了AndroidStduio3.0 使用gradle將module打包jar文件的方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-04-04
基于GridView和ActivityGroup實(shí)現(xiàn)的TAB分頁(附源碼)
今天為大家介紹下使用GridView和ActivityGroup實(shí)現(xiàn)的分頁,這里需要將Activity轉(zhuǎn)換成Window,然后再換成成View添加到容器中,具體實(shí)現(xiàn)代碼如下,感興趣的朋友可以參考下哈2013-06-06
Android?Flutter中Offstage組件的使用教程詳解
這篇文章主要為大家詳細(xì)介紹了Android?Flutter中Offstage組件的使用教程,文中的示例代碼講解詳細(xì),對(duì)我們了解Flutter有一定的幫助,需要的可以參考一下2023-02-02
Android 7.0 手電筒控制實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了Android 7.0 手電筒控制實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09
Android中DrawerLayout+ViewPager滑動(dòng)沖突的解決方法
這篇文章主要為大家詳細(xì)介紹了Android中DrawerLayout+ViewPager滑動(dòng)沖突的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06
Android實(shí)現(xiàn)退出界面彈出提示對(duì)話框
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)退出界面彈出提示對(duì)話框,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12

