Google Androidのタッチセンサーと方位センサーを組み合わせたコードを書いたみた

今日も、ベローチェで一人もくもく会

前に書いたタッチセンサーと方位センサーを組み合わせて、図形をタッチと傾斜で動かすコードを書いた。図形(円)は、内部を押下しはじめたときだけ、動かせるようにしている。ただ、傾斜の移動量は前回同様、加速度を考慮していないので、動きがぎこちない。加速度はどう扱えばいいのだろう?

ソースコードは長くなってしまった。分割の仕方を身につけたい。
長いので、コードは以下の続きから。↓

package com.example.android.movecircle;

import java.util.List;

import android.app.Activity;
import android.content.Context;
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.MotionEvent;
import android.view.View;

public class MoveCircle extends Activity implements SensorEventListener {
    TouchView touchView;
	private Sensor orientationSensor;
	private Sensor accelerometerSensor;
	private MyCircle myCircle = new MyCircle();
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        touchView = new TouchView(this);
        setContentView(touchView);
        
        SensorManager sm = (SensorManager)getSystemService(SENSOR_SERVICE);
        List<Sensor> sensorList;
        sensorList = sm.getSensorList(Sensor.TYPE_ORIENTATION);
        orientationSensor = sensorList.get(0);
        sensorList = sm.getSensorList(Sensor.TYPE_ACCELEROMETER);
        accelerometerSensor = sensorList.get(0);
        
        sm.registerListener(this, orientationSensor, SensorManager.SENSOR_DELAY_NORMAL);
        sm.registerListener(this, accelerometerSensor, SensorManager.SENSOR_DELAY_NORMAL);
    }
    
    public void onSensorChanged(SensorEvent event) {
		if (event.sensor == orientationSensor) {
			final int DELTA = 7;
			final int ALLOWANCE = 10;
			int x = myCircle.getX();
			int y = myCircle.getY();
			
			if (event.values[2] < ALLOWANCE*-1) {
				x += DELTA;
			}
			else if (event.values[2] > ALLOWANCE) {
				x -= DELTA;
			}

			if (event.values[1] < ALLOWANCE*-1) {
				y += DELTA;
			}
			else if (event.values[1] > ALLOWANCE) {
				y -= DELTA;
			}
			myCircle.moveTo(x, y);
			touchView.invalidate();
		}
		else if (event.sensor == accelerometerSensor) {
		}
    }
    
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
    }
}

class TouchView extends View {
	private int touchX = 0;
	private int touchY = 0;
	private int touchAction;
	private MyCircle myCircle = new MyCircle();
	
	public TouchView(Context context) {
		super(context);
		setFocusable(true);
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		touchX = (int)event.getX();
		touchY = (int)event.getY();
		touchAction = (int)event.getAction();
		
		if ( myCircle.isInnerCircle(touchX, touchY) == true ) {
			if (touchAction == MotionEvent.ACTION_MOVE) {
				myCircle.moveTo(touchX, touchY);
			}
		}
		invalidate();
		return true;
	}
	
	@Override
	protected void onDraw(Canvas canvas) {
		final int TEXT_SIZE = 16;
		
		Paint paint = new Paint();
		paint.setAntiAlias(true);
		paint.setTextSize(TEXT_SIZE);
		paint.setColor(0xFFFFFFFF);
		
		// draw touch position
		canvas.drawText("Touch (x,y) = ("+touchX+","+touchY+")", 0, TEXT_SIZE, paint);
		
		// draw touch action
		String action = "NONE";
		if (touchAction == MotionEvent.ACTION_UP) {
			action = "ACTION_UP";
		}
		else if (touchAction == MotionEvent.ACTION_DOWN) {
			action = "ACTION_DOWN";
		}
		else if (touchAction == MotionEvent.ACTION_MOVE) {
			action = "ACTION_MOVE";
		}
		else if (touchAction == MotionEvent.ACTION_CANCEL) {
			action = "ACTION_CANCEL";
		}
		canvas.drawText("Touch Action : "+action, 0, TEXT_SIZE*2, paint);
		
		// draw circle
		canvas.drawText("Circle (x,y) = ("+myCircle.getX()+","+myCircle.getY()+")", 0, TEXT_SIZE*3, paint);
		paint.setStyle(Paint.Style.FILL_AND_STROKE);
		paint.setColor(myCircle.getColor());
		canvas.drawCircle(myCircle.getX(), myCircle.getY(), myCircle.getR(), paint);
	}
}

class MyCircle {
	private static int circleX;
	private static int circleY;
	private static int circleR;
	private static int circleColor;
	
	MyCircle() {
		circleX = 150;
		circleY = 200;
		circleR = 40;
		circleColor = Color.RED;
	}
	
	MyCircle(int x, int y, int r, int col) {
		circleX = x;
		circleY = y;
		circleR = r;
		circleColor = col;
	}
	
	public int getX() {
		return circleX;
	}
	
	public int getY() {
		return circleY;
	}
	
	public int getR() {
		return circleR;
	}
	
	public int getColor() {
		return circleColor;
	}
	
	public void setX(int x) {
		circleX = x;
	}
	
	public void setY(int y) {
		circleY = y;
	}
	
	public void setR(int r) {
		circleR = r;
	}
	
	public void setColor(int col) {
		circleColor = col;
	}
	
	public boolean isInnerCircle(int tx, int ty) {
		boolean result = false;
		
		if ( (circleX-circleR <= tx) && (tx <= circleX+circleR) ) {
			if ( (circleY-circleR <= ty) && (ty <= circleY+circleR) ) {
				result = true;
			}
		}
		return result;
	}
	
	public void moveTo(int x, int y) {
		circleX = x;
		circleY = y;
	}
}