mirror of
https://athene2.informatik.unibw-muenchen.de/progproj/gruppen-ht24/Gruppe-02.git
synced 2025-08-04 21:21:44 +02:00
Compare commits
38 Commits
client_log
...
c3a33b4402
Author | SHA1 | Date | |
---|---|---|---|
|
c3a33b4402 | ||
|
e12f00aad6 | ||
|
47bac0185f | ||
|
dafe1dab2a | ||
|
8ba4ea2819 | ||
|
f6f708fd5b | ||
|
1203077aed | ||
|
ddbf79c928 | ||
|
aa47dd579f | ||
|
cdce478d77 | ||
|
f11f4a59f1 | ||
|
d631e8df1e | ||
|
af80d40700 | ||
|
3a6f8a945a | ||
|
bb9727d54a | ||
|
7da8b3e545 | ||
|
b6968df451 | ||
|
b85bbdd0ad | ||
|
aa986fb948 | ||
|
6e63de6e99 | ||
|
962ecd08fa | ||
|
580a26b3ea | ||
|
0cda6b5fa0 | ||
|
cc8c3795b8 | ||
|
3c21165efb | ||
|
818fdf4670 | ||
|
b7d679b492 | ||
|
a42093df23 | ||
|
6157db51da | ||
|
843052989b | ||
|
8e01fa3192 | ||
|
e2126a7ea7 | ||
|
0b46d14650 | ||
|
9e28deedf7 | ||
|
9c0172b413 | ||
|
2933d022aa | ||
|
bdefb7193e | ||
|
69b68a6975 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,6 +4,7 @@ build
|
|||||||
|
|
||||||
# VSC
|
# VSC
|
||||||
bin
|
bin
|
||||||
|
.vscode
|
||||||
|
|
||||||
# IntelliJ
|
# IntelliJ
|
||||||
*.iml
|
*.iml
|
||||||
|
18
Projekte/.run/MonopolyApp.run.xml
Normal file
18
Projekte/.run/MonopolyApp.run.xml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="MonopolyApp" type="Application" factoryName="Application" singleton="false"
|
||||||
|
nameIsGenerated="true">
|
||||||
|
<option name="MAIN_CLASS_NAME" value="pp.monopoly.client.MonopolyApp"/>
|
||||||
|
<module name="Projekte.monopoly.client.main"/>
|
||||||
|
<option name="VM_PARAMETERS" value="-Djava.util.logging.config.file=logging.properties"/>
|
||||||
|
<option name="WORKING_DIRECTORY" value="$MODULE_WORKING_DIR$"/>
|
||||||
|
<extension name="coverage">
|
||||||
|
<pattern>
|
||||||
|
<option name="PATTERN" value="pp.monopoly.client.*"/>
|
||||||
|
<option name="ENABLED" value="true"/>
|
||||||
|
</pattern>
|
||||||
|
</extension>
|
||||||
|
<method v="2">
|
||||||
|
<option name="Make" enabled="true"/>
|
||||||
|
</method>
|
||||||
|
</configuration>
|
||||||
|
</component>
|
17
Projekte/.run/MonopolyServer.run.xml
Normal file
17
Projekte/.run/MonopolyServer.run.xml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="MonopolyServer" type="Application" factoryName="Application"
|
||||||
|
nameIsGenerated="true">
|
||||||
|
<option name="MAIN_CLASS_NAME" value="pp.monopoly.server.MonopolyServer"/>
|
||||||
|
<module name="Projekte.monopoly.server.main"/>
|
||||||
|
<option name="WORKING_DIRECTORY" value="$MODULE_WORKING_DIR$"/>
|
||||||
|
<extension name="coverage">
|
||||||
|
<pattern>
|
||||||
|
<option name="PATTERN" value="pp.monopoly.server.*"/>
|
||||||
|
<option name="ENABLED" value="true"/>
|
||||||
|
</pattern>
|
||||||
|
</extension>
|
||||||
|
<method v="2">
|
||||||
|
<option name="Make" enabled="true"/>
|
||||||
|
</method>
|
||||||
|
</configuration>
|
||||||
|
</component>
|
@@ -7,22 +7,21 @@
|
|||||||
|
|
||||||
package pp.battleship.client;
|
package pp.battleship.client;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.prefs.Preferences;
|
||||||
|
|
||||||
import com.simsilica.lemur.Button;
|
import com.simsilica.lemur.Button;
|
||||||
import com.simsilica.lemur.Checkbox;
|
import com.simsilica.lemur.Checkbox;
|
||||||
import com.simsilica.lemur.Label;
|
import com.simsilica.lemur.Label;
|
||||||
import com.simsilica.lemur.style.ElementId;
|
import com.simsilica.lemur.style.ElementId;
|
||||||
|
|
||||||
|
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.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 java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.prefs.Preferences;
|
|
||||||
|
|
||||||
import static pp.battleship.Resources.lookup;
|
|
||||||
import static pp.util.PreferencesUtils.getPreferences;
|
import static pp.util.PreferencesUtils.getPreferences;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,7 +38,7 @@ class Menu extends Dialog {
|
|||||||
private final VolumeSlider slider;
|
private final VolumeSlider slider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs the Menu dialog for the Battleship application.
|
* Constructs the Menu dialog for the Battleship application.+
|
||||||
*
|
*
|
||||||
* @param app the BattleshipApp instance
|
* @param app the BattleshipApp instance
|
||||||
*/
|
*/
|
||||||
|
@@ -7,24 +7,23 @@
|
|||||||
|
|
||||||
package pp.battleship.client;
|
package pp.battleship.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.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 static pp.battleship.Resources.lookup;
|
||||||
import pp.battleship.server.BattleshipServer;
|
import pp.battleship.server.BattleshipServer;
|
||||||
import pp.dialog.Dialog;
|
import pp.dialog.Dialog;
|
||||||
import pp.dialog.DialogBuilder;
|
import pp.dialog.DialogBuilder;
|
||||||
import pp.dialog.SimpleDialog;
|
import pp.dialog.SimpleDialog;
|
||||||
|
|
||||||
import java.lang.System.Logger;
|
|
||||||
import java.lang.System.Logger.Level;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
|
|
||||||
import static pp.battleship.Resources.lookup;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a dialog for setting up a network connection in the Battleship 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.
|
* Allows users to specify the host and port for connecting to a game server.
|
||||||
@@ -32,7 +31,7 @@ import static pp.battleship.Resources.lookup;
|
|||||||
class NetworkDialog extends SimpleDialog {
|
class NetworkDialog extends SimpleDialog {
|
||||||
private static final Logger LOGGER = System.getLogger(NetworkDialog.class.getName());
|
private static final Logger LOGGER = System.getLogger(NetworkDialog.class.getName());
|
||||||
private static final String LOCALHOST = "localhost"; //NON-NLS
|
private static final String LOCALHOST = "localhost"; //NON-NLS
|
||||||
private static final String DEFAULT_PORT = "1234"; //NON-NLS
|
private static final String DEFAULT_PORT = "42069"; //NON-NLS
|
||||||
private final NetworkSupport network;
|
private final NetworkSupport network;
|
||||||
private final TextField host = new TextField(LOCALHOST);
|
private final TextField host = new TextField(LOCALHOST);
|
||||||
private final TextField port = new TextField(DEFAULT_PORT);
|
private final TextField port = new TextField(DEFAULT_PORT);
|
||||||
|
@@ -7,12 +7,11 @@
|
|||||||
|
|
||||||
package pp.battleship;
|
package pp.battleship;
|
||||||
|
|
||||||
import pp.util.config.Config;
|
import static java.lang.Math.max;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
import static java.lang.Math.max;
|
import pp.util.config.Config;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides access to the configuration settings for the Battleship game.
|
* Provides access to the configuration settings for the Battleship game.
|
||||||
@@ -31,7 +30,7 @@ public class BattleshipConfig extends Config {
|
|||||||
* The default port number for the Battleship server.
|
* The default port number for the Battleship server.
|
||||||
*/
|
*/
|
||||||
@Property("port")
|
@Property("port")
|
||||||
private int port = 1234;
|
private int port = 12234;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The width of the game map in terms of grid units.
|
* The width of the game map in terms of grid units.
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
# This file defines the configuration settings for the Battleship server.
|
# This file defines the configuration settings for the Battleship server.
|
||||||
#
|
#
|
||||||
# The port number on which the server will listen for incoming connections.
|
# The port number on which the server will listen for incoming connections.
|
||||||
port=1234
|
port=42069
|
||||||
#
|
#
|
||||||
# The dimensions of the game map.
|
# The dimensions of the game map.
|
||||||
# 'map.width' defines the number of columns, and 'map.height' defines the number of rows.
|
# 'map.width' defines the number of columns, and 'map.height' defines the number of rows.
|
||||||
|
@@ -20,6 +20,8 @@ def sliderBgColor = color(0.5, 0.75, 0.75, 1)
|
|||||||
def gradientColor = color(0.5, 0.75, 0.85, 0.5)
|
def gradientColor = color(0.5, 0.75, 0.85, 0.5)
|
||||||
def tabbuttonEnabledColor = color(0.4, 0.45, 0.5, 1)
|
def tabbuttonEnabledColor = color(0.4, 0.45, 0.5, 1)
|
||||||
def solidWhiteBackground = new QuadBackgroundComponent(color(1, 1, 1, 1)) // Solid white
|
def solidWhiteBackground = new QuadBackgroundComponent(color(1, 1, 1, 1)) // Solid white
|
||||||
|
def greyBackground = color(0.8, 0.8, 0.8, 1) // Grey background color
|
||||||
|
def redBorderColor = color(1, 0, 0, 1) // Red border color
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -34,7 +36,7 @@ doubleGradient.texture = texture(name: "/com/simsilica/lemur/icons/double-gradie
|
|||||||
generateMips: false)
|
generateMips: false)
|
||||||
|
|
||||||
def orangeBorder = TbtQuadBackgroundComponent.create(
|
def orangeBorder = TbtQuadBackgroundComponent.create(
|
||||||
texture(name: "/com/simsilica/lemur/icons/bordered-gradient.png", // Replace with an appropriate texture if needed
|
texture(name: "/com/simsilica/lemur/icons/border.png", // Replace with an appropriate texture if needed
|
||||||
generateMips: false),
|
generateMips: false),
|
||||||
1, 1, 1, 126, 126,
|
1, 1, 1, 126, 126,
|
||||||
1f, false)
|
1f, false)
|
||||||
@@ -54,6 +56,7 @@ selector("header", "pp") {
|
|||||||
insets = new Insets3f(2, 2, 2, 2)
|
insets = new Insets3f(2, 2, 2, 2)
|
||||||
color = color(1, 0.5, 0, 1)
|
color = color(1, 0.5, 0, 1)
|
||||||
textHAlignment = HAlignment.Center
|
textHAlignment = HAlignment.Center
|
||||||
|
textVAlignment = VAlignment.Center
|
||||||
}
|
}
|
||||||
|
|
||||||
selector("container", "pp") {
|
selector("container", "pp") {
|
||||||
@@ -61,6 +64,22 @@ selector("container", "pp") {
|
|||||||
background.setColor(bgColor)
|
background.setColor(bgColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
selector("toolbar") {
|
||||||
|
// Set the grey background
|
||||||
|
background = new QuadBackgroundComponent(greyBackground)
|
||||||
|
|
||||||
|
// Add a red border using a TbtQuadBackgroundComponent
|
||||||
|
def redBorder = TbtQuadBackgroundComponent.create(
|
||||||
|
texture(name: "/com/simsilica/lemur/icons/bordered-gradient.png",
|
||||||
|
generateMips: false),
|
||||||
|
1, 1, 1, 1, 1,
|
||||||
|
1f, false)
|
||||||
|
redBorder.color = redBorderColor
|
||||||
|
background = greyBackground
|
||||||
|
|
||||||
|
// Optional: Set padding inside the toolbar
|
||||||
|
insets = new Insets3f(10, 10, 10, 10)
|
||||||
|
}
|
||||||
selector("slider", "pp") {
|
selector("slider", "pp") {
|
||||||
background = gradient.clone()
|
background = gradient.clone()
|
||||||
background.setColor(bgColor)
|
background.setColor(bgColor)
|
||||||
@@ -128,6 +147,8 @@ selector("title", "pp") {
|
|||||||
background.texture = texture(name: "/com/simsilica/lemur/icons/double-gradient-128.png",
|
background.texture = texture(name: "/com/simsilica/lemur/icons/double-gradient-128.png",
|
||||||
generateMips: false)
|
generateMips: false)
|
||||||
insets = new Insets3f(2, 2, 2, 2)
|
insets = new Insets3f(2, 2, 2, 2)
|
||||||
|
textHAlignment = HAlignment.Center
|
||||||
|
textVAlignment = VAlignment.Center
|
||||||
|
|
||||||
buttonCommands = stdButtonCommands
|
buttonCommands = stdButtonCommands
|
||||||
}
|
}
|
||||||
@@ -142,6 +163,8 @@ selector("button", "pp") {
|
|||||||
|
|
||||||
// Use insets to create a margin/padding effect for the inner background
|
// Use insets to create a margin/padding effect for the inner background
|
||||||
insets = new Insets3f(3, 3, 3, 3) // Adjust the border thickness
|
insets = new Insets3f(3, 3, 3, 3) // Adjust the border thickness
|
||||||
|
textHAlignment = HAlignment.Center
|
||||||
|
textVAlignment = VAlignment.Center
|
||||||
buttonCommands = stdButtonCommands
|
buttonCommands = stdButtonCommands
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,6 +213,7 @@ selector("slider.down.button", "pp") {
|
|||||||
|
|
||||||
selector("checkbox", "pp") {
|
selector("checkbox", "pp") {
|
||||||
color = buttonEnabledColor
|
color = buttonEnabledColor
|
||||||
|
fontSize = 20
|
||||||
}
|
}
|
||||||
|
|
||||||
selector("rollup", "pp") {
|
selector("rollup", "pp") {
|
||||||
@@ -213,3 +237,17 @@ selector("tab.button", "pp") {
|
|||||||
|
|
||||||
buttonCommands = stdButtonCommands
|
buttonCommands = stdButtonCommands
|
||||||
}
|
}
|
||||||
|
selector("settings-title", "pp") {
|
||||||
|
fontSize = 48 // Set font size
|
||||||
|
background = new QuadBackgroundComponent(color(0.4157f, 0.4235f, 0.4392f, 1.0f)) // Grey background
|
||||||
|
textHAlignment = HAlignment.Center
|
||||||
|
textVAlignment = VAlignment.Center
|
||||||
|
}
|
||||||
|
|
||||||
|
selector("menu-button", "pp") {
|
||||||
|
fontSize = 40 // Set font size
|
||||||
|
background = new QuadBackgroundComponent(color(0.4157f, 0.4235f, 0.4392f, 1.0f)) // Grey background
|
||||||
|
textHAlignment = HAlignment.Center
|
||||||
|
textVAlignment = VAlignment.Center
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -7,8 +7,14 @@ description = 'Monopoly Client'
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation project(":jme-common")
|
implementation project(":jme-common")
|
||||||
implementation project(":monopoly:model")
|
implementation project(":monopoly:model")
|
||||||
|
implementation project(":monopoly:server")
|
||||||
|
|
||||||
|
implementation 'com.simsilica:lemur-proto:1.13.0'
|
||||||
implementation libs.jme3.desktop
|
implementation libs.jme3.desktop
|
||||||
|
implementation libs.lemur
|
||||||
|
implementation libs.lemurproto
|
||||||
|
|
||||||
|
implementation libs.selenium
|
||||||
|
|
||||||
runtimeOnly libs.jme3.awt.dialogs
|
runtimeOnly libs.jme3.awt.dialogs
|
||||||
runtimeOnly libs.jme3.plugins
|
runtimeOnly libs.jme3.plugins
|
||||||
|
@@ -0,0 +1,122 @@
|
|||||||
|
package pp.monopoly.client;
|
||||||
|
|
||||||
|
import static pp.util.PreferencesUtils.getPreferences;
|
||||||
|
|
||||||
|
import java.lang.System.Logger;
|
||||||
|
import java.lang.System.Logger.Level;
|
||||||
|
import java.util.prefs.Preferences;
|
||||||
|
|
||||||
|
import com.jme3.app.Application;
|
||||||
|
import com.jme3.app.state.AbstractAppState;
|
||||||
|
import com.jme3.app.state.AppStateManager;
|
||||||
|
import com.jme3.asset.AssetLoadException;
|
||||||
|
import com.jme3.asset.AssetNotFoundException;
|
||||||
|
import com.jme3.audio.AudioData;
|
||||||
|
import com.jme3.audio.AudioNode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the background music beeing played. Is able to start and stop the music. Set the Volume of the Audio.
|
||||||
|
*/
|
||||||
|
public class GameMusic extends AbstractAppState{
|
||||||
|
private static final Logger LOGGER = System.getLogger(GameMusic.class.getName());
|
||||||
|
private static final Preferences PREFERENCES = getPreferences(GameMusic.class);
|
||||||
|
private static final String ENABLED_PREF = "enabled"; //NON-NLS
|
||||||
|
private static final String VOLUME_PREF = "volume"; //NON-NLS
|
||||||
|
|
||||||
|
private AudioNode music;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if sound is enabled in the preferences.
|
||||||
|
*
|
||||||
|
* @return {@code true} if sound is enabled, {@code false} otherwise.
|
||||||
|
*/
|
||||||
|
public static boolean enabledInPreferences() {
|
||||||
|
return PREFERENCES.getBoolean(ENABLED_PREF, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if sound is enabled in the preferences.
|
||||||
|
*
|
||||||
|
* @return float to which the volume is set
|
||||||
|
*/
|
||||||
|
public static float volumeInPreferences() {
|
||||||
|
return PREFERENCES.getFloat(VOLUME_PREF, 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the sound effects for the game.
|
||||||
|
* Overrides {@link AbstractAppState#initialize(AppStateManager, Application)}
|
||||||
|
*
|
||||||
|
* @param stateManager The state manager
|
||||||
|
* @param app The application
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void initialize(AppStateManager stateManager, Application app) {
|
||||||
|
super.initialize(stateManager, app);
|
||||||
|
music = loadSound(app, "Sound/background.ogg");
|
||||||
|
setVolume(volumeInPreferences());
|
||||||
|
music.setLooping(true);
|
||||||
|
if (isEnabled() && music != null) {
|
||||||
|
music.play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a sound from the specified file.
|
||||||
|
*
|
||||||
|
* @param app The application
|
||||||
|
* @param name The name of the sound file.
|
||||||
|
* @return The loaded AudioNode.
|
||||||
|
*/
|
||||||
|
private AudioNode loadSound(Application app, String name) {
|
||||||
|
try {
|
||||||
|
final AudioNode sound = new AudioNode(app.getAssetManager(), name, AudioData.DataType.Buffer);
|
||||||
|
sound.setLooping(false);
|
||||||
|
sound.setPositional(false);
|
||||||
|
return sound;
|
||||||
|
}
|
||||||
|
catch (AssetLoadException | AssetNotFoundException ex) {
|
||||||
|
LOGGER.log(Level.ERROR, ex.getMessage(), ex);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the enabled state of this AppState.
|
||||||
|
* Overrides {@link com.jme3.app.state.AbstractAppState#setEnabled(boolean)}
|
||||||
|
*
|
||||||
|
* @param enabled {@code true} to enable the AppState, {@code false} to disable it.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setEnabled(boolean enabled) {
|
||||||
|
if (isEnabled() == enabled) return;
|
||||||
|
|
||||||
|
if (music != null) {
|
||||||
|
if (enabled) {
|
||||||
|
music.play();
|
||||||
|
} else {
|
||||||
|
music.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
super.setEnabled(enabled);
|
||||||
|
LOGGER.log(Level.INFO, "Sound enabled: {0}", enabled); //NON-NLS
|
||||||
|
PREFERENCES.putBoolean(ENABLED_PREF, enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggles the game sound on or off.
|
||||||
|
*/
|
||||||
|
public void toggleSound() {
|
||||||
|
setEnabled(!isEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the volume of music
|
||||||
|
* @param vol the volume to which the music should be set
|
||||||
|
*/
|
||||||
|
public void setVolume(float vol){
|
||||||
|
music.setVolume(vol);
|
||||||
|
PREFERENCES.putFloat(VOLUME_PREF, vol);
|
||||||
|
}
|
||||||
|
}
|
@@ -31,9 +31,17 @@ public class GameSound extends AbstractAppState implements GameEventListener {
|
|||||||
private static final Preferences PREFERENCES = getPreferences(GameSound.class);
|
private static final Preferences PREFERENCES = getPreferences(GameSound.class);
|
||||||
private static final String ENABLED_PREF = "enabled"; //NON-NLS
|
private static final String ENABLED_PREF = "enabled"; //NON-NLS
|
||||||
|
|
||||||
private AudioNode splashSound;
|
private AudioNode passStartSound;
|
||||||
private AudioNode shipDestroyedSound;
|
private AudioNode eventCardSound;
|
||||||
private AudioNode explosionSound;
|
private AudioNode gulagSound;
|
||||||
|
private AudioNode diceRollSound;
|
||||||
|
private AudioNode moneyCollectSound;
|
||||||
|
private AudioNode moneyLostSound;
|
||||||
|
private AudioNode tradeAcceptedSound;
|
||||||
|
private AudioNode tradeRejectedSound;
|
||||||
|
private AudioNode winnerSound;
|
||||||
|
private AudioNode looserSound;
|
||||||
|
private AudioNode buttonSound;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if sound is enabled in the preferences.
|
* Checks if sound is enabled in the preferences.
|
||||||
@@ -75,6 +83,17 @@ public class GameSound extends AbstractAppState implements GameEventListener {
|
|||||||
@Override
|
@Override
|
||||||
public void initialize(AppStateManager stateManager, Application app) {
|
public void initialize(AppStateManager stateManager, Application app) {
|
||||||
super.initialize(stateManager, app);
|
super.initialize(stateManager, app);
|
||||||
|
passStartSound = loadSound(app, "Sound/Effects/passStart.ogg");
|
||||||
|
eventCardSound = loadSound(app, "Sound/Effects/eventCard.ogg");
|
||||||
|
gulagSound = loadSound(app, "Sound/Effects/gulag.ogg");
|
||||||
|
diceRollSound = loadSound(app, "Sound/Effects/diceRoll.ogg");
|
||||||
|
moneyCollectSound = loadSound(app, "Sound/Effects/moneyCollect.ogg");
|
||||||
|
moneyLostSound = loadSound(app, "Sound/Effects/moneyLost.ogg");
|
||||||
|
tradeAcceptedSound = loadSound(app, "Sound/Effects/tradeAccepted.ogg");
|
||||||
|
tradeRejectedSound = loadSound(app, "Sound/Effects/tradeRejected.ogg");
|
||||||
|
winnerSound = loadSound(app, "Sound/Effects/winner.ogg");
|
||||||
|
looserSound = loadSound(app, "Sound/Effects/looser.ogg");
|
||||||
|
buttonSound = loadSound(app, "Sound/Effects/button.ogg");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -98,32 +117,97 @@ public class GameSound extends AbstractAppState implements GameEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plays the splash sound effect.
|
* Plays the passStart sound effect.
|
||||||
*/
|
*/
|
||||||
public void splash() {
|
public void passStart() {
|
||||||
if (isEnabled() && splashSound != null)
|
if (isEnabled() && passStartSound != null)
|
||||||
splashSound.playInstance();
|
passStartSound.playInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plays the explosion sound effect.
|
* Plays the eventCard sound effect.
|
||||||
*/
|
*/
|
||||||
public void explosion() {
|
public void eventCard() {
|
||||||
if (isEnabled() && explosionSound != null)
|
if (isEnabled() && eventCardSound != null)
|
||||||
explosionSound.playInstance();
|
eventCardSound.playInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plays sound effect when a ship has been destroyed.
|
* Plays the gulag sound effect.
|
||||||
*/
|
*/
|
||||||
public void shipDestroyed() {
|
public void gulag() {
|
||||||
if (isEnabled() && shipDestroyedSound != null)
|
if (isEnabled() && gulagSound != null)
|
||||||
shipDestroyedSound.playInstance();
|
gulagSound.playInstance();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Plays the diceRoll sound effect.
|
||||||
|
*/
|
||||||
|
public void diceRoll() {
|
||||||
|
if (isEnabled() && diceRollSound != null)
|
||||||
|
diceRollSound.playInstance();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Plays the moneyCollect sound effect.
|
||||||
|
*/
|
||||||
|
public void moneyCollect() {
|
||||||
|
if (isEnabled() && moneyCollectSound != null)
|
||||||
|
moneyCollectSound.playInstance();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Plays the moneyLost sound effect.
|
||||||
|
*/
|
||||||
|
public void moneyLost() {
|
||||||
|
if (isEnabled() && moneyLostSound != null)
|
||||||
|
moneyLostSound.playInstance();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Plays the tradeAccepted sound effect.
|
||||||
|
*/
|
||||||
|
public void tradeAccepted() {
|
||||||
|
if (isEnabled() && tradeAcceptedSound != null)
|
||||||
|
tradeAcceptedSound.playInstance();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Plays the tradeRejected sound effect.
|
||||||
|
*/
|
||||||
|
public void tradeRejected() {
|
||||||
|
if (isEnabled() && tradeRejectedSound != null)
|
||||||
|
tradeRejectedSound.playInstance();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Plays the winner sound effect.
|
||||||
|
*/
|
||||||
|
public void winner() {
|
||||||
|
if (isEnabled() && winnerSound != null)
|
||||||
|
winnerSound.playInstance();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Plays the looser sound effect.
|
||||||
|
*/
|
||||||
|
public void looser() {
|
||||||
|
if (isEnabled() && looserSound != null)
|
||||||
|
looserSound.playInstance();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Plays the button sound effect.
|
||||||
|
*/
|
||||||
|
public void button() {
|
||||||
|
if (isEnabled() && buttonSound != null)
|
||||||
|
buttonSound.playInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void receivedEvent(SoundEvent event) {
|
public void receivedEvent(SoundEvent event) {
|
||||||
switch (event.sound()) {
|
switch (event.sound()) {
|
||||||
|
case PASS_START -> passStart();
|
||||||
|
case EVENT_CARD -> eventCard();
|
||||||
|
case GULAG -> eventCard();
|
||||||
|
case DICE_ROLL -> eventCard();
|
||||||
|
case MONEY_COLLECTED -> eventCard();
|
||||||
|
case MONEY_LOST -> eventCard();
|
||||||
|
case TRADE_ACCEPTED -> eventCard();
|
||||||
|
case TRADE_REJECTED -> eventCard();
|
||||||
|
case WINNER -> eventCard();
|
||||||
|
case LOSER -> eventCard();
|
||||||
|
case BUTTON -> eventCard();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -23,8 +23,10 @@ import pp.monopoly.game.client.MonopolyClient;
|
|||||||
import pp.monopoly.game.client.ServerConnection;
|
import pp.monopoly.game.client.ServerConnection;
|
||||||
import pp.monopoly.notification.GameEventListener;
|
import pp.monopoly.notification.GameEventListener;
|
||||||
import pp.monopoly.notification.InfoTextEvent;
|
import pp.monopoly.notification.InfoTextEvent;
|
||||||
|
import pp.monopoly.server.MonopolyServer;
|
||||||
|
|
||||||
public class MonopolyApp extends SimpleApplication implements MonopolyClient, GameEventListener {
|
public class MonopolyApp extends SimpleApplication implements MonopolyClient, GameEventListener {
|
||||||
|
|
||||||
private BitmapText topText;
|
private BitmapText topText;
|
||||||
private final ServerConnection serverConnection;
|
private final ServerConnection serverConnection;
|
||||||
private final ClientGameLogic logic;
|
private final ClientGameLogic logic;
|
||||||
@@ -37,15 +39,17 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
|
|||||||
private TestWorld testWorld;
|
private TestWorld testWorld;
|
||||||
private boolean isSettingsMenuOpen = false;
|
private boolean isSettingsMenuOpen = false;
|
||||||
private boolean inputBlocked = false;
|
private boolean inputBlocked = false;
|
||||||
|
private MonopolyServer monopolyServer;
|
||||||
|
private NetworkSupport networkSupport;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
new MonopolyApp().start();
|
new MonopolyApp().start();
|
||||||
@@ -54,7 +58,8 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
|
|||||||
public MonopolyApp() {
|
public MonopolyApp() {
|
||||||
this.draw = new Draw(assetManager);
|
this.draw = new Draw(assetManager);
|
||||||
config = new MonopolyAppConfig();
|
config = new MonopolyAppConfig();
|
||||||
serverConnection = new NetworkSupport(this);
|
networkSupport = new NetworkSupport(this); // Initialize NetworkSupport
|
||||||
|
serverConnection = networkSupport;
|
||||||
logic = new ClientGameLogic(serverConnection);
|
logic = new ClientGameLogic(serverConnection);
|
||||||
logic.addListener(this);
|
logic.addListener(this);
|
||||||
setShowSettings(config.getShowSettings());
|
setShowSettings(config.getShowSettings());
|
||||||
@@ -71,6 +76,10 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
|
|||||||
return logic;
|
return logic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public NetworkSupport getNetworkSupport() {
|
||||||
|
return networkSupport;
|
||||||
|
}
|
||||||
|
|
||||||
private AppSettings makeSettings() {
|
private AppSettings makeSettings() {
|
||||||
final AppSettings settings = new AppSettings(true);
|
final AppSettings settings = new AppSettings(true);
|
||||||
settings.setTitle("Monopoly Game");
|
settings.setTitle("Monopoly Game");
|
||||||
@@ -83,8 +92,8 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
|
|||||||
public void simpleInitApp() {
|
public void simpleInitApp() {
|
||||||
GuiGlobals.initialize(this);
|
GuiGlobals.initialize(this);
|
||||||
BaseStyles.loadStyleResources(STYLES_SCRIPT);
|
BaseStyles.loadStyleResources(STYLES_SCRIPT);
|
||||||
GuiGlobals.getInstance().getStyles().setDefaultStyle("pp"); //NON-NLS
|
GuiGlobals.getInstance().getStyles().setDefaultStyle("pp"); // NON-NLS
|
||||||
final BitmapFont normalFont = assetManager.loadFont(FONT); //NON-NLS
|
final BitmapFont normalFont = assetManager.loadFont(FONT); // NON-NLS
|
||||||
|
|
||||||
setupInput();
|
setupInput();
|
||||||
setupGui();
|
setupGui();
|
||||||
@@ -124,18 +133,16 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void blockInputs() {
|
private void blockInputs() {
|
||||||
if (!inputBlocked) {
|
if (!inputBlocked) {
|
||||||
System.out.println("Blockiere Eingaben...");
|
System.out.println("Blockiere Eingaben...");
|
||||||
inputManager.setCursorVisible(true); // Cursor sichtbar machen
|
inputManager.setCursorVisible(true); // Cursor sichtbar machen
|
||||||
inputManager.clearMappings(); // Alle Mappings entfernen
|
inputManager.clearMappings(); // Alle Mappings entfernen
|
||||||
inputBlocked = true;
|
inputBlocked = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unblockInputs() {
|
public void unblockInputs() {
|
||||||
if (inputBlocked) {
|
if (inputBlocked) {
|
||||||
System.out.println("Aktiviere Eingaben...");
|
System.out.println("Aktiviere Eingaben...");
|
||||||
@@ -199,11 +206,32 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
|
|||||||
public void startTestWorld() {
|
public void startTestWorld() {
|
||||||
guiNode.detachAllChildren(); // Entferne GUI
|
guiNode.detachAllChildren(); // Entferne GUI
|
||||||
testWorld = new TestWorld(this); // Erstelle eine Instanz von TestWorld
|
testWorld = new TestWorld(this); // Erstelle eine Instanz von TestWorld
|
||||||
testWorld.initializeScene(); // Initialisiere die Szene
|
testWorld.initializeScene(); // Initialisiere die Szene
|
||||||
}
|
}
|
||||||
|
|
||||||
public void returnToMenu() {
|
public void returnToMenu() {
|
||||||
guiNode.detachAllChildren(); // Entferne die GUI
|
guiNode.detachAllChildren(); // Entferne die GUI
|
||||||
StartMenu.createStartMenu(this); // Zeige das Startmenü erneut
|
StartMenu.createStartMenu(this); // Zeige das Startmenü erneut
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Startet den Server in einem neuen Thread.
|
||||||
|
*/
|
||||||
|
public void startServer() {
|
||||||
|
new Thread(() -> {
|
||||||
|
try {
|
||||||
|
MonopolyServer.main(new String[0]); // Startet den MonopolyServer
|
||||||
|
} catch (Exception e) {
|
||||||
|
errorDialog("Fehler: Server konnte nicht gestartet werden.");
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MonopolyServer getMonopolyServer() {
|
||||||
|
return monopolyServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServerConnection getServerConnection() {
|
||||||
|
return serverConnection;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -21,7 +21,7 @@ import pp.dialog.SimpleDialog;
|
|||||||
class NetworkDialog extends SimpleDialog {
|
class NetworkDialog extends SimpleDialog {
|
||||||
private static final Logger LOGGER = System.getLogger(NetworkDialog.class.getName());
|
private static final Logger LOGGER = System.getLogger(NetworkDialog.class.getName());
|
||||||
private static final String LOCALHOST = "localhost";
|
private static final String LOCALHOST = "localhost";
|
||||||
private static final String DEFAULT_PORT = "1234";
|
private static final String DEFAULT_PORT = "42069";
|
||||||
private final NetworkSupport network;
|
private final NetworkSupport network;
|
||||||
private final TextField host = new TextField(LOCALHOST);
|
private final TextField host = new TextField(LOCALHOST);
|
||||||
private final TextField port = new TextField(DEFAULT_PORT);
|
private final TextField port = new TextField(DEFAULT_PORT);
|
||||||
|
@@ -18,7 +18,7 @@ import pp.monopoly.message.server.ServerMessage;
|
|||||||
* Manages the network connection for the Monopoly application.
|
* Manages the network connection for the Monopoly application.
|
||||||
* Handles connecting to and disconnecting from the server, and sending messages.
|
* Handles connecting to and disconnecting from the server, and sending messages.
|
||||||
*/
|
*/
|
||||||
class NetworkSupport implements MessageListener<Client>, ClientStateListener, ServerConnection {
|
public class NetworkSupport implements MessageListener<Client>, ClientStateListener, ServerConnection {
|
||||||
private static final Logger LOGGER = System.getLogger(NetworkSupport.class.getName());
|
private static final Logger LOGGER = System.getLogger(NetworkSupport.class.getName());
|
||||||
private final MonopolyApp app;
|
private final MonopolyApp app;
|
||||||
private Client client;
|
private Client client;
|
||||||
@@ -141,4 +141,40 @@ class NetworkSupport implements MessageListener<Client>, ClientStateListener, Se
|
|||||||
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,7 +1,6 @@
|
|||||||
package pp.monopoly.client;
|
package pp.monopoly.client;
|
||||||
|
|
||||||
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;
|
||||||
|
@@ -12,22 +12,21 @@ 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 pp.monopoly.client.MonopolyApp;
|
import pp.monopoly.client.MonopolyApp;
|
||||||
import pp.monopoly.client.StartMenu;
|
import pp.monopoly.client.StartMenu;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CreateGameMenu class represents the menu for creating a new game.
|
* CreateGameMenu class represents the menu for creating a new game.
|
||||||
*/
|
*/
|
||||||
public class CreateGameMenu {
|
public class CreateGameMenu {
|
||||||
|
|
||||||
private final MonopolyApp app;
|
private final MonopolyApp app;
|
||||||
private final Container menuContainer;
|
private final Container menuContainer;
|
||||||
private Geometry background;
|
private Geometry background;
|
||||||
|
private Label serverStatusLabel;
|
||||||
|
|
||||||
/**
|
|
||||||
* Konstruktor für das CreateGameMenu.
|
|
||||||
*
|
|
||||||
* @param app Die Hauptanwendung (MonopolyApp)
|
|
||||||
*/
|
|
||||||
public CreateGameMenu(MonopolyApp app) {
|
public CreateGameMenu(MonopolyApp app) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
|
|
||||||
@@ -39,8 +38,10 @@ public class CreateGameMenu {
|
|||||||
menuContainer.setPreferredSize(new Vector3f(600, 400, 0)); // Feste Größe des Containers
|
menuContainer.setPreferredSize(new Vector3f(600, 400, 0)); // Feste Größe des Containers
|
||||||
|
|
||||||
// Titel
|
// Titel
|
||||||
Label title = menuContainer.addChild(new Label("Neues Spiel"));
|
Label title = menuContainer.addChild(new Label("Neues Spiel", new ElementId("header")));
|
||||||
title.setFontSize(48);
|
title.setFont(app.getAssetManager().loadFont("Interface/Fonts/Metropolis/Metropolis-Bold-42.fnt"));
|
||||||
|
title.setFontSize(50);
|
||||||
|
|
||||||
|
|
||||||
// Eingabefelder-Container
|
// Eingabefelder-Container
|
||||||
Container inputContainer = menuContainer.addChild(new Container(new SpringGridLayout(Axis.Y, Axis.X)));
|
Container inputContainer = menuContainer.addChild(new Container(new SpringGridLayout(Axis.Y, Axis.X)));
|
||||||
@@ -48,12 +49,12 @@ public class CreateGameMenu {
|
|||||||
inputContainer.setLocalTranslation(20, 0, 0); // Abstand vom Rand
|
inputContainer.setLocalTranslation(20, 0, 0); // Abstand vom Rand
|
||||||
|
|
||||||
inputContainer.addChild(new Label("Server-Adresse:"));
|
inputContainer.addChild(new Label("Server-Adresse:"));
|
||||||
TextField serverAddressField = inputContainer.addChild(new TextField("localhost"));
|
TextField playerNameField = inputContainer.addChild(new TextField("localhost"));
|
||||||
serverAddressField.setPreferredWidth(400); // Breite des Textfelds
|
playerNameField.setPreferredWidth(400); // Breite des Textfelds
|
||||||
|
|
||||||
inputContainer.addChild(new Label("Port:"));
|
inputContainer.addChild(new Label("Port:"));
|
||||||
TextField portField = inputContainer.addChild(new TextField("42069"));
|
TextField serverAddressField = inputContainer.addChild(new TextField("42069"));
|
||||||
portField.setPreferredWidth(400); // Breite des Textfelds
|
serverAddressField.setPreferredWidth(400); // Breite des Textfelds
|
||||||
|
|
||||||
// Button-Container
|
// Button-Container
|
||||||
Container buttonContainer = menuContainer.addChild(new Container(new SpringGridLayout(Axis.X, Axis.Y)));
|
Container buttonContainer = menuContainer.addChild(new Container(new SpringGridLayout(Axis.X, Axis.Y)));
|
||||||
@@ -65,25 +66,49 @@ public class CreateGameMenu {
|
|||||||
cancelButton.setPreferredSize(new Vector3f(120, 40, 0));
|
cancelButton.setPreferredSize(new Vector3f(120, 40, 0));
|
||||||
cancelButton.addClickCommands(source -> goBackToStartMenu());
|
cancelButton.addClickCommands(source -> goBackToStartMenu());
|
||||||
|
|
||||||
// "Spiel hosten"-Button
|
// "Selber hosten"-Button
|
||||||
Button hostButton = buttonContainer.addChild(new Button("Spiel hosten"));
|
Button hostButton = buttonContainer.addChild(new Button("Selber hosten"));
|
||||||
hostButton.setPreferredSize(new Vector3f(120, 40, 0));
|
hostButton.setPreferredSize(new Vector3f(120, 40, 0));
|
||||||
hostButton.addClickCommands(source -> {
|
hostButton.addClickCommands(source -> app.getNetworkSupport().startServerAndJoin());
|
||||||
closeCreateGameMenu(); // Schließt das Menü
|
|
||||||
app.startTestWorld(); // Starte die TestWorld im selben Fenster
|
|
||||||
});
|
|
||||||
|
|
||||||
// "Beitreten"-Button
|
// "Beitreten"-Button
|
||||||
Button joinButton = buttonContainer.addChild(new Button("Beitreten"));
|
Button joinButton = buttonContainer.addChild(new Button("Beitreten"));
|
||||||
joinButton.setPreferredSize(new Vector3f(120, 40, 0));
|
joinButton.setPreferredSize(new Vector3f(120, 40, 0));
|
||||||
// Placeholder für die Beitrittslogik
|
joinButton.addClickCommands(source -> {
|
||||||
|
try {
|
||||||
|
String host = playerNameField.getText().trim();
|
||||||
|
int port = Integer.parseInt(serverAddressField.getText().trim());
|
||||||
|
app.getNetworkSupport().connectToServer(host, port);
|
||||||
|
|
||||||
|
// 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.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Serverstatus-Label
|
||||||
|
serverStatusLabel = menuContainer.addChild(new Label("Serverstatus: Noch nicht gestartet"));
|
||||||
|
serverStatusLabel.setFontSize(24);
|
||||||
|
|
||||||
// Zentrierung des Containers
|
// Zentrierung des Containers
|
||||||
menuContainer.setLocalTranslation(
|
menuContainer.setLocalTranslation(
|
||||||
(app.getCamera().getWidth() - menuContainer.getPreferredSize().x) / 2,
|
(app.getCamera().getWidth() - menuContainer.getPreferredSize().x) / 2,
|
||||||
(app.getCamera().getHeight() + menuContainer.getPreferredSize().y) / 2,
|
(app.getCamera().getHeight() + menuContainer.getPreferredSize().y) / 2,
|
||||||
1 // Höhere Z-Ebene für den Vordergrund
|
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");
|
||||||
|
|
||||||
app.getGuiNode().attachChild(menuContainer);
|
app.getGuiNode().attachChild(menuContainer);
|
||||||
}
|
}
|
||||||
@@ -107,15 +132,8 @@ public class CreateGameMenu {
|
|||||||
* Geht zum Startmenü zurück, wenn "Abbrechen" angeklickt wird.
|
* Geht zum Startmenü zurück, wenn "Abbrechen" angeklickt wird.
|
||||||
*/
|
*/
|
||||||
private void goBackToStartMenu() {
|
private void goBackToStartMenu() {
|
||||||
closeCreateGameMenu(); // Schließt das Menü
|
app.getGuiNode().detachChild(menuContainer);
|
||||||
StartMenu.createStartMenu(app); // Zeige das Startmenü
|
app.getGuiNode().detachChild(background); // Entfernt das Hintergrundbild
|
||||||
}
|
StartMenu.createStartMenu(app);
|
||||||
|
|
||||||
/**
|
|
||||||
* Entfernt das CreateGameMenu und dessen Hintergrund.
|
|
||||||
*/
|
|
||||||
private void closeCreateGameMenu() {
|
|
||||||
app.getGuiNode().detachChild(menuContainer); // Entfernt den Menü-Container
|
|
||||||
app.getGuiNode().detachChild(background); // Entfernt das Hintergrundbild
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,51 +0,0 @@
|
|||||||
package pp.monopoly.client.gui;
|
|
||||||
|
|
||||||
|
|
||||||
import com.jme3.math.ColorRGBA;
|
|
||||||
import com.simsilica.lemur.Button;
|
|
||||||
import com.simsilica.lemur.Label;
|
|
||||||
import com.simsilica.lemur.style.ElementId;
|
|
||||||
|
|
||||||
import pp.dialog.Dialog;
|
|
||||||
import pp.monopoly.client.MonopolyApp;
|
|
||||||
|
|
||||||
public class GameMenu extends Dialog {
|
|
||||||
private final MonopolyApp app;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs the SettingsMenu dialog for the Monopoly application.
|
|
||||||
*
|
|
||||||
* @param app the MonopolyApp instance
|
|
||||||
*/
|
|
||||||
public GameMenu(MonopolyApp app) {
|
|
||||||
super(app.getDialogManager());
|
|
||||||
this.app = app;
|
|
||||||
|
|
||||||
// Add a title label for Settings
|
|
||||||
Label settingsTitle = new Label("Einstellungen", new ElementId("settings-title"));
|
|
||||||
settingsTitle.setFontSize(48); // Set font size for the title
|
|
||||||
settingsTitle.setColor(ColorRGBA.White);
|
|
||||||
|
|
||||||
// Add any settings-related components here, such as volume control, toggles, etc.
|
|
||||||
|
|
||||||
// Add a back button to return to StartMenu
|
|
||||||
Button backButton = new Button("Zurück", new ElementId("menu-button"));
|
|
||||||
backButton.setColor(ColorRGBA.White);
|
|
||||||
backButton.setFontSize(24);
|
|
||||||
backButton.addClickCommands(source -> returnToStartMenu());
|
|
||||||
|
|
||||||
// Add components to this dialog
|
|
||||||
addChild(settingsTitle);
|
|
||||||
addChild(backButton);
|
|
||||||
|
|
||||||
// You can add more settings components here, like checkboxes or sliders.
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns to the StartMenu when the back button is clicked.
|
|
||||||
*/
|
|
||||||
private void returnToStartMenu() {
|
|
||||||
app.getDialogManager().close(this); // Close the current settings dialog
|
|
||||||
//TODO return zum Ausgangsmenü
|
|
||||||
}
|
|
||||||
}
|
|
@@ -0,0 +1,99 @@
|
|||||||
|
package pp.monopoly.client.gui;
|
||||||
|
|
||||||
|
import com.jme3.material.Material;
|
||||||
|
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.Container;
|
||||||
|
import com.simsilica.lemur.Label;
|
||||||
|
import com.simsilica.lemur.component.SpringGridLayout;
|
||||||
|
|
||||||
|
import pp.monopoly.client.MonopolyApp;
|
||||||
|
|
||||||
|
public class LobbyMenu {
|
||||||
|
|
||||||
|
private final MonopolyApp app;
|
||||||
|
private final Container menuContainer;
|
||||||
|
private Geometry background;
|
||||||
|
|
||||||
|
public LobbyMenu(MonopolyApp app) {
|
||||||
|
this.app = app;
|
||||||
|
|
||||||
|
// Entfernt das CreateGameMenu (inklusive Hintergrund)
|
||||||
|
app.getGuiNode().detachAllChildren();
|
||||||
|
|
||||||
|
// Hintergrundbild laden und hinzufügen
|
||||||
|
addBackgroundImage();
|
||||||
|
|
||||||
|
// 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("Lobby"));
|
||||||
|
title.setFontSize(48);
|
||||||
|
|
||||||
|
// Spielerstatus anzeigen
|
||||||
|
Container playerListContainer = menuContainer.addChild(new Container(new SpringGridLayout(Axis.Y, Axis.X)));
|
||||||
|
playerListContainer.addChild(new Label("Spieler in der Lobby:"));
|
||||||
|
Label playersLabel = playerListContainer.addChild(new Label("Noch keine Spieler verbunden.")); // Beispieltext
|
||||||
|
|
||||||
|
// Buttons
|
||||||
|
Container buttonContainer = menuContainer.addChild(new Container(new SpringGridLayout(Axis.X, Axis.Y)));
|
||||||
|
buttonContainer.setPreferredSize(new Vector3f(400, 50, 0));
|
||||||
|
|
||||||
|
// "Bereit"-Button
|
||||||
|
Button readyButton = buttonContainer.addChild(new Button("Bereit"));
|
||||||
|
readyButton.setPreferredSize(new Vector3f(120, 40, 0));
|
||||||
|
readyButton.addClickCommands(source -> toggleReady(playersLabel));
|
||||||
|
|
||||||
|
// "Zurück"-Button
|
||||||
|
Button backButton = buttonContainer.addChild(new Button("Zurück"));
|
||||||
|
backButton.setPreferredSize(new Vector3f(120, 40, 0));
|
||||||
|
backButton.addClickCommands(source -> goBackToCreateGame());
|
||||||
|
|
||||||
|
// 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.getGuiNode().attachChild(menuContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lädt das Hintergrundbild und fügt es als geometrische Ebene hinzu.
|
||||||
|
*/
|
||||||
|
private void addBackgroundImage() {
|
||||||
|
Texture backgroundImage = app.getAssetManager().loadTexture("Pictures/unibw-Bib2.png");
|
||||||
|
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
|
||||||
|
background = new Geometry("Background", quad);
|
||||||
|
Material backgroundMaterial = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
|
||||||
|
backgroundMaterial.setTexture("ColorMap", backgroundImage);
|
||||||
|
background.setMaterial(backgroundMaterial);
|
||||||
|
background.setLocalTranslation(0, 0, -1); // Hintergrundebene
|
||||||
|
|
||||||
|
app.getGuiNode().attachChild(background);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schaltet den "Bereit"-Status um.
|
||||||
|
*/
|
||||||
|
private void toggleReady(Label playersLabel) {
|
||||||
|
// Beispiel-Logik für das Umschalten des Status
|
||||||
|
playersLabel.setText("Spielerstatus aktualisiert."); // Beispieltext
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Geht zurück zum CreateGameMenu.
|
||||||
|
*/
|
||||||
|
private void goBackToCreateGame() {
|
||||||
|
app.getGuiNode().detachChild(menuContainer);
|
||||||
|
app.getGuiNode().detachChild(background); // Entfernt das Hintergrundbild
|
||||||
|
new CreateGameMenu(app);
|
||||||
|
}
|
||||||
|
}
|
@@ -3,6 +3,7 @@ package pp.monopoly.client.gui;
|
|||||||
import com.jme3.material.Material;
|
import com.jme3.material.Material;
|
||||||
import com.jme3.material.RenderState.BlendMode;
|
import com.jme3.material.RenderState.BlendMode;
|
||||||
import com.jme3.math.ColorRGBA;
|
import com.jme3.math.ColorRGBA;
|
||||||
|
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.simsilica.lemur.Button;
|
import com.simsilica.lemur.Button;
|
||||||
@@ -12,7 +13,9 @@ import com.simsilica.lemur.Label;
|
|||||||
import com.simsilica.lemur.Slider;
|
import com.simsilica.lemur.Slider;
|
||||||
import com.simsilica.lemur.component.QuadBackgroundComponent;
|
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 pp.dialog.Dialog;
|
import pp.dialog.Dialog;
|
||||||
import pp.monopoly.client.MonopolyApp;
|
import pp.monopoly.client.MonopolyApp;
|
||||||
|
|
||||||
@@ -23,6 +26,7 @@ public class SettingsMenu extends Dialog {
|
|||||||
private final MonopolyApp app;
|
private final MonopolyApp app;
|
||||||
private final Geometry overlayBackground;
|
private final Geometry overlayBackground;
|
||||||
private final Container settingsContainer;
|
private final Container settingsContainer;
|
||||||
|
private final Container backgroundContainer;
|
||||||
|
|
||||||
public SettingsMenu(MonopolyApp app) {
|
public SettingsMenu(MonopolyApp app) {
|
||||||
super(app.getDialogManager());
|
super(app.getDialogManager());
|
||||||
@@ -32,10 +36,17 @@ public class SettingsMenu extends Dialog {
|
|||||||
overlayBackground = createOverlayBackground();
|
overlayBackground = createOverlayBackground();
|
||||||
app.getGuiNode().attachChild(overlayBackground);
|
app.getGuiNode().attachChild(overlayBackground);
|
||||||
|
|
||||||
|
// Create the background container
|
||||||
|
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ü
|
// 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)));
|
settingsContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.1f, 0.1f, 0.1f, 0.9f)));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Titel
|
// Titel
|
||||||
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);
|
||||||
@@ -44,24 +55,59 @@ public class SettingsMenu extends Dialog {
|
|||||||
Container effectSoundContainer = settingsContainer.addChild(new Container());
|
Container effectSoundContainer = settingsContainer.addChild(new Container());
|
||||||
effectSoundContainer.addChild(new Label("Effekt Sound", new ElementId("label")));
|
effectSoundContainer.addChild(new Label("Effekt Sound", new ElementId("label")));
|
||||||
effectSoundContainer.addChild(new Slider());
|
effectSoundContainer.addChild(new Slider());
|
||||||
effectSoundContainer.addChild(new Checkbox("Aktivieren")).setChecked(true);
|
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
|
// Hintergrundmusik: Slider und Checkbox
|
||||||
Container backgroundMusicContainer = settingsContainer.addChild(new Container());
|
Container backgroundMusicContainer = settingsContainer.addChild(new Container());
|
||||||
backgroundMusicContainer.addChild(new Label("Hintergrund Musik", new ElementId("label")));
|
backgroundMusicContainer.addChild(new Label("Hintergrund Musik", new ElementId("label")));
|
||||||
backgroundMusicContainer.addChild(new Slider());
|
backgroundMusicContainer.addChild(new Slider());
|
||||||
backgroundMusicContainer.addChild(new Checkbox("Aktivieren")).setChecked(true);
|
backgroundMusicContainer.addChild(new Checkbox("Musik an")).setChecked(true);
|
||||||
|
backgroundMusicContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
|
||||||
|
|
||||||
|
/*Selector<String> dropdown = new Selector<>();
|
||||||
|
backgroundMusicContainer.addChild(dropdown);
|
||||||
|
|
||||||
|
Vector3f dimens = settingsContainer.getPreferredSize();
|
||||||
|
Vector3f dimens2 = dropdown.getPopupContainer().getPreferredSize();
|
||||||
|
dimens2.setX(dimens.getX());
|
||||||
|
dropdown.getPopupContainer().setPreferredSize(dimens2);*/
|
||||||
|
// Create the dropdown menu
|
||||||
|
Selector<String> dropdown = new Selector<>();
|
||||||
|
|
||||||
|
// Generate and add numbered examples to the dropdown
|
||||||
|
for (int i = 1; i <= 10; i++) { // Generate 10 examples
|
||||||
|
dropdown.getModel().add("Example " + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Add the dropdown to the container
|
||||||
|
backgroundMusicContainer.addChild(dropdown);
|
||||||
|
|
||||||
|
// Adjust the dropdown's popup container size if necessary
|
||||||
|
Vector3f dimens = settingsContainer.getPreferredSize();
|
||||||
|
Vector3f dimens2 = dropdown.getPopupContainer().getPreferredSize();
|
||||||
|
dimens2.setX(dimens.getX());
|
||||||
|
dropdown.getPopupContainer().setPreferredSize(dimens2);
|
||||||
// Beenden-Button
|
// 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.addClickCommands(source -> app.stop());
|
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ü
|
// 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
|
4
|
||||||
|
);
|
||||||
|
|
||||||
|
backgroundContainer.setLocalTranslation(
|
||||||
|
(app.getCamera().getWidth() - settingsContainer.getPreferredSize().x - padding) / 2,
|
||||||
|
(app.getCamera().getHeight() + settingsContainer.getPreferredSize().y+ padding) / 2,
|
||||||
|
3
|
||||||
);
|
);
|
||||||
|
|
||||||
app.getGuiNode().attachChild(settingsContainer);
|
app.getGuiNode().attachChild(settingsContainer);
|
||||||
@@ -90,6 +136,7 @@ public class SettingsMenu extends Dialog {
|
|||||||
public void close() {
|
public void close() {
|
||||||
System.out.println("Schließe SettingsMenu..."); // Debugging-Ausgabe
|
System.out.println("Schließe SettingsMenu..."); // Debugging-Ausgabe
|
||||||
app.getGuiNode().detachChild(settingsContainer); // Entferne das Menü
|
app.getGuiNode().detachChild(settingsContainer); // Entferne das Menü
|
||||||
|
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
|
||||||
|
@@ -80,7 +80,7 @@ public class TestWorld {
|
|||||||
|
|
||||||
// Setze das Material mit Textur
|
// Setze das Material mit Textur
|
||||||
Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
|
Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
|
||||||
Texture texture = app.getAssetManager().loadTexture("Pictures/board.png");
|
Texture texture = app.getAssetManager().loadTexture("Pictures/board2.png");
|
||||||
mat.setTexture("ColorMap", texture);
|
mat.setTexture("ColorMap", texture);
|
||||||
geom.setMaterial(mat);
|
geom.setMaterial(mat);
|
||||||
|
|
||||||
|
@@ -3,20 +3,22 @@ package pp.monopoly.client.gui;
|
|||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import com.jme3.font.BitmapText;
|
import com.jme3.font.BitmapText;
|
||||||
|
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.simsilica.lemur.Axis;
|
import com.simsilica.lemur.*;
|
||||||
import com.simsilica.lemur.Button;
|
import com.simsilica.lemur.component.QuadBackgroundComponent;
|
||||||
import com.simsilica.lemur.Container;
|
|
||||||
import com.simsilica.lemur.component.SpringGridLayout;
|
import com.simsilica.lemur.component.SpringGridLayout;
|
||||||
|
|
||||||
|
import com.simsilica.lemur.style.ElementId;
|
||||||
|
import pp.dialog.Dialog;
|
||||||
import pp.monopoly.client.MonopolyApp;
|
import pp.monopoly.client.MonopolyApp;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toolbar Klasse, die am unteren Rand der Szene angezeigt wird.
|
* Toolbar Klasse, die am unteren Rand der Szene angezeigt wird.
|
||||||
* Die Buttons bewegen den Würfel auf dem Spielfeld.
|
* Die Buttons bewegen den Würfel auf dem Spielfeld.
|
||||||
*/
|
*/
|
||||||
public class Toolbar {
|
public class Toolbar extends Dialog {
|
||||||
|
|
||||||
private final MonopolyApp app;
|
private final MonopolyApp app;
|
||||||
private final Container toolbarContainer;
|
private final Container toolbarContainer;
|
||||||
@@ -35,6 +37,7 @@ public class Toolbar {
|
|||||||
* @param cube Der Würfel, der bewegt werden soll
|
* @param cube Der Würfel, der bewegt werden soll
|
||||||
*/
|
*/
|
||||||
public Toolbar(MonopolyApp app, Geometry cube) {
|
public Toolbar(MonopolyApp app, Geometry cube) {
|
||||||
|
super(app.getDialogManager());
|
||||||
this.app = app;
|
this.app = app;
|
||||||
this.cube = cube;
|
this.cube = cube;
|
||||||
|
|
||||||
@@ -44,13 +47,41 @@ public class Toolbar {
|
|||||||
// Setze die Position am unteren Rand und die Breite
|
// Setze die Position am unteren Rand und die Breite
|
||||||
toolbarContainer.setLocalTranslation(
|
toolbarContainer.setLocalTranslation(
|
||||||
0, // Links bündig
|
0, // Links bündig
|
||||||
100, // Höhe über dem unteren Rand
|
200, // Höhe über dem unteren Rand
|
||||||
0 // Z-Ebene
|
0 // Z-Ebene
|
||||||
);
|
);
|
||||||
toolbarContainer.setPreferredSize(new Vector3f(app.getCamera().getWidth(), 100, 0)); // Volle Breite
|
toolbarContainer.setPreferredSize(new Vector3f(app.getCamera().getWidth(), 200, 0)); // Volle Breite
|
||||||
|
|
||||||
|
// Hintergrund Grau
|
||||||
|
toolbarContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f)));
|
||||||
|
|
||||||
// Füge Buttons zur Toolbar hinzu
|
// Füge Buttons zur Toolbar hinzu
|
||||||
initializeButtons();
|
//initializeButtons();
|
||||||
|
|
||||||
|
|
||||||
|
// Menü-Container: Ein Nested-Container für Kontostand und "Meine Gulag Frei Karten"
|
||||||
|
Container accountContainer = toolbarContainer.addChild(new Container());
|
||||||
|
accountContainer.addChild(new Label("Kontostand", new ElementId("label")));
|
||||||
|
accountContainer.addChild(new Label("Gulag Frei Karten", new ElementId("label")));
|
||||||
|
accountContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
|
||||||
|
|
||||||
|
// Menü-Container: Ein Container für Übersicht
|
||||||
|
Container overviewContainer = toolbarContainer.addChild(new Container());
|
||||||
|
overviewContainer.addChild(new Label("Übersicht", new ElementId("label")));
|
||||||
|
overviewContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
|
||||||
|
|
||||||
|
// Menü-Container: Ein Container für Würfel
|
||||||
|
Container diceContainer = toolbarContainer.addChild(new Container());
|
||||||
|
diceContainer.addChild(new Label("Wo Würfel?", new ElementId("label")));
|
||||||
|
diceContainer.addChild(new Button("Würfeln"));
|
||||||
|
diceContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
|
||||||
|
|
||||||
|
// Menü-Container: Ein Nested-Container für Handeln, Grundstücke und Zug beenden
|
||||||
|
Container menuContainer = toolbarContainer.addChild(new Container());
|
||||||
|
menuContainer.addChild(new Button("Handeln"));
|
||||||
|
menuContainer.addChild(new Button("Grundstücke"));
|
||||||
|
menuContainer.addChild(new Button("Zug beenden"));
|
||||||
|
menuContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
|
||||||
|
|
||||||
// Füge die Toolbar zur GUI hinzu
|
// Füge die Toolbar zur GUI hinzu
|
||||||
app.getGuiNode().attachChild(toolbarContainer);
|
app.getGuiNode().attachChild(toolbarContainer);
|
||||||
@@ -64,9 +95,10 @@ public class Toolbar {
|
|||||||
* Initialisiert die Buttons in der Toolbar.
|
* Initialisiert die Buttons in der Toolbar.
|
||||||
*/
|
*/
|
||||||
private void initializeButtons() {
|
private void initializeButtons() {
|
||||||
addButton("Vorwärts", 1); // Bewegung nach vorne
|
addTradeMenuButton(); // Bewegung nach vorne
|
||||||
addButton("Rückwärts", -1); // Bewegung nach hinten
|
addEndTurnButton(); // Bewegung nach hinten
|
||||||
addDiceRollButton(); // Würfel-Button
|
addDiceRollButton(); // Würfel-Button
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -75,12 +107,13 @@ public class Toolbar {
|
|||||||
* @param label Der Text des Buttons
|
* @param label Der Text des Buttons
|
||||||
* @param step Schrittweite (+1 für vorwärts, -1 für rückwärts)
|
* @param step Schrittweite (+1 für vorwärts, -1 für rückwärts)
|
||||||
*/
|
*/
|
||||||
private void addButton(String label, int step) {
|
|
||||||
|
/*private void addButton(String label, int step) {
|
||||||
Button button = new Button(label);
|
Button button = new Button(label);
|
||||||
button.setPreferredSize(new Vector3f(150, 50, 0)); // Größe der Buttons
|
button.setPreferredSize(new Vector3f(150, 50, 0)); // Größe der Buttons
|
||||||
button.addClickCommands(source -> moveCube(step));
|
button.addClickCommands(source -> moveCube(step));
|
||||||
toolbarContainer.addChild(button);
|
toolbarContainer.addChild(button);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fügt den Würfel-Button hinzu, der die Figur entsprechend der gewürfelten Zahl bewegt.
|
* Fügt den Würfel-Button hinzu, der die Figur entsprechend der gewürfelten Zahl bewegt.
|
||||||
@@ -92,6 +125,27 @@ public class Toolbar {
|
|||||||
toolbarContainer.addChild(diceButton);
|
toolbarContainer.addChild(diceButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addTradeMenuButton() {
|
||||||
|
Button diceButton = new Button("Handeln");
|
||||||
|
diceButton.setPreferredSize(new Vector3f(150, 50, 0)); // Größe des Buttons
|
||||||
|
diceButton.addClickCommands(source -> rollDice());
|
||||||
|
toolbarContainer.addChild(diceButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addEndTurnButton() {
|
||||||
|
Button diceButton = new Button("Grundstücke");
|
||||||
|
diceButton.setPreferredSize(new Vector3f(150, 50, 0)); // Größe des Buttons
|
||||||
|
diceButton.addClickCommands(source -> rollDice());
|
||||||
|
toolbarContainer.addChild(diceButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addPropertyMenuButton() {
|
||||||
|
Button diceButton = new Button("Zug beenden");
|
||||||
|
diceButton.setPreferredSize(new Vector3f(150, 50, 0)); // Größe des Buttons
|
||||||
|
diceButton.addClickCommands(source -> rollDice());
|
||||||
|
toolbarContainer.addChild(diceButton);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simuliert einen Würfelwurf und bewegt die Figur entsprechend.
|
* Simuliert einen Würfelwurf und bewegt die Figur entsprechend.
|
||||||
*/
|
*/
|
||||||
|
@@ -0,0 +1,168 @@
|
|||||||
|
package pp.monopoly.client.gui;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import com.jme3.font.BitmapText;
|
||||||
|
import com.jme3.math.Vector3f;
|
||||||
|
import com.jme3.scene.Geometry;
|
||||||
|
import com.simsilica.lemur.Axis;
|
||||||
|
import com.simsilica.lemur.Button;
|
||||||
|
import com.simsilica.lemur.Container;
|
||||||
|
import com.simsilica.lemur.component.SpringGridLayout;
|
||||||
|
|
||||||
|
import pp.monopoly.client.MonopolyApp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toolbar Klasse, die am unteren Rand der Szene angezeigt wird.
|
||||||
|
* Die Buttons bewegen den Würfel auf dem Spielfeld.
|
||||||
|
*/
|
||||||
|
public class Toolbar2 {
|
||||||
|
|
||||||
|
private final MonopolyApp app;
|
||||||
|
private final Container toolbarContainer;
|
||||||
|
private final Geometry cube; // Referenz auf den Würfel
|
||||||
|
private final BitmapText positionText; // Anzeige für die aktuelle Position
|
||||||
|
private final float boardLimit = 0.95f; // Grenzen des Bretts
|
||||||
|
private final float stepSize = 0.18f; // Schrittgröße pro Bewegung
|
||||||
|
private int currentPosition = 0; // Aktuelle Position auf dem Spielfeld
|
||||||
|
private final int positionsPerSide = 10; // Anzahl der Positionen pro Seite
|
||||||
|
private final Random random = new Random(); // Zufallsgenerator für den Würfelwurf
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Konstruktor für die Toolbar.
|
||||||
|
*
|
||||||
|
* @param app Die Hauptanwendung (MonopolyApp)
|
||||||
|
* @param cube Der Würfel, der bewegt werden soll
|
||||||
|
*/
|
||||||
|
public Toolbar2(MonopolyApp app, Geometry cube) {
|
||||||
|
this.app = app;
|
||||||
|
this.cube = cube;
|
||||||
|
|
||||||
|
// Erstelle die Toolbar
|
||||||
|
toolbarContainer = new Container(new SpringGridLayout(Axis.X, Axis.Y));
|
||||||
|
|
||||||
|
// Setze die Position am unteren Rand und die Breite
|
||||||
|
toolbarContainer.setLocalTranslation(
|
||||||
|
0, // Links bündig
|
||||||
|
100, // Höhe über dem unteren Rand
|
||||||
|
0 // Z-Ebene
|
||||||
|
);
|
||||||
|
toolbarContainer.setPreferredSize(new Vector3f(app.getCamera().getWidth(), 100, 0)); // Volle Breite
|
||||||
|
|
||||||
|
// Füge Buttons zur Toolbar hinzu
|
||||||
|
initializeButtons();
|
||||||
|
|
||||||
|
// Füge die Toolbar zur GUI hinzu
|
||||||
|
app.getGuiNode().attachChild(toolbarContainer);
|
||||||
|
|
||||||
|
// Erstelle die Position-Anzeige
|
||||||
|
positionText = createPositionDisplay();
|
||||||
|
updatePositionDisplay(); // Initialisiere die Anzeige mit der Startposition
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialisiert die Buttons in der Toolbar.
|
||||||
|
*/
|
||||||
|
private void initializeButtons() {
|
||||||
|
addButton("Vorwärts", 1); // Bewegung nach vorne
|
||||||
|
addButton("Rückwärts", -1); // Bewegung nach hinten
|
||||||
|
addDiceRollButton(); // Würfel-Button
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fügt einen Button mit einer Bewegung hinzu.
|
||||||
|
*
|
||||||
|
* @param label Der Text des Buttons
|
||||||
|
* @param step Schrittweite (+1 für vorwärts, -1 für rückwärts)
|
||||||
|
*/
|
||||||
|
private void addButton(String label, int step) {
|
||||||
|
Button button = new Button(label);
|
||||||
|
button.setPreferredSize(new Vector3f(150, 50, 0)); // Größe der Buttons
|
||||||
|
button.addClickCommands(source -> moveCube(step));
|
||||||
|
toolbarContainer.addChild(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fügt den Würfel-Button hinzu, der die Figur entsprechend der gewürfelten Zahl bewegt.
|
||||||
|
*/
|
||||||
|
private void addDiceRollButton() {
|
||||||
|
Button diceButton = new Button("Würfeln");
|
||||||
|
diceButton.setPreferredSize(new Vector3f(150, 50, 0)); // Größe des Buttons
|
||||||
|
diceButton.addClickCommands(source -> rollDice());
|
||||||
|
toolbarContainer.addChild(diceButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simuliert einen Würfelwurf und bewegt die Figur entsprechend.
|
||||||
|
*/
|
||||||
|
private void rollDice() {
|
||||||
|
int diceRoll = random.nextInt(6) + 1; // Zahl zwischen 1 und 6
|
||||||
|
System.out.println("Gewürfelt: " + diceRoll);
|
||||||
|
moveCube(diceRoll); // Bewege die Figur um die gewürfelte Zahl
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bewegt den Würfel basierend auf der aktuellen Position auf dem Brett.
|
||||||
|
*
|
||||||
|
* @param step Schrittweite (+1 für vorwärts, -1 für rückwärts oder andere Werte)
|
||||||
|
*/
|
||||||
|
private void moveCube(int step) {
|
||||||
|
currentPosition = (currentPosition + step + 4 * positionsPerSide) % (4 * positionsPerSide);
|
||||||
|
Vector3f newPosition = calculatePosition(currentPosition);
|
||||||
|
cube.setLocalTranslation(newPosition);
|
||||||
|
updatePositionDisplay(); // Aktualisiere die Positionsanzeige
|
||||||
|
System.out.println("Würfelposition: " + newPosition + " (Feld-ID: " + currentPosition + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Berechnet die neue Position des Würfels basierend auf der aktuellen Brettseite und Position.
|
||||||
|
*
|
||||||
|
* @param position Aktuelle Position auf dem Spielfeld
|
||||||
|
* @return Die berechnete Position als Vector3f
|
||||||
|
*/
|
||||||
|
private Vector3f calculatePosition(int position) {
|
||||||
|
int side = position / positionsPerSide; // Seite des Bretts (0 = unten, 1 = rechts, 2 = oben, 3 = links)
|
||||||
|
int offset = position % positionsPerSide; // Position auf der aktuellen Seite
|
||||||
|
|
||||||
|
switch (side) {
|
||||||
|
case 0: // Unten (positive x-Achse)
|
||||||
|
return new Vector3f(-boardLimit + offset * stepSize, 0.1f, -boardLimit + 0.05f);
|
||||||
|
case 1: // Rechts (positive z-Achse)
|
||||||
|
return new Vector3f(boardLimit - 0.05f, 0.1f, -boardLimit + offset * stepSize);
|
||||||
|
case 2: // Oben (negative x-Achse)
|
||||||
|
return new Vector3f(boardLimit - offset * stepSize, 0.1f, boardLimit - 0.05f);
|
||||||
|
case 3: // Links (negative z-Achse)
|
||||||
|
return new Vector3f(-boardLimit + 0.05f, 0.1f, boardLimit - offset * stepSize);
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Ungültige Position: " + position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Erstellt die Anzeige für die aktuelle Position.
|
||||||
|
*
|
||||||
|
* @return Das BitmapText-Objekt für die Anzeige
|
||||||
|
*/
|
||||||
|
private BitmapText createPositionDisplay() {
|
||||||
|
BitmapText text = new BitmapText(app.getAssetManager().loadFont("Interface/Fonts/Default.fnt"), false);
|
||||||
|
text.setSize(20); // Schriftgröße
|
||||||
|
text.setLocalTranslation(10, app.getCamera().getHeight() - 10, 0); // Oben links
|
||||||
|
app.getGuiNode().attachChild(text);
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aktualisiert die Anzeige für die aktuelle Position.
|
||||||
|
*/
|
||||||
|
private void updatePositionDisplay() {
|
||||||
|
positionText.setText("Feld-ID: " + currentPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entfernt die Toolbar.
|
||||||
|
*/
|
||||||
|
public void remove() {
|
||||||
|
app.getGuiNode().detachChild(toolbarContainer);
|
||||||
|
app.getGuiNode().detachChild(positionText);
|
||||||
|
}
|
||||||
|
}
|
BIN
Projekte/monopoly/client/src/main/resources/Pictures/board2.png
Normal file
BIN
Projekte/monopoly/client/src/main/resources/Pictures/board2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 MiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Projekte/monopoly/client/src/main/resources/Sound/background.ogg
Normal file
BIN
Projekte/monopoly/client/src/main/resources/Sound/background.ogg
Normal file
Binary file not shown.
@@ -7,13 +7,10 @@
|
|||||||
|
|
||||||
package pp.monopoly;
|
package pp.monopoly;
|
||||||
|
|
||||||
import pp.util.config.Config;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.TreeMap;
|
|
||||||
|
|
||||||
import static java.lang.Math.max;
|
import static java.lang.Math.max;
|
||||||
|
|
||||||
|
import pp.util.config.Config;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides access to the configuration settings for the Monopoly game.
|
* Provides access to the configuration settings for the Monopoly game.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -31,19 +28,19 @@ 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 = 1234;
|
private int port = 4321;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The width of the game map in terms of grid units.
|
* The width of the game map in terms of grid units.
|
||||||
*/
|
*/
|
||||||
@Property("map.width")
|
@Property("map.width")
|
||||||
private int mapWidth = 10;
|
private int mapWidth = 12;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The height of the game map in terms of grid units.
|
* The height of the game map in terms of grid units.
|
||||||
*/
|
*/
|
||||||
@Property("map.height")
|
@Property("map.height")
|
||||||
private int mapHeight = 10;
|
private int mapHeight = 12;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an instance of {@code MonopolyConfig} with default settings.
|
* Creates an instance of {@code MonopolyConfig} with default settings.
|
||||||
|
@@ -50,6 +50,14 @@ public class PlayerHandler {
|
|||||||
return players.size();
|
return players.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retuns all players
|
||||||
|
* @return List of all players
|
||||||
|
*/
|
||||||
|
public List<Player> getPlayers() {
|
||||||
|
return players;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Chechs if all players are ready to start the game
|
* Chechs if all players are ready to start the game
|
||||||
* @return {@code true} if all players are ready, otherwise {@code false}
|
* @return {@code true} if all players are ready, otherwise {@code false}
|
||||||
|
@@ -1,7 +1,18 @@
|
|||||||
package pp.monopoly.game.server;
|
package pp.monopoly.game.server;
|
||||||
|
|
||||||
|
import java.lang.System.Logger;
|
||||||
|
import java.lang.System.Logger.Level;
|
||||||
|
|
||||||
import pp.monopoly.MonopolyConfig;
|
import pp.monopoly.MonopolyConfig;
|
||||||
import pp.monopoly.message.client.*;
|
import pp.monopoly.message.client.BuyPropertyRequest;
|
||||||
|
import pp.monopoly.message.client.ClientInterpreter;
|
||||||
|
import pp.monopoly.message.client.EndTurn;
|
||||||
|
import pp.monopoly.message.client.PlayerReady;
|
||||||
|
import pp.monopoly.message.client.RollDice;
|
||||||
|
import pp.monopoly.message.client.TradeOffer;
|
||||||
|
import pp.monopoly.message.client.TradeResponse;
|
||||||
|
import pp.monopoly.message.client.ViewAssetsRequest;
|
||||||
|
import pp.monopoly.message.server.GameStart;
|
||||||
import pp.monopoly.message.server.ServerMessage;
|
import pp.monopoly.message.server.ServerMessage;
|
||||||
import pp.monopoly.message.server.TradeReply;
|
import pp.monopoly.message.server.TradeReply;
|
||||||
import pp.monopoly.message.server.TradeRequest;
|
import pp.monopoly.message.server.TradeRequest;
|
||||||
@@ -9,13 +20,6 @@ import pp.monopoly.message.server.ViewAssetsResponse;
|
|||||||
import pp.monopoly.model.fields.BoardManager;
|
import pp.monopoly.model.fields.BoardManager;
|
||||||
import pp.monopoly.model.fields.PropertyField;
|
import pp.monopoly.model.fields.PropertyField;
|
||||||
|
|
||||||
import java.lang.System.Logger;
|
|
||||||
import java.lang.System.Logger.Level;
|
|
||||||
|
|
||||||
import pp.monopoly.MonopolyConfig;
|
|
||||||
import pp.monopoly.message.client.ClientInterpreter;
|
|
||||||
import pp.monopoly.message.server.ServerMessage;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controls the server-side game logic for Monopoly.
|
* Controls the server-side game logic for Monopoly.
|
||||||
* Manages game states, player interactions, and message handling.
|
* Manages game states, player interactions, and message handling.
|
||||||
@@ -26,7 +30,7 @@ public class ServerGameLogic implements ClientInterpreter {
|
|||||||
private final MonopolyConfig config;
|
private final MonopolyConfig config;
|
||||||
private final PlayerHandler playerHandler = new PlayerHandler(this);
|
private final PlayerHandler playerHandler = new PlayerHandler(this);
|
||||||
private final ServerSender serverSender;
|
private final ServerSender serverSender;
|
||||||
private ServerState state = ServerState.CREATEGAME;
|
private ServerState state = ServerState.LOBBY;
|
||||||
private static final int MAX_PLAYERS = 6;
|
private static final int MAX_PLAYERS = 6;
|
||||||
private BoardManager boardManager = new BoardManager();
|
private BoardManager boardManager = new BoardManager();
|
||||||
|
|
||||||
@@ -120,6 +124,7 @@ public class ServerGameLogic implements ClientInterpreter {
|
|||||||
|
|
||||||
playerHandler.addPlayer(player);
|
playerHandler.addPlayer(player);
|
||||||
LOGGER.log(Level.DEBUG, "Player added: {0}", player.getId());
|
LOGGER.log(Level.DEBUG, "Player added: {0}", player.getId());
|
||||||
|
System.out.println("Anzahl Spieler verbunden:"+ playerHandler.getPlayerCount());
|
||||||
|
|
||||||
return player;
|
return player;
|
||||||
}
|
}
|
||||||
@@ -174,10 +179,15 @@ public class ServerGameLogic implements ClientInterpreter {
|
|||||||
Player player = playerHandler.getPlayerById(from);
|
Player player = playerHandler.getPlayerById(from);
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
player.setName(msg.getName());
|
player.setName(msg.getName());
|
||||||
player.setColor(msg.getColor());
|
playerHandler.setPlayerReady(player, true);
|
||||||
player.setName(msg.getName());
|
|
||||||
LOGGER.log(Level.DEBUG, "Player {0} is ready", player.getName());
|
LOGGER.log(Level.DEBUG, "Player {0} is ready", player.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(playerHandler.allPlayersReady()) {
|
||||||
|
for (Player p : playerHandler.getPlayers()) {
|
||||||
|
send(p, new GameStart(playerHandler.getPlayers()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1,50 +1,38 @@
|
|||||||
package pp.monopoly.message.client;
|
package pp.monopoly.message.client;
|
||||||
|
|
||||||
import pp.monopoly.game.server.PlayerColor;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a message indicating the player is ready to play.
|
* Represents a message indicating the player is ready to play.
|
||||||
*/
|
*/
|
||||||
public class PlayerReady extends ClientMessage{
|
public class PlayerReady extends ClientMessage {
|
||||||
private boolean isReady;
|
private boolean isReady;
|
||||||
private String name;
|
private String name;
|
||||||
private PlayerColor color;
|
private String figure;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a PlayerReady message.
|
* Constructs a PlayerReady message.
|
||||||
*
|
*
|
||||||
* @param isReady true if the player is ready, false otherwise
|
* @param isReady true if the player is ready, false otherwise
|
||||||
|
* @param name the name of the player
|
||||||
|
* @param color the color of the player (can be null)
|
||||||
*/
|
*/
|
||||||
public PlayerReady(boolean isReady) {
|
public PlayerReady(boolean isReady, String name, String figure) {
|
||||||
this.isReady = isReady;
|
this.isReady = isReady;
|
||||||
|
this.name = name;
|
||||||
|
this.figure = figure;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Getter for the Name
|
|
||||||
* @return the Name
|
|
||||||
*/
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public String getFigure() {
|
||||||
* Getter for the Playercolor
|
return figure;
|
||||||
* @return the Playercolor
|
|
||||||
*/
|
|
||||||
public PlayerColor getColor() {
|
|
||||||
return color;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the player is ready.
|
|
||||||
*
|
|
||||||
* @return true if ready, false otherwise
|
|
||||||
*/
|
|
||||||
public boolean isReady() {
|
public boolean isReady() {
|
||||||
return isReady;
|
return isReady;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(ClientInterpreter interpreter, int from) {
|
public void accept(ClientInterpreter interpreter, int from) {
|
||||||
interpreter.received(this, from);
|
interpreter.received(this, from);
|
||||||
|
@@ -1,7 +1,21 @@
|
|||||||
package pp.monopoly.message.server;
|
package pp.monopoly.message.server;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import pp.monopoly.game.server.Player;
|
||||||
|
|
||||||
public class GameStart extends ServerMessage{
|
public class GameStart extends ServerMessage{
|
||||||
|
|
||||||
|
private final List<Player> players;
|
||||||
|
|
||||||
|
public GameStart(List<Player> players) {
|
||||||
|
this.players = players;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Player> getPlayers() {
|
||||||
|
return players;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(ServerInterpreter interpreter) {
|
public void accept(ServerInterpreter interpreter) {
|
||||||
interpreter.received(this);
|
interpreter.received(this);
|
||||||
|
@@ -26,45 +26,45 @@ public class BoardManager {
|
|||||||
ArrayList<Field> fields = new ArrayList<>();
|
ArrayList<Field> fields = new ArrayList<>();
|
||||||
|
|
||||||
fields.add(new GoField());
|
fields.add(new GoField());
|
||||||
fields.add(new BuildingProperty("Gym", 1, 600, 20));
|
fields.add(new BuildingProperty("Gym", 1, 600, 20, 500, FieldColor.BROWN));
|
||||||
fields.add(new EventField("Hausfeier", 2));
|
fields.add(new EventField("Hausfeier", 2));
|
||||||
fields.add(new BuildingProperty("Sportplatz", 3, 600, 40));
|
fields.add(new BuildingProperty("Sportplatz", 3, 600, 40, 500, FieldColor.BROWN));
|
||||||
fields.add(new FineField("Diszi", 4, 2000));
|
fields.add(new FineField("Diszi", 4, 2000));
|
||||||
fields.add(new GateField("Südtor", 5));
|
fields.add(new GateField("Südtor", 5));
|
||||||
fields.add(new BuildingProperty("Studium+", 6, 1000, 60));
|
fields.add(new BuildingProperty("Studium+", 6, 1000, 60, 500, FieldColor.BLUE_LIGHT));
|
||||||
fields.add(new EventField("Üvas", 7));
|
fields.add(new EventField("Üvas", 7));
|
||||||
fields.add(new BuildingProperty("PhysikHörsaal", 8, 1000, 60));
|
fields.add(new BuildingProperty("PhysikHörsaal", 8, 1000, 60, 500, FieldColor.BLUE_LIGHT));
|
||||||
fields.add(new BuildingProperty("Audimax", 9, 1200, 80));
|
fields.add(new BuildingProperty("Audimax", 9, 1200, 80, 500, FieldColor.BLUE_LIGHT));
|
||||||
fields.add(new GulagField());
|
fields.add(new GulagField());
|
||||||
fields.add(new BuildingProperty("99er", 11, 1400, 100));
|
fields.add(new BuildingProperty("99er", 11, 1400, 100, 1000, FieldColor.PINK));
|
||||||
fields.add(new FoodField("Brandl", 12));
|
fields.add(new FoodField("Brandl", 12));
|
||||||
fields.add(new BuildingProperty("12er", 13, 1400, 100));
|
fields.add(new BuildingProperty("12er", 13, 1400, 100, 1000, FieldColor.PINK));
|
||||||
fields.add(new BuildingProperty("23er", 14, 1600, 120));
|
fields.add(new BuildingProperty("23er", 14, 1600, 120, 1000, FieldColor.PINK));
|
||||||
fields.add(new GateField("HauptWache", 15));
|
fields.add(new GateField("HauptWache", 15));
|
||||||
fields.add(new BuildingProperty("Schwimmhalle", 16, 1800, 140));
|
fields.add(new BuildingProperty("Schwimmhalle", 16, 1800, 140, 1000, FieldColor.ORANGE));
|
||||||
fields.add(new BuildingProperty("CISM-Bahn", 17, 1800, 140));
|
fields.add(new BuildingProperty("CISM-Bahn", 17, 1800, 140, 1000, FieldColor.ORANGE));
|
||||||
fields.add(new EventField("Marine-Welcome-Party", 18));
|
fields.add(new EventField("Marine-Welcome-Party", 18));
|
||||||
fields.add(new BuildingProperty("Kletterturm", 19, 2000, 160));
|
fields.add(new BuildingProperty("Kletterturm", 19, 2000, 160, 1000, FieldColor.ORANGE));
|
||||||
fields.add(new TestStreckeField());
|
fields.add(new TestStreckeField());
|
||||||
fields.add(new BuildingProperty("StudFBer C", 21, 2200, 180));
|
fields.add(new BuildingProperty("StudFBer C", 21, 2200, 180, 1500, FieldColor.RED));
|
||||||
fields.add(new EventField("Üvas", 22));
|
fields.add(new EventField("Üvas", 22));
|
||||||
fields.add(new BuildingProperty("StudFBer B", 23, 2200, 180));
|
fields.add(new BuildingProperty("StudFBer B", 23, 2200, 180, 1500, FieldColor.RED));
|
||||||
fields.add(new BuildingProperty("StudFBer A", 24, 2400, 200));
|
fields.add(new BuildingProperty("StudFBer A", 24, 2400, 200, 1500, FieldColor.RED));
|
||||||
fields.add(new GateField("Nordtor", 25));
|
fields.add(new GateField("Nordtor", 25));
|
||||||
fields.add(new BuildingProperty("Cascada", 26, 2600, 220));
|
fields.add(new BuildingProperty("Cascada", 26, 2600, 220, 1500, FieldColor.YELLOW));
|
||||||
fields.add(new BuildingProperty("Fakultätsgebäude", 27, 2600, 220));
|
fields.add(new BuildingProperty("Fakultätsgebäude", 27, 2600, 220, 1500, FieldColor.YELLOW));
|
||||||
fields.add(new FoodField("Truppenküche", 28));
|
fields.add(new FoodField("Truppenküche", 28));
|
||||||
fields.add(new BuildingProperty("Prüfungsamt", 29, 2800, 240));
|
fields.add(new BuildingProperty("Prüfungsamt", 29, 2800, 240, 1500, FieldColor.YELLOW));
|
||||||
fields.add(new WacheField());
|
fields.add(new WacheField());
|
||||||
fields.add(new BuildingProperty("Feuerwehr", 31, 3000, 260));
|
fields.add(new BuildingProperty("Feuerwehr", 31, 3000, 260, 2000, FieldColor.GREEN));
|
||||||
fields.add(new BuildingProperty("SanZ", 32, 300, 260));
|
fields.add(new BuildingProperty("SanZ", 32, 300, 260, 2000, FieldColor.GREEN));
|
||||||
fields.add(new EventField("Maibock", 33));
|
fields.add(new EventField("Maibock", 33));
|
||||||
fields.add(new BuildingProperty("Rechenzentrum", 34, 3200, 280));
|
fields.add(new BuildingProperty("Rechenzentrum", 34, 3200, 280, 2000, FieldColor.GREEN));
|
||||||
fields.add(new GateField("Osttor", 35));
|
fields.add(new GateField("Osttor", 35));
|
||||||
fields.add(new EventField("Üvas", 36));
|
fields.add(new EventField("Üvas", 36));
|
||||||
fields.add(new BuildingProperty("2er", 37, 3500, 350));
|
fields.add(new BuildingProperty("2er", 37, 3500, 350, 2000, FieldColor.BLUE_DARK));
|
||||||
fields.add(new FineField("EZM", 38, 1000));
|
fields.add(new FineField("EZM", 38, 1000));
|
||||||
fields.add(new BuildingProperty("20er", 39, 4000, 500));
|
fields.add(new BuildingProperty("20er", 39, 4000, 500, 2000, FieldColor.BLUE_DARK));
|
||||||
|
|
||||||
return fields;
|
return fields;
|
||||||
}
|
}
|
||||||
|
@@ -1,30 +1,42 @@
|
|||||||
package pp.monopoly.model.fields;
|
package pp.monopoly.model.fields;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import pp.monopoly.game.server.Player;
|
import pp.monopoly.game.server.Player;
|
||||||
|
|
||||||
public class BuildingProperty extends PropertyField {
|
public class BuildingProperty extends PropertyField {
|
||||||
|
|
||||||
private int houses;
|
private int houses;
|
||||||
private boolean hotel = false;
|
private boolean hotel = false;
|
||||||
|
private final int housePrice;
|
||||||
|
private final FieldColor color;
|
||||||
|
private final int rentFactor1 = 5;
|
||||||
|
private final int rentFactor2 = 15;
|
||||||
|
private final int rentFactor3 = 40;
|
||||||
|
private final int rentFactor4 = 55;
|
||||||
|
private final int rentFactorHotel = 70;
|
||||||
|
|
||||||
BuildingProperty(String name, int id, int price, int rent) {
|
BuildingProperty(String name, int id, int price, int rent, int housePrice, FieldColor color) {
|
||||||
super(name, id, price, rent);
|
super(name, id, price, rent);
|
||||||
|
this.housePrice = housePrice;
|
||||||
|
this.color = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int calcRent() {
|
public int calcRent() {
|
||||||
if (hotel) {
|
if (hotel) {
|
||||||
return (int) Math.round(rent*70/10)*10;
|
return (int) Math.round(rent*rentFactorHotel/10)*10;
|
||||||
}
|
}
|
||||||
switch (houses) {
|
switch (houses) {
|
||||||
case 1:
|
case 1:
|
||||||
return (int) Math.round(rent*5/10)*10;
|
return (int) Math.round(rent*rentFactor1/10)*10;
|
||||||
case 2:
|
case 2:
|
||||||
return (int) Math.round(rent*15/10)*10;
|
return (int) Math.round(rent*rentFactor2/10)*10;
|
||||||
case 3:
|
case 3:
|
||||||
return (int) Math.round(rent*40/10)*10;
|
return (int) Math.round(rent*rentFactor3/10)*10;
|
||||||
case 4:
|
case 4:
|
||||||
return (int) Math.round(rent*55/10)*10;
|
return (int) Math.round(rent*rentFactor4/10)*10;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return rent;
|
return rent;
|
||||||
@@ -67,4 +79,23 @@ public class BuildingProperty extends PropertyField {
|
|||||||
public void accept(Player player) {
|
public void accept(Player player) {
|
||||||
player.visit(this);
|
player.visit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Integer> getAllRent() {
|
||||||
|
List<Integer> list = new ArrayList<>();
|
||||||
|
list.add(rent);
|
||||||
|
list.add((int) Math.round(rent*rentFactor1/10)*10);
|
||||||
|
list.add((int) Math.round(rent*rentFactor2/10)*10);
|
||||||
|
list.add((int) Math.round(rent*rentFactor3/10)*10);
|
||||||
|
list.add((int) Math.round(rent*rentFactor4/10)*10);
|
||||||
|
list.add((int) Math.round(rent*rentFactorHotel/10)*10);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FieldColor getColor() {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHousePrice() {
|
||||||
|
return housePrice;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,37 @@
|
|||||||
|
package pp.monopoly.model.fields;
|
||||||
|
|
||||||
|
import com.jme3.math.ColorRGBA;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enum representing eight distinct colors for properties in the game.
|
||||||
|
*/
|
||||||
|
enum FieldColor {
|
||||||
|
BROWN(new ColorRGBA(148 / 255f, 86 / 255f, 57 / 255f, 1)),
|
||||||
|
GREEN(new ColorRGBA(30 / 255f, 179 / 255f, 90 / 255f, 1)),
|
||||||
|
YELLOW(new ColorRGBA(252 / 255f, 241 / 255f, 1 / 255f, 1)),
|
||||||
|
BLUE_LIGHT(new ColorRGBA(170 / 255f, 223 / 255f, 246 / 255f, 1)),
|
||||||
|
PINK(new ColorRGBA(214 / 255f, 60 / 255f, 153 / 255f, 1)),
|
||||||
|
ORANGE(new ColorRGBA(244 / 255f, 147 / 255f, 32 / 255f, 1)),
|
||||||
|
RED(new ColorRGBA(232 / 255f, 27 / 255f, 30 / 255f, 1)),
|
||||||
|
BLUE_DARK(new ColorRGBA(2 / 255f, 112 / 255f, 191 / 255f, 1));
|
||||||
|
|
||||||
|
private final ColorRGBA color;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a FieldColor with the specified ColorRGBA value.
|
||||||
|
*
|
||||||
|
* @param color the ColorRGBA value associated with the field color
|
||||||
|
*/
|
||||||
|
FieldColor(ColorRGBA color) {
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the ColorRGBA value of the field color.
|
||||||
|
*
|
||||||
|
* @return the ColorRGBA value
|
||||||
|
*/
|
||||||
|
public ColorRGBA getColor() {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
}
|
@@ -10,5 +10,5 @@
|
|||||||
# This file defines the configuration settings for the Battleship server.
|
# This file defines the configuration settings for the Battleship server.
|
||||||
#
|
#
|
||||||
# The port number on which the server will listen for incoming connections.
|
# The port number on which the server will listen for incoming connections.
|
||||||
port=1234
|
port=42069
|
||||||
|
|
||||||
|
@@ -7,21 +7,6 @@
|
|||||||
|
|
||||||
package pp.monopoly.server;
|
package pp.monopoly.server;
|
||||||
|
|
||||||
import com.jme3.network.ConnectionListener;
|
|
||||||
import com.jme3.network.HostedConnection;
|
|
||||||
import com.jme3.network.Message;
|
|
||||||
import com.jme3.network.MessageListener;
|
|
||||||
import com.jme3.network.Network;
|
|
||||||
import com.jme3.network.Server;
|
|
||||||
import com.jme3.network.serializing.Serializer;
|
|
||||||
import pp.monopoly.MonopolyConfig;
|
|
||||||
import pp.monopoly.game.server.Player;
|
|
||||||
import pp.monopoly.game.server.ServerGameLogic;
|
|
||||||
import pp.monopoly.game.server.ServerSender;
|
|
||||||
import pp.monopoly.message.client.ClientMessage;
|
|
||||||
import pp.monopoly.message.server.ServerMessage;
|
|
||||||
import pp.monopoly.model.IntPoint;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -31,6 +16,22 @@ import java.util.concurrent.BlockingQueue;
|
|||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.logging.LogManager;
|
import java.util.logging.LogManager;
|
||||||
|
|
||||||
|
import com.jme3.network.ConnectionListener;
|
||||||
|
import com.jme3.network.HostedConnection;
|
||||||
|
import com.jme3.network.Message;
|
||||||
|
import com.jme3.network.MessageListener;
|
||||||
|
import com.jme3.network.Network;
|
||||||
|
import com.jme3.network.Server;
|
||||||
|
import com.jme3.network.serializing.Serializer;
|
||||||
|
|
||||||
|
import pp.monopoly.MonopolyConfig;
|
||||||
|
import pp.monopoly.game.server.Player;
|
||||||
|
import pp.monopoly.game.server.ServerGameLogic;
|
||||||
|
import pp.monopoly.game.server.ServerSender;
|
||||||
|
import pp.monopoly.message.client.ClientMessage;
|
||||||
|
import pp.monopoly.message.server.ServerMessage;
|
||||||
|
import pp.monopoly.model.IntPoint;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Server implementing the visitor pattern as MessageReceiver for ClientMessages
|
* Server implementing the visitor pattern as MessageReceiver for ClientMessages
|
||||||
*/
|
*/
|
||||||
@@ -65,7 +66,7 @@ public class MonopolyServer implements MessageListener<HostedConnection>, Connec
|
|||||||
/**
|
/**
|
||||||
* Creates the server.
|
* Creates the server.
|
||||||
*/
|
*/
|
||||||
MonopolyServer() {
|
public MonopolyServer() {
|
||||||
config.readFromIfExists(CONFIG_FILE);
|
config.readFromIfExists(CONFIG_FILE);
|
||||||
LOGGER.log(Level.INFO, "Configuration: {0}", config); //NON-NLS
|
LOGGER.log(Level.INFO, "Configuration: {0}", config); //NON-NLS
|
||||||
logic = new ServerGameLogic(this, config);
|
logic = new ServerGameLogic(this, config);
|
||||||
@@ -119,8 +120,9 @@ public class MonopolyServer implements MessageListener<HostedConnection>, Connec
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void connectionAdded(Server server, HostedConnection hostedConnection) {
|
public void connectionAdded(Server server, HostedConnection hostedConnection) {
|
||||||
LOGGER.log(Level.INFO, "new connection {0}", hostedConnection); //NON-NLS
|
LOGGER.log(Level.INFO, "New connection established: {0}", hostedConnection); //NON-NLS
|
||||||
logic.addPlayer(hostedConnection.getId());
|
logic.addPlayer(hostedConnection.getId());
|
||||||
|
System.out.println("Spieler verbunden: ID = " + hostedConnection.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -25,7 +25,9 @@ dependencyResolutionManagement {
|
|||||||
library('jme3-effects', 'org.jmonkeyengine', 'jme3-effects').versionRef('jme')
|
library('jme3-effects', 'org.jmonkeyengine', 'jme3-effects').versionRef('jme')
|
||||||
|
|
||||||
library('lemur', 'com.simsilica:lemur:1.16.0')
|
library('lemur', 'com.simsilica:lemur:1.16.0')
|
||||||
library('lemur-proto', 'com.simsilica:lemur-proto:1.13.0')
|
library('lemurproto', 'com.simsilica:lemur-proto:1.13.0')
|
||||||
|
|
||||||
|
library('selenium', 'org.seleniumhq.selenium:selenium-java:4.11.0')
|
||||||
|
|
||||||
library('junit4', 'junit:junit:4.13.2')
|
library('junit4', 'junit:junit:4.13.2')
|
||||||
library('gson', 'com.google.code.gson:gson:2.11.0')
|
library('gson', 'com.google.code.gson:gson:2.11.0')
|
||||||
|
Reference in New Issue
Block a user