很多Android手机都没有实体的上下左右导航键,那么怎么控制游戏方向呢?Android游戏开发者想到了利用Android手机的触屏特性,制作360度摇杆来取代游戏方向键,最终使得界面UI变得美观,用户操作也方便。
       先贴上效果图:

       下面开始实现:
       首先,肯定是绘制两个圆形,无可置疑;圆心点重合,为了区分 ,所以设置了不同颜色;
       灰色:固定不动的摇杆背景(也意味着摇杆的活动范围);
       红色:摇杆;
       然后考虑:红色摇杆肯定跟随手指触屏的位置而移动,那么这个很easy啦,只要在触屏事件中处理,将获取的触屏XY坐标赋值与摇杆XY坐标即可;这个没问题;但是紧接着在思考一个问题:
       一般情况下,我们不可能希望摇杆一直跟随手指位置,所以需要一个摇杆的活动区域,也就如同上图中的灰色区域,在灰色区域内摇杆可以随着用户的触屏位置移动,但是一旦用户触屏位置在活动区域之外,摇杆就不应该跑出灰色区域;所以具体实现步骤如下:
       1)得到通过摇杆的坐标与触屏点的坐标得到所形成的角度Angle。
       2)根据Angle,以及已知所在圆的半径,算出摇杆所在灰色圆形上做圆周运动的当前X,Y坐标。
       首先第一步: 算出摇杆坐标与触屏坐标形成的角度。
       我们肯定已知摇杆当前坐标,并且当用户触屏时的坐标也可以在触屏按键中得到,那么获取的方法就可以写成一个方法,方法如下:
Java代码
    -  
-  
-   
- public double getRad(float px1, float py1, float px2, float py2) {   
-       
-     float x = px2 - px1;   
-       
-     float y = py1 - py2;   
-       
-     float xie = (float) Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));   
-       
-     float cosAngle = x / xie;   
-       
-     float rad = (float) Math.acos(cosAngle);   
-       
-     if (py2 < py1) {   
-         rad = -rad;   
-     }   
-     return rad;   
- }  
       在Java中,Math类中的反余弦函数返回的不是角度是弧度,这一点要格外注意。
       另外一点就是,因为三角函数角度范围是0~180度,所以反之应该是-0~-180度;
       通过此函数获取到摇杆与用户触屏位置所形成的角度之后,我们就可以通过圆周公式来得到其摇杆的XY坐标了;方法如下:
Java代码
    -  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-   
- public void getXY(float centerX, float centerY, float R, double rad) {   
-       
-     SmallRockerCircleX = (float) (R * Math.cos(rad)) + centerX;   
-       
-     SmallRockerCircleY = (float) (R * Math.sin(rad)) + centerY;   
- }  
       圆周运动公式:通过三角函数定理得出:
       X坐标:所在圆的半径*角度的余弦值
       Y坐标:所在圆形半径*角度的正弦值
       圆周的大小,由所在圆的半径R的大小来决定。
       通过以上的公式我们就可以让摇杆在灰色圆形上做圆周运动,当然除此之外我们还要注意三点:
       1、做圆周运动的大小,应该跟灰色区域的半径相同;
       2、触屏事件中应该首先判定用户触屏的位置是否在灰色区域中,如果不在,我们就应该获取摇杆与触屏点的角度然后获取摇杆应该在圆周运动上的XY坐标;如果在,就没有处理了,只要将摇杆位置随着用户点击位置就好了;
       3、在触屏事件中,当用户手指离开屏幕后,应该让摇杆的位置恢复到初始的位置状态。
       下面是整个项目的MySurfaceView中全部代码:
Java代码
    - package com.rp;   
- import android.content.Context;   
- import android.graphics.Canvas;   
- import android.graphics.Color;   
- import android.graphics.Paint;   
- import android.util.Log;   
- import android.view.MotionEvent;   
- import android.view.SurfaceHolder;   
- import android.view.SurfaceView;   
- import android.view.SurfaceHolder.Callback;   
- public class MySurfaceView extends SurfaceView implements Callback, Runnable {   
-     private Thread th;   
-     private SurfaceHolder sfh;   
-     private Canvas canvas;   
-     private Paint paint;   
-     private boolean flag;   
-       
-     private int RockerCircleX = 100;   
-     private int RockerCircleY = 100;   
-     private int RockerCircleR = 50;   
-       
-     private float SmallRockerCircleX = 100;   
-     private float SmallRockerCircleY = 100;   
-     private float SmallRockerCircleR = 20;   
-     public MySurfaceView(Context context) {   
-         super(context);   
-         Log.v("Himi", "MySurfaceView");   
-         this.setKeepScreenOn(true);   
-         sfh = this.getHolder();   
-         sfh.addCallback(this);   
-         paint = new Paint();   
-         paint.setAntiAlias(true);   
-         setFocusable(true);   
-         setFocusableInTouchMode(true);   
-     }   
-     public void surfaceCreated(SurfaceHolder holder) {   
-         th = new Thread(this);   
-         flag = true;   
-         th.start();   
-     }   
-      
-  
-   
-     public double getRad(float px1, float py1, float px2, float py2) {   
-           
-         float x = px2 - px1;   
-           
-         float y = py1 - py2;   
-           
-         float xie = (float) Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));   
-           
-         float cosAngle = x / xie;   
-           
-         float rad = (float) Math.acos(cosAngle);   
-           
-         if (py2 < py1) {   
-             rad = -rad;   
-         }   
-         return rad;   
-     }   
-     @Override  
-     public boolean onTouchEvent(MotionEvent event) {   
-         if (event.getAction() == MotionEvent.ACTION_DOWN ||   
-                     event.getAction() == MotionEvent.ACTION_MOVE) {   
-               
-             if (Math.sqrt(Math.pow((RockerCircleX - (int) event.getX()), 2)   
-                     + Math.pow((RockerCircleY - (int) event.getY()), 2)) >= RockerCircleR) {   
-                   
-                 double tempRad = getRad(RockerCircleX, RockerCircleY, event.getX(), event.getY());   
-                   
-                 getXY(RockerCircleX, RockerCircleY, RockerCircleR, tempRad);   
-             } else {  
-                 SmallRockerCircleX = (int) event.getX();   
-                 SmallRockerCircleY = (int) event.getY();   
-             }   
-         } else if (event.getAction() == MotionEvent.ACTION_UP) {   
-               
-             SmallRockerCircleX = 100;   
-             SmallRockerCircleY = 100;   
-         }   
-         return true;   
-     }   
-      
-  
-  
-  
-  
-  
-  
-  
-  
-  
-   
-     public void getXY(float centerX, float centerY, float R, double rad) {   
-           
-         SmallRockerCircleX = (float) (R * Math.cos(rad)) + centerX;   
-           
-         SmallRockerCircleY = (float) (R * Math.sin(rad)) + centerY;   
-     }   
-     public void draw() {   
-         try {   
-             canvas = sfh.lockCanvas();   
-             canvas.drawColor(Color.WHITE);   
-               
-             paint.setColor(0x70000000);   
-               
-             canvas.drawCircle(RockerCircleX, RockerCircleY, RockerCircleR, paint);   
-             paint.setColor(0x70ff0000);   
-               
-             canvas.drawCircle(SmallRockerCircleX, SmallRockerCircleY,   
-                     SmallRockerCircleR, paint);   
-         } catch (Exception e) {   
-               
-         } finally {   
-             try {   
-                 if (canvas != null)   
-                     sfh.unlockCanvasAndPost(canvas);   
-             } catch (Exception e2) {   
-             }   
-         }   
-     }   
-     public void run() {   
-           
-         while (flag) {   
-             draw();   
-             try {   
-                 Thread.sleep(50);   
-             } catch (Exception ex) {   
-             }   
-         }   
-     }   
-     public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {   
-         Log.v("Himi", "surfaceChanged");   
-     }   
-     public void surfaceDestroyed(SurfaceHolder holder) {   
-         flag = false;   
-         Log.v("Himi", "surfaceDestroyed");   
-     }   
- }  
       如果大家想美化摇杆,那就让你们的美工给出两张圆形图吧。
       还在等什么?立刻为你的游戏加上摇杆吧!