山寨腾讯“爱消除”游戏之生命特效
来源:互联网 发布:淘宝信用中差评查询 编辑:程序博客网 时间:2024/06/08 18:26
【广而告之】山寨腾讯“爱消除”游戏已经正式入驻GitHub,项目地址是:https://github.com/3125788/CrazyLink
欢迎广大寨友一起来完善这个游戏。
好了,山寨了那么久,今天开始,我们自己也要来点创新的东西了。
今天我们就为山寨“爱消除”游戏加上生命指示器的效果。所谓生命指示器,就是告诉玩家当前还剩余几条命。好,废话不多说,直接上图。
多于三条命时的效果如下,数字5代表5条命,三颗星星代表三条命,总共8条命。
当生命不足三条时的效果如下,这里只剩下两条命了。
详细的代码在DrawLife渲染类中。调用 public void draw(GL10 gl, int life)传入生命数,就可以将生命指示器渲染出来了。
public class DrawLife {private IntBuffer mLifeVertexBuffer;//顶点坐标数据缓冲private IntBuffer mNumVertexBuffer;//顶点坐标数据缓冲 private FloatBuffer mLifeTextureBuffer;//顶点纹理数据缓冲 private FloatBuffer mNumTextureBuffer;//顶点纹理数据缓冲 int vCount=0;//顶点数量 int textureId;//纹理索引 int numTextureId; final int mBitmapW = 64; final int mBitmapH = 32; final int mFontSize = 24;//字体大小 float textureRatio;//为了准确获取纹理图片中的素材对象,需要设置纹理的变换率 public DrawLife(GL10 gl, int textureId) { this.textureId=textureId; initNumTextureBuffer(); int[] textures = new int[1];gl.glGenTextures(1, textures, 0);this.numTextureId = textures[0]; }//顶点坐标数据的初始化 private void initVertexBuffer(int col) { int w = 16; int h = 16; vCount=6;//顶点的数量,一个正方形用两个三角形表示,共需要6个顶点 int deltaX = ((col + 2)*2*w*CrazyLinkConstent.UNIT_SIZE); int deltaY = 10*2*h*CrazyLinkConstent.UNIT_SIZE; int vertices[]=new int[]//顶点坐标数据数组 { -w*CrazyLinkConstent.UNIT_SIZE+deltaX,h*CrazyLinkConstent.UNIT_SIZE+deltaY,0, -w*CrazyLinkConstent.UNIT_SIZE+deltaX,-h*CrazyLinkConstent.UNIT_SIZE+deltaY,0, w*CrazyLinkConstent.UNIT_SIZE+deltaX,-h*CrazyLinkConstent.UNIT_SIZE+deltaY,0, w*CrazyLinkConstent.UNIT_SIZE+deltaX,-h*CrazyLinkConstent.UNIT_SIZE+deltaY,0, w*CrazyLinkConstent.UNIT_SIZE+deltaX,h*CrazyLinkConstent.UNIT_SIZE+deltaY,0, -w*CrazyLinkConstent.UNIT_SIZE+deltaX,h*CrazyLinkConstent.UNIT_SIZE+deltaY,0 }; //创建顶点坐标数据缓冲 //int类型占用4个字节,因此转换为byte的数据时需要*4 ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4); vbb.order(ByteOrder.nativeOrder());//设置本地的字节顺序 //特别提示:由于不同平台字节顺序不同数据单元不是字节的一定要经过ByteBuffer //转换,关键是要通过ByteOrder设置nativeOrder(),否则有可能会出问题 mLifeVertexBuffer = vbb.asIntBuffer();//转换为int型缓冲 mLifeVertexBuffer.put(vertices);//向缓冲区中放入顶点坐标数据 mLifeVertexBuffer.position(0);//设置缓冲区起始位置 return; } private void initNumVertexBuffer() { vCount=6;//顶点的数量,一个正方形用两个三角形表示,共需要6个顶点 float deltaX = 160*CrazyLinkConstent.UNIT_SIZE;//((col-3)*64*CrazyLinkConstent.UNIT_SIZE); float deltaY = 320*CrazyLinkConstent.UNIT_SIZE;//(((float)row-3 + y)*64*CrazyLinkConstent.UNIT_SIZE); int vertices[]=new int[]//顶点坐标数据数组 { -mBitmapW/2*CrazyLinkConstent.UNIT_SIZE+(int)deltaX,mBitmapH/2*CrazyLinkConstent.UNIT_SIZE+(int)deltaY,0, -mBitmapW/2*CrazyLinkConstent.UNIT_SIZE+(int)deltaX,-mBitmapH/2*CrazyLinkConstent.UNIT_SIZE+(int)deltaY,0, mBitmapW/2*CrazyLinkConstent.UNIT_SIZE+(int)deltaX,-mBitmapH/2*CrazyLinkConstent.UNIT_SIZE+(int)deltaY,0, mBitmapW/2*CrazyLinkConstent.UNIT_SIZE+(int)deltaX,-mBitmapH/2*CrazyLinkConstent.UNIT_SIZE+(int)deltaY,0, mBitmapW/2*CrazyLinkConstent.UNIT_SIZE+(int)deltaX,mBitmapH/2*CrazyLinkConstent.UNIT_SIZE+(int)deltaY,0, -mBitmapW/2*CrazyLinkConstent.UNIT_SIZE+(int)deltaX,mBitmapH/2*CrazyLinkConstent.UNIT_SIZE+(int)deltaY,0 }; //创建顶点坐标数据缓冲 //int类型占用4个字节,因此转换为byte的数据时需要*4 ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4); vbb.order(ByteOrder.nativeOrder());//设置本地的字节顺序 //特别提示:由于不同平台字节顺序不同数据单元不是字节的一定要经过ByteBuffer //转换,关键是要通过ByteOrder设置nativeOrder(),否则有可能会出问题 mNumVertexBuffer = vbb.asIntBuffer();//转换为int型缓冲 mNumVertexBuffer.put(vertices);//向缓冲区中放入顶点坐标数据 mNumVertexBuffer.position(0);//设置缓冲区起始位置 return; } //顶点纹理数据的初始化 private void initTextureBuffer(int witch) { textureRatio = (float)(1/2.0f);//图片是2个独立的素材对象组成,每次需要根据witch准确地获取对应的素材 float textureCoors[]=new float[]//顶点纹理S、T坐标值数组 { witch * textureRatio,0, witch * textureRatio,1, (witch+1) * textureRatio,1, (witch+1) * textureRatio,1, (witch+1) * textureRatio,0, witch * textureRatio,0 }; //创建顶点纹理数据缓冲 //int类型占用4个字节,因此转换为byte的数据时需要*4 ByteBuffer cbb = ByteBuffer.allocateDirect(textureCoors.length*4); cbb.order(ByteOrder.nativeOrder());//设置本地字节顺序 //特别提示:由于不同平台字节顺序不同数据单元不是字节的一定要经过ByteBuffer //转换,关键是要通过ByteOrder设置nativeOrder(),否则有可能会出问题 mLifeTextureBuffer = cbb.asFloatBuffer();//转换为int型缓冲 mLifeTextureBuffer.put(textureCoors);//向缓冲区中放入顶点着色数据 mLifeTextureBuffer.position(0);//设置缓冲区起始位置 return; } private void initNumTextureBuffer() { float textureCoors[]=new float[]//顶点纹理S、T坐标值数组 { 0,0, 0,1, 1,1, 1,1, 1,0, 0,0 }; //创建顶点纹理数据缓冲 //int类型占用4个字节,因此转换为byte的数据时需要*4 ByteBuffer cbb = ByteBuffer.allocateDirect(textureCoors.length*4); cbb.order(ByteOrder.nativeOrder());//设置本地字节顺序 //特别提示:由于不同平台字节顺序不同数据单元不是字节的一定要经过ByteBuffer //转换,关键是要通过ByteOrder设置nativeOrder(),否则有可能会出问题 mNumTextureBuffer = cbb.asFloatBuffer();//转换为int型缓冲 mNumTextureBuffer.put(textureCoors);//向缓冲区中放入顶点着色数据 mNumTextureBuffer.position(0);//设置缓冲区起始位置 return; } private void bindTexture(GL10 gl, Bitmap bmp){gl.glBindTexture(GL10.GL_TEXTURE_2D, numTextureId);gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);//指定缩小过滤方法gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);//指定放大过滤方法gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);//指定S坐标轴贴图模式gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);//指定T坐标轴贴图模式GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);bmp.recycle();}Bitmap genBitmap(int life){//生成的位图要带ALPHA通道信息,否则无法进行透明化处理Bitmap bitmap = Bitmap.createBitmap(mBitmapW, mBitmapH, Config.ARGB_4444);Canvas canvas = new Canvas(bitmap);Paint paint = new Paint();paint.setColor(Color.TRANSPARENT);canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), paint);paint.setTextSize(mFontSize);paint.setColor(Color.WHITE);String str = Integer.toString(life);canvas.drawText(str, 20, 28, paint);//书写的位置,根据具体情况可以调整一下return bitmap;}public void drawNumber(GL10 gl, int life) {life -= 3;if (life <= 0) return; Bitmap bmp = genBitmap(life); bindTexture(gl, bmp); initNumVertexBuffer();//根据col,row初始化顶点坐标 //顶点坐标,允许使用顶点数组 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);//为画笔指定顶点坐标数据 gl.glVertexPointer ( 3,//每个顶点的坐标数量为3 xyz GL10.GL_FIXED,//顶点坐标值的类型为 GL_FIXED 0, //连续顶点坐标数据之间的间隔 mNumVertexBuffer//顶点坐标数据 ); //纹理坐标,开启纹理 gl.glEnable(GL10.GL_TEXTURE_2D); //允许使用纹理数组 gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); //为画笔指定纹理uv坐标数据 gl.glTexCoordPointer ( 2, //每个顶点两个纹理坐标数据 S、T GL10.GL_FLOAT, //数据类型 0, //连续纹理坐标数据之间的间隔 mNumTextureBuffer//纹理坐标数据 ); gl.glBindTexture(GL10.GL_TEXTURE_2D,numTextureId);//为画笔绑定指定名称ID纹理 //绘制图形 gl.glDrawArrays ( GL10.GL_TRIANGLES, 0, vCount ); gl.glDisable(GL10.GL_TEXTURE_2D);//关闭纹理 } void drawLife(GL10 gl, int pic, int col) { initVertexBuffer(col);//根据col,row初始化顶点坐标 initTextureBuffer(pic);//根据witch来初始化纹理顶点数据 //gl.glTranslatef(col * textureRatio, row * textureRatio, 0);//在x=col,y=row的位置绘制选定的素材对象 //顶点坐标,允许使用顶点数组 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);//为画笔指定顶点坐标数据 gl.glVertexPointer ( 3,//每个顶点的坐标数量为3 xyz GL10.GL_FIXED,//顶点坐标值的类型为 GL_FIXED 0, //连续顶点坐标数据之间的间隔 mLifeVertexBuffer//顶点坐标数据 ); //纹理坐标,开启纹理 gl.glEnable(GL10.GL_TEXTURE_2D); //允许使用纹理数组 gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); //为画笔指定纹理uv坐标数据 gl.glTexCoordPointer ( 2, //每个顶点两个纹理坐标数据 S、T GL10.GL_FLOAT, //数据类型 0, //连续纹理坐标数据之间的间隔 mLifeTextureBuffer//纹理坐标数据 ); gl.glBindTexture(GL10.GL_TEXTURE_2D,textureId);//为画笔绑定指定名称ID纹理 //绘制图形 gl.glDrawArrays ( GL10.GL_TRIANGLES, 0, vCount ); gl.glDisable(GL10.GL_TEXTURE_2D);//关闭纹理 } public void draw(GL10 gl, int life) { int lifeCnt = life; if (life > 3) lifeCnt = 3; for(int i = 0; i < 3; i++) { if(lifeCnt >= 3) drawLife(gl, 1, i); else drawLife(gl, 0, i); lifeCnt++; } drawNumber(gl, life); }}
要修改渲染的效果,请修改\CrazyLink\res\drawable-nodpi\life.png图片。如果你设计了更炫的效果,欢迎上传到GitHub上,让更多的寨友一起分享。
当前life.png的效果如下,唯一要注意的是:背景要求是透明的。
- 山寨腾讯“爱消除”游戏之生命特效
- 山寨腾讯“爱消除”游戏之获得生命特效
- 山寨腾讯“爱消除”游戏之失去生命特效
- 山寨腾讯“爱消除”游戏之奖励特效
- 山寨腾讯“爱消除”游戏之自动提示特效
- 山寨腾讯“爱消除”游戏之交换特效优化
- 山寨腾讯“爱消除”游戏之菜单特效
- 山寨腾讯“爱消除”游戏之声音效果
- 山寨腾讯“爱消除”游戏之屏幕自动适配
- 山寨腾讯“爱消除”游戏之屏幕拾取技术
- 山寨腾讯“爱消除”游戏之框架总结
- 山寨腾讯“爱消除”游戏7日教程
- 山寨腾讯“爱消除”游戏7日教程--DAY2
- 山寨腾讯“爱消除”游戏7日教程--DAY3
- 山寨腾讯“爱消除”游戏7日教程--DAY4
- 山寨腾讯“爱消除”游戏7日教程--DAY5
- 山寨腾讯“爱消除”游戏7日教程--DAY6
- 山寨腾讯“爱消除”游戏7日教程--DAY7
- 你的沟通力对你公司很重要
- 图像处理(卷积)
- 面向对象7_【异常】【异常的处理】【异常的应用】
- 单臂路由应用的例子
- 搭建通用的自动化部署脚本
- 山寨腾讯“爱消除”游戏之生命特效
- C++ 高精度运算类(BigC类)
- md1的反思
- HashSet在 java 中的使用
- 1-SnailBoard开篇
- requirejs 正序加载,逆序初始化
- 1.C#基础知识
- 使用SIM908实现GPS的GPRS传输
- 关于一次导入数据提示的MySQL server has gone away