package manakeri.Zombicalypse; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Camera; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.Mesh; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.Sprite; import com.badlogic.gdx.graphics.g2d.SpriteCache; import com.badlogic.gdx.graphics.g3d.model.still.StillSubMesh; import com.badlogic.gdx.math.Matrix4; import com.badlogic.gdx.math.Vector3; public class City { public static int getnumVertices() { return _numVertices; } private int[][] grid; private final int _width, _height; private Mesh houses; private final Texture tex; private final SpriteCache scache; private final int cacheID; private static int _numVertices; private int road_tiles; private boolean _initialized = false; public City(int width, int height) { if (TGame.DEBUG) { Gdx.app.log(TGame.TAG, "city.constructor"); } _width = width; _height = height; if (TGame.DEBUG) { Gdx.app.log(TGame.TAG, "city.build()"); } build(); Sprite[] sprite = new Sprite[3]; sprite[0] = TGame.atlas.createSprite("road1"); sprite[1] = TGame.atlas.createSprite("road2"); sprite[2] = TGame.atlas.createSprite("road3"); if (TGame.DEBUG) { Gdx.app.log(TGame.TAG, "city.scache"); } scache = new SpriteCache(width * height, true); scache.beginCache(); for (int x = 0; x < _width; x++) { for (int y = 0; y < _height; y++) { int tile = grid[x][y]; if (tile >= 128) { Sprite sp = sprite[tile - 128]; sp.setBounds(x, y, 1, 1); scache.add(sp); } } } cacheID = scache.endCache(); Matrix4 matrix = new Matrix4(); matrix.setToRotation(new Vector3(1, 0, 0), 90); scache.setTransformMatrix(matrix); if (TGame.DEBUG) { Gdx.app.log(TGame.TAG, "city.generateVA()"); } generateVA(); tex = new Texture("data/img/house.png"); _initialized = true; } private void build() { road_tiles = 0; grid = new int[_width][_height]; for (int x = 0; x < _width; x++) { for (int y = 0; y < _height; y++) { if (x == 0 || y == 0 || x == _width - 1 || y == _height - 1) { grid[x][y] = TGame.rand.nextInt(3); } else if ((x % 4 == 0) && (y % 3 == 0)) { // crossroad grid[x][y] = 128; road_tiles++; } else if (x % 4 == 0) { // road x grid[x][y] = 128 + 1; road_tiles++; } else if (y % 3 == 0) { // road y grid[x][y] = 128 + 2; road_tiles++; } else { grid[x][y] = TGame.rand.nextInt(TGame.house.length); } } } } public void dispose() { scache.dispose(); tex.dispose(); } public void draw(Camera cam) { Gdx.gl.glEnable(GL20.GL_DEPTH_TEST); Gdx.gl.glEnable(GL20.GL_CULL_FACE); tex.bind(); TGame.texshader.begin(); TGame.texshader.setUniformi("u_texture", 0); TGame.texshader.setUniformMatrix("u_worldView", cam.combined); houses.render(TGame.texshader, GL20.GL_TRIANGLES); TGame.texshader.end(); scache.setProjectionMatrix(cam.combined); scache.begin(); scache.draw(cacheID); scache.end(); Gdx.gl.glDisable(GL20.GL_DEPTH_TEST); Gdx.gl.glDisable(GL20.GL_CULL_FACE); } private void generateVA() { int house_vertices = 0; for (int x = 0; x < _width; x++) { for (int y = 0; y < _height; y++) { if (grid[x][y] < 128) { for (StillSubMesh mesh : TGame.house[grid[x][y]].subMeshes) { house_vertices += mesh.mesh.getNumVertices(); } // Gdx.app.log(TGame.TAG, "all houses vertices: " + // house_vertices); } } } houses = new Mesh(true, house_vertices * 8, 0, TGame.house[0].subMeshes[0].mesh.getVertexAttributes()); float[] vertices = new float[house_vertices * 8]; int vi = 0; for (int x = 0; x < _width; x++) { for (int z = 0; z < _height; z++) { if (grid[x][z] < 128) { float[] buf = new float[TGame.house[grid[x][z]].subMeshes[0].mesh .getNumVertices() * 8]; TGame.house[grid[x][z]].subMeshes[0].mesh.getVertices(buf); for (int i = 0; i < buf.length;) { vertices[vi++] = buf[i++] + x; vertices[vi++] = buf[i++] + 0; vertices[vi++] = buf[i++] + z + 1; vertices[vi++] = buf[i++]; vertices[vi++] = buf[i++]; vertices[vi++] = buf[i++]; vertices[vi++] = buf[i++]; vertices[vi++] = buf[i++]; } } } } houses.setVertices(vertices); _numVertices = house_vertices + road_tiles * 6; } public int getHeight() { return _height; } /** * Returns the type of the tile at given position * * @param x * X position of the tile at range 0..1 as float * @param z * Z position of the tile at range 0..1 as float * @return Tile type */ public int getTile(float x, float z) { return getTile((int) (x * _width), (int) (z * _height)); } /** * Returns the type of the tile at given position * * @param x * X position of the tile * @param z * Z position of the tile * @return Tile type */ public int getTile(int x, int z) { if (x >= _width) { return -1; } if (z >= _height) { return -1; } return grid[x][z]; } public int getWidth() { return _width; } public boolean isInitialized() { return _initialized; } /** * Is the tile road or not * * @param x * X position of the tile at range 0..1 as float * @param z * Z position of the tile at range 0..1 as float */ public boolean isRoad(float x, float z) { return isRoad((int) (x * _width), (int) (z * _height)); } /** * Is the tile road or not * * @param x * X position of the tile * @param z * Z position of the tile */ public boolean isRoad(int x, int z) { if (getTile(x, z) > 127) { return true; } return false; } }