This commit is contained in:
Johannes Schmelz 2024-12-02 08:28:09 +01:00
commit 3260d06bc8
5 changed files with 215 additions and 40 deletions

View File

@ -18,18 +18,46 @@ import pp.monopoly.client.gui.popups.SellHouse;
import pp.monopoly.client.gui.popups.TakeMortage; import pp.monopoly.client.gui.popups.TakeMortage;
import pp.monopoly.notification.Sound; import pp.monopoly.notification.Sound;
/**
* Represents the building administration menu in the Monopoly application.
* <p>
* Provides options to manage properties, including building houses, demolishing houses,
* taking mortgages, repaying mortgages, and viewing an overview of owned properties.
* </p>
*/
public class BuildingAdminMenu extends Dialog { public class BuildingAdminMenu extends Dialog {
/** Reference to the Monopoly application instance. */
private final MonopolyApp app; private final MonopolyApp app;
/** Main container for the menu's UI components. */
private final Container mainContainer; private final Container mainContainer;
/** Background geometry for the menu. */
private Geometry background; private Geometry background;
/** Button to navigate back to the previous menu. */
private final Button backButton = new Button("Zurück"); private final Button backButton = new Button("Zurück");
/** Button to build houses on properties. */
private final Button buildButton = new Button("Bauen"); private final Button buildButton = new Button("Bauen");
/** Button to demolish houses on properties. */
private final Button demolishButton = new Button("Abriss"); private final Button demolishButton = new Button("Abriss");
/** Button to take out a mortgage on properties. */
private final Button takeMortgageButton = new Button("Hypothek aufnehmen"); private final Button takeMortgageButton = new Button("Hypothek aufnehmen");
/** Button to repay a mortgage on properties. */
private final Button payMortgageButton = new Button("Hypothek bezahlen"); private final Button payMortgageButton = new Button("Hypothek bezahlen");
/** Button to open the property overview menu. */
private final Button overviewButton = new Button("Übersicht"); private final Button overviewButton = new Button("Übersicht");
/**
* Constructs the building administration menu.
*
* @param app the Monopoly application instance
*/
public BuildingAdminMenu(MonopolyApp app) { public BuildingAdminMenu(MonopolyApp app) {
super(app.getDialogManager()); super(app.getDialogManager());
this.app = app; this.app = app;
@ -163,6 +191,9 @@ public class BuildingAdminMenu extends Dialog {
app.getGuiNode().attachChild(background); app.getGuiNode().attachChild(background);
} }
/**
* Closes the building administration menu and detaches its elements from the GUI.
*/
@Override @Override
public void close() { public void close() {
app.getGuiNode().detachChild(mainContainer); app.getGuiNode().detachChild(mainContainer);
@ -170,11 +201,19 @@ public class BuildingAdminMenu extends Dialog {
super.close(); super.close();
} }
/**
* Opens the settings menu when the escape key is pressed.
*/
@Override @Override
public void escape() { public void escape() {
new SettingsMenu(app).open(); new SettingsMenu(app).open();
} }
/**
* Periodic updates for the menu, if required.
*
* @param delta Time since the last update in seconds.
*/
@Override @Override
public void update(float delta) { public void update(float delta) {
// Periodic updates if necessary // Periodic updates if necessary

View File

@ -4,20 +4,16 @@ import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera; import com.jme3.renderer.Camera;
/** /**
* Steuert die Kamerabewegung in der Szene. * Controls the movement of the camera within the scene.
*/ */
public class CameraController { public class CameraController {
private final Camera camera; private final Camera camera;
private final float height = 25; // Höhe der Kamera über dem Spielfeld // Aktueller Winkel in der Kreisbewegung private final float height = 25; // Height of the camera above the game board
/** /**
* Konstruktor für den CameraController. * Constructor for the CameraController.
* *
* @param camera Die Kamera, die gesteuert werden soll * @param camera The camera to be controlled
* @param center Der Mittelpunkt der Kreisbewegung (Fokuspunkt)
* @param radius Der Radius der Kreisbewegung
* @param height Die Höhe der Kamera über dem Fokuspunkt
* @param speed Die Geschwindigkeit der Kamerabewegung
*/ */
public CameraController(Camera camera) { public CameraController(Camera camera) {
this.camera = camera; this.camera = camera;
@ -26,27 +22,45 @@ public class CameraController {
} }
/** /**
* Aktualisiert die Kameraposition und -ausrichtung. * Updates the camera's position and orientation.
* *
* @param tpf Zeit pro Frame * @param tpf Time per frame
*/ */
public void update(float tpf) { public void update(float tpf) {
camera.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y); camera.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);
} }
/**
* Sets the camera's position based on the field ID.
*
* @param fieldID The ID of the field to which the camera should move
*/
public void setPosition(int fieldID) { public void setPosition(int fieldID) {
camera.setLocation(fieldIdToVector(fieldID)); camera.setLocation(fieldIdToVector(fieldID));
} }
/**
* Sets the camera's position using specific coordinates.
*
* @param x The X-coordinate of the new camera position
* @param y The Y-coordinate of the new camera position
*/
public void setPosition(float x, float y) { public void setPosition(float x, float y) {
camera.setLocation(new Vector3f(x,height,y)); camera.setLocation(new Vector3f(x, height, y));
} }
/**
* Maps a field ID to its corresponding position in the game world.
*
* @param fieldID The ID of the field
* @return The position of the field as a {@link Vector3f}
* @throws IllegalArgumentException If the field ID is invalid
*/
private Vector3f fieldIdToVector(int fieldID) { private Vector3f fieldIdToVector(int fieldID) {
if (fieldID <= 10) return new Vector3f(30,height,0); if (fieldID <= 10) return new Vector3f(30, height, 0);
if (fieldID <= 20) return new Vector3f(0, height, 30); if (fieldID <= 20) return new Vector3f(0, height, 30);
if (fieldID <= 30) return new Vector3f(-30, height, 0); if (fieldID <= 30) return new Vector3f(-30, height, 0);
if (fieldID <= 40) return new Vector3f(0, height, -30); if (fieldID <= 40) return new Vector3f(0, height, -30);
else throw new IllegalArgumentException(); else throw new IllegalArgumentException();
} }
} }

View File

@ -26,9 +26,9 @@ import static pp.util.FloatMath.PI;
/** /**
* The {@code GameBoardSynchronizer} class is responsible for synchronizing the graphical * The {@code GameBoardSynchronizer} class is responsible for synchronizing the graphical
* representation of the ships and shots on the sea map with the underlying data model. * representation of the Game board and figures with the underlying data model.
* It extends the {@link BoardSynchronizer} to provide specific synchronization * It extends the {@link BoardSynchronizer} to provide specific synchronization
* logic for the sea map. * logic for the Game board.
*/ */
class GameBoardSynchronizer extends BoardSynchronizer { class GameBoardSynchronizer extends BoardSynchronizer {
private static final String UNSHADED = "Common/MatDefs/Misc/Unshaded.j3md"; //NON-NLS private static final String UNSHADED = "Common/MatDefs/Misc/Unshaded.j3md"; //NON-NLS
@ -42,9 +42,9 @@ class GameBoardSynchronizer extends BoardSynchronizer {
/** /**
* Constructs a {@code GameBoardSynchronizer} object with the specified application, root node, and ship map. * Constructs a {@code GameBoardSynchronizer} object with the specified application, root node, and ship map.
* *
* @param app the Battleship application * @param app the Monopoly application
* @param root the root node to which graphical elements will be attached * @param root the root node to which graphical elements will be attached
* @param map the ship map containing the ships and shots * @param map the Game Board containing fields and figures
*/ */
public GameBoardSynchronizer(MonopolyApp app, Node root, Board board) { public GameBoardSynchronizer(MonopolyApp app, Node root, Board board) {
super(board, root); super(board, root);
@ -54,17 +54,15 @@ class GameBoardSynchronizer extends BoardSynchronizer {
} }
/** /**
* Visits a {@link Battleship} and creates a graphical representation of it. * Visits a {@link Figure} and creates a graphical representation of it.
* The representation is either a 3D model or a simple box depending on the * The representation is a 3D model.
* type of battleship.
* *
* @param ship the battleship to be represented * @param figure the figure to be represented
* @return the node containing the graphical representation of the battleship * @return the node containing the graphical representation of the figure
*/ */
public Spatial visit(Figure figure) { public Spatial visit(Figure figure) {
final Node node = new Node(FIGURE); final Node node = new Node(FIGURE);
node.attachChild(createBox(figure)); node.attachChild(createBox(figure));
// compute the center of the ship in world coordinates
final float x = 1; final float x = 1;
final float z = 1; final float z = 1;
node.setLocalTranslation(x, 0f, z); node.setLocalTranslation(x, 0f, z);
@ -72,10 +70,10 @@ class GameBoardSynchronizer extends BoardSynchronizer {
} }
/** /**
* Creates a simple box to represent a battleship that is not of the "King George V" type. * Creates a representation of a figure
* *
* @param ship the battleship to be represented * @param figure the figure to be represented
* @return the geometry representing the battleship as a box * @return the geometry representing the figure
*/ */
private Spatial createBox(Figure figure) { private Spatial createBox(Figure figure) {
final Box box = new Box(0.5f * (figure.getMaxY() - figure.getMinY()) + 0.3f, final Box box = new Box(0.5f * (figure.getMaxY() - figure.getMinY()) + 0.3f,

View File

@ -31,19 +31,47 @@ import pp.monopoly.notification.Sound;
import java.util.Set; import java.util.Set;
/**
* Represents the lobby menu in the Monopoly application.
* <p>
* Provides functionality for player configuration, including input for starting capital,
* player name, and figure selection, as well as options to ready up or exit the game.
* </p>
*/
public class LobbyMenu extends Dialog { public class LobbyMenu extends Dialog {
/** Reference to the Monopoly application instance. */
private final MonopolyApp app; private final MonopolyApp app;
/** Main container for the lobby menu UI. */
private final Container menuContainer; private final Container menuContainer;
/** Background geometry for the menu. */
private Geometry background; private Geometry background;
/** Colored circle displayed between input fields and dropdown menus. */
private Geometry circle; private Geometry circle;
/** Container for the lower-left section of the menu. */
private Container lowerLeftMenu; private Container lowerLeftMenu;
/** Container for the lower-right section of the menu. */
private Container lowerRightMenu; private Container lowerRightMenu;
/** Text field for entering the player's name. */
private TextField playerInputField; private TextField playerInputField;
/** Text field for entering the starting capital. */
private TextField startingCapital = new TextField("15000"); private TextField startingCapital = new TextField("15000");
/** Selected player figure. */
private String figure; private String figure;
/**
* Constructs the lobby menu for player configuration.
*
* @param app the Monopoly application instance
*/
public LobbyMenu(MonopolyApp app) { public LobbyMenu(MonopolyApp app) {
super(app.getDialogManager()); super(app.getDialogManager());
this.app = app; this.app = app;
@ -193,7 +221,7 @@ public class LobbyMenu extends Dialog {
/** /**
* Lädt das Hintergrundbild und fügt es als geometrische Ebene hinzu. * Adds a background image to the lobby menu.
*/ */
private void addBackgroundImage() { private void addBackgroundImage() {
Texture backgroundImage = app.getAssetManager().loadTexture("Pictures/lobby.png"); Texture backgroundImage = app.getAssetManager().loadTexture("Pictures/lobby.png");
@ -207,6 +235,11 @@ public class LobbyMenu extends Dialog {
app.getGuiNode().attachChild(background); app.getGuiNode().attachChild(background);
} }
/**
* Creates a circle graphic element for the menu.
*
* @return the created circle geometry
*/
private Geometry createCircle() { private Geometry createCircle() {
Sphere sphere = new Sphere(90,90,60.0f); Sphere sphere = new Sphere(90,90,60.0f);
@ -220,6 +253,11 @@ public class LobbyMenu extends Dialog {
return circleGeometry; return circleGeometry;
} }
/**
* Maps the player's ID to a corresponding color.
*
* @return the color associated with the player's ID
*/
private ColorRGBA idToColor() { private ColorRGBA idToColor() {
switch (app.getId()+1) { switch (app.getId()+1) {
case 1: return PlayerColor.CYAN.getColor(); case 1: return PlayerColor.CYAN.getColor();
@ -235,19 +273,25 @@ public class LobbyMenu extends Dialog {
} }
/** /**
* Schaltet den "Bereit"-Status um. * Toggles the player's ready state and sends the configuration to the server.
*/ */
private void toggleReady() { private void toggleReady() {
app.getGameLogic().send(new PlayerReady(true, playerInputField.getText(), figure, Integer.parseInt(startingCapital.getText()))); app.getGameLogic().send(new PlayerReady(true, playerInputField.getText(), figure, Integer.parseInt(startingCapital.getText())));
} }
/**
* Opens the settings menu when the escape key is pressed.
*/
@Override @Override
public void escape() { public void escape() {
new SettingsMenu(app).open(); new SettingsMenu(app).open();
} }
/** /**
* Adds a custom action listener to the Selector. * Adds a custom action listener to a dropdown selector.
*
* @param selector the selector to add the listener to
* @param listener the action to perform when a selection changes
*/ */
private void addSelectionActionListener(Selector<String> selector, SelectionActionListener<String> listener) { private void addSelectionActionListener(Selector<String> selector, SelectionActionListener<String> listener) {
VersionedReference<Set<Integer>> selectionRef = selector.getSelectionModel().createReference(); VersionedReference<Set<Integer>> selectionRef = selector.getSelectionModel().createReference();
@ -282,7 +326,9 @@ public class LobbyMenu extends Dialog {
} }
/** /**
* Callback for when the dropdown selection changes. * Updates the selected figure based on the dropdown menu selection.
*
* @param selected the selected figure
*/ */
private void onDropdownSelectionChanged(String selected) { private void onDropdownSelectionChanged(String selected) {
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
@ -311,10 +357,17 @@ public class LobbyMenu extends Dialog {
} }
/** /**
* Functional interface for a selection action listener. * Functional interface for handling selection changes in dropdown menus.
*
* @param <T> the type of the selection
*/ */
@FunctionalInterface @FunctionalInterface
private interface SelectionActionListener<T> { private interface SelectionActionListener<T> {
/**
* Triggered when the selection changes.
*
* @param selection the new selection
*/
void onSelectionChanged(T selection); void onSelectionChanged(T selection);
} }
} }

View File

@ -23,12 +23,25 @@ import pp.monopoly.notification.Sound;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
/**
* Represents the trade menu dialog in the Monopoly application.
* <p>
* Facilitates trade interactions between players, including selection of properties,
* currency, and special cards for offers and requests.
* </p>
*/
public class TradeMenu extends Dialog { public class TradeMenu extends Dialog {
/** The Monopoly application instance. */
private final MonopolyApp app; private final MonopolyApp app;
/** The trade handler managing trade logic. */
private final TradeHandler tradeHandler; private final TradeHandler tradeHandler;
/** Main container for the trade menu UI. */
private final Container mainContainer; private final Container mainContainer;
/** Background geometry for the menu. */
private Geometry background; private Geometry background;
private Selector<String> leftBuildingSelector, leftSpecialCardSelector; private Selector<String> leftBuildingSelector, leftSpecialCardSelector;
private Selector<String> rightBuildingSelector, rightSpecialCardSelector; private Selector<String> rightBuildingSelector, rightSpecialCardSelector;
@ -44,6 +57,12 @@ public class TradeMenu extends Dialog {
private static final ColorRGBA TRANSLUCENT_WHITE = new ColorRGBA(1, 1, 1, 0.5f); private static final ColorRGBA TRANSLUCENT_WHITE = new ColorRGBA(1, 1, 1, 0.5f);
/**
* Constructs the trade menu dialog.
*
* @param app the Monopoly application instance
* @param tradeHandler the handler managing trade interactions
*/
public TradeMenu(MonopolyApp app, TradeHandler tradeHandler) { public TradeMenu(MonopolyApp app, TradeHandler tradeHandler) {
super(app.getDialogManager()); super(app.getDialogManager());
this.app = app; this.app = app;
@ -57,7 +76,7 @@ public class TradeMenu extends Dialog {
initializeReferences(); initializeReferences();
} }
/** Creates the main container for the trade menu UI. */
private Container createMainContainer() { private Container createMainContainer() {
Container container = new Container(new SpringGridLayout(Axis.Y, Axis.X)); Container container = new Container(new SpringGridLayout(Axis.Y, Axis.X));
container.setPreferredSize(new Vector3f(1200, 800, 0)); container.setPreferredSize(new Vector3f(1200, 800, 0));
@ -67,7 +86,7 @@ public class TradeMenu extends Dialog {
container.addChild(createMainContent()); container.addChild(createMainContent());
return container; return container;
} }
/** Creates the header label for the trade menu. */
private Label createHeader() { private Label createHeader() {
Label header = new Label("Handelsmenü", new ElementId("label-Bold")); Label header = new Label("Handelsmenü", new ElementId("label-Bold"));
header.setFontSize(50); header.setFontSize(50);
@ -75,7 +94,7 @@ public class TradeMenu extends Dialog {
header.setBackground(new QuadBackgroundComponent(TRANSLUCENT_WHITE)); header.setBackground(new QuadBackgroundComponent(TRANSLUCENT_WHITE));
return header; return header;
} }
/** Creates the main content section of the trade menu. */
private Container createMainContent() { private Container createMainContent() {
Container mainContent = new Container(new SpringGridLayout(Axis.X, Axis.Y)); Container mainContent = new Container(new SpringGridLayout(Axis.X, Axis.Y));
mainContent.setPreferredSize(new Vector3f(1200, 700, 0)); mainContent.setPreferredSize(new Vector3f(1200, 700, 0));
@ -87,6 +106,7 @@ public class TradeMenu extends Dialog {
return mainContent; return mainContent;
} }
/** Sets the trade data based on the current selections. */
private void setTrades() { private void setTrades() {
String leftCurreny = leftCurrencyInput.getText().equals("")? "0" : leftCurrencyInput.getText(); String leftCurreny = leftCurrencyInput.getText().equals("")? "0" : leftCurrencyInput.getText();
String rightCurreny = rightCurrencyInput.getText().equals("")? "0" : rightCurrencyInput.getText(); String rightCurreny = rightCurrencyInput.getText().equals("")? "0" : rightCurrencyInput.getText();
@ -109,6 +129,12 @@ public class TradeMenu extends Dialog {
tradeHandler.setRequestedProperties(requestedProperties); tradeHandler.setRequestedProperties(requestedProperties);
} }
/**
* Creates a trade column for either the sender or receiver.
*
* @param label the label text for the column
* @param isLeft true if the column is for the sender; false otherwise
*/
private Container createTradeColumn(String label, boolean isLeft) { private Container createTradeColumn(String label, boolean isLeft) {
Container column = new Container(new SpringGridLayout(Axis.Y, Axis.X)); Container column = new Container(new SpringGridLayout(Axis.Y, Axis.X));
column.setBackground(new QuadBackgroundComponent(ColorRGBA.White)); column.setBackground(new QuadBackgroundComponent(ColorRGBA.White));
@ -134,6 +160,12 @@ public class TradeMenu extends Dialog {
return column; return column;
} }
/**
* Creates a property selector for buildings.
*
* @param isLeft true if the selector is for the sender; false otherwise
* @return the created property selector
*/
private Selector<String> createPropertySelector(boolean isLeft) { private Selector<String> createPropertySelector(boolean isLeft) {
VersionedList<String> properties = new VersionedList<>(); VersionedList<String> properties = new VersionedList<>();
for (PropertyField field : getPropertyFields(isLeft)) { for (PropertyField field : getPropertyFields(isLeft)) {
@ -144,6 +176,12 @@ public class TradeMenu extends Dialog {
return selector; return selector;
} }
/**
* Creates a selector for special cards.
*
* @param isLeft true if the selector is for the sender; false otherwise
* @return the created special card selector
*/
private Selector<String> createSpecialCardSelector(boolean isLeft) { private Selector<String> createSpecialCardSelector(boolean isLeft) {
VersionedList<String> numbers = new VersionedList<>(); VersionedList<String> numbers = new VersionedList<>();
for (int i = 0; i <= app.getGameLogic().getPlayerHandler().getPlayerById(isLeft ? tradeHandler.getReceiver().getId() : tradeHandler.getSender().getId()).getNumJailCard(); i++) { for (int i = 0; i <= app.getGameLogic().getPlayerHandler().getPlayerById(isLeft ? tradeHandler.getReceiver().getId() : tradeHandler.getSender().getId()).getNumJailCard(); i++) {
@ -154,6 +192,12 @@ public class TradeMenu extends Dialog {
return selector; return selector;
} }
/**
* Retrieves the property fields owned by the respective player.
*
* @param isLeft true if retrieving fields for the sender; false otherwise
* @return an iterable of property fields
*/
private Iterable<PropertyField> getPropertyFields(boolean isLeft) { private Iterable<PropertyField> getPropertyFields(boolean isLeft) {
return app.getGameLogic() return app.getGameLogic()
.getBoardManager() .getBoardManager()
@ -162,13 +206,13 @@ public class TradeMenu extends Dialog {
.getPlayerById(isLeft ? tradeHandler.getSender().getId() : tradeHandler.getReceiver().getId()) .getPlayerById(isLeft ? tradeHandler.getSender().getId() : tradeHandler.getReceiver().getId())
.getProperties()); .getProperties());
} }
/** Creates a text field for currency input. */
private TextField createCurrencyInput() { private TextField createCurrencyInput() {
TextField currencyInput = new TextField("0"); TextField currencyInput = new TextField("0");
styleTextField(currencyInput); styleTextField(currencyInput);
return currencyInput; return currencyInput;
} }
/** Creates the middle section containing buttons and summary fields. */
private Container createMiddleSection() { private Container createMiddleSection() {
Container middleSection = new Container(new SpringGridLayout(Axis.Y, Axis.X)); Container middleSection = new Container(new SpringGridLayout(Axis.Y, Axis.X));
middleSection.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8f, 0.8f, 0.8f, 1.0f))); middleSection.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8f, 0.8f, 0.8f, 1.0f)));
@ -207,17 +251,28 @@ public class TradeMenu extends Dialog {
return middleSection; return middleSection;
} }
/** Styles the given selector with insets and background color. */
private void styleSelector(Selector<String> selector) { private void styleSelector(Selector<String> selector) {
selector.setInsets(new Insets3f(5, 10, 5, 10)); selector.setInsets(new Insets3f(5, 10, 5, 10));
selector.setBackground(new QuadBackgroundComponent(ColorRGBA.Black)); selector.setBackground(new QuadBackgroundComponent(ColorRGBA.Black));
} }
/** Styles the given text field with insets and background color. */
private void styleTextField(TextField textField) { private void styleTextField(TextField textField) {
textField.setInsets(new Insets3f(5, 10, 5, 10)); textField.setInsets(new Insets3f(5, 10, 5, 10));
textField.setBackground(new QuadBackgroundComponent(ColorRGBA.Black)); textField.setBackground(new QuadBackgroundComponent(ColorRGBA.Black));
textField.setPreferredSize(new Vector3f(300, 30, 0)); textField.setPreferredSize(new Vector3f(300, 30, 0));
} }
/**
* Assigns selectors and input fields to either the left or right column.
*
* @param buildingSelector the building selector
* @param specialCardSelector the special card selector
* @param currencyInput the currency input field
* @param isLeft true if assigning to the left column; false otherwise
*/
private void assignSelectors(Selector<String> buildingSelector, Selector<String> specialCardSelector, TextField currencyInput, boolean isLeft) { private void assignSelectors(Selector<String> buildingSelector, Selector<String> specialCardSelector, TextField currencyInput, boolean isLeft) {
if (isLeft) { if (isLeft) {
leftBuildingSelector = buildingSelector; leftBuildingSelector = buildingSelector;
@ -229,7 +284,7 @@ public class TradeMenu extends Dialog {
rightCurrencyInput = currencyInput; rightCurrencyInput = currencyInput;
} }
} }
/** Positions the main container at the center of the screen. */
private void positionMainContainer() { private void positionMainContainer() {
mainContainer.setLocalTranslation( mainContainer.setLocalTranslation(
(app.getCamera().getWidth() - mainContainer.getPreferredSize().x) / 2, (app.getCamera().getWidth() - mainContainer.getPreferredSize().x) / 2,
@ -237,7 +292,7 @@ public class TradeMenu extends Dialog {
7 7
); );
} }
/** Adds a background image to the trade menu. */
private void addBackgroundImage() { private void addBackgroundImage() {
Texture backgroundImage = app.getAssetManager().loadTexture("Pictures/unibw-Bib2.png"); Texture backgroundImage = app.getAssetManager().loadTexture("Pictures/unibw-Bib2.png");
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight()); Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
@ -248,7 +303,7 @@ public class TradeMenu extends Dialog {
background.setLocalTranslation(0, 0, 6); background.setLocalTranslation(0, 0, 6);
app.getGuiNode().attachChild(background); app.getGuiNode().attachChild(background);
} }
/** Initializes references for tracking UI changes. */
private void initializeReferences() { private void initializeReferences() {
leftBuildingRef = leftBuildingSelector.getSelectionModel().createReference(); leftBuildingRef = leftBuildingSelector.getSelectionModel().createReference();
leftCardRef = leftSpecialCardSelector.getSelectionModel().createReference(); leftCardRef = leftSpecialCardSelector.getSelectionModel().createReference();
@ -259,6 +314,11 @@ public class TradeMenu extends Dialog {
rightCurrencyRef = rightCurrencyInput.getDocumentModel().createReference(); rightCurrencyRef = rightCurrencyInput.getDocumentModel().createReference();
} }
/**
* Updates the trade menu state, including selected properties and values.
*
* @param delta the time elapsed since the last update
*/
@Override @Override
public void update(float delta) { public void update(float delta) {
if (leftBuildingRef.update() || leftCardRef.update() || leftCurrencyRef.update()) { if (leftBuildingRef.update() || leftCardRef.update() || leftCurrencyRef.update()) {
@ -270,6 +330,15 @@ public class TradeMenu extends Dialog {
} }
} }
/**
* Updates the displayed selections for properties, currency, and cards.
*
* @param target the target text field to update
* @param building the building selector
* @param currency the currency input field
* @param card the special card selector
* @param isLeft true if updating the left column; false otherwise
*/
private void updateSelections(TextField target, Selector<String> building, TextField currency, Selector<String> card, boolean isLeft) { private void updateSelections(TextField target, Selector<String> building, TextField currency, Selector<String> card, boolean isLeft) {
StringBuilder buildingText = new StringBuilder(); StringBuilder buildingText = new StringBuilder();
if (isLeft) { if (isLeft) {
@ -297,11 +366,13 @@ public class TradeMenu extends Dialog {
target.setText(String.join(" | ", buildingText, currencyText, cardText)); target.setText(String.join(" | ", buildingText, currencyText, cardText));
} }
/** Opens the settings menu when the escape key is pressed. */
@Override @Override
public void escape() { public void escape() {
new SettingsMenu(app).open(); new SettingsMenu(app).open();
} }
/** Closes the trade menu and detaches UI elements. */
@Override @Override
public void close() { public void close() {
app.getGuiNode().detachChild(mainContainer); app.getGuiNode().detachChild(mainContainer);