山寨腾讯“爱消除”游戏之生命特效
2013-12-01 14:36
399 查看
【广而告之】山寨腾讯“爱消除”游戏已经正式入驻GitHub,项目地址是:https://github.com/3125788/CrazyLink
欢迎广大寨友一起来完善这个游戏。
好了,山寨了那么久,今天开始,我们自己也要来点创新的东西了。
今天我们就为山寨“爱消除”游戏加上生命指示器的效果。所谓生命指示器,就是告诉玩家当前还剩余几条命。好,废话不多说,直接上图。
多于三条命时的效果如下,数字5代表5条命,三颗星星代表三条命,总共8条命。
当生命不足三条时的效果如下,这里只剩下两条命了。
详细的代码在DrawLife渲染类中。调用 public void draw(GL10 gl, int life)传入生命数,就可以将生命指示器渲染出来了。
要修改渲染的效果,请修改\CrazyLink\res\drawable-nodpi\life.png图片。如果你设计了更炫的效果,欢迎上传到GitHub上,让更多的寨友一起分享。
当前life.png的效果如下,唯一要注意的是:背景要求是透明的。
欢迎广大寨友一起来完善这个游戏。
好了,山寨了那么久,今天开始,我们自己也要来点创新的东西了。
今天我们就为山寨“爱消除”游戏加上生命指示器的效果。所谓生命指示器,就是告诉玩家当前还剩余几条命。好,废话不多说,直接上图。
多于三条命时的效果如下,数字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日教程--DAY5
- 山寨腾讯“爱消除”游戏7日教程--DAY6
- 山寨腾讯“爱消除”游戏7日教程--DAY3
- 山寨腾讯“爱消除”游戏之屏幕拾取技术
- 山寨腾讯“爱消除”游戏之框架总结
- 山寨腾讯“爱消除”游戏7日教程--DAY4
- 山寨腾讯“爱消除”游戏7日教程--DAY7
- Android 山寨腾讯“爱消除”游戏源码 视频教程
- 山寨腾讯“爱消除”游戏之屏幕拾取技术
- 山寨腾讯“爱消除”游戏之屏幕自动适配