360°平滑游戏摇杆 Rocker

来源:互联网 发布:js数字正则表达式 编辑:程序博客网 时间:2024/05/01 13:05
public class Rocker extends Activity{@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.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);}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {// TODO Auto-generated method stub}@Overridepublic void surfaceCreated(SurfaceHolder holder) {mIsFlag=true;mThread=new Thread(this);mThread.start();}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {mIsFlag=false;}@Overridepublic 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;}@Overridepublic void run() {while (mIsFlag) {doDraw();try {Thread.sleep(100);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.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 blocke.printStackTrace();}finally{if (mCanvas!=null) {mSurfaceHolder.unlockCanvasAndPost(mCanvas);}}}}}

问题一:

@Overridepublic 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;}
这个还不是太理解,看来数学退化了。。。

原创粉丝点击