1. 程式人生 > >仿掌上英雄聯盟能力值圖形繪制

仿掌上英雄聯盟能力值圖形繪制

坐標 array 程序 mea gre 直接 star super 依據

一,前沿 相信玩擼啊擼的擼友們一定記得掌上英雄聯盟App的能力值吧~~ 好吧,不記得沒關系我來給大家上張圖!

技術分享
所以今天呢我就抽出時間模仿了一下: 照例線來張GIF,有圖有真相 技術分享
以下是我的微博賬號希望能夠關註哈: Email:[email protected] Github: https://github.com/icuihai.

weibo:http://weibo.com/icuihai 二.言歸正傳 在尋常做項目的時候自己定義控件用的還是蠻多的,使用別人造好的輪子比較節省時間,可是作為了一個優雅的程序猿 肯定得學會造輪子給別人用啦,俗話說不裝逼那跟鹹魚有什麽差別~~,這邊文章呢不是輪子。僅僅是一個小小的自己定義view,用到了一些比較基礎的知識,希望對剛開始學習的人有幫助,也希望大牛可以發現錯誤以便及時糾正或者提出更好的idear. 我們從GIF圖能夠看出基本上就是在瞄點和畫線,所以說要想做個合格的程序猿。數學的基本功要夠紮實~~ 1,我們這個用的是正七邊形,所以說我們分析首先畫一根線。然後讓其旋轉能夠得到七條,效果例如以下
技術分享
我去,好醜。

當中調用兩個基本的api就是

canvas.drawLine
canvas.rotate
畫完線之後呢。我們再把外圈連在一起組成一個封閉的圖形 技術分享

之後呢我們在畫內多變形,在此Demo中我們為了省時間僅僅畫了一個1/2內多邊形, 最後我們在依據SeekBar傳過來的值在邊線成瞄點連線。 廢話不多說。直接上代碼: 2,MyView
public class MyView extends View{
    private int startX=720,startY=200;//起始點
    private int centerX=720,centerY=600;//圓心
    private int r=centerY-startY;//半徑
    private String[]str= {"擊殺","生存","助攻","物理","魔法","防禦","金錢"};
    private int dimension;//文字大小
    private float xA,xB,xC,xD,xE,xF,xG;//x軸坐標
    private float yA,yB,yC,yD,yE,yF,yG;//y軸坐標
    private static final int TEXTSIZE=20;
    private float y1,y2,y3,y4,y5,y6,y7,x1,x2,x3,x4,x5,x6,x7;//能力值坐標
    private float pre1=0.2f,pre2=0.2f,pre3=0.2f,pre4=0.2f,pre5=0.2f,pre6=0.2f,pre7=0.2f;//百分率

    public MyView(Context context) {
        this(context,null);
    }

    public MyView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }
    public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
        TypedArray typedArray=context.obtainStyledAttributes(attrs,R.styleable.textSize);
        dimension = (int) typedArray.getDimension(R.styleable.textSize_textsize, TEXTSIZE);
        typedArray.recycle();
    }
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
    private void initView(){
        initData();
    }

上面這些呢主要是構造方法,和一些常量,圓心坐標呢我並沒有對屏幕做適配,而是依據我的模擬器選擇的一個大概的值,大家假設想做的話直接調用WindowManger窗體管理器,或者重寫onMeasure()方法都能夠得到view的寬度去做調整, 3,瞄點
private void initData() {
        //首先A點坐標(其有用不到)
        xA=startX;
        yA=startY;
        //先求出B點的坐標
        xB= (float) (centerX+Math.sin(Math.toRadians(360/7))*r);
        yB= (float) (centerY-Math.cos(Math.toRadians(360/7))*r);
        //在求出C點坐標
        xC= (float) (startX+Math.sin(Math.toRadians(360/7*1.5))*r);
        yC= (float) (centerY+Math.cos(Math.toRadians(360/7*1.5))*r);
        //Log.i("TAG",""+xC+"---"+yC);
        //在求出D點坐標
        xD= (float) (startX+Math.sin(Math.toRadians(360/7/2))*r);
        yD= (float) (centerY+Math.cos(Math.toRadians(360/7/2))*r);
        //於D點水平對稱的E點坐標
        xE=(float) (centerX-Math.sin(Math.toRadians(360/7/2))*r);
        yE= (float) (centerY+Math.cos(Math.toRadians(360/7/2))*r);
        //與C點水平對稱點的坐標F
        xF= (float) (centerX-Math.sin(Math.toRadians(360/7*1.5))*r);
        yF= (float) (centerY+Math.cos(Math.toRadians(360/7*1.5))*r);
        //與B點水平對稱點的坐標G
        xG= (float) (centerX-Math.sin(Math.toRadians(360/7))*r);
        yG= (float) (centerY-Math.cos(Math.toRadians(360/7))*r);
    }
我們這次瞄點是依據角度進行繪制的。應該還有其它方法。PathMeasure這個類應該有api能夠繪制,感興趣的同學能夠去研究下,上面的A點呢就是最上面的那個點,然後呢順時針以此往下, 4。連線(外多邊形)
 @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.save();
        Paint paint=new Paint();
        paint.setColor(Color.GREEN);
        paint.setStrokeWidth(2);
        for (int i = 0; i < 7; i++) {
            canvas.drawLine(startX,startY,centerX,centerY,paint);
            canvas.rotate((float) 360/7,centerX,centerY);
        }
        canvas.restore();
        //畫AB之間的直線
        canvas.drawLine(startX,startY,xB,yB,paint);
        //畫BC之間的直線
        canvas.drawLine(xB,yB,xC,yC,paint);
        //畫BD之間的直線
        canvas.drawLine(xC,yC,xD,yD,paint);
        //畫DE之間的直線
        canvas.drawLine(xD,yD,xE,yE,paint);
        //畫EF之間的直線
        canvas.drawLine(xE,yE,xF,yF,paint);
        //畫FG之間的直線
        canvas.drawLine(xF,yF,xG,yG,paint);
        //畫FA之間的直線
        canvas.drawLine(xG,yG,startX,startY,paint);
點已經喵好了接下來肯定就是把這些點連載一起嘍。代碼凝視的非常清楚對吧~~註意上面這些是最最外面的多邊形

5,連線(畫內多邊形)
//畫內多變形
        canvas.drawLine(startX,centerY-r/2,(xB+startX)/2,yB+(centerY-yB)/2,paint);
        canvas.drawLine((xB+startX)/2,yB+(centerY-yB)/2,(startX+xC)/2,(centerY+yC)/2,paint);
        canvas.drawLine((startX+xC)/2,(centerY+yC)/2,(startX+xD)/2,(centerY+yD)/2,paint);
        canvas.drawLine((startX+xD)/2,(centerY+yD)/2,(startX+xE)/2,(centerY+yE)/2,paint);
        canvas.drawLine((startX+xE)/2,(centerY+yE)/2,(startX+xF)/2,(centerY+yF)/2,paint);
        canvas.drawLine((startX+xF)/2,(centerY+yF)/2,(startX+xG)/2,(centerY+yG)/2,paint);
        canvas.drawLine((startX+xG)/2,(centerY+yG)/2,startX,centerY-r/2,paint);
        canvas.drawLine((startX+xG)/2,(centerY+yG)/2,startX,centerY-r/2,paint);
6。動態的繪制圖形
//順時針依次
        x1=startX;
        y1= (centerY-(pre1*r));

        x2= (float) (startX+Math.sin(Math.toRadians(360/7))*pre2*r);
        y2= (float) (centerY-Math.cos(Math.toRadians(360/7))*pre2*r);

        x3= (float) (startX+Math.sin(Math.toRadians(180-360/7*2))*pre3*r);
        y3= (float) (centerY+Math.cos(Math.toRadians(180-360/7*2))*pre3*r);

        x4= (float) (startX+Math.sin(Math.toRadians(180-360/7*3))*r*pre4);
        y4= (float) (centerY+Math.cos(Math.toRadians(180-360/7*3))*r*pre4);

        x5= (float) (centerX-Math.sin(Math.toRadians(180-360/7*3))*r*pre5);
        y5= (float) (centerY+Math.cos(Math.toRadians(180-360/7*3))*r*pre5);

        x6= (float) (centerX-Math.sin(Math.toRadians(180-360/7*2))*r*pre6);
        y6= (float) (centerY+Math.cos(Math.toRadians(180-360/7*2))*r*pre6);

        x7= (float) (centerX-Math.sin(Math.toRadians(360/7))*r*pre7);
        y7= (float) (centerY-Math.sin(Math.toRadians(90-360/7))*r*pre7);

        mPath.moveTo(x7,y7);//把起點設置為7點能夠使圖形封閉
        mPath.lineTo(x1,y1);
        mPath.lineTo(x2,y2);
        mPath.lineTo(x3,y3);
        mPath.lineTo(x4,y4);
        mPath.lineTo(x5,y5);
        mPath.lineTo(x6,y6);
        mPath.lineTo(x7,y7);

        // 繪制路徑
        canvas.drawPath(mPath, mPaint);
        //mPath.close(); //封閉曲線
        invalidate();

pre代表SeekBar滑動的值/最大值,由於我用了mPath.moveTo(x7,y7);所以不須要在調用mPath.close()了。它是能夠是線條首尾連在一起組成一個封閉的圖形,註意上面這些都要用float值,由於這些角度大部分都是float值,假設用int的話會讓圖片看起來有一定的偏差,我也截了一張錯誤的圖大家細致看一下是有差別的: 技術分享

好了基本上就這些了,其它的代碼我就不貼出來了,不然看起來太長了,完整的代碼我會放在github上,https://github.com/icuihai/LolCustomView ,喜歡的能夠給個star,感謝

仿掌上英雄聯盟能力值圖形繪制