net.noviden.towerdefense.MapCreator.MapCreatorScreen.java Source code

Java tutorial

Introduction

Here is the source code for net.noviden.towerdefense.MapCreator.MapCreatorScreen.java

Source

/**
 Infinite Paths : Infinite Tower Defense Game With User Created Maps
 Copyright (C) 2015 Tristan Kernan
    
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.
    
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
    
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package net.noviden.towerdefense.MapCreator;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputMultiplexer;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.input.GestureDetector;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.CheckBox;
import com.badlogic.gdx.scenes.scene2d.ui.Dialog;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.ui.TextField;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;

import net.noviden.towerdefense.Maps.Map;
import net.noviden.towerdefense.MapEditor.MapEditorSelectorScreen;
import net.noviden.towerdefense.MapSettings;
import net.noviden.towerdefense.Path;
import net.noviden.towerdefense.Point;
import net.noviden.towerdefense.TowerDefense;
import net.noviden.towerdefense.TurretFactory.BaseTurret;

import java.util.ArrayList;
import java.util.Stack;
import java.util.UUID;

public class MapCreatorScreen implements Screen {

    final TowerDefense towerDefense;

    private Stage stage;
    private ShapeRenderer shapeRenderer;
    private SpriteBatch batch;
    private OrthographicCamera camera;

    private Stack<Path> paths;
    private ArrayList<Point> pointSet;
    private String name;

    private Table table;
    private InputMultiplexer inputMultiplexer;

    public MapCreatorScreen(final TowerDefense towerDefense) {
        this.towerDefense = towerDefense;

        camera = new OrthographicCamera();
        camera.setToOrtho(true, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
        camera.update();

        stage = new Stage();

        final Skin skin = new Skin(Gdx.files.internal("assets/uiskin.json"));

        table = new Table();
        table.setFillParent(true);

        name = UUID.randomUUID().toString().substring(0, 5);

        Label nameLabel = new Label("Name:", skin);
        final TextField nameField = new TextField(name, skin);
        TextButton addPathButton = new TextButton("Add New Path", skin);
        TextButton undoButton = new TextButton("Remove Last Point", skin);
        TextButton finishButton = new TextButton("Save Map", skin);
        TextButton exitButton = new TextButton("Exit", skin);

        final TextButton displayOptionsButton = new TextButton("Options", skin);

        // set up options table
        final Table optionsTable = new Table();
        optionsTable.setVisible(false);

        Label initialPlayerHealthLabel = new Label("Initial Player Health:", skin);
        final TextField initialPlayerHealthText = new TextField("" + MapSettings.DEFAULT_INITIAL_PLAYER_HEALTH,
                skin);
        Label initialPlayerResourcesLabel = new Label("Initial Player Resources:", skin);
        final TextField initialPlayerResourcesText = new TextField(
                "" + MapSettings.DEFAULT_INITIAL_PLAYER_RESOURCES, skin);
        Label initialUnitHealthLabel = new Label("Initial Unit Health:", skin);
        final TextField initialUnitHealthText = new TextField("" + MapSettings.DEFAULT_INITIAL_UNIT_HEALTH, skin);
        Label initialUnitMovementSpeedLabel = new Label("Initial Unit Movement Speed:", skin);
        final TextField initialUnitMovementSpeedText = new TextField("" + MapSettings.DEFAULT_INITIAL_UNIT_SPEED,
                skin);
        Label initialUnitDamageLabel = new Label("Initial Unit Damage:", skin);
        final TextField initialUnitDamageText = new TextField("" + MapSettings.DEFAULT_INITIAL_UNIT_DAMAGE, skin);
        Label defaultUnitSpawnRateLabel = new Label("Unit Spawn Rate:", skin);
        final TextField defaultUnitSpawnRateText = new TextField("" + MapSettings.DEFAULT_UNIT_SPAWN_RATE, skin);

        TextButton displayWavesCreatorButton = new TextButton("Waves Creator", skin);
        TextButton displayTurretsButton = new TextButton("Disable Turrets", skin);

        optionsTable.add(initialPlayerHealthLabel, initialPlayerHealthText);
        optionsTable.row();
        optionsTable.add(initialPlayerResourcesLabel, initialPlayerResourcesText);
        optionsTable.row();
        optionsTable.add(initialUnitHealthLabel, initialUnitHealthText);
        optionsTable.row();
        optionsTable.add(initialUnitMovementSpeedLabel, initialUnitMovementSpeedText);
        optionsTable.row();
        optionsTable.add(initialUnitDamageLabel, initialUnitDamageText);
        optionsTable.row();
        optionsTable.add(defaultUnitSpawnRateLabel, defaultUnitSpawnRateText);
        optionsTable.row();
        optionsTable.add(displayTurretsButton);

        final Table disableTurretsTable = new Table();
        disableTurretsTable.setVisible(false);

        final CheckBox disableChaingunTurretCheckbox = new CheckBox("Disable Chaingun", skin);
        final CheckBox disableBasicTurretCheckbox = new CheckBox("Disable Basic", skin);
        final CheckBox disableBuffTurretCheckbox = new CheckBox("Disable Buff", skin);
        final CheckBox disableHomingTurretCheckbox = new CheckBox("Disable Homing", skin);
        final CheckBox disableRocketTurretCheckbox = new CheckBox("Disable Rocket", skin);
        final CheckBox disableShotgunTurretCheckbox = new CheckBox("Disable Shotgun", skin);

        disableTurretsTable.add(disableChaingunTurretCheckbox);
        disableTurretsTable.row();
        disableTurretsTable.add(disableBasicTurretCheckbox);
        disableTurretsTable.row();
        disableTurretsTable.add(disableBuffTurretCheckbox);
        disableTurretsTable.row();
        disableTurretsTable.add(disableHomingTurretCheckbox);
        disableTurretsTable.row();
        disableTurretsTable.add(disableRocketTurretCheckbox);
        disableTurretsTable.row();
        disableTurretsTable.add(disableShotgunTurretCheckbox);

        optionsTable.row();
        optionsTable.add(disableTurretsTable);

        table.add(addPathButton);
        table.add(undoButton);
        table.add(finishButton);
        table.add(exitButton);
        table.row();
        table.add(nameLabel, nameField);
        table.add(displayOptionsButton);
        table.row();
        table.add(optionsTable);

        table.top();
        table.right();

        stage.addActor(table);

        inputMultiplexer = new InputMultiplexer();
        inputMultiplexer.addProcessor(stage);
        inputMultiplexer.addProcessor(new GestureDetector(new MyGestureListener()));

        Gdx.input.setInputProcessor(inputMultiplexer);

        addPathButton.addListener(new ClickListener() {
            @Override
            public void clicked(InputEvent event, float x, float y) {
                // remove last point in set
                if (pointSet.size() > 1) {
                    // valid to create a new path
                    paths.push(new Path(pointSet, 5.0f));
                    System.out.println("Added a path to paths Stack");
                    pointSet = new ArrayList<Point>();
                } else {
                    Dialog errorDialog = new Dialog("Error!", skin);
                    errorDialog.text("Error! Must finish one path before starting another!");
                    errorDialog.button("Ok");
                    errorDialog.show(stage);
                }
            }
        });

        undoButton.addListener(new ClickListener() {
            @Override
            public void clicked(InputEvent event, float x, float y) {
                // remove last point in set
                if (pointSet.size() > 0) {
                    pointSet.remove(pointSet.size() - 1);
                } else {
                    if (paths.size() > 0) {
                        Path path = paths.pop();
                        pointSet = (ArrayList<Point>) path.set.clone();
                        System.out.println("Popped from paths");
                    }
                }
            }
        });

        exitButton.addListener(new ClickListener() {
            @Override
            public void clicked(InputEvent event, float x, float y) {
                towerDefense.setScreen(new MapEditorSelectorScreen(towerDefense));
                dispose();
            }
        });

        finishButton.addListener(new ClickListener() {
            @Override
            public void clicked(InputEvent event, float x, float y) {

                if (paths.size() == 0 && pointSet.size() < 2) {
                    displayErrorMessage("Error! Each path must have at least an entrance and exit", skin);
                    return;
                }

                // create settings for map
                int playerHealth = Integer.parseInt(initialPlayerHealthText.getText()),
                        playerResources = Integer.parseInt(initialPlayerResourcesText.getText()),
                        unitDamage = Integer.parseInt(initialUnitDamageText.getText());
                float unitHealth = Float.parseFloat(initialUnitHealthText.getText()),
                        unitSpeed = Float.parseFloat(initialUnitMovementSpeedText.getText()),
                        unitSpawnRate = Float.parseFloat(defaultUnitSpawnRateText.getText());

                // validation
                if (playerHealth <= 0.0f) {
                    displayErrorMessage("Error! Player cannot start with 0.0 health", skin);
                    return;
                } else if (unitHealth <= 0.0f) {
                    displayErrorMessage("Error! Units cannot start with 0.0 health", skin);
                    return;
                } else if (unitDamage <= 0.0f) {
                    displayErrorMessage("Error! Units cannot start with 0.0 damage", skin);
                    return;
                } else if (unitSpeed <= 0.0f) {
                    displayErrorMessage("Error! Units cannot start with 0.0 speed", skin);
                    return;
                } else if (unitSpawnRate <= 0.0f) {
                    displayErrorMessage("Error! Spawn rate cannot be 0.0", skin);
                    return;
                }

                ArrayList<BaseTurret.Type> disabledTypes = new ArrayList<BaseTurret.Type>();

                if (disableBasicTurretCheckbox.isChecked()) {
                    disabledTypes.add(BaseTurret.Type.NORMAL);
                }
                if (disableBuffTurretCheckbox.isChecked()) {
                    disabledTypes.add(BaseTurret.Type.BUFF);
                }
                if (disableChaingunTurretCheckbox.isChecked()) {
                    disabledTypes.add(BaseTurret.Type.CHAINGUN);
                }
                if (disableHomingTurretCheckbox.isChecked()) {
                    disabledTypes.add(BaseTurret.Type.HOMING);
                }
                if (disableRocketTurretCheckbox.isChecked()) {
                    disabledTypes.add(BaseTurret.Type.ROCKET);
                }
                if (disableShotgunTurretCheckbox.isChecked()) {
                    disabledTypes.add(BaseTurret.Type.SHOTGUN);
                }

                if (disabledTypes.size() == BaseTurret.Type.values().length) {
                    displayErrorMessage("Error! Cannot disable all turrets", skin);
                    return;
                }

                MapSettings mapSettings = new MapSettings();

                BaseTurret.Type[] disabledTypesArr = new BaseTurret.Type[disabledTypes.size()];
                disabledTypesArr = disabledTypes.toArray(disabledTypesArr);

                mapSettings.setDisabledTurretTypes(disabledTypesArr);

                String[] keys = { MapSettings.PLAYER_INITIAL_HEALTH_KEY, MapSettings.PLAYER_INITIAL_RESOURCES_KEY,
                        MapSettings.UNIT_INITIAL_DAMAGE_KEY, MapSettings.UNIT_INITIAL_HEALTH_KEY,
                        MapSettings.UNIT_INITIAL_SPEED_KEY, MapSettings.UNIT_SPAWN_RATE_KEY };

                float[] values = { playerHealth, playerResources, unitDamage, unitHealth, unitSpeed,
                        unitSpawnRate };

                mapSettings.putValues(keys, values);

                // make sure current pointSet is included in new map
                if (pointSet.size() > 1) {
                    paths.push(new Path(pointSet, 5.0f));
                }

                // convert stack to array
                Path[] pathsForMap = new Path[paths.size()];
                int i = 0;
                while (!paths.empty()) {
                    pathsForMap[i++] = paths.pop();
                }

                // finally create the map
                Map map = new Map(new Map.Dimensions(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()),
                        pathsForMap, nameField.getText(), mapSettings);

                towerDefense.maps.add(map);

                // return to main menu
                towerDefense.setScreen(new MapEditorSelectorScreen(towerDefense));
                dispose();
            }
        });

        displayOptionsButton.addListener(new ClickListener() {
            @Override
            public void clicked(InputEvent event, float x, float y) {
                if (optionsTable.isVisible()) {
                    optionsTable.setVisible(false);
                    //                    disableTurretsTable.setVisible(false);
                } else {
                    optionsTable.setVisible(true);
                }
            }
        });

        displayTurretsButton.addListener(new ClickListener() {
            @Override
            public void clicked(InputEvent event, float x, float y) {
                if (disableTurretsTable.isVisible()) {
                    disableTurretsTable.setVisible(false);
                } else {
                    disableTurretsTable.setVisible(true);
                }
            }
        });

        pointSet = new ArrayList<Point>();
        paths = new Stack<Path>();

        batch = new SpriteBatch();
        shapeRenderer = new ShapeRenderer();
    }

    public void render(float deltaTime) {
        Gdx.gl.glClearColor(0, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        camera.update();
        batch.setProjectionMatrix(camera.combined);
        shapeRenderer.setProjectionMatrix(camera.combined);

        batch.begin();
        shapeRenderer.begin(ShapeRenderer.ShapeType.Line);

        // draw paths
        shapeRenderer.setColor(Color.GREEN);
        for (Path path : paths) {
            for (int i = 0; i < (path.set.size() - 1); i++) {
                Point a = path.set.get(i), b = path.set.get(i + 1);
                shapeRenderer.line(a.x, a.y, b.x, b.y);

                shapeRenderer.circle(a.x, a.y, 5.0f);
            }

            if (path.set.size() > 0) {
                Point lastPoint = path.set.get(path.set.size() - 1);
                shapeRenderer.circle(lastPoint.x, lastPoint.y, 8.0f);
            }
        }

        // draw current path a different color
        shapeRenderer.setColor(Color.NAVY);
        for (int i = 0; i < (pointSet.size() - 1); i++) {
            Point a = pointSet.get(i), b = pointSet.get(i + 1);
            shapeRenderer.line(a.x, a.y, b.x, b.y);

            shapeRenderer.circle(a.x, a.y, 5.0f);
        }

        if (pointSet.size() > 0) {
            Point lastPoint = pointSet.get(pointSet.size() - 1);
            shapeRenderer.circle(lastPoint.x, lastPoint.y, 8.0f);
        }

        shapeRenderer.end();
        batch.end();

        stage.act(deltaTime);
        stage.draw();
    }

    private void displayErrorMessage(String message, Skin skin) {
        Dialog errorDialog = new Dialog("Error!", skin);
        errorDialog.text(message);
        errorDialog.button("Ok");
        errorDialog.show(stage);
    }

    public void pause() {
    }

    public void resume() {
    }

    public void show() {
    }

    public void hide() {
    }

    public void dispose() {
    }

    public void resize(int width, int height) {
        stage.dispose();
        stage = new Stage();
        stage.addActor(table);

        inputMultiplexer.clear();
        inputMultiplexer = new InputMultiplexer(stage, new GestureDetector(new MyGestureListener()));

        Gdx.input.setInputProcessor(inputMultiplexer);

        camera.setToOrtho(true, width, height);
    }

    private class MyGestureListener implements GestureDetector.GestureListener {

        @Override
        public boolean touchDown(float x, float y, int pointer, int button) {

            return false;
        }

        @Override
        public boolean tap(float screenX, float screenY, int count, int button) {

            pointSet.add(new Point(screenX, screenY));

            return true;
        }

        @Override
        public boolean longPress(float x, float y) {

            return false;
        }

        @Override
        public boolean fling(float velocityX, float velocityY, int button) {

            return false;
        }

        @Override
        public boolean pan(float x, float y, float deltaX, float deltaY) {

            return false;
        }

        @Override
        public boolean panStop(float x, float y, int pointer, int button) {

            return false;
        }

        @Override
        public boolean zoom(float initialDistance, float distance) {

            return false;
        }

        @Override
        public boolean pinch(Vector2 initialPointer1, Vector2 initialPointer2, Vector2 pointer1, Vector2 pointer2) {

            return false;
        }

    }
}