UIRenderer.java
package com.vikingz.unitycoon.render;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.ImageButton;
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.utils.ClickListener;
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
import com.badlogic.gdx.utils.viewport.FitViewport;
import com.badlogic.gdx.utils.viewport.Viewport;
import com.vikingz.unitycoon.global.GameConfig;
import com.vikingz.unitycoon.global.GameGlobals;
import com.vikingz.unitycoon.menus.*;
import com.vikingz.unitycoon.screens.GameScreen;
import com.vikingz.unitycoon.screens.ScreenMultiplexer;
import com.vikingz.unitycoon.util.Leaderboard;
/**
* This class renders all the UI elements to the Screen.
*
* This enables us to control how the UI is draw and resized differently from how the rest of
* the game is drawn.
*
* This class essentially forms another layer on the screen that renders all the UI elements on
* this layer as opposed to the game layer.
*
* This class has been refactored to change the appearance of the UI to complete NFR_EASE_OF_USE.
* It also completes UR_ACHIEVEMENTS and UR_LEADERBOARD.
*/
public class UIRenderer {
final Stage stage;
final Viewport viewport;
final SpriteBatch spriteBatch;
final BuildMenu buildMenu;
final StatsRenderer statsRenderer;
// Popup Menus
final PauseMenu pauseMenu;
final EndMenu endOfTimerPopup;
final LeaderboardMenu leaderboardPopUp;
boolean displayingAchievement = false;
TextButton achievementLabel;
Texture statsBarTexture;
ImageButton pauseBtn;
GameScreen gameScreen;
/**
* Creates a new UIRenderer
* @param skin Skin used to style content
* @param buildingRenderer Building renderer
*/
public UIRenderer(Skin skin, BuildingRenderer buildingRenderer){
viewport = new FitViewport(GameConfig.getInstance().getWindowWidth(), GameConfig.getInstance().getWindowHeight());
spriteBatch = new SpriteBatch();
stage = new Stage(viewport);
//Set pause button
Table table = new Table();
table.setFillParent(true);
table.right().top();
Texture pauseTexture = new Texture("png\\pause.png");
Texture pauseHoverTexture = new Texture("png\\pauseHover.png");
pauseBtn = new ImageButton(new ImageButton.ImageButtonStyle());
pauseBtn.getStyle().imageUp = new TextureRegionDrawable(new TextureRegion(pauseTexture));
pauseBtn.getStyle().imageOver = new TextureRegionDrawable(new TextureRegion(pauseHoverTexture));
table.add(pauseBtn).size(43).padRight(5);
stage.addActor(table);
pauseBtn.addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
pause(GameGlobals.TIME.isPaused());
}
});
statsRenderer = new StatsRenderer(skin);
buildMenu = new BuildMenu(skin, buildingRenderer, stage);
pauseMenu = new PauseMenu(skin, stage);
endOfTimerPopup = new EndMenu(skin, "End of Game");
leaderboardPopUp = new LeaderboardMenu(skin, "");
statsBarTexture = new Texture("png\\statsBar.png");
// Set up achievements popup
achievementLabel = new TextButton("", skin);
achievementLabel.setWidth(1000);
achievementLabel.setPosition((stage.getWidth() - achievementLabel.getWidth()) / 2,
(stage.getHeight() - 100));
achievementLabel.getLabel().setFontScale((float)0.4,(float)0.4);
// Sets what the buttons do on the end of timer window
Runnable rightBtn = ScreenMultiplexer::closeGame;
Runnable leftBtn = () -> {
leaderboardPopUp.setPosition((stage.getWidth() - leaderboardPopUp.getWidth()) / 2,
(stage.getHeight() - leaderboardPopUp.getHeight()) / 2);
stage.addActor(leaderboardPopUp);};
endOfTimerPopup.setupButtons(leftBtn, "Leaderboard", rightBtn, "Menu");
leaderboardPopUp.setupButton();
//Allows building pop-ups to be added to the ui stage
buildingRenderer.setUIStage(stage);
}
/**
* When the game has finished the game will call this function which will show the end of game popup.
*/
public void endGame(String title) {
Leaderboard.loadLeaderboard();
String message = "Final Satisfaction: " + GameGlobals.SATISFACTION.getSatisfaction() + "\n\n";
message += GameGlobals.ACHIEVEMENTS.allAchievementsCompleted();
endOfTimerPopup.setTitle(title);
endOfTimerPopup.setMessage(message);
endOfTimerPopup.setPosition((stage.getWidth() - endOfTimerPopup.getWidth()) / 2,
(stage.getHeight() - endOfTimerPopup.getHeight()) / 2);
stage.addActor(endOfTimerPopup);
if (Leaderboard.isLeaderboardScore(GameGlobals.SATISFACTION.getSatisfaction())) {
Leaderboard.addScoreToLeaderBoard(GameGlobals.SATISFACTION.getSatisfaction(),
UsernameMenu.getUsername());
Leaderboard.saveLeaderboard();
}
leaderboardPopUp.setMessage(Leaderboard.getLeaderboardValue(), Leaderboard.getLeaderboardPos());
GameGlobals.ACHIEVEMENTS.saveAchievements();
}
/**
* Creates the event and displays it
*/
public void createEvent() {
PopupMenu event = GameGlobals.EVENT.randomEvent().getPopup();
stage.addActor(event);
event.setPosition((stage.getWidth() - event.getWidth()) / 2,
(stage.getHeight() - event.getHeight()) / 2);
GameGlobals.TIME.setPaused(true);
}
/**
* Creates a specific event and displays it
*/
public void createEvent(String eventName) {
PopupMenu event = GameGlobals.EVENT.setEvent(eventName).getPopup();
stage.addActor(event);
event.setPosition((stage.getWidth() - event.getWidth()) / 2,
(stage.getHeight() - event.getHeight()) / 2);
GameGlobals.TIME.setPaused(true);
}
/**
* Pauses the game displays the pause menu
* @param isPaused boolean of if the game is paused
*/
public void pause(boolean isPaused) {
if(!pauseMenu.hasParent()){
stage.addActor(pauseMenu);
pauseMenu.setPosition((stage.getWidth() - pauseMenu.getWidth()) / 2,
(stage.getHeight() - pauseMenu.getHeight()) / 2);
GameGlobals.TIME.setPaused(true);
}
else{
pauseMenu.remove();
GameGlobals.TIME.setPaused(false);
}
}
/**
* Calls all render functions in the renderers.
* @param delta
*/
public void render(float delta){
// Draws stats bar
spriteBatch.setProjectionMatrix(viewport.getCamera().combined);
spriteBatch.begin();
// Uses values defined when viewport is created
spriteBatch.draw(statsBarTexture, 0,
GameConfig.getInstance().getWindowHeight() * 24/25, GameConfig.getInstance().getWindowWidth(),
GameConfig.getInstance().getWindowHeight() * 1/24);
spriteBatch.end();
viewport.apply();
statsRenderer.render(delta);
buildMenu.render(delta);
}
/**
* Resizes UI content when the window is resized
* @param width New width
* @param height New height
*/
public void resize(int width, int height){
viewport.update(width, height);
stage.getViewport().update(width, height, true);
buildMenu.resize(width, height);
statsRenderer.resize(width, height);
}
/**
* Sets the input process to this class when called
*/
public void takeInput(){
Gdx.input.setInputProcessor(stage);
}
/**
* Disposes of content in this screen
*/
public void dispose(){
stage.dispose();
}
/**
* Displays achievements in the order they were completed.
*/
public void displayAchievements() {
//Creates a task to remove the achievement from the screen after 8s.
Timer timer = new Timer(8000, new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0) {
achievementLabel.remove();
displayingAchievement = false;
}
});
timer.setRepeats(false);
if (GameGlobals.ACHIEVEMENTS.achievementsToDisplay.size() != 0 && !displayingAchievement) {
achievementLabel.setText(GameGlobals.ACHIEVEMENTS.achievementsToDisplay.remove());
stage.addActor(achievementLabel);
displayingAchievement = true;
timer.start();
}
}
}