ホームへ戻る

s2.5 加速度センサーで自機を操作する


 本節では、先ほど作った自機を加速度センサーで操作出来るようにします。
Androidはx,y,z軸にわけて傾きを検知することができます。



端末をただ平坦な場所に置いているだけであれば、x=y=0, z=10となります。
左右に傾けるとxが、縦に引き起こしたりするとyが変化します。

この値を利用して自機を動かしてみましょう。

ではまず、加速度センサークラスを作ります。

↓AcSensor.java (新規追加)

public class AcSensor implements SensorEventListener {

        private SensorManager _sensorManager = null;
        private float _x, _y, _z;

        public void onCreate(Context c) {
                _sensorManager = (SensorManager) c.getSystemService(Context.SENSOR_SERVICE);//センサーマネージャを取得
                onResume();
        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
                //今回は使用しません。
        }

        //アクティビティが動き始めたらリスナーを登録する
        public void onResume() {
                List<Sensor> sensorList = _sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);//センサーリストを取得
                if (sensorList != null && !sensorList.isEmpty()) {
                        Sensor sensor = sensorList.get(0);
                        _sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_FASTEST);//リスナー登録
                }
        }

        //アクティビティがポーズになったらリスナーを止める
        public void onPause() {
                if( _sensorManager == null ){
                        return;
                }
                _sensorManager.unregisterListener(this);
        }

        //センサーの値に変化があった時呼ばれる
        public void onSensorChanged(SensorEvent event) {
                if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
                        _x = event.values[SensorManager.DATA_X]; // X軸
                        _y = event.values[SensorManager.DATA_Y]; // Y軸
                        _z = event.values[SensorManager.DATA_Z]; // Z軸
                }
        }
        
        public float getX(){
                return _x;
        }
        
        public float getY(){
                return _y;
        }
        
        public float getZ(){
                return _z;
        }

        //シングルトン
        private static AcSensor _instance = new AcSensor();
        private AcSensor() {
                _x = _y = _z = 0;
        }
        public static AcSensor Inst() {
                return _instance;
        }
}

特に覚える必要はないので、流してもらえたらいいのですが、生成時に、まずマネージャークラスを取得します。
このクラスは「SensorEventListener」を implements しているので、センサーの変化があった時コールバック式で情報が通知されます。
リスナーへの登録は、onResume() で行っています。
リスナーを登録すると、センサーの情報に変化があったらonSensorChanged()が呼ばれるようになります。
取得の方法は記述通りです。

アクティビティはオフになったりオンになったりします。
オフになったらリスナーもオフに、オンになったら改めてリスナーをオンにするようにコーディングしています。

自機クラスからこの値を参照してみましょう
↓Player.java
(一部変更 
赤字部)
public class Player extends Task {
        private final static float SIZE = 20;           //自機の大きさ
        private Circle _cir = null;             //自機の円
        private Paint _paint = new Paint();     //描画設定
        private Vec _vec = new Vec();           //自機の移動ベクトル
        
        public Player(){
                _cir = new Circle( 240, 0, SIZE );      //(240,0)の位置にSIZEの大きさの円を作る
                _paint.setColor(Color.BLUE);            //色を青に設定
                _paint.setAntiAlias(true);              //エイリアスをオン
                _vec._y = 2;                            //移動ベクトルを下に向ける
        }

        @Override
        public boolean onUpdate(){
                
                _vec._x = -AcSensor.Inst().getX();      //加速度センサーの情報を取得
                _vec._y =  AcSensor.Inst().getY();
                
                _cir._x += _vec._x;     //移動ベクトル_vecが指す方向に移動させる 
                _cir._y += _vec._y;

                return true;
        }

        @Override
        public void onDraw( Canvas c ){
                c.drawCircle(_cir._x, _cir._y, _cir._r, _paint);
        }

}

取得した値をそのまま移動ベクトルに代入しているだけです。
x方向は感覚と逆なので方向を逆にしています。

Activityがオフになったらセンサーを止め、オンになったら動かすため、Activityのイベントに応じてメソッドをコールします。
↓IrairaBarActivity.java
 (一部変更 
赤字部
public class IrairaBarActivity extends Activity {
        @Override
        public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(new GameSurfaceView(this));

                AcSensor.Inst().onCreate(this); // センサー初期化
        }

        @Override
        protected void onResume() { // アクティビティが動き始める時呼ばれる
                super.onResume();
                AcSensor.Inst().onResume();// 開始時にセンサーを動かし始める
        }

        @Override
        protected void onPause() { // アクティビティの動きが止まる時呼ばれる
                super.onPause();
                AcSensor.Inst().onPause();// 中断時にセンサーを止める
        }
}


それでは実行してみて下さい。

実行結果


傾けた向きに応じて円が移動すれば成功です。

この章のプロジェクトをダウンロード

→分からないことがあれば掲示板で質問して下さい


Portions of this page are modifications based on work created and shared by Google and used according to terms described in the Creative Commons 3.0 Attribution License.

- Remical Soft -