Android自定义View--螺旋丸
0.前言
最近在做游戏,所以博客就改成双周更了。诚恳的地说,我不是一个火影迷,初中的时候看了几集,高中的时候看了几集,然后就拉倒了。我觉得嘴遁鸣人的螺旋丸挺不错的,今天准备做一个9.9元包邮版螺旋丸。看效果图
1.分析
1.1这个球是个立体的
立体的话这里采用opengl es进行实现
1.2球分三层
最里面是白色,碗面浅蓝,再者更蓝,最后是白色线段框架
1.3球要旋转
螺旋丸螺旋丸,自然得转圈了
2.代码
2.1绘制球体
HelicalCircle是主体,包括program和shader的创建,球坐标的创建,最后的绘制
2.1.1准备球体坐标
private fun preparePosList() {var x0 = 0fvar y0 = 0fvar z0 = radiusvar x1 = 0fvar y1 = 0fvar z1 = radiusval h = 360 / precisionval v = 360 / precisionfor (i in 0 until h) {val arc0 = Math.PI / 180 * i * precisionval arc1 = Math.PI / 180 * (i + 1) * precisiony0 = (radius * Math.cos(arc0)).toFloat()y1 = (radius * Math.cos(arc1)).toFloat()for (j in 0 until v) {val arc = Math.PI / 180 * j * precisionx0 = (radius * Math.sin(arc0) * sin(arc)).toFloat()z0 = (radius * Math.sin(arc0) * cos(arc)).toFloat()x1 = (radius * Math.sin(arc1) * sin(arc)).toFloat()z1 = (radius * Math.sin(arc1) * cos(arc)).toFloat()posList.add(x0)posList.add(y0)posList.add(z0)posList.add(x1)posList.add(y1)posList.add(z1)}}pos= posList.toFloatArray()}
复制代码
这段代码生成了一个float数组,就是每个球体上点的坐标。这里采用的是球坐标,原理很简单,你可以把球体横向按照precision为梯度进行横切,然后每个切面也按照precision进行竖切,每个点的坐标计算出来后添加进一个List然后转换为float数组。
2.1.2准备program和shader
private val vertexSlgl="#version 300 es\n" +"\n" +"layout(location=0) in vec3 pos;\n" +"uniform mat4 model;\n" +"uniform mat4 view;\n" +"uniform mat4 projection;\n" +"void main()\n" +"{\n" +" gl_Position=projection*view*model*vec4(pos,1.0);\n" +"}"private val fragmentSlgl="#version 300 es\n" +"precision mediump float;\n" +"uniform vec4 aColor;\n" +"out vec4 fragColor;\n" +"void main()\n" +"{\n" +" fragColor=aColor;\n" +"}"private fun prepareProgram(){programId = createProgram(vertexSlgl, fragmentSlgl)val vaoArray = IntArray(1)GLES30.glGenVertexArrays(1, vaoArray, 0)VAO = vaoArray[0]GLES30.glBindVertexArray(VAO)val vboArray = IntArray(1)GLES30.glGenBuffers(1, vboArray, 0)VBO = vboArray[0]GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, VBO)val posBuffer = ByteBuffer.allocateDirect(4 * pos.size).order(ByteOrder.nativeOrder()).asFloatBuffer()posBuffer.put(pos)posBuffer.position(0)GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, 4 * pos.size, posBuffer, GLES30.GL_STATIC_DRAW)GLES30.glVertexAttribPointer(0, 3, GLES30.GL_FLOAT, false, 3 * 4, 0)GLES30.glEnableVertexAttribArray(0)}private fun createProgram(vertexSource: String, fragmentSource: String): Int {val vertexShader = createShader(GLES30.GL_VERTEX_SHADER, vertexSource)val fragmentShader = createShader(GLES30.GL_FRAGMENT_SHADER, fragmentSource)return createProgram(vertexShader, fragmentShader)}private fun createShader(type: Int, source: String): Int {val shaderId = GLES30.glCreateShader(type)if (shaderId <= 0) {Log.d(TAG, "create shader failed")}GLES30.glShaderSource(shaderId, source)GLES30.glCompileShader(shaderId)val status = IntArray(1)GLES30.glGetShaderiv(shaderId, GLES30.GL_COMPILE_STATUS, status, 0)if (status[0] <= 0) {Log.d(TAG, "compile shader failed")val infoLog = GLES30.glGetShaderInfoLog(shaderId)Log.d(TAG, infoLog)GLES30.glDeleteShader(shaderId)}return shaderId}private fun createProgram(vertexShader: Int, fragmentShader: Int): Int {val programId = GLES30.glCreateProgram()if (programId <= 0) {Log.d(TAG, "create program failed")}GLES30.glAttachShader(programId, vertexShader)GLES30.glAttachShader(programId, fragmentShader)GLES30.glLinkProgram(programId)val status = IntArray(1)GLES30.glGetProgramiv(programId, GLES30.GL_LINK_STATUS, status, 0)if (status[0] <= 0) {Log.d(TAG, "link program failed")val infoLog = GLES30.glGetProgramInfoLog(programId)Log.d(TAG, infoLog)}return programId}复制代码
这段代码就是创建shader和program,很简单,没什么可说的。
2.1.2绘制
fun draw(aspect:Float,r:Float=0.0f,g:Float=0.0f,b:Float=1.0f,a:Float=0.5f,scale:Float=1.0f){degree+=10GLES30.glUseProgram(programId)val colorLocation=GLES30.glGetUniformLocation(programId,"aColor")GLES30.glUniform4f(colorLocation,r,g,b,a)val modelMatrixLocation=GLES30.glGetUniformLocation(programId,"model")Matrix.setIdentityM(modelMatrix,0)Matrix.scaleM(modelMatrix,0,scale,scale,scale)Matrix.rotateM(modelMatrix,0, Math.toRadians(degree).toFloat(),0f,1f,0f)GLES30.glUniformMatrix4fv(modelMatrixLocation,1,false,modelMatrix,0)val viewMatrixLocation=GLES30.glGetUniformLocation(programId,"view")Matrix.setLookAtM(viewMatrix,0,0f,0f,10f,0f,0f,0f,0f,1f,0f)GLES30.glUniformMatrix4fv(viewMatrixLocation,1,false,viewMatrix,0)val projectionMatrixLocation=GLES30.glGetUniformLocation(programId,"projection")Matrix.perspectiveM(projectionMatrix,0,45.0f, aspect,0.1f,100f)GLES30.glUniformMatrix4fv(projectionMatrixLocation,1,false,projectionMatrix,0)GLES30.glDrawArrays(model,0,pos.size / 3)}}
复制代码
绘制球体,设置球体颜色和缩放程度
2.HelicalCircleRender
override fun onSurfaceCreated(gl: GL10?, config: EGLConfig?) {helicalCircle.prepare()}override fun onSurfaceChanged(gl: GL10?, width: Int, height: Int) {GLES30.glViewport(0, 0, width, height)screenWidth = width.toFloat()screenHeight = height.toFloat()}override fun onDrawFrame(gl: GL10?) {GLES30.glEnable(GLES30.GL_BLEND)GLES30.glClearColor(0f,0f,0f,1.0f)GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT or GLES30.GL_DEPTH_BUFFER_BIT)val aspect=screenWidth / screenHeightGLES30.glDisable(GLES30.GL_DEPTH_TEST)helicalCircle.model=GLES30.GL_TRIANGLE_STRIPhelicalCircle.draw(aspect,r=0.67f,g=0.85f,b=0.98f,a=0.5f,scale = 0.99f*scale)helicalCircle.draw(aspect,r=0.85f,g=0.96f,b=0.99f,a=0.5f,scale= 0.5f*scale)helicalCircle.draw(aspect,r=0.97f,g=1.0f,b=0.99f,a=0.5f,scale= 0.3f*scale)GLES30.glEnable(GLES30.GL_DEPTH_TEST)helicalCircle.model=GLES30.GL_LINE_STRIPhelicalCircle.draw(aspect,r=1.0f,g=1.0f,b=1.0f,a=0.2f,scale = 0.998f*scale)}
复制代码
onSurfaceCreated里进行球坐标的计算和program以及shader的准备,在onDrawFrame里绘制三个球
2.3旋转
override fun onTouchEvent(event: MotionEvent?): Boolean {when(event?.action){MotionEvent.ACTION_DOWN->{touchX=event.x}MotionEvent.ACTION_MOVE->{val scaleOffset=(event.x-touchX)/widthrender.scale+=scaleOffsettouchX=event.x}}return true}
复制代码
复写HelicalCircleView的onTouchEvent方法,通过修改HelicalCircleRender的scale来对球体进行缩放。
3源码
github
关注我的公众号
Android自定义View--螺旋丸相关推荐
- Android自定义View —— TypedArray
在上一篇中Android 自定义View Canvas -- Bitmap写到了TypedArray 这个属性 下面也简单的说一下TypedArray的使用 TypedArray 的作用: 用于从该结 ...
- Android 自定义View —— Canvas
上一篇在android 自定义view Paint 里面 说了几种常见的Point 属性 绘制图形的时候下面总有一个canvas ,Canvas 是是画布 上面可以绘制点,线,正方形,圆,等等,需要和 ...
- android自定义view获取控件,android 自定义控件View在Activity中使用findByViewId得到结果为null...
转载:http://blog.csdn.net/xiabing082/article/details/48781489 1. 大家常常自定义view,,然后在xml 中添加该view 组件..如果在 ...
- Android自定义View:ViewGroup(三)
自定义ViewGroup本质是什么? 自定义ViewGroup本质上就干一件事--layout. layout 我们知道ViewGroup是一个组合View,它与普通的基本View(只要不是ViewG ...
- android 自定义图形,Android自定义View之图形图像(模仿360的刷新球自定
概述: 360安全卫士的那个刷新球(姑且叫它刷新球,因为真的不知道叫什么好,不是dota里的刷新球!!),里面像住了水一样,生动可爱,看似简单,写起来不太简单,本例程只是实现了它的部分功能而已,说实话 ...
- android代码实现手机加速功能,Android自定义View实现内存清理加速球效果
Android自定义View实现内存清理加速球效果 发布时间:2020-09-21 22:21:57 来源:脚本之家 阅读:105 作者:程序员的自我反思 前言 用过猎豹清理大师或者相类似的安全软件, ...
- android中仿qq最新版抽屉,Android 自定义View实现抽屉效果
Android 自定义View实现抽屉效果 说明 这个自定义View,没有处理好多点触摸问题 View跟着手指移动,没有采用传统的scrollBy方法,而是通过不停地重新布局子View的方式,来使得子 ...
- Android 自定义 圆环,Android自定义view实现圆环效果实例代码
先上效果图,如果大家感觉不错,请参考实现代码. 重要的是如何实现自定义的view效果 (1)创建类,继承view,重写onDraw和onMesure方法 public class CirclePerc ...
- android自定义抽奖,Android自定义view制作抽奖转盘
本文实例为大家分享了Android自定义view制作抽奖转盘的具体代码,供大家参考,具体内容如下 效果图 TurntableActivity package com.bawei.myapplicati ...
- android view 渐变动画,Android自定义view渐变圆形动画
本文实例为大家分享了Android自定义view渐变圆形动画的具体代码,供大家参考,具体内容如下 直接上效果图 自定义属性 attrs.xml文件 创建一个类 ProgressRing继承自 view ...
最新文章
- perl dancer + net::ssh2监控服务器性能
- histeq函数实现直方图的均衡化和规定化
- 三星专业级360度视频拍摄设备登场,能直接传输3D VR视频
- 【随笔】“阴面”和“阳面”
- NLB+Cluster(一)
- Excel表哥表姐如何突破职业天花板?我有两个忠告
- 自动化系统计算机网络期末考试题,模拟试卷_计算机网络试题B-自动化-孙璐
- python下载网页中的pdf文件_Python读取网页上的pdf文件,输出字符串
- java零碎要点012---linux Centos下编译、运行、调试java程序
- CentOS6.5 环境安装配置
- python 皮尔森相关系数(Pearson)
- 《The Selfish Giant》
- 3rd Batch请查收!您的问题解答清单
- Quorum简介部署
- 你真的会用苹果备忘录吗?iPhone用户必须学会的10个备忘录使用技巧
- IE浏览器提示代理服务器没有响应,但是360浏览器可以用
- 【C++面试必备】一个专栏带你搞定剑指offer第二版
- Resistors in Parallel(Gym - 102028E 2018 ICPC 焦作E题 大数+规律C++版)
- 宠物领养系统C语言代码,基于JavaEE的宠物领养系统的设计与实现毕业论文+任务书+中期表+外文翻译及原文+答辩PPT+项目源码及数据库+运行说明...
- 周鸿祎力荐|纽约客16000字重磅刊文:区块链是回归互联网本质的唯一希望
热门文章
- 商品房买卖纠纷适用什么样的诉讼时效?
- Android开发 精美Gallery图册
- HTML中横线的使用
- 汇报工作是技术活,其中艺术你可知道?
- Webots安装教程
- jmeter使用之文件读取
- android音乐播放器扫描本地,简单实现Android本地音乐播放器
- 计算机专业选学经济系,高考咋选专业?看福布斯排行榜就知道了,跟着“大佬”走吃不了亏...
- 那些值得学习的C++框架和常用库
- 鸿蒙麒麟安卓骁龙IOS,华为用户“福利”!这10款麒麟芯片手机,能升级鸿蒙OS3.0!...