仿掌上英雄聯盟能力值圖形繪制
阿新 • • 發佈:2017-08-20
坐標 array 程序 mea gre 直接 star super 依據
一,前沿
相信玩擼啊擼的擼友們一定記得掌上英雄聯盟App的能力值吧~~ 好吧,不記得沒關系我來給大家上張圖!
所以今天呢我就抽出時間模仿了一下: 照例線來張GIF,有圖有真相
以下是我的微博賬號希望能夠關註哈: Email:[email protected] Github: https://github.com/icuihai.
weibo:http://weibo.com/icuihai
二.言歸正傳
在尋常做項目的時候自己定義控件用的還是蠻多的,使用別人造好的輪子比較節省時間,可是作為了一個優雅的程序猿
肯定得學會造輪子給別人用啦,俗話說不裝逼那跟鹹魚有什麽差別~~,這邊文章呢不是輪子。僅僅是一個小小的自己定義view,用到了一些比較基礎的知識,希望對剛開始學習的人有幫助,也希望大牛可以發現錯誤以便及時糾正或者提出更好的idear.
我們從GIF圖能夠看出基本上就是在瞄點和畫線,所以說要想做個合格的程序猿。數學的基本功要夠紮實~~
1,我們這個用的是正七邊形,所以說我們分析首先畫一根線。然後讓其旋轉能夠得到七條,效果例如以下
我去,好醜。
之後呢我們在畫內多變形,在此Demo中我們為了省時間僅僅畫了一個1/2內多邊形, 最後我們在依據SeekBar傳過來的值在邊線成瞄點連線。 廢話不多說。直接上代碼: 2,MyView
上面這些呢主要是構造方法,和一些常量,圓心坐標呢我並沒有對屏幕做適配,而是依據我的模擬器選擇的一個大概的值,大家假設想做的話直接調用WindowManger窗體管理器,或者重寫onMeasure()方法都能夠得到view的寬度去做調整, 3,瞄點
5,連線(畫內多邊形)
pre代表SeekBar滑動的值/最大值,由於我用了mPath.moveTo(x7,y7);所以不須要在調用mPath.close()了。它是能夠是線條首尾連在一起組成一個封閉的圖形,註意上面這些都要用float值,由於這些角度大部分都是float值,假設用int的話會讓圖片看起來有一定的偏差,我也截了一張錯誤的圖大家細致看一下是有差別的:
好了基本上就這些了,其它的代碼我就不貼出來了,不然看起來太長了,完整的代碼我會放在github上,https://github.com/icuihai/LolCustomView ,喜歡的能夠給個star,感謝
!
所以今天呢我就抽出時間模仿了一下: 照例線來張GIF,有圖有真相
以下是我的微博賬號希望能夠關註哈: Email:[email protected] Github: https://github.com/icuihai.
我去,好醜。
。
。
當中調用兩個基本的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,感謝
仿掌上英雄聯盟能力值圖形繪制