com.sebasxogo2d.pantallas.PantallaXogo.java Source code

Java tutorial

Introduction

Here is the source code for com.sebasxogo2d.pantallas.PantallaXogo.java

Source

package com.sebasxogo2d.pantallas;

/*
 * #################################################################################
 #
 #
 #    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/>.
 #
 #
 #    
 #################################################################################
 * 
 * */

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.Preferences;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.Intersector;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Button;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.ui.TextField;
import com.badlogic.gdx.scenes.scene2d.utils.Align;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.mygdx.game.Sebas.AssetsXogo;
import com.mygdx.game.Sebas.MeuXogoGame;
import com.sebasxogo2d.modelo.Mundo;
import com.sebasxogo2d.renderer.RendererXogo;

/**
 * The Game Screen.
 * Implements the interface Screen to use the render, resize and the lifecycle methods.
 *
 * @author Sebastin Cabanas 
 * @version 1.5
 * */

public class PantallaXogo implements Screen, InputProcessor {

    /*
      * Final which have the true if the version is Android or false if you are playing another
      * version of the game (IOs, PC, Web...)
      */
    private final boolean ANDROID = Gdx.app.getType().name().equalsIgnoreCase("android");

    /*
      * Boolean var which indicate if the game is on pause or not.
      */
    private boolean pause = false;

    /*
      * Boolean var which indicate if the game finish or not (finxogo = true = end of the game).
      * Lives = 0
      */
    private boolean finxogo = false;

    /*
      * Time between levels
      */
    private int tempo_Nivel = 30;// 15 - 30 - 45 - 60

    /*
      * Velocity for add to the ball every tempo_Nivel seconds
      */
    private final int aumentoVelocidade = 50;

    /*
      * Cronometer for the game
      */
    private float crono;

    /*
      * The time when the game adds velocity to the ball and begin to give more points to the user (level up)
      */
    private int segCambioNivel;

    /*
      * Allows the user to move the paddle or not.
      */
    private boolean moverPala = true;

    /*
      * Var to store a instance of the main class
      */
    private MeuXogoGame meuxogogame;

    /*
      * Var to store a instance of class which render the game
      */
    private RendererXogo rendererxogo;

    /*
      * The class Mundo have the size of the world game and other properties.
      */
    private Mundo meuMundo;

    /*
      * Vector of 3 dimensions
      */
    private Vector3 vecTemporal;

    /*
      * Rectangles which represents the position of the finger in the screen, when the user
      * touch the screen and the position of some buttons.
      */
    private Rectangle dedo, sound, pauseBtn, exit;

    /*
      * Background music of the game
      */
    private Music sonFondo;

    /*
      * State of the sound, enabled or disabled
      */
    private boolean soundState;

    /*
     * Volume of the sound in the PC version and Web version
     */
    private final float VOLUMEN = 0.2f;

    /*
     * Volume of the sound in the ANDROID version
     */
    private final float VOLUMENANDROID = 1f;

    // Preferences 
    private Preferences prefs;
    public static String puntuacion1 = "puntuacion1";
    public static String puntuacion2 = "puntuacion2";
    public static String puntuacion3 = "puntuacion3";
    public static String puntuacion4 = "puntuacion4";
    public static String puntuacion5 = "puntuacion5";
    public static String nivel = "nivel", level;
    public static int levelInteger;

    /*
     * Best scores stored as in the preferences
     */
    private int p1, p2, p3, p4, p5;

    /*
     * Names of the users who have the biggest scores.
     */
    private String n1, n2, n3, n4;

    // User Interface properties.

    /*
     * The stage handles the viewport and distributes input events.
     */
    private Stage stage;

    /*
       * The skin to use for this user interface.
       *
     * The Skin class stores resources for UI widgets to use. It is a convenient container 
     * for texture regions, ninepatches, fonts, colors, etc. Skin also provides convenient 
     * conversions, such as retrieving a texture region as a ninepatch, sprite, or drawable.
     */
    private Skin skin = MeuXogoGame.skin;

    /*
       * Textfield with the score board
       */
    private TextField marcador;

    /*
       * Label with the test "Type a nickname please: "
       */
    private Label labTexto;
    private final String LABEL = "Type a nickname please: ";

    /*
       * Textfield wich have the nickname of the user who's reach X score.
       */
    private TextField texto;

    /*
       * Button Save which save the nickname of the user and his score (if his score is better than
       * at least one of the best scores)
       */
    private Button save;

    /*
       * Size of the score board.
       */
    private float anchoMarcador;

    // Sizes of the elements in the UI

    /*
       * Size of the textfield with the nichname of the user.
       */
    private final float ANCHO_NOMBRE = (float) (Gdx.graphics.getWidth() / 3),
            ALTO_NOMBRE = Gdx.graphics.getHeight() / 20;

    /*
       * SIze of the button Save
       */
    private final float ANCHO_SAVE = (float) (Gdx.graphics.getWidth() / 5.3),
            ALTO_SAVE = Gdx.graphics.getHeight() / 23;

    /*
       * Size of the label
       */
    private final float ANCHO_LAB = Gdx.graphics.getWidth() / 23, ALTO_LAB = Gdx.graphics.getHeight() / 30;

    /*
       * Position of the textfield (nickname) in the screen
       */
    private final float nombreX = (float) (Gdx.graphics.getWidth() / 3),
            nombreY = (float) (Gdx.graphics.getHeight() / 2.3);

    /*
       * Position of the button Save in the screen
       */
    private final float saveX = (float) (Gdx.graphics.getWidth() / 2.45),
            saveY = (float) (Gdx.graphics.getHeight() / 2.8);

    /*
       * Position of the label in the screen.
       */
    private final float labNombreX = (float) (Gdx.graphics.getWidth() / 2.3),
            labNombreY = (float) (Gdx.graphics.getHeight() / 2);

    /*
       * Position of the score board in the X axis.
       */
    private final float MARCADOR_X = (float) (Gdx.graphics.getWidth() / 2.3);

    /*
       * Position of the score board in the Y axis.
       */
    private final float MARCADOR_Y = (float) (Gdx.graphics.getHeight() * 0.93);

    /*
       * Height of the score board.
       */
    private final float MARCADOR_ALTO = Gdx.graphics.getHeight() / 19;

    private int id = 1;

    /*
       * Move to left or to right
       */
    private int idMove;

    /*
       * Left and right keys. Only for PC version, because if the user choose to change the keys 
       * to move the paddle
       */
    private String teclaIz, teclaDer;

    /**
      * Constructor which receive an object of the main class, initialize and create objects
     * for the properties of this class. It's the screen of the game.
      *
      * @param meuxogogame A instance of the main class
      * @author Sebastin Cabanas
     */
    public PantallaXogo(MeuXogoGame meuxogogame) {

        meuMundo = new Mundo();

        this.meuxogogame = meuxogogame;
        rendererxogo = new RendererXogo(meuMundo);

        vecTemporal = new Vector3();

        dedo = new Rectangle();
        sound = new Rectangle();
        pauseBtn = new Rectangle();
        exit = new Rectangle();

        soundState = meuxogogame.getSoundState();
        sonFondo = AssetsXogo.musica;

        prefs = meuxogogame.getPrefs();
        getPrefs();

        // User interface. After the user lose.
        anchoMarcador = 27f;
        stage = new Stage();
        marcador(); // score
        nombre(); // for name
        gardarBoton(); // button saveY
        labNombre(); // label with info

        segCambioNivel = 0; // time to the next add on the velocity of the ball.

    }

    /**
     * Method which load the saved preferences of the application, then set the dificult level.
     *
     * @author Sebastin Cabanas
     */
    private void getPrefs() {
        // Get the scores saved to compare with the result of the current game.
        p1 = prefs.getInteger(puntuacion1, 0);
        p2 = prefs.getInteger(puntuacion2, 0);
        p3 = prefs.getInteger(puntuacion3, 0);
        p4 = prefs.getInteger(puntuacion4, 0);
        p5 = prefs.getInteger(puntuacion5, 0);

        // Get the name of the people who earn this scores. 
        n1 = prefs.getString("name1", "");
        n2 = prefs.getString("name2", "");
        n3 = prefs.getString("name3", "");
        n4 = prefs.getString("name4", "");

        // Get dificult level selected in the options screen. Default easy
        level = prefs.getString(nivel, "pEasy");

        // Only for PC version. Get the controls for move the paddle
        teclaIz = prefs.getString("controisLeft", "left");
        teclaDer = prefs.getString("controisRight", "right");

        prefs.flush();
        asignarLevel(); // Set the dificult level for the current game.

    }

    /**
     * Method which set the dificult level to the current game with the info of the preferences. 
     *
     * @author Sebastin Cabanas
     */
    public void asignarLevel() {
        if (level.equalsIgnoreCase("pEasy")) {
            levelInteger = 1;
        } else if (level.equalsIgnoreCase("pNormal")) {
            levelInteger = 2;
        } else {
            levelInteger = 3;
        }
    }

    /**
     * Method which create the UI for the button Save and a listener for its events.
     *
     * @author Sebastin Cabanas
     */
    private void gardarBoton() {
        save = new TextButton("Save", skin);
        save.setBounds(saveX, saveY, ANCHO_SAVE, ALTO_SAVE);
        save.setVisible(false);

        save.addListener(new ClickListener() {
            public void clicked(InputEvent event, float x, float y) {
                // Save the best score in the hide method.
                meuxogogame.setComprobarSound(false);
                meuxogogame.setScreen(new Presentacion(meuxogogame));
            }
        });
        stage.addActor(save);
    }

    /**
     * Method which create the UI for a text field where the user may write the name
     *
     * @author Sebastin Cabanas
     */
    private void nombre() {
        texto = new TextField("", skin);
        texto.setBounds(nombreX, nombreY, ANCHO_NOMBRE, ALTO_NOMBRE);
        texto.setVisible(false);
        //texto.
        stage.addActor(texto);
    }

    /**
     * Method which create the UI for a scoreboard.
     *
     * @author Sebastin Cabanas
     */
    private void marcador() {
        marcador = new TextField("0", skin);
        marcador.setColor(Color.RED);
        marcador.setBounds(MARCADOR_X, MARCADOR_Y, anchoMarcador, MARCADOR_ALTO);
        stage.addActor(marcador);
    }

    /**
     * Method which create the UI for the label which says "Put here a nickname please..."
     *
     * @author Sebastin Cabanas
     */
    private void labNombre() {
        labTexto = new Label(LABEL, skin);
        labTexto.setColor(Color.DARK_GRAY);
        labTexto.setFontScale(1);
        labTexto.setBounds(labNombreX, labNombreY, ANCHO_LAB, ALTO_LAB);
        labTexto.setAlignment(Align.center);
        labTexto.setVisible(false);
        stage.addActor(labTexto);
    }

    /**
     * Method which update the current score into the scoreboard.
     *
     * @author Sebastin Cabanas
     */
    private void cargarElementosGraficos() {
        marcador.setText("" + rendererxogo.getPuntuacionTotal());
    }

    /**
     * Method which play the background music in a infinite looping. With diferent volume 
     * in the Android version.
     *
     * @author Sebastin Cabanas
     */
    private void play_musica() {
        sonFondo.setVolume(VOLUMEN);
        if (ANDROID)
            sonFondo.setVolume(VOLUMENANDROID);
        sonFondo.setLooping(true);
        sonFondo.play();
    }

    /**
     * Method which get the score of the game already finished and the name written by the user, 
     * then compare to the saved max. scores and replace it if it's higher
     *
     * @author Sebastin Cabanas
     */
    private void actualizarPuntuacions() {
        // Score of this game.
        int puntosPartida = rendererxogo.getPuntuacionTotal(); // Total score of this game.
        String nome = texto.getText(); // Name written by the user.
        if (nome.length() > 8)
            nome = nome.substring(0, 8); // The nickname can hold more than 8 chars,

        if (puntosPartida > p1) {
            prefs.putInteger(puntuacion1, puntosPartida);
            prefs.putString("name1", nome);

            puntosPartida = p1;
            nome = n1;
        }

        if (puntosPartida > p2) {
            prefs.putInteger(puntuacion2, puntosPartida);
            prefs.putString("name2", nome);

            puntosPartida = p2;
            nome = n2;
        }

        if (puntosPartida > p3) {
            prefs.putInteger(puntuacion3, puntosPartida);
            prefs.putString("name3", nome);

            puntosPartida = p3;
            nome = n3;
        }

        if (puntosPartida > p4) {
            prefs.putInteger(puntuacion4, puntosPartida);
            prefs.putString("name4", nome);

            puntosPartida = p4;
            nome = n4;
        }

        if (puntosPartida > p5) {
            prefs.putInteger(puntuacion5, puntosPartida);
            prefs.putString("name5", nome);

        }

        prefs.flush();
    }

    @Override
    public void render(float delta) {
        crono = rendererxogo.getCrono();
        rendererxogo.render(delta);
        soundState = meuxogogame.getSoundState();
        rendererxogo.setSoundState(soundState);
        controlarCrono();
        ampliarMarcador();
        moverPala();

        if (!soundState)
            sonFondo.pause();
        else
            play_musica();

        if (pause) {
            meuxogogame.setScreen(new PantallaPause(meuxogogame, this));
            return;
        }

        // Check if the user have at least 1 live
        if (rendererxogo.getVidas() <= 0) {
            finxogo = true;
        }

        if (finxogo) {
            rendererxogo.setOver(true);
            texto.setVisible(true);
            save.setVisible(true);
            labTexto.setVisible(true);
            Gdx.input.setInputProcessor(stage);
        }

        // User interface
        cargarElementosGraficos();
        stage.act(Gdx.graphics.getDeltaTime());
        stage.draw();
    }

    /**
     * Method which call to other method in the class render to move the paddle when the
     * user touch the screen or the keyboard in a PC.
     *
     * @author Sebastin Cabanas
     */
    public void moverPala() {
        if (moverPala)
            rendererxogo.moverPala(1, claves(teclaIz), claves(teclaDer));

        switch (idMove) {
        case 2:
            rendererxogo.moverPala(2);
            break;

        case 3:
            rendererxogo.moverPala(3);
            break;
        }
    }

    /**
     * Method which have the control over the chronometer.
     *
     * @author Sebastin Cabanas
     */
    public void controlarCrono() {

        // Show the initial message 3  2 1 GO!
        if (crono > 3.5)
            rendererxogo.setRuning(true);

        if ((int) crono == tempo_Nivel && (int) crono != segCambioNivel) {
            rendererxogo.addVelocidadeBola(aumentoVelocidade);
            rendererxogo.addPuntos(10, levelInteger); // Earn more points each time the velocity increase.
            segCambioNivel = (int) crono;// Save the last time when the velocity increase to do it only one time.
            tempo_Nivel += tempo_Nivel;// Add velocity each tempo_Nivel seconds 15 - 30 - 45 -60 etc
            rendererxogo.setBola2(true); // Enable to have 2 balls when the user reach a specific score.
            rendererxogo.setLevelUP(true);
        }
    }

    /**
     * Method which increase the size of the scoreboard every time the user reach a specific score.
     *
     * @author Sebastin Cabanas
     */
    private void ampliarMarcador() {

        if (rendererxogo.getPuntuacionTotal() > 99 && id == 1) {
            anchoMarcador += 10;
            marcador.setWidth(anchoMarcador);
            id++;
        }

        if (rendererxogo.getPuntuacionTotal() > 999 && id == 2) {
            anchoMarcador += 10;
            marcador.setWidth(anchoMarcador);
            id++;
        }

        if (rendererxogo.getPuntuacionTotal() > 99999 && id == 3) {
            anchoMarcador += 10;
            marcador.setWidth(anchoMarcador);
            id++;
        }
    }

    @Override
    public void resize(int width, int height) {
        rendererxogo.resize(width, height);
    }

    @Override
    public void show() {
        // TODO Auto-generated method stub
        Gdx.input.setInputProcessor(this);
        pause = false;

        if (soundState)
            play_musica();
    }

    @Override
    public void hide() {
        // TODO Auto-generated method stub
        Gdx.input.setInputProcessor(null);
        sonFondo.stop();
        actualizarPuntuacions();
    }

    @Override
    public void pause() {
        // TODO Auto-generated method stub
        Gdx.input.setInputProcessor(null);
        if (!finxogo) {
            pause = true;
        }
        sonFondo.pause();

    }

    @Override
    public void resume() {
        // TODO Auto-generated method stub
        Gdx.input.setInputProcessor(this);
        pause = false;
        if (soundState)
            play_musica();
    }

    @Override
    public void dispose() {
        Gdx.input.setInputProcessor(null);
        rendererxogo.dispose();
        sonFondo.dispose();

        skin.dispose();
        stage.dispose();
    }

    @Override
    public boolean keyDown(int keycode) {
        if (keycode == Keys.ENTER) {
            if (finxogo) {
                meuxogogame.setComprobarSound(false);
                meuxogogame.setScreen(new Presentacion(meuxogogame));
            }
        }

        if (keycode == Keys.BACK) {
            meuxogogame.setComprobarSound(false);
            meuxogogame.setScreen(new Presentacion(meuxogogame));
        }

        return false;
    }

    @Override
    public boolean keyUp(int keycode) {
        // TODO Auto-generated method stub
        return false;
    }

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

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

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

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

    @Override
    public boolean mouseMoved(int screenX, int screenY) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean scrolled(int amount) {
        // TODO Auto-generated method stub
        return false;
    }

    private void touch(int screenX, int screenY) {

        moverPala = true;

        // Vector with the position touched.
        Vector3 temporal = new Vector3(screenX, screenY, 0);

        // Turn the position in the real screen into the coordinates of the game screem
        RendererXogo.camara2d.unproject(temporal);

        vecTemporal.set(screenX, screenY, 0);
        RendererXogo.camara2d.unproject(vecTemporal);

        // Finger, rectangle in the position touched of 2x2
        dedo.set(vecTemporal.x, vecTemporal.y, 2, 2);

        //  Buttons in the top of the screen 
        sound.set(RendererXogo.X_SOUND, RendererXogo.Y_BOTONS, RendererXogo.ANCHO_BOTONS,
                RendererXogo.ALTO_BOTTONS);
        pauseBtn.set(RendererXogo.X_PAUSE, RendererXogo.Y_BOTONS, RendererXogo.ANCHO_BOTONS,
                RendererXogo.ALTO_BOTTONS);
        exit.set(RendererXogo.X_EXIT, RendererXogo.Y_BOTONS, RendererXogo.ANCHO_BOTONS, RendererXogo.ALTO_BOTTONS);

        // Check if the position touch match with the buttons.
        comprobarBoton(sound, 1);
        comprobarBoton(pauseBtn, 2);
        comprobarBoton(exit, 3);

        // Check if the user has touched the buttons to move the padle 
        if (Intersector.overlaps(dedo, rendererxogo.getIz())) {
            idMove = 2;
        }

        if (Intersector.overlaps(dedo, rendererxogo.getDerecho())) {
            idMove = 3;
        }

    }

    /**
     * Method which check if the user touch x or y button and execute some instructions if true. 
     *
     * @author Sebastin Cabanas
     */
    private void comprobarBoton(Rectangle boton, int id) {
        switch (id) {
        case 1:// Button sound
            if (Intersector.overlaps(dedo, boton)) {
                changeSound();
                moverPala = false;
            }
            break;

        case 2:// Button pause
            if (Intersector.overlaps(dedo, boton)) {
                pause = true;
                moverPala = false;
            }
            break;

        case 3:// Button exit
            if (Intersector.overlaps(dedo, boton)) {
                meuxogogame.setComprobarSound(false);
                meuxogogame.setScreen(new Presentacion(meuxogogame));
            }
            break;
        }
    }

    /**
     * Method which turns the sound state into the opposite state, if the sound is active then deactive it.
     *
     * @author Sebastin Cabanas
     */
    public void changeSound() {
        if (soundState) {
            meuxogogame.setSoundState(false);// Invertir estado.
            prefs.putBoolean("soundState", false);
        } else {
            meuxogogame.setSoundState(true);
            prefs.putBoolean("soundState", true);
        }

        prefs.flush();
    }

    /**
     * Method which return the constant related with a key. 
     *
     * @author Sebastin Cabanas
     */
    public int claves(String key) {
        if (key.equalsIgnoreCase("a"))
            return Keys.A;
        if (key.equalsIgnoreCase("q"))
            return Keys.Q;
        if (key.equalsIgnoreCase("w"))
            return Keys.W;
        if (key.equalsIgnoreCase("e"))
            return Keys.E;
        if (key.equalsIgnoreCase("r"))
            return Keys.R;
        if (key.equalsIgnoreCase("t"))
            return Keys.T;
        if (key.equalsIgnoreCase("y"))
            return Keys.Y;
        if (key.equalsIgnoreCase("u"))
            return Keys.U;
        if (key.equalsIgnoreCase("i"))
            return Keys.I;
        if (key.equalsIgnoreCase("o"))
            return Keys.O;
        if (key.equalsIgnoreCase("p"))
            return Keys.P;
        if (key.equalsIgnoreCase("s"))
            return Keys.S;
        if (key.equalsIgnoreCase("d"))
            return Keys.D;
        if (key.equalsIgnoreCase("f"))
            return Keys.F;
        if (key.equalsIgnoreCase("g"))
            return Keys.G;
        if (key.equalsIgnoreCase("h"))
            return Keys.H;
        if (key.equalsIgnoreCase("y"))
            return Keys.Y;
        if (key.equalsIgnoreCase("j"))
            return Keys.J;
        if (key.equalsIgnoreCase("k"))
            return Keys.K;
        if (key.equalsIgnoreCase("l"))
            return Keys.L;
        if (key.equalsIgnoreCase("z"))
            return Keys.Z;
        if (key.equalsIgnoreCase("x"))
            return Keys.X;
        if (key.equalsIgnoreCase("c"))
            return Keys.C;
        if (key.equalsIgnoreCase("v"))
            return Keys.V;
        if (key.equalsIgnoreCase("b"))
            return Keys.B;
        if (key.equalsIgnoreCase("n"))
            return Keys.N;
        if (key.equalsIgnoreCase("m"))
            return Keys.M;
        if (key.equalsIgnoreCase("left"))
            return Keys.LEFT;
        if (key.equalsIgnoreCase("right"))
            return Keys.RIGHT;
        return 0;
    }
}