mirror of
https://athene2.informatik.unibw-muenchen.de/progproj/gruppen-ht24/Gruppe-02.git
synced 2025-08-04 12:29:16 +02:00
Compare commits
10 Commits
main
...
dcf10e0819
Author | SHA1 | Date | |
---|---|---|---|
|
dcf10e0819 | ||
|
6b78733a5d | ||
|
c124a99901 | ||
|
d7df4002da | ||
|
8b0ef97a82 | ||
|
75d3bef5c8 | ||
|
c2d5611ab9 | ||
|
fb28f3fefc | ||
|
6a34dab00c | ||
|
c7bd7d18b7 |
@@ -18,10 +18,11 @@ import com.simsilica.lemur.style.ElementId;
|
|||||||
|
|
||||||
import static pp.battleship.Resources.lookup;
|
import static pp.battleship.Resources.lookup;
|
||||||
import pp.battleship.client.gui.GameMusic;
|
import pp.battleship.client.gui.GameMusic;
|
||||||
import pp.battleship.client.gui.VolumeSlider;
|
|
||||||
import pp.dialog.Dialog;
|
import pp.dialog.Dialog;
|
||||||
import pp.dialog.StateCheckboxModel;
|
import pp.dialog.StateCheckboxModel;
|
||||||
import pp.dialog.TextInputDialog;
|
import pp.dialog.TextInputDialog;
|
||||||
|
import pp.monopoly.client.gui.VolumeSlider;
|
||||||
|
|
||||||
import static pp.util.PreferencesUtils.getPreferences;
|
import static pp.util.PreferencesUtils.getPreferences;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -24,10 +24,10 @@ overlay.top.color=1, 1, 1, 1
|
|||||||
settings.show=false
|
settings.show=false
|
||||||
#
|
#
|
||||||
# Specifies the width of the application window in pixels.
|
# Specifies the width of the application window in pixels.
|
||||||
settings.resolution.width=1920
|
settings.resolution.width=1200
|
||||||
#
|
#
|
||||||
# Specifies the height of the application window in pixels.
|
# Specifies the height of the application window in pixels.
|
||||||
settings.resolution.height=1080
|
settings.resolution.height=800
|
||||||
#
|
#
|
||||||
# Determines whether the application runs in full-screen mode.
|
# Determines whether the application runs in full-screen mode.
|
||||||
settings.full-screen=false
|
settings.full-screen=false
|
||||||
|
@@ -1,51 +0,0 @@
|
|||||||
////////////////////////////////////////
|
|
||||||
// Programming project code
|
|
||||||
// UniBw M, 2022, 2023, 2024
|
|
||||||
// www.unibw.de/inf2
|
|
||||||
// (c) Mark Minas (mark.minas@unibw.de)
|
|
||||||
////////////////////////////////////////
|
|
||||||
|
|
||||||
package pp.monopoly.client;
|
|
||||||
|
|
||||||
import java.util.prefs.Preferences;
|
|
||||||
|
|
||||||
import pp.dialog.Dialog;
|
|
||||||
import static pp.util.PreferencesUtils.getPreferences;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Menu class represents the main menu in the Battleship game application.
|
|
||||||
* It extends the Dialog class and provides functionalities for loading, saving,
|
|
||||||
* returning to the game, and quitting the application.
|
|
||||||
*/
|
|
||||||
class Menu extends Dialog {
|
|
||||||
private static final Preferences PREFERENCES = getPreferences(Menu.class);
|
|
||||||
private static final String LAST_PATH = "last.file.path";
|
|
||||||
private final MonopolyApp app;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs the Menu dialog for the Battleship application.
|
|
||||||
*
|
|
||||||
* @param app the BattleshipApp instance
|
|
||||||
*/
|
|
||||||
public Menu(MonopolyApp app) {
|
|
||||||
super(app.getDialogManager());
|
|
||||||
this.app = app;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the state of the load and save buttons based on the game logic.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void update() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* As an escape action, this method closes the menu if it is the top dialog.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void escape() {
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,290 +1,437 @@
|
|||||||
|
////////////////////////////////////////
|
||||||
|
// 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 java.util.concurrent.ExecutorService;
|
import com.jme3.app.DebugKeysAppState;
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
|
|
||||||
import com.jme3.app.SimpleApplication;
|
import com.jme3.app.SimpleApplication;
|
||||||
|
import com.jme3.app.StatsAppState;
|
||||||
import com.jme3.font.BitmapFont;
|
import com.jme3.font.BitmapFont;
|
||||||
import com.jme3.font.BitmapText;
|
import com.jme3.font.BitmapText;
|
||||||
import com.jme3.input.KeyInput;
|
import com.jme3.input.KeyInput;
|
||||||
|
import com.jme3.input.MouseInput;
|
||||||
import com.jme3.input.controls.ActionListener;
|
import com.jme3.input.controls.ActionListener;
|
||||||
import com.jme3.input.controls.KeyTrigger;
|
import com.jme3.input.controls.KeyTrigger;
|
||||||
|
import com.jme3.input.controls.MouseButtonTrigger;
|
||||||
import com.jme3.system.AppSettings;
|
import com.jme3.system.AppSettings;
|
||||||
import com.simsilica.lemur.GuiGlobals;
|
import com.simsilica.lemur.GuiGlobals;
|
||||||
import com.simsilica.lemur.style.BaseStyles;
|
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.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.dialog.DialogBuilder;
|
import pp.dialog.DialogBuilder;
|
||||||
import pp.dialog.DialogManager;
|
import pp.dialog.DialogManager;
|
||||||
import pp.graphics.Draw;
|
import pp.graphics.Draw;
|
||||||
import pp.monopoly.client.gui.*;
|
|
||||||
import pp.monopoly.client.gui.popups.BuildingPropertyCard;
|
|
||||||
import pp.monopoly.client.gui.popups.BuyCard;
|
|
||||||
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.MonopolyClient;
|
|
||||||
import pp.monopoly.game.client.ServerConnection;
|
|
||||||
import pp.monopoly.model.fields.BoardManager;
|
|
||||||
import pp.monopoly.notification.GameEventListener;
|
|
||||||
import pp.monopoly.notification.InfoTextEvent;
|
|
||||||
import pp.monopoly.server.MonopolyServer;
|
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.System.Logger;
|
||||||
|
import java.lang.System.Logger.Level;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.logging.LogManager;
|
||||||
|
|
||||||
|
import static pp.monopoly.Resources.lookup;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The main class for the Battleship client application.
|
||||||
|
* It manages the initialization, input setup, GUI setup, and game states for the client.
|
||||||
|
*/
|
||||||
public class MonopolyApp extends SimpleApplication implements MonopolyClient, GameEventListener {
|
public class MonopolyApp extends SimpleApplication implements MonopolyClient, GameEventListener {
|
||||||
|
|
||||||
private BitmapText topText;
|
/**
|
||||||
private final ServerConnection serverConnection;
|
* Logger for logging messages within the application.
|
||||||
private final ClientGameLogic logic;
|
*/
|
||||||
private final MonopolyAppConfig config;
|
private static final Logger LOGGER = System.getLogger(MonopolyApp.class.getName());
|
||||||
private final ActionListener escapeListener = (name, isPressed, tpf) -> handleEscape(isPressed);
|
|
||||||
private final DialogManager dialogManager = new DialogManager(this);
|
|
||||||
private final ExecutorService executor = Executors.newCachedThreadPool();
|
|
||||||
private final Draw draw;
|
|
||||||
private SettingsMenu settingsMenu;
|
|
||||||
private TestWorld testWorld;
|
|
||||||
private boolean isSettingsMenuOpen = false;
|
|
||||||
private boolean inputBlocked = false;
|
|
||||||
private MonopolyServer monopolyServer;
|
|
||||||
private NetworkSupport networkSupport;
|
|
||||||
private BoardManager boardManager = new BoardManager();
|
|
||||||
|
|
||||||
// TODO Temp später entfernen
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Path to the styles script for GUI elements.
|
* Path to the styles script for GUI elements.
|
||||||
*/
|
*/
|
||||||
private static final String STYLES_SCRIPT = "Interface/Lemur/pp-styles.groovy"; // NON-NLS
|
private static final String STYLES_SCRIPT = "Interface/Lemur/pp-styles.groovy"; //NON-NLS
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Path to the font resource used in the GUI.
|
* Path to the font resource used in the GUI.
|
||||||
*/
|
*/
|
||||||
private static final String FONT = "Interface/Fonts/Default.fnt"; // NON-NLS
|
private static final String FONT = "Interface/Fonts/Default.fnt"; //NON-NLS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Path to the client configuration file, if one exists.
|
||||||
|
*/
|
||||||
|
private static final File CONFIG_FILE = new File("client.properties");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Input mapping name for mouse clicks.
|
||||||
|
*/
|
||||||
|
public static final String CLICK = "CLICK";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Input mapping name for the Escape key.
|
||||||
|
*/
|
||||||
|
private static final String ESC = "ESC";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manager for handling dialogs within the application.
|
||||||
|
*/
|
||||||
|
private final DialogManager dialogManager = new DialogManager(this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The server connection instance, used for communicating with the game server.
|
||||||
|
*/
|
||||||
|
private final ServerConnection serverConnection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instance of the {@link Draw} class for rendering graphics.
|
||||||
|
*/
|
||||||
|
private Draw draw;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Text display at the top of the GUI for showing information to the user.
|
||||||
|
*/
|
||||||
|
private BitmapText topText;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executor service for handling asynchronous tasks within the application.
|
||||||
|
*/
|
||||||
|
private ExecutorService executor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for managing the client's game logic.
|
||||||
|
*/
|
||||||
|
private final ClientGameLogic logic;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration settings for the Battleship client application.
|
||||||
|
*/
|
||||||
|
private final MonopolyAppConfig config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listener for handling actions triggered by the Escape key.
|
||||||
|
*/
|
||||||
|
private final ActionListener escapeListener = (name, isPressed, tpf) -> escape(isPressed);
|
||||||
|
|
||||||
|
static {
|
||||||
|
// Configure logging
|
||||||
|
LogManager manager = LogManager.getLogManager();
|
||||||
|
try {
|
||||||
|
manager.readConfiguration(new FileInputStream("logging.properties"));
|
||||||
|
LOGGER.log(Level.INFO, "Successfully read logging properties"); //NON-NLS
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
LOGGER.log(Level.INFO, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the Battleship application.
|
||||||
|
*
|
||||||
|
* @param args Command-line arguments for launching the application.
|
||||||
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
new MonopolyApp().start();
|
new MonopolyApp().start();
|
||||||
}
|
}
|
||||||
|
|
||||||
public MonopolyApp() {
|
/**
|
||||||
this.draw = new Draw(assetManager);
|
* Constructs a new {@code MonopolyApp} instance.
|
||||||
|
* Initializes the configuration, server connection, and game logic listeners.
|
||||||
|
*/
|
||||||
|
private MonopolyApp() {
|
||||||
config = new MonopolyAppConfig();
|
config = new MonopolyAppConfig();
|
||||||
networkSupport = new NetworkSupport(this); // Initialize NetworkSupport
|
config.readFromIfExists(CONFIG_FILE);
|
||||||
serverConnection = networkSupport;
|
serverConnection = makeServerConnection();
|
||||||
logic = new ClientGameLogic(serverConnection);
|
logic = new ClientGameLogic(serverConnection);
|
||||||
logic.addListener(this);
|
logic.addListener(this);
|
||||||
setShowSettings(config.getShowSettings());
|
setShowSettings(config.getShowSettings());
|
||||||
setSettings(makeSettings());
|
setSettings(makeSettings());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public MonopolyAppConfig getConfig() {
|
* Creates and configures application settings from the client configuration.
|
||||||
return config;
|
*
|
||||||
|
* @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
|
@Override
|
||||||
public ClientGameLogic getGameLogic() {
|
public ClientGameLogic getGameLogic() {
|
||||||
return logic;
|
return logic;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BoardManager getBoardManager() {
|
/**
|
||||||
return boardManager;
|
* Returns the current configuration settings for the Battleship client.
|
||||||
}
|
*
|
||||||
|
* @return The {@link BattleshipClientConfig} instance.
|
||||||
public NetworkSupport getNetworkSupport() {
|
*/
|
||||||
return networkSupport;
|
@Override
|
||||||
}
|
public MonopolyAppConfig getConfig() {
|
||||||
|
return config;
|
||||||
private AppSettings makeSettings() {
|
|
||||||
final AppSettings settings = new AppSettings(true);
|
|
||||||
settings.setTitle("Monopoly Game");
|
|
||||||
settings.setResolution(config.getResolutionWidth(), config.getResolutionHeight());
|
|
||||||
settings.setFullscreen(config.fullScreen());
|
|
||||||
return settings;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the application.
|
||||||
|
* Sets up input mappings, GUI, game states, and connects to the server.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void simpleInitApp() {
|
public void simpleInitApp() {
|
||||||
GuiGlobals.initialize(this);
|
setPauseOnLostFocus(false);
|
||||||
BaseStyles.loadStyleResources(STYLES_SCRIPT);
|
draw = new Draw(assetManager);
|
||||||
GuiGlobals.getInstance().getStyles().setDefaultStyle("pp"); // NON-NLS
|
|
||||||
BaseStyles.loadStyleResources("com/simsilica/lemur/style/base/glass-styles.groovy");
|
|
||||||
GuiGlobals.getInstance().getStyles();
|
|
||||||
final BitmapFont normalFont = assetManager.loadFont(FONT); // NON-NLS
|
|
||||||
|
|
||||||
setupInput();
|
setupInput();
|
||||||
|
setupStates();
|
||||||
setupGui();
|
setupGui();
|
||||||
|
new StartMenu(this).open();
|
||||||
// Zeige das Startmenü
|
|
||||||
StartMenu.createStartMenu(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets up the graphical user interface (GUI) for the application.
|
||||||
|
*/
|
||||||
private void setupGui() {
|
private void setupGui() {
|
||||||
BitmapFont normalFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
|
GuiGlobals.initialize(this);
|
||||||
|
BaseStyles.loadStyleResources(STYLES_SCRIPT);
|
||||||
|
GuiGlobals.getInstance().getStyles().setDefaultStyle("pp"); //NON-NLS
|
||||||
|
final BitmapFont normalFont = assetManager.loadFont(FONT); //NON-NLS
|
||||||
topText = new BitmapText(normalFont);
|
topText = new BitmapText(normalFont);
|
||||||
topText.setLocalTranslation(10, settings.getHeight() - 10, 0);
|
final int height = context.getSettings().getHeight();
|
||||||
|
topText.setLocalTranslation(10f, height - 10f, 0f);
|
||||||
|
topText.setColor(config.getTopColor());
|
||||||
guiNode.attachChild(topText);
|
guiNode.attachChild(topText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures input mappings and sets up listeners for user interactions.
|
||||||
|
*/
|
||||||
private void setupInput() {
|
private void setupInput() {
|
||||||
inputManager.deleteMapping(INPUT_MAPPING_EXIT);
|
inputManager.deleteMapping(INPUT_MAPPING_EXIT);
|
||||||
inputManager.setCursorVisible(true);
|
inputManager.setCursorVisible(false);
|
||||||
inputManager.addMapping("ESC", new KeyTrigger(KeyInput.KEY_ESCAPE));
|
inputManager.addMapping(ESC, new KeyTrigger(KeyInput.KEY_ESCAPE));
|
||||||
inputManager.addListener(escapeListener, "ESC");
|
inputManager.addMapping(CLICK, new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
|
||||||
|
inputManager.addListener(escapeListener, ESC);
|
||||||
inputManager.addMapping("B", new KeyTrigger(KeyInput.KEY_B));
|
|
||||||
inputManager.addListener(BListener, "B");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleEscape(boolean isPressed) {
|
/**
|
||||||
if (isPressed) {
|
* Initializes and attaches the necessary application states for the game.
|
||||||
if (settingsMenu != null && isSettingsMenuOpen) {
|
*/
|
||||||
// Schließe das SettingsMenu
|
private void setupStates() {
|
||||||
System.out.println("Schließe SettingsMenu...");
|
if (config.getShowStatistics()) {
|
||||||
settingsMenu.close();
|
final BitmapFont normalFont = assetManager.loadFont(FONT); //NON-NLS
|
||||||
settingsMenu = null;
|
final StatsAppState stats = new StatsAppState(guiNode, normalFont);
|
||||||
setSettingsMenuOpen(false);
|
stateManager.attach(stats);
|
||||||
} else {
|
|
||||||
// Öffne das SettingsMenu
|
|
||||||
System.out.println("Öffne SettingsMenu...");
|
|
||||||
settingsMenu = new SettingsMenu(this);
|
|
||||||
settingsMenu.open();
|
|
||||||
setSettingsMenuOpen(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
flyCam.setEnabled(false);
|
||||||
|
stateManager.detach(stateManager.getState(StatsAppState.class));
|
||||||
|
stateManager.detach(stateManager.getState(DebugKeysAppState.class));
|
||||||
|
|
||||||
|
attachGameSound();
|
||||||
|
attachGameMusic();
|
||||||
}
|
}
|
||||||
|
|
||||||
//logik zum wechselnden erscheinen und verschwinden beim drücken von B //TODO süäter entfernen
|
/**
|
||||||
private void handleB(boolean isPressed) {
|
* Attaches the game sound state and sets its initial enabled state.
|
||||||
if (isPressed) {
|
*/
|
||||||
if (gateField != null && isBuyCardPopupOpen) {
|
private void attachGameSound() {
|
||||||
// Schließe das SettingsMenu
|
final GameSound gameSound = new GameSound();
|
||||||
System.out.println("Schließe BuyCardPopup...");
|
logic.addListener(gameSound);
|
||||||
gateField.close();
|
gameSound.setEnabled(GameSound.enabledInPreferences());
|
||||||
gateField = null;
|
stateManager.attach(gameSound);
|
||||||
setBuyCardPopupOpen(false);
|
|
||||||
} else {
|
|
||||||
// Öffne das SettingsMenu
|
|
||||||
System.out.println("Öffne BuyCardPopup...");
|
|
||||||
gateField = new GateFieldCard(this);
|
|
||||||
gateField.open();
|
|
||||||
setBuyCardPopupOpen(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void blockInputs() {
|
/**
|
||||||
if (!inputBlocked) {
|
* Attaches the background music state and sets its initial enabled state.
|
||||||
System.out.println("Blockiere Eingaben...");
|
*/
|
||||||
inputManager.setCursorVisible(true); // Cursor sichtbar machen
|
private void attachGameMusic() {
|
||||||
inputManager.clearMappings(); // Alle Mappings entfernen
|
final GameMusic gameSound = new GameMusic();
|
||||||
inputBlocked = true;
|
gameSound.setEnabled(GameMusic.enabledInPreferences());
|
||||||
}
|
stateManager.attach(gameSound);
|
||||||
}
|
|
||||||
|
|
||||||
public void unblockInputs() {
|
|
||||||
if (inputBlocked) {
|
|
||||||
System.out.println("Aktiviere Eingaben...");
|
|
||||||
setupInput(); // Standard-Eingaben neu registrieren
|
|
||||||
inputBlocked = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setInfoText(String text) {
|
|
||||||
topText.setText(text);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the application state every frame.
|
||||||
|
* This method is called once per frame during the game loop.
|
||||||
|
*
|
||||||
|
* @param tpf Time per frame in seconds.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void receivedEvent(InfoTextEvent event) {
|
public void simpleUpdate(float tpf) {
|
||||||
setInfoText(event.key());
|
super.simpleUpdate(tpf);
|
||||||
|
dialogManager.update(tpf);
|
||||||
|
logic.update(tpf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public void stop(boolean waitFor) {
|
* Handles the Escape key action to either close the top dialog or show the main menu.
|
||||||
if (executor != null) executor.shutdownNow();
|
*
|
||||||
serverConnection.disconnect();
|
* @param isPressed Indicates whether the Escape key is pressed.
|
||||||
super.stop(waitFor);
|
*/
|
||||||
}
|
private void escape(boolean isPressed) {
|
||||||
|
if (!isPressed) return;
|
||||||
public DialogManager getDialogManager() {
|
if (dialogManager.showsDialog())
|
||||||
return dialogManager;
|
dialogManager.escape();
|
||||||
|
else
|
||||||
|
new SettingsMenu(this).open();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@link Draw} instance used for rendering graphical elements in the game.
|
||||||
|
*
|
||||||
|
* @return The {@link Draw} instance.
|
||||||
|
*/
|
||||||
public Draw getDraw() {
|
public Draw getDraw() {
|
||||||
return draw;
|
return draw;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExecutorService getExecutor() {
|
/**
|
||||||
return executor;
|
* Tries to connect
|
||||||
|
*/
|
||||||
|
public void connect() {
|
||||||
|
serverConnection.connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles a request to close the application.
|
||||||
|
* If the request is initiated by pressing ESC, this parameter is true.
|
||||||
|
*
|
||||||
|
* @param esc If true, the request is due to the ESC key being pressed.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void requestClose(boolean esc) { /* do nothing */ }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the application, displaying a confirmation dialog if the client is connected to a server.
|
||||||
|
*/
|
||||||
public void closeApp() {
|
public void closeApp() {
|
||||||
|
if (serverConnection.isConnected())
|
||||||
|
confirmDialog(lookup("confirm.leaving"), this::close);
|
||||||
|
else
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the application, disconnecting from the server and stopping the application.
|
||||||
|
*/
|
||||||
|
private void close() {
|
||||||
|
serverConnection.disconnect();
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void errorDialog(String errorMessage) {
|
/**
|
||||||
|
* Updates the informational text displayed in the GUI.
|
||||||
|
*
|
||||||
|
* @param text The information text to display.
|
||||||
|
*/
|
||||||
|
public void setInfoText(String text) {
|
||||||
|
LOGGER.log(Level.DEBUG, "setInfoText {0}", text); //NON-NLS
|
||||||
|
topText.setText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the informational text in the GUI based on the key received in an {@link InfoTextEvent}.
|
||||||
|
*
|
||||||
|
* @param event The {@link InfoTextEvent} containing the key for the text to display.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void receivedEvent(InfoTextEvent event) {
|
||||||
|
LOGGER.log(Level.DEBUG, "received info text {0}", event.key()); //NON-NLS
|
||||||
|
setInfoText(lookup(event.key()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles client state events to update the game states accordingly.
|
||||||
|
*
|
||||||
|
* @param event The {@link ClientStateEvent} representing the state change.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void receivedEvent(ClientStateEvent event) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the executor service used for handling multithreaded tasks.
|
||||||
|
*
|
||||||
|
* @return The {@link ExecutorService} instance.
|
||||||
|
*/
|
||||||
|
public ExecutorService getExecutor() {
|
||||||
|
if (executor == null)
|
||||||
|
executor = Executors.newCachedThreadPool();
|
||||||
|
return executor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops the application, shutting down the executor service and halting execution.
|
||||||
|
*
|
||||||
|
* @param waitFor If true, waits for the application to stop before returning.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void stop(boolean waitFor) {
|
||||||
|
if (executor != null) executor.shutdownNow();
|
||||||
|
super.stop(waitFor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a confirmation dialog with a specified question and action for the "Yes" button.
|
||||||
|
*
|
||||||
|
* @param question The question to display in the dialog.
|
||||||
|
* @param yesAction The action to perform if "Yes" is selected.
|
||||||
|
*/
|
||||||
|
public void confirmDialog(String question, Runnable yesAction) {
|
||||||
DialogBuilder.simple(dialogManager)
|
DialogBuilder.simple(dialogManager)
|
||||||
.setTitle("Fehler")
|
.setTitle(lookup("dialog.question"))
|
||||||
.setText(errorMessage)
|
.setText(question)
|
||||||
.setOkButton("OK")
|
.setOkButton(lookup("button.yes"), yesAction)
|
||||||
|
.setNoButton(lookup("button.no"))
|
||||||
.build()
|
.build()
|
||||||
.open();
|
.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSettingsMenuOpen(boolean isOpen) {
|
|
||||||
this.isSettingsMenuOpen = isOpen;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO später entfernen
|
|
||||||
|
|
||||||
public void setBuyCardPopupOpen(boolean isOpen) {
|
|
||||||
this.isBuyCardPopupOpen = isOpen;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void simpleUpdate(float tpf) {
|
|
||||||
if (testWorld != null) {
|
|
||||||
testWorld.update(tpf); // Aktualisiere die Kamera in der TestWorld
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void startTestWorld() {
|
|
||||||
guiNode.detachAllChildren(); // Entferne GUI
|
|
||||||
testWorld = new TestWorld(this); // Erstelle eine Instanz von TestWorld
|
|
||||||
testWorld.initializeScene(); // Initialisiere die Szene
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO später entfernen
|
|
||||||
|
|
||||||
public void startBuyCard() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void returnToMenu() {
|
|
||||||
guiNode.detachAllChildren(); // Entferne die GUI
|
|
||||||
StartMenu.createStartMenu(this); // Zeige das Startmenü erneut
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Startet den Server in einem neuen Thread.
|
* Displays an error dialog with the specified error message.
|
||||||
|
*
|
||||||
|
* @param errorMessage The error message to display in the dialog.
|
||||||
*/
|
*/
|
||||||
public void startServer() {
|
public void errorDialog(String errorMessage) {
|
||||||
new Thread(() -> {
|
DialogBuilder.simple(dialogManager)
|
||||||
try {
|
.setTitle(lookup("dialog.error"))
|
||||||
MonopolyServer.main(new String[0]); // Startet den MonopolyServer
|
.setText(errorMessage)
|
||||||
} catch (Exception e) {
|
.setOkButton(lookup("button.ok"))
|
||||||
errorDialog("Fehler: Server konnte nicht gestartet werden.");
|
.build()
|
||||||
}
|
.open();
|
||||||
}).start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public MonopolyServer getMonopolyServer() {
|
|
||||||
return monopolyServer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ServerConnection getServerConnection() {
|
|
||||||
return serverConnection;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,146 +0,0 @@
|
|||||||
package pp.monopoly.client;
|
|
||||||
|
|
||||||
import java.lang.System.Logger;
|
|
||||||
import java.lang.System.Logger.Level;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
|
|
||||||
import com.simsilica.lemur.Button;
|
|
||||||
import com.simsilica.lemur.Container;
|
|
||||||
import com.simsilica.lemur.Label;
|
|
||||||
import com.simsilica.lemur.TextField;
|
|
||||||
|
|
||||||
import pp.dialog.Dialog;
|
|
||||||
import pp.dialog.DialogBuilder;
|
|
||||||
import pp.dialog.SimpleDialog;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a dialog for setting up a network connection in the Monopoly game.
|
|
||||||
* Allows users to specify the host and port for connecting to a game server.
|
|
||||||
*/
|
|
||||||
class NetworkDialog extends SimpleDialog {
|
|
||||||
private static final Logger LOGGER = System.getLogger(NetworkDialog.class.getName());
|
|
||||||
private static final String LOCALHOST = "localhost";
|
|
||||||
private static final String DEFAULT_PORT = "42069";
|
|
||||||
private final NetworkSupport network;
|
|
||||||
private final TextField host = new TextField(LOCALHOST);
|
|
||||||
private final TextField port = new TextField(DEFAULT_PORT);
|
|
||||||
private String hostname;
|
|
||||||
private int portNumber;
|
|
||||||
private Future<Object> connectionFuture;
|
|
||||||
private Dialog progressDialog;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a new NetworkDialog.
|
|
||||||
*
|
|
||||||
* @param network The NetworkSupport instance to be used for network operations.
|
|
||||||
*/
|
|
||||||
NetworkDialog(NetworkSupport network) {
|
|
||||||
super(network.getApp().getDialogManager());
|
|
||||||
this.network = network;
|
|
||||||
initializeDialog();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the dialog with input fields and connection buttons.
|
|
||||||
*/
|
|
||||||
private void initializeDialog() {
|
|
||||||
final MonopolyApp app = network.getApp();
|
|
||||||
Container inputContainer = new Container();
|
|
||||||
|
|
||||||
// Titel und Eingabefelder für Host und Port
|
|
||||||
inputContainer.addChild(new Label("Server-Adresse"));
|
|
||||||
inputContainer.addChild(host);
|
|
||||||
|
|
||||||
inputContainer.addChild(new Label("Port"));
|
|
||||||
inputContainer.addChild(port);
|
|
||||||
|
|
||||||
Button connectButton = inputContainer.addChild(new Button("Verbinden"));
|
|
||||||
connectButton.addClickCommands(source -> connect());
|
|
||||||
|
|
||||||
Button cancelButton = inputContainer.addChild(new Button("Abbrechen"));
|
|
||||||
cancelButton.addClickCommands(source -> app.closeApp());
|
|
||||||
|
|
||||||
app.getGuiNode().attachChild(inputContainer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initiates the connection attempt based on the entered host and port.
|
|
||||||
*/
|
|
||||||
private void connect() {
|
|
||||||
LOGGER.log(Level.INFO, "Connecting to host={0}, port={1}", host, port);
|
|
||||||
try {
|
|
||||||
hostname = host.getText().trim().isEmpty() ? LOCALHOST : host.getText();
|
|
||||||
portNumber = Integer.parseInt(port.getText());
|
|
||||||
openProgressDialog();
|
|
||||||
connectionFuture = network.getApp().getExecutor().submit(this::initNetwork);
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
network.getApp().errorDialog("Port muss eine Zahl sein.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Opens a progress dialog while connecting.
|
|
||||||
*/
|
|
||||||
private void openProgressDialog() {
|
|
||||||
progressDialog = DialogBuilder.simple(network.getApp().getDialogManager())
|
|
||||||
.setText("Verbinde zum Server...")
|
|
||||||
.build();
|
|
||||||
progressDialog.open();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attempts to initialize the network connection.
|
|
||||||
*
|
|
||||||
* @throws RuntimeException If an error occurs when creating the client.
|
|
||||||
*/
|
|
||||||
private Object initNetwork() {
|
|
||||||
try {
|
|
||||||
network.initNetwork(hostname, portNumber);
|
|
||||||
return null;
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the connection status and handles completion or failure.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void update(float delta) {
|
|
||||||
if (connectionFuture != null && connectionFuture.isDone()) {
|
|
||||||
try {
|
|
||||||
connectionFuture.get();
|
|
||||||
onSuccess();
|
|
||||||
} catch (ExecutionException e) {
|
|
||||||
onFailure(e.getCause());
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
LOGGER.log(Level.WARNING, "Connection interrupted.", e);
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles a successful connection to the game server.
|
|
||||||
*/
|
|
||||||
private void onSuccess() {
|
|
||||||
connectionFuture = null;
|
|
||||||
progressDialog.close();
|
|
||||||
this.close();
|
|
||||||
network.getApp().setInfoText("Warte auf einen Gegner...");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles a failed connection attempt.
|
|
||||||
*
|
|
||||||
* @param e The cause of the failure.
|
|
||||||
*/
|
|
||||||
private void onFailure(Throwable e) {
|
|
||||||
connectionFuture = null;
|
|
||||||
progressDialog.close();
|
|
||||||
network.getApp().errorDialog("Verbindung zum Server fehlgeschlagen.");
|
|
||||||
network.getApp().setInfoText(e.getLocalizedMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,8 +1,11 @@
|
|||||||
package pp.monopoly.client;
|
////////////////////////////////////////
|
||||||
|
// Programming project code
|
||||||
|
// UniBw M, 2022, 2023, 2024
|
||||||
|
// www.unibw.de/inf2
|
||||||
|
// (c) Mark Minas (mark.minas@unibw.de)
|
||||||
|
////////////////////////////////////////
|
||||||
|
|
||||||
import java.io.IOException;
|
package pp.monopoly.client;
|
||||||
import java.lang.System.Logger;
|
|
||||||
import java.lang.System.Logger.Level;
|
|
||||||
|
|
||||||
import com.jme3.network.Client;
|
import com.jme3.network.Client;
|
||||||
import com.jme3.network.ClientStateListener;
|
import com.jme3.network.ClientStateListener;
|
||||||
@@ -10,12 +13,19 @@ import com.jme3.network.Message;
|
|||||||
import com.jme3.network.MessageListener;
|
import com.jme3.network.MessageListener;
|
||||||
import com.jme3.network.Network;
|
import com.jme3.network.Network;
|
||||||
|
|
||||||
|
import pp.monopoly.client.gui.CreateGameMenu;
|
||||||
import pp.monopoly.game.client.ServerConnection;
|
import pp.monopoly.game.client.ServerConnection;
|
||||||
import pp.monopoly.message.client.ClientMessage;
|
import pp.monopoly.message.client.ClientMessage;
|
||||||
import pp.monopoly.message.server.ServerMessage;
|
import pp.monopoly.message.server.ServerMessage;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.System.Logger;
|
||||||
|
import java.lang.System.Logger.Level;
|
||||||
|
|
||||||
|
import static pp.monopoly.Resources.lookup;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages the network connection for the Monopoly application.
|
* Manages the network connection for the Battleship application.
|
||||||
* Handles connecting to and disconnecting from the server, and sending messages.
|
* Handles connecting to and disconnecting from the server, and sending messages.
|
||||||
*/
|
*/
|
||||||
public class NetworkSupport implements MessageListener<Client>, ClientStateListener, ServerConnection {
|
public class NetworkSupport implements MessageListener<Client>, ClientStateListener, ServerConnection {
|
||||||
@@ -24,28 +34,32 @@ public class NetworkSupport implements MessageListener<Client>, ClientStateListe
|
|||||||
private Client client;
|
private Client client;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a NetworkSupport instance for the Monopoly application.
|
* Constructs a NetworkSupport instance for the given Battleship application.
|
||||||
*
|
*
|
||||||
* @param app The Monopoly application instance.
|
* @param app The Battleship application instance.
|
||||||
*/
|
*/
|
||||||
public NetworkSupport(MonopolyApp app) {
|
public NetworkSupport(MonopolyApp app) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the Monopoly application instance.
|
* Return the client connections Id
|
||||||
*
|
* @return the client id
|
||||||
* @return Monopoly application instance
|
|
||||||
*/
|
*/
|
||||||
MonopolyApp getApp() {
|
|
||||||
return app;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getId() {
|
public int getId() {
|
||||||
if (client == null) return 0;
|
if (client == null) return 0;
|
||||||
return client.getId();
|
return client.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Battleship application instance.
|
||||||
|
*
|
||||||
|
* @return Battleship application instance
|
||||||
|
*/
|
||||||
|
public MonopolyApp getApp() {
|
||||||
|
return app;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if there is a connection to the game server.
|
* Checks if there is a connection to the game server.
|
||||||
*
|
*
|
||||||
@@ -62,9 +76,8 @@ public class NetworkSupport implements MessageListener<Client>, ClientStateListe
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void connect() {
|
public void connect() {
|
||||||
if (client == null) {
|
if (client == null)
|
||||||
new NetworkDialog(this).open();
|
new CreateGameMenu(this).open();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -75,7 +88,7 @@ public class NetworkSupport implements MessageListener<Client>, ClientStateListe
|
|||||||
if (client == null) return;
|
if (client == null) return;
|
||||||
client.close();
|
client.close();
|
||||||
client = null;
|
client = null;
|
||||||
LOGGER.log(Level.INFO, "Client connection closed.");
|
LOGGER.log(Level.INFO, "client closed"); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -86,9 +99,8 @@ public class NetworkSupport implements MessageListener<Client>, ClientStateListe
|
|||||||
* @throws IOException If an I/O error occurs when creating the client.
|
* @throws IOException If an I/O error occurs when creating the client.
|
||||||
*/
|
*/
|
||||||
public void initNetwork(String host, int port) throws IOException {
|
public void initNetwork(String host, int port) throws IOException {
|
||||||
if (client != null) {
|
if (client != null)
|
||||||
throw new IllegalStateException("Already connected to the game server.");
|
throw new IllegalStateException("trying to join a game again");
|
||||||
}
|
|
||||||
client = Network.connectToServer(host, port);
|
client = Network.connectToServer(host, port);
|
||||||
client.start();
|
client.start();
|
||||||
client.addMessageListener(this);
|
client.addMessageListener(this);
|
||||||
@@ -103,11 +115,10 @@ public class NetworkSupport implements MessageListener<Client>, ClientStateListe
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void messageReceived(Client client, Message message) {
|
public void messageReceived(Client client, Message message) {
|
||||||
LOGGER.log(Level.INFO, "Message received from server: {0}", message);
|
LOGGER.log(Level.INFO, "message received from server: {0}", message); //NON-NLS
|
||||||
if (message instanceof ServerMessage serverMessage) {
|
if (message instanceof ServerMessage serverMessage)
|
||||||
app.enqueue(() -> serverMessage.accept(app.getGameLogic()));
|
app.enqueue(() -> serverMessage.accept(app.getGameLogic()));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the client has successfully connected to the server.
|
* Called when the client has successfully connected to the server.
|
||||||
@@ -116,7 +127,7 @@ public class NetworkSupport implements MessageListener<Client>, ClientStateListe
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void clientConnected(Client client) {
|
public void clientConnected(Client client) {
|
||||||
LOGGER.log(Level.INFO, "Successfully connected to server: {0}", client);
|
LOGGER.log(Level.INFO, "Client connected: {0}", client); //NON-NLS
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -127,9 +138,13 @@ public class NetworkSupport implements MessageListener<Client>, ClientStateListe
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void clientDisconnected(Client client, DisconnectInfo disconnectInfo) {
|
public void clientDisconnected(Client client, DisconnectInfo disconnectInfo) {
|
||||||
LOGGER.log(Level.INFO, "Disconnected from server: {0}", disconnectInfo);
|
LOGGER.log(Level.INFO, "Client {0} disconnected: {1}", client, disconnectInfo); //NON-NLS
|
||||||
|
if (this.client != client)
|
||||||
|
throw new IllegalArgumentException("parameter value must be client");
|
||||||
|
LOGGER.log(Level.INFO, "client still connected: {0}", client.isConnected()); //NON-NLS
|
||||||
this.client = null;
|
this.client = null;
|
||||||
app.enqueue(() -> app.setInfoText("Verbindung zum Server verloren."));
|
disconnect();
|
||||||
|
app.enqueue(() -> app.setInfoText(lookup("lost.connection.to.server")));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -139,47 +154,10 @@ public class NetworkSupport implements MessageListener<Client>, ClientStateListe
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void send(ClientMessage message) {
|
public void send(ClientMessage message) {
|
||||||
LOGGER.log(Level.INFO, "Sending message to server: {0}", message);
|
LOGGER.log(Level.INFO, "sending {0}", message); //NON-NLS
|
||||||
if (client == null) {
|
if (client == null)
|
||||||
app.errorDialog("Verbindung zum Server verloren.");
|
app.errorDialog(lookup("lost.connection.to.server"));
|
||||||
} else {
|
else
|
||||||
client.send(message);
|
client.send(message);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
public void startServerAndJoin() {
|
|
||||||
new Thread(() -> {
|
|
||||||
// Server starten
|
|
||||||
app.startServer();
|
|
||||||
|
|
||||||
// Warten, bis der Server tatsächlich betriebsbereit ist
|
|
||||||
int retries = 5;
|
|
||||||
while (retries > 0) {
|
|
||||||
try {
|
|
||||||
initNetwork("localhost", app.getConfig().getPort());
|
|
||||||
app.enqueue(() -> app.setInfoText("Erfolgreich verbunden!"));
|
|
||||||
return; // Verbindung erfolgreich
|
|
||||||
} catch (IOException e) {
|
|
||||||
retries--;
|
|
||||||
try {
|
|
||||||
Thread.sleep(1000); // Eine Sekunde warten und erneut versuchen
|
|
||||||
} catch (InterruptedException ex) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
break; // Abbrechen, wenn der Thread unterbrochen wird
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wenn alle Versuche fehlschlagen
|
|
||||||
app.enqueue(() -> app.errorDialog("Fehler: Verbindung zum Server fehlgeschlagen."));
|
|
||||||
}).start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void connectToServer(String host, int port) {
|
|
||||||
try {
|
|
||||||
initNetwork(host, port); // Verbindung initialisieren
|
|
||||||
app.setInfoText("Erfolgreich mit Server verbunden!");
|
|
||||||
} catch (IOException e) {
|
|
||||||
app.errorDialog("Fehler: Verbindung zum Server fehlgeschlagen.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
@@ -1,151 +1,192 @@
|
|||||||
|
////////////////////////////////////////
|
||||||
|
// Programming project code
|
||||||
|
// UniBw M, 2022, 2023, 2024
|
||||||
|
// www.unibw.de/inf2
|
||||||
|
// (c) Mark Minas (mark.minas@unibw.de)
|
||||||
|
////////////////////////////////////////
|
||||||
|
|
||||||
package pp.monopoly.client.gui;
|
package pp.monopoly.client.gui;
|
||||||
|
|
||||||
import com.jme3.material.Material;
|
import java.lang.System.Logger;
|
||||||
|
import java.lang.System.Logger.Level;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
import com.jme3.math.Vector3f;
|
import com.jme3.math.Vector3f;
|
||||||
import com.jme3.scene.Geometry;
|
|
||||||
import com.jme3.scene.shape.Quad;
|
|
||||||
import com.jme3.texture.Texture;
|
|
||||||
import com.simsilica.lemur.Axis;
|
|
||||||
import com.simsilica.lemur.Button;
|
import com.simsilica.lemur.Button;
|
||||||
import com.simsilica.lemur.Container;
|
import com.simsilica.lemur.Container;
|
||||||
import com.simsilica.lemur.Label;
|
import com.simsilica.lemur.Label;
|
||||||
import com.simsilica.lemur.TextField;
|
import com.simsilica.lemur.TextField;
|
||||||
import com.simsilica.lemur.component.SpringGridLayout;
|
import com.simsilica.lemur.component.SpringGridLayout;
|
||||||
|
|
||||||
import com.simsilica.lemur.style.ElementId;
|
import static pp.monopoly.Resources.lookup;
|
||||||
import pp.monopoly.client.MonopolyApp;
|
|
||||||
import pp.monopoly.client.StartMenu;
|
|
||||||
|
|
||||||
|
import pp.monopoly.client.MonopolyApp;
|
||||||
|
import pp.monopoly.client.NetworkSupport;
|
||||||
|
import pp.monopoly.server.MonopolyServer;
|
||||||
|
import pp.dialog.Dialog;
|
||||||
|
import pp.dialog.DialogBuilder;
|
||||||
|
import pp.dialog.SimpleDialog;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CreateGameMenu class represents the menu for creating a new game.
|
* Represents a dialog for setting up a network connection in the Battleship game.
|
||||||
|
* Allows users to specify the host and port for connecting to a game server.
|
||||||
*/
|
*/
|
||||||
public class CreateGameMenu {
|
public class CreateGameMenu extends SimpleDialog {
|
||||||
|
private static final Logger LOGGER = System.getLogger(CreateGameMenu.class.getName());
|
||||||
|
private static final String LOCALHOST = "localhost"; //NON-NLS
|
||||||
|
private static final String DEFAULT_PORT = "42069"; //NON-NLS
|
||||||
|
private final NetworkSupport network;
|
||||||
|
private final TextField host = new TextField(LOCALHOST);
|
||||||
|
private final TextField port = new TextField(DEFAULT_PORT);
|
||||||
|
private final Button serverButton = new Button("Selber hosten");
|
||||||
|
private final Button cancelButton = new Button("Abbrechen");
|
||||||
|
private final Button joinButton = new Button("Beitreten");
|
||||||
|
private String hostname;
|
||||||
|
private int portNumber;
|
||||||
|
private Future<Object> connectionFuture;
|
||||||
|
private Dialog progressDialog;
|
||||||
|
|
||||||
private final MonopolyApp app;
|
/**
|
||||||
private final Container menuContainer;
|
* Constructs a new CreateGameMenu.
|
||||||
private Geometry background;
|
*
|
||||||
private Label serverStatusLabel;
|
* @param network The NetworkSupport instance to be used for network operations.
|
||||||
|
*/
|
||||||
|
public CreateGameMenu(NetworkSupport network) {
|
||||||
|
super(network.getApp().getDialogManager());
|
||||||
|
this.network = network;
|
||||||
|
host.setSingleLine(true);
|
||||||
|
host.setPreferredWidth(400f);
|
||||||
|
port.setSingleLine(true);
|
||||||
|
|
||||||
public CreateGameMenu(MonopolyApp app) {
|
final MonopolyApp app = network.getApp();
|
||||||
this.app = app;
|
final Container input = new Container(new SpringGridLayout());
|
||||||
|
input.addChild(new Label(lookup("host.name") + ": "));
|
||||||
// Hintergrundbild laden und hinzufügen
|
input.addChild(host, 1);
|
||||||
addBackgroundImage();
|
input.addChild(new Label(lookup("port.number") + ": "));
|
||||||
|
input.addChild(port, 1);
|
||||||
// Hauptcontainer für das Menü
|
|
||||||
menuContainer = new Container(new SpringGridLayout(Axis.Y, Axis.X));
|
|
||||||
menuContainer.setPreferredSize(new Vector3f(600, 400, 0)); // Feste Größe des Containers
|
|
||||||
|
|
||||||
// Titel
|
|
||||||
Label title = menuContainer.addChild(new Label("Neues Spiel", new ElementId("header")));
|
|
||||||
title.setFont(app.getAssetManager().loadFont("Interface/Fonts/Metropolis/Metropolis-Bold-42.fnt"));
|
|
||||||
title.setFontSize(50);
|
|
||||||
|
|
||||||
|
|
||||||
// Eingabefelder-Container
|
|
||||||
Container inputContainer = menuContainer.addChild(new Container(new SpringGridLayout(Axis.Y, Axis.X)));
|
|
||||||
inputContainer.setPreferredSize(new Vector3f(200, 150, 0)); // Eingabefelder nicht ganz so breit
|
|
||||||
inputContainer.setLocalTranslation(20, 0, 0); // Abstand vom Rand
|
|
||||||
|
|
||||||
inputContainer.addChild(new Label("Server-Adresse:"));
|
|
||||||
TextField playerNameField = inputContainer.addChild(new TextField("localhost"));
|
|
||||||
playerNameField.setPreferredWidth(400); // Breite des Textfelds
|
|
||||||
|
|
||||||
inputContainer.addChild(new Label("Port:"));
|
|
||||||
TextField serverAddressField = inputContainer.addChild(new TextField("42069"));
|
|
||||||
serverAddressField.setPreferredWidth(400); // Breite des Textfelds
|
|
||||||
|
|
||||||
// Button-Container
|
|
||||||
Container buttonContainer = menuContainer.addChild(new Container(new SpringGridLayout(Axis.X, Axis.Y)));
|
|
||||||
buttonContainer.setPreferredSize(new Vector3f(400, 50, 0));
|
|
||||||
buttonContainer.setLocalTranslation(20, 0, 0); // Abstand vom Rand
|
|
||||||
|
|
||||||
|
addChild(input);
|
||||||
// "Abbrechen"-Button
|
// "Abbrechen"-Button
|
||||||
Button cancelButton = buttonContainer.addChild(new Button("Abbrechen"));
|
|
||||||
cancelButton.setPreferredSize(new Vector3f(120, 40, 0));
|
cancelButton.setPreferredSize(new Vector3f(120, 40, 0));
|
||||||
cancelButton.addClickCommands(source -> goBackToStartMenu());
|
cancelButton.addClickCommands(source -> new StartMenu(app).open());
|
||||||
|
addChild(cancelButton);
|
||||||
|
cancelButton.addClickCommands(s -> new StartMenu(app));
|
||||||
|
|
||||||
// "Selber hosten"-Button
|
// "Selber hosten"-Button
|
||||||
Button hostButton = buttonContainer.addChild(new Button("Selber hosten"));
|
addChild(serverButton).addClickCommands(s -> startServerInThread());
|
||||||
hostButton.setPreferredSize(new Vector3f(120, 40, 0));
|
|
||||||
hostButton.addClickCommands(source -> app.getNetworkSupport().startServerAndJoin());
|
|
||||||
|
|
||||||
// "Beitreten"-Button
|
// "Beitreten"-Button
|
||||||
Button joinButton = buttonContainer.addChild(new Button("Beitreten"));
|
|
||||||
joinButton.setPreferredSize(new Vector3f(120, 40, 0));
|
joinButton.setPreferredSize(new Vector3f(120, 40, 0));
|
||||||
joinButton.addClickCommands(source -> {
|
addChild(joinButton);
|
||||||
|
joinButton.addClickCommands(s -> connect());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the action for the connect button in the connection dialog.
|
||||||
|
* Tries to parse the port number and initiate connection to the server.
|
||||||
|
*/
|
||||||
|
private void connect() {
|
||||||
|
LOGGER.log(Level.INFO, "connect to host={0}, port={1}", host, port); //NON-NLS
|
||||||
try {
|
try {
|
||||||
String host = playerNameField.getText().trim();
|
hostname = host.getText().trim().isEmpty() ? LOCALHOST : host.getText();
|
||||||
int port = Integer.parseInt(serverAddressField.getText().trim());
|
portNumber = Integer.parseInt(port.getText());
|
||||||
app.getNetworkSupport().connectToServer(host, port);
|
openProgressDialog();
|
||||||
|
connectionFuture = network.getApp().getExecutor().submit(this::initNetwork);
|
||||||
// LobbyMenu öffnen
|
|
||||||
app.enqueue(() -> {
|
|
||||||
app.getGuiNode().detachAllChildren(); // Bestehende GUI entfernen
|
|
||||||
new LobbyMenu(app); // LobbyMenu erstellen
|
|
||||||
});
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
app.errorDialog("Port muss eine Zahl sein.");
|
|
||||||
}
|
}
|
||||||
});
|
catch (NumberFormatException e) {
|
||||||
|
network.getApp().errorDialog(lookup("port.must.be.integer"));
|
||||||
// Serverstatus-Label
|
|
||||||
serverStatusLabel = menuContainer.addChild(new Label("Serverstatus: Noch nicht gestartet"));
|
|
||||||
serverStatusLabel.setFontSize(24);
|
|
||||||
|
|
||||||
// Zentrierung des Containers
|
|
||||||
menuContainer.setLocalTranslation(
|
|
||||||
(app.getCamera().getWidth() - menuContainer.getPreferredSize().x) / 2,
|
|
||||||
(app.getCamera().getHeight() + menuContainer.getPreferredSize().y) / 2,
|
|
||||||
1 // Höhere Z-Ebene für den Vordergrund
|
|
||||||
);
|
|
||||||
app.getInputManager().addMapping("OpenTestWorld", new com.jme3.input.controls.KeyTrigger(com.jme3.input.KeyInput.KEY_T));
|
|
||||||
app.getInputManager().addListener(new com.jme3.input.controls.ActionListener() {
|
|
||||||
@Override
|
|
||||||
public void onAction(String name, boolean isPressed, float tpf) {
|
|
||||||
if (name.equals("OpenTestWorld") && isPressed) {
|
|
||||||
app.startTestWorld(); // Öffnet die TestWorld
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, "OpenTestWorld");
|
|
||||||
|
|
||||||
// TODO später entfernen
|
|
||||||
|
|
||||||
app.getInputManager().addMapping("OpenBuyCard", new com.jme3.input.controls.KeyTrigger(com.jme3.input.KeyInput.KEY_B));
|
|
||||||
app.getInputManager().addListener(new com.jme3.input.controls.ActionListener() {
|
|
||||||
@Override
|
|
||||||
public void onAction(String name, boolean isPressed, float tpf) {
|
|
||||||
if (name.equals("OpenBuyCard") && isPressed) {
|
|
||||||
app.startBuyCard(); // Öffnet die TestWorld
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, "OpenBuyCard");
|
|
||||||
|
|
||||||
app.getGuiNode().attachChild(menuContainer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lädt das Hintergrundbild und fügt es als geometrische Ebene hinzu.
|
* Creates a dialog indicating that the connection is in progress.
|
||||||
*/
|
*/
|
||||||
private void addBackgroundImage() {
|
private void openProgressDialog() {
|
||||||
Texture backgroundImage = app.getAssetManager().loadTexture("Pictures/unibw-Bib2.png");
|
progressDialog = DialogBuilder.simple(network.getApp().getDialogManager())
|
||||||
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
|
.setText(lookup("label.connecting"))
|
||||||
background = new Geometry("Background", quad);
|
.build();
|
||||||
Material backgroundMaterial = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
|
progressDialog.open();
|
||||||
backgroundMaterial.setTexture("ColorMap", backgroundImage);
|
|
||||||
background.setMaterial(backgroundMaterial);
|
|
||||||
background.setLocalTranslation(0, 0, -1); // Hintergrundebene
|
|
||||||
|
|
||||||
app.getGuiNode().attachChild(background);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Geht zum Startmenü zurück, wenn "Abbrechen" angeklickt wird.
|
* Tries to initialize the network connection.
|
||||||
|
*
|
||||||
|
* @throws RuntimeException If an error occurs when creating the client.
|
||||||
*/
|
*/
|
||||||
private void goBackToStartMenu() {
|
private Object initNetwork() {
|
||||||
app.getGuiNode().detachChild(menuContainer);
|
try {
|
||||||
app.getGuiNode().detachChild(background); // Entfernt das Hintergrundbild
|
network.initNetwork(hostname, portNumber);
|
||||||
StartMenu.createStartMenu(app);
|
return null;
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is called by {@linkplain pp.dialog.DialogManager#update(float)} for periodically
|
||||||
|
* updating this dialog. T
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void update(float delta) {
|
||||||
|
if (connectionFuture != null && connectionFuture.isDone())
|
||||||
|
try {
|
||||||
|
connectionFuture.get();
|
||||||
|
success();
|
||||||
|
}
|
||||||
|
catch (ExecutionException e) {
|
||||||
|
failure(e.getCause());
|
||||||
|
}
|
||||||
|
catch (InterruptedException e) {
|
||||||
|
LOGGER.log(Level.WARNING, "Interrupted!", e); //NON-NLS
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles a successful connection to the game server.
|
||||||
|
*/
|
||||||
|
private void success() {
|
||||||
|
connectionFuture = null;
|
||||||
|
progressDialog.close();
|
||||||
|
this.close();
|
||||||
|
new LobbyMenu(network.getApp()).open();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles a failed connection attempt.
|
||||||
|
*
|
||||||
|
* @param e The cause of the failure.
|
||||||
|
*/
|
||||||
|
private void failure(Throwable e) {
|
||||||
|
connectionFuture = null;
|
||||||
|
progressDialog.close();
|
||||||
|
network.getApp().errorDialog(lookup("server.connection.failed"));
|
||||||
|
network.getApp().setInfoText(e.getLocalizedMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the server in a separate thread.
|
||||||
|
*/
|
||||||
|
private void startServerInThread() {
|
||||||
|
serverButton.setEnabled(false);
|
||||||
|
Thread serverThread = new Thread(() -> {
|
||||||
|
try {
|
||||||
|
MonopolyServer.main(null);
|
||||||
|
} catch (Exception e) {
|
||||||
|
serverButton.setEnabled(true);
|
||||||
|
LOGGER.log(Level.ERROR, "Server could not be started", e);
|
||||||
|
network.getApp().errorDialog("Could not start server: " + e.getMessage());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
serverThread.start();
|
||||||
|
try {
|
||||||
|
Thread.sleep(2000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
connect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -22,11 +22,14 @@ import com.simsilica.lemur.component.SpringGridLayout;
|
|||||||
import com.simsilica.lemur.core.VersionedList;
|
import com.simsilica.lemur.core.VersionedList;
|
||||||
import com.simsilica.lemur.core.VersionedReference;
|
import com.simsilica.lemur.core.VersionedReference;
|
||||||
import com.simsilica.lemur.style.ElementId;
|
import com.simsilica.lemur.style.ElementId;
|
||||||
|
|
||||||
|
import pp.dialog.Dialog;
|
||||||
import pp.monopoly.client.MonopolyApp;
|
import pp.monopoly.client.MonopolyApp;
|
||||||
|
import pp.monopoly.message.client.PlayerReady;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class LobbyMenu {
|
public class LobbyMenu extends Dialog {
|
||||||
|
|
||||||
private final MonopolyApp app;
|
private final MonopolyApp app;
|
||||||
private final Container menuContainer;
|
private final Container menuContainer;
|
||||||
@@ -35,7 +38,11 @@ public class LobbyMenu {
|
|||||||
private Container lowerLeftMenu;
|
private Container lowerLeftMenu;
|
||||||
private Container lowerRightMenu;
|
private Container lowerRightMenu;
|
||||||
|
|
||||||
|
private TextField playerInputField = new TextField("Spieler 1");
|
||||||
|
private TextField startingCapital = new TextField("15000");
|
||||||
|
|
||||||
public LobbyMenu(MonopolyApp app) {
|
public LobbyMenu(MonopolyApp app) {
|
||||||
|
super(app.getDialogManager());
|
||||||
this.app = app;
|
this.app = app;
|
||||||
|
|
||||||
// Entfernt das CreateGameMenu (inklusive Hintergrund)
|
// Entfernt das CreateGameMenu (inklusive Hintergrund)
|
||||||
@@ -64,7 +71,7 @@ public class LobbyMenu {
|
|||||||
spacerBeforeInput.setPreferredSize(new Vector3f(20, 1, 0)); // Width of the spacer
|
spacerBeforeInput.setPreferredSize(new Vector3f(20, 1, 0)); // Width of the spacer
|
||||||
|
|
||||||
// Add an input field (TextField)
|
// Add an input field (TextField)
|
||||||
TextField startingCapital = horizontalContainer.addChild(new TextField("15 000"));
|
horizontalContainer.addChild(startingCapital);
|
||||||
startingCapital.setPreferredWidth(100); // Set the width of the input field
|
startingCapital.setPreferredWidth(100); // Set the width of the input field
|
||||||
startingCapital.setPreferredSize(new Vector3f(150, 50, 0));
|
startingCapital.setPreferredSize(new Vector3f(150, 50, 0));
|
||||||
startingCapital.setInsets(new Insets3f(5, 10, 5, 10)); // Add padding around the text inside the field
|
startingCapital.setInsets(new Insets3f(5, 10, 5, 10)); // Add padding around the text inside the field
|
||||||
@@ -91,7 +98,6 @@ public class LobbyMenu {
|
|||||||
playerInputContainer.setBackground(null);
|
playerInputContainer.setBackground(null);
|
||||||
|
|
||||||
|
|
||||||
TextField playerInputField = new TextField("Spieler 1");
|
|
||||||
playerInputField.setPreferredSize(new Vector3f(100, 20, 0));
|
playerInputField.setPreferredSize(new Vector3f(100, 20, 0));
|
||||||
playerInputField.setInsets(new Insets3f(5, 10, 5, 10)); // Add padding for the text inside the field
|
playerInputField.setInsets(new Insets3f(5, 10, 5, 10)); // Add padding for the text inside the field
|
||||||
playerInputField.setBackground(new QuadBackgroundComponent(ColorRGBA.Black));
|
playerInputField.setBackground(new QuadBackgroundComponent(ColorRGBA.Black));
|
||||||
@@ -129,7 +135,7 @@ public class LobbyMenu {
|
|||||||
Button cancelButton = new Button("Abbrechen");
|
Button cancelButton = new Button("Abbrechen");
|
||||||
cancelButton.setPreferredSize(new Vector3f(200, 60, 0)); // Set size to match the appearance in the image
|
cancelButton.setPreferredSize(new Vector3f(200, 60, 0)); // Set size to match the appearance in the image
|
||||||
cancelButton.setFontSize(18); // Adjust font size
|
cancelButton.setFontSize(18); // Adjust font size
|
||||||
cancelButton.addClickCommands(source -> goBackToCreateGame()); // Add functionality
|
cancelButton.addClickCommands(source -> close()); // Add functionality
|
||||||
lowerLeftMenu.addChild(cancelButton);
|
lowerLeftMenu.addChild(cancelButton);
|
||||||
|
|
||||||
// Position the container near the bottom-left corner
|
// Position the container near the bottom-left corner
|
||||||
@@ -201,20 +207,12 @@ public class LobbyMenu {
|
|||||||
* Schaltet den "Bereit"-Status um.
|
* Schaltet den "Bereit"-Status um.
|
||||||
*/
|
*/
|
||||||
private void toggleReady(Label playersLabel) {
|
private void toggleReady(Label playersLabel) {
|
||||||
// Beispiel-Logik für das Umschalten des Status
|
app.getGameLogic().send(new PlayerReady(true, "Test", "flugzeug", 15000));;
|
||||||
playersLabel.setText("Spielerstatus aktualisiert."); // Beispieltext
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Geht zurück zum CreateGameMenu.
|
public void close() {
|
||||||
*/
|
super.close();
|
||||||
private void goBackToCreateGame() {
|
|
||||||
app.getGuiNode().detachChild(menuContainer);
|
|
||||||
app.getGuiNode().detachChild(background);
|
|
||||||
app.getGuiNode().detachChild(circle);
|
|
||||||
app.getGuiNode().detachChild(lowerLeftMenu);
|
|
||||||
app.getGuiNode().detachChild(lowerRightMenu);
|
|
||||||
new CreateGameMenu(app);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -269,7 +267,7 @@ public class LobbyMenu {
|
|||||||
System.out.println("Gamma selected");
|
System.out.println("Gamma selected");
|
||||||
break;
|
break;
|
||||||
case "[3]":
|
case "[3]":
|
||||||
goBackToCreateGame();
|
close();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
System.out.println("Unknown selection");
|
System.out.println("Unknown selection");
|
||||||
|
@@ -1,123 +1,79 @@
|
|||||||
|
////////////////////////////////////////
|
||||||
|
// Programming project code
|
||||||
|
// UniBw M, 2022, 2023, 2024
|
||||||
|
// www.unibw.de/inf2
|
||||||
|
// (c) Mark Minas (mark.minas@unibw.de)
|
||||||
|
////////////////////////////////////////
|
||||||
|
|
||||||
package pp.monopoly.client.gui;
|
package pp.monopoly.client.gui;
|
||||||
|
|
||||||
import com.jme3.material.Material;
|
import java.util.prefs.Preferences;
|
||||||
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;
|
import com.simsilica.lemur.Button;
|
||||||
import com.simsilica.lemur.Checkbox;
|
import com.simsilica.lemur.Checkbox;
|
||||||
import com.simsilica.lemur.Container;
|
|
||||||
import com.simsilica.lemur.Label;
|
import com.simsilica.lemur.Label;
|
||||||
import com.simsilica.lemur.Slider;
|
|
||||||
import com.simsilica.lemur.component.QuadBackgroundComponent;
|
|
||||||
import com.simsilica.lemur.style.ElementId;
|
import com.simsilica.lemur.style.ElementId;
|
||||||
import com.simsilica.lemur.ValueRenderer;
|
|
||||||
|
|
||||||
import com.simsilica.lemur.Selector;
|
import static pp.monopoly.Resources.lookup;
|
||||||
import pp.dialog.Dialog;
|
import pp.monopoly.client.GameMusic;
|
||||||
|
import pp.monopoly.client.GameSound;
|
||||||
import pp.monopoly.client.MonopolyApp;
|
import pp.monopoly.client.MonopolyApp;
|
||||||
|
import pp.dialog.Dialog;
|
||||||
|
import pp.dialog.StateCheckboxModel;
|
||||||
|
import static pp.util.PreferencesUtils.getPreferences;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SettingsMenu ist ein Overlay-Menü, das durch ESC aufgerufen werden kann.
|
* The Menu class represents the main menu in the Battleship game application.
|
||||||
|
* It extends the Dialog class and provides functionalities for loading, saving,
|
||||||
|
* returning to the game, and quitting the application.
|
||||||
*/
|
*/
|
||||||
public class SettingsMenu extends Dialog {
|
public class SettingsMenu extends Dialog {
|
||||||
|
private static final Preferences PREFERENCES = getPreferences(SettingsMenu.class);
|
||||||
|
private static final String LAST_PATH = "last.file.path";
|
||||||
private final MonopolyApp app;
|
private final MonopolyApp app;
|
||||||
private final Geometry overlayBackground;
|
private final VolumeSlider slider;
|
||||||
private final Container settingsContainer;
|
|
||||||
private final Container backgroundContainer;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs the Menu dialog for the Battleship application.
|
||||||
|
*
|
||||||
|
* @param app the MonopolyApp instance
|
||||||
|
*/
|
||||||
public SettingsMenu(MonopolyApp app) {
|
public SettingsMenu(MonopolyApp app) {
|
||||||
super(app.getDialogManager());
|
super(app.getDialogManager());
|
||||||
this.app = app;
|
this.app = app;
|
||||||
|
slider = new VolumeSlider(app.getStateManager().getState(GameMusic.class));
|
||||||
|
addChild(new Label("Einstellungen", new ElementId("header"))); //NON-NLS
|
||||||
|
addChild(new Label("Sound Effekte", new ElementId("label"))); //NON-NLS
|
||||||
|
addChild(new Checkbox("Soundeffekte an / aus", new StateCheckboxModel(app, GameSound.class)));
|
||||||
|
|
||||||
// Halbtransparentes Overlay hinzufügen
|
addChild(new Label("Hintergrund Musik", new ElementId("label"))); //NON-NLS
|
||||||
overlayBackground = createOverlayBackground();
|
addChild(new Checkbox("Musik an / aus", new StateCheckboxModel(app, GameMusic.class)));
|
||||||
app.getGuiNode().attachChild(overlayBackground);
|
|
||||||
|
|
||||||
// Create the background container
|
addChild(slider);
|
||||||
backgroundContainer = new Container();
|
|
||||||
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Darker background
|
|
||||||
app.getGuiNode().attachChild(backgroundContainer);
|
|
||||||
|
|
||||||
// Hauptcontainer für das Menü
|
addChild(new Button("Zurück zum Spiel")).addClickCommands(s -> ifTopDialog(this::close));
|
||||||
settingsContainer = new Container();
|
addChild(new Button("Beenden")).addClickCommands(s -> ifTopDialog(app::closeApp));
|
||||||
settingsContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.1f, 0.1f, 0.1f, 0.9f)));
|
|
||||||
|
|
||||||
|
update();
|
||||||
|
|
||||||
// Titel
|
|
||||||
Label settingsTitle = settingsContainer.addChild(new Label("Einstellungen", new ElementId("settings-title")));
|
|
||||||
settingsTitle.setFontSize(48);
|
|
||||||
|
|
||||||
// Effekt-Sound: Slider und Checkbox
|
|
||||||
Container effectSoundContainer = settingsContainer.addChild(new Container());
|
|
||||||
effectSoundContainer.addChild(new Label("Effekt Sound", new ElementId("label")));
|
|
||||||
effectSoundContainer.addChild(new Slider());
|
|
||||||
effectSoundContainer.addChild(new Checkbox("Soundeffekte an")).setChecked(true);
|
|
||||||
effectSoundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
|
|
||||||
// Hintergrundmusik: Slider und Checkbox
|
|
||||||
Container backgroundMusicContainer = settingsContainer.addChild(new Container());
|
|
||||||
backgroundMusicContainer.addChild(new Label("Hintergrund Musik", new ElementId("label")));
|
|
||||||
backgroundMusicContainer.addChild(new Slider());
|
|
||||||
backgroundMusicContainer.addChild(new Checkbox("Musik an")).setChecked(true);
|
|
||||||
backgroundMusicContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
|
|
||||||
|
|
||||||
// Beenden-Button
|
|
||||||
Button quitButton = settingsContainer.addChild(new Button("Beenden", new ElementId("menu-button")));
|
|
||||||
quitButton.setFontSize(32);
|
|
||||||
quitButton.addClickCommands(source -> app.stop());
|
|
||||||
|
|
||||||
float padding = 10; // Padding around the settingsContainer for the background
|
|
||||||
backgroundContainer.setPreferredSize(settingsContainer.getPreferredSize().addLocal(padding, padding, 0));
|
|
||||||
|
|
||||||
|
|
||||||
// Zentriere das Menü
|
|
||||||
settingsContainer.setLocalTranslation(
|
|
||||||
(app.getCamera().getWidth() - settingsContainer.getPreferredSize().x) / 2,
|
|
||||||
(app.getCamera().getHeight() + settingsContainer.getPreferredSize().y) / 2,
|
|
||||||
4
|
|
||||||
);
|
|
||||||
|
|
||||||
backgroundContainer.setLocalTranslation(
|
|
||||||
(app.getCamera().getWidth() - settingsContainer.getPreferredSize().x - padding) / 2,
|
|
||||||
(app.getCamera().getHeight() + settingsContainer.getPreferredSize().y+ padding) / 2,
|
|
||||||
3
|
|
||||||
);
|
|
||||||
|
|
||||||
app.getGuiNode().attachChild(settingsContainer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Erstellt einen halbtransparenten Hintergrund für das Menü.
|
* Updates the state of the load and save buttons based on the game logic.
|
||||||
*
|
|
||||||
* @return Geometrie des Overlays
|
|
||||||
*/
|
|
||||||
private Geometry createOverlayBackground() {
|
|
||||||
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
|
|
||||||
Geometry overlay = new Geometry("Overlay", quad);
|
|
||||||
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
|
|
||||||
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Halbtransparent
|
|
||||||
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
|
|
||||||
overlay.setMaterial(material);
|
|
||||||
overlay.setLocalTranslation(0, 0, 0);
|
|
||||||
return overlay;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Schließt das Menü und entfernt die GUI-Elemente.
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void update() {
|
||||||
System.out.println("Schließe SettingsMenu..."); // Debugging-Ausgabe
|
|
||||||
app.getGuiNode().detachChild(settingsContainer); // Entferne das Menü
|
|
||||||
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
|
|
||||||
app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
|
|
||||||
app.setSettingsMenuOpen(false); // Menü als geschlossen markieren
|
|
||||||
app.unblockInputs(); // Eingaben wieder aktivieren
|
|
||||||
System.out.println("SettingsMenu geschlossen."); // Debugging-Ausgabe
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(float delta) {
|
||||||
|
slider.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* As an escape action, this method closes the menu if it is the top dialog.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void escape() {
|
||||||
|
close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
package pp.monopoly.client;
|
package pp.monopoly.client.gui;
|
||||||
|
|
||||||
import com.jme3.material.Material;
|
import com.jme3.material.Material;
|
||||||
import com.jme3.math.Vector3f;
|
import com.jme3.math.Vector3f;
|
||||||
@@ -13,8 +13,7 @@ import com.simsilica.lemur.component.QuadBackgroundComponent;
|
|||||||
import com.simsilica.lemur.component.SpringGridLayout;
|
import com.simsilica.lemur.component.SpringGridLayout;
|
||||||
|
|
||||||
import pp.dialog.Dialog;
|
import pp.dialog.Dialog;
|
||||||
import pp.monopoly.client.gui.CreateGameMenu;
|
import pp.monopoly.client.MonopolyApp;
|
||||||
import pp.monopoly.client.gui.SettingsMenu;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs the startup menu dialog for the Monopoly application.
|
* Constructs the startup menu dialog for the Monopoly application.
|
||||||
@@ -33,13 +32,7 @@ public class StartMenu extends Dialog {
|
|||||||
public StartMenu(MonopolyApp app) {
|
public StartMenu(MonopolyApp app) {
|
||||||
super(app.getDialogManager());
|
super(app.getDialogManager());
|
||||||
this.app = app;
|
this.app = app;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates and displays the Start Menu with buttons for starting the game,
|
|
||||||
* opening settings, and quitting the application.
|
|
||||||
*/
|
|
||||||
public static void createStartMenu(MonopolyApp app) {
|
|
||||||
int screenWidth = app.getContext().getSettings().getWidth();
|
int screenWidth = app.getContext().getSettings().getWidth();
|
||||||
int screenHeight = app.getContext().getSettings().getHeight();
|
int screenHeight = app.getContext().getSettings().getHeight();
|
||||||
|
|
||||||
@@ -53,9 +46,6 @@ public class StartMenu extends Dialog {
|
|||||||
background.setLocalTranslation(0, 0, -1); // Ensure it is behind other GUI elements
|
background.setLocalTranslation(0, 0, -1); // Ensure it is behind other GUI elements
|
||||||
app.getGuiNode().attachChild(background);
|
app.getGuiNode().attachChild(background);
|
||||||
|
|
||||||
createMonopolyLogo(app);
|
|
||||||
createUnibwLogo(app);
|
|
||||||
|
|
||||||
// Center container for title and play button
|
// Center container for title and play button
|
||||||
Container centerMenu = new Container(new SpringGridLayout(Axis.Y, Axis.X));
|
Container centerMenu = new Container(new SpringGridLayout(Axis.Y, Axis.X));
|
||||||
|
|
||||||
@@ -64,7 +54,7 @@ public class StartMenu extends Dialog {
|
|||||||
startButton.setFontSize(40); // Set the font size for the button text
|
startButton.setFontSize(40); // Set the font size for the button text
|
||||||
startButton.setTextHAlignment(HAlignment.Center); // Center the text horizontally
|
startButton.setTextHAlignment(HAlignment.Center); // Center the text horizontally
|
||||||
|
|
||||||
startButton.addClickCommands(source -> startGame(app));
|
startButton.addClickCommands(s -> app.connect());
|
||||||
centerMenu.addChild(startButton);
|
centerMenu.addChild(startButton);
|
||||||
|
|
||||||
// Position the center container in the middle of the screen
|
// Position the center container in the middle of the screen
|
||||||
@@ -79,7 +69,7 @@ public class StartMenu extends Dialog {
|
|||||||
Button quitButton = new Button("Spiel beenden");
|
Button quitButton = new Button("Spiel beenden");
|
||||||
quitButton.setPreferredSize(new Vector3f(130, 40, 0)); // Increase button size slightly (width, height)
|
quitButton.setPreferredSize(new Vector3f(130, 40, 0)); // Increase button size slightly (width, height)
|
||||||
quitButton.setFontSize(18);
|
quitButton.setFontSize(18);
|
||||||
quitButton.addClickCommands(source -> quitGame());
|
quitButton.addClickCommands(source -> ifTopDialog(app::closeApp));
|
||||||
lowerLeftMenu.addChild(quitButton);
|
lowerLeftMenu.addChild(quitButton);
|
||||||
app.getGuiNode().attachChild(lowerLeftMenu);
|
app.getGuiNode().attachChild(lowerLeftMenu);
|
||||||
|
|
||||||
@@ -89,17 +79,10 @@ public class StartMenu extends Dialog {
|
|||||||
Button settingsButton = new Button("Einstellungen");
|
Button settingsButton = new Button("Einstellungen");
|
||||||
settingsButton.setPreferredSize(new Vector3f(130, 40, 0)); // Increase button size slightly (width, height)
|
settingsButton.setPreferredSize(new Vector3f(130, 40, 0)); // Increase button size slightly (width, height)
|
||||||
settingsButton.setFontSize(18); // Increase the font size for the text
|
settingsButton.setFontSize(18); // Increase the font size for the text
|
||||||
settingsButton.addClickCommands(source -> openSettings(app));
|
settingsButton.addClickCommands(source -> new SettingsMenu(app).open());
|
||||||
lowerRightMenu.addChild(settingsButton);
|
lowerRightMenu.addChild(settingsButton);
|
||||||
app.getGuiNode().attachChild(lowerRightMenu);
|
app.getGuiNode().attachChild(lowerRightMenu);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates and positions the Monopoly logo container in the center of the screen.
|
|
||||||
*/
|
|
||||||
private static void createMonopolyLogo(MonopolyApp app) {
|
|
||||||
int screenWidth = app.getContext().getSettings().getWidth();
|
|
||||||
int screenHeight = app.getContext().getSettings().getHeight();
|
|
||||||
|
|
||||||
// Load the Monopoly logo as a texture
|
// Load the Monopoly logo as a texture
|
||||||
Texture logoTexture = app.getAssetManager().loadTexture("Pictures/logo-monopoly.png");
|
Texture logoTexture = app.getAssetManager().loadTexture("Pictures/logo-monopoly.png");
|
||||||
@@ -123,14 +106,6 @@ public class StartMenu extends Dialog {
|
|||||||
|
|
||||||
// Attach the container to the GUI node
|
// Attach the container to the GUI node
|
||||||
app.getGuiNode().attachChild(logoContainer);
|
app.getGuiNode().attachChild(logoContainer);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates and positions the Unibw logo container in the center of the screen.
|
|
||||||
*/
|
|
||||||
private static void createUnibwLogo(MonopolyApp app) {
|
|
||||||
int screenWidth = app.getContext().getSettings().getWidth();
|
|
||||||
int screenHeight = app.getContext().getSettings().getHeight();
|
|
||||||
|
|
||||||
// Load the Unibw logo as a texture
|
// Load the Unibw logo as a texture
|
||||||
Texture unibwTexture = app.getAssetManager().loadTexture("Pictures/logo-unibw.png");
|
Texture unibwTexture = app.getAssetManager().loadTexture("Pictures/logo-unibw.png");
|
||||||
@@ -156,26 +131,8 @@ public class StartMenu extends Dialog {
|
|||||||
app.getGuiNode().attachChild(unibwContainer);
|
app.getGuiNode().attachChild(unibwContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Starts the game by transitioning to the CreateGameMenu.
|
public void escape() {
|
||||||
*/
|
close();
|
||||||
private static void startGame(MonopolyApp app) {
|
|
||||||
app.getGuiNode().detachAllChildren();
|
|
||||||
new CreateGameMenu(app);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Opens the settings menu.
|
|
||||||
*/
|
|
||||||
private static void openSettings(MonopolyApp app) {
|
|
||||||
app.getGuiNode().detachAllChildren();
|
|
||||||
new SettingsMenu(app);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Quits the game application.
|
|
||||||
*/
|
|
||||||
private static void quitGame() {
|
|
||||||
System.exit(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,6 +1,8 @@
|
|||||||
package pp.battleship.client.gui;
|
package pp.monopoly.client.gui;
|
||||||
|
|
||||||
import com.simsilica.lemur.Slider;
|
import com.simsilica.lemur.Slider;
|
||||||
|
|
||||||
|
import pp.monopoly.client.GameMusic;
|
||||||
/**
|
/**
|
||||||
* The VolumeSlider class represents the Volume Slider in the Menu.
|
* The VolumeSlider class represents the Volume Slider in the Menu.
|
||||||
* It extends the Slider class and provides functionalities for setting the music volume,
|
* It extends the Slider class and provides functionalities for setting the music volume,
|
||||||
@@ -8,7 +10,7 @@ import com.simsilica.lemur.Slider;
|
|||||||
*/
|
*/
|
||||||
public class VolumeSlider extends Slider {
|
public class VolumeSlider extends Slider {
|
||||||
|
|
||||||
private final GameMusic music;
|
private final pp.monopoly.client.GameMusic music;
|
||||||
private double vol;
|
private double vol;
|
||||||
|
|
||||||
/**
|
/**
|
@@ -30,7 +30,7 @@ public class BuildingPropertyCard extends Dialog {
|
|||||||
this.app = app;
|
this.app = app;
|
||||||
|
|
||||||
//Generate the corresponfing field
|
//Generate the corresponfing field
|
||||||
BuildingProperty field = (BuildingProperty) app.getBoardManager().getFieldAtIndex(index);
|
BuildingProperty field = (BuildingProperty) app.getGameLogic().getBoardManager().getFieldAtIndex(index);
|
||||||
|
|
||||||
// Halbtransparentes Overlay hinzufügen
|
// Halbtransparentes Overlay hinzufügen
|
||||||
overlayBackground = createOverlayBackground();
|
overlayBackground = createOverlayBackground();
|
||||||
@@ -121,8 +121,8 @@ public class BuildingPropertyCard extends Dialog {
|
|||||||
app.getGuiNode().detachChild(buildingPropertyContainer); // Entferne das Menü
|
app.getGuiNode().detachChild(buildingPropertyContainer); // Entferne das Menü
|
||||||
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
|
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
|
||||||
app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
|
app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
|
||||||
app.setSettingsMenuOpen(false); // Menü als geschlossen markieren
|
// app.setSettingsMenuOpen(false); // Menü als geschlossen markieren
|
||||||
app.unblockInputs(); // Eingaben wieder aktivieren
|
// app.unblockInputs(); // Eingaben wieder aktivieren
|
||||||
System.out.println("SettingsMenu geschlossen."); // Debugging-Ausgabe
|
System.out.println("SettingsMenu geschlossen."); // Debugging-Ausgabe
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -107,8 +107,8 @@ public class BuyCard extends Dialog {
|
|||||||
app.getGuiNode().detachChild(settingsContainer); // Entferne das Menü
|
app.getGuiNode().detachChild(settingsContainer); // Entferne das Menü
|
||||||
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
|
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
|
||||||
app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
|
app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
|
||||||
app.setSettingsMenuOpen(false); // Menü als geschlossen markieren
|
// app.setSettingsMenuOpen(false); // Menü als geschlossen markieren
|
||||||
app.unblockInputs(); // Eingaben wieder aktivieren
|
// app.unblockInputs(); // Eingaben wieder aktivieren
|
||||||
System.out.println("SettingsMenu geschlossen."); // Debugging-Ausgabe
|
System.out.println("SettingsMenu geschlossen."); // Debugging-Ausgabe
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -30,7 +30,7 @@ public class FoodFieldCard extends Dialog {
|
|||||||
this.app = app;
|
this.app = app;
|
||||||
|
|
||||||
//Generate the corresponfing field
|
//Generate the corresponfing field
|
||||||
FoodField field = (FoodField) app.getBoardManager().getFieldAtIndex(index);
|
FoodField field = (FoodField) app.getGameLogic().getBoardManager().getFieldAtIndex(index);
|
||||||
|
|
||||||
// Halbtransparentes Overlay hinzufügen
|
// Halbtransparentes Overlay hinzufügen
|
||||||
overlayBackground = createOverlayBackground();
|
overlayBackground = createOverlayBackground();
|
||||||
@@ -125,8 +125,8 @@ public class FoodFieldCard extends Dialog {
|
|||||||
app.getGuiNode().detachChild(foodFieldContainer); // Entferne das Menü
|
app.getGuiNode().detachChild(foodFieldContainer); // Entferne das Menü
|
||||||
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
|
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
|
||||||
app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
|
app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
|
||||||
app.setSettingsMenuOpen(false); // Menü als geschlossen markieren
|
// app.setSettingsMenuOpen(false); // Menü als geschlossen markieren
|
||||||
app.unblockInputs(); // Eingaben wieder aktivieren
|
// app.unblockInputs(); // Eingaben wieder aktivieren
|
||||||
System.out.println("SettingsMenu geschlossen."); // Debugging-Ausgabe
|
System.out.println("SettingsMenu geschlossen."); // Debugging-Ausgabe
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -28,7 +28,7 @@ public class GateFieldCard extends Dialog {
|
|||||||
this.app = app;
|
this.app = app;
|
||||||
|
|
||||||
//Generate the corresponfing field
|
//Generate the corresponfing field
|
||||||
GateField field = (GateField) app.getBoardManager().getFieldAtIndex(index);
|
GateField field = (GateField) app.getGameLogic().getBoardManager().getFieldAtIndex(index);
|
||||||
|
|
||||||
// Halbtransparentes Overlay hinzufügen
|
// Halbtransparentes Overlay hinzufügen
|
||||||
overlayBackground = createOverlayBackground();
|
overlayBackground = createOverlayBackground();
|
||||||
@@ -118,8 +118,8 @@ public class GateFieldCard extends Dialog {
|
|||||||
app.getGuiNode().detachChild(gateFieldContainer); // Entferne das Menü
|
app.getGuiNode().detachChild(gateFieldContainer); // Entferne das Menü
|
||||||
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
|
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
|
||||||
app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
|
app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
|
||||||
app.setSettingsMenuOpen(false); // Menü als geschlossen markieren
|
// app.setSettingsMenuOpen(false); // Menü als geschlossen markieren
|
||||||
app.unblockInputs(); // Eingaben wieder aktivieren
|
// app.unblockInputs(); // Eingaben wieder aktivieren
|
||||||
System.out.println("SettingsMenu geschlossen."); // Debugging-Ausgabe
|
System.out.println("SettingsMenu geschlossen."); // Debugging-Ausgabe
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -28,7 +28,7 @@ public class MonopolyConfig extends Config {
|
|||||||
* The default port number for the Monopoly server.
|
* The default port number for the Monopoly server.
|
||||||
*/
|
*/
|
||||||
@Property("port")
|
@Property("port")
|
||||||
private int port = 4321;
|
private int port = 42069;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The width of the game map in terms of grid units.
|
* The width of the game map in terms of grid units.
|
||||||
|
@@ -22,6 +22,7 @@ import pp.monopoly.message.server.TradeRequest;
|
|||||||
import pp.monopoly.message.server.ViewAssetsResponse;
|
import pp.monopoly.message.server.ViewAssetsResponse;
|
||||||
import pp.monopoly.model.Board;
|
import pp.monopoly.model.Board;
|
||||||
import pp.monopoly.model.IntPoint;
|
import pp.monopoly.model.IntPoint;
|
||||||
|
import pp.monopoly.model.fields.BoardManager;
|
||||||
import pp.monopoly.notification.ClientStateEvent;
|
import pp.monopoly.notification.ClientStateEvent;
|
||||||
import pp.monopoly.notification.GameEvent;
|
import pp.monopoly.notification.GameEvent;
|
||||||
import pp.monopoly.notification.GameEventBroker;
|
import pp.monopoly.notification.GameEventBroker;
|
||||||
@@ -53,6 +54,8 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker {
|
|||||||
|
|
||||||
private PlayerHandler playerHandler;
|
private PlayerHandler playerHandler;
|
||||||
|
|
||||||
|
private BoardManager boardManager = new BoardManager();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a ClientGameLogic with the specified sender object.
|
* Constructs a ClientGameLogic with the specified sender object.
|
||||||
*
|
*
|
||||||
@@ -62,6 +65,14 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker {
|
|||||||
this.clientSender = clientSender;
|
this.clientSender = clientSender;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reutns the BoardManager
|
||||||
|
* @return the boardManager
|
||||||
|
*/
|
||||||
|
public BoardManager getBoardManager() {
|
||||||
|
return boardManager;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current state of the game logic.
|
* Returns the current state of the game logic.
|
||||||
*
|
*
|
||||||
@@ -128,7 +139,7 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker {
|
|||||||
*
|
*
|
||||||
* @param msg the message to be sent
|
* @param msg the message to be sent
|
||||||
*/
|
*/
|
||||||
void send(ClientMessage msg) {
|
public void send(ClientMessage msg) {
|
||||||
if (clientSender == null) {
|
if (clientSender == null) {
|
||||||
LOGGER.log(Level.ERROR, "trying to send {0} with sender==null", msg); //NON-NLS
|
LOGGER.log(Level.ERROR, "trying to send {0} with sender==null", msg); //NON-NLS
|
||||||
} else {
|
} else {
|
||||||
|
Reference in New Issue
Block a user