【广而告之】山寨腾讯“爱消除”游戏已经正式入驻GitHub,项目地址是:https://github.com/3125788/CrazyLink
欢迎广大寨友一起来完善这个游戏。
上一篇介绍了生命特效,这次,继续介绍获得生命的动态渲染特效,先上图,效果如下:
满足获得新生命的条件后,触发渲染获得生命特效。
代码在DrawLifeAdd及CtlLifeAdd中,详细请参考GitHub上的开源项目。
DrawLifeAdd渲染类
public class DrawLifeAdd { private IntBuffer mVertexBuffer; //顶点坐标数据缓冲 private FloatBuffer mTextureBuffer; //顶点纹理数据缓冲 int vCount=0; //顶点数量 int textureId; //纹理索引 float textureRatio; //为了准确获取纹理图片中的素材对象,需要设置纹理的变换率 public IControl control; public DrawLifeAdd(int textureId) { this.textureId=textureId; control = new CtlLifeAdd(); } //顶点坐标数据的初始化 private void initVertexBuffer() { CtlLifeAdd ctl = (CtlLifeAdd)control; int w = CrazyLinkConstent.UNIT_SIZE*ctl.getW(); int h = CrazyLinkConstent.UNIT_SIZE*ctl.getH(); float x = ctl.getX(); float y = ctl.getY(); vCount=6;//顶点的数量,一个正方形用两个三角形表示,共需要6个顶点 int deltaX = (int)(x*32*CrazyLinkConstent.UNIT_SIZE); int deltaY = (int)(y*32*CrazyLinkConstent.UNIT_SIZE); int vertices[]=new int[]//顶点坐标数据数组 { deltaX-w,deltaY+h,0, deltaX-w,deltaY-h,0, deltaX+w,deltaY-h,0, deltaX+w,deltaY-h,0, deltaX+w,deltaY+h,0, deltaX-w,deltaY+h,0 }; //创建顶点坐标数据缓冲 //int类型占用4个字节,因此转换为byte的数据时需要*4 ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4); vbb.order(ByteOrder.nativeOrder()); //设置本地的字节顺序 //特别提示:由于不同平台字节顺序不同数据单元不是字节的一定要经过ByteBuffer //转换,关键是要通过ByteOrder设置nativeOrder(),否则有可能会出问题 mVertexBuffer = vbb.asIntBuffer(); //转换为int型缓冲 mVertexBuffer.put(vertices); //向缓冲区中放入顶点坐标数据 mVertexBuffer.position(0); //设置缓冲区起始位置 return; } //顶点纹理数据的初始化 private void initTextureBuffer(int witch) { textureRatio = (float)(1/4.0f); //图片是4个独立的素材对象组成,每次需要根据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(),否则有可能会出问题 mTextureBuffer = cbb.asFloatBuffer();//转换为int型缓冲 mTextureBuffer.put(textureCoors);//向缓冲区中放入顶点着色数据 mTextureBuffer.position(0);//设置缓冲区起始位置 return; } public void draw(GL10 gl) { if(!control.isRun()) return; CtlLifeAdd ctl = (CtlLifeAdd)control; initVertexBuffer(); //根据col,row初始化顶点坐标 initTextureBuffer(ctl.getPicId()); //根据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, //连续顶点坐标数据之间的间隔 mVertexBuffer //顶点坐标数据 ); //纹理坐标,开启纹理 gl.glEnable(GL10.GL_TEXTURE_2D); //允许使用纹理数组 gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); //为画笔指定纹理uv坐标数据 gl.glTexCoordPointer ( 2, //每个顶点两个纹理坐标数据 S、T GL10.GL_FLOAT, //数据类型 0, //连续纹理坐标数据之间的间隔 mTextureBuffer //纹理坐标数据 ); gl.glBindTexture(GL10.GL_TEXTURE_2D,textureId);//为画笔绑定指定名称ID纹理 //绘制图形 gl.glDrawArrays ( GL10.GL_TRIANGLES, 0, vCount ); gl.glDisable(GL10.GL_TEXTURE_2D);//关闭纹理 } }
CtlLifeAdd控制类
public class CtlLifeAdd extends CtlBase{ int mDeltaW = 0; int mDeltaH = 0; float mDeltaX = 0; float mDeltaY = 0; float mCol = 0; int mStep = 0; int mKeep = 0; int mPicId = 0; int mGoodCnt = 0; int mTimeCnt = 0; public void run() { int maxW = 48; int minW = 12; int deltaW = 4; int deltaH = 4; if(!mStop) { mTimeCnt++; if (1 == (mTimeCnt %2)) { mPicId++; if (mPicId > 3) mPicId = 0; } if(0 == mStep) { mDeltaW += deltaW; mDeltaH += deltaH; if (mDeltaW >= maxW) { mStep = 1; } } else if(1 == mStep) { mKeep++; if(mKeep >= 30) { mKeep = 0; mStep = 2; } } else if(2 == mStep) { mDeltaW -= deltaW; mDeltaH -= deltaH; mDeltaY ++; mDeltaX = mDeltaY / 2; if(mDeltaX >= mCol) mDeltaX = mCol; //瞄准新添加生命出现的位置 if (mDeltaW <= minW) { mStep = 3; } } else if(3 == mStep) { mStop = true; sendMsg(); } } } public int getW() { return mDeltaW; } public int getH() { return mDeltaH; } public float getX() { return mDeltaX; } public float getY() { return mDeltaY; } public void init(int life) { if(!mStop) return; mDeltaW = 0; mDeltaH = 0; mDeltaX = 0; mDeltaY = 0; //根据当前生命值设定新加的图案出现的位置 if(life >= 3) mCol = 5; else if(2 == life) mCol = 2; else if(1 == life) mCol = 3; else if(0 == life) mCol = 4; mStep = 0; mPicId = 0; super.start(); } public int getPicId() { return mPicId; } public void sendMsg() { Message msg = new Message(); msg.what = ControlCenter.LIFEADD_END; ControlCenter.mHandler.sendMessage(msg); } }
作者:elong_2009 发表于2013-12-3 0:34:05 原文链接
阅读:182 评论:0 查看评论