写点什么

Android 自定义 View 之游戏摇杆键盘实现 (一),二本学渣考研失败

  • 2021 年 11 月 05 日
  • 本文字数:1732 字

    阅读完需:约 6 分钟

由来

原本的项目,操作方向的方式为上下左右,左上需要同时按住左键和右键的方式进行操作。



近来升级项目,操作方式改为类似王者荣耀的摇杆操作。如下图:


绘制背景

实现遥感按钮,需要绘制背景,绘制中心的遥感按钮。绘制遥感背景,需要创建一个 RemoteViewBg 类,存储背景图,减少重复创建 bitmap。RemoteViewBg 类代码如下:


public class RemoteViewBg {private Bitmap bitmapBg;public RemoteViewBg(Bitmap bitmap) {bitmapBg = bitmap;}


//背景的绘图函数 public void draw(Canvas canvas, Paint paint, Rect src0 ,Rect dst0 ) {canvas.drawBitmap(bitmapBg, src0, dst0, paint);}}

点击触摸事件

重写系统的触摸时间,判断触摸点在背景范围内还是背景范围外


@Overridepublic boolean onTouchEvent(MotionEvent event) {if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE) {// // 在范围外触摸 if (Math.sqrt(Math.pow((bigCircleX - (int) event.getX()), 2) + Math.pow((bigCircleY - (int) event.getY()), 2)) >= bigCircleR) {


double tempRad = getRad(bigCircleX, bigCircleY, event.getX(), event.getY());


getXY(bigCircleX, bigCircleY, bigCircleR, tempRad);} else {//范围内触摸 smallCircleX = (int) event.getX();smallCircleY = (int) event.getY();}} else if (event.getAction() == MotionEvent.ACTION_UP) {smallCircleX = bigCircleX;smallCircleY = bigCircleY;


}return true;}

弧度计算

通过 event.getX(), event.getY()获得当前的触摸点,与圆点进行计算,获取弧度


/***


  • 得到两点之间的弧度*/public float getRad(float px1, float py1, float px2, float py2) {float x = px2 - px1;


float y = py1 - py2;//斜边的长 float z = (float) Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));float cosAngle = x / z;float rad = (float) Math.acos(cosAngle);


if (py2 < py1) {rad = -rad;}return rad;}

图形绘制

通过 canvas.drawCircle()和 canvas.drawBitmap()分别进行遥感按钮和遥感背景的绘制,注意对遥感背景的保存,如果在绘制的时候每次 BitmapFactory.decodeResource()会增加耗时,因此只需在 surfaceCreated()中进行 bitmap 的生成即可。


public void draw() {try {canvas = sfh.lockCanvas();canvas.drawColor(getResources().getColor(R.color.ghostwhite));


// 指定图片绘制区域(左上角的四分之一)Rect src = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());


// 指定图片在屏幕上显示的区域 Rect dst = new Rect(bigCircleX - bigCircleR, bigCircleY - bigCircleR, bigCircleX + bigCircleR, bigCircleY + bigCircleR);// 绘制图片 remoteViewBg.draw(canvas, paint


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


, src, dst);paint.setColor(0x70ff0000);//绘制摇杆 canvas.drawCircle(smallCircleX, smallCircleY, smallCircleR, paint);} catch (Exception e) {// TODO: handle exception} finally {try {if (canvas != null)sfh.unlockCanvasAndPost(canvas);} catch (Exception e2) {e2.printStackTrace();}}}

使用

在 activity 中动态添加


RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.dance_relative_layout);remoteSurfaceView = new RemoteSurfaceView(this);params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,RelativeLayout.LayoutParams.MATCH_PARENT);remoteSurfaceView.setLayoutParams(params);relativeLayout.addView(remoteSurfaceView);

关键代码

public RemoteSurfaceView(Context context) {super(context);sfh = this.getHolder();sfh.addCallback(this);paint = new Paint();paint.setAntiAlias(true);setFocusable(true);setFocusableInTouchMode(true);setZOrderOnTop(true);getHolder().setFormat(PixelFormat.TRANSPARENT);


}


public void surfaceCreated(SurfaceHolder holder) {int width = getWidth();int height = getHeight();bigCircleX = width / 2;bigCircleY = height / 2;bigCircleR = width / 4;

评论

发布
暂无评论
Android自定义View之游戏摇杆键盘实现(一),二本学渣考研失败