5.Rtm
public class Rtm extends AndroidApplication
public void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
initialize(new LevelRenderer(), false);
}
这个是固定模式,一定要initialize,而它自己是个Activity
一定要new一个ApplicationListener
public class LevelRenderer implements ApplicationListener {
产生一个camera,来确定坐标系的位置
public void create () {
camera = new PerspectiveCamera(67, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
camera.near = 1;
camera.far = 2000;
batch = new SpriteBatch();
font = new BitmapFont();
load();
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
}
这个camera很简单
public PerspectiveCamera (float fieldOfView, float viewportWidth, float viewportHeight) {
this.fieldOfView = fieldOfView;
this.viewportWidth = viewportWidth;
this.viewportHeight = viewportHeight;
update();
}
public void update () {
float aspect = viewportWidth / viewportHeight;
projection.setToProjection(Math.abs(near), Math.abs(far), fieldOfView, aspect);
view.setToLookAt(position, tmp.set(position).add(direction), up);
combined.set(projection);
Matrix4.mul(combined.val, view.val);
invProjectionView.set(combined);
Matrix4.inv(invProjectionView.val);
frustum.update(invProjectionView);
}
viewport设置为屏幕大小
投影矩阵设置projection.setToProjection(Math.abs(near), Math.abs(far), fieldOfView, aspect);
fieldOfView: The field of view in degrees,是锥形的倾斜角度
//加载资源
private void load () {
try {
//瓦
tiles = new Texture(Gdx.files.internal("data/tiles-3.png"));
tiles.setFilter(TextureFilter.MipMapLinearNearest, TextureFilter.Nearest);
TextureAtlas atlas = new TextureAtlas();
for (int i = 0; i < 12; i++) {
TextureRegion region = new TextureRegion(tiles, i % 4 * 64 + 1, i / 4 * 64 + 1, 64, 64);
atlas.addRegion("" + i, region);
}
float uSize = 62.0f / 256.0f;
float vSize = 62.0f / 256.0f;
//加载了一张地图,没有使用默认的加载mesh的方式,而是采用了map的方式来生成两个mesh
BufferedReader reader = new BufferedReader(new InputStreamReader(Gdx.files.internal("data/level.map").read()));
String line = reader.readLine();
String tokens[] = line.split(",");
camera.position.set(Float.parseFloat(tokens[0]), 0, Float.parseFloat(tokens[1]));
int floors = Integer.parseInt(reader.readLine());
int walls = Integer.parseInt(reader.readLine());
float[] floorVertices = new float[floors * 20];
float[] wallVertices = new float[walls * 20];
short[] floorIndices = new short[floors * 6];
short[] wallIndices = new short[walls * 6];
int idx = 0;
for (int i = 0, j = 0; i < floors; i++) {
for (int k = 0; k < 4; k++) {
tokens = reader.readLine().split(",");
floorVertices[j++] = Float.parseFloat(tokens[0]);
floorVertices[j++] = Float.parseFloat(tokens[1]);
floorVertices[j++] = Float.parseFloat(tokens[2]);
floorVertices[j++] = 0;
floorVertices[j++] = 0;
}
short startIndex = (short)(i * 4);
floorIndices[idx++] = startIndex;
floorIndices[idx++] = (short)(startIndex + 1);
floorIndices[idx++] = (short)(startIndex + 2);
floorIndices[idx++] = (short)(startIndex + 2);
floorIndices[idx++] = (short)(startIndex + 3);
floorIndices[idx++] = startIndex;
int type = Integer.parseInt(reader.readLine());
String textureId = reader.readLine();
TextureRegion region = atlas.findRegion(textureId);
float u = region.getU();
float v = region.getV();
floorVertices[j - 2] = u + uSize;
floorVertices[j - 1] = v;
floorVertices[j - 2 - 5] = u + uSize;
floorVertices[j - 1 - 5] = v + vSize;
floorVertices[j - 2 - 10] = u;
floorVertices[j - 1 - 10] = v + vSize;
floorVertices[j - 2 - 15] = u;
floorVertices[j - 1 - 15] = v;
}
idx = 0;
short startIndex = 0;
for (int i = 0, j = 0; i < walls; i++) {
tokens = reader.readLine().split(",");
if (!tokens[1].equals("0")) {
for (int k = 0; k < 4; k++) {
wallVertices[j++] = Float.parseFloat(tokens[0]);
wallVertices[j++] = Float.parseFloat(tokens[1]);
wallVertices[j++] = Float.parseFloat(tokens[2]);
wallVertices[j++] = 0;
wallVertices[j++] = 0;
if (k < 3) tokens = reader.readLine().split(",");
}
wallIndices[idx++] = startIndex;
wallIndices[idx++] = (short)(startIndex + 1);
wallIndices[idx++] = (short)(startIndex + 2);
wallIndices[idx++] = (short)(startIndex + 2);
wallIndices[idx++] = (short)(startIndex + 3);
wallIndices[idx++] = startIndex;
startIndex += 4;
int type = Integer.parseInt(reader.readLine());
String textureId = reader.readLine();
TextureRegion region = atlas.findRegion(textureId);
float u = region.getU();
float v = region.getV();
wallVertices[j - 2] = u + uSize;
wallVertices[j - 1] = v;
wallVertices[j - 2 - 5] = u + vSize;
wallVertices[j - 1 - 5] = v + vSize;
wallVertices[j - 2 - 10] = u;
wallVertices[j - 1 - 10] = v + vSize;
wallVertices[j - 2 - 15] = u;
wallVertices[j - 1 - 15] = v;
} else {
reader.readLine();
reader.readLine();
reader.readLine();
int type = Integer.parseInt(reader.readLine());
int textureId = Integer.parseInt(reader.readLine());
}
}
floorMesh = new Mesh(true, floors * 4, floors * 6,
new VertexAttribute(VertexAttributes.Usage.Position, 3, "a_position"), new VertexAttribute(
VertexAttributes.Usage.TextureCoordinates, 2, "a_texCoord"));
floorMesh.setVertices(floorVertices);
floorMesh.setIndices(floorIndices);
wallMesh = new Mesh(true, walls * 4, walls * 6, new VertexAttribute(VertexAttributes.Usage.Position, 3, "a_position"),
new VertexAttribute(VertexAttributes.Usage.TextureCoordinates, 2, "a_texCoord"));
wallMesh.setVertices(wallVertices);
wallMesh.setIndices(wallIndices);
reader.close();
} catch (IOException ex) {
throw new GdxRuntimeException(ex);
}
}
//渲染
@Override
public void render () {
GL10 gl = Gdx.gl10;
//viewport设置为全屏
gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glEnable(GL10.GL_TEXTURE_2D);
//应用刚才的投影设置
camera.update();
camera.apply(gl);
//绑定纹理
tiles.bind();
gl.glColor4f(1, 1, 1, 1);
//绘制mesh
floorMesh.render(GL10.GL_TRIANGLES);
wallMesh.render(GL10.GL_TRIANGLES);
batch.begin();
batch.setBlendFunction(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);
//在10,25的地方写一句话
font.draw(batch, "fps: " + Gdx.graphics.getFramesPerSecond() + ", delta:" + Gdx.graphics.getDeltaTime(), 10, 25);
batch.end();
//处理业务逻辑
processInput();
}
//处理业务逻辑
private void processInput () {
float delta = Gdx.graphics.getDeltaTime();
//
// if (Gdx.input.isKeyPressed(Keys.ANY_KEY)==false)
// Gdx.app.log("RTM", "No key pressed");
if (Gdx.input.isKeyPressed(Keys.W)) camera.position.add(camera.direction.tmp().mul(80 * delta));
if (Gdx.input.isKeyPressed(Keys.S)) camera.position.add(camera.direction.tmp().mul(-80 * delta));
if (Gdx.input.isKeyPressed(Keys.A)) angle -= 90 * delta;
if (Gdx.input.isKeyPressed(Keys.D)) angle += 90 * delta;
if (Gdx.input.isTouched()) {
float x = Gdx.input.getX();
float y = Gdx.input.getY();
if (x > Gdx.graphics.getWidth() / 2 + Gdx.graphics.getWidth() / 4) angle += 90 * delta;
if (x < Gdx.graphics.getWidth() / 2 - Gdx.graphics.getWidth() / 4) angle -= 90 * delta;
if (y > Gdx.graphics.getHeight() / 2 + Gdx.graphics.getHeight() / 4)
camera.position.add(camera.direction.tmp().mul(80 * delta));
if (y < Gdx.graphics.getHeight() / 2 - Gdx.graphics.getHeight() / 4)
camera.position.add(camera.direction.tmp().mul(-80 * delta));
}
camera.direction.set((float)Math.cos(Math.toRadians(angle)), 0, (float)Math.sin(Math.toRadians(angle)));
}