360°平滑游戏摇杆 Rocker

public class Rocker extends Activity{
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(new RockerView(this));
	}
	
	private class RockerView extends SurfaceView implements SurfaceHolder.Callback,Runnable{
		private SurfaceHolder mSurfaceHolder;
		private Thread mThread;
		private Canvas mCanvas;
		private Paint mPaint;
		private boolean mIsFlag;
		
		private float mCircleX=100;
		private float mCircleY=100;
		private float mCircleR=50;
		private float mRockerCircleX=100;
		private float mRockerCircleY=100;
		private float mRockerCircleR=20;

		public RockerView(Context context) {
			super(context);
			
			mSurfaceHolder=this.getHolder();
			mSurfaceHolder.addCallback(this);
			mPaint=new Paint();
			mPaint.setAntiAlias(true);
			
			setFocusable(true);
			setFocusableInTouchMode(true);
			
		}

		@Override
		public void surfaceChanged(SurfaceHolder holder, int format, int width,
				int height) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void surfaceCreated(SurfaceHolder holder) {
			mIsFlag=true;
			mThread=new Thread(this);
			mThread.start();
		}

		@Override
		public void surfaceDestroyed(SurfaceHolder holder) {
			mIsFlag=false;
		}
		
		@Override
		public boolean onTouchEvent(MotionEvent event) {
			if (event.getAction()==MotionEvent.ACTION_DOWN||event.getAction()==MotionEvent.ACTION_MOVE) {
				if (Math.sqrt((Math.pow(mCircleX-event.getX(), 2)+Math.pow(mCircleY-event.getY(), 2)))>mCircleR) {
					double angle=getAngle(mCircleX,mCircleY,event.getX(),event.getY());
					setRockerXYInCircle(angle);
				}else {
					mRockerCircleX=event.getX();
					mRockerCircleY=event.getY();
				}
				return true;
			}else if (event.getAction()==MotionEvent.ACTION_UP) {
				mRockerCircleX=mCircleX;
				mRockerCircleY=mCircleY;
				return true;
			}
			
			return super.onTouchEvent(event);
		}

		private void setRockerXYInCircle(double angle) {
			mRockerCircleX=(float)(mCircleR*Math.cos(angle))+mCircleX;
			mRockerCircleY=(float)(mCircleR*Math.sin(angle))+mCircleY;
		}

		private double getAngle(float circleX, float circleY, float targetX, float targetY) {
			float disX=targetX-circleX;
			float disY=targetY-circleY;
			float hypotenuse=(float)Math.sqrt(Math.pow(disX, 2)+Math.pow(disY, 2));
			float cosAngle=disX/hypotenuse;
			float angle=(float)Math.acos(cosAngle);
			if (targetY<circleY) {
				angle=-angle;
			}
			return angle;
		}

		@Override
		public void run() {
			while (mIsFlag) {
				doDraw();
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}

		private void doDraw() {
			try {
				mCanvas=mSurfaceHolder.lockCanvas();
				if (mCanvas!=null) {
					mCanvas.drawColor(Color.WHITE);
					mPaint.setColor(0x70000000);
					mCanvas.drawCircle(mCircleX, mCircleY, mCircleR, mPaint);
					mPaint.setColor(0x70ff0000);
					mCanvas.drawCircle(mRockerCircleX, mRockerCircleY, mRockerCircleR, mPaint);
				}
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}finally{
				if (mCanvas!=null) {
					mSurfaceHolder.unlockCanvasAndPost(mCanvas);
				}
			}
		}
		
	}

}

360°平滑游戏摇杆 Rocker_第1张图片

问题一:

@Override
		public boolean onTouchEvent(MotionEvent event) {
			if (event.getAction()==MotionEvent.ACTION_DOWN||event.getAction()==MotionEvent.ACTION_MOVE) {
				if (Math.sqrt((Math.pow(mCircleX-event.getX(), 2)+Math.pow(mCircleY-event.getY(), 2)))>mCircleR) {
					double angle=getAngle(mCircleX,mCircleY,event.getX(),event.getY());
					setRockerXYInCircle(angle);
				}else {
					mRockerCircleX=event.getX();
					mRockerCircleY=event.getY();
				}
				return true;
			}else if (event.getAction()==MotionEvent.ACTION_UP) {
				mRockerCircleX=mCircleX;
				mRockerCircleY=mCircleY;
				return true;
			}
			
			return super.onTouchEvent(event);
		}
这个是当if (event.getAction()==MotionEvent.ACTION_DOWN||event.getAction()==MotionEvent.ACTION_MOVE) 当手指按下和移动的时候,计算摇杆的x和y坐标,当手指抬起的时候恢复和大圆相同的x和y坐标,再进行绘制的时候就会画在中间

问题二:

private void setRockerXYInCircle(double angle) {
			mRockerCircleX=(float)(mCircleR*Math.cos(angle))+mCircleX;
			mRockerCircleY=(float)(mCircleR*Math.sin(angle))+mCircleY;
		}
当手指移动的距离大于大圆的半径的时候,要重新计算摇杆的x和y坐标,使其仍然在大圆的圆周上,也就是是大圆圆心和手指所在点的直线与圆周相交的点。
问题三:

private double getAngle(float circleX, float circleY, float targetX, float targetY) {
			float disX=targetX-circleX;
			float disY=targetY-circleY;
			float hypotenuse=(float)Math.sqrt(Math.pow(disX, 2)+Math.pow(disY, 2));
			float cosAngle=disX/hypotenuse;
			float angle=(float)Math.acos(cosAngle);
			if (targetY<circleY) {
				angle=-angle;
			}
			return angle;
		}
这个还不是太理解,看来数学退化了。。。

你可能感兴趣的:(360°平滑游戏摇杆 Rocker)