BuildMenu.java
package com.vikingz.unitycoon.menus;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.*;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
import com.vikingz.unitycoon.building.BuildingStats;
import com.vikingz.unitycoon.building.BuildingStats.BuildingType;
import com.vikingz.unitycoon.global.GameConfig;
import com.vikingz.unitycoon.global.GameGlobals;
import com.vikingz.unitycoon.render.BuildingRenderer;
import static com.vikingz.unitycoon.building.BuildingStats.buildingCoinDict;
import static com.vikingz.unitycoon.building.BuildingStats.BuildingType.*;
/**
* This class is what creates the build menu in the game.
*
* It contains a single constructor that takes a Skin, BuildingRenderer
* and a Stage as parameters to create the Building Menu.
*
* This class also creates the 4 buttons at the bottom of the game screen
* by which the build menu is accessed.
*
* This class has been refactored to update the UI.
*/
public class BuildMenu{
final BuildingRenderer buildingRenderer;
final Stage stage;
final Skin skin;
boolean windowActive = false;
int width = GameConfig.getInstance().getWindowWidth();
int height = GameConfig.getInstance().getWindowHeight();
Window currentMenu;
//Selects which building of BuildingType should be displayed currently.
int index = 0;
// Determines if the user has ever seen the inDebtMenu
boolean seenDebtMenu;
/**
* Creates a new BuildMenu
* @param skin SKin of the buttons on the menu
* @param buildingRenderer BuildingRenderer instance that renders the buildings in the game
* @param stage The stage on which the menu is drawn
*/
public BuildMenu(Skin skin, BuildingRenderer buildingRenderer, Stage stage) {
this.stage = stage;
this.buildingRenderer = buildingRenderer;
this.skin = skin;
//Texture atlas of building menu bar
Texture textureAtlas = new Texture(Gdx.files.internal("textureAtlases/buildMenuButtonsAtlas.png"));
//Sets the pixel size of tiles used for build menu bar
int atlasTileSize = 128;
TextureRegion btn1Texture = new TextureRegion(textureAtlas, 0, 0, atlasTileSize, atlasTileSize);
TextureRegion btn2Texture = new TextureRegion(textureAtlas, atlasTileSize, 0, atlasTileSize,
atlasTileSize);
TextureRegion btn3Texture = new TextureRegion(textureAtlas, atlasTileSize * 2, 0, atlasTileSize,
atlasTileSize);
TextureRegion btn4Texture = new TextureRegion(textureAtlas, atlasTileSize * 3, 0, atlasTileSize,
atlasTileSize);
TextureRegion btn1Texture_hover = new TextureRegion(textureAtlas, 0, atlasTileSize, atlasTileSize,
atlasTileSize);
TextureRegion btn2Texture_hover = new TextureRegion(textureAtlas, atlasTileSize, atlasTileSize,
atlasTileSize, atlasTileSize);
TextureRegion btn3Texture_hover = new TextureRegion(textureAtlas, atlasTileSize*2, atlasTileSize,
atlasTileSize, atlasTileSize);
TextureRegion btn4Texture_hover = new TextureRegion(textureAtlas, atlasTileSize*3, atlasTileSize,
atlasTileSize, atlasTileSize);
// Create ImageButtons
ImageButton studyBtn = new ImageButton(new ImageButton.ImageButtonStyle());
studyBtn.getStyle().imageUp = new TextureRegionDrawable(btn1Texture);
studyBtn.getStyle().imageOver = new TextureRegionDrawable(btn1Texture_hover);
ImageButton accommBtn = new ImageButton(new ImageButton.ImageButtonStyle());
accommBtn.getStyle().imageUp = new TextureRegionDrawable(new TextureRegion(btn2Texture));
accommBtn.getStyle().imageOver = new TextureRegionDrawable(new TextureRegion(btn2Texture_hover));
ImageButton recBtn = new ImageButton(new ImageButton.ImageButtonStyle());
recBtn.getStyle().imageUp = new TextureRegionDrawable(new TextureRegion(btn3Texture));
recBtn.getStyle().imageOver = new TextureRegionDrawable(new TextureRegion(btn3Texture_hover));
ImageButton foodBtn = new ImageButton(new ImageButton.ImageButtonStyle());
foodBtn.getStyle().imageUp = new TextureRegionDrawable(new TextureRegion(btn4Texture));
foodBtn.getStyle().imageOver = new TextureRegionDrawable(new TextureRegion(btn4Texture_hover));
// Table for layout
Table table = new Table();
table.setFillParent(true);
table.center();
table.bottom();
// Add buttons to table
table.add(studyBtn).pad(10);
table.add(accommBtn).pad(10);
table.add(recBtn).pad(10);
table.add(foodBtn).pad(10);
// Add table to stage
stage.addActor(table);
// Set up click listeners for buttons
studyBtn.addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
if (buildingRenderer.getOpenMenu()) {
if(currentMenu != null) { currentMenu.remove(); }
showMenu(ACADEMIC);
}
buildingRenderer.setOpenMenu(true);
}
});
accommBtn.addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
if (buildingRenderer.getOpenMenu()) {
if(currentMenu != null) { currentMenu.remove(); }
showMenu(ACCOMODATION);
}
buildingRenderer.setOpenMenu(true);
}
});
recBtn.addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
if (buildingRenderer.getOpenMenu()) {
if(currentMenu != null) { currentMenu.remove(); }
showMenu(RECREATIONAL);
}
buildingRenderer.setOpenMenu(true);
}
});
foodBtn.addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
if (buildingRenderer.getOpenMenu()) {
if(currentMenu != null) { currentMenu.remove(); }
showMenu(FOOD);
}
buildingRenderer.setOpenMenu(true);
}
});
seenDebtMenu = false;
}
/**
* Creates a new window and sets up all of the contents of the window so that when the user
* presses one of the buttons at the bottom of the game screen the corresponding menu is shown.
* This method has been refactored to add a debt popup for UI.
* @param buildingType contains Type of building from BuildingStats
*/
private void showMenu(BuildingStats.BuildingType buildingType) {
// Create a window (menu)
index = 0;
Window window = new Window("", skin);
window.getTitleTable().padTop(25).padLeft(437);
this.currentMenu = window;
window.setMovable(false);
window.setBackground(GameGlobals.backGroundDrawable);
//Building name Label
Label buildingNameLabel = new Label(BuildingStats.buildingNameDict.get(buildingType)[0], skin);
window.add((Actor) null);
window.add(buildingNameLabel);
window.row().padTop(10);
//Image Of Building
window.add((Actor) null);
Image buildingImage = new Image(BuildingStats.getTextureOfBuilding( BuildingStats.buildingDict.get(
buildingType)[0]));
window.add(buildingImage);
window.row().padTop(20);
//Student Label
window.add((Actor) null);
Label buildingStudent = new Label("Student Space: " + BuildingStats.buildingStudentDict.get(
buildingType)[0],skin);
window.add(buildingStudent).expandX();
window.row();
//Coins Label
window.add((Actor) null);
Label buildingCoins;
// Sets label to semester if the building changes money every semester and second otherwise
if (buildingType == BuildingType.ACADEMIC || buildingType == BuildingType.ACCOMODATION) {
buildingCoins = new Label("Coins Per Semester: " + buildingCoinDict.get(buildingType)[0] + "k",
skin);
}
else {
buildingCoins = new Label("Coins Per Second: " + buildingCoinDict.get(buildingType)[0] + "k",
skin);
}
window.add(buildingCoins).expandX();
window.row();
//Price Label
window.add((Actor) null);
Label buildingPrice;
if (BuildingStats.nextBuildingFree) {
buildingPrice = new Label("Price: FREE", skin);
}
else {
buildingPrice= new Label("Price: " + BuildingStats.buildingPriceDict.get(buildingType)[0] + "k",skin);
}
window.add(buildingPrice);
window.row().padTop(20);
//Back Building Button
TextButton backButton = new TextButton("Back", skin);
backButton.setSize(100, 30); // Set size for the back button
backButton.addListener(new ClickListener(){
@Override
public void clicked(InputEvent event, float x, float y) {
try {
index--;
SetLabelText(buildingNameLabel, buildingType, buildingPrice, buildingStudent,
buildingCoins, buildingImage);
}
catch (ArrayIndexOutOfBoundsException e){
index = BuildingStats.buildingNameDict.get(buildingType).length-1;
SetLabelText(buildingNameLabel, buildingType, buildingPrice, buildingStudent,
buildingCoins, buildingImage);
}
}
});
window.add(backButton).padLeft(50);
// Create the Buy Button
TextButton buyButton = new TextButton("Buy", skin);
buyButton.setSize(100, 30);
buyButton.addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
// Creates an going into debt pop-up if the user doesn't have enough money for the building.
// Only shows the first time
if(!seenDebtMenu && (GameGlobals.MONEY.getBalance() - Integer.valueOf(
BuildingStats.buildingPriceDict.get(buildingType)[index]) < 0)) {
seenDebtMenu = true;
DebtMenu debtPopUp = new DebtMenu(skin);
debtPopUp.setPosition((stage.getWidth() - debtPopUp.getWidth()) / 2,
(stage.getHeight() - debtPopUp.getHeight()) / 2);
debtPopUp.setupButton(skin, buildingRenderer, window, buildingType, index);
stage.addActor(debtPopUp);
}
else {
buildingRenderer.selectBuilding(buildingType,index);
window.remove();
}
}
});
window.add(buyButton);
//Next Building Button
TextButton nextButton = new TextButton("Next", skin);
nextButton.setSize(100, 30); // Set size for the next button
nextButton.addListener(new ClickListener(){
@Override
public void clicked(InputEvent event, float x, float y) {
try {
index++;
SetLabelText(buildingNameLabel, buildingType, buildingPrice, buildingStudent,
buildingCoins, buildingImage);
}
catch (ArrayIndexOutOfBoundsException e){
index = 0;
SetLabelText(buildingNameLabel, buildingType, buildingPrice, buildingStudent,
buildingCoins, buildingImage);
}
}
});
window.add(nextButton).padRight(50);
// Create the close button
TextButton closeButton = new TextButton("Close", skin);
closeButton.setSize(100, 30); // Set size for the close button
closeButton.addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
setWindowActive(false);
window.remove(); // Remove window from the stage
}
});
// Add close button to the window
window.row().padTop(10); // Add a row before adding the close button
window.add((Actor) null);
window.add(closeButton);
// Set size and position of the window
//Size of the window
int MENU_WINDOW_WIDTH = 1000;
int MENU_WINDOW_HEIGHT = 800;
window.setSize(MENU_WINDOW_WIDTH, MENU_WINDOW_HEIGHT);
window.setPosition(this.width / 2f - (MENU_WINDOW_WIDTH / 2), this.height / 2f -
(MENU_WINDOW_HEIGHT / 2));
// Add window to the stage
stage.addActor(window);
}
/**
* Sets the text of each label to current index
* This method has been refactored to allow free buildings for UR_EVENTS.
* @param buildingNameLabel Name Of building
* @param buildingType Type of Building used, for dictionary lookup
* @param buildingPrice Price of building
* @param buildingStudent Student space of building
* @param buildingCoins coin generated per second by building
* @param buildingImage Image of building being, used for preview
*/
private void SetLabelText(Label buildingNameLabel, BuildingStats.BuildingType buildingType,
Label buildingPrice, Label buildingStudent, Label buildingCoins, Image buildingImage) {
buildingNameLabel.setText(BuildingStats.buildingNameDict.get(buildingType)[index]);
if (BuildingStats.nextBuildingFree) {
buildingPrice.setText("Price: FREE");
}
else {
buildingPrice.setText("Price: " + BuildingStats.buildingPriceDict.get(buildingType)[index]
+ "k");
}
buildingStudent.setText("Student Space: " + BuildingStats.buildingStudentDict.get(
buildingType)[index]);
if (buildingType == BuildingType.ACADEMIC || buildingType == BuildingType.ACCOMODATION) {
buildingCoins.setText("Coins Per Semester: " + buildingCoinDict.get(buildingType)[index] + "k");
}
else {
buildingCoins.setText("Coins Per Second: " + buildingCoinDict.get(buildingType)[index] + "k");
}
buildingImage.setDrawable(BuildingStats.getTextureDrawableOfBuilding(BuildingStats.buildingDict.get(
buildingType)[index]));
}
/**
* Returns if the window is currently open.
* @return windowActive boolean
*/
public boolean isWindowActive() {
return windowActive;
}
/**
* Sets the windowActive, used when the menu is opened or closed, to prevent two windows being
* opened at same time.
* @param windowActive boolean
*/
public void setWindowActive(boolean windowActive) {
this.windowActive = windowActive;
}
/**
* BuildingMenu render actors objects.
* @param delta
*/
public void render(float delta) {
stage.act(delta);
stage.draw();
}
/**
* Called when the window resizes.
* @param width New width
* @param height New height
*/
public void resize(int width, int height) {
stage.getViewport().update(width, height, true);
this.width = width;
this.height = height;
}
/**
* Disposes of the build menu.
*/
public void dispose() {
stage.dispose();
}
}