game.states.State_PREFAB_EDITOR.java Source code

Java tutorial

Introduction

Here is the source code for game.states.State_PREFAB_EDITOR.java

Source

/*******************************************************************************
 * Copyright (c) 2013 Glynn Taylor.
 * All rights reserved. This program and the accompanying materials, 
 * (excluding imported libraries, such as LWJGL and Slick2D)
 * are made available under the terms of the GNU Public License
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/gpl.html
 * 
 * Contributors:
 *     Glynn Taylor - initial API and implementation
 ******************************************************************************/
/*
 * A state that handles how the prefab editor functions
 */
package game.states;

import game.graphics.GUI_Layer;
import game.graphics.GUI_PrefabMap;
import game.graphics.GUI_PrefabPalette;
import game.level.map.Prefab;
import game.level.map.TileDefinition;
import game.level.map.TileMapGenerator;
import game.states.Game.GameState;
import game.util.PrefabBrowser;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import javax.swing.JOptionPane;

import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;
import org.newdawn.slick.Color;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
import org.newdawn.slick.util.ResourceLoader;

public class State_PREFAB_EDITOR extends State {
    private final int RoomWidth = 100;
    private final int RoomHeight = 75;
    private Prefab prefab = new Prefab(RoomWidth, RoomHeight);
    private final int ScreenHeight = Game.Height;
    private float CameraX = -16;
    private float CameraY = 30;
    private float CameraZ = 0;

    private final float MapRotatef = 180;
    private final long InputTimePassed = 0;
    private final long InputDelayMili = 100;
    private int FPS;
    private long LastSecond;
    private final float CameraDisplacement = TileMapGenerator.CUBE_LENGTH;
    private GUI_Layer ButtonGUILayer;
    private GUI_Layer MenuGUILayer;
    private final GUI_PrefabMap PrefabMap = new GUI_PrefabMap(90, 68, 493, 389, prefab);
    private final GUI_PrefabPalette PrefabPalette = new GUI_PrefabPalette(53, 533, 558, 62, 634, 558, 62);

    public void Create(int xLimit, int yLimit) {
        prefab = new Prefab(xLimit, yLimit);
        PrefabMap.setPrefab(prefab);
    }

    @Override
    protected void Init() {
        ButtonGUILayer = new GUI_Layer();
        ButtonGUILayer.SetEnabled(true);
        MenuGUILayer = new GUI_Layer();
        MenuGUILayer.SetEnabled(false);
        int ButtonStartX = 712;
        int ButtonStartY = 600;
        float xScale = 1.5f;
        float yScale = 1.5f;
        int Spacing = 145;
        int menuButtonStartX = 640 - 128;
        int menuButtonStartY = 150;
        float menuXScale = 1f;
        float menuYScale = 1f;
        int menuSpacing = 110;
        try {
            GL11.glEnable(GL11.GL_TEXTURE_2D);
            BackGroundImage = TextureLoader.getTexture("PNG",
                    ResourceLoader.getResourceAsStream("res/Materials/GUI/UI/GUIPrefab.png"));
            Texture button1 = TextureLoader.getTexture("PNG",
                    ResourceLoader.getResourceAsStream("res/Materials/GUI/UI/SaveIconButton.png"), false,
                    GL11.GL_NEAREST);
            ButtonGUILayer.AddButton(ButtonStartX + Spacing * 0, ButtonStartY,
                    (int) (button1.getImageWidth() * xScale), (int) (button1.getImageHeight() * yScale), button1);
            Texture button2 = TextureLoader.getTexture("PNG",
                    ResourceLoader.getResourceAsStream("res/Materials/GUI/UI/LoadIconButton.png"), false,
                    GL11.GL_NEAREST);
            ButtonGUILayer.AddButton(ButtonStartX + Spacing * 1, ButtonStartY,
                    (int) (button2.getImageWidth() * xScale), (int) (button2.getImageHeight() * yScale), button2);
            Texture button3 = TextureLoader.getTexture("PNG",
                    ResourceLoader.getResourceAsStream("res/Materials/GUI/UI/OptionsIconButton.png"), false,
                    GL11.GL_NEAREST);
            ButtonGUILayer.AddButton(ButtonStartX + Spacing * 2, ButtonStartY,
                    (int) (button3.getImageWidth() * xScale), (int) (button3.getImageHeight() * yScale), button3);
            Texture button4 = TextureLoader.getTexture("PNG",
                    ResourceLoader.getResourceAsStream("res/Materials/GUI/UI/HelpIconButton.png"), false,
                    GL11.GL_NEAREST);
            ButtonGUILayer.AddButton(ButtonStartX + Spacing * 3, ButtonStartY,
                    (int) (button4.getImageWidth() * xScale), (int) (button4.getImageHeight() * yScale), button4);

            Texture mButton0 = TextureLoader.getTexture("PNG",
                    ResourceLoader.getResourceAsStream("res/Materials/GUI/Buttons/ReturnButton.png"), false,
                    GL11.GL_NEAREST);
            MenuGUILayer.AddButton(menuButtonStartX, menuButtonStartY + menuSpacing * 0,
                    (int) (mButton0.getImageWidth() * menuXScale), (int) (mButton0.getImageHeight() * menuYScale),
                    mButton0);
            Texture mButton1 = TextureLoader.getTexture("PNG",
                    ResourceLoader.getResourceAsStream("res/Materials/GUI/Buttons/LoadButton.png"), false,
                    GL11.GL_NEAREST);
            MenuGUILayer.AddButton(menuButtonStartX, menuButtonStartY + menuSpacing * 1,
                    (int) (mButton1.getImageWidth() * menuXScale), (int) (mButton1.getImageHeight() * menuYScale),
                    mButton1);
            Texture mButton2 = TextureLoader.getTexture("PNG",
                    ResourceLoader.getResourceAsStream("res/Materials/GUI/Buttons/SaveButton.png"), false,
                    GL11.GL_NEAREST);
            MenuGUILayer.AddButton(menuButtonStartX, menuButtonStartY + menuSpacing * 2,
                    (int) (mButton2.getImageWidth() * menuXScale), (int) (mButton2.getImageHeight() * menuYScale),
                    mButton2);
            Texture mButton3 = TextureLoader.getTexture("PNG",
                    ResourceLoader.getResourceAsStream("res/Materials/GUI/Buttons/BackButton.png"), false,
                    GL11.GL_NEAREST);
            MenuGUILayer.AddButton(menuButtonStartX, menuButtonStartY + menuSpacing * 3,
                    (int) (mButton3.getImageWidth() * menuXScale), (int) (mButton3.getImageHeight() * menuYScale),
                    mButton3);

        } catch (IOException e) {
            e.printStackTrace();
        }

        GL11.glEnable(GL11.GL_LIGHTING);
        GL11.glEnable(GL11.GL_LIGHT0);
        GL11.glEnableClientState(GL11.GL_NORMAL_ARRAY);
        GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);
        GL11.glMatrixMode(GL11.GL_PROJECTION);
        GL11.glLoadIdentity();

        GLU.gluPerspective(45.0f, (float) Display.getWidth() / (float) Display.getHeight(), 0.1f, 600.0f);
        GLU.gluLookAt(0, 20, 50, 0, -2, -100, 0, -1, 0);
        GL11.glMatrixMode(GL11.GL_MODELVIEW);
        GL11.glLoadIdentity();

        GL11.glEnable(GL11.GL_TEXTURE_2D);
        GL11.glEnable(GL11.GL_BLEND);
        GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
    }

    @Override
    protected void Update() {

        FPS++;
        if (System.currentTimeMillis() - LastSecond > 1000) {
            LastSecond = System.currentTimeMillis();
            System.out.println("Running PREFAB EDITOR: " + Integer.toString(FPS));
            FPS = 0;
        }

    }

    private void DisableAllMenus() {
        MenuGUILayer.SetEnabled(false);
    }

    @Override
    protected void ProcessInput() {

        MenuGUILayer.ProcessInput(MouseLastX, MouseLastY, Mouse.isButtonDown(0));
        ButtonGUILayer.ProcessInput(MouseLastX, MouseLastY, Mouse.isButtonDown(0));
        PrefabMap.ProcessInput(MouseLastX, ScreenHeight - MouseLastY, Mouse.isButtonDown(0),
                PrefabPalette.getSelectedTile());
        PrefabPalette.ProcessInput(MouseLastX, ScreenHeight - MouseLastY, Mouse.isButtonDown(0));
        if (Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) {
            DisableAllMenus();
            MenuGUILayer.toggleEnabled();
        }
        if (Keyboard.isKeyDown(Keyboard.KEY_0)) {
            System.out.println(CameraX);
            System.out.println(CameraY);
            System.out.println(CameraZ);
        }
        if (ButtonGUILayer.isButtonDown(2)) {
            DisableAllMenus();
            MenuGUILayer.toggleEnabled();
        }
        if (ButtonGUILayer.isButtonDown(1))
            LoadPrefab();

        if (ButtonGUILayer.isButtonDown(0))
            SavePrefab();

        if (MenuGUILayer.isButtonDown(0)) {
            DisableAllMenus();
        }
        // Save
        if (MenuGUILayer.isButtonDown(1)) {

        }
        // Load
        if (MenuGUILayer.isButtonDown(2)) {

        }
        if (MenuGUILayer.isButtonDown(3)) {
            DisableAllMenus();
            GameState.SwitchToState(GameState.State_MapEditor, GameState.State_Menu_MapEditor);
        }
        if (ButtonGUILayer.isButtonDown(3)) {
            JOptionPane.showMessageDialog(null, "Use the squares of color to the bottom left to select a color,"
                    + System.getProperty("line.separator")
                    + "then click on a tile on the top left to alter the prefab. View user manual for reference.",
                    "Help", JOptionPane.PLAIN_MESSAGE);

        }

        if (System.currentTimeMillis() - InputTimePassed >= InputDelayMili) {
            if (Keyboard.isKeyDown(Keyboard.KEY_W)) {
                MoveCamera(0, -1);

            } else if (Keyboard.isKeyDown(Keyboard.KEY_S)) {

                MoveCamera(0, 1);
            }
            if (Keyboard.isKeyDown(Keyboard.KEY_A)) {

                MoveCamera(-1, 0);
            } else if (Keyboard.isKeyDown(Keyboard.KEY_D)) {
                MoveCamera(1, 0);
            }

        }
        if (Keyboard.isKeyDown(Keyboard.KEY_Q)) {
            CameraZ -= 1f;
            CameraX -= 0.01f;
            CameraY -= 0.2f;
        }
        if (Keyboard.isKeyDown(Keyboard.KEY_E)) {
            CameraZ += 1f;
            CameraX += 0.01f;
            CameraY += 0.2f;
        }

    }

    private void SavePrefab() {
        if (CheckBoundary(prefab.getMap()) & CheckMiddle(prefab.getMap()) & CheckConnected(prefab.getMap())) {
            PrefabBrowser fb = new PrefabBrowser();
            try {
                String path = fb.GetSavePath();
                if (path != null) {
                    FileOutputStream fileOut = new FileOutputStream(path + ".prefab");
                    ObjectOutputStream out = new ObjectOutputStream(fileOut);
                    out.writeObject(prefab);
                    out.close();
                    fileOut.close();
                }
            } catch (IOException i) {
                i.printStackTrace();
            }
        } else {

            JOptionPane.showMessageDialog(null,
                    "A tile is not connected, the center of the room is a wall, or a boundary tile is floor.",
                    "Room not valid", JOptionPane.PLAIN_MESSAGE);
        }

    }

    private boolean CheckConnected(int[][] map) {
        int xRef = 0;
        int yRef = 0;
        int count = 0;
        String[][] refMap = new String[map.length][map[0].length];
        for (int y = 0; y < map.length; y++) {
            for (int x = 0; x < map[0].length; x++) {
                if (map[y][x] < 0) {
                    count++;
                    xRef = x;
                    yRef = y;
                    refMap[y][x] = "O";
                } else {
                    refMap[y][x] = "X";
                }
            }
        }
        int[] burnedCount = { 0 };
        BurnNode(refMap, xRef, yRef, burnedCount);
        if (burnedCount[0] == count) {
            return true;
        } else {
            System.out.println("Unconnected tile");
            return false;
        }

    }

    private void BurnNode(String[][] refMap, int xRef, int yRef, int[] burnedCount) {

        if (refMap[yRef][xRef] == "O") {
            refMap[yRef][xRef] = "X";
            burnedCount[0]++;
            if (yRef + 1 < refMap.length)
                BurnNode(refMap, xRef, yRef + 1, burnedCount);
            if (yRef - 1 >= 0)
                BurnNode(refMap, xRef, yRef - 1, burnedCount);
            if (xRef + 1 < refMap[0].length)
                BurnNode(refMap, xRef + 1, yRef, burnedCount);
            if (xRef - 1 >= 0)
                BurnNode(refMap, xRef - 1, yRef, burnedCount);
        }
    }

    private boolean CheckMiddle(int[][] map) {
        if (map[map.length / 2][map[0].length / 2] >= 0) {
            System.out.println("Middle tile");
            return false;
        }
        return true;
    }

    private boolean CheckBoundary(int[][] map) {
        boolean valid = true;
        for (int y = 0; y < map.length; y++) {
            if (map[y][0] < 0 || map[y][map[0].length - 1] < 0)
                valid = false;
        }
        for (int x = 0; x < map[0].length; x++) {
            if (map[0][x] < 0 || map[map.length - 1][x] < 0)
                valid = false;
        }
        if (!valid)
            System.out.println("Boundary");
        return valid;
    }

    public void LoadPrefab() {
        PrefabBrowser fb = new PrefabBrowser();
        try {

            String path = fb.GetOpenPath();
            if (path != null) {
                File f = new File(path);
                FileInputStream fileIn = new FileInputStream(f);

                ObjectInputStream in = new ObjectInputStream(fileIn);
                Prefab p = (Prefab) in.readObject();
                prefab = p;
                PrefabMap.setPrefab(prefab);
                in.close();
                fileIn.close();
                fb.DestroyMe();

            }
        } catch (IOException | ClassNotFoundException e) {

            System.out.println("ERROR: Failed to load image @ Filebrowser");
            e.printStackTrace();
        }

    }

    private void MoveCamera(int x, int y) {
        CameraY -= CameraDisplacement * y;
        CameraX += CameraDisplacement * x;

    }

    @Override
    protected void Render() {

        OrthoMode();
        ModelMode();

        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
        GL11.glEnable(GL11.GL_TEXTURE_2D);
        DrawBackground();

        ButtonGUILayer.Render();
        if (PrefabMap != null)
            PrefabMap.Render();
        PrefabPalette.Render();
        Color.white.bind();
        MenuGUILayer.Render();

        ProjectionMode();
        ModelMode();
        GL11.glDisable(GL11.GL_TEXTURE_2D);

        GL11.glTranslatef(CameraX, CameraY, -20f + CameraZ); // Move Right 1.5

        GL11.glTranslatef(9, -45, 0);
        GL11.glRotatef(MapRotatef, 0f, 1.0f, 0f);
        RenderPrefab();

    }

    private void RenderPrefab() {

        for (int y = 0; y < prefab.GetHeight(); y++) {
            for (int x = 0; x < prefab.GetWidth(); x++) {
                GL11.glTranslatef(x * TileMapGenerator.CUBE_LENGTH + 0.7f, y * TileMapGenerator.CUBE_LENGTH + 0.7f,
                        0);

                if (prefab.getColorRef(x, y) < 0) {
                    try {

                        DrawFloor(x, y, prefab.getColorRef(x, y));
                    } catch (Exception e) {

                    }

                } else {
                    DrawWall(x, y, prefab.getColorRef(x, y));
                }
                GL11.glTranslatef(-x * TileMapGenerator.CUBE_LENGTH - 0.7f,
                        -y * TileMapGenerator.CUBE_LENGTH - 0.7f, 0);
            }
        }
    }

    private void DrawWall(int x, int y, int i) {
        // BOTTOM
        GL11.glBegin(GL11.GL_QUADS);
        TileDefinition.setColor(i);
        GL11.glNormal3f(0, -1, 0);
        GL11.glVertex3f(-1f, -1f, 0f);
        GL11.glVertex3f(1f, -1f, 0);
        GL11.glVertex3f(1f, 1f, 0f);
        GL11.glVertex3f(-1f, 1f, 0f);

        // SIDES
        GL11.glNormal3f(1, 0, 0);
        GL11.glVertex3f(-1f, -1f, 0f);
        GL11.glVertex3f(1f, -1f, 0f);
        GL11.glVertex3f(1f, -1f, -4f);
        GL11.glVertex3f(-1f, -1f, -4f);

        GL11.glNormal3f(0, 0, 1);
        GL11.glVertex3f(1f, -1f, 0f);
        GL11.glVertex3f(1f, 1f, 0f);
        GL11.glVertex3f(1f, 1f, -4f);
        GL11.glVertex3f(1f, -1f, -4f);

        GL11.glNormal3f(1, 0, 0);
        GL11.glVertex3f(1f, 1f, 0f);
        GL11.glVertex3f(-1f, 1f, 0f);
        GL11.glVertex3f(-1f, 1f, -4f);
        GL11.glVertex3f(1f, 1f, -4f);

        GL11.glNormal3f(0, 0, 1);
        GL11.glVertex3f(-1f, 1f, 0f);
        GL11.glVertex3f(-1f, -1f, 0f);
        GL11.glVertex3f(-1f, -1f, -4f);
        GL11.glVertex3f(-1f, 1f, -4f);

        // BOTTOM
        GL11.glNormal3f(0, 1, 0);
        GL11.glVertex3f(-1f, -1f, -4f);
        GL11.glVertex3f(1f, -1f, -4f);
        GL11.glVertex3f(1f, 1f, -4f);
        GL11.glVertex3f(-1f, 1f, -4f);
        GL11.glEnd();

    }

    private void DrawFloor(int x, int y, int i) {
        GL11.glBegin(GL11.GL_QUADS);
        TileDefinition.setColor(i);
        GL11.glNormal3f(0, 1, 0);
        GL11.glVertex3f(-1f, -1f, 0f);
        GL11.glVertex3f(1f, -1f, 0f);
        GL11.glVertex3f(1f, 1f, 0f);
        GL11.glVertex3f(-1f, 1f, 0f);
        GL11.glEnd();

    }

    @Override
    public void Unload() {

    }

}