android怎么模拟实现航拍遥控
本文小编为大家详细介绍“android怎么模拟实现航拍遥控”,内容详细,步骤清晰,细节处理妥当,希望这篇“android怎么模拟实现航拍遥控”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。
先贴图
左右两个点,在圈内活动,一个是控制油门,一个是控制方向,放手后会返回中心点,这些在游戏场景中经常看到,比如射击类的游戏,这里自定义view,继承ImageView,难点就在手指控制这部分,以下是源码。
package .remotecontrol;importandroid.annotation.TargetApi;importandroid.content.Context;importandroid.graphics.Bitmap;importandroid.graphics.BitmapFactory;importandroid.graphics.Canvas;importandroid.graphics.Matrix;importandroid.graphics.Point;importandroid.graphics.Rect;importandroid.os.Build;importandroid.util.AttributeSet;importandroid.util.DisplayMetrics;importandroid.view.MotionEvent;importandroid.view.WindowManager;importandroid.widget.ImageView;/***Createdbyqingyuanon2023/5/20.*自定义view模拟遥控器*/publicclassRemoteControlextendsImageView{publicfinalStringTAG="RemoteControl";publicRemoteControl(Contextcontext){super(context);InitData(context);}publicRemoteControl(Contextcontext,AttributeSetattrs){super(context,attrs);InitData(context);}publicRemoteControl(Contextcontext,AttributeSetattrs,intdefStyleAttr){super(context,attrs,defStyleAttr);InitData(context);}@TargetApi(Build.VERSION_CODES.LOLLIPOP)publicRemoteControl(Contextcontext,AttributeSetattrs,intdefStyleAttr,intdefStyleRes){super(context,attrs,defStyleAttr,defStyleRes);InitData(context);}DisplayMetricsdm=newDisplayMetrics();WindowManagermanager;//屏幕的宽跟高intmDisplayWidth;intmDisplayWidth_2;//屏幕宽的1/2intmDisplayWidth_4;//屏幕宽的1/4intmDisplayWidth_43;//屏幕宽的3/4intmDisplayHeight;intmDisplayHeight_2;//屏幕高的1/2intmDisplayHeight_4;//屏幕高的1/4intmDisplayHeight_43;//屏幕高的3/4PointleftCenter;//左边中点的坐标PointrightCenter;//右边中点的坐标/********************右边的底图**************************/Bitmapbtm_bg;RectrectSrc_bg;RectrectDst_bg;/********************左边的底图**************************/Bitmapbtm_bar;RectrectSrc_bar;RectrectDst_bar;/********************左边的圆点**************************/Bitmapbtm_circle_left;MyPointleftPoint;doubleleftDistance;//距离中心点的距离doubleleftAngle;//atan2的角度值intleftCircle_2;//圆的一半/********************右边的圆点**************************/Bitmapbtm_circle_right;MyPointrightPoint;doublerightDistance;//距离中心点的距离doublerightAngle;//atan2的角度值intrightCircle_2;//圆的一半intstopRadius;//圆的半径,左右的半径是一样的Matrixmatrix;//矩阵,同过改变矩阵来改变bitmap的位置finaldoubledegToRad=Math.PI/180.0;finaldoubleradToDeg=180.0/Math.PI;publicvoidInitData(Contextcontext){manager=(WindowManager)context.getSystemService(Context.WINDOW_SERVICE);manager.getDefaultDisplay().getMetrics(dm);mDisplayWidth=dm.widthPixels;mDisplayHeight=dm.heightPixels;mDisplayWidth_2=mDisplayWidth/2;//屏幕宽的1/2mDisplayWidth_4=mDisplayWidth/4;//屏幕宽的1/4mDisplayWidth_43=mDisplayWidth*3/4;//屏幕宽的3/4mDisplayHeight_2=mDisplayHeight/2;//屏幕高的1/2mDisplayHeight_4=mDisplayHeight/4;//屏幕高的1/4mDisplayHeight_43=mDisplayHeight*3/4;//屏幕高的3/4btm_bg=BitmapFactory.decodeResource(context.getResources(),R.drawable.control_bg);btm_circle_left=BitmapFactory.decodeResource(context.getResources(),R.drawable.records);btm_circle_right=BitmapFactory.decodeResource(context.getResources(),R.drawable.help);btm_bar=BitmapFactory.decodeResource(context.getResources(),R.drawable.shift_bar_bg);matrix=newMatrix();floatscaleSize=(float)(mDisplayHeight*1.0/btm_bg.getWidth()*0.65f);//缩放为屏幕的0.65matrix.postScale(scaleSize,scaleSize);btm_bg=Bitmap.createBitmap(btm_bg,0,0,btm_bg.getWidth(),btm_bg.getHeight(),matrix,true);btm_bar=Bitmap.createBitmap(btm_bar,0,0,btm_bar.getWidth(),btm_bar.getHeight(),matrix,true);btm_circle_left=Bitmap.createBitmap(btm_circle_left,0,0,btm_circle_left.getWidth(),btm_circle_left.getHeight(),matrix,true);btm_circle_right=Bitmap.createBitmap(btm_circle_right,0,0,btm_circle_right.getWidth(),btm_circle_right.getHeight(),matrix,true);leftCircle_2=btm_circle_left.getWidth()/2;rightCircle_2=btm_circle_right.getWidth()/2;//左边中心点的位置设为leftCenter=newPoint();leftCenter.set(mDisplayWidth_4,mDisplayHeight_2);//右边中心点的位置设为rightCenter=newPoint();rightCenter.set(mDisplayWidth_43,mDisplayHeight_2);/***********************左边的地图位置***************************/rectSrc_bar=newRect(0,0,btm_bar.getWidth(),btm_bar.getHeight());rectDst_bar=newRect(leftCenter.x-btm_bg.getWidth()/2,leftCenter.y-btm_bg.getHeight()/2,leftCenter.x+btm_bg.getWidth()/2,leftCenter.y+btm_bg.getHeight()/2);/***********************左边的圆点位置***************************/leftPoint=newMyPoint(leftCenter.x,leftCenter.y);/***********************右边的圆底图位置***************************/rectSrc_bg=newRect(0,0,btm_bg.getWidth(),btm_bg.getHeight());rectDst_bg=newRect(rightCenter.x-btm_bar.getWidth()/2,rightCenter.y-btm_bar.getHeight()/2,rightCenter.x+btm_bar.getWidth()/2,rightCenter.y+btm_bar.getHeight()/2);/***********************右边边的圆点位置***************************/rightPoint=newMyPoint(rightCenter.x,rightCenter.y);//半径为底图的一半,这里决定了可移动圆的大小stopRadius=btm_bg.getWidth()/2;}@OverrideprotectedvoidonDraw(Canvascanvas){super.onDraw(canvas);canvas.drawBitmap(btm_bg,rectSrc_bg,rectDst_bg,null);canvas.drawBitmap(btm_bar,rectSrc_bar,rectDst_bar,null);//更新的左中心点的位置matrix.reset();matrix.postTranslate(leftPoint.x-leftCircle_2,leftPoint.y-leftCircle_2);canvas.drawBitmap(btm_circle_left,matrix,null);//更新的右中心点的位置matrix.reset();matrix.postTranslate(rightPoint.x-rightCircle_2,rightPoint.y-rightCircle_2);canvas.drawBitmap(btm_circle_right,matrix,null);}@TargetApi(Build.VERSION_CODES.ECLAIR)@OverridepublicbooleanonTouchEvent(MotionEventevent){floatx;floaty;doubledistance;//圆点离中心点的距离doubleangle;//圆点tan2的角度floatx2;floaty2;doubleangle2;doubledistance2;switch(MotionEvent.ACTION_MASK&event.getAction()){caseMotionEvent.ACTION_DOWN://判断第一个手指按下的位置所在的区域if(Math.abs(event.getX()-rightPoint.x)<btm_circle_right.getWidth()&&Math.abs(event.getY()-rightPoint.y)<btm_circle_right.getHeight()){rightPoint.setPointerIndex(0);rightPoint.setCanMove(true);}elseif(Math.abs(event.getX()-leftPoint.x)<btm_circle_left.getWidth()&&Math.abs(event.getY()-leftPoint.y)<btm_circle_left.getHeight()){leftPoint.setPointerIndex(0);leftPoint.setCanMove(true);}break;caseMotionEvent.ACTION_POINTER_UP://获取离开手指的idintpointerId=(event.getAction()&MotionEvent.ACTION_POINTER_ID_MASK)>>>MotionEvent.ACTION_POINTER_ID_SHIFT;//根据手指离开的id判断是开了的是哪个移动的点if(rightPoint.isCanMove()&&rightPoint.getPointerIndex()==pointerId){rightPoint.setCanMove(false);//手指离开让圆点返回中心点rightPoint.x=rightCenter.x;rightPoint.y=rightCenter.y;rightPoint.setPointerIndex(-1);}if(leftPoint.isCanMove()&&leftPoint.getPointerIndex()==pointerId){leftPoint.setCanMove(false);leftPoint.x=leftCenter.x;leftPoint.y=rightCenter.y;leftPoint.setPointerIndex(-1);}break;caseMotionEvent.ACTION_UP://全部手指离开之后rightPoint.setCanMove(false);rightPoint.x=rightCenter.x;rightPoint.y=rightCenter.y;rightPoint.setPointerIndex(0);leftPoint.setCanMove(false);leftPoint.x=leftCenter.x;leftPoint.y=leftCenter.y;leftPoint.setPointerIndex(0);break;caseMotionEvent.ACTION_POINTER_DOWN://获取第二根手指的idpointerId=(event.getAction()&MotionEvent.ACTION_POINTER_ID_MASK)>>>MotionEvent.ACTION_POINTER_ID_SHIFT;//第二根手指按下if(!rightPoint.isCanMove()&&Math.abs(event.getX(pointerId)-rightPoint.x)<btm_circle_right.getWidth()&&Math.abs(event.getY(pointerId)-rightPoint.y)<btm_circle_right.getHeight()){rightPoint.setPointerIndex(pointerId);rightPoint.setCanMove(true);}elseif(!leftPoint.isCanMove()&&Math.abs(event.getX(pointerId)-leftPoint.x)<btm_circle_left.getWidth()&&Math.abs(event.getY(pointerId)-leftPoint.y)<btm_circle_left.getHeight()){leftPoint.setPointerIndex(pointerId);leftPoint.setCanMove(true);}break;caseMotionEvent.ACTION_MOVE://如果是单指移动if(event.getPointerCount()==1){if(rightPoint.isCanMove()){x=event.getX(0)-rightCenter.x;y=event.getY(0)-rightCenter.y;//计算角度,atan2的用法自己百度咯angle=(Math.atan2(x,y)*radToDeg)-90;distance=Math.sqrt((x*x)+(y*y));//判断是不是超出了规定的半径长度if(distance>=stopRadius){distance=stopRadius;doubleradAngle=angle*degToRad;rightPoint.x=(int)(distance*Math.cos(radAngle))+rightCenter.x;rightPoint.y=(int)(-distance*Math.sin(radAngle))+rightCenter.y;}else{rightPoint.x=(int)event.getX(0);rightPoint.y=(int)event.getY(0);}rightDistance=distance;rightAngle=angle;}elseif(leftPoint.isCanMove()){x=event.getX(0)-leftCenter.x;y=event.getY(0)-leftCenter.y;angle=(Math.atan2(x,y)*radToDeg)-90;distance=Math.sqrt((x*x)+(y*y));if(distance>=stopRadius){distance=stopRadius;doubleradAngle=angle*degToRad;leftPoint.x=(int)(distance*Math.cos(radAngle))+leftCenter.x;leftPoint.y=(int)(-distance*Math.sin(radAngle))+leftCenter.y;}else{leftPoint.x=(int)event.getX(0);leftPoint.y=(int)event.getY(0);}}}else{//双指移动if(rightPoint.isCanMove()&&rightPoint.getPointerIndex()!=-1&&rightPoint.getPointerIndex()<event.getPointerCount()){x=event.getX(rightPoint.getPointerIndex())-rightCenter.x;y=event.getY(rightPoint.getPointerIndex())-rightCenter.y;angle=(Math.atan2(x,y)*radToDeg)-90;distance=Math.sqrt((x*x)+(y*y));if(distance>=stopRadius){distance=stopRadius;doubleradAngle=angle*degToRad;rightPoint.x=(int)(distance*Math.cos(radAngle))+rightCenter.x;rightPoint.y=(int)(-distance*Math.sin(radAngle))+rightCenter.y;}else{rightPoint.x=(int)event.getX(rightPoint.getPointerIndex());rightPoint.y=(int)event.getY(rightPoint.getPointerIndex());}rightDistance=distance;rightAngle=angle;}if(leftPoint.isCanMove()&&leftPoint.getPointerIndex()!=-1&&leftPoint.getPointerIndex()<event.getPointerCount()){x2=event.getX(leftPoint.getPointerIndex())-leftCenter.x;y2=event.getY(leftPoint.getPointerIndex())-leftCenter.y;angle2=(Math.atan2(x2,y2)*radToDeg)-90;distance2=Math.sqrt((x2*x2)+(y2*y2));if(distance2>=stopRadius){distance2=stopRadius;doubleradAngle=angle2*degToRad;leftPoint.x=(int)(distance2*Math.cos(radAngle))+leftCenter.x;leftPoint.y=(int)(-distance2*Math.sin(radAngle))+leftCenter.y;}else{leftPoint.x=(int)event.getX(leftPoint.getPointerIndex());leftPoint.y=(int)event.getY(leftPoint.getPointerIndex());}leftDistance=distance2;leftAngle=angle2;}}break;}invalidate();returntrue;}publicdoublegetRightDistance(){returnrightDistance;}publicdoublegetRightAngle(){returnrightAngle;}publicdoublegetLeftAngle(){returnleftAngle;}publicdoublegetLeftDistance(){returnleftDistance;}/***自定义坐标点,添加了两个属性*/publicclassMyPointextendsPoint{//手指的indexprivateintpointerIndex=-1;//是否能移动privatebooleanisCanMove;publicbooleanisCanMove(){returnisCanMove;}publicvoidsetCanMove(booleancanMove){isCanMove=canMove;}publicMyPoint(intx,inty){super(x,y);}publicintgetPointerIndex(){returnpointerIndex;}publicvoidsetPointerIndex(intpointerIndex){this.pointerIndex=pointerIndex;}}}
在我的真正项目中对内存性能要求比较高,所有我并没有直接用继承ImageView,而是使用了SurfaceView,双缓冲,单独线程刷新画面,还有局部刷新,基本上跟上面的差不多,只是将onDraw()里面的刷新代码放到SurfaceView中,网上也有很多SurfaceView使用的例子,稍微借鉴一下就能转过来。
读到这里,这篇“android怎么模拟实现航拍遥控”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注主机评测网行业资讯频道。
输入法切换键是哪个键?输入法切
冬月是哪一个月?冬月是什么意思
个人所得税退税金额怎么算出来的
输入法全角和半角有什么区别?输
a4纸尺寸是多少厘米?a4纸的由来
个人所得税扣除标准?个人所得税
输入法哪个好用?输入法介绍
卡拉OK是哪个国家发明的?卡拉OK
mikutools原神网页版入口链接?m
关机特别慢什么原因?电脑和手机