6 Commits

Author SHA1 Message Date
Johannes Schmelz
72cb7049ba remove demo cube 2024-11-25 04:19:13 +01:00
Johannes Schmelz
2e42f3afac added testing shortcuts 2024-11-25 04:09:48 +01:00
Yvonne Schmidt
8474c9f5bc fixed EventCard sizing 2024-11-25 03:56:07 +01:00
Johannes Schmelz
b7ed03f7e8 resolve merge conflicts 2024-11-25 03:55:06 +01:00
Johannes Schmelz
a44b6b5e4c Merge branch 'connect' into 'gui'
Client connect to server

See merge request progproj/gruppen-ht24/Gruppe-02!14
2024-11-25 02:46:03 +00:00
Johannes Schmelz
5268f75e17 Client connect to server 2024-11-25 02:46:03 +00:00
9 changed files with 107 additions and 150 deletions

View File

@@ -23,12 +23,19 @@ import com.simsilica.lemur.style.BaseStyles;
import pp.monopoly.game.client.MonopolyClient;
import pp.monopoly.client.gui.SettingsMenu;
import pp.monopoly.client.gui.StartMenu;
import pp.monopoly.client.gui.TestWorld;
import pp.monopoly.client.gui.popups.BuildingPropertyCard;
import pp.monopoly.client.gui.popups.BuyCard;
import pp.monopoly.client.gui.popups.EventCard;
import pp.monopoly.client.gui.popups.FoodFieldCard;
import pp.monopoly.client.gui.popups.GateFieldCard;
import pp.monopoly.game.client.ClientGameLogic;
import pp.monopoly.game.client.ServerConnection;
import pp.monopoly.notification.ClientStateEvent;
import pp.monopoly.notification.GameEventListener;
import pp.monopoly.notification.InfoTextEvent;
import pp.monopoly.notification.Sound;
import pp.dialog.Dialog;
import pp.dialog.DialogBuilder;
import pp.dialog.DialogManager;
import pp.graphics.Draw;
@@ -120,6 +127,16 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
*/
private final ActionListener escapeListener = (name, isPressed, tpf) -> escape(isPressed);
//TODO temp for testing
private EventCard eventCard;
private BuildingPropertyCard buildingProperty;
private FoodFieldCard foodField;
private GateFieldCard gateField;
private BuyCard buyCard;
private boolean isBuyCardPopupOpen = false;
private final ActionListener BListener = (name, isPressed, tpf) -> handleB(isPressed);
private final ActionListener TListener = (name, isPressed, tpf) -> handleT(isPressed);
static {
// Configure logging
LogManager manager = LogManager.getLogManager();
@@ -248,8 +265,44 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
inputManager.addMapping(ESC, new KeyTrigger(KeyInput.KEY_ESCAPE));
inputManager.addMapping(CLICK, new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
inputManager.addListener(escapeListener, ESC);
//TODO tmp for testing
inputManager.addMapping("B", new KeyTrigger(KeyInput.KEY_B));
inputManager.addListener(BListener, "B");
inputManager.addMapping("T", new KeyTrigger(KeyInput.KEY_T));
inputManager.addListener(TListener, "T");
}
//logik zum wechselnden erscheinen und verschwinden beim drücken von B //TODO süäter entfernen
private void handleB(boolean isPressed) {
if (isPressed) {
Dialog tmp = new BuyCard(this);
if (eventCard != null && isBuyCardPopupOpen) {
// Schließe das SettingsMenu
System.out.println("Schließe BuyCardPopup...");
eventCard.close();
eventCard = null;
tmp.open();
} else {
// Öffne das SettingsMenu
System.out.println("Öffne BuyCardPopup...");
eventCard = new EventCard(this);
eventCard.open();
dialogManager.close(tmp);
}
}
}
//logik zum wechselnden erscheinen und verschwinden beim drücken von B //TODO süäter entfernen
private void handleT(boolean isPressed) {
if (isPressed) {
TestWorld tmp = new TestWorld(this);
tmp.initializeScene();
}
}
/**
* Initializes and attaches the necessary application states for the game.
*/

View File

@@ -38,13 +38,6 @@ public class LobbyMenu extends Dialog {
private Geometry circle;
private Container lowerLeftMenu;
private Container lowerRightMenu;
private ColorRGBA playerColor= ColorRGBA.Gray;
private PlayerHandler playerHandler;
private TextField startingCapital;
private TextField playerInputField;
private Selector<String> figureDropdown;
private TextField playerInputField = new TextField("Spieler 1");
private TextField startingCapital = new TextField("15000");
@@ -54,20 +47,19 @@ public class LobbyMenu extends Dialog {
super(app.getDialogManager());
this.app = app;
app.getGuiNode().detachAllChildren(); // Entfernt das CreateGameMenu (inklusive Hintergrund)
addBackgroundImage();// Hintergrundbild laden und hinzufügen
// Hintergrundbild laden und hinzufügen
addBackgroundImage();
QuadBackgroundComponent translucentWhiteBackground =
new QuadBackgroundComponent(new ColorRGBA(1.0f, 1.0f, 1.0f, 0.5f));
menuContainer = new Container(new SpringGridLayout(Axis.Y, Axis.X));
menuContainer.setPreferredSize(new Vector3f(1000, 600, 0));
menuContainer.setPreferredSize(new Vector3f(1000, 600, 0)); // Fixed size of the container
menuContainer.setBackground(translucentWhiteBackground);
// Create a smaller horizontal container for the label, input field, and spacers
Container horizontalContainer = menuContainer.addChild(new Container(new SpringGridLayout(Axis.X, Axis.Y)));
horizontalContainer.setPreferredSize(new Vector3f(600, 40, 0));
horizontalContainer.setPreferredSize(new Vector3f(600, 40, 0)); // Adjust container size
horizontalContainer.setBackground(null);
Label title = horizontalContainer.addChild(new Label("Startkapital:", new ElementId("label-Bold")));
@@ -106,16 +98,15 @@ public class LobbyMenu extends Dialog {
playerInputField.setPreferredSize(new Vector3f(100, 20, 0));
playerInputField.setInsets(new Insets3f(5, 10, 5, 10));
playerInputField.setInsets(new Insets3f(5, 10, 5, 10)); // Add padding for the text inside the field
playerInputField.setBackground(new QuadBackgroundComponent(ColorRGBA.Black));
playerInputContainer.addChild(playerInputField);
// Spacer (Center Circle Area)
Label spacer = dropdownContainer.addChild(new Label(""));
spacer.setPreferredSize(new Vector3f(200, 200, 0));
spacer.setPreferredSize(new Vector3f(200, 200, 0)); // Adjust this to fit the center graphic
// Figur Dropdown
Container figureDropdownContainer = dropdownContainer.addChild(new Container(new SpringGridLayout(Axis.Y, Axis.X)));
figureDropdownContainer.setPreferredSize(new Vector3f(150, 80, 0));
figureDropdownContainer.addChild(new Label("Figur:"));
figureDropdownContainer.setBackground(null);
@@ -129,11 +120,7 @@ public class LobbyMenu extends Dialog {
Selector<String> figureDropdown = new Selector<>(figures, "glass");
figureDropdown.setBackground(new QuadBackgroundComponent(ColorRGBA.DarkGray));
figureDropdown.setPreferredSize(new Vector3f(150, 140, 0));
Vector3f dimens = figureDropdownContainer.getPreferredSize();
Vector3f dimens2 = figureDropdown.getPopupContainer().getPreferredSize();
dimens2.setX( dimens.getX() );
figureDropdown.getPopupContainer().setPreferredSize( dimens2 );
figureDropdown.setPreferredSize(new Vector3f(100, 20, 0));
figureDropdownContainer.addChild(figureDropdown);
addSelectionActionListener(figureDropdown, this::onDropdownSelectionChanged);
@@ -168,14 +155,13 @@ public class LobbyMenu extends Dialog {
app.getGameLogic().playSound(Sound.BUTTON);
}));
lowerRightMenu.addChild(readyButton);
//TODO aktivieren des Spielers in den ready Status und Sprung in den nächsten Menüzustand
// Position the container near the bottom-right corner
lowerRightMenu.setLocalTranslation(new Vector3f(app.getCamera().getWidth() - 320, 170, 3)); // X: 220px from the right, Y: 50px above the bottom
app.getGuiNode().attachChild(lowerRightMenu);
// Add a colored circle between the input field and the dropdown menu
circle = createCircle(); // 50 is the diameter, Red is the color
circle = createCircle( ColorRGBA.Red); // 50 is the diameter, Red is the color
circle.setLocalTranslation(new Vector3f(
(app.getCamera().getWidth()) / 2, // Center horizontally
(app.getCamera().getHeight() / 2) - 90, // Adjust Y position
@@ -192,59 +178,7 @@ public class LobbyMenu extends Dialog {
app.getGuiNode().attachChild(menuContainer);
}
/**
* Apply the starting capital only if the current player is the host.
*/
private void applyStartingCapital(int playerID) {
Player currentPlayer = playerHandler.getPlayerById(playerID);
// Check if the current player is the host
if (currentPlayer.equals(playerHandler.getHostPlayer())) {
try {
// Parse and validate starting capital
int startBalance = Integer.parseInt(startingCapital.getText().replaceAll("[^\\d]", ""));
if (startBalance < 0) throw new NumberFormatException("Starting capital must be positive.");
// Apply the starting balance to all players
playerHandler.setStartBalance(startBalance);
System.out.println("Starting balance set to: " + startBalance);
} catch (NumberFormatException e) {
System.err.println("Invalid starting capital: " + e.getMessage());
}
} else {
System.out.println("Only the host can set the starting balance.");
}
}
/**
* Apply the player name from the input field.
*/
private void applyPlayerName(int playerID) {
Player currentPlayer = playerHandler.getPlayerById(playerID);
String playerName = playerInputField.getText().trim();
if (!playerName.isEmpty()) {
currentPlayer.setName(playerName);
System.out.println("Player name set to: " + playerName);
} else {
System.err.println("Invalid player name: Name cannot be empty.");
}
}
/**
* Apply the selected figure to the player.
*/
private void applyFigure(int playerID) {
Player currentPlayer = playerHandler.getPlayerById(playerID);
String selectedFigure = figureDropdown.getSelectedItem();
if (selectedFigure != null && !selectedFigure.isEmpty()) {
currentPlayer.setFigure(new Figure(0, 0, 0, Rotation.RIGHT, "selectedFigure"));
System.out.println("Player figure set to: " + selectedFigure);
} else {
System.err.println("Invalid figure selection.");
}
}
/**
* Lädt das Hintergrundbild und fügt es als geometrische Ebene hinzu.
@@ -261,32 +195,21 @@ public class LobbyMenu extends Dialog {
app.getGuiNode().attachChild(background);
}
private Geometry createCircle() {
private Geometry createCircle(ColorRGBA color) {
Sphere sphere = new Sphere(90,90,60.0f);
Geometry circleGeometry = new Geometry("Circle", sphere);
// Create a material with a solid color
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
material.setColor("Color", playerColor); // Set the desired color
material.setColor("Color", color); // Set the desired color
circleGeometry.setMaterial(material);
return circleGeometry;
}
public void setPlayerColor(ColorRGBA newColor) {
this.playerColor = newColor;
// Update the circle's color
if (circle != null) {
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
material.setColor("Color", playerColor);
circle.setMaterial(material);
}
}
/**
* Assigns a color to the player based on their ID.
*
* @param playerID the player's ID
* Schaltet den "Bereit"-Status um.
*/
private void toggleReady() {
app.getGameLogic().send(new PlayerReady(true, playerInputField.getText(), figure, Integer.parseInt(startingCapital.getText())));

View File

@@ -21,7 +21,6 @@ public class TestWorld {
private final MonopolyApp app;
private CameraController cameraController; // Steuert die Kamera
private Geometry cube; // Spielfigur
/**
* Konstruktor für TestWorld.
@@ -41,7 +40,6 @@ public class TestWorld {
setSkyColor(); // Setze den Himmel auf hellblau
createBoard(); // Erstelle das Spielfeld
createCube(); // Füge den Würfel hinzu
// Erstelle den CameraController
cameraController = new CameraController(
@@ -53,7 +51,7 @@ public class TestWorld {
);
// Füge die Toolbar hinzu
new Toolbar(app, cube);
new Toolbar(app).open();
cameraController.setPosition(0);
}
@@ -93,22 +91,4 @@ public class TestWorld {
app.getRootNode().attachChild(geom);
}
/**
* Erstellt den Würfel (Spielfigur) in der Szene.
*/
private void createCube() {
Box box = new Box(0.05f, 0.05f, 0.05f); // Kleinere Größe für Spielfigur
cube = new Geometry("Cube", box);
// Setze das Material für den Würfel
Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
mat.setColor("Color", ColorRGBA.Blue); // Blau gefärbter Würfel
cube.setMaterial(mat);
// Setze den Startpunkt des Würfels
cube.setLocalTranslation(0.8999999f, 0.1f, -0.9f);
app.getRootNode().attachChild(cube);
}
}

View File

@@ -6,7 +6,6 @@ import java.util.Random;
import com.jme3.font.BitmapText;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.simsilica.lemur.*;
import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.component.SpringGridLayout;
@@ -24,7 +23,6 @@ public class Toolbar extends Dialog {
private final MonopolyApp app;
private final Container toolbarContainer;
private final Geometry cube; // Referenz auf den Würfel
private final BitmapText positionText; // Anzeige für die aktuelle Position
private final float boardLimit = 0.95f; // Grenzen des Bretts
private final float stepSize = 0.18f; // Schrittgröße pro Bewegung
@@ -38,10 +36,9 @@ public class Toolbar extends Dialog {
* @param app Die Hauptanwendung (MonopolyApp)
* @param cube Der Würfel, der bewegt werden soll
*/
public Toolbar(MonopolyApp app, Geometry cube) {
public Toolbar(MonopolyApp app) {
super(app.getDialogManager());
this.app = app;
this.cube = cube;
// Erstelle die Toolbar
toolbarContainer = new Container(new SpringGridLayout(Axis.X, Axis.Y), "toolbar");
@@ -180,20 +177,6 @@ public class Toolbar extends Dialog {
private void rollDice() {
int diceRoll = random.nextInt(6) + 1; // Zahl zwischen 1 und 6
System.out.println("Gewürfelt: " + diceRoll);
moveCube(diceRoll); // Bewege die Figur um die gewürfelte Zahl
}
/**
* Bewegt den Würfel basierend auf der aktuellen Position auf dem Brett.
*
* @param step Schrittweite (+1 für vorwärts, -1 für rückwärts oder andere Werte)
*/
private void moveCube(int step) {
currentPosition = (currentPosition + step + 4 * positionsPerSide) % (4 * positionsPerSide);
Vector3f newPosition = calculatePosition(currentPosition);
cube.setLocalTranslation(newPosition);
updatePositionDisplay(); // Aktualisiere die Positionsanzeige
System.out.println("Würfelposition: " + newPosition + " (Feld-ID: " + currentPosition + ")");
}
/**

View File

@@ -12,6 +12,7 @@ import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog;
import pp.monopoly.client.MonopolyApp;
import pp.monopoly.client.gui.SettingsMenu;
import pp.monopoly.model.fields.BuildingProperty;
/**
@@ -117,17 +118,18 @@ public class BuildingPropertyCard extends Dialog {
*/
@Override
public void close() {
System.out.println("Schließe SettingsMenu..."); // Debugging-Ausgabe
app.getGuiNode().detachChild(buildingPropertyContainer); // Entferne das Menü
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
app.setSettingsMenuOpen(false); // Menü als geschlossen markieren TODO passt diese Variable noch (zu finden unter den Temps in MonopolyApp
app.unblockInputs(); // Eingaben wieder aktivieren
System.out.println("SettingsMenu geschlossen."); // Debugging-Ausgabe
super.close();
}
public void setIndex(int index) {
this.index = index;
}
@Override
public void escape() {
new SettingsMenu(app).open();
}
}

View File

@@ -12,6 +12,8 @@ import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog;
import pp.monopoly.client.MonopolyApp;
import pp.monopoly.client.gui.SettingsMenu;
import pp.monopoly.model.fields.BoardManager;
import pp.monopoly.model.fields.BuildingProperty;
/**
@@ -30,7 +32,7 @@ public class BuyCard extends Dialog {
this.app = app;
//Generate the corresponfing field
BuildingProperty field = (BuildingProperty) app.getBoardManager().getFieldAtIndex(index);
BuildingProperty field = (BuildingProperty) new BoardManager().getFieldAtIndex(index);
// Halbtransparentes Overlay hinzufügen
overlayBackground = createOverlayBackground();
@@ -113,12 +115,14 @@ public class BuyCard extends Dialog {
*/
@Override
public void close() {
System.out.println("Schließe SettingsMenu..."); // Debugging-Ausgabe
app.getGuiNode().detachChild(buyCardContainer); // Entferne das Menü
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
app.setSettingsMenuOpen(false); // Menü als geschlossen markieren TODO passt diese Variable noch (zu finden unter den Temps in MonopolyApp
app.unblockInputs(); // Eingaben wieder aktivieren
System.out.println("SettingsMenu geschlossen."); // Debugging-Ausgabe
super.close();
}
@Override
public void escape() {
new SettingsMenu(app).open();
}
}

View File

@@ -3,6 +3,7 @@ package pp.monopoly.client.gui.popups;
import com.jme3.material.Material;
import com.jme3.material.RenderState.BlendMode;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Quad;
import com.simsilica.lemur.Button;
@@ -12,8 +13,9 @@ import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog;
import pp.monopoly.client.MonopolyApp;
import pp.monopoly.client.gui.SettingsMenu;
import pp.monopoly.model.card.Card; // TODO für den Import der Queue notwendig
import pp.monopoly.model.card.DeckHelper;
/**
* SettingsMenu ist ein Overlay-Menü, das durch ESC aufgerufen werden kann.
*/
@@ -29,7 +31,7 @@ public class EventCard extends Dialog {
this.app = app;
//Generate the corresponfing field
Card card = app.getDeckHelper().drawCard(); // TODO nimmt die Karten gerade unabhängig aus dem DeckHelper
Card card = new DeckHelper().drawCard(); // TODO nimmt die Karten gerade unabhängig aus dem DeckHelper
// Halbtransparentes Overlay hinzufügen
overlayBackground = createOverlayBackground();
@@ -43,6 +45,7 @@ public class EventCard extends Dialog {
// Hauptcontainer für die Gebäudekarte
eventCardContainer = new Container();
eventCardContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f)));
eventCardContainer.setPreferredSize(new Vector3f(550,400,10));
// Titel
// Die Namen werden dynamisch dem BoardManager entnommen
@@ -55,6 +58,7 @@ public class EventCard extends Dialog {
Container propertyValuesContainer = eventCardContainer.addChild(new Container());
propertyValuesContainer.addChild(new Label(card.getDescription(), new ElementId("label-Text")));
propertyValuesContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
propertyValuesContainer.setPreferredSize(new Vector3f(300,200,10));
// Beenden-Button
Button quitButton = eventCardContainer.addChild(new Button("Jawohl", new ElementId("button")));
@@ -107,12 +111,14 @@ public class EventCard extends Dialog {
*/
@Override
public void close() {
System.out.println("Schließe SettingsMenu..."); // Debugging-Ausgabe
app.getGuiNode().detachChild(eventCardContainer); // Entferne das Menü
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
app.setBuyCardPopupOpen(false); // Menü als geschlossen markieren TODO passt diese Variable noch (zu finden unter den Temps in MonopolyApp
app.unblockInputs(); // Eingaben wieder aktivieren
System.out.println("SettingsMenu geschlossen."); // Debugging-Ausgabe
super.close();
}
@Override
public void escape() {
new SettingsMenu(app).open();
}
}

View File

@@ -12,6 +12,7 @@ import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog;
import pp.monopoly.client.MonopolyApp;
import pp.monopoly.client.gui.SettingsMenu;
import pp.monopoly.model.fields.FoodField;
/**
@@ -120,17 +121,19 @@ public class FoodFieldCard extends Dialog {
*/
@Override
public void close() {
System.out.println("Schließe SettingsMenu..."); // Debugging-Ausgabe
app.getGuiNode().detachChild(foodFieldContainer); // Entferne das Menü
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
app.setSettingsMenuOpen(false); // Menü als geschlossen markieren TODO passt diese Variable noch (zu finden unter den Temps in MonopolyApp
app.unblockInputs(); // Eingaben wieder aktivieren
System.out.println("SettingsMenu geschlossen."); // Debugging-Ausgabe
super.close();
}
public void setIndex(int index) {
this.index = index;
}
@Override
public void escape() {
new SettingsMenu(app).open();
}
}

View File

@@ -11,6 +11,7 @@ import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog;
import pp.monopoly.client.MonopolyApp;
import pp.monopoly.client.gui.SettingsMenu;
import pp.monopoly.model.fields.GateField;
/**
@@ -114,16 +115,18 @@ public class GateFieldCard extends Dialog {
*/
@Override
public void close() {
System.out.println("Schließe SettingsMenu..."); // Debugging-Ausgabe
app.getGuiNode().detachChild(gateFieldContainer); // Entferne das Menü
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
app.setSettingsMenuOpen(false); // Menü als geschlossen markieren TODO passt diese Variable noch (zu finden unter den Temps in MonopolyApp
app.unblockInputs(); // Eingaben wieder aktivieren
System.out.println("SettingsMenu geschlossen."); // Debugging-Ausgabe
super.close();
}
public void setIndex(int index) {
this.index = index;
}
@Override
public void escape() {
new SettingsMenu(app).open();
}
}