zoukankan      html  css  js  c++  java
  • 仿掌上英雄联盟能力值图形绘制

    一,前沿
    相信玩撸啊撸的撸友们一定记得掌上英雄联盟App的能力值吧~~ 好吧,不记得没关系我来给大家上张图!


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

    以下是我的微博账号希望能够关注哈:
    Email:icuihai@gmail.com.
    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,感谢
  • 相关阅读:
    推荐19个很有用的 JavaScript 库
    李开复:我对年轻人是分享经验 不是要当导师
    DotNET企业架构应用实践数据库表记录的唯一性设计的设计兼议主键设定原则
    cookies,session,viewstate浅析
    不是HR,Leader你到底需要招什么样的程序员(变形金刚?超人?可能吗!)
    IBatis.Net学习笔记系列文章
    学习mvc的一些资料
    数据库日常维护常用的脚本部分收录
    设定Grid行的颜色
    被WSS3.0耍了一把
  • 原文地址:https://www.cnblogs.com/yutingliuyl/p/7399772.html
Copyright © 2011-2022 走看看