仿掌上英雄联盟能力值图形绘制

来源:互联网 发布:centos 安装php 编辑:程序博客网 时间:2024/04/28 09:47
一,前沿
相信玩撸啊撸的撸友们一定记得掌上英雄联盟App的能力值吧~~ 好吧,不记得没关系我来给大家上张图!!

所以今天呢我就抽空模仿了一下:
照例线来张GIF,有图有真相

下面是我的微博账号希望可以关注哈:
Email:icuihai@gmail.com.
Github: https://github.com/icuihai.
weibo:http://weibo.com/icuihai
二.言归正传
在平常做项目的时候自定义控件用的还是蛮多的,使用别人造好的轮子比较节省时间,但是作为了一个优雅的程序员
肯定得学会造轮子给别人用啦,俗话说不装逼那跟咸鱼有什么区别~~,这边文章呢不是轮子,只是一个小小的自定义view,用到了一些比较基础的知识,希望对初学者有帮助,也希望大牛能够发现错误以便及时纠正或者提出更好的idear.
我们从GIF图可以看出基本上就是在瞄点和画线,所以说要想做个合格的程序员,数学的基本功要够扎实~~
1,我们这个用的是正七边形,所以说我们分析首先画一根线,然后让其旋转可以得到七条,效果如下

我去,好丑。。。
其中调用两个主要的api就是
canvas.drawLinecanvas.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,感谢
4 0
原创粉丝点击