mirror of
https://athene2.informatik.unibw-muenchen.de/progproj/gruppen-ht24/Gruppe-02.git
synced 2024-11-25 03:29:44 +01:00
Merge remote-tracking branch 'origin/gui' into gui
This commit is contained in:
commit
8df859bbef
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,6 +4,7 @@ build
|
||||
|
||||
# VSC
|
||||
bin
|
||||
.vscode
|
||||
|
||||
# IntelliJ
|
||||
*.iml
|
||||
|
BIN
Battle.j3o
BIN
Battle.j3o
Binary file not shown.
BIN
BoatSmall.j3o
BIN
BoatSmall.j3o
Binary file not shown.
BIN
KingGeorgeV.j3o
BIN
KingGeorgeV.j3o
Binary file not shown.
@ -7,24 +7,23 @@
|
||||
|
||||
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.Container;
|
||||
import com.simsilica.lemur.Label;
|
||||
import com.simsilica.lemur.TextField;
|
||||
import com.simsilica.lemur.component.SpringGridLayout;
|
||||
|
||||
import static pp.battleship.Resources.lookup;
|
||||
import pp.battleship.server.BattleshipServer;
|
||||
import pp.dialog.Dialog;
|
||||
import pp.dialog.DialogBuilder;
|
||||
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.
|
||||
* 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 {
|
||||
private static final Logger LOGGER = System.getLogger(NetworkDialog.class.getName());
|
||||
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 TextField host = new TextField(LOCALHOST);
|
||||
private final TextField port = new TextField(DEFAULT_PORT);
|
||||
|
@ -7,12 +7,11 @@
|
||||
|
||||
package pp.battleship;
|
||||
|
||||
import pp.util.config.Config;
|
||||
|
||||
import static java.lang.Math.max;
|
||||
import java.util.Map;
|
||||
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.
|
||||
@ -31,7 +30,7 @@ public class BattleshipConfig extends Config {
|
||||
* The default port number for the Battleship server.
|
||||
*/
|
||||
@Property("port")
|
||||
private int port = 1234;
|
||||
private int port = 12234;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
#
|
||||
# The port number on which the server will listen for incoming connections.
|
||||
port=1234
|
||||
port=42069
|
||||
#
|
||||
# The dimensions of the game map.
|
||||
# 'map.width' defines the number of columns, and 'map.height' defines the number of rows.
|
||||
|
@ -1,6 +1,8 @@
|
||||
// Styling of Lemur components
|
||||
// For documentation, see:
|
||||
// https://github.com/jMonkeyEngine-Contributions/Lemur/wiki/Styling
|
||||
|
||||
import com.jme3.math.ColorRGBA
|
||||
import com.simsilica.lemur.*
|
||||
import com.simsilica.lemur.component.QuadBackgroundComponent
|
||||
import com.simsilica.lemur.Button
|
||||
@ -34,9 +36,10 @@ def gradient = TbtQuadBackgroundComponent.create(
|
||||
def doubleGradient = new QuadBackgroundComponent(gradientColor)
|
||||
doubleGradient.texture = texture(name: "/com/simsilica/lemur/icons/double-gradient-128.png",
|
||||
generateMips: false)
|
||||
//doubleGradient.color = color(0, 0, 0, 1)
|
||||
|
||||
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),
|
||||
1, 1, 1, 126, 126,
|
||||
1f, false)
|
||||
@ -51,11 +54,27 @@ selector("label", "pp") {
|
||||
color = buttonEnabledColor
|
||||
}
|
||||
|
||||
selector("label-Bold", "pp") {
|
||||
insets = new Insets3f(2, 2, 2, 2)
|
||||
font = font("Interface/Fonts/Metropolis/Metropolis-Bold-32.fnt")
|
||||
fontSize = 30
|
||||
color = buttonEnabledColor
|
||||
textHAlignment = HAlignment.Center
|
||||
textVAlignment = VAlignment.Center
|
||||
|
||||
}
|
||||
selector("label-Text", "pp") {
|
||||
insets = new Insets3f(2, 2, 2, 2)
|
||||
fontSize = 25
|
||||
color = buttonEnabledColor
|
||||
}
|
||||
|
||||
selector("header", "pp") {
|
||||
font = font("Interface/Fonts/Metropolis/Metropolis-Bold-42.fnt")
|
||||
insets = new Insets3f(2, 2, 2, 2)
|
||||
color = color(1, 0.5, 0, 1)
|
||||
textHAlignment = HAlignment.Center
|
||||
textVAlignment = VAlignment.Center
|
||||
}
|
||||
|
||||
selector("container", "pp") {
|
||||
@ -64,20 +83,10 @@ selector("container", "pp") {
|
||||
}
|
||||
|
||||
selector("toolbar") {
|
||||
// Set the grey background
|
||||
background = new QuadBackgroundComponent(greyBackground)
|
||||
background = gradient.clone()
|
||||
background.setColor(bgColor)
|
||||
//color = (new ColorRGBA(0.4157f, 0.4235f, 0.4392f, 1.0f))
|
||||
|
||||
// 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") {
|
||||
background = gradient.clone()
|
||||
@ -146,6 +155,8 @@ selector("title", "pp") {
|
||||
background.texture = texture(name: "/com/simsilica/lemur/icons/double-gradient-128.png",
|
||||
generateMips: false)
|
||||
insets = new Insets3f(2, 2, 2, 2)
|
||||
textHAlignment = HAlignment.Center
|
||||
textVAlignment = VAlignment.Center
|
||||
|
||||
buttonCommands = stdButtonCommands
|
||||
}
|
||||
@ -160,6 +171,8 @@ selector("button", "pp") {
|
||||
|
||||
// Use insets to create a margin/padding effect for the inner background
|
||||
insets = new Insets3f(3, 3, 3, 3) // Adjust the border thickness
|
||||
textHAlignment = HAlignment.Center
|
||||
textVAlignment = VAlignment.Center
|
||||
buttonCommands = stdButtonCommands
|
||||
}
|
||||
|
||||
@ -234,5 +247,41 @@ selector("tab.button", "pp") {
|
||||
}
|
||||
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
|
||||
textHAlignment = HAlignment.Center
|
||||
textVAlignment = VAlignment.Center
|
||||
buttonCommands = stdButtonCommands
|
||||
}
|
||||
|
||||
// Style for Selector text
|
||||
selector("selector.item.label") {
|
||||
color = color(0, 0, 0, 1) // Black text
|
||||
fontSize = 16 // Optional: Adjust the text size if needed
|
||||
textHAlignment = HAlignment.Left // Optional: Align text to the left
|
||||
insets = new Insets3f(2, 2, 2, 2) // Optional: Add padding around text
|
||||
}
|
||||
// Style the popup container background
|
||||
selector("selector.popup") {
|
||||
background = new QuadBackgroundComponent(new ColorRGBA(1, 1, 1, 0.8f)) // Translucent white background
|
||||
insets = new Insets3f(5, 5, 5, 5) // Padding inside the popup container
|
||||
}
|
||||
|
||||
// Style the text of dropdown options
|
||||
selector("selector.item.label") {
|
||||
color = color(0, 0, 0, 1) // Black text
|
||||
fontSize = 16 // Optional: Adjust font size
|
||||
textHAlignment = HAlignment.Left // Align text to the left
|
||||
insets = new Insets3f(2, 5, 2, 5) // Add padding for each option
|
||||
}
|
||||
|
||||
// Style the hover state of dropdown options
|
||||
selector("selector.item.label", "hover") {
|
||||
color = color(1, 1, 1, 1) // White text when hovered
|
||||
background = new QuadBackgroundComponent(new ColorRGBA(0.2f, 0.6f, 1.0f, 0.9f)) // Highlighted background
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,12 @@ dependencies {
|
||||
implementation project(":monopoly:model")
|
||||
implementation project(":monopoly:server")
|
||||
|
||||
implementation 'com.simsilica:lemur-proto:1.13.0'
|
||||
implementation libs.jme3.desktop
|
||||
implementation libs.lemur
|
||||
implementation libs.lemurproto
|
||||
|
||||
implementation libs.selenium
|
||||
|
||||
runtimeOnly libs.jme3.awt.dialogs
|
||||
runtimeOnly libs.jme3.plugins
|
||||
|
@ -5,47 +5,13 @@
|
||||
## (c) Mark Minas (mark.minas@unibw.de)
|
||||
########################################
|
||||
#
|
||||
# Battleship client configuration
|
||||
#
|
||||
# Specifies the map used by the opponent in single mode.
|
||||
# Single mode is activated if this property is set.
|
||||
#map.opponent=maps/map2.json
|
||||
#
|
||||
# Specifies the map used by the player in single mode.
|
||||
# The player must define their own map if this property is not set.
|
||||
map.own=maps/map1.json
|
||||
#
|
||||
# Coordinates of the shots fired by the RobotClient in the order listed.
|
||||
# Example:
|
||||
# 2, 0,\
|
||||
# 2, 1,\
|
||||
# 2, 2,\
|
||||
# 2, 3
|
||||
# defines four shots, namely at the coordinates
|
||||
# (x=2, y=0), (x=2, y=1), (x=2, y=2), and (x=2, y=3)
|
||||
robot.targets=2, 0,\
|
||||
2, 1,\
|
||||
2, 2,\
|
||||
2, 3
|
||||
#
|
||||
# Delay in milliseconds between each shot fired by the RobotClient.
|
||||
robot.delay=500
|
||||
# Monopoly client configuration
|
||||
#
|
||||
# The dimensions of the game map used in single mode.
|
||||
# 'map.width' defines the number of columns, and 'map.height' defines the number of rows.
|
||||
map.width=10
|
||||
map.height=10
|
||||
#
|
||||
# The number of ships of each length available in single mode.
|
||||
# The value is a comma-separated list where each element corresponds to the number of ships
|
||||
# with a specific length. For example:
|
||||
# ship.nums=4, 3, 2, 1
|
||||
# This configuration means:
|
||||
# - 4 ships of length 1
|
||||
# - 3 ships of length 2
|
||||
# - 2 ships of length 3
|
||||
# - 1 ship of length 4
|
||||
ship.nums=4, 3, 2, 1
|
||||
#
|
||||
# Screen settings
|
||||
#
|
||||
@ -58,10 +24,10 @@ overlay.top.color=1, 1, 1, 1
|
||||
settings.show=false
|
||||
#
|
||||
# Specifies the width of the application window in pixels.
|
||||
settings.resolution.width=1200
|
||||
settings.resolution.width=1920
|
||||
#
|
||||
# Specifies the height of the application window in pixels.
|
||||
settings.resolution.height=800
|
||||
settings.resolution.height=1080
|
||||
#
|
||||
# Determines whether the application runs in full-screen mode.
|
||||
settings.full-screen=false
|
||||
|
@ -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 String ENABLED_PREF = "enabled"; //NON-NLS
|
||||
|
||||
private AudioNode splashSound;
|
||||
private AudioNode shipDestroyedSound;
|
||||
private AudioNode explosionSound;
|
||||
private AudioNode passStartSound;
|
||||
private AudioNode eventCardSound;
|
||||
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.
|
||||
@ -75,6 +83,17 @@ public class GameSound extends AbstractAppState implements GameEventListener {
|
||||
@Override
|
||||
public void initialize(AppStateManager stateManager, Application 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() {
|
||||
if (isEnabled() && splashSound != null)
|
||||
splashSound.playInstance();
|
||||
public void passStart() {
|
||||
if (isEnabled() && passStartSound != null)
|
||||
passStartSound.playInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays the explosion sound effect.
|
||||
* Plays the eventCard sound effect.
|
||||
*/
|
||||
public void explosion() {
|
||||
if (isEnabled() && explosionSound != null)
|
||||
explosionSound.playInstance();
|
||||
public void eventCard() {
|
||||
if (isEnabled() && eventCardSound != null)
|
||||
eventCardSound.playInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays sound effect when a ship has been destroyed.
|
||||
* Plays the gulag sound effect.
|
||||
*/
|
||||
public void shipDestroyed() {
|
||||
if (isEnabled() && shipDestroyedSound != null)
|
||||
shipDestroyedSound.playInstance();
|
||||
public void gulag() {
|
||||
if (isEnabled() && gulagSound != null)
|
||||
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
|
||||
public void receivedEvent(SoundEvent event) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,25 +9,25 @@ import com.jme3.font.BitmapText;
|
||||
import com.jme3.input.KeyInput;
|
||||
import com.jme3.input.controls.ActionListener;
|
||||
import com.jme3.input.controls.KeyTrigger;
|
||||
|
||||
import com.jme3.system.AppSettings;
|
||||
import com.simsilica.lemur.GuiGlobals;
|
||||
import com.simsilica.lemur.Label;
|
||||
import com.simsilica.lemur.style.BaseStyles;
|
||||
|
||||
import pp.dialog.DialogBuilder;
|
||||
import pp.dialog.DialogManager;
|
||||
import pp.graphics.Draw;
|
||||
import pp.monopoly.client.gui.SettingsMenu;
|
||||
import pp.monopoly.client.gui.TestWorld;
|
||||
import pp.monopoly.client.gui.*;
|
||||
import pp.monopoly.client.gui.popups.*;
|
||||
import pp.monopoly.game.client.ClientGameLogic;
|
||||
import pp.monopoly.game.client.MonopolyClient;
|
||||
import pp.monopoly.game.client.ServerConnection;
|
||||
import pp.monopoly.model.fields.BoardManager;
|
||||
import pp.monopoly.notification.GameEventListener;
|
||||
import pp.monopoly.notification.InfoTextEvent;
|
||||
import pp.monopoly.server.MonopolyServer;
|
||||
|
||||
public class MonopolyApp extends SimpleApplication implements MonopolyClient, GameEventListener {
|
||||
|
||||
private BitmapText topText;
|
||||
private final ServerConnection serverConnection;
|
||||
private final ClientGameLogic logic;
|
||||
@ -41,16 +41,27 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
|
||||
private boolean isSettingsMenuOpen = false;
|
||||
private boolean inputBlocked = false;
|
||||
private MonopolyServer monopolyServer;
|
||||
private NetworkSupport networkSupport;
|
||||
private BoardManager boardManager = new BoardManager();
|
||||
|
||||
// TODO Temp später entfernen
|
||||
|
||||
private EventCard eventCard;
|
||||
private BuildingPropertyCard buildingProperty;
|
||||
private FoodFieldCard foodField;
|
||||
private GateFieldCard gateField;
|
||||
private BuyCard buyCard;
|
||||
private boolean isBuyCardPopupOpen = false;
|
||||
private final ActionListener BListener = (name, isPressed, tpf) -> handleB(isPressed);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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) {
|
||||
new MonopolyApp().start();
|
||||
@ -59,7 +70,8 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
|
||||
public MonopolyApp() {
|
||||
this.draw = new Draw(assetManager);
|
||||
config = new MonopolyAppConfig();
|
||||
serverConnection = new NetworkSupport(this);
|
||||
networkSupport = new NetworkSupport(this); // Initialize NetworkSupport
|
||||
serverConnection = networkSupport;
|
||||
logic = new ClientGameLogic(serverConnection);
|
||||
logic.addListener(this);
|
||||
setShowSettings(config.getShowSettings());
|
||||
@ -76,6 +88,14 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
|
||||
return logic;
|
||||
}
|
||||
|
||||
public BoardManager getBoardManager() {
|
||||
return boardManager;
|
||||
}
|
||||
|
||||
public NetworkSupport getNetworkSupport() {
|
||||
return networkSupport;
|
||||
}
|
||||
|
||||
private AppSettings makeSettings() {
|
||||
final AppSettings settings = new AppSettings(true);
|
||||
settings.setTitle("Monopoly Game");
|
||||
@ -88,8 +108,10 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
|
||||
public void simpleInitApp() {
|
||||
GuiGlobals.initialize(this);
|
||||
BaseStyles.loadStyleResources(STYLES_SCRIPT);
|
||||
GuiGlobals.getInstance().getStyles().setDefaultStyle("pp"); //NON-NLS
|
||||
final BitmapFont normalFont = assetManager.loadFont(FONT); //NON-NLS
|
||||
GuiGlobals.getInstance().getStyles().setDefaultStyle("pp"); // NON-NLS
|
||||
BaseStyles.loadStyleResources("com/simsilica/lemur/style/base/glass-styles.groovy");
|
||||
GuiGlobals.getInstance().getStyles();
|
||||
final BitmapFont normalFont = assetManager.loadFont(FONT); // NON-NLS
|
||||
|
||||
setupInput();
|
||||
setupGui();
|
||||
@ -110,6 +132,9 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
|
||||
inputManager.setCursorVisible(true);
|
||||
inputManager.addMapping("ESC", new KeyTrigger(KeyInput.KEY_ESCAPE));
|
||||
inputManager.addListener(escapeListener, "ESC");
|
||||
|
||||
inputManager.addMapping("B", new KeyTrigger(KeyInput.KEY_B));
|
||||
inputManager.addListener(BListener, "B");
|
||||
}
|
||||
|
||||
private void handleEscape(boolean isPressed) {
|
||||
@ -129,18 +154,35 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//logik zum wechselnden erscheinen und verschwinden beim drücken von B //TODO süäter entfernen
|
||||
private void handleB(boolean isPressed) {
|
||||
if (isPressed) {
|
||||
if (eventCard != null && isBuyCardPopupOpen) {
|
||||
// Schließe das SettingsMenu
|
||||
System.out.println("Schließe BuyCardPopup...");
|
||||
eventCard.close();
|
||||
eventCard = null;
|
||||
setBuyCardPopupOpen(false);
|
||||
} else {
|
||||
// Öffne das SettingsMenu
|
||||
System.out.println("Öffne BuyCardPopup...");
|
||||
eventCard = new EventCard(this);
|
||||
eventCard.open();
|
||||
setBuyCardPopupOpen(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void blockInputs() {
|
||||
if (!inputBlocked) {
|
||||
System.out.println("Blockiere Eingaben...");
|
||||
inputManager.setCursorVisible(true); // Cursor sichtbar machen
|
||||
inputManager.clearMappings(); // Alle Mappings entfernen
|
||||
inputManager.clearMappings(); // Alle Mappings entfernen
|
||||
inputBlocked = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void unblockInputs() {
|
||||
if (inputBlocked) {
|
||||
System.out.println("Aktiviere Eingaben...");
|
||||
@ -194,6 +236,12 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
|
||||
this.isSettingsMenuOpen = isOpen;
|
||||
}
|
||||
|
||||
// TODO später entfernen
|
||||
|
||||
public void setBuyCardPopupOpen(boolean isOpen) {
|
||||
this.isBuyCardPopupOpen = isOpen;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void simpleUpdate(float tpf) {
|
||||
if (testWorld != null) {
|
||||
@ -204,7 +252,12 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
|
||||
public void startTestWorld() {
|
||||
guiNode.detachAllChildren(); // Entferne GUI
|
||||
testWorld = new TestWorld(this); // Erstelle eine Instanz von TestWorld
|
||||
testWorld.initializeScene(); // Initialisiere die Szene
|
||||
testWorld.initializeScene(); // Initialisiere die Szene
|
||||
}
|
||||
|
||||
// TODO später entfernen
|
||||
|
||||
public void startBuyCard() {
|
||||
}
|
||||
|
||||
public void returnToMenu() {
|
||||
@ -218,9 +271,9 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
|
||||
public void startServer() {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
monopolyServer = new MonopolyServer(); // Erstelle Serverinstanz
|
||||
MonopolyServer.main(new String[0]); // Startet den MonopolyServer
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
errorDialog("Fehler: Server konnte nicht gestartet werden.");
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
@ -228,4 +281,8 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
|
||||
public MonopolyServer getMonopolyServer() {
|
||||
return monopolyServer;
|
||||
}
|
||||
|
||||
public ServerConnection getServerConnection() {
|
||||
return serverConnection;
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ import pp.dialog.SimpleDialog;
|
||||
class NetworkDialog extends SimpleDialog {
|
||||
private static final Logger LOGGER = System.getLogger(NetworkDialog.class.getName());
|
||||
private static final String LOCALHOST = "localhost";
|
||||
private static final String DEFAULT_PORT = "1234";
|
||||
private static final String DEFAULT_PORT = "42069";
|
||||
private final NetworkSupport network;
|
||||
private final TextField host = new TextField(LOCALHOST);
|
||||
private final TextField port = new TextField(DEFAULT_PORT);
|
||||
|
@ -18,7 +18,7 @@ import pp.monopoly.message.server.ServerMessage;
|
||||
* Manages the network connection for the Monopoly application.
|
||||
* 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 final MonopolyApp app;
|
||||
private Client client;
|
||||
@ -41,6 +41,11 @@ class NetworkSupport implements MessageListener<Client>, ClientStateListener, Se
|
||||
return app;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
if (client == null) return 0;
|
||||
return client.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there is a connection to the game server.
|
||||
*
|
||||
@ -80,7 +85,7 @@ class NetworkSupport implements MessageListener<Client>, ClientStateListener, Se
|
||||
* @param port The server's port.
|
||||
* @throws IOException If an I/O error occurs when creating the client.
|
||||
*/
|
||||
void initNetwork(String host, int port) throws IOException {
|
||||
public void initNetwork(String host, int port) throws IOException {
|
||||
if (client != null) {
|
||||
throw new IllegalStateException("Already connected to the game server.");
|
||||
}
|
||||
@ -141,4 +146,40 @@ class NetworkSupport implements MessageListener<Client>, ClientStateListener, Se
|
||||
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.");
|
||||
}
|
||||
}
|
||||
}
|
@ -39,21 +39,22 @@ public class CameraController {
|
||||
* @param tpf Zeit pro Frame
|
||||
*/
|
||||
public void update(float tpf) {
|
||||
// Aktualisiere den Winkel basierend auf der Geschwindigkeit
|
||||
angle += speed * tpf;
|
||||
if (angle >= FastMath.TWO_PI) {
|
||||
angle -= FastMath.TWO_PI; // Winkel zurücksetzen, um Überläufe zu vermeiden
|
||||
}
|
||||
|
||||
// Berechne die neue Position der Kamera
|
||||
float x = center.x + radius * FastMath.cos(angle);
|
||||
float z = center.z + radius * FastMath.sin(angle);
|
||||
float y = center.y + height;
|
||||
|
||||
// Setze die Kameraposition
|
||||
camera.setLocation(new Vector3f(x, y, z));
|
||||
|
||||
// Lasse die Kamera auf den Fokuspunkt blicken
|
||||
camera.lookAt(center, Vector3f.UNIT_Y);
|
||||
}
|
||||
|
||||
public void setPosition(int fieldID) {
|
||||
camera.setLocation(fieldIdToVector(fieldID));
|
||||
}
|
||||
|
||||
public void setPosition(float x, float y) {
|
||||
camera.setLocation(new Vector3f(x,height,y));
|
||||
}
|
||||
|
||||
private Vector3f fieldIdToVector(int fieldID) {
|
||||
if (fieldID <= 10) return new Vector3f(30,height,0);
|
||||
if (fieldID <= 20) return new Vector3f(0, height, 30);
|
||||
if (fieldID <= 30) return new Vector3f(-30, height, 0);
|
||||
if (fieldID <= 40) return new Vector3f(0, height, -30);
|
||||
else throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,7 @@
|
||||
package pp.monopoly.client.gui;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.network.Client;
|
||||
import com.jme3.network.Network;
|
||||
import com.jme3.scene.Geometry;
|
||||
import com.jme3.scene.shape.Quad;
|
||||
import com.jme3.texture.Texture;
|
||||
@ -16,9 +12,10 @@ import com.simsilica.lemur.Label;
|
||||
import com.simsilica.lemur.TextField;
|
||||
import com.simsilica.lemur.component.SpringGridLayout;
|
||||
|
||||
import com.simsilica.lemur.style.ElementId;
|
||||
import pp.monopoly.client.MonopolyApp;
|
||||
import pp.monopoly.client.StartMenu;
|
||||
import pp.monopoly.server.MonopolyServer;
|
||||
|
||||
|
||||
/**
|
||||
* CreateGameMenu class represents the menu for creating a new game.
|
||||
@ -41,8 +38,10 @@ public class CreateGameMenu {
|
||||
menuContainer.setPreferredSize(new Vector3f(600, 400, 0)); // Feste Größe des Containers
|
||||
|
||||
// Titel
|
||||
Label title = menuContainer.addChild(new Label("Neues Spiel"));
|
||||
title.setFontSize(48);
|
||||
Label title = menuContainer.addChild(new Label("Neues Spiel", new ElementId("header")));
|
||||
title.setFont(app.getAssetManager().loadFont("Interface/Fonts/Metropolis/Metropolis-Bold-42.fnt"));
|
||||
title.setFontSize(50);
|
||||
|
||||
|
||||
// Eingabefelder-Container
|
||||
Container inputContainer = menuContainer.addChild(new Container(new SpringGridLayout(Axis.Y, Axis.X)));
|
||||
@ -70,11 +69,26 @@ public class CreateGameMenu {
|
||||
// "Selber hosten"-Button
|
||||
Button hostButton = buttonContainer.addChild(new Button("Selber hosten"));
|
||||
hostButton.setPreferredSize(new Vector3f(120, 40, 0));
|
||||
hostButton.addClickCommands(source -> app.startServer());
|
||||
hostButton.addClickCommands(source -> app.getNetworkSupport().startServerAndJoin());
|
||||
|
||||
// "Beitreten"-Button (vorerst funktionslos)
|
||||
// "Beitreten"-Button
|
||||
Button joinButton = buttonContainer.addChild(new Button("Beitreten"));
|
||||
joinButton.setPreferredSize(new Vector3f(120, 40, 0));
|
||||
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"));
|
||||
@ -86,7 +100,6 @@ public class CreateGameMenu {
|
||||
(app.getCamera().getHeight() + menuContainer.getPreferredSize().y) / 2,
|
||||
1 // Höhere Z-Ebene für den Vordergrund
|
||||
);
|
||||
|
||||
app.getInputManager().addMapping("OpenTestWorld", new com.jme3.input.controls.KeyTrigger(com.jme3.input.KeyInput.KEY_T));
|
||||
app.getInputManager().addListener(new com.jme3.input.controls.ActionListener() {
|
||||
@Override
|
||||
@ -97,6 +110,18 @@ public class CreateGameMenu {
|
||||
}
|
||||
}, "OpenTestWorld");
|
||||
|
||||
// TODO später entfernen
|
||||
|
||||
app.getInputManager().addMapping("OpenBuyCard", new com.jme3.input.controls.KeyTrigger(com.jme3.input.KeyInput.KEY_B));
|
||||
app.getInputManager().addListener(new com.jme3.input.controls.ActionListener() {
|
||||
@Override
|
||||
public void onAction(String name, boolean isPressed, float tpf) {
|
||||
if (name.equals("OpenBuyCard") && isPressed) {
|
||||
app.startBuyCard(); // Öffnet die TestWorld
|
||||
}
|
||||
}
|
||||
}, "OpenBuyCard");
|
||||
|
||||
app.getGuiNode().attachChild(menuContainer);
|
||||
}
|
||||
|
||||
|
@ -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,398 @@
|
||||
package pp.monopoly.client.gui;
|
||||
|
||||
import com.jme3.app.Application;
|
||||
import com.jme3.app.state.BaseAppState;
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.math.ColorRGBA;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.scene.Geometry;
|
||||
import com.jme3.scene.shape.Quad;
|
||||
import com.jme3.scene.shape.Sphere;
|
||||
import com.jme3.texture.Texture;
|
||||
import com.simsilica.lemur.Axis;
|
||||
import com.simsilica.lemur.Button;
|
||||
import com.simsilica.lemur.Container;
|
||||
import com.simsilica.lemur.Insets3f;
|
||||
import com.simsilica.lemur.Label;
|
||||
import com.simsilica.lemur.Selector;
|
||||
import com.simsilica.lemur.TextField;
|
||||
import com.simsilica.lemur.component.QuadBackgroundComponent;
|
||||
import com.simsilica.lemur.component.SpringGridLayout;
|
||||
|
||||
import com.simsilica.lemur.core.VersionedList;
|
||||
import com.simsilica.lemur.core.VersionedReference;
|
||||
import com.simsilica.lemur.style.ElementId;
|
||||
import pp.monopoly.client.MonopolyApp;
|
||||
import pp.monopoly.game.client.ClientGameLogic;
|
||||
import pp.monopoly.game.server.Player;
|
||||
import pp.monopoly.game.server.PlayerColor;
|
||||
import pp.monopoly.game.server.PlayerHandler;
|
||||
import pp.monopoly.model.Figure;
|
||||
import pp.monopoly.model.Rotation;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class LobbyMenu {
|
||||
|
||||
private final MonopolyApp app;
|
||||
private final Container menuContainer;
|
||||
private Geometry background;
|
||||
private Geometry circle;
|
||||
private Container lowerLeftMenu;
|
||||
private Container lowerRightMenu;
|
||||
private ColorRGBA playerColor= ColorRGBA.Gray;
|
||||
|
||||
private PlayerHandler playerHandler;
|
||||
private TextField startingCapital;
|
||||
private TextField playerInputField;
|
||||
private Selector<String> figureDropdown;
|
||||
|
||||
|
||||
public LobbyMenu(MonopolyApp app) {
|
||||
this.app = app;
|
||||
this.playerHandler = ClientGameLogic.getPlayerHandler(); // Initialize PlayerHandler
|
||||
|
||||
int playerID = app.getNetworkSupport().getId(); // Retrieve the player ID
|
||||
assignPlayerColor(playerID); //set the Players Color
|
||||
|
||||
app.getGuiNode().detachAllChildren(); // Entfernt das CreateGameMenu (inklusive Hintergrund)
|
||||
|
||||
addBackgroundImage();// Hintergrundbild laden und hinzufügen
|
||||
|
||||
QuadBackgroundComponent translucentWhiteBackground =
|
||||
new QuadBackgroundComponent(new ColorRGBA(1.0f, 1.0f, 1.0f, 0.5f));
|
||||
|
||||
menuContainer = new Container(new SpringGridLayout(Axis.Y, Axis.X));
|
||||
menuContainer.setPreferredSize(new Vector3f(1000, 600, 0));
|
||||
menuContainer.setBackground(translucentWhiteBackground);
|
||||
|
||||
// Create a smaller horizontal container for the label, input field, and spacers
|
||||
Container horizontalContainer = menuContainer.addChild(new Container(new SpringGridLayout(Axis.X, Axis.Y)));
|
||||
horizontalContainer.setPreferredSize(new Vector3f(600, 40, 0));
|
||||
horizontalContainer.setBackground(null);
|
||||
|
||||
Label title = horizontalContainer.addChild(new Label("Startkapital:", new ElementId("label-Bold")));
|
||||
title.setFontSize(40);
|
||||
|
||||
// Add a spacer between the title and the input field
|
||||
Label spacerBeforeInput = horizontalContainer.addChild(new Label("")); // Invisible spacer
|
||||
spacerBeforeInput.setPreferredSize(new Vector3f(20, 1, 0)); // Width of the spacer
|
||||
|
||||
// Add an input field (TextField)
|
||||
TextField startingCapital = horizontalContainer.addChild(new TextField("15 000"));
|
||||
startingCapital.setPreferredWidth(100); // Set the width of the input field
|
||||
startingCapital.setPreferredSize(new Vector3f(150, 50, 0));
|
||||
startingCapital.setInsets(new Insets3f(5, 10, 5, 10)); // Add padding around the text inside the field
|
||||
|
||||
// Add a spacer after the input field
|
||||
Label spacerAfterInput = horizontalContainer.addChild(new Label("")); // Invisible spacer
|
||||
spacerAfterInput.setPreferredSize(new Vector3f(20, 1, 0)); // Width of the spacer
|
||||
|
||||
menuContainer.setLocalTranslation(
|
||||
(app.getCamera().getWidth() - menuContainer.getPreferredSize().x) / 2,
|
||||
(app.getCamera().getHeight() + menuContainer.getPreferredSize().y) / 2,
|
||||
1
|
||||
);
|
||||
app.getGuiNode().attachChild(menuContainer);
|
||||
|
||||
// Dropdowns and Labels
|
||||
Container dropdownContainer = menuContainer.addChild(new Container(new SpringGridLayout(Axis.X, Axis.Y)));
|
||||
dropdownContainer.setPreferredSize(new Vector3f(800, 200, 0));
|
||||
dropdownContainer.setBackground(null);
|
||||
dropdownContainer.setInsets(new Insets3f(10, 0, 0, 0));
|
||||
// Player Input Field
|
||||
Container playerInputContainer = dropdownContainer.addChild(new Container(new SpringGridLayout(Axis.Y, Axis.X)));
|
||||
playerInputContainer.addChild(new Label("Spieler:"));
|
||||
playerInputContainer.setBackground(null);
|
||||
|
||||
|
||||
TextField playerInputField = new TextField("Spieler 1");
|
||||
playerInputField.setPreferredSize(new Vector3f(100, 20, 0));
|
||||
playerInputField.setInsets(new Insets3f(5, 10, 5, 10));
|
||||
playerInputField.setBackground(new QuadBackgroundComponent(ColorRGBA.Black));
|
||||
playerInputContainer.addChild(playerInputField);
|
||||
// Spacer (Center Circle Area)
|
||||
Label spacer = dropdownContainer.addChild(new Label(""));
|
||||
spacer.setPreferredSize(new Vector3f(200, 200, 0));
|
||||
|
||||
// Figur Dropdown
|
||||
Container figureDropdownContainer = dropdownContainer.addChild(new Container(new SpringGridLayout(Axis.Y, Axis.X)));
|
||||
figureDropdownContainer.setPreferredSize(new Vector3f(150, 80, 0));
|
||||
figureDropdownContainer.addChild(new Label("Figur:"));
|
||||
figureDropdownContainer.setBackground(null);
|
||||
|
||||
VersionedList<String> figures = new VersionedList<>();
|
||||
figures.add("Laptop");
|
||||
figures.add("Flugzeug");
|
||||
figures.add("Jägermeister");
|
||||
figures.add("Katze");
|
||||
figures.add("OOP");
|
||||
figures.add("Handyholster");
|
||||
|
||||
Selector<String> figureDropdown = new Selector<>(figures, "glass");
|
||||
figureDropdown.setBackground(new QuadBackgroundComponent(ColorRGBA.DarkGray));
|
||||
figureDropdown.setPreferredSize(new Vector3f(150, 140, 0));
|
||||
Vector3f dimens = figureDropdownContainer.getPreferredSize();
|
||||
Vector3f dimens2 = figureDropdown.getPopupContainer().getPreferredSize();
|
||||
dimens2.setX( dimens.getX() );
|
||||
figureDropdown.getPopupContainer().setPreferredSize( dimens2 );
|
||||
figureDropdownContainer.addChild(figureDropdown);
|
||||
|
||||
addSelectionActionListener(figureDropdown, this::onDropdownSelectionChanged);
|
||||
|
||||
Container buttonContainer = menuContainer.addChild(new Container(new SpringGridLayout(Axis.X, Axis.Y)));
|
||||
buttonContainer.setPreferredSize(new Vector3f(100, 40, 0));
|
||||
buttonContainer.setInsets(new Insets3f(20, 0, 10, 0)); // Add spacing above the buttons
|
||||
buttonContainer.setBackground(null);
|
||||
// Lower-left container for "Abbrechen" button
|
||||
lowerLeftMenu = new Container();
|
||||
Button cancelButton = new Button("Abbrechen");
|
||||
cancelButton.setPreferredSize(new Vector3f(200, 60, 0)); // Set size to match the appearance in the image
|
||||
cancelButton.setFontSize(18); // Adjust font size
|
||||
cancelButton.addClickCommands(source -> goBackToCreateGame()); // Add functionality
|
||||
lowerLeftMenu.addChild(cancelButton);
|
||||
|
||||
// Position the container near the bottom-left corner
|
||||
lowerLeftMenu.setLocalTranslation(new Vector3f(120, 170, 3)); // Adjust X and Y to align with the bottom-left corner
|
||||
app.getGuiNode().attachChild(lowerLeftMenu);
|
||||
|
||||
// Lower-right container for "Bereit" button
|
||||
lowerRightMenu = new Container();
|
||||
Button readyButton = new Button("Bereit");
|
||||
readyButton.setPreferredSize(new Vector3f(200, 60, 0)); // Set size to match the appearance in the image
|
||||
readyButton.setFontSize(18); // Adjust font size
|
||||
readyButton.setBackground(new QuadBackgroundComponent(ColorRGBA.Green)); // Add color to match the style
|
||||
readyButton.addClickCommands(source -> applyStartingCapital(playerID));
|
||||
readyButton.addClickCommands(source -> applyPlayerName(playerID));
|
||||
readyButton.addClickCommands(source -> applyFigure(playerID));
|
||||
lowerRightMenu.addChild(readyButton);
|
||||
//TODO aktivieren des Spielers in den ready Status und Sprung in den nächsten Menüzustand
|
||||
|
||||
// Position the container near the bottom-right corner
|
||||
lowerRightMenu.setLocalTranslation(new Vector3f(app.getCamera().getWidth() - 320, 170, 3)); // X: 220px from the right, Y: 50px above the bottom
|
||||
app.getGuiNode().attachChild(lowerRightMenu);
|
||||
|
||||
// Add a colored circle between the input field and the dropdown menu
|
||||
circle = createCircle(); // 50 is the diameter, Red is the color
|
||||
circle.setLocalTranslation(new Vector3f(
|
||||
(app.getCamera().getWidth()) / 2, // Center horizontally
|
||||
(app.getCamera().getHeight() / 2) - 90, // Adjust Y position
|
||||
2 // Ensure it's in front of the background but behind the dropdown
|
||||
));
|
||||
app.getGuiNode().attachChild(circle); // Attach to the GUI node
|
||||
|
||||
// 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);
|
||||
}
|
||||
/**
|
||||
* Apply the starting capital only if the current player is the host.
|
||||
*/
|
||||
private void applyStartingCapital(int playerID) {
|
||||
Player currentPlayer = playerHandler.getPlayerById(playerID);
|
||||
|
||||
// Check if the current player is the host
|
||||
if (currentPlayer.equals(playerHandler.getHostPlayer())) {
|
||||
try {
|
||||
// Parse and validate starting capital
|
||||
int startBalance = Integer.parseInt(startingCapital.getText().replaceAll("[^\\d]", ""));
|
||||
if (startBalance < 0) throw new NumberFormatException("Starting capital must be positive.");
|
||||
|
||||
// Apply the starting balance to all players
|
||||
playerHandler.setStartBalance(startBalance);
|
||||
System.out.println("Starting balance set to: " + startBalance);
|
||||
} catch (NumberFormatException e) {
|
||||
System.err.println("Invalid starting capital: " + e.getMessage());
|
||||
}
|
||||
} else {
|
||||
System.out.println("Only the host can set the starting balance.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the player name from the input field.
|
||||
*/
|
||||
private void applyPlayerName(int playerID) {
|
||||
Player currentPlayer = playerHandler.getPlayerById(playerID);
|
||||
|
||||
String playerName = playerInputField.getText().trim();
|
||||
if (!playerName.isEmpty()) {
|
||||
currentPlayer.setName(playerName);
|
||||
System.out.println("Player name set to: " + playerName);
|
||||
} else {
|
||||
System.err.println("Invalid player name: Name cannot be empty.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the selected figure to the player.
|
||||
*/
|
||||
private void applyFigure(int playerID) {
|
||||
Player currentPlayer = playerHandler.getPlayerById(playerID);
|
||||
|
||||
String selectedFigure = figureDropdown.getSelectedItem();
|
||||
if (selectedFigure != null && !selectedFigure.isEmpty()) {
|
||||
currentPlayer.setFigure(new Figure(0, 0, 0, Rotation.RIGHT, "selectedFigure"));
|
||||
System.out.println("Player figure set to: " + selectedFigure);
|
||||
} else {
|
||||
System.err.println("Invalid figure selection.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt das Hintergrundbild und fügt es als geometrische Ebene hinzu.
|
||||
*/
|
||||
private void addBackgroundImage() {
|
||||
Texture backgroundImage = app.getAssetManager().loadTexture("Pictures/lobby.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);
|
||||
}
|
||||
|
||||
private Geometry createCircle() {
|
||||
|
||||
Sphere sphere = new Sphere(90,90,60.0f);
|
||||
Geometry circleGeometry = new Geometry("Circle", sphere);
|
||||
|
||||
// Create a material with a solid color
|
||||
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
|
||||
material.setColor("Color", playerColor); // Set the desired color
|
||||
circleGeometry.setMaterial(material);
|
||||
|
||||
return circleGeometry;
|
||||
}
|
||||
public void setPlayerColor(ColorRGBA newColor) {
|
||||
this.playerColor = newColor;
|
||||
// Update the circle's color
|
||||
if (circle != null) {
|
||||
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
|
||||
material.setColor("Color", playerColor);
|
||||
circle.setMaterial(material);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns a color to the player based on their ID.
|
||||
*
|
||||
* @param playerID the player's ID
|
||||
*/
|
||||
private void assignPlayerColor(int playerID) {
|
||||
switch (playerID) {
|
||||
case 0:
|
||||
playerColor = PlayerColor.RED.getColor();
|
||||
break;
|
||||
case 1:
|
||||
playerColor = PlayerColor.GREEN_LIGHT.getColor();
|
||||
break;
|
||||
case 2:
|
||||
playerColor = PlayerColor.BLUE.getColor();
|
||||
break;
|
||||
case 3:
|
||||
playerColor = PlayerColor.PINK.getColor();
|
||||
break;
|
||||
case 4:
|
||||
playerColor = PlayerColor.GREEN_DARK.getColor();
|
||||
break;
|
||||
case 5:
|
||||
playerColor = PlayerColor.YELLOW.getColor();
|
||||
break;
|
||||
default:
|
||||
playerColor = ColorRGBA.White; // Default color if ID is unknown
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Geht zurück zum CreateGameMenu.
|
||||
*/
|
||||
private void goBackToCreateGame() {
|
||||
app.getGuiNode().detachChild(menuContainer);
|
||||
app.getGuiNode().detachChild(background);
|
||||
app.getGuiNode().detachChild(circle);
|
||||
app.getGuiNode().detachChild(lowerLeftMenu);
|
||||
app.getGuiNode().detachChild(lowerRightMenu);
|
||||
new CreateGameMenu(app);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a custom action listener to the Selector.
|
||||
*/
|
||||
private void addSelectionActionListener(Selector<String> selector, SelectionActionListener<String> listener) {
|
||||
VersionedReference<Set<Integer>> selectionRef = selector.getSelectionModel().createReference();
|
||||
|
||||
app.getStateManager().attach(new BaseAppState() {
|
||||
@Override
|
||||
public void update(float tpf) {
|
||||
if (selectionRef.update()) {
|
||||
String selected = selectionRef.get().toString();
|
||||
System.out.println(selected);
|
||||
listener.onSelectionChanged(selected);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initialize(Application app) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void cleanup(Application app) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onEnable() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDisable() {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for when the dropdown selection changes.
|
||||
*/
|
||||
private void onDropdownSelectionChanged(String selected) {
|
||||
System.out.println("Selected: " + selected);
|
||||
switch (selected) {
|
||||
case "[0]":
|
||||
System.out.println("Laptop selected");
|
||||
break;
|
||||
case "[1]":
|
||||
System.out.println("Flugzeug selected");
|
||||
break;
|
||||
case "[2]":
|
||||
System.out.println("Jägermeister selected");
|
||||
break;
|
||||
case "[3]":
|
||||
System.out.println("Katze selected");
|
||||
break;
|
||||
case "[4]":
|
||||
System.out.println("OOP selected");
|
||||
break;
|
||||
case "[5]":
|
||||
System.out.println("Handyholster selected");
|
||||
break;
|
||||
default:
|
||||
System.out.println("Unknown selection");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Functional interface for a selection action listener.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
private interface SelectionActionListener<T> {
|
||||
void onSelectionChanged(T selection);
|
||||
}
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
package pp.monopoly.client.gui;
|
||||
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.material.RenderState.BlendMode;
|
||||
import com.jme3.math.ColorRGBA;
|
||||
import com.jme3.scene.Geometry;
|
||||
import com.jme3.scene.Node;
|
||||
import com.jme3.scene.Spatial.CullHint;
|
||||
import com.jme3.scene.shape.Quad;
|
||||
|
||||
import pp.monopoly.client.MonopolyApp;
|
||||
import pp.monopoly.model.Board;
|
||||
|
||||
/**
|
||||
* Represents the visual view of a {@link Board}, used to display the map structure and elements.
|
||||
* This class handles the graphical representation of the board, including background setup and grid lines.
|
||||
*/
|
||||
class MapView {
|
||||
private static final float FIELD_SIZE = 40f;
|
||||
private static final float BACKGROUND_DEPTH = -4f;
|
||||
private static final ColorRGBA BACKGROUND_COLOR = new ColorRGBA(0, 0.05f, 0.05f, 0.5f);
|
||||
|
||||
private final MonopolyApp app;
|
||||
private final Node mapNode = new Node("map");
|
||||
private final Board board;
|
||||
private final MapViewSynchronizer synchronizer;
|
||||
|
||||
/**
|
||||
* Constructs a new MapView for a given {@link Board} and {@link MonopolyApp}.
|
||||
*
|
||||
* @param board the board to visualize
|
||||
* @param app the main application instance
|
||||
*/
|
||||
MapView(Board board, MonopolyApp app) {
|
||||
this.board = board;
|
||||
this.app = app;
|
||||
this.synchronizer = new MapViewSynchronizer(this);
|
||||
setupBackground();
|
||||
app.getGameLogic().addListener(synchronizer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters the {@link MapViewSynchronizer} from listening to board changes.
|
||||
*/
|
||||
void unregister() {
|
||||
app.getGameLogic().removeListener(synchronizer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the background of the map view using a quad geometry.
|
||||
*/
|
||||
private void setupBackground() {
|
||||
Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
|
||||
mat.setColor("Color", BACKGROUND_COLOR);
|
||||
mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
|
||||
Geometry background = new Geometry("MapBackground", new Quad(board.getWidth() * FIELD_SIZE, board.getHeight() * FIELD_SIZE));
|
||||
background.setMaterial(mat);
|
||||
background.setLocalTranslation(0f, 1f, BACKGROUND_DEPTH);
|
||||
background.setCullHint(CullHint.Never);
|
||||
mapNode.attachChild(background);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the root node containing all visual elements in this map view.
|
||||
*
|
||||
* @return the root node for the map view
|
||||
*/
|
||||
public Node getNode() {
|
||||
return mapNode;
|
||||
}
|
||||
|
||||
public Board getBoard() {
|
||||
return board;
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
package pp.monopoly.client.gui;
|
||||
|
||||
import com.jme3.scene.Spatial;
|
||||
|
||||
import pp.monopoly.model.Figure;
|
||||
|
||||
/**
|
||||
* Synchronizes the visual representation of the board with the game model.
|
||||
* Handles updates for items on the board.
|
||||
*/
|
||||
class MapViewSynchronizer extends BoardSynchronizer {
|
||||
private final MapView view;
|
||||
|
||||
/**
|
||||
* Constructs a new MapViewSynchronizer for the given MapView.
|
||||
*
|
||||
* @param view the MapView to synchronize with the game model
|
||||
*/
|
||||
public MapViewSynchronizer(MapView view) {
|
||||
super(view.getBoard(), view.getNode());
|
||||
this.view = view;
|
||||
addExisting();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the state by performing initial setup, such as adding any items to the view.
|
||||
*/
|
||||
|
||||
protected void enableState() {
|
||||
// Platz für zusätzliche Initialisierungen
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the state by clearing the view.
|
||||
*/
|
||||
|
||||
protected void disableState() {
|
||||
view.getNode().detachAllChildren(); // Entfernt alle visuellen Elemente vom Knoten
|
||||
}
|
||||
|
||||
|
||||
public Spatial visit(Figure figure) {
|
||||
return figure.accept(this);
|
||||
}
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
package pp.monopoly.client.gui;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.FlowLayout;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
public class ServerScreen {
|
||||
private JFrame frame;
|
||||
private JTextField inputField;
|
||||
private JLabel label;
|
||||
private JButton startButton;
|
||||
private JButton stopButton;
|
||||
|
||||
public ServerScreen() {
|
||||
initialize();
|
||||
}
|
||||
|
||||
private void initialize() {
|
||||
// Erstelle das Hauptfenster
|
||||
frame = new JFrame("Server Placeholder"); // Setze den Titel
|
||||
frame.setSize(400, 200);
|
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
frame.setLayout(new BorderLayout());
|
||||
|
||||
// Eingabefeld und Label im oberen Bereich
|
||||
JPanel topPanel = new JPanel();
|
||||
topPanel.setLayout(new FlowLayout());
|
||||
|
||||
label = new JLabel("Server-Port:");
|
||||
inputField = new JTextField("42069", 10);
|
||||
topPanel.add(label);
|
||||
topPanel.add(inputField);
|
||||
|
||||
// Buttons im unteren Bereich
|
||||
JPanel bottomPanel = new JPanel();
|
||||
bottomPanel.setLayout(new FlowLayout());
|
||||
|
||||
startButton = new JButton("Start Server");
|
||||
stopButton = new JButton("Stop Server");
|
||||
stopButton.setEnabled(false); // Stop-Button ist anfangs deaktiviert
|
||||
|
||||
bottomPanel.add(startButton);
|
||||
bottomPanel.add(stopButton);
|
||||
|
||||
// Füge die Panels zum Hauptfenster hinzu
|
||||
frame.add(topPanel, BorderLayout.NORTH);
|
||||
frame.add(bottomPanel, BorderLayout.SOUTH);
|
||||
|
||||
// Aktion für Start-Button
|
||||
startButton.addActionListener(e -> startServer());
|
||||
|
||||
// Aktion für Stop-Button
|
||||
stopButton.addActionListener(e -> stopServer());
|
||||
|
||||
// Zeige das Fenster
|
||||
frame.setVisible(true);
|
||||
}
|
||||
|
||||
private void startServer() {
|
||||
String port = inputField.getText();
|
||||
try {
|
||||
int portNumber = Integer.parseInt(port);
|
||||
// Server-Startlogik hier einfügen
|
||||
JOptionPane.showMessageDialog(frame, "Server gestartet auf Port " + portNumber);
|
||||
startButton.setEnabled(false); // Deaktiviere den Start-Button
|
||||
stopButton.setEnabled(true); // Aktiviere den Stop-Button
|
||||
} catch (NumberFormatException e) {
|
||||
JOptionPane.showMessageDialog(frame, "Ungültiger Port: " + port, "Fehler", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
private void stopServer() {
|
||||
// Server-Stoplogik hier einfügen
|
||||
JOptionPane.showMessageDialog(frame, "Server gestoppt.");
|
||||
startButton.setEnabled(true); // Aktiviere den Start-Button
|
||||
stopButton.setEnabled(false); // Deaktiviere den Stop-Button
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SwingUtilities.invokeLater(ServerScreen::new);
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ package pp.monopoly.client.gui;
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.material.RenderState.BlendMode;
|
||||
import com.jme3.math.ColorRGBA;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.scene.Geometry;
|
||||
import com.jme3.scene.shape.Quad;
|
||||
import com.simsilica.lemur.Button;
|
||||
@ -12,7 +13,9 @@ import com.simsilica.lemur.Label;
|
||||
import com.simsilica.lemur.Slider;
|
||||
import com.simsilica.lemur.component.QuadBackgroundComponent;
|
||||
import com.simsilica.lemur.style.ElementId;
|
||||
import com.simsilica.lemur.ValueRenderer;
|
||||
|
||||
import com.simsilica.lemur.Selector;
|
||||
import pp.dialog.Dialog;
|
||||
import pp.monopoly.client.MonopolyApp;
|
||||
|
||||
@ -23,6 +26,7 @@ public class SettingsMenu extends Dialog {
|
||||
private final MonopolyApp app;
|
||||
private final Geometry overlayBackground;
|
||||
private final Container settingsContainer;
|
||||
private final Container backgroundContainer;
|
||||
|
||||
public SettingsMenu(MonopolyApp app) {
|
||||
super(app.getDialogManager());
|
||||
@ -32,10 +36,17 @@ public class SettingsMenu extends Dialog {
|
||||
overlayBackground = createOverlayBackground();
|
||||
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ü
|
||||
settingsContainer = new Container();
|
||||
settingsContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.1f, 0.1f, 0.1f, 0.9f)));
|
||||
|
||||
|
||||
|
||||
// Titel
|
||||
Label settingsTitle = settingsContainer.addChild(new Label("Einstellungen", new ElementId("settings-title")));
|
||||
settingsTitle.setFontSize(48);
|
||||
@ -45,24 +56,34 @@ public class SettingsMenu extends Dialog {
|
||||
effectSoundContainer.addChild(new Label("Effekt Sound", new ElementId("label")));
|
||||
effectSoundContainer.addChild(new Slider());
|
||||
effectSoundContainer.addChild(new Checkbox("Soundeffekte an")).setChecked(true);
|
||||
|
||||
effectSoundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
|
||||
// Hintergrundmusik: Slider und Checkbox
|
||||
Container backgroundMusicContainer = settingsContainer.addChild(new Container());
|
||||
backgroundMusicContainer.addChild(new Label("Hintergrund Musik", new ElementId("label")));
|
||||
backgroundMusicContainer.addChild(new Slider());
|
||||
backgroundMusicContainer.addChild(new Checkbox("Musik an")).setChecked(true);
|
||||
backgroundMusicContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
|
||||
|
||||
// Beenden-Button
|
||||
Button quitButton = settingsContainer.addChild(new Button("Beenden", new ElementId("menu-button")));
|
||||
quitButton.setFontSize(32);
|
||||
quitButton.addClickCommands(source -> app.stop());
|
||||
|
||||
|
||||
float padding = 10; // Padding around the settingsContainer for the background
|
||||
backgroundContainer.setPreferredSize(settingsContainer.getPreferredSize().addLocal(padding, padding, 0));
|
||||
|
||||
|
||||
// Zentriere das Menü
|
||||
settingsContainer.setLocalTranslation(
|
||||
(app.getCamera().getWidth() - settingsContainer.getPreferredSize().x) / 2,
|
||||
(app.getCamera().getHeight() + settingsContainer.getPreferredSize().y) / 2,
|
||||
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);
|
||||
@ -91,6 +112,7 @@ public class SettingsMenu extends Dialog {
|
||||
public void close() {
|
||||
System.out.println("Schließe SettingsMenu..."); // Debugging-Ausgabe
|
||||
app.getGuiNode().detachChild(settingsContainer); // Entferne das Menü
|
||||
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
|
||||
app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
|
||||
app.setSettingsMenuOpen(false); // Menü als geschlossen markieren
|
||||
app.unblockInputs(); // Eingaben wieder aktivieren
|
||||
|
@ -1,5 +1,9 @@
|
||||
package pp.monopoly.client.gui;
|
||||
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.math.ColorRGBA;
|
||||
import com.jme3.math.Vector3f;
|
||||
@ -43,15 +47,18 @@ public class TestWorld {
|
||||
cameraController = new CameraController(
|
||||
app.getCamera(), // Die Kamera der App
|
||||
Vector3f.ZERO, // Fokus auf die Mitte des Spielfelds
|
||||
5, // Radius des Kreises
|
||||
3, // Höhe der Kamera
|
||||
0.5f // Geschwindigkeit der Bewegung
|
||||
4, // Radius des Kreises
|
||||
15, // Höhe der Kamera
|
||||
0 // Geschwindigkeit der Bewegung
|
||||
);
|
||||
|
||||
// Füge die Toolbar hinzu
|
||||
new Toolbar(app, cube);
|
||||
|
||||
cameraController.setPosition(0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Aktualisiert die Kameraposition.
|
||||
*
|
||||
@ -75,12 +82,12 @@ public class TestWorld {
|
||||
*/
|
||||
private void createBoard() {
|
||||
// Erstelle ein Quadrat
|
||||
Box box = new Box(1, 0.01f, 1); // Dünnes Quadrat für die Textur
|
||||
Box box = new Box(10, 0.1f, 10); // Dünnes Quadrat für die Textur
|
||||
Geometry geom = new Geometry("Board", box);
|
||||
|
||||
// Setze das Material mit Textur
|
||||
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);
|
||||
geom.setMaterial(mat);
|
||||
|
||||
|
@ -1,22 +1,25 @@
|
||||
|
||||
package pp.monopoly.client.gui;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import com.jme3.font.BitmapText;
|
||||
import com.jme3.math.ColorRGBA;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.scene.Geometry;
|
||||
import com.simsilica.lemur.Axis;
|
||||
import com.simsilica.lemur.Button;
|
||||
import com.simsilica.lemur.Container;
|
||||
import com.simsilica.lemur.*;
|
||||
import com.simsilica.lemur.component.QuadBackgroundComponent;
|
||||
import com.simsilica.lemur.component.SpringGridLayout;
|
||||
|
||||
import com.simsilica.lemur.style.ElementId;
|
||||
import pp.dialog.Dialog;
|
||||
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 Toolbar {
|
||||
public class Toolbar extends Dialog {
|
||||
|
||||
private final MonopolyApp app;
|
||||
private final Container toolbarContainer;
|
||||
@ -35,22 +38,64 @@ public class Toolbar {
|
||||
* @param cube Der Würfel, der bewegt werden soll
|
||||
*/
|
||||
public Toolbar(MonopolyApp app, Geometry cube) {
|
||||
super(app.getDialogManager());
|
||||
this.app = app;
|
||||
this.cube = cube;
|
||||
|
||||
// Erstelle die Toolbar
|
||||
toolbarContainer = new Container(new SpringGridLayout(Axis.X, Axis.Y));
|
||||
toolbarContainer = new Container(new SpringGridLayout(Axis.X, Axis.Y), "toolbar");
|
||||
|
||||
// Setze die Position am unteren Rand und die Breite
|
||||
toolbarContainer.setLocalTranslation(
|
||||
0, // Links bündig
|
||||
100, // Höhe über dem unteren Rand
|
||||
200, // Höhe über dem unteren Rand
|
||||
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
|
||||
|
||||
|
||||
// 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-Bold")));
|
||||
accountContainer.addChild(new Label("6666€", new ElementId("label-Text"))); //TODO Variable hier einsetzen
|
||||
accountContainer.addChild(new Label("Gulag Frei Karten", new ElementId("label-Bold")));
|
||||
accountContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
|
||||
|
||||
// Add a spacer between accountContainer and overviewContainer
|
||||
Panel spacer = new Panel(); // Create an empty panel as a spacer
|
||||
spacer.setPreferredSize(new Vector3f(5, 0, 0)); // Adjust the width as needed
|
||||
spacer.setBackground(null);
|
||||
toolbarContainer.addChild(spacer);
|
||||
|
||||
// Menü-Container: Ein Container für Übersicht
|
||||
Container overviewContainer = toolbarContainer.addChild(new Container());
|
||||
overviewContainer.addChild(new Label("Übersicht", new ElementId("label-Bold")));
|
||||
overviewContainer.addChild(new Label("„Spieler 1“: 1244€", new ElementId("label-Text")));//TODO Variable hier einsetzen
|
||||
overviewContainer.addChild(new Label("„Spieler 2“: 1244€", new ElementId("label-Text")));//TODO Variable hier einsetzen
|
||||
overviewContainer.addChild(new Label("„Spieler 3“: 1244€", new ElementId("label-Text")));//TODO Variable hier einsetzen
|
||||
overviewContainer.addChild(new Label("„Spieler 4“: 1244€", new ElementId("label-Text")));//TODO Variable hier einsetzen
|
||||
overviewContainer.addChild(new Label("„Spieler 5“: 1244€", new ElementId("label-Text")));//TODO Variable hier einsetzen
|
||||
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.setPreferredSize(new Vector3f(400, 150, 0));
|
||||
diceContainer.addChild(new Label("Wo Würfel?", new ElementId("label")));
|
||||
diceContainer.addChild(addDiceRollButton());
|
||||
diceContainer.setBackground(null);
|
||||
|
||||
|
||||
// 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
|
||||
app.getGuiNode().attachChild(toolbarContainer);
|
||||
@ -64,9 +109,10 @@ public class Toolbar {
|
||||
* Initialisiert die Buttons in der Toolbar.
|
||||
*/
|
||||
private void initializeButtons() {
|
||||
addButton("Vorwärts", 1); // Bewegung nach vorne
|
||||
addButton("Rückwärts", -1); // Bewegung nach hinten
|
||||
addTradeMenuButton(); // Bewegung nach vorne
|
||||
addEndTurnButton(); // Bewegung nach hinten
|
||||
addDiceRollButton(); // Würfel-Button
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -75,18 +121,41 @@ public class Toolbar {
|
||||
* @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) {
|
||||
|
||||
/*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() {
|
||||
private Button addDiceRollButton() {
|
||||
Button diceButton = new Button("Würfeln");
|
||||
diceButton.setPreferredSize(new Vector3f(50, 20, 0));
|
||||
diceButton.addClickCommands(source -> rollDice());
|
||||
toolbarContainer.addChild(diceButton);
|
||||
return 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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -0,0 +1,133 @@
|
||||
package pp.monopoly.client.gui.popups;
|
||||
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.material.RenderState.BlendMode;
|
||||
import com.jme3.math.ColorRGBA;
|
||||
import com.jme3.scene.Geometry;
|
||||
import com.jme3.scene.shape.Quad;
|
||||
import com.simsilica.lemur.Container;
|
||||
import com.simsilica.lemur.Label;
|
||||
import com.simsilica.lemur.component.QuadBackgroundComponent;
|
||||
import com.simsilica.lemur.style.ElementId;
|
||||
|
||||
import pp.dialog.Dialog;
|
||||
import pp.monopoly.client.MonopolyApp;
|
||||
import pp.monopoly.model.fields.BuildingProperty;
|
||||
|
||||
/**
|
||||
* TODO Kommentare fixen
|
||||
* SettingsMenu ist ein Overlay-Menü, das durch ESC aufgerufen werden kann.
|
||||
*/
|
||||
public class BuildingPropertyCard extends Dialog {
|
||||
private final MonopolyApp app;
|
||||
private final Geometry overlayBackground;
|
||||
private final Container buildingPropertyContainer;
|
||||
private final Container backgroundContainer;
|
||||
private int index = 37;
|
||||
|
||||
public BuildingPropertyCard(MonopolyApp app) {
|
||||
super(app.getDialogManager());
|
||||
this.app = app;
|
||||
|
||||
//Generate the corresponfing field
|
||||
BuildingProperty field = (BuildingProperty) app.getBoardManager().getFieldAtIndex(index);
|
||||
|
||||
// Halbtransparentes Overlay hinzufügen
|
||||
overlayBackground = createOverlayBackground();
|
||||
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 die Gebäudekarte
|
||||
buildingPropertyContainer = new Container();
|
||||
buildingPropertyContainer.setBackground(new QuadBackgroundComponent(field.getColor().getColor()));
|
||||
|
||||
|
||||
Label settingsTitle = buildingPropertyContainer.addChild(new Label( field.getName(), new ElementId("settings-title")));
|
||||
settingsTitle.setFontSize(48);
|
||||
|
||||
// Text, der auf der Karte steht
|
||||
// Die Preise werden dynamisch dem BoardManager entnommen
|
||||
Container propertyValuesContainer = buildingPropertyContainer.addChild(new Container());
|
||||
propertyValuesContainer.addChild(new Label("„Grundstückswert: " + field.getPrice() + " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));// Leerzeile
|
||||
propertyValuesContainer.addChild(new Label("„Miete allein: " + field.getAllRent().get(0)+ " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("„-mit 1 Haus: " + field.getAllRent().get(1) + " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("„-mit 2 Häuser: " + field.getAllRent().get(2) + " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("„-mit 3 Häuser: " + field.getAllRent().get(3) + " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("„-mit 4 Häuser: " + field.getAllRent().get(4) + " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("„-mit 1 Hotel: " + field.getAllRent().get(5) + " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("„-1 Haus kostet: " + field.getHousePrice()+ " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));// Leerzeile
|
||||
propertyValuesContainer.addChild(new Label("„Hypothek: " + field.getHypo() + " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
|
||||
|
||||
//TODO eventuell diese Stelle löschen, da nur die BuyCard Kaufen und beenden hat
|
||||
|
||||
/*
|
||||
// Beenden-Button
|
||||
Button quitButton = foodFieldContainer.addChild(new Button("Beenden", new ElementId("button")));
|
||||
quitButton.setFontSize(32);
|
||||
// Kaufen-Button
|
||||
Button buyButton = foodFieldContainer.addChild(new Button("Kaufen", new ElementId("button")));
|
||||
buyButton.setFontSize(32);
|
||||
*/
|
||||
|
||||
float padding = 10; // Padding around the settingsContainer for the background
|
||||
backgroundContainer.setPreferredSize(buildingPropertyContainer.getPreferredSize().addLocal(padding, padding, 0));
|
||||
|
||||
|
||||
// Zentriere das Menü
|
||||
buildingPropertyContainer.setLocalTranslation(
|
||||
(app.getCamera().getWidth() - buildingPropertyContainer.getPreferredSize().x) / 2,
|
||||
(app.getCamera().getHeight() + buildingPropertyContainer.getPreferredSize().y) / 2,
|
||||
8
|
||||
);
|
||||
|
||||
backgroundContainer.setLocalTranslation(
|
||||
(app.getCamera().getWidth() - buildingPropertyContainer.getPreferredSize().x - padding) / 2,
|
||||
(app.getCamera().getHeight() + buildingPropertyContainer.getPreferredSize().y+ padding) / 2,
|
||||
7
|
||||
);
|
||||
|
||||
app.getGuiNode().attachChild(buildingPropertyContainer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erstellt einen halbtransparenten Hintergrund für das Menü.
|
||||
*
|
||||
* @return Geometrie des Overlays
|
||||
*/
|
||||
private Geometry createOverlayBackground() {
|
||||
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
|
||||
Geometry overlay = new Geometry("Overlay", quad);
|
||||
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
|
||||
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Halbtransparent
|
||||
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
|
||||
overlay.setMaterial(material);
|
||||
overlay.setLocalTranslation(0, 0, 0);
|
||||
return overlay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schließt das Menü und entfernt die GUI-Elemente.
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
System.out.println("Schließe SettingsMenu..."); // Debugging-Ausgabe
|
||||
app.getGuiNode().detachChild(buildingPropertyContainer); // Entferne das Menü
|
||||
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
|
||||
app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
|
||||
app.setSettingsMenuOpen(false); // Menü als geschlossen markieren TODO passt diese Variable noch (zu finden unter den Temps in MonopolyApp
|
||||
app.unblockInputs(); // Eingaben wieder aktivieren
|
||||
System.out.println("SettingsMenu geschlossen."); // Debugging-Ausgabe
|
||||
}
|
||||
|
||||
public void setIndex(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,122 @@
|
||||
package pp.monopoly.client.gui.popups;
|
||||
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.material.RenderState.BlendMode;
|
||||
import com.jme3.math.ColorRGBA;
|
||||
import com.jme3.scene.Geometry;
|
||||
import com.jme3.scene.shape.Quad;
|
||||
import com.simsilica.lemur.*;
|
||||
import com.simsilica.lemur.component.QuadBackgroundComponent;
|
||||
import com.simsilica.lemur.style.ElementId;
|
||||
import pp.dialog.Dialog;
|
||||
import pp.monopoly.client.MonopolyApp;
|
||||
import pp.monopoly.model.fields.BuildingProperty;
|
||||
|
||||
/**
|
||||
* SettingsMenu ist ein Overlay-Menü, das durch ESC aufgerufen werden kann.
|
||||
*/
|
||||
public class BuyCard extends Dialog {
|
||||
private final MonopolyApp app;
|
||||
private final Geometry overlayBackground;
|
||||
private final Container buyCardContainer;
|
||||
private final Container backgroundContainer;
|
||||
|
||||
private int index = 37;
|
||||
|
||||
public BuyCard(MonopolyApp app) {
|
||||
super(app.getDialogManager());
|
||||
this.app = app;
|
||||
|
||||
//Generate the corresponfing field
|
||||
BuildingProperty field = (BuildingProperty) app.getBoardManager().getFieldAtIndex(index);
|
||||
|
||||
// Halbtransparentes Overlay hinzufügen
|
||||
overlayBackground = createOverlayBackground();
|
||||
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 die Gebäudekarte
|
||||
buyCardContainer = new Container();
|
||||
buyCardContainer.setBackground(new QuadBackgroundComponent(field.getColor().getColor()));
|
||||
|
||||
|
||||
Label settingsTitle = buyCardContainer.addChild(new Label( field.getName(), new ElementId("settings-title")));
|
||||
settingsTitle.setFontSize(48);
|
||||
|
||||
// Text, der auf der Karte steht
|
||||
// Die Preise werden dynamisch dem BoardManager entnommen
|
||||
Container propertyValuesContainer = buyCardContainer.addChild(new Container());
|
||||
propertyValuesContainer.addChild(new Label("„Grundstückswert: " + field.getPrice() + " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));// Leerzeile
|
||||
propertyValuesContainer.addChild(new Label("„Miete allein: " + field.getAllRent().get(0)+ " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("„-mit 1 Haus: " + field.getAllRent().get(1) + " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("„-mit 2 Häuser: " + field.getAllRent().get(2) + " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("„-mit 3 Häuser: " + field.getAllRent().get(3) + " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("„-mit 4 Häuser: " + field.getAllRent().get(4) + " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("„-mit 1 Hotel: " + field.getAllRent().get(5) + " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("„-1 Haus kostet: " + field.getHousePrice()+ " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));// Leerzeile
|
||||
propertyValuesContainer.addChild(new Label("„Hypothek: " + field.getHypo() + " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
|
||||
|
||||
// Beenden-Button
|
||||
Button quitButton = buyCardContainer.addChild(new Button("Beenden", new ElementId("button")));
|
||||
quitButton.setFontSize(32);
|
||||
// Kaufen-Button
|
||||
Button buyButton = buyCardContainer.addChild(new Button("Kaufen", new ElementId("button")));
|
||||
buyButton.setFontSize(32);
|
||||
|
||||
float padding = 10; // Padding around the settingsContainer for the background
|
||||
backgroundContainer.setPreferredSize(buyCardContainer.getPreferredSize().addLocal(padding, padding, 0));
|
||||
|
||||
|
||||
// Zentriere das Menü
|
||||
buyCardContainer.setLocalTranslation(
|
||||
(app.getCamera().getWidth() - buyCardContainer.getPreferredSize().x) / 2,
|
||||
(app.getCamera().getHeight() + buyCardContainer.getPreferredSize().y) / 2,
|
||||
8
|
||||
);
|
||||
|
||||
backgroundContainer.setLocalTranslation(
|
||||
(app.getCamera().getWidth() - buyCardContainer.getPreferredSize().x - padding) / 2,
|
||||
(app.getCamera().getHeight() + buyCardContainer.getPreferredSize().y+ padding) / 2,
|
||||
7
|
||||
);
|
||||
|
||||
app.getGuiNode().attachChild(buyCardContainer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erstellt einen halbtransparenten Hintergrund für das Menü.
|
||||
*
|
||||
* @return Geometrie des Overlays
|
||||
*/
|
||||
private Geometry createOverlayBackground() {
|
||||
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
|
||||
Geometry overlay = new Geometry("Overlay", quad);
|
||||
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
|
||||
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Halbtransparent
|
||||
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
|
||||
overlay.setMaterial(material);
|
||||
overlay.setLocalTranslation(0, 0, 0);
|
||||
return overlay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schließt das Menü und entfernt die GUI-Elemente.
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
System.out.println("Schließe SettingsMenu..."); // Debugging-Ausgabe
|
||||
app.getGuiNode().detachChild(buyCardContainer); // Entferne das Menü
|
||||
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
|
||||
app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
|
||||
app.setSettingsMenuOpen(false); // Menü als geschlossen markieren TODO passt diese Variable noch (zu finden unter den Temps in MonopolyApp
|
||||
app.unblockInputs(); // Eingaben wieder aktivieren
|
||||
System.out.println("SettingsMenu geschlossen."); // Debugging-Ausgabe
|
||||
}
|
||||
}
|
@ -0,0 +1,119 @@
|
||||
package pp.monopoly.client.gui.popups;
|
||||
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.material.RenderState.BlendMode;
|
||||
import com.jme3.math.ColorRGBA;
|
||||
import com.jme3.scene.Geometry;
|
||||
import com.jme3.scene.shape.Quad;
|
||||
import com.simsilica.lemur.Button;
|
||||
import com.simsilica.lemur.Container;
|
||||
import com.simsilica.lemur.Label;
|
||||
import com.simsilica.lemur.component.QuadBackgroundComponent;
|
||||
import com.simsilica.lemur.style.ElementId;
|
||||
import pp.dialog.Dialog;
|
||||
import pp.monopoly.client.MonopolyApp;
|
||||
import pp.monopoly.model.fields.BuildingProperty;
|
||||
|
||||
/**
|
||||
* SettingsMenu ist ein Overlay-Menü, das durch ESC aufgerufen werden kann.
|
||||
*/
|
||||
public class EventCard extends Dialog {
|
||||
private final MonopolyApp app;
|
||||
private final Geometry overlayBackground;
|
||||
private final Container eventCardContainer;
|
||||
private final Container backgroundContainer;
|
||||
|
||||
private int index = 37;
|
||||
|
||||
public EventCard(MonopolyApp app) {
|
||||
super(app.getDialogManager());
|
||||
this.app = app;
|
||||
|
||||
//Generate the corresponfing field
|
||||
BuildingProperty field = (BuildingProperty) app.getBoardManager().getFieldAtIndex(index);
|
||||
|
||||
// Halbtransparentes Overlay hinzufügen
|
||||
overlayBackground = createOverlayBackground();
|
||||
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 die Gebäudekarte
|
||||
eventCardContainer = new Container();
|
||||
eventCardContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f)));
|
||||
|
||||
// Titel
|
||||
// Die Namen werden dynamisch dem BoardManager entnommen
|
||||
Label gateFieldTitle = eventCardContainer.addChild(new Label("Ereigniskarte", new ElementId("settings-title")));
|
||||
gateFieldTitle.setFontSize(48);
|
||||
gateFieldTitle.setColor(ColorRGBA.Black);
|
||||
|
||||
// Text, der auf der Karte steht
|
||||
// Die Preise werden dynamisch dem BoardManager entnommen
|
||||
Container propertyValuesContainer = eventCardContainer.addChild(new Container());
|
||||
propertyValuesContainer.addChild(new Label("Hier könnte ihre Beschreibung stehen ", new ElementId("label-Text")));
|
||||
propertyValuesContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
|
||||
|
||||
// Beenden-Button
|
||||
Button quitButton = eventCardContainer.addChild(new Button("Jawohl", new ElementId("button")));
|
||||
quitButton.setFontSize(32);
|
||||
quitButton.addClickCommands(source -> close());
|
||||
|
||||
|
||||
// TODO Kaufen-Button wird nicht mehr benötigt, prüfen ob weg kann
|
||||
//Button buyButton = buyCardContainer.addChild(new Button("Kaufen", new ElementId("button")));
|
||||
//buyButton.setFontSize(32);
|
||||
|
||||
float padding = 10; // Padding around the settingsContainer for the background
|
||||
backgroundContainer.setPreferredSize(eventCardContainer.getPreferredSize().addLocal(padding, padding, 0));
|
||||
|
||||
|
||||
// Zentriere das Menü
|
||||
eventCardContainer.setLocalTranslation(
|
||||
(app.getCamera().getWidth() - eventCardContainer.getPreferredSize().x) / 2,
|
||||
(app.getCamera().getHeight() + eventCardContainer.getPreferredSize().y) / 2,
|
||||
8
|
||||
);
|
||||
|
||||
backgroundContainer.setLocalTranslation(
|
||||
(app.getCamera().getWidth() - eventCardContainer.getPreferredSize().x - padding) / 2,
|
||||
(app.getCamera().getHeight() + eventCardContainer.getPreferredSize().y+ padding) / 2,
|
||||
7
|
||||
);
|
||||
|
||||
app.getGuiNode().attachChild(eventCardContainer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erstellt einen halbtransparenten Hintergrund für das Menü.
|
||||
*
|
||||
* @return Geometrie des Overlays
|
||||
*/
|
||||
private Geometry createOverlayBackground() {
|
||||
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
|
||||
Geometry overlay = new Geometry("Overlay", quad);
|
||||
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
|
||||
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Halbtransparent
|
||||
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
|
||||
overlay.setMaterial(material);
|
||||
overlay.setLocalTranslation(0, 0, 0);
|
||||
return overlay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schließt das Menü und entfernt die GUI-Elemente.
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
System.out.println("Schließe SettingsMenu..."); // Debugging-Ausgabe
|
||||
app.getGuiNode().detachChild(eventCardContainer); // Entferne das Menü
|
||||
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
|
||||
app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
|
||||
app.setBuyCardPopupOpen(false); // Menü als geschlossen markieren TODO passt diese Variable noch (zu finden unter den Temps in MonopolyApp
|
||||
app.unblockInputs(); // Eingaben wieder aktivieren
|
||||
System.out.println("SettingsMenu geschlossen."); // Debugging-Ausgabe
|
||||
}
|
||||
}
|
@ -0,0 +1,137 @@
|
||||
package pp.monopoly.client.gui.popups;
|
||||
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.material.RenderState.BlendMode;
|
||||
import com.jme3.math.ColorRGBA;
|
||||
import com.jme3.scene.Geometry;
|
||||
import com.jme3.scene.shape.Quad;
|
||||
import com.simsilica.lemur.Button;
|
||||
import com.simsilica.lemur.Container;
|
||||
import com.simsilica.lemur.Label;
|
||||
import com.simsilica.lemur.component.QuadBackgroundComponent;
|
||||
import com.simsilica.lemur.style.ElementId;
|
||||
|
||||
import pp.dialog.Dialog;
|
||||
import pp.monopoly.client.MonopolyApp;
|
||||
import pp.monopoly.model.fields.FoodField;
|
||||
|
||||
/**
|
||||
* FoodFieldCard erstellt die Geböudekarte vom Brandl und der Truppenküche
|
||||
*/
|
||||
public class FoodFieldCard extends Dialog {
|
||||
private final MonopolyApp app;
|
||||
private final Geometry overlayBackground;
|
||||
private final Container foodFieldContainer;
|
||||
private final Container backgroundContainer;
|
||||
private int index = 12;
|
||||
|
||||
public FoodFieldCard(MonopolyApp app) {
|
||||
super(app.getDialogManager());
|
||||
this.app = app;
|
||||
|
||||
//Generate the corresponfing field
|
||||
FoodField field = (FoodField) app.getBoardManager().getFieldAtIndex(index);
|
||||
|
||||
// Halbtransparentes Overlay hinzufügen
|
||||
overlayBackground = createOverlayBackground();
|
||||
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 die Gebäudekarte
|
||||
foodFieldContainer = new Container();
|
||||
foodFieldContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.1f, 0.1f, 0.1f, 0.9f)));
|
||||
|
||||
|
||||
|
||||
// Titel, bestehend aus dynamischen Namen anhand der ID und der Schriftfarbe/größe
|
||||
Label settingsTitle = foodFieldContainer.addChild(new Label(field.getName(), new ElementId("settings-title")));
|
||||
settingsTitle.setFontSize(48);
|
||||
|
||||
// Text, der auf der Karte steht
|
||||
Container propertyValuesContainer = foodFieldContainer.addChild(new Container());
|
||||
propertyValuesContainer.addChild(new Label("„Preis: " + field.getPrice() + " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); // Leerzeile
|
||||
propertyValuesContainer.addChild(new Label("„Wenn man Besitzer des", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label(field.getName()+" ist, so ist die", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("Miete 40-mal so hoch, wie", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("Augen auf den zwei Würfeln sind.", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); // Leerzeile
|
||||
propertyValuesContainer.addChild(new Label("„Wenn man Besitzer beider", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("Restaurants ist, so ist die", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("Miete 100-mal so hoch, wie", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("Augen auf den zwei Würfeln sind.", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); // Leerzeile
|
||||
propertyValuesContainer.addChild(new Label("„Hypothek: " + field.getHypo() + " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
|
||||
|
||||
|
||||
//TODO eventuell diese Stelle löschen, da nur die BuyCard Kaufen und beenden hat
|
||||
|
||||
/*
|
||||
// Beenden-Button
|
||||
Button quitButton = foodFieldContainer.addChild(new Button("Beenden", new ElementId("button")));
|
||||
quitButton.setFontSize(32);
|
||||
// Kaufen-Button
|
||||
Button buyButton = foodFieldContainer.addChild(new Button("Kaufen", new ElementId("button")));
|
||||
buyButton.setFontSize(32);
|
||||
*/
|
||||
|
||||
float padding = 10; // Padding around the settingsContainer for the background
|
||||
backgroundContainer.setPreferredSize(foodFieldContainer.getPreferredSize().addLocal(padding, padding, 0));
|
||||
|
||||
|
||||
// Zentriere das Menü
|
||||
foodFieldContainer.setLocalTranslation(
|
||||
(app.getCamera().getWidth() - foodFieldContainer.getPreferredSize().x) / 2,
|
||||
(app.getCamera().getHeight() + foodFieldContainer.getPreferredSize().y) / 2,
|
||||
8
|
||||
);
|
||||
|
||||
backgroundContainer.setLocalTranslation(
|
||||
(app.getCamera().getWidth() - foodFieldContainer.getPreferredSize().x - padding) / 2,
|
||||
(app.getCamera().getHeight() + foodFieldContainer.getPreferredSize().y+ padding) / 2,
|
||||
7
|
||||
);
|
||||
|
||||
app.getGuiNode().attachChild(foodFieldContainer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erstellt einen halbtransparenten Hintergrund für das Menü.
|
||||
*
|
||||
* @return Geometrie des Overlays
|
||||
*/
|
||||
private Geometry createOverlayBackground() {
|
||||
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
|
||||
Geometry overlay = new Geometry("Overlay", quad);
|
||||
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
|
||||
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Halbtransparent
|
||||
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
|
||||
overlay.setMaterial(material);
|
||||
overlay.setLocalTranslation(0, 0, 0);
|
||||
return overlay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schließt das Menü und entfernt die GUI-Elemente.
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
System.out.println("Schließe SettingsMenu..."); // Debugging-Ausgabe
|
||||
app.getGuiNode().detachChild(foodFieldContainer); // Entferne das Menü
|
||||
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
|
||||
app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
|
||||
app.setSettingsMenuOpen(false); // Menü als geschlossen markieren TODO passt diese Variable noch (zu finden unter den Temps in MonopolyApp
|
||||
app.unblockInputs(); // Eingaben wieder aktivieren
|
||||
System.out.println("SettingsMenu geschlossen."); // Debugging-Ausgabe
|
||||
}
|
||||
|
||||
public void setIndex(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,129 @@
|
||||
package pp.monopoly.client.gui.popups;
|
||||
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.material.RenderState.BlendMode;
|
||||
import com.jme3.math.ColorRGBA;
|
||||
import com.jme3.scene.Geometry;
|
||||
import com.jme3.scene.shape.Quad;
|
||||
import com.simsilica.lemur.Container;
|
||||
import com.simsilica.lemur.Label;
|
||||
import com.simsilica.lemur.component.QuadBackgroundComponent;
|
||||
import com.simsilica.lemur.style.ElementId;
|
||||
import pp.dialog.Dialog;
|
||||
import pp.monopoly.client.MonopolyApp;
|
||||
import pp.monopoly.model.fields.GateField;
|
||||
|
||||
/**
|
||||
* SettingsMenu ist ein Overlay-Menü, das durch ESC aufgerufen werden kann.
|
||||
*/
|
||||
public class GateFieldCard extends Dialog {
|
||||
private final MonopolyApp app;
|
||||
private final Geometry overlayBackground;
|
||||
private final Container gateFieldContainer;
|
||||
private final Container backgroundContainer;
|
||||
private int index = 5;
|
||||
|
||||
public GateFieldCard(MonopolyApp app) {
|
||||
super(app.getDialogManager());
|
||||
this.app = app;
|
||||
|
||||
//Generate the corresponfing field
|
||||
GateField field = (GateField) app.getBoardManager().getFieldAtIndex(index);
|
||||
|
||||
// Halbtransparentes Overlay hinzufügen
|
||||
overlayBackground = createOverlayBackground();
|
||||
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 die Gebäudekarte
|
||||
gateFieldContainer = new Container();
|
||||
gateFieldContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f)));
|
||||
|
||||
// Titel
|
||||
// Die Namen werden dynamisch dem BoardManager entnommen
|
||||
Label gateFieldTitle = gateFieldContainer.addChild(new Label(field.getName(), new ElementId("settings-title")));
|
||||
gateFieldTitle.setFontSize(48);
|
||||
gateFieldTitle.setColor(ColorRGBA.Black);
|
||||
|
||||
// Text, der auf der Karte steht
|
||||
// Die Preise werden dynamisch dem BoardManager entnommen
|
||||
Container propertyValuesContainer = gateFieldContainer.addChild(new Container());
|
||||
propertyValuesContainer.addChild(new Label("„Preis: " + field.getPrice() + " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("Wenn man 1 Bahnhof besitzt: 250 EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("Wenn man 2 Bahnhöfe besitzt: 500 EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("Wenn man 3 Bahnhöfe besitzt: 1000 EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("Wenn man 4 Bahnhöfe besitzt: 2000 EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("„Hypothek: " + field.getHypo() + " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
|
||||
|
||||
//TODO eventuell diese Stelle löschen, da nur die BuyCard Kaufen und beenden hat
|
||||
|
||||
/*
|
||||
// Beenden-Button
|
||||
Button quitButton = foodFieldContainer.addChild(new Button("Beenden", new ElementId("button")));
|
||||
quitButton.setFontSize(32);
|
||||
// Kaufen-Button
|
||||
Button buyButton = foodFieldContainer.addChild(new Button("Kaufen", new ElementId("button")));
|
||||
buyButton.setFontSize(32);
|
||||
*/
|
||||
|
||||
float padding = 10; // Padding around the settingsContainer for the background
|
||||
backgroundContainer.setPreferredSize(gateFieldContainer.getPreferredSize().addLocal(padding, padding, 0));
|
||||
|
||||
|
||||
// Zentriere das Menü
|
||||
gateFieldContainer.setLocalTranslation(
|
||||
(app.getCamera().getWidth() - gateFieldContainer.getPreferredSize().x) / 2,
|
||||
(app.getCamera().getHeight() + gateFieldContainer.getPreferredSize().y) / 2,
|
||||
8
|
||||
);
|
||||
|
||||
backgroundContainer.setLocalTranslation(
|
||||
(app.getCamera().getWidth() - gateFieldContainer.getPreferredSize().x - padding) / 2,
|
||||
(app.getCamera().getHeight() + gateFieldContainer.getPreferredSize().y+ padding) / 2,
|
||||
7
|
||||
);
|
||||
|
||||
app.getGuiNode().attachChild(gateFieldContainer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erstellt einen halbtransparenten Hintergrund für das Menü.
|
||||
*
|
||||
* @return Geometrie des Overlays
|
||||
*/
|
||||
private Geometry createOverlayBackground() {
|
||||
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
|
||||
Geometry overlay = new Geometry("Overlay", quad);
|
||||
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
|
||||
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Halbtransparent
|
||||
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
|
||||
overlay.setMaterial(material);
|
||||
overlay.setLocalTranslation(0, 0, 0);
|
||||
return overlay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schließt das Menü und entfernt die GUI-Elemente.
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
System.out.println("Schließe SettingsMenu..."); // Debugging-Ausgabe
|
||||
app.getGuiNode().detachChild(gateFieldContainer); // Entferne das Menü
|
||||
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
|
||||
app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
|
||||
app.setSettingsMenuOpen(false); // Menü als geschlossen markieren TODO passt diese Variable noch (zu finden unter den Temps in MonopolyApp
|
||||
app.unblockInputs(); // Eingaben wieder aktivieren
|
||||
System.out.println("SettingsMenu geschlossen."); // Debugging-Ausgabe
|
||||
}
|
||||
|
||||
public void setIndex(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package pp.monopoly.client.gui.popups;
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 2013-2013 jMonkeyEngine
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
import com.jme3.scene.Spatial;
|
||||
|
||||
|
||||
/**
|
||||
* Notified when the current selection changes.
|
||||
*
|
||||
* @author Paul Speed
|
||||
*/
|
||||
public interface SelectionListener {
|
||||
|
||||
public void selectionChanged( Spatial selection, Spatial previous );
|
||||
}
|
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 |
BIN
Projekte/monopoly/client/src/main/resources/Pictures/lobby.png
Normal file
BIN
Projekte/monopoly/client/src/main/resources/Pictures/lobby.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.9 MiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
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.
@ -28,19 +28,19 @@ public class MonopolyConfig extends Config {
|
||||
* The default port number for the Monopoly server.
|
||||
*/
|
||||
@Property("port")
|
||||
private int port = 42069;
|
||||
private int port = 4321;
|
||||
|
||||
/**
|
||||
* The width of the game map in terms of grid units.
|
||||
*/
|
||||
@Property("map.width")
|
||||
private int mapWidth = 10;
|
||||
private int mapWidth = 12;
|
||||
|
||||
/**
|
||||
* The height of the game map in terms of grid units.
|
||||
*/
|
||||
@Property("map.height")
|
||||
private int mapHeight = 10;
|
||||
private int mapHeight = 12;
|
||||
|
||||
/**
|
||||
* Creates an instance of {@code MonopolyConfig} with default settings.
|
||||
|
@ -0,0 +1,8 @@
|
||||
package pp.monopoly.game.client;
|
||||
|
||||
public class ActiveState extends ClientState{
|
||||
|
||||
ActiveState(ClientGameLogic logic) {
|
||||
super(logic);
|
||||
}
|
||||
}
|
@ -1,19 +1,11 @@
|
||||
////////////////////////////////////////
|
||||
// Programming project code
|
||||
// UniBw M, 2022, 2023, 2024
|
||||
// www.unibw.de/inf2
|
||||
// (c) Mark Minas (mark.minas@unibw.de)
|
||||
////////////////////////////////////////
|
||||
|
||||
package pp.monopoly.game.client;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.System.Logger;
|
||||
import java.lang.System.Logger.Level;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import pp.monopoly.game.server.PlayerHandler;
|
||||
import pp.monopoly.message.client.ClientMessage;
|
||||
import pp.monopoly.message.server.BuyPropertyResponse;
|
||||
import pp.monopoly.message.server.DiceResult;
|
||||
@ -21,6 +13,7 @@ import pp.monopoly.message.server.EventDrawCard;
|
||||
import pp.monopoly.message.server.GameOver;
|
||||
import pp.monopoly.message.server.GameStart;
|
||||
import pp.monopoly.message.server.JailEvent;
|
||||
import pp.monopoly.message.server.NextPlayerTurn;
|
||||
import pp.monopoly.message.server.PlayerStatusUpdate;
|
||||
import pp.monopoly.message.server.ServerInterpreter;
|
||||
import pp.monopoly.message.server.TimeOutWarning;
|
||||
@ -37,26 +30,28 @@ import pp.monopoly.notification.InfoTextEvent;
|
||||
import pp.monopoly.notification.Sound;
|
||||
import pp.monopoly.notification.SoundEvent;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.System.Logger;
|
||||
import java.lang.System.Logger.Level;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Controls the client-side game logic for Monopoly.
|
||||
* Manages the player's placement, interactions with the map, and response to server messages.
|
||||
* Handles interactions with the server and game state management on the client side.
|
||||
*/
|
||||
public class ClientGameLogic implements ServerInterpreter, GameEventBroker {
|
||||
|
||||
/** Logger for the client-side game logic. */
|
||||
static final Logger LOGGER = System.getLogger(ClientGameLogic.class.getName());
|
||||
|
||||
/** The object responsible for sending messages to the server. */
|
||||
private final ClientSender clientSender;
|
||||
|
||||
/** A list of listeners to receive game events. */
|
||||
private final List<GameEventListener> listeners = new ArrayList<>();
|
||||
|
||||
/** The game board representing the player's current state. */
|
||||
private Board board;
|
||||
|
||||
private ClientState state = new ClientState(this) {
|
||||
|
||||
};
|
||||
/** The current state of the client game logic. */
|
||||
private ClientState state = new LobbyState(this);
|
||||
|
||||
private static PlayerHandler playerHandler;
|
||||
|
||||
/**
|
||||
* Constructs a ClientGameLogic with the specified sender object.
|
||||
@ -69,6 +64,8 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker {
|
||||
|
||||
/**
|
||||
* Returns the current state of the game logic.
|
||||
*
|
||||
* @return the current state
|
||||
*/
|
||||
ClientState getState() {
|
||||
return state;
|
||||
@ -86,10 +83,14 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker {
|
||||
state.entry();
|
||||
}
|
||||
|
||||
public static PlayerHandler getPlayerHandler() {
|
||||
return playerHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the player's own map.
|
||||
* Returns the player's game board.
|
||||
*
|
||||
* @return the player's own map
|
||||
* @return the player's game board
|
||||
*/
|
||||
public Board getBoard() {
|
||||
return board;
|
||||
@ -116,32 +117,23 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker {
|
||||
/**
|
||||
* Emits an event to play the specified sound.
|
||||
*
|
||||
* @param sound the sound to be played.
|
||||
* @param sound the sound to be played
|
||||
*/
|
||||
public void playSound(Sound sound) {
|
||||
notifyListeners(new SoundEvent(sound));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a map from the specified file.
|
||||
*
|
||||
* @param file the file to load the map from
|
||||
* @throws IOException if an I/O error occurs
|
||||
*/
|
||||
public void loadMap(File file) throws IOException {
|
||||
state.loadMap(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to the server.
|
||||
*
|
||||
* @param msg the message to be sent
|
||||
*/
|
||||
void send(ClientMessage msg) {
|
||||
if (clientSender == null)
|
||||
if (clientSender == null) {
|
||||
LOGGER.log(Level.ERROR, "trying to send {0} with sender==null", msg); //NON-NLS
|
||||
else
|
||||
} else {
|
||||
clientSender.send(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -173,12 +165,13 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker {
|
||||
synchronized (this) {
|
||||
copy = new ArrayList<>(listeners);
|
||||
}
|
||||
for (GameEventListener listener : copy)
|
||||
for (GameEventListener listener : copy) {
|
||||
event.notifyListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called once per frame by the update loop.
|
||||
* Updates the game logic once per frame in the update loop.
|
||||
*
|
||||
* @param delta time in seconds since the last update call
|
||||
*/
|
||||
@ -186,6 +179,11 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker {
|
||||
state.update(delta);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the response for buying a property.
|
||||
*
|
||||
* @param msg the message containing the buy property response
|
||||
*/
|
||||
@Override
|
||||
public void received(BuyPropertyResponse msg) {
|
||||
if (msg.isSuccessful()) {
|
||||
@ -195,35 +193,66 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker {
|
||||
setInfoText("Unable to buy " + msg.getPropertyName() + ". Reason: " + msg.getReason());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handles the result of a dice roll.
|
||||
*
|
||||
* @param msg the message containing the dice roll result
|
||||
*/
|
||||
@Override
|
||||
public void received(DiceResult msg) {
|
||||
setInfoText("You rolled a " + msg.calcTotal() + "!");
|
||||
//Set the dice images
|
||||
playSound(Sound.DICE_ROLL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handles drawing an event card.
|
||||
*
|
||||
* @param msg the message containing the drawn card details
|
||||
*/
|
||||
@Override
|
||||
public void received(EventDrawCard msg) {
|
||||
setInfoText("Event card drawn: " + msg.getCardDescription());
|
||||
//event card logic
|
||||
playSound(Sound.EVENT_CARD);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handles the game over message.
|
||||
*
|
||||
* @param msg the message containing game over details
|
||||
*/
|
||||
@Override
|
||||
public void received(GameOver msg) {
|
||||
if (msg.isWinner()) {
|
||||
setInfoText("Congratulations! You have won the game!");
|
||||
//Winner popup
|
||||
playSound(Sound.WINNER);
|
||||
} else {
|
||||
setInfoText("Game over. Better luck next time!");
|
||||
// Looser popup
|
||||
playSound(Sound.LOSER);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handles the start of the game.
|
||||
*
|
||||
* @param msg the game start message
|
||||
*/
|
||||
@Override
|
||||
public void received(GameStart msg) {
|
||||
playerHandler = msg.getPlayerHandler();
|
||||
setInfoText("The game has started! Good luck!");
|
||||
setState(new WaitForTurnState(this));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handles jail-related events.
|
||||
*
|
||||
* @param msg the message containing jail event details
|
||||
*/
|
||||
@Override
|
||||
public void received(JailEvent msg) {
|
||||
if (msg.isGoingToJail()) {
|
||||
@ -233,28 +262,74 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker {
|
||||
setInfoText("You are out of jail!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates the status of a player.
|
||||
*
|
||||
* @param msg the message containing player status update details
|
||||
*/
|
||||
@Override
|
||||
public void received(PlayerStatusUpdate msg) {
|
||||
|
||||
setInfoText("Player " + msg.getPlayerName() + " status updated: " + msg.getStatus());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handles timeout warnings.
|
||||
*
|
||||
* @param msg the message containing timeout warning details
|
||||
*/
|
||||
@Override
|
||||
public void received(TimeOutWarning msg) {
|
||||
setInfoText("Warning! Time is running out. You have " + msg.getRemainingTime() + " seconds left.");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Displays the player's assets in response to a server query.
|
||||
*
|
||||
* @param msg the message containing the player's assets
|
||||
*/
|
||||
@Override
|
||||
public void received(ViewAssetsResponse msg) {
|
||||
setInfoText("Your current assets are being displayed.");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handles trade replies from other players.
|
||||
*
|
||||
* @param msg the message containing the trade reply
|
||||
*/
|
||||
@Override
|
||||
public void received(TradeReply msg) {
|
||||
if (msg.getTradeHandler().getStatus()) {
|
||||
setInfoText("Trade accepted by " + msg.getTradeHandler().getReceiver().getName() + ".");
|
||||
playSound(Sound.TRADE_ACCEPTED);
|
||||
} else {
|
||||
setInfoText("Trade rejected by " + msg.getTradeHandler().getReceiver().getName() + ".");
|
||||
playSound(Sound.TRADE_REJECTED);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handles trade requests from other players.
|
||||
*
|
||||
* @param msg the message containing the trade request details
|
||||
*/
|
||||
@Override
|
||||
public void received(TradeRequest msg) {
|
||||
setInfoText("Trade offer received from " + msg.getTradeHandler().getSender().getName());
|
||||
// playSound(Sound.TRADE_REQUEST); no sound effect
|
||||
// notifyListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the transition to the next player's turn.
|
||||
*
|
||||
* @param msg the message indicating it's the next player's turn
|
||||
*/
|
||||
@Override
|
||||
public void received(NextPlayerTurn msg) {
|
||||
setInfoText("It's your turn!");
|
||||
setState(new ActiveState(this));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,8 @@
|
||||
package pp.monopoly.game.client;
|
||||
|
||||
public class LobbyState extends ClientState{
|
||||
|
||||
LobbyState(ClientGameLogic logic) {
|
||||
super(logic);
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package pp.monopoly.game.client;
|
||||
|
||||
public class WaitForTurnState extends ClientState{
|
||||
|
||||
WaitForTurnState(ClientGameLogic logic) {
|
||||
super(logic);
|
||||
}
|
||||
}
|
@ -13,7 +13,7 @@ import java.util.Random;
|
||||
import pp.monopoly.message.server.DiceResult;
|
||||
import pp.monopoly.model.FieldVisitor;
|
||||
import pp.monopoly.model.Figure;
|
||||
import pp.monopoly.model.card.DeckHelper;
|
||||
import pp.monopoly.model.card.Card;
|
||||
import pp.monopoly.model.fields.BuildingProperty;
|
||||
import pp.monopoly.model.fields.EventField;
|
||||
import pp.monopoly.model.fields.FineField;
|
||||
@ -31,8 +31,7 @@ import pp.monopoly.model.fields.WacheField;
|
||||
public class Player implements FieldVisitor<Void>{
|
||||
private final int id;
|
||||
private String name;
|
||||
private PlayerColor color;
|
||||
private int accountBalance = 0;
|
||||
private int accountBalance = 15000;
|
||||
private Figure figure;
|
||||
private List<PropertyField> properties;
|
||||
private int getOutOfJailCard;
|
||||
@ -63,20 +62,38 @@ public class Player implements FieldVisitor<Void>{
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
public void setFigure(Figure figure) {
|
||||
this.figure = figure;
|
||||
}
|
||||
|
||||
public PlayerColor getColor() {
|
||||
switch ((id%6)+1) {
|
||||
case 1: return PlayerColor.BLUE;
|
||||
case 2: return PlayerColor.GREEN_DARK;
|
||||
case 3: return PlayerColor.GREEN_LIGHT;
|
||||
case 4: return PlayerColor.PINK;
|
||||
case 5: return PlayerColor.RED;
|
||||
case 6: return PlayerColor.YELLOW;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of the Player
|
||||
* @param name the new name
|
||||
*/
|
||||
void setName(String name) {
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the PlayerColor
|
||||
* @param color the color to be set to
|
||||
* Retuns the Playerhandler
|
||||
* @return the Playerhandler
|
||||
*/
|
||||
void setColor(PlayerColor color) {
|
||||
this.color = color;
|
||||
public PlayerHandler getHandler() {
|
||||
return handler;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -94,6 +111,21 @@ public class Player implements FieldVisitor<Void>{
|
||||
public int getFieldID() {
|
||||
return fieldID;
|
||||
}
|
||||
void setActive() {
|
||||
state = new ActiveState();
|
||||
}
|
||||
|
||||
boolean finishTurn() {
|
||||
if(canFinishTurn()) {
|
||||
state = new WaitForTurnState();
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
boolean canFinishTurn() {
|
||||
return accountBalance >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves by the specified amount of steps
|
||||
@ -115,9 +147,11 @@ public class Player implements FieldVisitor<Void>{
|
||||
fieldID = fieldID%40;
|
||||
earnMoney(2000);
|
||||
}
|
||||
figure.moveTo(fieldID);
|
||||
return fieldID;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets all the properties owned by this player
|
||||
* @return List of all properties owned by this player
|
||||
@ -134,6 +168,7 @@ public class Player implements FieldVisitor<Void>{
|
||||
public void buyProperty(PropertyField property) {
|
||||
if (property.getOwner() == null && accountBalance >= property.getPrice()) {
|
||||
properties.add(property);
|
||||
property.setOwner(this);
|
||||
pay(property.getPrice());
|
||||
}
|
||||
}
|
||||
@ -149,6 +184,14 @@ public class Player implements FieldVisitor<Void>{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the account Balance
|
||||
* @param accountBalance the amount to be set to
|
||||
*/
|
||||
public void setAccountBalance(int accountBalance) {
|
||||
this.accountBalance = accountBalance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this players current accountBalanece
|
||||
* @return the amount of money currently owned by this player
|
||||
@ -264,7 +307,8 @@ public class Player implements FieldVisitor<Void>{
|
||||
|
||||
@Override
|
||||
public Void visit(EventField field) {
|
||||
DeckHelper.drawCard();
|
||||
Card c = getHandler().getLogic().getDeckHelper().drawCard();
|
||||
getHandler().getLogic().getDeckHelper().visit(c, this);
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -307,6 +351,26 @@ public class Player implements FieldVisitor<Void>{
|
||||
return count;
|
||||
}
|
||||
|
||||
public int getNumHouses() {
|
||||
int total = 0;
|
||||
for (PropertyField field : properties) {
|
||||
if (field.getClass() == BuildingProperty.class) {
|
||||
total += ((BuildingProperty) field).getHouses();
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
public int getNumHotels() {
|
||||
int total = 0;
|
||||
for (PropertyField field : properties) {
|
||||
if (field.getClass() == BuildingProperty.class) {
|
||||
total += ((BuildingProperty) field).getHotel();
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inner class for dice functionality in the game.
|
||||
* Rolls random dice values.
|
||||
@ -440,47 +504,19 @@ public class Player implements FieldVisitor<Void>{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class BankruptState implements PlayerState {
|
||||
|
||||
@Override
|
||||
public DiceResult rollDice() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'rollDice'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void payBail() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'payBail'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void useJailCard() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'useJailCard'");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class WaitForTurnState implements PlayerState {
|
||||
|
||||
@Override
|
||||
public DiceResult rollDice() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'rollDice'");
|
||||
throw new UnsupportedOperationException("not allowed");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void payBail() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'payBail'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void useJailCard() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'useJailCard'");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,17 +2,22 @@ package pp.monopoly.game.server;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
|
||||
import pp.monopoly.model.LimitedLinkedList;
|
||||
/**
|
||||
* A class for helping with player actions and managing thier turns
|
||||
*/
|
||||
public class PlayerHandler {
|
||||
private List<Player> players = new LinkedList<>();
|
||||
private List<Player> players = new LimitedLinkedList<>(6);
|
||||
private Set<Player> readyPlayers = new HashSet<>();
|
||||
private ServerGameLogic logic;
|
||||
private Player hostPlayer;
|
||||
private Player extra = null;
|
||||
|
||||
/**
|
||||
* Contructs a PlayerHandler
|
||||
@ -42,6 +47,14 @@ public class PlayerHandler {
|
||||
players.addAll(players);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the host player
|
||||
* @return the host player
|
||||
*/
|
||||
public Player getHostPlayer() {
|
||||
return hostPlayer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of players
|
||||
* @return number of players in the game
|
||||
@ -50,6 +63,14 @@ public class PlayerHandler {
|
||||
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
|
||||
* @return {@code true} if all players are ready, otherwise {@code false}
|
||||
@ -85,6 +106,9 @@ public class PlayerHandler {
|
||||
throw new IllegalArgumentException("Player already registered");
|
||||
}
|
||||
players.add(player);
|
||||
if(hostPlayer == null) {
|
||||
hostPlayer = player;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -108,8 +132,13 @@ public class PlayerHandler {
|
||||
* Completes a player turn and return the next player
|
||||
* @return the next players who is active
|
||||
*/
|
||||
Player nextPlayer() {
|
||||
public Player nextPlayer() {
|
||||
Player tmp = players.get(0);
|
||||
if (extra != null) {
|
||||
tmp = extra;
|
||||
extra = null;
|
||||
return tmp;
|
||||
}
|
||||
players.remove(0);
|
||||
players.add(tmp);
|
||||
return players.get(0);
|
||||
@ -119,7 +148,7 @@ public class PlayerHandler {
|
||||
* Returns the {@link ServerGameLogic} of this PlayerHandler
|
||||
* @return the {@link ServerGameLogic} of this PlayerHandler
|
||||
*/
|
||||
ServerGameLogic getLogic() {
|
||||
public ServerGameLogic getLogic() {
|
||||
return logic;
|
||||
}
|
||||
|
||||
@ -128,10 +157,32 @@ public class PlayerHandler {
|
||||
* @param id the id to be searched for
|
||||
* @return the player with the required id
|
||||
*/
|
||||
Player getPlayerById(int id) {
|
||||
public Player getPlayerById(int id) {
|
||||
for (Player player : players) {
|
||||
if (player.getId() == id) return player;
|
||||
}
|
||||
throw new NoSuchElementException("Player mit id "+id+" existiert nicht");
|
||||
}
|
||||
|
||||
/**
|
||||
* Arranges the players turns in a random order.
|
||||
* Shuffles the players and sets their state to WaitForNextTurn, the first one will be active
|
||||
*/
|
||||
void randomOrder() {
|
||||
Collections.shuffle(players);
|
||||
for (Player player : players) {
|
||||
player.finishTurn();
|
||||
}
|
||||
players.get(0).setActive();
|
||||
}
|
||||
|
||||
public void setStartBalance(int amount) {
|
||||
for (Player player : players) {
|
||||
player.setAccountBalance(amount);
|
||||
}
|
||||
}
|
||||
|
||||
public void extraTurn(Player player) {
|
||||
if (players.contains(player)) extra = player;
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,30 @@
|
||||
package pp.monopoly.game.server;
|
||||
|
||||
import pp.monopoly.MonopolyConfig;
|
||||
import pp.monopoly.message.client.*;
|
||||
import pp.monopoly.message.server.ServerMessage;
|
||||
import pp.monopoly.message.server.TradeReply;
|
||||
import pp.monopoly.message.server.TradeRequest;
|
||||
import pp.monopoly.message.server.ViewAssetsResponse;
|
||||
import pp.monopoly.model.fields.BoardManager;
|
||||
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.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.NextPlayerTurn;
|
||||
import pp.monopoly.message.server.PlayerStatusUpdate;
|
||||
import pp.monopoly.message.server.ServerMessage;
|
||||
import pp.monopoly.message.server.TradeReply;
|
||||
import pp.monopoly.message.server.TradeRequest;
|
||||
import pp.monopoly.message.server.ViewAssetsResponse;
|
||||
import pp.monopoly.model.Board;
|
||||
import pp.monopoly.model.Figure;
|
||||
import pp.monopoly.model.Rotation;
|
||||
import pp.monopoly.model.card.DeckHelper;
|
||||
import pp.monopoly.model.fields.BoardManager;
|
||||
import pp.monopoly.model.fields.PropertyField;
|
||||
|
||||
/**
|
||||
* Controls the server-side game logic for Monopoly.
|
||||
@ -26,9 +36,11 @@ public class ServerGameLogic implements ClientInterpreter {
|
||||
private final MonopolyConfig config;
|
||||
private final PlayerHandler playerHandler = new PlayerHandler(this);
|
||||
private final ServerSender serverSender;
|
||||
private ServerState state = ServerState.CREATEGAME;
|
||||
private ServerState state = ServerState.LOBBY;
|
||||
private static final int MAX_PLAYERS = 6;
|
||||
private BoardManager boardManager = new BoardManager();
|
||||
private final DeckHelper deckHelper = new DeckHelper();
|
||||
private int startMoney;
|
||||
|
||||
/**
|
||||
* Constructs a ServerGameLogic instance with the specified sender and configuration.
|
||||
@ -120,6 +132,7 @@ public class ServerGameLogic implements ClientInterpreter {
|
||||
|
||||
playerHandler.addPlayer(player);
|
||||
LOGGER.log(Level.DEBUG, "Player added: {0}", player.getId());
|
||||
System.out.println("Anzahl Spieler verbunden:"+ playerHandler.getPlayerCount());
|
||||
|
||||
return player;
|
||||
}
|
||||
@ -158,8 +171,12 @@ public class ServerGameLogic implements ClientInterpreter {
|
||||
public void received(EndTurn msg, int from) {
|
||||
Player player = playerHandler.getPlayerById(from);
|
||||
if (player != null && state == ServerState.INGAME) {
|
||||
LOGGER.log(Level.DEBUG, "Ending turn for player {0}", player.getName());
|
||||
playerHandler.nextPlayer();
|
||||
if (player.finishTurn()) {
|
||||
LOGGER.log(Level.DEBUG, "Ending turn for player {0}", player.getName());
|
||||
Player next = playerHandler.nextPlayer();
|
||||
next.setActive();
|
||||
send(next, new NextPlayerTurn(next));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -172,12 +189,26 @@ public class ServerGameLogic implements ClientInterpreter {
|
||||
@Override
|
||||
public void received(PlayerReady msg, int from) {
|
||||
Player player = playerHandler.getPlayerById(from);
|
||||
if(player == playerHandler.getHostPlayer()) {
|
||||
startMoney = msg.getStartMoney();
|
||||
}
|
||||
|
||||
if (player != null) {
|
||||
player.setName(msg.getName());
|
||||
player.setColor(msg.getColor());
|
||||
player.setName(msg.getName());
|
||||
player.setFigure(new Figure(1, -10, -10, Rotation.LEFT, msg.getFigure()));
|
||||
//TODO add figure to the map
|
||||
playerHandler.setPlayerReady(player, true);
|
||||
LOGGER.log(Level.DEBUG, "Player {0} is ready", player.getName());
|
||||
}
|
||||
|
||||
if(playerHandler.allPlayersReady()) {
|
||||
playerHandler.setStartBalance(startMoney);
|
||||
for (Player p : playerHandler.getPlayers()) {
|
||||
send(p, new GameStart(playerHandler));
|
||||
}
|
||||
playerHandler.randomOrder();
|
||||
send(playerHandler.getPlayerAtIndex(0), new NextPlayerTurn(playerHandler.getPlayerAtIndex(0)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -236,11 +267,12 @@ public class ServerGameLogic implements ClientInterpreter {
|
||||
*/
|
||||
@Override
|
||||
public void received(ViewAssetsRequest msg, int from) {
|
||||
Player player = playerHandler.getPlayerById(from);
|
||||
if (player != null) {
|
||||
LOGGER.log(Level.DEBUG, "Processing ViewAssetsRequest for player {0}", player.getName());
|
||||
Player sender = playerHandler.getPlayerById(from);
|
||||
Player player = msg.getPlayer();
|
||||
if (sender != null && player != null) {
|
||||
LOGGER.log(Level.DEBUG, "Processing ViewAssetsRequest for player {0}", sender.getName());
|
||||
|
||||
send(player, new ViewAssetsResponse(player.getProperties(), player.getAccountBalance(), player.getNumJailCard()));
|
||||
send(sender, new ViewAssetsResponse(boardManager, player.getProperties(), player.getAccountBalance(), player.getNumJailCard()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -256,4 +288,8 @@ public class ServerGameLogic implements ClientInterpreter {
|
||||
public Player getPlayerById(int id) {
|
||||
return playerHandler.getPlayerById(id);
|
||||
}
|
||||
|
||||
public DeckHelper getDeckHelper() {
|
||||
return deckHelper;
|
||||
}
|
||||
}
|
||||
|
@ -1,49 +1,43 @@
|
||||
package pp.monopoly.message.client;
|
||||
|
||||
import pp.monopoly.game.server.PlayerColor;
|
||||
|
||||
/**
|
||||
* Represents a message indicating the player is ready to play.
|
||||
*/
|
||||
public class PlayerReady extends ClientMessage{
|
||||
private boolean isReady;
|
||||
private String name;
|
||||
private PlayerColor color;
|
||||
public class PlayerReady extends ClientMessage {
|
||||
private final boolean isReady;
|
||||
private final String name;
|
||||
private final String figure;
|
||||
private final int startMoney;
|
||||
|
||||
/**
|
||||
* Constructs a PlayerReady message.
|
||||
*
|
||||
* @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, int startMoney) {
|
||||
this.isReady = isReady;
|
||||
this.name = name;
|
||||
this.figure = figure;
|
||||
this.startMoney = startMoney;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the Name
|
||||
* @return the Name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the Playercolor
|
||||
* @return the Playercolor
|
||||
*/
|
||||
public PlayerColor getColor() {
|
||||
return color;
|
||||
public String getFigure() {
|
||||
return figure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player is ready.
|
||||
*
|
||||
* @return true if ready, false otherwise
|
||||
*/
|
||||
public boolean isReady() {
|
||||
return isReady;
|
||||
}
|
||||
|
||||
public int getStartMoney() {
|
||||
return startMoney;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(ClientInterpreter interpreter, int from) {
|
||||
|
@ -1,12 +1,25 @@
|
||||
package pp.monopoly.message.client;
|
||||
|
||||
import pp.monopoly.game.server.Player;
|
||||
|
||||
/**
|
||||
* Represents a request from a player to view their assets.
|
||||
*/
|
||||
public class ViewAssetsRequest extends ClientMessage{
|
||||
|
||||
private final Player player;
|
||||
|
||||
public ViewAssetsRequest(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(ClientInterpreter interpreter, int from) {
|
||||
interpreter.received(this, from);
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
}
|
@ -1,7 +1,19 @@
|
||||
package pp.monopoly.message.server;
|
||||
|
||||
import pp.monopoly.game.server.PlayerHandler;
|
||||
|
||||
public class GameStart extends ServerMessage{
|
||||
|
||||
private final PlayerHandler ph;
|
||||
|
||||
public GameStart(PlayerHandler ph) {
|
||||
this.ph = ph;
|
||||
}
|
||||
|
||||
public PlayerHandler getPlayerHandler() {
|
||||
return ph;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(ServerInterpreter interpreter) {
|
||||
interpreter.received(this);
|
||||
|
@ -0,0 +1,28 @@
|
||||
package pp.monopoly.message.server;
|
||||
|
||||
import pp.monopoly.game.server.Player;
|
||||
|
||||
public class NextPlayerTurn extends ServerMessage{
|
||||
|
||||
private final Player player;
|
||||
|
||||
public NextPlayerTurn(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(ServerInterpreter interpreter) {
|
||||
interpreter.received(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfoTextKey() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getInfoTextKey'");
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
}
|
@ -89,4 +89,11 @@ public interface ServerInterpreter {
|
||||
* @param msg the TradeRequest message received
|
||||
*/
|
||||
void received(TradeRequest msg);
|
||||
|
||||
/**
|
||||
* Handles a NextPlayerTurn message received from the server.
|
||||
*
|
||||
* @param msg the NextPlayerTurn message received
|
||||
*/
|
||||
void received(NextPlayerTurn msg);
|
||||
}
|
||||
|
@ -2,13 +2,16 @@ package pp.monopoly.message.server;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import pp.monopoly.model.fields.BoardManager;
|
||||
import pp.monopoly.model.fields.PropertyField;
|
||||
|
||||
/**
|
||||
* Represents a response containing the player's assets.
|
||||
*/
|
||||
public class ViewAssetsResponse extends ServerMessage{
|
||||
|
||||
private final List<PropertyField> properties;
|
||||
private final BoardManager board;
|
||||
private final int accountBalance;
|
||||
private final int jailCards;
|
||||
|
||||
@ -18,7 +21,8 @@ public class ViewAssetsResponse extends ServerMessage{
|
||||
* @param properties a List of PropertyField objects representing the player's properties
|
||||
* @param accountBalance the player's current account balance
|
||||
*/
|
||||
public ViewAssetsResponse(List<PropertyField> properties, int accountBalance, int jailCards) {
|
||||
public ViewAssetsResponse(BoardManager board, List<PropertyField> properties, int accountBalance, int jailCards) {
|
||||
this.board = board;
|
||||
this.properties = properties;
|
||||
this.accountBalance = accountBalance;
|
||||
this.jailCards = jailCards;
|
||||
@ -47,4 +51,7 @@ public class ViewAssetsResponse extends ServerMessage{
|
||||
return jailCards;
|
||||
}
|
||||
|
||||
public BoardManager getboard() {
|
||||
return board;
|
||||
}
|
||||
}
|
||||
|
@ -57,7 +57,6 @@ public class Board {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.eventBroker = eventBroker;
|
||||
addItem(new Figure(5, 5, 5, Rotation.LEFT));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,7 +0,0 @@
|
||||
package pp.monopoly.model;
|
||||
|
||||
import pp.monopoly.model.card.Card;
|
||||
|
||||
public interface CardVisitor<T> {
|
||||
T visit(Card c);
|
||||
}
|
@ -8,31 +8,11 @@ import static java.lang.Math.max;
|
||||
import static java.lang.Math.min;
|
||||
|
||||
public class Figure implements Item{
|
||||
/**
|
||||
* Enumeration representing the different statuses a Figure can have during the game.
|
||||
*/
|
||||
public enum Status {
|
||||
/**
|
||||
* The ship is in its normal state, not being previewed for placement.
|
||||
*/
|
||||
NORMAL,
|
||||
|
||||
/**
|
||||
* The ship is being previewed in a valid position for placement.
|
||||
*/
|
||||
VALID_PREVIEW,
|
||||
|
||||
/**
|
||||
* The ship is being previewed in an invalid position for placement.
|
||||
*/
|
||||
INVALID_PREVIEW
|
||||
}
|
||||
|
||||
private final String type;
|
||||
private final int length; // The length of the Figure
|
||||
private int x; // The x-coordinate of the Figure's position
|
||||
private int y; // The y-coordinate of the Figure's position
|
||||
private Rotation rot; // The rotation of the Figure
|
||||
private Status status; // The current status of the Figure
|
||||
private final Set<IntPoint> damaged = new HashSet<>(); // The set of positions that have been hit on this ship
|
||||
|
||||
/**
|
||||
@ -40,7 +20,7 @@ public class Figure implements Item{
|
||||
* at position (0, 0), with a default rotation of RIGHT.
|
||||
*/
|
||||
private Figure() {
|
||||
this(0, 0, 0, Rotation.RIGHT);
|
||||
this(0, 0, 0, Rotation.RIGHT, "cube");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -51,12 +31,12 @@ public class Figure implements Item{
|
||||
* @param y the y-coordinate of the Figure's initial position
|
||||
* @param rot the rotation of the Figure
|
||||
*/
|
||||
public Figure(int length, int x, int y, Rotation rot) {
|
||||
public Figure(int length, int x, int y, Rotation rot, String type) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.rot = rot;
|
||||
this.length = length;
|
||||
this.status = Status.NORMAL;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -87,7 +67,7 @@ public class Figure implements Item{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Moves the Figure to the specified position.
|
||||
*
|
||||
@ -98,21 +78,46 @@ public class Figure implements Item{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current status of the Figure.
|
||||
* Moves the Figure to the specified coordinates.
|
||||
*
|
||||
* @return the status of the Figure
|
||||
* @param x the new x-coordinate of the Figure's position
|
||||
* @param y the new y-coordinate of the Figure's position
|
||||
*/
|
||||
public Status getStatus() {
|
||||
return status;
|
||||
public void moveTo(int fieldId) {
|
||||
moveTo(fieldIdToPosition(fieldId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the status of the Figure.
|
||||
*
|
||||
* @param status the new status to be set for the Figure
|
||||
*/
|
||||
public void setStatus(Status status) {
|
||||
this.status = status;
|
||||
private IntPoint fieldIdToPosition(int fieldId) {
|
||||
if (fieldId < 0 || fieldId > 39) {
|
||||
throw new IllegalArgumentException("Invalid fieldId: " + fieldId);
|
||||
}
|
||||
|
||||
// Determine which edge and position along the edge
|
||||
if (fieldId <= 9) {
|
||||
// Bottom edge: From (-10, -10) to (10, -10)
|
||||
int x = -10 + fieldId * 2;
|
||||
return new IntPoint(x, -10);
|
||||
} else if (fieldId <= 19) {
|
||||
// Right edge: From (10, -10) to (10, 10)
|
||||
int y = -10 + (fieldId - 10) * 2;
|
||||
return new IntPoint(10, y);
|
||||
} else if (fieldId <= 29) {
|
||||
// Top edge: From (10, 10) to (-10, 10)
|
||||
int x = 10 - (fieldId - 20) * 2;
|
||||
return new IntPoint(x, 10);
|
||||
} else {
|
||||
// Left edge: From (-10, 10) to (-10, -10)
|
||||
int y = 10 - (fieldId - 30) * 2;
|
||||
return new IntPoint(-10, y);
|
||||
}
|
||||
}
|
||||
|
||||
private Rotation fieldIdToRotation(int fieldId) {
|
||||
if (fieldId >= 0 && fieldId <= 10) return Rotation.DOWN;
|
||||
else if (fieldId <= 20) return Rotation.LEFT;
|
||||
else if (fieldId <= 30) return Rotation.UP;
|
||||
else if (fieldId <= 39) return Rotation.RIGHT;
|
||||
else throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,49 @@
|
||||
package pp.monopoly.model;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* A LinkedList with a maximum size limit.
|
||||
*
|
||||
* @param <E> the type of elements held in this collection
|
||||
*/
|
||||
public class LimitedLinkedList<E> extends LinkedList<E> {
|
||||
|
||||
private final int maxSize;
|
||||
|
||||
/**
|
||||
* Constructs a LimitedLinkedList with the specified maximum size.
|
||||
*
|
||||
* @param maxSize the maximum number of elements this list can hold
|
||||
*/
|
||||
public LimitedLinkedList(int maxSize) {
|
||||
if (maxSize <= 0) {
|
||||
throw new IllegalArgumentException("Max size must be greater than 0");
|
||||
}
|
||||
this.maxSize = maxSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an element to the list. If the list exceeds its maximum size,
|
||||
* the oldest element (first) is removed.
|
||||
*
|
||||
* @param element the element to be added
|
||||
* @return true if the element was added successfully
|
||||
*/
|
||||
@Override
|
||||
public boolean add(E element) {
|
||||
if (size() >= maxSize) {
|
||||
return false;
|
||||
}
|
||||
return super.add(element);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the maximum size of this list.
|
||||
*
|
||||
* @return the maximum size
|
||||
*/
|
||||
public int getMaxSize() {
|
||||
return maxSize;
|
||||
}
|
||||
}
|
@ -6,66 +6,112 @@ import pp.monopoly.model.fields.PropertyField;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Helper class that handles the trade logic between two players.
|
||||
* Manages trade initiation, validation, acceptance, and rejection involving multiple properties, money, and jail cards.
|
||||
* Handles a single trade between two players.
|
||||
* Encapsulates trade details, validation, acceptance, and rejection.
|
||||
*/
|
||||
public class TradeHandler {
|
||||
|
||||
private final Player sender;
|
||||
private final Player receiver;
|
||||
private final int offeredAmount;
|
||||
private final List<PropertyField> offeredProperties;
|
||||
private final int offeredJailCards;
|
||||
private final int requestedAmount;
|
||||
private final List<PropertyField> requestedProperties;
|
||||
private final int requestedJailCards;
|
||||
private Boolean status = null;
|
||||
|
||||
/**
|
||||
* Initiates a trade offer between two players involving properties, money, and jail cards.
|
||||
* Constructs a TradeHandler for a single trade instance.
|
||||
*
|
||||
* @param sender the Player who is initiating the trade
|
||||
* @param receiver the Player who is the target of the trade offer
|
||||
* @param offeredAmount the amount of money the sender offers
|
||||
* @param offeredProperties the list of properties the sender offers
|
||||
* @param offeredJailCards the number of jail cards the sender offers
|
||||
* @param requestedAmount the amount of money the sender requests from the receiver
|
||||
* @param requestedProperties the list of properties the sender requests from the receiver
|
||||
* @param requestedJailCards the number of jail cards the sender requests from the receiver
|
||||
* @return true if the trade offer is valid and initiated, false otherwise
|
||||
* @param sender the Player initiating the trade
|
||||
* @param receiver the Player receiving the trade offer
|
||||
* @param offeredAmount the amount of money offered by the sender
|
||||
* @param offeredProperties the properties offered by the sender
|
||||
* @param offeredJailCards the jail cards offered by the sender
|
||||
* @param requestedAmount the amount of money requested from the receiver
|
||||
* @param requestedProperties the properties requested from the receiver
|
||||
* @param requestedJailCards the jail cards requested from the receiver
|
||||
*/
|
||||
public boolean initiateTrade(Player sender, Player receiver, int offeredAmount, List<PropertyField> offeredProperties,
|
||||
int offeredJailCards, int requestedAmount, List<PropertyField> requestedProperties, int requestedJailCards) {
|
||||
// Validate the trade offer
|
||||
if (!validateTrade(sender, offeredAmount, offeredProperties, offeredJailCards, receiver, requestedAmount, requestedProperties, requestedJailCards)) {
|
||||
public TradeHandler(Player sender, Player receiver, int offeredAmount, List<PropertyField> offeredProperties,
|
||||
int offeredJailCards, int requestedAmount, List<PropertyField> requestedProperties, int requestedJailCards) {
|
||||
this.sender = sender;
|
||||
this.receiver = receiver;
|
||||
this.offeredAmount = offeredAmount;
|
||||
this.offeredProperties = offeredProperties;
|
||||
this.offeredJailCards = offeredJailCards;
|
||||
this.requestedAmount = requestedAmount;
|
||||
this.requestedProperties = requestedProperties;
|
||||
this.requestedJailCards = requestedJailCards;
|
||||
}
|
||||
|
||||
public int getOfferedAmount() {
|
||||
return offeredAmount;
|
||||
}
|
||||
|
||||
public int getOfferedJailCards() {
|
||||
return offeredJailCards;
|
||||
}
|
||||
|
||||
public List<PropertyField> getOfferedProperties() {
|
||||
return offeredProperties;
|
||||
}
|
||||
|
||||
public Player getReceiver() {
|
||||
return receiver;
|
||||
}
|
||||
|
||||
public int getRequestedAmount() {
|
||||
return requestedAmount;
|
||||
}
|
||||
|
||||
public int getRequestedJailCards() {
|
||||
return requestedJailCards;
|
||||
}
|
||||
|
||||
public List<PropertyField> getRequestedProperties() {
|
||||
return requestedProperties;
|
||||
}
|
||||
|
||||
public Player getSender() {
|
||||
return sender;
|
||||
}
|
||||
|
||||
public Boolean getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiates the trade and validates its terms.
|
||||
*
|
||||
* @return true if the trade is valid and can proceed, false otherwise
|
||||
*/
|
||||
public boolean initiateTrade() {
|
||||
if (!validateTrade()) {
|
||||
System.out.println("Trade offer is invalid.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Notify the receiver about the trade offer (this would be an actual message in a real implementation)
|
||||
System.out.println("Trade offer initiated by " + sender.getName() + " to " + receiver.getName());
|
||||
System.out.println("Trade initiated by " + sender.getName() + " to " + receiver.getName());
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts the trade offer and completes the trade between two players.
|
||||
*
|
||||
* @param sender the Player who initiated the trade
|
||||
* @param receiver the Player who accepted the trade
|
||||
* @param offeredAmount the amount of money to transfer from the sender to the receiver
|
||||
* @param offeredProperties the list of properties to transfer from the sender to the receiver
|
||||
* @param offeredJailCards the number of jail cards to transfer from the sender to the receiver
|
||||
* @param requestedAmount the amount of money to transfer from the receiver to the sender
|
||||
* @param requestedProperties the list of properties to transfer from the receiver to the sender
|
||||
* @param requestedJailCards the number of jail cards to transfer from the receiver to the sender
|
||||
* Completes the trade by transferring money, properties, and jail cards.
|
||||
*/
|
||||
public void acceptTrade(Player sender, Player receiver, int offeredAmount, List<PropertyField> offeredProperties,
|
||||
int offeredJailCards, int requestedAmount, List<PropertyField> requestedProperties, int requestedJailCards) {
|
||||
public void acceptTrade() {
|
||||
// Transfer money
|
||||
sender.earnMoney(-offeredAmount); // Deduct money from the sender
|
||||
receiver.earnMoney(offeredAmount); // Add money to the receiver
|
||||
sender.earnMoney(-offeredAmount);
|
||||
receiver.earnMoney(offeredAmount);
|
||||
|
||||
receiver.earnMoney(-requestedAmount); // Deduct money from the receiver
|
||||
sender.earnMoney(requestedAmount); // Add money to the sender
|
||||
receiver.earnMoney(-requestedAmount);
|
||||
sender.earnMoney(requestedAmount);
|
||||
|
||||
// Transfer ownership of the properties from sender to receiver
|
||||
// Transfer properties
|
||||
if (offeredProperties != null) {
|
||||
for (PropertyField property : offeredProperties) {
|
||||
transferProperty(sender, receiver, property);
|
||||
}
|
||||
}
|
||||
|
||||
// Transfer ownership of the properties from receiver to sender
|
||||
if (requestedProperties != null) {
|
||||
for (PropertyField property : requestedProperties) {
|
||||
transferProperty(receiver, sender, property);
|
||||
@ -76,73 +122,57 @@ public class TradeHandler {
|
||||
transferJailCards(sender, receiver, offeredJailCards);
|
||||
transferJailCards(receiver, sender, requestedJailCards);
|
||||
|
||||
System.out.println("Trade accepted. " + sender.getName() + " and " + receiver.getName() + " completed the trade.");
|
||||
System.out.println("Trade completed between " + sender.getName() + " and " + receiver.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Rejects the trade offer.
|
||||
*
|
||||
* @param receiver the Player who is rejecting the trade
|
||||
* Rejects the trade.
|
||||
*/
|
||||
public void rejectTrade(Player receiver) {
|
||||
System.out.println("Trade rejected by " + receiver.getName());
|
||||
public void rejectTrade() {
|
||||
System.out.println(receiver.getName() + " rejected the trade.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a trade offer by checking if the sender and receiver own the properties involved,
|
||||
* have sufficient funds for the money involved in the trade, and have enough jail cards.
|
||||
* Validates the trade offer by checking ownership, balances, and jail cards.
|
||||
*
|
||||
* @param sender the Player initiating the trade
|
||||
* @param offeredAmount the amount of money the sender is offering
|
||||
* @param offeredProperties the list of properties the sender is offering
|
||||
* @param offeredJailCards the number of jail cards the sender is offering
|
||||
* @param receiver the Player receiving the trade offer
|
||||
* @param requestedAmount the amount of money the sender is requesting
|
||||
* @param requestedProperties the list of properties the sender is requesting from the receiver
|
||||
* @param requestedJailCards the number of jail cards the sender is requesting from the receiver
|
||||
* @return true if the trade offer is valid, false otherwise
|
||||
* @return true if the trade is valid, false otherwise
|
||||
*/
|
||||
private boolean validateTrade(Player sender, int offeredAmount, List<PropertyField> offeredProperties, int offeredJailCards,
|
||||
Player receiver, int requestedAmount, List<PropertyField> requestedProperties, int requestedJailCards) {
|
||||
// Check if sender has enough money to offer
|
||||
private boolean validateTrade() {
|
||||
// Validate sender's ability to offer money
|
||||
if (sender.getAccountBalance() < offeredAmount) {
|
||||
System.out.println("Sender does not have enough balance to make this offer.");
|
||||
System.out.println("Sender does not have enough money to offer.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if receiver has enough money to offer
|
||||
// Validate receiver's ability to fulfill the requested amount
|
||||
if (receiver.getAccountBalance() < requestedAmount) {
|
||||
System.out.println("Receiver does not have enough balance to fulfill requested amount.");
|
||||
System.out.println("Receiver does not have enough money to fulfill the request.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if sender owns all the offered properties
|
||||
// Validate property ownership
|
||||
if (offeredProperties != null) {
|
||||
for (PropertyField property : offeredProperties) {
|
||||
if (!sender.getProperties().contains(property)) {
|
||||
System.out.println("Sender does not own the property " + property.getName() + " being offered.");
|
||||
System.out.println("Sender does not own property: " + property.getName());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if receiver owns all the requested properties
|
||||
if (requestedProperties != null) {
|
||||
for (PropertyField property : requestedProperties) {
|
||||
if (!receiver.getProperties().contains(property)) {
|
||||
System.out.println("Receiver does not own the property " + property.getName() + " requested.");
|
||||
System.out.println("Receiver does not own property: " + property.getName());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if sender has enough jail cards to offer
|
||||
// Validate jail cards
|
||||
if (sender.getNumJailCard() < offeredJailCards) {
|
||||
System.out.println("Sender does not have enough jail cards to offer.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if receiver has enough jail cards to fulfill the request
|
||||
if (receiver.getNumJailCard() < requestedJailCards) {
|
||||
System.out.println("Receiver does not have enough jail cards to fulfill the request.");
|
||||
return false;
|
||||
@ -152,17 +182,16 @@ public class TradeHandler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfers a property from one player to another.
|
||||
* Transfers a property between players.
|
||||
*
|
||||
* @param from the Player transferring the property
|
||||
* @param to the Player receiving the property
|
||||
* @param from the Player transferring the property
|
||||
* @param to the Player receiving the property
|
||||
* @param property the PropertyField being transferred
|
||||
*/
|
||||
private void transferProperty(Player from, Player to, PropertyField property) {
|
||||
from.sellProperty(property);
|
||||
to.buyProperty(property);
|
||||
property.setOwner(to); // Update the property's owner
|
||||
|
||||
property.setOwner(to);
|
||||
System.out.println("Property " + property.getName() + " transferred from " + from.getName() + " to " + to.getName());
|
||||
}
|
||||
|
||||
@ -178,6 +207,6 @@ public class TradeHandler {
|
||||
from.removeJailCard();
|
||||
to.addJailCard();
|
||||
}
|
||||
System.out.println("Transferred " + numCards + " jail card(s) from " + from.getName() + " to " + to.getName());
|
||||
System.out.println(numCards + " jail card(s) transferred from " + from.getName() + " to " + to.getName());
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package pp.monopoly.model.card;
|
||||
|
||||
import pp.monopoly.game.server.Player;
|
||||
|
||||
public class Card {
|
||||
private final String description;
|
||||
private final String keyword;
|
||||
@ -9,8 +11,8 @@ public class Card {
|
||||
this.keyword = keyword;
|
||||
}
|
||||
|
||||
public void accept(DeckHelper visitor) {
|
||||
visitor.visit(this);
|
||||
public void accept(DeckHelper visitor, Player player) {
|
||||
visitor.visit(this, player);
|
||||
}
|
||||
|
||||
String getDescription() {
|
||||
|
@ -2,24 +2,317 @@ package pp.monopoly.model.card;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
|
||||
import pp.monopoly.model.CardVisitor;
|
||||
import pp.monopoly.game.server.Player;
|
||||
import pp.monopoly.message.client.EndTurn;
|
||||
|
||||
public class DeckHelper implements CardVisitor<Void>{
|
||||
public class DeckHelper{
|
||||
|
||||
private static Queue<Card> cards;
|
||||
private Queue<Card> cards;
|
||||
private List<Card> drawn = new ArrayList<>();
|
||||
|
||||
private DeckHelper() {
|
||||
public DeckHelper() {
|
||||
cards = new LinkedList<Card>();
|
||||
cards.add(new Card("Du wurdest mit einem Dienst KFZ geblitzt. Zahle: 800€", "dienst-kfz-blitzer"));
|
||||
cards.add(new Card("Die erste Spoparty steht bevor. Ziehe vor zum 23er.", "spoparty"));
|
||||
cards.add(new Card("Du kommst aus dem Gulak frei.", "gulak-frei-1"));
|
||||
cards.add(new Card("Du kommst aus dem Gulak frei.", "gulak-frei-2"));
|
||||
cards.add(new Card("Du hast den Dienstführerschein bestanden. Ziehe vor bis Teststrecke.", "dienstfuehrerschein"));
|
||||
cards.add(new Card("Malkmus läd zum Pubquiz ein. Rücke vor bis zum 20er.", "pubquiz"));
|
||||
cards.add(new Card("Du warst ohne Namensschild in der Truppenküche. Rücke vor zum 10er. Gehe nicht über Monatsgehalt. Ziehe keine 2000x€ ein.", "namensschild-truppenkueche"));
|
||||
cards.add(new Card("Du hast heute die Spendierhosen an und gibst eine Runde in der Unibar. Zahle jedem Spieler: 400€", "spendierhosen-unibar"));
|
||||
cards.add(new Card("Du warst in der Prüfungsphase krank. Gehe 3 Felder zurück.", "pruefungsphase-krank"));
|
||||
cards.add(new Card("Ziehe vor bis zum nächsten Monatsgehalt.", "naechstes-monatsgehalt"));
|
||||
cards.add(new Card("Du hast ein Antreten verschlafen. Zahle: 500€", "antreten-verschlafen-1"));
|
||||
cards.add(new Card("Du hast den Maibock organisiert. Du erhältst: 3000€", "maibock-organisiert"));
|
||||
cards.add(new Card("Der Spieß macht eine unangekündigte Inventur. Zahle für jedes Haus: 400€ und jedes Hotel: 2800€", "inventur-haeuser-hotels"));
|
||||
cards.add(new Card("Es gab keine Mozzarella Bällchen mehr für Thoma. Alle Spieler ziehen vor auf Gym.", "dienstsport-gym"));
|
||||
cards.add(new Card("Auf deiner Stube wurde Schimmel gefunden. Gehe ins Gulak. Begib Dich direkt dorthin. Gehe nicht über Monatsgehalt. Ziehe nicht ein.", "schimmel-gulak"));
|
||||
cards.add(new Card("Deine Stube ist nach einer Partynacht nicht mehr bewohnbar. Du ziehst ins Gulak. Begib Dich direkt dorthin. Gehe nicht über Monatsgehalt. Ziehe nicht ein.", "partynacht-gulak"));
|
||||
cards.add(new Card("Das Jahresabschlussantreten steht an. Ziehe vor bis Schwimmhalle.", "jahresabschlussantreten"));
|
||||
cards.add(new Card("Du wurdest beim Verkaufen von Versicherungen erwischt. Zahle: 4000€", "verkaufen-versicherungen"));
|
||||
cards.add(new Card("Du musstest einen Rückstuferantrag stellen. Setze eine Runde aus.", "rueckstuferantrag"));
|
||||
cards.add(new Card("Auf einer Hausfeier bist du betrunken auf der Treppe gestürzt und dabei auf einen Kameraden gefallen. Zahle: 800€ und gehe zurück zu SanZ.", "hausfeier-sturz"));
|
||||
cards.add(new Card("Beförderung. Beim nächsten Monatsgehalt ziehst du ein: 3000€", "befoerderung"));
|
||||
cards.add(new Card("Du entscheidest dich für eine Dienstreise nach Lourd. Zahle: 1000€ und setze eine Runde aus.", "dienstreise-lourd"));
|
||||
cards.add(new Card("Du warst fleißig Blutspenden und erhältst einen Tag Sonderurlaub. Du bist nochmal an der Reihe.", "blutspenden-sonderurlaub"));
|
||||
cards.add(new Card("Dir wurde auf dem Oktoberfest dein Geldbeutel geklaut. Gebe 10% deines Vermögens ab.", "geldbeutel-oktoberfest"));
|
||||
cards.add(new Card("Du wirst von deinem Chef für vorbildliches Verhalten gelobt. Du erhältst: 4000€", "lob-chef"));
|
||||
cards.add(new Card("Deine Bekanntschaft von letzter Nacht war eine Spo. Lasse dich testen und zahle: 200€", "spo-testen"));
|
||||
cards.add(new Card("Du wurdest von Kranz geexmattet. Gehe zurück zu Prüfungsamt.", "kranz-exmatrikulation"));
|
||||
cards.add(new Card("Die letzte Party ist ein wenig eskaliert. Setze eine Runde aus.", "party-eskaliert"));
|
||||
cards.add(new Card("Du wurdest zur VP gewählt und schmeißt eine Einstandsparty. Zahle: 800€", "vp-einstandsparty"));
|
||||
cards.add(new Card("Du hast eine Party veranstaltet und dick Gewinn gemacht. Ziehe ein: 1500€", "party-gewinn"));
|
||||
cards.add(new Card("Zur falschen Zeit am falschen Ort. Du musst einen Bergmarsch planen und setzt eine Runde aus.", "bergmarsch"));
|
||||
cards.add(new Card("Dein Jodel eines Eispenis mit Unterhodenbeleuchtung geht viral. Ziehe ein: 1000€", "jodel-eispenis"));
|
||||
}
|
||||
|
||||
public void visit(Card card, Player player) {
|
||||
switch (card.getKeyword()) {
|
||||
case "dienst-kfz-blitzer":
|
||||
dienstKfzBlitzer(player);
|
||||
break;
|
||||
|
||||
case "spoparty":
|
||||
spoparty(player);
|
||||
break;
|
||||
|
||||
case "gulak-frei-1":
|
||||
case "gulak-frei-2":
|
||||
gulakFrei(player);
|
||||
break;
|
||||
|
||||
case "dienstfuehrerschein":
|
||||
dienstfuehrerschein(player);
|
||||
break;
|
||||
|
||||
case "pubquiz":
|
||||
pubquiz(player);
|
||||
break;
|
||||
|
||||
case "namensschild-truppenkueche":
|
||||
namensschildTruppenkueche(player);
|
||||
break;
|
||||
|
||||
case "spendierhosen-unibar":
|
||||
spendierhosenUnibar(player);
|
||||
break;
|
||||
|
||||
case "pruefungsphase-krank":
|
||||
pruefungsphaseKrank(player);
|
||||
break;
|
||||
|
||||
case "naechstes-monatsgehalt":
|
||||
naechstesMonatsgehalt(player);
|
||||
break;
|
||||
|
||||
case "antreten-verschlafen-1":
|
||||
antretenVerschlafen(player);
|
||||
break;
|
||||
|
||||
case "maibock-organisiert":
|
||||
maibockOrganisiert(player);
|
||||
break;
|
||||
|
||||
case "inventur-haeuser-hotels":
|
||||
inventurHaeuserHotels(player);
|
||||
break;
|
||||
|
||||
case "dienstsport-gym":
|
||||
dienstsportGym(player);
|
||||
break;
|
||||
|
||||
case "schimmel-gulak":
|
||||
schimmelGulak(player);
|
||||
break;
|
||||
|
||||
case "partynacht-gulak":
|
||||
partynachtGulak(player);
|
||||
break;
|
||||
|
||||
case "jahresabschlussantreten":
|
||||
jahresabschlussantreten(player);
|
||||
break;
|
||||
|
||||
case "verkaufen-versicherungen":
|
||||
verkaufenVersicherungen(player);
|
||||
break;
|
||||
|
||||
case "rueckstuferantrag":
|
||||
rueckstuferantrag(player);
|
||||
break;
|
||||
|
||||
case "hausfeier-sturz":
|
||||
hausfeierSturz(player);
|
||||
break;
|
||||
|
||||
case "befoerderung":
|
||||
befoerderung(player);
|
||||
break;
|
||||
|
||||
case "dienstreise-lourd":
|
||||
dienstreiseLourd(player);
|
||||
break;
|
||||
|
||||
case "blutspenden-sonderurlaub":
|
||||
blutspendenSonderurlaub(player);
|
||||
break;
|
||||
|
||||
case "geldbeutel-oktoberfest":
|
||||
geldbeutelOktoberfest(player);
|
||||
break;
|
||||
|
||||
case "lob-chef":
|
||||
lobChef(player);
|
||||
break;
|
||||
|
||||
case "spo-testen":
|
||||
spoTesten(player);
|
||||
break;
|
||||
|
||||
case "kranz-exmatrikulation":
|
||||
kranzExmatrikulation(player);
|
||||
break;
|
||||
|
||||
case "party-eskaliert":
|
||||
partyEskaliert(player);
|
||||
break;
|
||||
|
||||
case "vp-einstandsparty":
|
||||
vpEinstandsparty(player);
|
||||
break;
|
||||
|
||||
case "party-gewinn":
|
||||
partyGewinn(player);
|
||||
break;
|
||||
|
||||
case "bergmarsch":
|
||||
bergmarsch(player);
|
||||
break;
|
||||
|
||||
case "jodel-eispenis":
|
||||
jodelEispenis(player);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(Card c) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'visit'");
|
||||
}
|
||||
private void dienstKfzBlitzer(Player player) {
|
||||
player.pay(800);
|
||||
}
|
||||
|
||||
private void spoparty(Player player) {
|
||||
player.movePos(14);
|
||||
}
|
||||
|
||||
private void gulakFrei(Player player) {
|
||||
player.addJailCard();
|
||||
}
|
||||
|
||||
private void dienstfuehrerschein(Player player) {
|
||||
player.movePos(20);
|
||||
}
|
||||
|
||||
private void pubquiz(Player player) {
|
||||
player.movePos(39);
|
||||
}
|
||||
|
||||
private void namensschildTruppenkueche(Player player) {
|
||||
//TODO
|
||||
}
|
||||
|
||||
private void spendierhosenUnibar(Player player) {
|
||||
for (Player p : player.getHandler().getPlayers()) {
|
||||
p.earnMoney(400);
|
||||
}
|
||||
player.pay(player.getHandler().getPlayerCount()*400 - 400);
|
||||
}
|
||||
|
||||
private void pruefungsphaseKrank(Player player) {
|
||||
player.movePos(player.getFieldID() - 3);
|
||||
}
|
||||
|
||||
private void naechstesMonatsgehalt(Player player) {
|
||||
player.movePos(0);
|
||||
}
|
||||
|
||||
private void antretenVerschlafen(Player player) {
|
||||
player.pay(500);
|
||||
}
|
||||
|
||||
private void maibockOrganisiert(Player player) {
|
||||
player.earnMoney(3000);
|
||||
}
|
||||
|
||||
private void inventurHaeuserHotels(Player player) {
|
||||
player.pay(player.getNumHouses() * 400 + player.getNumHotels() * 2800);
|
||||
}
|
||||
|
||||
private void dienstsportGym(Player player) {
|
||||
for (Player p : player.getHandler().getPlayers()) {
|
||||
p.movePos(1);
|
||||
}
|
||||
}
|
||||
|
||||
private void schimmelGulak(Player player) {
|
||||
player.movePos(10);
|
||||
}
|
||||
|
||||
private void partynachtGulak(Player player) {
|
||||
player.movePos(10);
|
||||
}
|
||||
|
||||
private void jahresabschlussantreten(Player player) {
|
||||
player.movePos(17);
|
||||
}
|
||||
|
||||
private void verkaufenVersicherungen(Player player) {
|
||||
player.pay(4000);
|
||||
}
|
||||
|
||||
private void rueckstuferantrag(Player player) {
|
||||
player.getHandler().getLogic().received(new EndTurn(), player.getId());
|
||||
}
|
||||
|
||||
private void hausfeierSturz(Player player) {
|
||||
player.pay(800);
|
||||
player.movePos(32);
|
||||
}
|
||||
|
||||
private void befoerderung(Player player) {
|
||||
player.earnMoney(3000);
|
||||
}
|
||||
|
||||
private void dienstreiseLourd(Player player) {
|
||||
player.pay(1000);
|
||||
player.getHandler().getLogic().received(new EndTurn(), player.getId());
|
||||
}
|
||||
|
||||
private void blutspendenSonderurlaub(Player player) {
|
||||
player.getHandler().extraTurn(player);
|
||||
}
|
||||
|
||||
private void geldbeutelOktoberfest(Player player) {
|
||||
player.pay(player.getAccountBalance() / 10);
|
||||
}
|
||||
|
||||
private void lobChef(Player player) {
|
||||
player.earnMoney( 4000);
|
||||
}
|
||||
|
||||
private void spoTesten(Player player) {
|
||||
player.pay( 200);
|
||||
}
|
||||
|
||||
private void kranzExmatrikulation(Player player) {
|
||||
player.movePos(5);
|
||||
}
|
||||
|
||||
private void partyEskaliert(Player player) {
|
||||
player.getHandler().getLogic().received(new EndTurn(), player.getId());
|
||||
}
|
||||
|
||||
private void vpEinstandsparty(Player player) {
|
||||
player.pay( 800);
|
||||
}
|
||||
|
||||
private void partyGewinn(Player player) {
|
||||
player.earnMoney( 1500);
|
||||
}
|
||||
|
||||
private void bergmarsch(Player player) {
|
||||
player.getHandler().getLogic().received(new EndTurn(), player.getId());
|
||||
}
|
||||
|
||||
private void jodelEispenis(Player player) {
|
||||
player.earnMoney(1000);
|
||||
}
|
||||
|
||||
|
||||
private void shuffle() {
|
||||
List<Card> cardList = new ArrayList<>(cards);
|
||||
@ -28,7 +321,13 @@ public class DeckHelper implements CardVisitor<Void>{
|
||||
cards.addAll(cardList);
|
||||
}
|
||||
|
||||
public static Card drawCard() {
|
||||
return cards != null ? cards.poll() : null;
|
||||
public Card drawCard() {
|
||||
if (cards.isEmpty()) {
|
||||
drawn.forEach(cards::add);
|
||||
shuffle();
|
||||
}
|
||||
Card card = cards.poll();
|
||||
drawn.add(card);
|
||||
return card;
|
||||
}
|
||||
}
|
||||
|
@ -22,49 +22,49 @@ public class BoardManager {
|
||||
* Creates a Monopoly GameBoard
|
||||
* @return the List of Fields in correct Order
|
||||
*/
|
||||
private static List<Field> createBoard() {
|
||||
public static List<Field> createBoard() {
|
||||
ArrayList<Field> fields = new ArrayList<>();
|
||||
|
||||
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 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 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 BuildingProperty("PhysikHörsaal", 8, 1000, 60));
|
||||
fields.add(new BuildingProperty("Audimax", 9, 1200, 80));
|
||||
fields.add(new BuildingProperty("PhysikHörsaal", 8, 1000, 60, 500, FieldColor.BLUE_LIGHT));
|
||||
fields.add(new BuildingProperty("Audimax", 9, 1200, 80, 500, FieldColor.BLUE_LIGHT));
|
||||
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 BuildingProperty("12er", 13, 1400, 100));
|
||||
fields.add(new BuildingProperty("23er", 14, 1600, 120));
|
||||
fields.add(new BuildingProperty("12er", 13, 1400, 100, 1000, FieldColor.PINK));
|
||||
fields.add(new BuildingProperty("23er", 14, 1600, 120, 1000, FieldColor.PINK));
|
||||
fields.add(new GateField("HauptWache", 15));
|
||||
fields.add(new BuildingProperty("Schwimmhalle", 16, 1800, 140));
|
||||
fields.add(new BuildingProperty("CISM-Bahn", 17, 1800, 140));
|
||||
fields.add(new BuildingProperty("Schwimmhalle", 16, 1800, 140, 1000, FieldColor.ORANGE));
|
||||
fields.add(new BuildingProperty("CISM-Bahn", 17, 1800, 140, 1000, FieldColor.ORANGE));
|
||||
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 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 BuildingProperty("StudFBer B", 23, 2200, 180));
|
||||
fields.add(new BuildingProperty("StudFBer A", 24, 2400, 200));
|
||||
fields.add(new BuildingProperty("StudFBer B", 23, 2200, 180, 1500, FieldColor.RED));
|
||||
fields.add(new BuildingProperty("StudFBer A", 24, 2400, 200, 1500, FieldColor.RED));
|
||||
fields.add(new GateField("Nordtor", 25));
|
||||
fields.add(new BuildingProperty("Cascada", 26, 2600, 220));
|
||||
fields.add(new BuildingProperty("Fakultätsgebäude", 27, 2600, 220));
|
||||
fields.add(new BuildingProperty("Cascada", 26, 2600, 220, 1500, FieldColor.YELLOW));
|
||||
fields.add(new BuildingProperty("Fakultätsgebäude", 27, 2600, 220, 1500, FieldColor.YELLOW));
|
||||
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 BuildingProperty("Feuerwehr", 31, 3000, 260));
|
||||
fields.add(new BuildingProperty("SanZ", 32, 300, 260));
|
||||
fields.add(new BuildingProperty("Feuerwehr", 31, 3000, 260, 2000, FieldColor.GREEN));
|
||||
fields.add(new BuildingProperty("SanZ", 32, 300, 260, 2000, FieldColor.GREEN));
|
||||
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 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 BuildingProperty("20er", 39, 4000, 500));
|
||||
fields.add(new BuildingProperty("20er", 39, 4000, 500, 2000, FieldColor.BLUE_DARK));
|
||||
|
||||
return fields;
|
||||
}
|
||||
@ -88,4 +88,8 @@ public class BoardManager {
|
||||
if (board.contains(field)) return field.getId();
|
||||
else throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
public List<Field> getBoard() {
|
||||
return board;
|
||||
}
|
||||
}
|
||||
|
@ -1,30 +1,42 @@
|
||||
package pp.monopoly.model.fields;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import pp.monopoly.game.server.Player;
|
||||
|
||||
public class BuildingProperty extends PropertyField {
|
||||
|
||||
private int houses;
|
||||
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);
|
||||
this.housePrice = housePrice;
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int calcRent() {
|
||||
if (hotel) {
|
||||
return (int) Math.round(rent*70/10)*10;
|
||||
return (int) Math.round(rent*rentFactorHotel/10)*10;
|
||||
}
|
||||
switch (houses) {
|
||||
case 1:
|
||||
return (int) Math.round(rent*5/10)*10;
|
||||
return (int) Math.round(rent*rentFactor1/10)*10;
|
||||
case 2:
|
||||
return (int) Math.round(rent*15/10)*10;
|
||||
return (int) Math.round(rent*rentFactor2/10)*10;
|
||||
case 3:
|
||||
return (int) Math.round(rent*40/10)*10;
|
||||
return (int) Math.round(rent*rentFactor3/10)*10;
|
||||
case 4:
|
||||
return (int) Math.round(rent*55/10)*10;
|
||||
return (int) Math.round(rent*rentFactor4/10)*10;
|
||||
|
||||
default:
|
||||
return rent;
|
||||
@ -67,4 +79,31 @@ public class BuildingProperty extends PropertyField {
|
||||
public void accept(Player player) {
|
||||
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;
|
||||
}
|
||||
|
||||
public int getHouses() {
|
||||
return houses;
|
||||
}
|
||||
|
||||
public int getHotel() {
|
||||
return hotel ? 1:0;
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,6 @@ package pp.monopoly.model.fields;
|
||||
|
||||
|
||||
import pp.monopoly.game.server.Player;
|
||||
import pp.monopoly.model.card.Card;
|
||||
import pp.monopoly.model.card.DeckHelper;
|
||||
|
||||
public class EventField extends Field{
|
||||
|
||||
@ -15,9 +13,4 @@ public class EventField extends Field{
|
||||
public void accept(Player player) {
|
||||
player.visit(this);
|
||||
}
|
||||
|
||||
public Card drawCard() {
|
||||
return DeckHelper.drawCard();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,37 @@
|
||||
package pp.monopoly.model.fields;
|
||||
|
||||
import com.jme3.math.ColorRGBA;
|
||||
|
||||
/**
|
||||
* Enum representing eight distinct colors for properties in the game.
|
||||
*/
|
||||
public 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;
|
||||
}
|
||||
}
|
@ -15,4 +15,8 @@ public class GulagField extends Field{
|
||||
player.visit(this);
|
||||
}
|
||||
|
||||
public int getBailCost() {
|
||||
return bailCost;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ public class TestStreckeField extends Field{
|
||||
}
|
||||
|
||||
public int collectMoney() {
|
||||
return money = 0;
|
||||
int tmp = money;
|
||||
money = 0;
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
|
@ -10,5 +10,5 @@
|
||||
# This file defines the configuration settings for the Battleship server.
|
||||
#
|
||||
# The port number on which the server will listen for incoming connections.
|
||||
port=1234
|
||||
port=42069
|
||||
|
||||
|
@ -7,21 +7,6 @@
|
||||
|
||||
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.FileInputStream;
|
||||
import java.io.IOException;
|
||||
@ -31,6 +16,22 @@ import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
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
|
||||
*/
|
||||
@ -119,8 +120,9 @@ public class MonopolyServer implements MessageListener<HostedConnection>, Connec
|
||||
|
||||
@Override
|
||||
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());
|
||||
System.out.println("Spieler verbunden: ID = " + hostedConnection.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -25,7 +25,9 @@ dependencyResolutionManagement {
|
||||
library('jme3-effects', 'org.jmonkeyengine', 'jme3-effects').versionRef('jme')
|
||||
|
||||
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('gson', 'com.google.code.gson:gson:2.11.0')
|
||||
|
Loading…
Reference in New Issue
Block a user