com.lyeeedar.Roguelike3D.Game.Level.LevelGraphics.java Source code

Java tutorial

Introduction

Here is the source code for com.lyeeedar.Roguelike3D.Game.Level.LevelGraphics.java

Source

/*******************************************************************************
 * 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;
    }
}