Resolve merge conflicts

This commit is contained in:
Luca Puderbach 2024-11-18 04:42:30 +01:00
parent 5189c74058
commit af4b4243ea
10 changed files with 139 additions and 241 deletions

View File

@ -55,55 +55,6 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
setSettings(makeSettings()); setSettings(makeSettings());
} }
/**
* Creates and configures application settings from the client configuration.
*
* @return A configured {@link AppSettings} object.
*/
private AppSettings makeSettings() {
final AppSettings settings = new AppSettings(true);
settings.setTitle(lookup("monopoly.name"));
settings.setResolution(config.getResolutionWidth(), config.getResolutionHeight());
settings.setFullscreen(config.fullScreen());
settings.setUseRetinaFrameBuffer(config.useRetinaFrameBuffer());
settings.setGammaCorrection(config.useGammaCorrection());
return settings;
}
/**
* Factory method for creating a server connection based on the current
* client configuration.
*
* @return A {@link ServerConnection} instance, which could be a real or mock server.
*/
private ServerConnection makeServerConnection() {
return new NetworkSupport(this);
}
/**
* Returns the dialog manager responsible for managing in-game dialogs.
*
* @return The {@link DialogManager} instance.
*/
public DialogManager getDialogManager() {
return dialogManager;
}
/**
* Returns the game logic handler for the client.
*
* @return The {@link ClientGameLogic} instance.
*/
@Override
public ClientGameLogic getGameLogic() {
return logic;
}
/**
* Returns the current configuration settings for the Monopoly client.
*
* @return The {@link MonopolyClientConfig} instance.
*/
@Override @Override
public MonopolyAppConfig getConfig() { public MonopolyAppConfig getConfig() {
return config; return config;
@ -243,4 +194,4 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
} }
} }

View File

@ -1,10 +1,3 @@
////////////////////////////////////////
// Programming project code
// UniBw M, 2022, 2023, 2024
// www.unibw.de/inf2
// (c) Mark Minas (mark.minas@unibw.de)
////////////////////////////////////////
package pp.monopoly.client; package pp.monopoly.client;
import com.jme3.math.ColorRGBA; import com.jme3.math.ColorRGBA;
@ -194,4 +187,4 @@ public class MonopolyAppConfig extends MonopolyClientConfig {
public ColorRGBA getTopColor() { public ColorRGBA getTopColor() {
return topColor; return topColor;
} }
} }

View File

@ -81,4 +81,4 @@ public abstract class MonopolyAppState extends AbstractAppState {
* Called when the state is disabled. Override to define specific behavior. * Called when the state is disabled. Override to define specific behavior.
*/ */
protected abstract void disableState(); protected abstract void disableState();
} }

View File

@ -142,4 +142,5 @@ class NetworkDialog extends SimpleDialog {
network.getApp().errorDialog("Verbindung zum Server fehlgeschlagen."); network.getApp().errorDialog("Verbindung zum Server fehlgeschlagen.");
network.getApp().setInfoText(e.getLocalizedMessage()); network.getApp().setInfoText(e.getLocalizedMessage());
} }
}
}

View File

@ -141,4 +141,4 @@ class NetworkSupport implements MessageListener<Client>, ClientStateListener, Se
client.send(message); client.send(message);
} }
} }
} }

View File

@ -1,117 +1,123 @@
package pp.monopoly.client; package pp.monopoly.client;
import com.jme3.asset.TextureKey;
import com.jme3.material.Material; import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f; import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry; import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Quad; import com.jme3.scene.shape.Quad;
import com.jme3.texture.Texture; import com.jme3.texture.Texture;
import com.simsilica.lemur.Axis;
import com.simsilica.lemur.Button; import com.simsilica.lemur.Button;
import com.simsilica.lemur.Insets3f; import com.simsilica.lemur.Container;
import com.simsilica.lemur.Label; import com.simsilica.lemur.HAlignment;
import com.simsilica.lemur.Panel;
import com.simsilica.lemur.style.ElementId;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.jme3.math.ColorRGBA; import com.simsilica.lemur.component.SpringGridLayout;
import pp.dialog.Dialog; import pp.dialog.Dialog;
import pp.monopoly.client.gui.CreateGameMenu;
import pp.monopoly.client.gui.SettingsMenu;
/**
* Constructs the startup menu dialog for the Monopoly application.
import pp.monopoly.client.gui.GameMenu; import pp.monopoly.client.gui.GameMenu;
import pp.dialog.DialogManager; */
import java.util.prefs.Preferences;
import static pp.monopoly.Resources.lookup;
import static pp.util.PreferencesUtils.getPreferences;
public class StartMenu extends Dialog { public class StartMenu extends Dialog {
private static final Preferences PREFERENCES = getPreferences(StartMenu.class);
private final MonopolyApp app; private final MonopolyApp app;
// Buttons for the menu
private final Button playButton = new Button(lookup("button.play"));
private final Button quitButton = new Button(lookup("menu.quit"));
private final Button settingsButton = new Button("Einstellungen", new ElementId("menu-button"));
/** /**
* Constructs the StartMenu dialog for the Monopoly application. * Constructs the Startup Menu dialog for the Monopoly application.
* *
* @param app the MonopolyApp instance * @param app the MonopolyApp instance
*/ */
public StartMenu(MonopolyApp app) { public StartMenu(MonopolyApp app) {
super(app.getDialogManager()); super(app.getDialogManager());
this.app = app; this.app = app;
}
// Load and display the background image /**
TextureKey backgroundKey = new TextureKey("unibw-bib", false); * Creates and displays the Start Menu with buttons for starting the game,
Texture backgroundTexture = app.getAssetManager().loadTexture(backgroundKey); * opening settings, and quitting the application.
*/
public static void createStartMenu(MonopolyApp app) {
int screenWidth = app.getContext().getSettings().getWidth();
int screenHeight = app.getContext().getSettings().getHeight();
// Set up the background image
Texture backgroundImage = app.getAssetManager().loadTexture("Pictures/unibw-Bib2.png");
Quad quad = new Quad(screenWidth, screenHeight);
Geometry background = new Geometry("Background", quad);
Material backgroundMaterial = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); Material backgroundMaterial = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
backgroundMaterial.setTexture("ColorMap", backgroundTexture); backgroundMaterial.setTexture("ColorMap", backgroundImage);
// Create a large Quad for the background
Quad backgroundQuad = new Quad(16, 9); // Adjust size as necessary to fill the screen
Geometry background = new Geometry("Background", backgroundQuad);
background.setMaterial(backgroundMaterial); background.setMaterial(backgroundMaterial);
background.setLocalTranslation(new Vector3f(-8, -4.5f, -1)); // Position it behind the UI components background.setLocalTranslation(0, 0, -1); // Ensure it is behind other GUI elements
// Attach the background as the first element
app.getGuiNode().attachChild(background); app.getGuiNode().attachChild(background);
// Load and display the Monopoly logo // Center container for title and play button
TextureKey monopolyLogoKey = new TextureKey("log-Monopoly", false); Container centerMenu = new Container(new SpringGridLayout(Axis.Y, Axis.X));
Texture monopolyLogoTexture = app.getAssetManager().loadTexture(monopolyLogoKey);
Material monopolyLogoMaterial = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
monopolyLogoMaterial.setTexture("ColorMap", monopolyLogoTexture);
Quad monopolyQuad = new Quad(5, 1.5f); // Adjust dimensions as necessary Button startButton = new Button("Spielen");
Geometry monopolyLogo = new Geometry("MonopolyLogo", monopolyQuad); startButton.setPreferredSize(new Vector3f(190, 60, 0)); // Increase button size (width, height)
monopolyLogo.setMaterial(monopolyLogoMaterial); startButton.setFontSize(40); // Set the font size for the button text
monopolyLogo.setLocalTranslation(new Vector3f(0, 5, 0)); // Position Monopoly logo at the top startButton.setTextHAlignment(HAlignment.Center); // Center the text horizontally
Panel monopolyLogoPanel = new Panel(); // Set a custom border and background color
addChild(monopolyLogoPanel); ColorRGBA borderColor = ColorRGBA.Orange; // Example: White border
ColorRGBA backgroundColor = ColorRGBA.LightGray; // Example: light gray background
QuadBackgroundComponent backgroundColorSp = new QuadBackgroundComponent(backgroundColor);
backgroundColorSp.setMargin(2, 2); // Optional: Adjust margin for the border
backgroundColorSp.setColor(borderColor); // Set border color
startButton.setBackground(backgroundColorSp);
// Load and display the university logo startButton.addClickCommands(source -> startGame(app));
TextureKey universityLogoKey = new TextureKey("unibw-logo.png", false); centerMenu.addChild(startButton);
Texture universityLogoTexture = app.getAssetManager().loadTexture(universityLogoKey);
Material universityLogoMaterial = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
universityLogoMaterial.setTexture("ColorMap", universityLogoTexture);
Quad universityQuad = new Quad(4, 1); // Adjust dimensions to fit below Monopoly logo // Position the center container in the middle of the screen
Geometry universityLogo = new Geometry("UniversityLogo", universityQuad); centerMenu.setLocalTranslation(new Vector3f(screenWidth / 2f - centerMenu.getPreferredSize().x / 2f,
universityLogo.setMaterial(universityLogoMaterial); screenHeight / 2f - 280 + centerMenu.getPreferredSize().y / 2f,
universityLogo.setLocalTranslation(new Vector3f(0, 3, 0)); // Position below the Monopoly logo 0));
app.getGuiNode().attachChild(centerMenu);
Panel universityLogoPanel = new Panel(); // Lower-left container for "Spiel beenden" button
addChild(universityLogoPanel); Container lowerLeftMenu = new Container();
lowerLeftMenu.setLocalTranslation(new Vector3f(100, 90, 0));
Button quitButton = new Button("Spiel beenden");
quitButton.setPreferredSize(new Vector3f(130, 40, 0)); // Increase button size slightly (width, height)
quitButton.setFontSize(20);
quitButton.addClickCommands(source -> quitGame());
lowerLeftMenu.addChild(quitButton);
app.getGuiNode().attachChild(lowerLeftMenu);
// Lower-right container for "Einstellungen" button
Container lowerRightMenu = new Container();
// Button actions lowerRightMenu.setLocalTranslation(new Vector3f(screenWidth - 200, 90, 0));
playButton.addClickCommands(source -> startGame()); Button settingsButton = new Button("Einstellungen");
quitButton.addClickCommands(source -> app.closeApp()); settingsButton.setPreferredSize(new Vector3f(130, 40, 0)); // Increase button size slightly (width, height)
settingsButton.addClickCommands(source -> openSettings()); settingsButton.setFontSize(20); // Increase the font size for the text
settingsButton.addClickCommands(source -> openSettings(app));
addChild(monopolyLogoPanel); lowerRightMenu.addChild(settingsButton);
addChild(universityLogoPanel); app.getGuiNode().attachChild(lowerRightMenu);
addChild(playButton);
addChild(quitButton);
addChild(settingsButton);
} }
private void startGame() { /**
System.out.println("Starting game..."); * Starts the game by transitioning to the CreateGameMenu.
*/
private static void startGame(MonopolyApp app) {
app.getGuiNode().detachAllChildren();
new CreateGameMenu(app);
} }
private void openSettings() { /**
app.getDialogManager().close(this); * Opens the settings menu.
app.getDialogManager().open(new GameMenu(app)); */
private static void openSettings(MonopolyApp app) {
app.getGuiNode().detachAllChildren();
new SettingsMenu(app);
} }
@Override /**
public void update() { * Quits the game application.
*/
private static void quitGame() {
System.exit(0);
} }
}
@Override
public void escape() {
close();
}
}

View File

@ -126,4 +126,4 @@ public class CreateGameMenu {
} }
} }

View File

@ -5,6 +5,7 @@ import com.jme3.math.ColorRGBA;
import com.simsilica.lemur.Button; import com.simsilica.lemur.Button;
import com.simsilica.lemur.Label; import com.simsilica.lemur.Label;
import com.simsilica.lemur.style.ElementId; import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog; import pp.dialog.Dialog;
import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.MonopolyApp;

View File

@ -1,10 +1,10 @@
package pp.monopoly.client.gui; package pp.monopoly.client.gui;
import com.jme3.material.Material;
import com.jme3.material.RenderState.BlendMode;
import com.jme3.math.ColorRGBA; import com.jme3.math.ColorRGBA;
import com.jme3.scene.Geometry; import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Quad; import com.jme3.scene.shape.Quad;
import com.jme3.texture.Texture;
import com.simsilica.lemur.Button; import com.simsilica.lemur.Button;
import com.simsilica.lemur.Checkbox; import com.simsilica.lemur.Checkbox;
import com.simsilica.lemur.Container; import com.simsilica.lemur.Container;
@ -16,122 +16,80 @@ import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog; import pp.dialog.Dialog;
import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.MonopolyApp;
/**
* SettingsMenu ist ein Overlay-Menü, das durch ESC aufgerufen werden kann.
*/
public class SettingsMenu extends Dialog { public class SettingsMenu extends Dialog {
private final MonopolyApp app; private final MonopolyApp app;
private final Geometry overlayBackground;
private final Container settingsContainer; private final Container settingsContainer;
private Geometry blockLayer;
private final Node savedGuiNodeContent = new Node("SavedGuiNodeContent");
public SettingsMenu(MonopolyApp app) { public SettingsMenu(MonopolyApp app) {
super(app.getDialogManager()); super(app.getDialogManager());
this.app = app; this.app = app;
// Blockierungsebene hinzufügen // Halbtransparentes Overlay hinzufügen
addBlockLayer(); overlayBackground = createOverlayBackground();
app.getGuiNode().attachChild(overlayBackground);
// Hintergrundbild
addBackgroundImage();
// Hauptcontainer für das Menü
settingsContainer = new Container(); settingsContainer = new Container();
settingsContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.1f, 0.1f, 0.1f, 0.9f)));
// Hintergrundfarbe für das Container-Element setzen, um es undurchsichtig zu machen // Titel
settingsContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.1f, 0.1f, 0.1f, 0.8f))); // Teiltransparent, falls gewünscht
// Titel "Einstellungen"
Label settingsTitle = settingsContainer.addChild(new Label("Einstellungen", new ElementId("settings-title"))); Label settingsTitle = settingsContainer.addChild(new Label("Einstellungen", new ElementId("settings-title")));
settingsTitle.setFontSize(48); settingsTitle.setFontSize(48);
settingsTitle.setColor(ColorRGBA.White);
// Effekt Sound mit Slider und Checkbox // Effekt-Sound: Slider und Checkbox
Container effectSoundContainer = settingsContainer.addChild(new Container()); Container effectSoundContainer = settingsContainer.addChild(new Container());
Label effectSoundLabel = effectSoundContainer.addChild(new Label("Effekt Sound", new ElementId("label"))); effectSoundContainer.addChild(new Label("Effekt Sound", new ElementId("label")));
effectSoundLabel.setFontSize(24); effectSoundContainer.addChild(new Slider());
effectSoundLabel.setColor(ColorRGBA.White); effectSoundContainer.addChild(new Checkbox("Aktivieren")).setChecked(true);
Slider effectSoundSlider = effectSoundContainer.addChild(new Slider()); // Hintergrundmusik: Slider und Checkbox
effectSoundSlider.setPreferredSize(new com.jme3.math.Vector3f(300, 30, 0));
Checkbox effectSoundCheckbox = effectSoundContainer.addChild(new Checkbox(""));
effectSoundCheckbox.setChecked(true);
// Hintergrund Musik mit Slider und Checkbox
Container backgroundMusicContainer = settingsContainer.addChild(new Container()); Container backgroundMusicContainer = settingsContainer.addChild(new Container());
Label backgroundMusicLabel = backgroundMusicContainer.addChild(new Label("Hintergrund Musik", new ElementId("label"))); backgroundMusicContainer.addChild(new Label("Hintergrund Musik", new ElementId("label")));
backgroundMusicLabel.setFontSize(24); backgroundMusicContainer.addChild(new Slider());
backgroundMusicLabel.setColor(ColorRGBA.White); backgroundMusicContainer.addChild(new Checkbox("Aktivieren")).setChecked(true);
Slider backgroundMusicSlider = backgroundMusicContainer.addChild(new Slider()); // Beenden-Button
backgroundMusicSlider.setPreferredSize(new com.jme3.math.Vector3f(300, 30, 0));
Checkbox backgroundMusicCheckbox = backgroundMusicContainer.addChild(new Checkbox(""));
backgroundMusicCheckbox.setChecked(true);
// Beenden Button
Button quitButton = settingsContainer.addChild(new Button("Beenden", new ElementId("menu-button"))); Button quitButton = settingsContainer.addChild(new Button("Beenden", new ElementId("menu-button")));
quitButton.setFontSize(32); quitButton.setFontSize(32);
quitButton.setColor(ColorRGBA.White);
quitButton.addClickCommands(source -> app.stop()); quitButton.addClickCommands(source -> app.stop());
// Zentrieren des Containers // Zentriere das Menü
settingsContainer.setLocalTranslation( settingsContainer.setLocalTranslation(
(app.getCamera().getWidth() - settingsContainer.getPreferredSize().x) / 2, (app.getCamera().getWidth() - settingsContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + settingsContainer.getPreferredSize().y) / 2, (app.getCamera().getHeight() + settingsContainer.getPreferredSize().y) / 2,
1 // Höhere Z-Ebene für den Vordergrund 1
); );
app.getGuiNode().attachChild(settingsContainer); app.getGuiNode().attachChild(settingsContainer);
} }
private void addBlockLayer() { /**
// Sichern des aktuellen GUI-Inhalts * Erstellt einen halbtransparenten Hintergrund für das Menü.
for (var child : app.getGuiNode().getChildren()) { *
savedGuiNodeContent.attachChild(child); * @return Geometrie des Overlays
} */
app.getGuiNode().detachAllChildren(); private Geometry createOverlayBackground() {
// Blockierungsebene erstellen und hinzufügen
blockLayer = new Geometry("BlockLayer", new Quad(app.getCamera().getWidth(), app.getCamera().getHeight()));
blockLayer.setMaterial(createTransparentMaterial());
blockLayer.setLocalTranslation(0, 0, 0); // Platzierung unterhalb des SettingsMenu
app.getGuiNode().attachChild(blockLayer);
}
private com.jme3.material.Material createTransparentMaterial() {
com.jme3.material.Material material = new com.jme3.material.Material(
app.getAssetManager(),
"Common/MatDefs/Misc/Unshaded.j3md"
);
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Halbtransparent
material.getAdditionalRenderState().setBlendMode(com.jme3.material.RenderState.BlendMode.Alpha);
return material;
}
private void addBackgroundImage() {
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());
Geometry background = new Geometry("Background", quad); Geometry overlay = new Geometry("Overlay", quad);
com.jme3.material.Material backgroundMaterial = new com.jme3.material.Material( Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
app.getAssetManager(), material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Halbtransparent
"Common/MatDefs/Misc/Unshaded.j3md" material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
); overlay.setMaterial(material);
backgroundMaterial.setTexture("ColorMap", backgroundImage); overlay.setLocalTranslation(0, 0, 0);
background.setMaterial(backgroundMaterial); return overlay;
background.setLocalTranslation(0, 0, -1); // Platzierung hinter dem SettingsMenu
app.getGuiNode().attachChild(background);
} }
/**
* Schließt das Menü und entfernt die GUI-Elemente.
*/
@Override @Override
public void close() { public void close() {
// Entfernt das SettingsMenu und die Blockierungsebene
app.getGuiNode().detachChild(settingsContainer); app.getGuiNode().detachChild(settingsContainer);
app.getGuiNode().detachChild(blockLayer); app.getGuiNode().detachChild(overlayBackground);
// Stellt die ursprüngliche GUI wieder her
for (var child : savedGuiNodeContent.getChildren()) {
app.getGuiNode().attachChild(child);
}
savedGuiNodeContent.detachAllChildren();
app.setSettingsMenuOpen(false); app.setSettingsMenuOpen(false);
} }
} }

View File

@ -7,6 +7,13 @@
package pp.monopoly.game.client; package pp.monopoly.game.client;
import java.io.File;
import java.io.IOException;
import java.lang.System.Logger;
import java.lang.System.Logger.Level;
import java.util.ArrayList;
import java.util.List;
import pp.monopoly.message.client.ClientMessage; import pp.monopoly.message.client.ClientMessage;
import pp.monopoly.message.server.BuyPropertyResponse; import pp.monopoly.message.server.BuyPropertyResponse;
import pp.monopoly.message.server.DiceResult; import pp.monopoly.message.server.DiceResult;
@ -21,25 +28,6 @@ import pp.monopoly.message.server.TradeReply;
import pp.monopoly.message.server.TradeRequest; import pp.monopoly.message.server.TradeRequest;
import pp.monopoly.message.server.UpdatePlayerAssets; import pp.monopoly.message.server.UpdatePlayerAssets;
import pp.monopoly.message.server.ViewAssetsResponse; import pp.monopoly.message.server.ViewAssetsResponse;
import pp.monopoly.model.IntPoint;
import pp.monopoly.model.Board;
import pp.monopoly.notification.ClientStateEvent;
import pp.monopoly.notification.GameEvent;
import pp.monopoly.notification.GameEventBroker;
import pp.monopoly.notification.GameEventListener;
import pp.monopoly.notification.InfoTextEvent;
import pp.monopoly.notification.Sound;
import pp.monopoly.notification.SoundEvent;
import java.io.File;
import java.io.IOException;
import java.lang.System.Logger;
import java.lang.System.Logger.Level;
import java.util.ArrayList;
import java.util.List;
import pp.monopoly.message.client.ClientMessage;
import pp.monopoly.message.server.ServerInterpreter;
import pp.monopoly.model.Board; import pp.monopoly.model.Board;
import pp.monopoly.model.IntPoint; import pp.monopoly.model.IntPoint;
import pp.monopoly.notification.ClientStateEvent; import pp.monopoly.notification.ClientStateEvent;