com.tumblr.oddlydrawn.nahlc.screens.GameOverScreen.java Source code

Java tutorial

Introduction

Here is the source code for com.tumblr.oddlydrawn.nahlc.screens.GameOverScreen.java

Source

/*
 *   Copyright 2014 oddlydrawn
 *
 *   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 com.tumblr.oddlydrawn.nahlc.screens;

import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.math.Interpolation;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.Group;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
import com.badlogic.gdx.scenes.scene2d.ui.Button;
import com.badlogic.gdx.scenes.scene2d.ui.Button.ButtonStyle;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;
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.TextButton.TextButtonStyle;
import com.badlogic.gdx.scenes.scene2d.utils.Align;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import com.badlogic.gdx.utils.viewport.StretchViewport;
import com.tumblr.oddlydrawn.nahlc.Assets;
import com.tumblr.oddlydrawn.nahlc.Renderer;
import com.tumblr.oddlydrawn.nahlc.SavedStuff;

/** @author oddlydrawn */
public class GameOverScreen implements Screen {
    private Game game;
    private Stage stage;
    private Table rootTable;
    private Table topScoreTable;
    private Skin skin;
    private SavedStuff savedStuff;
    private Assets assets;

    public GameOverScreen(Game g, int level, int score) {
        game = g;
        savedStuff = new SavedStuff();
        assets = new Assets();
        assets.initGameOver();
        stage = new Stage(new StretchViewport(Renderer.WIDTH, Renderer.HEIGHT));
        skin = new Skin();

        savedStuff.loadScores();
        savedStuff.setScore(score);

        skin.add("default", new BitmapFont(Gdx.files.internal("data/fonts/deja.fnt")));

        LabelStyle labelStyle = new LabelStyle();
        labelStyle.font = skin.getFont("default");
        skin.add("default", labelStyle);

        ButtonStyle buttonStyle = new ButtonStyle();
        skin.add("default", buttonStyle);

        TextButtonStyle textButtonStyle = new TextButtonStyle();
        textButtonStyle.font = skin.getFont("default");
        skin.add("default", textButtonStyle);

        // Background NinePatch image
        Image boxPatchImage = new Image(assets.getBoxPatch());
        boxPatchImage.setSize(Renderer.WIDTH - 40, Renderer.HEIGHT - 5);
        boxPatchImage.setPosition(20, 2);
        stage.addActor(boxPatchImage);

        // Top Score's background NinePatch image
        Image boxPatchImageTwo = new Image(assets.getBoxPatch());
        boxPatchImageTwo.setSize(220, 295);
        boxPatchImageTwo.setPosition(50, 90);
        stage.addActor(boxPatchImageTwo);

        // Single-column table that holds all the things.
        rootTable = new Table();
        rootTable.setFillParent(true);
        stage.addActor(rootTable);
        rootTable.debug();

        // Three-column table that holds the top scores.
        topScoreTable = new Table();
        topScoreTable.debug();
        topScoreTable.columnDefaults(0).width(73);
        topScoreTable.columnDefaults(1).width(50);
        topScoreTable.columnDefaults(1).align(Align.center);

        Label scoreLabel = new Label("Score: " + score, skin);
        Label topScoresLabel = new Label("Top Scores", skin);

        Image mainMenuImage = new Image(assets.getMainMenuSprite());
        Image newGameImage = new Image(assets.getNewGameSprite());

        Button mainMenuButton = new Button(skin);
        mainMenuButton.add(mainMenuImage);

        Button newGameButton = new Button(skin);
        newGameButton.add(newGameImage);

        Image newRecordImage = new Image(assets.getNewRecordSprite());
        Image gameOverImage = new Image(assets.getGameOverSprite());

        Image titleImage;
        if (savedStuff.isPreviousScoreInTopScore()) {
            titleImage = newRecordImage;
        } else {
            titleImage = gameOverImage;
        }

        Label[][] allTheScores = new Label[3][11];

        // Creates the labels for all the scores, populates them, and adds animations.
        for (int y = 0; y < 10; y++) {
            for (int x = 0; x < 3; x++) {
                switch (x) {
                case 0: // The labels from 1 - 10, left most to show score rank.
                    if (y == 9) {
                        allTheScores[x][y] = new Label(String.valueOf(y + 1) + ".", skin);
                    } else {
                        // Adds a space, for correct padding to numbers 1-9 (or the array indexes 0-8)
                        allTheScores[x][y] = new Label(" " + String.valueOf(y + 1) + ".", skin);
                    }
                    topScoreTable.add(allTheScores[x][y]);
                    break;
                case 1: // The labels with the Level associated with each score
                    allTheScores[x][y] = new Label(savedStuff.getLevel(y, x - 1), skin);
                    topScoreTable.add(allTheScores[x][y]);

                    if (savedStuff.isPreviousScoreInTopScore()) {
                        // Adds the drop animation to scores below the score to replace
                        if (y >= savedStuff.getScoreToReplace()) {
                            allTheScores[x][y].addAction(Actions.sequence(Actions.delay(2f), Actions.delay(0.5f),
                                    Actions.moveBy(0, -26, 2, Interpolation.bounceOut)));
                        }
                    }
                    break;
                case 2: // The labels with the Score associated with each rank and level
                    allTheScores[x][y] = new Label(savedStuff.getScore(y, x - 1), skin);
                    topScoreTable.add(allTheScores[x][y]).right();

                    if (savedStuff.isPreviousScoreInTopScore()) {
                        // Adds the drop animation to scores below the score to replace
                        if (y >= savedStuff.getScoreToReplace()) {
                            allTheScores[x][y].addAction(Actions.sequence(Actions.delay(2f), Actions.delay(0.5f),
                                    Actions.moveBy(0, -26, 2, Interpolation.bounceOut)));
                        }
                    }
                    break;
                default:
                    break;
                }
            }
            topScoreTable.row();
        }

        rootTable.add(titleImage);
        rootTable.row();

        rootTable.add(scoreLabel).expand();
        rootTable.row();

        rootTable.add(topScoresLabel);
        rootTable.row();
        topScoreTable.setWidth(rootTable.getWidth());
        topScoreTable.setTransform(true);
        rootTable.setTransform(true);
        rootTable.add(topScoreTable);
        rootTable.row();

        rootTable.add(newGameButton).expand().bottom();
        rootTable.row();
        rootTable.add(mainMenuButton).expand();

        rootTable.padLeft(35f);
        rootTable.padRight(35f);
        rootTable.padTop(9f);
        rootTable.padBottom(9f);

        newGameButton.toBack();
        mainMenuButton.toBack();

        // Adds padding to Level and 10th rank strings for correct padding
        String levelButtonString;
        int mew = Integer.valueOf(String.valueOf(allTheScores[1][9].getText()));
        if (mew < 10) {
            levelButtonString = String.valueOf(allTheScores[1][9].getText()) + " ";
        } else {
            levelButtonString = String.valueOf(allTheScores[1][9].getText());
        }
        String previousLevelButtonString;
        if (level < 10) {
            previousLevelButtonString = String.valueOf(level + " ");
        } else {
            previousLevelButtonString = String.valueOf(level);
        }
        String previousScoreString = String.valueOf(score);

        TextButton previousLevelButton = new TextButton(previousLevelButtonString, skin);
        TextButton previousScoreButton = new TextButton(previousScoreString, skin);
        TextButton tenthLevelButton = new TextButton(levelButtonString, skin);
        TextButton tenthScoreButton = new TextButton(String.valueOf(allTheScores[2][9].getText()), skin);

        // Pads Button text with spaces for correct alignment
        tenthLevelButton.setText(fillStringWithSpaces(String.valueOf(tenthLevelButton.getText())));
        previousLevelButton.setText(fillStringWithSpaces(previousLevelButtonString));
        stage.addActor(tenthLevelButton);
        stage.addActor(tenthScoreButton);

        // Groups to link the scores and levels for 10th-rank scores and the score just obtained
        // Needed to apply transforms to buttons since transforming text isn't possible, I think.
        Group group = new Group();
        group.addActor(tenthScoreButton);
        group.addActor(tenthLevelButton);

        Group groupPrevious = new Group();
        groupPrevious.addActor(previousLevelButton);
        groupPrevious.addActor(previousScoreButton);

        // Modifies score buttons positions for correct alignment with the rest of the table
        tenthScoreButton.setPosition(144 - subPosFromLength(tenthScoreButton.getText().length()), 00);
        previousScoreButton.setPosition(144 - subPosFromLength(previousScoreString.length()), 00);
        tenthScoreButton.align(Align.left);
        previousScoreButton.align(Align.left);

        tenthLevelButton.setTransform(true);
        tenthScoreButton.setTransform(true);

        stage.addActor(group);
        group.setPosition(105, 97);

        allTheScores[1][9].setVisible(false);
        allTheScores[2][9].setVisible(false);

        group.setTransform(true);

        // Adds animation for drop and bounce then rotate and drop to 10th rank score
        if (savedStuff.isPreviousScoreInTopScore()) {
            group.setOrigin(group.getX() + group.getWidth() + 50, 10);
            group.addAction(Actions.sequence(Actions.delay(2f), Actions.delay(0.5f),
                    Actions.moveBy(0, -26, 2, Interpolation.bounceOut), Actions.delay(0.1f),
                    Actions.rotateBy(90f, 2f, Interpolation.bounceOut), Actions.delay(0.1f),
                    Actions.moveBy(0, -120, 2, Interpolation.bounceOut)));
        }

        // Adds spaces to first score in top score table to have the same column width regardless of score size
        allTheScores[2][0].setText(fillCSWithSpaces(allTheScores[2][0].getText()));

        mainMenuButton.addListener(new ChangeListener() {
            public void changed(ChangeEvent event, Actor actor) {
                dispose();
                game.setScreen(new MainMenuScreen(game));
            }
        });

        newGameButton.addListener(new ChangeListener() {
            public void changed(ChangeEvent event, Actor actor) {
                dispose();
                game.setScreen(new GameScreen(game));
            }
        });

        // Sets correct vertical position for score just obtained
        groupPrevious.setPosition(group.getX(), group.getY() + getVerticalPosSub(savedStuff.getScoreToReplace()));
        groupPrevious.setTransform(true);

        // Score is now in position, this makes it invisible
        groupPrevious.addAction(Actions.fadeOut(0.1f));

        // Fades the score in after the bottom-most score rotates and drops
        if (savedStuff.isPreviousScoreInTopScore()) {
            groupPrevious.addAction(Actions.sequence(Actions.delay(7.5f), Actions.fadeIn(1f)));
        }
        stage.addActor(groupPrevious);

        savedStuff.setSavedGameExists(false);
        savedStuff.savePreferences();

        savedStuff.updateLevelAndScore(level, score);
        try {
            savedStuff.saveScoresToFile();
        } catch (RuntimeException ex) {
            Gdx.app.log("ERROR NAHLC", ex.getMessage());
            ex.printStackTrace();
        } catch (Exception e) {
            Gdx.app.log("ERROR NAHLC", e.getMessage());
            e.printStackTrace();
        }
        Gdx.app.log("NAHLC", "leaving create()");
    }

    private float subPosFromLength(int length) {
        return 11 * (length - 1);
    }

    private float getVerticalPosSub(int level) {
        int diff = 9 - level;
        return diff * 26;
    }

    public String fillStringWithSpaces(String s) {
        int optimum = 7;
        int missing = optimum - s.length();
        for (int i = 0; i < missing; i++) {
            s = " " + s;
        }
        return s;
    }

    public CharSequence fillCSWithSpaces(CharSequence charSequence) {
        int optimum = 7;
        int missing = optimum - charSequence.length();
        for (int i = 0; i < missing; i++) {
            charSequence = " " + charSequence;
        }
        return charSequence;
    }

    @Override
    public void render(float delta) {
        Gdx.gl.glClearColor(0.2f, 0.2f, 0.2f, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        try {
            stage.act(delta);
        } catch (RuntimeException ex) {
            Gdx.app.log("NAHLC", "RUNTIME EXCEPTION while acting on stage");
            Gdx.app.log("ERROR NAHLC", ex.getMessage());
            ex.printStackTrace();
        } catch (Exception e) {
            Gdx.app.log("NAHLC", "EXCEPTION while acting on stage");
            Gdx.app.log("ERROR NAHLC", e.getMessage());
            e.printStackTrace();
        }

        try {
            stage.draw();
        } catch (RuntimeException ex) {
            Gdx.app.log("NAHLC", "RUNTIME EXCEPTION while drawing stage");
            Gdx.app.log("ERROR NAHLC", ex.getMessage());
            ex.printStackTrace();
        } catch (Exception e) {
            Gdx.app.log("NAHLC", "EXCEPTION while drawing stage");
            Gdx.app.log("ERROR NAHLC", e.getMessage());
            e.printStackTrace();
        }
    }

    @Override
    public void resize(int width, int height) {
        stage.getViewport().update(width, height, true);
        Gdx.app.log("NAHLC", "leaving resize()");
    }

    @Override
    public void show() {
        Gdx.input.setInputProcessor(stage);
        Gdx.app.log("NAHLC", "leaving show");
    }

    @Override
    public void hide() {
        Gdx.app.log("NAHLC", "leaving hide()");
    }

    @Override
    public void pause() {
        Gdx.app.log("NAHLC", "leaving pause()");
    }

    @Override
    public void resume() {
        Gdx.app.log("NAHLC", "leaving resume()");
    }

    @Override
    public void dispose() {
        stage.dispose();
        skin.dispose();
        assets.disposeGameOver();
        Gdx.app.log("NAHLC", "leaving dispose()");
    }

    public void log(String s) {
        System.out.println(s);
    }
}