ca.hiphiparray.amazingmaze.SettingsScreen.java Source code

Java tutorial

Introduction

Here is the source code for ca.hiphiparray.amazingmaze.SettingsScreen.java

Source

/********************************************************************************
 * Amazing Maze is an educational game created in Java with the libGDX library.
 * Copyright (C) 2017 Hip Hip Array
 *
 * This file is part of Amazing Maze.
 *
 * Amazing Maze 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.
 *
 * Amazing Maze 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 Amazing Maze. If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
package ca.hiphiparray.amazingmaze;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.InputMultiplexer;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Slider;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import com.badlogic.gdx.utils.viewport.ScreenViewport;

/**
 * SettingsScreen allows users to adjust the settings for the game.
 *
 * @since 0.2
 * @author Chloe Nguyen
 * @author Vincent Macri
 * <br>
 * Time (Chloe): 3 hours
 * <br>
 * Time (Vincent: 1 hour
 */
public class SettingsScreen implements Screen, InputProcessor {

    /** The {@link AmazingMazeGame} instance for this screen. */
    private final AmazingMazeGame game;
    /** The stage for the settings screen */
    private final Stage settings;

    /** Table for widgets and the layout */
    private Table table;

    /** Label for the settings screen header */
    private Label screenHeader;
    /** Label for the music slider */
    private Label musicSliderLabel;
    /** Label for the controls table */
    private Label controlsHeader;

    /** Slider for the music volume */
    private Slider musicSlider;

    /** Button to go back to the previous screen. */
    private TextButton backButton;

    /** Table for game controls */
    private Table controlsTable;

    /** Array of Labels for all possible game actions */
    private Label[] actions;

    /** Array of TextButtons for changeable game action buttons */
    private TextButton[] actionControls;

    /** Button to reset settings. */
    private TextButton resetSettingsButton;
    /** Button to reset save. */
    private TextButton resetSaveButton;

    /** Action currently being set. This is -1 when no actions are being set. */
    private int actionBeingSet = -1;

    /** A reference to the screen that sent the user to the settings screen. */
    private Screen sourceScreen;

    /**
     * For InputProcessors and allows for UI to process events first. Otherwise, regular InputProcessor take over.
     */
    private InputMultiplexer multiplexer;

    /**
     * Create a new SettingsScreen.
     *
     * @param game Instance of AmazingMazeGame to be used
     */
    public SettingsScreen(final AmazingMazeGame game) {
        this.game = game;
        this.sourceScreen = game.menuScreen;
        settings = new Stage(new ScreenViewport(), this.game.batch);
        multiplexer = new InputMultiplexer();
        multiplexer.addProcessor(settings);
        multiplexer.addProcessor(this);
        table = new Table();
        table.top();
        table.setFillParent(true);
        controlsTable = new Table();

        settings.addActor(table);

        Skin skin = game.assets.skin;

        screenHeader = new Label("Settings", game.assets.skin, Assets.SANS_HEADER_STYLE);

        musicSlider = new Slider(0, 1, 0.1f, false, game.assets.skin);
        musicSlider.setValue(game.save.getMusicLevel());
        musicSlider.setAnimateDuration(0.25f);

        musicSlider.addListener(new ChangeListener() {
            @Override
            public void changed(ChangeEvent event, Actor actor) {
                game.music.setVolume(musicSlider.getValue());
                game.save.setMusicLevel(game.music.getVolume());
            }
        });
        musicSliderLabel = new Label("Music Volume", game.assets.skin);

        controlsHeader = new Label("Controls", game.assets.skin);

        actions = new Label[] { new Label("Up", game.assets.skin), new Label("Down", game.assets.skin),
                new Label("Left", game.assets.skin), new Label("Right", game.assets.skin),
                new Label("Pause", game.assets.skin) };

        actionControls = new TextButton[] { new TextButton(Keys.toString(game.save.getUpButton()), skin),
                new TextButton(Keys.toString(game.save.getDownButton()), skin),
                new TextButton(Keys.toString(game.save.getLeftButton()), skin),
                new TextButton(Keys.toString(game.save.getRightButton()), skin),
                new TextButton(Keys.toString(game.save.getPauseButton()), skin) };

        actionControls[0].addListener(new ChangeListener() {

            @Override
            public void changed(ChangeEvent event, Actor actor) {
                if (actionControls[0].isPressed()) {
                    updateControls(0);
                }
            }

        });

        actionControls[1].addListener(new ChangeListener() {

            @Override
            public void changed(ChangeEvent event, Actor actor) {
                if (actionControls[1].isPressed()) {
                    updateControls(1);
                }
            }

        });

        actionControls[2].addListener(new ChangeListener() {

            @Override
            public void changed(ChangeEvent event, Actor actor) {
                if (actionControls[2].isPressed()) {
                    updateControls(2);
                }
            }

        });

        actionControls[3].addListener(new ChangeListener() {

            @Override
            public void changed(ChangeEvent event, Actor actor) {
                if (actionControls[3].isPressed()) {
                    updateControls(3);
                }
            }

        });

        actionControls[4].addListener(new ChangeListener() {
            @Override
            public void changed(ChangeEvent event, Actor actor) {
                if (actionControls[4].isPressed()) {
                    updateControls(4);
                }
            }
        });

        // Reset settings button
        resetSettingsButton = new TextButton("Reset Settings", skin);
        resetSettingsButton.addListener(new ChangeListener() {
            @Override
            public void changed(ChangeEvent event, Actor actor) {
                if (resetSettingsButton.isPressed()) {
                    game.save.resetSettings();
                    musicSlider.setValue(game.save.getMusicLevel());
                    resetActionControlsLabels();
                }
            }
        });

        // Reset save button.
        resetSaveButton = new TextButton("Reset Save", skin);
        resetSaveButton.addListener(new ChangeListener() {
            @Override
            public void changed(ChangeEvent event, Actor actor) {
                if (resetSaveButton.isPressed()) {
                    game.save.resetSave();
                }
            }
        });

        backButton = new TextButton("Back", skin);

    }

    /**
     * Reset Labels for elements in actionControl array.
     */
    protected void resetActionControlsLabels() {
        actionControls[0].setText(Keys.toString(game.save.getUpButton()));
        actionControls[1].setText(Keys.toString(game.save.getDownButton()));
        actionControls[2].setText(Keys.toString(game.save.getLeftButton()));
        actionControls[3].setText(Keys.toString(game.save.getRightButton()));
        actionControls[4].setText(Keys.toString(game.save.getPauseButton()));
    }

    /**
     * For updating key with specific action.
     *
     * @param Specifies which element of actionControls array
     */
    protected void updateControls(int i) {
        resetActionControlsLabels();
        actionControls[i].setText("Press a key");
        actionBeingSet = i;
    }

    /**
     * Layout for the settings.
     *
     * @param width The width of the screen.
     * @param height The height of the screen.
     */
    private void layoutSettings(int width, int height) {
        table.clear();

        table.add(screenHeader).pad(10f).colspan(2);
        table.row();

        table.add(musicSliderLabel).colspan(2);
        table.row();

        table.add(musicSlider).pad(10f).colspan(2);
        table.row();

        table.add(controlsHeader).pad(10f).colspan(2);
        table.row();

        table.add(controlsTable).colspan(2);

        controlsTable.clear();
        for (int i = 0; i < actions.length; i++) {
            controlsTable.add(actionControls[i]).pad(5f).fill().width(actionControls[i].getHeight() * 5);
            controlsTable.add(actions[i]).left().pad(5f);
            controlsTable.row();
        }
        table.row();

        table.add(resetSettingsButton).prefSize(width / 6, height / 15).padLeft(width / 64).padRight(width / 64)
                .expandY();
        table.add(resetSaveButton).prefSize(width / 6, height / 15).padLeft(width / 64).padRight(width / 64)
                .expandY();

        table.row();

        table.add(backButton).padBottom(10f).minSize(width / 4, height / 20).maxSize(width, height / 5)
                .prefSize(width / 3, height / 15).colspan(2);
    }

    @Override
    public void render(float delta) {
        Gdx.gl.glClearColor(1, 1, 1, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        settings.act(delta);
        settings.draw();

        if (backButton.isPressed()) {
            game.save.writeScores();
            game.setScreen(sourceScreen);
            setSourceScreen(game.menuScreen);
        }
    }

    /**
     * Set the source screen for this time the settings screen is shown.
     * It is reset to {@link AmazingMazeGame#menuScreen} after back is clicked.
     *
     * @param sourceScreen the screen to go back to when the user clicks {@link #backButton}.
     */
    public void setSourceScreen(Screen sourceScreen) {
        this.sourceScreen = sourceScreen;
    }

    @Override
    public void resize(int width, int height) {
        settings.getViewport().update(width, height, true);
        layoutSettings(width, height);
    }

    @Override
    public void pause() {

    }

    @Override
    public void resume() {

    }

    @Override
    public void hide() {
        actionBeingSet = -1;
        game.save.writeSettings();
    }

    @Override
    public void dispose() {

    }

    @Override
    public boolean keyDown(int keycode) {
        if (actionBeingSet >= 0 && actionBeingSet < actionControls.length) {
            switch (actionBeingSet) {
            case 0: // Up.
                game.save.setUpButton(keycode);
                break;

            case 1: // Down
                game.save.setDownButton(keycode);
                break;
            case 2: // Left
                game.save.setLeftButton(keycode);
                break;

            case 3: // Right
                game.save.setRightButton(keycode);
                break;
            case 4: // Pause
                game.save.setPauseButton(keycode);
                break;
            }
            actionControls[actionBeingSet].setText(Keys.toString(keycode));
            actionBeingSet = -1;
        }

        return true;
    }

    @Override
    public boolean keyUp(int keycode) {
        return true;
    }

    @Override
    public boolean keyTyped(char character) {
        return false;
    }

    @Override
    public boolean touchDown(int screenX, int screenY, int pointer, int button) {
        return false;
    }

    @Override
    public boolean touchUp(int screenX, int screenY, int pointer, int button) {
        return false;
    }

    @Override
    public boolean touchDragged(int screenX, int screenY, int pointer) {
        return false;
    }

    @Override
    public boolean mouseMoved(int screenX, int screenY) {
        return false;
    }

    @Override
    public boolean scrolled(int amount) {
        return false;
    }

    @Override
    public void show() {
        Gdx.input.setInputProcessor(multiplexer);
    }
}