android studio遊戲搖桿開發教程,仿王者榮耀搖桿

李子果 原創。。。

最近在做一個山寨版的王者榮耀,剛開始做的時候毫無頭緒 搖桿的多點觸控做的特別爛

經過幾天的思考已完美解決所有問題,下面就和大家分享下這個搖桿的開發思路

若有不正之處,請多多諒解並歡迎指正。

首先這個搖桿要用到較多的數學知識,小編的數學特別爛也就高中水平吧

我們這個搖桿一共就五個按鈕,一個移動搖桿、三個技能搖桿和一個普通攻擊按鈕

最終效果


好了廢話少說讓我們開始吧

新建一個項目


建好項目之後,我們先新建一個類叫做“畫”。也是我們的主View


修改Hua.java的代碼

public class Hua extends RelativeLayout implements Runnable{ //繼承RelativeLayout 實現Runnable接口

    private Paint p;//畫筆

    public Hua(Context context) {
        super(context);
        p=new Paint();
        setBackgroundColor(Color.BLACK);//背景顏色設爲黑色
    }

    @Override
    protected void onDraw(Canvas g) {//重寫onDraw方法
        super.onDraw(g);
    }

    @Override
    public void run() {

    }
}

接下來我們做移動搖桿


我們要準備一張圖片(待會我會把圖片都丟在附件裏)

首先用ps畫一個這樣半透明的圓ps部分就不做教程了


把背景隱藏掉 保存爲png格式


把我們剛剛製作的圖片添加進來


先新建一個類 my.java

public class my { //這個類當一個全局變量使用
    public static int w,h;//屏幕的寬高
    public static float bili;
    public static MainActivity main;
    public static RectF re=new RectF();
    public static int ontouchAlpha=100;//觸控區透明度0-255 0爲透明,爲了測試我們先設爲100
}

修改 MainActivity 的代碼

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        my.main=this;
        getSupportActionBar().hide();//隱藏標題欄
        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//全屏 隱藏狀態欄
        //判斷當前是否橫屏 如果不是就設爲橫屏,設爲橫屏之後會自動調用onCreate方法
        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
            //獲取屏幕的寬高
            DisplayMetrics dis = getResources().getDisplayMetrics();
            my.w = dis.widthPixels;
            my.h = dis.heightPixels;
            //獲取屏幕分辨率和1920*1080的比例 以便適應不同大小的屏幕
            my.bili = (float) (Math.sqrt(my.w * my.h) / Math.sqrt(1920 * 1080));
            setContentView(new Hua(this));
        } else {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);// 橫屏
        }
    }
}

新建類 Move.java

package com.yaogan.liziguo.yaogan;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;

/**
 * Created by Liziguo on 2018/6/15.
 */

public class Move {
    private float x1,y1;//按下時的座標 大圓
    private float x2,y2;//移動後的座標 小圓
    private final float r1,r2;//r1大圓的半徑 r2小圓的半徑
    public float angle;//x1y1指向x2y2的角度 弧度制
    public boolean down=false;//判斷是否被按下
    public boolean in=false;//判斷小圓是否在大圓裏面,簡單的說就是防止小圓被脫太遠
    public boolean move=false;//判斷手指按下後是否移動(MY實際開發中用到,該教程用不到此變量)
    public Bitmap img;//大圓小圓的圖片

    public Move(){
        r1 = 480 * 0.5f * my.bili;//乘上一個比例 適應不同大小的屏幕
        r2 = 300 * 0.5f * my.bili;
        img= BitmapFactory.decodeResource(my.main.getResources(),R.mipmap.yaogan);//初始化搖桿圖片
    }

    public void down(float xx,float yy){ //搖桿按下後的操作
        if(xx<r1) x1=r1;
        else x1 = xx;

        if(my.h-yy<r1) y1=my.h-r1;
        else y1 = yy;
        //上面的代碼是防止按下的位置太靠近屏幕邊緣
        //跟x1=xx;y1=yy;區別不大,待會可以改成x1=xx;y1=yy;看看效果有什麼不同
        down=true;
    }
    public void move(float xx,float yy){ //按下搖桿後移動的操作
        angle=getAngle(xx,yy);
        in=in(xx, yy);
        move=isMove(xx,yy);
        if (!in) {
            //下面會做解釋
            xx= (float) (x1+ Math.sin(angle)*r1*0.7f);
            yy= (float) (y1+ Math.cos(angle)*r1*0.7f);
        }
        x2=xx;
        y2=yy;
    }
    public void up(){ //鬆開後的操作
        down=false;
    }

    public float getAngle(float xx,float yy){ //獲取x1y1指向x2y2的角度
        double angle,k;
        if (y1==yy)//斜率不存在時
            if (x1 > xx)//判斷x1指向x2的方向
                angle=-Math.PI/2;
            else
                angle=Math.PI/2;
        else{
            k=(x1-xx)/(y1-yy); //兩點的座標求斜率,至於爲什麼是(x1-x2)/(y1-y2)不是(y1-y2)/(x1-x2)待會我們再做解釋
            if (y1 > yy) {//判斷x1y1指向x2y2的方向
                // 用反tan求角度 這個高中好像沒學過 既然Math類已經幫我們封裝好了就直接拿來用吧
                angle=Math.atan(k) + Math.PI;
            } else {
                angle=Math.atan(k);
            }
            //這段可寫可不寫 讓計算出來的角度屬於-PI/2到PI/2
            if(angle>Math.PI)
                angle-=Math.PI*2;
            else if(angle<-Math.PI)
                angle+=Math.PI*2;
        }
        return (float) angle;
    }

    public boolean in(float xx, float yy) { //防止小圓被脫太遠 拖動範圍不超出r1的70%
        double r = Math.sqrt((x1 - xx) * (x1 - xx) + (y1 - yy) * (y1 - yy));//兩點間距離公式
        if (r < r1*0.7f)
            return true;
        else return false;
    }
    public boolean isMove(float xx, float yy) { //判斷按下搖桿後 是否移動,如果x1y1 x2y2的距離大於r1*0.15視爲移動
        // MY實際開發中用到,該教程用不到此變量
        double r = Math.sqrt((x1 - xx) * (x1 - xx) + (y1 - yy) * (y1 - yy));//兩點間距離公式
        if (r > r1*0.15f)
            return true;
        else return false;
    }
    public void onDraw(Canvas g, Paint p){ //畫搖桿
        if(down) { //當搖桿被按下時 才顯示
            //怎麼用Canvas畫圖這裏就不說了
            my.re.left = x1 - r1;
            my.re.top = y1 - r1;
            my.re.right = x1 + r1;
            my.re.bottom = y1 + r1;
            g.drawBitmap(img, null, my.re, p); //畫大圓
            my.re.left = x2 - r2;
            my.re.top = y2 - r2;
            my.re.right = x2 + r2;
            my.re.bottom = y2 + r2;
            g.drawBitmap(img, null, my.re, p); //畫小圓
        }
    }
}

新建類 OnTouchMove.java 

package com.yaogan.liziguo.yaogan;

import android.content.Context;
import android.graphics.Color;
import android.view.MotionEvent;
import android.view.View;

/**
 * Created by Liziguo on 2018/6/16.
 */

public class OnTouchMove extends View { //這個view負責監聽移動搖桿的手勢
    
    private Move m;
    
    public OnTouchMove(Context context,Move move) {
        super(context);
        this.m=move;
        setBackgroundColor(Color.WHITE);//背景色設爲白色
        getBackground().setAlpha(my.ontouchAlpha);//設置觸控區透明度
        setOnTouchListener(new OnTouchListener() { //設置觸控監聽
            @Override
            public boolean onTouch(View v, MotionEvent ev) {
                //加上getX() getY()因爲這個view不是分佈在左上角的
                final float xx = ev.getX() + getX(), yy = ev.getY() + getY();

                if (ev.getAction() == MotionEvent.ACTION_DOWN) {
                    m.down(xx, yy);//按下時的操作
//                    m.move(xx, yy);
                }
                m.move(xx, yy);//移動時的操作
                if (ev.getAction() == MotionEvent.ACTION_UP) {
                    m.up();//鬆開時的操作
                }
                return true;//不要返回false
            }
        });
    }
}

修改 Hua.java 的代碼

package com.yaogan.liziguo.yaogan;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.widget.RelativeLayout;

/**
 * Created by Liziguo on 2018/6/15.
 */

public class Hua extends RelativeLayout implements Runnable{ //繼承RelativeLayout 實現Runnable接口

    private Paint p;//畫筆
    private Move m=new Move();//移動搖桿

    public Hua(Context context) {
        super(context);
        p=new Paint();
        setBackgroundColor(Color.BLACK);//背景顏色設爲黑色
        //實例化一個OnTouchMove
        OnTouchMove onTouchMove=new OnTouchMove(context,m);
        //把onTouchMove添加進來 寬度爲屏幕的1/3 高度爲屏幕的1/2
        addView(onTouchMove,my.w/3,my.h/2);
        //設置onTouchMove的位置
        onTouchMove.setX(0);
        onTouchMove.setY(my.h/2);

        new Thread(this).start();//啓動重繪線程
    }

    @Override
    protected void onDraw(Canvas g) {//重寫onDraw方法
        super.onDraw(g);
        m.onDraw(g,p);//畫移動搖桿
    }

    @Override
    public void run() { //每隔20毫秒刷新一次畫布
        while(true){
            try {Thread.sleep(20);} catch (InterruptedException e) {e.printStackTrace();}
            postInvalidate();//重繪 在子線程重繪不能調用Invalidate()方法
        }
    }
}

好的 現在我們的搖桿可以說已經做好一大半了,因爲剩下的原理都一樣

先運行一遍看看效果吧


左下角的白色矩形是我們的OnTouchMove類,爲了更好的測試我們先讓他顯示出來 等做好了再隱藏掉

下面我們來解釋一下爲什麼斜率k=(x1-x2)/(y1-y2)而不是(y1-y2)/(x1-x2)吧

因爲我們手機上的平面直角座標系跟數學上的平面直角座標系不一樣

數學上的平面直角座標系是這樣的


而我們手機是這樣的


有沒有發現把手機的座標系 逆時針旋轉一下就是數學裏的座標系了,不過x跟y調了一下位置

所以我們在寫代碼的時候把x y換一下就行了

數學座標系中k=1的直線


程序中k=1的直線


再解釋下 Move 類的 move方法

public void move(float xx,float yy){ //按下搖桿後移動的操作
        angle=getAngle(xx,yy);
        in=in(xx, yy);
        move=isMove(xx,yy);
        if (!in) {
            //下面會做解釋
            xx= (float) (x1+ Math.sin(angle)*r1*0.7f);
            yy= (float) (y1+ Math.cos(angle)*r1*0.7f);
        }
        x2=xx;
        y2=yy;
    }

不知不覺已經凌晨2:46了,今天就寫到這吧

明天繼續。。。。。。


好的下面我們開始做技能搖桿,這教程做的比較累啊

下面的技能類是我直接從我遊戲裏拷貝過來的並做了些小修改

解釋可能沒那麼清楚畢竟原理都一樣

只不過是多了幾個功能而已


準備圖片



添加到工程裏


由於圖片比較多 我們加載圖的代碼位置改一下

修改 MainActivity。java 和 my.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        my.main=this;
        getSupportActionBar().hide();//隱藏標題欄
        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//全屏 隱藏狀態欄
        //判斷當前是否橫屏 如果不是就設爲橫屏,設爲橫屏之後會自動調用onCreate方法
        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
            //獲取屏幕的寬高
            DisplayMetrics dis = getResources().getDisplayMetrics();
            my.w = dis.widthPixels;
            my.h = dis.heightPixels;
            //獲取屏幕分辨率和1920*1080的比例 以便適應不同大小的屏幕
            my.bili = (float) (Math.sqrt(my.w * my.h) / Math.sqrt(1920 * 1080));
            //加載圖片
            my.border= BitmapFactory.decodeResource(my.main.getResources(),R.mipmap.border);
            my.cancel= BitmapFactory.decodeResource(my.main.getResources(),R.mipmap.cancel);
            my.down= BitmapFactory.decodeResource(my.main.getResources(),R.mipmap.down);
            my.yaogan= BitmapFactory.decodeResource(my.main.getResources(),R.mipmap.yaogan);
            my.cd= BitmapFactory.decodeResource(my.main.getResources(),R.mipmap.cd);
            setContentView(new Hua(this));
        } else {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);// 橫屏
        }
    }
}
public class my { //這個類當一個全局變量使用
    public static int w,h;//屏幕的寬高
    public static float bili;
    public static MainActivity main;
    public static RectF re=new RectF();
    public static int ontouchAlpha=100;//觸控區透明度0-255 0爲透明,爲了測試我們先設爲100

    public static Bitmap border,cancel,down,yaogan,cd;

    public static Skill skill;//當前正在使用的技能 現在會報錯 因爲我們還沒新建技能Skill類
}

修改 Move 類的構造方法

    public Move(){
        r1 = 480 * 0.5f * my.bili;//乘上一個比例 適應不同大小的屏幕
        r2 = 300 * 0.5f * my.bili;
//      img= BitmapFactory.decodeResource(my.main.getResources(),R.mipmap.yaogan);//初始化搖桿圖片////////////////////////
        img=my.yaogan;////////////////////////////////////////////////////
    }


新建技能類 Skill.java

package com.yaogan.liziguo.yaogan;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;

/**
 * Created by Liziguo on 2018/6/16.
 */

public abstract class Skill {
    public int jineng;
    private final float x,y;//技能圖標中心位置,不是按下時的位置
    private float x2, y2;//技能按下移動後手指的座標
    private float xxx,yyy;//判斷拖動點是否超出兩倍r的範圍
    private final float calcelx, cancely;
    public float angle;//技能按下後 x y指向xx yy的角度
    public Bitmap img, imgborder, imgdown, imgyaogan,imgcd,imgcancel;
    private final float r2;
    private final float r3=50*my.bili;
    public boolean down=false;
    public boolean down_main=false;//down_main 只觸發一次;
    public boolean cancel=false;
    public int cdmax;
    public long last,cd=0;//last最後一次釋放技能的時間
    /*
    0 普通攻擊
    1 技能1
    2 技能2
    3 技能3
     */
    public Skill(int jineng, int cd, Bitmap image){
        this.jineng=jineng;
        switch (jineng){
            case 0:
                x= my.w*0.87f;
                y= my.h*0.8f;
                break;
            case 1:
                x= my.w*0.7f;
                y= my.h*0.88f;
                break;
            case 2:
                x= my.w*0.75f;
                y= my.h*0.62f;
                break;
            case 3:
                x= my.w*0.9f;
                y= my.h*0.5f;
                break;
            default:x=y=0;
        }
        cdmax=cd;
        if(jineng == 0) r2=125*my.bili;
        else r2=80*my.bili;
        calcelx =my.w-r2*2;
        cancely =my.h/4;
        img=image;
        imgborder=my.border;
        imgdown=my.down;
        imgyaogan=my.yaogan;
        imgcd=my.cd;
        imgcancel=my.cancel;
    }
    //    public abstract void down();
//    public abstract void move();
//    public abstract void up();
    public void down(){ //DOWN 由ontouch觸發
        if(cd>0)return;
        down=true;
        my.skill=this;
    }
    public abstract void down_main(); //DOWN 教程用不到該抽象方法

    public void move(float x,float y){//按下技能後 由ontouch觸發
        x2 =x;
        y2 =y;
        angle=getAngle(x2, y2);
        cancel=incancel(x,y);
        if (jineng !=0 && !in2(x,y)) {
            xxx= (float) (this.x+ Math.sin(angle)*r2*2);
            yyy= (float) (this.y+ Math.cos(angle)*r2*2);
        }else{
            xxx=x;
            yyy=y;
        }
    }
    public abstract void move_main();//按下技能後 由MyActor觸發 教程用不到該抽象方法
    public abstract void up(); //鬆開後 由MyActor觸發 釋放技能

    public boolean in(float xx,float yy){ //判斷是否被點中
        double r= Math.sqrt((x - xx)*(x-xx)+(y-yy)*(y-yy));
        if(r<r2)
            return true;
        else return false;
    }
    public boolean in2(float xx, float yy) { //判斷拖動點是否超出兩倍r的範圍
        double r = Math.sqrt((x - xx) * (x - xx) + (y - yy) * (y - yy));
        if (r < r2 * 2)
            return true;
        else return false;
    }
    public boolean incancel(float xx,float yy){ //判斷是否取消
        double r= Math.sqrt((calcelx - xx)*(calcelx -xx)+(cancely -yy)*(cancely -yy));
        if(r<r2)
            return true;
        else return false;
    }
    public float getAngle(float xx,float yy){ //x y指向xx yy的角度
        float angle,k;
        if (y==yy)
            if (x > xx)
                angle= (float) (-Math.PI/2);
            else
                angle= (float) (Math.PI/2);
        else{
            k=(x-xx)/(y-yy);
            if (y > yy) {
                angle= (float) (Math.atan(k) + Math.PI);
            } else {
                angle= (float) Math.atan(k);
            }
            if(angle>Math.PI)
                angle-=Math.PI*2;
            else if(angle<-Math.PI)
                angle+=Math.PI*2;

        }
        return angle;
    }
    private float drawpx=10*my.bili;

    public void next(){
        //計算技能冷卻時間
        cd=cdmax-System.currentTimeMillis()+last;
    }
    //按下的時候技能圖標下移 顯示藍色框框
    public void onDraw(Canvas g, Paint p){
        my.re.left=x-r2;
        my.re.top=y-r2;
        my.re.right=x+r2;
        my.re.bottom=y+r2;
        if(down){
//            new RectF(x-r2,y-r2,x+r2,y+r2);
//            new RectF(x-r2,y-r2+10*my.bili,x+r2,y+r2+10*my.bili);
//            my.re.left=x-r2;
//            my.re.top=y-r2;
//            my.re.right=x+r2;
//            my.re.bottom=y+r2;
            if(jineng!=0){
                final float bl=2;
                my.re.left=x-r2*bl;
                my.re.top=y-r2*bl;
                my.re.right=x+r2*bl;
                my.re.bottom=y+r2*bl;
                //藍色框框未下移
                g.drawBitmap(imgdown,null,my.re,p);
            }
            my.re.left=x-r2;
            my.re.top=y-r2;
            my.re.right=x+r2;
            my.re.bottom=y+r2;
            ///////////////////////////////////////////////////////////
            //技能圖片和技能邊框下移
            my.re.top+=drawpx;
            my.re.bottom+=drawpx;
            g.drawBitmap(img,null,my.re,p);
            my.re.left-=drawpx;
            my.re.top-=drawpx;
            my.re.right+=drawpx;
            my.re.bottom+=drawpx;

            g.drawBitmap(imgborder,null,my.re,p);
            if(jineng!=0){
                my.re.left=xxx-r3;
                my.re.top=yyy-r3;
                my.re.right=xxx+r3;
                my.re.bottom=yyy+r3;
                g.drawBitmap(imgyaogan,null,my.re,p);
                //cancle
                my.re.left= calcelx -r2;
                my.re.top= cancely -r2;
                my.re.right= calcelx +r2;
                my.re.bottom= cancely +r2;
                g.drawBitmap(imgcancel,null,my.re,p);
            }
        }else{
            g.drawBitmap(img,null,my.re,p);
            if(jineng!=0 && cd>0) {
                p.setTextSize(40*my.bili);
                p.setColor(Color.WHITE);
                g.drawBitmap(imgcd,null,my.re,p);
                float f=cd/100f;
                f=(int)f;
                f=f/10;
                g.drawText(String.valueOf(f),x-p.getTextSize()*4/5,y+p.getTextSize()/3,p);

            }
            my.re.left-=drawpx;
            my.re.top-=drawpx;
            my.re.right+=drawpx;
            my.re.bottom+=drawpx;
            g.drawBitmap(imgborder,null,my.re,p);
        }
    }
}

新建一個類 OnTouchSkill.java 他也是一個監聽view

這樣多點觸控會好寫很多,剛開始我是用一個view做監聽的 寫到我心態爆炸。。。

package com.yaogan.liziguo.yaogan;

import android.content.Context;
import android.graphics.Color;
import android.view.MotionEvent;
import android.view.View;

/**
 * Created by Liziguo on 2018/6/16.
 */

public class OnTouchSkill extends View {
    /*
    A 普通攻擊
    Q 技能1
    W 技能2
    E 技能3
    R 沒有R
     */

    public Skill A,Q,W,E;

    public OnTouchSkill(Context context,Skill a,Skill q,Skill w,Skill e) {
        super(context);
        A=a;Q=q;W=w;E=e;
        setBackgroundColor(Color.WHITE);
        getBackground().setAlpha(my.ontouchAlpha);//0-255
        setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent ev) {
                final float xx = ev.getX() + getX(), yy = ev.getY() + getY();
                if (ev.getAction() == MotionEvent.ACTION_DOWN) {
                    if ( A.in(xx, yy)) {
                        A.down();
                    } else if ( Q.in(xx, yy)) {
                        Q.down();
                    } else if ( W.in(xx, yy)) {
                        W.down();
                    } else if ( E.in(xx, yy)) {
                        E.down();
                    }

                }
                if (my.skill != null) my.skill.move(xx, yy);
                if(ev.getAction()==MotionEvent.ACTION_UP){
                    A.down = false;
                    Q.down = false;
                    W.down = false;
                    E.down = false;
                }
                return true;
            }
        });
    }
}

把監聽控件添加到Hua,修改 Hua.java

package com.yaogan.liziguo.yaogan;

import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.widget.RelativeLayout;

/**
 * Created by Liziguo on 2018/6/15.
 */

public class Hua extends RelativeLayout implements Runnable{ //繼承RelativeLayout 實現Runnable接口

    private Paint p;//畫筆
    private Move m=new Move();//移動搖桿

     /*
    A 普通攻擊
    Q 技能1
    W 技能2
    E 技能3
    R 沒有R
     */

    public Skill A=new Skill(0,100, BitmapFactory.decodeResource(getResources(),R.mipmap.putonggongji)) {
        @Override
        public void down_main() { }
        @Override
        public void move_main() { }
        @Override
        public void up() { }
    };
    public Skill Q=new Skill(1,1000, BitmapFactory.decodeResource(getResources(),R.mipmap.skill1)) {
        @Override
        public void down_main() { }
        @Override
        public void move_main() { }
        @Override
        public void up() {
            down_main=false;
            if(!cancel){ //技能冷卻時間
                last= System.currentTimeMillis();
            }
        }
    };
    public Skill W=new Skill(2,1000, BitmapFactory.decodeResource(getResources(),R.mipmap.skill2)) {
        @Override
        public void down_main() { }
        @Override
        public void move_main() { }
        @Override
        public void up() {
            down_main=false;
            if(!cancel){
                last= System.currentTimeMillis();
            }
        }
    };
    public Skill E=new Skill(3,1000, BitmapFactory.decodeResource(getResources(),R.mipmap.skill3)) {
        @Override
        public void down_main() { }
        @Override
        public void move_main() { }
        @Override
        public void up() {
            down_main=false;
            if(!cancel){
                last= System.currentTimeMillis();
            }
        }
    };

    public Hua(Context context) {
        super(context);
        p=new Paint();
        setBackgroundColor(Color.BLACK);//背景顏色設爲黑色
        //實例化一個OnTouchMove
        OnTouchMove onTouchMove=new OnTouchMove(context,m);
        //把onTouchMove添加進來 寬度爲屏幕的1/3 高度爲屏幕的1/2
        addView(onTouchMove,my.w/3,my.h/2);
        //設置onTouchMove的位置
        onTouchMove.setX(0);
        onTouchMove.setY(my.h/2);

        //添加技能搖桿監聽
        OnTouchSkill onTouchSkill=new OnTouchSkill(context,A,Q,W,E);//後添加的優先級高
        addView(onTouchSkill);
        onTouchSkill.setX(my.w*0.7f-85*my.bili);
        onTouchSkill.setY(my.h/2-85*my.bili);
        new Thread(this).start();//啓動重繪線程
    }

    @Override
    protected void onDraw(Canvas g) {//重寫onDraw方法
        super.onDraw(g);
        m.onDraw(g,p);//畫移動搖桿
        //畫技能
        A.onDraw(g,p);
        Q.onDraw(g,p);
        W.onDraw(g,p);
        E.onDraw(g,p);
    }

    @Override
    public void run() { //每隔20毫秒刷新一次畫布
        while(true){
            try {Thread.sleep(20);} catch (InterruptedException e) {e.printStackTrace();}
            //計算冷卻時間
            A.next();
            Q.next();
            W.next();
            E.next();
            //釋放技能
            if (my.skill != null) {
                my.skill.down_main();//教程用不到該方法
                my.skill.move_main();//教程用不到該方法
                if (my.skill.down == false) {
                    my.skill.up();
                    my.skill = null;
                }
            }

            postInvalidate();//重繪 在子線程重繪不能調用Invalidate()方法
        }
    }
}

運行下看看效果吧


修改 my.java

public class my { //這個類當一個全局變量使用
    public static int w,h;//屏幕的寬高
    public static float bili;
    public static MainActivity main;
    public static RectF re=new RectF();
    public static int ontouchAlpha=0;//把觸控區透明度改成0

    public static Bitmap border,cancel,down,yaogan,cd;

    public static Skill skill;//當前正在使用的技能
}

再運行下


大功告成

下載地址:https://download.csdn.net/download/u010756046/10482434


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章