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

   2016-11-10 0
核心提示:一,前沿相信玩撸啊撸的撸友们一定记得掌上英雄联盟App的能力值吧~~ 好吧,不记得没关系我来给大家上张图!!所以今天呢我就抽空模仿了一下:照例线来张GIF,有图有真相下面是我的微博账号希望可以关注哈:Email:icuihai@aliyun.com.Github: https://github.c

一,前沿

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

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

所以今天呢我就抽空模仿了一下:

照例线来张GIF,有图有真相

下面是我的微博账号希望可以关注哈:

Email:icuihai@aliyun.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,感谢

 
标签: 安卓开发
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • 安卓中通知功能的具体实现
    安卓中通知功能的具体实现
    通知[Notification]是Android中比较有特色的功能,当某个应用程序希望给用户发出一些提示信息,而该应用程序又不在前台运行时,就可以借助通知实现。使用通知的步骤1、需要一个NotificationManager来获得NotificationManager manager = (NotificationManager
    02-05 安卓开发
  • Android view系统分析-setContentView
    Android view系统分析-setContentView
    第一天上班,列了一下今年要学习的东西。主要就是深入学习Android相关的系统源代码,夯实基础。对于学习Android系统源代码,也没什么大概,就从我们平常使用最基础的东西学起,也就是从view这个切入点开始学习Android的源码,在没分析源码之前,我们有的时候
    02-05 安卓开发
  • 如何进行网络视频截图/获取视频的缩略图
    如何进行网络视频截图/获取视频的缩略图
    小编导读:获取视频的缩略图,截图正在播放的视频某一帧,是在音视频开发中,常遇到的问题。本文是主要用于点播中截图视频,同时还可以获取点播视频的缩略图进行显示,留下一个问题,如下图所示, 如果要获取直播中节目视频缩略图,该怎么做呢?(ps:直播是直
  • Android NDK 层发起 HTTP 请求的问题及解决
    Android NDK 层发起 HTTP 请求的问题及解决
    前言新的一年,大家新年快乐~~鸡年大吉!本次给大家带来何老师的最新文章~虽然何老师还在过节,但依然放心不下广大开发者,在此佳节还未结束之际,给大家带来最新的技术分享~ 事件的起因不说了,总之是需要实现一个 NDK 层的网络请求。为了多端适用,还是选择
  • Android插件化(六): OpenAtlasの改写aapt以防止资源ID冲突
    Android插件化(六): OpenAtlasの改写aapt以防
    引言Android应用程序的编译中,负责资源打包的是aapt,如果不对打包后的资源ID进行控制,就会导致插件中的资源ID冲突。所以,我们需要改写aapt的源码,以达到通过某种方式传递资源ID的Package ID,通过aapt打包时获取到这个Package ID并且应用才插件资源的命名
    02-05 安卓开发
  • Android架构(一)MVP架构在Android中的实践
    Android架构(一)MVP架构在Android中的实践
    为什么要重视程序的架构设计 对程序进行架构设计的原因,归根结底是为了 提高生产力 。通过设计是程序模块化,做到模块内部的 高聚合 和模块之间的 低耦合 (如依赖注入就是低耦合的集中体现)。 这样做的好处是使得程序开发过程中,开发人员主需要专注于一点,
    02-05 安卓开发
  • 安卓逆向系列教程 4.2 分析锁机软件
    安卓逆向系列教程 4.2 分析锁机软件
    安卓逆向系列教程 4.2 分析锁机软件 作者: 飞龙 这个教程中我们要分析一个锁机软件。像这种软件都比较简单,完全可以顺着入口看下去,但我这里还是用关键点来定位。首先这个软件的截图是这样,进入这个界面之后,除非退出模拟器,否则没办法回到桌面。上面那
    02-05 安卓开发
  • Android插件化(二):OpenAtlas插件安装过程分析
    Android插件化(二):OpenAtlas插件安装过程分析
    在前一篇博客 Android插件化(一):OpenAtlas架构以及实现原理概要 中,我们对应Android插件化存在的问题,实现原理,以及目前的实现方案进行了简单的叙述。从这篇开始,我们要深入到OpenAtlas的源码中进行插件安装过程的分析。 插件的安装分为3种:宿主启动时立
    02-05 安卓开发
  • [译] Android API 指南
    [译] Android API 指南
    众所周知,Android开发者有中文网站了,API 指南一眼看去最左侧的菜单都是中文,然而点进去内容还是很多是英文,并没有全部翻译,我这里整理了API 指南的目录,便于查看,如果之前还没有通读,现在可以好好看一遍。注意,如果标题带有英文,说明官方还没有翻
  • 使用FileProvider解决file:// URI引起的FileUriExposedException
    使用FileProvider解决file:// URI引起的FileUri
    问题以下是一段简单的代码,它调用系统的相机app来拍摄照片:void takePhoto(String cameraPhotoPath) {File cameraPhoto = new File(cameraPhotoPath);Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);takePhotoIntent.putExtra(Medi
    02-05 安卓开发
点击排行