Java tutorial
/******************************************************************************* * Copyright (c) 2013 Philip Collin. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html * * Contributors: * Philip Collin - initial API and implementation ******************************************************************************/ package com.lyeeedar.Roguelike3D.Game.Level; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.Mesh; import com.badlogic.gdx.graphics.Pixmap.Format; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.BitmapFont; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.glutils.FrameBuffer; import com.badlogic.gdx.math.Vector3; import com.lyeeedar.Roguelike3D.Game.GameData; import com.lyeeedar.Roguelike3D.Game.Level.XML.BiomeReader; import com.lyeeedar.Roguelike3D.Graphics.Lights.LightManager; import com.lyeeedar.Roguelike3D.Graphics.Models.Shapes; import com.lyeeedar.Roguelike3D.Graphics.Models.TempMesh; import com.lyeeedar.Roguelike3D.Graphics.Models.TempVO; import com.lyeeedar.Roguelike3D.Graphics.Models.VisibleObject; public class LevelGraphics { public static final int CHUNK_WIDTH = 10; public static final int CHUNK_HEIGHT = 10; public ArrayList<VisibleObject> graphics = new ArrayList<VisibleObject>(); Tile[][] levelArray; HashMap<Character, Color> colours; BiomeReader biome; public int width; public int height; TempVO[][] tempVOs; TempVO[][] tempRoofs; int wBlocks; int hBlocks; public Texture map; public final boolean drawRoofs; public LevelGraphics(Tile[][] levelArray, HashMap<Character, Color> colours, BiomeReader biome, boolean drawRoofs) { this.drawRoofs = drawRoofs; this.levelArray = levelArray; this.colours = colours; this.biome = biome; width = levelArray.length; height = levelArray[0].length; tempVOs = new TempVO[width][height]; if (drawRoofs) tempRoofs = new TempVO[width][height]; wBlocks = (width / CHUNK_WIDTH) + 1; hBlocks = (height / CHUNK_HEIGHT) + 1; createMap(levelArray); } public static final int STEP = 10; public void createMap(Tile[][] levelArray) { BitmapFont font = new BitmapFont(); SpriteBatch sB = new SpriteBatch(); FrameBuffer fB = new FrameBuffer(Format.RGBA4444, width * STEP, height * STEP, false); fB.begin(); sB.begin(); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { char c = levelArray[x][y].character; if (c == ' ') continue; font.setColor(colours.get(c)); font.draw(sB, "" + c, x * STEP, y * STEP); } } sB.end(); fB.end(); map = fB.getColorBufferTexture(); } int tileX = 0; public boolean createTileRow() { if (tileX == width) return true; for (int z = 0; z < height; z++) { Tile t = levelArray[tileX][z]; if (t.character == ' ') continue; TempVO vo = new TempVO(Shapes.genTempCuboid(GameData.BLOCK_SIZE, t.height, GameData.BLOCK_SIZE), GL20.GL_TRIANGLES, colours.get(t.character), getTexture(t.character, biome), tileX * 10, t.height / 2, z * 10); tempVOs[tileX][z] = vo; if (drawRoofs && t.height < t.roof) { TempVO voRf = new TempVO(Shapes.genTempCuboid(GameData.BLOCK_SIZE, 1, GameData.BLOCK_SIZE), GL20.GL_TRIANGLES, colours.get('#'), getTexture('#', biome), tileX * 10, t.roof, z * 10); tempRoofs[tileX][z] = voRf; } } tileX++; return false; } int chunkX = 0; public boolean createChunkRow() { if (chunkX == wBlocks) return true; for (int y = 0; y < hBlocks; y++) { Chunk chunk = new Chunk(); int startx = chunkX * CHUNK_WIDTH; int starty = y * CHUNK_HEIGHT; for (int ix = 0; ix < CHUNK_WIDTH; ix++) { if (startx + ix == width) break; for (int iy = 0; iy < CHUNK_HEIGHT; iy++) { if (starty + iy == height) break; chunk.addVO(tempVOs[startx + ix][starty + iy], levelArray[startx + ix][starty + iy].character); if (drawRoofs) chunk.addVO(tempRoofs[startx + ix][starty + iy], '#'); } } if (!chunk.isEmpty()) { ArrayList<VisibleObject> chunkGraphics = chunk.merge(); for (VisibleObject vo : chunkGraphics) { graphics.add(vo); } } } chunkX++; return false; } public void bakeLights(LightManager lights, boolean bakeStatics) { for (VisibleObject vo : graphics) { vo.bakeLights(lights, bakeStatics); } } public String getTexture(char c, BiomeReader biome) { String text = null; if (c == '#') { text = biome.getWallTexture(); } else if (c == '.') { text = biome.getFloorTexture(); } return text; } public void dispose() { for (VisibleObject vo : graphics) { vo.dispose(); } } } class Chunk { HashMap<Character, ArrayList<TempVO>> block = new HashMap<Character, ArrayList<TempVO>>(); public boolean isEmpty() { for (Map.Entry<Character, ArrayList<TempVO>> entry : block.entrySet()) { if (entry.getValue().size() != 0) return false; } return true; } public void addVO(TempVO vo, char c) { if (vo == null) return; if (block.containsKey(c)) { ArrayList<TempVO> vos = block.get(c); vos.add(vo); } else { ArrayList<TempVO> vos = new ArrayList<TempVO>(); vos.add(vo); block.put(c, vos); } } final Vector3 tempVec = new Vector3(); public ArrayList<VisibleObject> merge() { ArrayList<VisibleObject> vos = new ArrayList<VisibleObject>(); for (Map.Entry<Character, ArrayList<TempVO>> entry : block.entrySet()) { final TempMesh[] meshes = new TempMesh[entry.getValue().size()]; final TempVO base = entry.getValue().get(0); final Vector3 baseVec = new Vector3(base.x, base.y, base.z); int i = 0; for (TempVO vo : entry.getValue()) { TempMesh mesh = vo.mesh; tempVec.set(vo.x, vo.y, vo.z); tempVec.sub(baseVec); Shapes.translateCubeVertices(mesh.vertexNum, mesh.vertexSize, mesh.vertices, tempVec.x, tempVec.y, tempVec.z); meshes[i] = mesh; i++; } Mesh merged = Shapes.merge(meshes); VisibleObject vo = new VisibleObject(merged, base.colour, base.textureName, base.primitive_type, 1.0f); vo.attributes.getTransform().setToTranslation(baseVec); vo.attributes.radius *= 4; vos.add(vo); } return vos; } }