zoukankan      html  css  js  c++  java
  • Android实现游戏摇杆的源代码

    这段时间研究Android自定义控件,遂想起游戏里的摇杆的实现挺有意思,于是来自己写一套熟悉熟悉,关于SurfaceView的特性网上也有很多,故不赘述,反正绘图用起来挺爽就是了,永远的告别了JAVA GUI手动实现双缓冲的时代了……

    Android相关内容:

    import com.game.graphics.utils.MathUtils;
     
     import android.content.Context;
     import android.graphics.Canvas;
     import android.graphics.Color;
     import android.graphics.Paint;
     import android.graphics.PixelFormat;
     import android.graphics.Point;
     import android.graphics.PorterDuff.Mode;
     import android.util.AttributeSet;
     import android.view.MotionEvent;
     import android.view.SurfaceHolder;
     import android.view.SurfaceView;
     import android.view.SurfaceHolder.Callback;
     
     public class Rudder extends SurfaceView implements Runnable,Callback{
     
         private SurfaceHolder mHolder;
         private boolean isStop = false;
         private Thread mThread;
         private Paint  mPaint;
         private Point  mRockerPosition; //摇杆位置
         private Point  mCtrlPoint = new Point(80,80);//摇杆起始位置
         private int    mRudderRadius = 20;//摇杆半径
         private int    mWheelRadius = 60;//摇杆活动范围半径
         private RudderListener listener = null; //事件回调接口
         public static final int ACTION_RUDDER = 1 , ACTION_ATTACK = 2; // 1:摇杆事件 2:按钮事件(未实现)
        
         public Rudder(Context context) {
             super(context);
         }
        
         public Rudder(Context context, AttributeSet as) {
             super(context, as);
             this.setKeepScreenOn(true);
             mHolder = getHolder();
             mHolder.addCallback(this);
             mThread = new Thread(this);
             mPaint = new Paint();
             mPaint.setColor(Color.GREEN);
             mPaint.setAntiAlias(true);//抗锯齿
             mRockerPosition = new Point(mCtrlPoint);
             setFocusable(true);
             setFocusableInTouchMode(true);
             setZOrderOnTop(true);
             mHolder.setFormat(PixelFormat.TRANSPARENT);//设置背景透明
         }
        
         //设置回调接口
         public void setRudderListener(RudderListener rockerListener) {
             listener = rockerListener;
         }
     
         @Override
         public void run() {
             Canvas canvas = null;
             while(!isStop) {
                 try {
                     canvas = mHolder.lockCanvas();
                     canvas.drawColor(Color.TRANSPARENT,Mode.CLEAR);//清除屏幕
                     mPaint.setColor(Color.CYAN);
                     canvas.drawCircle(mCtrlPoint.x, mCtrlPoint.y, mWheelRadius, mPaint);//绘制范围
                     mPaint.setColor(Color.RED);
                     canvas.drawCircle(mRockerPosition.x, mRockerPosition.y, mRudderRadius, mPaint);//绘制摇杆
                 } catch (Exception e) {
                     e.printStackTrace();
                 } finally {
                     if(canvas != null) {
                         mHolder.unlockCanvasAndPost(canvas);
                     }
                 }
                 try {
                     Thread.sleep(30);
                 } catch (InterruptedException e) {
                     e.printStackTrace();
                 }
             }
         }
        
         @Override
         public void surfaceChanged(SurfaceHolder holder, int format, int width,
                 int height) {
            
         }
     
         @Override
         public void surfaceCreated(SurfaceHolder holder) {
             mThread.start();
         }
     
         @Override
         public void surfaceDestroyed(SurfaceHolder holder) {
             isStop = true;
         }
        
         @Override
         public boolean onTouchEvent(MotionEvent event) {
             int len = MathUtils.getLength(mCtrlPoint.x, mCtrlPoint.y, event.getX(), event.getY());
             if(event.getAction() == MotionEvent.ACTION_DOWN) {
                 //如果屏幕接触点不在摇杆挥动范围内,则不处理
                 if(len >mWheelRadius) {
                     return true;
                 }
             }
             if(event.getAction() == MotionEvent.ACTION_MOVE){
                 if(len <= mWheelRadius) {
                     //如果手指在摇杆活动范围内,则摇杆处于手指触摸位置
                     mRockerPosition.set((int)event.getX(), (int)event.getY());
                    
                 }else{
                     //设置摇杆位置,使其处于手指触摸方向的 摇杆活动范围边缘
                     mRockerPosition = MathUtils.getBorderPoint(mCtrlPoint, new Point((int)event.getX(), (int)event.getY()), mWheelRadius);
                 }
                 if(listener != null) {
                     float radian = MathUtils.getRadian(mCtrlPoint, new Point((int)event.getX(), (int)event.getY()));
                     listener.onSteeringWheelChanged(ACTION_RUDDER,Rudder.this.getAngleCouvert(radian));
                 }
             }
             //如果手指离开屏幕,则摇杆返回初始位置
             if(event.getAction() == MotionEvent.ACTION_UP) {
                 mRockerPosition = new Point(mCtrlPoint);
             }
             return true;
         }
        
         //获取摇杆偏移角度 0-360°
         private int getAngleCouvert(float radian) {
             int tmp = (int)Math.round(radian/Math.PI*180);
             if(tmp < 0) {
                 return -tmp;
             }else{
                 return 180 + (180 - tmp);
             }
         }
        
         //回调接口
         public interface RudderListener {
             void onSteeringWheelChanged(int action,int angle);
         }
     }

    import android.graphics.Point;
     
     public class MathUtils {
         //获取两点间直线距离
         public static int getLength(float x1,float y1,float x2,float y2) {
             return (int)Math.sqrt(Math.pow(x1-x2, 2) + Math.pow(y1-y2, 2));
         }
         /**
          * 获取线段上某个点的坐标,长度为a.x - cutRadius
          * @param a 点A
          * @param b 点B
          * @param cutRadius 截断距离
          * @return 截断点
          */
         public static Point getBorderPoint(Point a, Point b,int cutRadius) {
             float radian = getRadian(a, b);
             return new Point(a.x + (int)(cutRadius * Math.cos(radian)), a.x + (int)(cutRadius * Math.sin(radian)));
         }
        
         //获取水平线夹角弧度
         public static float getRadian (Point a, Point b) {
             float lenA = b.x-a.x;
             float lenB = b.y-a.y;
             float lenC = (float)Math.sqrt(lenA*lenA+lenB*lenB);
             float ang = (float)Math.acos(lenA/lenC);
             ang = ang * (b.y < a.y ? -1 : 1);
             return ang;
         }
     }

    <?xml version="1.0" encoding="utf-8"?>
     <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:orientation="vertical"
         android:layout_width="fill_parent"
         android:layout_height="fill_parent">
         <ImageView
             android:layout_width="fill_parent"
             android:layout_height="fill_parent"
             android:scaleType="fitXY"
             android:src="@drawable/xx"/>
         <RelativeLayout
             android:id="@+id/ctrls"
             android:layout_width="fill_parent"
             android:layout_height="fill_parent">
              <com.game.demo.views.Rudder
                 android:id="@+id/rudder"
                 android:layout_width="480dip"
                 android:layout_height="160dip"
                 android:layout_alignParentBottom="true"
                 android:layout_centerHorizontal="true"/>
         </RelativeLayout>
     </FrameLayout>

         setContentView(R.layout.main);
             Rudder rudder = (Rudder) findViewById(R.id.rudder);
             rudder.setRudderListener(new RudderListener() {
                
                 @Override
                 public void onSteeringWheelChanged(int action, int angle) {
                     if(action == Rudder.ACTION_RUDDER) {
                         //TODO:事件实现
                     }
                 }
             });

  • 相关阅读:
    《RTC — RTC相关操作以及如何同步系统时间》
    《关闭服务器,再次启动服务器提示bind:address already in use》
    《海思中内存分配和优化》
    《开发板 — 查看共享内存情况》
    《通过himm读取指定引脚并保存在共享内存中》
    《开发板 — 格式化TF卡》
    《网络编程 — UDP》
    《网络编程 — 服务器中bind的ip地址是什么》
    《使用gdb中core dump》
    《 Linux套接字编程中的5个隐患 》
  • 原文地址:https://www.cnblogs.com/sky7034/p/2918121.html
Copyright © 2011-2022 走看看