From c9172947a0f53661bb7e503c33eddd3f472d01b7 Mon Sep 17 00:00:00 2001 From: Jonas Bengtsson Date: Sat, 7 Apr 2012 22:10:20 +0200 Subject: [PATCH] improve control, dead zone --- src/se/forskningsavd/NavigationView.java | 68 ++++++++++++++++++------ 1 file changed, 53 insertions(+), 15 deletions(-) diff --git a/src/se/forskningsavd/NavigationView.java b/src/se/forskningsavd/NavigationView.java index 3c587d3..43728e0 100644 --- a/src/se/forskningsavd/NavigationView.java +++ b/src/se/forskningsavd/NavigationView.java @@ -9,8 +9,17 @@ import static android.view.MotionEvent.*; class NavigationView extends View { + private static final float DEADZONE = 0.1f; // 0..1 private final Paint mPaint = new Paint(); private final Navigator mNavigator; + private int mMoveCenterX; + private int mMoveCenterY; + private int mMoveDistanceX; + private int mMoveDistanceY; + private int mLookCenterX; + private int mLookCenterY; + private int mLookDistanceX; + private int mLookDistanceY; public NavigationView(Context context, Navigator navigator) { super(context); @@ -19,14 +28,31 @@ public NavigationView(Context context, Navigator navigator) { mPaint.setStyle(Paint.Style.STROKE); } + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + + mMoveCenterX = w / 4; + mLookCenterX = w * 3 / 4; + mMoveCenterY = mLookCenterY = h / 2; + + mMoveDistanceX = mLookDistanceX = w / 4; + mMoveDistanceY = mLookDistanceY = h / 2; + } + @Override protected void onDraw(Canvas canvas) { - final int width = getWidth(); - final int height = getHeight(); - canvas.drawLine(0, height / 3, width, height / 3, mPaint); - canvas.drawLine(0, height * 2 / 3, width, height * 2 / 3, mPaint); - canvas.drawLine(width / 3, 0, width / 3, height, mPaint); - canvas.drawLine(width * 2 / 3, 0, width * 2 / 3, height, mPaint); + drawRings(canvas, mMoveCenterX, mMoveCenterY, mMoveDistanceX, mMoveDistanceY, mPaint); + drawRings(canvas, mLookCenterX, mLookCenterY, mLookDistanceX, mLookDistanceY, mPaint); + } + + private void drawRings(Canvas canvas, int centerX, int centerY, int radiusX, int radiusY, Paint paint) { + final int minRadius = Math.min(radiusX, radiusY); + final int rings = minRadius / 30; + final float ringDistance = (float) minRadius / rings; + for (int i = 0; i < rings; i++) { + canvas.drawCircle(centerX, centerY, (i + 1) * ringDistance, paint); + } } @Override @@ -36,18 +62,20 @@ public boolean onTouchEvent(MotionEvent event) { return true; case ACTION_MOVE: case ACTION_DOWN: - final int width = getWidth(); - final int height = getHeight(); - for (int i = 0; i < event.getPointerCount(); i++) { final float x = event.getX(i); final float y = event.getY(i); - if (x < width / 2) { - mNavigator.moveX = (x - width / 4) / (width / 4); - mNavigator.moveY = (y - height / 2) / (height / 2); - } else { - mNavigator.rotation = (x - width / 2 - width / 4) / (width / 4); - mNavigator.cameraAngle = (y - height / 2) / (height / 2); + final float moveX = normalizeAxis(x, mMoveCenterX, mMoveDistanceX); + final float moveY = normalizeAxis(y, mMoveCenterY, mMoveDistanceY); + final float lookX = normalizeAxis(x, mLookCenterX, mLookDistanceX); + final float lookY = normalizeAxis(y, mLookCenterY, mLookDistanceY); + + if (Math.abs(moveX) <= 1.f && Math.abs(moveY) <= 1.f) { + mNavigator.moveX = moveX; + mNavigator.moveY = moveY; + } else if (Math.abs(lookX) <= 1.f && Math.abs(lookY) <= 1.f) { + mNavigator.rotation = lookX; + mNavigator.cameraAngle = lookY; } } /* @@ -66,4 +94,14 @@ public boolean onTouchEvent(MotionEvent event) { return false; } } + + private float normalizeAxis(float actual, int reference, int maxDistance) { + float d = actual - reference; + final float dead = DEADZONE * maxDistance; + if (Math.abs(d) < dead) { + return 0; + } + d += (d > 0 ? dead : -dead); + return (d / maxDistance); + } }