zoukankan      html  css  js  c++  java
  • 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     }
  • 相关阅读:
    时间复杂度理解
    elementUI表单校验汇总
    严选促销中心价格计算体系的建设之路
    sqlserver日志文件太大解决方法
    数据分析的 5 种细分方法
    批处理记录电脑磁盘剩余容量并输出到txt中
    关于sqlserver收缩数据库(引起的问题、可以半途停止吗)
    Sql Server 数据库总是显示“正在恢复、恢复挂起”的解决办法
    数据库“xxx”的事务日志已满,原因为“LOG_BACKUP”
    数据库分库分表策略的具体实现方案
  • 原文地址:https://www.cnblogs.com/IKang8701348/p/11333713.html
Copyright © 2011-2022 走看看