ve.ucv.ciens.ccg.nxtar.states.MainMenuStateBase.java Source code

Java tutorial

Introduction

Here is the source code for ve.ucv.ciens.ccg.nxtar.states.MainMenuStateBase.java

Source

/*
 * Copyright (C) 2014 Miguel Angel Astor Romero
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package ve.ucv.ciens.ccg.nxtar.states;

import ve.ucv.ciens.ccg.nxtar.NxtARCore.game_states_t;
import ve.ucv.ciens.ccg.nxtar.utils.ProjectConstants;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.Texture.TextureWrap;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.NinePatch;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator.FreeTypeFontParameter;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton.TextButtonStyle;
import com.badlogic.gdx.scenes.scene2d.utils.NinePatchDrawable;

public abstract class MainMenuStateBase extends BaseState {
    protected static final String TAG = "MAIN_MENU";
    private static final String CLASS_NAME = MainMenuStateBase.class.getSimpleName();
    private static final String SHADER_PATH = "shaders/movingBckg/movingBckg";

    protected final int NUM_MENU_BUTTONS = 3;

    // Helper fields.
    protected boolean clientConnected;
    protected boolean cameraCalibrated;
    protected boolean assetsLoaded;
    private float u_scaling[];
    private float u_displacement;

    // Buttons and other gui components.
    protected TextButton startButton;
    protected Rectangle startButtonBBox;
    protected TextButton calibrationButton;
    protected Rectangle calibrationButtonBBox;
    protected TextButton autoButton;
    protected Rectangle autoButtonBBox;
    protected Sprite cameraCalibratedLedOn;
    protected Sprite cameraCalibratedLedOff;
    protected Sprite assetsLoadedLedOn;
    protected Sprite assetsLoadedLedOff;
    protected Sprite background;

    // Graphic data for the start button.
    private Texture menuButtonEnabledTexture;
    private Texture menuButtonDisabledTexture;
    private Texture menuButtonPressedTexture;
    private NinePatch menuButtonEnabled9p;
    private NinePatch menuButtonDisabled9p;
    private NinePatch menuButtonPressed9p;
    private BitmapFont font;

    // Other graphics.
    private Texture ledOffTexture;
    private Texture ledOnTexture;
    private Texture backgroundTexture;
    private ShaderProgram backgroundShader;

    // Button touch helper fields.
    protected boolean startButtonTouched;
    protected int startButtonTouchPointer;
    protected boolean calibrationButtonTouched;
    protected int calibrationButtonTouchPointer;
    protected boolean autoButtonTouched;
    protected int autoButtonTouchPointer;

    public MainMenuStateBase() {
        TextureRegion region;
        TextButtonStyle textButtonStyle;
        FreeTypeFontGenerator fontGenerator;
        FreeTypeFontParameter fontParameters;

        this.pixelPerfectCamera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());

        // Create the start button background.
        menuButtonEnabledTexture = new Texture(Gdx.files.internal("data/gfx/gui/Anonymous_Pill_Button_Yellow.png"));
        menuButtonEnabled9p = new NinePatch(new TextureRegion(menuButtonEnabledTexture, 0, 0,
                menuButtonEnabledTexture.getWidth(), menuButtonEnabledTexture.getHeight()), 49, 49, 45, 45);
        menuButtonDisabledTexture = new Texture(Gdx.files.internal("data/gfx/gui/Anonymous_Pill_Button_Cyan.png"));
        menuButtonDisabled9p = new NinePatch(new TextureRegion(menuButtonDisabledTexture, 0, 0,
                menuButtonDisabledTexture.getWidth(), menuButtonDisabledTexture.getHeight()), 49, 49, 45, 45);
        menuButtonPressedTexture = new Texture(Gdx.files.internal("data/gfx/gui/Anonymous_Pill_Button_Blue.png"));
        menuButtonPressed9p = new NinePatch(new TextureRegion(menuButtonPressedTexture, 0, 0,
                menuButtonPressedTexture.getWidth(), menuButtonPressedTexture.getHeight()), 49, 49, 45, 45);

        // Create the start button font.
        fontParameters = new FreeTypeFontParameter();
        fontParameters.characters = ProjectConstants.FONT_CHARS;
        fontParameters.size = ProjectConstants.MENU_BUTTON_FONT_SIZE;
        fontParameters.flip = false;
        fontGenerator = new FreeTypeFontGenerator(Gdx.files.internal("data/fonts/d-puntillas-B-to-tiptoe.ttf"));
        font = fontGenerator.generateFont(fontParameters);
        fontGenerator.dispose();

        // Create the buttons.
        textButtonStyle = new TextButtonStyle();
        textButtonStyle.font = font;
        textButtonStyle.up = new NinePatchDrawable(menuButtonEnabled9p);
        textButtonStyle.checked = new NinePatchDrawable(menuButtonPressed9p);
        textButtonStyle.disabled = new NinePatchDrawable(menuButtonDisabled9p);
        textButtonStyle.fontColor = new Color(Color.BLACK);
        textButtonStyle.downFontColor = new Color(Color.WHITE);
        textButtonStyle.disabledFontColor = new Color(Color.BLACK);

        startButton = new TextButton("Manual control", textButtonStyle);
        startButton.setText("Manual control");
        startButton.setDisabled(true);
        startButtonBBox = new Rectangle(0, 0, startButton.getWidth(), startButton.getHeight());

        calibrationButton = new TextButton("Calibrate camera", textButtonStyle);
        calibrationButton.setText("Calibrate camera");
        calibrationButton.setDisabled(true);
        calibrationButtonBBox = new Rectangle(0, 0, calibrationButton.getWidth(), calibrationButton.getHeight());

        autoButton = new TextButton("Automatic action", textButtonStyle);
        autoButton.setText("Automatic action");
        autoButton.setDisabled(true);
        autoButtonBBox = new Rectangle(0, 0, autoButton.getWidth(), autoButton.getHeight());

        // Create the connection leds.
        ledOnTexture = new Texture("data/gfx/gui/Anonymous_Button_Green.png");
        ledOffTexture = new Texture("data/gfx/gui/Anonymous_Button_Red.png");

        region = new TextureRegion(ledOnTexture);
        cameraCalibratedLedOn = new Sprite(region);
        region = new TextureRegion(ledOffTexture);
        cameraCalibratedLedOff = new Sprite(region);
        region = new TextureRegion(ledOnTexture);
        assetsLoadedLedOn = new Sprite(region);
        region = new TextureRegion(ledOffTexture);
        assetsLoadedLedOff = new Sprite(region);

        // Set up the background.
        backgroundTexture = new Texture(Gdx.files.internal("data/gfx/textures/tile_aqua.png"));
        backgroundTexture.setWrap(TextureWrap.Repeat, TextureWrap.Repeat);
        backgroundTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
        region = new TextureRegion(backgroundTexture);
        background = new Sprite(backgroundTexture);
        background.setSize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
        background.setPosition(-(Gdx.graphics.getWidth() / 2), -(Gdx.graphics.getHeight() / 2));

        backgroundShader = new ShaderProgram(Gdx.files.internal(SHADER_PATH + "_vert.glsl"),
                Gdx.files.internal(SHADER_PATH + "_frag.glsl"));
        if (!backgroundShader.isCompiled()) {
            Gdx.app.error(TAG, CLASS_NAME + ".MainMenuStateBase() :: Failed to compile the background shader.");
            Gdx.app.error(TAG, CLASS_NAME + backgroundShader.getLog());
            backgroundShader = null;
        }

        u_scaling = new float[2];
        u_scaling[0] = Gdx.graphics.getWidth() > Gdx.graphics.getHeight() ? 16.0f : 9.0f;
        u_scaling[1] = Gdx.graphics.getHeight() > Gdx.graphics.getWidth() ? 16.0f : 9.0f;

        u_displacement = 1.0f;

        win2world = new Vector3(0.0f, 0.0f, 0.0f);
        touchPointWorldCoords = new Vector2();
        startButtonTouched = false;
        startButtonTouchPointer = -1;
        calibrationButtonTouched = false;
        calibrationButtonTouchPointer = -1;
        autoButtonTouched = false;
        autoButtonTouchPointer = -1;

        clientConnected = false;
        cameraCalibrated = false;
        assetsLoaded = false;
        stateActive = false;
    }

    @Override
    public abstract void render(float delta);

    @Override
    public void dispose() {
        menuButtonEnabledTexture.dispose();
        menuButtonDisabledTexture.dispose();
        menuButtonPressedTexture.dispose();
        ledOnTexture.dispose();
        ledOffTexture.dispose();
        backgroundTexture.dispose();
        if (backgroundShader != null)
            backgroundShader.dispose();
        font.dispose();
    }

    protected void drawBackground(SpriteBatch batch) {
        if (backgroundShader != null) {
            batch.setShader(backgroundShader);
            backgroundShader.setUniform2fv("u_scaling", u_scaling, 0, 2);
            backgroundShader.setUniformf("u_displacement", u_displacement);
        }
        background.draw(batch);
        if (backgroundShader != null)
            batch.setShader(null);
        u_displacement = u_displacement < 0.0f ? 1.0f : u_displacement - 0.0005f;
    }

    @Override
    public void onStateSet() {
        stateActive = true;
        Gdx.input.setInputProcessor(this);
        Gdx.input.setCatchBackKey(true);
        Gdx.input.setCatchMenuKey(true);
    }

    @Override
    public void onStateUnset() {
        stateActive = false;
        Gdx.input.setInputProcessor(null);
        Gdx.input.setCatchBackKey(false);
        Gdx.input.setCatchMenuKey(false);
    }

    public void onClientConnected() {
        clientConnected = true;
        calibrationButton.setDisabled(false);
    }

    public void onCameraCalibrated() {
        cameraCalibrated = true;
        enableGameButtons();
    }

    public void onAssetsLoaded() {
        assetsLoaded = true;
        enableGameButtons();
    }

    private void enableGameButtons() {
        startButton.setDisabled(!(cameraCalibrated && assetsLoaded));
        autoButton.setDisabled(!(cameraCalibrated && assetsLoaded));
    }

    /*;;;;;;;;;;;;;;;;;;;;;;;;;;
      ; INPUT LISTENER METHODS ;
      ;;;;;;;;;;;;;;;;;;;;;;;;;;*/

    @Override
    public boolean touchDown(int screenX, int screenY, int pointer, int button) {
        unprojectTouch(screenX, screenY);

        Gdx.app.log(TAG,
                CLASS_NAME + String.format(".touchDown(%d, %d, %d, %d)", screenX, screenY, pointer, button));
        Gdx.app.log(TAG, CLASS_NAME + String.format(".touchDown() :: Unprojected touch point: (%f, %f)",
                touchPointWorldCoords.x, touchPointWorldCoords.y));

        if (!startButton.isDisabled() && startButtonBBox.contains(touchPointWorldCoords)
                && (!calibrationButtonTouched && !autoButtonTouched)) {
            startButton.setChecked(true);
            startButtonTouched = true;
            startButtonTouchPointer = pointer;
            Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Start button pressed.");
        } else if (!calibrationButton.isDisabled() && calibrationButtonBBox.contains(touchPointWorldCoords)
                && (!startButtonTouched && !autoButtonTouched)) {
            calibrationButton.setChecked(true);
            calibrationButtonTouched = true;
            calibrationButtonTouchPointer = pointer;
            Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Calibration button pressed.");
        } else if (!autoButton.isDisabled() && autoButtonBBox.contains(touchPointWorldCoords)
                && (!startButtonTouched && !calibrationButtonTouched)) {
            autoButton.setChecked(true);
            autoButtonTouched = true;
            autoButtonTouchPointer = pointer;
            Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Auto button pressed.");
        }

        return true;
    }

    @Override
    public boolean touchUp(int screenX, int screenY, int pointer, int button) {
        unprojectTouch(screenX, screenY);

        Gdx.app.log(TAG, CLASS_NAME + String.format(".touchUp(%d, %d, %d, %d)", screenX, screenY, pointer, button));
        Gdx.app.log(TAG, CLASS_NAME + String.format(".touchUp() :: Unprojected touch point: (%f, %f)",
                touchPointWorldCoords.x, touchPointWorldCoords.y));

        if (!startButton.isDisabled() && startButtonBBox.contains(touchPointWorldCoords) && startButtonTouched) {
            startButton.setChecked(false);
            startButtonTouched = false;
            startButtonTouchPointer = -1;
            core.nextState = game_states_t.IN_GAME;
            Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Start button released.");
        } else if (!calibrationButton.isDisabled() && calibrationButtonBBox.contains(touchPointWorldCoords)
                && calibrationButtonTouched) {
            calibrationButton.setChecked(false);
            calibrationButtonTouched = false;
            calibrationButtonTouchPointer = -1;
            core.nextState = game_states_t.CALIBRATION;
            Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Calibration button released.");
        } else if (!autoButton.isDisabled() && autoButtonBBox.contains(touchPointWorldCoords)
                && autoButtonTouched) {
            autoButton.setChecked(false);
            autoButtonTouched = false;
            autoButtonTouchPointer = -1;
            core.nextState = game_states_t.AUTOMATIC_ACTION;
            Gdx.app.log(TAG, CLASS_NAME + ".touchDown() :: Auto button released.");
        }

        return true;
    }

    @Override
    public boolean touchDragged(int screenX, int screenY, int pointer) {
        unprojectTouch(screenX, screenY);

        if (!startButton.isDisabled() && startButtonTouched && pointer == startButtonTouchPointer
                && !startButtonBBox.contains(touchPointWorldCoords)) {
            startButtonTouchPointer = -1;
            startButtonTouched = false;
            startButton.setChecked(false);
            Gdx.app.log(TAG, CLASS_NAME + ".touchDragged() :: Start button released.");
        } else if (!calibrationButton.isDisabled() && calibrationButtonTouched
                && pointer == calibrationButtonTouchPointer
                && !calibrationButtonBBox.contains(touchPointWorldCoords)) {
            calibrationButtonTouchPointer = -1;
            calibrationButtonTouched = false;
            calibrationButton.setChecked(false);
            Gdx.app.log(TAG, CLASS_NAME + ".touchDragged() :: Start button released.");
        } else if (!autoButton.isDisabled() && autoButtonTouched && pointer == autoButtonTouchPointer
                && !autoButtonBBox.contains(touchPointWorldCoords)) {
            autoButtonTouchPointer = -1;
            autoButtonTouched = false;
            autoButton.setChecked(false);
            Gdx.app.log(TAG, CLASS_NAME + ".touchDragged() :: Auto button released.");
        }

        return true;
    }

    @Override
    public boolean keyDown(int keycode) {
        if (keycode == Input.Keys.BACK) {
            Gdx.app.exit();
            return true;
        }
        return false;
    }
}