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); } } } } }

问题一:

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值