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--螺旋丸相关推荐

  1. Android自定义View —— TypedArray

    在上一篇中Android 自定义View Canvas -- Bitmap写到了TypedArray 这个属性 下面也简单的说一下TypedArray的使用 TypedArray 的作用: 用于从该结 ...

  2. Android 自定义View —— Canvas

    上一篇在android 自定义view Paint 里面 说了几种常见的Point 属性 绘制图形的时候下面总有一个canvas ,Canvas 是是画布 上面可以绘制点,线,正方形,圆,等等,需要和 ...

  3. android自定义view获取控件,android 自定义控件View在Activity中使用findByViewId得到结果为null...

    转载:http://blog.csdn.net/xiabing082/article/details/48781489 1.  大家常常自定义view,,然后在xml 中添加该view 组件..如果在 ...

  4. Android自定义View:ViewGroup(三)

    自定义ViewGroup本质是什么? 自定义ViewGroup本质上就干一件事--layout. layout 我们知道ViewGroup是一个组合View,它与普通的基本View(只要不是ViewG ...

  5. android 自定义图形,Android自定义View之图形图像(模仿360的刷新球自定

    概述: 360安全卫士的那个刷新球(姑且叫它刷新球,因为真的不知道叫什么好,不是dota里的刷新球!!),里面像住了水一样,生动可爱,看似简单,写起来不太简单,本例程只是实现了它的部分功能而已,说实话 ...

  6. android代码实现手机加速功能,Android自定义View实现内存清理加速球效果

    Android自定义View实现内存清理加速球效果 发布时间:2020-09-21 22:21:57 来源:脚本之家 阅读:105 作者:程序员的自我反思 前言 用过猎豹清理大师或者相类似的安全软件, ...

  7. android中仿qq最新版抽屉,Android 自定义View实现抽屉效果

    Android 自定义View实现抽屉效果 说明 这个自定义View,没有处理好多点触摸问题 View跟着手指移动,没有采用传统的scrollBy方法,而是通过不停地重新布局子View的方式,来使得子 ...

  8. Android 自定义 圆环,Android自定义view实现圆环效果实例代码

    先上效果图,如果大家感觉不错,请参考实现代码. 重要的是如何实现自定义的view效果 (1)创建类,继承view,重写onDraw和onMesure方法 public class CirclePerc ...

  9. android自定义抽奖,Android自定义view制作抽奖转盘

    本文实例为大家分享了Android自定义view制作抽奖转盘的具体代码,供大家参考,具体内容如下 效果图 TurntableActivity package com.bawei.myapplicati ...

  10. android view 渐变动画,Android自定义view渐变圆形动画

    本文实例为大家分享了Android自定义view渐变圆形动画的具体代码,供大家参考,具体内容如下 直接上效果图 自定义属性 attrs.xml文件 创建一个类 ProgressRing继承自 view ...

最新文章

  1. perl dancer + net::ssh2监控服务器性能
  2. histeq函数实现直方图的均衡化和规定化
  3. 三星专业级360度视频拍摄设备登场,能直接传输3D VR视频
  4. 【随笔】“阴面”和“阳面”
  5. NLB+Cluster(一)
  6. Excel表哥表姐如何突破职业天花板?我有两个忠告
  7. 自动化系统计算机网络期末考试题,模拟试卷_计算机网络试题B-自动化-孙璐
  8. python下载网页中的pdf文件_Python读取网页上的pdf文件,输出字符串
  9. java零碎要点012---linux Centos下编译、运行、调试java程序
  10. CentOS6.5 环境安装配置
  11. python 皮尔森相关系数(Pearson)
  12. 《The Selfish Giant》
  13. 3rd Batch请查收!您的问题解答清单
  14. Quorum简介部署
  15. 你真的会用苹果备忘录吗?iPhone用户必须学会的10个备忘录使用技巧
  16. IE浏览器提示代理服务器没有响应,但是360浏览器可以用
  17. 【C++面试必备】一个专栏带你搞定剑指offer第二版
  18. Resistors in Parallel(Gym - 102028E 2018 ICPC 焦作E题 大数+规律C++版)
  19. 宠物领养系统C语言代码,基于JavaEE的宠物领养系统的设计与实现毕业论文+任务书+中期表+外文翻译及原文+答辩PPT+项目源码及数据库+运行说明...
  20. 周鸿祎力荐|纽约客16000字重磅刊文:区块链是回归互联网本质的唯一希望

热门文章

  1. 商品房买卖纠纷适用什么样的诉讼时效?
  2. Android开发 精美Gallery图册
  3. HTML中横线的使用
  4. 汇报工作是技术活,其中艺术你可知道?
  5. Webots安装教程
  6. jmeter使用之文件读取
  7. android音乐播放器扫描本地,简单实现Android本地音乐播放器
  8. 计算机专业选学经济系,高考咋选专业?看福布斯排行榜就知道了,跟着“大佬”走吃不了亏...
  9. 那些值得学习的C++框架和常用库
  10. 鸿蒙麒麟安卓骁龙IOS,华为用户“福利”!这10款麒麟芯片手机,能升级鸿蒙OS3.0!...