xamarin.android SurfaceView 实现 游戏 触摸摇杆

先上图

  

页面

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:gridSpec="1|8|#0093eeff|K:#ee8700ff:16,l:72,l:16,r|S:#0000ffff:16,0,l:16,56,l:16,0,r">

    <LinearLayout
        android:id="@+id/ll_controller"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:layout_weight="1"
        android:orientation="vertical"/>
</RelativeLayout>

代码

[Activity(Label = "@string/app_name", Theme = "@style/AppTheme", MainLauncher = true)]
    public class MainActivity : AppCompatActivity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.activity_main);

            LinearLayout relativeLayout = FindViewById<LinearLayout>(Resource.Id.ll_controller);
            RemoteSurfaceView remoteSurfaceView = new RemoteSurfaceView(this);
            var a = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MatchParent, RelativeLayout.LayoutParams.MatchParent);
            remoteSurfaceView.LayoutParameters = a;
            relativeLayout.AddView(remoteSurfaceView);
        }
        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
        {
            Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

            base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }
    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);
        }
    }
  1 public class RemoteSurfaceView : SurfaceView, ISurfaceHolderCallback, IRunnable
  2     {
  3         // private float scale = this.Resources().getDisplayMetrics().density;
  4         private Thread th;
  5         private ISurfaceHolder sfh;
  6         private Canvas canvas;
  7         private Paint paint;
  8         private bool flag;
  9 
 10         private int bigCircleX = 0;
 11         private int bigCircleY = 0;
 12         private int bigCircleR = 0;
 13         //摇杆的X,Y坐标以及摇杆的半径
 14         private float smallCircleX = 0;
 15         private float smallCircleY = 0;
 16         private float smallCircleR = 0;
 17 
 18 
 19         private Bitmap bitmap;
 20         private RemoteViewBg remoteViewBg;
 21         public RemoteSurfaceView(Context context) : base(context)
 22         {
 23             sfh = this.Holder;
 24             sfh.AddCallback(this);
 25             paint = new Paint();
 26             paint.AntiAlias = true;
 27             Focusable = true;
 28             FocusableInTouchMode = true;
 29             SetZOrderOnTop(true);
 30             Holder.SetFormat(Format.Transparent);
 31         }
 32         public void SetLayoutParams() { }
 33         /***
 34          * 得到两点之间的弧度
 35          */
 36         public float getRad(float px1, float py1, float px2, float py2)
 37         {
 38             float x = px2 - px1;
 39 
 40             float y = py1 - py2;
 41             //斜边的长
 42             float z = (float)Java.Lang.Math.Sqrt(Java.Lang.Math.Pow(x, 2) + Java.Lang.Math.Pow(y, 2));
 43             float cosAngle = x / z;
 44             float rad = (float)Java.Lang.Math.Acos(cosAngle);
 45 
 46             if (py2 < py1)
 47             {
 48                 rad = -rad;
 49             }
 50             return rad;
 51         }
 52 
 53         public void GetXY(float x, float y, float R, double rad)
 54         {
 55 
 56             smallCircleX = (float)(R * Java.Lang.Math.Cos(rad)) + x;
 57 
 58             smallCircleY = (float)(R * Java.Lang.Math.Sin(rad)) + y;
 59         }
 60 
 61         public void draw()
 62         {
 63             try
 64             {
 65                 canvas = sfh.LockCanvas();
 66                 canvas.DrawColor(Color.White);//Resources.GetColor(Resources.GetColor("colorAccent").));
 67                 Rect src = new Rect(0, 0, bitmap.Width, bitmap.Height);
 68                 Rect dst = new Rect(bigCircleX - bigCircleR, bigCircleY - bigCircleR, bigCircleX + bigCircleR, bigCircleY + bigCircleR);
 69                 // 绘制图片
 70                 remoteViewBg.draw(canvas, paint, src, dst);
 71                 paint.Color = Color.AliceBlue;
 72                 //绘制摇杆
 73                 canvas.DrawCircle(smallCircleX, smallCircleY, smallCircleR, paint);
 74             }
 75             catch (Java.Lang.Exception e)
 76             {
 77                 // TODO: handle exception
 78             }
 79             finally
 80             {
 81                 try
 82                 {
 83                     if (canvas != null)
 84                         sfh.UnlockCanvasAndPost(canvas);
 85                 }
 86                 catch (Java.Lang.Exception e2)
 87                 {
 88                     e2.PrintStackTrace();
 89                 }
 90             }
 91         }
 92 
 93         public void Run()
 94         {
 95             while (flag)
 96             {
 97                 draw();
 98                 try
 99                 {
100                     //Thread.Sleep(50);
101                 }
102                 catch (Java.Lang.Exception ex)
103                 {
104                     ex.PrintStackTrace();
105                 }
106             }
107         }
108 
109         public void SurfaceCreated(ISurfaceHolder holder)
110         {
111             int width = Width;
112             int height = Height;
113             bigCircleX = width / 2;
114             bigCircleY = height / 2;
115             bigCircleR = width / 4;
116             smallCircleX = width / 2;
117             smallCircleY = height / 2;
118             smallCircleR = width / 8;
119             bitmap = BitmapFactory.DecodeResource(Resources, Resource.Mipmap.fangxiang);
120             remoteViewBg = new RemoteViewBg(bitmap);
121             th = new Thread(this);
122             flag = true;
123             th.Start();
124         }
125         public override bool OnTouchEvent(MotionEvent e)
126         {
127             if (e.Action == MotionEventActions.Down || e.Action == MotionEventActions.Move)
128             {
129                 // 范围外触摸
130                 if (Java.Lang.Math.Sqrt(Java.Lang.Math.Pow((bigCircleX - (int)e.GetX()), 2) +
131                     Java.Lang.Math.Pow((bigCircleY - (int)e.GetY()), 2)) >= bigCircleR)
132                 {
133 
134                     double tempRad = getRad(bigCircleX, bigCircleY, e.GetX(), e.GetY());
135 
136                     GetXY(bigCircleX, bigCircleY, bigCircleR, tempRad);
137                 }
138                 else
139                 {//范围内触摸
140                     smallCircleX = (int)e.GetX();
141                     smallCircleY = (int)e.GetY();
142                 }
143             }
144             else if (e.Action == MotionEventActions.Up)
145             {
146                 smallCircleX = bigCircleX;
147                 smallCircleY = bigCircleY;
148 
149             }
150             return true;
151         }
152         public void SurfaceDestroyed(ISurfaceHolder holder)
153         {
154             flag = false;
155         }
156 
157         public void SurfaceChanged(ISurfaceHolder holder, [GeneratedEnum] Format format, int width, int height)
158         {
159           
160         }
161     }

猜你喜欢

转载自www.cnblogs.com/IKang8701348/p/11333713.html