初次提交

This commit is contained in:
2022-09-19 18:05:01 +08:00
commit 57051fc44b
5401 changed files with 325410 additions and 0 deletions

View File

@@ -0,0 +1,465 @@
package com.bn.clp;
import static com.bn.clp.Constant.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import com.bn.core.MatrixState;
import android.opengl.GLES20;
//该类为飞艇类
public class AirShip extends BNDrawer
{
static float feitingX;//飞艇所在运行轨迹中心点位置
static float feitingY;
static float feitingZ;
final static float NORMAL_SIZE=5.0f;
static float A=UNIT_SIZE-10;//飞艇运动椭球的a半径————x方向
static float B=UNIT_SIZE-10;//飞艇运动椭球的b半径————z方向
static float angle=360;//飞艇当前角度
static float angle_Rotate=0;//飞艇扰动角度
static float height=1f;//飞艇上下扰动高差
static float angle_Y=270;//正玄曲线当前帧角度
public static GoThread goThread;//运动线程
DrawSpheroid bodyback;
DrawSpheroid bodyhead;
DrawSpheroid cabin;
DrawWeiba weiba;
//飞艇身体椭圆的三个轴分量
final static float BODYBACK_A=3f*NORMAL_SIZE;
final static float BODYBACK_B=1f*NORMAL_SIZE;
final static float BODYBACK_C=1f*NORMAL_SIZE;
//飞艇身体小椭圆的三个轴分量
final static float BODYHEAD_A=2f*NORMAL_SIZE;
final static float BODYHEAD_B=1f*NORMAL_SIZE;
final static float BODYHEAD_C=1f*NORMAL_SIZE;
final static float WEIBA_WIDTH=0.3f*NORMAL_SIZE;
final static float WEIBA_HEIGHT=0.3f*NORMAL_SIZE;
final static float CABIN_A=0.4f*NORMAL_SIZE;
final static float CABIN_B=0.2f*NORMAL_SIZE;
final static float CABIN_C=0.2f*NORMAL_SIZE;
public AirShip(int programId)
{
bodyback=new DrawSpheroid(programId,BODYBACK_A,BODYBACK_B,BODYBACK_C,30,-90,90,-90,90);
bodyhead=new DrawSpheroid(programId,BODYHEAD_A,BODYHEAD_B,BODYHEAD_C,30,-90,90,-90,90);
cabin=new DrawSpheroid(programId,CABIN_A,CABIN_B,CABIN_C,30,0,360,-90,90);
weiba=new DrawWeiba(programId,WEIBA_WIDTH,WEIBA_HEIGHT);
goThread=new GoThread();
goThread.start();
}
//绘制方法
public void drawSelf(int[] texId, int dyFlag)
{
feitingX=(float) (A*Math.cos(Math.toRadians(angle)));
feitingY=(float) (height*Math.sin(Math.toRadians(angle_Y)));
feitingZ=(float) (B*Math.sin(Math.toRadians(angle)));
MatrixState.pushMatrix();
MatrixState.translate
(
feitingX,
feitingY,
feitingZ
);
MatrixState.rotate(angle_Rotate-90, 0, 1, 0);
//飞艇后方
MatrixState.pushMatrix();
bodyback.drawSelf(texId[0]);
MatrixState.popMatrix();
//飞艇前方
MatrixState.pushMatrix();
MatrixState.rotate(180, 0, 1, 0);
MatrixState.rotate(180, 1, 0, 0);
bodyhead.drawSelf(texId[0]);
MatrixState.popMatrix();
//下侧的飞艇
MatrixState.pushMatrix();
MatrixState.translate(BODYHEAD_C*0.2f, -BODYHEAD_B, 0);
cabin.drawSelf(texId[0]);
MatrixState.popMatrix();
//尾翼部分
//上侧
MatrixState.pushMatrix();
MatrixState.translate(BODYBACK_A*0.8f, BODYBACK_C*0.7f, 0);
weiba.drawSelf(texId[1]);
MatrixState.popMatrix();
//前侧
MatrixState.pushMatrix();
MatrixState.translate(BODYBACK_A*0.8f, 0, BODYBACK_B*0.7f);
MatrixState.rotate(90, 1, 0, 0);
weiba.drawSelf(texId[1]);
MatrixState.popMatrix();
//后侧
MatrixState.pushMatrix();
MatrixState.translate(BODYBACK_A*0.8f, 0, -BODYBACK_B*0.7f);
MatrixState.rotate(-90, 1, 0, 0);
weiba.drawSelf(texId[1]);
MatrixState.popMatrix();
//下侧
MatrixState.pushMatrix();
MatrixState.translate(BODYBACK_A*0.8f, -BODYBACK_C*0.7f, 0);
MatrixState.rotate(180, 1, 0, 0);
weiba.drawSelf(texId[1]);
MatrixState.popMatrix();
MatrixState.popMatrix();
}
//绘制飞艇身体的椭球
private class DrawSpheroid
{
//自定义渲染管线的id
int mProgram;
//总变化矩阵引用的id
int muMVPMatrixHandle;
//顶点位置属性引用id
int maPositionHandle;
//顶点纹理坐标属性引用id
int maTexCoorHandle;
//顶点数据缓冲和纹理坐标数据缓冲
FloatBuffer mVertexBuffer;
FloatBuffer mTexCoorBuffer;
//顶点数量
int vCount=0;
public DrawSpheroid
(
int programId,float a,float b,float c,float angleSpan,
float hAngleBegin,float hAngleOver,float vAngleBegin,float vAngleOver
)
{
initVertexData(a,b,c,angleSpan,hAngleBegin,hAngleOver,vAngleBegin,vAngleOver);
initShader(programId);
}
//初始的顶点数据
public void initVertexData
(
float a,float b,float c,
float angleSpan,
float hAngleBegin,float hAngleOver,
float vAngleBegin,float vAngleOver
)
{
ArrayList<Float> alVertix=new ArrayList<Float>();//存放顶点坐标
for(float vAngle=vAngleBegin;vAngle<vAngleOver;vAngle=vAngle+angleSpan)//垂直方向angleSpan度一份
{
for(float hAngle=hAngleBegin;hAngle<hAngleOver;hAngle=hAngle+angleSpan)//水平方向angleSpan度一份
{//纵向横向各到一个角度后计算对应的此点在球面上的坐标
float x0=(float)(a*Math.cos(Math.toRadians(vAngle))*Math.cos(Math.toRadians(hAngle)));
float y0=(float)(b*Math.cos(Math.toRadians(vAngle))*Math.sin(Math.toRadians(hAngle)));
float z0=(float)(c*Math.sin(Math.toRadians(vAngle)));
float x1=(float)(a*Math.cos(Math.toRadians(vAngle))*Math.cos(Math.toRadians(hAngle+angleSpan)));
float y1=(float)(b*Math.cos(Math.toRadians(vAngle))*Math.sin(Math.toRadians(hAngle+angleSpan)));
float z1=(float)(c*Math.sin(Math.toRadians(vAngle)));
float x2=(float)(a*Math.cos(Math.toRadians(vAngle+angleSpan))*Math.cos(Math.toRadians(hAngle+angleSpan)));
float y2=(float)(b*Math.cos(Math.toRadians(vAngle+angleSpan))*Math.sin(Math.toRadians(hAngle+angleSpan)));
float z2=(float)(c*Math.sin(Math.toRadians(vAngle+angleSpan)));
float x3=(float)(a*Math.cos(Math.toRadians(vAngle+angleSpan))*Math.cos(Math.toRadians(hAngle)));
float y3=(float)(b*Math.cos(Math.toRadians(vAngle+angleSpan))*Math.sin(Math.toRadians(hAngle)));
float z3=(float)(c*Math.sin(Math.toRadians(vAngle+angleSpan)));
//将计算出来的XYZ坐标加入存放顶点坐标的ArrayList
alVertix.add(x1);alVertix.add(y1);alVertix.add(z1);
alVertix.add(x3);alVertix.add(y3);alVertix.add(z3);
alVertix.add(x0);alVertix.add(y0);alVertix.add(z0);
alVertix.add(x1);alVertix.add(y1);alVertix.add(z1);
alVertix.add(x2);alVertix.add(y2);alVertix.add(z2);
alVertix.add(x3);alVertix.add(y3);alVertix.add(z3);
}
}
vCount=alVertix.size()/3;//顶点的数量为坐标值数量的1/3因为一个顶点有3个坐标
//将alVertix中的坐标值转存到一个int数组中
float[] vertices=new float[vCount*3];
for(int i=0;i<alVertix.size();i++)
{
vertices[i]=alVertix.get(i);
}
//创建顶点坐标数据缓冲
//vertices.length*4是因为一个整数四个字节
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());//设置字节顺序
mVertexBuffer = vbb.asFloatBuffer();//转换为int型缓冲
mVertexBuffer.put(vertices);//向缓冲区中放入顶点坐标数据
mVertexBuffer.position(0);//设置缓冲区起始位置
//获取切分整图的纹理数组
float[] texCoorArray=
generateTexCoor
(
(int)((hAngleOver-hAngleBegin)/angleSpan), //纹理图切分的列数
(int)((vAngleOver-vAngleBegin)/angleSpan) //纹理图切分的行数
);
ByteBuffer tbb=ByteBuffer.allocateDirect(texCoorArray.length*4);
tbb.order(ByteOrder.nativeOrder());
mTexCoorBuffer=tbb.asFloatBuffer();
mTexCoorBuffer.put(texCoorArray);
mTexCoorBuffer.position(0);
}
//初始化着色器程序的initShader方法
public void initShader(int programId)
{
//基于顶点着色器与片元着色器创建程序
mProgram =programId;
//获取程序中顶点位置属性引用id
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
//获取程序中顶点纹理坐标属性引用id
maTexCoorHandle= GLES20.glGetAttribLocation(mProgram, "aTexCoor");
//获取程序中总变换矩阵引用id
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
}
//实际的绘制方法
public void drawSelf(int texId)
{
//制定使用某套shader程序
GLES20.glUseProgram(mProgram);
//将最终变换矩阵传入shader程序
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//为画笔指定顶点位置数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入纹理坐标数据
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false,
2*4,
mTexCoorBuffer
);
//允许顶点位置数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
//绘制纹理矩形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
//自动切分纹理产生纹理数组的方法
public float[] generateTexCoor(int bw,int bh)
{
float[] result=new float[bw*bh*6*2];
float sizew=1.0f/bw;//列数
float sizeh=1.0f/bh;//行数
int c=0;
for(int i=0;i<bh;i++)
{
for(int j=0;j<bw;j++)
{
//每行列一个矩形由两个三角形构成共六个点12个纹理坐标
float s=j*sizew;
float t=i*sizeh;
result[c++]=s+sizew;
result[c++]=t;
result[c++]=s;
result[c++]=t+sizeh;
result[c++]=s;
result[c++]=t;
result[c++]=s+sizew;
result[c++]=t;
result[c++]=s+sizew;
result[c++]=t+sizeh;
result[c++]=s;
result[c++]=t+sizeh;
}
}
return result;
}
}
//绘制飞艇的尾部
private class DrawWeiba
{
//自定义渲染管线的id
int mProgram;
//总变化矩阵引用的id
int muMVPMatrixHandle;
//顶点位置属性引用id
int maPositionHandle;
//顶点纹理坐标属性引用id
int maTexCoorHandle;
//顶点数据缓冲和纹理坐标数据缓冲
FloatBuffer mVertexBuffer;
FloatBuffer mTexCoorBuffer;
//顶点数量
int vCount=0;
public DrawWeiba(int programId,float width,float height)
{
initVertexData(width,height);
initShader(programId);
}
//初始的顶点数据的initVertexData方法
public void initVertexData(float width,float height)
{
float[] vertices=new float[]
{
-width,height,0,
-width*1.5f,-height,0,
width,-height,0,
-width,height,0,
width,-height,0,
width,height,0,
-width,height,0,
width,height,0,
width,-height,0,
-width,height,0,
width,-height,0,
-width*1.5f,-height,0,
};
vCount=12;
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());//设置字节顺序
mVertexBuffer = vbb.asFloatBuffer();//转换为int型缓冲
mVertexBuffer.put(vertices);//向缓冲区中放入顶点坐标数据
mVertexBuffer.position(0);//设置缓冲区起始位置
//获取切分整图的纹理数组
float[] texCoorArray=new float[]
{
0.2f,0, 0,1, 1,1,
0.2f,0, 1,1, 1,0,
0.2f,0, 1,0, 1,1,
0.2f,0, 1,1, 0,1
};
ByteBuffer tbb=ByteBuffer.allocateDirect(texCoorArray.length*4);
tbb.order(ByteOrder.nativeOrder());
mTexCoorBuffer=tbb.asFloatBuffer();
mTexCoorBuffer.put(texCoorArray);
mTexCoorBuffer.position(0);
}
//初始化着色器程序的initShader方法
public void initShader(int programId)
{
//基于顶点着色器与片元着色器创建程序
mProgram =programId;
//获取程序中顶点位置属性引用id
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
//获取程序中顶点纹理坐标属性引用id
maTexCoorHandle= GLES20.glGetAttribLocation(mProgram, "aTexCoor");
//获取程序中总变换矩阵引用id
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
}
//实际的绘制方法
public void drawSelf(int texId)
{
//制定使用某套shader程序
GLES20.glUseProgram(mProgram);
//将最终变换矩阵传入shader程序
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//传入顶点位置数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入纹理坐标数据
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false,
2*4,
mTexCoorBuffer
);
//允许顶点位置数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
//绘制纹理矩形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
}
//飞艇运动线程
public class GoThread extends Thread
{
public GoThread()
{
this.setName("GoThread");
}
public void run()
{
while(Constant.threadFlag)
{
angle=angle-0.2f;
angle_Y=angle_Y+30;
angle_Rotate=angle_Rotate+0.2f;
if(angle<=0)
{
angle=360;
}
if(angle_Y>=360)
{
angle_Y=0;
}
if(angle_Rotate>=360)
{
angle_Rotate=0;
}
try
{
Thread.sleep(200);
}catch(Exception e)
{
e.printStackTrace();
}
}
}
}
}

View File

@@ -0,0 +1,9 @@
package com.bn.clp;
/*
* 该类是一个抽象类所有的3D物体的绘制均继承自该类
*/
public abstract class BNDrawer
{
public abstract void drawSelf(int[] texId,int dyFlag);
}

View File

@@ -0,0 +1,259 @@
package com.bn.clp;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import android.opengl.GLES20;
import com.bn.core.MatrixState;
//代表半崖子的类
public class B_YZ extends BNDrawer
{
//单位长度
float UNIT_SIZE=2.5f;
X_BYZ x_byz;
public B_YZ(int programId)
{
x_byz=new X_BYZ(programId);
}
@Override
public void drawSelf(int[] texId,int dyFlag)
{
MatrixState.pushMatrix();
x_byz.drawSelf(texId[0], texId[1]);
MatrixState.popMatrix();
//右侧
MatrixState.pushMatrix();
MatrixState.translate(22*UNIT_SIZE, 0, -4*UNIT_SIZE);
MatrixState.rotate(180, 0, 1, 0);
x_byz.drawSelf(texId[0], texId[1]);
MatrixState.popMatrix();
}
//半崖子内部类
private class X_BYZ
{
//自定义渲染管线id
int mProgram;
//顶点位置属性的引用id
int maPositionHandle;
//顶点纹理坐标属性的引用id
int maTexCoorHandle;
//总变化矩阵的引用id
int muMVPMatrixHandle;
//草地的id
int sTextureGrassHandle;
//石头的id
int sTextureRockHandle;
//起始x值
int b_YZ_StartXHandle;
//长度
int b_YZ_XSpanHandle;
//顶点坐标数据缓冲和顶点纹理数据缓冲
FloatBuffer mVertexBuffer;
FloatBuffer mTexCoorBuffer;
int vCount=0;
public X_BYZ(int programId)
{
initVertexData();
initShader(programId);
}
//初始化顶点数据的initVertexData方法
public void initVertexData()
{
float[] vertex=new float[]
{
//底部
//中间部分
//前侧
UNIT_SIZE,3*UNIT_SIZE,-UNIT_SIZE,
UNIT_SIZE,2*UNIT_SIZE,-UNIT_SIZE,
5*UNIT_SIZE,4*UNIT_SIZE,-UNIT_SIZE,
UNIT_SIZE,3*UNIT_SIZE,-UNIT_SIZE,
5*UNIT_SIZE,4*UNIT_SIZE,-UNIT_SIZE,
5*UNIT_SIZE,5*UNIT_SIZE,-UNIT_SIZE,
//右侧
5*UNIT_SIZE,4*UNIT_SIZE,-UNIT_SIZE,
UNIT_SIZE,2*UNIT_SIZE,-UNIT_SIZE,
UNIT_SIZE,2*UNIT_SIZE,-3*UNIT_SIZE,
5*UNIT_SIZE,4*UNIT_SIZE,-UNIT_SIZE,
UNIT_SIZE,2*UNIT_SIZE,-3*UNIT_SIZE,
5*UNIT_SIZE,4*UNIT_SIZE,-3*UNIT_SIZE,
//后侧
UNIT_SIZE,3*UNIT_SIZE,-3*UNIT_SIZE,
5*UNIT_SIZE,4*UNIT_SIZE,-3*UNIT_SIZE,
UNIT_SIZE,2*UNIT_SIZE,-3*UNIT_SIZE,
UNIT_SIZE,3*UNIT_SIZE,-3*UNIT_SIZE,
5*UNIT_SIZE,5*UNIT_SIZE,-3*UNIT_SIZE,
5*UNIT_SIZE,4*UNIT_SIZE,-3*UNIT_SIZE,
//左侧
5*UNIT_SIZE,5*UNIT_SIZE,-3*UNIT_SIZE,
UNIT_SIZE,3*UNIT_SIZE,-3*UNIT_SIZE,
UNIT_SIZE,3*UNIT_SIZE,-UNIT_SIZE,
5*UNIT_SIZE,5*UNIT_SIZE,-3*UNIT_SIZE,
UNIT_SIZE,3*UNIT_SIZE,-UNIT_SIZE,
5*UNIT_SIZE,5*UNIT_SIZE,-UNIT_SIZE,
//最上侧部分
//前侧
5*UNIT_SIZE,5*UNIT_SIZE,-UNIT_SIZE,
5*UNIT_SIZE,4*UNIT_SIZE,-UNIT_SIZE,
7*UNIT_SIZE,4.3f*UNIT_SIZE,-UNIT_SIZE,
5*UNIT_SIZE,5*UNIT_SIZE,-UNIT_SIZE,
7*UNIT_SIZE,4.3f*UNIT_SIZE,-UNIT_SIZE,
7*UNIT_SIZE,4.7f*UNIT_SIZE,-UNIT_SIZE,
//右侧(下)
7*UNIT_SIZE,4.3f*UNIT_SIZE,-UNIT_SIZE,
5*UNIT_SIZE,4*UNIT_SIZE,-UNIT_SIZE,
5*UNIT_SIZE,4*UNIT_SIZE,-3*UNIT_SIZE,
7*UNIT_SIZE,4.3f*UNIT_SIZE,-UNIT_SIZE,
5*UNIT_SIZE,4*UNIT_SIZE,-3*UNIT_SIZE,
7*UNIT_SIZE,4.3f*UNIT_SIZE,-3*UNIT_SIZE,
//后侧
5*UNIT_SIZE,5*UNIT_SIZE,-3*UNIT_SIZE,
7*UNIT_SIZE,4.3f*UNIT_SIZE,-3*UNIT_SIZE,
5*UNIT_SIZE,4*UNIT_SIZE,-3*UNIT_SIZE,
5*UNIT_SIZE,5*UNIT_SIZE,-3*UNIT_SIZE,
7*UNIT_SIZE,4.7f*UNIT_SIZE,-3*UNIT_SIZE,
7*UNIT_SIZE,4.3f*UNIT_SIZE,-3*UNIT_SIZE,
//左侧(上)
7*UNIT_SIZE,4.7f*UNIT_SIZE,-3*UNIT_SIZE,
5*UNIT_SIZE,5*UNIT_SIZE,-3*UNIT_SIZE,
5*UNIT_SIZE,5*UNIT_SIZE,-UNIT_SIZE,
7*UNIT_SIZE,4.7f*UNIT_SIZE,-3*UNIT_SIZE,
5*UNIT_SIZE,5*UNIT_SIZE,-UNIT_SIZE,
7*UNIT_SIZE,4.7f*UNIT_SIZE,-UNIT_SIZE,
//最右侧的封闭
7*UNIT_SIZE,4.7f*UNIT_SIZE,-UNIT_SIZE,
7*UNIT_SIZE,4.3f*UNIT_SIZE,-UNIT_SIZE,
7*UNIT_SIZE,4.3f*UNIT_SIZE,-3*UNIT_SIZE,
7*UNIT_SIZE,4.7f*UNIT_SIZE,-UNIT_SIZE,
7*UNIT_SIZE,4.3f*UNIT_SIZE,-3*UNIT_SIZE,
7*UNIT_SIZE,4.7f*UNIT_SIZE,-3*UNIT_SIZE
};
vCount=vertex.length/3;
ByteBuffer vbb=ByteBuffer.allocateDirect(vertex.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer=vbb.asFloatBuffer();
mVertexBuffer.put(vertex);
mVertexBuffer.position(0);
float[] texcoor=new float[]
{
//中间部分
//前侧
0.1f,0.4f, 0.1f,0.6f, 0.5f,0.2f,
0.1f,0.4f, 0.5f,0.2f, 0.5f,0,
//右侧
0.5f,0.2f, 0.1f,0.6f, 0.2f,1.0f,
0.5f,0.2f, 0.2f,1.0f, 0.6f,0.6f,
//后侧
0.1f,0.4f, 0.5f,0.2f, 0.1f,0.6f,
0.1f,0.4f, 0.5f,0, 0.5f,0.2f,
//左侧
0.6f,0.6f, 0.2f,1.0f, 0.1f,0.6f,
0.6f,0.6f, 0.1f,0.6f, 0.5f,0.2f,
//最上侧部分
//前侧
0.5f,0, 0.5f,0.2f, 0.7f,0.14f,
0.5f,0, 0.7f,0.14f, 0.7f,0.06f,
//右侧(下)
0.7f,0.14f, 0.5f,0.2f, 0.6f,0.6f,
0.7f,0.14f, 0.6f,0.6f, 0.8f,0.54f,
//后侧
0.5f,0, 0.7f,0.14f, 0.5f,0.2f,
0.5f,0, 0.7f,0.06f, 0.7f,0.14f,
//左侧(上)
0.8f,0.54f, 0.6f,0.6f, 0.5f,0.2f,
0.8f,0.54f, 0.5f,0.2f, 0.7f,0.14f,
//最右侧的封闭
0.7f,0.06f, 0.7f,0.14f, 0.9f,0.14f,
0.7f,0.06f, 0.9f,0.14f, 0.9f,0.06f
};
ByteBuffer tbb=ByteBuffer.allocateDirect(texcoor.length*4);
tbb.order(ByteOrder.nativeOrder());
mTexCoorBuffer=tbb.asFloatBuffer();
mTexCoorBuffer.put(texcoor);
mTexCoorBuffer.position(0);
}
//初始化着色器的initShader方法
public void initShader(int programId)
{
mProgram=programId;
//获得顶点坐标属性的引用id
maPositionHandle=GLES20.glGetAttribLocation(mProgram, "aPosition");
//获得顶点纹理坐标属性的引用id
maTexCoorHandle=GLES20.glGetAttribLocation(mProgram, "aTexCoor");
//获得总变化矩阵引用的id
muMVPMatrixHandle=GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
//纹理
//草地
sTextureGrassHandle=GLES20.glGetUniformLocation(mProgram, "sTextureGrass");
//石头
sTextureRockHandle=GLES20.glGetUniformLocation(mProgram, "sTextureRock");
//x位置
b_YZ_StartXHandle=GLES20.glGetUniformLocation(mProgram, "b_YZ_StartX");
//x最大
b_YZ_XSpanHandle=GLES20.glGetUniformLocation(mProgram, "b_YZ_XSpan");
}
//自定义的绘制方法
public void drawSelf(int texIdGrass,int texIdRock)
{
//指定某套Shader程序
GLES20.glUseProgram(mProgram);
//将最终变化矩阵传入到Shader程序
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//为画笔指定顶点坐标——>此处将坐标传入Shader??????
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入顶点纹理坐标
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false,
2*4,
mTexCoorBuffer
);
//允许使用顶点坐标以及顶点纹理坐标
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
//启用纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texIdGrass);
GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texIdRock);
GLES20.glUniform1i(sTextureGrassHandle, 0);//使用0号纹理
GLES20.glUniform1i(sTextureRockHandle, 1); //使用1号纹理
//传送相应的x参数
GLES20.glUniform1f(b_YZ_StartXHandle, 0);
GLES20.glUniform1f(b_YZ_XSpanHandle, 7*UNIT_SIZE);
//绘制物体
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
}
}

View File

@@ -0,0 +1,110 @@
package com.bn.clp;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import android.opengl.GLES20;
import com.bn.core.MatrixState;
public class BackGround
{
//自定义渲染管线着色器程序的id
int mProgram;
//总变化矩阵引用的id
int muMVPMatrixHandle;
//顶点位置属性引用id
int maPositionHandle;
//顶点纹理坐标属性引用id
int maTexCoorHandle;
//顶点数据缓冲和纹理坐标数据缓冲
FloatBuffer mVertexBuffer;
FloatBuffer mTexCoorBuffer;
//顶点数量
int vCount=0;
public BackGround(int programId,float width,float height,float[] texCoor)
{
initVertexData(width,height,texCoor);
initShader(programId);
}
//初始化顶点数据的initVertexData方法
public void initVertexData(float width,float height,float[] texCoor)
{
float[] vertex=new float[]
{
-width,height,0,
-width,-height,0,
width,-height,0,
-width,height,0,
width,-height,0,
width,height,0,
};
vCount=vertex.length/3;
ByteBuffer vbb=ByteBuffer.allocateDirect(vertex.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer=vbb.asFloatBuffer();
mVertexBuffer.put(vertex);
mVertexBuffer.position(0);
//纹理坐标数据缓冲
ByteBuffer tbb=ByteBuffer.allocateDirect(texCoor.length*4);
tbb.order(ByteOrder.nativeOrder());
mTexCoorBuffer=tbb.asFloatBuffer();
mTexCoorBuffer.put(texCoor);
mTexCoorBuffer.position(0);
}
//初始化着色器的initShader方法
public void initShader(int programId)
{
//基于顶点着色器与片元着色器创建程序
mProgram =programId;
//获取程序中顶点位置属性引用id
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
//获取程序中顶点纹理坐标属性引用id
maTexCoorHandle= GLES20.glGetAttribLocation(mProgram, "aTexCoor");
//获取程序中总变换矩阵引用id
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
}
//自定义的绘制方法drawSelf
public void drawSelf(int texId)
{
//制定使用某套shader程序
GLES20.glUseProgram(mProgram);
//将最终变换矩阵传入shader程序
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//传入顶点位置数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入纹理坐标数据
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false,
2*4,
mTexCoorBuffer
);
//允许顶点位置数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
//绘制纹理矩形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
}

View File

@@ -0,0 +1,63 @@
package com.bn.clp;
import static com.bn.clp.Constant.*;
import java.util.ArrayList;
import java.util.List;
import android.opengl.GLES20;
import com.bn.core.MatrixState;
public class Boat
{
List<LoadedObjectVertexNormal> lovo=new ArrayList<LoadedObjectVertexNormal>();
//str位文件的名称color位每一个部分对应的颜色其为二维数组
public Boat(String [] str,MyGLSurfaceView mv,int programId)
{
for(int i=0;i<str.length;i++)
{
lovo.add
(
LoadUtil.loadFromFileVertexOnly
(
str[i],
mv.getResources(),
programId
)
);
}
}
public void drawSelf(float bx,float by,float bz,float yAngle,int dyFlag,int[] texId)
{
for(int i=0;i<lovo.size();i++)
{
if(dyFlag==0)//绘制实体
{
MatrixState.pushMatrix();
MatrixState.translate(bx, by, bz);
MatrixState.rotate(yAngle, 0, 1, 0);
MatrixState.rotate(head_Angle, 1, 0, 0);
lovo.get(i).drawSelf(texId[i]);
MatrixState.popMatrix();
}
else if(dyFlag==1)//绘制倒影
{
//实际绘制时Y的零点
float yTranslate=by;
//进行镜像绘制时的调整值
float yjx=(WATER_HIGH_ADJUST-yTranslate)*2;
//关闭背面剪裁
GLES20.glDisable(GLES20.GL_CULL_FACE);
MatrixState.pushMatrix();
MatrixState.translate(bx, by, bz);
MatrixState.rotate(yAngle, 0, 1, 0);
MatrixState.rotate(-head_Angle, 1, 0, 0);
MatrixState.translate(0, yjx, 0);
MatrixState.scale(1, -1, 1);
lovo.get(i).drawSelf(texId[i]);
MatrixState.popMatrix();
//打开背面剪裁
GLES20.glEnable(GLES20.GL_CULL_FACE);
}
}
}
}

View File

@@ -0,0 +1,62 @@
package com.bn.clp;
import com.bn.R;
public class BoatInfo
{
public static int cuttBoatIndex=2;
//´¬²¿¼þµÄÃû×Ö
public static String[][] boatPartNames=
{
{
"one_chuanshen.obj",
"one_dizuo.obj",
"one_houmian.obj",
"one_qiandizuo.obj",
"one_qianmian.obj"
},
{
"three_chuanshen.obj",
"three_liangce.obj",
"three_pentong.obj",
"three_shangmian.obj",
"three_shangmianqian.obj",
"three_weiyi.obj"
},
{//ÅíÅí
"two_ceyi.obj",
"two_chuanshen.obj",
"two_pentong.obj",
"two_shangmian.obj",
"two_weijia.obj",
"two_weiyi.obj"
}
};
public final static int[][] boatTexIdName=
{
{
R.raw.one_chuanshen,
R.raw.one_dizuo,
R.raw.one_houmian,
R.raw.one_qiandizuo,
R.raw.one_qianmian
},
{
R.raw.three_chuanshen,
R.raw.three_liangce,
R.raw.three_pentong,
R.raw.three_shangmian,
R.raw.three_shangmianqian,
R.raw.three_weiyi
},
{
R.drawable.two_ceyi,
R.drawable.two_chuanshen,
R.drawable.two_pentong,
R.drawable.two_shangmian,
R.drawable.two_weijia,
R.drawable.two_weiyi
}
};
}

View File

@@ -0,0 +1,351 @@
package com.bn.clp;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import android.opengl.GLES20;
import com.bn.core.MatrixState;
public class Bridge extends BNDrawer
{
Bridge_In bridge_in;
public Bridge(int programId)
{
bridge_in=new Bridge_In(programId);
}
@Override
public void drawSelf(int[] texId,int dyFlag)
{
MatrixState.pushMatrix();
bridge_in.realDrawSelf(texId[0]);
MatrixState.popMatrix();
}
private class Bridge_In
{
//单位长度
float UNIT_SIZE=2.1f;
//自定义渲染管线的id
int mProgram;
//总变化矩阵引用的id
int muMVPMatrixHandle;
//顶点位置属性引用id
int maPositionHandle;
//顶点纹理坐标属性引用id
int maTexCoorHandle;
//顶点数据缓冲和纹理坐标数据缓冲
FloatBuffer mVertexBuffer;
FloatBuffer mTexCoorBuffer;
//顶点数量
int vCount=0;
public Bridge_In(int programId)
{
initVertexData();
initShader(programId);
}
//初始化顶点数据的initVertexData方法
public void initVertexData()
{
float[] vertex=new float[]
{
//桥面的前侧
-6*UNIT_SIZE,4.5f*UNIT_SIZE,0,
-6*UNIT_SIZE,4*UNIT_SIZE,0,
23*UNIT_SIZE,4*UNIT_SIZE,0,
-6*UNIT_SIZE,4.5f*UNIT_SIZE,0,
23*UNIT_SIZE,4*UNIT_SIZE,0,
23*UNIT_SIZE,4.5f*UNIT_SIZE,0,
//桥面下侧
23*UNIT_SIZE,4*UNIT_SIZE,0,
-6*UNIT_SIZE,4*UNIT_SIZE,0,
-6*UNIT_SIZE,4*UNIT_SIZE,-4*UNIT_SIZE,
23*UNIT_SIZE,4*UNIT_SIZE,0,
-6*UNIT_SIZE,4*UNIT_SIZE,-4*UNIT_SIZE,
23*UNIT_SIZE,4*UNIT_SIZE,-4*UNIT_SIZE,
//桥面后侧
-6*UNIT_SIZE,4.5f*UNIT_SIZE,-4*UNIT_SIZE,
23*UNIT_SIZE,4*UNIT_SIZE,-4*UNIT_SIZE,
-6*UNIT_SIZE,4*UNIT_SIZE,-4*UNIT_SIZE,
-6*UNIT_SIZE,4.5f*UNIT_SIZE,-4*UNIT_SIZE,
23*UNIT_SIZE,4.5f*UNIT_SIZE,-4*UNIT_SIZE,
23*UNIT_SIZE,4*UNIT_SIZE,-4*UNIT_SIZE,
//桥下侧的支柱——左侧的
//桥下侧的支柱——梯形——左侧的
//前侧
2*UNIT_SIZE,4*UNIT_SIZE,0,
3*UNIT_SIZE,3*UNIT_SIZE,-UNIT_SIZE,
4*UNIT_SIZE,3*UNIT_SIZE,-UNIT_SIZE,
2*UNIT_SIZE,4*UNIT_SIZE,0,
4*UNIT_SIZE,3*UNIT_SIZE,-UNIT_SIZE,
5*UNIT_SIZE,4*UNIT_SIZE,0,
//右侧
5*UNIT_SIZE,4*UNIT_SIZE,0,
4*UNIT_SIZE,3*UNIT_SIZE,-UNIT_SIZE,
4*UNIT_SIZE,3*UNIT_SIZE,-3*UNIT_SIZE,
5*UNIT_SIZE,4*UNIT_SIZE,0,
4*UNIT_SIZE,3*UNIT_SIZE,-3*UNIT_SIZE,
5*UNIT_SIZE,4*UNIT_SIZE,-4*UNIT_SIZE,
//后侧
2*UNIT_SIZE,4*UNIT_SIZE,-4*UNIT_SIZE,
4*UNIT_SIZE,3*UNIT_SIZE,-3*UNIT_SIZE,
3*UNIT_SIZE,3*UNIT_SIZE,-3*UNIT_SIZE,
2*UNIT_SIZE,4*UNIT_SIZE,-4*UNIT_SIZE,
5*UNIT_SIZE,4*UNIT_SIZE,-4*UNIT_SIZE,
4*UNIT_SIZE,3*UNIT_SIZE,-3*UNIT_SIZE,
//左侧
2*UNIT_SIZE,4*UNIT_SIZE,0,
2*UNIT_SIZE,4*UNIT_SIZE,-4*UNIT_SIZE,
3*UNIT_SIZE,3*UNIT_SIZE,-3*UNIT_SIZE,
2*UNIT_SIZE,4*UNIT_SIZE,0,
3*UNIT_SIZE,3*UNIT_SIZE,-3*UNIT_SIZE,
3*UNIT_SIZE,3*UNIT_SIZE,-UNIT_SIZE,
//桥下侧的支柱——立方体——左侧的
//前侧
3*UNIT_SIZE,3*UNIT_SIZE,-UNIT_SIZE,
3*UNIT_SIZE,0,-UNIT_SIZE,
4*UNIT_SIZE,0,-UNIT_SIZE,
3*UNIT_SIZE,3*UNIT_SIZE,-UNIT_SIZE,
4*UNIT_SIZE,0,-UNIT_SIZE,
4*UNIT_SIZE,3*UNIT_SIZE,-UNIT_SIZE,
//右侧
4*UNIT_SIZE,3*UNIT_SIZE,-UNIT_SIZE,
4*UNIT_SIZE,0,-UNIT_SIZE,
4*UNIT_SIZE,0,-3*UNIT_SIZE,
4*UNIT_SIZE,3*UNIT_SIZE,-UNIT_SIZE,
4*UNIT_SIZE,0,-3*UNIT_SIZE,
4*UNIT_SIZE,3*UNIT_SIZE,-3*UNIT_SIZE,
//后侧
3*UNIT_SIZE,3*UNIT_SIZE,-3*UNIT_SIZE,
4*UNIT_SIZE,0,-3*UNIT_SIZE,
3*UNIT_SIZE,0,-3*UNIT_SIZE,
3*UNIT_SIZE,3*UNIT_SIZE,-3*UNIT_SIZE,
4*UNIT_SIZE,3*UNIT_SIZE,-3*UNIT_SIZE,
4*UNIT_SIZE,0,-3*UNIT_SIZE,
//左侧
3*UNIT_SIZE,3*UNIT_SIZE,-UNIT_SIZE,
3*UNIT_SIZE,3*UNIT_SIZE,-3*UNIT_SIZE,
3*UNIT_SIZE,0,-3*UNIT_SIZE,
3*UNIT_SIZE,3*UNIT_SIZE,-UNIT_SIZE,
3*UNIT_SIZE,0,-3*UNIT_SIZE,
3*UNIT_SIZE,0,-UNIT_SIZE,
//桥下侧的支柱——左侧的
//桥下侧的支柱——右侧的
//桥下侧的支柱——梯形——右侧的
//前侧
10*UNIT_SIZE,4*UNIT_SIZE,0,
11*UNIT_SIZE,3*UNIT_SIZE,-UNIT_SIZE,
12*UNIT_SIZE,3*UNIT_SIZE,-UNIT_SIZE,
10*UNIT_SIZE,4*UNIT_SIZE,0,
12*UNIT_SIZE,3*UNIT_SIZE,-UNIT_SIZE,
13*UNIT_SIZE,4*UNIT_SIZE,0,
//右侧
13*UNIT_SIZE,4*UNIT_SIZE,0,
12*UNIT_SIZE,3*UNIT_SIZE,-UNIT_SIZE,
12*UNIT_SIZE,3*UNIT_SIZE,-3*UNIT_SIZE,
13*UNIT_SIZE,4*UNIT_SIZE,0,
12*UNIT_SIZE,3*UNIT_SIZE,-3*UNIT_SIZE,
13*UNIT_SIZE,4*UNIT_SIZE,-4*UNIT_SIZE,
//后侧
10*UNIT_SIZE,4*UNIT_SIZE,-4*UNIT_SIZE,
12*UNIT_SIZE,3*UNIT_SIZE,-3*UNIT_SIZE,
11*UNIT_SIZE,3*UNIT_SIZE,-3*UNIT_SIZE,
10*UNIT_SIZE,4*UNIT_SIZE,-4*UNIT_SIZE,
13*UNIT_SIZE,4*UNIT_SIZE,-4*UNIT_SIZE,
12*UNIT_SIZE,3*UNIT_SIZE,-3*UNIT_SIZE,
//左侧
10*UNIT_SIZE,4*UNIT_SIZE,0,
10*UNIT_SIZE,4*UNIT_SIZE,-4*UNIT_SIZE,
11*UNIT_SIZE,3*UNIT_SIZE,-3*UNIT_SIZE,
10*UNIT_SIZE,4*UNIT_SIZE,0,
11*UNIT_SIZE,3*UNIT_SIZE,-3*UNIT_SIZE,
11*UNIT_SIZE,3*UNIT_SIZE,-UNIT_SIZE,
//桥下侧的支柱——立方体——右侧的
//前侧
11*UNIT_SIZE,3*UNIT_SIZE,-UNIT_SIZE,
11*UNIT_SIZE,0,-UNIT_SIZE,
12*UNIT_SIZE,0,-UNIT_SIZE,
11*UNIT_SIZE,3*UNIT_SIZE,-UNIT_SIZE,
12*UNIT_SIZE,0,-UNIT_SIZE,
12*UNIT_SIZE,3*UNIT_SIZE,-UNIT_SIZE,
//右侧
12*UNIT_SIZE,3*UNIT_SIZE,-UNIT_SIZE,
12*UNIT_SIZE,0,-UNIT_SIZE,
12*UNIT_SIZE,0,-3*UNIT_SIZE,
12*UNIT_SIZE,3*UNIT_SIZE,-UNIT_SIZE,
12*UNIT_SIZE,0,-3*UNIT_SIZE,
12*UNIT_SIZE,3*UNIT_SIZE,-3*UNIT_SIZE,
//后侧
11*UNIT_SIZE,3*UNIT_SIZE,-3*UNIT_SIZE,
12*UNIT_SIZE,0,-3*UNIT_SIZE,
11*UNIT_SIZE,0,-3*UNIT_SIZE,
11*UNIT_SIZE,3*UNIT_SIZE,-3*UNIT_SIZE,
12*UNIT_SIZE,3*UNIT_SIZE,-3*UNIT_SIZE,
12*UNIT_SIZE,0,-3*UNIT_SIZE,
//左侧
11*UNIT_SIZE,3*UNIT_SIZE,-UNIT_SIZE,
11*UNIT_SIZE,3*UNIT_SIZE,-3*UNIT_SIZE,
11*UNIT_SIZE,0,-3*UNIT_SIZE,
11*UNIT_SIZE,3*UNIT_SIZE,-UNIT_SIZE,
11*UNIT_SIZE,0,-3*UNIT_SIZE,
11*UNIT_SIZE,0,-UNIT_SIZE
};
vCount=vertex.length/3;
ByteBuffer vbb=ByteBuffer.allocateDirect(vertex.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer=vbb.asFloatBuffer();
mVertexBuffer.put(vertex);
mVertexBuffer.position(0);
float[] texcoor=new float[]
{
//桥面的前侧
0,0, 0,0.1f, 2,0.1f,
0,0, 2,0.1f, 2,0,
//桥面下侧
2,0, 0,0, 0,0.7f,
2,0, 0,0.7f, 2,0.7f,
//桥面后侧
0,0, 2,0.1f, 0,0.1f,
0,0, 2,0, 2,0.1f,
//桥下侧的支柱——左侧的
//桥下侧的支柱——梯形——左侧的
//前侧
0.0667f,0.2f, 0.1333f,0.4f, 0.2667f,0.4f,
0.0667f,0.2f, 0.2667f,0.4f, 0.3333f,0.2f,
//右侧
0.0667f,0.2f, 0.1333f,0.4f, 0.2667f,0.4f,
0.0667f,0.2f, 0.2667f,0.4f, 0.3333f,0.2f,
//后侧
0.0667f,0.2f, 0.2667f,0.4f, 0.1333f,0.4f,
0.0667f,0.2f, 0.3333f,0.2f, 0.2667f,0.4f,
//左侧
0.3333f,0.2f, 0.0667f,0.2f, 0.1333f,0.4f,
0.3333f,0.2f, 0.1333f,0.4f, 0.2667f,0.4f,
//桥下侧的支柱——立方体——左侧的
//前侧
0.1333f,0.4f, 0.1333f,1, 0.2667f,1,
0.1333f,0.4f, 0.2667f,1, 0.2667f,0.4f,
//右侧
0.1333f,0.4f, 0.1333f,1, 0.2667f,1,
0.1333f,0.4f, 0.2667f,1, 0.2667f,0.4f,
//后侧
0.1333f,0.4f, 0.2667f,1, 0.1333f,1,
0.1333f,0.4f, 0.2667f,0.4f, 0.2667f,1,
//左侧
0.2667f,0.4f, 0.1333f,0.4f, 0.1333f,1,
0.2667f,0.4f, 0.1333f,1, 0.2667f,1,
//桥下侧的支柱——左侧的
//桥下侧的支柱——右侧的
//桥下侧的支柱——梯形——右侧的
//前侧
0.6667f,0.2f, 0.7333f,0.4f, 0.8667f,0.4f,
0.6667f,0.2f, 0.8667f,0.4f, 0.9333f,0.2f,
//右侧
0.6667f,0.2f, 0.7333f,0.4f, 0.8667f,0.4f,
0.6667f,0.2f, 0.8667f,0.4f, 0.9333f,0.2f,
//后侧
0.6667f,0.2f, 0.8667f,0.4f, 0.7333f,0.4f,
0.6667f,0.2f, 0.9333f,0.2f, 0.8667f,0.4f,
//左侧
0.9333f,0.2f, 0.6667f,0.2f, 0.7333f,0.4f,
0.9333f,0.2f, 0.7333f,0.4f, 0.8667f,0.4f,
//桥下侧的支柱——立方体——右侧的
//前侧
0.7333f,0.4f, 0.7333f,1, 0.8667f,1,
0.7333f,0.4f, 0.8667f,1, 0.8667f,0.4f,
//右侧
0.7333f,0.4f, 0.7333f,1, 0.8667f,1,
0.7333f,0.4f, 0.8667f,1, 0.8667f,0.4f,
//后侧
0.7333f,0.4f, 0.8667f,1, 0.7333f,1,
0.7333f,0.4f, 0.8667f,0.4f, 0.8667f,1,
//左侧
0.8667f,0.4f, 0.7333f,0.4f, 0.7333f,1,
0.8667f,0.4f, 0.7333f,1, 0.8667f,1,
};
ByteBuffer tbb=ByteBuffer.allocateDirect(texcoor.length*4);
tbb.order(ByteOrder.nativeOrder());
mTexCoorBuffer=tbb.asFloatBuffer();
mTexCoorBuffer.put(texcoor);
mTexCoorBuffer.position(0);
}
//初始化着色器的initShader方法
public void initShader(int programId)
{
//基于顶点着色器与片元着色器创建程序
mProgram = programId;
//获取程序中顶点位置属性引用id
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
//获取程序中顶点纹理坐标属性引用id
maTexCoorHandle= GLES20.glGetAttribLocation(mProgram, "aTexCoor");
//获取程序中总变换矩阵引用id
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
}
//自定义的绘制方法drawSelf
public void realDrawSelf(int texId)
{
//制定使用某套shader程序
GLES20.glUseProgram(mProgram);
//将最终变换矩阵传入shader程序
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//传入顶点位置数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入纹理坐标数据
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false,
2*4,
mTexCoorBuffer
);
//允许顶点位置数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
//绘制纹理矩形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
}
}

View File

@@ -0,0 +1,443 @@
package com.bn.clp;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.List;
import android.opengl.GLES20;
import com.bn.core.MatrixState;
//城堡
public class Castle extends BNDrawer
{
//城堡上方的物体
Castle_Up castle_Up;
//下侧的圆柱
Cylinder cylinder;
Cylinder cylinder0;
Cylinder cylinder1;
Cylinder cylinder2;
//切分的角度
final float ANGLE_SPAN=30;
final float UNIT_SIZE=3.75f;
final float r=UNIT_SIZE*1.75f;
final float R=UNIT_SIZE*2.2f;
final float mR=UNIT_SIZE*2f;
//自下至上各个高度值
final float HEIGHT0=UNIT_SIZE*1.7f;
final float HEIGHT1=UNIT_SIZE*0.18f;
final float HEIGHT2=UNIT_SIZE*0.18f;
public Castle(int programId)
{
cylinder=new Cylinder(programId,mR,mR,ANGLE_SPAN,HEIGHT2);
//圆柱1
cylinder0=new Cylinder(programId,r,r,ANGLE_SPAN,HEIGHT0);
//圆柱2
cylinder1=new Cylinder(programId,r,R,ANGLE_SPAN,HEIGHT1);
//圆柱3
cylinder2=new Cylinder(programId,R,R,ANGLE_SPAN,HEIGHT2);
//城堡上方的物体
castle_Up=new Castle_Up(programId,R,ANGLE_SPAN,HEIGHT2);
}
//总的绘制方法drawSelf
public void drawSelf(int[] texId, int dyFlag)
{
MatrixState.pushMatrix();
cylinder.drawSelf(texId[1]);
MatrixState.popMatrix();
//1
MatrixState.pushMatrix();
MatrixState.translate(0, HEIGHT2+HEIGHT0, 0);
cylinder0.drawSelf(texId[0]);
MatrixState.popMatrix();
//2
MatrixState.pushMatrix();
MatrixState.translate(0, HEIGHT2+HEIGHT0*2+HEIGHT1, 0);
cylinder1.drawSelf(texId[1]);
MatrixState.popMatrix();
//3
MatrixState.pushMatrix();
MatrixState.translate(0, HEIGHT2+HEIGHT0*2+HEIGHT1*2+HEIGHT2, 0);
cylinder2.drawSelf(texId[1]);
MatrixState.popMatrix();
//4
MatrixState.pushMatrix();
MatrixState.translate(0, HEIGHT2+HEIGHT0*2+HEIGHT1*2+HEIGHT2*2, 0);
castle_Up.drawSelf(texId[1]);
MatrixState.popMatrix();
}
//内部类——圆柱
private class Cylinder
{
//自定义Shader程序的引用
int mProgram;
//总变换矩阵的引用id
int muMVPMatrixHandle;
//顶点属性的引用id
int maPositionHandle;
//顶点纹理坐标的引用id
int maTexCoorHandle;
//顶点坐标数据缓冲
FloatBuffer mVertexBuffer;
//顶点纹理坐标数据缓冲
FloatBuffer mTexCoorBuffer;
int vCount=0;//顶点数量
//R为圆柱底部的半径r为圆柱上部的半径angle_span表示的是切分的角度
public Cylinder(int programId,float R,float r,float angle_span,float height)
{
initVertexData(R,r,angle_span,height);
initShader(programId);
}
//初始化坐标数据的initVertexData方法
public void initVertexData(float R,float r,float angle_span,float height)
{
List<Float> tempList=new ArrayList<Float>();
for(float vAngle=0;vAngle<360;vAngle=vAngle+angle_span)
{
float x0=(float) (r*Math.cos(Math.toRadians(vAngle)));
float y0=height;
float z0=(float) (-r*Math.sin(Math.toRadians(vAngle)));
float x1=(float) (R*Math.cos(Math.toRadians(vAngle)));
float y1=-height;
float z1=(float) (-R*Math.sin(Math.toRadians(vAngle)));
float x2=(float) (R*Math.cos(Math.toRadians(vAngle+angle_span)));
float y2=-height;
float z2=(float) (-R*Math.sin(Math.toRadians(vAngle+angle_span)));
float x3=(float) (r*Math.cos(Math.toRadians(vAngle+angle_span)));
float y3=height;
float z3=(float) (-r*Math.sin(Math.toRadians(vAngle+angle_span)));
tempList.add(x0); tempList.add(y0); tempList.add(z0);
tempList.add(x1); tempList.add(y1); tempList.add(z1);
tempList.add(x3); tempList.add(y3); tempList.add(z3);
tempList.add(x3); tempList.add(y3); tempList.add(z3);
tempList.add(x1); tempList.add(y1); tempList.add(z1);
tempList.add(x2); tempList.add(y2); tempList.add(z2);
}
vCount=tempList.size()/3;//顶点数量
float[] vertex=new float[tempList.size()];
for(int i=0;i<tempList.size();i++)
{
vertex[i]=tempList.get(i);
}
ByteBuffer vbb=ByteBuffer.allocateDirect(vertex.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer=vbb.asFloatBuffer();
mVertexBuffer.put(vertex);
mVertexBuffer.position(0);
float[] texcoor=generateTexCoor((int)(360/angle_span),1,1,1);
ByteBuffer tbb=ByteBuffer.allocateDirect(texcoor.length*4);
tbb.order(ByteOrder.nativeOrder());
mTexCoorBuffer=tbb.asFloatBuffer();
mTexCoorBuffer.put(texcoor);
mTexCoorBuffer.position(0);
}
//初始化着色器程序的initShader方法
public void initShader(int programId)
{
mProgram=programId;
//获得顶点坐标数据的引用
maPositionHandle=GLES20.glGetAttribLocation(mProgram, "aPosition");
//顶点纹理坐标的引用id
maTexCoorHandle=GLES20.glGetAttribLocation(mProgram, "aTexCoor");
muMVPMatrixHandle=GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
}
//自定义的绘制方法
public void drawSelf(int texId)
{
//使用某套指定的Shader程序
GLES20.glUseProgram(mProgram);
//将最终变换矩阵传入到Shader程序中
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//传入坐标数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入纹理坐标数据
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false,
2*4,
mTexCoorBuffer
);
//允许顶点位置数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
//绘制纹理矩形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
//自动切分纹理产生纹理数组的方法
public float[] generateTexCoor(int bw,int bh,float width,float height)
{
float[] result=new float[bw*bh*6*2];
float sizew=width/bw;//列数
float sizeh=height/bh;//行数
int c=0;
for(int i=0;i<bh;i++)
{
for(int j=0;j<bw;j++)
{
//每行列一个矩形由两个三角形构成共六个点12个纹理坐标
float s=j*sizew;
float t=i*sizeh;
result[c++]=s;
result[c++]=t;
result[c++]=s;
result[c++]=t+sizeh;
result[c++]=s+sizew;
result[c++]=t;
result[c++]=s+sizew;
result[c++]=t;
result[c++]=s;
result[c++]=t+sizeh;
result[c++]=s+sizew;
result[c++]=t+sizeh;
}
}
return result;
}
}
//该类表示城堡上侧的部分
private class Castle_Up
{
//自定义Shader程序的引用
int mProgram;
//总变换矩阵的引用id
int muMVPMatrixHandle;
//顶点属性的引用id
int maPositionHandle;
//顶点纹理坐标的引用id
int maTexCoorHandle;
//顶点坐标数据缓冲
FloatBuffer mVertexBuffer;
//顶点纹理坐标数据缓冲
FloatBuffer mTexCoorBuffer;
int vCount=0;//顶点数量
//R为圆柱底部的半径r为圆柱上部的半径angle_span表示的是切分的角度
public Castle_Up(int programId,float R,float angle_span,float height)
{
initVertexData(R,angle_span,height);
initShader(programId);
}
//初始化坐标数据的initVertexData方法
public void initVertexData(float R,float angle_span,float height)
{
List<Float> vertexList=new ArrayList<Float>();
for(float vAngle=0;vAngle<360;vAngle=vAngle+angle_span)
{
float tempX0=(float) (R*Math.cos(Math.toRadians(vAngle)));
float tempZ0=(float) (-R*Math.sin(Math.toRadians(vAngle)));
float tempX1=(float) (R*Math.cos(Math.toRadians(vAngle+angle_span)));
float tempZ1=(float) (-R*Math.sin(Math.toRadians(vAngle+angle_span)));
//两点之间的间距平分3份
float tempX=(tempX1-tempX0)/3;
float tempZ=(tempZ1-tempZ0)/3;
float x0=tempX0;
float y0=height;
float z0=tempZ0;
float x1=tempX0;
float y1=-height;
float z1=tempZ0;
float x2=tempX0+tempX;
float y2=height;
float z2=tempZ0+tempZ;
float x3=tempX0+tempX;
float y3=-height;
float z3=tempZ0+tempZ;
float x4=tempX0+tempX*2;
float y4=height;
float z4=tempZ0+tempZ*2;
float x5=tempX0+tempX*2;
float y5=-height;
float z5=tempZ0+tempZ*2;
float x6=tempX1;
float y6=height;
float z6=tempZ1;
float x7=tempX1;
float y7=-height;
float z7=tempZ1;
//第一个三角形
vertexList.add(x0); vertexList.add(y0); vertexList.add(z0);
vertexList.add(x1); vertexList.add(y1); vertexList.add(z1);
vertexList.add(x3); vertexList.add(y3); vertexList.add(z3);
//第二个三角形
vertexList.add(x0); vertexList.add(y0); vertexList.add(z0);
vertexList.add(x3); vertexList.add(y3); vertexList.add(z3);
vertexList.add(x2); vertexList.add(y2); vertexList.add(z2);
//第三个三角形
vertexList.add(x4); vertexList.add(y4); vertexList.add(z4);
vertexList.add(x5); vertexList.add(y5); vertexList.add(z5);
vertexList.add(x7); vertexList.add(y7); vertexList.add(z7);
//第四个三角形
vertexList.add(x4); vertexList.add(y4); vertexList.add(z4);
vertexList.add(x7); vertexList.add(y7); vertexList.add(z7);
vertexList.add(x6); vertexList.add(y6); vertexList.add(z6);
}
vCount=vertexList.size()/3;
System.out.println("vCount="+vCount);
float[] vertex=new float[vertexList.size()];
for(int i=0;i<vertexList.size();i++)
{
vertex[i]=vertexList.get(i);
}
ByteBuffer vbb=ByteBuffer.allocateDirect(vertex.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer=vbb.asFloatBuffer();
mVertexBuffer.put(vertex);
mVertexBuffer.position(0);
float[] texcoor=generateTexCoor((int)(360/angle_span),1,1,1);
ByteBuffer tbb=ByteBuffer.allocateDirect(texcoor.length*4);
tbb.order(ByteOrder.nativeOrder());
mTexCoorBuffer=tbb.asFloatBuffer();
mTexCoorBuffer.put(texcoor);
mTexCoorBuffer.position(0);
}
//初始化着色器程序的initShader方法
public void initShader(int programId)
{
mProgram=programId;
//获得顶点坐标数据的引用
maPositionHandle=GLES20.glGetAttribLocation(mProgram, "aPosition");
//顶点纹理坐标的引用id
maTexCoorHandle=GLES20.glGetAttribLocation(mProgram, "aTexCoor");
muMVPMatrixHandle=GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
}
//自定义的绘制方法
public void drawSelf(int texId)
{
//使用某套指定的Shader程序
GLES20.glUseProgram(mProgram);
//将最终变换矩阵传入到Shader程序中
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//为传入坐标数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//为传入纹理坐标数据
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false,
2*4,
mTexCoorBuffer
);
//允许顶点位置数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
//绘制纹理矩形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
//自动切分纹理产生纹理数组的方法
public float[] generateTexCoor(int bw,int bh,float width,float height)
{
float[] result=new float[bw*bh*12*2];
float sizew=width/bw;//列数
float sizeh=height/bh;//行数
int c=0;
for(int i=0;i<bh;i++)
{
for(int j=0;j<bw;j++)
{
//每行列一个矩形由两个三角形构成共六个点12个纹理坐标
float s=j*sizew;
float t=i*sizeh;
//第一个三角形
result[c++]=s;
result[c++]=t;
result[c++]=s;
result[c++]=t+sizeh;
result[c++]=s+sizew/3;
result[c++]=t+sizeh;
//第二个三角形
result[c++]=s;
result[c++]=t;
result[c++]=s+sizew/3;
result[c++]=t+sizeh;
result[c++]=s+sizew/3;
result[c++]=t;
//第三个三角形
result[c++]=s+sizew*2/3;
result[c++]=t;
result[c++]=s+sizew*2/3;
result[c++]=t+sizeh;
result[c++]=s+sizew;
result[c++]=t+sizeh;
//第四个三角形
result[c++]=s+sizew*2/3;
result[c++]=t;
result[c++]=s+sizew;
result[c++]=t+sizeh;
result[c++]=s+sizew;
result[c++]=t;
}
}
return result;
}
}
}

View File

@@ -0,0 +1,36 @@
package com.bn.clp;
//ÓÃÀ´½øÐлæÖÆÇиîµÄÀà
public class ClipGrid
{
public static final boolean[][][] CLIP_MASK=
{
{
{true,true,true,true,true},
{true,true,true,true,true},
{true,true,true,true,true},
{true,true,true,true,true},
{false,false,false,false,false}
},
{
{true,true,true,true,false},
{true,true,true,true,false},
{true,true,true,true,false},
{true,true,true,true,false},
{true,true,true,true,false}
},
{
{false,false,false,false,false},
{true,true,true,true,true},
{true,true,true,true,true},
{true,true,true,true,true},
{true,true,true,true,true}
},
{
{false,true,true,true,true},
{false,true,true,true,true},
{false,true,true,true,true},
{false,true,true,true,true},
{false,true,true,true,true}
}
};
}

View File

@@ -0,0 +1,469 @@
package com.bn.clp;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.List;
import android.opengl.GLES20;
import com.bn.core.MatrixState;
//交通柱
public class Cone extends KZBJDrawer
{
//交通柱上方的圆柱
Cone_In cone_in;
//交通柱下侧的底
Pedestal pedestal;
//交通柱下侧的六角
Cylinder cylinder;
//切分的角度
final float ANGLE_SPAN=20;
final float UNIT_SIZE=1.0f;
final float HEIGHT=0.2f;
//下面的片切分的角度
float SPAN=60;
public Cone(int programId,float R,float R2)
{
//圆锥的上半部分
cone_in=new Cone_In(programId,R,ANGLE_SPAN,UNIT_SIZE);
cylinder=new Cylinder(programId,R2,R2,60,HEIGHT);
pedestal=new Pedestal(programId,R2,SPAN);
}
//总的绘制方法drawSelf
public void drawSelf(int texId)
{
//绘制交通柱的圆柱部分
cone_in.drawSelf(texId);
//绘制交通柱下方底座的上面
MatrixState.pushMatrix();
MatrixState.translate(0, -UNIT_SIZE, 0);
pedestal.drawSelf(texId);
MatrixState.popMatrix();
//绘制交通柱下方底座的侧面
MatrixState.pushMatrix();
MatrixState.translate(0, -UNIT_SIZE-HEIGHT, 0);
cylinder.drawSelf(texId);
MatrixState.popMatrix();
//绘制交通柱下方底座的下面
MatrixState.pushMatrix();
MatrixState.translate(0, -UNIT_SIZE-HEIGHT*2, 0);
MatrixState.rotate(180, 1, 0, 0);
pedestal.drawSelf(texId);
MatrixState.popMatrix();
}
//内部类——圆锥
private class Cone_In
{
//自定义Shader程序的引用
int mProgram;
//总变换矩阵的引用id
int muMVPMatrixHandle;
//顶点属性的引用id
int maPositionHandle;
//顶点纹理坐标的引用id
int maTexCoorHandle;
//顶点坐标数据缓冲
FloatBuffer mVertexBuffer;
//顶点纹理坐标数据缓冲
FloatBuffer mTexCoorBuffer;
int vCount=0;//顶点数量
//R为圆柱底部的半径r为圆柱上部的半径angle_span表示的是切分的角度
public Cone_In(int programId,float R,float angle_span,float height)
{
initVertexData(R,angle_span,height);
initShader(programId);
}
//初始化坐标数据的方法
public void initVertexData(float R,float angle_span,float height)
{
List<Float> tempList=new ArrayList<Float>();
//将交通锥的上侧顶点添加到List集合中
tempList.add(0f);
tempList.add(height);
tempList.add(0f);
for(float vAngle=0;vAngle<=360;vAngle=vAngle+angle_span)
{
float x=(float) (R*Math.cos(Math.toRadians(vAngle)));
float y=-height;
float z=(float) (-R*Math.sin(Math.toRadians(vAngle)));
tempList.add(x); tempList.add(y); tempList.add(z);
}
vCount=tempList.size()/3;//顶点数量
float[] vertex=new float[tempList.size()];
for(int i=0;i<tempList.size();i++)
{
vertex[i]=tempList.get(i);
}
ByteBuffer vbb=ByteBuffer.allocateDirect(vertex.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer=vbb.asFloatBuffer();
mVertexBuffer.put(vertex);
mVertexBuffer.position(0);
float[] texcoor=generateTexCoor((int)(360/angle_span+1),1,1);
ByteBuffer tbb=ByteBuffer.allocateDirect(texcoor.length*4);
tbb.order(ByteOrder.nativeOrder());
mTexCoorBuffer=tbb.asFloatBuffer();
mTexCoorBuffer.put(texcoor);
mTexCoorBuffer.position(0);
}
//初始化着色器程序的initShader方法
public void initShader(int programId)
{
mProgram=programId;
//获得顶点坐标数据的引用
maPositionHandle=GLES20.glGetAttribLocation(mProgram, "aPosition");
//顶点纹理坐标的引用id
maTexCoorHandle=GLES20.glGetAttribLocation(mProgram, "aTexCoor");
muMVPMatrixHandle=GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
}
//自定义的绘制方法
public void drawSelf(int texId)
{
//使用某套指定的Shader程序
GLES20.glUseProgram(mProgram);
//将最终变换矩阵传入到Shader程序中
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//为画笔指定坐标数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//为画笔指定纹理坐标数据
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false,
2*4,
mTexCoorBuffer
);
//允许顶点位置数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
//绘制纹理矩形
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, vCount);
}
//自动切分纹理产生纹理数组的方法
public float[] generateTexCoor(int bh,float width,float height)
{
float[] result=new float[bh*2+2];
//每一列对应的宽度
float tempW=width/bh;
int c=0;
result[c++]=0.5f*width;
result[c++]=0;
for(int i=0;i<bh;i++)
{
result[c++]=i*tempW;
result[c++]=height;
}
return result;
}
}
//下方的底座
private class Pedestal
{
//自定义Shader程序的引用
int mProgram;
//总变换矩阵的引用id
int muMVPMatrixHandle;
//顶点属性的引用id
int maPositionHandle;
//顶点纹理坐标的引用id
int maTexCoorHandle;
//顶点坐标数据缓冲
FloatBuffer mVertexBuffer;
//顶点纹理坐标数据缓冲
FloatBuffer mTexCoorBuffer;
int vCount=0;//顶点数量
//R为圆柱底部的半径r为圆柱上部的半径
public Pedestal(int programId,float R,float span)
{
initVertexData(R,span);
initShader(programId);
}
//初始化坐标数据的initVertexData方法
public void initVertexData(float R,float span)
{
List<Float> alist=new ArrayList<Float>();
for(float vAngle=0;vAngle<360;vAngle=vAngle+span)
{
float x0=0;
float y0=0;
float z0=0;
float x1=(float) (R*Math.cos(Math.toRadians(vAngle)));
float y1=0;
float z1=(float) (-R*Math.sin(Math.toRadians(vAngle)));
float x2=(float) (R*Math.cos(Math.toRadians(vAngle+span)));
float y2=0;
float z2=(float) (-R*Math.sin(Math.toRadians(vAngle+span)));
alist.add(x0); alist.add(y0); alist.add(z0);
alist.add(x1); alist.add(y1); alist.add(z1);
alist.add(x2); alist.add(y2); alist.add(z2);
}
vCount=alist.size()/3;
float[] vertex=new float[alist.size()];
for(int i=0;i<alist.size();i++)
{
vertex[i]=alist.get(i);
}
ByteBuffer vbb=ByteBuffer.allocateDirect(vertex.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer=vbb.asFloatBuffer();
mVertexBuffer.put(vertex);
mVertexBuffer.position(0);
float[] texcoor=generateTexCoor(span,1,1);
ByteBuffer tbb=ByteBuffer.allocateDirect(texcoor.length*4);
tbb.order(ByteOrder.nativeOrder());
mTexCoorBuffer=tbb.asFloatBuffer();
mTexCoorBuffer.put(texcoor);
mTexCoorBuffer.position(0);
}
//初始化着色器程序的initShader方法
public void initShader(int programId)
{
mProgram=programId;
//获得顶点坐标数据的引用
maPositionHandle=GLES20.glGetAttribLocation(mProgram, "aPosition");
//顶点纹理坐标的引用id
maTexCoorHandle=GLES20.glGetAttribLocation(mProgram, "aTexCoor");
muMVPMatrixHandle=GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
}
//自定义的绘制方法
public void drawSelf(int texId)
{
//使用某套指定的Shader程序
GLES20.glUseProgram(mProgram);
//将最终变换矩阵传入到Shader程序中
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//传入坐标数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入纹理坐标数据
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false,
2*4,
mTexCoorBuffer
);
//允许顶点位置数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
//绘制纹理矩形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
//自动切分纹理产生纹理数组的方法,triangleSize表示的是切分的三角形份数
public float[] generateTexCoor(float angle_span,float width,float height)
{
float[] result=new float[(int) (360/angle_span*3*2)];
int c=0;
for(float i=0;i<360;i=i+angle_span)
{
result[c++]=0.5f*width;
result[c++]=0.5f*height;
result[c++]=(float) (0.5f+0.5f*Math.cos(Math.toRadians(i)))*width;
result[c++]=(float) (0.5f-0.5f*Math.sin(Math.toRadians(i)))*height;
result[c++]=(float) (0.5f+0.5f*Math.cos(Math.toRadians(i+angle_span)))*width;
result[c++]=(float) (0.5f-0.5f*Math.sin(Math.toRadians(i+angle_span)))*height;
}
return result;
}
}
//内部类——圆柱
private class Cylinder
{
//自定义着色器程序的引用
int mProgram;
//总变换矩阵的引用id
int muMVPMatrixHandle;
//顶点属性的引用id
int maPositionHandle;
//顶点纹理坐标的引用id
int maTexCoorHandle;
//顶点坐标数据缓冲
FloatBuffer mVertexBuffer;
//顶点纹理坐标数据缓冲
FloatBuffer mTexCoorBuffer;
int vCount=0;//顶点数量
//R为圆柱底部的半径r为圆柱上部的半径angle_span表示的是切分的角度
public Cylinder(int programId,float R,float r,float angle_span,float height)
{
initVertexData(R,r,angle_span,height);
initShader(programId);
}
//初始化坐标数据的方法
public void initVertexData(float R,float r,float angle_span,float height)
{
List<Float> tempList=new ArrayList<Float>();
for(float vAngle=0;vAngle<360;vAngle=vAngle+angle_span)
{
float x0=(float) (r*Math.cos(Math.toRadians(vAngle)));
float y0=height;
float z0=(float) (-r*Math.sin(Math.toRadians(vAngle)));
float x1=(float) (R*Math.cos(Math.toRadians(vAngle)));
float y1=-height;
float z1=(float) (-R*Math.sin(Math.toRadians(vAngle)));
float x2=(float) (R*Math.cos(Math.toRadians(vAngle+angle_span)));
float y2=-height;
float z2=(float) (-R*Math.sin(Math.toRadians(vAngle+angle_span)));
float x3=(float) (r*Math.cos(Math.toRadians(vAngle+angle_span)));
float y3=height;
float z3=(float) (-r*Math.sin(Math.toRadians(vAngle+angle_span)));
tempList.add(x0); tempList.add(y0); tempList.add(z0);
tempList.add(x1); tempList.add(y1); tempList.add(z1);
tempList.add(x3); tempList.add(y3); tempList.add(z3);
tempList.add(x3); tempList.add(y3); tempList.add(z3);
tempList.add(x1); tempList.add(y1); tempList.add(z1);
tempList.add(x2); tempList.add(y2); tempList.add(z2);
}
vCount=tempList.size()/3;//顶点数量
float[] vertex=new float[tempList.size()];
for(int i=0;i<tempList.size();i++)
{
vertex[i]=tempList.get(i);
}
ByteBuffer vbb=ByteBuffer.allocateDirect(vertex.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer=vbb.asFloatBuffer();
mVertexBuffer.put(vertex);
mVertexBuffer.position(0);
float[] texcoor=generateTexCoor((int)(360/angle_span),1,1,1);
ByteBuffer tbb=ByteBuffer.allocateDirect(texcoor.length*4);
tbb.order(ByteOrder.nativeOrder());
mTexCoorBuffer=tbb.asFloatBuffer();
mTexCoorBuffer.put(texcoor);
mTexCoorBuffer.position(0);
}
//初始化着色器程序的initShader方法
public void initShader(int programId)
{
mProgram=programId;
//获得顶点坐标数据的引用
maPositionHandle=GLES20.glGetAttribLocation(mProgram, "aPosition");
//顶点纹理坐标的引用id
maTexCoorHandle=GLES20.glGetAttribLocation(mProgram, "aTexCoor");
muMVPMatrixHandle=GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
}
//自定义的绘制方法
public void drawSelf(int texId)
{
//使用某套指定的Shader程序
GLES20.glUseProgram(mProgram);
//将最终变换矩阵传入到Shader程序中
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//传入坐标数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入纹理坐标数据
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false,
2*4,
mTexCoorBuffer
);
//允许顶点位置数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
//绘制纹理矩形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
//自动切分纹理产生纹理数组的方法
public float[] generateTexCoor(int bw,int bh,float width,float height)
{
float[] result=new float[bw*bh*6*2];
float sizew=width/bw;//列数
float sizeh=height/bh;//行数
int c=0;
for(int i=0;i<bh;i++)
{
for(int j=0;j<bw;j++)
{
//每行列一个矩形由两个三角形构成共六个点12个纹理坐标
float s=j*sizew;
float t=i*sizeh;
result[c++]=s;
result[c++]=t;
result[c++]=s;
result[c++]=t+sizeh;
result[c++]=s+sizew;
result[c++]=t;
result[c++]=s+sizew;
result[c++]=t;
result[c++]=s;
result[c++]=t+sizeh;
result[c++]=s+sizew;
result[c++]=t+sizeh;
}
}
return result;
}
}
}

View File

@@ -0,0 +1,464 @@
package com.bn.clp;
import java.util.Date;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import com.bn.R;
//常量类
public class Constant
{
//新添加的,是否突破记录
public static boolean isBreakRecord;
//草地格子单位长度
public static final float GRASS_UNIT_SIZE=2.5f;
//用于绘制小雷达时进行缩放的值
public static final float Radar_Ratio=1100;
//获取当前时间字符串的方法
public static String getCurrTime()
{
String result=null;
Date d=new Date();
String month=d.getMonth()+1<10?"0"+(d.getMonth()+1):(d.getMonth()+1)+"";
String day=d.getDate()<10?"0"+d.getDate():d.getDate()+"";
String hours=d.getHours()<10?"0"+d.getHours():d.getHours()+"";
String minutes=d.getMinutes()<10?"0"+d.getMinutes():d.getMinutes()+"";
String seconds=d.getSeconds()<10?"0"+d.getSeconds():d.getSeconds()+"";
result=month+":"+day+":"+hours+":"+minutes+":"+seconds;
return result;
}
//获取游戏耗时
public static long gameTimeUse;
//获取游戏耗时字符串的方法
public static String getUseTime()
{
String result=null;
long[] timeUseTemp=new long[3];
timeUseTemp[0]=(long) Math.floor((gameTimeUse%1000)/10);
timeUseTemp[1]=(long) Math.floor((gameTimeUse%60000)/1000);
timeUseTemp[2]=(long) Math.floor((gameTimeUse/60000));
String minutes=timeUseTemp[2]<10?"0"+timeUseTemp[2]:timeUseTemp[2]+"";
String seconds=timeUseTemp[1]<10?"0"+timeUseTemp[1]:timeUseTemp[1]+"";
String minseconds=timeUseTemp[0]<10?"0"+timeUseTemp[0]:timeUseTemp[0]+"";
result=minutes+":"+seconds+":"+minseconds;
return result;
}
//音乐设置的相关标志位
public static boolean BgSoundFlag;//背景音乐播放标志位
public static boolean SoundEffectFlag;//游戏中音效播放标志位
//游戏模式选择的相关标志位
public static boolean isSpeedMode; //为true则为竞速模式 false则为计时模式
//小雷达中其他船的位置
public static float[][] other_Boat_XZ;
//为仪表板进行自适应的常量数据 0号为480x800 1号为480x854 2号为540x960 3号为320x480
public static int screenId=0;
public static float screenRatio;
public static final float screenRatio480x320=1.5f;//屏幕宽高比
public static final float screenRatio800x480=1.667f;
public static final float screenRatio854x480=1.779f;
public static final float screenRatio960x540=1.778f;
public static final float[][] Self_Adapter_Data_ON_TOUCH=
{//换视角 暂停 GO[每个部件四个参数,顺序为上下范围,左右范围]--新加 刹车按钮--新加时间(后视镜)按钮
{
0,0.104f,0,0.063f,
0,0.104f,0.938f,1,
0.792f,0.938f,0.875f,1,
0.792f,0.958f,0.018f,0.220f,
0,0.144f,0.400f,0.670f
},
{
0,0.104f,0,0.059f,
0,0.104f,0.941f,1,
0.792f,1,0.855f,0.972f,
0.792f,1,0.017f,0.220f,
0,0.154f,0.450f,0.70f
},
{
0,0.093f,0,0.052f,
0,0.093f,0.948f,1,
0.778f,0.963f,0.875f,0.979f,
0.778f,0.963f,0.016f,0.208f,
0,0.123f,0.400f,0.660f
},
{
0,0.156f,0,0.104f,
0,0.156f,0.896f,1,
0.625f,0.938f,0.75f,0.958f,
0.625f,0.938f,0.031f,0.278f,
0,0.156f,0.510f,0.720f
}
};
public static final float[][] Self_Adapter_Data_TRASLATE=
{//换视角 暂停 加速器 计速器 雷达[x,y,width] ---新加一个刹车按钮 //320x480的数据暂时没有给出需要进行测试
{-1.15f, 0.09f, 0.264f ,1.9f, 0.09f, 0.264f, 1.65f, -1.5f, 0.64f, -1.4f, 0.40f, 0.295f, 1.3f, 0.40f, 0.31f, -1.0f, -1.53f, 0.5f},
{-1.27f, 0.09f, 0.264f ,2.0f, 0.09f, 0.264f, 1.75f, -1.5f, 0.63f, -1.5f, 0.40f, 0.295f, 1.4f, 0.40f, 0.3f, -1.07f, -1.52f, 0.55f},
{-1.27f, 0.09f, 0.264f ,2.0f, 0.09f, 0.264f, 1.75f, -1.5f, 0.63f, -1.5f, 0.40f, 0.295f, 1.4f, 0.40f, 0.3f, -1.09f, -1.52f, 0.55f},
{-1f, 0.09f, 0.264f ,1.76f, 0.09f, 0.264f, 1.47f, -1.56f, 0.62f, -1.2f, 0.40f, 0.297f, 1.18f, 0.40f, 0.3f, -0.79f, -1.53f, 0.5f}
};
//为后视镜的大小和后视镜框进行自适应的常量数据 0号为480x800 1号为480x854 2号为540x960 3号为320x480
//依次为裁剪窗口的xy后视镜框的y偏移量后视镜框的宽、高
public static final float[][] Self_Adapter_Data_HSJ_XY=
{
{253,390,0.82f,0.66f,0.22f}, //0.82f,0.66f,0.22f
{280,390,0.82f,0.66f,0.22f}, //0.82f,0.66f,0.22f
{330,450,0.84f,0.59f,0.20f}, //0.84f,0.59f,0.20f
{280,390,0.82f,0.66f,0.22f} //0.82f,0.66f,0.22f
};
//为竞速模式服务的参数
//用来帮助记录英雄船名次的常量
public static int RANK_FOR_HELP=1;
//用来记录英雄船的名次
public static int RANK_FOR_HERO_BOAT=0;
//用来记录其他船的圈数
public static int[] BOAT_LAP_NUMBER_OTHER;
//其他船的速度
public static final float[] Max_BOAT_V_OTHER={1.26f,1.19f};
//32*32的地图矩阵的路线
public static final int[][] PATH=
{
{1,0},{0,0},{0,1},{0,2},{0,3},{0,4},{1,4},{2,4},{2,5},{2,6},
{2,7},{2,8},{3,8},{3,9},{2,9},{2,10},{2,11},{2,12},{2,13},{2,14},
{2,15},{3,15},{4,15},{4,14},{4,13},{4,12},{4,11},{5,11},{6,11},{7,11},
{7,12},{8,12},{9,12},{9,11},{10,11},{11,11},{12,11},{13,11},{13,12},{12,12},
{12,13},{13,13},{13,14},{13,15},{14,15},{14,16},{13,16},{13,17},{13,18},{13,19},
{12,19},{12,20},{11,20},{10,20},{9,20},{9,21},{8,21},{7,21},{7,20},{6,20},
{5,20},{4,20},{4,21},{5,21},{5,22},{5,23},{5,24},{5,25},{4,25},{3,25},
{2,25},{2,26},{2,27},{2,28},{2,29},{3,29},{4,29},{5,29},{5,28},{6,28},
{6,27},{6,26},{7,26},{8,26},{9,26},{10,26},{10,27},{11,27},{11,26},{12,26},
{12,25},{13,25},{14,25},{15,25},{15,26},{16,26},{17,26},{17,25},{18,25},{19,25},
{19,26},{20,26},{21,26},{22,26},{23,26},{23,25},{22,25},{21,25},{21,24},{22,24},
{23,24},{24,24},{25,24},{25,25},{26,25},{26,24},{27,24},{28,24},{29,24},{29,23},
{28,23},{28,22},{29,22},{29,21},{28,21},{28,20},{29,20},{29,19},{28,19},{28,17},
{28,16},{28,15},{27,15},{26,15},{25,15},{24,15},{24,16},{23,16},{22,16},{21,16},
{20,16},{20,15},{20,14},{20,13},{20,12},{20,11},{21,11},{22,11},{23,11},{23,10},
{24,10},{25,10},{26,10},{26,9},{27,9},{27,8},{28,8},{28,7},{28,6},{29,6},
{30,6},{30,5},{29,5},{29,4},{29,3},{29,2},{28,2},{27,2},{26,2},{26,1},
{25,1},{25,2},{24,2},{23,2},{23,3},{22,3},{22,2},{21,2},{21,1},{20,1},
{19,1},{19,2},{18,2},{18,1},{17,1},{16,1},{15,1},{15,2},{14,2},{14,1},
{13,1},{13,2},{12,2},{11,2},{10,2},{9,2},{8,2},{8,3},{7,3},{7,2},
{6,2},{5,2},{4,2},{3,2},{3,1},{3,0},{2,0}
};
//是否暂停游戏标志位
public static boolean isPaused=false;
//是否打开后视镜标志位
public static boolean isOpenHSJ=true;
//暂停游戏时,船的速度,以用来回到游戏
public static float CURR_BOAT_V_PAUSE=0;
//暂停游戏时,船的加速度,以用来回到游戏
public static float BOAT_A_PAUSE=0;
public static int numberOfN2=0;//当前氮气数初始为0
static int maxNumberOfN2=5;//最大氮气数最多只能同时拥有5个氮气
public static boolean halfFlag=false;//是否行驶半圈的标志位
public static int numberOfTurns=1;//圈数
final static int maxOfTurns=2; //最大圈数
//船的半径大小
public static final float BOAT_UNIT_SIZE=2.0f;
//用来锁定某些参数,保证不闪屏
static Object lockA=new Object();
//地图、3D物体宫格数控制参数
public static final float NUMBER_MAP=3;
//小船向上翘的角度值,行驶状态中
public static float head_Angle=4;
//小船速度为0时小船前后晃动的最大角度值
public static final float head_Angle_Max=4.25f;
//小船速度为0时小船前后晃动值的加速度
public static final float head_Angle_A=0.25f;
//检测在船行驶时速度是否大于该值当大于该值时将碰撞标志位置为false表示可以进行下一次的碰撞声音的播放
public final static float CURR_BOAT_V_PZ=0.3f;
//水面换帧线程工作标志位
public static boolean threadFlag=true;
//水面的高度值
public static float WATER_HIGH_ADJUST=0.0f;
//每一个格子对应的宽度以及高度
static final float UNIT_SIZE=60.0f;
//摄像机每次转动的角度
public static float DEGREE_SPAN=0;
//摄像机每次移动的距离 (船的当前速度)
public static float CURR_BOAT_V=0f;
public static float CURR_BOAT_V_TMD=0;
//船的最终最高速度
public static final float Max_BOAT_V_FINAL=1.3f*1.3f;
//船的最高速度
public static float Max_BOAT_V=1.3f;
//船的最高速度
public static final float Max_BOAT_V_VALUE=1.3f;
//船的加速度
public static float BOAT_A=0.0f;
//摄像机初始的视线方向0表示为z轴负方向
public static final float DIRECTION_INI=0;
//摄像机距离所观察目标点的距离
static final float DISTANCE=4.0f;
//摄像机初始时相应观察点的Y坐标
static final float CAMERA_INI_Y=2;
//小船初始XZ坐标
public static float YACHT_INI_X=0;
public static float YACHT_INI_Z=UNIT_SIZE/2+1*UNIT_SIZE;
//纹理图片的宽度
static final float TEXTURE_WIDTH=2.0f;
//纹理图片的高度
static final float TEXTURE_HEIGHT=2.0f;
//陆地最大高差
public static final float LAND_MAX_HIGHEST=10f;
//陆地上每个顶点的高度数组(直道)
public static float[][] yArray_ZD;
//陆地上每个顶点的高度数组(直道带小岛)
public static float[][] yArray_ZD_DXD;
//陆地上每个顶点的高度数组(弯道)
public static float[][] yArray_WD;
//陆地上每个顶点的高度数组(平原)
public static float[][] yArray_PD;
//陆地行数
public static int ROWS;
//陆地列数
public static int COLS;
//32*32的地图矩阵
public static final int[][] MAP_ARRAY=
{
{4,0,0,0,5,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8},
{1,8,8,8,10,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8},
{1,8,8,8,6,0,0,2,5,4,0,2,0,0,0,5,8,8,8,8,8,8,8,8,8,4,0,0,0,5,8,8},
{15,9,14,8,8,8,8,8,6,7,8,8,8,8,8,10,8,8,8,8,8,8,8,8,8,1,8,8,8,10,8,8},
{8,8,3,8,8,8,8,8,8,8,8,13,11,9,11,16,8,8,8,8,4,5,8,8,8,1,8,8,8,10,8,8},
{8,8,1,8,8,8,8,8,8,8,8,10,8,8,8,8,8,8,8,8,1,6,0,0,0,7,8,8,13,16,8,8},
{8,8,1,8,8,8,8,8,8,8,8,10,8,8,8,8,8,8,8,8,3,8,8,8,8,8,13,9,16,8,8,8},
{8,8,15,14,8,8,8,8,8,8,8,6,5,8,8,8,8,8,8,8,15,14,8,8,8,8,10,8,8,8,8,8},
{8,8,4,7,8,8,8,8,8,8,8,8,10,8,8,8,8,8,8,8,8,1,8,8,8,8,10,8,8,8,8,8},
{8,8,1,8,8,8,8,8,8,8,8,13,16,8,8,8,8,8,8,8,4,7,8,8,8,8,10,8,8,8,8,8},
{8,8,1,8,8,8,8,8,8,8,8,10,8,8,8,8,8,8,8,8,1,8,8,8,8,8,6,5,8,8,8,8},
{8,8,1,8,8,8,8,8,8,8,8,10,8,8,8,8,8,8,8,8,1,8,8,8,8,8,13,16,8,8,8,8},
{8,8,3,8,8,8,8,8,8,8,8,10,4,5,8,8,8,8,8,4,7,8,8,8,8,13,16,8,8,8,8,8},
{8,4,7,8,8,8,8,8,8,8,8,6,7,6,2,5,4,0,2,7,8,8,8,8,8,10,8,8,8,8,8,8},
{8,15,14,8,8,8,8,8,8,8,8,8,8,8,8,6,7,8,8,8,8,8,8,8,8,12,8,8,8,8,8,8},
{8,4,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,6,5,8,8,8,8,8},
{8,1,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,10,8,8,8,8,8},
{8,1,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,13,16,8,8,8,8,8},
{8,15,14,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,10,8,8,8,8,8,8},
{8,4,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,6,5,8,8,8,8,8},
{8,1,8,8,8,8,8,8,8,8,8,13,9,11,9,9,14,8,8,8,8,8,8,8,8,8,12,8,8,8,8,8},
{8,15,14,8,8,8,8,8,8,8,8,10,8,8,8,8,1,8,8,8,8,8,8,8,13,14,10,8,8,8,8,8},
{8,8,15,14,8,8,8,8,8,8,8,10,8,8,8,8,1,8,8,8,8,8,8,8,10,1,10,8,8,8,8,8},
{8,8,4,7,8,8,8,8,8,8,13,16,8,8,8,8,1,8,8,8,8,8,8,8,12,15,16,8,8,8,8,8},
{8,8,1,8,8,8,8,8,8,8,10,8,8,8,8,4,7,8,8,8,8,8,8,8,10,8,8,8,8,8,8,8},
{8,4,7,8,8,8,8,8,8,8,10,8,8,8,8,1,8,8,8,8,8,8,8,8,6,5,8,8,8,8,8,8},
{8,15,14,8,8,8,8,8,8,13,16,8,8,8,8,1,8,8,8,8,8,8,8,8,13,16,8,8,8,8,8,8},
{8,8,1,8,8,8,8,8,13,16,8,8,8,8,8,3,8,8,8,8,8,8,8,8,10,8,8,8,8,8,8,8},
{8,8,3,8,8,8,13,11,16,8,8,8,8,8,8,15,9,9,9,14,13,14,13,14,10,8,8,8,8,8,8,8},
{8,8,15,9,9,14,10,8,8,8,8,8,8,8,8,8,8,8,8,15,16,15,16,15,16,8,8,8,8,8,8,8},
{8,8,8,8,8,15,16,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8},
{8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8}
};
//由程序自动产生直道各行顶点Y坐标的方法
//赛道宽度
static int KD=13; //赛道宽度
static int PDKD=9; //平底宽度必须为奇数
static int rows=15;
public static float zdYRowFunction(float k)
{
//第一平直范围0~(行数减去平底的行数/2即0~((rows-KD)/2)
if(k<((rows-KD)/2))
{
return LAND_MAX_HIGHEST;
}
//第一下降范围((rows-KD)/2)((rows-PDKD)/2)
float span=((rows-PDKD)/2)-((rows-KD)/2);
if(k<((rows-PDKD)/2))
{
return LAND_MAX_HIGHEST*(-((k-((rows-PDKD)/2))/span));
}
//中间平直范围
if(k<((rows-PDKD)/2)+PDKD)
{
return 0;
}
//第一上升范围
if(k<rows-(rows-KD)/2)
{
float ratio=(k-((rows-PDKD)/2+PDKD))/span;
return LAND_MAX_HIGHEST*ratio;
}
//最后平直范围
return LAND_MAX_HIGHEST;
}
//产生直道Y坐标数组的方法
public static void generateZDY()
{
int colsPlusOne=rows+1;
int rowsPlusOne=rows+1;
yArray_ZD=new float[rowsPlusOne][colsPlusOne];
for(int i=0;i<rowsPlusOne;i++)
{
float h=zdYRowFunction(i);
for(int j=0;j<colsPlusOne;j++)
{
yArray_ZD[i][j]=h;
}
}
}
//产生直道带小岛Y坐标数组的方法
public static void generateZDY_XD(Resources resources)
{
float[][] xddata=loadLandforms(resources,R.drawable.xd,LAND_MAX_HIGHEST);
int colsPlusOne=rows+1;
int rowsPlusOne=rows+1;
yArray_ZD_DXD=new float[rowsPlusOne][colsPlusOne];
for(int i=0;i<rowsPlusOne;i++)
{
float h=zdYRowFunction(i);
for(int j=0;j<colsPlusOne;j++)
{
yArray_ZD_DXD[i][j]=h+xddata[i][j];
}
}
}
//产生弯道Y坐标数组的方法
public static void generateWDY()
{
int colsPlusOne=rows+1;
int rowsPlusOne=rows+1;
yArray_WD=new float[rowsPlusOne][colsPlusOne];
for(int i=0;i<rowsPlusOne;i++)
{
for(int j=0;j<colsPlusOne;j++)
{
float p=(float) Math.sqrt(i*i+j*j);
float h=zdYRowFunction(p);
if(h>LAND_MAX_HIGHEST)
{
h=LAND_MAX_HIGHEST;
}
if(h<LAND_MAX_HIGHEST/5.0f)
{
h=0;
}
yArray_WD[i][j]=h;
}
}
}
//产生平地Y坐标数组的方法
public static void generatePDY()
{
int colsPlusOne=rows+1;
int rowsPlusOne=rows+1;
yArray_PD=new float[rowsPlusOne][colsPlusOne];
for(int i=0;i<rowsPlusOne;i++)
{
for(int j=0;j<colsPlusOne;j++)
{
yArray_PD[i][j]=LAND_MAX_HIGHEST;
}
}
}
//从灰度图片中加载陆地上每个顶点的高度
public static float[][] loadLandforms(Resources resources,int index,float heightOffset)
{
Bitmap bt=BitmapFactory.decodeResource(resources, index);
int colsPlusOne=bt.getWidth();
int rowsPlusOne=bt.getHeight();
float[][] result=new float[rowsPlusOne][colsPlusOne];
for(int i=0;i<rowsPlusOne;i++)
{
for(int j=0;j<colsPlusOne;j++)
{
int color=bt.getPixel(j,i);
int r=Color.red(color);
int g=Color.green(color);
int b=Color.blue(color);
int h=(r+g+b)/3;
result[i][j]=h*heightOffset*0.9f/255;
}
}
bt.recycle();
return result;
}
static int directNo=3;
//根据角度的变化得到小船船头所指方向
public static int getDirectionNumber(float angleForSpecFrame)
{
float tempAngle=angleForSpecFrame%360;
if(tempAngle>=0)
{
if(tempAngle>225&&tempAngle<=315)
{
return 2;
}
else if(tempAngle>135&&tempAngle<=225)
{
return 1;
}
else if(tempAngle>45&&tempAngle<=135)
{
return 0;
}
else
{
return 3;
}
}
else
{
if(tempAngle>-135&&tempAngle<=-45)
{
return 3;
}
else if(tempAngle>-225&&tempAngle<=-135)
{
return 2;
}
else if(tempAngle>-315&&tempAngle<=-225)
{
return 1;
}
else
{
return 0;
}
}
}
//新添加的小山的坐标的数组
public static float[][] yArray_Mountion;
//山的最大高差
public static final float SD_HEIGHT=40;
public static void generateMountion(Resources resources)
{
yArray_Mountion=loadLandforms(resources,R.drawable.mountion_land_0,SD_HEIGHT);
}
//新添加的隧道的y坐标数组
public static float[][] yArray_Tunnel;
public static void generateTunnel(Resources resources)
{
yArray_Tunnel=loadLandforms(resources,R.drawable.mountion_land,SD_HEIGHT);
}
}

View File

@@ -0,0 +1,260 @@
package com.bn.clp;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import static com.bn.clp.Constant.*;
import android.opengl.GLES20;
import com.bn.core.MatrixState;
import com.bn.st.d2.MyActivity;
import static com.bn.clp.MyGLSurfaceView.*;
public class DaoJiShiForDraw
{
//数字矩形块的宽度和高度
float SHUZI_KUANDU=0.5f;
int DaoJiShiFlag=3;
float z_Order_Offset=-10;
WenLiJuXing wljx;
public static boolean DAOJISHI_FLAG=true;
public DJSThread djst;
MyActivity ma;
MyGLSurfaceView mgsv;
public DaoJiShiForDraw(int mProgram,MyActivity ma,MyGLSurfaceView mgsv)
{
wljx=new WenLiJuXing
(
SHUZI_KUANDU*5,
SHUZI_KUANDU*5
);
this.ma=ma;
this.mgsv=mgsv;
djst=new DJSThread();
wljx.initShader(mProgram);
}
public void drawSelf(int texId)
{
if(DaoJiShiFlag==3)
{
MatrixState.pushMatrix();
MatrixState.translate(0, 0, z_Order_Offset);
MatrixState.rotate(90, 1, 0, 0);
wljx.drawSelf(texId,0);
MatrixState.popMatrix();
}
else if(DaoJiShiFlag==2)
{
MatrixState.pushMatrix();
MatrixState.translate(0, 0, z_Order_Offset);
MatrixState.rotate(90, 1, 0, 0);
wljx.drawSelf(texId,1);
MatrixState.popMatrix();
}
else if(DaoJiShiFlag==1)
{
MatrixState.pushMatrix();
MatrixState.translate(0, 0, z_Order_Offset);
MatrixState.rotate(90, 1, 0, 0);
wljx.drawSelf(texId,2);
MatrixState.popMatrix();
}
else if(DaoJiShiFlag==0)
{
MatrixState.pushMatrix();
MatrixState.translate(0, 0, z_Order_Offset);
MatrixState.rotate(90, 1, 0, 0);
wljx.drawSelf(texId,3);
MatrixState.popMatrix();
}
}
//纹理矩形内部类
class WenLiJuXing
{
int mProgram;//自定义渲染管线着色器程序id
int muMVPMatrixHandle;//总变换矩阵引用id
int muMMatrixHandle;//位置、旋转变换矩阵
int maCameraHandle; //摄像机位置属性引用id
int maPositionHandle; //顶点位置属性引用id
int maNormalHandle; //顶点法向量属性引用id
int maTexCoorHandle; //顶点纹理坐标属性引用id
int maSunLightLocationHandle;//光源位置属性引用id
private FloatBuffer mVertexBuffer;//顶点坐标数据缓冲
private FloatBuffer mTextureBuffer[];//顶点着色数据缓冲
int vCount;//顶点数量
int texId;//纹理Id
public WenLiJuXing(float width,float height){//传入宽高和纹理坐标数组
//顶点坐标数据的初始化================begin============================
vCount=6;//每个格子两个三角形每个三角形3个顶点
float vertices[]=
{
-width/2,0,-height/2,
-width/2,0,height/2,
width/2,0,height/2,
-width/2,0,-height/2,
width/2,0,height/2,
width/2,0,-height/2
};
//创建顶点坐标数据缓冲
//vertices.length*4是因为一个整数四个字节
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());//设置字节顺序
mVertexBuffer = vbb.asFloatBuffer();//转换为float型缓冲
mVertexBuffer.put(vertices);//向缓冲区中放入顶点坐标数据
mVertexBuffer.position(0);//设置缓冲区起始位置
float[][] texTures=new float[][]
{
{
0.41f,0, 0.41f,1, 0.615f,1,
0.41f,0, 0.615f,1, 0.615f,0
},
{
0.2f,0, 0.2f,1, 0.415f,1,
0.2f,0, 0.415f,1, 0.415f,0
},
{
0,0, 0,1, 0.2f,1,
0,0, 0.2f,1, 0.2f,0
},
{
0.62f,0, 0.62f,1, 1,1,
0.62f,0, 1,1, 1,0
}
};
mTextureBuffer=new FloatBuffer[4];
for(int i=0;i<texTures.length;i++)
{
//创建顶点纹理数据缓冲
ByteBuffer tbb = ByteBuffer.allocateDirect(texTures[i].length*4);
tbb.order(ByteOrder.nativeOrder());//设置字节顺序
mTextureBuffer[i]= tbb.asFloatBuffer();//转换为Float型缓冲
mTextureBuffer[i].put(texTures[i]);//向缓冲区中放入顶点着色数据
mTextureBuffer[i].position(0);//设置缓冲区起始位置
//加载顶点着色器的脚本内容
}
}
//初始化着色器的initShader方法
public void initShader(int mProgram)
{
this.mProgram=mProgram;
//获取程序中顶点位置属性引用id
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
//获取程序中顶点纹理坐标属性引用id
maTexCoorHandle= GLES20.glGetAttribLocation(mProgram, "aTexCoor");
//获取程序中总变换矩阵引用id
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
}
public void drawSelf(int texId,int number)
{
//制定使用某套shader程序
GLES20.glUseProgram(mProgram);
//将最终变换矩阵传入shader程序
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//传入顶点位置数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入顶点纹理坐标数据
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false,
2*4,
mTextureBuffer[number]
);
//允许顶点位置数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
//绘制纹理矩形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
}
class DJSThread extends Thread
{
public DJSThread()
{
this.setName("DJSThread");
}
public void run()
{
while(DAOJISHI_FLAG)
{
//当游戏开始时倒计时3时播放一声
if(DaoJiShiFlag==3&&z_Order_Offset==-10&&SoundEffectFlag)
{
ma.shengyinBoFang(5, 0);
}
z_Order_Offset=z_Order_Offset+0.3f;
if(z_Order_Offset>-5)
{
z_Order_Offset=-10;
DaoJiShiFlag=DaoJiShiFlag-1;
//当换图时倒计时2、1各播放一声
if(DaoJiShiFlag>0&&SoundEffectFlag)
{
ma.shengyinBoFang(5, 0);
}//倒计时为0时播放可以开船的声音
else if(DaoJiShiFlag==0&&SoundEffectFlag)
{
ma.shengyinBoFang(6, 0);
}
}
if(DaoJiShiFlag<0)
{
DAOJISHI_FLAG=false;
isJiShi=true;
isAllowToClick=true;
DEGREE_SPAN=2.5f;
BOAT_A=0.025f;
MyGLSurfaceView.yachtLeftOrRightAngleA=yachtLeftOrRightAngleValue;
gameStartTime=System.currentTimeMillis();
mgsv.kt.start();
mgsv.tc.start();
mgsv.tfe.start();
}
try
{
Thread.sleep(80);
}catch(Exception e)
{
e.printStackTrace();
}
}
}
}
}

View File

@@ -0,0 +1,253 @@
package com.bn.clp;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import com.bn.core.MatrixState;
import android.opengl.GLES20;
import static com.bn.clp.Constant.*;
//绘制计速器的类
public class Dashboard
{
TextureRect tr;
DrawLine dl;
float angle;
float startAngle=125;
public Dashboard(int programId)
{
tr=new TextureRect(programId,Self_Adapter_Data_TRASLATE[screenId][11],0.25f);
dl=new DrawLine(programId,0.005f,0.16f);
}
//绘制方法
public void drawSelf(int texId)
{
//绘制仪表盘
MatrixState.pushMatrix();
tr.drawSelf(texId);
MatrixState.popMatrix();
//绘制线
MatrixState.pushMatrix();
MatrixState.translate(0.005f, -0.01f, 0.5f);
MatrixState.rotate(angle, 0, 0, 1);
dl.drawSelf(texId);
MatrixState.popMatrix();
}
public void changeangle(float v)//指针角度转的方法
{
float vSpan=Max_BOAT_V_FINAL/250;//每一仪表盘指针角度所表示的速度
{
float v_Angle=v/vSpan;
angle=startAngle-v_Angle;
}
}
//绘制仪表盘的类
private class TextureRect
{
//自定义渲染管线着色器程序id
int mProgram;
//总变化矩阵的引用id
int muMVPMatrixHandle;
//顶点属性的引用id
int maPositionHandle;
//顶点纹理属性的引用id
int maTexCoorHandle;
//顶点坐标数据缓冲、顶点纹理坐标数据缓冲
FloatBuffer mVertexBuffer;
FloatBuffer mTexCoorBuffer;
//顶点数量
int vCount;
public TextureRect(int mProgramId,float width,float height)
{
initVertexData(width,height);
initShader(mProgramId);
}
//初始化相应顶点数据的方法
public void initVertexData(float width,float height)
{
float[] vertices=new float[]
{
-width,height,0,
-width,-height,0,
width,-height,0,
-width,height,0,
width,-height,0,
width,height,0,
};
vCount=6;
//设置顶点坐标缓冲区
ByteBuffer vbb=ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer=vbb.asFloatBuffer();
mVertexBuffer.put(vertices);
mVertexBuffer.position(0);
float[] texcoor=new float[]
{
0,0.129f, 0,0.98f, 1,0.98f,
0,0.129f, 1,0.98f, 1,0.129f,
};
ByteBuffer tbb=ByteBuffer.allocateDirect(texcoor.length*4);
tbb.order(ByteOrder.nativeOrder());
mTexCoorBuffer=tbb.asFloatBuffer();
mTexCoorBuffer.put(texcoor);
mTexCoorBuffer.position(0);
}
//初始化着色器程序的initShader方法
public void initShader(int programId)
{
//创建自定义的Shader程序
mProgram=programId;
//获得顶点坐标属性的引用id
maPositionHandle=GLES20.glGetAttribLocation(mProgram, "aPosition");
//获得顶点纹理坐标属性的引用id
maTexCoorHandle=GLES20.glGetAttribLocation(mProgram, "aTexCoor");
//获得总变换矩阵的引用id
muMVPMatrixHandle=GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
}
//自定义的绘制方法
public void drawSelf(int texId)
{
//使用某套指定的Shader程序
GLES20.glUseProgram(mProgram);
//将总变换矩阵传入Shader程序
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//传入顶点数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入顶点纹理坐标数据
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false,
2*4,
mTexCoorBuffer
);
//允许顶点位置数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
//绘制
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
}
//红线类
private class DrawLine
{
//自定义渲染管线着色器程序id
int mProgram;
//总变化矩阵的引用id
int muMVPMatrixHandle;
//顶点属性的引用id
int maPositionHandle;
//顶点纹理属性的引用id
int maTexCoorHandle;
//顶点坐标数据缓冲、顶点纹理坐标数据缓冲
FloatBuffer mVertexBuffer;
FloatBuffer mTexCoorBuffer;
//顶点数量
int vCount;
public DrawLine(int mProgramId,float width,float height)
{
initVertexData(width,height);
initShader(mProgramId);
}
//初始化相应顶点数据的initVertexData方法
public void initVertexData(float width,float height)
{
float[] vertices=new float[]
{
-width,height,0,
-width,0,0,
width,0,0,
-width,height,0,
width,0,0,
width,height,0,
};
vCount=6;
//设置顶点坐标缓冲区
ByteBuffer vbb=ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer=vbb.asFloatBuffer();
mVertexBuffer.put(vertices);
mVertexBuffer.position(0);
float[] texcoor=new float[]
{
0,0, 0,0.125f, 0.45f,0.125f,
0,0, 0.45f,0.125f, 0.45f,0,
};
ByteBuffer tbb=ByteBuffer.allocateDirect(texcoor.length*4);
tbb.order(ByteOrder.nativeOrder());
mTexCoorBuffer=tbb.asFloatBuffer();
mTexCoorBuffer.put(texcoor);
mTexCoorBuffer.position(0);
}
//初始化着色器程序的initShader方法
public void initShader(int programId)
{
//创建自定义的Shader程序
mProgram=programId;
//获得顶点坐标属性的引用id
maPositionHandle=GLES20.glGetAttribLocation(mProgram, "aPosition");
//获得顶点纹理坐标属性的引用id
maTexCoorHandle=GLES20.glGetAttribLocation(mProgram, "aTexCoor");
//获得总变换矩阵的引用id
muMVPMatrixHandle=GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
}
//自定义的绘制方法
public void drawSelf(int texId)
{
//使用某套指定的Shader程序
GLES20.glUseProgram(mProgram);
//将总变换矩阵传入Shader程序
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//传入顶点数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入顶点纹理坐标数据
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false,
2*4,
mTexCoorBuffer
);
//允许顶点位置数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
//绘制
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
}
}

View File

@@ -0,0 +1,462 @@
package com.bn.clp;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import android.opengl.GLES20;
import com.bn.core.MatrixState;
//该类是船埠头
public class Dock extends BNDrawer
{
DockIn dockIn;
public Dock(int programId)
{
dockIn=new DockIn(programId);
}
@Override
public void drawSelf(int[] texId, int dyFlag)
{
MatrixState.pushMatrix();
dockIn.drawSelf(texId[0]);
MatrixState.popMatrix();
}
private class DockIn
{
//单位长度
float UNIT_SIZE=0.3f;
//自定义渲染管线着色器的id
int mProgram;
//总变化矩阵引用的id
int muMVPMatrixHandle;
//顶点位置属性引用id
int maPositionHandle;
//顶点纹理坐标属性引用id
int maTexCoorHandle;
//顶点数据缓冲和纹理坐标数据缓冲
FloatBuffer mVertexBuffer;
FloatBuffer mTexCoorBuffer;
//顶点数量
int vCount=0;
public DockIn(int programId)
{
initVertexData();
initShader(programId);
}
//初始化顶点数据的initVertexData方法
public void initVertexData()
{
float[] vertex=new float[]
{
//板上面
-15*UNIT_SIZE,9.5f*UNIT_SIZE,-5*UNIT_SIZE,
-15*UNIT_SIZE,9.5f*UNIT_SIZE,5*UNIT_SIZE,
15*UNIT_SIZE,9.5f*UNIT_SIZE,-5*UNIT_SIZE,
15*UNIT_SIZE,9.5f*UNIT_SIZE,-5*UNIT_SIZE,
-15*UNIT_SIZE,9.5f*UNIT_SIZE,5*UNIT_SIZE,
15*UNIT_SIZE,9.5f*UNIT_SIZE,5*UNIT_SIZE,
//板下面
15*UNIT_SIZE,8.5f*UNIT_SIZE,-5*UNIT_SIZE,
15*UNIT_SIZE,8.5f*UNIT_SIZE,5*UNIT_SIZE,
-15*UNIT_SIZE,8.5f*UNIT_SIZE,-5*UNIT_SIZE,
-15*UNIT_SIZE,8.5f*UNIT_SIZE,-5*UNIT_SIZE,
15*UNIT_SIZE,8.5f*UNIT_SIZE,5*UNIT_SIZE,
-15*UNIT_SIZE,8.5f*UNIT_SIZE,5*UNIT_SIZE,
//板前面
-15*UNIT_SIZE,9.5f*UNIT_SIZE,5*UNIT_SIZE,
-15*UNIT_SIZE,8.5f*UNIT_SIZE,5*UNIT_SIZE,
15*UNIT_SIZE,9.5f*UNIT_SIZE,5*UNIT_SIZE,
15*UNIT_SIZE,9.5f*UNIT_SIZE,5*UNIT_SIZE,
-15*UNIT_SIZE,8.5f*UNIT_SIZE,5*UNIT_SIZE,
15*UNIT_SIZE,8.5f*UNIT_SIZE,5*UNIT_SIZE,
//板后面
15*UNIT_SIZE,9.5f*UNIT_SIZE,-5*UNIT_SIZE,
15*UNIT_SIZE,8.5f*UNIT_SIZE,-5*UNIT_SIZE,
-15*UNIT_SIZE,9.5f*UNIT_SIZE,-5*UNIT_SIZE,
-15*UNIT_SIZE,9.5f*UNIT_SIZE,-5*UNIT_SIZE,
15*UNIT_SIZE,8.5f*UNIT_SIZE,-5*UNIT_SIZE,
-15*UNIT_SIZE,8.5f*UNIT_SIZE,-5*UNIT_SIZE,
//板左面
-15*UNIT_SIZE,9.5f*UNIT_SIZE,-5*UNIT_SIZE,
-15*UNIT_SIZE,8.5f*UNIT_SIZE,-5*UNIT_SIZE,
-15*UNIT_SIZE,9.5f*UNIT_SIZE,5*UNIT_SIZE,
-15*UNIT_SIZE,9.5f*UNIT_SIZE,5*UNIT_SIZE,
-15*UNIT_SIZE,8.5f*UNIT_SIZE,-5*UNIT_SIZE,
-15*UNIT_SIZE,8.5f*UNIT_SIZE,5*UNIT_SIZE,
//板右面
15*UNIT_SIZE,9.5f*UNIT_SIZE,5*UNIT_SIZE,
15*UNIT_SIZE,8.5f*UNIT_SIZE,5*UNIT_SIZE,
15*UNIT_SIZE,9.5f*UNIT_SIZE,-5*UNIT_SIZE,
15*UNIT_SIZE,9.5f*UNIT_SIZE,-5*UNIT_SIZE,
15*UNIT_SIZE,9.5f*UNIT_SIZE,5*UNIT_SIZE,
15*UNIT_SIZE,9.5f*UNIT_SIZE,-5*UNIT_SIZE,
//---------------------左上角支柱---------------------------
//上面
-13*UNIT_SIZE,12*UNIT_SIZE,-5*UNIT_SIZE,
-13*UNIT_SIZE,12*UNIT_SIZE,-4*UNIT_SIZE,
-12*UNIT_SIZE,12*UNIT_SIZE,-5*UNIT_SIZE,
-12*UNIT_SIZE,12*UNIT_SIZE,-5*UNIT_SIZE,
-13*UNIT_SIZE,12*UNIT_SIZE,-4*UNIT_SIZE,
-12*UNIT_SIZE,12*UNIT_SIZE,-4*UNIT_SIZE,
//下面
-12*UNIT_SIZE,0*UNIT_SIZE,-5*UNIT_SIZE,
-12*UNIT_SIZE,0*UNIT_SIZE,-4*UNIT_SIZE,
-13*UNIT_SIZE,0*UNIT_SIZE,-5*UNIT_SIZE,
-13*UNIT_SIZE,0*UNIT_SIZE,-5*UNIT_SIZE,
-12*UNIT_SIZE,0*UNIT_SIZE,-4*UNIT_SIZE,
-13*UNIT_SIZE,0*UNIT_SIZE,-4*UNIT_SIZE,
//前面
-13*UNIT_SIZE,12*UNIT_SIZE,-4*UNIT_SIZE,
-13*UNIT_SIZE,0*UNIT_SIZE,-4*UNIT_SIZE,
-12*UNIT_SIZE,12*UNIT_SIZE,-4*UNIT_SIZE,
-12*UNIT_SIZE,12*UNIT_SIZE,-4*UNIT_SIZE,
-13*UNIT_SIZE,0*UNIT_SIZE,-4*UNIT_SIZE,
-12*UNIT_SIZE,0*UNIT_SIZE,-4*UNIT_SIZE,
//后面
-12*UNIT_SIZE,12*UNIT_SIZE,-5*UNIT_SIZE,
-12*UNIT_SIZE,0*UNIT_SIZE,-5*UNIT_SIZE,
-13*UNIT_SIZE,12*UNIT_SIZE,-5*UNIT_SIZE,
-13*UNIT_SIZE,12*UNIT_SIZE,-5*UNIT_SIZE,
-12*UNIT_SIZE,0*UNIT_SIZE,-5*UNIT_SIZE,
-13*UNIT_SIZE,0*UNIT_SIZE,-5*UNIT_SIZE,
//左面
-13*UNIT_SIZE,12*UNIT_SIZE,-5*UNIT_SIZE,
-13*UNIT_SIZE,0*UNIT_SIZE,-5*UNIT_SIZE,
-13*UNIT_SIZE,12*UNIT_SIZE,-4*UNIT_SIZE,
-13*UNIT_SIZE,12*UNIT_SIZE,-4*UNIT_SIZE,
-13*UNIT_SIZE,0*UNIT_SIZE,-5*UNIT_SIZE,
-13*UNIT_SIZE,0*UNIT_SIZE,-4*UNIT_SIZE,
//右面
-12*UNIT_SIZE,12*UNIT_SIZE,-4*UNIT_SIZE,
-12*UNIT_SIZE,0*UNIT_SIZE,-4*UNIT_SIZE,
-12*UNIT_SIZE,12*UNIT_SIZE,-5*UNIT_SIZE,
-12*UNIT_SIZE,12*UNIT_SIZE,-5*UNIT_SIZE,
-12*UNIT_SIZE,0*UNIT_SIZE,-4*UNIT_SIZE,
-12*UNIT_SIZE,0*UNIT_SIZE,-5*UNIT_SIZE,
//----------------------左下角支柱------------------
//上面
-13*UNIT_SIZE,12*UNIT_SIZE,4*UNIT_SIZE,
-13*UNIT_SIZE,12*UNIT_SIZE,5*UNIT_SIZE,
-12*UNIT_SIZE,12*UNIT_SIZE,4*UNIT_SIZE,
-12*UNIT_SIZE,12*UNIT_SIZE,4*UNIT_SIZE,
-13*UNIT_SIZE,12*UNIT_SIZE,5*UNIT_SIZE,
-12*UNIT_SIZE,12*UNIT_SIZE,5*UNIT_SIZE,
//下面
-12*UNIT_SIZE,0*UNIT_SIZE,4*UNIT_SIZE,
-12*UNIT_SIZE,0*UNIT_SIZE,5*UNIT_SIZE,
-13*UNIT_SIZE,0*UNIT_SIZE,4*UNIT_SIZE,
-13*UNIT_SIZE,0*UNIT_SIZE,4*UNIT_SIZE,
-12*UNIT_SIZE,0*UNIT_SIZE,5*UNIT_SIZE,
-13*UNIT_SIZE,0*UNIT_SIZE,5*UNIT_SIZE,
//前面
-13*UNIT_SIZE,12*UNIT_SIZE,5*UNIT_SIZE,
-13*UNIT_SIZE,0*UNIT_SIZE,5*UNIT_SIZE,
-12*UNIT_SIZE,12*UNIT_SIZE,5*UNIT_SIZE,
-12*UNIT_SIZE,12*UNIT_SIZE,5*UNIT_SIZE,
-13*UNIT_SIZE,0*UNIT_SIZE,5*UNIT_SIZE,
-12*UNIT_SIZE,0*UNIT_SIZE,5*UNIT_SIZE,
//后面
-12*UNIT_SIZE,12*UNIT_SIZE,4*UNIT_SIZE,
-12*UNIT_SIZE,0*UNIT_SIZE,4*UNIT_SIZE,
-13*UNIT_SIZE,12*UNIT_SIZE,4*UNIT_SIZE,
-13*UNIT_SIZE,12*UNIT_SIZE,4*UNIT_SIZE,
-12*UNIT_SIZE,0*UNIT_SIZE,4*UNIT_SIZE,
-13*UNIT_SIZE,0*UNIT_SIZE,4*UNIT_SIZE,
//左面
-13*UNIT_SIZE,12*UNIT_SIZE,4*UNIT_SIZE,
-13*UNIT_SIZE,0*UNIT_SIZE,4*UNIT_SIZE,
-13*UNIT_SIZE,12*UNIT_SIZE,5*UNIT_SIZE,
-13*UNIT_SIZE,12*UNIT_SIZE,5*UNIT_SIZE,
-13*UNIT_SIZE,0*UNIT_SIZE,4*UNIT_SIZE,
-13*UNIT_SIZE,0*UNIT_SIZE,5*UNIT_SIZE,
//右面
-12*UNIT_SIZE,12*UNIT_SIZE,5*UNIT_SIZE,
-12*UNIT_SIZE,0*UNIT_SIZE,5*UNIT_SIZE,
-12*UNIT_SIZE,12*UNIT_SIZE,4*UNIT_SIZE,
-12*UNIT_SIZE,12*UNIT_SIZE,4*UNIT_SIZE,
-12*UNIT_SIZE,0*UNIT_SIZE,5*UNIT_SIZE,
-12*UNIT_SIZE,0*UNIT_SIZE,4*UNIT_SIZE,
//----------右上角支柱------------
//上面
-0.5f*UNIT_SIZE,12*UNIT_SIZE,-5*UNIT_SIZE,
-0.5f*UNIT_SIZE,12*UNIT_SIZE,-4*UNIT_SIZE,
0.5f*UNIT_SIZE,12*UNIT_SIZE,-5*UNIT_SIZE,
0.5f*UNIT_SIZE,12*UNIT_SIZE,-5*UNIT_SIZE,
-0.5f*UNIT_SIZE,12*UNIT_SIZE,-4*UNIT_SIZE,
0.5f*UNIT_SIZE,12*UNIT_SIZE,-4*UNIT_SIZE,
//下面
0.5f*UNIT_SIZE,0*UNIT_SIZE,-5*UNIT_SIZE,
0.5f*UNIT_SIZE,0*UNIT_SIZE,-4*UNIT_SIZE,
-0.5f*UNIT_SIZE,0*UNIT_SIZE,-5*UNIT_SIZE,
-0.5f*UNIT_SIZE,0*UNIT_SIZE,-5*UNIT_SIZE,
0.5f*UNIT_SIZE,0*UNIT_SIZE,-4*UNIT_SIZE,
-0.5f*UNIT_SIZE,0*UNIT_SIZE,-4*UNIT_SIZE,
//前面
-0.5f*UNIT_SIZE,12*UNIT_SIZE,-4*UNIT_SIZE,
-0.5f*UNIT_SIZE,0*UNIT_SIZE,-4*UNIT_SIZE,
0.5f*UNIT_SIZE,12*UNIT_SIZE,-4*UNIT_SIZE,
0.5f*UNIT_SIZE,12*UNIT_SIZE,-4*UNIT_SIZE,
-0.5f*UNIT_SIZE,0*UNIT_SIZE,-4*UNIT_SIZE,
0.5f*UNIT_SIZE,0*UNIT_SIZE,-4*UNIT_SIZE,
//后面
0.5f*UNIT_SIZE,12*UNIT_SIZE,-5*UNIT_SIZE,
0.5f*UNIT_SIZE,0*UNIT_SIZE,-5*UNIT_SIZE,
-0.5f*UNIT_SIZE,12*UNIT_SIZE,-5*UNIT_SIZE,
-0.5f*UNIT_SIZE,12*UNIT_SIZE,-5*UNIT_SIZE,
0.5f*UNIT_SIZE,0*UNIT_SIZE,-5*UNIT_SIZE,
-0.5f*UNIT_SIZE,0*UNIT_SIZE,-5*UNIT_SIZE,
//左面
-0.5f*UNIT_SIZE,12*UNIT_SIZE,-5*UNIT_SIZE,
-0.5f*UNIT_SIZE,0*UNIT_SIZE,-5*UNIT_SIZE,
-0.5f*UNIT_SIZE,12*UNIT_SIZE,-4*UNIT_SIZE,
-0.5f*UNIT_SIZE,12*UNIT_SIZE,-4*UNIT_SIZE,
-0.5f*UNIT_SIZE,0*UNIT_SIZE,-5*UNIT_SIZE,
-0.5f*UNIT_SIZE,0*UNIT_SIZE,-4*UNIT_SIZE,
//右面
0.5f*UNIT_SIZE,12*UNIT_SIZE,-4*UNIT_SIZE,
0.5f*UNIT_SIZE,0*UNIT_SIZE,-4*UNIT_SIZE,
0.5f*UNIT_SIZE,12*UNIT_SIZE,-5*UNIT_SIZE,
0.5f*UNIT_SIZE,12*UNIT_SIZE,-5*UNIT_SIZE,
0.5f*UNIT_SIZE,0*UNIT_SIZE,-4*UNIT_SIZE,
0.5f*UNIT_SIZE,0*UNIT_SIZE,-5*UNIT_SIZE,
//----------右下角支柱------------
//上面
-0.5f*UNIT_SIZE,12*UNIT_SIZE,4*UNIT_SIZE,
-0.5f*UNIT_SIZE,12*UNIT_SIZE,5*UNIT_SIZE,
0.5f*UNIT_SIZE,12*UNIT_SIZE,4*UNIT_SIZE,
0.5f*UNIT_SIZE,12*UNIT_SIZE,4*UNIT_SIZE,
-0.5f*UNIT_SIZE,12*UNIT_SIZE,5*UNIT_SIZE,
0.5f*UNIT_SIZE,12*UNIT_SIZE,5*UNIT_SIZE,
//下面
0.5f*UNIT_SIZE,0*UNIT_SIZE,4*UNIT_SIZE,
0.5f*UNIT_SIZE,0*UNIT_SIZE,5*UNIT_SIZE,
-0.5f*UNIT_SIZE,0*UNIT_SIZE,4*UNIT_SIZE,
-0.5f*UNIT_SIZE,0*UNIT_SIZE,4*UNIT_SIZE,
0.5f*UNIT_SIZE,0*UNIT_SIZE,5*UNIT_SIZE,
-0.5f*UNIT_SIZE,0*UNIT_SIZE,5*UNIT_SIZE,
//前面
-0.5f*UNIT_SIZE,12*UNIT_SIZE,5*UNIT_SIZE,
-0.5f*UNIT_SIZE,0*UNIT_SIZE,5*UNIT_SIZE,
0.5f*UNIT_SIZE,12*UNIT_SIZE,5*UNIT_SIZE,
0.5f*UNIT_SIZE,12*UNIT_SIZE,5*UNIT_SIZE,
-0.5f*UNIT_SIZE,0*UNIT_SIZE,5*UNIT_SIZE,
0.5f*UNIT_SIZE,0*UNIT_SIZE,5*UNIT_SIZE,
//后面
0.5f*UNIT_SIZE,12*UNIT_SIZE,4*UNIT_SIZE,
0.5f*UNIT_SIZE,0*UNIT_SIZE,4*UNIT_SIZE,
-0.5f*UNIT_SIZE,12*UNIT_SIZE,4*UNIT_SIZE,
-0.5f*UNIT_SIZE,12*UNIT_SIZE,4*UNIT_SIZE,
0.5f*UNIT_SIZE,0*UNIT_SIZE,4*UNIT_SIZE,
-0.5f*UNIT_SIZE,0*UNIT_SIZE,4*UNIT_SIZE,
//左面
-0.5f*UNIT_SIZE,12*UNIT_SIZE,4*UNIT_SIZE,
-0.5f*UNIT_SIZE,0*UNIT_SIZE,4*UNIT_SIZE,
-0.5f*UNIT_SIZE,12*UNIT_SIZE,5*UNIT_SIZE,
-0.5f*UNIT_SIZE,12*UNIT_SIZE,5*UNIT_SIZE,
-0.5f*UNIT_SIZE,0*UNIT_SIZE,4*UNIT_SIZE,
-0.5f*UNIT_SIZE,0*UNIT_SIZE,5*UNIT_SIZE,
//右面
0.5f*UNIT_SIZE,12*UNIT_SIZE,5*UNIT_SIZE,
0.5f*UNIT_SIZE,0*UNIT_SIZE,5*UNIT_SIZE,
0.5f*UNIT_SIZE,12*UNIT_SIZE,4*UNIT_SIZE,
0.5f*UNIT_SIZE,12*UNIT_SIZE,4*UNIT_SIZE,
0.5f*UNIT_SIZE,0*UNIT_SIZE,5*UNIT_SIZE,
0.5f*UNIT_SIZE,0*UNIT_SIZE,4*UNIT_SIZE,
};
vCount=vertex.length/3;
ByteBuffer vbb=ByteBuffer.allocateDirect(vertex.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer=vbb.asFloatBuffer();
mVertexBuffer.put(vertex);
mVertexBuffer.position(0);
float[] texcoor=new float[]
{
//--------一个长方体的纹理坐标--------------
0,0, 0,1, 1,0,
1,0, 0,1, 1,1,
0,0, 0,1, 1,0,
1,0, 0,1, 1,1,
0,0, 0,1, 1,0,
1,0, 0,1, 1,1,
0,0, 0,1, 1,0,
1,0, 0,1, 1,1,
0,0, 0,1, 1,0,
1,0, 0,1, 1,1,
0,0, 0,1, 1,0,
1,0, 0,1, 1,1,
//--------一个长方体的纹理坐标--------------
0,0, 0,1, 1,0,
1,0, 0,1, 1,1,
0,0, 0,1, 1,0,
1,0, 0,1, 1,1,
0,0, 0,1, 1,0,
1,0, 0,1, 1,1,
0,0, 0,1, 1,0,
1,0, 0,1, 1,1,
0,0, 0,1, 1,0,
1,0, 0,1, 1,1,
0,0, 0,1, 1,0,
1,0, 0,1, 1,1,
//--------一个长方体的纹理坐标--------------
0,0, 0,1, 1,0,
1,0, 0,1, 1,1,
0,0, 0,1, 1,0,
1,0, 0,1, 1,1,
0,0, 0,1, 1,0,
1,0, 0,1, 1,1,
0,0, 0,1, 1,0,
1,0, 0,1, 1,1,
0,0, 0,1, 1,0,
1,0, 0,1, 1,1,
0,0, 0,1, 1,0,
1,0, 0,1, 1,1,
//--------一个长方体的纹理坐标--------------
0,0, 0,1, 1,0,
1,0, 0,1, 1,1,
0,0, 0,1, 1,0,
1,0, 0,1, 1,1,
0,0, 0,1, 1,0,
1,0, 0,1, 1,1,
0,0, 0,1, 1,0,
1,0, 0,1, 1,1,
0,0, 0,1, 1,0,
1,0, 0,1, 1,1,
0,0, 0,1, 1,0,
1,0, 0,1, 1,1,
//--------一个长方体的纹理坐标--------------
0,0, 0,1, 1,0,
1,0, 0,1, 1,1,
0,0, 0,1, 1,0,
1,0, 0,1, 1,1,
0,0, 0,1, 1,0,
1,0, 0,1, 1,1,
0,0, 0,1, 1,0,
1,0, 0,1, 1,1,
0,0, 0,1, 1,0,
1,0, 0,1, 1,1,
0,0, 0,1, 1,0,
1,0, 0,1, 1,1,
};
ByteBuffer tbb=ByteBuffer.allocateDirect(texcoor.length*4);
tbb.order(ByteOrder.nativeOrder());
mTexCoorBuffer=tbb.asFloatBuffer();
mTexCoorBuffer.put(texcoor);
mTexCoorBuffer.position(0);
}
//初始化着色器的initShader方法
public void initShader(int programId)
{
//基于顶点着色器与片元着色器创建程序
mProgram =programId;
//获取程序中顶点位置属性引用id
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
//获取程序中顶点纹理坐标属性引用id
maTexCoorHandle= GLES20.glGetAttribLocation(mProgram, "aTexCoor");
//获取程序中总变换矩阵引用id
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
}
//自定义的绘制方法drawSelf
public void drawSelf(int texId)
{
//制定使用某套shader程序
GLES20.glUseProgram(mProgram);
//将最终变换矩阵传入shader程序
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//传入顶点位置数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入纹理坐标数据
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false,
2*4,
mTexCoorBuffer
);
//允许顶点位置数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
//绘制纹理矩形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
}
}

View File

@@ -0,0 +1,551 @@
package com.bn.clp;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import static com.bn.clp.Constant.*;
import android.opengl.GLES20;
import com.bn.core.MatrixState;
//绘制时间 计圈 氮气 暂停 换人称视角 加速按钮的类
public class DrawTime
{
//数字矩形块的宽度和高度
float SHUZI_KUANDU=0.1f;
float SHUZI_GAODU=0.12f;
//记录总时间的数组
public static long timeTotal[]=new long[3];
//数字的绘制矩形
WenLiJuXing[] shuzi=new WenLiJuXing[10];
//冒号的绘制矩形
WenLiJuXing maohao;
//“time”的绘制矩形
WenLiJuXing timeText;
//“lap”的绘制矩形
WenLiJuXing lapText;
//斜杠的绘制矩形
WenLiJuXing xiegan;
//"氮气"图片的绘制矩形
WenLiJuXing n2;
//乘号的绘制矩形
WenLiJuXing chenhao;
//使用氮气的绘制矩形
WenLiJuXing kejiasu;
//不可加速的氮气的绘制矩形
WenLiJuXing bukejiasu;
//第一和第三人称按钮
// WenLiJuXing firstView;
// WenLiJuXing thirdView;
//暂停、恢复按钮
WenLiJuXing pauseButton;
WenLiJuXing resumeButton;
//迷你地图功能按钮
WenLiJuXing miniMapButton;
WenLiJuXing shache;
WenLiJuXing noshache;
public DrawTime(int mProgram)
{
for(int i=0;i<10;i++)
{
shuzi[i]=new WenLiJuXing
(
SHUZI_KUANDU,
SHUZI_GAODU,
new float[]
{
0.1f*i,0, 0.1f*i,0.26f, 0.1f*(i+1),0.26f,
0.1f*i,0, 0.1f*(i+1),0.26f, 0.1f*(i+1),0
}
);
}
maohao=new WenLiJuXing
(
SHUZI_KUANDU,
SHUZI_GAODU,
new float[]
{
0.725f,0.46f, 0.725f,0.71f, 0.8f,0.71f,
0.725f,0.46f, 0.8f,0.71f, 0.8f,0.46f
}
);
timeText=new WenLiJuXing
(
SHUZI_KUANDU*4,
SHUZI_GAODU,
new float[]
{
0.025f,0.48f, 0.025f,0.7f, 0.31f,0.7f,
0.025f,0.48f, 0.31f,0.7f, 0.31f,0.48f
}
);
lapText=new WenLiJuXing
(
SHUZI_KUANDU*3,
SHUZI_GAODU,
new float[]
{
0.33f,0.48f, 0.33f,0.7f, 0.625f,0.7f,
0.33f,0.48f, 0.625f,0.7f, 0.625f,0.48f
}
);
xiegan=new WenLiJuXing
(
SHUZI_KUANDU,
SHUZI_GAODU,
new float[]
{
0.63f,0.445f, 0.63f,0.71f, 0.71f,0.71f,
0.63f,0.445f, 0.71f,0.71f, 0.71f,0.445f
}
);
n2=new WenLiJuXing
(
SHUZI_KUANDU*2,
SHUZI_GAODU*2,
new float[]
{
0.81f,0.3f, 0.81f,0.72f, 0.95f,0.72f,
0.81f,0.3f, 0.95f,0.72f, 0.95f,0.3f
}
);
chenhao=new WenLiJuXing
(
SHUZI_KUANDU,
SHUZI_GAODU,
new float[]
{
0.02f,0.795f, 0.02f,0.945f, 0.095f,0.945f,
0.02f,0.795f, 0.095f,0.945f, 0.095f,0.795f
}
);
noshache=new WenLiJuXing
(
Self_Adapter_Data_TRASLATE[screenId][17],
SHUZI_GAODU*1.5f,
new float[]
{
0,0f, 0,1f, 0.5f,1f,
0f,0f, 0.5f,1f, 0.5f,0f
}
);
shache=new WenLiJuXing
(
Self_Adapter_Data_TRASLATE[screenId][17],
SHUZI_GAODU*1.5f,
new float[]
{
0.5f,0f, 0.5f,1f, 1f,1f,
0.5f,0f, 1f,1f, 1f,0f
}
);
kejiasu=new WenLiJuXing
(
Self_Adapter_Data_TRASLATE[screenId][8],
SHUZI_GAODU*5,
new float[]
{
0,0f, 0,1f, 0.5f,1f,
0f,0f, 0.5f,1f, 0.5f,0f
}
);
bukejiasu=new WenLiJuXing
(
Self_Adapter_Data_TRASLATE[screenId][8],
SHUZI_GAODU*5,
new float[]
{
0.5f,0f, 0.5f,1f, 1f,1f,
0.5f,0f, 1f,1f, 1f,0f
}
);
// firstView=new WenLiJuXing
// (
// Self_Adapter_Data_TRASLATE[screenId][2],
// SHUZI_GAODU*2,
// new float[]
// {
// 0.15f,0.73f, 0.15f,1f, 0.29f,1f,
// 0.15f,0.73f, 0.29f,1f, 0.29f,0.73f
// }
// );
//
// thirdView=new WenLiJuXing
// (
// Self_Adapter_Data_TRASLATE[screenId][2],
// SHUZI_GAODU*2,
// new float[]
// {
// 0.3f,0.73f, 0.3f,1f, 0.44f,1f,
// 0.3f,0.73f, 0.44f,1f, 0.44f,0.73f
// }
// );
pauseButton=new WenLiJuXing
(
Self_Adapter_Data_TRASLATE[screenId][5],
SHUZI_GAODU*2,
new float[]
{
0.47f,0.73f, 0.47f,1f, 0.61f,1f,
0.47f,0.73f, 0.61f,1f, 0.61f,0.73f
}
);
resumeButton=new WenLiJuXing
(
Self_Adapter_Data_TRASLATE[screenId][5],
SHUZI_GAODU*2,
new float[]
{
0.63f,0.73f, 0.63f,1f, 0.77f,1f,
0.63f,0.73f, 0.77f,1f, 0.77f,0.73f
}
);
miniMapButton=new WenLiJuXing
(
SHUZI_GAODU*2,
SHUZI_GAODU*2,
new float[]
{
0.75f,0.75f, 0.75f,1f, 0.95f,1f,
0.75f,0.75f, 0.95f,1f, 0.95f,0.75f
}
);
//初始化shader
initShader(mProgram);
}
public void initShader(int mProgram)
{
for(WenLiJuXing fl:shuzi)
{
fl.initShader(mProgram);
}
maohao.initShader(mProgram);
timeText.initShader(mProgram);
lapText.initShader(mProgram);
xiegan.initShader(mProgram);
n2.initShader(mProgram);
chenhao.initShader(mProgram);
kejiasu.initShader(mProgram);
bukejiasu.initShader(mProgram);
pauseButton.initShader(mProgram);
resumeButton.initShader(mProgram);
// firstView.initShader(mProgram);
// thirdView.initShader(mProgram);
miniMapButton.initShader(mProgram);
shache.initShader(mProgram);
noshache.initShader(mProgram);
}
//算总时间的方法
public void toTotalTime(long ms)
{
timeTotal[0]=(long) Math.floor((ms%1000)/10);
timeTotal[1]=(long) Math.floor((ms%60000)/1000);
timeTotal[2]=(long) Math.floor((ms/60000));
}
//绘制计时器和lap标志
public void drawSelf(int timeTexId,int currLap,int numberOfN2,int goTexId,int shacheTexId,boolean isShaChe)
{
MatrixState.pushMatrix();
MatrixState.translate(-SHUZI_KUANDU*8+0.025f, SHUZI_GAODU+0.02f, 0);
MatrixState.rotate(90, 1, 0, 0);
lapText.drawSelf(timeTexId);//lap图标
MatrixState.popMatrix();
MatrixState.pushMatrix();
MatrixState.translate(-SHUZI_KUANDU*8, 0, 0);
MatrixState.rotate(90, 1, 0, 0);
xiegan.drawSelf(timeTexId);//lap中的斜杠
MatrixState.popMatrix();
MatrixState.pushMatrix();
MatrixState.translate(-SHUZI_KUANDU*9, 0, 0);
lapDrawSelf(timeTexId,currLap);//lap中的数字
MatrixState.popMatrix();
MatrixState.pushMatrix();
MatrixState.translate(SHUZI_KUANDU*4-0.05f, SHUZI_GAODU+0.02f, 0);
MatrixState.rotate(90, 1, 0, 0);
timeText.drawSelf(timeTexId);//time图标
MatrixState.popMatrix();
MatrixState.pushMatrix();
MatrixState.translate(-0.055f, 0, 0);
timeDrawSelf(timeTexId,2);//绘制时间中的分
MatrixState.popMatrix();
MatrixState.pushMatrix();
MatrixState.translate(SHUZI_GAODU*3-0.055f, 0, 0);
timeDrawSelf(timeTexId,1);//绘制时间中的秒
MatrixState.popMatrix();
MatrixState.pushMatrix();
MatrixState.translate(SHUZI_GAODU*6-0.055f, 0, 0);
timeDrawSelf(timeTexId,0);//绘制时间中的毫秒
MatrixState.popMatrix();
MatrixState.pushMatrix();
MatrixState.translate(SHUZI_KUANDU*13, SHUZI_GAODU-0.05f, 0);
MatrixState.rotate(90, 1, 0, 0);
n2.drawSelf(timeTexId);//氮气图标
MatrixState.popMatrix();
MatrixState.pushMatrix();
MatrixState.translate(SHUZI_KUANDU*15-0.025f, SHUZI_GAODU-0.05f, 0);
MatrixState.rotate(90, 1, 0, 0);
chenhao.drawSelf(timeTexId);//乘号图标
MatrixState.popMatrix();
MatrixState.pushMatrix();
MatrixState.translate(SHUZI_KUANDU*16, SHUZI_GAODU-0.05f, 0);
drawNumberOfN2(timeTexId,numberOfN2);//氮气数量
MatrixState.popMatrix();
//加速按钮
if(numberOfN2>0)
{
MatrixState.pushMatrix();
MatrixState.translate(Self_Adapter_Data_TRASLATE[screenId][6], Self_Adapter_Data_TRASLATE[screenId][7], 0);
MatrixState.rotate(90, 1, 0, 0);
kejiasu.drawSelf(goTexId);
MatrixState.popMatrix();
}
else
{
MatrixState.pushMatrix();
MatrixState.translate(Self_Adapter_Data_TRASLATE[screenId][6], Self_Adapter_Data_TRASLATE[screenId][7], 0);
MatrixState.rotate(90, 1, 0, 0);
bukejiasu.drawSelf(goTexId);
MatrixState.popMatrix();
}
//刹车按钮
if(isShaChe)
{
MatrixState.pushMatrix();
MatrixState.translate(Self_Adapter_Data_TRASLATE[screenId][15], Self_Adapter_Data_TRASLATE[screenId][16], 0);
MatrixState.rotate(90, 1, 0, 0);
shache.drawSelf(shacheTexId);
MatrixState.popMatrix();
}
else
{
MatrixState.pushMatrix();
MatrixState.translate(Self_Adapter_Data_TRASLATE[screenId][15], Self_Adapter_Data_TRASLATE[screenId][16], 0);
MatrixState.rotate(90, 1, 0, 0);
noshache.drawSelf(shacheTexId);
MatrixState.popMatrix();
}
// //换视角按钮
// if(isFirstPersonView)
// {
// MatrixState.pushMatrix();
// MatrixState.translate(Self_Adapter_Data_TRASLATE[screenId][0], Self_Adapter_Data_TRASLATE[screenId][1], 0);
// MatrixState.rotate(90, 1, 0, 0);
// firstView.drawSelf(timeTexId);
// MatrixState.popMatrix();
// }
// else
// {
// MatrixState.pushMatrix();
// MatrixState.translate(Self_Adapter_Data_TRASLATE[screenId][0], Self_Adapter_Data_TRASLATE[screenId][1], 0);
// MatrixState.rotate(90, 1, 0, 0);
// thirdView.drawSelf(timeTexId);
// MatrixState.popMatrix();
// }
//暂停按钮
if(!isPaused)
{
MatrixState.pushMatrix();
MatrixState.translate(Self_Adapter_Data_TRASLATE[screenId][3], Self_Adapter_Data_TRASLATE[screenId][4], 0);
MatrixState.rotate(90, 1, 0, 0);
pauseButton.drawSelf(timeTexId);
MatrixState.popMatrix();
}
else
{
MatrixState.pushMatrix();
MatrixState.translate(Self_Adapter_Data_TRASLATE[screenId][3], Self_Adapter_Data_TRASLATE[screenId][4], 0);
MatrixState.rotate(90, 1, 0, 0);
resumeButton.drawSelf(timeTexId);
MatrixState.popMatrix();
}
}
//时间绘制者
public void timeDrawSelf(int texId,int number)
{
String scoreStr;
if(timeTotal[number]<10)
{
scoreStr="0"+timeTotal[number]+"";
}
else
{
scoreStr=timeTotal[number]+"";
}
for(int i=0;i<scoreStr.length();i++)
{
char c=scoreStr.charAt(i);
MatrixState.pushMatrix();
MatrixState.translate(i*SHUZI_KUANDU, 0, 0);
MatrixState.rotate(90, 1, 0, 0);
shuzi[c-'0'].drawSelf(texId);
MatrixState.popMatrix();
}
if(number!=0)
{
MatrixState.pushMatrix();
MatrixState.translate(2*SHUZI_KUANDU+0.02f, 0, 0);
MatrixState.rotate(90, 1, 0, 0);
maohao.drawSelf(texId);
MatrixState.popMatrix();
}
}
//圈数绘制者
public void lapDrawSelf(int texId,int currLap)
{
String curr=currLap+"";
String total=maxOfTurns+"";
char c=curr.charAt(0);
MatrixState.pushMatrix();
MatrixState.rotate(90, 1, 0, 0);
shuzi[c-'0'].drawSelf(texId);
MatrixState.popMatrix();
c=total.charAt(0);
MatrixState.pushMatrix();
MatrixState.translate(SHUZI_KUANDU*2, 0, 0);
MatrixState.rotate(90, 1, 0, 0);
shuzi[c-'0'].drawSelf(texId);
MatrixState.popMatrix();
}
//氮气的数量绘制者
public void drawNumberOfN2(int texId,int number)
{
String numberStr=number+"";
char c=numberStr.charAt(0);
MatrixState.pushMatrix();
MatrixState.rotate(90, 1, 0, 0);
shuzi[c-'0'].drawSelf(texId);
MatrixState.popMatrix();
}
//纹理矩形内部类
class WenLiJuXing
{
int mProgram;//自定义渲染管线着色器程序id
int muMVPMatrixHandle;//总变换矩阵引用id
int muMMatrixHandle;//位置、旋转变换矩阵
int maCameraHandle; //摄像机位置属性引用id
int maPositionHandle; //顶点位置属性引用id
int maNormalHandle; //顶点法向量属性引用id
int maTexCoorHandle; //顶点纹理坐标属性引用id
int maSunLightLocationHandle;//光源位置属性引用id
private FloatBuffer mVertexBuffer;//顶点坐标数据缓冲
private FloatBuffer mTextureBuffer;//顶点着色数据缓冲
int vCount;//顶点数量
int texId;//纹理Id
public WenLiJuXing(float width,float height,float[] textures){//传入宽高和纹理坐标数组
//顶点坐标数据的初始化================begin============================
vCount=6;//每个格子两个三角形每个三角形3个顶点
float vertices[]=
{
-width/2,0,-height/2,
-width/2,0,height/2,
width/2,0,height/2,
-width/2,0,-height/2,
width/2,0,height/2,
width/2,0,-height/2
};
//创建顶点坐标数据缓冲
//vertices.length*4是因为一个整数四个字节
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());//设置字节顺序
mVertexBuffer = vbb.asFloatBuffer();//转换为int型缓冲
mVertexBuffer.put(vertices);//向缓冲区中放入顶点坐标数据
mVertexBuffer.position(0);//设置缓冲区起始位置
//创建顶点纹理数据缓冲
ByteBuffer tbb = ByteBuffer.allocateDirect(textures.length*4);
tbb.order(ByteOrder.nativeOrder());//设置字节顺序
mTextureBuffer= tbb.asFloatBuffer();//转换为Float型缓冲
mTextureBuffer.put(textures);//向缓冲区中放入顶点着色数据
mTextureBuffer.position(0);//设置缓冲区起始位置
//加载顶点着色器的脚本内容
}
//初始化着色器的initShader方法
public void initShader(int mProgram)
{
this.mProgram=mProgram;
//获取程序中顶点位置属性引用id
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
//获取程序中顶点纹理坐标属性引用id
maTexCoorHandle= GLES20.glGetAttribLocation(mProgram, "aTexCoor");
//获取程序中总变换矩阵引用id
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
}
public void drawSelf(int texId)
{
//制定使用某套shader程序
GLES20.glUseProgram(mProgram);
//将最终变换矩阵传入shader程序
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//传入顶点位置数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入顶点纹理坐标数据
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false,
2*4,
mTextureBuffer
);
//允许顶点位置数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
//绘制纹理矩形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
}
}

View File

@@ -0,0 +1,212 @@
package com.bn.clp;
import static com.bn.clp.Constant.*;
//可吃物体的数据类
public class KEatData
{
//新添加的,可以吃掉物件的列表
static float[][] KEAT_ARRAY=new float[][]
{
//2-4//吃了增加氮气的 弯道6
{1, UNIT_SIZE*4-5, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*2-20f, 0, 2, 4},
{0, UNIT_SIZE*4, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*2-20f, 0, 2, 4},
{1, UNIT_SIZE*4+5, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*2-20f, 0, 2, 4},
//2-8//吃了减速 弯道5
{0, UNIT_SIZE*8, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*2+25f, 0, 2, 8},
{1, UNIT_SIZE*8, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*2+20f, 0, 2, 8},
{0, UNIT_SIZE*8, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*2+15f, 0, 2, 8},
//3-9//吃了减速 弯道7
{0, UNIT_SIZE*9, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*3-25f, 0, 3, 9},
{0, UNIT_SIZE*9, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*3-20f, 0, 3, 9},
{1, UNIT_SIZE*9, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*3-15f, 0, 3, 9},
//2-15//吃了增加氮气的 弯道5
{0, UNIT_SIZE*15, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*2+25f, 0, 2, 15},
{1, UNIT_SIZE*15, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*2+20f, 0, 2, 15},
{1, UNIT_SIZE*15, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*2+15f, 0, 2, 15},
//7-11 吃了加速 弯道6
{1, UNIT_SIZE*11-5, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*7-20f, 0, 7, 11},
{0, UNIT_SIZE*11, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*7-20f, 0, 7, 11},
{0, UNIT_SIZE*11+5, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*7-20f, 0, 7, 11},
//13-11 吃了减速 弯道6
{1, UNIT_SIZE*11-5, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*13-20f, 0, 13, 11},
{1, UNIT_SIZE*11, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*13-20f, 0, 13, 11},
{1, UNIT_SIZE*11+5, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*13-20f, 0, 13, 11},
//12-13 吃了加速 弯道5
{0, UNIT_SIZE*13, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*12+25f, 0, 12, 13},
{1, UNIT_SIZE*13, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*12+20f, 0, 12, 13},
{0, UNIT_SIZE*13, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*12+15f, 0, 12, 13},
//12-20 吃了加速 弯道7
{1, UNIT_SIZE*20-3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*12-23f, 0, 12, 20},
{0, UNIT_SIZE*20, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*12-20f, 0, 12, 20},
{1, UNIT_SIZE*20+3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*12-17f, 0, 12, 20},
//7-21 吃了减速 弯道5
{1, UNIT_SIZE*21, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*7+25f, 0, 7, 21},
{0, UNIT_SIZE*21, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*7+20f, 0, 7, 21},
{1, UNIT_SIZE*21, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*7+15f, 0, 7, 21},
//4-21 吃了加速 弯道5
{0, UNIT_SIZE*21, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*4+25f, 0, 4, 21},
{0, UNIT_SIZE*21, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*4+20f, 0, 4, 21},
{0, UNIT_SIZE*21, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*4+15f, 0, 4, 21},
//6-28 吃了加速 弯道7
{0, UNIT_SIZE*28-3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*6-23f, 0, 6, 28},
{1, UNIT_SIZE*28, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*6-20f, 0, 6, 28},
{0, UNIT_SIZE*28+3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*6-17f, 0, 6, 28},
//12-26 吃了加速 弯道7
{1, UNIT_SIZE*26-3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*12-23f, 0, 12, 26},
{0, UNIT_SIZE*26, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*12-20f, 0, 12, 26},
{0, UNIT_SIZE*26+3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*12-17f, 0, 12, 26},
//19-25 吃了减速 弯道6
{1, UNIT_SIZE*25-5, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*19-20f, 0, 19, 25},
{0, UNIT_SIZE*25, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*19-20f, 0, 19, 25},
{1, UNIT_SIZE*25+5, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*19-20f, 0, 19, 25},
//28-23 吃了加速 弯道5
{0, UNIT_SIZE*23, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*28+25f, 0, 28, 23},
{0, UNIT_SIZE*23, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*28+20f, 0, 28, 23},
{1, UNIT_SIZE*23, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*28+15f, 0, 28, 23},
//29-21 吃了减速 弯道6
{1, UNIT_SIZE*21-5, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*29-20f, 0, 29, 21},
{1, UNIT_SIZE*21, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*29-20f, 0, 29, 21},
{0, UNIT_SIZE*21+5, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*29-20f, 0, 29, 21},
//28-19 吃了加速 弯道5
{0, UNIT_SIZE*19, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*28+25f, 0, 28, 19},
{0, UNIT_SIZE*19, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*28+20f, 0, 28, 19},
{1, UNIT_SIZE*19, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*28+15f, 0, 28, 19},
//20-16 吃了加速 弯道5
{0, UNIT_SIZE*16, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*20-25f, 0, 20, 16},
{1, UNIT_SIZE*16, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*20-20f, 0, 20, 16},
{0, UNIT_SIZE*16, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*20-15f, 0, 20, 16},
//23-11 吃了减速 弯道7
{1, UNIT_SIZE*11-3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*3-23f, 0, 23, 11},
{0, UNIT_SIZE*11, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*3-20f, 0, 23, 11},
{1, UNIT_SIZE*11+3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*3-17f, 0, 23, 11},
//27-9 吃了减速 弯道7
{0, UNIT_SIZE*9-3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*27-23f, 0, 27, 9},
{1, UNIT_SIZE*9, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*27-20f, 0, 27, 9},
{1, UNIT_SIZE*9+3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*27-17f, 0, 27, 9},
//28-6 吃了减速 弯道4
{1, UNIT_SIZE*6+3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*28+23f, 0, 28, 6},
{1, UNIT_SIZE*6, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*28+20f, 0, 28, 6},
{0, UNIT_SIZE*6-3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*28+17f, 0, 28, 6},
//26-1 吃了加速 弯道6
{0, UNIT_SIZE*1-5, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*26-20f, 0, 26, 1},
{0, UNIT_SIZE*1, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*26-20f, 0, 26, 1},
{1, UNIT_SIZE*1+5, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*26-20f, 0, 26, 1},
//25-2 吃了加速 弯道7
{0, UNIT_SIZE*2-3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*25-23f, 0, 25, 2},
{1, UNIT_SIZE*2, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*25-20f, 0, 25, 2},
{0, UNIT_SIZE*2+3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*25-17f, 0, 25, 2},
//18-2 吃了减速 弯道5
{1, UNIT_SIZE*2, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*18+25f, 0, 18, 2},
{0, UNIT_SIZE*2, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*18+20f, 0, 18, 2},
{0, UNIT_SIZE*2, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*18+15f, 0, 18, 2},
//18-1 吃了加速 弯道6
{0, UNIT_SIZE*1-5, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*18-20f, 0, 18, 1},
{1, UNIT_SIZE*1, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*18-20f, 0, 18, 1},
{0, UNIT_SIZE*1+5, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*18-20f, 0, 18, 1},
//14-1 吃了减速 弯道6
{1, UNIT_SIZE*1-5, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*14-20f, 0, 14, 1},
{0, UNIT_SIZE*1, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*14-20f, 0, 14, 1},
{1, UNIT_SIZE*1+5, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*14-20f, 0, 14, 1},
//13-2 吃了加速 弯道7
{1, UNIT_SIZE*2-3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*13-23f, 0, 13, 2},
{0, UNIT_SIZE*2, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*13-20f, 0, 13, 2},
{0, UNIT_SIZE*2+3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*13-17f, 0, 13, 2},
//新添加的
//4-15 吃了加速 弯道7
{0, UNIT_SIZE*15-3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*4-23f, 0, 4, 15},
{1, UNIT_SIZE*15, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*4-20f, 0, 4, 15},
{0, UNIT_SIZE*15+3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*4-17f, 0, 4, 15},
//4-11吃了减速 弯道4
{1, UNIT_SIZE*11+3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*4+23f, 0, 4, 11},
{1, UNIT_SIZE*11, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*4+20f, 0, 4, 11},
{0, UNIT_SIZE*11-3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*4+17f, 0, 4, 11},
//9-12吃了加速 弯道7
{0, UNIT_SIZE*12-3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*9-23f, 0, 9, 12},
{1, UNIT_SIZE*12, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*9-20f, 0, 9, 12},
{0, UNIT_SIZE*12+3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*9-17f, 0, 9, 12},
//14-15 吃了减速 弯道6
{1, UNIT_SIZE*15-5, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*14-20f, 0, 14, 15},
{0, UNIT_SIZE*15, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*14-20f, 0, 14, 15},
{1, UNIT_SIZE*15+5, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*14-20f, 0, 14, 15},
//13-19吃了加速 弯道7
{0, UNIT_SIZE*19-3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*13-23f, 0, 13, 19},
{1, UNIT_SIZE*19, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*13-20f, 0, 13, 19},
{0, UNIT_SIZE*19+3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*13-17f, 0, 13, 19},
//5-25吃了加速 弯道7
{0, UNIT_SIZE*25-3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*5-23f, 0, 5, 25},
{1, UNIT_SIZE*25, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*5-20f, 0, 5, 25},
{0, UNIT_SIZE*25+3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*5-17f, 0, 5, 25},
//2-25吃了减速 弯道4
{1, UNIT_SIZE*25+3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*2+23f, 0, 2, 25},
{1, UNIT_SIZE*25, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*2+20f, 0, 2, 25},
{0, UNIT_SIZE*25-3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*2+17f, 0, 2, 25},
//2-29吃了减速 弯道5
{1, UNIT_SIZE*29, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*2+25f, 0, 2, 29},
{0, UNIT_SIZE*29, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*2+20f, 0, 2, 29},
{0, UNIT_SIZE*29, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*2+15f, 0, 2, 29},
//10-27吃了减速 弯道5
{1, UNIT_SIZE*27, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*10+25f, 0, 10, 27},
{0, UNIT_SIZE*27, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*10+20f, 0, 10, 27},
{0, UNIT_SIZE*27, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*10+15f, 0, 10, 27},
//15-25 吃了减速 弯道6
{1, UNIT_SIZE*25-5, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*15-20f, 0, 15, 25},
{0, UNIT_SIZE*25, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*15-20f, 0, 15, 25},
{1, UNIT_SIZE*25+5, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*15-20f, 0, 15, 25},
//17-26吃了加速 弯道7
{0, UNIT_SIZE*26-3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*17-23f, 0, 17, 26},
{1, UNIT_SIZE*26, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*17-20f, 0, 17, 26},
{0, UNIT_SIZE*26+3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*17-17f, 0, 17, 26},
//23-26吃了加速 弯道7
{0, UNIT_SIZE*26-3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*23-23f, 0, 23, 26},
{1, UNIT_SIZE*26, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*23-20f, 0, 23, 26},
{0, UNIT_SIZE*26+3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*23-17f, 0, 23, 26},
//21-25吃了减速 弯道5
{1, UNIT_SIZE*25, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*21+25f, 0, 21, 25},
{0, UNIT_SIZE*25, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*21+20f, 0, 21, 25},
{0, UNIT_SIZE*25, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*21+15f, 0, 21, 25},
//26-25吃了加速 弯道7
{0, UNIT_SIZE*25-3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*26-23f, 0, 26, 25},
{1, UNIT_SIZE*25, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*26-20f, 0, 26, 25},
{0, UNIT_SIZE*25+3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*26-17f, 0, 26, 25},
//29-24吃了加速 弯道7
{0, UNIT_SIZE*24-3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*29-23f, 0, 29, 24},
{1, UNIT_SIZE*24, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*29-20f, 0, 29, 24},
{0, UNIT_SIZE*24+3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*29-17f, 0, 29, 24},
//28-15 吃了减速 弯道6
{1, UNIT_SIZE*15-5, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*28-20f, 0, 28, 15},
{0, UNIT_SIZE*15, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*28-20f, 0, 28, 15},
{1, UNIT_SIZE*15+5, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*28-20f, 0, 28, 15},
//24-16吃了加速 弯道7
{0, UNIT_SIZE*16-3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*24-23f, 0, 24, 16},
{1, UNIT_SIZE*16, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*24-20f, 0, 24, 16},
{0, UNIT_SIZE*16+3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*24-17f, 0, 24, 16},
//20-11吃了减速 弯道4
{1, UNIT_SIZE*11+3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*20+23f, 0, 20, 11},
{1, UNIT_SIZE*11, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*20+20f, 0, 20, 11},
{0, UNIT_SIZE*11-3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*20+17f, 0, 20, 11},
//29-2 吃了减速 弯道6
{1, UNIT_SIZE*2-5, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*29-20f, 0, 29, 2},
{0, UNIT_SIZE*2, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*29-20f, 0, 29, 2},
{1, UNIT_SIZE*2+5, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*29-20f, 0, 29, 2},
//22-3吃了减速 弯道5
{1, UNIT_SIZE*3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*22+25f, 0, 22, 3},
{0, UNIT_SIZE*3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*22+20f, 0, 22, 3},
{0, UNIT_SIZE*3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*22+15f, 0, 22, 3},
//21-1 吃了减速 弯道6
{1, UNIT_SIZE*1-5, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*21-20f, 0, 21, 1},
{0, UNIT_SIZE*1, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*21-20f, 0, 21, 1},
{1, UNIT_SIZE*1+5, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*21-20f, 0, 21, 1},
//8-3吃了加速 弯道7
{0, UNIT_SIZE*3-3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*8-23f, 0, 8, 3},
{1, UNIT_SIZE*3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*8-20f, 0, 8, 3},
{0, UNIT_SIZE*3+3, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*8-17f, 0, 8, 3},
//7-2 吃了减速 弯道6
{1, UNIT_SIZE*2-5, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*7-20f, 0, 7, 2},
{0, UNIT_SIZE*2, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*7-20f, 0, 7, 2},
{1, UNIT_SIZE*2+5, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*7-20f, 0, 7, 2},
//3-2吃了减速 弯道5
{1, UNIT_SIZE*2, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*3+25f, 0, 3, 2},
{0, UNIT_SIZE*2, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*3+20f, 0, 3, 2},
{0, UNIT_SIZE*2, WATER_HIGH_ADJUST+2.0f, UNIT_SIZE*3+15f, 0, 3, 2},
};
}

View File

@@ -0,0 +1,387 @@
package com.bn.clp;
import static com.bn.clp.Constant.*;
//可撞部件数据类
public class KZBJData
{
//可碰撞物体的相关数据列表列表数据的结构为id,x,y,z,row,cols
static float[][] KZBJ_ARRAY=new float[][]
{
//1-4竖直
{0, UNIT_SIZE*4, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*1+16f, 1, 4}, //交通柱
{0, UNIT_SIZE*4, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*1-16f, 1, 4}, //交通柱
{1, UNIT_SIZE*4, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*1+12f, 1, 4}, //交通柱
{1, UNIT_SIZE*4, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*1-12f, 1, 4}, //交通柱
{0, UNIT_SIZE*4, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*1+8f, 1, 4}, //交通柱
{0, UNIT_SIZE*4, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*1-8f, 1, 4}, //交通柱
{1, UNIT_SIZE*4, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*1+4f, 1, 4}, //交通柱
{1, UNIT_SIZE*4, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*1-4f, 1, 4}, //交通柱
{0, UNIT_SIZE*4, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*1+0f, 1, 4}, //交通柱
//2-5横着
{0, UNIT_SIZE*5+16f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 5}, //交通柱
{0, UNIT_SIZE*5-16f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 5}, //交通柱
{1, UNIT_SIZE*5+12f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 5}, //交通柱
{1, UNIT_SIZE*5-12f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 5}, //交通柱
{0, UNIT_SIZE*5+8f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 5}, //交通柱
{0, UNIT_SIZE*5-8f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 5}, //交通柱
{1, UNIT_SIZE*5+4f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 5}, //交通柱
{1, UNIT_SIZE*5-4f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 5}, //交通柱
{0, UNIT_SIZE*5+0f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 5}, //交通柱
//2-12横着
{0, UNIT_SIZE*12+16f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 12}, //交通柱
{0, UNIT_SIZE*12-16f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 12}, //交通柱
{1, UNIT_SIZE*12+12f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 12}, //交通柱
{1, UNIT_SIZE*12-12f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 12}, //交通柱
{0, UNIT_SIZE*12+8f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 12}, //交通柱
{0, UNIT_SIZE*12-8f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 12}, //交通柱
{1, UNIT_SIZE*12+4f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 12}, //交通柱
{1, UNIT_SIZE*12-4f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 12}, //交通柱
{0, UNIT_SIZE*12+0f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 12}, //交通柱
//2-13横着
{0, UNIT_SIZE*13+16f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 13}, //交通柱
{0, UNIT_SIZE*13-16f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 13}, //交通柱
{1, UNIT_SIZE*13+12f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 13}, //交通柱
{1, UNIT_SIZE*13-12f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 13}, //交通柱
{0, UNIT_SIZE*13+8f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 13}, //交通柱
{0, UNIT_SIZE*13-8f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 13}, //交通柱
{1, UNIT_SIZE*13+4f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 13}, //交通柱
{1, UNIT_SIZE*13-4f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 13}, //交通柱
{0, UNIT_SIZE*13+0f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 13}, //交通柱
//3-15竖直
{0, UNIT_SIZE*15, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*3+16f, 3, 15}, //交通柱
{0, UNIT_SIZE*15, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*3-16f, 3, 15}, //交通柱
{1, UNIT_SIZE*15, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*3+12f, 3, 15}, //交通柱
{1, UNIT_SIZE*15, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*3-12f, 3, 15}, //交通柱
{0, UNIT_SIZE*15, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*3+8f, 3, 15}, //交通柱
{0, UNIT_SIZE*15, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*3-8f, 3, 15}, //交通柱
{1, UNIT_SIZE*15, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*3+4f, 3, 15}, //交通柱
{1, UNIT_SIZE*15, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*3-4f, 3, 15}, //交通柱
{0, UNIT_SIZE*15, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*3+0f, 3, 15}, //交通柱
//4-13横着
{0, UNIT_SIZE*13+16f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*4, 4, 13}, //交通柱
{0, UNIT_SIZE*13-16f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*4, 4, 13}, //交通柱
{1, UNIT_SIZE*13+12f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*4, 4, 13}, //交通柱
{1, UNIT_SIZE*13-12f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*4, 4, 13}, //交通柱
{0, UNIT_SIZE*13+8f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*4, 4, 13}, //交通柱
{0, UNIT_SIZE*13-8f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*4, 4, 13}, //交通柱
{1, UNIT_SIZE*13+4f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*4, 4, 13}, //交通柱
{1, UNIT_SIZE*13-4f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*4, 4, 13}, //交通柱
{0, UNIT_SIZE*13+0f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*4, 4, 13}, //交通柱
//5-11竖直
{0, UNIT_SIZE*11, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5+16f, 5, 11}, //交通柱
{0, UNIT_SIZE*11, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5-16f, 5, 11}, //交通柱
{1, UNIT_SIZE*11, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5+12f, 5, 11}, //交通柱
{1, UNIT_SIZE*11, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5-12f, 5, 11}, //交通柱
{0, UNIT_SIZE*11, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5+8f, 5, 11}, //交通柱
{0, UNIT_SIZE*11, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5-8f, 5, 11}, //交通柱
{1, UNIT_SIZE*11, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5+4f, 5, 11}, //交通柱
{1, UNIT_SIZE*11, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5-4f, 5, 11}, //交通柱
{0, UNIT_SIZE*11, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5+0f, 5, 11}, //交通柱
//8-12竖直
{0, UNIT_SIZE*12, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*8+16f, 8, 12}, //交通柱
{0, UNIT_SIZE*12, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*8-16f, 8, 12}, //交通柱
{1, UNIT_SIZE*12, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*8+12f, 8, 12}, //交通柱
{1, UNIT_SIZE*12, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*8-12f, 8, 12}, //交通柱
{0, UNIT_SIZE*12, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*8+8f, 8, 12}, //交通柱
{0, UNIT_SIZE*12, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*8-8f, 8, 12}, //交通柱
{1, UNIT_SIZE*12, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*8+4f, 8, 12}, //交通柱
{1, UNIT_SIZE*12, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*8-4f, 8, 12}, //交通柱
{0, UNIT_SIZE*12, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*8+0f, 8, 12}, //交通柱
//12-11竖直
{0, UNIT_SIZE*11, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*12+16f, 12, 11}, //交通柱
{0, UNIT_SIZE*11, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*12-16f, 12, 11}, //交通柱
{1, UNIT_SIZE*11, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*12+12f, 12, 11}, //交通柱
{1, UNIT_SIZE*11, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*12-12f, 12, 11}, //交通柱
{0, UNIT_SIZE*11, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*12+8f, 12, 11}, //交通柱
{0, UNIT_SIZE*11, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*12-8f, 12, 11}, //交通柱
{1, UNIT_SIZE*11, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*12+4f, 12, 11}, //交通柱
{1, UNIT_SIZE*11, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*12-4f, 12, 11}, //交通柱
{0, UNIT_SIZE*11, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*12+0f, 12, 11}, //交通柱
//13-17横着
{0, UNIT_SIZE*17+16f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*13, 13, 17}, //交通柱
{0, UNIT_SIZE*17-16f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*13, 13, 17}, //交通柱
{1, UNIT_SIZE*17+12f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*13, 13, 17}, //交通柱
{1, UNIT_SIZE*17-12f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*13, 13, 17}, //交通柱
{0, UNIT_SIZE*17+8f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*13, 13, 17}, //交通柱
{0, UNIT_SIZE*17-8f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*13, 13, 17}, //交通柱
{1, UNIT_SIZE*17+4f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*13, 13, 17}, //交通柱
{1, UNIT_SIZE*17-4f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*13, 13, 17}, //交通柱
{0, UNIT_SIZE*17+0f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*13, 13, 17}, //交通柱
//11-20竖直
{0, UNIT_SIZE*20, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*11+16f, 11, 20}, //交通柱
{0, UNIT_SIZE*20, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*11-16f, 11, 20}, //交通柱
{1, UNIT_SIZE*20, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*11+12f, 11, 20}, //交通柱
{1, UNIT_SIZE*20, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*11-12f, 11, 20}, //交通柱
{0, UNIT_SIZE*20, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*11+8f, 11, 20}, //交通柱
{0, UNIT_SIZE*20, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*11-8f, 11, 20}, //交通柱
{1, UNIT_SIZE*20, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*11+4f, 11, 20}, //交通柱
{1, UNIT_SIZE*20, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*11-4f, 11, 20}, //交通柱
{0, UNIT_SIZE*20, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*11+0f, 11, 20}, //交通柱
//8-21竖直
{0, UNIT_SIZE*21, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*8+16f, 8, 21}, //交通柱
{0, UNIT_SIZE*21, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*8-16f, 8, 21}, //交通柱
{1, UNIT_SIZE*21, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*8+12f, 8, 21}, //交通柱
{1, UNIT_SIZE*21, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*8-12f, 8, 21}, //交通柱
{0, UNIT_SIZE*21, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*8+8f, 8, 21}, //交通柱
{0, UNIT_SIZE*21, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*8-8f, 8, 21}, //交通柱
{1, UNIT_SIZE*21, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*8+4f, 8, 21}, //交通柱
{1, UNIT_SIZE*21, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*8-4f, 8, 21}, //交通柱
{0, UNIT_SIZE*21, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*8+0f, 8, 21}, //交通柱
//5-20竖直
{0, UNIT_SIZE*20, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5+16f, 5, 20}, //交通柱
{0, UNIT_SIZE*20, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5-16f, 5, 20}, //交通柱
{1, UNIT_SIZE*20, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5+12f, 5, 20}, //交通柱
{1, UNIT_SIZE*20, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5-12f, 5, 20}, //交通柱
{0, UNIT_SIZE*20, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5+8f, 5, 20}, //交通柱
{0, UNIT_SIZE*20, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5-8f, 5, 20}, //交通柱
{1, UNIT_SIZE*20, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5+4f, 5, 20}, //交通柱
{1, UNIT_SIZE*20, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5-4f, 5, 20}, //交通柱
{0, UNIT_SIZE*20, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5+0f, 5, 20}, //交通柱
//5-23横着
{0, UNIT_SIZE*23+16f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5, 5, 23}, //交通柱
{0, UNIT_SIZE*23-16f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5, 5, 23}, //交通柱
{1, UNIT_SIZE*23+12f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5, 5, 23}, //交通柱
{1, UNIT_SIZE*23-12f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5, 5, 23}, //交通柱
{0, UNIT_SIZE*23+8f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5, 5,23}, //交通柱
{0, UNIT_SIZE*23-8f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5, 5, 23}, //交通柱
{1, UNIT_SIZE*23+4f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5, 5, 23}, //交通柱
{1, UNIT_SIZE*23-4f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5, 5, 23}, //交通柱
{0, UNIT_SIZE*23+0f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5, 5, 23}, //交通柱
//2-27横着
{0, UNIT_SIZE*27+16f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 27}, //交通柱
{0, UNIT_SIZE*27-16f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 27}, //交通柱
{1, UNIT_SIZE*27+12f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 27}, //交通柱
{1, UNIT_SIZE*27-12f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 27}, //交通柱
{0, UNIT_SIZE*27+8f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2,27}, //交通柱
{0, UNIT_SIZE*27-8f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 27}, //交通柱
{1, UNIT_SIZE*27+4f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 27}, //交通柱
{1, UNIT_SIZE*27-4f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 27}, //交通柱
{0, UNIT_SIZE*27+0f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*2, 2, 27}, //交通柱
//7-26竖直
{0, UNIT_SIZE*26, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*7+16f, 7, 26}, //交通柱
{0, UNIT_SIZE*26, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*7-16f, 7, 26}, //交通柱
{1, UNIT_SIZE*26, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*7+12f, 7, 26}, //交通柱
{1, UNIT_SIZE*26, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*7-12f, 7, 26}, //交通柱
{0, UNIT_SIZE*26, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*7+8f, 7, 26}, //交通柱
{0, UNIT_SIZE*26, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*7-8f, 7, 26}, //交通柱
{1, UNIT_SIZE*26, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*7+4f, 7, 26}, //交通柱
{1, UNIT_SIZE*26, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*7-4f, 7, 26}, //交通柱
{0, UNIT_SIZE*26, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*7+0f, 7, 26}, //交通柱
//16-26竖直
{0, UNIT_SIZE*26, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*16+16f, 16, 26}, //交通柱
{0, UNIT_SIZE*26, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*16-16f, 16, 26}, //交通柱
{1, UNIT_SIZE*26, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*16+12f, 16, 26}, //交通柱
{1, UNIT_SIZE*26, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*16-12f, 16, 26}, //交通柱
{0, UNIT_SIZE*26, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*16+8f, 16, 26}, //交通柱
{0, UNIT_SIZE*26, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*16-8f, 16, 26}, //交通柱
{1, UNIT_SIZE*26, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*16+4f, 16, 26}, //交通柱
{1, UNIT_SIZE*26, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*16-4f, 16, 26}, //交通柱
{0, UNIT_SIZE*26, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*16+0f, 16, 26}, //交通柱
//18-25竖直
{0, UNIT_SIZE*25, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*18+16f, 18, 25}, //交通柱
{0, UNIT_SIZE*25, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*18-16f, 18, 25}, //交通柱
{1, UNIT_SIZE*25, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*18+12f, 18, 25}, //交通柱
{1, UNIT_SIZE*25, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*18-12f, 18, 25}, //交通柱
{0, UNIT_SIZE*25, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*18+8f, 18, 25}, //交通柱
{0, UNIT_SIZE*25, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*18-8f, 18, 25}, //交通柱
{1, UNIT_SIZE*25, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*18+4f, 18, 25}, //交通柱
{1, UNIT_SIZE*25, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*18-4f, 18, 25}, //交通柱
{0, UNIT_SIZE*25, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*18+0f, 18, 25}, //交通柱
//22-26竖直
{0, UNIT_SIZE*26, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*22+16f, 22, 26}, //交通柱
{0, UNIT_SIZE*26, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*22-16f, 22, 26}, //交通柱
{1, UNIT_SIZE*26, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*22+12f, 22, 26}, //交通柱
{1, UNIT_SIZE*26, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*22-12f, 22, 26}, //交通柱
{0, UNIT_SIZE*26, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*22+8f, 22, 26}, //交通柱
{0, UNIT_SIZE*26, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*22-8f, 22, 26}, //交通柱
{1, UNIT_SIZE*26, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*22+4f, 22, 26}, //交通柱
{1, UNIT_SIZE*26, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*22-4f, 22, 26}, //交通柱
{0, UNIT_SIZE*26, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*22+0f, 22, 26}, //交通柱
//22-25竖直
{0, UNIT_SIZE*25, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*22+16f, 22, 25}, //交通柱
{0, UNIT_SIZE*25, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*22-16f, 22, 25}, //交通柱
{1, UNIT_SIZE*25, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*22+12f, 22, 25}, //交通柱
{1, UNIT_SIZE*25, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*22-12f, 22, 25}, //交通柱
{0, UNIT_SIZE*25, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*22+8f, 22, 25}, //交通柱
{0, UNIT_SIZE*25, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*22-8f, 22, 25}, //交通柱
{1, UNIT_SIZE*25, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*22+4f, 22, 25}, //交通柱
{1, UNIT_SIZE*25, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*22-4f, 22, 25}, //交通柱
{0, UNIT_SIZE*25, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*22+0f, 22, 25}, //交通柱
//24-24竖直
{0, UNIT_SIZE*24, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*24+16f, 24, 24}, //交通柱
{0, UNIT_SIZE*24, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*24-16f, 24, 24}, //交通柱
{1, UNIT_SIZE*24, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*24+12f, 24, 24}, //交通柱
{1, UNIT_SIZE*24, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*24-12f, 24, 24}, //交通柱
{0, UNIT_SIZE*24, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*24+8f, 24, 24}, //交通柱
{0, UNIT_SIZE*24, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*24-8f, 24, 24}, //交通柱
{1, UNIT_SIZE*24, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*24+4f, 24, 24}, //交通柱
{1, UNIT_SIZE*24, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*24-4f, 24, 24}, //交通柱
{0, UNIT_SIZE*24, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*24+0f, 24, 24}, //交通柱
//26-15竖直
{0, UNIT_SIZE*15, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*26+16f, 26, 15}, //交通柱
{0, UNIT_SIZE*15, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*26-16f, 26, 15}, //交通柱
{1, UNIT_SIZE*15, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*26+12f, 26, 15}, //交通柱
{1, UNIT_SIZE*15, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*26-12f, 26, 15}, //交通柱
{0, UNIT_SIZE*15, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*26+8f, 26, 15}, //交通柱
{0, UNIT_SIZE*15, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*26-8f, 26, 15}, //交通柱
{1, UNIT_SIZE*15, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*26+4f, 26, 15}, //交通柱
{1, UNIT_SIZE*15, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*26-4f, 26, 15}, //交通柱
{0, UNIT_SIZE*15, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*26+0f, 26, 15}, //交通柱
//21-16竖直
{0, UNIT_SIZE*16, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*21+16f, 21, 16}, //交通柱
{0, UNIT_SIZE*16, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*21-16f, 21, 16}, //交通柱
{1, UNIT_SIZE*16, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*21+12f, 21, 16}, //交通柱
{1, UNIT_SIZE*16, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*21-12f, 21, 16}, //交通柱
{0, UNIT_SIZE*16, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*21+8f, 21, 16}, //交通柱
{0, UNIT_SIZE*16, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*21-8f, 21, 16}, //交通柱
{1, UNIT_SIZE*16, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*21+4f, 21, 16}, //交通柱
{1, UNIT_SIZE*16, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*21-4f, 21, 16}, //交通柱
{0, UNIT_SIZE*16, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*21+0f, 21, 16}, //交通柱
//20-14横着
{0, UNIT_SIZE*14+16f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*20, 20, 14}, //交通柱
{0, UNIT_SIZE*14-16f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*20, 20, 14}, //交通柱
{1, UNIT_SIZE*14+12f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*20, 20, 14}, //交通柱
{1, UNIT_SIZE*14-12f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*20, 20, 14}, //交通柱
{0, UNIT_SIZE*14+8f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*20, 20,14}, //交通柱
{0, UNIT_SIZE*14-8f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*20, 20, 14}, //交通柱
{1, UNIT_SIZE*14+4f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*20, 20, 14}, //交通柱
{1, UNIT_SIZE*14-4f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*20, 20, 14}, //交通柱
{0, UNIT_SIZE*14+0f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*20, 20, 14}, //交通柱
//20-12横着
{0, UNIT_SIZE*12+16f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*20, 20, 12}, //交通柱
{0, UNIT_SIZE*12-16f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*20, 20, 12}, //交通柱
{1, UNIT_SIZE*12+12f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*20, 20, 12}, //交通柱
{1, UNIT_SIZE*12-12f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*20, 20, 12}, //交通柱
{0, UNIT_SIZE*12+8f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*20, 20, 12}, //交通柱
{0, UNIT_SIZE*12-8f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*20, 20, 12}, //交通柱
{1, UNIT_SIZE*12+4f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*20, 20, 12}, //交通柱
{1, UNIT_SIZE*12-4f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*20, 20, 12}, //交通柱
{0, UNIT_SIZE*12+0f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*20, 20, 12}, //交通柱
//22-12竖直
{0, UNIT_SIZE*12, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*22+16f, 22, 12}, //交通柱
{0, UNIT_SIZE*12, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*22-16f, 22, 12}, //交通柱
{1, UNIT_SIZE*12, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*22+12f, 22, 12}, //交通柱
{1, UNIT_SIZE*12, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*22-12f, 22, 12}, //交通柱
{0, UNIT_SIZE*12, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*22+8f, 22, 12}, //交通柱
{0, UNIT_SIZE*12, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*22-8f, 22, 12}, //交通柱
{1, UNIT_SIZE*12, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*22+4f, 22, 12}, //交通柱
{1, UNIT_SIZE*12, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*22-4f, 22, 12}, //交通柱
{0, UNIT_SIZE*12, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*22+0f, 22, 12}, //交通柱
//25-12竖直
{0, UNIT_SIZE*12, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*25+16f, 25, 12}, //交通柱
{0, UNIT_SIZE*12, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*25-16f, 25, 12}, //交通柱
{1, UNIT_SIZE*12, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*25+12f, 25, 12}, //交通柱
{1, UNIT_SIZE*12, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*25-12f, 25, 12}, //交通柱
{0, UNIT_SIZE*12, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*25+8f, 25, 12}, //交通柱
{0, UNIT_SIZE*12, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*25-8f, 25, 12}, //交通柱
{1, UNIT_SIZE*12, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*25+4f, 25, 12}, //交通柱
{1, UNIT_SIZE*12, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*25-4f, 25, 12}, //交通柱
{0, UNIT_SIZE*12, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*25+0f, 25, 12}, //交通柱
//29-6竖直
{0, UNIT_SIZE*6, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*29+16f, 29, 6}, //交通柱
{0, UNIT_SIZE*6, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*29-16f, 29, 6}, //交通柱
{1, UNIT_SIZE*6, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*29+12f, 29, 6}, //交通柱
{1, UNIT_SIZE*6, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*29-12f, 29, 6}, //交通柱
{0, UNIT_SIZE*6, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*29+8f, 29, 6}, //交通柱
{0, UNIT_SIZE*6, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*29-8f, 29, 6}, //交通柱
{1, UNIT_SIZE*6, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*29+4f, 29, 6}, //交通柱
{1, UNIT_SIZE*6, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*29-4f, 29, 6}, //交通柱
{0, UNIT_SIZE*6, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*29+0f, 29, 6}, //交通柱
//27-2竖直
{0, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*27+16f, 27, 2}, //交通柱
{0, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*27-16f, 27, 2}, //交通柱
{1, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*27+12f, 27, 2}, //交通柱
{1, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*27-12f, 27, 2}, //交通柱
{0, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*27+8f, 27, 2}, //交通柱
{0, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*27-8f, 27, 2}, //交通柱
{1, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*27+4f, 27, 2}, //交通柱
{1, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*27-4f, 27, 2}, //交通柱
{0, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*27+0f, 27, 2}, //交通柱
//24-2竖直
{0, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*24+16f, 24, 2}, //交通柱
{0, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*24-16f, 24, 2}, //交通柱
{1, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*24+12f, 24, 2}, //交通柱
{1, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*24-12f, 24, 2}, //交通柱
{0, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*24+8f, 24, 2}, //交通柱
{0, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*24-8f, 24, 2}, //交通柱
{1, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*24+4f, 24, 2}, //交通柱
{1, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*24-4f, 24, 2}, //交通柱
{0, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*24+0f, 24, 2}, //交通柱
//20-1竖直
{0, UNIT_SIZE*1, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*20+16f, 20, 1}, //交通柱
{0, UNIT_SIZE*1, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*20-16f, 20, 1}, //交通柱
{1, UNIT_SIZE*1, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*20+12f, 20, 1}, //交通柱
{1, UNIT_SIZE*1, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*20-12f, 20, 1}, //交通柱
{0, UNIT_SIZE*1, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*20+8f, 20, 1}, //交通柱
{0, UNIT_SIZE*1, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*20-8f, 20, 1}, //交通柱
{1, UNIT_SIZE*1, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*20+4f, 20, 1}, //交通柱
{1, UNIT_SIZE*1, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*20-4f, 20, 1}, //交通柱
{0, UNIT_SIZE*1, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*20+0f, 20, 1}, //交通柱
//16-1竖直
{0, UNIT_SIZE*1, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*16+16f, 16, 1}, //交通柱
{0, UNIT_SIZE*1, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*16-16f, 16, 1}, //交通柱
{1, UNIT_SIZE*1, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*16+12f, 16, 1}, //交通柱
{1, UNIT_SIZE*1, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*16-12f, 16, 1}, //交通柱
{0, UNIT_SIZE*1, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*16+8f, 16, 1}, //交通柱
{0, UNIT_SIZE*1, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*16-8f, 16, 1}, //交通柱
{1, UNIT_SIZE*1, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*16+4f, 16, 1}, //交通柱
{1, UNIT_SIZE*1, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*16-4f, 16, 1}, //交通柱
{0, UNIT_SIZE*1, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*16+0f, 16, 1}, //交通柱
//9-2竖直
{0, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*9+16f, 9, 2}, //交通柱
{0, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*9-16f, 9, 2}, //交通柱
{1, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*9+12f, 9, 2}, //交通柱
{1, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*9-12f, 9, 2}, //交通柱
{0, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*9+8f, 9, 2}, //交通柱
{0, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*9-8f, 9, 2}, //交通柱
{1, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*9+4f, 9, 2}, //交通柱
{1, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*9-4f, 9, 2}, //交通柱
{0, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*9+0f, 9, 2}, //交通柱
//5-2竖直
{0, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5+16f, 5, 2}, //交通柱
{0, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5-16f, 5, 2}, //交通柱
{1, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5+12f, 5, 2}, //交通柱
{1, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5-12f, 5, 2}, //交通柱
{0, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5+8f, 5, 2}, //交通柱
{0, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5-8f, 5, 2}, //交通柱
{1, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5+4f, 5, 2}, //交通柱
{1, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5-4f, 5, 2}, //交通柱
{0, UNIT_SIZE*2, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5+0f, 5, 2}, //交通柱
//3-1横着
{0, UNIT_SIZE*1+16f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*3, 3, 1}, //交通柱
{0, UNIT_SIZE*1-16f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*3, 3, 1}, //交通柱
{1, UNIT_SIZE*1+12f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*3, 3, 1}, //交通柱
{1, UNIT_SIZE*1-12f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*3, 3, 1}, //交通柱
{0, UNIT_SIZE*1+8f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*3, 3, 1}, //交通柱
{0, UNIT_SIZE*1-8f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*3, 3, 1}, //交通柱
{1, UNIT_SIZE*1+4f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*3, 3, 1}, //交通柱
{1, UNIT_SIZE*1-4f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*3, 3, 1}, //交通柱
{0, UNIT_SIZE*1+0f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*3, 3, 1}, //交通柱
//5-24横着
{0, UNIT_SIZE*24+16f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5, 5, 24}, //交通柱
{0, UNIT_SIZE*24-16f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5, 5, 24}, //交通柱
{1, UNIT_SIZE*24+12f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5, 5, 24}, //交通柱
{1, UNIT_SIZE*24-12f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5, 5, 24}, //交通柱
{0, UNIT_SIZE*24+8f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5, 5, 24}, //交通柱
{0, UNIT_SIZE*24-8f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5, 5, 24}, //交通柱
{1, UNIT_SIZE*24+4f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5, 5, 24}, //交通柱
{1, UNIT_SIZE*24-4f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5, 5, 24}, //交通柱
{0, UNIT_SIZE*24+0f, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*5, 5, 24}, //交通柱
//新添加的
//11-11竖直
{0, UNIT_SIZE*11, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*11+16f, 11, 11}, //交通柱
{0, UNIT_SIZE*11, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*11-16f, 11, 11}, //交通柱
{1, UNIT_SIZE*11, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*11+12f, 11, 11}, //交通柱
{1, UNIT_SIZE*11, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*11-12f, 11, 11}, //交通柱
{0, UNIT_SIZE*11, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*11+8f, 11, 11}, //交通柱
{0, UNIT_SIZE*11, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*11-8f, 11, 11}, //交通柱
{1, UNIT_SIZE*11, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*11+4f, 11, 11}, //交通柱
{1, UNIT_SIZE*11, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*11-4f, 11, 11}, //交通柱
{0, UNIT_SIZE*11, WATER_HIGH_ADJUST+1.3f, UNIT_SIZE*11+0f, 11, 11}, //交通柱
//新添加的
};
}

View File

@@ -0,0 +1,7 @@
package com.bn.clp;
//可碰撞物件的父类,所有的可碰撞物体均是继承自该类
public abstract class KZBJDrawer
{
public abstract void drawSelf(int texId);
}

View File

@@ -0,0 +1,168 @@
package com.bn.clp;
import static com.bn.clp.Constant.*;
import com.bn.core.MatrixState;
import com.bn.st.d2.MyActivity;
import android.opengl.GLES20;
import static com.bn.clp.MyGLSurfaceView.*;
//可碰撞部件控制类,交通柱的id为0交通锥的id为1
public class KZBJForControl
{
KZBJDrawer kzbjdrawer;
int id;//对应的碰撞物id0表示交通筒1表示障碍物
boolean state=false;//false表示可被碰撞true表示被撞后飞行中否则不可碰撞。
float x;//摆放的初始位置
float y;
float z;
float alpha;//转动角度
float alphaX;//转动轴向量
float alphaY;
float alphaZ;
float currentX;//飞行中的当前位置
float currentY;
float currentZ;
int row;//位置所在地图行和列
int col;
float vx;//飞行中的速度分量
float vy;
float vz;
float time_Fly;//飞行累计时间
MyActivity ma;
public KZBJForControl(KZBJDrawer kzbjdrawer,int id,float x,float y,float z,int row,int col,MyActivity ma)
{
this.kzbjdrawer=kzbjdrawer;
this.id=id;
this.x=x;
this.y=y;
this.z=z;
this.row=row;
this.col=col;
this.ma=ma;
}
public void drawSelf(int texId,int dyFlag)
{
if(dyFlag==0)//绘制实体
{
MatrixState.pushMatrix();
if(!state)
{//原始状态绘制
MatrixState.translate(x, y, z);
//MyGLSurfaceView类中的该控制类的列表
ma.gameV.kzbj_array[id].drawSelf(texId);
}
else
{//飞行中绘制
if(currentY>-40)
{//如果已经飞行到地面以下,就不再绘制
MatrixState.translate(currentX, currentY, currentZ);
MatrixState.rotate(alpha,alphaX, alphaY, alphaZ);
ma.gameV.kzbj_array[id].drawSelf(texId);
}
}
MatrixState.popMatrix();
}
else if(dyFlag==1)//绘制倒影
{
//实际绘制时Y的零点
float yTranslate=y;
//进行镜像绘制时的调整值
float yjx=(0-yTranslate)*2;
MatrixState.pushMatrix();
//关闭背面剪裁
GLES20.glDisable(GLES20.GL_CULL_FACE);
if(!state)
{//原始状态绘制
MatrixState.translate(x, y, z);
MatrixState.translate(0, yjx, 0);
MatrixState.scale(1, -1, 1);
//MyGLSurfaceView类中的该控制类的列表
ma.gameV.kzbj_array[id].drawSelf(texId);
}
else
{//飞行中绘制
if(currentY>-40)
{//如果已经飞行到地面以下,就不再绘制
MatrixState.translate(currentX, currentY, currentZ);
MatrixState.rotate(alpha,alphaX, alphaY, alphaZ);
MatrixState.translate(0, yjx, 0);
MatrixState.scale(1, -1, 1);
ma.gameV.kzbj_array[id].drawSelf(texId);
}
}
//打开背面剪裁
GLES20.glEnable(GLES20.GL_CULL_FACE);
MatrixState.popMatrix();
}
}
//根据船的位置计算出船头位置,并判断是否与某个可撞物体碰撞
public void checkColl(float bX,float bZ,float carAlphaTemp)
{
//首先求出碰撞检测点坐标
float bPointX=(float) (bX-BOAT_UNIT_SIZE*Math.sin(Math.toRadians(sight_angle)));
float bPointZ=(float) (bZ-BOAT_UNIT_SIZE*Math.cos(Math.toRadians(sight_angle)));
//计算碰撞点在地图上的行和列
float carCol=(float) Math.floor((bPointX+UNIT_SIZE/2)/UNIT_SIZE);
float carRow=(float) Math.floor((bPointZ+UNIT_SIZE/2)/UNIT_SIZE);
if(carRow==row&&carCol==col)
{//如果大家在同一个格子里进行严格的碰撞检测KZBJBJ
double disP2=(bPointX-x)*(bPointX-x)+(bPointZ-z)*(bPointZ-z);
//若船头距离目标小于4则为碰撞
if(disP2<=4)
{
if(SoundEffectFlag)
{
ma.shengyinBoFang(4, 0);
}
state=true;//设置状态为飞行中状态
time_Fly=0;//飞行持续时间清零
alpha=0;
alphaX=(float) (-20*Math.cos(Math.toRadians(carAlphaTemp)));
alphaY=0;
alphaZ=(float) (20*Math.sin(Math.toRadians(carAlphaTemp)));
currentX=x;//设置飞行起始点为原始摆放点
currentY=y;
currentZ=z;
//根据船的行进方向确定飞行速度的三个分量
vx=(float) (-20*Math.sin(Math.toRadians(carAlphaTemp)));
vy=15;
vz=(float) (-10*Math.cos(Math.toRadians(carAlphaTemp)));
}
}
}
//飞行移动方法,线程定时调用此方法,实现可撞物体飞行
public void go()
{
if(!state)
{//如果不在飞行状态中不需要go
return;
}
time_Fly=time_Fly+0.3f;//飞行持续时间增加
alpha=alpha+10;
//根据飞行速度的三个分量及飞行持续时间与飞行起点计算当前位置
currentX=x+vx*time_Fly;
currentZ=z+vz*time_Fly;
currentY=y+vy*time_Fly-0.5f*5*time_Fly*time_Fly;//5为重力加速度
//当碰撞物体飞行落到地面以下2000时恢复原位
if(currentY<-2000)
{
state=false;
}
}
}

View File

@@ -0,0 +1,598 @@
package com.bn.clp;
import static com.bn.clp.Constant.*;
import static com.bn.clp.MyGLSurfaceView.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.bn.st.d2.DBUtil;
import com.bn.st.d2.MyActivity;
//监听键盘状态的线程
public class KeyThread extends Thread
{
MyGLSurfaceView mgmv;
MyActivity ma;
public boolean flag=true;
public boolean moveFlag=true;
public static boolean otherBoatFlag=true;
boolean pzFlag=false;
public static boolean upFlag=true;
float bOldZ;
int[] stepIndex;//大步索引
int[] stepStatus;//0-大步 0-小步 2-结束
int[] stepIndexC;//小步索引
float[][] bdbqs;//本大步起始
float[][] bdbjb;//本大步渐变
int[] bdbzxb;//本大步总小步
int dqCount=0;//氮气计数器
public KeyThread(MyGLSurfaceView mv,MyActivity ma)
{
this.setName("KeyThread");
this.mgmv=mv;
this.ma=ma;
stepIndex=new int[MyGLSurfaceView.qtCount];
stepStatus=new int[MyGLSurfaceView.qtCount];
stepIndexC=new int[MyGLSurfaceView.qtCount];
bdbqs=new float[MyGLSurfaceView.qtCount][2];
bdbjb=new float[MyGLSurfaceView.qtCount][2];
bdbzxb=new int[MyGLSurfaceView.qtCount];
}
public void run()
{
while(flag)
{
if(moveFlag)
{
synchronized(lockA)
{
if(!mgmv.isShaChe)
{
if(CURR_BOAT_V<Max_BOAT_V)
{
CURR_BOAT_V=CURR_BOAT_V+BOAT_A;
}
else if(CURR_BOAT_V>Max_BOAT_V)
{
CURR_BOAT_V=CURR_BOAT_V-BOAT_A;
}
}
else
{
if(CURR_BOAT_V>0)
{
CURR_BOAT_V=CURR_BOAT_V+BOAT_A;
}
else
{
CURR_BOAT_V=0;
}
}
CURR_BOAT_V_TMD=CURR_BOAT_V/Max_BOAT_V;
if(CURR_BOAT_V_TMD>1)
{
CURR_BOAT_V_TMD=1;
}
if((MyGLSurfaceView.keyState&0x1)!=0)
{//有UP键按下
float xOffset=0;//此步的X位移
float zOffset=0;//此步的Z位移
xOffset=(float)-Math.sin(Math.toRadians(sight_angle))*CURR_BOAT_V;
zOffset=(float)-Math.cos(Math.toRadians(sight_angle))*CURR_BOAT_V;
//计算运动后的船的XZ值
float tempbx=bx+xOffset;
float tempbz=bz+zOffset;
//判断船头所在位置的陆地高度是否低于水面并且没有与桥墩发生碰撞
if(isYachtHeadCollectionsWithLand(tempbx,tempbz)&&!isPZ(tempbx,tempbz))
{
bOldZ=bz;
bx=tempbx;
bz=tempbz;
if(CURR_BOAT_V>CURR_BOAT_V_PZ)
{
pzFlag=false;
}
}
else
{
Constant.CURR_BOAT_V=0;
if(pzFlag==false&&SoundEffectFlag)
{
ma.shengyinBoFang(1, 0);
pzFlag=true;
}
}
}
if((MyGLSurfaceView.keyState&0x4)!=0)
{//有left键按下
//向左转动帆船
sight_angle=sight_angle+DEGREE_SPAN;
//帆船视觉上向左斜
if(yachtLeftOrRightAngle<yachtLeftOrRightAngleMax)
{
yachtLeftOrRightAngle=yachtLeftOrRightAngle+yachtLeftOrRightAngleA;
}
else
{
yachtLeftOrRightAngle=yachtLeftOrRightAngleMax;
}
}
else if((MyGLSurfaceView.keyState&0x8)!=0)
{//有right键按下
//向右转动帆船
sight_angle=sight_angle-DEGREE_SPAN;
//帆船视觉上向右斜
if(yachtLeftOrRightAngle>-yachtLeftOrRightAngleMax)
{
yachtLeftOrRightAngle=yachtLeftOrRightAngle-yachtLeftOrRightAngleA;
}
else
{
yachtLeftOrRightAngle=-yachtLeftOrRightAngleMax;
}
}
else
{//若左后键都没有按下,则帆船视觉上不倾斜
if(yachtLeftOrRightAngle<0)
{
yachtLeftOrRightAngle=yachtLeftOrRightAngle+yachtLeftOrRightAngleA;
}
else if(yachtLeftOrRightAngle>0)
{
yachtLeftOrRightAngle=yachtLeftOrRightAngle-yachtLeftOrRightAngleA;
}
}
// if(isFirstPersonView)
// {
// //设置新的摄像机XZ坐标
// cx=(float)(bx);//摄像机x坐标
// cz=(float)(bz);//摄像机z坐标
//
// //设置新的观察目标点XZ坐标
// tx=(float)(cx-Math.sin(Math.toRadians(sight_angle))*DISTANCE+0.5f);//观察目标点x坐标
// tz=(float)(cz-Math.cos(Math.toRadians(sight_angle))*DISTANCE);//观察目标点z坐标
// }
// else
// {
//设置新的摄像机XZ坐标
cx=(float)(bx+Math.sin(Math.toRadians(sight_angle-yachtLeftOrRightAngle/2))*DISTANCE);//摄像机x坐标
cz=(float)(bz+Math.cos(Math.toRadians(sight_angle-yachtLeftOrRightAngle/2))*DISTANCE);//摄像机z坐标
//设置新的观察目标点XZ坐标
tx=(float)(cx-Math.sin(Math.toRadians(sight_angle-yachtLeftOrRightAngle/2))*DISTANCE);//观察目标点x坐标
tz=(float)(cz-Math.cos(Math.toRadians(sight_angle-yachtLeftOrRightAngle/2))*DISTANCE);//观察目标点z坐标
// }
}
}
isHalfForBoat(bx,bz);
isOneCycleForBoat(bx,bz);
if(otherBoatFlag)
{
for(int i=0;i<mgmv.otherPaths.size();i++)
{
if(stepStatus[i]==0)
{//若是大步调整
ArrayList<float[]> pathCurr=mgmv.otherPaths.get(i);
bdbqs[i][0]=pathCurr.get(stepIndex[i])[0];
bdbqs[i][1]=pathCurr.get(stepIndex[i])[1];
stepIndexC[i]=0;
float bdbjsX=pathCurr.get((stepIndex[i]+1)%pathCurr.size())[0];
float bdbjsZ=pathCurr.get((stepIndex[i]+1)%pathCurr.size())[1];
double distance=Math.sqrt((bdbjsX-bdbqs[i][0])*(bdbjsX-bdbqs[i][0])+(bdbjsZ-bdbqs[i][1])*(bdbjsZ-bdbqs[i][1]));
if(distance<1)
{
stepIndex[i]=stepIndex[i]+1;
if(stepIndex[i]==pathCurr.size())
{
stepIndex[i]=0;
Constant.BOAT_LAP_NUMBER_OTHER[i]=Constant.BOAT_LAP_NUMBER_OTHER[i]+1;
//若圈数到了
if(Constant.BOAT_LAP_NUMBER_OTHER[i]==3)
{
stepStatus[i]=2;
Constant.RANK_FOR_HELP=Constant.RANK_FOR_HELP+1;
}
}
}
else
{
bdbzxb[i]=(int) (distance/Constant.Max_BOAT_V_OTHER[i]);
bdbjb[i][0]=(bdbjsX-bdbqs[i][0])/bdbzxb[i];
bdbjb[i][1]=(bdbjsZ-bdbqs[i][1])/bdbzxb[i];
float degree=(float) Math.toDegrees(Math.atan2(bdbjb[i][0], bdbjb[i][1]));
MyGLSurfaceView.otherBoatLocation[i][2]=degree+180;
stepStatus[i]=1;
stepIndex[i]=stepIndex[i]+1;
if(stepIndex[i]==pathCurr.size())
{
stepIndex[i]=0;
Constant.BOAT_LAP_NUMBER_OTHER[i]=Constant.BOAT_LAP_NUMBER_OTHER[i]+1;
//若圈数到了
if(Constant.BOAT_LAP_NUMBER_OTHER[i]==3)
{
stepStatus[i]=2;
Constant.RANK_FOR_HELP=Constant.RANK_FOR_HELP+1;
}
}
if(stepStatus[i]!=2)
{
MyGLSurfaceView.otherBoatLocation[i][0]=bdbqs[i][0]+ bdbjb[i][0]*stepIndexC[i];
MyGLSurfaceView.otherBoatLocation[i][1]=bdbqs[i][1]+ bdbjb[i][1]*stepIndexC[i];
stepIndexC[i]++;
}
}
}
else if(stepStatus[i]==1)
{
MyGLSurfaceView.otherBoatLocation[i][0]=bdbqs[i][0]+ bdbjb[i][0]*stepIndexC[i];
MyGLSurfaceView.otherBoatLocation[i][1]=bdbqs[i][1]+ bdbjb[i][1]*stepIndexC[i];
stepIndexC[i]++;
if(stepIndexC[i]>=bdbzxb[i])
{
stepStatus[i]=0;
}
}
}
}
if(moveFlag)
{
if(dqCount>0)
{
dqCount--;
}
else if(dqCount<=0)
{
dqCount=0;
Max_BOAT_V=Max_BOAT_V_VALUE;
}
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//判断是否与桥墩发生碰撞的方法
public boolean isPZ(float bx,float bz)
{
//首先求出碰撞检测点坐标
float bPointX=(float) (bx-BOAT_UNIT_SIZE*Math.sin(Math.toRadians(sight_angle)));
float bPointZ=(float) (bz-BOAT_UNIT_SIZE*Math.cos(Math.toRadians(sight_angle)));
//计算碰撞点在地图上的行和列
float carCol=(float) Math.floor((bPointX+UNIT_SIZE/2)/UNIT_SIZE);
float carRow=(float) Math.floor((bPointZ+UNIT_SIZE/2)/UNIT_SIZE);
for(PZZ temp:ma.gameV.pzzList)
{
if(temp.row==carRow&&temp.col==carCol)
{
if(temp.isIn(bPointX, bPointZ))
{
return true;
}
}
}
return false;
}
//判断船头所在位置的陆地高度是否低于水面
public boolean isYachtHeadCollectionsWithLand(float bx,float bz)
{
final float PRE_UNIT_SIZE=UNIT_SIZE/(yArray_ZD.length-1);
//首先求出碰撞检测点坐标
float tempbx=(float) (bx-BOAT_UNIT_SIZE*Math.sin(Math.toRadians(sight_angle)));
float tempbz=(float) (bz-BOAT_UNIT_SIZE*Math.cos(Math.toRadians(sight_angle)));
//计算碰撞点在地图上的行和列
float col=(float) Math.floor((tempbx+UNIT_SIZE/2)/UNIT_SIZE);
float row=(float) Math.floor((tempbz+UNIT_SIZE/2)/UNIT_SIZE);
int id=MAP_ARRAY[(int) row][(int) col];
if(id==8)
{
return true;
}
float colx=col*UNIT_SIZE-UNIT_SIZE/2;
float rowz=row*UNIT_SIZE-UNIT_SIZE/2;
//计算碰撞点在对应的行列格子中的x、z坐标每个小格子的中心点即为该格子的坐标原点
float rawXIn=tempbx-colx;
float rawZIn=tempbz-rowz;
float xIn=rawXIn;
float zIn=rawZIn;
if(id==1||id==10)
{
xIn=UNIT_SIZE-rawZIn;
zIn=rawXIn;
}
else if(id==3||id==12)
{
xIn=UNIT_SIZE-rawZIn;
zIn=rawXIn;
}
else if(id==4||id==13)
{
xIn=UNIT_SIZE-rawXIn;
zIn=UNIT_SIZE-rawZIn;
}
else if(id==5||id==14)
{
xIn=UNIT_SIZE-rawZIn;
zIn=rawXIn;
}
else if(id==6||id==15)
{
xIn=rawZIn;
zIn=UNIT_SIZE-rawXIn;
}
float[][] yArrayCurr=null;
if(id==0||id==1||id==9||id==10) //直道(包括横竖)
{
yArrayCurr=yArray_ZD;
}
else if(id==2||id==3||id==11||id==12) //直道(包括横竖带小山)
{
yArrayCurr=yArray_ZD_DXD;
}
else if(id==4||id==5||id==6||id==7||id==13||id==14|id==15|id==16) //弯道
{
yArrayCurr=yArray_WD;
}
//计算船头对应的陆地格子的行、列
int tempCol=(int)(xIn/PRE_UNIT_SIZE);
int tempRow=(int)(zIn/PRE_UNIT_SIZE);
//计算船头对应的陆地格子的四个点的坐标
float x0=tempCol*PRE_UNIT_SIZE;
float z0=tempRow*PRE_UNIT_SIZE;
float y0=yArrayCurr[tempRow][tempCol];
float x1=x0+PRE_UNIT_SIZE;
float z1=z0;
float y1=yArrayCurr[tempRow][tempCol+1];
float x2=x0+PRE_UNIT_SIZE;
float z2=z0+PRE_UNIT_SIZE;
float y2=yArrayCurr[tempRow+1][tempCol+1];
float x3=x0;
float z3=z0+PRE_UNIT_SIZE;
float y3=yArrayCurr[tempRow+1][tempCol];
//船头处的陆地高度
float cty=0;
if(isInTriangle(x0,z0,x1,z1,x3,z3,xIn,zIn))
{//判断帆船船头是否位于0-1-3三角形
//求0-1-3面在船头处的高度
cty=fromXZToY
(
x0,y0,z0,
x3,y3,z3,
x1,y1,z1,
xIn,zIn
);
}
else
{
//求1-2-3面在船头处的高度
cty=fromXZToY
(
x1,y1,z1,
x3,y3,z3,
x2,y2,z2,
xIn,zIn
);
}
if(cty<=0)
{//若船头处的陆地低于水面则返回true
return true;
}
return false;
}
//判断一个点是否在三角形内的方法
//基本算法思想是首先求要被判断的点到三角形三个顶点的矢量1、2、3
//然后三个矢量求叉积,若三个叉积同号则点位于三角形内,否则位于三角形外
public boolean isInTriangle
(
//三角形第一个点的XY坐标
float x1,
float y1,
//三角形第二个点的XY坐标
float x2,
float y2,
//三角形第三个点的XY坐标
float x3,
float y3,
//被判断点的XY坐标
float dx,
float dy
)
{
//被判断点到三角形第一个点的矢量
float vector1x=dx-x1;
float vector1y=dy-y1;
//被判断点到三角形第二个点的矢量
float vector2x=dx-x2;
float vector2y=dy-y2;
//被判断点到三角形第三个点的矢量
float vector3x=dx-x3;
float vector3y=dy-y3;
//计算第1、2矢量个叉积
float crossProduct1=vector1x*vector2y-vector1y*vector2x;
//计算第2、3矢量个叉积
float crossProduct2=vector2x*vector3y-vector2y*vector3x;
//计算第3、1矢量个叉积
float crossProduct3=vector3x*vector1y-vector3y*vector1x;
if(crossProduct1<0&&crossProduct2<0&&crossProduct3<0)
{//若三个叉积同号返回true
return true;
}
if(crossProduct1>0&&crossProduct2>0&&crossProduct3>0)
{//若三个叉积同号返回true
return true;
}
return false;
}
//计算由三个点0、1、2确定的平面在指定XZ坐标处的高度
//基本算法思想首先求出0号点到1、2号点的矢量
//然后这两个矢量求叉积得到三角形平面的法矢量{A,B,C}
//接着通过法矢量和0号点坐标可以写出三角形平面的方程
// A(x-x0)+B(y-y0)+c(z-z0)=0
//然后可以推导出指定xz坐标处y的求值公式
//y=(C(z0-z)+A(x0-x))/B+y0;
//最后通过求值公式求出指定xz坐标处y的值
public float fromXZToY
(
float tx0,float ty0,float tz0,//确定平面的点0
float tx1,float ty1,float tz1,//确定平面的点1
float tx2,float ty2,float tz2,//确定平面的点2
float ctx,float ctz//船头的XZ坐标
)
{
//求出0号点到1号点的矢量
float x1=tx1-tx0;
float y1=ty1-ty0;
float z1=tz1-tz0;
//求出0号点到2号点的矢量
float x2=tx2-tx0;
float y2=ty2-ty0;
float z2=tz2-tz0;
//求出两个矢量叉积矢量在XYZ轴的分量ABC
float A=y1*z2-y2*z1;
float B=z1*x2-z2*x1;
float C=x1*y2-x2*y1;
//通过求值公式求指定xz处的y值
float yResult=(C*(tz0-ctz)+A*(tx0-ctx))/B+ty0;
//返回结果
return yResult;
}
//新添加的,主要是判断是否一圈结束====================================================
final float RACE_HALF_X=14*UNIT_SIZE;
final float RACE_HALF_Z=20*UNIT_SIZE;
final float RACE_BEGIN_X=30;
final float RACE_BEGIN_Z=90;
public void isHalfForBoat(float carTempX,float carTempZ)
{
double dis=Math.sqrt
(
(carTempX-RACE_HALF_X)* (carTempX-RACE_HALF_X)
+(carTempZ-RACE_HALF_Z)*(carTempZ-RACE_HALF_Z)
);
if(dis<=120)
{
halfFlag=true;
}
}
//是否跑完一圈的方法
public void isOneCycleForBoat(float carTempX,float carTempZ)
{
double dis=Math.sqrt
(
(carTempX-RACE_BEGIN_X)*(carTempX-RACE_BEGIN_X)
+(carTempZ-RACE_BEGIN_Z)*(carTempZ-RACE_BEGIN_Z)
);
if(dis<=60&&bOldZ>RACE_BEGIN_Z&&carTempZ<=RACE_BEGIN_Z)
{
if(halfFlag==true)
{
numberOfTurns=numberOfTurns+1;//圈数加1
if(numberOfTurns==3&&isSpeedMode) //若为竞速模式在跑完圈数后获得当前的名次并且把速度和加速度设置为0
{
RANK_FOR_HERO_BOAT=RANK_FOR_HELP;
CURR_BOAT_V=0;
BOAT_A=0;
String currSysTime=Constant.getCurrTime();
String currUseTime=Constant.getUseTime();
DBUtil.insertRcRDatabase(currSysTime, currUseTime, RANK_FOR_HERO_BOAT);
//弹出对话框
ma.hd.sendEmptyMessage(12);
}
else if(numberOfTurns==3&&!isSpeedMode) //若为计时模式
{
CURR_BOAT_V=0;
BOAT_A=0;
String currSysTime=Constant.getCurrTime();
String currUseTime=Constant.getUseTime();
List<String> alist=DBUtil.getTimeFromJSDatabase();
isBreakRecord=isFast(currUseTime,alist);
DBUtil.insertJSDatabase(currSysTime, currUseTime);
//弹出是否破纪录的对话框
ma.hd.sendEmptyMessage(11);
}
}
halfFlag=false;
}
else if(dis<=60&&bOldZ<=RACE_BEGIN_Z&&carTempZ>RACE_BEGIN_Z)
{
halfFlag=false;
}
}
//本次玩家用时是否为最短时间的判断方法
public static boolean isFast(String currTime,List<String> aList)
{//这里的true表是当前时间为最短时间即破纪录这里把当前时间先当做最短时间
boolean result=false;
//将当前的时间以“:”分开
String[] str=currTime.split(":");
int currT=Integer.parseInt(str[0])*60*100+Integer.parseInt(str[1])*100+Integer.parseInt(str[2]);
List<Integer> tempInteger=new ArrayList<Integer>();
for(int i=0;i<aList.size();i++)
{
String[] tempStr=aList.get(i).split(":");
tempInteger.add(Integer.parseInt(tempStr[0])*60*100+Integer.parseInt(tempStr[1])*100+Integer.parseInt(tempStr[2]));
}
Collections.sort(tempInteger);
if(tempInteger.size()==0)
{
result=true;
}
else if(currT<tempInteger.get(0))
{
result=true;
}
return result;
}
}

View File

@@ -0,0 +1,170 @@
package com.bn.clp;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import android.content.res.Resources;
import android.util.Log;
public class LoadUtil
{
//求两个向量的叉积
public static float[] getCrossProduct(float x1,float y1,float z1,float x2,float y2,float z2)
{
//求出两个矢量叉积矢量在XYZ轴的分量ABC
float A=y1*z2-y2*z1;
float B=z1*x2-z2*x1;
float C=x1*y2-x2*y1;
return new float[]{A,B,C};
}
//向量规格化
public static float[] vectorNormal(float[] vector)
{
//求向量的模
float module=(float)Math.sqrt(vector[0]*vector[0]+vector[1]*vector[1]+vector[2]*vector[2]);
return new float[]{vector[0]/module,vector[1]/module,vector[2]/module};
}
//从obj文件中加载携带顶点信息的物体
public static LoadedObjectVertexNormal loadFromFileVertexOnly
(String fname, Resources r,int mProgramId)
{
//加载后物体的引用
LoadedObjectVertexNormal lo=null;
//原始顶点坐标列表--直接从obj文件中加载
ArrayList<Float> alv=new ArrayList<Float>();
//顶点组装面索引列表--根据面的信息从文件中加载
ArrayList<Integer> alFaceIndex=new ArrayList<Integer>();
//结果顶点坐标列表--按面组织好
ArrayList<Float> alvResult=new ArrayList<Float>();
//原始纹理坐标列表
ArrayList<Float> alt=new ArrayList<Float>();
//纹理坐标结果列表
ArrayList<Float> altResult=new ArrayList<Float>();
try
{
InputStream in=r.getAssets().open(fname);
InputStreamReader isr=new InputStreamReader(in);
BufferedReader br=new BufferedReader(isr);
String temps=null;
//扫面文件,根据行类型的不同执行不同的处理逻辑
while((temps=br.readLine())!=null)
{
//用空格分割行中的各个组成部分
String[] tempsa=temps.split("[ ]+");
if(tempsa[0].trim().equals("v"))
{//此行为顶点坐标
//若为顶点坐标行则提取出此顶点的XYZ坐标添加到原始顶点坐标列表中
alv.add(Float.parseFloat(tempsa[1]));
alv.add(Float.parseFloat(tempsa[2]));
alv.add(Float.parseFloat(tempsa[3]));
}
else if(tempsa[0].trim().equals("vt"))
{//此行为纹理坐标行
//若为纹理坐标行则提取ST坐标并添加进原始纹理坐标列表中
//采用国画小品纹理图时的代码
alt.add(Float.parseFloat(tempsa[1]));
alt.add(Float.parseFloat(tempsa[2]));
}
else if(tempsa[0].trim().equals("f"))
{//此行为三角形面
/*
*若为三角形面行则根据 组成面的顶点的索引从原始顶点坐标列表中
*提取相应的顶点坐标值添加到结果顶点坐标列表中,同时根据三个
*顶点的坐标计算出此面的法向量并添加到平均前各个索引对应的点
*的法向量集合组成的Map中
*/
int[] index=new int[3];//三个顶点索引值的数组
//计算第0个顶点的索引并获取此顶点的XYZ三个坐标
index[0]=Integer.parseInt(tempsa[1].split("/")[0])-1;
float x0=alv.get(3*index[0]);
float y0=alv.get(3*index[0]+1);
float z0=alv.get(3*index[0]+2);
alvResult.add(x0);
alvResult.add(y0);
alvResult.add(z0);
//计算第1个顶点的索引并获取此顶点的XYZ三个坐标
index[1]=Integer.parseInt(tempsa[2].split("/")[0])-1;
float x1=alv.get(3*index[1]);
float y1=alv.get(3*index[1]+1);
float z1=alv.get(3*index[1]+2);
alvResult.add(x1);
alvResult.add(y1);
alvResult.add(z1);
//计算第2个顶点的索引并获取此顶点的XYZ三个坐标
index[2]=Integer.parseInt(tempsa[3].split("/")[0])-1;
float x2=alv.get(3*index[2]);
float y2=alv.get(3*index[2]+1);
float z2=alv.get(3*index[2]+2);
alvResult.add(x2);
alvResult.add(y2);
alvResult.add(z2);
//记录此面的顶点索引
alFaceIndex.add(index[0]);
alFaceIndex.add(index[1]);
alFaceIndex.add(index[2]);
//将纹理坐标组织到结果纹理坐标列表中
//第0个顶点的纹理坐标
int indexTex=Integer.parseInt(tempsa[1].split("/")[1])-1;
altResult.add(alt.get(indexTex*2));
altResult.add(alt.get(indexTex*2+1));
//第1个顶点的纹理坐标
indexTex=Integer.parseInt(tempsa[2].split("/")[1])-1;
altResult.add(alt.get(indexTex*2));
altResult.add(alt.get(indexTex*2+1));
//第2个顶点的纹理坐标
indexTex=Integer.parseInt(tempsa[3].split("/")[1])-1;
altResult.add(alt.get(indexTex*2));
altResult.add(alt.get(indexTex*2+1));
}
}
//生成顶点数组
int size=alvResult.size();
float[] vXYZ=new float[size];
for(int i=0;i<size;i++)
{
vXYZ[i]=alvResult.get(i);
}
//生成纹理数组
size=altResult.size();
// float[] tST=new float[size];
// for(int i=0;i<size;i++)
// {
// tST[i]=altResult.get(i);
// }
//================贴图没问题的==============
float[] tST=new float[size];
for(int i=0;i<size;i++)
{
if(i%2==1){
tST[i]=1-altResult.get(i);
}else{
tST[i]=altResult.get(i);
}
}
//================贴图没问题的==============
//创建3D物体对象
lo=new LoadedObjectVertexNormal(mProgramId,vXYZ,tST);
}
catch(Exception e)
{
Log.d("load error", "load error");
e.printStackTrace();
}
return lo;
}
}

View File

@@ -0,0 +1,107 @@
package com.bn.clp;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import com.bn.core.MatrixState;
import android.opengl.GLES20;
//加载后的物体——顶点+纹理坐标
public class LoadedObjectVertexNormal
{
int mProgram;//自定义渲染管线着色器程序id
int muMVPMatrixHandle;//总变换矩阵引用id
int muMMatrixHandle;//位置、旋转变换矩阵
int maPositionHandle; //顶点位置属性引用id
int maTexCoorHandle; //顶点纹理坐标属性引用id
FloatBuffer mVertexBuffer;//顶点坐标数据缓冲
FloatBuffer mTexCoorBuffer;//顶点纹理坐标数据缓冲
int vCount=0;
public LoadedObjectVertexNormal(int mProgramId,float[] vertices,float texCoors[])
{
//初始化顶点坐标的initVertexData方法
initVertexData(vertices,texCoors);
//初始化着色器的initShader方法
initShader(mProgramId);
}
//初始化顶点坐标的initVertexData方法
public void initVertexData(float[] vertices,float texCoors[])
{
//顶点坐标数据的初始化================begin============================
vCount=vertices.length/3;
//创建顶点坐标数据缓冲
//vertices.length*4是因为一个整数四个字节
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());//设置字节顺序
mVertexBuffer = vbb.asFloatBuffer();//转换为Float型缓冲
mVertexBuffer.put(vertices);//向缓冲区中放入顶点坐标数据
mVertexBuffer.position(0);//设置缓冲区起始位置
//顶点纹理坐标数据的初始化================begin============================
ByteBuffer tbb = ByteBuffer.allocateDirect(texCoors.length*4);
tbb.order(ByteOrder.nativeOrder());//设置字节顺序
mTexCoorBuffer = tbb.asFloatBuffer();//转换为Float型缓冲
mTexCoorBuffer.put(texCoors);//向缓冲区中放入顶点纹理坐标数据
mTexCoorBuffer.position(0);//设置缓冲区起始位置
}
//初始化着色器的initShader方法
public void initShader(int mProgramId)
{
//基于顶点着色器与片元着色器创建程序
mProgram = mProgramId;
//获取程序中顶点位置属性引用id
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
//获取程序中总变换矩阵引用id
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
//获取位置、旋转变换矩阵引用id
muMMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMMatrix");
//获取程序中顶点纹理坐标属性引用id
maTexCoorHandle= GLES20.glGetAttribLocation(mProgram, "aTexCoor");
}
public void drawSelf(int texId)
{
//制定使用某套shader程序
GLES20.glUseProgram(mProgram);
//将最终变换矩阵传入shader程序
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//将位置、旋转变换矩阵传入shader程序
GLES20.glUniformMatrix4fv(muMMatrixHandle, 1, false, MatrixState.getMMatrix(), 0);
//为画笔指定顶点位置数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入顶点纹理坐标数据
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false,
2*4,
mTexCoorBuffer
);
//允许顶点位置、法向量、纹理坐标数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
//绘制加载的物体
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
}

View File

@@ -0,0 +1,232 @@
package com.bn.clp;
import static com.bn.clp.Constant.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import android.opengl.GLES20;
import com.bn.core.MatrixState;
public class Mountion extends BNDrawer
{
Mountion_In mountion_in;
public Mountion(int programId,float[][] yArray,int rows,int cols)
{
mountion_in=new Mountion_In(programId,yArray,rows,cols);
}
@Override
public void drawSelf(int[] texId,int dyFlag)
{
//texId[0]为草皮纹理idtexId[1]为石头纹理id
mountion_in.drawSelf(texId[0], texId[1]);
}
//真正小山的内部类
private class Mountion_In
{
//单位长度
float UNIT_SIZE=Constant.UNIT_SIZE/15;
//自定义渲染管线着色器程序的id
int mProgram;
//总变化矩阵引用的id
int muMVPMatrixHandle;
//顶点位置属性引用id
int maPositionHandle;
//顶点纹理坐标属性引用id
int maTexCoorHandle;
//草地的id
int sTextureGrassHandle;
//石头的id
int sTextureRockHandle;
//起始x值
int b_YZ_StartYHandle;
//长度
int b_YZ_YSpanHandle;
//是否为隧道山的标志位的引用id
int sdflagHandle;
//此处flag值为0表示隧道山值为1表示为普通山
private int flag=1;
//顶点数据缓冲和纹理坐标数据缓冲
FloatBuffer mVertexBuffer;
FloatBuffer mTexCoorBuffer;
//顶点数量
int vCount=0;
public Mountion_In(int programId,float[][] yArray,int rows,int cols)
{
initVertexData(yArray,rows,cols);
initShader(programId);
}
//初始化顶点数据的initVertexData方法
public void initVertexData(float[][] yArray,int rows,int cols)
{
//顶点坐标数据的初始化================begin============================
vCount=cols*rows*2*3;//每个格子两个三角形每个三角形3个顶点
float vertices[]=new float[vCount*3];//每个顶点xyz三个坐标
int count=0;//顶点计数器
for(int j=0;j<rows;j++)
{
for(int i=0;i<cols;i++)
{
//计算当前格子左上侧点坐标
float zsx=-UNIT_SIZE*cols/2+i*UNIT_SIZE;
float zsz=-UNIT_SIZE*rows/2+j*UNIT_SIZE;
vertices[count++]=zsx;
vertices[count++]=yArray[j][i];
vertices[count++]=zsz;
vertices[count++]=zsx;
vertices[count++]=yArray[j+1][i];
vertices[count++]=zsz+UNIT_SIZE;
vertices[count++]=zsx+UNIT_SIZE;
vertices[count++]=yArray[j][i+1];
vertices[count++]=zsz;
vertices[count++]=zsx+UNIT_SIZE;
vertices[count++]=yArray[j][i+1];
vertices[count++]=zsz;
vertices[count++]=zsx;
vertices[count++]=yArray[j+1][i];
vertices[count++]=zsz+UNIT_SIZE;
vertices[count++]=zsx+UNIT_SIZE;
vertices[count++]=yArray[j+1][i+1];
vertices[count++]=zsz+UNIT_SIZE;
}
}
//创建顶点坐标数据缓冲
//vertices.length*4是因为一个整数四个字节
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());//设置字节顺序
mVertexBuffer = vbb.asFloatBuffer();//转换为Float型缓冲
mVertexBuffer.put(vertices);//向缓冲区中放入顶点坐标数据
mVertexBuffer.position(0);//设置缓冲区起始位置
//顶点纹理坐标数据的初始化================begin============================
float[] texCoor=generateTexCoor(cols,rows);
//创建顶点纹理坐标数据缓冲
ByteBuffer cbb = ByteBuffer.allocateDirect(texCoor.length*4);
cbb.order(ByteOrder.nativeOrder());//设置字节顺序
mTexCoorBuffer = cbb.asFloatBuffer();//转换为Float型缓冲
mTexCoorBuffer.put(texCoor);//向缓冲区中放入顶点着色数据
mTexCoorBuffer.position(0);//设置缓冲区起始位置
}
//初始化着色器的initShader方法
public void initShader(int programId)
{
//基于顶点着色器与片元着色器创建程序
mProgram = programId;
//获取程序中顶点位置属性引用id
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
//获取程序中顶点纹理坐标属性引用id
maTexCoorHandle= GLES20.glGetAttribLocation(mProgram, "aTexCoor");
//获取程序中总变换矩阵引用id
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
//纹理
//草地
sTextureGrassHandle=GLES20.glGetUniformLocation(mProgram, "sTextureGrass");
//石头
sTextureRockHandle=GLES20.glGetUniformLocation(mProgram, "sTextureRock");
//x位置
b_YZ_StartYHandle=GLES20.glGetUniformLocation(mProgram, "b_YZ_StartY");
//x最大
b_YZ_YSpanHandle=GLES20.glGetUniformLocation(mProgram, "b_YZ_YSpan");
sdflagHandle=GLES20.glGetUniformLocation(mProgram, "sdflag");
}
//自定义的绘制方法drawSelf
public void drawSelf(int texId,int rock_textId)
{
//制定使用某套shader程序
GLES20.glUseProgram(mProgram);
//将最终变换矩阵传入shader程序
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
GLES20.glUniform1i(sdflagHandle, flag);
//传入顶点位置数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入纹理坐标数据
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false,
2*4,
mTexCoorBuffer
);
//允许顶点位置数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, rock_textId);
GLES20.glUniform1i(sTextureGrassHandle, 0);//使用0号纹理
GLES20.glUniform1i(sTextureRockHandle, 1); //使用1号纹理
//传送相应的x参数
GLES20.glUniform1f(b_YZ_StartYHandle, 0);
GLES20.glUniform1f(b_YZ_YSpanHandle, SD_HEIGHT);
//绘制纹理矩形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
//自动切分纹理产生纹理数组的方法
public float[] generateTexCoor(int bw,int bh)
{
float[] result=new float[bw*bh*6*2];
float sizew=8.0f/bw;//列数
float sizeh=8.0f/bh;//行数
int c=0;
for(int i=0;i<bh;i++)
{
for(int j=0;j<bw;j++)
{
//每行列一个矩形由两个三角形构成共六个点12个纹理坐标
float s=j*sizew;
float t=i*sizeh;
result[c++]=s;
result[c++]=t;
result[c++]=s;
result[c++]=t+sizeh;
result[c++]=s+sizew;
result[c++]=t;
result[c++]=s+sizew;
result[c++]=t;
result[c++]=s;
result[c++]=t+sizeh;
result[c++]=s+sizew;
result[c++]=t+sizeh;
}
}
return result;
}
}
}

View File

@@ -0,0 +1,22 @@
package com.bn.clp;
import static com.bn.clp.MyGLSurfaceView.*;
import java.util.Comparator;
public class MyComparable implements Comparator<float[]>
{
public int compare(float another[], float another2[])
{
//重写的比较两个灌木离摄像机距离的方法
float xs=another[0]-cxForSpecFrame;
float zs=another[1]-czForSpecFrame;
float xo=another2[0]-cxForSpecFrame;
float zo=another2[1]-czForSpecFrame;
float disA=(float)Math.sqrt(xs*xs+zs*zs);
float disB=(float)Math.sqrt(xo*xo+zo*zo);
return ((disA-disB)==0)?0:((disA-disB)>0)?-1:1;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,66 @@
package com.bn.clp;
import java.util.Set;
//表示法向量的类,此类的一个对象表示一个法向量
public class Normal
{
public static final float DIFF=0.0000001f;//判断两个法向量是否相同的阈值
//法向量在XYZ轴上的分量
float nx;
float ny;
float nz;
public Normal(float nx,float ny,float nz)
{
this.nx=nx;
this.ny=ny;
this.nz=nz;
}
@Override
public boolean equals(Object o)
{
if(o instanceof Normal)
{//若两个法向量XYZ三个分量的差都小于指定的阈值则认为这两个法向量相等
Normal tn=(Normal)o;
if(Math.abs(nx-tn.nx)<DIFF&&
Math.abs(ny-tn.ny)<DIFF&&
Math.abs(ny-tn.ny)<DIFF
)
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
//由于要用到HashSet因此一定要重写hashCode方法
@Override
public int hashCode()
{
return 1;
}
//求法向量平均值的工具方法
public static float[] getAverage(Set<Normal> sn)
{
//存放法向量和的数组
float[] result=new float[3];
//把集合中所有的法向量求和
for(Normal n:sn)
{
result[0]+=n.nx;
result[1]+=n.ny;
result[2]+=n.nz;
}
//将求和后的法向量规格化
return LoadUtil.vectorNormal(result);
}
}

View File

@@ -0,0 +1,48 @@
package com.bn.clp;
public class PZZ
{
final float UNIT_SIZE=2.1f;//这里的2.1f与桥类中的相同,需要关联起来
float x;
float z;
float xL=UNIT_SIZE;
float zL=2*UNIT_SIZE;
float row;
float col;
float whichBridge;//是哪种桥0度和-90度的桥x和z分别增加的值是相反的。
public PZZ(float x,float z,float row,float col,float whichBridge)
{
this.x=x;
this.z=z;
this.row=row;
this.col=col;
this.whichBridge=whichBridge;
}
public boolean isIn(float bx,float bz)
{
if(whichBridge==0)
{
if(bx>=x&&bx<=x+xL&&bz>=z&&bz<=z+zL)
{
return true;
}
else
{
return false;
}
}
else
{
if(bx>=x&&bx<=x+zL&&bz>=z&&bz<=z+xL)
{
return true;
}
else
{
return false;
}
}
}
}

View File

@@ -0,0 +1,254 @@
package com.bn.clp;
import static com.bn.clp.Constant.*;
import java.util.ArrayList;
public class PathUtil
{
//产生标准路径
public static ArrayList<float[]> generatePath()
{
ArrayList<float[]> path=new ArrayList<float[]>();
for(int[] grid:PATH)
{//加入一个格子的路径
//获取此格子的类型编号
int type=MAP_ARRAY[grid[0]][grid[1]];
float[][] pathTemp=getSubPath(grid[0],grid[1],type);
for(float[] fa:pathTemp)
{
path.add(fa);
}
}
return path;
}
//获取指定行列指定类型的赛道的路线
public static float[][] getSubPath(int row,int col,int type)
{
float[][] result=null;
float startX=col*UNIT_SIZE-UNIT_SIZE/2;
float startZ=row*UNIT_SIZE-UNIT_SIZE/2;
switch(type)
{
case 0:
result=new float[2][2];
result[0][0]=0;
result[0][1]=UNIT_SIZE/2+3;
result[1][0]=UNIT_SIZE;
result[1][1]=UNIT_SIZE/2+3;
break;
case 1:
result=new float[2][2];
result[0][0]=UNIT_SIZE/2+3;
result[0][1]=UNIT_SIZE;
result[1][0]=UNIT_SIZE/2+3;
result[1][1]=0;
break;
case 2:
result=new float[4][2];
result[0][0]=0;
result[0][1]=UNIT_SIZE/2+3;
result[1][0]=UNIT_SIZE/3;
result[1][1]=UNIT_SIZE/2-13;
result[2][0]=(UNIT_SIZE/3)*2;
result[2][1]=UNIT_SIZE/2-13;
result[3][0]=UNIT_SIZE;
result[3][1]=UNIT_SIZE/2+3;
break;
case 3:
result=new float[4][2];
result[0][0]=UNIT_SIZE/2+3;
result[0][1]=UNIT_SIZE;
result[1][0]=UNIT_SIZE/2-13;
result[1][1]=(UNIT_SIZE/3)*2;
result[2][0]=UNIT_SIZE/2-13;
result[2][1]=UNIT_SIZE/3;
result[3][0]=UNIT_SIZE/2+3;
result[3][1]=0;
break;
case 4:
result=new float[3][2];
result[0][0]=UNIT_SIZE/2+3;
result[0][1]=UNIT_SIZE;
result[1][0]=UNIT_SIZE/2+10;
result[1][1]=UNIT_SIZE/2+10;
result[2][0]=UNIT_SIZE;
result[2][1]=UNIT_SIZE/2+3;
break;
case 5:
result=new float[3][2];
result[0][0]=0;
result[0][1]=UNIT_SIZE/2+3;
result[1][0]=UNIT_SIZE/2-10;
result[1][1]=UNIT_SIZE/2+10;
result[2][0]=UNIT_SIZE/2-3;
result[2][1]=UNIT_SIZE;
break;
case 6:
result=new float[3][2];
result[0][0]=UNIT_SIZE/2-3;
result[0][1]=0;
result[1][0]=UNIT_SIZE/2+10;
result[1][1]=UNIT_SIZE/2-10;
result[2][0]=UNIT_SIZE;
result[2][1]=UNIT_SIZE/2+3;
break;
case 7:
result=new float[3][2];
result[0][0]=0;
result[0][1]=UNIT_SIZE/2+3;
result[1][0]=UNIT_SIZE/2-10;
result[1][1]=UNIT_SIZE/2-10;
result[2][0]=UNIT_SIZE/2+3;
result[2][1]=0;
break;
case 9:
result=new float[2][2];
result[0][0]=UNIT_SIZE;
result[0][1]=UNIT_SIZE/2-3;
result[1][0]=0;
result[1][1]=UNIT_SIZE/2-3;
break;
case 10:
result=new float[2][2];
result[0][0]=UNIT_SIZE/2-3;
result[0][1]=0;
result[1][0]=UNIT_SIZE/2-3;
result[1][1]=UNIT_SIZE;
break;
case 11:
result=new float[4][2];
result[0][0]=UNIT_SIZE;
result[0][1]=UNIT_SIZE/2-3;
result[1][0]=(UNIT_SIZE/3)*2;
result[1][1]=UNIT_SIZE/2+13;
result[2][0]=UNIT_SIZE/3;
result[2][1]=UNIT_SIZE/2+13;
result[3][0]=0;
result[3][1]=UNIT_SIZE/2-3;
break;
case 12:
result=new float[4][2];
result[0][0]=UNIT_SIZE/2-3;
result[0][1]=0;
result[1][0]=UNIT_SIZE/2+13;
result[1][1]=UNIT_SIZE/3;
result[2][0]=UNIT_SIZE/2+13;
result[2][1]=(UNIT_SIZE/3)*2;
result[3][0]=UNIT_SIZE/2-3;
result[3][1]=UNIT_SIZE;
break;
case 13:
result=new float[3][2];
result[0][0]=UNIT_SIZE;
result[0][1]=UNIT_SIZE/2-3;
result[1][0]=UNIT_SIZE/2+10;
result[1][1]=UNIT_SIZE/2+10;
result[2][0]=UNIT_SIZE/2-3;
result[2][1]=UNIT_SIZE;
break;
case 14:
result=new float[3][2];
result[0][0]=UNIT_SIZE/2+3;
result[0][1]=UNIT_SIZE;
result[1][0]=UNIT_SIZE/2-10;
result[1][1]=UNIT_SIZE/2+10;
result[2][0]=0;
result[2][1]=UNIT_SIZE/2-3;
break;
case 15:
result=new float[3][2];
result[0][0]=UNIT_SIZE;
result[0][1]=UNIT_SIZE/2-3;
result[1][0]=UNIT_SIZE/2+10;
result[1][1]=UNIT_SIZE/2-10;
result[2][0]=UNIT_SIZE/2+3;
result[2][1]=0;
break;
case 16:
result=new float[3][2];
result[0][0]=UNIT_SIZE/2-3;
result[0][1]=0;
result[1][0]=UNIT_SIZE/2-10;
result[1][1]=UNIT_SIZE/2-10;
result[2][0]=0;
result[2][1]=UNIT_SIZE/2-3;
break;
}
for(int i=0;i<result.length;i++)
{
result[i][0]=result[i][0]+startX;
result[i][1]=result[i][1]+startZ;
}
return result;
}
}

View File

@@ -0,0 +1,364 @@
package com.bn.clp;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.List;
import android.opengl.GLES20;
import com.bn.core.MatrixState;
//广告
public class Poster extends BNDrawer
{
//开始结束条幅的条幅
TextureRect tr;
//开始结束条幅的支柱
Cylinder cylinder;
//切分的角度
final float ANGLE_SPAN=90;
//单位长度
final float UNIT_SIZE=1.0f;
final float R=UNIT_SIZE/2;
float cHeight=UNIT_SIZE*8;
float width=UNIT_SIZE*6;
float height=UNIT_SIZE*2;
int texIdA=1;
int texIdB=2;
int texIdC=3;
ChangeThread ct;
public Poster(int programId)
{
cylinder=new Cylinder(programId,R,ANGLE_SPAN,cHeight);
tr=new TextureRect(programId,width,height);
ct=new ChangeThread();
ct.start();
}
//总的绘制方法drawSelf
@Override
public void drawSelf(int[] texId,int dyFlag)
{
//左侧支柱
MatrixState.pushMatrix();
MatrixState.translate(0, cHeight, 0);
cylinder.drawSelf(texId[0]);
MatrixState.popMatrix();
//绘制前侧广告牌子
MatrixState.pushMatrix();
MatrixState.translate(0, cHeight*2, 0.577f*width);
tr.drawSelf(texId[texIdA]);
MatrixState.popMatrix();
//绘制左侧广告牌子
MatrixState.pushMatrix();
MatrixState.translate(-0.5f*width, cHeight*2, -0.289f*width);
MatrixState.rotate(60, 0, 1, 0);
tr.drawSelf(texId[texIdB]);
MatrixState.popMatrix();
//绘制右侧广告牌子
MatrixState.pushMatrix();
MatrixState.translate(0.5f*width, cHeight*2, -0.289f*width);
MatrixState.rotate(-60, 0, 1, 0);
tr.drawSelf(texId[texIdC]);
MatrixState.popMatrix();
}
//内部类——圆柱
private class Cylinder
{
//自定义Shader程序的引用
int mProgram;
//总变换矩阵的引用id
int muMVPMatrixHandle;
//顶点属性的引用id
int maPositionHandle;
//顶点纹理坐标的引用id
int maTexCoorHandle;
//顶点坐标数据缓冲
FloatBuffer mVertexBuffer;
//顶点纹理坐标数据缓冲
FloatBuffer mTexCoorBuffer;
int vCount=0;//顶点数量
//R为圆柱底部的半径r为圆柱上部的半径angle_span表示的是切分的角度
public Cylinder(int programId,float R,float angle_span,float height)
{
initVertexData(R,angle_span,height);
initShader(programId);
}
//初始化坐标数据的initVertexData方法
public void initVertexData(float R,float angle_span,float height)
{
List<Float> tempList=new ArrayList<Float>();
for(float vAngle=0;vAngle<360;vAngle=vAngle+angle_span)
{
float x0=(float) (R*Math.cos(Math.toRadians(vAngle)));
float y0=height;
float z0=(float) (-R*Math.sin(Math.toRadians(vAngle)));
float x1=(float) (R*Math.cos(Math.toRadians(vAngle)));
float y1=-height;
float z1=(float) (-R*Math.sin(Math.toRadians(vAngle)));
float x2=(float) (R*Math.cos(Math.toRadians(vAngle+angle_span)));
float y2=-height;
float z2=(float) (-R*Math.sin(Math.toRadians(vAngle+angle_span)));
float x3=(float) (R*Math.cos(Math.toRadians(vAngle+angle_span)));
float y3=height;
float z3=(float) (-R*Math.sin(Math.toRadians(vAngle+angle_span)));
tempList.add(x0); tempList.add(y0); tempList.add(z0);
tempList.add(x1); tempList.add(y1); tempList.add(z1);
tempList.add(x3); tempList.add(y3); tempList.add(z3);
tempList.add(x3); tempList.add(y3); tempList.add(z3);
tempList.add(x1); tempList.add(y1); tempList.add(z1);
tempList.add(x2); tempList.add(y2); tempList.add(z2);
}
vCount=tempList.size()/3;//顶点数量
float[] vertex=new float[tempList.size()];
for(int i=0;i<tempList.size();i++)
{
vertex[i]=tempList.get(i);
}
ByteBuffer vbb=ByteBuffer.allocateDirect(vertex.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer=vbb.asFloatBuffer();
mVertexBuffer.put(vertex);
mVertexBuffer.position(0);
float[] texcoor=generateTexCoor((int)(360/angle_span),1,1,1);
ByteBuffer tbb=ByteBuffer.allocateDirect(texcoor.length*4);
tbb.order(ByteOrder.nativeOrder());
mTexCoorBuffer=tbb.asFloatBuffer();
mTexCoorBuffer.put(texcoor);
mTexCoorBuffer.position(0);
}
//初始化着色器程序的方法
public void initShader(int programId)
{
mProgram=programId;
//获得顶点坐标数据的引用
maPositionHandle=GLES20.glGetAttribLocation(mProgram, "aPosition");
//顶点纹理坐标的引用id
maTexCoorHandle=GLES20.glGetAttribLocation(mProgram, "aTexCoor");
muMVPMatrixHandle=GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
}
//自定义的绘制方法
public void drawSelf(int texId)
{
//使用某套指定的Shader程序
GLES20.glUseProgram(mProgram);
//将最终变换矩阵传入到Shader程序中
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//为画笔指定坐标数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入纹理坐标数据
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false,
2*4,
mTexCoorBuffer
);
//允许顶点位置数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
//绘制纹理矩形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
//自动切分纹理产生纹理数组的方法
public float[] generateTexCoor(int bw,int bh,float width,float height)
{
float[] result=new float[bw*bh*6*2];
float sizew=width/bw;//列数
float sizeh=height/bh;//行数
int c=0;
for(int i=0;i<bh;i++)
{
for(int j=0;j<bw;j++)
{
//每行列一个矩形由两个三角形构成共六个点12个纹理坐标
float s=j*sizew;
float t=i*sizeh;
result[c++]=s;
result[c++]=t;
result[c++]=s;
result[c++]=t+sizeh;
result[c++]=s+sizew;
result[c++]=t;
result[c++]=s+sizew;
result[c++]=t;
result[c++]=s;
result[c++]=t+sizeh;
result[c++]=s+sizew;
result[c++]=t+sizeh;
}
}
return result;
}
}
//下方的底座
private class TextureRect
{
//自定义Shader程序的引用
int mProgram;
//总变换矩阵的引用id
int muMVPMatrixHandle;
//顶点属性的引用id
int maPositionHandle;
//顶点纹理坐标的引用id
int maTexCoorHandle;
//顶点坐标数据缓冲
FloatBuffer mVertexBuffer;
//顶点纹理坐标数据缓冲
FloatBuffer mTexCoorBuffer;
int vCount=0;//顶点数量
//R为圆柱底部的半径r为圆柱上部的半径
public TextureRect(int programId,float width,float height)
{
initVertexData(width,height);
initShader(programId);
}
//初始化坐标数据的方法
public void initVertexData(float width,float height)
{
float[] vertex=new float[]
{
-width,height,0,
-width,-height,0,
width,-height,0,
-width,height,0,
width,-height,0,
width,height,0,
-width,height,0,
width,-height,0,
-width,-height,0,
-width,height,0,
width,height,0,
width,-height,0,
};
vCount=12;
ByteBuffer vbb=ByteBuffer.allocateDirect(vertex.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer=vbb.asFloatBuffer();
mVertexBuffer.put(vertex);
mVertexBuffer.position(0);
float[] texcoor=new float[]
{
0,0, 0,1, 1,1,
0,0, 1,1, 1,0,
0,0, 1,1, 0,1,
0,0, 1,0, 1,1
};
ByteBuffer tbb=ByteBuffer.allocateDirect(texcoor.length*4);
tbb.order(ByteOrder.nativeOrder());
mTexCoorBuffer=tbb.asFloatBuffer();
mTexCoorBuffer.put(texcoor);
mTexCoorBuffer.position(0);
}
//初始化Shader程序的方法
public void initShader(int programId)
{
mProgram=programId;
//获得顶点坐标数据的引用
maPositionHandle=GLES20.glGetAttribLocation(mProgram, "aPosition");
//顶点纹理坐标的引用id
maTexCoorHandle=GLES20.glGetAttribLocation(mProgram, "aTexCoor");
muMVPMatrixHandle=GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
}
//自定义的绘制方法
public void drawSelf(int texId)
{
//使用某套指定的Shader程序
GLES20.glUseProgram(mProgram);
//将最终变换矩阵传入到Shader程序中
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//为画笔指定坐标数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//为画笔指定纹理坐标数据
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false,
2*4,
mTexCoorBuffer
);
//允许顶点位置数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
//绘制纹理矩形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
}
//广告换图线程
public class ChangeThread extends Thread
{
public void run()
{
while(Constant.threadFlag)
{
int temp=texIdA;
texIdA=texIdB;
texIdB=texIdC;
texIdC=temp;
try
{
Thread.sleep(500);
}catch(Exception e)
{
e.printStackTrace();
}
}
}
}
}

View File

@@ -0,0 +1,157 @@
package com.bn.clp;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import android.opengl.GLES20;
import com.bn.core.MatrixState;
public class Process
{
//自定义渲染管线的id
int mProgram;
//总变化矩阵引用的id
int muMVPMatrixHandle;
//顶点位置属性引用id
int maPositionHandle;
//顶点纹理坐标属性引用id
int maTexCoorHandle;
int maPrograss;//j进度条位置坐标
//顶点数据缓冲和纹理坐标数据缓冲
FloatBuffer mVertexBuffer;
FloatBuffer mTexCoorBuffer;
//顶点数量
int vCount=0;
//循环标志位
boolean flag=true;
float currPrograss;//当前进度
float width;
float percent;
//percent表示进度值
public Process(int programId,float width,float height,float[] texCoor,float percent)
{
this.width=width;
this.percent=percent;
//初始化顶点数据
initVertexData(width,height,texCoor);
initShader(programId);
new Thread()
{
@Override
public void run()
{
while(flag)
{
if(currPrograss>=Process.this.width)
{
flag=false;
break;
}
currPrograss=percentToWidth(Process.this.percent,Process.this.width);
try
{
Thread.sleep(100);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
}.start();
}
//初始化顶点数据的方法
public void initVertexData(float width,float height,float[] texCoor)
{
float[] vertex=new float[]
{
-width,height,0,
-width,-height,0,
width,-height,0,
-width,height,0,
width,-height,0,
width,height,0,
};
vCount=vertex.length/3;
ByteBuffer vbb=ByteBuffer.allocateDirect(vertex.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer=vbb.asFloatBuffer();
mVertexBuffer.put(vertex);
mVertexBuffer.position(0);
//纹理坐标数据缓冲
ByteBuffer tbb=ByteBuffer.allocateDirect(texCoor.length*4);
tbb.order(ByteOrder.nativeOrder());
mTexCoorBuffer=tbb.asFloatBuffer();
mTexCoorBuffer.put(texCoor);
mTexCoorBuffer.position(0);
}
//初始化着色器的方法
public void initShader(int programId)
{
//基于顶点着色器与片元着色器创建程序
mProgram =programId;
//获取程序中顶点位置属性引用id
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
//获取程序中顶点纹理坐标属性引用id
maTexCoorHandle= GLES20.glGetAttribLocation(mProgram, "aTexCoor");
//获取程序中总变换矩阵引用id
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
//进度的引用id
maPrograss= GLES20.glGetUniformLocation(mProgram, "aPrograss");
}
//自定义的绘制方法drawSelf
public void drawSelf(int texId)
{
//制定使用某套shader程序
GLES20.glUseProgram(mProgram);
//将最终变换矩阵传入shader程序
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//将当前的进度传入到Shader程序
GLES20.glUniform1f(maPrograss, currPrograss);
//传入顶点位置数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入纹理坐标数据
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false,
2*4,
mTexCoorBuffer
);
//允许顶点位置数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
//绘制纹理矩形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
//将百分比对应成与width相关的数据percent为百分比width为相应的屏幕的半宽度
public float percentToWidth(float percent,float width)
{
return percent*width*2-width;
}
}

View File

@@ -0,0 +1,558 @@
package com.bn.clp;
import static com.bn.clp.Constant.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import com.bn.core.MatrixState;
import android.opengl.GLES20;
//代表赛艇赛道中竖直的赛道类
public class RaceTrack
{
//自定义渲染管线着色器程序的id
private int mProgram;
//总变化矩阵引用的id
private int muMVPMatrixHandle;
//位置、旋转变换矩阵
int muMMatrixHandle;
//顶点位置属性的id
private int maPositionHandle;
//顶点纹理属性引用的id
private int maTexCoorHandle;
//新添加的==========================================================================
//草地的id
int sTextureGrassHandle;
//石头的id
int sTextureRockHandle;
//起始x值
int b_YZ_StartYHandle;
//长度
int b_YZ_YSpanHandle;
//是否为隧道山的标志位的引用id
int sdflagHandle;
//此处flag值为0表示隧道山值为1表示为普通山
private int flag=1;
//新添加的=============================================================================
//顶点坐标缓冲
private FloatBuffer mVertexBuffer;
//片元纹理缓冲
private FloatBuffer mTexCoorBuffer;
//顶点的数量
private int vCount=0;
//是否为直道标记
boolean isZD;
/*
* 本类的有参构造器其中mv为MyGLSurfaceView类的引用
* yArray为相应灰度图顶点的y坐标rows为该灰度图的行数cols为该灰度图的列数
*/
public RaceTrack(int programId,float[][] yArray,int rows,int cols,boolean isZD)
{
this.isZD=isZD;
//初始化顶点数据
initVertexData(yArray,rows,cols,isZD);
//初始化Shader
initShader(programId);
}
//初始化顶点数据的initVertexData方法
public void initVertexData(float[][] yArray,int rows,int cols,boolean isZD)
{
if(isZD)
{
initVertexDataZD(yArray,rows,cols);
}
else
{
initVertexDataFZD(yArray,rows,cols);
}
}
//初始化普通直道顶点数据的方法
public void initVertexDataZD(float[][] yArray,int rows,int cols)
{
float width=UNIT_SIZE/cols;//分成格子的宽度
float height=UNIT_SIZE/rows;//分成格子的宽高度
vCount=rows*cols*2*3;//顶点的数量
float[] vertex=new float[vCount*3];
float[] texture=new float[vCount*2];
float tempWidth=2.0f/cols;//分成格子的纹理宽度
float tempHeight=2.0f/rows;//分成格子的纹理高度
int countv=0;
int countt=0;
int state=0;//0--一开始 1--高度为0 2--恢复
for(int j=0;j<cols;j++)
{
state=0;
for(int i=0;i<rows+1;i++)
{
if(j!=0&&i==0)
{
//本列右面点
vertex[countv++]=width*(j+1)-UNIT_SIZE/2;
vertex[countv++]=yArray[i][j+1];
vertex[countv++]=height*i-UNIT_SIZE/2;
//纹理的S、T坐标
texture[countt++]=tempWidth*(j+1)-width/2;
texture[countt++]=tempHeight*i-height/2;
//本列右面点
vertex[countv++]=width*(j+1)-UNIT_SIZE/2;
vertex[countv++]=yArray[i][j+1];
vertex[countv++]=height*i-UNIT_SIZE/2;
//纹理的S、T坐标
texture[countt++]=tempWidth*(j+1)-width/2;
texture[countt++]=tempHeight*i-height/2;
}
if(state==0)
{
//本列右面点
vertex[countv++]=width*(j+1)-UNIT_SIZE/2;
vertex[countv++]=yArray[i][j+1];
vertex[countv++]=height*i-UNIT_SIZE/2;
//纹理的S、T坐标
texture[countt++]=tempWidth*(j+1)-width/2;
texture[countt++]=tempHeight*i-height/2;
//本行左面点
vertex[countv++]=width*j-UNIT_SIZE/2;
vertex[countv++]=yArray[i][j];
vertex[countv++]=height*i-UNIT_SIZE/2;
//纹理的S、T坐标
texture[countt++]=tempWidth*j-width/2;
texture[countt++]=tempHeight*i-height/2;
if(yArray[i][j]==0&&yArray[i][j+1]==0&&yArray[i+1][j]==0&&yArray[i+1][j+1]==0)
{
state=1;
//本行左面点
vertex[countv++]=width*j-UNIT_SIZE/2;
vertex[countv++]=yArray[i][j];
vertex[countv++]=height*i-UNIT_SIZE/2;
//纹理的S、T坐标
texture[countt++]=tempWidth*j-width/2;
texture[countt++]=tempHeight*i-height/2;
//本行左面点
vertex[countv++]=width*j-UNIT_SIZE/2;
vertex[countv++]=yArray[i][j];
vertex[countv++]=height*i-UNIT_SIZE/2;
//纹理的S、T坐标
texture[countt++]=tempWidth*j-width/2;
texture[countt++]=tempHeight*i-height/2;
}
}
else if(state==1)
{
if(!(yArray[i+1][j]==0&&yArray[i+1][j+1]==0))
{
//本列右面点
vertex[countv++]=width*(j+1)-UNIT_SIZE/2;
vertex[countv++]=yArray[i][j+1];
vertex[countv++]=height*i-UNIT_SIZE/2;
//纹理的S、T坐标
texture[countt++]=tempWidth*(j+1)-width/2;
texture[countt++]=tempHeight*i-height/2;
//本列右面点
vertex[countv++]=width*(j+1)-UNIT_SIZE/2;
vertex[countv++]=yArray[i][j+1];
vertex[countv++]=height*i-UNIT_SIZE/2;
//纹理的S、T坐标
texture[countt++]=tempWidth*(j+1)-width/2;
texture[countt++]=tempHeight*i-height/2;
//本列右面点
vertex[countv++]=width*(j+1)-UNIT_SIZE/2;
vertex[countv++]=yArray[i][j+1];
vertex[countv++]=height*i-UNIT_SIZE/2;
//纹理的S、T坐标
texture[countt++]=tempWidth*(j+1)-width/2;
texture[countt++]=tempHeight*i-height/2;
//本行左面点
vertex[countv++]=width*j-UNIT_SIZE/2;
vertex[countv++]=yArray[i][j];
vertex[countv++]=height*i-UNIT_SIZE/2;
//纹理的S、T坐标
texture[countt++]=tempWidth*j-width/2;
texture[countt++]=tempHeight*i-height/2;
state=2;
}
}
else if(state==2)
{
//本列右面点
vertex[countv++]=width*(j+1)-UNIT_SIZE/2;
vertex[countv++]=yArray[i][j+1];
vertex[countv++]=height*i-UNIT_SIZE/2;
//纹理的S、T坐标
texture[countt++]=tempWidth*(j+1)-width/2;
texture[countt++]=tempHeight*i-height/2;
//本行左面点
vertex[countv++]=width*j-UNIT_SIZE/2;
vertex[countv++]=yArray[i][j];
vertex[countv++]=height*i-UNIT_SIZE/2;
//纹理的S、T坐标
texture[countt++]=tempWidth*j-width/2;
texture[countt++]=tempHeight*i-height/2;
}
if(i==rows&&j!=cols-1)
{
//本行左面点
vertex[countv++]=width*j-UNIT_SIZE/2;
vertex[countv++]=yArray[i][j];
vertex[countv++]=height*i-UNIT_SIZE/2;
//纹理的S、T坐标
texture[countt++]=tempWidth*j-width/2;
texture[countt++]=tempHeight*i-height/2;
//本行左面点
vertex[countv++]=width*j-UNIT_SIZE/2;
vertex[countv++]=yArray[i][j];
vertex[countv++]=height*i-UNIT_SIZE/2;
//纹理的S、T坐标
texture[countt++]=tempWidth*j-width/2;
texture[countt++]=tempHeight*i-height/2;
}
}
}
vCount=countt/2;
//产生包括倒影的多加两个顶点的数组
float[] vertexL=new float[vCount*3];
for(int i=0;i<vertexL.length;i++)
{
vertexL[i]=vertex[i];
}
vertex=vertexL;
vertexL=new float[(vCount*2+2)*3];
int cTemp=0;
for(int i=0;i<vertex.length;i++)
{
vertexL[cTemp++]=vertex[i];
}
vertexL[cTemp++]=vertex[vertex.length-3];
vertexL[cTemp++]=vertex[vertex.length-2];
vertexL[cTemp++]=vertex[vertex.length-1];
vertexL[cTemp++]=vertex[0];
vertexL[cTemp++]=-vertex[1];
vertexL[cTemp++]=vertex[2];
for(int i=0;i<vertex.length;i++)
{
if(i%3==1)
{
vertexL[cTemp++]=-vertex[i];
}
else
{
vertexL[cTemp++]=vertex[i];
}
}
float[] textureL=new float[vCount*2];
for(int i=0;i<textureL.length;i++)
{
textureL[i]=texture[i];
}
texture=textureL;
textureL=new float[(vCount*2+2)*2];
cTemp=0;
for(int i=0;i<texture.length;i++)
{
textureL[cTemp++]=texture[i];
}
textureL[cTemp++]=texture[texture.length-2];
textureL[cTemp++]=texture[texture.length-1];
textureL[cTemp++]=texture[0];
textureL[cTemp++]=texture[1];
for(int i=0;i<texture.length;i++)
{
textureL[cTemp++]=texture[i];
}
vCount=vCount*2+2;
//创建顶点缓冲区坐标
ByteBuffer vbb=ByteBuffer.allocateDirect(vertexL.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer=vbb.asFloatBuffer();
mVertexBuffer.put(vertexL);
mVertexBuffer.position(0);
//切分纹理图片的方法
ByteBuffer cbb=ByteBuffer.allocateDirect(textureL.length*4);
cbb.order(ByteOrder.nativeOrder());
mTexCoorBuffer=cbb.asFloatBuffer();
mTexCoorBuffer.put(textureL);
mTexCoorBuffer.position(0);
}
//初始化非普通直道顶点数据的方法
public void initVertexDataFZD(float[][] yArray,int rows,int cols)
{
float width=UNIT_SIZE/cols;//分成格子的宽度
float height=UNIT_SIZE/rows;//分成格子的宽高度
vCount=rows*cols*2*3;//顶点的数量
float[] vertex=new float[vCount*3];
float[] texture=new float[vCount*2];
float tempWidth=2.0f/cols;//分成格子的宽度
float tempHeight=2.0f/rows;//分成格子的宽高度
int countv=0;
int countt=0;
//循环遍历顶点,行->列
for(int i=0;i<rows;i++)
{
for(int j=0;j<cols;j++)
{
if(yArray[i][j]!=0||yArray[i+1][j]!=0||yArray[i][j+1]!=0)
{
//逆时针卷绕第一个三角形的左上角的顶点
vertex[countv++]=width*j-UNIT_SIZE/2;
vertex[countv++]=yArray[i][j];
vertex[countv++]=height*i-UNIT_SIZE/2;
//逆时针卷绕第一个三角形的左下角的顶点
vertex[countv++]=width*j-UNIT_SIZE/2;
vertex[countv++]=yArray[i+1][j];
vertex[countv++]=height*(i+1)-UNIT_SIZE/2;
//逆时针卷绕第一个三角形的右上角的顶点
vertex[countv++]=width*(j+1)-UNIT_SIZE/2;
vertex[countv++]=yArray[i][j+1];
vertex[countv++]=height*i-UNIT_SIZE/2;
//纹理图形中第一个三角形左上角的S、T坐标
texture[countt++]=tempWidth*i-width/2;
texture[countt++]=tempHeight*j-height/2;
//纹理图形中第一个三角形左下角的S、T坐标
texture[countt++]=tempWidth*(i+1)-width/2;
texture[countt++]=tempHeight*j-height/2;
//纹理图形中第一个三角形右上角的S、T坐标
texture[countt++]=tempWidth*i-width/2;
texture[countt++]=tempHeight*(j+1)-height/2;
}
if(yArray[i][j+1]!=0||yArray[i+1][j]!=0||yArray[i+1][j+1]!=0)
{
//逆时针卷绕第二个三角形的右上角的顶点
vertex[countv++]=width*(j+1)-UNIT_SIZE/2;
vertex[countv++]=yArray[i][j+1];
vertex[countv++]=height*i-UNIT_SIZE/2;
//逆时针卷绕第二个三角形的左下角的顶点
vertex[countv++]=width*j-UNIT_SIZE/2;
vertex[countv++]=yArray[i+1][j];
vertex[countv++]=height*(i+1)-UNIT_SIZE/2;
//逆时针卷绕第二个三角形的右下角的顶点
vertex[countv++]=width*(j+1)-UNIT_SIZE/2;
vertex[countv++]=yArray[i+1][j+1];
vertex[countv++]=height*(i+1)-UNIT_SIZE/2;
//纹理图形中第二个三角形右上角的S、T坐标
texture[countt++]=tempWidth*i-width/2;
texture[countt++]=tempHeight*(j+1)-height/2;
//纹理图形中第二个三角形左下角的S、T坐标
texture[countt++]=tempWidth*(i+1)-width/2;
texture[countt++]=tempHeight*j-height/2;
//纹理图形中第二个三角形右上角的S、T坐标
texture[countt++]=tempWidth*(i+1)-width/2;
texture[countt++]=tempHeight*(j+1)-height/2;
}
}
}
vCount=countt/2;
//产生包括倒影的多加两个顶点的数组
float[] vertexL=new float[vCount*3];
for(int i=0;i<vertexL.length;i++)
{
vertexL[i]=vertex[i];
}
vertex=vertexL;
vertexL=new float[(vCount*2)*3];
int cTemp=0;
for(int i=0;i<vertex.length;i++)
{
vertexL[cTemp++]=vertex[i];
}
for(int i=0;i<vertex.length;i++)
{
if(i%3==1)
{
vertexL[cTemp++]=-vertex[i];
}
else
{
vertexL[cTemp++]=vertex[i];
}
}
float[] textureL=new float[vCount*2];
for(int i=0;i<textureL.length;i++)
{
textureL[i]=texture[i];
}
texture=textureL;
textureL=new float[(vCount*2)*2];
cTemp=0;
for(int i=0;i<texture.length;i++)
{
textureL[cTemp++]=texture[i];
}
for(int i=0;i<texture.length;i++)
{
textureL[cTemp++]=texture[i];
}
vCount=vCount*2;
//创建顶点缓冲区坐标
ByteBuffer vbb=ByteBuffer.allocateDirect(vertexL.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer=vbb.asFloatBuffer();
mVertexBuffer.put(vertexL);
mVertexBuffer.position(0);
//切分纹理图片的方法
ByteBuffer cbb=ByteBuffer.allocateDirect(textureL.length*4);
cbb.order(ByteOrder.nativeOrder());
mTexCoorBuffer=cbb.asFloatBuffer();
mTexCoorBuffer.put(textureL);
mTexCoorBuffer.position(0);
}
//初始化着色器的方法
public void initShader(int programId)
{
//基于顶点着色器与片元着色器创建程序
mProgram=programId;
//获取程序中顶点位置属性引用id
maPositionHandle=GLES20.glGetAttribLocation(mProgram, "aPosition");
//获取程序中片元属性引用id
maTexCoorHandle=GLES20.glGetAttribLocation(mProgram, "aTexCoor");
//获取程序中总变换矩阵引用id
muMVPMatrixHandle=GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
//获取位置、旋转变换矩阵引用id
muMMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMMatrix");
//新添加的=========================================================================
//纹理
//草地
sTextureGrassHandle=GLES20.glGetUniformLocation(mProgram, "sTextureGrass");
//石头
sTextureRockHandle=GLES20.glGetUniformLocation(mProgram, "sTextureRock");
//x位置
b_YZ_StartYHandle=GLES20.glGetUniformLocation(mProgram, "b_YZ_StartY");
//x最大
b_YZ_YSpanHandle=GLES20.glGetUniformLocation(mProgram, "b_YZ_YSpan");
sdflagHandle=GLES20.glGetUniformLocation(mProgram, "sdflag");
//新添加的=========================================================================
}
//绘制图形的方法
public void drawSelf(int rock_textId,int textureId)
{
realDrawTask(textureId,rock_textId);
}
//真正的绘制任务
public void realDrawTask(int textureId,int rock_textId)
{
//制定使用某套shader程序
GLES20.glUseProgram(mProgram);
//将最终变换矩阵传入Shader程序
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//将位置、旋转变换矩阵传入shader程序
GLES20.glUniformMatrix4fv(muMMatrixHandle, 1, false, MatrixState.getMMatrix(), 0);
//新添加的============================================================
//将是否为普通山的标志位传到Shader程序中
GLES20.glUniform1i(sdflagHandle, flag);
//新添加的============================================================
//传入顶点位置数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false, //这个参数的具体意义???????
3*4, //3是顶点的坐标数量但是4到底是什么
mVertexBuffer //顶点坐标缓冲数据
);
//传入顶点纹理坐标数据
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false, //这个参数的具体意义???????
2*4, //3是顶点的坐标数量但是4到底是什么
mTexCoorBuffer //顶点坐标缓冲数据
);
//允许顶点位置、纹理坐标数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);//顶点坐标
GLES20.glEnableVertexAttribArray(maTexCoorHandle);//纹理坐标
//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
//新添加的===============================================================
GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, rock_textId);
GLES20.glUniform1i(sTextureGrassHandle, 0);//使用0号纹理
GLES20.glUniform1i(sTextureRockHandle, 1); //使用1号纹理
//传送相应的x参数
GLES20.glUniform1f(b_YZ_StartYHandle, 0);
GLES20.glUniform1f(b_YZ_YSpanHandle, LAND_MAX_HIGHEST);
//新添加的===============================================================
if(isZD)
{
//绘制纹理矩形
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, vCount);
}
else
{
//绘制纹理矩形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
}
}

View File

@@ -0,0 +1,62 @@
package com.bn.clp;
import static com.bn.clp.Constant.CURR_BOAT_V;
import static com.bn.clp.Constant.head_Angle;
import static com.bn.clp.Constant.head_Angle_A;
import static com.bn.clp.Constant.head_Angle_Max;
//¾§ÌåÐýתÏß³Ì
public class RotateThread extends Thread
{
public RotateThread()
{
this.setName("RotateThread");
}
public void run()
{
while(Constant.threadFlag)
{
SpeedForControl.angleY=(SpeedForControl.angleY+6)%360;
if(CURR_BOAT_V==0)
{
if(head_Angle<=head_Angle_Max&&KeyThread.upFlag)
{
head_Angle=head_Angle+head_Angle_A;
if(head_Angle==head_Angle_Max)
{
KeyThread.upFlag=false;
}
}
else if(head_Angle>=-head_Angle_Max&&!KeyThread.upFlag)
{
head_Angle=head_Angle-head_Angle_A;
if(head_Angle==-head_Angle_Max)
{
KeyThread.upFlag=true;
}
}
}
else
{
if(head_Angle<4)
{
head_Angle=head_Angle+head_Angle_A;
}
else
{
head_Angle=head_Angle-head_Angle_A;
}
}
try
{
Thread.sleep(60);
}catch(Exception e)
{
e.printStackTrace();
}
}
}
}

View File

@@ -0,0 +1,85 @@
package com.bn.clp;
import com.bn.core.ShaderUtil;
import android.content.res.Resources;
public class ShaderManager
{
final static int shaderCount=7;
final static String[][] shaderName=
{
{"vertex_color_light.sh","frag_color_light.sh"},
{"vertex_b_yz.sh","frag_b_yz.sh"},
{"vertex_tex_g.sh","frag_tex_g.sh"},
{"vertex_tex_xz.sh","frag_tex_xz.sh"},
{"vertex_mountion.sh","frag_mountion.sh"},
{"vertex_prograss.sh","frag_prograss.sh"},
{"vertex_tex_xz.sh","frag_weilang.sh"}
};
static String[]mVertexShader=new String[shaderCount];
static String[]mFragmentShader=new String[shaderCount];
static int[] program=new int[shaderCount];
public static void loadCodeFromFile(Resources r)
{
for(int i=0;i<shaderCount;i++)
{
//加载顶点着色器的脚本内容
mVertexShader[i]=ShaderUtil.loadFromAssetsFile(shaderName[i][0],r);
//加载片元着色器的脚本内容
mFragmentShader[i]=ShaderUtil.loadFromAssetsFile(shaderName[i][1], r);
}
}
//这里主要是编译shader
public static void compileShader()
{
program[0]=ShaderUtil.createProgram(mVertexShader[0], mFragmentShader[0]);
program[1]=ShaderUtil.createProgram(mVertexShader[1], mFragmentShader[1]);
program[3]=ShaderUtil.createProgram(mVertexShader[3], mFragmentShader[3]);
program[4]=ShaderUtil.createProgram(mVertexShader[4], mFragmentShader[4]);
program[6]=ShaderUtil.createProgram(mVertexShader[6], mFragmentShader[6]);
}
public static void compileShaderHY()
{
program[2]=ShaderUtil.createProgram(mVertexShader[2], mFragmentShader[2]);
program[5]=ShaderUtil.createProgram(mVertexShader[5], mFragmentShader[5]);
}
//这里返回的是设置光照的Shader程序
public static int getLightShaderProgram()
{
return program[0];
}
//这里返回的是半崖子的Shader程序
public static int getBYZTextureShaderProgram()
{
return program[1];
}
//这里返回的是只有纹理的Shader程序
public static int getTextureShaderProgram()
{
return program[2];
}
//这里返回的是绘制水面时用到的Shader程序
public static int getWaterShaderProgram()
{
return program[3];
}
//这里返回绘制山时用到的Shader程序
public static int getMountionShaderProgram()
{
return program[4];
}
//这里返回的是进度条的Shader程序
public static int getPrograssShaderProgram()
{
return program[5];
}
//返回尾浪的shader程序
public static int getWeiLangShaderProgram()
{
return program[6];
}
}

View File

@@ -0,0 +1,42 @@
package com.bn.clp;
import static com.bn.clp.MyGLSurfaceView.*;
//表示灌木组的控制类
public class ShrubForControl implements Comparable<ShrubForControl>
{
int rows;
int cols;
float xoffset;
float yoffset;
float zoffset;
int id;
int texIds;
public ShrubForControl(int rows,int cols,float xoffset,float yoffset,float zoffset,int id,int texIds)
{
this.rows=rows;
this.cols=cols;
this.xoffset=xoffset;
this.yoffset=yoffset;
this.zoffset=zoffset;
this.id=id;
this.texIds=texIds;
}
@Override
public int compareTo(ShrubForControl another)
{
//重写的比较两个灌木离摄像机距离的方法
float xs=xoffset-cxForSpecFrame;
float zs=zoffset-czForSpecFrame;
float xo=another.xoffset-cxForSpecFrame;
float zo=another.zoffset-czForSpecFrame;
float disA=(float)Math.sqrt(xs*xs+zs*zs);
float disB=(float)Math.sqrt(xo*xo+zo*zo);
return ((disA-disB)==0)?0:((disA-disB)>0)?-1:1;
}
}

View File

@@ -0,0 +1,119 @@
package com.bn.clp;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import com.bn.core.MatrixState;
import android.opengl.GLES20;
import static com.bn.clp.Constant.*;
//用于绘制单个灌木的纹理矩形
public class ShrubForDraw
{
int mProgram;//自定义渲染管线着色器程序id
int muMVPMatrixHandle;//总变换矩阵引用id
int maPositionHandle; //顶点位置属性引用id
int maTexCoorHandle; //顶点纹理坐标属性引用id
String mVertexShader;//顶点着色器
String mFragmentShader;//片元着色器
FloatBuffer mVertexBuffer;//顶点坐标数据缓冲
FloatBuffer mTexCoorBuffer;//顶点纹理坐标数据缓冲
int vCount=0;
public ShrubForDraw(int programId,float[] texCoor)
{
//初始化顶点数据的initVertexData方法
initVertexData(texCoor);
//初始化着色器的initShader方法
initShader(programId);
}
//初始化顶点数据的方法
public void initVertexData(float[] texCoor)
{
//顶点坐标数据的初始化================begin============================
vCount=6;
float vertices[]=new float[]
{
-GRASS_UNIT_SIZE,GRASS_UNIT_SIZE*5,0,
-GRASS_UNIT_SIZE,0,0,
GRASS_UNIT_SIZE,GRASS_UNIT_SIZE*5,0,
GRASS_UNIT_SIZE,GRASS_UNIT_SIZE*5,0,
-GRASS_UNIT_SIZE,0,0,
GRASS_UNIT_SIZE,0,0,
};
//创建顶点坐标数据缓冲
//vertices.length*4是因为一个整数四个字节
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());//设置字节顺序
mVertexBuffer = vbb.asFloatBuffer();//转换为Float型缓冲
mVertexBuffer.put(vertices);//向缓冲区中放入顶点坐标数据
mVertexBuffer.position(0);//设置缓冲区起始位置
//顶点纹理坐标数据的初始化================begin============================
//创建顶点纹理坐标数据缓冲
ByteBuffer cbb = ByteBuffer.allocateDirect(texCoor.length*4);
cbb.order(ByteOrder.nativeOrder());//设置字节顺序
mTexCoorBuffer = cbb.asFloatBuffer();//转换为Float型缓冲
mTexCoorBuffer.put(texCoor);//向缓冲区中放入顶点着色数据
mTexCoorBuffer.position(0);//设置缓冲区起始位置
}
//初始化着色器的initShader方法
public void initShader(int programId)
{
//基于顶点着色器与片元着色器创建程序
mProgram =programId;
//获取程序中顶点位置属性引用id
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
//获取程序中顶点纹理坐标属性引用id
maTexCoorHandle= GLES20.glGetAttribLocation(mProgram, "aTexCoor");
//获取程序中总变换矩阵引用id
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
}
public void drawSelf(int texId)
{
//制定使用某套shader程序
GLES20.glUseProgram(mProgram);
//将最终变换矩阵传入shader程序
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//传入顶点位置数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入顶点纹理坐标数据
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false,
2*4,
mTexCoorBuffer
);
//允许顶点位置、纹理坐标数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
//绘制纹理矩形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
}

View File

@@ -0,0 +1,84 @@
package com.bn.clp;
import static com.bn.clp.Constant.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import com.bn.core.MatrixState;
//表示单个灌木的类
public class SingleShrub
{
//六瓣的列表
List<float []> all=new ArrayList<float []>();
//用于绘制各个瓣的纹理矩形
ShrubForDraw sfd;
//纹理数组,每个树的纹理坐标可能不同
float[] texList=
{
0,0, 0,1, 0.5f,0,
0.5f, 0,0,1, 0.5f,1
};
public SingleShrub(int programId)
{
//初始化用于绘制单个灌木的对象
sfd=new ShrubForDraw
(
programId,
texList
);
}
public void drawSelf(int texIds,int id,float x,float y,float z,int dyFlag)
{
//生成六瓣树的信息
float[][] tempData=
{
{x,z,0},
{x+GRASS_UNIT_SIZE/2, z+GRASS_UNIT_SIZE*0.866f, 60},
{x+GRASS_UNIT_SIZE*1.5f, z+GRASS_UNIT_SIZE*0.866f, 120},
{x+GRASS_UNIT_SIZE*2, z, 180},
{x+GRASS_UNIT_SIZE*1.5f, z-GRASS_UNIT_SIZE*0.866f, 240},
{x+GRASS_UNIT_SIZE/2, z-GRASS_UNIT_SIZE*0.866f, 300}
};
all=Arrays.asList(tempData);
//对六瓣进行排序
Collections.sort(all, new MyComparable());
if(dyFlag==0)//绘制实体
{
//循环列表进行树木的绘制
for(float []tt:all)
{
MatrixState.pushMatrix();
MatrixState.translate(tt[0], y, tt[1]);
MatrixState.rotate(tt[2], 0, 1, 0);
sfd.drawSelf(texIds);
MatrixState.popMatrix();
}
}
else if(dyFlag==1)//绘制倒影
{
//实际绘制时Y的零点============!!!!!!!!!!!????????????
float yTranslate=y;
//进行镜像绘制时的调整值
float yjx=(0-yTranslate)*2;
//循环列表进行树木的绘制
for(float []tt:all)
{
MatrixState.pushMatrix();
MatrixState.translate(tt[0], y, tt[1]);
MatrixState.rotate(tt[2], 0, 1, 0);
MatrixState.translate(0, yjx, 0);
MatrixState.scale(1, -1, 1);
sfd.drawSelf(texIds);
MatrixState.popMatrix();
}
}
}
}

View File

@@ -0,0 +1,245 @@
package com.bn.clp;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import android.opengl.GLES20;
import com.bn.core.MatrixState;
public class Sky
{
//自定义渲染着色器程序的引用
int mProgram;
//总变换矩阵的引用
int muMVPMatrixHandle;
//顶点属性的引用
int maPositionHandle;
//顶点纹理坐标属性的引用
int maTexCoorHandle;
//顶点数据缓冲以及顶点纹理坐标数据缓冲
FloatBuffer mVertexBuffer;
FloatBuffer mTexCoorBuffer;
//顶点数量
int vCount=0;
public Sky(int programId,float radius)
{
initVertexData(radius);
initShader(programId);
}
//初始化顶点数据的方法
public void initVertexData(float radius)
{
float ANGLE_SPAN=18;
float angleV=90;
//获取切分整图的纹理数组
float[] texCoorArray=
generateTexCoor
(
(int)(360/ANGLE_SPAN), //纹理图切分的列数
(int)(angleV/ANGLE_SPAN) //纹理图切分的行数
);
int tc=0;//纹理数组计数器
int ts=texCoorArray.length;//纹理数组长度
ArrayList<Float> alVertix=new ArrayList<Float>();//存放顶点坐标的ArrayList
ArrayList<Float> alTexture=new ArrayList<Float>();//存放纹理坐标的ArrayList
for(float vAngle=angleV;vAngle>0;vAngle=vAngle-ANGLE_SPAN)//垂直方向angleSpan度一份
{
for(float hAngle=360;hAngle>0;hAngle=hAngle-ANGLE_SPAN)//水平方向angleSpan度一份
{
//纵向横向各到一个角度后计算对应的此点在球面上的四边形顶点坐标
//并构建两个组成四边形的三角形
double xozLength=radius*Math.cos(Math.toRadians(vAngle));
float x1=(float)(xozLength*Math.cos(Math.toRadians(hAngle)));
float z1=(float)(xozLength*Math.sin(Math.toRadians(hAngle)));
float y1=(float)(radius*Math.sin(Math.toRadians(vAngle)));
xozLength=radius*Math.cos(Math.toRadians(vAngle-ANGLE_SPAN));
float x2=(float)(xozLength*Math.cos(Math.toRadians(hAngle)));
float z2=(float)(xozLength*Math.sin(Math.toRadians(hAngle)));
float y2=(float)(radius*Math.sin(Math.toRadians(vAngle-ANGLE_SPAN)));
xozLength=radius*Math.cos(Math.toRadians(vAngle-ANGLE_SPAN));
float x3=(float)(xozLength*Math.cos(Math.toRadians(hAngle-ANGLE_SPAN)));
float z3=(float)(xozLength*Math.sin(Math.toRadians(hAngle-ANGLE_SPAN)));
float y3=(float)(radius*Math.sin(Math.toRadians(vAngle-ANGLE_SPAN)));
xozLength=radius*Math.cos(Math.toRadians(vAngle));
float x4=(float)(xozLength*Math.cos(Math.toRadians(hAngle-ANGLE_SPAN)));
float z4=(float)(xozLength*Math.sin(Math.toRadians(hAngle-ANGLE_SPAN)));
float y4=(float)(radius*Math.sin(Math.toRadians(vAngle)));
//构建第一三角形
alVertix.add(x1);alVertix.add(y1);alVertix.add(z1);
alVertix.add(x4);alVertix.add(y4);alVertix.add(z4);
alVertix.add(x2);alVertix.add(y2);alVertix.add(z2);
//构建第二三角形
alVertix.add(x2);alVertix.add(y2);alVertix.add(z2);
alVertix.add(x4);alVertix.add(y4);alVertix.add(z4);
alVertix.add(x3);alVertix.add(y3);alVertix.add(z3);
//第一三角形3个顶点的6个纹理坐标
alTexture.add(texCoorArray[tc++%ts]);
alTexture.add(texCoorArray[tc++%ts]);
alTexture.add(texCoorArray[tc++%ts]);
alTexture.add(texCoorArray[tc++%ts]);
alTexture.add(texCoorArray[tc++%ts]);
alTexture.add(texCoorArray[tc++%ts]);
//第二三角形3个顶点的6个纹理坐标
alTexture.add(texCoorArray[tc++%ts]);
alTexture.add(texCoorArray[tc++%ts]);
alTexture.add(texCoorArray[tc++%ts]);
alTexture.add(texCoorArray[tc++%ts]);
alTexture.add(texCoorArray[tc++%ts]);
alTexture.add(texCoorArray[tc++%ts]);
}
}
vCount=alVertix.size()/3;//顶点的数量为坐标值数量的1/3因为一个顶点有3个坐标
//将alVertix中的坐标值转存到一个float数组中
float vertices[]=new float[vCount*3];
for(int i=0;i<alVertix.size();i++)
{
vertices[i]=alVertix.get(i);
}
//创建绘制顶点数据缓冲
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());//设置字节顺序
mVertexBuffer = vbb.asFloatBuffer();//转换为float型缓冲
mVertexBuffer.put(vertices);//向缓冲区中放入顶点坐标数据
mVertexBuffer.position(0);//设置缓冲区起始位置
//创建纹理坐标缓冲
float textureCoors[]=new float[alTexture.size()];//顶点纹理值数组
for(int i=0;i<alTexture.size();i++)
{
textureCoors[i]=alTexture.get(i);
}
ByteBuffer tbb = ByteBuffer.allocateDirect(textureCoors.length*4);
tbb.order(ByteOrder.nativeOrder());//设置字节顺序
mTexCoorBuffer = tbb.asFloatBuffer();//转换为int型缓冲
mTexCoorBuffer.put(textureCoors);//向缓冲区中放入顶点着色数据
mTexCoorBuffer.position(0);//设置缓冲区起始位置
}
//初始化着色器程序的方法
public void initShader(int programId)
{
mProgram=programId;
//获得顶点坐标数据的引用
maPositionHandle=GLES20.glGetAttribLocation(mProgram, "aPosition");
//顶点纹理坐标的引用id
maTexCoorHandle=GLES20.glGetAttribLocation(mProgram, "aTexCoor");
muMVPMatrixHandle=GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
}
//绘制方法
public void drawSelf(int texId,float x,float z,int dyFlag)
{
if(dyFlag==0)//绘制实体
{
MatrixState.pushMatrix();
MatrixState.translate(x, 0, z);
realDrawSelf(texId);
MatrixState.popMatrix();
}
else if(dyFlag==1)//绘制倒影
{
//实际绘制时Y的零点
final float yTranslate=0;
//进行镜像绘制时的调整值
float yjx=(0-yTranslate)*2;
//关闭背面剪裁
GLES20.glDisable(GLES20.GL_CULL_FACE);
MatrixState.pushMatrix();
MatrixState.translate(x, 0, z);
MatrixState.translate(0, yjx, 0);
MatrixState.scale(1, -1, 1);
realDrawSelf(texId);
MatrixState.popMatrix();
//打开背面剪裁
GLES20.glEnable(GLES20.GL_CULL_FACE);
}
}
//自定义的绘制方法
public void realDrawSelf(int texId)
{
//使用某套指定的Shader程序
GLES20.glUseProgram(mProgram);
//将最终变换矩阵传入到Shader程序中
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//传入顶点坐标数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入纹理坐标数据
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false,
2*4,
mTexCoorBuffer
);
//允许顶点位置数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
//绘制纹理矩形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
//自动切分纹理产生纹理数组的方法
public float[] generateTexCoor(int bw,int bh)
{
float[] result=new float[bw*bh*6*2];
float sizew=1.0f/bw;//列数
float sizeh=1.0f/bh;//行数
int c=0;
for(int i=0;i<bh;i++)
{
for(int j=0;j<bw;j++)
{
//每行列一个矩形由两个三角形构成共六个点12个纹理坐标
float s=j*sizew;
float t=i*sizeh;
result[c++]=s;
result[c++]=t;
result[c++]=s+sizew;
result[c++]=t;
result[c++]=s;
result[c++]=t+sizeh;
result[c++]=s;
result[c++]=t+sizeh;
result[c++]=s+sizew;
result[c++]=t;
result[c++]=s+sizew;
result[c++]=t+sizeh;
}
}
return result;
}
}

View File

@@ -0,0 +1,138 @@
package com.bn.clp;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import android.opengl.GLES20;
import com.bn.core.MatrixState;
//可吃物体
public class Speed extends SpeedForEat
{
Diamond dd;
final float UNIT_SIZE=1.0f;
final float width=UNIT_SIZE;
final float height=UNIT_SIZE*2;
public Speed(int programId)
{
dd=new Diamond(programId,width,height);
}
//总的绘制方法drawSelf
public void drawSelf(int texId)
{
dd.drawSelf(texId);
}
//内部类——菱形
private class Diamond
{
//自定义Shader程序的引用
int mProgram;
//总变换矩阵的引用id
int muMVPMatrixHandle;
//顶点属性的引用id
int maPositionHandle;
//顶点纹理坐标的引用id
int maTexCoorHandle;
//顶点坐标数据缓冲
FloatBuffer mVertexBuffer;
//顶点纹理坐标数据缓冲
FloatBuffer mTexCoorBuffer;
int vCount=0;//顶点数量
//R为圆柱底部的半径r为圆柱上部的半径angle_span表示的是切分的角度
public Diamond(int programId,float width,float height)
{
initVertexData(width,height);
initShader(programId);
}
//初始化坐标数据的initVertexData方法
public void initVertexData(float width,float height)
{
float[] vertex=new float[]
{
0,height,0, -width,0,-width, -width,0,width,
0,height,0, -width,0,width, width,0,width,
0,height,0, width,0,width, width,0,-width,
0,height,0, width,0,-width, -width,0,-width,
0,-height,0, -width,0,width, -width,0,-width,
0,-height,0, width,0,width, -width,0,width,
0,-height,0, width,0,-width, width,0,width,
0,-height,0, -width,0, -width, width,0,-width,
};
vCount=24;//顶点数量
ByteBuffer vbb=ByteBuffer.allocateDirect(vertex.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer=vbb.asFloatBuffer();
mVertexBuffer.put(vertex);
mVertexBuffer.position(0);
float[] texcoor=new float[]
{
0.5f,0, 0,1, 1,1,
0.5f,0, 0,1, 1,1,
0.5f,0, 0,1, 1,1,
0.5f,0, 0,1, 1,1,
0.5f,0, 0,1, 1,1,
0.5f,0, 0,1, 1,1,
0.5f,0, 0,1, 1,1,
0.5f,0, 0,1, 1,1,
};
ByteBuffer tbb=ByteBuffer.allocateDirect(texcoor.length*4);
tbb.order(ByteOrder.nativeOrder());
mTexCoorBuffer=tbb.asFloatBuffer();
mTexCoorBuffer.put(texcoor);
mTexCoorBuffer.position(0);
}
//初始化着色器程序的initShader方法
public void initShader(int programId)
{
mProgram=programId;
//获得顶点坐标数据的引用
maPositionHandle=GLES20.glGetAttribLocation(mProgram, "aPosition");
//顶点纹理坐标的引用id
maTexCoorHandle=GLES20.glGetAttribLocation(mProgram, "aTexCoor");
muMVPMatrixHandle=GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
}
//自定义的绘制方法
public void drawSelf(int texId)
{
//使用某套指定的Shader程序
GLES20.glUseProgram(mProgram);
//将最终变换矩阵传入到Shader程序中
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//传入顶点坐标数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入纹理坐标数据
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false,
2*4,
mTexCoorBuffer
);
//允许顶点位置数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
//绘制纹理矩形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
}
}

View File

@@ -0,0 +1,120 @@
package com.bn.clp;
import static com.bn.clp.Constant.*;
import static com.bn.clp.MyGLSurfaceView.sight_angle;
import com.bn.core.MatrixState;
import com.bn.st.d2.MyActivity;
//可吃物体的控制类
public class SpeedForControl
{
long pzTime;//碰撞时的时间
SpeedForEat speed;//物件的引用
int id;//物件id
float x;
float y;
float z;
static float angleY;
float rows;
float cols;
boolean isDrawFlag=true;//是否绘制的标志位
MyActivity ma;
public SpeedForControl(SpeedForEat speedForEat,int id,float x,float y,float z,float angleY,float rows,float cols,MyActivity ma)
{
this.speed=speedForEat;
this.id=id;
this.x=x;
this.y=y;
this.z=z;
this.rows=rows;
this.cols=cols;
this.ma=ma;
}
//绘制方法
public void drawSelf(int texId,int dyFlag)
{
if(isDrawFlag)
{
if(dyFlag==0)//绘制实体
{
MatrixState.pushMatrix();
MatrixState.translate(x, y, z);
MatrixState.rotate(angleY, 0, 1, 0);
speed.drawSelf(texId);
MatrixState.popMatrix();
}
else if(dyFlag==1)//绘制倒影
{
//实际绘制时Y的零点
float yTranslate=y;
//进行镜像绘制时的调整值
float yjx=(0-yTranslate)*2;
MatrixState.pushMatrix();
MatrixState.translate(x, y, z);
MatrixState.rotate(angleY, 0, 1, 0);
MatrixState.translate(0, yjx, 0);
MatrixState.scale(1, -1, 1);
speed.drawSelf(texId);
MatrixState.popMatrix();
}
}
}
//计算是否发生碰撞
//根据船的位置计算出船头位置,并判断是否与某个可撞物体碰撞
public void checkColl(float bX,float bZ,float carAlphaTemp)
{
//首先求出碰撞检测点坐标
float bPointX=(float) (bX-BOAT_UNIT_SIZE*Math.sin(Math.toRadians(sight_angle)));
float bPointZ=(float) (bZ-BOAT_UNIT_SIZE*Math.cos(Math.toRadians(sight_angle)));
//计算碰撞点在地图上的行和列
float carCol=(float) Math.floor((bPointX+UNIT_SIZE/2)/UNIT_SIZE);
float carRow=(float) Math.floor((bPointZ+UNIT_SIZE/2)/UNIT_SIZE);
if(carRow==rows&&carCol==cols&&isDrawFlag)
{//如果大家在同一个格子里进行严格的碰撞检测KZBJBJ
double disP2=(bPointX-x)*(bPointX-x)+(bPointZ-z)*(bPointZ-z);
//这里的4为一个测试值以后需要根据实际情况更改
if(disP2<=4)
{//碰撞了
if(id==0)//吃了增加氮气的物件
{
if(numberOfN2<maxNumberOfN2)
{
numberOfN2=numberOfN2+1;//氮气的数量值增加1
}
if(SoundEffectFlag)
{
ma.shengyinBoFang(3, 0);
}
isDrawFlag=false;
pzTime=System.currentTimeMillis();
}
else if(id==1)//吃掉减速
{
if(SoundEffectFlag)
{
ma.shengyinBoFang(3, 0);
}
CURR_BOAT_V=CURR_BOAT_V/2;//吃掉减速物体之后,速度变为原先的一半
isDrawFlag=false;
pzTime=System.currentTimeMillis();
}
}
}
}
//该方法是判断已经吃掉的物体是否已经经过50秒如果经过50秒则重新显示
public void checkEatYet()
{
//如果物件的绘制标志位为true并且时间差不大于60秒
if(!isDrawFlag&&((System.currentTimeMillis()-pzTime)%60000/1000>=50))
{
isDrawFlag=true;
}
}
}

View File

@@ -0,0 +1,7 @@
package com.bn.clp;
//所有可以吃掉物体的父类
public abstract class SpeedForEat
{
public abstract void drawSelf(int texId);
}

View File

@@ -0,0 +1,360 @@
package com.bn.clp;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.List;
import android.opengl.GLES20;
import com.bn.core.MatrixState;
//起始结束牌子
public class StartAndEnd
{
//开始结束条幅的条幅
TextureRect tr;
//开始结束条幅的支柱
Cylinder cylinder;
//切分的角度
final float ANGLE_SPAN=20;
final float UNIT_SIZE=1.0f;
final float R=0.5f;
final float width=24;
final float cHeight=12;
final float height=2;
public StartAndEnd(int programId)
{
cylinder=new Cylinder(programId,R,ANGLE_SPAN,cHeight);
tr=new TextureRect(programId,width-R,height);
}
//总的绘制方法drawSelf
public void drawSelf(int zzTexId,int tfTexId,float y,int dyFlag)
{
if(dyFlag==0)//绘制实体
{
//左侧支柱
MatrixState.pushMatrix();
MatrixState.translate(-width, 0, 0);
cylinder.drawSelf(zzTexId);
MatrixState.popMatrix();
//右侧支柱
MatrixState.pushMatrix();
MatrixState.translate(width, 0, 0);
cylinder.drawSelf(zzTexId);
MatrixState.popMatrix();
//条幅
MatrixState.pushMatrix();
MatrixState.translate(0, cHeight-height, 0);
tr.drawSelf(tfTexId);
MatrixState.popMatrix();
}
else if(dyFlag==1)//绘制倒影
{
//实际绘制时Y的零点
float yTranslate=y;
//进行镜像绘制时的调整值
float yjx=(0-yTranslate)*2;
//关闭背面剪裁
GLES20.glDisable(GLES20.GL_CULL_FACE);
//左侧支柱
MatrixState.pushMatrix();
MatrixState.translate(-width, 0, 0);
MatrixState.translate(0, yjx, 0);
MatrixState.scale(1, -1, 1);
cylinder.drawSelf(zzTexId);
MatrixState.popMatrix();
//右侧支柱
MatrixState.pushMatrix();
MatrixState.translate(width, 0, 0);
MatrixState.translate(0, yjx, 0);
MatrixState.scale(1, -1, 1);
cylinder.drawSelf(zzTexId);
MatrixState.popMatrix();
//条幅
MatrixState.pushMatrix();
MatrixState.translate(0, cHeight-height, 0);
MatrixState.translate(0, (0-yTranslate-cHeight+height)*2, 0);
MatrixState.scale(1, -1, 1);
tr.drawSelf(tfTexId);
MatrixState.popMatrix();
//打开背面剪裁
GLES20.glEnable(GLES20.GL_CULL_FACE);
}
}
//内部类——圆柱
private class Cylinder
{
//自定义Shader程序的引用
int mProgram;
//总变换矩阵的引用id
int muMVPMatrixHandle;
//顶点属性的引用id
int maPositionHandle;
//顶点纹理坐标的引用id
int maTexCoorHandle;
//顶点坐标数据缓冲
FloatBuffer mVertexBuffer;
//顶点纹理坐标数据缓冲
FloatBuffer mTexCoorBuffer;
int vCount=0;//顶点数量
//R为圆柱底部的半径r为圆柱上部的半径angle_span表示的是切分的角度
public Cylinder(int programId,float R,float angle_span,float height)
{
initVertexData(R,angle_span,height);
initShader(programId);
}
//初始化坐标数据的方法
public void initVertexData(float R,float angle_span,float height)
{
List<Float> tempList=new ArrayList<Float>();
for(float vAngle=0;vAngle<360;vAngle=vAngle+angle_span)
{
float x0=(float) (R*Math.cos(Math.toRadians(vAngle)));
float y0=height;
float z0=(float) (-R*Math.sin(Math.toRadians(vAngle)));
float x1=(float) (R*Math.cos(Math.toRadians(vAngle)));
float y1=-height;
float z1=(float) (-R*Math.sin(Math.toRadians(vAngle)));
float x2=(float) (R*Math.cos(Math.toRadians(vAngle+angle_span)));
float y2=-height;
float z2=(float) (-R*Math.sin(Math.toRadians(vAngle+angle_span)));
float x3=(float) (R*Math.cos(Math.toRadians(vAngle+angle_span)));
float y3=height;
float z3=(float) (-R*Math.sin(Math.toRadians(vAngle+angle_span)));
tempList.add(x0); tempList.add(y0); tempList.add(z0);
tempList.add(x1); tempList.add(y1); tempList.add(z1);
tempList.add(x3); tempList.add(y3); tempList.add(z3);
tempList.add(x3); tempList.add(y3); tempList.add(z3);
tempList.add(x1); tempList.add(y1); tempList.add(z1);
tempList.add(x2); tempList.add(y2); tempList.add(z2);
}
vCount=tempList.size()/3;//顶点数量
float[] vertex=new float[tempList.size()];
for(int i=0;i<tempList.size();i++)
{
vertex[i]=tempList.get(i);
}
ByteBuffer vbb=ByteBuffer.allocateDirect(vertex.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer=vbb.asFloatBuffer();
mVertexBuffer.put(vertex);
mVertexBuffer.position(0);
float[] texcoor=generateTexCoor((int)(360/angle_span),1,1,1);
ByteBuffer tbb=ByteBuffer.allocateDirect(texcoor.length*4);
tbb.order(ByteOrder.nativeOrder());
mTexCoorBuffer=tbb.asFloatBuffer();
mTexCoorBuffer.put(texcoor);
mTexCoorBuffer.position(0);
}
//初始化着色器程序的initShader方法
public void initShader(int programId)
{
mProgram=programId;
//获得顶点坐标数据的引用
maPositionHandle=GLES20.glGetAttribLocation(mProgram, "aPosition");
//顶点纹理坐标的引用id
maTexCoorHandle=GLES20.glGetAttribLocation(mProgram, "aTexCoor");
muMVPMatrixHandle=GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
}
//自定义的绘制方法
public void drawSelf(int texId)
{
//使用某套指定的Shader程序
GLES20.glUseProgram(mProgram);
//将最终变换矩阵传入到Shader程序中
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//传入顶点坐标数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入纹理坐标数据
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false,
2*4,
mTexCoorBuffer
);
//允许顶点位置数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
//绘制纹理矩形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
//自动切分纹理产生纹理数组的方法
public float[] generateTexCoor(int bw,int bh,float width,float height)
{
float[] result=new float[bw*bh*6*2];
float sizew=width/bw;//列数
float sizeh=height/bh;//行数
int c=0;
for(int i=0;i<bh;i++)
{
for(int j=0;j<bw;j++)
{
//每行列一个矩形由两个三角形构成共六个点12个纹理坐标
float s=j*sizew;
float t=i*sizeh;
result[c++]=s;
result[c++]=t;
result[c++]=s;
result[c++]=t+sizeh;
result[c++]=s+sizew;
result[c++]=t;
result[c++]=s+sizew;
result[c++]=t;
result[c++]=s;
result[c++]=t+sizeh;
result[c++]=s+sizew;
result[c++]=t+sizeh;
}
}
return result;
}
}
//下方的底座
private class TextureRect
{
//自定义渲染管线着色器程序的引用
int mProgram;
//总变换矩阵的引用id
int muMVPMatrixHandle;
//顶点属性的引用id
int maPositionHandle;
//顶点纹理坐标的引用id
int maTexCoorHandle;
//顶点坐标数据缓冲
FloatBuffer mVertexBuffer;
//顶点纹理坐标数据缓冲
FloatBuffer mTexCoorBuffer;
int vCount=0;//顶点数量
//R为圆柱底部的半径r为圆柱上部的半径
public TextureRect(int programId,float width,float height)
{
initVertexData(width,height);
initShader(programId);
}
//初始化坐标数据的方法
public void initVertexData(float width,float height)
{
float[] vertex=new float[]
{
-width,height,0,
-width,-height,0,
width,-height,0,
-width,height,0,
width,-height,0,
width,height,0,
-width,height,0,
width,-height,0,
-width,-height,0,
-width,height,0,
width,height,0,
width,-height,0,
};
vCount=12;
ByteBuffer vbb=ByteBuffer.allocateDirect(vertex.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer=vbb.asFloatBuffer();
mVertexBuffer.put(vertex);
mVertexBuffer.position(0);
float[] texcoor=new float[]
{
0,0, 0,1, 1,1,
0,0, 1,1, 1,0,
0,0, 1,1, 0,1,
0,0, 1,0, 1,1
};
ByteBuffer tbb=ByteBuffer.allocateDirect(texcoor.length*4);
tbb.order(ByteOrder.nativeOrder());
mTexCoorBuffer=tbb.asFloatBuffer();
mTexCoorBuffer.put(texcoor);
mTexCoorBuffer.position(0);
}
//初始化着色器程序的方法
public void initShader(int programId)
{
mProgram=programId;
//获得顶点坐标数据的引用
maPositionHandle=GLES20.glGetAttribLocation(mProgram, "aPosition");
//顶点纹理坐标的引用id
maTexCoorHandle=GLES20.glGetAttribLocation(mProgram, "aTexCoor");
muMVPMatrixHandle=GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
}
//自定义的绘制方法
public void drawSelf(int texId)
{
//使用某套指定的Shader程序
GLES20.glUseProgram(mProgram);
//将最终变换矩阵传入到Shader程序中
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//传入坐标数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入纹理坐标数据
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false,
2*4,
mTexCoorBuffer
);
//允许顶点位置数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
//绘制纹理矩形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
}
}

View File

@@ -0,0 +1,504 @@
package com.bn.clp;
import static com.bn.clp.Constant.*;
//3D物件数据类
public class TDObjectData
{
//游戏中3D物体的相关数据列表
static float[][] PART_LIST=new float[][]
{
//==================桥=======================
//==================桥=======================
{0,UNIT_SIZE*6f,WATER_HIGH_ADJUST,UNIT_SIZE*2f-15f,-90,2,6},//桥
{0,UNIT_SIZE*14f,WATER_HIGH_ADJUST,UNIT_SIZE*2f-15f,-90,2,14},//桥
{0,UNIT_SIZE*4f,WATER_HIGH_ADJUST,UNIT_SIZE*29f-15f,-90,29,4},//桥
{0,UNIT_SIZE*25f-15f,WATER_HIGH_ADJUST,UNIT_SIZE*3f,0,3,25},//桥
{0,UNIT_SIZE*29f-15f,WATER_HIGH_ADJUST,UNIT_SIZE*4f,0,4,29},//桥
{0,UNIT_SIZE*11f-15f,WATER_HIGH_ADJUST,UNIT_SIZE*6f,0,6,11},//桥
{0,UNIT_SIZE*20f-15f,WATER_HIGH_ADJUST,UNIT_SIZE*10f,0,10,20},//桥
{0,UNIT_SIZE*11f-15f,WATER_HIGH_ADJUST,UNIT_SIZE*11f-20,0,11,11},//桥
{0,UNIT_SIZE*1f-15f,WATER_HIGH_ADJUST,UNIT_SIZE*17f,0,17,1},//桥
{0,UNIT_SIZE*24f-15f,WATER_HIGH_ADJUST,UNIT_SIZE*22f,0,22,24},//桥
{0,UNIT_SIZE*15f-15f,WATER_HIGH_ADJUST,UNIT_SIZE*25f,0,25,15},//桥
{0,UNIT_SIZE*24f-15f,WATER_HIGH_ADJUST,UNIT_SIZE*27f,0,27,24},//桥
{0,UNIT_SIZE*0f-15f,WATER_HIGH_ADJUST,UNIT_SIZE*2f,0,2,0},//桥
{0,UNIT_SIZE*1f,WATER_HIGH_ADJUST,UNIT_SIZE*0f-15f,-90,0,1},//桥
//新添加的桥的数据
//2-10 横
{0,UNIT_SIZE*10f,WATER_HIGH_ADJUST,UNIT_SIZE*2f-15f,-90,2,10},
//13-14 横
{0,UNIT_SIZE*14f+15,WATER_HIGH_ADJUST,UNIT_SIZE*13f-15f,-90,13,14},
//13-18 横
{0,UNIT_SIZE*18f+15,WATER_HIGH_ADJUST,UNIT_SIZE*13f-15f,-90,13,18},
//5-20 竖
{0,UNIT_SIZE*20f-15f,WATER_HIGH_ADJUST,UNIT_SIZE*5f+15,0,5,20},
//13-25 竖
{0,UNIT_SIZE*25f-15f,WATER_HIGH_ADJUST,UNIT_SIZE*13f,0,13,25},
//18-25 竖
{0,UNIT_SIZE*25f-15f,WATER_HIGH_ADJUST,UNIT_SIZE*18f-15,0,18,25},
//20-12 横
{0,UNIT_SIZE*12f+15,WATER_HIGH_ADJUST,UNIT_SIZE*20f-15f,-90,20,12},
//24-2 竖
{0,UNIT_SIZE*2f-15f,WATER_HIGH_ADJUST,UNIT_SIZE*24f+20,0,24,2},
//24-1 竖
{0,UNIT_SIZE*1f-15f,WATER_HIGH_ADJUST,UNIT_SIZE*24f,0,24,1},
//==================桥=======================
//=================隧道=======================
{1,UNIT_SIZE*2f,WATER_HIGH_ADJUST,0,-90,0,2},//横着的
{1,UNIT_SIZE*26f,WATER_HIGH_ADJUST,UNIT_SIZE*8f,0,8,26},
{1,UNIT_SIZE*16f,WATER_HIGH_ADJUST,UNIT_SIZE*22f,0,22,16},
{1,UNIT_SIZE*17f,WATER_HIGH_ADJUST,UNIT_SIZE*28f,-90,28,17},
{1,UNIT_SIZE*2f,WATER_HIGH_ADJUST,UNIT_SIZE*10f,0,10,2},
//=================隧道=======================
//==================山=======================
{2,UNIT_SIZE*2f,LAND_MAX_HIGHEST-1,UNIT_SIZE+10,0,2,2},//山
{2,UNIT_SIZE*5f,LAND_MAX_HIGHEST-1,UNIT_SIZE*0+10,0,0,5},
{2,UNIT_SIZE*3f,LAND_MAX_HIGHEST-1,UNIT_SIZE*2+10,0,2,3},
{2,UNIT_SIZE*8f,LAND_MAX_HIGHEST-1,UNIT_SIZE*4+10,0,4,8},
{2,UNIT_SIZE*9f,LAND_MAX_HIGHEST-1,UNIT_SIZE*1,0,1,9},
{2,UNIT_SIZE*15f,LAND_MAX_HIGHEST-1,UNIT_SIZE*1,0,1,15},
{2,UNIT_SIZE*10f,LAND_MAX_HIGHEST-1,UNIT_SIZE*7+10,0,7,10},
{2,UNIT_SIZE*10f,LAND_MAX_HIGHEST-1,UNIT_SIZE*11+10,0,11,10},
{2,UNIT_SIZE*14f,LAND_MAX_HIGHEST-1,UNIT_SIZE*14+10,0,14,14},
{2,UNIT_SIZE*17f,LAND_MAX_HIGHEST-1,UNIT_SIZE*12,0,12,17},
{2,UNIT_SIZE*19f,LAND_MAX_HIGHEST-1,UNIT_SIZE*7+10,0,7,19},
{2,UNIT_SIZE*23f,LAND_MAX_HIGHEST-1,UNIT_SIZE*4,0,4,23},
{2,UNIT_SIZE*29f,LAND_MAX_HIGHEST-1,UNIT_SIZE*6+10,0,6,29},
{2,UNIT_SIZE*25f,LAND_MAX_HIGHEST-1,UNIT_SIZE*11,0,11,25},
{2,UNIT_SIZE*27f,LAND_MAX_HIGHEST-1,UNIT_SIZE*17+10,0,17,27},
{2,UNIT_SIZE*23f,LAND_MAX_HIGHEST-1,UNIT_SIZE*22+10,0,22,23},
{2,UNIT_SIZE*23f,LAND_MAX_HIGHEST-1,UNIT_SIZE*30+10,0,30,23},
{2,UNIT_SIZE*19f,LAND_MAX_HIGHEST-1,UNIT_SIZE*30+10,0,30,19},
{2,UNIT_SIZE*16f,LAND_MAX_HIGHEST-1,UNIT_SIZE*25+10,0,25,16},
{2,UNIT_SIZE*13f,LAND_MAX_HIGHEST-1,UNIT_SIZE*19,0,19,13},
{2,UNIT_SIZE*12f,LAND_MAX_HIGHEST-1,UNIT_SIZE*23+10,0,23,12},
{2,UNIT_SIZE*8f,LAND_MAX_HIGHEST-1,UNIT_SIZE*29+10,0,29,8},
{2,UNIT_SIZE*4f,LAND_MAX_HIGHEST-1,UNIT_SIZE*30+10,0,30,4},
{2,UNIT_SIZE*0f,LAND_MAX_HIGHEST-1,UNIT_SIZE*26+10,0,26,0},
{2,UNIT_SIZE*3f,LAND_MAX_HIGHEST-1,UNIT_SIZE*21,0,21,3},
{2,UNIT_SIZE*0f,LAND_MAX_HIGHEST-1,UNIT_SIZE*16+10,0,16,0},
{2,UNIT_SIZE*1f,LAND_MAX_HIGHEST-1,UNIT_SIZE*11+10,0,11,1},
{2,UNIT_SIZE*3f,LAND_MAX_HIGHEST-1,UNIT_SIZE*9+10,0,9,3},
{2,UNIT_SIZE*3f,LAND_MAX_HIGHEST-1,UNIT_SIZE*5+10,0,5,3},
{2,UNIT_SIZE*1f,LAND_MAX_HIGHEST-1,UNIT_SIZE*4+10,0,4,1},
{2,UNIT_SIZE*14f,LAND_MAX_HIGHEST-1,UNIT_SIZE*3,0,3,14},
{2,UNIT_SIZE*14f,LAND_MAX_HIGHEST-1,UNIT_SIZE*5+10,0,5,14},
{2,UNIT_SIZE*11f,LAND_MAX_HIGHEST-1,UNIT_SIZE*8,0,8,11},
{2,UNIT_SIZE*12f,LAND_MAX_HIGHEST-1,UNIT_SIZE*10+10,0,10,12},
{2,UNIT_SIZE*10f,LAND_MAX_HIGHEST-1,UNIT_SIZE*13+10,0,13,10},
{2,UNIT_SIZE*14f,LAND_MAX_HIGHEST-1,UNIT_SIZE*12,0,12,14},
{2,UNIT_SIZE*20f,LAND_MAX_HIGHEST-1,UNIT_SIZE*13+10,0,13,20},
{2,UNIT_SIZE*19f,LAND_MAX_HIGHEST-1,UNIT_SIZE*11,0,11,19},
{2,UNIT_SIZE*19f,LAND_MAX_HIGHEST-1,UNIT_SIZE*4+10,0,4,19},
{2,UNIT_SIZE*26f,LAND_MAX_HIGHEST-1,UNIT_SIZE*5,0,5,26},
{2,UNIT_SIZE*30f,LAND_MAX_HIGHEST-1,UNIT_SIZE*2,0,2,30},
{2,UNIT_SIZE*28f,LAND_MAX_HIGHEST-1,UNIT_SIZE*11+10,0,11,28},
{2,UNIT_SIZE*24f,LAND_MAX_HIGHEST-1,UNIT_SIZE*13+10,0,13,24},
{2,UNIT_SIZE*24f,LAND_MAX_HIGHEST-1,UNIT_SIZE*19+10,0,19,24},
{2,UNIT_SIZE*27f,LAND_MAX_HIGHEST-1,UNIT_SIZE*22+10,0,22,27},
{2,UNIT_SIZE*26f,LAND_MAX_HIGHEST-1,UNIT_SIZE*25+10,0,25,26},
{2,UNIT_SIZE*25f,LAND_MAX_HIGHEST-1,UNIT_SIZE*27+10,0,27,25},
{2,UNIT_SIZE*20f,LAND_MAX_HIGHEST-1,UNIT_SIZE*27,0,27,20},
{2,UNIT_SIZE*14f,LAND_MAX_HIGHEST-1,UNIT_SIZE*27+10,0,27,14},
{2,UNIT_SIZE*15f,LAND_MAX_HIGHEST-1,UNIT_SIZE*21+10,0,21,15},
{2,UNIT_SIZE*10f,LAND_MAX_HIGHEST-1,UNIT_SIZE*22,0,22,10},
{2,UNIT_SIZE*8f,LAND_MAX_HIGHEST-1,UNIT_SIZE*26,0,26,8},
{2,UNIT_SIZE*3f,LAND_MAX_HIGHEST-1,UNIT_SIZE*28,0,28,3},
{2,UNIT_SIZE*1f,LAND_MAX_HIGHEST-1,UNIT_SIZE*23+10,0,23,1},
{2,UNIT_SIZE*3f,LAND_MAX_HIGHEST-1,UNIT_SIZE*15+10,0,15,3},
{2,UNIT_SIZE*1f,LAND_MAX_HIGHEST-1,UNIT_SIZE*7+10,0,7,1},
//==================山=======================
//================半崖子=======================
{3,UNIT_SIZE*4-26f,WATER_HIGH_ADJUST,UNIT_SIZE*1,0,1,4},//半崖子
{3,UNIT_SIZE*12f,WATER_HIGH_ADJUST,UNIT_SIZE*2-26f,-90,2,12},
{3,UNIT_SIZE*13f,WATER_HIGH_ADJUST,UNIT_SIZE*2-26f,-90,2,13},
{3,UNIT_SIZE*12f-26f,WATER_HIGH_ADJUST,UNIT_SIZE*8,0,8,12},
{3,UNIT_SIZE*21f-26f,WATER_HIGH_ADJUST,UNIT_SIZE*8,0,8,21},
{3,UNIT_SIZE*27f,WATER_HIGH_ADJUST,UNIT_SIZE*2-26f,-90,2,27},
{3,UNIT_SIZE*27f,WATER_HIGH_ADJUST,UNIT_SIZE*6-26f,-90,6,27},
{3,UNIT_SIZE*26f-26f,WATER_HIGH_ADJUST,UNIT_SIZE*16,0,16,26},
{3,UNIT_SIZE*24f-26f,WATER_HIGH_ADJUST,UNIT_SIZE*24,0,24,24},
{3,UNIT_SIZE*15f,WATER_HIGH_ADJUST,UNIT_SIZE*20-26f,-90,20,15},
{3,UNIT_SIZE*12f,WATER_HIGH_ADJUST,UNIT_SIZE*20-26f,-90,20,12},
{3,UNIT_SIZE*10f-26f,WATER_HIGH_ADJUST,UNIT_SIZE*25,0,25,10},
{3,UNIT_SIZE*2f-26f,WATER_HIGH_ADJUST,UNIT_SIZE*27,0,27,2},
{3,UNIT_SIZE*1f-26f,WATER_HIGH_ADJUST,UNIT_SIZE*20,0,20,1},
{3,UNIT_SIZE*2f-26f,WATER_HIGH_ADJUST,UNIT_SIZE*6,0,6,2},
{3,UNIT_SIZE*2f-26f,WATER_HIGH_ADJUST,UNIT_SIZE*9,0,9,2},
//2-5 直道0半崖子
{3,UNIT_SIZE*5f,WATER_HIGH_ADJUST,UNIT_SIZE*2-26f,-90,2,5},
//3-15 直道1半崖子
{3,UNIT_SIZE*15-26f,WATER_HIGH_ADJUST,UNIT_SIZE*3,0,3,15},//半崖子
//10-11 直道1半崖子
{3,UNIT_SIZE*11-26f,WATER_HIGH_ADJUST,UNIT_SIZE*10,0,10,11},//半崖子
//5-22 直道0半崖子
{3,UNIT_SIZE*22f,WATER_HIGH_ADJUST,UNIT_SIZE*5-26f,-90,5,22},
//4-25 直道1半崖子
{3,UNIT_SIZE*25-26f,WATER_HIGH_ADJUST,UNIT_SIZE*4,0,4,25},
//13-17直道0半崖子
{3,UNIT_SIZE*17f,WATER_HIGH_ADJUST,UNIT_SIZE*13-26f,-90,13,17},
//5-20直道1半崖子
{3,UNIT_SIZE*20-26f,WATER_HIGH_ADJUST,UNIT_SIZE*5,0,5,20},
//29-6直道1半崖子
{3,UNIT_SIZE*6-26f,WATER_HIGH_ADJUST,UNIT_SIZE*29,0,29,6},
//0-0弯道4 半崖子
{3,UNIT_SIZE*0f-10,WATER_HIGH_ADJUST,UNIT_SIZE*0-5,-45,0,0},
//0-4弯道5半崖子
{3,UNIT_SIZE*4+13f,WATER_HIGH_ADJUST,UNIT_SIZE*0-5,-150,0,4},
//新添加的飞艇=======================================================
//2-6
{4,UNIT_SIZE*6f,UNIT_SIZE-15,UNIT_SIZE*2,-60,2,6},
//2-11
{4,UNIT_SIZE*11f,UNIT_SIZE-15,UNIT_SIZE*2,-60,2,11},
//4-11
{4,UNIT_SIZE*11f,UNIT_SIZE-15,UNIT_SIZE*4,-60,4,11},
//7-12
{4,UNIT_SIZE*12f,UNIT_SIZE-15,UNIT_SIZE*7,-60,7,12},
//12-12
{4,UNIT_SIZE*12f,UNIT_SIZE-15,UNIT_SIZE*12,-60,12,12},
//14-16
{4,UNIT_SIZE*16f,UNIT_SIZE-15,UNIT_SIZE*14,-60,14,16},
//7-20
{4,UNIT_SIZE*20f,UNIT_SIZE-15,UNIT_SIZE*7,-60,7,20},
//4-25
{4,UNIT_SIZE*25f,UNIT_SIZE-15,UNIT_SIZE*4,-60,4,25},
//4-29
{4,UNIT_SIZE*29f,UNIT_SIZE-15,UNIT_SIZE*4,-60,4,29},
//10-26
{4,UNIT_SIZE*26f,UNIT_SIZE-15,UNIT_SIZE*10,-60,10,26},
//15-26
{4,UNIT_SIZE*26f,UNIT_SIZE-15,UNIT_SIZE*15,-60,15,26},
//19-26
{4,UNIT_SIZE*26f,UNIT_SIZE-15,UNIT_SIZE*19,-60,19,26},
//24-24
{4,UNIT_SIZE*24f,UNIT_SIZE-15,UNIT_SIZE*24,-60,24,24},
//29-24
{4,UNIT_SIZE*24f,UNIT_SIZE-15,UNIT_SIZE*29,-60,29,24},
//20-16
{4,UNIT_SIZE*16f,UNIT_SIZE-15,UNIT_SIZE*20,-60,20,16},
//20-11
{4,UNIT_SIZE*11f,UNIT_SIZE-15,UNIT_SIZE*20,-60,20,11},
//25-10
{4,UNIT_SIZE*10f,UNIT_SIZE-15,UNIT_SIZE*25,-60,25,10},
//28-6
{4,UNIT_SIZE*6f,UNIT_SIZE-15,UNIT_SIZE*28,-60,28,6},
//26-2
{4,UNIT_SIZE*2f,UNIT_SIZE-15,UNIT_SIZE*26,-60,26,2},
//18-2
{4,UNIT_SIZE*2f,UNIT_SIZE-15,UNIT_SIZE*18,-60,18,2},
//13-2
{4,UNIT_SIZE*2f,UNIT_SIZE-15,UNIT_SIZE*13,-60,13,2},
//7-3
{4,UNIT_SIZE*3f,UNIT_SIZE-15,UNIT_SIZE*7,-60,7,3},
//广告牌子
//2-7 竖着的
{5,UNIT_SIZE*7f-20,LAND_MAX_HIGHEST-5,UNIT_SIZE*2+23,0,2,7},
//4-14
{5,UNIT_SIZE*14f-20,LAND_MAX_HIGHEST-5,UNIT_SIZE*4-23,0,4,14},
//5-22
{5,UNIT_SIZE*22f,LAND_MAX_HIGHEST-5,UNIT_SIZE*5-23,0,5,22},
//2-28
{5,UNIT_SIZE*28f,LAND_MAX_HIGHEST-5,UNIT_SIZE*2+23,0,2,28},
//14-25竖着的1
{5,UNIT_SIZE*25f+23,LAND_MAX_HIGHEST-5,UNIT_SIZE*14,0,14,25},
//18-25
{5,UNIT_SIZE*25f-23,LAND_MAX_HIGHEST-5,UNIT_SIZE*18,0,18,25},
//22-25
{5,UNIT_SIZE*25f-23,LAND_MAX_HIGHEST-5,UNIT_SIZE*22-20,0,22,25},
//28-16
{5,UNIT_SIZE*16f-20,LAND_MAX_HIGHEST-5,UNIT_SIZE*28-23,0,28,16},
//28-10
{5,UNIT_SIZE*10f-23,LAND_MAX_HIGHEST-5,UNIT_SIZE*28,0,28,10},
//24-2
{5,UNIT_SIZE*2f-23,LAND_MAX_HIGHEST-5,UNIT_SIZE*24-20,0,24,2},
//12-2
{5,UNIT_SIZE*2f-23,LAND_MAX_HIGHEST-5,UNIT_SIZE*12,0,12,2},
//2-10
{5,UNIT_SIZE*10f,LAND_MAX_HIGHEST-5,UNIT_SIZE*2-23,0,2,10},
//2-13
{5,UNIT_SIZE*13f+20,LAND_MAX_HIGHEST-5,UNIT_SIZE*2-23,0,2,13},
//13-14
{5,UNIT_SIZE*14f,LAND_MAX_HIGHEST-5,UNIT_SIZE*13-23,0,13,14},
//3-25
{5,UNIT_SIZE*25f-23,LAND_MAX_HIGHEST-5,UNIT_SIZE*3-20,0,3,25},
//6-27
{5,UNIT_SIZE*27f,LAND_MAX_HIGHEST-5,UNIT_SIZE*6+23,0,6,27},
//20-26
{5,UNIT_SIZE*26f-23,LAND_MAX_HIGHEST-5,UNIT_SIZE*20-20,0,20,26},
//22-24
{5,UNIT_SIZE*24f+23,LAND_MAX_HIGHEST-5,UNIT_SIZE*22,0,22,24},
//新添加的
//0-0 弯道4外侧
{5,UNIT_SIZE*0f-10,LAND_MAX_HIGHEST-8,UNIT_SIZE*0-5,0,0,0},
//2-4 弯道6外侧
{5,UNIT_SIZE*4f-10,LAND_MAX_HIGHEST-8,UNIT_SIZE*2+5,0,2,4},
//2-8 弯道5外侧
{5,UNIT_SIZE*8f+10,LAND_MAX_HIGHEST-8,UNIT_SIZE*2-5,0,2,8},
//3-9 弯道7外侧
{5,UNIT_SIZE*9f+10,LAND_MAX_HIGHEST-8,UNIT_SIZE*3+5,0,3,9},
//2-15 弯道5外侧
{5,UNIT_SIZE*15f+10,LAND_MAX_HIGHEST-8,UNIT_SIZE*2-5,0,2,15},
//4-15 弯道7内测
{5,UNIT_SIZE*15f-25,LAND_MAX_HIGHEST-8,UNIT_SIZE*4-25,0,4,15},
//14-16 弯道7外侧
{5,UNIT_SIZE*16f+10,LAND_MAX_HIGHEST-8,UNIT_SIZE*14+5,0,14,16},
//12-20 弯道7外侧
{5,UNIT_SIZE*20f+10,LAND_MAX_HIGHEST-8,UNIT_SIZE*12+5,0,12,20},
//7-21 弯道5外侧
{5,UNIT_SIZE*21f+10,LAND_MAX_HIGHEST-8,UNIT_SIZE*7-5,0,7,21},
//4-21 弯道5外侧
{5,UNIT_SIZE*21f+10,LAND_MAX_HIGHEST-8,UNIT_SIZE*4-5,0,4,21},
//5-25 弯道7外侧
{5,UNIT_SIZE*25f+10,LAND_MAX_HIGHEST-8,UNIT_SIZE*5+5,0,5,25},
//2-29 弯道5外侧
{5,UNIT_SIZE*29f+10,LAND_MAX_HIGHEST-8,UNIT_SIZE*2-5,0,2,29},
//6-28 弯道7外侧
{5,UNIT_SIZE*28f+10,LAND_MAX_HIGHEST-8,UNIT_SIZE*6+5,0,6,28},
//10-26 弯道6外侧
{5,UNIT_SIZE*26f-10,LAND_MAX_HIGHEST-8,UNIT_SIZE*10+5,0,10,26},
//11-27 弯道7外侧
{5,UNIT_SIZE*27f+10,LAND_MAX_HIGHEST-8,UNIT_SIZE*11+5,0,11,27},
//15-25 弯道6外侧
{5,UNIT_SIZE*25f-10,LAND_MAX_HIGHEST-8,UNIT_SIZE*15+5,0,15,25},
//17-26 弯道7外侧
{5,UNIT_SIZE*26f+10,LAND_MAX_HIGHEST-8,UNIT_SIZE*17+5,0,17,26},
//23-26 弯道7外侧
{5,UNIT_SIZE*26f+10,LAND_MAX_HIGHEST-8,UNIT_SIZE*23+5,0,23,26},
//21-25 弯道5外侧
{5,UNIT_SIZE*25f+10,LAND_MAX_HIGHEST-8,UNIT_SIZE*21-5,0,21,25},
//26-25 弯道7外侧
{5,UNIT_SIZE*25f+10,LAND_MAX_HIGHEST-8,UNIT_SIZE*26+5,0,26,25},
//29-24 弯道7外侧
{5,UNIT_SIZE*24f+10,LAND_MAX_HIGHEST-8,UNIT_SIZE*29+5,0,29,24},
//28-23 弯道5外侧
{5,UNIT_SIZE*23f+10,LAND_MAX_HIGHEST-8,UNIT_SIZE*28-5,0,28,23},
//28-21 弯道5外侧
{5,UNIT_SIZE*21f+10,LAND_MAX_HIGHEST-8,UNIT_SIZE*28-5,0,28,21},
//29-19 弯道6外侧
{5,UNIT_SIZE*19f-10,LAND_MAX_HIGHEST-8,UNIT_SIZE*29+5,0,29,19},
//24-16 弯道7外侧
{5,UNIT_SIZE*16f+10,LAND_MAX_HIGHEST-8,UNIT_SIZE*24+5,0,24,16},
//20-11 弯道4外侧
{5,UNIT_SIZE*11f-10,LAND_MAX_HIGHEST-8,UNIT_SIZE*20-5,0,20,11},
//26-9 弯道4外侧
{5,UNIT_SIZE*9f-10,LAND_MAX_HIGHEST-8,UNIT_SIZE*26-5,0,26,9},
//28-6 弯道4外侧
{5,UNIT_SIZE*6f-10,LAND_MAX_HIGHEST-8,UNIT_SIZE*28-5,0,28,6},
//29-2 弯道6外侧
{5,UNIT_SIZE*2f-10,LAND_MAX_HIGHEST-8,UNIT_SIZE*29+5,0,29,2},
//23-3 弯道7外侧
{5,UNIT_SIZE*3f+10,LAND_MAX_HIGHEST-8,UNIT_SIZE*23+5,0,23,3},
//21-1 弯道6外侧
{5,UNIT_SIZE*1f-10,LAND_MAX_HIGHEST-8,UNIT_SIZE*21+5,0,21,1},
//19-2 弯道7外侧
{5,UNIT_SIZE*2f+10,LAND_MAX_HIGHEST-8,UNIT_SIZE*19+5,0,19,2},
//15-2 弯道7外侧
{5,UNIT_SIZE*2f+10,LAND_MAX_HIGHEST-8,UNIT_SIZE*15+5,0,15,2},
//8-3 弯道7外侧
{5,UNIT_SIZE*3f+10,LAND_MAX_HIGHEST-8,UNIT_SIZE*8+5,0,8,3},
//3-2 弯道5外侧
{5,UNIT_SIZE*2f+10,LAND_MAX_HIGHEST-8,UNIT_SIZE*3-5,0,3,2},
//新添加的
//船埠头
//2-5 横着的、上侧
{6,UNIT_SIZE*5f-21,0,UNIT_SIZE*2-15,90,2,5},
//2-6 横着的、下侧
{6,UNIT_SIZE*6f-13,0,UNIT_SIZE*2+15,-90,2,6},
//2-10 横着的、上侧
{6,UNIT_SIZE*10f-19,0,UNIT_SIZE*2-15,90,2,10},
//2-12 横着的、上侧
{6,UNIT_SIZE*12f-21,0,UNIT_SIZE*2-15,90,2,12},
//2-13 横着的、下侧
{6,UNIT_SIZE*13f-10,0,UNIT_SIZE*2+15,-90,2,13},
//2-14 横着的、下侧
{6,UNIT_SIZE*14f-7,0,UNIT_SIZE*2+15,-90,2,14},
//3-15 竖着的、左侧
{6,UNIT_SIZE*15f-15,0,UNIT_SIZE*3,180,3,15},
{6,UNIT_SIZE*15f-15,0,UNIT_SIZE*3+3,180,3,15},
//4-13 横着的、下侧
{6,UNIT_SIZE*13f-10,0,UNIT_SIZE*4+15,-90,4,13},
//5-11 竖着的、左侧
{6,UNIT_SIZE*11f-15,0,UNIT_SIZE*5,180,5,11},
//6-11 竖着的、右侧
{6,UNIT_SIZE*11f+15,0,UNIT_SIZE*6,0,6,11},
//10-11 竖着的、左侧
{6,UNIT_SIZE*11f-15,0,UNIT_SIZE*10,180,10,11},
//12-11 竖着的、右侧
{6,UNIT_SIZE*11f+15,0,UNIT_SIZE*12,0,12,11},
//13-17 横着的、下侧
{6,UNIT_SIZE*17f-7,0,UNIT_SIZE*13+15,-90,13,17},
//10-20 竖着的、右侧
{6,UNIT_SIZE*20f+15,0,UNIT_SIZE*10,0,10,20},
//8-21 竖着的、右侧
{6,UNIT_SIZE*21f+15,0,UNIT_SIZE*8,0,8,21},
//5-20 竖着的、右侧
{6,UNIT_SIZE*20f+15,0,UNIT_SIZE*5,0,5,20},
//5-22 横着的、上侧
{6,UNIT_SIZE*22f-7,0,UNIT_SIZE*5-15,90,5,22},
//5-23 横着的、下侧
{6,UNIT_SIZE*23f-7,0,UNIT_SIZE*5+15,-90,5,23},
//5-24 横着的、下侧
{6,UNIT_SIZE*24f-7,0,UNIT_SIZE*5+15,-90,5,24},
//2-26 横着的、上侧
{6,UNIT_SIZE*26f-7,0,UNIT_SIZE*2-15,90,2,26},
//2-27 横着的、下侧
{6,UNIT_SIZE*27f-7,0,UNIT_SIZE*2+15,-90,2,27},
//2-28 横着的、下侧
{6,UNIT_SIZE*28f-7,0,UNIT_SIZE*2+15,-90,2,28},
//3-29 竖着的、左侧
{6,UNIT_SIZE*29f-15,0,UNIT_SIZE*3,180,3,29},
//6-27 横着的、下侧
{6,UNIT_SIZE*27f-7,0,UNIT_SIZE*6+15,-90,6,27},
//7-26 竖着的、左侧
{6,UNIT_SIZE*26f-15,0,UNIT_SIZE*7,180,7,26},
//9-26 竖着的、右侧
{6,UNIT_SIZE*26f+15,0,UNIT_SIZE*9,0,9,26},
//13-25 竖着的、右侧
{6,UNIT_SIZE*25f+15,0,UNIT_SIZE*13,0,13,25},
//16-26 竖着的、右侧
{6,UNIT_SIZE*26f+15,0,UNIT_SIZE*16,0,16,26},
//21-26 竖着的、右侧
{6,UNIT_SIZE*26f+15,0,UNIT_SIZE*21,0,21,26},
//22-25 竖着的、左侧
{6,UNIT_SIZE*25f-15,0,UNIT_SIZE*22,180,22,25},
//24-24 竖着的、左侧
{6,UNIT_SIZE*24f-15,0,UNIT_SIZE*24+3,180,24,24},
//24-28 竖着的、左侧
{6,UNIT_SIZE*28f-15,0,UNIT_SIZE*24,180,24,28},
//28-16 横着的、上侧
{6,UNIT_SIZE*16f-7,0,UNIT_SIZE*28-15,90,28,16},
//28-18 横着的、下侧
{6,UNIT_SIZE*18f-7,0,UNIT_SIZE*28+15,-90,28,18},
//25-15 竖着的、右侧
{6,UNIT_SIZE*15f+15,0,UNIT_SIZE*25,0,25,15},
//26-15 竖着的、左侧
{6,UNIT_SIZE*15f-15,0,UNIT_SIZE*26,180,26,15},
//23-16 竖着的、右侧
{6,UNIT_SIZE*16f+15,0,UNIT_SIZE*23,0,23,16},
//21-16 竖着的、左侧
{6,UNIT_SIZE*16f-15,0,UNIT_SIZE*21,180,21,16},
//20-15 横着的、上侧
{6,UNIT_SIZE*15f-7,0,UNIT_SIZE*20-15,90,20,15},
//20-14 横着的、下侧
{6,UNIT_SIZE*14f-7,0,UNIT_SIZE*20+15,-90,20,14},
//21-11 竖着的、右侧
{6,UNIT_SIZE*11f+15,0,UNIT_SIZE*21,0,21,11},
//22-11 竖着的、右侧
{6,UNIT_SIZE*11f+15,0,UNIT_SIZE*22,0,22,11},
//24-10 竖着的、右侧
{6,UNIT_SIZE*10f+15,0,UNIT_SIZE*24,0,24,10},
//25-10 竖着的、右侧
{6,UNIT_SIZE*10f+15,0,UNIT_SIZE*25,0,25,10},
//29-3 横着的、上侧
{6,UNIT_SIZE*3f-7,0,UNIT_SIZE*29-15,90,29,3},
//29-4 横着的、下侧
{6,UNIT_SIZE*4f-10,0,UNIT_SIZE*29+15,-90,29,4},
//16-1 竖着的、右侧
{6,UNIT_SIZE*1f+15,0,UNIT_SIZE*16,0,16,1},
//17-1 竖着的、右侧
{6,UNIT_SIZE*1f+15,0,UNIT_SIZE*17,0,22,1},
//11-2 竖着的、右侧
{6,UNIT_SIZE*2f+15,0,UNIT_SIZE*11,0,11,2},
//21-16 竖着的、左侧
{6,UNIT_SIZE*2f-15,0,UNIT_SIZE*9,180,9,2},
//5-2 竖着的、右侧
{6,UNIT_SIZE*2f+15,0,UNIT_SIZE*5,0,5,2},
//6-2 竖着的、右侧
{6,UNIT_SIZE*2f+15,0,UNIT_SIZE*6,0,6,2},
//新添加的,船埠头
//城堡数据
//2-7 横
{7,UNIT_SIZE*7f,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*2-35,0,2,7},
//2-11 横
{7,UNIT_SIZE*11f,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*2-35,0,2,11},
//2-13 横
{7,UNIT_SIZE*13f,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*2-35,0,2,13},
//3-15 竖道
{7,UNIT_SIZE*15f-35,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*3,0,3,15},
//4-13 横
{7,UNIT_SIZE*13f,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*4-35,0,4,13},
//12-12 弯道4
{7,UNIT_SIZE*12f-17,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*12-17,0,12,12},
//14-16 弯道7
{7,UNIT_SIZE*16f+17,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*14+17,0,14,16},
//10-20 竖直
{7,UNIT_SIZE*20f+35,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*10,0,10,20},
//9-20 弯道4
{7,UNIT_SIZE*20f-17,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*9-17,0,9,20},
//8-21 竖直
{7,UNIT_SIZE*21f+35,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*8,0,8,21},
//4-21 弯道5
{7,UNIT_SIZE*21f+17,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*4-17,0,4,21},
//5-22 横道
{7,UNIT_SIZE*22f,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*5-35,0,5,22},
//5-24 横道
{7,UNIT_SIZE*24f,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*5-35,0,5,24},
//2-26 横道
{7,UNIT_SIZE*26f,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*2-35,0,2,26},
//2-28 横道
{7,UNIT_SIZE*28f,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*2-35,0,2,28},
//6-27 横道
{7,UNIT_SIZE*27f,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*6-35,0,6,27},
//7-26 竖直
{7,UNIT_SIZE*26f+35,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*7,0,7,26},
//9-26 竖直
{7,UNIT_SIZE*26f-35,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*9,0,9,26},
//15-26 弯道5
{7,UNIT_SIZE*26f+17,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*15-17,0,15,26},
//17-25 弯道4
{7,UNIT_SIZE*25f-17,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*17-17,0,17,25},
//20-26 竖直
{7,UNIT_SIZE*26f-35,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*20,0,20,26},
//21-24 弯道4
{7,UNIT_SIZE*24f-17,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*21-17,0,21,24},
//21-26 竖直
{7,UNIT_SIZE*26f+35,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*21,0,21,26},
//23-24 竖直
{7,UNIT_SIZE*24f-35,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*23,0,23,24},
//24-24 竖直
{7,UNIT_SIZE*24f-35,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*24,0,24,24},
//26-24 弯道4
{7,UNIT_SIZE*24f-17,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*26-17,0,26,24},
//27-24 竖直
{7,UNIT_SIZE*24f-35,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*27,0,27,24},
//28-22 弯道4
{7,UNIT_SIZE*22f-17,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*28-17,0,28,22},
//29-20 弯道7
{7,UNIT_SIZE*20f+17,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*29+17,0,29,20},
//24-15 弯道4
{7,UNIT_SIZE*15f-17,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*24-17,0,24,15},
//20-14 横道
{7,UNIT_SIZE*14f,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*20-35,0,20,14},
//24-10 竖直
{7,UNIT_SIZE*10f-35,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*24,0,24,10},
//28-6 弯道4
{7,UNIT_SIZE*6f-17,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*28-17,0,28,6},
//30-6 弯道7
{7,UNIT_SIZE*6f+17,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*30+17,0,30,6},
//27-1 竖直
{7,UNIT_SIZE*1-35,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*27,0,27,1},
//24-2 竖直
{7,UNIT_SIZE*2+35,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*24,0,24,2},
//20-1 竖直
{7,UNIT_SIZE*1-35,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*20,0,20,1},
//17-2 竖直
{7,UNIT_SIZE*2+35,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*17,0,17,2},
//13-1 弯道4
{7,UNIT_SIZE*1f-17,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*13-17,0,13,1},
//12-2 竖直
{7,UNIT_SIZE*2+35,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*12,0,12,2},
//2-0竖直
{7,UNIT_SIZE*0-35,LAND_MAX_HIGHEST+0.4f,UNIT_SIZE*2,0,2,0},
//新添加的,城堡
};
}

View File

@@ -0,0 +1,62 @@
package com.bn.clp;
import android.opengl.GLES20;
import com.bn.core.MatrixState;
/*
* 该类的主要作用是控制相应3D物体的绘制
* 需要获得相应3D物体的对象objectId物件的id物体相应的x、y、z位置、旋转的角度yAngle
*/
public class TDObjectForControl
{
BNDrawer bndrawer;//3D物体的对象
int objectId;//objectId物件的id
float x;
float y;
float z;
float yAngle;
int rows;
int cols;
public TDObjectForControl(BNDrawer bndrawer,int objectId,float x,float y,float z,float yAngle,int rows,int cols)
{
this.bndrawer=bndrawer;
this.objectId=objectId;
this.x=x;
this.y=y;
this.z=z;
this.yAngle=yAngle;
this.rows=rows;
this.cols=cols;
}
//自定义的绘制方法drawSelf由于在该方法中需要对矩阵进行平移以及旋转变换所以首先需要pushMatrix最后需要popMatrix
public void drawSelf(int[] texId,int dyFlag)
{
if(dyFlag==0)//绘制实体
{
MatrixState.pushMatrix();
MatrixState.translate(x, y, z);
MatrixState.rotate(yAngle, 0, 1, 0);
bndrawer.drawSelf(texId,dyFlag);
MatrixState.popMatrix();
}
else if(dyFlag==1)//绘制倒影
{
//实际绘制时Y的零点
float yTranslate=y;
//进行镜像绘制时的调整值
float yjx=(0-yTranslate)*2;
//关闭背面剪裁
GLES20.glDisable(GLES20.GL_CULL_FACE);
MatrixState.pushMatrix();
MatrixState.translate(x, y, z);
MatrixState.rotate(yAngle, 0, 1, 0);
MatrixState.translate(0, yjx, 0);
MatrixState.scale(1, -1, 1);
bndrawer.drawSelf(texId,dyFlag);
MatrixState.popMatrix();
//打开背面剪裁
GLES20.glEnable(GLES20.GL_CULL_FACE);
}
}
}

View File

@@ -0,0 +1,39 @@
package com.bn.clp;
import static com.bn.clp.MyGLSurfaceView.*;
//定时检查可以撞飞的部件,如交通筒灯部件,是否被碰撞的线程
public class ThreadColl extends Thread
{
MyGLSurfaceView surface;
public boolean flag=true;
public ThreadColl(MyGLSurfaceView surface)
{
this.surface=surface;
this.setName("ThreadColl");
}
public void run()
{
while(flag)
{
for(KZBJForControl kzbjfcTemp:surface.kzbjList)
{
if(!kzbjfcTemp.state)
{
kzbjfcTemp.checkColl(bxForSpecFrame, bzForSpecFrame, angleForSpecFrame);
}
kzbjfcTemp.go();
}
try
{
Thread.sleep(50);//50
}catch(Exception e)
{
e.printStackTrace();
}
}
}
}

View File

@@ -0,0 +1,41 @@
package com.bn.clp;
import static com.bn.clp.MyGLSurfaceView.*;
//检查与可吃掉的物体是否发生碰撞
public class ThreadForEat extends Thread
{
MyGLSurfaceView surface;
public boolean flag=true;
public ThreadForEat(MyGLSurfaceView surface)
{
this.surface=surface;
this.setName("ThreadForEat");
}
@Override
public void run()
{
while(flag)
{
for(SpeedForControl ksfcTemp:surface.speedWtList)
{
if(ksfcTemp.isDrawFlag)
{
ksfcTemp.checkColl(bxForSpecFrame, bzForSpecFrame, angleForSpecFrame);
}
else
{
ksfcTemp.checkEatYet();
}
}
try
{
Thread.sleep(50);//50
}catch(Exception e)
{
e.printStackTrace();
}
}
}
}

View File

@@ -0,0 +1,352 @@
package com.bn.clp;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.List;
import android.opengl.GLES20;
import com.bn.core.MatrixState;
//交通柱
public class TrafficCylinder extends KZBJDrawer
{
//交通柱上侧的圆片
Pedestal circle;
//交通柱上方的圆柱
Cylinder cylinder;
//交通柱下侧的底
Pedestal pedestal;
//交通柱下侧的六角
Cylinder cld_lj;
//切分的角度
final float ANGLE_SPAN=20;
final float UNIT_SIZE=1.0f;
final float HEIGHT=0.2f;
//下面的片切分的角度
float SPAN=60;
public TrafficCylinder(int programId,float R,float r,float R2)
{
cylinder=new Cylinder(programId,R,r,ANGLE_SPAN,UNIT_SIZE);
cld_lj=new Cylinder(programId,R2,R2,60,HEIGHT);
pedestal=new Pedestal(programId,R2,SPAN);
circle=new Pedestal(programId,r,ANGLE_SPAN);
}
//总的绘制方法drawSelf
public void drawSelf(int texId)
{
//绘制圆柱上侧的圆片
MatrixState.pushMatrix();
MatrixState.translate(0, UNIT_SIZE, 0);
circle.drawSelf(texId);
MatrixState.popMatrix();
//绘制交通柱的圆柱部分
cylinder.drawSelf(texId);
//绘制交通柱下方底座的上面
MatrixState.pushMatrix();
MatrixState.translate(0, -UNIT_SIZE, 0);
pedestal.drawSelf(texId);
MatrixState.popMatrix();
//绘制交通柱下方底座的侧面
MatrixState.pushMatrix();
MatrixState.translate(0, -UNIT_SIZE-HEIGHT, 0);
cld_lj.drawSelf(texId);
MatrixState.popMatrix();
//绘制交通柱下方底座的下面
MatrixState.pushMatrix();
MatrixState.translate(0, -UNIT_SIZE-HEIGHT*2, 0);
MatrixState.rotate(180, 1, 0, 0);
pedestal.drawSelf(texId);
MatrixState.popMatrix();
}
//内部类——圆柱
private class Cylinder
{
//自定义着色器程序的引用
int mProgram;
//总变换矩阵的引用id
int muMVPMatrixHandle;
//顶点属性的引用id
int maPositionHandle;
//顶点纹理坐标的引用id
int maTexCoorHandle;
//顶点坐标数据缓冲
FloatBuffer mVertexBuffer;
//顶点纹理坐标数据缓冲
FloatBuffer mTexCoorBuffer;
int vCount=0;//顶点数量
//R为圆柱底部的半径r为圆柱上部的半径angle_span表示的是切分的角度
public Cylinder(int programId,float R,float r,float angle_span,float height)
{
initVertexData(R,r,angle_span,height);
initShader(programId);
}
//初始化坐标数据的方法
public void initVertexData(float R,float r,float angle_span,float height)
{
List<Float> tempList=new ArrayList<Float>();
for(float vAngle=0;vAngle<360;vAngle=vAngle+angle_span)
{
float x0=(float) (r*Math.cos(Math.toRadians(vAngle)));
float y0=height;
float z0=(float) (-r*Math.sin(Math.toRadians(vAngle)));
float x1=(float) (R*Math.cos(Math.toRadians(vAngle)));
float y1=-height;
float z1=(float) (-R*Math.sin(Math.toRadians(vAngle)));
float x2=(float) (R*Math.cos(Math.toRadians(vAngle+angle_span)));
float y2=-height;
float z2=(float) (-R*Math.sin(Math.toRadians(vAngle+angle_span)));
float x3=(float) (r*Math.cos(Math.toRadians(vAngle+angle_span)));
float y3=height;
float z3=(float) (-r*Math.sin(Math.toRadians(vAngle+angle_span)));
tempList.add(x0); tempList.add(y0); tempList.add(z0);
tempList.add(x1); tempList.add(y1); tempList.add(z1);
tempList.add(x3); tempList.add(y3); tempList.add(z3);
tempList.add(x3); tempList.add(y3); tempList.add(z3);
tempList.add(x1); tempList.add(y1); tempList.add(z1);
tempList.add(x2); tempList.add(y2); tempList.add(z2);
}
vCount=tempList.size()/3;//顶点数量
float[] vertex=new float[tempList.size()];
for(int i=0;i<tempList.size();i++)
{
vertex[i]=tempList.get(i);
}
ByteBuffer vbb=ByteBuffer.allocateDirect(vertex.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer=vbb.asFloatBuffer();
mVertexBuffer.put(vertex);
mVertexBuffer.position(0);
float[] texcoor=generateTexCoor((int)(360/angle_span),1,1,1);
ByteBuffer tbb=ByteBuffer.allocateDirect(texcoor.length*4);
tbb.order(ByteOrder.nativeOrder());
mTexCoorBuffer=tbb.asFloatBuffer();
mTexCoorBuffer.put(texcoor);
mTexCoorBuffer.position(0);
}
//初始化着色器程序的方法
public void initShader(int programId)
{
mProgram=programId;
//获得顶点坐标数据的引用
maPositionHandle=GLES20.glGetAttribLocation(mProgram, "aPosition");
//顶点纹理坐标的引用id
maTexCoorHandle=GLES20.glGetAttribLocation(mProgram, "aTexCoor");
muMVPMatrixHandle=GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
}
//自定义的绘制方法
public void drawSelf(int texId)
{
//使用某套指定的Shader程序
GLES20.glUseProgram(mProgram);
//将最终变换矩阵传入到Shader程序中
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//传入顶点坐标数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入纹理坐标数据
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false,
2*4,
mTexCoorBuffer
);
//允许顶点位置数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
//绘制纹理矩形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
//自动切分纹理产生纹理数组的方法
public float[] generateTexCoor(int bw,int bh,float width,float height)
{
float[] result=new float[bw*bh*6*2];
float sizew=width/bw;//列数
float sizeh=height/bh;//行数
int c=0;
for(int i=0;i<bh;i++)
{
for(int j=0;j<bw;j++)
{
//每行列一个矩形由两个三角形构成共六个点12个纹理坐标
float s=j*sizew;
float t=i*sizeh;
result[c++]=s;
result[c++]=t;
result[c++]=s;
result[c++]=t+sizeh;
result[c++]=s+sizew;
result[c++]=t;
result[c++]=s+sizew;
result[c++]=t;
result[c++]=s;
result[c++]=t+sizeh;
result[c++]=s+sizew;
result[c++]=t+sizeh;
}
}
return result;
}
}
//下方的底座
private class Pedestal
{
//自定义着色器程序的引用
int mProgram;
//总变换矩阵的引用id
int muMVPMatrixHandle;
//顶点属性的引用id
int maPositionHandle;
//顶点纹理坐标的引用id
int maTexCoorHandle;
//顶点坐标数据缓冲
FloatBuffer mVertexBuffer;
//顶点纹理坐标数据缓冲
FloatBuffer mTexCoorBuffer;
int vCount=0;//顶点数量
//R为圆柱底部的半径r为圆柱上部的半径
public Pedestal(int programId,float R,float span)
{
initVertexData(R,span);
initShader(programId);
}
//初始化坐标数据的initVertexData方法
public void initVertexData(float R,float span)
{
List<Float> alist=new ArrayList<Float>();
for(float vAngle=0;vAngle<360;vAngle=vAngle+span)
{
float x0=0;
float y0=0;
float z0=0;
float x1=(float) (R*Math.cos(Math.toRadians(vAngle)));
float y1=0;
float z1=(float) (-R*Math.sin(Math.toRadians(vAngle)));
float x2=(float) (R*Math.cos(Math.toRadians(vAngle+span)));
float y2=0;
float z2=(float) (-R*Math.sin(Math.toRadians(vAngle+span)));
alist.add(x0); alist.add(y0); alist.add(z0);
alist.add(x1); alist.add(y1); alist.add(z1);
alist.add(x2); alist.add(y2); alist.add(z2);
}
vCount=alist.size()/3;
float[] vertex=new float[alist.size()];
for(int i=0;i<alist.size();i++)
{
vertex[i]=alist.get(i);
}
ByteBuffer vbb=ByteBuffer.allocateDirect(vertex.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer=vbb.asFloatBuffer();
mVertexBuffer.put(vertex);
mVertexBuffer.position(0);
float[] texcoor=generateTexCoor(span,1,1);
ByteBuffer tbb=ByteBuffer.allocateDirect(texcoor.length*4);
tbb.order(ByteOrder.nativeOrder());
mTexCoorBuffer=tbb.asFloatBuffer();
mTexCoorBuffer.put(texcoor);
mTexCoorBuffer.position(0);
}
//初始化着色器程序的initShader方法
public void initShader(int programId)
{
mProgram=programId;
//获得顶点坐标数据的引用
maPositionHandle=GLES20.glGetAttribLocation(mProgram, "aPosition");
//顶点纹理坐标的引用id
maTexCoorHandle=GLES20.glGetAttribLocation(mProgram, "aTexCoor");
muMVPMatrixHandle=GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
}
//自定义的绘制方法
public void drawSelf(int texId)
{
//使用某套指定的Shader程序
GLES20.glUseProgram(mProgram);
//将最终变换矩阵传入到Shader程序中
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//传入顶点坐标数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入纹理坐标数据
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false,
2*4,
mTexCoorBuffer
);
//允许顶点位置数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
//绘制纹理矩形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
//自动切分纹理产生纹理数组的方法,triangleSize表示的是切分的三角形份数
public float[] generateTexCoor(float angle_span,float width,float height)
{
float[] result=new float[(int) (360/angle_span*3*2)];
int c=0;
for(float i=0;i<360;i=i+angle_span)
{
result[c++]=0.5f*width;
result[c++]=0.5f*height;
result[c++]=(float) (0.5f+0.5f*Math.cos(Math.toRadians(i)))*width;
result[c++]=(float) (0.5f-0.5f*Math.sin(Math.toRadians(i)))*height;
result[c++]=(float) (0.5f+0.5f*Math.cos(Math.toRadians(i+angle_span)))*width;
result[c++]=(float) (0.5f-0.5f*Math.sin(Math.toRadians(i+angle_span)))*height;
}
return result;
}
}
}

View File

@@ -0,0 +1,631 @@
package com.bn.clp;
import static com.bn.clp.Constant.*;
public class TreeData
{
//树的相关数据列表
static float[][] Tree_Data=new float[][]
{
//2-28横
{3, UNIT_SIZE*28f+10, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+UNIT_SIZE/3, 2, 28}, //树4
{3, UNIT_SIZE*28f+10, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+-UNIT_SIZE/3, 2, 28}, //树4
{3, UNIT_SIZE*28f+30, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+UNIT_SIZE/3, 2, 28}, //树4
{3, UNIT_SIZE*28f+30, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+-UNIT_SIZE/3, 2, 28}, //树4
//2-26横
{3, UNIT_SIZE*26f+10, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+UNIT_SIZE/3, 2, 26}, //树4
{3, UNIT_SIZE*26f+10, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+-UNIT_SIZE/3, 2, 26}, //树4
{3, UNIT_SIZE*26f+30, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+UNIT_SIZE/3, 2, 26}, //树4
{3, UNIT_SIZE*26f+30, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+-UNIT_SIZE/3, 2, 26}, //树4
//2-5横
{3, UNIT_SIZE*5f+10, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+UNIT_SIZE/3, 2, 5}, //树4
{3, UNIT_SIZE*5f+10, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+-UNIT_SIZE/3, 2, 5}, //树4
{3, UNIT_SIZE*5f+30, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+UNIT_SIZE/3, 2, 5}, //树4
{3, UNIT_SIZE*5f+30, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+-UNIT_SIZE/3, 2, 5}, //树4
//13-18
{3, UNIT_SIZE*18f+10, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*13+UNIT_SIZE/3, 13, 18}, //树4
{3, UNIT_SIZE*18f+10, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*13+-UNIT_SIZE/3, 13, 18}, //树4
{3, UNIT_SIZE*18f+30, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*13+UNIT_SIZE/3, 13, 18}, //树4
{3, UNIT_SIZE*18f+30, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*13+-UNIT_SIZE/3, 13, 18}, //树4
//0-3横
{0, UNIT_SIZE*2f+45, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE/3, 0, 3}, //树1
{0, UNIT_SIZE*2f+45, WATER_HIGH_ADJUST+1.5f, -UNIT_SIZE/3, 0, 3}, //树1
{1, UNIT_SIZE*2f+65, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE/3, 0, 3}, //树2
{1, UNIT_SIZE*2f+65, WATER_HIGH_ADJUST+1.5f, -UNIT_SIZE/3, 0, 3}, //树2
{0, UNIT_SIZE*2f+85, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE/3, 0, 3}, //树3
{0, UNIT_SIZE*2f+85, WATER_HIGH_ADJUST+1.5f, -UNIT_SIZE/3, 0, 3}, //树3
//0-0弯道4
{3, UNIT_SIZE*0f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*0-10, 0, 0}, //树4
{3, UNIT_SIZE*0f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*0+10, 0, 0}, //树4
//2-9
{3, UNIT_SIZE*9f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2-10, 2, 9}, //树4
{3, UNIT_SIZE*9f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+10, 2, 9}, //树4
//4-11
{3, UNIT_SIZE*11f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*4-10, 4, 11}, //树4
{3, UNIT_SIZE*11f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*4+10, 4, 11}, //树4
//9-11
{3, UNIT_SIZE*11f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*9-10, 9, 11}, //树4
{3, UNIT_SIZE*11f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*9+10, 9, 11}, //树4
//12-12
{3, UNIT_SIZE*12f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*12-10, 12, 12}, //树4
{3, UNIT_SIZE*12f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*12+10, 12, 12}, //树4
//13-16
{3, UNIT_SIZE*16f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*13-10, 13, 16}, //树4
{3, UNIT_SIZE*16f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*13+10, 13, 16}, //树4
//12-19
{3, UNIT_SIZE*19f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*12-10, 12, 19}, //树4
{3, UNIT_SIZE*19f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*12+10, 12, 19}, //树4
//9-20
{3, UNIT_SIZE*20f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*9-10, 9, 20}, //树4
{3, UNIT_SIZE*20f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*9+10, 9, 20}, //树4
//4-20
{3, UNIT_SIZE*20f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*4-10, 4, 20}, //树4
{3, UNIT_SIZE*20f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*4+10, 4, 20}, //树4
//2-25
{3, UNIT_SIZE*25f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2-10, 2, 25}, //树4
{3, UNIT_SIZE*25f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+10, 2, 25}, //树4
//5-28
{3, UNIT_SIZE*28f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*5-10, 5, 28}, //树4
{3, UNIT_SIZE*28f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*5+10, 5, 28}, //树4
//6-26
{3, UNIT_SIZE*26f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*6-10, 6, 26}, //树4
{3, UNIT_SIZE*26f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*6+10, 6, 26}, //树4
//11-26
{3, UNIT_SIZE*26f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*11-10, 11, 26}, //树4
{3, UNIT_SIZE*26f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*11+10, 11, 26}, //树4
//12-25
{3, UNIT_SIZE*25f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*12-10, 12, 25}, //树4
{3, UNIT_SIZE*25f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*12+10, 12, 25}, //树4
//17-25
{3, UNIT_SIZE*25f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*17-10, 17, 25}, //树4
{3, UNIT_SIZE*25f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*17+10, 17, 25}, //树4
//21-24
{3, UNIT_SIZE*24f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*21-10, 21, 24}, //树4
{3, UNIT_SIZE*24f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*21+10, 21, 24}, //树4
//26-24
{3, UNIT_SIZE*24f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*26-10, 26, 24}, //树4
{3, UNIT_SIZE*24f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*26+10, 26, 24}, //树4
//28-22
{3, UNIT_SIZE*22f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*28-10, 28, 22}, //树4
{3, UNIT_SIZE*22f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*28+10, 28, 22}, //树4
//28-20
{3, UNIT_SIZE*20f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*28-10, 28, 20}, //树4
{3, UNIT_SIZE*20f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*28+10, 28, 20}, //树4
//24-15
{3, UNIT_SIZE*15f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*24-10, 24, 15}, //树4
{3, UNIT_SIZE*15f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*24+10, 24, 15}, //树4
//20-11
{3, UNIT_SIZE*11f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*20-10, 20, 11}, //树4
{3, UNIT_SIZE*11f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*20+10, 20, 11}, //树4
//23-10
{3, UNIT_SIZE*10f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*23-10, 23, 10}, //树4
{3, UNIT_SIZE*10f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*23+10, 23, 10}, //树4
//26-9
{3, UNIT_SIZE*9f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*26-10, 26, 9}, //树4
{3, UNIT_SIZE*9f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*26+10, 26, 9}, //树4
//27-8
{3, UNIT_SIZE*8f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*27-10, 27, 8}, //树4
{3, UNIT_SIZE*8f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*27+10, 27, 8}, //树4
//28-6
{3, UNIT_SIZE*6f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*28-10, 28, 6}, //树4
{3, UNIT_SIZE*6f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*28+10, 28, 6}, //树4
//25-1
{3, UNIT_SIZE*1f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*25-10, 25, 1}, //树4
{3, UNIT_SIZE*1f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*25+10, 25, 1}, //树4
//23-2
{3, UNIT_SIZE*2f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*23-10, 23, 2}, //树4
{3, UNIT_SIZE*2f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*23+10, 23, 2}, //树4
//19-1
{3, UNIT_SIZE*1f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*19-10, 19, 1}, //树4
{3, UNIT_SIZE*1f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*19+10, 19, 1}, //树4
//15-1
{3, UNIT_SIZE*1f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*15-10, 15, 1}, //树4
{3, UNIT_SIZE*1f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*15+10, 15, 1}, //树4
//13-1
{3, UNIT_SIZE*1f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*13-10, 13, 1}, //树4
{3, UNIT_SIZE*1f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*13+10, 13, 1}, //树4
//8-2
{3, UNIT_SIZE*2f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*8-10, 8, 2}, //树4
{3, UNIT_SIZE*2f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*8+10, 8, 2}, //树4
//弯道5的数据=============================================================
//0-4弯道5
{2, UNIT_SIZE*4f-3, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*0-10, 0, 4}, //树4
{2, UNIT_SIZE*4f+13, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*0+10, 0, 4}, //树4
//2-8
{2, UNIT_SIZE*8f-3, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2-10, 2, 8}, //树4
{2, UNIT_SIZE*8f+13, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+10, 2, 8}, //树4
//2-15
{2, UNIT_SIZE*15f-3, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2-10, 2, 15}, //树4
{2, UNIT_SIZE*15f+13, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+10, 2, 15}, //树4
//7-12
{2, UNIT_SIZE*12f-3, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*7-10, 7, 12}, //树4
{2, UNIT_SIZE*12f+13, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*7+10, 7, 12}, //树4
//12-13
{2, UNIT_SIZE*13f-3, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*12-10, 12, 13}, //树4
{2, UNIT_SIZE*13f+13, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*12+10, 12, 13}, //树4
//13-15
{2, UNIT_SIZE*15f-3, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*13-10, 13, 15}, //树4
{2, UNIT_SIZE*15f+13, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*13+10, 13, 15}, //树4
//7-21
{2, UNIT_SIZE*21f-3, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*7-10, 7, 21}, //树4
{2, UNIT_SIZE*21f+13, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*7+10, 7, 21}, //树4
//4-21
{2, UNIT_SIZE*21f-3, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*4-10, 4, 21}, //树4
{2, UNIT_SIZE*21f+13, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*4+10, 4, 21}, //树4
//2-29
{2, UNIT_SIZE*29f-3, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2-10, 2, 29}, //树4
{2, UNIT_SIZE*29f+13, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+10, 2, 29}, //树4
//10-28
{2, UNIT_SIZE*28f-3, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*10-10, 10, 28}, //树4
{2, UNIT_SIZE*28f+13, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*10+10, 10, 28}, //树4
//15-26
{2, UNIT_SIZE*26f-3, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*15-10, 15, 26}, //树4
{2, UNIT_SIZE*26f+13, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*15+10, 15, 26}, //树4
//19-26
{2, UNIT_SIZE*26f-3, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*19-10, 19, 26}, //树4
{2, UNIT_SIZE*26f+13, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*19+10, 19, 26}, //树4
//21-25
{2, UNIT_SIZE*25f-3, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*21-10, 21, 25}, //树4
{2, UNIT_SIZE*25f+13, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*21+10, 21, 25}, //树4
//25-25
{2, UNIT_SIZE*25f-3, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*25-10, 25, 25}, //树4
{2, UNIT_SIZE*25f+13, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*25+10, 25, 25}, //树4
//28-23
{2, UNIT_SIZE*23f-3, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*28-10, 28, 23}, //树4
{2, UNIT_SIZE*23f+13, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*28+10, 28, 23}, //树4
//28-21
{2, UNIT_SIZE*21f-3, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*28-10, 28, 21}, //树4
{2, UNIT_SIZE*21f+13, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*28+10, 28, 21}, //树4
//28-19
{2, UNIT_SIZE*19f-3, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*28-10, 28, 19}, //树4
{2, UNIT_SIZE*19f+13, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*28+10, 28,19}, //树4
//20-16
{2, UNIT_SIZE*16f-3, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*20-10, 20, 16}, //树4
{2, UNIT_SIZE*16f+13, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*20+10, 20, 16}, //树4
//29-5
{2, UNIT_SIZE*5f-3, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*29-10, 29, 5}, //树4
{2, UNIT_SIZE*5f+13, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*29+10, 29, 5}, //树4
//26-2
{2, UNIT_SIZE*2f-3, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*26-10, 26, 2}, //树4
{2, UNIT_SIZE*2f+13, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*26+10, 26, 2}, //树4
//22-3
{2, UNIT_SIZE*3f-3, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*22-10, 22, 3}, //树4
{2, UNIT_SIZE*3f+13, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*22+10, 22, 3}, //树4
//21-2
{2, UNIT_SIZE*2f-3, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*21-10, 21, 2}, //树4
{2, UNIT_SIZE*2f+13, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*21+10, 21, 2}, //树4
//18-2
{2, UNIT_SIZE*2f-3, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*18-10, 18, 2}, //树4
{2, UNIT_SIZE*2f+13, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*18+10, 18, 2}, //树4
//14-2
{2, UNIT_SIZE*2f-3, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*14-10, 14, 2}, //树4
{2, UNIT_SIZE*2f+13, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*14+10, 14, 2}, //树4
//7-3
{2, UNIT_SIZE*3f-3, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*7-10, 7, 3}, //树4
{2, UNIT_SIZE*3f+13, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*7+10, 7, 3}, //树4
//3-2
{2, UNIT_SIZE*2f-3, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*3-10, 3, 2}, //树4
{2, UNIT_SIZE*2f+13, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*3+10, 3, 2}, //树4
//3-0弯道6========================
{3, UNIT_SIZE*0f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*3+10, 3, 0}, //树4
{3, UNIT_SIZE*0f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*3-10, 3, 0}, //树4
//2-4
{3, UNIT_SIZE*4f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+10, 2, 4}, //树4
{3, UNIT_SIZE*4f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2-10, 2, 4}, //树4
//3-8
{3, UNIT_SIZE*8f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*3+10, 3, 8}, //树4
{3, UNIT_SIZE*8f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*3-10, 3, 8}, //树4
//7-11
{3, UNIT_SIZE*11f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*7+10, 7, 11}, //树4
{3, UNIT_SIZE*11f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*7-10, 7, 11}, //树4
//13-11
{3, UNIT_SIZE*11f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*13+10, 13, 11}, //树4
{3, UNIT_SIZE*11f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*13-10, 13, 11}, //树4
//13-13
{3, UNIT_SIZE*13f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*13+10, 13, 13}, //树4
{3, UNIT_SIZE*13f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*13-10, 13, 13}, //树4
//14-15
{3, UNIT_SIZE*15f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*14+10, 14, 15}, //树4
{3, UNIT_SIZE*15f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*14-10, 14, 15}, //树4
//7-20
{3, UNIT_SIZE*20f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*7+10, 7, 20}, //树4
{3, UNIT_SIZE*20f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*7-10, 7, 20}, //树4
//5-21
{3, UNIT_SIZE*21f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*5+10, 5, 21}, //树4
{3, UNIT_SIZE*21f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*5-10, 5, 21}, //树4
//10-26
{3, UNIT_SIZE*26f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*10+10, 10, 26}, //树4
{3, UNIT_SIZE*26f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*10-10, 10, 26}, //树4
//15-25
{3, UNIT_SIZE*25f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*15+10, 15, 25}, //树4
{3, UNIT_SIZE*25f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*15-10, 15, 25}, //树4
//19-25
{3, UNIT_SIZE*25f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*19+10, 19, 25}, //树4
{3, UNIT_SIZE*25f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*19-10, 19, 25}, //树4
//23-25
{3, UNIT_SIZE*25f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*23+10, 23, 25}, //树4
{3, UNIT_SIZE*25f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*23-10, 23, 25}, //树4
//25-24
{3, UNIT_SIZE*24f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*25+10, 25, 24}, //树4
{3, UNIT_SIZE*24f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*25-10, 25, 24}, //树4
//29-23
{3, UNIT_SIZE*23f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*29+10, 29, 23}, //树4
{3, UNIT_SIZE*23f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*29-10, 29, 23}, //树4
//29-21
{3, UNIT_SIZE*21f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*29+10, 29, 21}, //树4
{3, UNIT_SIZE*21f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*29-10, 29, 21}, //树4
//29-19
{3, UNIT_SIZE*19f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*29+10, 29, 19}, //树4
{3, UNIT_SIZE*19f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*29-10, 29, 19}, //树4
//28-15
{3, UNIT_SIZE*15f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*28+10, 28, 15}, //树4
{3, UNIT_SIZE*15f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*28-10, 28, 15}, //树4
//30-5
{3, UNIT_SIZE*5f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*30+10, 30, 5}, //树4
{3, UNIT_SIZE*5f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*30-10, 30, 5}, //树4
//29-2
{3, UNIT_SIZE*2f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*29+10, 29, 2}, //树4
{3, UNIT_SIZE*2f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*29-10, 29, 2}, //树4
//26-1
{3, UNIT_SIZE*1f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*26+10, 26, 1}, //树4
{3, UNIT_SIZE*1f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*26-10, 26, 1}, //树4
//22-2
{3, UNIT_SIZE*2f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*22+10, 22, 2}, //树4
{3, UNIT_SIZE*2f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*22-10, 22, 2}, //树4
//21-1
{3, UNIT_SIZE*1f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*21+10, 21, 1}, //树4
{3, UNIT_SIZE*1f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*21-10, 21, 1}, //树4
//18-1
{3, UNIT_SIZE*1f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*18+10, 18, 1}, //树4
{3, UNIT_SIZE*1f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*18-10, 18, 1}, //树4
//14-1
{3, UNIT_SIZE*1f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*14+10, 14, 1}, //树4
{3, UNIT_SIZE*1f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*14-10, 14, 1}, //树4
//7-2
{3, UNIT_SIZE*2f-4, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*7+10, 7, 2}, //树4
{3, UNIT_SIZE*2f-19, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*7-10, 7, 2}, //树4
//3-9弯道7=========================
{3, UNIT_SIZE*9f-1, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*3+10, 3, 9}, //树4
{3, UNIT_SIZE*9f+14, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*3-10, 3, 9}, //树4
//4-16
{3, UNIT_SIZE*16f-1, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*4+10, 4, 16}, //树4
{3, UNIT_SIZE*16f+14, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*4-10, 4, 16}, //树4
//9-12
{3, UNIT_SIZE*12f-1, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*9+10, 9, 12}, //树4
{3, UNIT_SIZE*12f+14, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*9-10, 9, 12}, //树4
//13-12
{3, UNIT_SIZE*12f-1, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*13+10, 13, 12}, //树4
{3, UNIT_SIZE*12f+14, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*13-10, 13, 12}, //树4
//14-16
{3, UNIT_SIZE*16f-1, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*14+10, 14, 16}, //树4
{3, UNIT_SIZE*16f+14, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*14-10, 14, 16}, //树4
//13-19
{3, UNIT_SIZE*19f-1, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*13+10, 13, 19}, //树4
{3, UNIT_SIZE*19f+14, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*13-10, 13, 19}, //树4
//12-20
{3, UNIT_SIZE*20f-1, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*12+10, 12, 20}, //树4
{3, UNIT_SIZE*20f+14, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*12-10, 12, 20}, //树4
//9-21
{3, UNIT_SIZE*21f-1, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*9+10, 9, 21}, //树4
{3, UNIT_SIZE*21f+14, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*9-10, 9, 21}, //树4
//5-25
{3, UNIT_SIZE*25f-1, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*5+10, 5, 25}, //树4
{3, UNIT_SIZE*25f+14, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*5-10, 5, 25}, //树4
//5-29
{3, UNIT_SIZE*29f-1, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*5+10, 5, 29}, //树4
{3, UNIT_SIZE*29f+14, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*5-10, 5, 29}, //树4
//6-28
{3, UNIT_SIZE*28f-1, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*6+10, 6, 28}, //树4
{3, UNIT_SIZE*28f+14, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*6-10, 6, 28}, //树4
//11-27
{3, UNIT_SIZE*27f-1, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*11+10, 11, 27}, //树4
{3, UNIT_SIZE*27f+14, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*11-10, 11, 27}, //树4
//12-26
{3, UNIT_SIZE*26f-1, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*12+10, 12, 26}, //树4
{3, UNIT_SIZE*26f+14, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*12-10, 12, 26}, //树4
//17-26
{3, UNIT_SIZE*26f-1, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*17+10, 17, 26}, //树4
{3, UNIT_SIZE*26f+14, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*17-10, 17, 26}, //树4
//23-26
{3, UNIT_SIZE*26f-1, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*23+10, 23, 26}, //树4
{3, UNIT_SIZE*26f+14, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*23-10, 23, 26}, //树4
//26-25
{3, UNIT_SIZE*25f-1, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*26+10, 26, 25}, //树4
{3, UNIT_SIZE*25f+14, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*26-10, 26, 25}, //树4
//29-24
{3, UNIT_SIZE*24f-1, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*29+10, 29, 24}, //树4
{3, UNIT_SIZE*24f+14, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*29-10, 29, 24}, //树4
//29-22
{3, UNIT_SIZE*22f-1, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*29+10, 29, 22}, //树4
{3, UNIT_SIZE*22f+14, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*29-10, 29, 22}, //树4
//29-20
{3, UNIT_SIZE*20f-1, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*29+10, 29, 20}, //树4
{3, UNIT_SIZE*20f+14, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*29-10, 29, 20}, //树4
//24-16
{3, UNIT_SIZE*16f-1, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*24+10, 24, 16}, //树4
{3, UNIT_SIZE*16f+14, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*24-10, 24, 16}, //树4
//23-11
{3, UNIT_SIZE*11f-1, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*23+10, 23, 11}, //树4
{3, UNIT_SIZE*11f+14, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*23-10, 23, 11}, //树4
//26-10
{3, UNIT_SIZE*10f-1, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*26+10, 26, 10}, //树4
{3, UNIT_SIZE*10f+14, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*26-10, 26, 10}, //树4
//27-9
{3, UNIT_SIZE*9f-1, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*27+10, 27, 9}, //树4
{3, UNIT_SIZE*9f+14, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*27-10, 27, 9}, //树4
//28-8
{3, UNIT_SIZE*8f-1, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*28+10, 28, 8}, //树4
{3, UNIT_SIZE*8f+14, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*28-10, 28, 8}, //树4
//30-6
{3, UNIT_SIZE*6f-1, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*30+10, 30, 6}, //树4
{3, UNIT_SIZE*6f+14, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*30-10, 30, 6}, //树4
//25-2
{3, UNIT_SIZE*2f-1, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*25+10, 25, 2}, //树4
{3, UNIT_SIZE*2f+14, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*25-10, 25, 2}, //树4
//23-3
{3, UNIT_SIZE*3f-1, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*23+10, 23, 3}, //树4
{3, UNIT_SIZE*3f+14, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*23-10, 23, 3}, //树4
//19-2
{3, UNIT_SIZE*2f-1, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*19+10, 19, 2}, //树4
{3, UNIT_SIZE*2f+14, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*19-10, 19, 2}, //树4
//15-2
{3, UNIT_SIZE*2f-1, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*15+10, 15, 2}, //树4
{3, UNIT_SIZE*2f+14, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*15-10, 15, 2}, //树4
//13-2
{3, UNIT_SIZE*2f-1, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*13+10, 13, 2}, //树4
{3, UNIT_SIZE*2f+14, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*13-10, 13, 2}, //树4
//8-3
{3, UNIT_SIZE*3f-1, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*8+10, 8, 3}, //树4
{3, UNIT_SIZE*3f+14, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*8-10, 8, 3}, //树4
//1-4带半崖子的竖直赛道
{2, UNIT_SIZE*4f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*1-30, 1, 4}, //树4
{2, UNIT_SIZE*4f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*1-30, 1, 4}, //树4
{3, UNIT_SIZE*4f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*1-10, 1, 4}, //树4
{3, UNIT_SIZE*4f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*1-10, 1, 4}, //树4
{2, UNIT_SIZE*4f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*1+10, 1, 4}, //树4
{2, UNIT_SIZE*4f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*1+10, 1, 4}, //树4
{3, UNIT_SIZE*4f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*1+30, 1, 4}, //树4
{3, UNIT_SIZE*4f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*1+30, 1, 4}, //树4
{2, UNIT_SIZE*6f+20, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+UNIT_SIZE/3, 2, 6}, //树4
{2, UNIT_SIZE*6f+20, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+-UNIT_SIZE/3, 2, 6}, //树4
{3, UNIT_SIZE*6f+40, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+UNIT_SIZE/3, 2, 6}, //树4
{3, UNIT_SIZE*6f+40, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+-UNIT_SIZE/3, 2, 6}, //树4
{1, UNIT_SIZE*7f+20, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+UNIT_SIZE/3, 2, 7}, //树4
{1, UNIT_SIZE*7f+20, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+-UNIT_SIZE/3, 2, 7}, //树4
{3, UNIT_SIZE*11f-20, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+UNIT_SIZE/3, 2, 11}, //树4
{3, UNIT_SIZE*11f-20, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+-UNIT_SIZE/3, 2, 11}, //树4
{0, UNIT_SIZE*11f, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+UNIT_SIZE/3, 2, 11}, //树4
{0, UNIT_SIZE*11f, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+-UNIT_SIZE/3, 2, 11}, //树4
{3, UNIT_SIZE*11f+20, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+UNIT_SIZE/3, 2, 11}, //树4
{3, UNIT_SIZE*11f+20, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+-UNIT_SIZE/3, 2, 11}, //树4
{0, UNIT_SIZE*11f+40, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+UNIT_SIZE/3, 2, 11}, //树4
{0, UNIT_SIZE*11f+40, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+-UNIT_SIZE/3, 2, 11}, //树4
{1, UNIT_SIZE*13f+20, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+UNIT_SIZE/3, 2, 13}, //树4
{1, UNIT_SIZE*13f+20, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+-UNIT_SIZE/3, 2, 13}, //树4
{3, UNIT_SIZE*13f+40, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+UNIT_SIZE/3, 2, 13}, //树4
{3, UNIT_SIZE*13f+40, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*2+-UNIT_SIZE/3, 2, 13}, //树4
{3, UNIT_SIZE*14f, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*4+UNIT_SIZE/3, 4, 14}, //树4
{3, UNIT_SIZE*14f, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*4+-UNIT_SIZE/3, 4, 14}, //树4
{0, UNIT_SIZE*14f+20, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*4+UNIT_SIZE/3, 4, 14}, //树4
{0, UNIT_SIZE*14f+20, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*4+-UNIT_SIZE/3, 4, 14}, //树4
{3, UNIT_SIZE*12f+20, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*4+UNIT_SIZE/3, 4, 12}, //树4
{3, UNIT_SIZE*12f+20, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*4+-UNIT_SIZE/3, 4, 12}, //树4
{3, UNIT_SIZE*12f+40, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*4+UNIT_SIZE/3, 4, 12}, //树4
{3, UNIT_SIZE*12f+40, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*4+-UNIT_SIZE/3, 4, 12}, //树4
{3, UNIT_SIZE*12f+60, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*4+UNIT_SIZE/3, 4, 12}, //树4
{3, UNIT_SIZE*12f+60, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*4+-UNIT_SIZE/3, 4, 12}, //树4
//5-11竖直
{3, UNIT_SIZE*11f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*5+10, 5, 11}, //树4
{3, UNIT_SIZE*11f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*5+10, 5, 11}, //树4
{3, UNIT_SIZE*11f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*5+30, 5, 11}, //树4
{3, UNIT_SIZE*11f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*5+30, 5, 11}, //树4
//6-11竖直
{3, UNIT_SIZE*11f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*6+10, 6, 11}, //树4
{3, UNIT_SIZE*11f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*6+10, 6, 11}, //树4
{3, UNIT_SIZE*11f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*6+30, 6, 11}, //树4
{3, UNIT_SIZE*11f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*6+30, 6, 11}, //树4
//8-12竖直
{3, UNIT_SIZE*12f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*8+10, 8, 12}, //树4
{3, UNIT_SIZE*12f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*8+10, 8, 12}, //树4
{3, UNIT_SIZE*12f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*8+30, 8, 12}, //树4
{3, UNIT_SIZE*12f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*8+30, 8, 12}, //树4
//12-11竖直
{3, UNIT_SIZE*11f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*12+10, 12, 11}, //树4
{3, UNIT_SIZE*11f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*12+10, 12, 11}, //树4
{3, UNIT_SIZE*11f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*12+30, 12, 11}, //树4
{3, UNIT_SIZE*11f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*12+30, 12, 11}, //树4
//11-20竖直
{3, UNIT_SIZE*20f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*11+10, 11, 20}, //树4
{3, UNIT_SIZE*20f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*11+10, 11, 20}, //树4
{3, UNIT_SIZE*20f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*11+30, 11, 20}, //树4
{3, UNIT_SIZE*20f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*11+30, 11, 20}, //树4
//10-20竖直
{3, UNIT_SIZE*20f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*10+10, 10, 20}, //树4
{3, UNIT_SIZE*20f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*10+10, 10, 20}, //树4
{3, UNIT_SIZE*20f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*10+30, 10, 20}, //树4
{3, UNIT_SIZE*20f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*10+30, 10, 20}, //树4
//8-21竖直
{3, UNIT_SIZE*21f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*8+10, 8, 21}, //树4
{3, UNIT_SIZE*21f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*8+10, 8, 21}, //树4
{3, UNIT_SIZE*21f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*8+30, 8, 21}, //树4
{3, UNIT_SIZE*21f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*8+30, 8, 21}, //树4
//5-22横
{3, UNIT_SIZE*22f+20, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*5+UNIT_SIZE/3, 5, 22}, //树4
{3, UNIT_SIZE*22f+20, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*5+-UNIT_SIZE/3, 5, 22}, //树4
{3, UNIT_SIZE*22f+40, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*5+UNIT_SIZE/3, 5, 22}, //树4
{3, UNIT_SIZE*22f+40, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*5+-UNIT_SIZE/3, 5, 22}, //树4
//5-24横
{3, UNIT_SIZE*24f+10, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*5+UNIT_SIZE/3, 5, 24}, //树4
{3, UNIT_SIZE*24f+10, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*5+-UNIT_SIZE/3, 5, 24}, //树4
{3, UNIT_SIZE*24f+20, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*5+UNIT_SIZE/3, 5, 24}, //树4
{3, UNIT_SIZE*24f+20, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*5+-UNIT_SIZE/3, 5, 24}, //树4
//4-25竖直
{3, UNIT_SIZE*25f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*4+10, 4, 25}, //树4
{3, UNIT_SIZE*25f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*4+10, 4, 25}, //树4
{3, UNIT_SIZE*25f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*4+30, 4, 25}, //树4
{3, UNIT_SIZE*25f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*4+30, 4, 25}, //树4
//3-29竖直
{3, UNIT_SIZE*29f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*3+20, 3, 29}, //树4
{3, UNIT_SIZE*29f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*3+20, 3, 29}, //树4
{3, UNIT_SIZE*29f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*3+40, 3, 29}, //树4
{3, UNIT_SIZE*29f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*3+40, 3, 29}, //树4
//6-27横
{3, UNIT_SIZE*27f+10, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*6+UNIT_SIZE/3, 6, 27}, //树4
{3, UNIT_SIZE*27f+10, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*6+-UNIT_SIZE/3, 6, 27}, //树4
{3, UNIT_SIZE*27f+30, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*6+UNIT_SIZE/3, 6, 27}, //树4
{3, UNIT_SIZE*27f+30, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*6+-UNIT_SIZE/3, 6, 27}, //树4
//9-26竖直
{3, UNIT_SIZE*26f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*9+10, 9, 26}, //树4
{3, UNIT_SIZE*26f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*9+10, 9, 26}, //树4
{3, UNIT_SIZE*26f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*9+30, 9, 26}, //树4
{3, UNIT_SIZE*26f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*9+30, 9, 26}, //树4
//13-25竖直
{3, UNIT_SIZE*25f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*13+10, 13, 25}, //树4
{3, UNIT_SIZE*25f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*13+10, 13, 25}, //树4
{3, UNIT_SIZE*25f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*13+30, 13, 25}, //树4
{3, UNIT_SIZE*25f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*13+30, 13, 25}, //树4
//14-25竖直
{3, UNIT_SIZE*25f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*14+10, 14, 25}, //树4
{3, UNIT_SIZE*25f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*14+10, 14, 25}, //树4
{3, UNIT_SIZE*25f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*14+30, 14, 25}, //树4
{3, UNIT_SIZE*25f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*14+30, 14, 25}, //树4
//16-26竖直
{3, UNIT_SIZE*26f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*16+10, 16, 26}, //树4
{3, UNIT_SIZE*26f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*16+10, 16, 26}, //树4
{3, UNIT_SIZE*26f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*16+30, 16, 26}, //树4
{3, UNIT_SIZE*26f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*16+30, 16, 26}, //树4
//18-25竖直
{3, UNIT_SIZE*25f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*18+10, 18, 25}, //树4
{3, UNIT_SIZE*25f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*18+10, 18, 25}, //树4
{3, UNIT_SIZE*25f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*18+20, 18, 25}, //树4
{3, UNIT_SIZE*25f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*18+20, 18, 25}, //树4
//24-24竖直
{3, UNIT_SIZE*24f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*24+10, 24, 24}, //树4
{3, UNIT_SIZE*24f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*24+10, 24, 24}, //树4
{3, UNIT_SIZE*24f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*24+30, 24, 24}, //树4
{3, UNIT_SIZE*24f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*24+30, 24, 24}, //树4
//27-24竖直
{3, UNIT_SIZE*24f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*27+10, 27, 24}, //树4
{3, UNIT_SIZE*24f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*27+10, 27, 24}, //树4
{3, UNIT_SIZE*24f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*27+30, 27, 24}, //树4
{3, UNIT_SIZE*24f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*27+30, 27, 24}, //树4
//28-24竖直
{3, UNIT_SIZE*24f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*28+10, 28, 24}, //树4
{3, UNIT_SIZE*24f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*28+10, 28, 24}, //树4
{3, UNIT_SIZE*24f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*28+30, 28, 24}, //树4
{3, UNIT_SIZE*24f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*28+30, 28, 24}, //树4
//26-15竖直
{3, UNIT_SIZE*15f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*26+10, 26, 15}, //树4
{3, UNIT_SIZE*15f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*26+10, 26, 15}, //树4
{3, UNIT_SIZE*15f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*26+30, 26, 15}, //树4
{3, UNIT_SIZE*15f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*26+30, 26, 15}, //树4
//25-15竖直
{3, UNIT_SIZE*15f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*25+10, 25, 15}, //树4
{3, UNIT_SIZE*15f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*25+10, 25, 15}, //树4
{3, UNIT_SIZE*15f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*25+30, 25, 15}, //树4
{3, UNIT_SIZE*15f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*25+30, 25, 15}, //树4
//23-16竖直
{3, UNIT_SIZE*16f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*23+10, 23, 16}, //树4
{3, UNIT_SIZE*16f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*23+10, 23, 16}, //树4
{3, UNIT_SIZE*16f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*23+30, 23, 16}, //树4
{3, UNIT_SIZE*16f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*23+30, 23, 16}, //树4
//20-13横
{3, UNIT_SIZE*13f+20, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*20+UNIT_SIZE/3, 20, 13}, //树4
{3, UNIT_SIZE*13f+20, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*20+-UNIT_SIZE/3, 20, 13}, //树4
{3, UNIT_SIZE*13f+40, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*20+UNIT_SIZE/3, 20, 13}, //树4
{3, UNIT_SIZE*13f+40, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*20+-UNIT_SIZE/3, 20, 13}, //树4
//20-14横
{3, UNIT_SIZE*14f+20, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*20+UNIT_SIZE/3, 20, 14}, //树4
{3, UNIT_SIZE*14f+20, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*20+-UNIT_SIZE/3, 20, 14}, //树4
{3, UNIT_SIZE*14f+40, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*20+UNIT_SIZE/3, 20, 14}, //树4
{3, UNIT_SIZE*14f+40, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*20+-UNIT_SIZE/3, 20, 14}, //树4
//21-11竖直
{3, UNIT_SIZE*11f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*21+10, 21, 11}, //树4
{3, UNIT_SIZE*11f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*21+10, 21, 11}, //树4
{3, UNIT_SIZE*11f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*21+30, 21, 11}, //树4
{3, UNIT_SIZE*11f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*21+30, 21, 11}, //树4
//22-11竖直
{3, UNIT_SIZE*11f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*22+10, 22, 11}, //树4
{3, UNIT_SIZE*11f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*22+10, 22, 11}, //树4
{3, UNIT_SIZE*11f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*22+30, 22, 11}, //树4
{3, UNIT_SIZE*11f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*22+30, 22, 11}, //树4
//24-10竖直
{3, UNIT_SIZE*10f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*24+10, 24, 10}, //树4
{3, UNIT_SIZE*10f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*24+10, 24, 10}, //树4
{3, UNIT_SIZE*10f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*24+30, 24, 10}, //树4
{3, UNIT_SIZE*10f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*24+30, 24, 10}, //树4
//25-10竖直
{3, UNIT_SIZE*10f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*25+10, 25, 10}, //树4
{3, UNIT_SIZE*10f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*25+10, 25, 10}, //树4
{3, UNIT_SIZE*10f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*25+30, 25, 10}, //树4
{3, UNIT_SIZE*10f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*25+30, 25, 10}, //树4
//29-3横
{3, UNIT_SIZE*3f+20, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*29+UNIT_SIZE/3, 29, 3}, //树4
{3, UNIT_SIZE*3f+20, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*29+-UNIT_SIZE/3, 29, 3}, //树4
{3, UNIT_SIZE*3f+40, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*29+UNIT_SIZE/3, 29, 3}, //树4
{3, UNIT_SIZE*3f+40, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*29+-UNIT_SIZE/3, 29, 3}, //树4
{3, UNIT_SIZE*3f+60, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*29+UNIT_SIZE/3, 29, 3}, //树4
{3, UNIT_SIZE*3f+60, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*29+-UNIT_SIZE/3, 29, 3}, //树4
//29-4横
{3, UNIT_SIZE*4f+10, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*29+UNIT_SIZE/3, 29, 4}, //树4
{3, UNIT_SIZE*4f+10, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*29+-UNIT_SIZE/3, 29, 4}, //树4
{3, UNIT_SIZE*4f+30, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*29+UNIT_SIZE/3, 29, 4}, //树4
{3, UNIT_SIZE*4f+30, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*29+-UNIT_SIZE/3, 29, 4}, //树4
//27-2竖直
{3, UNIT_SIZE*2f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*27+10, 27, 2}, //树4
{3, UNIT_SIZE*2f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*27+10, 27, 2}, //树4
{3, UNIT_SIZE*2f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*27+30, 27, 2}, //树4
{3, UNIT_SIZE*2f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*27+30, 27, 2}, //树4
//24-2竖直
{3, UNIT_SIZE*2f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*24+10, 24, 2}, //树4
{3, UNIT_SIZE*2f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*24+10, 24, 2}, //树4
{3, UNIT_SIZE*2f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*24+30, 24, 2}, //树4
{3, UNIT_SIZE*2f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*24+30, 24, 2}, //树4
//20-1竖直
{3, UNIT_SIZE*1f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*20+10, 20, 1}, //树4
{3, UNIT_SIZE*1f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*20+10, 20, 1}, //树4
{3, UNIT_SIZE*1f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*20+30, 20, 1}, //树4
{3, UNIT_SIZE*1f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*20+30, 20, 1}, //树4
//17-1竖直
{3, UNIT_SIZE*1f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*17+10, 17, 1}, //树4
{3, UNIT_SIZE*1f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*17+10, 17, 1}, //树4
{3, UNIT_SIZE*1f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*17+30, 17, 1}, //树4
{3, UNIT_SIZE*1f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*17+30, 17, 1}, //树4
//16-1竖直
{3, UNIT_SIZE*1f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*16+10, 16, 1}, //树4
{3, UNIT_SIZE*1f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*16+10, 16, 1}, //树4
{3, UNIT_SIZE*1f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*16+30, 16, 1}, //树4
{3, UNIT_SIZE*1f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*16+30, 16, 1}, //树4
//12-2竖直
{3, UNIT_SIZE*2f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*12+10, 12, 2}, //树4
{3, UNIT_SIZE*2f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*12+10, 12, 2}, //树4
{3, UNIT_SIZE*2f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*12+30, 12, 2}, //树4
{3, UNIT_SIZE*2f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*12+30, 12, 2}, //树4
//11-2竖直
{3, UNIT_SIZE*2f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*11+10, 11, 2}, //树4
{3, UNIT_SIZE*2f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*11+10, 11, 2}, //树4
{3, UNIT_SIZE*2f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*11+30, 11, 2}, //树4
{3, UNIT_SIZE*2f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*11+30, 11, 2}, //树4
//6-2竖直
{3, UNIT_SIZE*2f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*6+10, 6, 2}, //树4
{3, UNIT_SIZE*2f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*6+10, 6, 2}, //树4
{3, UNIT_SIZE*2f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*6+30, 6, 2}, //树4
{3, UNIT_SIZE*2f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*6+30, 6, 2}, //树4
//4-2竖直
{3, UNIT_SIZE*2f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*4+10, 4, 2}, //树4
{3, UNIT_SIZE*2f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*4+10, 4, 2}, //树4
{3, UNIT_SIZE*2f+17, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*4+30, 4, 2}, //树4
{3, UNIT_SIZE*2f-22, WATER_HIGH_ADJUST+1.5f, UNIT_SIZE*4+30, 4, 2}, //树4
};
}

View File

@@ -0,0 +1,379 @@
package com.bn.clp;
import static com.bn.clp.Constant.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.List;
import android.opengl.GLES20;
import com.bn.core.MatrixState;
public class Tunnel extends BNDrawer
{
//单位长度
float UNIT_SIZE=15f;
PipeLine ppl;//隧道下方的通道
Mountion mountion;
public Tunnel(int mProgramId0,int mProgramId1,float[][] yArray,int rows,int cols)
{
ppl=new PipeLine(mProgramId0);
mountion=new Mountion(mProgramId1,yArray,rows,cols);
}
public void drawSelf(int[] texId,int udyflag)
{
//texId[0]为隧道的纹理IdtexId[1]表示小山的纹理idtexId[2]表示小山上方岩石的纹理id
ppl.drawSelf(texId[0]);//绘制下方通道
mountion.drawSelf(texId[1],texId[2]);
}
//隧道下方的通道
private class PipeLine
{
//自定义渲染管线着色器的id
int mProgram;
//总变化矩阵引用的id
int muMVPMatrixHandle;
//顶点位置属性引用id
int maPositionHandle;
//顶点纹理坐标属性引用id
int maTexCoorHandle;
//顶点数据缓冲和纹理坐标数据缓冲
FloatBuffer mVertexBuffer;
FloatBuffer mTexCoorBuffer;
//顶点数量
int vCount=0;
final float R=18f;
float height=UNIT_SIZE*3f;
final float ANGLE_SPAN=18;//分割的度数
public PipeLine(int programId)
{
initVertexData();
initShader(programId);
}
//初始化顶点数据的方法
public void initVertexData()
{
List<Float> tempList=new ArrayList<Float>();
for(float vAngle=180;vAngle>0;vAngle=vAngle-ANGLE_SPAN)
{
float x0=(float) (R*Math.cos(Math.toRadians(vAngle)));
float y0=(float) (R*Math.sin(Math.toRadians(vAngle)));
float z0=height;
float x1=(float) (R*Math.cos(Math.toRadians(vAngle)));
float y1=(float) (R*Math.sin(Math.toRadians(vAngle)));
float z1=-height;
float x2=(float) (R*Math.cos(Math.toRadians(vAngle-ANGLE_SPAN)));
float y2=(float) (R*Math.sin(Math.toRadians(vAngle-ANGLE_SPAN)));
float z2=-height;
float x3=(float) (R*Math.cos(Math.toRadians(vAngle-ANGLE_SPAN)));
float y3=(float) (R*Math.sin(Math.toRadians(vAngle-ANGLE_SPAN)));
float z3=height;
tempList.add(x0);tempList.add(y0);tempList.add(z0);
tempList.add(x1);tempList.add(y1);tempList.add(z1);
tempList.add(x3);tempList.add(y3);tempList.add(z3);
tempList.add(x3);tempList.add(y3);tempList.add(z3);
tempList.add(x1);tempList.add(y1);tempList.add(z1);
tempList.add(x2);tempList.add(y2);tempList.add(z2);
}
float[] vertex=new float[tempList.size()];
for(int i=0;i<tempList.size();i++)
{
vertex[i]=tempList.get(i);
}
vCount=tempList.size()/3;
ByteBuffer vbb=ByteBuffer.allocateDirect(vertex.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer=vbb.asFloatBuffer();
mVertexBuffer.put(vertex);
mVertexBuffer.position(0);
float[] texcoor=generateTexCoor((int)(180/ANGLE_SPAN),1,3,3);
ByteBuffer tbb=ByteBuffer.allocateDirect(texcoor.length*4);
tbb.order(ByteOrder.nativeOrder());
mTexCoorBuffer=tbb.asFloatBuffer();
mTexCoorBuffer.put(texcoor);
mTexCoorBuffer.position(0);
}
//初始化着色器的initShader方法
public void initShader(int programId)
{
//基于顶点着色器与片元着色器创建程序
mProgram = programId;
//获取程序中顶点位置属性引用id
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
//获取程序中顶点纹理坐标属性引用id
maTexCoorHandle= GLES20.glGetAttribLocation(mProgram, "aTexCoor");
//获取程序中总变换矩阵引用id
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
}
//实际的绘制方法
public void drawSelf(int texId)
{
//制定使用某套shader程序
GLES20.glUseProgram(mProgram);
//将最终变换矩阵传入shader程序
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//传入顶点位置数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入纹理坐标数据
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false,
2*4,
mTexCoorBuffer
);
//允许顶点位置数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
//绘制纹理矩形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
}
//隧道上的小山
private class Mountion
{
//自定义渲染管线的id
int mProgram;
//总变化矩阵引用的id
int muMVPMatrixHandle;
//顶点位置属性引用id
int maPositionHandle;
//顶点纹理坐标属性引用id
int maTexCoorHandle;
//草地的id
int sTextureGrassHandle;
//石头的id
int sTextureRockHandle;
//起始x值
int b_YZ_StartYHandle;
//长度
int b_YZ_YSpanHandle;
//位置、旋转变换矩阵
int muMMatrixHandle;
//是否为隧道山的标志位的引用id
int sdflagHandle;
//此处flag值为0表示隧道山值为1表示为普通山
private int flag=0;
//顶点数据缓冲和纹理坐标数据缓冲
FloatBuffer mVertexBuffer;
FloatBuffer mTexCoorBuffer;
//顶点数量
int vCount=0;
final float TEMP_UNIT_SIZE_X=6*UNIT_SIZE/15;
final float TEMP_UNIT_SIZE_Z=6*UNIT_SIZE/15;
public Mountion(int programId,float[][] yArray,int rows,int cols)
{
initVertexData(yArray,rows,cols);
initShader(programId);
}
//初始化顶点坐标数据的initVertexData方法
public void initVertexData(float[][] yArray,int rows,int cols)
{
//顶点坐标数据的初始化================begin============================
vCount=cols*rows*2*3;//每个格子两个三角形每个三角形3个顶点
float vertices[]=new float[vCount*3];//每个顶点xyz三个坐标
int count=0;//顶点计数器
for(int j=0;j<rows;j++)
{
for(int i=0;i<cols;i++)
{
//计算当前格子左上侧点坐标
float zsx=-TEMP_UNIT_SIZE_X*cols/2+i*TEMP_UNIT_SIZE_X;
float zsz=-TEMP_UNIT_SIZE_Z*rows/2+j*TEMP_UNIT_SIZE_Z;
vertices[count++]=zsx;
vertices[count++]=yArray[j][i];
vertices[count++]=zsz;
vertices[count++]=zsx;
vertices[count++]=yArray[j+1][i];
vertices[count++]=zsz+TEMP_UNIT_SIZE_Z;
vertices[count++]=zsx+TEMP_UNIT_SIZE_X;
vertices[count++]=yArray[j][i+1];
vertices[count++]=zsz;
vertices[count++]=zsx+TEMP_UNIT_SIZE_X;
vertices[count++]=yArray[j][i+1];
vertices[count++]=zsz;
vertices[count++]=zsx;
vertices[count++]=yArray[j+1][i];
vertices[count++]=zsz+TEMP_UNIT_SIZE_Z;
vertices[count++]=zsx+TEMP_UNIT_SIZE_X;
vertices[count++]=yArray[j+1][i+1];
vertices[count++]=zsz+TEMP_UNIT_SIZE_Z;
}
}
//创建顶点坐标数据缓冲
//vertices.length*4是因为一个整数四个字节
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());//设置字节顺序
mVertexBuffer = vbb.asFloatBuffer();//转换为Float型缓冲
mVertexBuffer.put(vertices);//向缓冲区中放入顶点坐标数据
mVertexBuffer.position(0);//设置缓冲区起始位置
//顶点纹理坐标数据的初始化================begin============================
float[] texCoor=generateTexCoor(cols,rows,8,8);
//创建顶点纹理坐标数据缓冲
ByteBuffer cbb = ByteBuffer.allocateDirect(texCoor.length*4);
cbb.order(ByteOrder.nativeOrder());//设置字节顺序
mTexCoorBuffer = cbb.asFloatBuffer();//转换为Float型缓冲
mTexCoorBuffer.put(texCoor);//向缓冲区中放入顶点着色数据
mTexCoorBuffer.position(0);//设置缓冲区起始位置
}
//初始化着色器的initShader方法
public void initShader(int programId)
{
//基于顶点着色器与片元着色器创建程序
mProgram = programId;
//获取程序中顶点位置属性引用id
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
//获取程序中顶点纹理坐标属性引用id
maTexCoorHandle= GLES20.glGetAttribLocation(mProgram, "aTexCoor");
//获取程序中总变换矩阵引用id
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
//纹理
//草地
sTextureGrassHandle=GLES20.glGetUniformLocation(mProgram, "sTextureGrass");
//石头
sTextureRockHandle=GLES20.glGetUniformLocation(mProgram, "sTextureRock");
//x位置
b_YZ_StartYHandle=GLES20.glGetUniformLocation(mProgram, "b_YZ_StartY");
//x最大
b_YZ_YSpanHandle=GLES20.glGetUniformLocation(mProgram, "b_YZ_YSpan");
//位置、旋转变换矩阵的引用id
muMMatrixHandle=GLES20.glGetUniformLocation(mProgram, "uMMatrix");
sdflagHandle=GLES20.glGetUniformLocation(mProgram, "sdflag");
}
//实际的绘制方法
public void drawSelf(int texId,int rock_textId)
{
//制定使用某套shader程序
GLES20.glUseProgram(mProgram);
//将最终变换矩阵传入shader程序
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//将位置、旋转变换矩阵传入到Shader程序中
GLES20.glUniformMatrix4fv(muMMatrixHandle, 1, false, MatrixState.getMMatrix(), 0);
GLES20.glUniform1i(sdflagHandle, flag);
//传入顶点位置数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入纹理坐标数据
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false,
2*4,
mTexCoorBuffer
);
//允许顶点位置数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, rock_textId);
GLES20.glUniform1i(sTextureGrassHandle, 0);//使用0号纹理
GLES20.glUniform1i(sTextureRockHandle, 1); //使用1号纹理
//传送相应的x参数
GLES20.glUniform1f(b_YZ_StartYHandle, 0);
GLES20.glUniform1f(b_YZ_YSpanHandle, SD_HEIGHT);
//开启混合
GLES20.glEnable(GLES20.GL_BLEND);
//设置混合因子
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
//绘制纹理矩形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
//关闭混合
GLES20.glDisable(GLES20.GL_BLEND);
}
}
//自动切分纹理产生纹理数组的方法
public float[] generateTexCoor(int bw,int bh,float width,float height)
{
float[] result=new float[bw*bh*6*2];
float sizew=width/bw;//列数
float sizeh=height/bh;//行数
int c=0;
for(int i=0;i<bh;i++)
{
for(int j=0;j<bw;j++)
{
//每行列一个矩形由两个三角形构成共六个点12个纹理坐标
float s=j*sizew;
float t=i*sizeh;
result[c++]=s;
result[c++]=t;
result[c++]=s;
result[c++]=t+sizeh;
result[c++]=s+sizew;
result[c++]=t;
result[c++]=s+sizew;
result[c++]=t;
result[c++]=s;
result[c++]=t+sizeh;
result[c++]=s+sizew;
result[c++]=t+sizeh;
}
}
return result;
}
}

View File

@@ -0,0 +1,210 @@
package com.bn.clp;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import com.bn.core.MatrixState;
import android.opengl.GLES20;
import static com.bn.clp.Constant.*;
//有波浪效果的水面
public class Water
{
int mPrograms;//自定义渲染管线着色器程序id
int muMVPMatrixHandle;//总变换矩阵引用id
int maPositionHandle; //顶点位置属性引用id
int maTexCoorHandle; //顶点纹理坐标属性引用id
int maSTOffset; //水面纹理图的偏移量引用id
static float[] mMMatrix = new float[16];//具体物体的移动旋转矩阵
FloatBuffer mVertexBuffer;//顶点坐标数据缓冲
FloatBuffer mTexCoorBuffer;//顶点纹理坐标数据缓冲
int vCount=0; //顶点数量
float currStartST=0; //水面纹理坐标的当前起始坐标0~1
public Water(int programId,int rows,int cols)
{
//初始化顶点坐标的initVertexData方法
initVertexData(rows,cols);
//初始化着色器的方法
initShader(programId);
//启动一个线程定时换帧
new Thread()
{
public void run()
{
while(Constant.threadFlag)
{
//所谓水面定时换帧只是修改每帧起始角度即可,
//水面顶点Y坐标的变化由顶点着色单元完成
currStartST=(currStartST+0.004f)%1;
try
{
Thread.sleep(100);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}.start();
}
//初始化顶点坐标的initVertexData方法
public void initVertexData(int rows,int cols)
{
final float pre_Size=UNIT_SIZE/rows;
//顶点坐标数据的初始化================begin============================
vCount=cols*rows*2*3;//每个格子两个三角形每个三角形3个顶点
float vertices[]=new float[vCount*3];//每个顶点xyz三个坐标
int count=0;//顶点计数器
for(int j=0;j<rows;j++)
{
for(int i=0;i<cols;i++)
{
//计算当前格子左上侧点坐标
float zsx=-UNIT_SIZE/2+i*pre_Size;
float zsy=WATER_HIGH_ADJUST;
float zsz=-UNIT_SIZE/2+j*pre_Size;
vertices[count++]=zsx;
vertices[count++]=zsy;
vertices[count++]=zsz;
vertices[count++]=zsx;
vertices[count++]=zsy;
vertices[count++]=zsz+pre_Size;
vertices[count++]=zsx+pre_Size;
vertices[count++]=zsy;
vertices[count++]=zsz;
vertices[count++]=zsx+pre_Size;
vertices[count++]=zsy;
vertices[count++]=zsz;
vertices[count++]=zsx;
vertices[count++]=zsy;
vertices[count++]=zsz+pre_Size;
vertices[count++]=zsx+pre_Size;
vertices[count++]=zsy;
vertices[count++]=zsz+pre_Size;
}
}
//创建顶点坐标数据缓冲
//vertices.length*4是因为一个整数四个字节
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());//设置字节顺序
mVertexBuffer = vbb.asFloatBuffer();//转换为Float型缓冲
mVertexBuffer.put(vertices);//向缓冲区中放入顶点坐标数据
mVertexBuffer.position(0);//设置缓冲区起始位置
//顶点纹理坐标数据的初始化================begin============================
float texCoor[]=generateTexCoor(cols,rows);
//创建顶点纹理坐标数据缓冲
ByteBuffer cbb = ByteBuffer.allocateDirect(texCoor.length*4);
cbb.order(ByteOrder.nativeOrder());//设置字节顺序
mTexCoorBuffer = cbb.asFloatBuffer();//转换为Float型缓冲
mTexCoorBuffer.put(texCoor);//向缓冲区中放入顶点着色数据
mTexCoorBuffer.position(0);//设置缓冲区起始位置
}
//初始化着色器的initShader方法
public void initShader(int programId)
{
//基于顶点着色器与片元着色器创建程序
mPrograms =programId;
//获取程序中顶点位置属性引用id
maPositionHandle = GLES20.glGetAttribLocation(mPrograms, "aPosition");
//获取程序中顶点纹理坐标属性引用id
maTexCoorHandle= GLES20.glGetAttribLocation(mPrograms, "aTexCoor");
//获取程序中总变换矩阵引用id
muMVPMatrixHandle = GLES20.glGetUniformLocation(mPrograms, "uMVPMatrix");
//获取水面纹理图偏移量的引用id
maSTOffset=GLES20.glGetUniformLocation(mPrograms, "stK");
}
public void drawSelf(int texId,float startST)
{
//制定使用某套shader程序
GLES20.glUseProgram(mPrograms);
//将最终变换矩阵传入shader程序
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//将水面纹理图的st偏移量传入shader程序
GLES20.glUniform1f(maSTOffset, startST);
//传入顶点位置数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入顶点纹理坐标数据
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false,
2*4,
mTexCoorBuffer
);
//允许顶点位置、纹理坐标数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
//绘制纹理矩形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
//自动切分纹理产生纹理数组的方法
public float[] generateTexCoor(int bw,int bh)
{
float[] result=new float[bw*bh*6*2];
float sizew=1.0f/bw;//列数
float sizeh=1.0f/bh;//行数
int c=0;
for(int i=0;i<bh;i++)
{
for(int j=0;j<bw;j++)
{
//每行列一个矩形由两个三角形构成共六个点12个纹理坐标
float s=j*sizew;
float t=i*sizeh;
result[c++]=s;
result[c++]=t;
result[c++]=s;
result[c++]=t+sizeh;
result[c++]=s+sizew;
result[c++]=t;
result[c++]=s+sizew;
result[c++]=t;
result[c++]=s;
result[c++]=t+sizeh;
result[c++]=s+sizew;
result[c++]=t+sizeh;
}
}
return result;
}
}

View File

@@ -0,0 +1,144 @@
package com.bn.clp;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import android.opengl.GLES20;
import com.bn.core.MatrixState;
public class WeiLang
{
//自定义渲染管线着色器程序id
int mProgram;
//总变化矩阵引用的id
int muMVPMatrixHandle;
//顶点位置属性引用id
int maPositionHandle;
//顶点纹理坐标属性引用id
int maTexCoorHandle;
int maSTOffset; //水面纹理图的偏移量引用id
int muTMD;//速度透明度参数
float currStartST=0; //水面纹理坐标的当前起始坐标0~1
//顶点数据缓冲和纹理坐标数据缓冲
FloatBuffer mVertexBuffer;
FloatBuffer mTexCoorBuffer;
//顶点数量
int vCount=0;
public WeiLang(float a,float b,float height,float[] texCoor,int programId)
{
initVertexData(a,b,height,texCoor);
initShader(programId);
//启动一个线程定时换帧
new Thread()
{
public void run()
{
while(Constant.threadFlag)
{
//所谓水面定时换帧只是修改每帧起始角度即可,
//水面顶点Y坐标的变化由顶点着色单元完成
currStartST=(currStartST+0.1f)%1;
try
{
Thread.sleep(100);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}.start();
}
//初始化顶点数据的方法
public void initVertexData(float a,float b,float height,float[] texCoor)
{
float[] vertex=new float[]
{
-a,height/3,0,
-b,-height*2,0,
b,-height*2,0,
-a,height/3,0,
b,-height*2,0,
a,height/3,0,
};
vCount=vertex.length/3;
ByteBuffer vbb=ByteBuffer.allocateDirect(vertex.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer=vbb.asFloatBuffer();
mVertexBuffer.put(vertex);
mVertexBuffer.position(0);
//纹理坐标数据缓冲
ByteBuffer tbb=ByteBuffer.allocateDirect(texCoor.length*4);
tbb.order(ByteOrder.nativeOrder());
mTexCoorBuffer=tbb.asFloatBuffer();
mTexCoorBuffer.put(texCoor);
mTexCoorBuffer.position(0);
}
//初始化着色器的方法
public void initShader(int programId)
{
//基于顶点着色器与片元着色器创建程序
mProgram = programId;
//获取程序中顶点位置属性引用id
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
//获取程序中顶点纹理坐标属性引用id
maTexCoorHandle= GLES20.glGetAttribLocation(mProgram, "aTexCoor");
//获取程序中总变换矩阵引用id
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
//获取水面纹理图偏移量的引用id
maSTOffset=GLES20.glGetUniformLocation(mProgram, "stK");
//获取尾浪速度透明度的引用id
muTMD=GLES20.glGetUniformLocation(mProgram, "tmd");
}
//自定义的绘制方法drawSelf
public void drawSelf(int texId,float startST)
{
//制定使用某套shader程序
GLES20.glUseProgram(mProgram);
//将最终变换矩阵传入shader程序
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//将水面纹理图的st偏移量传入shader程序
GLES20.glUniform1f(maSTOffset, startST);
//将尾浪速度透明度传入shader程序
GLES20.glUniform1f(muTMD, Constant.CURR_BOAT_V_TMD);
//传入顶点位置数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入纹理坐标数据
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false,
2*4,
mTexCoorBuffer
);
//允许顶点位置数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
//绘制纹理矩形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
}

View File

@@ -0,0 +1,179 @@
package com.bn.core;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import android.opengl.Matrix;
//存储系统矩阵状态的类
public class MatrixState
{
private static float[] mProjMatrix = new float[16];//4x4矩阵 投影用
private static float[] mVMatrix = new float[16];//摄像机位置朝向9参数矩阵
private static float[] currMatrix;//当前变换矩阵
public static float[] lightLocation=new float[]{0,0,0};//定位光光源位置
public static FloatBuffer cameraFB;
public static FloatBuffer lightPositionFB;
//保护变换矩阵的栈
static float[][] mStack=new float[10][16];
static int stackTop=-1;
public static void setInitStack()//获取不变换初始矩阵
{
currMatrix=new float[16];
Matrix.setRotateM(currMatrix, 0, 0, 1, 0, 0);
}
public static void pushMatrix()//保护变换矩阵
{
stackTop++;
for(int i=0;i<16;i++)
{
mStack[stackTop][i]=currMatrix[i];
}
}
public static void popMatrix()//恢复变换矩阵
{
for(int i=0;i<16;i++)
{
currMatrix[i]=mStack[stackTop][i];
}
stackTop--;
}
public static void translate(float x,float y,float z)//设置沿xyz轴移动
{
Matrix.translateM(currMatrix, 0, x, y, z);
}
public static void rotate(float angle,float x,float y,float z)//设置绕xyz轴移动
{
Matrix.rotateM(currMatrix,0,angle,x,y,z);
}
public static void scale(float x,float y,float z)
{
Matrix.scaleM(currMatrix,0, x, y, z);
}
//插入自带矩阵
public static void matrix(float[] self)
{
float[] result=new float[16];
Matrix.multiplyMM(result,0,currMatrix,0,self,0);
currMatrix=result;
}
//设置摄像机
static ByteBuffer llbb= ByteBuffer.allocateDirect(3*4);
static float[] cameraLocation=new float[3];//摄像机位置
public static void setCamera
(
float cx, //摄像机位置x
float cy, //摄像机位置y
float cz, //摄像机位置z
float tx, //摄像机目标点x
float ty, //摄像机目标点y
float tz, //摄像机目标点z
float upx, //摄像机UP向量X分量
float upy, //摄像机UP向量Y分量
float upz //摄像机UP向量Z分量
)
{
Matrix.setLookAtM
(
mVMatrix,
0,
cx,
cy,
cz,
tx,
ty,
tz,
upx,
upy,
upz
);
cameraLocation[0]=cx;
cameraLocation[1]=cy;
cameraLocation[2]=cz;
llbb.clear();
llbb.order(ByteOrder.nativeOrder());//设置字节顺序
cameraFB=llbb.asFloatBuffer();
cameraFB.put(cameraLocation);
cameraFB.position(0);
}
//设置透视投影参数
public static void setProjectFrustum
(
float left, //near面的left
float right, //near面的right
float bottom, //near面的bottom
float top, //near面的top
float near, //near面距离
float far //far面距离
)
{
Matrix.frustumM(mProjMatrix, 0, left, right, bottom, top, near, far);
}
//设置正交投影参数
public static void setProjectOrtho
(
float left, //near面的left
float right, //near面的right
float bottom, //near面的bottom
float top, //near面的top
float near, //near面距离
float far //far面距离
)
{
Matrix.orthoM(mProjMatrix, 0, left, right, bottom, top, near, far);
}
//用于一帧内的摄像机矩阵
private static float[] mVMatrixForSpecFrame = new float[16];//摄像机位置朝向9参数矩阵
public static void copyMVMatrix()
{
for(int i=0;i<16;i++)
{
mVMatrixForSpecFrame[i]=mVMatrix[i];
}
}
//获取具体物体的总变换矩阵
static float[] mMVPMatrix=new float[16];
public static float[] getFinalMatrix()
{
Matrix.multiplyMM(mMVPMatrix, 0, mVMatrixForSpecFrame, 0, currMatrix, 0);
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);
return mMVPMatrix;
}
//获取具体物体的变换矩阵
public static float[] getMMatrix()
{
return currMatrix;
}
//设置灯光位置的方法
static ByteBuffer llbbL = ByteBuffer.allocateDirect(3*4);
public static void setLightLocation(float x,float y,float z)
{
llbbL.clear();
lightLocation[0]=x;
lightLocation[1]=y;
lightLocation[2]=z;
llbbL.order(ByteOrder.nativeOrder());//设置字节顺序
lightPositionFB=llbbL.asFloatBuffer();
lightPositionFB.put(lightLocation);
lightPositionFB.position(0);
}
}

View File

@@ -0,0 +1,80 @@
package com.bn.core;
import android.opengl.Matrix;
/*
将手机当前在yaw、pitch、row三个轴的姿态数据通过此工具类计算转换成赛艇的转向数据以实现对赛艇的方向控制。
*/
public class RotateUtil
{
//angle为弧度 gVector 为重力向量[x,y,z,1]
//返回值为旋转后的向量----绕x轴旋转变换矩阵
static float[] pm=new float[16];
static float[] rv=new float[4];
public static float[] pitchRotate(float angle,float[] gVector)
{
Matrix.setRotateM(pm, 0, angle, 1, 0, 0);
Matrix.multiplyMV(rv,0, pm, 0, gVector, 0);
return rv;
}
//angle为弧度 gVector 为重力向量[x,y,z,1]
//返回值为旋转后的向量--绕y轴旋转变换矩阵
public static float[] rollRotate(float angle,float[] gVector)
{
Matrix.setRotateM(pm, 0, angle, 0, 1, 0);
Matrix.multiplyMV(rv,0, pm, 0, gVector, 0);
return rv;
}
//angle为弧度 gVector 为重力向量[x,y,z,1]
//返回值为旋转后的向量--绕z轴旋转变换矩阵
public static float[] yawRotate(float angle,float[] gVector)
{
Matrix.setRotateM(pm, 0, angle, 0, 0, 1);
Matrix.multiplyMV(rv,0, pm, 0, gVector, 0);
return rv;
}
static float[] gVector=new float[4];
static int[] result=new int[2];
public static int[] getDirectionDot(float[] values)
{
float yawAngle=-values[0];//获取Yaw轴旋转角度弧度
float pitchAngle=-values[1];//获取Pitch轴旋转角度弧度
float rollAngle=-values[2];//获取Roll轴旋转角度弧度
/*
* 算法思想为手机在一个姿态后首先虚拟出一个重力向量,
* 然后三次选装把手机恢复到原始姿态,期间重力向量伴随
* 变化,最后重力向量往手机平面上一投影。
*/
//虚拟一个重力向量
gVector[0]=0;
gVector[1]=0;
gVector[2]=-100;
gVector[3]=1;
/*
* 在这里需要注意沿三个空间方向x,y,z轴所旋转的角度的恢复顺序由于Yaw轴始终指向竖直向上重力加速度反向
* 标准的空间坐标系的z轴一样所以 可以通过负向旋转直接进行角度恢复沿yaw轴将转过的角度恢复后此时的pitch轴
* 就变成了空间坐标系中的x轴沿pitchx轴将 转过 的角度恢复此时的roll轴就修正为了空间坐标系中的y轴最后
* 按照y轴将转过的角度恢复则此时手机平面所在的平面变成了空间坐标 系中x-y平面而附着于手机平面上的重力加速度
* 的则是一个与手机平面相交的向量,将该向量投影到手机平面,通过投影点就可以计算出小球要滚动的方向
* 如果不按照上述顺序进行角度恢复,则空间坐标的计算转换将会非常复杂,而上述方法中每一步的角度恢复都是基于标准
* 的坐标系轴,而对标准坐标轴的转换在计算机图形
* 学中很容易实现
*/
//yaw轴恢复
gVector=RotateUtil.yawRotate(yawAngle,gVector);
//pitch轴恢复
gVector=RotateUtil.pitchRotate(pitchAngle,gVector);
//roll轴恢复
gVector=RotateUtil.rollRotate(rollAngle,gVector);
result[0]=(int) gVector[0];
result[1]=(int) gVector[1];
return result;
}
}

View File

@@ -0,0 +1,126 @@
package com.bn.core;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import android.content.res.Resources;
import android.opengl.GLES20;
import android.util.Log;
//加载顶点Shader与片元Shader的工具类
public class ShaderUtil
{
//加载制定shader的方法
public static int loadShader
(
int shaderType, //shader的类型 GLES20.GL_VERTEX_SHADER GLES20.GL_FRAGMENT_SHADER
String source //shader的脚本字符串
)
{
//创建一个新shader
int shader = GLES20.glCreateShader(shaderType);
//若创建成功则加载shader
if (shader != 0)
{
//加载shader的源代码
GLES20.glShaderSource(shader, source);
//编译shader
GLES20.glCompileShader(shader);
//存放编译成功shader数量的数组
int[] compiled = new int[1];
//获取Shader的编译情况
GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
if (compiled[0] == 0)
{//若编译失败则显示错误日志并删除此shader
Log.e("ES20_ERROR", "Could not compile shader " + shaderType + ":");
Log.e("ES20_ERROR", GLES20.glGetShaderInfoLog(shader));
GLES20.glDeleteShader(shader);
shader = 0;
}
}
return shader;
}
//创建shader程序的方法
public static int createProgram(String vertexSource, String fragmentSource)
{
//加载顶点着色器
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
if (vertexShader == 0)
{
return 0;
}
//加载片元着色器
int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
if (pixelShader == 0)
{
return 0;
}
//创建程序
int program = GLES20.glCreateProgram();
//若程序创建成功则向程序中加入顶点着色器与片元着色器
if (program != 0)
{
//向程序中加入顶点着色器
GLES20.glAttachShader(program, vertexShader);
checkGlError("glAttachShader");
//向程序中加入片元着色器
GLES20.glAttachShader(program, pixelShader);
checkGlError("glAttachShader");
//链接程序
GLES20.glLinkProgram(program);
//存放链接成功program数量的数组
int[] linkStatus = new int[1];
//获取program的链接情况
GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
//若链接失败则报错并删除程序
if (linkStatus[0] != GLES20.GL_TRUE)
{
Log.e("ES20_ERROR", "Could not link program: ");
Log.e("ES20_ERROR", GLES20.glGetProgramInfoLog(program));
GLES20.glDeleteProgram(program);
program = 0;
}
}
return program;
}
//检查每一步操作是否有错误的方法
public static void checkGlError(String op)
{
int error;
while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR)
{
Log.e("ES20_ERROR", op + ": glError " + error);
throw new RuntimeException(op + ": glError " + error);
}
}
//从sh脚本中加载shader内容的方法
public static String loadFromAssetsFile(String fname,Resources r)
{
String result=null;
try
{
InputStream in=r.getAssets().open(fname);
int ch=0;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while((ch=in.read())!=-1)
{
baos.write(ch);
}
byte[] buff=baos.toByteArray();
baos.close();
in.close();
result=new String(buff,"UTF-8");
result=result.replaceAll("\\r\\n","\n");
}
catch(Exception e)
{
e.printStackTrace();
}
return result;
}
}

View File

@@ -0,0 +1,27 @@
package com.bn.st.d2;
import com.bn.R;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
public class AndroidVersionDialog extends Dialog
{
public AndroidVersionDialog(Context context)
{
super(context,R.style.FullHeightDialog);
}
@Override
public void onCreate (Bundle savedInstanceState)
{
this.setContentView(R.layout.currandroidversion);
}
@Override
public String toString()
{
return "AndroidVersionDialog";
}
}

View File

@@ -0,0 +1,25 @@
package com.bn.st.d2;
import com.bn.R;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
public class BreakRecordOrNotDialog extends Dialog
{
public BreakRecordOrNotDialog(Context context)
{
super(context,R.style.FullHeightDialog);
}
@Override
public void onCreate (Bundle savedInstanceState)
{
this.setContentView(R.layout.breakrecordornot);
}
@Override
public String toString()
{
return "BreakRecordOrNotDialog";
}
}

View File

@@ -0,0 +1,27 @@
package com.bn.st.d2;
import com.bn.R;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
public class CheckVersionDialog extends Dialog
{
public CheckVersionDialog(Context context)
{
super(context,R.style.FullHeightDialog);
}
@Override
public void onCreate (Bundle savedInstanceState)
{
this.setContentView(R.layout.checkversion);
}
@Override
public String toString()
{
return "CheckVersionDialog";
}
}

View File

@@ -0,0 +1,164 @@
package com.bn.st.d2;
import java.util.ArrayList;
import java.util.List;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
//数据库工具类
public class DBUtil
{
static SQLiteDatabase sld;
//打开或创建数据库
public static void createorOpenDatabase()
{
try
{
sld=SQLiteDatabase.openDatabase
(
"/data/data/com.bn/mydb", //数据库所在路径
null, //CursorFactory
SQLiteDatabase.OPEN_READWRITE|SQLiteDatabase.CREATE_IF_NECESSARY //读写、若不存在则创建
);
}
catch(Exception e)
{
e.printStackTrace();
}
}
//关闭数据库
public static void closeDatabase()
{
try
{
sld.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
//创建表
public static void createTable()
{
createorOpenDatabase();
try
{
String jsSql="create table if not exists jsRecord" +
"(" +
"id INTEGER PRIMARY KEY AUTOINCREMENT," +
"date char(20)," +
"time char(10)" +
")";
String rcRSql="create table if not exists jRecord" +
"("+
"id INTEGER PRIMARY KEY AUTOINCREMENT," +
"date char(20)," +
"time char(10)," +
"ranking Integer"+
")";
sld.execSQL(jsSql);
sld.execSQL(rcRSql);
}
catch(Exception e)
{
e.printStackTrace();
}
closeDatabase();
}
//插入到计时赛数据库的方法
public static void insertJSDatabase(String date,String time)
{
createorOpenDatabase();
try
{
String sql="insert into jsRecord values(null, '"+date+"','"+time+"');";
sld.execSQL(sql);
}
catch(Exception e)
{
e.printStackTrace();
}
closeDatabase();
}
//插入到计时赛数据库的方法
public static void insertRcRDatabase(String date,String time,int ranking)
{
createorOpenDatabase();
try
{
String sql="insert into jRecord values(null, '"+date+"','"+time+"','"+ranking+"');";
sld.execSQL(sql);
}
catch(Exception e)
{
e.printStackTrace();
}
closeDatabase();
}
//查询数据库
public static List<String> queryDatabase(String tableName)
{
createorOpenDatabase();
List<String> alist=new ArrayList<String>();
try
{
String sql="select * from "+tableName;
Cursor cur=sld.rawQuery(sql, new String[]{});
while(cur.moveToNext())
{
int tempCount=cur.getColumnCount();
for(int i=1;i<tempCount;i++)
{
alist.add(cur.getString(i));
}
}
cur.close();
}
catch(Exception e)
{
e.printStackTrace();
}
closeDatabase();
return alist;
}
//删除表
public static void dropDatabase()
{
createorOpenDatabase();
try
{
String sql="drop table jsRecord;";
String sql0="drop table jRecord;";
sld.execSQL(sql);
sld.execSQL(sql0);
}
catch(Exception e)
{
e.printStackTrace();
}
closeDatabase();
}
//查询计时模式表中的用时
public static List<String> getTimeFromJSDatabase()
{
createorOpenDatabase();
List<String> alist=new ArrayList<String>();
try
{
String sql="select time from jsRecord;";
Cursor cur=sld.rawQuery(sql, new String[]{});
while(cur.moveToNext())
{
alist.add(cur.getString(0));
}
cur.close();
}
catch(Exception e)
{
e.printStackTrace();
}
closeDatabase();
return alist;
}
}

View File

@@ -0,0 +1,267 @@
package com.bn.st.d2;
import java.util.ArrayList;
import java.util.List;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.MotionEvent;
import static com.bn.st.xc.Constant.*;
public class DSurfaceView extends MySFView
{
MyActivity activity;
Paint paint;
int index=1;//计时模式和竞速模式的图片索引值
List<String> alist=new ArrayList<String>();//存储在数据库中取出数据的集合
float offset=55*ratio_width;
float tyoffset=20*ratio_width;
float clipYOffset=10*ratio_height;
//前一时刻触控点的Y位置
float beY;
//上下偏移量的数值
float uBOffset;
float yOffset=0;
public DSurfaceView(MyActivity activity)
{
this.activity=activity;
//设置生命周期回调接口的实现者
paint=new Paint();
paint.setAntiAlias(true);
}
public void onDraw(Canvas canvas)
{
canvas.drawBitmap(recordBitmap[0], picLocation[0][0], picLocation[0][1], paint);
canvas.drawBitmap(recordBitmap[index], picLocation[1][0], picLocation[1][1], paint);
canvas.save();//保存当前画布状态
canvas.clipRect(touchLocation[2][0], touchLocation[2][1]+clipYOffset, touchLocation[2][2], touchLocation[2][3]-clipYOffset);
if(index==1)//计时模式
{
for(int i=0;i<alist.size();i++)
{
if(i%2==0)
{
drawDate
(
canvas,
touchLocation[2][0]+offset,
touchLocation[2][1]+i*(recordNum[0].getHeight()+tyoffset)/2+tyoffset+yOffset,
recordNum[0].getWidth(),
paint,
alist.get(i),
recordBitmap[3],
recordBitmap[4]
);
}
else if(i%2==1)
{
drawTime
(
canvas,
touchLocation[2][0]+20*recordNum[0].getWidth()+offset,
touchLocation[2][1]+(i-1)*(recordNum[0].getHeight()+tyoffset)/2+tyoffset+yOffset,
recordNum[0].getWidth(),
paint,
alist.get(i),
recordBitmap[4]
);
}
}
}
else if(index==2)//竞速模式
{
for(int i=0;i<alist.size();i++)
{
if(i%3==0)
{
drawDate
(
canvas,
touchLocation[2][0]+offset,
touchLocation[2][1]+i*(recordNum[0].getHeight()+tyoffset)/3+tyoffset+yOffset,
recordNum[0].getWidth(),
paint,
alist.get(i),
recordBitmap[3],
recordBitmap[4]
);
}
else if(i%3==1)
{
drawTime
(
canvas,
touchLocation[2][0]+17*recordNum[0].getWidth()+offset,
touchLocation[2][1]+(i-1)*(recordNum[0].getHeight()+tyoffset)/3+tyoffset+yOffset,
recordNum[0].getWidth(),
paint,
alist.get(i),
recordBitmap[4]
);
}
else if(i%3==2)
{
drawDate
(
canvas,
touchLocation[2][0]+28*recordNum[0].getWidth()+offset,
touchLocation[2][1]+(i-2)*(recordNum[0].getHeight()+tyoffset)/3+tyoffset+yOffset,
recordNum[0].getWidth(),
paint,
alist.get(i),
recordBitmap[4],
recordBitmap[4]
);
}
}
}
canvas.restore();//恢复画布状态
}
//绘制日期和时间的方法
public void drawDate(Canvas canvas,float xoffset,float yoffset,float width,Paint paint,String str,Bitmap bmp0,Bitmap bmp1)
{
String[] tempStr=str.split(":");
for(int i=0;i<tempStr.length;i++)
{
//绘制数字
drawNum
(
canvas,
xoffset+tempStr[i].length()*width*i+bmp0.getWidth()*i,
yoffset,
width,
paint,
tempStr[i]
);
if(i==1)//绘制横线
{
canvas.drawBitmap
(
bmp0,
xoffset+tempStr[i].length()*width*i+(i-1)*bmp0.getWidth(),
yoffset,
paint
);
}
if(i>2)
{
canvas.drawBitmap
(
bmp1,
xoffset+tempStr[i].length()*width*i+(i-1)*bmp1.getWidth(),
yoffset,
paint
);
}
}
}
//绘制时间
public void drawTime(Canvas canvas,float xoffset,float yoffset,float width,Paint paint,String str,Bitmap bmp)
{
String[] tempStr=str.split(":");
for(int i=0;i<tempStr.length;i++)
{
//绘制数字
drawNum
(
canvas,
xoffset+tempStr[i].length()*width*i+bmp.getWidth()*i,
yoffset,
width,
paint,
tempStr[i]
);
if(i>=1&&i<3)//绘制横线
{
canvas.drawBitmap
(
bmp,
xoffset+tempStr[i].length()*width*i+(i-1)*bmp.getWidth(),
yoffset,
paint
);
}
}
}
//根据数字字符串绘制数字的方法
public void drawNum(Canvas canvas,float xoffset,float yoffset,float width,Paint paint,String str)
{
for(int i=0;i<str.length();i++)
{//循环绘制得分
int tempScore=str.charAt(i)-'0';
canvas.drawBitmap(recordNum[tempScore], xoffset+i*width,yoffset, paint);
}
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
float x=event.getX();
float y=event.getY();
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
if(x>touchLocation[0][0]&&x<touchLocation[0][2]&&
y>touchLocation[0][1]&&y<touchLocation[0][3])//计时模式
{
index=1;
yOffset=0;
alist=DBUtil.queryDatabase("jsRecord");
uBOffset=(alist.size()/(index+1)<=2)?alist.size()/(index+1)*(recordNum[0].getHeight()+tyoffset):3*(recordNum[0].getHeight()+tyoffset);
}
else if(x>touchLocation[1][0]&&x<touchLocation[1][2]&&
y>touchLocation[1][1]&&y<touchLocation[1][3])//竞速模式
{
index=2;
yOffset=0;
alist=DBUtil.queryDatabase("jRecord");
uBOffset=(alist.size()/(index+1)<=2)?alist.size()/(index+1)*(recordNum[0].getHeight()+tyoffset):3*(recordNum[0].getHeight()+tyoffset);
}
beY=y;
break;
case MotionEvent.ACTION_MOVE:
if(x>touchLocation[2][0]&&x<touchLocation[2][2]&&
y>touchLocation[2][1]&&y<touchLocation[2][3])//竞速模式
{
yOffset=yOffset+y-beY;
beY=y;
if(yOffset>=0)
{
yOffset=0;
}
else if(yOffset<=-(alist.size()/(index+1))*(recordNum[0].getHeight()+tyoffset)+uBOffset)
{
yOffset=-(alist.size()/(index+1))*(recordNum[0].getHeight()+tyoffset)+uBOffset;
}
}
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
public void init()
{
index=1;//计时模式和竞速模式的图片索引值
alist=new ArrayList<String>();//存储在数据库中取出数据的集合
offset=55*ratio_width;
tyoffset=20*ratio_width;
clipYOffset=10*ratio_height;
//前一时刻触控点的Y位置
beY=0;
//上下偏移量的数值
uBOffset=0;
yOffset=0;
//获取计时赛到的数据
alist=DBUtil.queryDatabase("jsRecord");
uBOffset=(alist.size()/(index+1)<=2)?alist.size()/(index+1)*(recordNum[0].getHeight()+tyoffset):3*(recordNum[0].getHeight()+tyoffset);
}
}

View File

@@ -0,0 +1,216 @@
package com.bn.st.d2;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import static com.bn.st.xc.Constant.*;
import com.bn.R;
public class GameModeView extends MySFView
{
MyActivity activity; //Activity引用
Canvas c; //画布的引用
SurfaceHolder holder; //SurfaceView锁的引用
Bitmap background; //背景图
Bitmap back; //返回按钮图片
Bitmap timer_mode; //计时模式图片
Bitmap speed_mode; //竞速模式图片
Bitmap record_select; //记录查询图片
Bitmap timer_mode_press; //计时模式按下图片
Bitmap speed_mode_press; //竞速模式按下图片
Bitmap record_select_press; //记录查询按下图片
Bitmap back_press;
private float timer_mode_x;//按钮图片的左上角X坐标
private float timer_mode_y;//按钮图片的左上角X坐标
private float speed_mode_x;//按钮图片的左上角Y坐标
private float speed_mode_y;//按钮图片的左上角Y坐标
private float record_select_x;//按钮图片的左上角Y坐标
private float record_select_y;//按钮图片的左上角Y坐标
private float button_back_x=20f*ratio_width;//back图片按钮的左上角的点的坐标
private float button_back_y=415f*ratio_height;
boolean time_flag=false;
boolean speed_flag=false;
boolean record_flag=false;
boolean back_flag=false;
public boolean flag_go=true;
int move_flag=1; //0---不移动 -1---向两侧移动 1---往中间移动
float move_span=MOVE_V;//按钮移动速度
public GameModeView(Context context)
{
this.activity = (MyActivity) context;//初始化activity的引用
initBitmap(); //初始化图片
}
public void initThread()
{
time_flag=false;
speed_flag=false;
record_flag=false;
back_flag=false;
flag_go=true;
move_flag=1; //0---不移动 -1---向两侧移动 1---往中间移动
timer_mode_x=-timer_mode.getWidth();//计时模式图片的初始左上角位置
timer_mode_y=190*ratio_height;
speed_mode_x=SCREEN_WIDTH; //竞速模式图片的初始左上角位置
speed_mode_y=275*ratio_height;
record_select_x=timer_mode_x; //记录查询图片的初始左上角位置
record_select_y=360*ratio_height;
new Thread()
{
@Override
public void run()
{
while(flag_go)
{
if(move_flag==1)
{
timer_mode_x=timer_mode_x+move_span*ratio_width;
speed_mode_x=speed_mode_x-move_span*ratio_width;
record_select_x=timer_mode_x;
if(timer_mode_x>=(SCREEN_WIDTH-timer_mode.getWidth())*0.5f)
{
timer_mode_x=(SCREEN_WIDTH-timer_mode.getWidth())*0.5f;
speed_mode_x=timer_mode_x;
record_select_x=timer_mode_x;
move_flag=0;
}
}
else if(move_flag==-1)
{
timer_mode_x=timer_mode_x-move_span*ratio_width;
speed_mode_x=speed_mode_x+move_span*ratio_width;
record_select_x=timer_mode_x;
if(timer_mode_x<=-timer_mode.getWidth())
{
timer_mode_x=-timer_mode.getWidth();
speed_mode_x=SCREEN_WIDTH;
record_select_x=timer_mode_x;
move_flag=0;
flag_go=false;
activity.hd.sendEmptyMessage(1);
}
}
try
{
Thread.sleep(MOVE_TIME);//休眠200毫秒
}catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}.start();
}
//将图片加载
public void initBitmap()
{
background = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.background),ratio_width,ratio_height);//菜单界面背景图片
back = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.back),ratio_width,ratio_height);//上一页按钮图片
timer_mode = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.timer_mode),ratio_width,ratio_height);//
speed_mode = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.speed_mode),ratio_width,ratio_height);//
record_select = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.record_select),ratio_width,ratio_height);//
timer_mode_press = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.timer_mode_press),ratio_width,ratio_height);//
speed_mode_press = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.speed_mode_press),ratio_width,ratio_height);//
record_select_press = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.record_select_press),ratio_width,ratio_height);//
back_press = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.back_press),ratio_width,ratio_height);//上一页按钮图片
}
@Override
public void onDraw(Canvas canvas)
{
super.onDraw(canvas);
canvas.drawColor(Color.argb(255, 0, 0, 0));//清屏为黑色
canvas.drawBitmap(background,0,0, null);//画背景
if(!back_flag)
{
canvas.drawBitmap(back, button_back_x, button_back_y, null);//绘制back按钮
}else
{
canvas.drawBitmap(back_press, button_back_x, button_back_y, null);//绘制back按钮
}
if(!time_flag)
{
canvas.drawBitmap(timer_mode, timer_mode_x, timer_mode_y, null);
}else
{
canvas.drawBitmap(timer_mode_press, timer_mode_x, timer_mode_y, null);
}
if(!speed_flag)
{
canvas.drawBitmap(speed_mode, speed_mode_x, speed_mode_y, null);
}else
{
canvas.drawBitmap(speed_mode_press, speed_mode_x, speed_mode_y, null);
}
if(!record_flag)
{
canvas.drawBitmap(record_select, record_select_x, record_select_y, null);
}else
{
canvas.drawBitmap(record_select_press, record_select_x, record_select_y, null);
}
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
int x = (int) event.getX();//获取触控点的X坐标
int y = (int) event.getY();//获取触控点的Y坐标
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN://按下事件
if(x>timer_mode_x&&x<timer_mode_x+timer_mode.getWidth()&&y>timer_mode_y&&y<timer_mode_y+timer_mode.getHeight())
{
time_flag=true;
}else if(x>speed_mode_x&&x<speed_mode_x+speed_mode.getWidth()&&y>speed_mode_y&&y<speed_mode_y+speed_mode.getHeight())
{
speed_flag=true;
}else if(x>record_select_x&&x<record_select_x+record_select.getWidth()&&y>record_select_y&&y<record_select_y+record_select.getHeight())
{
record_flag=true;
}else if(x>button_back_x&&x<button_back_x+back.getWidth()&&y>button_back_y&&y<button_back_y+back.getHeight())
{//返回按钮
back_flag=true;
}
break;
case MotionEvent.ACTION_UP://抬起事件
time_flag=false;
speed_flag=false;
record_flag=false;
back_flag=false;
if(x>timer_mode_x&&x<timer_mode_x+timer_mode.getWidth()&&y>timer_mode_y&&y<timer_mode_y+timer_mode.getHeight())
{
flag_go=false;
activity.hd.sendEmptyMessage(8);
}else if(x>speed_mode_x&&x<speed_mode_x+speed_mode.getWidth()&&y>speed_mode_y&&y<speed_mode_y+speed_mode.getHeight())
{
flag_go=false;
activity.hd.sendEmptyMessage(9);
}else if(x>record_select_x&&x<record_select_x+record_select.getWidth()&&y>record_select_y&&y<record_select_y+record_select.getHeight())
{
flag_go=false;
activity.hd.sendEmptyMessage(10);
}else if(x>button_back_x&&x<button_back_x+back.getWidth()&&y>button_back_y&&y<button_back_y+back.getHeight())
{//返回按钮
move_flag=-1;
}
break;
}
return true;
}
}

View File

@@ -0,0 +1,81 @@
package com.bn.st.d2;
import static com.bn.st.xc.Constant.ratio_height;
import static com.bn.st.xc.Constant.ratio_width;
import static com.bn.st.xc.Constant.scaleToFit;
import com.bn.R;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
public class GuanYuView extends MySFView
{
MyActivity activity; //Activity引用
Canvas c; //画布的引用
SurfaceHolder holder; //SurfaceView锁的引用
Bitmap background; //背景图
Bitmap back;
Bitmap back_press;
private float button_back_x=20f*ratio_width;//back图片按钮的左上角的点的坐标
private float button_back_y=415f*ratio_height;
boolean back_flag=false;
boolean flag=true;
public GuanYuView(Context context)
{
this.activity = (MyActivity) context;//初始化activity的引用
initBitmap(); //初始化图片
}
//将图片加载
public void initBitmap()
{
background = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.guanyu),ratio_width,ratio_height);//菜单界面背景图片
back = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.back),ratio_width,ratio_height);//上一页按钮图片
back_press = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.back_press),ratio_width,ratio_height);//上一页按钮图片
}
@Override
public void onDraw(Canvas canvas)
{
super.onDraw(canvas);
canvas.drawColor(Color.argb(255, 0, 0, 0));//清屏为黑色
canvas.drawBitmap(background,0,0, null);//画背景
if(!back_flag)
{
canvas.drawBitmap(back, button_back_x, button_back_y, null);//绘制back按钮
}else
{
canvas.drawBitmap(back_press, button_back_x, button_back_y, null);//绘制back按钮
}
}
@Override
public boolean onTouchEvent(MotionEvent e)
{
int x=(int)e.getX();
int y=(int)e.getY();
switch(e.getAction())
{
case MotionEvent.ACTION_DOWN:
if(x>button_back_x&&x<button_back_x+back.getWidth()&&y>button_back_y&&y<button_back_y+back.getHeight())
{//返回按钮
back_flag=true;
}
break;
case MotionEvent.ACTION_UP:
back_flag=false;
if(x>button_back_x&&x<button_back_x+back.getWidth()&&y>button_back_y&&y<button_back_y+back.getHeight())
{//返回按钮
activity.hd.sendEmptyMessage(1);
}
break;
}
return true;
}
}

View File

@@ -0,0 +1,338 @@
package com.bn.st.d2;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import static com.bn.st.xc.Constant.*;
import com.bn.R;
public class HelpSurfaceView extends MySFView
{
MyActivity activity;//Activity的引用
Canvas c;//画笔的引用
Paint paint;//画笔的引用
SurfaceHolder holder;//锁的引用
Bitmap[] bg_bitmap; //背景图
Bitmap pre_page; //上一页按钮图片
Bitmap next_page; //下一页按钮图片
Bitmap back;
Bitmap pre_page_press; //上一页按钮图片
Bitmap next_page_press; //下一页按钮图片
Bitmap back_press;
//帮助界面中的闪烁提示
Bitmap[] mark_bitmap;
//每张闪烁提示图片的xy坐标
private final float[][] mark_xy=
{
{246,308},
{44,170},
{15,115},
{50,160},
{184,242}
};
int fullTime=0;//记录从开始到当前的时间
long startTime;//开始时间
private float button_pre_x=20f*ratio_width;//back图片按钮的左上角的点的坐标
private float button_pre_y=415f*ratio_height;
private float button_next_x=710f*ratio_width;//next图片按钮的左上角点的坐标
private float button_next_y=415f*ratio_height;
private int next_flag=0;//0表示不移动,-1表示左移,1表示右移
private float bg_bitmap_curr_x=0;//当前背景图片的左上角点的X坐标
private float bg_bitmap_curr_y=0;//当前背景图片的左上角点的Y坐标
private float bg_bitmap_next_x;//下一幅背景图片的左上角点的X坐标
private float bg_bitmap_next_y=0;//下一幅背景图片的左上角点的Y坐标
private float move_span=80;//图片移动的速度
int page_index=0;//当前帮助页面的索引值
public boolean flag_go=true;
boolean back_flag=false;
boolean pre_page_flag=false;
boolean next_page_flag=false;
boolean isHaveNextFlag=true;
boolean isHavePreFlag=false;
public HelpSurfaceView(MyActivity activity)
{
this.activity = activity;
paint = new Paint(); //创建画笔
bg_bitmap=new Bitmap[5];//创建帮助界面背景图片数组对象
mark_bitmap=new Bitmap[5];//创建帮助界面中标注提醒图片数组对象
paint.setAntiAlias(true);//打开抗锯齿
initBitmap(); //初始化用到的图片资源
startTime=System.currentTimeMillis();
}
public void initThread()
{
next_flag=0;//0表示不移动,-1表示左移,1表示右移
bg_bitmap_curr_x=0;//当前背景图片的左上角点的X坐标
bg_bitmap_curr_y=0;//当前背景图片的左上角点的Y坐标
bg_bitmap_next_x=0;//下一幅背景图片的左上角点的X坐标
bg_bitmap_next_y=0;//下一幅背景图片的左上角点的Y坐标
move_span=80;//图片移动的速度
page_index=0;//当前帮助页面的索引值
flag_go=true;
back_flag=false;
pre_page_flag=false;
next_page_flag=false;
isHaveNextFlag=true;
isHavePreFlag=false;
new Thread()//创建一个线程调用doDraw方法
{
@Override
public void run()
{
while(flag_go)
{
//判断是左移还是右移
if(next_flag==-1)//左移
{
bg_bitmap_curr_x=bg_bitmap_curr_x-move_span;
bg_bitmap_next_x=bg_bitmap_next_x-move_span;
if(bg_bitmap_curr_x<=-SCREEN_WIDTH)
{
bg_bitmap_curr_x=-SCREEN_WIDTH;
next_flag=0;
page_index++;
bg_bitmap_curr_x=0;
bg_bitmap_next_x=SCREEN_WIDTH;
if(page_index==bg_bitmap.length-1)
{
isHaveNextFlag=false;
}
}
}
if(next_flag==1)//右移
{
bg_bitmap_curr_x=bg_bitmap_curr_x+move_span;
bg_bitmap_next_x=bg_bitmap_next_x+move_span;
if(bg_bitmap_curr_x>=SCREEN_WIDTH)
{
bg_bitmap_curr_x=SCREEN_WIDTH;
page_index--;
bg_bitmap_curr_x=0;
bg_bitmap_next_x=-SCREEN_WIDTH;
if(page_index==0)
{
isHavePreFlag=false;
}
next_flag=0;
}
}
try
{
Thread.sleep(10);//线程休眠100毫秒
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}.start();
}
//重写onDraw方法
@Override
public void onDraw(Canvas canvas)
{
super.onDraw(canvas);
canvas.drawColor(Color.argb(255, 0, 0, 0));//清屏为黑色
canvas.drawBitmap(bg_bitmap[page_index],bg_bitmap_curr_x,bg_bitmap_curr_y, null);//画当前背景
//当界面没有在移动的时候,绘制当前帮助界面的闪烁图标提示
if(next_flag==0)
{
//绘制帮助界面闪动的图标
long currentTime=System.currentTimeMillis();//记录当前时间
fullTime=(int) ((currentTime-startTime));//记录总时间
//将1秒分成两份在0.7秒内绘制0.3秒内不绘制
if((fullTime/100)%10 < 7) {
//绘制翻页指示图标
System.out.println(ratio_width+" "+ratio_height);
canvas.drawBitmap(mark_bitmap[page_index], mark_xy[page_index][0]*ratio_width, mark_xy[page_index][1]*ratio_height, paint);
}
}
if(next_flag==-1)
{
canvas.drawBitmap(bg_bitmap[page_index+1],bg_bitmap_next_x,bg_bitmap_next_y, null);//画下一幅背景
}
if(next_flag==1)
{
canvas.drawBitmap(bg_bitmap[page_index-1],bg_bitmap_next_x,bg_bitmap_next_y, null);//画下一幅背景
}
if(isHaveNextFlag==false)
{
if(!back_flag)
{
canvas.drawBitmap(back, button_next_x, button_next_y, null);//绘制back按钮
}
else
{
canvas.drawBitmap(back_press, button_next_x, button_next_y, null);//绘制back按钮
}
}
if(page_index>0)//当前的页面索引大于0
{
if(!pre_page_flag)
{
canvas.drawBitmap(pre_page, button_pre_x, button_pre_y, paint);//绘制上一页按钮
}else
{
canvas.drawBitmap(pre_page_press, button_pre_x, button_pre_y, paint);//绘制上一页按钮
}
}
if(!isHavePreFlag)
{
if(!back_flag)
{
canvas.drawBitmap(back, button_pre_x, button_pre_y, null);//绘制back按钮
}
else
{
canvas.drawBitmap(back_press, button_pre_x, button_pre_y, null);//绘制back按钮
}
}
if(page_index<bg_bitmap.length-1)//当前页面索引值小于帮助图片数组-1
{
if(!next_page_flag)
{
canvas.drawBitmap(next_page, button_next_x, button_next_y, paint);//绘制下一页按钮
}else
{
canvas.drawBitmap(next_page_press, button_next_x, button_next_y, paint);//绘制下一页按钮
}
}
}
//重写触摸事件方法
@Override
public boolean onTouchEvent(MotionEvent e)
{
int x=(int)e.getX();//获取触控点的XY坐标
int y=(int)e.getY();
switch(e.getAction())
{
case MotionEvent.ACTION_DOWN://抬起事件
if(next_flag==0&&x>button_pre_x&&x<button_pre_x+pre_page.getWidth()&&y>button_pre_y&&y<button_pre_y+pre_page.getHeight())
{
if(!isHavePreFlag)
{
back_flag=true;
}
else
{
pre_page_flag=true;
}
}
else if(next_flag==0&&x>button_next_x&&x<button_next_x+pre_page.getWidth()&&y>button_next_y&&y<button_next_y+pre_page.getHeight())
{
if(!isHaveNextFlag)
{
back_flag=true;
}
else
{
next_page_flag=true;
}
}
// else if(page_index==0&&x>button_next_x&&x<button_next_x+back.getWidth()&&y>button_next_y&&y<button_next_y+back.getHeight())
// {//返回按钮
// back_flag=true;
// }else if(page_index==bg_bitmap.length-1&&x>button_pre_x&&x<button_pre_x+back.getWidth()&&y>button_pre_y&&y<button_pre_y+back.getHeight())
// {//返回按钮
// back_flag=true;
// }
break;
case MotionEvent.ACTION_UP://抬起事件
pre_page_flag=false;
next_page_flag=false;
back_flag=false;
if(next_flag==0&&x>button_pre_x&&x<button_pre_x+pre_page.getWidth()&&y>button_pre_y&&y<button_pre_y+pre_page.getHeight())
{
if(!isHavePreFlag)
{
//返回到主菜单
flag_go=false;
activity.hd.sendEmptyMessage(1);
}
else
{
isHavePreFlag=true;
isHaveNextFlag=true;
//右移
next_flag=1;
bg_bitmap_next_x=-SCREEN_WIDTH;
}
}
else if(next_flag==0&&x>button_next_x&&x<button_next_x+pre_page.getWidth()&&y>button_next_y&&y<button_next_y+pre_page.getHeight())
{
if(!isHaveNextFlag)
{
//返回主菜单
flag_go=false;
activity.hd.sendEmptyMessage(1);
}
else
{
isHaveNextFlag=true;
isHavePreFlag=true;
//左移
next_flag=-1;
bg_bitmap_next_x=SCREEN_WIDTH;
}
}
break;
}
return true;
}
//初始化图片的方法
public void initBitmap()
{
bg_bitmap[0] = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.bg_bitmap0),ratio_width,ratio_height);//帮助界面背景图片
bg_bitmap[1] = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.bg_bitmap1),ratio_width,ratio_height);//帮助界面背景图片
bg_bitmap[2] = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.bg_bitmap2),ratio_width,ratio_height);//帮助界面背景图片
bg_bitmap[3] = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.bg_bitmap3),ratio_width,ratio_height);//帮助界面背景图片
bg_bitmap[4] = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.bg_bitmap4),ratio_width,ratio_height);//帮助界面背景图片
mark_bitmap[0] = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.mark0),ratio_width,ratio_height);
mark_bitmap[1] = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.mark1),ratio_width,ratio_height);
mark_bitmap[2] = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.mark2),ratio_width,ratio_height);
mark_bitmap[3] = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.mark3),ratio_width,ratio_height);
mark_bitmap[4] = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.mark4),ratio_width,ratio_height);
pre_page = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.pre_page),ratio_width,ratio_height);//上一页按钮图片
next_page = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.next_page),ratio_width,ratio_height);//下一页按钮图片
back = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.back),ratio_width,ratio_height);//上一页按钮图片
pre_page_press= scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.pre_page_press),ratio_width,ratio_height);//上一页按钮图片
next_page_press= scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.next_page_press),ratio_width,ratio_height);//下一页按钮图片
back_press= scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.back_press),ratio_width,ratio_height);//上一页按钮图片
}
//缩放图片的方法
public static Bitmap scaleToFit(Bitmap bm,float width_Ratio,float height_Ratio)
{
int width = bm.getWidth(); //图片宽度
int height = bm.getHeight(); //图片高度
Matrix matrix = new Matrix();
matrix.postScale((float)width_Ratio, (float)height_Ratio);//图片等比例缩小为原来的fblRatio倍
Bitmap bmResult = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true);//声明位图
return bmResult; //返回被缩放的图片
}
}

View File

@@ -0,0 +1,297 @@
package com.bn.st.d2; //声明包语句
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.os.Build;
import android.provider.Settings;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import static com.bn.st.xc.Constant.*;
import com.bn.R;
public class MenuView extends MySFView
{
MyActivity activity; //Activity引用
Canvas c; //画布的引用
SurfaceHolder holder; //SurfaceView锁的引用
Bitmap background; //背景图
Bitmap button_play; //进入游戏按钮图片
Bitmap button_chooseboat; //选船游戏按钮图片
Bitmap button_soundset; //音效设置按钮图片
Bitmap button_help; //游戏帮助按钮图片
Bitmap button_about; //关于按钮图片
Bitmap button_exit; //退出游戏按钮图片
Bitmap button_play_press; //进入游戏按钮图片
Bitmap button_chooseboat_press; //选船游戏按钮图片
Bitmap button_soundset_press; //音效设置按钮图片
Bitmap button_help_press; //游戏帮助按钮图片
Bitmap button_about_press; //关于按钮图片
Bitmap button_exit_press; //退出游戏按钮图片
private float button_play_x;//按钮图片的左上角X坐标
private float button_play_y;//按钮图片的左上角X坐标
private float button_chooseboat_x;//按钮图片的左上角Y坐标
private float button_chooseboat_y;//按钮图片的左上角Y坐标
private float button_soundset_x;//按钮图片的左上角Y坐标
private float button_soundset_y;//按钮图片的左上角Y坐标
private float button_help_x;//按钮图片的右上角X坐标
private float button_help_y;//按钮图片的右上角X坐标
private float button_about_x;//按钮图片的右上角Y坐标
private float button_about_y;//按钮图片的右上角Y坐标
private float button_exit_x;//按钮图片的右上角Y坐标
private float button_exit_y;//按钮图片的右上角Y坐标
boolean play_flag=false;
boolean chooseboat_flag=false;
boolean soundset_flag=false;
boolean help_flag=false;
boolean about_flag=false;
boolean exit_flag=false;
private boolean flag_go=true;
int move_flag=1; //0---不移动 -1---向两侧移动 1---往中间移动
float move_span=MOVE_V;//按钮移动速度
int curr_menuId=0;//自定义的菜单按钮编号
public MenuView(MyActivity activity)
{
this.activity = activity;//初始化activity的引用
initBitmap(); //初始化图片
if(Build.VERSION.SDK_INT<Build.VERSION_CODES.FROYO)
{
activity.showDialog(2);
}
else if(activity.getGLVersion()<2)
{
activity.showDialog(1);
}
}
public void initThread()
{
move_flag=1;
button_play_x=-button_play.getWidth();
button_play_y=190*ratio_height;
button_chooseboat_x=SCREEN_WIDTH;
button_chooseboat_y=button_play_y;
button_soundset_x=button_play_x;
button_soundset_y=275*ratio_height;
button_help_x=button_chooseboat_x;
button_help_y=button_soundset_y;
button_about_x=button_play_x;
button_about_y=360*ratio_height;
button_exit_x=button_chooseboat_x;
button_exit_y=button_about_y;
flag_go=true;
new Thread()
{
{
this.setName("menuview thread");
}
@Override
public void run()
{
while(flag_go)
{
if(move_flag==1)//移动标志位为真
{
button_play_x=button_play_x+move_span*ratio_width;
button_chooseboat_x=button_chooseboat_x-move_span*ratio_width;
button_soundset_x=button_play_x;
button_help_x=button_chooseboat_x;
button_about_x=button_play_x;
button_exit_x=button_chooseboat_x;
if(button_play_x>=200*ratio_width)
{
button_play_x=200*ratio_width;
button_chooseboat_x=485*ratio_width;
button_soundset_x=button_play_x;
button_help_x=button_chooseboat_x;
button_about_x=button_play_x;
button_exit_x=button_chooseboat_x;
move_flag=0;
}
}
else if(move_flag==-1)
{
button_play_x=button_play_x-move_span*ratio_width;
button_chooseboat_x=button_chooseboat_x+move_span*ratio_width;
button_soundset_x=button_play_x;
button_help_x=button_chooseboat_x;
button_about_x=button_play_x;
button_exit_x=button_chooseboat_x;
if(button_play_x<=-button_play.getWidth())
{
button_play_x=-button_play.getWidth();
button_chooseboat_x=SCREEN_WIDTH;
button_soundset_x=button_play_x;
button_help_x=button_chooseboat_x;
button_about_x=button_play_x;
button_exit_x=button_chooseboat_x;
move_flag=0;
flag_go=false;
MenuView.this.activity.hd.sendEmptyMessage(curr_menuId);
}
}
try
{
Thread.sleep(MOVE_TIME);//休眠200毫秒
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}.start();
}
//将图片加载
public void initBitmap()
{
background = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.background),ratio_width,ratio_height);//菜单界面背景图片
button_play = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.play),ratio_width,ratio_height);//进入游戏按钮
button_chooseboat = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.chooseboat),ratio_width,ratio_height);//选船按钮
button_soundset = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.soundset),ratio_width,ratio_height);//音效设置按钮
button_help = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.gamehelp),ratio_width,ratio_height);//游戏帮助按钮
button_about = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.about),ratio_width,ratio_height);//游戏帮助按钮
button_exit = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.exit),ratio_width,ratio_height);//设置按钮
button_play_press = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.play_press ),ratio_width,ratio_height);//进入游戏按钮
button_chooseboat_press = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.chooseboat_press ),ratio_width,ratio_height);//选船按钮
button_soundset_press = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.soundset_press ),ratio_width,ratio_height);//音效设置按钮
button_help_press = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.gamehelp_press ),ratio_width,ratio_height);//游戏帮助按钮
button_about_press = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.about_press ),ratio_width,ratio_height);//游戏帮助按钮
button_exit_press = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.exit_press ),ratio_width,ratio_height);//设置按钮
}
@Override
public void onDraw(Canvas canvas)
{
super.onDraw(canvas);
canvas.drawColor(Color.argb(255, 0, 0, 0));//清屏为黑色
canvas.drawBitmap(background,0,0, null);//画背景
if(!play_flag)
{
canvas.drawBitmap(button_play, button_play_x, button_play_y, null);
}else
{
canvas.drawBitmap(button_play_press, button_play_x, button_play_y, null);
}
if(!chooseboat_flag)
{
canvas.drawBitmap(button_chooseboat, button_chooseboat_x, button_chooseboat_y, null);
}else
{
canvas.drawBitmap(button_chooseboat_press, button_chooseboat_x, button_chooseboat_y, null);
}
if(!soundset_flag)
{
canvas.drawBitmap(button_soundset, button_soundset_x, button_soundset_y, null);
}else
{
canvas.drawBitmap(button_soundset_press, button_soundset_x, button_soundset_y, null);
}
if(!help_flag)
{
canvas.drawBitmap(button_help, button_help_x, button_help_y, null);
}else
{
canvas.drawBitmap(button_help_press, button_help_x, button_help_y, null);
}
if(!about_flag)
{
canvas.drawBitmap(button_about, button_about_x, button_about_y, null);
}else
{
canvas.drawBitmap(button_about_press, button_about_x, button_about_y, null);
}
if(!exit_flag)
{
canvas.drawBitmap(button_exit, button_exit_x, button_exit_y, null);
}
else
{
canvas.drawBitmap(button_exit_press, button_exit_x, button_exit_y, null);
}
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
int x = (int) event.getX();//获取触控点的X坐标
int y = (int) event.getY();//获取触控点的Y坐标
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN://按下事件,按下换图
if(move_flag==0&&x>button_play_x&&x<button_play_x+button_play.getWidth()&&y>button_play_y&&y<button_play_y+button_play.getHeight())
{//进入游戏
play_flag=true;
}else if(move_flag==0&&x>button_chooseboat_x&&x<button_chooseboat_x+button_chooseboat.getWidth()&&y>button_chooseboat_y&&y<button_chooseboat_y+button_chooseboat.getHeight())
{//选船
chooseboat_flag=true;
}else if(move_flag==0&&x>button_soundset_x&&x<button_soundset_x+button_soundset.getWidth()&&y>button_soundset_y&&y<button_soundset_y+button_soundset.getHeight())
{//音效设置
soundset_flag=true;
}else if(move_flag==0&&x>button_help_x&&x<button_help_x+button_help.getWidth()&&y>button_help_y&&y<button_help_y+button_help.getHeight())
{//游戏帮助
help_flag=true;
}else if(move_flag==0&&x>button_about_x&&x<button_about_x+button_about.getWidth()&&y>button_about_y&&y<button_about_y+button_about.getHeight())
{//关于
about_flag=true;
}else if(move_flag==0&&x>button_exit_x&&x<button_exit_x+button_exit.getWidth()&&y>button_exit_y&&y<button_exit_y+button_exit.getHeight())
{//退出
exit_flag=true;
}
break;
case MotionEvent.ACTION_UP://抬起事件
play_flag=false;
chooseboat_flag=false;
soundset_flag=false;
help_flag=false;
about_flag=false;
exit_flag=false;
if(move_flag==0&&x>button_play_x&&x<button_play_x+button_play.getWidth()&&y>button_play_y&&y<button_play_y+button_play.getHeight())
{//进入游戏
curr_menuId=2;
move_flag=-1;
}else if(move_flag==0&&x>button_chooseboat_x&&x<button_chooseboat_x+button_chooseboat.getWidth()&&y>button_chooseboat_y&&y<button_chooseboat_y+button_chooseboat.getHeight())
{//选船
curr_menuId=3;
move_flag=-1;
}else if(move_flag==0&&x>button_soundset_x&&x<button_soundset_x+button_soundset.getWidth()&&y>button_soundset_y&&y<button_soundset_y+button_soundset.getHeight())
{//音效设置
curr_menuId=4;
move_flag=-1;
}else if(move_flag==0&&x>button_help_x&&x<button_help_x+button_help.getWidth()&&y>button_help_y&&y<button_help_y+button_help.getHeight())
{//游戏帮助
curr_menuId=5;
move_flag=-1;
}else if(move_flag==0&&x>button_about_x&&x<button_about_x+button_about.getWidth()&&y>button_about_y&&y<button_about_y+button_about.getHeight())
{//关于
curr_menuId=6;
move_flag=-1;
}else if(move_flag==0&&x>button_exit_x&&x<button_exit_x+button_exit.getWidth()&&y>button_exit_y&&y<button_exit_y+button_exit.getHeight())
{//退出
Settings.System.putInt(activity.getContentResolver(),Settings.System.ACCELEROMETER_ROTATION,activity.flag);
System.exit(0);
}
break;
}
return true;
}
}

View File

@@ -0,0 +1,720 @@
package com.bn.st.d2;
import java.util.HashMap;
import com.bn.R;
import com.bn.clp.BoatInfo;
import com.bn.clp.Constant;
import com.bn.clp.DaoJiShiForDraw;
import com.bn.clp.KeyThread;
import com.bn.clp.MyGLSurfaceView;
import com.bn.clp.RotateThread;
import com.bn.core.RotateUtil;
import com.bn.st.xc.CircleForDraw;
import com.bn.st.xc.CylinderTextureByVertex;
import com.bn.st.xc.XCSurfaceView;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.Dialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.content.pm.ConfigurationInfo;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.SoundPool;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;
import static com.bn.clp.Constant.BgSoundFlag;
import static com.bn.clp.Constant.COLS;
import static com.bn.clp.Constant.ROWS;
import static com.bn.clp.Constant.generateMountion;
import static com.bn.clp.Constant.generatePDY;
import static com.bn.clp.Constant.generateTunnel;
import static com.bn.clp.Constant.generateWDY;
import static com.bn.clp.Constant.generateZDY;
import static com.bn.clp.Constant.generateZDY_XD;
import static com.bn.clp.Constant.yArray_ZD;
import static com.bn.st.xc.Constant.*;
/*
* 此为选船场景
*/
enum WhichView
{
WELCOME_VIEW,MENU_VIEW,XC_VIEW,GAME_VIEW,HELP_VIEW,SOUND_VIEW,GAME_MODE_VIEW,GUANYU_VIEW,RECORD_VIEW
};
public class MyActivity extends Activity
{
static WhichView curr;
public static Object boatInitLock=new Object();
public MyGLSurfaceView gameV;
XCSurfaceView xcV;//选船场景的引用
public Handler hd;//消息控制器
ViewForDraw vfd;
WelcomeView welV;//欢迎过场动画界面
MenuView menuV;//菜单界面的引用
SoundSurfaceView ssv;//声音界面的引用
HelpSurfaceView hsv;//游戏帮助界面的引用
GameModeView gmv;//游戏模式选择界面的引用
GuanYuView gyv;//关于界面的引用
DSurfaceView dsv;//记录查询界面的引用
//============================
CheckVersionDialog cvDialog;
AndroidVersionDialog avDialog;
BreakRecordOrNotDialog bronDialog;//是否破纪录的对话框
RankingDialog rDialog;//名次对话框
int flag;
//==============================
public MediaPlayer beijingyinyue;//游戏背景音乐播放器
SoundPool shengyinChi;//声音池
HashMap<Integer,Integer> soundIdMap;//声音池中声音ID与自定义声音ID的Map
//SensorManager对象引用
SensorManager mySensorManager;
SharedPreferences sp;
//开发实现了SensorEventListener接口的传感器监听器
private SensorEventListener mySensorListener = new SensorEventListener()
{
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@Override
public void onSensorChanged(SensorEvent event)
{
//若使用传感器标志位为true,并且场景可触控标志位为true,可使用传感器。
if(event.sensor.getType() == Sensor.TYPE_ORIENTATION)
{//判断是否为加速度传感器变化产生的数据
//计算出重力在屏幕上的投影方向
int[] directionDotXY=RotateUtil.getDirectionDot
(
event.values
);
if(directionDotXY[1]<-20)
{//right
MyGLSurfaceView.keyState=MyGLSurfaceView.keyState|0x4;
}
else if(directionDotXY[1]>20)
{//left
MyGLSurfaceView.keyState=MyGLSurfaceView.keyState|0x8;
}
else
{//no left and no right
MyGLSurfaceView.keyState=MyGLSurfaceView.keyState&0x3;
}
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//获取SharedPreferences
sp=this.getSharedPreferences("actm", Context.MODE_PRIVATE);
//获得值默认值为true
com.bn.clp.Constant.BgSoundFlag = sp.getBoolean("bgSoundFlag", true);
com.bn.clp.Constant.SoundEffectFlag = sp.getBoolean("soundEffectFlag", true);
//初始化声音资源
chushihuaSounds();
//设置为全屏
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN ,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
//设置为横屏模式
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
//游戏过程中只允许调整多媒体音量,而不允许调整通话音量。
setVolumeControlStream(AudioManager.STREAM_MUSIC);
//创建数据库表
DBUtil.createTable();
flag=Settings.System.getInt(this.getContentResolver(),
Settings.System.ACCELEROMETER_ROTATION, 0);
Settings.System.putInt(this.getContentResolver(),
Settings.System.ACCELEROMETER_ROTATION,1);
SCREEN_WIDTH=getWindowManager().getDefaultDisplay().getWidth();
SCREEN_HEIGHT=getWindowManager().getDefaultDisplay().getHeight();
float screenHeightTemp=SCREEN_HEIGHT;//记录系统返回的屏幕分辨率。
float screenWidthTemp=SCREEN_WIDTH;
if(screenHeightTemp>screenWidthTemp) //指定屏幕的宽和高。
{
SCREEN_WIDTH=screenHeightTemp;
SCREEN_HEIGHT=screenWidthTemp;
}
com.bn.clp.Constant.screenRatio=SCREEN_WIDTH/SCREEN_HEIGHT;//获取屏幕的宽高比
if(Math.abs(com.bn.clp.Constant.screenRatio-com.bn.clp.Constant.screenRatio854x480)<0.001f)
{
com.bn.clp.Constant.screenId=1;
}
else if(Math.abs(com.bn.clp.Constant.screenRatio-com.bn.clp.Constant.screenRatio480x320)<0.01f)
{
com.bn.clp.Constant.screenId=3;
}
else if(Math.abs(com.bn.clp.Constant.screenRatio-com.bn.clp.Constant.screenRatio960x540)<0.001f)
{
com.bn.clp.Constant.screenId=2;
}
else
{
com.bn.clp.Constant.screenId=0;
}
ratio_height=SCREEN_HEIGHT/480;
ratio_width=SCREEN_WIDTH/854;
//获得SensorManager对象
mySensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
new Thread()
{
public void run()
{
synchronized(boatInitLock)
{
//选船的
CylinderTextureByVertex.initVertexData(14, 6, 8, 1);
CircleForDraw.initVertexData(8, 14);
XCSurfaceView.loadWelcomeBitmap(MyActivity.this.getResources());
XCSurfaceView.loadVertexFromObj(MyActivity.this.getResources());
com.bn.st.xc.ShaderManager.loadCodeFromFile(MyActivity.this.getResources());
//主场景的
//产生直道的Y坐标数组
generateZDY();
//产生直道带小岛的Y坐标数组
generateZDY_XD(getResources());
//创建拐弯赛道的Y坐标数组
generateWDY();
//创建平地赛道的Y坐标数组
generatePDY();
generateMountion(getResources());
generateTunnel(getResources());
ROWS=yArray_ZD.length-1;
COLS=yArray_ZD[0].length-1;
MyGLSurfaceView.loadProgressBitmap(MyActivity.this.getResources());
com.bn.clp.ShaderManager.loadCodeFromFile(MyActivity.this.getResources());
}
}
}.start();
//初始化GLSurfaceView
hd=new Handler()
{
@Override
public void handleMessage(Message msg)
{
switch(msg.what)
{
case 0://去欢迎界面
gotoWelcomeView();
break;
case 1://去主菜单界面
gotoMenuView();
break;
case 2://去模式选择界面
gotoGameModeView();
break;
case 3://去选艇界面
gotoXCView();
break;
case 4://去音效设置界面
gotoMusicSetView();
break;
case 5://去游戏帮助界面
gotoHelpView();
break;
case 6://去关于界面
gotoGuanYuView();
break;
case 7://主界面退出游戏按钮
Settings.System.putInt(MyActivity.this.getContentResolver(),Settings.System.ACCELEROMETER_ROTATION,flag);
System.exit(0);
break;
case 8://去游戏界面-计时模式
gotoTimerGameView();
break;
case 9://去游戏界面-竞速模式
gotoSpeedGameView();
break;
case 10://去游戏记录查询界面
gotoRecordView();
break;
case 11://显示是否破纪录对话框
showDialog(3);
break;
case 12://显示当前名次对话框
showDialog(4);
break;
}
}
};
hd.sendEmptyMessage(0);
}
//跳转到游戏帮助界面
public void gotoHelpView()
{
if(hsv==null)
{
hsv=new HelpSurfaceView(MyActivity.this);
}
hsv.initThread();
vfd.curr=hsv;
curr=WhichView.HELP_VIEW;
}
//跳转到音效设置界面
public void gotoMusicSetView()
{
if(ssv==null)
{
ssv=new SoundSurfaceView(MyActivity.this);
}
ssv.initThread();
vfd.curr=ssv;
curr=WhichView.SOUND_VIEW;
}
//跳转到游戏模式选择界面
public void gotoGameModeView()
{
if(gmv==null)
{
gmv=new GameModeView(MyActivity.this);
}
if(!vfd.flag)
{
vfd.initThread();
setContentView(vfd);
}
gmv.initThread();
vfd.curr=gmv;
curr=WhichView.GAME_MODE_VIEW;
}
//跳转到关于界面的方法
public void gotoGuanYuView()
{
if(gyv==null)
{
gyv=new GuanYuView(MyActivity.this);
}
vfd.curr=gyv;
curr=WhichView.GUANYU_VIEW;
}
//跳转到欢迎界面的方法
public void gotoWelcomeView()
{
welV=new WelcomeView(MyActivity.this);
setContentView(welV);
curr=WhichView.WELCOME_VIEW;
}
//跳转到菜单界面
public void gotoMenuView()
{
if(vfd==null)
{
vfd=new ViewForDraw(this);
}
if(!vfd.flag)
{
vfd.initThread();
setContentView(vfd);
}
if(menuV==null)
{
menuV=new MenuView(MyActivity.this);
}
menuV.initThread();
vfd.curr=menuV;
curr=WhichView.MENU_VIEW;
}
//跳转到选艇界面
public void gotoXCView()
{
vfd.flag=false;
xcV = new XCSurfaceView(MyActivity.this);
xcV.index_boat=BoatInfo.cuttBoatIndex;
setContentView(xcV);
xcV.requestFocus();//获取焦点
xcV.setFocusableInTouchMode(true);//设置为可触控
curr=WhichView.XC_VIEW;
}
//跳转到计时模式游戏界面
public void gotoTimerGameView()
{
vfd.flag=false;
//重置游戏中参数的方法
restartGame();
com.bn.clp.Constant.isSpeedMode=false;
KeyThread.otherBoatFlag=false;
if(BgSoundFlag&&beijingyinyue==null)
{
beijingyinyue=MediaPlayer.create(this,com.bn.R.raw.backsound);
beijingyinyue.setLooping(true);//是否循环
beijingyinyue.start();
}
gameV = new MyGLSurfaceView(MyActivity.this);
//获取焦点
gameV.requestFocus();
//设置为可触控
gameV.setFocusableInTouchMode(true);
setContentView(gameV);
curr=WhichView.GAME_VIEW;
}
//跳转到竞速模式游戏界面
public void gotoSpeedGameView()
{
vfd.flag=false;
//重置游戏中参数的方法
restartGame();
com.bn.clp.Constant.isSpeedMode=true;
KeyThread.otherBoatFlag=true;
if(BgSoundFlag&&beijingyinyue==null)
{
beijingyinyue=MediaPlayer.create(this,com.bn.R.raw.backsound);
beijingyinyue.setLooping(true);//是否循环
beijingyinyue.start();
}
gameV = new MyGLSurfaceView(MyActivity.this);
//获取焦点
gameV.requestFocus();
//设置为可触控
gameV.setFocusableInTouchMode(true);
setContentView(gameV);
curr=WhichView.GAME_VIEW;
}
//跳转到记录查询界面
public void gotoRecordView()
{
if(dsv==null)
{
com.bn.st.xc.Constant.initBitmap(this.getResources());
com.bn.st.xc.Constant.initLoaction();
dsv=new DSurfaceView(MyActivity.this);
}
dsv.init();
vfd.curr=dsv;
curr=WhichView.RECORD_VIEW;
}
//初始化游戏中的静态参数的方法-重新进入游戏
public void restartGame()
{
KeyThread.upFlag=true;
DaoJiShiForDraw.DAOJISHI_FLAG=true;
com.bn.clp.Constant.CURR_BOAT_V=0;
com.bn.clp.Constant.BOAT_A=0;
com.bn.clp.Constant.isPaused=false;
com.bn.clp.Constant.DEGREE_SPAN=0;
com.bn.clp.Constant.RANK_FOR_HELP=1;
com.bn.clp.Constant.halfFlag=false;
com.bn.clp.Constant.CURR_BOAT_V_TMD=0;
com.bn.clp.Constant.numberOfN2=0;
com.bn.clp.Constant.RANK_FOR_HELP=1;
com.bn.clp.Constant.BOAT_LAP_NUMBER_OTHER=new int[2];
com.bn.clp.Constant.BOAT_LAP_NUMBER_OTHER[0]=1;
com.bn.clp.Constant.BOAT_LAP_NUMBER_OTHER[1]=1;
// com.bn.clp.Constant.isFirstPersonView=false;
MyGLSurfaceView.isDaoJiShi=true;
MyGLSurfaceView.isAllowToClick=false;
MyGLSurfaceView.isJiShi=false;
MyGLSurfaceView.sight_angle=com.bn.clp.Constant.DIRECTION_INI;
MyGLSurfaceView.yachtLeftOrRightAngle=0;
//新添加的
MyGLSurfaceView.betweenStartAndPauseTime=0;
Constant.gameTimeUse=0;
Constant.numberOfTurns=1;
Constant.threadFlag=true;
new RotateThread().start();
}
public void exitGame()
{
gameV.onPause();
gameV.otherPaths.clear();
gameV.tdObjectList.clear();
gameV.pzzList.clear();
gameV.speedWtList.clear();
gameV.treeList.clear();
gameV.kzbjList.clear();
Constant.threadFlag=false;
gameV.kt.flag=false;
gameV.tc.flag=false;
gameV.tfe.flag=false;
DaoJiShiForDraw.DAOJISHI_FLAG=false;
if(beijingyinyue!=null)
{
beijingyinyue.stop();
beijingyinyue=null;
}
gameV=null;
}
@Override
public void onResume()
{
super.onResume();
//注册监听器
mySensorManager.registerListener
(
mySensorListener, //监听器对象
mySensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), //传感器类型
//SensorManager.SENSOR_DELAY_UI //传感器事件传递的频度
SensorManager.SENSOR_DELAY_GAME
);
Constant.threadFlag=true;
if(gameV!=null)
{
gameV.kt.moveFlag=true;
}
}
@Override
public void onPause()
{
super.onPause();
mySensorManager.unregisterListener(mySensorListener); //取消注册监听器
Constant.threadFlag=false;
if(gameV!=null)
{
gameV.kt.moveFlag=false;
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent e)
{
//音量键上键是24下键是25以前由于按键时直接走该项所以导致设置后也不管用
if((keyCode==24)||(keyCode==25))
{
return false;
}
else if(keyCode==4)
{
if(curr==WhichView.MENU_VIEW&&menuV.move_flag==0)
{
Settings.System.putInt(this.getContentResolver(),Settings.System.ACCELEROMETER_ROTATION,flag);
System.exit(0);
}
else if(curr==WhichView.XC_VIEW)
{
xcV.flagForThread=false;
xcV.flag_display=false;
xcV=null;
gotoMenuView();
}
else if(curr==WhichView.GAME_VIEW)
{
if(DaoJiShiForDraw.DAOJISHI_FLAG)
{
return true;
}
else
{
gotoGameModeView();
exitGame();
gameV=null;
}
}
else if(curr==WhichView.GAME_MODE_VIEW)
{
if(gmv==null)
{
return false;
}
gmv.move_flag=-1;
gmv.flag_go=false;
gotoMenuView();
}
else if(curr==WhichView.SOUND_VIEW)
{
if(ssv==null)
{
return false;
}
ssv.move_flag=-1;
ssv.flag_go=false;
gotoMenuView();
}
else if(curr==WhichView.HELP_VIEW)
{
hsv.flag_go=false;
gotoMenuView();
}
else if(curr==WhichView.GUANYU_VIEW)
{
gotoMenuView();
}
else if(curr==WhichView.RECORD_VIEW)
{
gotoGameModeView();
}
}
return true;
}
//创建声音的方法
public void chushihuaSounds()
{
shengyinChi=new SoundPool
(
7,
AudioManager.STREAM_MUSIC,
100
);
soundIdMap=new HashMap<Integer,Integer>();
soundIdMap=new HashMap<Integer,Integer>();
soundIdMap.put(1, shengyinChi.load(this,com.bn.R.raw.pengzhuang,1));//碰撞声音
soundIdMap.put(2, shengyinChi.load(this,com.bn.R.raw.boatgo,1));//船加速的声音
soundIdMap.put(3, shengyinChi.load(this,com.bn.R.raw.eatthings1,1));//吃东西的声音
soundIdMap.put(4, shengyinChi.load(this,com.bn.R.raw.zhuangfei,1));//撞飞东西的声音
soundIdMap.put(5, shengyinChi.load(this,com.bn.R.raw.daojishi,1));//321倒计时的声音
soundIdMap.put(6, shengyinChi.load(this,com.bn.R.raw.start,1));//开始可以走的声音
}
//播放声音的方法
public void shengyinBoFang(int sound,int loop)
{
AudioManager mgr=(AudioManager)this.getSystemService(Context.AUDIO_SERVICE);
float streamVolumeCurrent=mgr.getStreamVolume(AudioManager.STREAM_MUSIC);
float streamVolumeMax=mgr.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float volume=streamVolumeCurrent/streamVolumeMax;
shengyinChi.play(soundIdMap.get(sound), volume, volume, 1, loop, 1f);
}
public int getGLVersion() //获取OPENGLES所支持的最高版本
{
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
ConfigurationInfo info = am.getDeviceConfigurationInfo();
int majorVersion=info.reqGlEsVersion;
majorVersion=majorVersion>>>16;
return majorVersion;
}
public Dialog onCreateDialog(int id)
{
Dialog result=null;
switch(id)
{
case 1:
cvDialog=new CheckVersionDialog(this);
cvDialog.setCancelable(false);
result=cvDialog;
break;
case 2:
avDialog=new AndroidVersionDialog(this);
avDialog.setCancelable(false);
result=avDialog;
break;
case 3:
bronDialog=new BreakRecordOrNotDialog(this);
bronDialog.setCancelable(false);
result=bronDialog;
break;
case 4:
rDialog=new RankingDialog(this);
rDialog.setCancelable(false);
result=rDialog;
break;
}
return result;
}
public void onPrepareDialog(int id, Dialog dialog)
{
//若不是等待对话框则返回
switch(id)
{
case 1:
Button bok=(Button)cvDialog.findViewById(R.id.ok_button);
bok.setOnClickListener(
new OnClickListener()
{
@Override
public void onClick(View v)
{
Settings.System.putInt(MyActivity.this.getContentResolver(),Settings.System.ACCELEROMETER_ROTATION,flag);
System.exit(0);
}
}
);
break;
case 2:
Button ok=(Button)avDialog.findViewById(R.id.ok);
ok.setOnClickListener(
new OnClickListener()
{
@Override
public void onClick(View v)
{
Settings.System.putInt(MyActivity.this.getContentResolver(),Settings.System.ACCELEROMETER_ROTATION,flag);
System.exit(0);
}
}
);
break;
case 3:
ok=(Button)bronDialog.findViewById(R.id.ok_button);
if(!com.bn.clp.Constant.isBreakRecord)
{
TextView tv=(TextView) bronDialog.findViewById(R.id.tview);
tv.setText("非常可惜,没有打破纪录,请再接再厉!");
}
else
{
TextView tv=(TextView) bronDialog.findViewById(R.id.tview);
tv.setText("恭喜您,成功的突破记录!");
}
ok.setOnClickListener(
new OnClickListener()
{
@Override
public void onClick(View v)
{
bronDialog.cancel();
MyActivity.this.hd.sendEmptyMessage(2);
exitGame();
gameV=null;
}
}
);
break;
case 4:
ok=(Button)rDialog.findViewById(R.id.ok_button);
TextView tv=(TextView) rDialog.findViewById(R.id.tview);
tv.setText("恭喜您,您获得了第"+com.bn.clp.Constant.RANK_FOR_HERO_BOAT+"名。");
ok.setOnClickListener(
new OnClickListener()
{
@Override
public void onClick(View v)
{
rDialog.cancel();
MyActivity.this.hd.sendEmptyMessage(2);
exitGame();
gameV=null;
}
}
);
break;
}
}
}

View File

@@ -0,0 +1,20 @@
package com.bn.st.d2;
import android.graphics.Canvas;
import android.view.MotionEvent;
public class MySFView
{
int xOffset;
int yOffset;
public void onDraw(Canvas canvas)
{
}
public boolean onTouchEvent(MotionEvent e)
{
return false;
}
}

View File

@@ -0,0 +1,25 @@
package com.bn.st.d2;
import com.bn.R;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
//Ãû´Î¶Ô»°¿ò
public class RankingDialog extends Dialog
{
public RankingDialog(Context context)
{
super(context,R.style.FullHeightDialog);
}
@Override
public void onCreate (Bundle savedInstanceState)
{
this.setContentView(R.layout.rankingdialog);
}
@Override
public String toString()
{
return "CheckVersionDialog";
}
}

View File

@@ -0,0 +1,264 @@
package com.bn.st.d2;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import static com.bn.st.xc.Constant.*;
import com.bn.R;
public class SoundSurfaceView extends MySFView
{
MyActivity activity;
Canvas c;
SurfaceHolder holder;
Bitmap background; //背景图
Bitmap back;
Bitmap back_press;
Bitmap button_bgsound; //背景音乐
Bitmap button_bgsound_open; //背景音乐开图片按钮
Bitmap button_bgsound_close; //背景音乐关图片按钮
Bitmap button_gameeffect; //游戏音效
Bitmap button_gameeffect_open; //游戏音效开按钮
Bitmap button_gameeffect_close; //游戏音效关按钮
private float button_bgsound_x;//背景音乐图片的左上角X坐标
private float button_bgsound_y;//背景音乐图片的左上角Y坐标
private float button_bgsound_open_x;//背景音乐开图片的左上角X坐标
private float button_bgsound_open_y;//背景音乐关图片的左上角Y坐标
private float button_gameeffect_x;//游戏音效图片的左上角X坐标
private float button_gameeffect_y;//游戏音效图片的左上角Y坐标
private float button_gameeffect_open_x;//游戏音效开图片的左上角X坐标
private float button_gameeffect_open_y;//游戏音效开图片的左上角Y坐标
private float button_back_x=20f*ratio_width;//back图片按钮的左上角的点的坐标
private float button_back_y=415f*ratio_height;
public boolean flag_go=true;
int move_flag=1; //0---不移动 -1---向两侧移动 1---往中间移动
float move_span=MOVE_V;//按钮移动速度
boolean back_flag=false;
public SoundSurfaceView(MyActivity activity)
{
this.activity = activity;
initBitmap(); //初始化图片
button_bgsound_x=-button_bgsound.getWidth();
button_bgsound_y=222f*ratio_height;
button_bgsound_open_x=SCREEN_WIDTH;
button_bgsound_open_y=button_bgsound_y;
button_gameeffect_x=button_bgsound_x;
button_gameeffect_y=307f*ratio_height;
button_gameeffect_open_x=button_bgsound_open_x;
button_gameeffect_open_y=button_gameeffect_y;
}
public void initThread()
{
flag_go=true;
move_flag=1; //0---不移动 -1---向两侧移动 1---往中间移动
button_bgsound_x=-button_bgsound.getWidth();
button_bgsound_y=222f*ratio_height;
button_bgsound_open_x=SCREEN_WIDTH;
button_bgsound_open_y=button_bgsound_y;
button_gameeffect_x=button_bgsound_x;
button_gameeffect_y=307f*ratio_height;
button_gameeffect_open_x=button_bgsound_open_x;
button_gameeffect_open_y=button_gameeffect_y;
new Thread()
{
@Override
public void run()
{
while(flag_go)//移动标志位为真
{
if(move_flag==1)
{
//更改两幅按钮图片的左上角点的X坐标
button_bgsound_x=button_bgsound_x+move_span*ratio_width;
button_bgsound_open_x=button_bgsound_open_x-move_span*ratio_width;
button_gameeffect_x=button_bgsound_x;
button_gameeffect_open_x=button_bgsound_open_x;
//当坐标值达到临界值时
if(button_bgsound_x>=200*ratio_width)
{
//得到此时的X坐标
button_bgsound_x=200*ratio_width;
button_bgsound_open_x=485*ratio_width;
button_gameeffect_x=button_bgsound_x;
button_gameeffect_open_x=button_bgsound_open_x;
move_flag=0;//将移动标志位置为0
}
}
else if(move_flag==-1)
{
//更改两幅按钮图片的左上角点的X坐标
button_bgsound_x=button_bgsound_x-move_span*ratio_width;
button_bgsound_open_x=button_bgsound_open_x+move_span*ratio_width;
button_gameeffect_x=button_bgsound_x;
button_gameeffect_open_x=button_bgsound_open_x;
if(button_bgsound_x<=-button_bgsound.getWidth())
{
button_bgsound_x=-button_bgsound.getWidth();
button_bgsound_open_x=SCREEN_WIDTH;
button_gameeffect_x=button_bgsound_x;
button_gameeffect_open_x=button_bgsound_open_x;
move_flag=0;
flag_go=false;
activity.hd.sendEmptyMessage(1);
}
}
try
{
Thread.sleep(MOVE_TIME);//休眠200毫秒
}catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}.start();
}
//将图片加载
public void initBitmap()
{
background = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.background),ratio_width,ratio_height);//菜单界面背景图片
back = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.back),ratio_width,ratio_height);//上一页按钮图片
back_press = scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.back_press),ratio_width,ratio_height);//上一页按钮图片
button_bgsound=scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.bg_music),ratio_width,ratio_height);//背景图片
button_bgsound_open=scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.open),ratio_width,ratio_height);//背景音乐开图片
button_bgsound_close=scaleToFit(BitmapFactory.decodeResource(activity.getResources(), R.drawable.close),ratio_width,ratio_height);//背景音乐关图片
button_gameeffect=scaleToFit(BitmapFactory.decodeResource(activity.getResources(),R.drawable.game_music),ratio_width,ratio_height);//游戏音效图片
button_gameeffect_open=scaleToFit(BitmapFactory.decodeResource(activity.getResources(),R.drawable.open),ratio_width,ratio_height);//游戏音效开图片
button_gameeffect_close=scaleToFit(BitmapFactory.decodeResource(activity.getResources(),R.drawable.close),ratio_width,ratio_height);//游戏音效关图片
}
@Override
public void onDraw(Canvas canvas)
{
super.onDraw(canvas);
canvas.drawColor(Color.argb(255, 0, 0, 0));//清屏为黑色
canvas.drawBitmap(background,0,0, null);//画背景
if(!back_flag)
{
canvas.drawBitmap(back, button_back_x, button_back_y, null);//绘制back按钮
}else
{
canvas.drawBitmap(back_press, button_back_x, button_back_y, null);//绘制back按钮
}
canvas.drawBitmap(button_bgsound, button_bgsound_x, button_bgsound_y, null);//绘制背景音乐图片
canvas.drawBitmap(button_gameeffect, button_gameeffect_x, button_gameeffect_y, null);//绘制游戏音效图片
if(com.bn.clp.Constant.BgSoundFlag)//根据背景音乐的标志位来绘制图片
{
canvas.drawBitmap(button_bgsound_open, button_bgsound_open_x, button_bgsound_open_y, null);
}
else if(!com.bn.clp.Constant.BgSoundFlag)//背景音乐关闭
{
canvas.drawBitmap(button_bgsound_close, button_bgsound_open_x, button_bgsound_open_y, null);
}
if(com.bn.clp.Constant.SoundEffectFlag)//游戏音效打开
{
canvas.drawBitmap(button_gameeffect_open, button_gameeffect_open_x, button_gameeffect_open_y, null);
}
else if(!com.bn.clp.Constant.SoundEffectFlag)//游戏关闭
{
canvas.drawBitmap(button_gameeffect_close, button_gameeffect_open_x, button_gameeffect_open_y, null);
}
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
int x = (int) event.getX();
int y = (int) event.getY();
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
if(x>button_bgsound_open_x&&x<button_bgsound_open_x+button_bgsound_open.getWidth()&&
y>button_bgsound_open_y&&y<button_bgsound_open_y+button_bgsound_open.getHeight())
{//背景音乐开关图片,点击换图
}
else if(x>button_gameeffect_open_x&&x<button_gameeffect_open_x+button_gameeffect_open.getWidth()&&
y>button_gameeffect_open_y&&y<button_gameeffect_open_y+button_gameeffect_open.getHeight())
{//游戏音效开关图片,点击换图
}
else if(x>button_back_x&&x<button_back_x+back.getWidth()&&y>button_back_y&&y<button_back_y+back.getHeight())
{//返回按钮
back_flag=true;
}
break;
case MotionEvent.ACTION_UP:
back_flag=false;
if(x>button_bgsound_open_x&&x<button_bgsound_open_x+button_bgsound_open.getWidth()&&
y>button_bgsound_open_y&&y<button_bgsound_open_y+button_bgsound_open.getHeight())
{
//向SharedPreferences中写回本次修改信息
SharedPreferences.Editor editor=activity.sp.edit();
editor.putBoolean("bgSoundFlag", !com.bn.clp.Constant.BgSoundFlag);
editor.commit();
com.bn.clp.Constant.BgSoundFlag=!com.bn.clp.Constant.BgSoundFlag;
if(com.bn.clp.Constant.BgSoundFlag)
{
//Toast.makeText(activity, "背景音乐开", Toast.LENGTH_SHORT).show();
}
else
{
//Toast.makeText(activity, "背景音乐关", Toast.LENGTH_SHORT).show();
}
}
else if(x>button_gameeffect_open_x&&x<button_gameeffect_open_x+button_gameeffect_open.getWidth()&&
y>button_gameeffect_open_y&&y<button_gameeffect_open_y+button_gameeffect_open.getHeight())
{
//向SharedPreferences中写回本次修改信息
SharedPreferences.Editor editor=activity.sp.edit();
editor.putBoolean("soundEffectFlag", !com.bn.clp.Constant.SoundEffectFlag);
editor.commit();
com.bn.clp.Constant.SoundEffectFlag=!com.bn.clp.Constant.SoundEffectFlag;
if(com.bn.clp.Constant.SoundEffectFlag)
{
//Toast.makeText(activity, "游戏音效开", Toast.LENGTH_SHORT).show();
}
else
{
//Toast.makeText(activity, "游戏音效关", Toast.LENGTH_SHORT).show();
}
}
else if(x>button_back_x&&x<button_back_x+back.getWidth()&&y>button_back_y&&y<button_back_y+back.getHeight())
{//返回按钮
move_flag=-1;
}
break;
}
return true;
}
//缩放图片的方法
public static Bitmap scaleToFit(Bitmap bm,float width_Ratio,float height_Ratio)
{
int width = bm.getWidth(); //图片宽度
int height = bm.getHeight(); //图片高度
Matrix matrix = new Matrix();
matrix.postScale((float)width_Ratio, (float)height_Ratio);//图片等比例缩小为原来的fblRatio倍
Bitmap bmResult = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true);//声明位图
return bmResult; //返回被缩放的图片
}
}

View File

@@ -0,0 +1,118 @@
package com.bn.st.d2;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
//主菜单View
public class ViewForDraw extends SurfaceView
implements SurfaceHolder.Callback //实现生命周期回调接口
{
MyActivity activity;
Paint paint;//画笔
boolean flag;
MySFView curr;
public ViewForDraw(MyActivity activity)
{
super(activity);
this.setKeepScreenOn(true);
this.activity = activity;
//设置生命周期回调接口的实现者
this.getHolder().addCallback(this);
//初始化画笔
paint = new Paint();//创建画笔
paint.setAntiAlias(true);//打开抗锯齿
}
public void initThread()
{
flag=true;
new Thread()
{
{
this.setName("VFD Thread");
}
public void run()
{
while(flag)
{
repaint();
try
{
Thread.sleep(40);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}.start();
}
public void onDraw(Canvas canvas)
{
if(canvas==null)
{
return;
}
canvas.clipRect
(
new Rect
(
0,
0,
(int)com.bn.st.xc.Constant.SCREEN_WIDTH,
(int)com.bn.st.xc.Constant.SCREEN_HEIGHT
)
);
curr.onDraw(canvas);
}
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3)
{
}
public void surfaceCreated(SurfaceHolder holder) {//创建时被调用
repaint();
}
public void surfaceDestroyed(SurfaceHolder arg0) {//销毁时被调用
}
public void repaint()
{
SurfaceHolder holder=this.getHolder();
Canvas canvas = holder.lockCanvas();//获取画布
try{
synchronized(holder){
onDraw(canvas);//绘制
}
}
catch(Exception e){
e.printStackTrace();
}
finally{
if(canvas != null){
holder.unlockCanvasAndPost(canvas);
}
}
}
//屏幕触控事件
@Override
public boolean onTouchEvent(MotionEvent e)
{
if(curr==null)
{
return false;
}
return curr.onTouchEvent(e);
}
}

View File

@@ -0,0 +1,107 @@
package com.bn.st.d2;
import com.bn.R;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import static com.bn.st.xc.Constant.*;
public class WelcomeView extends SurfaceView
implements SurfaceHolder.Callback //实现生命周期回调接口
{
MyActivity activity;//activity的引用
Paint paint; //画笔
int currentAlpha=0; //当前的不透明值
int sleepSpan=150; //动画的时延ms
Bitmap[] logos=new Bitmap[2];//logo图片数组
Bitmap currentLogo; //当前logo图片引用
float currentX; //图片位置
float currentY;
public WelcomeView(MyActivity activity)
{
super(activity);
this.activity = activity;
this.getHolder().addCallback(this); //设置生命周期回调接口的实现者
paint = new Paint(); //创建画笔
paint.setAntiAlias(true); //打开抗锯齿
//加载图片
logos[0]=BitmapFactory.decodeResource(activity.getResources(), R.drawable.heli);
logos[1]=BitmapFactory.decodeResource(activity.getResources(), R.drawable.androidheli);
}
public void onDraw(Canvas canvas)
{
//绘制黑填充矩形清背景
paint.setColor(Color.BLACK);//设置画笔颜色
paint.setAlpha(255);//设置不透明度为255
canvas.drawRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, paint);
//进行平面贴图
if(currentLogo==null)return;
paint.setAlpha(currentAlpha);
canvas.drawBitmap(currentLogo, currentX, currentY, paint);
}
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3)
{
}
public void surfaceCreated(SurfaceHolder holder) //创建时被调用
{
new Thread()
{
public void run()
{
for(Bitmap bm:logos)
{
currentLogo=bm;//当前图片的引用
currentX=SCREEN_WIDTH/2-bm.getWidth()/2;//图片位置
currentY=SCREEN_HEIGHT/2-bm.getHeight()/2;
for(int i=255;i>-10;i=i-10)
{//动态更改图片的透明度值并不断重绘
currentAlpha=i;
if(currentAlpha<0)//如果当前不透明度小于零
{
currentAlpha=0;//将不透明度置为零
}
SurfaceHolder myholder=WelcomeView.this.getHolder();//获取回调接口
Canvas canvas = myholder.lockCanvas();//获取画布
try{
synchronized(myholder)//同步
{
onDraw(canvas);//进行绘制绘制
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
if(canvas!= null)//如果当前画布不为空
{
myholder.unlockCanvasAndPost(canvas);//解锁画布
}
}
try
{
if(i==255)//若是新图片,多等待一会
{
Thread.sleep(1000);
}
Thread.sleep(sleepSpan);
}
catch(Exception e)//抛出异常
{
e.printStackTrace();
}
}
}
activity.hd.sendEmptyMessage(1);//发送消息,进入到主菜单界面
}
}.start();
}
public void surfaceDestroyed(SurfaceHolder arg0)
{//销毁时被调用
}
}

View File

@@ -0,0 +1,25 @@
package com.bn.st.xc;
import java.util.ArrayList;
import java.util.List;
public class Boat
{
List<LoadedObjectVertexTexXC> lovo=new ArrayList<LoadedObjectVertexTexXC>();
//str位文件的名称color位每一个部分对应的颜色其为二维数组
public Boat(LoadedObjectVertexTexXC[] parts,XCSurfaceView mv)
{
for(int i=0;i<parts.length;i++)
{
lovo.add(parts[i]);
parts[i].initShader(ShaderManager.getCommTextureShaderProgram());
}
}
public void drawSelf(int[] texId)
{
for(int i=0;i<lovo.size();i++)
{
lovo.get(i).drawSelf(texId[i]);
}
}
}

View File

@@ -0,0 +1,172 @@
/**
*
* 用于绘制圆
*/
package com.bn.st.xc;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
import com.bn.core.MatrixState;
import android.opengl.GLES20;
//用triangle_fan方式绘制圆面 此圆面是平行于XY平面的
public class CircleForDraw
{
int mProgram;//自定义渲染管着色器线程序id
int muMVPMatrixHandle;//总变换矩阵引用id
int maPositionHandle; //顶点位置属性引用id
int maNormalHandle; //顶点法向量属性引用id
int muMMatrixHandle;//位置、旋转变换矩阵
int maLightLocationHandle;//光源位置属性引用id
int maCameraHandle; //摄像机位置属性引用id
int maColorR; //颜色值的R分量引用id
int maColorG; //颜色值的G分量引用id
int maColorB; //颜色值的B分量引用id
int maColorA;
String mVertexShader;//顶点着色器
String mFragmentShader;//片元着色器
private static FloatBuffer mVertexBuffer;//顶点坐标数据缓冲
private static FloatBuffer mNormalBuffer;//顶点法向量数据缓冲
private static int vCount;
float r; //颜色值的R分量
float g; //颜色值的G分量
float b; //颜色值的B分量
public CircleForDraw
(
int mProgram,
float angleSpan,//切分角度
float radius,//圆半径
float[]color
)
{
this.r=color[0];
this.g=color[1];
this.b=color[2];
initShader(mProgram);
}
public static void initVertexData
(
float angleSpan,//切分角度
float radius//圆半径
)
{
//顶点纹理坐标数据的初始化================begin============================
vCount=1+(int)(360/angleSpan)+1;//顶点的个数
float[] vertices=new float[vCount*3];//初始化顶点数组
float[] normals=new float[vCount*3];//初始化顶点法向量数组
//存放中心点坐标
vertices[0]=0;
vertices[1]=0;
vertices[2]=0;
//存放中心点法向量
normals[0]=0;
normals[1]=0;
normals[2]=1;
int vcount=3;//当前顶点坐标索引
int ncount=3;//当前法向量坐标索引
for(float angle=0;angle<=360;angle=angle+angleSpan)
{
double angleRadian=Math.toRadians(angle);
//顶点坐标
vertices[vcount++]=radius*(float)Math.cos(angleRadian);
vertices[vcount++]=radius*(float)Math.sin(angleRadian);
vertices[vcount++]=0;
normals[ncount++]=0;
normals[ncount++]=0;
normals[ncount++]=1;
}
//创建顶点坐标数据缓冲
//vertices.length*4是因为一个整数四个字节
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());//设置字节顺序
mVertexBuffer = vbb.asFloatBuffer();//转换为int型缓冲
mVertexBuffer.put(vertices);//向缓冲区中放入顶点坐标数据
mVertexBuffer.position(0);//设置缓冲区起始位置
//创建顶点法向量数据缓冲
ByteBuffer nbb = ByteBuffer.allocateDirect(normals.length*4);
nbb.order(ByteOrder.nativeOrder());//设置字节顺序
mNormalBuffer = nbb.asFloatBuffer();//转换为float型缓冲
mNormalBuffer.put(normals);//向缓冲区中放入顶点坐标数据
mNormalBuffer.position(0);//设置缓冲区起始位置
}
public void initShader(int mProgramIn)
{
mProgram = mProgramIn;
//获取程序中顶点位置属性引用id
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
//获取程序中顶点颜色属性引用id
maNormalHandle= GLES20.glGetAttribLocation(mProgram, "aNormal");
//获取程序中总变换矩阵引用id
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
//获取位置、旋转变换矩阵引用id
muMMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMMatrix");
//获取程序中光源位置引用id
maLightLocationHandle=GLES20.glGetUniformLocation(mProgram, "uLightLocation");
//获取程序中摄像机位置引用id
maCameraHandle=GLES20.glGetUniformLocation(mProgram, "uCamera");
maColorR=GLES20.glGetUniformLocation(mProgram, "colorR");
maColorG=GLES20.glGetUniformLocation(mProgram, "colorG");
maColorB=GLES20.glGetUniformLocation(mProgram, "colorB");
maColorA=GLES20.glGetUniformLocation(mProgram, "colorA");
}
public void drawSelf(float alpha)
{
//制定使用某套shader程序
GLES20.glUseProgram(mProgram);
//将最终变换矩阵传入shader程序
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//将位置、旋转变换矩阵传入shader程序
GLES20.glUniformMatrix4fv(muMMatrixHandle, 1, false, MatrixState.getMMatrix(), 0);
//将光源位置传入shader程序
GLES20.glUniform3fv(maLightLocationHandle, 1, MatrixState.lightPositionFB);
//将摄像机位置传入shader程序
GLES20.glUniform3fv(maCameraHandle, 1, MatrixState.cameraFB);
//传入顶点位置数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入顶点法向量数据
GLES20.glVertexAttribPointer
(
maNormalHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mNormalBuffer
);
//允许顶点位置、法向量数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maNormalHandle);
GLES20.glUniform1f(maColorR , r);
GLES20.glUniform1f(maColorG , g);
GLES20.glUniform1f(maColorB , b);
GLES20.glUniform1f(maColorA , alpha);
//绘制图形
GLES20.glDrawArrays
(
GL10.GL_TRIANGLE_FAN, //以TRIANGLE_FAN方式填充
0,
vCount
);
}
}

View File

@@ -0,0 +1,146 @@
package com.bn.st.xc;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import com.bn.core.MatrixState;
import android.opengl.GLES20;
//纹理矩形 平行于XY平面
public class ColorLightRect
{
int mProgram;//自定义渲染管线着色器程序id
int muMVPMatrixHandle;//总变换矩阵引用id
int maPositionHandle; //顶点位置属性引用id
int maNormalHandle; //顶点法向量属性引用id
int muMMatrixHandle;//位置、旋转变换矩阵
int maLightLocationHandle;//光源位置属性引用id
int maCameraHandle; //摄像机位置属性引用id
int maColorR; //颜色值的R分量引用id
int maColorG; //颜色值的G分量引用id
int maColorB; //颜色值的B分量引用id
int maColorA;
String mVertexShader;//顶点着色器
String mFragmentShader;//片元着色器
private FloatBuffer mVertexBuffer;//顶点坐标数据缓冲
private FloatBuffer mNormalBuffer;//顶点法向量数据缓冲
float r; //颜色值的R分量
float g; //颜色值的G分量
float b; //颜色值的B分量
int vCount=0;//顶点数量
public ColorLightRect(int mProgramIn,float width,float height,float []color)
{
this.r=color[0];
this.g=color[1];
this.b=color[2];
//初始化顶点数据的方法
initVertexData(width,height);
//初始化着色器程序的方法
initShader(mProgramIn);
}
//初始化顶点坐标数据的方法
public void initVertexData(float width,float height)
{
vCount=6;
float vertices[]=new float[]
{
-width,height,0,
-width,-height,0,
width,-height,0,
width,-height,0,
width,height,0,
-width,height,0
};
float normals[]=new float[]
{
0,0,1,
0,0,1,
0,0,1,
0,0,1,
0,0,1,
0,0,1,
};
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());//设置字节顺序
mVertexBuffer = vbb.asFloatBuffer();//转换为Float型缓冲
mVertexBuffer.put(vertices);//向缓冲区中放入顶点坐标数据
mVertexBuffer.position(0);//设置缓冲区起始位置
ByteBuffer nbb = ByteBuffer.allocateDirect(normals.length*4);
nbb.order(ByteOrder.nativeOrder());//设置字节顺序
mNormalBuffer = nbb.asFloatBuffer();//转换为Float型缓冲
mNormalBuffer.put(normals);//向缓冲区中放入顶点着色数据
mNormalBuffer.position(0);//设置缓冲区起始位置
}
public void initShader(int mProgramIn)
{
mProgram = mProgramIn;
//获取程序中顶点位置属性引用id
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
//获取程序中顶点颜色属性引用id
maNormalHandle= GLES20.glGetAttribLocation(mProgram, "aNormal");
//获取程序中总变换矩阵引用id
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
//获取位置、旋转变换矩阵引用id
muMMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMMatrix");
//获取程序中光源位置引用id
maLightLocationHandle=GLES20.glGetUniformLocation(mProgram, "uLightLocation");
//获取程序中摄像机位置引用id
maCameraHandle=GLES20.glGetUniformLocation(mProgram, "uCamera");
maColorR=GLES20.glGetUniformLocation(mProgram, "colorR");
maColorG=GLES20.glGetUniformLocation(mProgram, "colorG");
maColorB=GLES20.glGetUniformLocation(mProgram, "colorB");
maColorA=GLES20.glGetUniformLocation(mProgram, "colorA");
}
public void drawSelf(float Alpha)
{
//制定使用某套shader程序
GLES20.glUseProgram(mProgram);
//将最终变换矩阵传入shader程序
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//将位置、旋转变换矩阵传入shader程序
GLES20.glUniformMatrix4fv(muMMatrixHandle, 1, false, MatrixState.getMMatrix(), 0);
//将光源位置传入shader程序
GLES20.glUniform3fv(maLightLocationHandle, 1, MatrixState.lightPositionFB);
//将摄像机位置传入shader程序
GLES20.glUniform3fv(maCameraHandle, 1, MatrixState.cameraFB);
//传入顶点位置数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入顶点法向量数据
GLES20.glVertexAttribPointer
(
maNormalHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mNormalBuffer
);
//允许顶点位置、法向量数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maNormalHandle);
GLES20.glUniform1f(maColorR , r);
GLES20.glUniform1f(maColorG , g);
GLES20.glUniform1f(maColorB , b);
GLES20.glUniform1f(maColorA , Alpha);
//绘制纹理矩形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
}

View File

@@ -0,0 +1,152 @@
package com.bn.st.xc;
import com.bn.R;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
public class Constant
{
//用来控制选船界面中上一个下一个键的自适应的常量 0号为480x800 1号为480x854 2号为540x960 3号为320x480
public static final float[][] XC_Self_Adapter_Data_TRASLATE=
{//上一个 下一个 按钮高度的一半
{0.21f},
{0.22f},
{0.22f},
{0.20f}
};
//用来控制菜单移动动画的常量
public static final float MOVE_V=20f;
public static final long MOVE_TIME=15;
//屏幕的大小
public static float SCREEN_WIDTH;
public static float SCREEN_HEIGHT;
//缩放比例
public static float ratio_width;
public static float ratio_height;
//--------设定房间的长宽高
public static final float HOUSE_CHANG=50;
public static final float HOUSE_KUAN=50;
public static final float HOUSE_GAO=30;
//-------=设定摄像机观察点和目标点的距离
public static final float XC_DISTANCE=35;
//三艘船格子的缩放比例
public static final float RATIO_BOAT=8.0f;
//展台的半径和高度
public static final float RADIUS_DISPLAY=14;
public static final float LENGTH_DISPLAY=6;
//设定房间的颜色
public static final float[][] HOUSE_COLOR=new float[][]
{
{1f,1f,1f},//不透明地面
{1f,1f,1f},//透明墙
};
//设定展台圆柱颜色
public static final float[] COLOR_CYLINDER=new float[]{0.9f,0.9f,0.9f,1.0f};
//设定展台圆面颜色
public static final float[] COLOR_CIRCLE=new float[]{0.9f,0.9f,0.9f,0.5f};
//围墙的宽高 这里的宽高均为 实际的一半
public static final float WALL_WIDHT=20f;
public static final float WALL_HEIGHT=18f;
//缩放纹理
public static Bitmap scaleToFit(Bitmap bm,float width_Ratio,float height_Ratio)
{
int width = bm.getWidth(); //图片宽度
int height = bm.getHeight(); //图片高度
Matrix matrix = new Matrix();
matrix.postScale((float)width_Ratio, (float)height_Ratio); //图片等比例缩小为原来的fblRatio倍
Bitmap bmResult = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true);//声明位图
return bmResult; //返回被缩放的图片
}
//新添加的=================================================================================
//需要的图片的id
public static int[] picId=new int[]
{
R.drawable.background, //大背景
R.drawable.tmode, //计时模式背景
R.drawable.rmode, //竞速模式背景
R.drawable.hengxian, //横线
R.drawable.maohao, //冒号
};
//数字图片
public static int[] picNum=new int[]
{
R.drawable.d0,R.drawable.d1,
R.drawable.d2,R.drawable.d3,
R.drawable.d4,R.drawable.d5,
R.drawable.d6,R.drawable.d7,
R.drawable.d8,R.drawable.d9,
};
public static Bitmap[] recordBitmap;
public static Bitmap[] recordNum;
//初始化图片的方法
public static void initBitmap(Resources res)
{
recordBitmap=new Bitmap[picId.length];
recordNum=new Bitmap[picNum.length];
for(int i=0;i<picId.length;i++)
{
recordBitmap[i]=scaleToFit(BitmapFactory.decodeResource(res, picId[i]),ratio_width,ratio_height);
}
for(int i=0;i<picNum.length;i++)
{
recordNum[i]=scaleToFit(BitmapFactory.decodeResource(res, picNum[i]),ratio_width,ratio_height);
}
}
public static float[][] picLocation;
public static float[][] touchLocation;
//初始化图片的位置信息
public static void initLoaction()
{
//图片的位置信息
float[][] tempPicLocation=new float[][]
{
{0,0},//大背景图片位置
{(SCREEN_WIDTH-recordBitmap[1].getWidth())/2,150},//计时模式图片位置
};
//可触控区间
float[][] tempTouchLocation=new float[][]
{
{(SCREEN_WIDTH-recordBitmap[1].getWidth())/2,150,(SCREEN_WIDTH)/2,200},//Timing Mode的位置
{(SCREEN_WIDTH)/2,150,(SCREEN_WIDTH+recordBitmap[1].getWidth())/2,200},//Racing Mode的位置
{(SCREEN_WIDTH-recordBitmap[1].getWidth())/2,230,(SCREEN_WIDTH+recordBitmap[1].getWidth())/2,410},//绘制时间信息的位置
};
picLocation=new float[tempPicLocation.length][tempPicLocation[0].length];
touchLocation=new float[tempTouchLocation.length][tempTouchLocation[0].length];
for(int i=0;i<tempPicLocation.length;i++)
{
for(int j=0;j<tempPicLocation[0].length;j++)
{
if(j%2==1)
{//高度
picLocation[i][j]=tempPicLocation[i][j]*ratio_height;
}
else if(j%2==0)
{//宽度
picLocation[i][j]=tempPicLocation[i][j];
}
}
}
for(int i=0;i<tempTouchLocation.length;i++)
{
for(int j=0;j<tempTouchLocation[0].length;j++)
{
if(j%2==1)
{//高度
touchLocation[i][j]=tempTouchLocation[i][j]*ratio_height;
}
else if(j%2==0)
{//宽度
touchLocation[i][j]=tempTouchLocation[i][j];
}
}
}
}
}

View File

@@ -0,0 +1,183 @@
package com.bn.st.xc;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import com.bn.core.MatrixState;
import android.opengl.GLES20;
/*
* 用于绘制圆柱,用光照和颜色
*/
public class CylinderTextureByVertex
{
int mProgram;//自定义渲染管着色器程序线程序id
int muMVPMatrixHandle;//总变换矩阵引用id
int maPositionHandle; //顶点位置属性引用id
int maNormalHandle; //顶点法向量属性引用id
int muMMatrixHandle;//位置、旋转变换矩阵
int maLightLocationHandle;//光源位置属性引用id
int maCameraHandle; //摄像机位置属性引用id
int maColorR; //颜色值的R分量引用id
int maColorG; //颜色值的G分量引用id
int maColorB; //颜色值的B分量引用id
int maColorA;
String mVertexShader;//顶点着色器
String mFragmentShader;//片元着色器
private static FloatBuffer mVertexBuffer;//顶点坐标数据缓冲
private static FloatBuffer mNormalBuffer;//顶点法向量数据缓冲
static int vCount=0;//顶点数量
float r; //颜色值的R分量
float g; //颜色值的G分量
float b; //颜色值的B分量
public CylinderTextureByVertex
(
int mProgramIn,
float radius,//圆柱半径
float length,//圆柱长度
float aspan,//切分角度
float lspan,//切分长度
float[]color
)
{
this.r=color[0];
this.g=color[1];
this.b=color[2];
//初始化着色器程序的方法
initShader(mProgramIn);
}
//初始化顶点坐标数据的方法
public static void initVertexData
(
float r,//圆柱半径
float length,//圆柱长度
float aspan,//切分角度
float lspan//切分长度
)
{
//顶点坐标数据的初始化================begin============================
//获取切分整图的纹理数组
ArrayList<Float> alVertix=new ArrayList<Float>();//存放顶点坐标的ArrayList
for(float tempY=length/2;tempY>-length/2;tempY=tempY-lspan)//垂直方向lspan长度一份
{
for(float hAngle=360;hAngle>0;hAngle=hAngle-aspan)//水平方向angleSpan度一份
{
//纵向横向各到一个角度后计算对应的此点在球面上的四边形顶点坐标
//并构建两个组成四边形的三角形
float x1=(float)(r*Math.cos(Math.toRadians(hAngle)));
float z1=(float)(r*Math.sin(Math.toRadians(hAngle)));
float y1=tempY;
float x2=(float)(r*Math.cos(Math.toRadians(hAngle)));
float z2=(float)(r*Math.sin(Math.toRadians(hAngle)));
float y2=tempY-lspan;
float x3=(float)(r*Math.cos(Math.toRadians(hAngle-aspan)));
float z3=(float)(r*Math.sin(Math.toRadians(hAngle-aspan)));
float y3=tempY-lspan;
float x4=(float)(r*Math.cos(Math.toRadians(hAngle-aspan)));
float z4=(float)(r*Math.sin(Math.toRadians(hAngle-aspan)));
float y4=tempY;
//构建第一三角形
alVertix.add(x1);alVertix.add(y1);alVertix.add(z1);
alVertix.add(x2);alVertix.add(y2);alVertix.add(z2);
alVertix.add(x4);alVertix.add(y4);alVertix.add(z4);
//构建第二三角形
alVertix.add(x4);alVertix.add(y4);alVertix.add(z4);
alVertix.add(x2);alVertix.add(y2);alVertix.add(z2);
alVertix.add(x3);alVertix.add(y3);alVertix.add(z3);
}
}
vCount=alVertix.size()/3;//顶点的数量为坐标值数量的1/3因为一个顶点有3个坐标
//将alVertix中的坐标值转存到一个int数组中
float vertices[]=new float[vCount*3];
for(int i=0;i<alVertix.size();i++)
{
vertices[i]=alVertix.get(i);
}
//创建顶点坐标数据缓冲
//vertices.length*4是因为一个整数四个字节
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());//设置字节顺序
mVertexBuffer = vbb.asFloatBuffer();//转换为Float型缓冲
mVertexBuffer.put(vertices);//向缓冲区中放入顶点坐标数据
mVertexBuffer.position(0);//设置缓冲区起始位置
//创建顶点法向量坐标缓冲
ByteBuffer nbb = ByteBuffer.allocateDirect(vertices.length*4);
nbb.order(ByteOrder.nativeOrder());//设置字节顺序
mNormalBuffer = nbb.asFloatBuffer();//转换为Float型缓冲
mNormalBuffer.put(vertices);//向缓冲区中放入顶点着色数据
mNormalBuffer.position(0);//设置缓冲区起始位置
}
public void initShader(int mProgramIn)
{
mProgram = mProgramIn;
//获取程序中顶点位置属性引用id
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
//获取程序中顶点颜色属性引用id
maNormalHandle= GLES20.glGetAttribLocation(mProgram, "aNormal");
//获取程序中总变换矩阵引用id
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
//获取位置、旋转变换矩阵引用id
muMMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMMatrix");
//获取程序中光源位置引用id
maLightLocationHandle=GLES20.glGetUniformLocation(mProgram, "uLightLocation");
//获取程序中摄像机位置引用id
maCameraHandle=GLES20.glGetUniformLocation(mProgram, "uCamera");
maColorR=GLES20.glGetUniformLocation(mProgram, "colorR");
maColorG=GLES20.glGetUniformLocation(mProgram, "colorG");
maColorB=GLES20.glGetUniformLocation(mProgram, "colorB");
maColorA=GLES20.glGetUniformLocation(mProgram, "colorA");
}
public void drawSelf(float alpha)
{
//制定使用某套shader程序
GLES20.glUseProgram(mProgram);
//将最终变换矩阵传入shader程序
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//将位置、旋转变换矩阵传入shader程序
GLES20.glUniformMatrix4fv(muMMatrixHandle, 1, false, MatrixState.getMMatrix(), 0);
//将光源位置传入shader程序
GLES20.glUniform3fv(maLightLocationHandle, 1, MatrixState.lightPositionFB);
//将摄像机位置传入shader程序
GLES20.glUniform3fv(maCameraHandle, 1, MatrixState.cameraFB);
//传入顶点位置数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入顶点法向量数据
GLES20.glVertexAttribPointer
(
maNormalHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mNormalBuffer
);
//允许顶点位置、法向量数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maNormalHandle);
GLES20.glUniform1f(maColorR , r);
GLES20.glUniform1f(maColorG , g);
GLES20.glUniform1f(maColorB , b);
GLES20.glUniform1f(maColorA , alpha);
//绘制整个圆柱
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
}

View File

@@ -0,0 +1,51 @@
package com.bn.st.xc;
import static com.bn.st.xc.Constant.*;
import com.bn.core.MatrixState;
import android.opengl.GLES20;
/*
* 用于绘制展台
*/
public class DisplayStation
{
CylinderTextureByVertex cylinderStation;//站台圆柱
private float aspan=8;//水平切分
private float lspan=1;//竖直切分
private float length;
CircleForDraw circle;//绘制圆面
private float alpha1=1.0f;
private float alpha2=0.5f;
public DisplayStation(float radius,float length)
{
this.length=length;
cylinderStation=new CylinderTextureByVertex(ShaderManager.getColorshaderProgram(),radius,length,aspan,lspan,COLOR_CYLINDER);
circle=new CircleForDraw(ShaderManager.getColorshaderProgram(), aspan, radius,COLOR_CIRCLE);
}
//绘制自身的圆柱面
public void drawSelfCylinder()
{
GLES20.glDisable(GLES20.GL_CULL_FACE);
cylinderStation.drawSelf(alpha1);
GLES20.glEnable(GLES20.GL_CULL_FACE);
}
//绘制自身的圆面
public void drawSelfCircle()
{
MatrixState.pushMatrix();
MatrixState.translate(0, length/2, 0);
MatrixState.rotate(-90, 1, 0, 0);
circle.drawSelf(alpha1);
MatrixState.popMatrix();
}
//画透明的圆面
public void drawTransparentCircle()
{
MatrixState.pushMatrix();
MatrixState.translate(0, -Constant.HOUSE_GAO/2+length/2,0);
MatrixState.rotate(-90, 1, 0, 0);
circle.drawSelf(alpha2);
MatrixState.popMatrix();
}
}

View File

@@ -0,0 +1,112 @@
package com.bn.st.xc;
import static com.bn.st.xc.Constant.*;
import com.bn.core.MatrixState;
//此类主要是用来绘制房间
public class HouseForDraw
{
//地面的长、宽和向下平移的距离
private float floorWidth=60;
private float floorHeight=60;
private float floorDownOffset=-WALL_HEIGHT;
//墙的宽高 这里是指 宽高的一半
private float wallWidth=WALL_WIDHT;
private float wallHeight=WALL_HEIGHT;
private float wall_z_offset=(float) Math.cos((float)(Math.PI/6))*wallWidth*2;
TextureRect floor;//地板
ColorLightRect wall;//围墙
TextureRect wall_tex;//纹理墙,用来放置广告
//透明度
private float alpha1=1.0f;
private float alpha2=0.3f;
//绘制展厅的方法
public HouseForDraw ()
{
//创建地面
floor=new TextureRect(ShaderManager.getCommTextureShaderProgram(),floorWidth,floorHeight);
//创建围墙
wall=new ColorLightRect(ShaderManager.getColorshaderProgram(),wallWidth,wallHeight,HOUSE_COLOR[1]);
//创建放置广告的纹理墙
wall_tex=new TextureRect(ShaderManager.getCommTextureShaderProgram(),wallWidth,wallHeight);
}
//绘制地板的方法
public void drawFloor(int texId)
{
MatrixState.pushMatrix();
MatrixState.translate(0, floorDownOffset,0);
MatrixState.rotate(-90, 1, 0, 0);
floor.drawSelf(texId);
MatrixState.popMatrix();
}
public void drawSelf()//不透明
{
//绘制围墙1
MatrixState.pushMatrix();
MatrixState.translate(0, 0,-wall_z_offset);
wall.drawSelf(alpha1);
MatrixState.popMatrix();
//绘制围墙3
MatrixState.pushMatrix();
MatrixState.rotate(120, 0,1, 0);
MatrixState.translate(0,0, -wall_z_offset);
wall.drawSelf(alpha1);
MatrixState.popMatrix();
//绘制围墙5
MatrixState.pushMatrix();
MatrixState.rotate(240, 0,1, 0);
MatrixState.translate(0,0, -wall_z_offset);
wall.drawSelf(alpha1);
MatrixState.popMatrix();
}
//绘制广告墙的方法
public void drawTexWall(int[] texId,int index)
{
//绘制围墙2
MatrixState.pushMatrix();
MatrixState.rotate(60, 0,1, 0);
MatrixState.translate(0,0, -wall_z_offset);
wall_tex.drawSelf(texId[index]);
MatrixState.popMatrix();
//绘制围墙4
MatrixState.pushMatrix();
MatrixState.rotate(180, 0,1, 0);
MatrixState.translate(0,0, -wall_z_offset);
wall_tex.drawSelf(texId[index]);
MatrixState.popMatrix();
//绘制围墙6
MatrixState.pushMatrix();
MatrixState.rotate(300, 0,1, 0);
MatrixState.translate(0,0, -wall_z_offset);
wall_tex.drawSelf(texId[index]);
MatrixState.popMatrix();
}
public void drawTransparentWall()
{
//绘制围墙1
MatrixState.pushMatrix();
MatrixState.translate(0, 0,-wall_z_offset+0.05f);
wall.drawSelf(alpha2);
MatrixState.popMatrix();
//绘制围墙3
MatrixState.pushMatrix();
MatrixState.rotate(120, 0,1, 0);
MatrixState.translate(0,0, -wall_z_offset+0.05f);
wall.drawSelf(alpha2);
MatrixState.popMatrix();
//绘制围墙5
MatrixState.pushMatrix();
MatrixState.rotate(240, 0,1, 0);
MatrixState.translate(0,0, -wall_z_offset+0.05f);
wall.drawSelf(alpha2);
MatrixState.popMatrix();
}
}

View File

@@ -0,0 +1,169 @@
package com.bn.st.xc;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import android.content.res.Resources;
import android.util.Log;
public class LoadUtilTexXC
{
//求两个向量的叉积
public static float[] getCrossProduct(float x1,float y1,float z1,float x2,float y2,float z2)
{
//求出两个矢量叉积矢量在XYZ轴的分量ABC
float A=y1*z2-y2*z1;
float B=z1*x2-z2*x1;
float C=x1*y2-x2*y1;
return new float[]{A,B,C};
}
//向量规格化
public static float[] vectorNormal(float[] vector)
{
//求向量的模
float module=(float)Math.sqrt(vector[0]*vector[0]+vector[1]*vector[1]+vector[2]*vector[2]);
return new float[]{vector[0]/module,vector[1]/module,vector[2]/module};
}
//从obj文件中加载携带顶点信息的物体
public static LoadedObjectVertexTexXC loadFromFileVertexOnly
(String fname, Resources r,int mProgramId)
{
//加载后物体的引用
LoadedObjectVertexTexXC lo=null;
//原始顶点坐标列表--直接从obj文件中加载
ArrayList<Float> alv=new ArrayList<Float>();
//顶点组装面索引列表--根据面的信息从文件中加载
ArrayList<Integer> alFaceIndex=new ArrayList<Integer>();
//结果顶点坐标列表--按面组织好
ArrayList<Float> alvResult=new ArrayList<Float>();
//原始纹理坐标列表
ArrayList<Float> alt=new ArrayList<Float>();
//纹理坐标结果列表
ArrayList<Float> altResult=new ArrayList<Float>();
try
{
InputStream in=r.getAssets().open(fname);
InputStreamReader isr=new InputStreamReader(in);
BufferedReader br=new BufferedReader(isr);
String temps=null;
//扫面文件,根据行类型的不同执行不同的处理逻辑
while((temps=br.readLine())!=null)
{
//用空格分割行中的各个组成部分
String[] tempsa=temps.split("[ ]+");
if(tempsa[0].trim().equals("v"))
{//此行为顶点坐标
//若为顶点坐标行则提取出此顶点的XYZ坐标添加到原始顶点坐标列表中
alv.add(Float.parseFloat(tempsa[1]));
alv.add(Float.parseFloat(tempsa[2]));
alv.add(Float.parseFloat(tempsa[3]));
}
else if(tempsa[0].trim().equals("vt"))
{//此行为纹理坐标行
//若为纹理坐标行则提取ST坐标并添加进原始纹理坐标列表中
//采用国画小品纹理图时的代码
alt.add(Float.parseFloat(tempsa[1]));
alt.add(Float.parseFloat(tempsa[2]));
}
else if(tempsa[0].trim().equals("f"))
{//此行为三角形面
/*
*若为三角形面行则根据 组成面的顶点的索引从原始顶点坐标列表中
*提取相应的顶点坐标值添加到结果顶点坐标列表中,同时根据三个
*顶点的坐标计算出此面的法向量并添加到平均前各个索引对应的点
*的法向量集合组成的Map中
*/
int[] index=new int[3];//三个顶点索引值的数组
//计算第0个顶点的索引并获取此顶点的XYZ三个坐标
index[0]=Integer.parseInt(tempsa[1].split("/")[0])-1;
float x0=alv.get(3*index[0]);
float y0=alv.get(3*index[0]+1);
float z0=alv.get(3*index[0]+2);
alvResult.add(x0);
alvResult.add(y0);
alvResult.add(z0);
//计算第1个顶点的索引并获取此顶点的XYZ三个坐标
index[1]=Integer.parseInt(tempsa[2].split("/")[0])-1;
float x1=alv.get(3*index[1]);
float y1=alv.get(3*index[1]+1);
float z1=alv.get(3*index[1]+2);
alvResult.add(x1);
alvResult.add(y1);
alvResult.add(z1);
//计算第2个顶点的索引并获取此顶点的XYZ三个坐标
index[2]=Integer.parseInt(tempsa[3].split("/")[0])-1;
float x2=alv.get(3*index[2]);
float y2=alv.get(3*index[2]+1);
float z2=alv.get(3*index[2]+2);
alvResult.add(x2);
alvResult.add(y2);
alvResult.add(z2);
//记录此面的顶点索引
alFaceIndex.add(index[0]);
alFaceIndex.add(index[1]);
alFaceIndex.add(index[2]);
//将纹理坐标组织到结果纹理坐标列表中
//第0个顶点的纹理坐标
int indexTex=Integer.parseInt(tempsa[1].split("/")[1])-1;
altResult.add(alt.get(indexTex*2));
altResult.add(alt.get(indexTex*2+1));
//第1个顶点的纹理坐标
indexTex=Integer.parseInt(tempsa[2].split("/")[1])-1;
altResult.add(alt.get(indexTex*2));
altResult.add(alt.get(indexTex*2+1));
//第2个顶点的纹理坐标
indexTex=Integer.parseInt(tempsa[3].split("/")[1])-1;
altResult.add(alt.get(indexTex*2));
altResult.add(alt.get(indexTex*2+1));
}
}
//生成顶点数组
int size=alvResult.size();
float[] vXYZ=new float[size];
for(int i=0;i<size;i++)
{
vXYZ[i]=alvResult.get(i);
}
//生成纹理数组
size=altResult.size();
// float[] tST=new float[size];
// for(int i=0;i<size;i++)
// {
// tST[i]=altResult.get(i);
// }
//================贴图没问题的==============
float[] tST=new float[size];
for(int i=0;i<size;i++)
{
if(i%2==1){
tST[i]=1-altResult.get(i);
}else{
tST[i]=altResult.get(i);
}
}
//================贴图没问题的==============
//创建3D物体对象
lo=new LoadedObjectVertexTexXC(mProgramId,vXYZ,tST);
}
catch(Exception e)
{
Log.d("load error", "load error");
e.printStackTrace();
}
return lo;
}
}

View File

@@ -0,0 +1,168 @@
package com.bn.st.xc;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import android.content.res.Resources;
import android.util.Log;
public class LoadUtilXC
{
//求两个向量的叉积
public static float[] getCrossProduct(float x1,float y1,float z1,float x2,float y2,float z2)
{
//求出两个矢量叉积矢量在XYZ轴的分量ABC
float A=y1*z2-y2*z1;
float B=z1*x2-z2*x1;
float C=x1*y2-x2*y1;
return new float[]{A,B,C};
}
//向量规格化
public static float[] vectorNormal(float[] vector)
{
//求向量的模
float module=(float)Math.sqrt(vector[0]*vector[0]+vector[1]*vector[1]+vector[2]*vector[2]);
return new float[]{vector[0]/module,vector[1]/module,vector[2]/module};
}
//从obj文件中加载携带顶点信息的物体并自动计算每个顶点的平均法向量
public static LoadedObjectVertexNormalXC loadFromFileVertexOnly(String fname, Resources r,float rz,float gz,float bz)
{
//加载后物体的引用
LoadedObjectVertexNormalXC lo=null;
//原始顶点坐标列表--直接从obj文件中加载
ArrayList<Float> alv=new ArrayList<Float>();
//顶点组装面索引列表--根据面的信息从文件中加载
ArrayList<Integer> alFaceIndex=new ArrayList<Integer>();
//结果顶点坐标列表--按面组织好
ArrayList<Float> alvResult=new ArrayList<Float>();
//平均前各个索引对应的点的法向量集合Map
//此HashMap的key为点的索引 value为点所在的各个面的法向量的集合
HashMap<Integer,HashSet<Normal>> hmn=new HashMap<Integer,HashSet<Normal>>();
try
{
InputStream in=r.getAssets().open(fname);
InputStreamReader isr=new InputStreamReader(in);
BufferedReader br=new BufferedReader(isr);
String temps=null;
//扫面文件,根据行类型的不同执行不同的处理逻辑
while((temps=br.readLine())!=null)
{
//用空格分割行中的各个组成部分
String[] tempsa=temps.split("[ ]+");
if(tempsa[0].trim().equals("v"))
{//此行为顶点坐标
//若为顶点坐标行则提取出此顶点的XYZ坐标添加到原始顶点坐标列表中
alv.add(Float.parseFloat(tempsa[1]));
alv.add(Float.parseFloat(tempsa[2]));
alv.add(Float.parseFloat(tempsa[3]));
}
else if(tempsa[0].trim().equals("f"))
{//此行为三角形面
/*
*若为三角形面行则根据 组成面的顶点的索引从原始顶点坐标列表中
*提取相应的顶点坐标值添加到结果顶点坐标列表中,同时根据三个
*顶点的坐标计算出此面的法向量并添加到平均前各个索引对应的点
*的法向量集合组成的Map中
*/
int[] index=new int[3];//三个顶点索引值的数组
//计算第0个顶点的索引并获取此顶点的XYZ三个坐标
index[0]=Integer.parseInt(tempsa[1].split("/")[0])-1;
float x0=alv.get(3*index[0]);
float y0=alv.get(3*index[0]+1);
float z0=alv.get(3*index[0]+2);
alvResult.add(x0);
alvResult.add(y0);
alvResult.add(z0);
//计算第1个顶点的索引并获取此顶点的XYZ三个坐标
index[1]=Integer.parseInt(tempsa[2].split("/")[0])-1;
float x1=alv.get(3*index[1]);
float y1=alv.get(3*index[1]+1);
float z1=alv.get(3*index[1]+2);
alvResult.add(x1);
alvResult.add(y1);
alvResult.add(z1);
//计算第2个顶点的索引并获取此顶点的XYZ三个坐标
index[2]=Integer.parseInt(tempsa[3].split("/")[0])-1;
float x2=alv.get(3*index[2]);
float y2=alv.get(3*index[2]+1);
float z2=alv.get(3*index[2]+2);
alvResult.add(x2);
alvResult.add(y2);
alvResult.add(z2);
//记录此面的顶点索引
alFaceIndex.add(index[0]);
alFaceIndex.add(index[1]);
alFaceIndex.add(index[2]);
//通过三角形面两个边向量0-10-2求叉积得到此面的法向量
//求0号点到1号点的向量
float vxa=x1-x0;
float vya=y1-y0;
float vza=z1-z0;
//求0号点到2号点的向量
float vxb=x2-x0;
float vyb=y2-y0;
float vzb=z2-z0;
//通过求两个向量的叉积计算法向量
float[] vNormal=getCrossProduct
(
vxa,vya,vza,vxb,vyb,vzb
);
for(int tempInxex:index)
{//记录每个索引点的法向量到平均前各个索引对应的点的法向量集合组成的Map中
//获取当前索引对应点的法向量集合
HashSet<Normal> hsn=hmn.get(tempInxex);
if(hsn==null)
{//若集合不存在则创建
hsn=new HashSet<Normal>();
}
//将此点的法向量添加到集合中
//由于Normal类重写了equals方法因此同样的法向量不会重复出现在此点
//对应的法向量集合中
hsn.add(new Normal(vNormal[0],vNormal[1],vNormal[2]));
//将集合放进HsahMap中
hmn.put(tempInxex, hsn);
}
}
}
//生成顶点数组
int size=alvResult.size();
float[] vXYZ=new float[size];
for(int i=0;i<size;i++)
{
vXYZ[i]=alvResult.get(i);
}
//生成法向量数组
float[] nXYZ=new float[alFaceIndex.size()*3];
int c=0;
for(Integer i:alFaceIndex)
{
//根据当前点的索引从Map中取出一个法向量的集合
HashSet<Normal> hsn=hmn.get(i);
//求出平均法向量
float[] tn=Normal.getAverage(hsn);
//将计算出的平均法向量存放到法向量数组中
nXYZ[c++]=tn[0];
nXYZ[c++]=tn[1];
nXYZ[c++]=tn[2];
}
//创建3D物体对象
lo=new LoadedObjectVertexNormalXC(vXYZ,nXYZ,rz,gz,bz);
}
catch(Exception e)
{
Log.d("load error", "load error");
e.printStackTrace();
}
return lo;
}
}

View File

@@ -0,0 +1,134 @@
package com.bn.st.xc;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import com.bn.core.MatrixState;
import android.opengl.GLES20;
//加载后的物体——携带顶点信息,自动计算面平均法向量
public class LoadedObjectVertexNormalXC
{
int mProgram;//自定义渲染管线着色器程序id
int muMVPMatrixHandle;//总变换矩阵引用id
int muMMatrixHandle;//位置、旋转变换矩阵
int maPositionHandle; //顶点位置属性引用id
int maNormalHandle; //顶点法向量属性引用id
int maLightLocationHandle;//光源位置属性引用id
int maCameraHandle; //摄像机位置属性引用id
String mVertexShader;//顶点着色器
String mFragmentShader;//片元着色器
int maColorR; //颜色值的R分量引用id
int maColorG; //颜色值的G分量引用id
int maColorB; //颜色值的B分量引用id
int maColorA;
FloatBuffer mVertexBuffer;//顶点坐标数据缓冲
FloatBuffer mNormalBuffer;//顶点法向量数据缓冲
int vCount=0;
float r; //颜色值的R分量
float g; //颜色值的G分量
float b; //颜色值的B分量
public LoadedObjectVertexNormalXC(float[] vertices,float[] normals,float r,float g,float b)
{
//初始化顶点坐标数据的方法
initVertexData(vertices,normals);
this.r=r;
this.g=g;
this.b=b;
}
//初始化顶点坐标数据的方法
public void initVertexData(float[] vertices,float[] normals)
{
//顶点坐标数据的初始化================begin============================
vCount=vertices.length/3;
//创建顶点坐标数据缓冲
//vertices.length*4是因为一个整数四个字节
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());//设置字节顺序
mVertexBuffer = vbb.asFloatBuffer();//转换为Float型缓冲
mVertexBuffer.put(vertices);//向缓冲区中放入顶点坐标数据
mVertexBuffer.position(0);//设置缓冲区起始位置
//顶点法向量数据的初始化================begin============================
ByteBuffer cbb = ByteBuffer.allocateDirect(normals.length*4);
cbb.order(ByteOrder.nativeOrder());//设置字节顺序
mNormalBuffer = cbb.asFloatBuffer();//转换为Float型缓冲
mNormalBuffer.put(normals);//向缓冲区中放入顶点法向量数据
mNormalBuffer.position(0);//设置缓冲区起始位置
}
//初始化着色器程序的方法
public void initShader(int mProgramIn)
{
mProgram = mProgramIn;
//获取程序中顶点位置属性引用id
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
//获取程序中顶点颜色属性引用id
maNormalHandle= GLES20.glGetAttribLocation(mProgram, "aNormal");
//获取程序中总变换矩阵引用id
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
//获取位置、旋转变换矩阵引用id
muMMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMMatrix");
//获取程序中光源位置引用id
maLightLocationHandle=GLES20.glGetUniformLocation(mProgram, "uLightLocation");
//获取程序中摄像机位置引用id
maCameraHandle=GLES20.glGetUniformLocation(mProgram, "uCamera");
maColorR=GLES20.glGetUniformLocation(mProgram, "colorR");
maColorG=GLES20.glGetUniformLocation(mProgram, "colorG");
maColorB=GLES20.glGetUniformLocation(mProgram, "colorB");
maColorA=GLES20.glGetUniformLocation(mProgram, "colorA");
}
public void drawSelf(float Alpha)
{
//制定使用某套shader程序
GLES20.glUseProgram(mProgram);
//将最终变换矩阵传入shader程序
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//将位置、旋转变换矩阵传入shader程序
GLES20.glUniformMatrix4fv(muMMatrixHandle, 1, false, MatrixState.getMMatrix(), 0);
//将光源位置传入shader程序
GLES20.glUniform3fv(maLightLocationHandle, 1, MatrixState.lightPositionFB);
//将摄像机位置传入shader程序
GLES20.glUniform3fv(maCameraHandle, 1, MatrixState.cameraFB);
//传入顶点位置数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入顶点法向量数据
GLES20.glVertexAttribPointer
(
maNormalHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mNormalBuffer
);
//允许顶点位置、法向量数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maNormalHandle);
GLES20.glUniform1f(maColorR , r);
GLES20.glUniform1f(maColorG , g);
GLES20.glUniform1f(maColorB , b);
GLES20.glUniform1f(maColorA , Alpha);
//绘制加载的物体
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
}

View File

@@ -0,0 +1,106 @@
package com.bn.st.xc;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import com.bn.core.MatrixState;
import android.opengl.GLES20;
//加载后的物体——顶点+纹理坐标
public class LoadedObjectVertexTexXC
{
int mProgram;//自定义渲染管线着色器程序id
int muMVPMatrixHandle;//总变换矩阵引用id
int muMMatrixHandle;//位置、旋转变换矩阵
int maPositionHandle; //顶点位置属性引用id
int maTexCoorHandle; //顶点纹理坐标属性引用id
FloatBuffer mVertexBuffer;//顶点坐标数据缓冲
FloatBuffer mTexCoorBuffer;//顶点纹理坐标数据缓冲
int vCount=0;
public LoadedObjectVertexTexXC(int mProgramId,float[] vertices,float texCoors[])
{
//初始化顶点坐标数据的方法
initVertexData(vertices,texCoors);
//初始化着色器程序的方法
//initShader(mProgramId);
}
//初始化顶点坐标数据的方法
public void initVertexData(float[] vertices,float texCoors[])
{
//顶点坐标数据的初始化================begin============================
vCount=vertices.length/3;
//创建顶点坐标数据缓冲
//vertices.length*4是因为一个整数四个字节
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());//设置字节顺序
mVertexBuffer = vbb.asFloatBuffer();//转换为Float型缓冲
mVertexBuffer.put(vertices);//向缓冲区中放入顶点坐标数据
mVertexBuffer.position(0);//设置缓冲区起始位置
//顶点纹理坐标数据的初始化================begin============================
ByteBuffer tbb = ByteBuffer.allocateDirect(texCoors.length*4);
tbb.order(ByteOrder.nativeOrder());//设置字节顺序
mTexCoorBuffer = tbb.asFloatBuffer();//转换为Float型缓冲
mTexCoorBuffer.put(texCoors);//向缓冲区中放入顶点纹理坐标数据
mTexCoorBuffer.position(0);//设置缓冲区起始位置
}
//初始化着色器程序的方法
public void initShader(int mProgramId)
{
//基于顶点着色器与片元着色器创建程序
mProgram = mProgramId;
//获取程序中顶点位置属性引用id
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
//获取程序中总变换矩阵引用id
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
//获取位置、旋转变换矩阵引用id
muMMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMMatrix");
//获取程序中顶点纹理坐标属性引用id
maTexCoorHandle= GLES20.glGetAttribLocation(mProgram, "aTexCoor");
}
public void drawSelf(int texId)
{
//制定使用某套shader程序
GLES20.glUseProgram(mProgram);
//将最终变换矩阵传入shader程序
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//将位置、旋转变换矩阵传入shader程序
GLES20.glUniformMatrix4fv(muMMatrixHandle, 1, false, MatrixState.getMMatrix(), 0);
//传入顶点位置数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入顶点纹理坐标数据
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false,
2*4,
mTexCoorBuffer
);
//允许顶点位置、法向量、纹理坐标数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
//绘制加载的物体
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
}

View File

@@ -0,0 +1,64 @@
package com.bn.st.xc;
import java.util.Set;
//表示法向量的类,此类的一个对象表示一个法向量
public class Normal
{
public static final float DIFF=0.0000001f;//判断两个法向量是否相同的阈值
//法向量在XYZ轴上的分量
float nx;
float ny;
float nz;
public Normal(float nx,float ny,float nz)
{
this.nx=nx;
this.ny=ny;
this.nz=nz;
}
@Override
public boolean equals(Object o)
{
if(o instanceof Normal)
{//若两个法向量XYZ三个分量的差都小于指定的阈值则认为这两个法向量相等
Normal tn=(Normal)o;
if(Math.abs(nx-tn.nx)<DIFF&&
Math.abs(ny-tn.ny)<DIFF&&
Math.abs(ny-tn.ny)<DIFF
)
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
//由于要用到HashSet因此一定要重写hashCode方法
@Override
public int hashCode()
{
return 1;
}
//求法向量平均值的工具方法
public static float[] getAverage(Set<Normal> sn)
{
//存放法向量和的数组
float[] result=new float[3];
//把集合中所有的法向量求和
for(Normal n:sn)
{
result[0]+=n.nx;
result[1]+=n.ny;
result[2]+=n.nz;
}
//将求和后的法向量规格化
return LoadUtilXC.vectorNormal(result);
}
}

View File

@@ -0,0 +1,48 @@
package com.bn.st.xc;
import com.bn.core.ShaderUtil;
import android.content.res.Resources;
public class ShaderManager
{
final static int shaderCount=2;
final static String[][] shaderName=
{
{"vertex_tex.sh","frag_tex.sh"},
{"vertex_color.sh","frag_color.sh"},
};
static String[]mVertexShader=new String[shaderCount];
static String[]mFragmentShader=new String[shaderCount];
static int[] program=new int[shaderCount];
public static void loadCodeFromFile(Resources r)
{
for(int i=0;i<shaderCount;i++)
{
//加载顶点着色器的脚本内容
mVertexShader[i]=ShaderUtil.loadFromAssetsFile(shaderName[i][0],r);
//加载片元着色器的脚本内容
mFragmentShader[i]=ShaderUtil.loadFromAssetsFile(shaderName[i][1], r);
}
}
//编译shader
public static void compileShaderReal()
{
for(int i=0;i<shaderCount;i++)
{
program[i]=ShaderUtil.createProgram(mVertexShader[i], mFragmentShader[i]);
}
}
//这里返回的是纹理的shader程序
public static int getCommTextureShaderProgram()
{
return program[0];
}
//这里返回的是颜色的shader程序
public static int getColorshaderProgram()
{
return program[1];
}
}

View File

@@ -0,0 +1,116 @@
package com.bn.st.xc;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import com.bn.core.MatrixState;
import android.opengl.GLES20;
//纹理矩形
public class TextureRect
{
int mProgram;//自定义渲染管线着色器程序id
int muMVPMatrixHandle;//总变换矩阵引用id
int maPositionHandle; //顶点位置属性引用id
int maTexCoorHandle; //顶点纹理坐标属性引用id
FloatBuffer mVertexBuffer;//顶点坐标数据缓冲
FloatBuffer mTexCoorBuffer;//顶点纹理坐标数据缓冲
int vCount=0;
public TextureRect(int mProgramIn,float width,float height)
{
//初始化顶点坐标数据的方法
initVertexData(width,height);
//初始化着色器程序的方法
initShader(mProgramIn);
}
//初始化顶点坐标数据的方法
public void initVertexData(float width,float height)
{
//顶点坐标数据的初始化================begin============================
vCount=6;
float vertices[]=new float[]
{
-width,height,0,
-width,-height,0,
width,-height,0,
width,-height,0,
width,height,0,
-width,height,0
};
//创建顶点坐标数据缓冲
//vertices.length*4是因为一个整数四个字节
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());//设置字节顺序
mVertexBuffer = vbb.asFloatBuffer();//转换为Float型缓冲
mVertexBuffer.put(vertices);//向缓冲区中放入顶点坐标数据
mVertexBuffer.position(0);//设置缓冲区起始位置
float texCoor[]=new float[]//顶点颜色值数组每个顶点4个色彩值RGBA
{
0,0, 0,1, 1,1,
1,1, 1,0, 0,0
};
//创建顶点纹理坐标数据缓冲
ByteBuffer cbb = ByteBuffer.allocateDirect(texCoor.length*4);
cbb.order(ByteOrder.nativeOrder());//设置字节顺序
mTexCoorBuffer = cbb.asFloatBuffer();//转换为Float型缓冲
mTexCoorBuffer.put(texCoor);//向缓冲区中放入顶点着色数据
mTexCoorBuffer.position(0);//设置缓冲区起始位置
}
//初始化着色器程序的方法
public void initShader(int mProgramIn)
{
mProgram = mProgramIn;
//获取程序中顶点位置属性引用id
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
//获取程序中顶点纹理坐标属性引用id
maTexCoorHandle= GLES20.glGetAttribLocation(mProgram, "aTexCoor");
//获取程序中总变换矩阵引用id
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
}
public void drawSelf(int texId)
{
//制定使用某套shader程序
GLES20.glUseProgram(mProgram);
//初始化变换矩阵
//将最终变换矩阵传入shader程序
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
//传入顶点位置数据
GLES20.glVertexAttribPointer
(
maPositionHandle,
3,
GLES20.GL_FLOAT,
false,
3*4,
mVertexBuffer
);
//传入顶点纹理坐标数据
GLES20.glVertexAttribPointer
(
maTexCoorHandle,
2,
GLES20.GL_FLOAT,
false,
2*4,
mTexCoorBuffer
);
//允许顶点位置数据数组
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glEnableVertexAttribArray(maTexCoorHandle);
//绑定纹理
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
//绘制纹理矩形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
}
}

View File

@@ -0,0 +1,684 @@
package com.bn.st.xc;
import java.io.IOException;
import java.io.InputStream;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import com.bn.R;
import com.bn.clp.BoatInfo;
import com.bn.core.MatrixState;
import com.bn.st.d2.MyActivity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.GLUtils;
import android.view.MotionEvent;
import static com.bn.st.xc.Constant.*;
public class XCSurfaceView extends GLSurfaceView
{
final float TOUCH_SCALE_FACTOR = 180.0f/SCREEN_WIDTH;//角度缩放比例
SceneRenderer mRenderer;//场景渲染器
float mPreviousX;//上次的触控位置X坐标
float mPreviousY;//上次的触控位置Y坐标
int tex_index=0;//广告纹理id索引
int textureUpId;//系统分配的游戏前进虚拟按钮纹理id
int textureDownId;//系统分配的游戏后退虚拟按钮纹理id
int texWallId[]=new int[3]; //广告墙纹理Id数组
int texFloorId;//地面纹理id
//船的纹理id数组
int[] heroBoatTexId;
int[] quickBoatTexId;
int[] slowBoatTexId;
//船的纹理图片数组
static Bitmap[] heroBoatTexBitmap;
static Bitmap[] quickBoatTexBitmap;
static Bitmap[] slowBoatTexBitmap;
static Bitmap bmUp;//前进虚拟按钮
static Bitmap bmDown;//后退虚拟按钮
static Bitmap[] bmaWall=new Bitmap[3];//广告墙纹理数组
static Bitmap bmFloor;//地面
private float yAngle=0;//绕Y轴转动角
private float xAngle=20;//仰角
//摄像机坐标
private float cx;
private float cz;
private float cy;
//目标点坐标
private float tx=0;
private float tz=0;
private float ty=-HOUSE_GAO/3;
//摄像机头顶指向
private float upX=0;
private float upY=1;
private float upZ=0;
//----创建物体----------------------
HouseForDraw house;//房间
DisplayStation displayStation;//展台
Boat boat[]=new Boat[3];//船
TextureRect button;//按钮
LoadedObjectVertexNormalXC rome;//创建罗马柱子
private float half_width_button=0.15f;
// private float half_height_button=0.1f;
private float offset_X_Button1=-0.7f;
private float offset_Y_Button1=-0.8f;
private float offset_X_Button2=0.7f;
private float offset_Y_Button2=-0.8f;
//按钮的范围
private float[] button1;
private float[] button2;
public boolean flagForThread=true;//线程标志
public int index_boat=0;//船的索引
private float ratio;//绘制投影矩阵缩放比例
//--------测试惯性---------------
private boolean flag_go;//允许惯性标志位
final int countGoStepInitValue=35;
private int countGoStep=0;
private float acceleratedVelocity=0.06f;
private float ori_angle_speed=7;//初始角速度
private float curr_angle_speed;//当前角速度
private boolean isMoved;//判断是否移动过
//---------纹理墙墙上的广告---------------
public boolean flag_display=true;//广告标志位
public XCSurfaceView(Context context)
{
super(context);
this.setEGLContextClientVersion(2); //设置使用OPENGL ES2.0
mRenderer = new SceneRenderer(); //创建场景渲染器
setRenderer(mRenderer); //设置渲染器
setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);//设置渲染模式为主动渲染
this.setKeepScreenOn(true);
cx=(float)(tx+Math.cos(Math.toRadians(xAngle))*Math.sin(Math.toRadians(yAngle))*XC_DISTANCE);//摄像机x坐标
cz=(float)(tz+Math.cos(Math.toRadians(xAngle))*Math.cos(Math.toRadians(yAngle))*XC_DISTANCE);//摄像机z坐标
cy=(float)(ty+Math.sin(Math.toRadians(xAngle))*XC_DISTANCE);//摄像机y坐标
}
//触摸事件回调方法
@Override
public boolean onTouchEvent(MotionEvent e)
{
float y = e.getY();//得到按下的XY坐标
float x = e.getX();
float domain_span=5;
switch (e.getAction())
{
case MotionEvent.ACTION_MOVE:
float dx = x - mPreviousX;//计算触控笔X位移
float dy = y- mPreviousY;//
yAngle -= dx * TOUCH_SCALE_FACTOR;//
xAngle -= dy * TOUCH_SCALE_FACTOR/2.0f;//仰角改变
if(xAngle>45)//仰角的最大值
{
xAngle=45;
}
if(xAngle<10){//仰角的最小值
xAngle=10;
}
if(Math.abs(dx)>domain_span)//确定一个阈值
{
isMoved=true;//表示当前移动过
//设置当前角速度
curr_angle_speed=ori_angle_speed*(-dx/SCREEN_WIDTH);
if(dx>20||dx<-20)
{
if(curr_angle_speed>0)
{
curr_angle_speed=curr_angle_speed+ori_angle_speed;
}
else
{
curr_angle_speed=curr_angle_speed-ori_angle_speed;
}
}
//设置加速度大小
acceleratedVelocity=0.03f;
//若当前角速度大于零则加速度置为负
if(curr_angle_speed>0)
{
acceleratedVelocity=-0.03f;
}
}
cx=(float)(tx+Math.cos(Math.toRadians(xAngle))*Math.sin(Math.toRadians(yAngle))*XC_DISTANCE);//摄像机x坐标
cz=(float)(tz+Math.cos(Math.toRadians(xAngle))*Math.cos(Math.toRadians(yAngle))*XC_DISTANCE);//摄像机z坐标
cy=(float)(ty+Math.sin(Math.toRadians(xAngle))*XC_DISTANCE);//摄像机y坐标
break;
case MotionEvent.ACTION_DOWN :
flag_go=false;
if(x>button1[0]&&x<button1[1]&&y>button1[2]&&y<button1[3])
{
index_boat=(index_boat-1+3)%3;
}
if(x>button2[0]&&x<button2[1]&&y>button2[2]&&y<button2[3])
{
index_boat=(index_boat+1)%3;
}
BoatInfo.cuttBoatIndex=index_boat;
break;
case MotionEvent.ACTION_UP:
if(isMoved)
{
flag_go=true;
countGoStep=countGoStepInitValue;
isMoved=false;
}
break;
}
mPreviousX = x;//记录触控笔位置
mPreviousY=y;
cx=(float)(tx+Math.cos(Math.toRadians(xAngle))*Math.sin(Math.toRadians(yAngle))*XC_DISTANCE);//摄像机x坐标
cz=(float)(tz+Math.cos(Math.toRadians(xAngle))*Math.cos(Math.toRadians(yAngle))*XC_DISTANCE);//摄像机z坐标
cy=(float)(ty+Math.sin(Math.toRadians(xAngle))*XC_DISTANCE);//摄像机y坐标
return true;
}
//船部件LoadedObjectVertexNormal列表
static LoadedObjectVertexTexXC[][] parts=new LoadedObjectVertexTexXC[3][];
static
{
parts[0]=new LoadedObjectVertexTexXC[BoatInfo.boatPartNames[0].length];
parts[1]=new LoadedObjectVertexTexXC[BoatInfo.boatPartNames[1].length];
parts[2]=new LoadedObjectVertexTexXC[BoatInfo.boatPartNames[2].length];
}
static LoadedObjectVertexNormalXC romeData;
public static void loadVertexFromObj(Resources r)
{
romeData=LoadUtilXC.loadFromFileVertexOnly("rome.obj",r, 1f, 1f, 1f);
for(int j=0;j<BoatInfo.boatPartNames.length;j++)
{
for(int i=0;i<BoatInfo.boatPartNames[j].length;i++)
{
parts[j][i]=LoadUtilTexXC.loadFromFileVertexOnly
(
BoatInfo.boatPartNames[j][i],
r,
ShaderManager.getCommTextureShaderProgram()
);
}
}
}
private class SceneRenderer implements GLSurfaceView.Renderer
{
//long olds;
//long currs;
public void onDrawFrame(GL10 gl)
{
//currs=System.nanoTime();
//System.out.println(1000000000.0/(currs-olds)+"FPS");
//olds=currs;
//清除深度缓冲与颜色缓冲
GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
MatrixState.setProjectFrustum(-ratio, ratio, -1, 1, 2.5f, 1000);
MatrixState.setCamera(cx,cy,cz,tx,ty,tz,upX,upY,upZ);
MatrixState.copyMVMatrix();
//初始化光源位置
MatrixState.setLightLocation(cx, cy+5, cz+3);
//--------------------------绘制船在墙壁上的倒影-------------------------------------------
drawBoatMirrorOnWall();
//在画透明墙
GLES20.glEnable(GLES20.GL_BLEND);//开启混合
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
house.drawTransparentWall();
GLES20.glDisable(GLES20.GL_BLEND); //关闭混合
house.drawFloor(texFloorId);//绘制地板
//绘制广告墙
house.drawTexWall(texWallId,tex_index);
//--------------------------绘制船在展台上的倒影-------------------------------------------
//绘制展台的不透明的圆柱
MatrixState.pushMatrix();
MatrixState.translate(0, -Constant.HOUSE_GAO/2, 0);
displayStation.drawSelfCylinder();
MatrixState.popMatrix();
//绘制船在展台上的倒影
MatrixState.pushMatrix();
drawBoatShadow();
MatrixState.popMatrix();
//绘制透明圆面,开启混合
GLES20.glEnable(GLES20.GL_BLEND);//开启混合
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);//设置混合因子
displayStation.drawTransparentCircle();
GLES20.glDisable(GLES20.GL_BLEND); //关闭混合
//绘制真实船
drawBoat();
//绘制柱子
drawRomeColumn();
//绘制上一个下一个按钮
drawButton();
}
public void onSurfaceChanged(GL10 gl, int width, int height)
{
//设置视窗大小及位置
GLES20.glViewport(0, 0, width, height);
//计算GLSurfaceView的宽高比
ratio = (float) width / height;
virtualButton();
new Thread()
{
@Override
public void run()
{
while(flagForThread)
{
try
{
//这里进行惯性测试
if(flag_go)//如果允许惯性
{
countGoStep--;
if(countGoStep<=0)
{
curr_angle_speed=curr_angle_speed+acceleratedVelocity;//计算当前角速度
}
if(Math.abs(curr_angle_speed)>0.1f)
{
yAngle=yAngle+curr_angle_speed;
cx=(float)(tx+Math.cos(Math.toRadians(xAngle))*Math.sin(Math.toRadians(yAngle))*XC_DISTANCE);//摄像机x坐标
cz=(float)(tz+Math.cos(Math.toRadians(xAngle))*Math.cos(Math.toRadians(yAngle))*XC_DISTANCE);//摄像机z坐标
cy=(float)(ty+Math.sin(Math.toRadians(xAngle))*XC_DISTANCE);//摄像机y坐标
}
else
{
curr_angle_speed=0;
flag_go=false;
}
}
Thread.sleep(10);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}.start();
}
public void onSurfaceCreated(GL10 gl, EGLConfig config)
{
synchronized(MyActivity.boatInitLock)
{
ShaderManager.compileShaderReal();
textureUpId=initTextureFromBitmap(bmUp);//上按钮
textureDownId=initTextureFromBitmap(bmDown);//下按钮
texWallId[0]=initTextureFromBitmap(bmaWall[0]);//广告纹理图1
texWallId[1]=initTextureFromBitmap(bmaWall[1]);//广告纹理图2
texWallId[2]=initTextureFromBitmap(bmaWall[2]);//广告纹理图3
texFloorId=initTextureFromBitmap(bmFloor);//地面纹理图3
heroBoatTexId=new int[heroBoatTexBitmap.length];
quickBoatTexId=new int[quickBoatTexBitmap.length];
slowBoatTexId=new int[slowBoatTexBitmap.length];
for(int i=0;i<heroBoatTexBitmap.length;i++)
{
heroBoatTexId[i]=initTextureFromBitmap(heroBoatTexBitmap[i]);
}
for(int i=0;i<quickBoatTexBitmap.length;i++)
{
quickBoatTexId[i]=initTextureFromBitmap(quickBoatTexBitmap[i]);
}
for(int i=0;i<slowBoatTexBitmap.length;i++)
{
slowBoatTexId[i]=initTextureFromBitmap(slowBoatTexBitmap[i]);
}
//设置屏幕背景色RGBA
GLES20.glClearColor(1f,1f,1f, 1.0f);
//立体物体==========================================================
house=new HouseForDraw();//创建房间
displayStation=new DisplayStation(RADIUS_DISPLAY, LENGTH_DISPLAY);//创建展台
boat[0]=new Boat(parts[0],XCSurfaceView.this);//创建船只ltf
boat[1]=new Boat(parts[1],XCSurfaceView.this);//创建船只cjg
boat[2]=new Boat(parts[2],XCSurfaceView.this);//创建船只pjh
button=new TextureRect(ShaderManager.getCommTextureShaderProgram(), half_width_button, XC_Self_Adapter_Data_TRASLATE[com.bn.clp.Constant.screenId][0]);//绘制相关按钮
//创建罗马柱对象
romeData.initShader(ShaderManager.getColorshaderProgram());
rome=romeData;
//开启背面剪裁
GLES20.glEnable(GLES20.GL_CULL_FACE);
//打开深度检测
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
//打开抖动
GLES20.glEnable(GLES20.GL_DITHER);
MatrixState.setInitStack();
//--------------------------绘制纹理墙------------------------------------------------
new Thread()
{
@Override
public void run()
{
while(flag_display)
{
tex_index=(tex_index+1)%texWallId.length;//每隔两秒换一幅纹理图
try
{
Thread.sleep(2000);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}.start();
//--------------------------绘制纹理墙------------------------------------------------
}
}
//绘制柱子
public void drawRomeColumn()
{
float ratio_column=0.55f;
float column_height=-18;
float adjust=3f;//调整值
//绘制第一个柱子
MatrixState.pushMatrix();
MatrixState.rotate(30, 0, 1, 0);
MatrixState.translate( 0,column_height, -WALL_WIDHT*2+adjust);
MatrixState.scale(ratio_column, ratio_column, ratio_column);
rome.drawSelf(1.0f);
MatrixState.popMatrix();
//逆时针绘制第二根柱子,此时为正方向
MatrixState.pushMatrix();
MatrixState.rotate(90, 0, 1, 0);
MatrixState.translate( 0,column_height, -WALL_WIDHT*2+adjust);
MatrixState.scale(ratio_column, ratio_column, ratio_column);
rome.drawSelf(1.0f);
MatrixState.popMatrix();
//逆时针绘制第三根柱子,此时为正方向
MatrixState.pushMatrix();
MatrixState.rotate(150, 0, 1, 0);
MatrixState.translate( 0,column_height, -WALL_WIDHT*2+adjust);
MatrixState.scale(ratio_column, ratio_column, ratio_column);
rome.drawSelf(1.0f);
MatrixState.popMatrix();
//逆时针绘制第四根柱子,此时为正方向
MatrixState.pushMatrix();
MatrixState.rotate(210, 0, 1, 0);
MatrixState.translate( 0,column_height, -WALL_WIDHT*2+adjust);
MatrixState.scale(ratio_column, ratio_column, ratio_column);
rome.drawSelf(1.0f);
MatrixState.popMatrix();
//逆时针绘制第五根柱子,此时为正方向
MatrixState.pushMatrix();
MatrixState.rotate(270, 0, 1, 0);
MatrixState.translate( 0,column_height, -WALL_WIDHT*2+adjust);
MatrixState.scale(ratio_column, ratio_column, ratio_column);
rome.drawSelf(1.0f);
MatrixState.popMatrix();
//逆时针绘制第六根柱子,此时为正方向
MatrixState.pushMatrix();
MatrixState.rotate(330, 0, 1, 0);
MatrixState.translate( 0,column_height, -WALL_WIDHT*2+adjust);
MatrixState.scale(ratio_column, ratio_column, ratio_column);
rome.drawSelf(1.0f);
MatrixState.popMatrix();
}
//绘制船的方法
public void drawBoat()
{
MatrixState.pushMatrix();
switch(index_boat)
{
case 0://腾飞的船
MatrixState.translate(0, -10f, 0);
MatrixState.scale(RATIO_BOAT, RATIO_BOAT, RATIO_BOAT);
boat[0].drawSelf(heroBoatTexId);
break;
case 1://大广的船
MatrixState.translate(0, -10f, 0);
MatrixState.scale(RATIO_BOAT, RATIO_BOAT, RATIO_BOAT);
boat[1].drawSelf(quickBoatTexId);
break;
case 2://彭彭的船
MatrixState.translate(0, -10f, 0);
MatrixState.scale(RATIO_BOAT, RATIO_BOAT, RATIO_BOAT);
boat[2].drawSelf(slowBoatTexId);
break;
}
MatrixState.popMatrix();
}
//绘制船的倒影的方法
public void drawBoatShadow()
{
//关闭背面剪裁
GLES20.glDisable(GLES20.GL_CULL_FACE);
MatrixState.pushMatrix();
switch(index_boat)
{
case 0://腾飞的船
MatrixState.translate(-1f, -14f, 0);
MatrixState.rotate(180, 0, 0, 1);
MatrixState.scale(RATIO_BOAT, RATIO_BOAT, RATIO_BOAT);
boat[0].drawSelf(heroBoatTexId);
break;
case 1://大广的船
MatrixState.translate(0.6f, -14f, 0);
MatrixState.rotate(180, 0, 0, 1);
MatrixState.scale(RATIO_BOAT, RATIO_BOAT, RATIO_BOAT);
boat[1].drawSelf(quickBoatTexId);
break;
case 2://彭彭的船
MatrixState.translate(0, -14f, 0);
MatrixState.rotate(180, 0, 0, 1);
MatrixState.scale(RATIO_BOAT, RATIO_BOAT, RATIO_BOAT);
boat[2].drawSelf(slowBoatTexId);
break;
}
MatrixState.popMatrix();
//打开背面剪裁
GLES20.glEnable(GLES20.GL_CULL_FACE);
}
//绘制船在墙中的镜像
public void drawBoatMirrorOnWall()
{
final float ydistance=6f;
final float zdistance=-43f;
int k=(int) Math.abs(yAngle)/360+2;
float yAngleTemp=(yAngle+360*k)%360;
final int span=68;
//在第一面墙
if(yAngleTemp<=span&&yAngleTemp>=0||yAngleTemp>=360-span&&yAngleTemp<=360)
{
MatrixState.pushMatrix();
MatrixState.translate(0, ydistance, zdistance);
MatrixState.rotate(180, 0, 1, 0);
MatrixState.rotate(-15, 1, 0, 0);
drawBoat();
MatrixState.popMatrix();
}
//逆时针在第二面墙画镜像========================?
int bzAngle;
//逆时针在第三个墙面镜像
bzAngle=120;
if(yAngleTemp>bzAngle-span&&yAngleTemp<bzAngle+span)
{
MatrixState.pushMatrix();
MatrixState.rotate(120, 0, 1, 0);
MatrixState.translate(0, ydistance, zdistance);
MatrixState.rotate(-90, 0, 1, 0);
MatrixState.rotate(-15, 0, 0, 1);
drawBoat();
MatrixState.popMatrix();
}
//逆时针第五个面
bzAngle=240;
if(yAngleTemp>bzAngle-span&&yAngleTemp<bzAngle+span)
{
MatrixState.pushMatrix();
MatrixState.rotate(240, 0, 1, 0);
MatrixState.translate(0, ydistance, zdistance);
MatrixState.rotate(90, 0, 1, 0);
MatrixState.rotate(15, 0, 0, 1);
drawBoat();
MatrixState.popMatrix();
}
}
//绘制相关按钮
public void drawButton()
{
//设置正交矩阵
MatrixState.setProjectOrtho(-1,1,-1,1,1,100);
//设置摄像机
MatrixState.setCamera(0, 0, 0, 0, 0,-1, 0, 1, 0);
MatrixState.copyMVMatrix();
//开启混合
GLES20.glEnable(GLES20.GL_BLEND);
//设置混合因子
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
MatrixState.pushMatrix();
MatrixState.translate(-0.7f, -0.8f, -1);
button.drawSelf(textureUpId);//绘制后移按钮
MatrixState.popMatrix();
MatrixState.pushMatrix();
MatrixState.translate(0.7f, -0.8f, -1);
button.drawSelf(textureDownId);//绘制后移按钮
MatrixState.popMatrix();
//关闭混合
GLES20.glDisable(GLES20.GL_BLEND);
}
}
//虚拟按钮的监听方法
public void virtualButton()
{
//按钮1左边所占的比例
float leftEdge=(float)(1-half_width_button+offset_X_Button1)/2*SCREEN_WIDTH;
float rightEdge=(float)(1+half_width_button+offset_X_Button1)/2*SCREEN_WIDTH;
float topEdge=(float)(1-XC_Self_Adapter_Data_TRASLATE[com.bn.clp.Constant.screenId][0]-offset_Y_Button1)/2*SCREEN_HEIGHT;
float bottomEdge=(float)(1+XC_Self_Adapter_Data_TRASLATE[com.bn.clp.Constant.screenId][0]-offset_Y_Button1)/2*SCREEN_HEIGHT;
button1=new float[]{leftEdge,rightEdge,topEdge,bottomEdge};
//按钮2左边所占的比例
leftEdge=(float)(1-half_width_button+offset_X_Button2)/2*SCREEN_WIDTH;
rightEdge=(float)(1+half_width_button+offset_X_Button2)/2*SCREEN_WIDTH;
topEdge=(float)(1-XC_Self_Adapter_Data_TRASLATE[com.bn.clp.Constant.screenId][0]-offset_Y_Button2)/2*SCREEN_HEIGHT;
bottomEdge=(float)(1+XC_Self_Adapter_Data_TRASLATE[com.bn.clp.Constant.screenId][0]-offset_Y_Button2)/2*SCREEN_HEIGHT;
button2=new float[]{leftEdge,rightEdge,topEdge,bottomEdge};
}
public int initTextureFromBitmap(Bitmap bitmapTmp)//textureId
{
//生成纹理ID
int[] textures = new int[1];
GLES20.glGenTextures
(
1, //产生的纹理id的数量
textures, //纹理id的数组
0 //偏移量
);
int textureId=textures[0];
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,GLES20.GL_NEAREST);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MAG_FILTER,GLES20.GL_NEAREST);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,GLES20.GL_REPEAT);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,GLES20.GL_REPEAT);
//实际加载纹理
GLUtils.texImage2D
(
GLES20.GL_TEXTURE_2D, //纹理类型在OpenGL ES中必须为GL10.GL_TEXTURE_2D
0, //纹理的层次0表示基本图像层可以理解为直接贴图
bitmapTmp, //纹理图像
0 //纹理边框尺寸
);
return textureId;
}
public static void loadWelcomeBitmap(Resources r)
{
InputStream is=null;
try
{
is= r.openRawResource(R.drawable.up);
bmUp=BitmapFactory.decodeStream(is);
is= r.openRawResource(R.drawable.down);
bmDown=BitmapFactory.decodeStream(is);
is= r.openRawResource(R.drawable.gg1);
bmaWall[0]=BitmapFactory.decodeStream(is);
is= r.openRawResource(R.drawable.gg2);
bmaWall[1]=BitmapFactory.decodeStream(is);
is= r.openRawResource(R.drawable.gg3);
bmaWall[2]=BitmapFactory.decodeStream(is);
is= r.openRawResource(R.drawable.floor);
bmFloor=BitmapFactory.decodeStream(is);
heroBoatTexBitmap=new Bitmap[parts[0].length];
quickBoatTexBitmap=new Bitmap[parts[1].length];
slowBoatTexBitmap=new Bitmap[parts[2].length];
for(int i=0;i<parts[0].length;i++)
{
is= r.openRawResource(BoatInfo.boatTexIdName[0][i]);
heroBoatTexBitmap[i]=BitmapFactory.decodeStream(is);
}
for(int i=0;i<parts[1].length;i++)
{
is= r.openRawResource(BoatInfo.boatTexIdName[1][i]);
quickBoatTexBitmap[i]=BitmapFactory.decodeStream(is);
}
for(int i=0;i<parts[2].length;i++)
{
is= r.openRawResource(BoatInfo.boatTexIdName[2][i]);
slowBoatTexBitmap[i]=BitmapFactory.decodeStream(is);
}
}
finally
{
try
{
is.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
}