mirror of
https://athene2.informatik.unibw-muenchen.de/progproj/gruppen-ht24/Gruppe-02.git
synced 2024-11-24 21:39:44 +01:00
Merge branch 'gui' into 'main'
Gui See merge request progproj/gruppen-ht24/Gruppe-02!10
This commit is contained in:
commit
e38a7e8cdd
BIN
Battle.j3o
Normal file
BIN
Battle.j3o
Normal file
Binary file not shown.
BIN
BoatSmall.j3o
Normal file
BIN
BoatSmall.j3o
Normal file
Binary file not shown.
BIN
KingGeorgeV.j3o
Normal file
BIN
KingGeorgeV.j3o
Normal file
Binary file not shown.
@ -45,7 +45,12 @@ public class ModelExporter extends SimpleApplication {
|
|||||||
export("Models/BoatSmall/12219_boat_v2_L2.obj", "BoatSmall.j3o"); //NON-NLS
|
export("Models/BoatSmall/12219_boat_v2_L2.obj", "BoatSmall.j3o"); //NON-NLS
|
||||||
export("Models/Battle/14084_WWII_Ship_German_Type_II_U-boat_v2_L1.obj", "Battle.j3o"); //NON-NLS
|
export("Models/Battle/14084_WWII_Ship_German_Type_II_U-boat_v2_L1.obj", "Battle.j3o"); //NON-NLS
|
||||||
export("Models/CV/essex_scb-125_generic.obj", "CV.j3o"); //NON-NLS
|
export("Models/CV/essex_scb-125_generic.obj", "CV.j3o"); //NON-NLS
|
||||||
|
export("Models/Figures/Würfel_blau.obj", "Würfel_blau.j30");
|
||||||
|
export("Models/Figures/Würfel_gelb.obj", "Würfel_gelb.j30");
|
||||||
|
export("Models/Figures/Würfel_grün.obj", "Würfel_grün.j30");
|
||||||
|
export("Models/Figures/Würfel_rosa.obj", "Würfel_rosa.j30");
|
||||||
|
export("Models/Figures/Würfel_rot.obj", "Würfel_rot.j30");
|
||||||
|
export("Models/Figures/Würfel_schwarz.obj", "Würfel_schwarz.j30");
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,76 +1,69 @@
|
|||||||
// Styling of Lemur components
|
// Styling of Lemur components
|
||||||
// For documentation, see:
|
// For documentation, see:
|
||||||
// https://github.com/jMonkeyEngine-Contributions/Lemur/wiki/Styling
|
// https://github.com/jMonkeyEngine-Contributions/Lemur/wiki/Styling
|
||||||
|
|
||||||
import com.simsilica.lemur.*
|
import com.simsilica.lemur.*
|
||||||
import com.simsilica.lemur.component.QuadBackgroundComponent
|
import com.simsilica.lemur.component.QuadBackgroundComponent
|
||||||
|
import com.simsilica.lemur.Button
|
||||||
|
import com.simsilica.lemur.Button.ButtonAction
|
||||||
|
import com.simsilica.lemur.Command
|
||||||
|
import com.simsilica.lemur.HAlignment
|
||||||
|
import com.simsilica.lemur.Insets3f
|
||||||
|
import com.simsilica.lemur.component.QuadBackgroundComponent
|
||||||
|
import com.simsilica.lemur.component.TbtQuadBackgroundComponent
|
||||||
|
|
||||||
def bgColor = color(1, 1, 1, 1)
|
def bgColor = color(1, 1, 1, 1)
|
||||||
def buttonEnabledColor = color(0.8, 0.9, 1, 1)
|
def buttonEnabledColor = color(0, 0, 0, 1)
|
||||||
def buttonDisabledColor = color(0.8, 0.9, 1, 0.2)
|
def buttonDisabledColor = color(0.8, 0.9, 1, 0.2)
|
||||||
//def buttonBgColor = color(0, 0.75, 0.75, 1)
|
def buttonBgColor = color(1, 1, 1, 1)
|
||||||
def sliderColor = color(0.6, 0.8, 0.8, 1)
|
def sliderColor = color(0.6, 0.8, 0.8, 1)
|
||||||
def sliderBgColor = color(0.5, 0.75, 0.75, 1)
|
def sliderBgColor = color(0.5, 0.75, 0.75, 1)
|
||||||
def gradientColor = color(1, 1, 1, 1)
|
def gradientColor = color(0.5, 0.75, 0.85, 0.5)
|
||||||
def tabbuttonEnabledColor = color(0.4, 0.45, 0.5, 1)
|
def tabbuttonEnabledColor = color(0.4, 0.45, 0.5, 1)
|
||||||
def playButtonBorderColor = color(1, 0.6, 0, 1) // For "Spielen" button
|
def solidWhiteBackground = new QuadBackgroundComponent(color(1, 1, 1, 1)) // Solid white
|
||||||
def blackColor = color(0, 0, 0, 1) // Define black color for border
|
|
||||||
|
|
||||||
def playButtonBorderColor = color(1, 0.6, 0, 1) // Orange border for "Spielen" button
|
|
||||||
def playButtonTextColor = color(0, 0, 0, 1) // Black text color for "Spielen" button
|
|
||||||
def buttonBgColor = color(1, 1, 1, 1) // White background for "Spiel beenden" and "Einstellungen" buttons
|
|
||||||
def buttonTextColor = color(0, 0, 0, 1) // Black text color for "Spiel beenden" and "Einstellungen" buttons
|
|
||||||
def borderColor = color(0, 0, 0, 1) // Black border for "Spiel beenden" and "Einstellungen"
|
|
||||||
|
|
||||||
|
|
||||||
def gradient = TbtQuadBackgroundComponent.create(
|
def gradient = TbtQuadBackgroundComponent.create(
|
||||||
texture(name: "/com/simsilica/lemur/icons/bordered-gradient.png", generateMips: false),
|
texture(name: "/com/simsilica/lemur/icons/bordered-gradient.png",
|
||||||
1, 1, 1, 126, 126, 1f, false)
|
generateMips: false),
|
||||||
|
1, 1, 1, 126, 126,
|
||||||
|
1f, false)
|
||||||
|
|
||||||
def doubleGradient = new QuadBackgroundComponent(gradientColor)
|
def doubleGradient = new QuadBackgroundComponent(gradientColor)
|
||||||
doubleGradient.texture = texture(name: "/com/simsilica/lemur/icons/double-gradient-128.png", generateMips: false)
|
doubleGradient.texture = texture(name: "/com/simsilica/lemur/icons/double-gradient-128.png",
|
||||||
|
generateMips: false)
|
||||||
|
|
||||||
|
def orangeBorder = TbtQuadBackgroundComponent.create(
|
||||||
|
texture(name: "/com/simsilica/lemur/icons/bordered-gradient.png", // Replace with an appropriate texture if needed
|
||||||
|
generateMips: false),
|
||||||
|
1, 1, 1, 126, 126,
|
||||||
|
1f, false)
|
||||||
|
orangeBorder.color = color(1, 0.5, 0, 1) // Orange color
|
||||||
|
|
||||||
// Hauptstil für die Schriftart
|
|
||||||
selector("pp") {
|
selector("pp") {
|
||||||
font = font("Interface/Fonts/Metropolis/Metropolis-Regular-32.fnt")
|
font = font("Interface/Fonts/Metropolis/Metropolis-Regular-32.fnt")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Titel für "Einstellungen"
|
selector("label", "pp") {
|
||||||
selector("settings-title", "pp") {
|
insets = new Insets3f(2, 2, 2, 2)
|
||||||
color = color(1, 1, 1, 1)
|
color = buttonEnabledColor
|
||||||
fontSize = 48
|
}
|
||||||
textHAlignment = HAlignment.Center
|
|
||||||
insets = new Insets3f(5, 5, 5, 5)
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
// Container Stil
|
|
||||||
selector("container", "pp") {
|
selector("container", "pp") {
|
||||||
background = gradient.clone()
|
background = solidWhiteBackground.clone()
|
||||||
background.setColor(bgColor)
|
background.setColor(bgColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Slider Stil
|
|
||||||
selector("slider", "pp") {
|
selector("slider", "pp") {
|
||||||
insets = new Insets3f(5, 10, 5, 10) // Abstand
|
background = gradient.clone()
|
||||||
background = new QuadBackgroundComponent(sliderBgColor)
|
background.setColor(bgColor)
|
||||||
}
|
|
||||||
|
|
||||||
selector("play-button", "pp") {
|
|
||||||
color = playButtonTextColor // Black text color
|
|
||||||
background = new QuadBackgroundComponent(playButtonBorderColor) // Orange border background
|
|
||||||
insets = new Insets3f(15, 25, 15, 25) // Padding for larger button size
|
|
||||||
background.setMargin(5, 5) // Thin border effect around the background color
|
|
||||||
fontSize = 36 // Larger font size for prominence
|
|
||||||
}
|
|
||||||
|
|
||||||
selector("menu-button", "pp") {
|
|
||||||
color = buttonTextColor // Black text color
|
|
||||||
background = new QuadBackgroundComponent(buttonBgColor) // White background
|
|
||||||
insets = new Insets3f(10, 20, 10, 20) // Padding
|
|
||||||
background.setMargin(1, 1) // Thin black border
|
|
||||||
background.setColor(borderColor) // Set black border color
|
|
||||||
|
|
||||||
fontSize = 24 // Standard font size
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def pressedCommand = new Command<Button>() {
|
def pressedCommand = new Command<Button>() {
|
||||||
@ -91,6 +84,30 @@ def enabledCommand = new Command<Button>() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def repeatCommand = new Command<Button>() {
|
||||||
|
private long startTime
|
||||||
|
private long lastClick
|
||||||
|
|
||||||
|
void execute(Button source) {
|
||||||
|
// Only do the repeating click while the mouse is
|
||||||
|
// over the button (and pressed of course)
|
||||||
|
if (source.isPressed() && source.isHighlightOn()) {
|
||||||
|
long elapsedTime = System.currentTimeMillis() - startTime
|
||||||
|
// After half a second pause, click 8 times a second
|
||||||
|
if (elapsedTime > 500 && elapsedTime > lastClick + 125) {
|
||||||
|
source.click()
|
||||||
|
|
||||||
|
// Try to quantize the last click time to prevent drift
|
||||||
|
lastClick = ((elapsedTime - 500) / 125) * 125 + 500
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
startTime = System.currentTimeMillis()
|
||||||
|
lastClick = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def stdButtonCommands = [
|
def stdButtonCommands = [
|
||||||
(ButtonAction.Down) : [pressedCommand],
|
(ButtonAction.Down) : [pressedCommand],
|
||||||
(ButtonAction.Up) : [pressedCommand],
|
(ButtonAction.Up) : [pressedCommand],
|
||||||
@ -98,9 +115,101 @@ def stdButtonCommands = [
|
|||||||
(ButtonAction.Disabled): [enabledCommand]
|
(ButtonAction.Disabled): [enabledCommand]
|
||||||
]
|
]
|
||||||
|
|
||||||
selector("button", "pp") {
|
def sliderButtonCommands = [
|
||||||
background = gradient.clone()
|
(ButtonAction.Hover): [repeatCommand]
|
||||||
color = buttonEnabledColor
|
]
|
||||||
|
|
||||||
|
selector("title", "pp") {
|
||||||
|
color = color(0.8, 0.9, 1, 0.85f)
|
||||||
|
highlightColor = color(1, 0.8, 1, 0.85f)
|
||||||
|
shadowColor = color(0, 0, 0, 0.75f)
|
||||||
|
shadowOffset = vec3(2, -2, -1)
|
||||||
|
background = new QuadBackgroundComponent(color(0.5, 0.75, 0.85, 1))
|
||||||
|
background.texture = texture(name: "/com/simsilica/lemur/icons/double-gradient-128.png",
|
||||||
|
generateMips: false)
|
||||||
insets = new Insets3f(2, 2, 2, 2)
|
insets = new Insets3f(2, 2, 2, 2)
|
||||||
|
|
||||||
|
buttonCommands = stdButtonCommands
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
selector("button", "pp") {
|
||||||
|
def outerBackground = new QuadBackgroundComponent(color(1, 0.5, 0, 1)) // Orange border
|
||||||
|
def innerBackground = new QuadBackgroundComponent(buttonBgColor) // Inner button background
|
||||||
|
|
||||||
|
// Apply the outer border as the main background
|
||||||
|
background = outerBackground
|
||||||
|
|
||||||
|
// Use insets to create a margin/padding effect for the inner background
|
||||||
|
insets = new Insets3f(3, 3, 3, 3) // Adjust the border thickness
|
||||||
|
buttonCommands = stdButtonCommands
|
||||||
|
}
|
||||||
|
|
||||||
|
selector("slider", "pp") {
|
||||||
|
insets = new Insets3f(1, 3, 1, 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
selector("slider", "button", "pp") {
|
||||||
|
background = doubleGradient.clone()
|
||||||
|
//background.setColor(sliderBgColor)
|
||||||
|
insets = new Insets3f(0, 0, 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
selector("slider.thumb.button", "pp") {
|
||||||
|
text = "[]"
|
||||||
|
color = sliderColor
|
||||||
|
}
|
||||||
|
|
||||||
|
selector("slider.left.button", "pp") {
|
||||||
|
text = "-"
|
||||||
|
background = doubleGradient.clone()
|
||||||
|
//background.setColor(sliderBgColor)
|
||||||
|
background.setMargin(5, 0)
|
||||||
|
color = sliderColor
|
||||||
|
|
||||||
|
buttonCommands = sliderButtonCommands
|
||||||
|
}
|
||||||
|
|
||||||
|
selector("slider.right.button", "pp") {
|
||||||
|
text = "+"
|
||||||
|
background = doubleGradient.clone()
|
||||||
|
//background.setColor(sliderBgColor)
|
||||||
|
background.setMargin(4, 0)
|
||||||
|
color = sliderColor
|
||||||
|
|
||||||
|
buttonCommands = sliderButtonCommands
|
||||||
|
}
|
||||||
|
|
||||||
|
selector("slider.up.button", "pp") {
|
||||||
|
buttonCommands = sliderButtonCommands
|
||||||
|
}
|
||||||
|
|
||||||
|
selector("slider.down.button", "pp") {
|
||||||
|
buttonCommands = sliderButtonCommands
|
||||||
|
}
|
||||||
|
|
||||||
|
selector("checkbox", "pp") {
|
||||||
|
color = buttonEnabledColor
|
||||||
|
}
|
||||||
|
|
||||||
|
selector("rollup", "pp") {
|
||||||
|
background = gradient.clone()
|
||||||
|
background.setColor(bgColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
selector("tabbedPanel", "pp") {
|
||||||
|
activationColor = buttonEnabledColor
|
||||||
|
}
|
||||||
|
|
||||||
|
selector("tabbedPanel.container", "pp") {
|
||||||
|
background = null
|
||||||
|
}
|
||||||
|
|
||||||
|
selector("tab.button", "pp") {
|
||||||
|
background = solidWhiteBackground.clone()
|
||||||
|
background.setColor(bgColor)
|
||||||
|
color = tabbuttonEnabledColor
|
||||||
|
insets = new Insets3f(4, 2, 0, 2)
|
||||||
|
|
||||||
buttonCommands = stdButtonCommands
|
buttonCommands = stdButtonCommands
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
|
////////////////////////////////////////
|
||||||
|
// Programming project code
|
||||||
|
// UniBw M, 2022, 2023, 2024
|
||||||
|
// www.unibw.de/inf2
|
||||||
|
// (c) Mark Minas (mark.minas@unibw.de)
|
||||||
|
////////////////////////////////////////
|
||||||
|
|
||||||
package pp.monopoly.client;
|
package pp.monopoly.client;
|
||||||
|
|
||||||
import java.lang.System.Logger;
|
import java.lang.System.Logger;
|
||||||
@ -7,6 +14,8 @@ import java.util.prefs.Preferences;
|
|||||||
import com.jme3.app.Application;
|
import com.jme3.app.Application;
|
||||||
import com.jme3.app.state.AbstractAppState;
|
import com.jme3.app.state.AbstractAppState;
|
||||||
import com.jme3.app.state.AppStateManager;
|
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.AudioData;
|
||||||
import com.jme3.audio.AudioNode;
|
import com.jme3.audio.AudioNode;
|
||||||
|
|
||||||
@ -15,14 +24,16 @@ import pp.monopoly.notification.SoundEvent;
|
|||||||
import static pp.util.PreferencesUtils.getPreferences;
|
import static pp.util.PreferencesUtils.getPreferences;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An application state that plays sounds based on game events.
|
* An application state that plays sounds.
|
||||||
*/
|
*/
|
||||||
public class GameSound extends AbstractAppState implements GameEventListener {
|
public class GameSound extends AbstractAppState implements GameEventListener {
|
||||||
private static final Logger LOGGER = System.getLogger(GameSound.class.getName());
|
private static final Logger LOGGER = System.getLogger(GameSound.class.getName());
|
||||||
private static final Preferences PREFERENCES = getPreferences(GameSound.class);
|
private static final Preferences PREFERENCES = getPreferences(GameSound.class);
|
||||||
private static final String ENABLED_PREF = "enabled";
|
private static final String ENABLED_PREF = "enabled"; //NON-NLS
|
||||||
|
|
||||||
private Application app; // Feld zum Speichern der Application-Instanz
|
private AudioNode splashSound;
|
||||||
|
private AudioNode shipDestroyedSound;
|
||||||
|
private AudioNode explosionSound;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if sound is enabled in the preferences.
|
* Checks if sound is enabled in the preferences.
|
||||||
@ -42,6 +53,7 @@ public class GameSound extends AbstractAppState implements GameEventListener {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the enabled state of this AppState.
|
* 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.
|
* @param enabled {@code true} to enable the AppState, {@code false} to disable it.
|
||||||
*/
|
*/
|
||||||
@ -49,52 +61,69 @@ public class GameSound extends AbstractAppState implements GameEventListener {
|
|||||||
public void setEnabled(boolean enabled) {
|
public void setEnabled(boolean enabled) {
|
||||||
if (isEnabled() == enabled) return;
|
if (isEnabled() == enabled) return;
|
||||||
super.setEnabled(enabled);
|
super.setEnabled(enabled);
|
||||||
LOGGER.log(Level.INFO, "Sound enabled: {0}", enabled);
|
LOGGER.log(Level.INFO, "Sound enabled: {0}", enabled); //NON-NLS
|
||||||
PREFERENCES.putBoolean(ENABLED_PREF, enabled);
|
PREFERENCES.putBoolean(ENABLED_PREF, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the sound effects for the game and stores the application reference.
|
* Initializes the sound effects for the game.
|
||||||
|
* Overrides {@link AbstractAppState#initialize(AppStateManager, Application)}
|
||||||
*
|
*
|
||||||
* @param stateManager The state manager
|
* @param stateManager The state manager
|
||||||
* @param app The application instance
|
* @param app The application
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void initialize(AppStateManager stateManager, Application app) {
|
public void initialize(AppStateManager stateManager, Application app) {
|
||||||
super.initialize(stateManager, app);
|
super.initialize(stateManager, app);
|
||||||
this.app = app; // Speichert die Application-Instanz
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads a sound from the specified file.
|
* Loads a sound from the specified file.
|
||||||
*
|
*
|
||||||
|
* @param app The application
|
||||||
* @param name The name of the sound file.
|
* @param name The name of the sound file.
|
||||||
* @return The loaded AudioNode.
|
* @return The loaded AudioNode.
|
||||||
*/
|
*/
|
||||||
private AudioNode loadSound(String name) {
|
private AudioNode loadSound(Application app, String name) {
|
||||||
try {
|
try {
|
||||||
AudioNode sound = new AudioNode(app.getAssetManager(), name, AudioData.DataType.Buffer);
|
final AudioNode sound = new AudioNode(app.getAssetManager(), name, AudioData.DataType.Buffer);
|
||||||
sound.setLooping(false);
|
sound.setLooping(false);
|
||||||
sound.setPositional(false);
|
sound.setPositional(false);
|
||||||
return sound;
|
return sound;
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (AssetLoadException | AssetNotFoundException ex) {
|
||||||
LOGGER.log(Level.ERROR, ex.getMessage(), ex);
|
LOGGER.log(Level.ERROR, ex.getMessage(), ex);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles sound-related game events to play specific sounds.
|
* Plays the splash sound effect.
|
||||||
*
|
|
||||||
* @param event The sound event received.
|
|
||||||
*/
|
*/
|
||||||
|
public void splash() {
|
||||||
|
if (isEnabled() && splashSound != null)
|
||||||
|
splashSound.playInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plays the explosion sound effect.
|
||||||
|
*/
|
||||||
|
public void explosion() {
|
||||||
|
if (isEnabled() && explosionSound != null)
|
||||||
|
explosionSound.playInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plays sound effect when a ship has been destroyed.
|
||||||
|
*/
|
||||||
|
public void shipDestroyed() {
|
||||||
|
if (isEnabled() && shipDestroyedSound != null)
|
||||||
|
shipDestroyedSound.playInstance();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void receivedEvent(SoundEvent event) {
|
public void receivedEvent(SoundEvent event) {
|
||||||
if (isEnabled()) {
|
switch (event.sound()) {
|
||||||
AudioNode sound = loadSound(event.getSoundFileName());
|
|
||||||
if (sound != null) {
|
|
||||||
sound.play();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}//heloo
|
}
|
||||||
|
@ -9,12 +9,7 @@ import com.jme3.font.BitmapText;
|
|||||||
import com.jme3.input.KeyInput;
|
import com.jme3.input.KeyInput;
|
||||||
import com.jme3.input.controls.ActionListener;
|
import com.jme3.input.controls.ActionListener;
|
||||||
import com.jme3.input.controls.KeyTrigger;
|
import com.jme3.input.controls.KeyTrigger;
|
||||||
import com.jme3.material.Material;
|
|
||||||
import com.jme3.math.Vector3f;
|
|
||||||
import com.jme3.scene.Geometry;
|
|
||||||
import com.jme3.scene.shape.Box;
|
|
||||||
import com.jme3.system.AppSettings;
|
import com.jme3.system.AppSettings;
|
||||||
import com.jme3.texture.Texture;
|
|
||||||
import com.simsilica.lemur.GuiGlobals;
|
import com.simsilica.lemur.GuiGlobals;
|
||||||
import com.simsilica.lemur.style.BaseStyles;
|
import com.simsilica.lemur.style.BaseStyles;
|
||||||
|
|
||||||
@ -22,6 +17,7 @@ import pp.dialog.DialogBuilder;
|
|||||||
import pp.dialog.DialogManager;
|
import pp.dialog.DialogManager;
|
||||||
import pp.graphics.Draw;
|
import pp.graphics.Draw;
|
||||||
import pp.monopoly.client.gui.SettingsMenu;
|
import pp.monopoly.client.gui.SettingsMenu;
|
||||||
|
import pp.monopoly.client.gui.TestWorld;
|
||||||
import pp.monopoly.game.client.ClientGameLogic;
|
import pp.monopoly.game.client.ClientGameLogic;
|
||||||
import pp.monopoly.game.client.MonopolyClient;
|
import pp.monopoly.game.client.MonopolyClient;
|
||||||
import pp.monopoly.game.client.ServerConnection;
|
import pp.monopoly.game.client.ServerConnection;
|
||||||
@ -36,10 +32,20 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
|
|||||||
private final ActionListener escapeListener = (name, isPressed, tpf) -> handleEscape(isPressed);
|
private final ActionListener escapeListener = (name, isPressed, tpf) -> handleEscape(isPressed);
|
||||||
private final DialogManager dialogManager = new DialogManager(this);
|
private final DialogManager dialogManager = new DialogManager(this);
|
||||||
private final ExecutorService executor = Executors.newCachedThreadPool();
|
private final ExecutorService executor = Executors.newCachedThreadPool();
|
||||||
private SettingsMenu settingsMenu;
|
|
||||||
private final Draw draw;
|
private final Draw draw;
|
||||||
|
private SettingsMenu settingsMenu;
|
||||||
|
private TestWorld testWorld;
|
||||||
private boolean isSettingsMenuOpen = false;
|
private boolean isSettingsMenuOpen = false;
|
||||||
|
private boolean inputBlocked = false;
|
||||||
|
/**
|
||||||
|
* Path to the styles script for GUI elements.
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
new MonopolyApp().start();
|
new MonopolyApp().start();
|
||||||
@ -55,55 +61,6 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
|
|||||||
setSettings(makeSettings());
|
setSettings(makeSettings());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates and configures application settings from the client configuration.
|
|
||||||
*
|
|
||||||
* @return A configured {@link AppSettings} object.
|
|
||||||
*/
|
|
||||||
private AppSettings makeSettings() {
|
|
||||||
final AppSettings settings = new AppSettings(true);
|
|
||||||
settings.setTitle(lookup("monopoly.name"));
|
|
||||||
settings.setResolution(config.getResolutionWidth(), config.getResolutionHeight());
|
|
||||||
settings.setFullscreen(config.fullScreen());
|
|
||||||
settings.setUseRetinaFrameBuffer(config.useRetinaFrameBuffer());
|
|
||||||
settings.setGammaCorrection(config.useGammaCorrection());
|
|
||||||
return settings;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Factory method for creating a server connection based on the current
|
|
||||||
* client configuration.
|
|
||||||
*
|
|
||||||
* @return A {@link ServerConnection} instance, which could be a real or mock server.
|
|
||||||
*/
|
|
||||||
private ServerConnection makeServerConnection() {
|
|
||||||
return new NetworkSupport(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the dialog manager responsible for managing in-game dialogs.
|
|
||||||
*
|
|
||||||
* @return The {@link DialogManager} instance.
|
|
||||||
*/
|
|
||||||
public DialogManager getDialogManager() {
|
|
||||||
return dialogManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the game logic handler for the client.
|
|
||||||
*
|
|
||||||
* @return The {@link ClientGameLogic} instance.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public ClientGameLogic getGameLogic() {
|
|
||||||
return logic;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the current configuration settings for the Monopoly client.
|
|
||||||
*
|
|
||||||
* @return The {@link MonopolyClientConfig} instance.
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public MonopolyAppConfig getConfig() {
|
public MonopolyAppConfig getConfig() {
|
||||||
return config;
|
return config;
|
||||||
@ -122,24 +79,17 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
|
|||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSettingsMenuOpen() {
|
|
||||||
return isSettingsMenuOpen;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSettingsMenuOpen(boolean isOpen) {
|
|
||||||
this.isSettingsMenuOpen = isOpen;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void simpleInitApp() {
|
public void simpleInitApp() {
|
||||||
GuiGlobals.initialize(this);
|
GuiGlobals.initialize(this);
|
||||||
BaseStyles.loadGlassStyle();
|
BaseStyles.loadStyleResources(STYLES_SCRIPT);
|
||||||
GuiGlobals.getInstance().getStyles().setDefaultStyle("glass");
|
GuiGlobals.getInstance().getStyles().setDefaultStyle("pp"); //NON-NLS
|
||||||
|
final BitmapFont normalFont = assetManager.loadFont(FONT); //NON-NLS
|
||||||
|
|
||||||
setupInput();
|
setupInput();
|
||||||
setupGui();
|
setupGui();
|
||||||
|
|
||||||
// Initialisiere das Startmenü
|
// Zeige das Startmenü
|
||||||
StartMenu.createStartMenu(this);
|
StartMenu.createStartMenu(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,23 +106,45 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
|
|||||||
inputManager.addMapping("ESC", new KeyTrigger(KeyInput.KEY_ESCAPE));
|
inputManager.addMapping("ESC", new KeyTrigger(KeyInput.KEY_ESCAPE));
|
||||||
inputManager.addListener(escapeListener, "ESC");
|
inputManager.addListener(escapeListener, "ESC");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void handleEscape(boolean isPressed) {
|
private void handleEscape(boolean isPressed) {
|
||||||
if (isPressed) {
|
if (isPressed) {
|
||||||
if (isSettingsMenuOpen && settingsMenu != null) {
|
if (settingsMenu != null && isSettingsMenuOpen) {
|
||||||
|
// Schließe das SettingsMenu
|
||||||
|
System.out.println("Schließe SettingsMenu...");
|
||||||
settingsMenu.close();
|
settingsMenu.close();
|
||||||
|
settingsMenu = null;
|
||||||
setSettingsMenuOpen(false);
|
setSettingsMenuOpen(false);
|
||||||
} else {
|
} else {
|
||||||
|
// Öffne das SettingsMenu
|
||||||
|
System.out.println("Öffne SettingsMenu...");
|
||||||
settingsMenu = new SettingsMenu(this);
|
settingsMenu = new SettingsMenu(this);
|
||||||
settingsMenu.open();
|
settingsMenu.open();
|
||||||
setSettingsMenuOpen(true);
|
setSettingsMenuOpen(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void blockInputs() {
|
||||||
|
if (!inputBlocked) {
|
||||||
|
System.out.println("Blockiere Eingaben...");
|
||||||
|
inputManager.setCursorVisible(true); // Cursor sichtbar machen
|
||||||
|
inputManager.clearMappings(); // Alle Mappings entfernen
|
||||||
|
inputBlocked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unblockInputs() {
|
||||||
|
if (inputBlocked) {
|
||||||
|
System.out.println("Aktiviere Eingaben...");
|
||||||
|
setupInput(); // Standard-Eingaben neu registrieren
|
||||||
|
inputBlocked = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void setInfoText(String text) {
|
public void setInfoText(String text) {
|
||||||
topText.setText(text);
|
topText.setText(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,35 +184,26 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
|
|||||||
.build()
|
.build()
|
||||||
.open();
|
.open();
|
||||||
}
|
}
|
||||||
//altes Fenster beim Start von TestWorld schließen
|
|
||||||
public void startTestWorld() {
|
|
||||||
// Entferne die aktuelle GUI
|
|
||||||
guiNode.detachAllChildren();
|
|
||||||
|
|
||||||
// Erstelle ein Quadrat mit Textur
|
|
||||||
Box box = new Box(1, 0.01f, 1); // Dünnes Quadrat
|
|
||||||
Geometry geom = new Geometry("Box", box);
|
|
||||||
|
|
||||||
// Setze das Material mit Textur
|
|
||||||
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
|
|
||||||
Texture texture = assetManager.loadTexture("Pictures/board.png");
|
|
||||||
mat.setTexture("ColorMap", texture);
|
|
||||||
geom.setMaterial(mat);
|
|
||||||
|
|
||||||
// Füge das Quadrat zur Szene hinzu
|
|
||||||
rootNode.attachChild(geom);
|
|
||||||
|
|
||||||
// Setze die Kameraposition
|
|
||||||
cam.setLocation(new Vector3f(0, 0, 3));
|
|
||||||
cam.lookAt(geom.getLocalTranslation(), Vector3f.UNIT_Y);
|
|
||||||
}
|
|
||||||
public void returnToMenu() {
|
|
||||||
// Entferne die Testszene
|
|
||||||
rootNode.detachAllChildren();
|
|
||||||
|
|
||||||
// Zeige das Startmenü erneut
|
|
||||||
StartMenu.createStartMenu(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
public void setSettingsMenuOpen(boolean isOpen) {
|
||||||
|
this.isSettingsMenuOpen = isOpen;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void simpleUpdate(float tpf) {
|
||||||
|
if (testWorld != null) {
|
||||||
|
testWorld.update(tpf); // Aktualisiere die Kamera in der TestWorld
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startTestWorld() {
|
||||||
|
guiNode.detachAllChildren(); // Entferne GUI
|
||||||
|
testWorld = new TestWorld(this); // Erstelle eine Instanz von TestWorld
|
||||||
|
testWorld.initializeScene(); // Initialisiere die Szene
|
||||||
|
}
|
||||||
|
|
||||||
|
public void returnToMenu() {
|
||||||
|
guiNode.detachAllChildren(); // Entferne die GUI
|
||||||
|
StartMenu.createStartMenu(this); // Zeige das Startmenü erneut
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,3 @@
|
|||||||
////////////////////////////////////////
|
|
||||||
// Programming project code
|
|
||||||
// UniBw M, 2022, 2023, 2024
|
|
||||||
// www.unibw.de/inf2
|
|
||||||
// (c) Mark Minas (mark.minas@unibw.de)
|
|
||||||
////////////////////////////////////////
|
|
||||||
|
|
||||||
package pp.monopoly.client;
|
package pp.monopoly.client;
|
||||||
|
|
||||||
import com.jme3.math.ColorRGBA;
|
import com.jme3.math.ColorRGBA;
|
||||||
@ -194,4 +187,4 @@ public class MonopolyAppConfig extends MonopolyClientConfig {
|
|||||||
public ColorRGBA getTopColor() {
|
public ColorRGBA getTopColor() {
|
||||||
return topColor;
|
return topColor;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -81,4 +81,4 @@ public abstract class MonopolyAppState extends AbstractAppState {
|
|||||||
* Called when the state is disabled. Override to define specific behavior.
|
* Called when the state is disabled. Override to define specific behavior.
|
||||||
*/
|
*/
|
||||||
protected abstract void disableState();
|
protected abstract void disableState();
|
||||||
}
|
}
|
@ -142,4 +142,5 @@ class NetworkDialog extends SimpleDialog {
|
|||||||
network.getApp().errorDialog("Verbindung zum Server fehlgeschlagen.");
|
network.getApp().errorDialog("Verbindung zum Server fehlgeschlagen.");
|
||||||
network.getApp().setInfoText(e.getLocalizedMessage());
|
network.getApp().setInfoText(e.getLocalizedMessage());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
}
|
@ -141,4 +141,4 @@ class NetworkSupport implements MessageListener<Client>, ClientStateListener, Se
|
|||||||
client.send(message);
|
client.send(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,117 +1,182 @@
|
|||||||
package pp.monopoly.client;
|
package pp.monopoly.client;
|
||||||
|
|
||||||
import com.jme3.asset.TextureKey;
|
|
||||||
import com.jme3.material.Material;
|
import com.jme3.material.Material;
|
||||||
|
import com.jme3.math.ColorRGBA;
|
||||||
import com.jme3.math.Vector3f;
|
import com.jme3.math.Vector3f;
|
||||||
import com.jme3.scene.Geometry;
|
import com.jme3.scene.Geometry;
|
||||||
import com.jme3.scene.shape.Quad;
|
import com.jme3.scene.shape.Quad;
|
||||||
import com.jme3.texture.Texture;
|
import com.jme3.texture.Texture;
|
||||||
|
import com.simsilica.lemur.Axis;
|
||||||
import com.simsilica.lemur.Button;
|
import com.simsilica.lemur.Button;
|
||||||
import com.simsilica.lemur.Insets3f;
|
import com.simsilica.lemur.Container;
|
||||||
import com.simsilica.lemur.Label;
|
import com.simsilica.lemur.HAlignment;
|
||||||
import com.simsilica.lemur.Panel;
|
|
||||||
import com.simsilica.lemur.style.ElementId;
|
|
||||||
import com.simsilica.lemur.component.QuadBackgroundComponent;
|
import com.simsilica.lemur.component.QuadBackgroundComponent;
|
||||||
import com.jme3.math.ColorRGBA;
|
import com.simsilica.lemur.component.SpringGridLayout;
|
||||||
|
|
||||||
import pp.dialog.Dialog;
|
import pp.dialog.Dialog;
|
||||||
|
import pp.monopoly.client.gui.CreateGameMenu;
|
||||||
|
import pp.monopoly.client.gui.SettingsMenu;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs the startup menu dialog for the Monopoly application.
|
||||||
import pp.monopoly.client.gui.GameMenu;
|
import pp.monopoly.client.gui.GameMenu;
|
||||||
import pp.dialog.DialogManager;
|
*/
|
||||||
|
|
||||||
import java.util.prefs.Preferences;
|
|
||||||
|
|
||||||
import static pp.monopoly.Resources.lookup;
|
|
||||||
import static pp.util.PreferencesUtils.getPreferences;
|
|
||||||
|
|
||||||
public class StartMenu extends Dialog {
|
public class StartMenu extends Dialog {
|
||||||
private static final Preferences PREFERENCES = getPreferences(StartMenu.class);
|
|
||||||
private final MonopolyApp app;
|
private final MonopolyApp app;
|
||||||
|
private Container logoContainer;
|
||||||
// Buttons for the menu
|
private Container unibwLogoContainer;
|
||||||
private final Button playButton = new Button(lookup("button.play"));
|
|
||||||
private final Button quitButton = new Button(lookup("menu.quit"));
|
|
||||||
private final Button settingsButton = new Button("Einstellungen", new ElementId("menu-button"));
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs the StartMenu dialog for the Monopoly application.
|
* Constructs the Startup Menu dialog for the Monopoly application.
|
||||||
*
|
*
|
||||||
* @param app the MonopolyApp instance
|
* @param app the MonopolyApp instance
|
||||||
*/
|
*/
|
||||||
public StartMenu(MonopolyApp app) {
|
public StartMenu(MonopolyApp app) {
|
||||||
super(app.getDialogManager());
|
super(app.getDialogManager());
|
||||||
this.app = app;
|
this.app = app;
|
||||||
|
}
|
||||||
|
|
||||||
// Load and display the background image
|
/**
|
||||||
TextureKey backgroundKey = new TextureKey("unibw-bib", false);
|
* Creates and displays the Start Menu with buttons for starting the game,
|
||||||
Texture backgroundTexture = app.getAssetManager().loadTexture(backgroundKey);
|
* opening settings, and quitting the application.
|
||||||
|
*/
|
||||||
|
public static void createStartMenu(MonopolyApp app) {
|
||||||
|
int screenWidth = app.getContext().getSettings().getWidth();
|
||||||
|
int screenHeight = app.getContext().getSettings().getHeight();
|
||||||
|
|
||||||
|
// Set up the background image
|
||||||
|
Texture backgroundImage = app.getAssetManager().loadTexture("Pictures/unibw-Bib2.png");
|
||||||
|
Quad quad = new Quad(screenWidth, screenHeight);
|
||||||
|
Geometry background = new Geometry("Background", quad);
|
||||||
Material backgroundMaterial = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
|
Material backgroundMaterial = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
|
||||||
backgroundMaterial.setTexture("ColorMap", backgroundTexture);
|
backgroundMaterial.setTexture("ColorMap", backgroundImage);
|
||||||
|
|
||||||
// Create a large Quad for the background
|
|
||||||
Quad backgroundQuad = new Quad(16, 9); // Adjust size as necessary to fill the screen
|
|
||||||
Geometry background = new Geometry("Background", backgroundQuad);
|
|
||||||
background.setMaterial(backgroundMaterial);
|
background.setMaterial(backgroundMaterial);
|
||||||
background.setLocalTranslation(new Vector3f(-8, -4.5f, -1)); // Position it behind the UI components
|
background.setLocalTranslation(0, 0, -1); // Ensure it is behind other GUI elements
|
||||||
|
|
||||||
// Attach the background as the first element
|
|
||||||
app.getGuiNode().attachChild(background);
|
app.getGuiNode().attachChild(background);
|
||||||
|
|
||||||
// Load and display the Monopoly logo
|
createMonopolyLogo(app);
|
||||||
TextureKey monopolyLogoKey = new TextureKey("log-Monopoly", false);
|
createUnibwLogo(app);
|
||||||
Texture monopolyLogoTexture = app.getAssetManager().loadTexture(monopolyLogoKey);
|
|
||||||
Material monopolyLogoMaterial = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
|
|
||||||
monopolyLogoMaterial.setTexture("ColorMap", monopolyLogoTexture);
|
|
||||||
|
|
||||||
Quad monopolyQuad = new Quad(5, 1.5f); // Adjust dimensions as necessary
|
// Center container for title and play button
|
||||||
Geometry monopolyLogo = new Geometry("MonopolyLogo", monopolyQuad);
|
Container centerMenu = new Container(new SpringGridLayout(Axis.Y, Axis.X));
|
||||||
monopolyLogo.setMaterial(monopolyLogoMaterial);
|
|
||||||
monopolyLogo.setLocalTranslation(new Vector3f(0, 5, 0)); // Position Monopoly logo at the top
|
|
||||||
|
|
||||||
Panel monopolyLogoPanel = new Panel();
|
Button startButton = new Button("Spielen");
|
||||||
addChild(monopolyLogoPanel);
|
startButton.setPreferredSize(new Vector3f(190, 60, 0)); // Increase button size (width, height)
|
||||||
|
startButton.setFontSize(40); // Set the font size for the button text
|
||||||
|
startButton.setTextHAlignment(HAlignment.Center); // Center the text horizontally
|
||||||
|
|
||||||
// Load and display the university logo
|
startButton.addClickCommands(source -> startGame(app));
|
||||||
TextureKey universityLogoKey = new TextureKey("unibw-logo.png", false);
|
centerMenu.addChild(startButton);
|
||||||
Texture universityLogoTexture = app.getAssetManager().loadTexture(universityLogoKey);
|
|
||||||
Material universityLogoMaterial = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
|
|
||||||
universityLogoMaterial.setTexture("ColorMap", universityLogoTexture);
|
|
||||||
|
|
||||||
Quad universityQuad = new Quad(4, 1); // Adjust dimensions to fit below Monopoly logo
|
// Position the center container in the middle of the screen
|
||||||
Geometry universityLogo = new Geometry("UniversityLogo", universityQuad);
|
centerMenu.setLocalTranslation(new Vector3f(screenWidth / 2f - centerMenu.getPreferredSize().x / 2f,
|
||||||
universityLogo.setMaterial(universityLogoMaterial);
|
screenHeight / 2f - 280 + centerMenu.getPreferredSize().y / 2f,
|
||||||
universityLogo.setLocalTranslation(new Vector3f(0, 3, 0)); // Position below the Monopoly logo
|
0));
|
||||||
|
app.getGuiNode().attachChild(centerMenu);
|
||||||
|
|
||||||
Panel universityLogoPanel = new Panel();
|
// Lower-left container for "Spiel beenden" button
|
||||||
addChild(universityLogoPanel);
|
Container lowerLeftMenu = new Container();
|
||||||
|
lowerLeftMenu.setLocalTranslation(new Vector3f(100, 90, 0));
|
||||||
|
Button quitButton = new Button("Spiel beenden");
|
||||||
|
quitButton.setPreferredSize(new Vector3f(130, 40, 0)); // Increase button size slightly (width, height)
|
||||||
|
quitButton.setFontSize(18);
|
||||||
|
quitButton.addClickCommands(source -> quitGame());
|
||||||
|
lowerLeftMenu.addChild(quitButton);
|
||||||
|
app.getGuiNode().attachChild(lowerLeftMenu);
|
||||||
|
|
||||||
|
// Lower-right container for "Einstellungen" button
|
||||||
|
Container lowerRightMenu = new Container();
|
||||||
// Button actions
|
lowerRightMenu.setLocalTranslation(new Vector3f(screenWidth - 200, 90, 0));
|
||||||
playButton.addClickCommands(source -> startGame());
|
Button settingsButton = new Button("Einstellungen");
|
||||||
quitButton.addClickCommands(source -> app.closeApp());
|
settingsButton.setPreferredSize(new Vector3f(130, 40, 0)); // Increase button size slightly (width, height)
|
||||||
settingsButton.addClickCommands(source -> openSettings());
|
settingsButton.setFontSize(18); // Increase the font size for the text
|
||||||
|
settingsButton.addClickCommands(source -> openSettings(app));
|
||||||
addChild(monopolyLogoPanel);
|
lowerRightMenu.addChild(settingsButton);
|
||||||
addChild(universityLogoPanel);
|
app.getGuiNode().attachChild(lowerRightMenu);
|
||||||
addChild(playButton);
|
|
||||||
addChild(quitButton);
|
|
||||||
addChild(settingsButton);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startGame() {
|
/**
|
||||||
System.out.println("Starting game...");
|
* Creates and positions the Monopoly logo container in the center of the screen.
|
||||||
|
*/
|
||||||
|
private static void createMonopolyLogo(MonopolyApp app) {
|
||||||
|
int screenWidth = app.getContext().getSettings().getWidth();
|
||||||
|
int screenHeight = app.getContext().getSettings().getHeight();
|
||||||
|
|
||||||
|
// Load the Monopoly logo as a texture
|
||||||
|
Texture logoTexture = app.getAssetManager().loadTexture("Pictures/logo-monopoly.png");
|
||||||
|
|
||||||
|
// Create a container for the logo
|
||||||
|
Container logoContainer = new Container();
|
||||||
|
QuadBackgroundComponent logoBackground = new QuadBackgroundComponent(logoTexture);
|
||||||
|
logoContainer.setBackground(logoBackground);
|
||||||
|
|
||||||
|
// Set the size of the container to fit the logo
|
||||||
|
float logoWidth = 512; // Adjust these values based on the logo dimensions
|
||||||
|
float logoHeight = 128; // Adjust these values based on the logo dimensions
|
||||||
|
logoContainer.setPreferredSize(new Vector3f(logoWidth, logoHeight, 0));
|
||||||
|
|
||||||
|
// Position the container at the center of the screen
|
||||||
|
logoContainer.setLocalTranslation(new Vector3f(
|
||||||
|
screenWidth / 2f - logoWidth / 2f,
|
||||||
|
screenHeight / 2f + 200, // Adjust this value for vertical position
|
||||||
|
0
|
||||||
|
));
|
||||||
|
|
||||||
|
// Attach the container to the GUI node
|
||||||
|
app.getGuiNode().attachChild(logoContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void openSettings() {
|
/**
|
||||||
app.getDialogManager().close(this);
|
* Creates and positions the Unibw logo container in the center of the screen.
|
||||||
app.getDialogManager().open(new GameMenu(app));
|
*/
|
||||||
|
private static void createUnibwLogo(MonopolyApp app) {
|
||||||
|
int screenWidth = app.getContext().getSettings().getWidth();
|
||||||
|
int screenHeight = app.getContext().getSettings().getHeight();
|
||||||
|
|
||||||
|
// Load the Unibw logo as a texture
|
||||||
|
Texture unibwTexture = app.getAssetManager().loadTexture("Pictures/logo-unibw.png");
|
||||||
|
|
||||||
|
// Create a container for the Unibw logo
|
||||||
|
Container unibwContainer = new Container();
|
||||||
|
QuadBackgroundComponent unibwBackground = new QuadBackgroundComponent(unibwTexture);
|
||||||
|
unibwContainer.setBackground(unibwBackground);
|
||||||
|
|
||||||
|
// Set the size of the container to fit the Unibw logo
|
||||||
|
float unibwWidth = 512; // Adjust these values based on the logo dimensions
|
||||||
|
float unibwHeight = 128; // Adjust these values based on the logo dimensions
|
||||||
|
unibwContainer.setPreferredSize(new Vector3f(unibwWidth, unibwHeight, 0));
|
||||||
|
|
||||||
|
// Position the container slightly below the Monopoly logo
|
||||||
|
unibwContainer.setLocalTranslation(new Vector3f(
|
||||||
|
screenWidth / 2f - unibwWidth / 2f,
|
||||||
|
screenHeight / 2f + 100, // Adjust this value for vertical position
|
||||||
|
0
|
||||||
|
));
|
||||||
|
|
||||||
|
// Attach the container to the GUI node
|
||||||
|
app.getGuiNode().attachChild(unibwContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public void update() {
|
* Starts the game by transitioning to the CreateGameMenu.
|
||||||
|
*/
|
||||||
|
private static void startGame(MonopolyApp app) {
|
||||||
|
app.getGuiNode().detachAllChildren();
|
||||||
|
new CreateGameMenu(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public void escape() {
|
* Opens the settings menu.
|
||||||
close();
|
*/
|
||||||
|
private static void openSettings(MonopolyApp app) {
|
||||||
|
app.getGuiNode().detachAllChildren();
|
||||||
|
new SettingsMenu(app);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* Quits the game application.
|
||||||
|
*/
|
||||||
|
private static void quitGame() {
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
}
|
@ -17,7 +17,7 @@ import pp.view.ModelViewSynchronizer;
|
|||||||
* are accurately reflected in the view.
|
* are accurately reflected in the view.
|
||||||
*/
|
*/
|
||||||
abstract class BoardSynchronizer extends ModelViewSynchronizer<Item> implements Visitor<Spatial>, GameEventListener {
|
abstract class BoardSynchronizer extends ModelViewSynchronizer<Item> implements Visitor<Spatial>, GameEventListener {
|
||||||
private final Board board;
|
protected final Board board;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new BoardSynchronizer.
|
* Constructs a new BoardSynchronizer.
|
||||||
|
@ -0,0 +1,59 @@
|
|||||||
|
package pp.monopoly.client.gui;
|
||||||
|
|
||||||
|
import com.jme3.math.FastMath;
|
||||||
|
import com.jme3.math.Vector3f;
|
||||||
|
import com.jme3.renderer.Camera;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Steuert die Kamerabewegung in der Szene.
|
||||||
|
*/
|
||||||
|
public class CameraController {
|
||||||
|
private final Camera camera;
|
||||||
|
private final Vector3f center; // Fokuspunkt der Kamera
|
||||||
|
private final float radius; // Radius der Kreisbewegung
|
||||||
|
private final float height; // Höhe der Kamera über dem Spielfeld
|
||||||
|
private final float speed; // Geschwindigkeit der Kamerabewegung
|
||||||
|
private float angle; // Aktueller Winkel in der Kreisbewegung
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Konstruktor für den CameraController.
|
||||||
|
*
|
||||||
|
* @param camera Die Kamera, die gesteuert werden soll
|
||||||
|
* @param center Der Mittelpunkt der Kreisbewegung (Fokuspunkt)
|
||||||
|
* @param radius Der Radius der Kreisbewegung
|
||||||
|
* @param height Die Höhe der Kamera über dem Fokuspunkt
|
||||||
|
* @param speed Die Geschwindigkeit der Kamerabewegung
|
||||||
|
*/
|
||||||
|
public CameraController(Camera camera, Vector3f center, float radius, float height, float speed) {
|
||||||
|
this.camera = camera;
|
||||||
|
this.center = center;
|
||||||
|
this.radius = radius;
|
||||||
|
this.height = height;
|
||||||
|
this.speed = speed;
|
||||||
|
this.angle = 0; // Starte bei Winkel 0
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aktualisiert die Kameraposition und -ausrichtung.
|
||||||
|
*
|
||||||
|
* @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);
|
||||||
|
}
|
||||||
|
}
|
@ -23,6 +23,11 @@ public class CreateGameMenu {
|
|||||||
private final Container menuContainer;
|
private final Container menuContainer;
|
||||||
private Geometry background;
|
private Geometry background;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Konstruktor für das CreateGameMenu.
|
||||||
|
*
|
||||||
|
* @param app Die Hauptanwendung (MonopolyApp)
|
||||||
|
*/
|
||||||
public CreateGameMenu(MonopolyApp app) {
|
public CreateGameMenu(MonopolyApp app) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
|
|
||||||
@ -43,12 +48,12 @@ public class CreateGameMenu {
|
|||||||
inputContainer.setLocalTranslation(20, 0, 0); // Abstand vom Rand
|
inputContainer.setLocalTranslation(20, 0, 0); // Abstand vom Rand
|
||||||
|
|
||||||
inputContainer.addChild(new Label("Server-Adresse:"));
|
inputContainer.addChild(new Label("Server-Adresse:"));
|
||||||
TextField playerNameField = inputContainer.addChild(new TextField("localhost"));
|
TextField serverAddressField = inputContainer.addChild(new TextField("localhost"));
|
||||||
playerNameField.setPreferredWidth(400); // Breite des Textfelds
|
serverAddressField.setPreferredWidth(400); // Breite des Textfelds
|
||||||
|
|
||||||
inputContainer.addChild(new Label("Port:"));
|
inputContainer.addChild(new Label("Port:"));
|
||||||
TextField serverAddressField = inputContainer.addChild(new TextField("42069"));
|
TextField portField = inputContainer.addChild(new TextField("42069"));
|
||||||
serverAddressField.setPreferredWidth(400); // Breite des Textfelds
|
portField.setPreferredWidth(400); // Breite des Textfelds
|
||||||
|
|
||||||
// Button-Container
|
// Button-Container
|
||||||
Container buttonContainer = menuContainer.addChild(new Container(new SpringGridLayout(Axis.X, Axis.Y)));
|
Container buttonContainer = menuContainer.addChild(new Container(new SpringGridLayout(Axis.X, Axis.Y)));
|
||||||
@ -64,15 +69,14 @@ public class CreateGameMenu {
|
|||||||
Button hostButton = buttonContainer.addChild(new Button("Spiel hosten"));
|
Button hostButton = buttonContainer.addChild(new Button("Spiel hosten"));
|
||||||
hostButton.setPreferredSize(new Vector3f(120, 40, 0));
|
hostButton.setPreferredSize(new Vector3f(120, 40, 0));
|
||||||
hostButton.addClickCommands(source -> {
|
hostButton.addClickCommands(source -> {
|
||||||
closeCreateGameMenu(); // Schließt das Menü
|
closeCreateGameMenu(); // Schließt das Menü
|
||||||
app.startTestWorld(); // Startet die Testwelt in der Hauptanwendung
|
app.startTestWorld(); // Starte die TestWorld im selben Fenster
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// "Beitreten"-Button
|
// "Beitreten"-Button
|
||||||
Button joinButton = buttonContainer.addChild(new Button("Beitreten"));
|
Button joinButton = buttonContainer.addChild(new Button("Beitreten"));
|
||||||
joinButton.setPreferredSize(new Vector3f(120, 40, 0));
|
joinButton.setPreferredSize(new Vector3f(120, 40, 0));
|
||||||
// joinButton.addClickCommands(source -> joinGame()); // Placeholder for joining logic
|
// Placeholder für die Beitrittslogik
|
||||||
|
|
||||||
// Zentrierung des Containers
|
// Zentrierung des Containers
|
||||||
menuContainer.setLocalTranslation(
|
menuContainer.setLocalTranslation(
|
||||||
@ -103,27 +107,15 @@ public class CreateGameMenu {
|
|||||||
* Geht zum Startmenü zurück, wenn "Abbrechen" angeklickt wird.
|
* Geht zum Startmenü zurück, wenn "Abbrechen" angeklickt wird.
|
||||||
*/
|
*/
|
||||||
private void goBackToStartMenu() {
|
private void goBackToStartMenu() {
|
||||||
app.getGuiNode().detachChild(menuContainer);
|
closeCreateGameMenu(); // Schließt das Menü
|
||||||
app.getGuiNode().detachChild(background); // Entfernt das Hintergrundbild
|
StartMenu.createStartMenu(app); // Zeige das Startmenü
|
||||||
StartMenu.createStartMenu(app);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Link zwischen createGame und TestWorld
|
|
||||||
*/
|
|
||||||
|
|
||||||
private void startTestWorld() {
|
|
||||||
// Entfernt das Menü
|
|
||||||
app.getGuiNode().detachChild(menuContainer);
|
|
||||||
app.getGuiNode().detachChild(background);
|
|
||||||
|
|
||||||
// Startet die Testszene
|
|
||||||
TestWorld.startTestWorld();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entfernt das CreateGameMenu und dessen Hintergrund.
|
||||||
|
*/
|
||||||
private void closeCreateGameMenu() {
|
private void closeCreateGameMenu() {
|
||||||
app.getGuiNode().detachChild(menuContainer); // Entfernt den Menü-Container
|
app.getGuiNode().detachChild(menuContainer); // Entfernt den Menü-Container
|
||||||
app.getGuiNode().detachChild(background); // Entfernt das Hintergrundbild
|
app.getGuiNode().detachChild(background); // Entfernt das Hintergrundbild
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,124 @@
|
|||||||
|
////////////////////////////////////////
|
||||||
|
// Programming project code
|
||||||
|
// UniBw M, 2022, 2023, 2024
|
||||||
|
// www.unibw.de/inf2
|
||||||
|
// (c) Mark Minas (mark.minas@unibw.de)
|
||||||
|
////////////////////////////////////////
|
||||||
|
|
||||||
|
package pp.monopoly.client.gui;
|
||||||
|
|
||||||
|
import com.jme3.material.Material;
|
||||||
|
import com.jme3.material.RenderState.BlendMode;
|
||||||
|
import com.jme3.math.ColorRGBA;
|
||||||
|
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
|
||||||
|
import com.jme3.scene.Geometry;
|
||||||
|
import com.jme3.scene.Node;
|
||||||
|
import com.jme3.scene.Spatial;
|
||||||
|
import com.jme3.scene.shape.Box;
|
||||||
|
|
||||||
|
import pp.monopoly.client.MonopolyApp;
|
||||||
|
import pp.monopoly.game.server.PlayerColor;
|
||||||
|
import pp.monopoly.model.Board;
|
||||||
|
import pp.monopoly.model.Figure;
|
||||||
|
import pp.monopoly.model.Rotation;
|
||||||
|
import static pp.util.FloatMath.HALF_PI;
|
||||||
|
import static pp.util.FloatMath.PI;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@code GameBoardSynchronizer} class is responsible for synchronizing the graphical
|
||||||
|
* representation of the ships and shots on the sea map with the underlying data model.
|
||||||
|
* It extends the {@link BoardSynchronizer} to provide specific synchronization
|
||||||
|
* logic for the sea map.
|
||||||
|
*/
|
||||||
|
class GameBoardSynchronizer extends BoardSynchronizer {
|
||||||
|
private static final String UNSHADED = "Common/MatDefs/Misc/Unshaded.j3md"; //NON-NLS
|
||||||
|
private static final String LIGHTING = "Common/MatDefs/Light/Lighting.j3md";
|
||||||
|
private static final String COLOR = "Color"; //NON-NLS
|
||||||
|
private static final String FIGURE = "figure"; //NON-NLS
|
||||||
|
|
||||||
|
private final MonopolyApp app;
|
||||||
|
private final ParticleEffectFactory particleFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a {@code GameBoardSynchronizer} object with the specified application, root node, and ship map.
|
||||||
|
*
|
||||||
|
* @param app the Battleship application
|
||||||
|
* @param root the root node to which graphical elements will be attached
|
||||||
|
* @param map the ship map containing the ships and shots
|
||||||
|
*/
|
||||||
|
public GameBoardSynchronizer(MonopolyApp app, Node root, Board board) {
|
||||||
|
super(board, root);
|
||||||
|
this.app = app;
|
||||||
|
this.particleFactory = new ParticleEffectFactory(app);
|
||||||
|
addExisting();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Visits a {@link Battleship} and creates a graphical representation of it.
|
||||||
|
* The representation is either a 3D model or a simple box depending on the
|
||||||
|
* type of battleship.
|
||||||
|
*
|
||||||
|
* @param ship the battleship to be represented
|
||||||
|
* @return the node containing the graphical representation of the battleship
|
||||||
|
*/
|
||||||
|
public Spatial visit(Figure figure) {
|
||||||
|
final Node node = new Node(FIGURE);
|
||||||
|
node.attachChild(createBox(figure));
|
||||||
|
// compute the center of the ship in world coordinates
|
||||||
|
final float x = 1;
|
||||||
|
final float z = 1;
|
||||||
|
node.setLocalTranslation(x, 0f, z);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a simple box to represent a battleship that is not of the "King George V" type.
|
||||||
|
*
|
||||||
|
* @param ship the battleship to be represented
|
||||||
|
* @return the geometry representing the battleship as a box
|
||||||
|
*/
|
||||||
|
private Spatial createBox(Figure figure) {
|
||||||
|
final Box box = new Box(0.5f * (figure.getMaxY() - figure.getMinY()) + 0.3f,
|
||||||
|
0.3f,
|
||||||
|
0.5f * (figure.getMaxX() - figure.getMinX()) + 0.3f);
|
||||||
|
final Geometry geometry = new Geometry(FIGURE, box);
|
||||||
|
geometry.setMaterial(createColoredMaterial(PlayerColor.PINK.getColor()));
|
||||||
|
geometry.setShadowMode(ShadowMode.CastAndReceive);
|
||||||
|
|
||||||
|
return geometry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new {@link Material} with the specified color.
|
||||||
|
* If the color includes transparency (i.e., alpha value less than 1),
|
||||||
|
* the material's render state is set to use alpha blending, allowing for
|
||||||
|
* semi-transparent rendering.
|
||||||
|
*
|
||||||
|
* @param color the {@link ColorRGBA} to be applied to the material. If the alpha value
|
||||||
|
* of the color is less than 1, the material will support transparency.
|
||||||
|
* @return a {@link Material} instance configured with the specified color and,
|
||||||
|
* if necessary, alpha blending enabled.
|
||||||
|
*/
|
||||||
|
private Material createColoredMaterial(ColorRGBA color) {
|
||||||
|
final Material material = new Material(app.getAssetManager(), UNSHADED);
|
||||||
|
if (color.getAlpha() < 1f)
|
||||||
|
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
|
||||||
|
material.setColor(COLOR, color);
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the rotation angle for the specified rotation.
|
||||||
|
*
|
||||||
|
* @param rot the rotation of the battleship
|
||||||
|
* @return the rotation angle in radians
|
||||||
|
*/
|
||||||
|
private static float calculateRotationAngle(Rotation rot) {
|
||||||
|
return switch (rot) {
|
||||||
|
case RIGHT -> HALF_PI;
|
||||||
|
case DOWN -> 0f;
|
||||||
|
case LEFT -> -HALF_PI;
|
||||||
|
case UP -> PI;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,7 @@ import com.jme3.math.ColorRGBA;
|
|||||||
import com.simsilica.lemur.Button;
|
import com.simsilica.lemur.Button;
|
||||||
import com.simsilica.lemur.Label;
|
import com.simsilica.lemur.Label;
|
||||||
import com.simsilica.lemur.style.ElementId;
|
import com.simsilica.lemur.style.ElementId;
|
||||||
|
|
||||||
import pp.dialog.Dialog;
|
import pp.dialog.Dialog;
|
||||||
import pp.monopoly.client.MonopolyApp;
|
import pp.monopoly.client.MonopolyApp;
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ class MapView {
|
|||||||
mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
|
mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
|
||||||
Geometry background = new Geometry("MapBackground", new Quad(board.getWidth() * FIELD_SIZE, board.getHeight() * FIELD_SIZE));
|
Geometry background = new Geometry("MapBackground", new Quad(board.getWidth() * FIELD_SIZE, board.getHeight() * FIELD_SIZE));
|
||||||
background.setMaterial(mat);
|
background.setMaterial(mat);
|
||||||
background.setLocalTranslation(0f, 0f, BACKGROUND_DEPTH);
|
background.setLocalTranslation(0f, 1f, BACKGROUND_DEPTH);
|
||||||
background.setCullHint(CullHint.Never);
|
background.setCullHint(CullHint.Never);
|
||||||
mapNode.attachChild(background);
|
mapNode.attachChild(background);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
package pp.monopoly.client.gui;
|
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.
|
* Synchronizes the visual representation of the board with the game model.
|
||||||
* Handles updates for items on the board.
|
* Handles updates for items on the board.
|
||||||
@ -33,4 +37,9 @@ class MapViewSynchronizer extends BoardSynchronizer {
|
|||||||
protected void disableState() {
|
protected void disableState() {
|
||||||
view.getNode().detachAllChildren(); // Entfernt alle visuellen Elemente vom Knoten
|
view.getNode().detachAllChildren(); // Entfernt alle visuellen Elemente vom Knoten
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Spatial visit(Figure figure) {
|
||||||
|
return figure.accept(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
package pp.monopoly.client.gui;
|
||||||
|
|
||||||
|
import com.jme3.effect.ParticleMesh.Type;
|
||||||
|
|
||||||
|
import pp.monopoly.client.MonopolyApp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory class responsible for creating particle effects used in the game.
|
||||||
|
* This centralizes the creation of various types of particle emitters.
|
||||||
|
*/
|
||||||
|
public class ParticleEffectFactory {
|
||||||
|
private static final int COUNT_FACTOR = 1;
|
||||||
|
private static final float COUNT_FACTOR_F = 1f;
|
||||||
|
private static final boolean POINT_SPRITE = true;
|
||||||
|
private static final Type EMITTER_TYPE = POINT_SPRITE ? Type.Point : Type.Triangle;
|
||||||
|
|
||||||
|
private final MonopolyApp app;
|
||||||
|
|
||||||
|
ParticleEffectFactory(MonopolyApp app) {
|
||||||
|
this.app = app;
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,10 @@
|
|||||||
package pp.monopoly.client.gui;
|
package pp.monopoly.client.gui;
|
||||||
|
|
||||||
|
import com.jme3.material.Material;
|
||||||
|
import com.jme3.material.RenderState.BlendMode;
|
||||||
import com.jme3.math.ColorRGBA;
|
import com.jme3.math.ColorRGBA;
|
||||||
import com.jme3.scene.Geometry;
|
import com.jme3.scene.Geometry;
|
||||||
import com.jme3.scene.Node;
|
|
||||||
import com.jme3.scene.shape.Quad;
|
import com.jme3.scene.shape.Quad;
|
||||||
import com.jme3.texture.Texture;
|
|
||||||
import com.simsilica.lemur.Button;
|
import com.simsilica.lemur.Button;
|
||||||
import com.simsilica.lemur.Checkbox;
|
import com.simsilica.lemur.Checkbox;
|
||||||
import com.simsilica.lemur.Container;
|
import com.simsilica.lemur.Container;
|
||||||
@ -16,122 +16,85 @@ import com.simsilica.lemur.style.ElementId;
|
|||||||
import pp.dialog.Dialog;
|
import pp.dialog.Dialog;
|
||||||
import pp.monopoly.client.MonopolyApp;
|
import pp.monopoly.client.MonopolyApp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SettingsMenu ist ein Overlay-Menü, das durch ESC aufgerufen werden kann.
|
||||||
|
*/
|
||||||
public class SettingsMenu extends Dialog {
|
public class SettingsMenu extends Dialog {
|
||||||
private final MonopolyApp app;
|
private final MonopolyApp app;
|
||||||
|
private final Geometry overlayBackground;
|
||||||
private final Container settingsContainer;
|
private final Container settingsContainer;
|
||||||
private Geometry blockLayer;
|
|
||||||
private final Node savedGuiNodeContent = new Node("SavedGuiNodeContent");
|
|
||||||
|
|
||||||
public SettingsMenu(MonopolyApp app) {
|
public SettingsMenu(MonopolyApp app) {
|
||||||
super(app.getDialogManager());
|
super(app.getDialogManager());
|
||||||
this.app = app;
|
this.app = app;
|
||||||
|
|
||||||
// Blockierungsebene hinzufügen
|
// Halbtransparentes Overlay hinzufügen
|
||||||
addBlockLayer();
|
overlayBackground = createOverlayBackground();
|
||||||
|
app.getGuiNode().attachChild(overlayBackground);
|
||||||
// Hintergrundbild
|
|
||||||
addBackgroundImage();
|
|
||||||
|
|
||||||
|
// Hauptcontainer für das Menü
|
||||||
settingsContainer = new Container();
|
settingsContainer = new Container();
|
||||||
|
settingsContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.1f, 0.1f, 0.1f, 0.9f)));
|
||||||
|
|
||||||
// Hintergrundfarbe für das Container-Element setzen, um es undurchsichtig zu machen
|
// Titel
|
||||||
settingsContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.1f, 0.1f, 0.1f, 0.8f))); // Teiltransparent, falls gewünscht
|
|
||||||
|
|
||||||
// Titel "Einstellungen"
|
|
||||||
Label settingsTitle = settingsContainer.addChild(new Label("Einstellungen", new ElementId("settings-title")));
|
Label settingsTitle = settingsContainer.addChild(new Label("Einstellungen", new ElementId("settings-title")));
|
||||||
settingsTitle.setFontSize(48);
|
settingsTitle.setFontSize(48);
|
||||||
settingsTitle.setColor(ColorRGBA.White);
|
|
||||||
|
|
||||||
// Effekt Sound mit Slider und Checkbox
|
// Effekt-Sound: Slider und Checkbox
|
||||||
Container effectSoundContainer = settingsContainer.addChild(new Container());
|
Container effectSoundContainer = settingsContainer.addChild(new Container());
|
||||||
Label effectSoundLabel = effectSoundContainer.addChild(new Label("Effekt Sound", new ElementId("label")));
|
effectSoundContainer.addChild(new Label("Effekt Sound", new ElementId("label")));
|
||||||
effectSoundLabel.setFontSize(24);
|
effectSoundContainer.addChild(new Slider());
|
||||||
effectSoundLabel.setColor(ColorRGBA.White);
|
effectSoundContainer.addChild(new Checkbox("Aktivieren")).setChecked(true);
|
||||||
|
|
||||||
Slider effectSoundSlider = effectSoundContainer.addChild(new Slider());
|
// Hintergrundmusik: Slider und Checkbox
|
||||||
effectSoundSlider.setPreferredSize(new com.jme3.math.Vector3f(300, 30, 0));
|
|
||||||
|
|
||||||
Checkbox effectSoundCheckbox = effectSoundContainer.addChild(new Checkbox(""));
|
|
||||||
effectSoundCheckbox.setChecked(true);
|
|
||||||
|
|
||||||
// Hintergrund Musik mit Slider und Checkbox
|
|
||||||
Container backgroundMusicContainer = settingsContainer.addChild(new Container());
|
Container backgroundMusicContainer = settingsContainer.addChild(new Container());
|
||||||
Label backgroundMusicLabel = backgroundMusicContainer.addChild(new Label("Hintergrund Musik", new ElementId("label")));
|
backgroundMusicContainer.addChild(new Label("Hintergrund Musik", new ElementId("label")));
|
||||||
backgroundMusicLabel.setFontSize(24);
|
backgroundMusicContainer.addChild(new Slider());
|
||||||
backgroundMusicLabel.setColor(ColorRGBA.White);
|
backgroundMusicContainer.addChild(new Checkbox("Aktivieren")).setChecked(true);
|
||||||
|
|
||||||
Slider backgroundMusicSlider = backgroundMusicContainer.addChild(new Slider());
|
// Beenden-Button
|
||||||
backgroundMusicSlider.setPreferredSize(new com.jme3.math.Vector3f(300, 30, 0));
|
|
||||||
|
|
||||||
Checkbox backgroundMusicCheckbox = backgroundMusicContainer.addChild(new Checkbox(""));
|
|
||||||
backgroundMusicCheckbox.setChecked(true);
|
|
||||||
|
|
||||||
// Beenden Button
|
|
||||||
Button quitButton = settingsContainer.addChild(new Button("Beenden", new ElementId("menu-button")));
|
Button quitButton = settingsContainer.addChild(new Button("Beenden", new ElementId("menu-button")));
|
||||||
quitButton.setFontSize(32);
|
quitButton.setFontSize(32);
|
||||||
quitButton.setColor(ColorRGBA.White);
|
|
||||||
quitButton.addClickCommands(source -> app.stop());
|
quitButton.addClickCommands(source -> app.stop());
|
||||||
|
|
||||||
// Zentrieren des Containers
|
// Zentriere das Menü
|
||||||
settingsContainer.setLocalTranslation(
|
settingsContainer.setLocalTranslation(
|
||||||
(app.getCamera().getWidth() - settingsContainer.getPreferredSize().x) / 2,
|
(app.getCamera().getWidth() - settingsContainer.getPreferredSize().x) / 2,
|
||||||
(app.getCamera().getHeight() + settingsContainer.getPreferredSize().y) / 2,
|
(app.getCamera().getHeight() + settingsContainer.getPreferredSize().y) / 2,
|
||||||
1 // Höhere Z-Ebene für den Vordergrund
|
1
|
||||||
);
|
);
|
||||||
|
|
||||||
app.getGuiNode().attachChild(settingsContainer);
|
app.getGuiNode().attachChild(settingsContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addBlockLayer() {
|
/**
|
||||||
// Sichern des aktuellen GUI-Inhalts
|
* Erstellt einen halbtransparenten Hintergrund für das Menü.
|
||||||
for (var child : app.getGuiNode().getChildren()) {
|
*
|
||||||
savedGuiNodeContent.attachChild(child);
|
* @return Geometrie des Overlays
|
||||||
}
|
*/
|
||||||
app.getGuiNode().detachAllChildren();
|
private Geometry createOverlayBackground() {
|
||||||
|
|
||||||
// Blockierungsebene erstellen und hinzufügen
|
|
||||||
blockLayer = new Geometry("BlockLayer", new Quad(app.getCamera().getWidth(), app.getCamera().getHeight()));
|
|
||||||
blockLayer.setMaterial(createTransparentMaterial());
|
|
||||||
blockLayer.setLocalTranslation(0, 0, 0); // Platzierung unterhalb des SettingsMenu
|
|
||||||
app.getGuiNode().attachChild(blockLayer);
|
|
||||||
}
|
|
||||||
|
|
||||||
private com.jme3.material.Material createTransparentMaterial() {
|
|
||||||
com.jme3.material.Material material = new com.jme3.material.Material(
|
|
||||||
app.getAssetManager(),
|
|
||||||
"Common/MatDefs/Misc/Unshaded.j3md"
|
|
||||||
);
|
|
||||||
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Halbtransparent
|
|
||||||
material.getAdditionalRenderState().setBlendMode(com.jme3.material.RenderState.BlendMode.Alpha);
|
|
||||||
return material;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addBackgroundImage() {
|
|
||||||
Texture backgroundImage = app.getAssetManager().loadTexture("Pictures/unibw-Bib2.png");
|
|
||||||
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
|
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
|
||||||
Geometry background = new Geometry("Background", quad);
|
Geometry overlay = new Geometry("Overlay", quad);
|
||||||
com.jme3.material.Material backgroundMaterial = new com.jme3.material.Material(
|
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
|
||||||
app.getAssetManager(),
|
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Halbtransparent
|
||||||
"Common/MatDefs/Misc/Unshaded.j3md"
|
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
|
||||||
);
|
overlay.setMaterial(material);
|
||||||
backgroundMaterial.setTexture("ColorMap", backgroundImage);
|
overlay.setLocalTranslation(0, 0, 0);
|
||||||
background.setMaterial(backgroundMaterial);
|
return overlay;
|
||||||
background.setLocalTranslation(0, 0, -1); // Platzierung hinter dem SettingsMenu
|
|
||||||
app.getGuiNode().attachChild(background);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schließt das Menü und entfernt die GUI-Elemente.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
// Entfernt das SettingsMenu und die Blockierungsebene
|
System.out.println("Schließe SettingsMenu..."); // Debugging-Ausgabe
|
||||||
app.getGuiNode().detachChild(settingsContainer);
|
app.getGuiNode().detachChild(settingsContainer); // Entferne das Menü
|
||||||
app.getGuiNode().detachChild(blockLayer);
|
app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
|
||||||
|
app.setSettingsMenuOpen(false); // Menü als geschlossen markieren
|
||||||
// Stellt die ursprüngliche GUI wieder her
|
app.unblockInputs(); // Eingaben wieder aktivieren
|
||||||
for (var child : savedGuiNodeContent.getChildren()) {
|
System.out.println("SettingsMenu geschlossen."); // Debugging-Ausgabe
|
||||||
app.getGuiNode().attachChild(child);
|
|
||||||
}
|
|
||||||
savedGuiNodeContent.detachAllChildren();
|
|
||||||
|
|
||||||
app.setSettingsMenuOpen(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,39 +1,107 @@
|
|||||||
package pp.monopoly.client.gui;
|
package pp.monopoly.client.gui;
|
||||||
|
|
||||||
import com.jme3.app.SimpleApplication;
|
|
||||||
import com.jme3.material.Material;
|
import com.jme3.material.Material;
|
||||||
|
import com.jme3.math.ColorRGBA;
|
||||||
import com.jme3.math.Vector3f;
|
import com.jme3.math.Vector3f;
|
||||||
import com.jme3.scene.Geometry;
|
import com.jme3.scene.Geometry;
|
||||||
import com.jme3.scene.shape.Box;
|
import com.jme3.scene.shape.Box;
|
||||||
import com.jme3.texture.Texture;
|
import com.jme3.texture.Texture;
|
||||||
|
|
||||||
|
import pp.monopoly.client.MonopolyApp;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TestWorld zeigt eine einfache Szene mit einem texturierten Quadrat.
|
* TestWorld zeigt eine einfache Szene mit einem texturierten Quadrat.
|
||||||
|
* Die Kamera wird durch den CameraController gesteuert.
|
||||||
*/
|
*/
|
||||||
public class TestWorld extends SimpleApplication {
|
public class TestWorld {
|
||||||
|
|
||||||
@Override
|
private final MonopolyApp app;
|
||||||
public void simpleInitApp() {
|
private CameraController cameraController; // Steuert die Kamera
|
||||||
|
private Geometry cube; // Spielfigur
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Konstruktor für TestWorld.
|
||||||
|
*
|
||||||
|
* @param app Die Hauptanwendung (MonopolyApp)
|
||||||
|
*/
|
||||||
|
public TestWorld(MonopolyApp app) {
|
||||||
|
this.app = app;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialisiert die Szene und startet die Kamerabewegung.
|
||||||
|
*/
|
||||||
|
public void initializeScene() {
|
||||||
|
app.getGuiNode().detachAllChildren(); // Entferne GUI
|
||||||
|
app.getRootNode().detachAllChildren(); // Entferne andere Szenenobjekte
|
||||||
|
|
||||||
|
setSkyColor(); // Setze den Himmel auf hellblau
|
||||||
|
createBoard(); // Erstelle das Spielfeld
|
||||||
|
createCube(); // Füge den Würfel hinzu
|
||||||
|
|
||||||
|
// Erstelle den CameraController
|
||||||
|
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
|
||||||
|
);
|
||||||
|
|
||||||
|
// Füge die Toolbar hinzu
|
||||||
|
new Toolbar(app, cube);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aktualisiert die Kameraposition.
|
||||||
|
*
|
||||||
|
* @param tpf Zeit pro Frame
|
||||||
|
*/
|
||||||
|
public void update(float tpf) {
|
||||||
|
if (cameraController != null) {
|
||||||
|
cameraController.update(tpf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setzt die Hintergrundfarbe der Szene auf hellblau.
|
||||||
|
*/
|
||||||
|
private void setSkyColor() {
|
||||||
|
app.getViewPort().setBackgroundColor(new ColorRGBA(0.5f, 0.7f, 1.0f, 1.0f)); // Hellblauer Himmel
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Erstelle das Spielfeld.
|
||||||
|
*/
|
||||||
|
private void createBoard() {
|
||||||
// Erstelle ein Quadrat
|
// Erstelle ein Quadrat
|
||||||
Box box = new Box(1, 0.01f, 1); // Dünnes Quadrat für die Textur
|
Box box = new Box(1, 0.01f, 1); // Dünnes Quadrat für die Textur
|
||||||
Geometry geom = new Geometry("Box", box);
|
Geometry geom = new Geometry("Board", box);
|
||||||
|
|
||||||
// Setze das Material mit Textur
|
// Setze das Material mit Textur
|
||||||
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
|
Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
|
||||||
Texture texture = assetManager.loadTexture("Pictures/board.png"); // Ersetze durch den Pfad zum gewünschten Bild
|
Texture texture = app.getAssetManager().loadTexture("Pictures/board.png");
|
||||||
mat.setTexture("ColorMap", texture);
|
mat.setTexture("ColorMap", texture);
|
||||||
geom.setMaterial(mat);
|
geom.setMaterial(mat);
|
||||||
|
|
||||||
// Füge das Quadrat zur Szene hinzu
|
app.getRootNode().attachChild(geom);
|
||||||
rootNode.attachChild(geom);
|
|
||||||
|
|
||||||
// Setze die Kameraposition, um das Quadrat zu fokussieren
|
|
||||||
cam.setLocation(new Vector3f(0, 0, 3)); // Kamera auf der Z-Achse, nah am Quadrat
|
|
||||||
cam.lookAt(geom.getLocalTranslation(), Vector3f.UNIT_Y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void startTestWorld() {
|
/**
|
||||||
TestWorld testWorldApp = new TestWorld();
|
* Erstellt den Würfel (Spielfigur) in der Szene.
|
||||||
testWorldApp.start();
|
*/
|
||||||
|
private void createCube() {
|
||||||
|
Box box = new Box(0.05f, 0.05f, 0.05f); // Kleinere Größe für Spielfigur
|
||||||
|
cube = new Geometry("Cube", box);
|
||||||
|
|
||||||
|
// Setze das Material für den Würfel
|
||||||
|
Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
|
||||||
|
mat.setColor("Color", ColorRGBA.Blue); // Blau gefärbter Würfel
|
||||||
|
cube.setMaterial(mat);
|
||||||
|
|
||||||
|
// Setze den Startpunkt des Würfels
|
||||||
|
cube.setLocalTranslation(0.8999999f, 0.1f, -0.9f);
|
||||||
|
|
||||||
|
app.getRootNode().attachChild(cube);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,80 +0,0 @@
|
|||||||
package pp.monopoly.client.gui;
|
|
||||||
|
|
||||||
import com.jme3.app.SimpleApplication;
|
|
||||||
import com.jme3.material.Material;
|
|
||||||
import com.jme3.math.Vector3f;
|
|
||||||
import com.jme3.scene.Geometry;
|
|
||||||
import com.jme3.scene.shape.Box;
|
|
||||||
import com.jme3.texture.Texture;
|
|
||||||
import com.jme3.system.JmeCanvasContext;
|
|
||||||
import com.jme3.system.AppSettings;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
|
|
||||||
public class TestWorldWithMenu extends SimpleApplication {
|
|
||||||
|
|
||||||
public static void createAndShowGUI() {
|
|
||||||
// Create JFrame
|
|
||||||
JFrame frame = new JFrame("Test World with Menu");
|
|
||||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
|
||||||
frame.setLayout(new BorderLayout());
|
|
||||||
frame.setSize(800, 600);
|
|
||||||
|
|
||||||
// Create Menu Bar
|
|
||||||
JMenuBar menuBar = new JMenuBar();
|
|
||||||
JMenu fileMenu = new JMenu("File");
|
|
||||||
JMenuItem exitItem = new JMenuItem(new AbstractAction("Exit") {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
fileMenu.add(exitItem);
|
|
||||||
menuBar.add(fileMenu);
|
|
||||||
frame.setJMenuBar(menuBar);
|
|
||||||
|
|
||||||
// Create Canvas for jMonkey
|
|
||||||
AppSettings settings = new AppSettings(true);
|
|
||||||
settings.setWidth(800);
|
|
||||||
settings.setHeight(600);
|
|
||||||
|
|
||||||
TestWorldWithMenu app = new TestWorldWithMenu();
|
|
||||||
app.setSettings(settings);
|
|
||||||
app.createCanvas(); // Create a canvas for embedding
|
|
||||||
JmeCanvasContext ctx = (JmeCanvasContext) app.getContext();
|
|
||||||
ctx.setSystemListener(app);
|
|
||||||
Canvas canvas = ctx.getCanvas();
|
|
||||||
canvas.setSize(800, 600);
|
|
||||||
|
|
||||||
// Add the canvas to JFrame
|
|
||||||
frame.add(canvas, BorderLayout.CENTER);
|
|
||||||
|
|
||||||
// Show the frame
|
|
||||||
frame.setVisible(true);
|
|
||||||
|
|
||||||
// Start the jMonkeyEngine application
|
|
||||||
app.startCanvas();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void simpleInitApp() {
|
|
||||||
// Erstelle ein Quadrat
|
|
||||||
Box box = new Box(1, 0.01f, 1); // Dünnes Quadrat für die Textur
|
|
||||||
Geometry geom = new Geometry("Box", box);
|
|
||||||
|
|
||||||
// Setze das Material mit Textur
|
|
||||||
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
|
|
||||||
Texture texture = assetManager.loadTexture("Pictures/board.png"); // Replace with the path to your image
|
|
||||||
mat.setTexture("ColorMap", texture);
|
|
||||||
geom.setMaterial(mat);
|
|
||||||
|
|
||||||
// Füge das Quadrat zur Szene hinzu
|
|
||||||
rootNode.attachChild(geom);
|
|
||||||
|
|
||||||
// Setze die Kameraposition, um das Quadrat zu fokussieren
|
|
||||||
cam.setLocation(new Vector3f(0, 0, 3)); // Kamera auf der Z-Achse, nah am Quadrat
|
|
||||||
cam.lookAt(geom.getLocalTranslation(), Vector3f.UNIT_Y);
|
|
||||||
}
|
|
||||||
}
|
|
@ -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 Toolbar {
|
||||||
|
|
||||||
|
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 Toolbar(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);
|
||||||
|
}
|
||||||
|
}
|
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.
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 484 KiB |
@ -7,6 +7,13 @@
|
|||||||
|
|
||||||
package pp.monopoly.game.client;
|
package pp.monopoly.game.client;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.System.Logger;
|
||||||
|
import java.lang.System.Logger.Level;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import pp.monopoly.message.client.ClientMessage;
|
import pp.monopoly.message.client.ClientMessage;
|
||||||
import pp.monopoly.message.server.BuyPropertyResponse;
|
import pp.monopoly.message.server.BuyPropertyResponse;
|
||||||
import pp.monopoly.message.server.DiceResult;
|
import pp.monopoly.message.server.DiceResult;
|
||||||
@ -19,10 +26,9 @@ import pp.monopoly.message.server.ServerInterpreter;
|
|||||||
import pp.monopoly.message.server.TimeOutWarning;
|
import pp.monopoly.message.server.TimeOutWarning;
|
||||||
import pp.monopoly.message.server.TradeReply;
|
import pp.monopoly.message.server.TradeReply;
|
||||||
import pp.monopoly.message.server.TradeRequest;
|
import pp.monopoly.message.server.TradeRequest;
|
||||||
import pp.monopoly.message.server.UpdatePlayerAssets;
|
|
||||||
import pp.monopoly.message.server.ViewAssetsResponse;
|
import pp.monopoly.message.server.ViewAssetsResponse;
|
||||||
import pp.monopoly.model.IntPoint;
|
|
||||||
import pp.monopoly.model.Board;
|
import pp.monopoly.model.Board;
|
||||||
|
import pp.monopoly.model.IntPoint;
|
||||||
import pp.monopoly.notification.ClientStateEvent;
|
import pp.monopoly.notification.ClientStateEvent;
|
||||||
import pp.monopoly.notification.GameEvent;
|
import pp.monopoly.notification.GameEvent;
|
||||||
import pp.monopoly.notification.GameEventBroker;
|
import pp.monopoly.notification.GameEventBroker;
|
||||||
@ -38,18 +44,6 @@ import java.lang.System.Logger.Level;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import pp.monopoly.message.client.ClientMessage;
|
|
||||||
import pp.monopoly.message.server.ServerInterpreter;
|
|
||||||
import pp.monopoly.model.Board;
|
|
||||||
import pp.monopoly.model.IntPoint;
|
|
||||||
import pp.monopoly.notification.ClientStateEvent;
|
|
||||||
import pp.monopoly.notification.GameEvent;
|
|
||||||
import pp.monopoly.notification.GameEventBroker;
|
|
||||||
import pp.monopoly.notification.GameEventListener;
|
|
||||||
import pp.monopoly.notification.InfoTextEvent;
|
|
||||||
import pp.monopoly.notification.Sound;
|
|
||||||
import pp.monopoly.notification.SoundEvent;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controls the client-side game logic for Monopoly.
|
* Controls the client-side game logic for Monopoly.
|
||||||
* Manages the player's placement, interactions with the map, and response to server messages.
|
* Manages the player's placement, interactions with the map, and response to server messages.
|
||||||
@ -58,9 +52,8 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker {
|
|||||||
static final Logger LOGGER = System.getLogger(ClientGameLogic.class.getName());
|
static final Logger LOGGER = System.getLogger(ClientGameLogic.class.getName());
|
||||||
private final ClientSender clientSender;
|
private final ClientSender clientSender;
|
||||||
private final List<GameEventListener> listeners = new ArrayList<>();
|
private final List<GameEventListener> listeners = new ArrayList<>();
|
||||||
private Board ownMap;
|
private Board board;
|
||||||
private Board harbor;
|
|
||||||
private Board opponentMap;
|
|
||||||
private ClientState state = new ClientState(this) {
|
private ClientState state = new ClientState(this) {
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -98,8 +91,8 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker {
|
|||||||
*
|
*
|
||||||
* @return the player's own map
|
* @return the player's own map
|
||||||
*/
|
*/
|
||||||
public Board getMap() {
|
public Board getBoard() {
|
||||||
return ownMap;
|
return board;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -195,73 +188,73 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void received(BuyPropertyResponse msg) {
|
public void received(BuyPropertyResponse msg) {
|
||||||
// TODO Auto-generated method stub
|
if (msg.isSuccessful()) {
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'received'");
|
setInfoText("You successfully bought " + msg.getPropertyName() + "!");
|
||||||
|
playSound(Sound.MONEY_LOST);
|
||||||
|
} else {
|
||||||
|
setInfoText("Unable to buy " + msg.getPropertyName() + ". Reason: " + msg.getReason());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void received(DiceResult msg) {
|
public void received(DiceResult msg) {
|
||||||
// TODO Auto-generated method stub
|
setInfoText("You rolled a " + msg.calcTotal() + "!");
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'received'");
|
playSound(Sound.DICE_ROLL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void received(EventDrawCard msg) {
|
public void received(EventDrawCard msg) {
|
||||||
// TODO Auto-generated method stub
|
setInfoText("Event card drawn: " + msg.getCardDescription());
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'received'");
|
playSound(Sound.EVENT_CARD);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void received(GameOver msg) {
|
public void received(GameOver msg) {
|
||||||
// TODO Auto-generated method stub
|
if (msg.isWinner()) {
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'received'");
|
setInfoText("Congratulations! You have won the game!");
|
||||||
|
playSound(Sound.WINNER);
|
||||||
|
} else {
|
||||||
|
setInfoText("Game over. Better luck next time!");
|
||||||
|
playSound(Sound.LOSER);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void received(GameStart msg) {
|
public void received(GameStart msg) {
|
||||||
// TODO Auto-generated method stub
|
setInfoText("The game has started! Good luck!");
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'received'");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void received(JailEvent msg) {
|
public void received(JailEvent msg) {
|
||||||
// TODO Auto-generated method stub
|
if (msg.isGoingToJail()) {
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'received'");
|
setInfoText("You are sent to jail!");
|
||||||
|
playSound(Sound.GULAG);
|
||||||
|
} else {
|
||||||
|
setInfoText("You are out of jail!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void received(PlayerStatusUpdate msg) {
|
public void received(PlayerStatusUpdate msg) {
|
||||||
// TODO Auto-generated method stub
|
setInfoText("Player " + msg.getPlayerName() + " status updated: " + msg.getStatus());
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'received'");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void received(TimeOutWarning msg) {
|
public void received(TimeOutWarning msg) {
|
||||||
// TODO Auto-generated method stub
|
setInfoText("Warning! Time is running out. You have " + msg.getRemainingTime() + " seconds left.");
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'received'");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void received(UpdatePlayerAssets msg) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'received'");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void received(ViewAssetsResponse msg) {
|
public void received(ViewAssetsResponse msg) {
|
||||||
// TODO Auto-generated method stub
|
setInfoText("Your current assets are being displayed.");
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'received'");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void received(TradeReply msg) {
|
public void received(TradeReply msg) {
|
||||||
// TODO Auto-generated method stub
|
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'received'");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void received(TradeRequest msg) {
|
public void received(TradeRequest msg) {
|
||||||
// TODO Auto-generated method stub
|
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'received'");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -109,8 +109,10 @@ public class PlayerHandler {
|
|||||||
* @return the next players who is active
|
* @return the next players who is active
|
||||||
*/
|
*/
|
||||||
Player nextPlayer() {
|
Player nextPlayer() {
|
||||||
players.addLast(players.removeFirst());
|
Player tmp = players.get(0);
|
||||||
return players.getFirst();
|
players.remove(0);
|
||||||
|
players.add(tmp);
|
||||||
|
return players.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,11 +1,34 @@
|
|||||||
package pp.monopoly.message.server;
|
package pp.monopoly.message.server;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the server's response to a player's request to buy a property.
|
||||||
|
*/
|
||||||
public class BuyPropertyResponse extends ServerMessage{
|
public class BuyPropertyResponse extends ServerMessage{
|
||||||
|
private final boolean successful;
|
||||||
|
private final String propertyName;
|
||||||
|
private final String reason; // Reason for failure, if any
|
||||||
|
|
||||||
|
public BuyPropertyResponse(boolean successful, String propertyName, String reason) {
|
||||||
|
this.successful = successful;
|
||||||
|
this.propertyName = propertyName;
|
||||||
|
this.reason = reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSuccessful() {
|
||||||
|
return successful;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPropertyName() {
|
||||||
|
return propertyName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReason() {
|
||||||
|
return reason;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(ServerInterpreter interpreter) {
|
public void accept(ServerInterpreter interpreter) {
|
||||||
// TODO Auto-generated method stub
|
interpreter.received(this);
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'accept'");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -13,5 +36,4 @@ public class BuyPropertyResponse extends ServerMessage{
|
|||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'getInfoTextKey'");
|
throw new UnsupportedOperationException("Unimplemented method 'getInfoTextKey'");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
package pp.monopoly.message.server;
|
package pp.monopoly.message.server;
|
||||||
|
|
||||||
public class EventDrawCard extends ServerMessage{
|
public class EventDrawCard extends ServerMessage{
|
||||||
|
private final String cardDescription;
|
||||||
|
|
||||||
|
public EventDrawCard(String cardDescription) {
|
||||||
|
this.cardDescription = cardDescription;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(ServerInterpreter interpreter) {
|
public void accept(ServerInterpreter interpreter) {
|
||||||
@ -13,4 +18,8 @@ public class EventDrawCard extends ServerMessage{
|
|||||||
throw new UnsupportedOperationException("Unimplemented method 'getInfoTextKey'");
|
throw new UnsupportedOperationException("Unimplemented method 'getInfoTextKey'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getCardDescription() {
|
||||||
|
return cardDescription;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,15 @@
|
|||||||
package pp.monopoly.message.server;
|
package pp.monopoly.message.server;
|
||||||
|
|
||||||
public class GameOver extends ServerMessage{
|
public class GameOver extends ServerMessage{
|
||||||
|
private final boolean isWinner;
|
||||||
|
|
||||||
|
public GameOver(boolean isWinner) {
|
||||||
|
this.isWinner = isWinner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isWinner() {
|
||||||
|
return isWinner;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(ServerInterpreter interpreter) {
|
public void accept(ServerInterpreter interpreter) {
|
||||||
|
@ -2,6 +2,16 @@ package pp.monopoly.message.server;
|
|||||||
|
|
||||||
public class JailEvent extends ServerMessage{
|
public class JailEvent extends ServerMessage{
|
||||||
|
|
||||||
|
private final boolean goingToJail;
|
||||||
|
|
||||||
|
public JailEvent(boolean goingToJail) {
|
||||||
|
this.goingToJail = goingToJail;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isGoingToJail() {
|
||||||
|
return goingToJail;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(ServerInterpreter interpreter) {
|
public void accept(ServerInterpreter interpreter) {
|
||||||
interpreter.received(this);
|
interpreter.received(this);
|
||||||
|
@ -1,7 +1,31 @@
|
|||||||
package pp.monopoly.message.server;
|
package pp.monopoly.message.server;
|
||||||
|
|
||||||
|
import pp.monopoly.game.server.PlayerColor;
|
||||||
|
|
||||||
public class PlayerStatusUpdate extends ServerMessage{
|
public class PlayerStatusUpdate extends ServerMessage{
|
||||||
|
|
||||||
|
private final String playerName;
|
||||||
|
private final String status;
|
||||||
|
private final PlayerColor color;
|
||||||
|
|
||||||
|
public PlayerStatusUpdate(String playerName, String status, PlayerColor color) {
|
||||||
|
this.playerName = playerName;
|
||||||
|
this.status = status;
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPlayerName() {
|
||||||
|
return playerName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlayerColor getColor() {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(ServerInterpreter interpreter) {
|
public void accept(ServerInterpreter interpreter) {
|
||||||
interpreter.received(this);
|
interpreter.received(this);
|
||||||
|
@ -69,13 +69,6 @@ public interface ServerInterpreter {
|
|||||||
*/
|
*/
|
||||||
void received(TimeOutWarning msg);
|
void received(TimeOutWarning msg);
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles a UpdatePlayerAssets message received from the server.
|
|
||||||
*
|
|
||||||
* @param msg the UpdatePlayerAssets message received
|
|
||||||
*/
|
|
||||||
void received(UpdatePlayerAssets msg);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles a ViewAssetsResponse message received from the server.
|
* Handles a ViewAssetsResponse message received from the server.
|
||||||
*
|
*
|
||||||
|
@ -2,6 +2,16 @@ package pp.monopoly.message.server;
|
|||||||
|
|
||||||
public class TimeOutWarning extends ServerMessage{
|
public class TimeOutWarning extends ServerMessage{
|
||||||
|
|
||||||
|
private final int remainingTime;
|
||||||
|
|
||||||
|
public TimeOutWarning(int remainingTime) {
|
||||||
|
this.remainingTime = remainingTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRemainingTime() {
|
||||||
|
return remainingTime;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(ServerInterpreter interpreter) {
|
public void accept(ServerInterpreter interpreter) {
|
||||||
interpreter.received(this);
|
interpreter.received(this);
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
package pp.monopoly.message.server;
|
|
||||||
|
|
||||||
public class UpdatePlayerAssets extends ServerMessage{
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void accept(ServerInterpreter interpreter) {
|
|
||||||
interpreter.received(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getInfoTextKey() {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'getInfoTextKey'");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -8,9 +8,9 @@ import pp.monopoly.model.fields.PropertyField;
|
|||||||
*/
|
*/
|
||||||
public class ViewAssetsResponse extends ServerMessage{
|
public class ViewAssetsResponse extends ServerMessage{
|
||||||
|
|
||||||
private List<PropertyField> properties;
|
private final List<PropertyField> properties;
|
||||||
private int accountBalance;
|
private final int accountBalance;
|
||||||
private int jailCards;
|
private final int jailCards;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a ViewAssetsResponse with the specified properties and account balance.
|
* Constructs a ViewAssetsResponse with the specified properties and account balance.
|
||||||
|
@ -57,6 +57,7 @@ public class Board {
|
|||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
this.eventBroker = eventBroker;
|
this.eventBroker = eventBroker;
|
||||||
|
addItem(new Figure(5, 5, 5, Rotation.LEFT));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,17 +1,309 @@
|
|||||||
package pp.monopoly.model;
|
package pp.monopoly.model;
|
||||||
|
|
||||||
public class Figure implements Item{
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
@Override
|
import static java.lang.Math.max;
|
||||||
public <T> T accept(Visitor<T> visitor) {
|
import static java.lang.Math.min;
|
||||||
// TODO Auto-generated method stub
|
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'accept'");
|
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 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
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor for serialization. Initializes a Figure with length 0,
|
||||||
|
* at position (0, 0), with a default rotation of RIGHT.
|
||||||
|
*/
|
||||||
|
private Figure() {
|
||||||
|
this(0, 0, 0, Rotation.RIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new Figure with the specified length, position, and rotation.
|
||||||
|
*
|
||||||
|
* @param length the length of the Figure
|
||||||
|
* @param x the x-coordinate of the Figure's initial position
|
||||||
|
* @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) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.rot = rot;
|
||||||
|
this.length = length;
|
||||||
|
this.status = Status.NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current x-coordinate of the Figure's position.
|
||||||
|
*
|
||||||
|
* @return the x-coordinate of the Figure
|
||||||
|
*/
|
||||||
|
public int getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current y-coordinate of the Figure's position.
|
||||||
|
*
|
||||||
|
* @return the y-coordinate of the Figure
|
||||||
|
*/
|
||||||
|
public int getY() {
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves the Figure to the specified coordinates.
|
||||||
|
*
|
||||||
|
* @param x the new x-coordinate of the Figure's position
|
||||||
|
* @param y the new y-coordinate of the Figure's position
|
||||||
|
*/
|
||||||
|
public void moveTo(int x, int y) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves the Figure to the specified position.
|
||||||
|
*
|
||||||
|
* @param pos the new position of the Figure
|
||||||
|
*/
|
||||||
|
public void moveTo(IntPosition pos) {
|
||||||
|
moveTo(pos.getX(), pos.getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current status of the Figure.
|
||||||
|
*
|
||||||
|
* @return the status of the Figure
|
||||||
|
*/
|
||||||
|
public Status getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the length of the Figure.
|
||||||
|
*
|
||||||
|
* @return the length of the Figure
|
||||||
|
*/
|
||||||
|
public int getLength() {
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the minimum x-coordinate that the Figure occupies based on its current position and rotation.
|
||||||
|
*
|
||||||
|
* @return the minimum x-coordinate of the Figure
|
||||||
|
*/
|
||||||
|
public int getMinX() {
|
||||||
|
return x + min(0, (length - 1) * rot.dx());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the maximum x-coordinate that the Figure occupies based on its current position and rotation.
|
||||||
|
*
|
||||||
|
* @return the maximum x-coordinate of the Figure
|
||||||
|
*/
|
||||||
|
public int getMaxX() {
|
||||||
|
return x + max(0, (length - 1) * rot.dx());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the minimum y-coordinate that the Figure occupies based on its current position and rotation.
|
||||||
|
*
|
||||||
|
* @return the minimum y-coordinate of the Figure
|
||||||
|
*/
|
||||||
|
public int getMinY() {
|
||||||
|
return y + min(0, (length - 1) * rot.dy());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the maximum y-coordinate that the Figure occupies based on its current position and rotation.
|
||||||
|
*
|
||||||
|
* @return the maximum y-coordinate of the Figure
|
||||||
|
*/
|
||||||
|
public int getMaxY() {
|
||||||
|
return y + max(0, (length - 1) * rot.dy());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current rotation of the Figure.
|
||||||
|
*
|
||||||
|
* @return the rotation of the Figure
|
||||||
|
*/
|
||||||
|
public Rotation getRot() {
|
||||||
|
return rot;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the rotation of the Figure.
|
||||||
|
*
|
||||||
|
* @param rot the new rotation to be set for the Figure
|
||||||
|
*/
|
||||||
|
public void setRotation(Rotation rot) {
|
||||||
|
this.rot = rot;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rotates the Figure by 90 degrees clockwise.
|
||||||
|
*/
|
||||||
|
public void rotated() {
|
||||||
|
setRotation(rot.rotate());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to hit the Figure at the specified position.
|
||||||
|
* If the position is part of the Figure, the hit is recorded.
|
||||||
|
*
|
||||||
|
* @param x the x-coordinate of the position to hit
|
||||||
|
* @param y the y-coordinate of the position to hit
|
||||||
|
* @return true if the position is part of the Figure, false otherwise
|
||||||
|
* @see #contains(int, int)
|
||||||
|
*/
|
||||||
|
public boolean hit(int x, int y) {
|
||||||
|
if (!contains(x, y))
|
||||||
|
return false;
|
||||||
|
damaged.add(new IntPoint(x, y));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to hit the Figure at the specified position.
|
||||||
|
* If the position is part of the Figure, the hit is recorded.
|
||||||
|
* This is a convenience method for {@linkplain #hit(int, int)}.
|
||||||
|
*
|
||||||
|
* @param position the position to hit
|
||||||
|
* @return true if the position is part of the Figure, false otherwise
|
||||||
|
*/
|
||||||
|
public boolean hit(IntPosition position) {
|
||||||
|
return hit(position.getX(), position.getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the positions of this Figure that have been hit.
|
||||||
|
*
|
||||||
|
* @return a set of positions that have been hit
|
||||||
|
* @see #hit(int, int)
|
||||||
|
*/
|
||||||
|
public Set<IntPoint> getDamaged() {
|
||||||
|
return Collections.unmodifiableSet(damaged);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the specified position is covered by the Figure. This method does
|
||||||
|
* not record a hit, only checks coverage.
|
||||||
|
* This is a convenience method for {@linkplain #contains(int, int)}.
|
||||||
|
*
|
||||||
|
* @param pos the position to check
|
||||||
|
* @return true if the position is covered by the Figure, false otherwise
|
||||||
|
*/
|
||||||
|
public boolean contains(IntPosition pos) {
|
||||||
|
return contains(pos.getX(), pos.getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the specified position is covered by the Figure. This method does
|
||||||
|
* not record a hit, only checks coverage.
|
||||||
|
*
|
||||||
|
* @param x the x-coordinate of the position to check
|
||||||
|
* @param y the y-coordinate of the position to check
|
||||||
|
* @return true if the position is covered by the Figure, false otherwise
|
||||||
|
*/
|
||||||
|
public boolean contains(int x, int y) {
|
||||||
|
return getMinX() <= x && x <= getMaxX() &&
|
||||||
|
getMinY() <= y && y <= getMaxY();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if the Figure has been completely destroyed. A Figure is considered
|
||||||
|
* destroyed if all of its positions have been hit.
|
||||||
|
*
|
||||||
|
* @return true if the Figure is destroyed, false otherwise
|
||||||
|
* @see #hit(int, int)
|
||||||
|
*/
|
||||||
|
public boolean isDestroyed() {
|
||||||
|
return damaged.size() == length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether this Figure collides with another Figure. Two Figures collide
|
||||||
|
* if any of their occupied positions overlap.
|
||||||
|
*
|
||||||
|
* @param other the other Figure to check collision with
|
||||||
|
* @return true if the Figures collide, false otherwise
|
||||||
|
*/
|
||||||
|
public boolean collidesWith(Figure other) {
|
||||||
|
return other.getMaxX() >= getMinX() && getMaxX() >= other.getMinX() &&
|
||||||
|
other.getMaxY() >= getMinY() && getMaxY() >= other.getMinY();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string representation of the Figure, including its length, position,
|
||||||
|
* and rotation.
|
||||||
|
*
|
||||||
|
* @return a string representation of the Figure
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Ship{length=" + length + ", x=" + x + ", y=" + y + ", rot=" + rot + '}'; //NON-NLS
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accepts a visitor that returns a value of type {@code T}. This method is part of the
|
||||||
|
* Visitor design pattern.
|
||||||
|
*
|
||||||
|
* @param visitor the visitor to accept
|
||||||
|
* @param <T> the type of the value returned by the visitor
|
||||||
|
* @return the value returned by the visitor
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public <T> T accept(Visitor<T> visitor) {
|
||||||
|
return visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accepts a visitor that does not return a value. This method is part of the
|
||||||
|
* Visitor design pattern.
|
||||||
|
*
|
||||||
|
* @param visitor the visitor to accept
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void accept(VoidVisitor visitor) {
|
public void accept(VoidVisitor visitor) {
|
||||||
// TODO Auto-generated method stub
|
visitor.visit(this);
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'accept'");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,4 +14,12 @@ package pp.monopoly.model;
|
|||||||
*/
|
*/
|
||||||
public interface Visitor<T> {
|
public interface Visitor<T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Visits a Figure element.
|
||||||
|
*
|
||||||
|
* @param figure the figure element to visit
|
||||||
|
* @return the result of visiting the figure element
|
||||||
|
*/
|
||||||
|
T visit(Figure figure);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,5 +12,11 @@ package pp.monopoly.model;
|
|||||||
* without returning any result.
|
* without returning any result.
|
||||||
*/
|
*/
|
||||||
public interface VoidVisitor {
|
public interface VoidVisitor {
|
||||||
|
/**
|
||||||
|
* Visits a Figure element.
|
||||||
|
*
|
||||||
|
* @param figure the Figure element to visit
|
||||||
|
*/
|
||||||
|
void visit(Figure figure);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -25,46 +25,46 @@ public class BoardManager {
|
|||||||
private static List<Field> createBoard() {
|
private static List<Field> createBoard() {
|
||||||
ArrayList<Field> fields = new ArrayList<>();
|
ArrayList<Field> fields = new ArrayList<>();
|
||||||
|
|
||||||
fields.addLast(new GoField());
|
fields.add(new GoField());
|
||||||
fields.addLast(new BuildingProperty("Gym", 1, 600, 20));
|
fields.add(new BuildingProperty("Gym", 1, 600, 20));
|
||||||
fields.addLast(new EventField("Hausfeier", 2));
|
fields.add(new EventField("Hausfeier", 2));
|
||||||
fields.addLast(new BuildingProperty("Sportplatz", 3, 600, 40));
|
fields.add(new BuildingProperty("Sportplatz", 3, 600, 40));
|
||||||
fields.addLast(new FineField("Diszi", 4, 2000));
|
fields.add(new FineField("Diszi", 4, 2000));
|
||||||
fields.addLast(new GateField("Südtor", 5));
|
fields.add(new GateField("Südtor", 5));
|
||||||
fields.addLast(new BuildingProperty("Studium+", 6, 1000, 60));
|
fields.add(new BuildingProperty("Studium+", 6, 1000, 60));
|
||||||
fields.addLast(new EventField("Üvas", 7));
|
fields.add(new EventField("Üvas", 7));
|
||||||
fields.addLast(new BuildingProperty("PhysikHörsaal", 8, 1000, 60));
|
fields.add(new BuildingProperty("PhysikHörsaal", 8, 1000, 60));
|
||||||
fields.addLast(new BuildingProperty("Audimax", 9, 1200, 80));
|
fields.add(new BuildingProperty("Audimax", 9, 1200, 80));
|
||||||
fields.addLast(new GulagField());
|
fields.add(new GulagField());
|
||||||
fields.addLast(new BuildingProperty("99er", 11, 1400, 100));
|
fields.add(new BuildingProperty("99er", 11, 1400, 100));
|
||||||
fields.addLast(new FoodField("Brandl", 12));
|
fields.add(new FoodField("Brandl", 12));
|
||||||
fields.addLast(new BuildingProperty("12er", 13, 1400, 100));
|
fields.add(new BuildingProperty("12er", 13, 1400, 100));
|
||||||
fields.addLast(new BuildingProperty("23er", 14, 1600, 120));
|
fields.add(new BuildingProperty("23er", 14, 1600, 120));
|
||||||
fields.addLast(new GateField("HauptWache", 15));
|
fields.add(new GateField("HauptWache", 15));
|
||||||
fields.addLast(new BuildingProperty("Schwimmhalle", 16, 1800, 140));
|
fields.add(new BuildingProperty("Schwimmhalle", 16, 1800, 140));
|
||||||
fields.addLast(new BuildingProperty("CISM-Bahn", 17, 1800, 140));
|
fields.add(new BuildingProperty("CISM-Bahn", 17, 1800, 140));
|
||||||
fields.addLast(new EventField("Marine-Welcome-Party", 18));
|
fields.add(new EventField("Marine-Welcome-Party", 18));
|
||||||
fields.addLast(new BuildingProperty("Kletterturm", 19, 2000, 160));
|
fields.add(new BuildingProperty("Kletterturm", 19, 2000, 160));
|
||||||
fields.addLast(new TestStreckeField());
|
fields.add(new TestStreckeField());
|
||||||
fields.addLast(new BuildingProperty("StudFBer C", 21, 2200, 180));
|
fields.add(new BuildingProperty("StudFBer C", 21, 2200, 180));
|
||||||
fields.addLast(new EventField("Üvas", 22));
|
fields.add(new EventField("Üvas", 22));
|
||||||
fields.addLast(new BuildingProperty("StudFBer B", 23, 2200, 180));
|
fields.add(new BuildingProperty("StudFBer B", 23, 2200, 180));
|
||||||
fields.addLast(new BuildingProperty("StudFBer A", 24, 2400, 200));
|
fields.add(new BuildingProperty("StudFBer A", 24, 2400, 200));
|
||||||
fields.addLast(new GateField("Nordtor", 25));
|
fields.add(new GateField("Nordtor", 25));
|
||||||
fields.addLast(new BuildingProperty("Cascada", 26, 2600, 220));
|
fields.add(new BuildingProperty("Cascada", 26, 2600, 220));
|
||||||
fields.addLast(new BuildingProperty("Fakultätsgebäude", 27, 2600, 220));
|
fields.add(new BuildingProperty("Fakultätsgebäude", 27, 2600, 220));
|
||||||
fields.addLast(new FoodField("Truppenküche", 28));
|
fields.add(new FoodField("Truppenküche", 28));
|
||||||
fields.addLast(new BuildingProperty("Prüfungsamt", 29, 2800, 240));
|
fields.add(new BuildingProperty("Prüfungsamt", 29, 2800, 240));
|
||||||
fields.addLast(new WacheField());
|
fields.add(new WacheField());
|
||||||
fields.addLast(new BuildingProperty("Feuerwehr", 31, 3000, 260));
|
fields.add(new BuildingProperty("Feuerwehr", 31, 3000, 260));
|
||||||
fields.addLast(new BuildingProperty("SanZ", 32, 300, 260));
|
fields.add(new BuildingProperty("SanZ", 32, 300, 260));
|
||||||
fields.addLast(new EventField("Maibock", 33));
|
fields.add(new EventField("Maibock", 33));
|
||||||
fields.addLast(new BuildingProperty("Rechenzentrum", 34, 3200, 280));
|
fields.add(new BuildingProperty("Rechenzentrum", 34, 3200, 280));
|
||||||
fields.addLast(new GateField("Osttor", 35));
|
fields.add(new GateField("Osttor", 35));
|
||||||
fields.addLast(new EventField("Üvas", 36));
|
fields.add(new EventField("Üvas", 36));
|
||||||
fields.addLast(new BuildingProperty("2er", 37, 3500, 350));
|
fields.add(new BuildingProperty("2er", 37, 3500, 350));
|
||||||
fields.addLast(new FineField("EZM", 38, 1000));
|
fields.add(new FineField("EZM", 38, 1000));
|
||||||
fields.addLast(new BuildingProperty("20er", 39, 4000, 500));
|
fields.add(new BuildingProperty("20er", 39, 4000, 500));
|
||||||
|
|
||||||
return fields;
|
return fields;
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,61 @@
|
|||||||
package pp.monopoly.notification;
|
package pp.monopoly.notification;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enumeration representing different types of sounds used in the game.
|
* Enum representing various sound effects in the game.
|
||||||
*/
|
*/
|
||||||
public enum Sound {
|
public enum Sound {
|
||||||
CLICK("click_sound.wav"),
|
/**
|
||||||
WIN("win_sound.wav"),
|
* UC-sound-01: Sound effect for passing the start/Los field.
|
||||||
LOSE("lose_sound.wav");
|
*/
|
||||||
|
PASS_START,
|
||||||
|
|
||||||
private final String fileName;
|
/**
|
||||||
|
* UC-sound-02: Sound effect for drawing an event card.
|
||||||
|
*/
|
||||||
|
EVENT_CARD,
|
||||||
|
|
||||||
Sound(String fileName) {
|
/**
|
||||||
this.fileName = fileName;
|
* UC-sound-03: Sound effect for entering the Gulag.
|
||||||
}
|
*/
|
||||||
|
GULAG,
|
||||||
|
|
||||||
public String getFileName() {
|
/**
|
||||||
return fileName;
|
* UC-sound-04: Sound effect for rolling the dice.
|
||||||
}
|
*/
|
||||||
|
DICE_ROLL,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UC-sound-05: Sound effect for collecting money.
|
||||||
|
*/
|
||||||
|
MONEY_COLLECTED,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UC-sound-06: Sound effect for losing money.
|
||||||
|
*/
|
||||||
|
MONEY_LOST,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UC-sound-07: Sound effect for accepting a trade offer.
|
||||||
|
*/
|
||||||
|
TRADE_ACCEPTED,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UC-sound-08: Sound effect for rejecting a trade offer.
|
||||||
|
*/
|
||||||
|
TRADE_REJECTED,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UC-sound-09: Sound effect for winning the game.
|
||||||
|
*/
|
||||||
|
WINNER,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UC-sound-10: Sound effect for losing the game.
|
||||||
|
*/
|
||||||
|
LOSER,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UC-sound-11: Sound effect for button click.
|
||||||
|
*/
|
||||||
|
BUTTON;
|
||||||
}
|
}
|
@ -1,25 +1,26 @@
|
|||||||
|
////////////////////////////////////////
|
||||||
|
// Programming project code
|
||||||
|
// UniBw M, 2022, 2023, 2024
|
||||||
|
// www.unibw.de/inf2
|
||||||
|
// (c) Mark Minas (mark.minas@unibw.de)
|
||||||
|
////////////////////////////////////////
|
||||||
|
|
||||||
package pp.monopoly.notification;
|
package pp.monopoly.notification;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event when a sound needs to be played.
|
* Event when an item is added to a map.
|
||||||
*
|
*
|
||||||
* @param soundFileName the sound file to be played
|
* @param sound the sound to be played
|
||||||
*/
|
*/
|
||||||
public class SoundEvent implements GameEvent {
|
public record SoundEvent(Sound sound) implements GameEvent {
|
||||||
private final String soundFileName;
|
|
||||||
|
|
||||||
public SoundEvent(Sound sound) {
|
|
||||||
this.soundFileName = sound.getFileName(); // Angenommen, Sound hat eine Methode getFileName()
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSoundFileName() {
|
|
||||||
return soundFileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notifies the game event listener of this event.
|
||||||
|
*
|
||||||
|
* @param listener the game event listener
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void notifyListener(GameEventListener listener) {
|
public void notifyListener(GameEventListener listener) {
|
||||||
listener.receivedEvent(this);
|
listener.receivedEvent(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user