3 Commits

Author SHA1 Message Date
Johannes Schmelz
249110f83c Merge remote-tracking branch 'origin/gui' 2024-12-09 14:13:44 +01:00
Johannes Schmelz
a686671c15 Merge branch 'reworkedGui' into 'main'
refactor Worlds and client States

See merge request progproj/gruppen-ht24/Gruppe-02!18
2024-12-08 01:18:35 +00:00
Johannes Schmelz
e102d22f14 refactor Worlds and client States 2024-12-08 01:18:35 +00:00
80 changed files with 1041 additions and 1479 deletions

View File

@@ -19,8 +19,6 @@ import java.util.Deque;
import static java.lang.Math.max; import static java.lang.Math.max;
import java.lang.System.Logger;
/** /**
* Manages dialog boxes within the application, handling their display, positioning, and focus. * Manages dialog boxes within the application, handling their display, positioning, and focus.
*/ */
@@ -30,15 +28,11 @@ public class DialogManager {
*/ */
private final SimpleApplication app; private final SimpleApplication app;
private final static Logger LOGGER = System.getLogger(DialogManager.class.getName());
/** /**
* A stack to keep track of the dialogs. * A stack to keep track of the dialogs.
*/ */
private final Deque<Dialog> dialogStack = new ArrayDeque<>(); private final Deque<Dialog> dialogStack = new ArrayDeque<>();
private final Deque<PopupDialog> popUpStack = new ArrayDeque<>();
/** /**
* Constructs a DialogManager for the specified application. * Constructs a DialogManager for the specified application.
* *
@@ -118,45 +112,11 @@ public class DialogManager {
* @param dialog the dialog to open * @param dialog the dialog to open
*/ */
public void open(Dialog dialog) { public void open(Dialog dialog) {
if(dialog instanceof PopupDialog) {
popUpStack.push((PopupDialog) dialog);
processPopUps();
} else {
showDialog(dialog);
}
}
private void showDialog(Dialog dialog) {
dialogStack.push(dialog); dialogStack.push(dialog);
if(dialog instanceof PopupDialog) {
((PopupDialog)dialog).show();
}
dialog.update(); dialog.update();
app.getGuiNode().attachChild(dialog); app.getGuiNode().attachChild(dialog);
} }
private void processPopUps() {
if (popUpStack.isEmpty()) {
return; // Nothing to process
}
// Check if a popup dialog is already on top
if (dialogStack.peek() instanceof PopupDialog) {
LOGGER.log(Logger.Level.DEBUG, "Popup dialog already on top");
return; // Already a popup dialog on top
} else {
// Pop the next popup from the stack and validate before showing
PopupDialog popUp = popUpStack.pop();
showDialog( (Dialog) popUp);
}
}
/** /**
* Checks if the specified dialog is the topmost dialog in the dialog stack. * Checks if the specified dialog is the topmost dialog in the dialog stack.
* *
@@ -180,8 +140,6 @@ public class DialogManager {
if (!dialogStack.isEmpty()) if (!dialogStack.isEmpty())
dialogStack.peek().update(); dialogStack.peek().update();
app.getGuiNode().detachChild(dialog); app.getGuiNode().detachChild(dialog);
processPopUps();
} }
/** /**

View File

@@ -1,5 +0,0 @@
package pp.dialog;
public interface PopupDialog {
void show();
}

View File

@@ -405,44 +405,3 @@ selector("button-clear", "pp") { playerColor ->
textHAlignment = HAlignment.Center // Text-Zentrierung textHAlignment = HAlignment.Center // Text-Zentrierung
textVAlignment = VAlignment.Center // Text-Zentrierung textVAlignment = VAlignment.Center // Text-Zentrierung
} }
def enabledCommandToolbar2= new Command<Button>() {
void execute(Button source) {
if (source.isEnabled()){
source.setColor(ColorRGBA.White)
def orangeBackground = new QuadBackgroundComponent(color(1, 0.5, 0, 1)); // Orange background
source.setBackground(orangeBackground);
} else{
source.setColor(ColorRGBA.White)
def grayBackground = new QuadBackgroundComponent(ColorRGBA.Gray); // Gray background
source.setBackground(grayBackground);
}
}
}
def stdButtonCommandsToolbar2 =[
(ButtonAction.Down) : [pressedCommand],
(ButtonAction.Up) : [pressedCommand],
(ButtonAction.Enabled) : [enabledCommandToolbar2],
(ButtonAction.Disabled): [enabledCommandToolbar2]
]
selector("button-toolbar2", "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
textHAlignment = HAlignment.Center
textVAlignment = VAlignment.Center
buttonCommands = stdButtonCommandsToolbar2
}

View File

@@ -3,35 +3,33 @@ package pp.monopoly.client;
import com.jme3.app.Application; import com.jme3.app.Application;
import com.jme3.app.state.AppStateManager; import com.jme3.app.state.AppStateManager;
import com.jme3.asset.AssetManager; import com.jme3.asset.AssetManager;
import com.jme3.effect.ParticleEmitter;
import com.jme3.effect.ParticleMesh;
import com.jme3.effect.shapes.EmitterSphereShape;
import com.jme3.light.AmbientLight; import com.jme3.light.AmbientLight;
import com.jme3.light.DirectionalLight; import com.jme3.light.DirectionalLight;
import com.jme3.material.Material; import com.jme3.material.Material;
import com.jme3.material.RenderState.FaceCullMode;
import com.jme3.math.ColorRGBA; import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath; import com.jme3.math.FastMath;
import com.jme3.math.Quaternion; import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f; import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue; import com.jme3.renderer.Camera;
import com.jme3.renderer.queue.RenderQueue.ShadowMode; import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.scene.Geometry; import com.jme3.scene.Geometry;
import com.jme3.scene.Node; import com.jme3.scene.Node;
import com.jme3.scene.Spatial; import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box; import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Cylinder;
import com.jme3.shadow.DirectionalLightShadowRenderer; import com.jme3.shadow.DirectionalLightShadowRenderer;
import com.jme3.shadow.EdgeFilteringMode; import com.jme3.shadow.EdgeFilteringMode;
import com.jme3.texture.Texture; import com.jme3.texture.Texture;
import com.jme3.util.SkyFactory;
import com.jme3.util.TangentBinormalGenerator; import com.jme3.util.TangentBinormalGenerator;
import pp.monopoly.client.gui.BobTheBuilder; import pp.monopoly.client.gui.BobTheBuilder;
import pp.monopoly.client.gui.CameraController;
import pp.monopoly.client.gui.CameraInputHandler;
import pp.monopoly.client.gui.Toolbar; import pp.monopoly.client.gui.Toolbar;
import pp.monopoly.model.Board; import pp.monopoly.model.Board;
import pp.monopoly.client.gui.FigureControl;
import static pp.util.FloatMath.TWO_PI;
import static pp.util.FloatMath.cos;
import static pp.util.FloatMath.sin;
import static pp.util.FloatMath.sqrt;
/** /**
* Manages the rendering and visual aspects of the sea and sky in the Battleship game. * Manages the rendering and visual aspects of the sea and sky in the Battleship game.
@@ -43,7 +41,6 @@ public class BoardAppState extends MonopolyAppState {
* The path to the unshaded texture material. * The path to the unshaded texture material.
*/ */
private static final String UNSHADED = "Common/MatDefs/Misc/Unshaded.j3md"; //NON-NLS private static final String UNSHADED = "Common/MatDefs/Misc/Unshaded.j3md"; //NON-NLS
private static final String LIGHTING = "Common/MatDefs/Light/Lighting.j3md";
/** /**
* The path to the sea texture material. * The path to the sea texture material.
@@ -68,12 +65,9 @@ public class BoardAppState extends MonopolyAppState {
/** /**
* The pop-up manager for displaying messages and notifications. * The pop-up manager for displaying messages and notifications.
*/ */
private PopUpManager popUpManager; private PopUpManager popUpManager;;
private CameraController cameraController;
private CameraInputHandler cameraInputHandler;
private Vector3f currentTarget = new Vector3f(0f,0,0f);
/** /**
* Initializes the state by setting up the sky, lights, and other visual components. * Initializes the state by setting up the sky, lights, and other visual components.
@@ -85,19 +79,10 @@ public class BoardAppState extends MonopolyAppState {
@Override @Override
public void initialize(AppStateManager stateManager, Application application) { public void initialize(AppStateManager stateManager, Application application) {
super.initialize(stateManager, application); super.initialize(stateManager, application);
// Initialisiere den CameraController zuerst
cameraController = new CameraController(getApp().getCamera(), getApp());
// Danach den CameraInputHandler mit dem initialisierten CameraController
cameraInputHandler = new CameraInputHandler(cameraController, getApp().getInputManager());
popUpManager = new PopUpManager(getApp()); popUpManager = new PopUpManager(getApp());
viewNode.attachChild(sceneNode); viewNode.attachChild(sceneNode);
setupLights(); setupLights();
// setupSky(); setupSky();
getApp().getViewPort().setBackgroundColor(new com.jme3.math.ColorRGBA(0.5f, 0.7f, 1.0f, 1.0f));
} }
/** /**
@@ -109,8 +94,6 @@ public class BoardAppState extends MonopolyAppState {
getApp().getRootNode().detachAllChildren(); getApp().getRootNode().detachAllChildren();
getApp().getGuiNode().detachAllChildren(); getApp().getGuiNode().detachAllChildren();
getApp().getDialogManager().close(getApp().getDialogManager().getDialogStack().peek());
new Toolbar(getApp()).open(); new Toolbar(getApp()).open();
sceneNode.detachAllChildren(); sceneNode.detachAllChildren();
setupScene(); setupScene();
@@ -120,6 +103,30 @@ public class BoardAppState extends MonopolyAppState {
} }
getApp().getRootNode().attachChild(viewNode); getApp().getRootNode().attachChild(viewNode);
} }
//TODO remove this only for camera testing
private static final float ABOVE_SEA_LEVEL = 10f;
private static final float INCLINATION = 2.5f;
private float cameraAngle;
/**
* Adjusts the camera position and orientation to create a circular motion around
* the center of the map. This provides a dynamic view of the sea and surrounding environment.
*/
private void adjustCamera() {
final Board board = getGameLogic().getBoard();
final float mx = 0.5f * board.getWidth();
final float my = 0.5f * board.getHeight();
final float radius = 2f * sqrt(mx * mx + my + my);
final float cos = radius * cos(cameraAngle);
final float sin = radius * sin(cameraAngle);
final float x = mx - cos;
final float y = my - sin;
final Camera camera = getApp().getCamera();
camera.setLocation(new Vector3f(30,20,0));
camera.lookAt(new Vector3f(getCurrentTarget()),
Vector3f.UNIT_Y);
camera.update();
}
@@ -136,7 +143,18 @@ public class BoardAppState extends MonopolyAppState {
} }
} }
/**
* Updates the state each frame, moving the camera to simulate it circling around the map.
*
* @param tpf the time per frame (seconds)
*/
@Override
public void update(float tpf) {
super.update(tpf);
//TODO remove this only for camera testing
cameraAngle += TWO_PI * 0.05f * tpf;
adjustCamera();
}
/** /**
* Sets up the lighting for the scene, including directional and ambient lights. * Sets up the lighting for the scene, including directional and ambient lights.
@@ -155,8 +173,7 @@ public class BoardAppState extends MonopolyAppState {
viewNode.addLight(sun); viewNode.addLight(sun);
shRend.setLight(sun); shRend.setLight(sun);
final AmbientLight ambientLight = new AmbientLight(); final AmbientLight ambientLight = new AmbientLight(new ColorRGBA(1f, 1f, 1f, 1f));
// ambientLight.setColor(ColorRGBA.White.mult(0.f)); // brightness
viewNode.addLight(ambientLight); viewNode.addLight(ambientLight);
} }
@@ -166,79 +183,17 @@ public class BoardAppState extends MonopolyAppState {
*/ */
private void setupSky() { private void setupSky() {
final AssetManager assetManager = getApp().getAssetManager(); final AssetManager assetManager = getApp().getAssetManager();
final Texture west = assetManager.loadTexture("Pictures/Backdrop/west.jpg"); //NON-NLS
// Create a cylinder for the sky final Texture east = assetManager.loadTexture("Pictures/Backdrop/ost.jpg"); //NON-NLS
float radius = 500f; // Adjust radius as needed final Texture north = assetManager.loadTexture("Pictures/Backdrop/nord.jpg"); //NON-NLS
float height = 200f; // Height of the cylinder final Texture south = assetManager.loadTexture("Pictures/Backdrop/sued.jpg"); //NON-NLS
int radialSamples = 64; // Number of radial segments for smoothness final Texture up = assetManager.loadTexture("Pictures/Backdrop/sued.jpg"); //NON-NLS
int axisSamples = 2; // No vertical divisions (flat vertical surface) final Texture down = assetManager.loadTexture("Pictures/Backdrop/sued.jpg"); //NON-NLS
final Spatial sky = SkyFactory.createSky(assetManager, west, east, north, south, up, down);
Cylinder skyCylinder = new Cylinder(axisSamples, radialSamples, radius, height, true); // sky.rotate(0, PI, 0);
viewNode.attachChild(sky);
// Create a geometry for the cylinder
Geometry skyGeometry = new Geometry("CylinderSky", skyCylinder);
// Load the cylindrical texture
Texture cylinderTexture = assetManager.loadTexture("Textures/CylinderMap.jpg");
// Create a material and apply the texture
Material skyMaterial = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
skyMaterial.setTexture("ColorMap", cylinderTexture);
skyMaterial.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off); // Render inside of the cylinder
// Assign material to the geometry
skyGeometry.setMaterial(skyMaterial);
skyGeometry.rotate(-FastMath.HALF_PI, 0, 0); // Rotate 90° along the Y-axis
// Position and attach the cylinder to the scene
skyGeometry.setQueueBucket(RenderQueue.Bucket.Sky); // Ensure it's rendered in the background
skyGeometry.setCullHint(Spatial.CullHint.Never); // Always render the sky
viewNode.attachChild(skyGeometry);
addCylinderCaps();
} }
/**
* Adds top and bottom caps to the cylinder sky.
*/
private void addCylinderCaps() {
final AssetManager assetManager = getApp().getAssetManager();
float radius = 500f; // Match the cylinder's radius
float height = 225f; // Match the cylinder's height
int radialSamples = 64; // Match the cylinder's radial samples
// Bottom Cap
Cylinder bottomCap = new Cylinder(2, radialSamples, radius, 0.01f, true, false); // Thin bottom cap
Geometry bottomGeometry = new Geometry("BottomCap", bottomCap);
bottomGeometry.setLocalTranslation(0, -height / 2, 0); // Position at the bottom
bottomGeometry.rotate(FastMath.HALF_PI, 0, 0); // Rotate to make it horizontal
Material bottomMaterial = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
bottomMaterial.setTexture("ColorMap", assetManager.loadTexture("Textures/grass.jpg")); // Bottom texture
bottomMaterial.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off); // Render both sides
bottomGeometry.setMaterial(bottomMaterial);
bottomGeometry.setQueueBucket(RenderQueue.Bucket.Sky);
bottomGeometry.setCullHint(Spatial.CullHint.Never);
// Top Cap
Cylinder topCap = new Cylinder(2, radialSamples, radius, 0.01f, true, false); // Thin top cap
Geometry topGeometry = new Geometry("TopCap", topCap);
topGeometry.setLocalTranslation(0, height / 2, 0); // Position at the top
topGeometry.rotate(FastMath.HALF_PI, 0, 0); // Rotate to make it horizontal
Material topMaterial = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
topMaterial.setTexture("ColorMap", assetManager.loadTexture("Textures/Top.png")); // Top texture
topMaterial.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off); // Render both sides
topGeometry.setMaterial(topMaterial);
topGeometry.setQueueBucket(RenderQueue.Bucket.Sky);
topGeometry.setCullHint(Spatial.CullHint.Never);
// Attach caps to the view node
viewNode.attachChild(bottomGeometry);
viewNode.attachChild(topGeometry);
}
/** /**
* Sets up the sea surface in the scene. This includes creating the sea mesh, * Sets up the sea surface in the scene. This includes creating the sea mesh,
* applying textures, and enabling shadows. * applying textures, and enabling shadows.
@@ -248,107 +203,39 @@ public class BoardAppState extends MonopolyAppState {
final float x = board.getWidth(); final float x = board.getWidth();
final float y = board.getHeight(); final float y = board.getHeight();
final Box seaMesh = new Box(y, 0.1f, x); final Box seaMesh = new Box(y, 0.1f, x);
final Geometry seaGeo = new Geometry("sea", seaMesh); //NON-NLS final Geometry seaGeo = new Geometry("sea", seaMesh); //NONs-NLS
seaGeo.setLocalTranslation(new Vector3f(0, -0.1f, 0)); seaGeo.setLocalTranslation(new Vector3f(0, -0.1f, 0));
Quaternion rotation = new Quaternion(); Quaternion rotation = new com.jme3.math.Quaternion();
rotation.fromAngleAxis(FastMath.HALF_PI, Vector3f.UNIT_Y); rotation.fromAngleAxis(FastMath.HALF_PI, com.jme3.math.Vector3f.UNIT_Y);
seaGeo.setLocalRotation(rotation); seaGeo.setLocalRotation(rotation);
final Material seaMat = new Material(getApp().getAssetManager(), "Common/MatDefs/Light/Lighting.j3md"); final Material seaMat = new Material(getApp().getAssetManager(), "Common/MatDefs/Light/Lighting.j3md");
Texture texture = getApp().getAssetManager().loadTexture("Pictures/board2.png"); Texture texture = getApp().getAssetManager().loadTexture("Pictures/board2.png");
texture.setMagFilter(Texture.MagFilter.Bilinear);
texture.setMinFilter(Texture.MinFilter.Trilinear);
seaMat.setTexture("DiffuseMap", texture); seaMat.setTexture("DiffuseMap", texture);
// Add specular highlights
// seaMat.setBoolean("UseMaterialColors", true);
seaMat.setColor("Diffuse", ColorRGBA.White);
seaMat.setColor("Specular", ColorRGBA.White);
// seaMat.setFloat("Shininess", 16f);
seaGeo.setMaterial(seaMat); seaGeo.setMaterial(seaMat);
seaGeo.setShadowMode(ShadowMode.CastAndReceive); seaGeo.setShadowMode(ShadowMode.CastAndReceive);
TangentBinormalGenerator.generate(seaGeo); TangentBinormalGenerator.generate(seaGeo);
sceneNode.attachChild(createCardDeck()); sceneNode.attachChild(createCardDeck());
sceneNode.attachChild(seaGeo); sceneNode.attachChild(seaGeo);
// Schneefall hinzufügen
// addSnowEffect(sceneNode);
} }
private Node createCardDeck() { private Node createCardDeck() {
Node cardDeck = new Node("cardDeck"); Node cardDeck = new Node("cardDeck");
Spatial card = getApp().getAssetManager().loadModel("models/Kartendecks/Ereigniskarten_Deck.j3o");
// Ereigniskarten card.setLocalTranslation(5.5f, 0, 2.7f);
Vector3f basePosition1 = new Vector3f(3.1f, 0.4f, 3.8f); // Basisposition für Ereigniskarten card.setLocalScale(4.1f);
float baseRotation1 = -60; // Basisrotation in Grad card.setLocalRotation(new Quaternion().fromAngleAxis(FastMath.QUARTER_PI, Vector3f.UNIT_Y));
for (int i = 0; i < 6; i++) {
Box box = new Box(1.2f, 0.05f, 1.8f); // Sehr flaches Rechteck Spatial card2 = getApp().getAssetManager().loadModel("models/Kartendecks/Gemeinschaftskarten_Deck.j3o");
Geometry flatCard = new Geometry("Ereigniskarten_" + i, box); card2.setLocalTranslation(-1.4f, 0, -3.8f);
Material mat = new Material(getApp().getAssetManager(), UNSHADED); card2.setLocalScale(4.1f);
mat.setTexture("ColorMap", getApp().getAssetManager().loadTexture("Textures/Ereigniskarten.png")); card2.setLocalRotation(new Quaternion().fromAngleAxis(FastMath.QUARTER_PI , Vector3f.UNIT_Y));
flatCard.setMaterial(mat);
cardDeck.attachChild(card);
// Position und Rotation für die Karte cardDeck.attachChild(card2);
flatCard.setLocalTranslation(basePosition1.x, basePosition1.y - (i * 0.08f), basePosition1.z);
flatCard.setLocalRotation(new Quaternion().fromAngleAxis(FastMath.DEG_TO_RAD * (baseRotation1 - (i * 5)), Vector3f.UNIT_Y));
cardDeck.attachChild(flatCard);
}
// Gemeinschaftskarten
Vector3f basePosition2 = new Vector3f(-3.3f, 0.4f, -3.8f); // Basisposition für Gemeinschaftskarten
float baseRotation2 = -220; // Basisrotation in Grad
for (int i = 0; i < 6; i++) {
Box box = new Box(1.2f, 0.04f, 1.8f); // Sehr flaches Rechteck
Geometry flatCard = new Geometry("Gemeinschaftskarten_" + i, box);
Material mat = new Material(getApp().getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
mat.setTexture("ColorMap", getApp().getAssetManager().loadTexture("Textures/Gemeinschaftskarten.png"));
flatCard.setMaterial(mat);
// Position und Rotation für die Karte
flatCard.setLocalTranslation(basePosition2.x, basePosition2.y - (i * 0.08f), basePosition2.z);
flatCard.setLocalRotation(new Quaternion().fromAngleAxis(FastMath.DEG_TO_RAD * (baseRotation2 - (i * 5)), Vector3f.UNIT_Y));
cardDeck.attachChild(flatCard);
}
return cardDeck; return cardDeck;
} }
private void addSnowEffect(Node parentNode) { public Vector3f getCurrentTarget(){
// ParticleEmitter für Schnee return currentTarget;
ParticleEmitter snowEmitter = new ParticleEmitter("Snow", ParticleMesh.Type.Triangle, 5000); }
Material snowMat = new Material(getApp().getAssetManager(), "Common/MatDefs/Misc/Particle.j3md");
snowMat.setTexture("Texture", getApp().getAssetManager().loadTexture("Textures/snowflake.png")); // Schneeflocken-Textur
snowEmitter.setMaterial(snowMat);
// Eigenschaften für Schneepartikel
snowEmitter.setImagesX(1);
snowEmitter.setImagesY(1);
snowEmitter.setEndColor(new ColorRGBA(1f, 1f, 1f, 0.5f)); // Weiß, halbtransparent
snowEmitter.setStartColor(new ColorRGBA(1f, 1f, 1f, 1f)); // Vollweiß
snowEmitter.setStartSize(0.1f);
snowEmitter.setEndSize(0.2f);
snowEmitter.setGravity(0, 0.5f, 0); // Langsames Fallen
snowEmitter.setLowLife(3f);
snowEmitter.setHighLife(15f);
snowEmitter.getParticleInfluencer().setInitialVelocity(new Vector3f(0, -1, 0));
snowEmitter.getParticleInfluencer().setVelocityVariation(0.3f);
// Spawn-Bereich für Schneeflocken definieren
snowEmitter.setParticlesPerSec(200);
snowEmitter.setLocalTranslation(0, 10, 0);
snowEmitter.setShape(new EmitterSphereShape(new Vector3f(0, 0, 0), 15)); // Bereich von -15 bis 15
// Emitter zur Szene hinzufügen
parentNode.attachChild(snowEmitter);
}
@Override
public void update(float tpf) {
super.update(tpf);
cameraController.update(tpf);
}
} }

View File

@@ -173,13 +173,9 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
final AppSettings settings = new AppSettings(true); final AppSettings settings = new AppSettings(true);
settings.setTitle(lookup("monopoly.name")); settings.setTitle(lookup("monopoly.name"));
try { try {
// Prüfen, ob das Betriebssystem ein Mac-System ist settings.setIcons(new Image[]{ImageIO.read(new File("src/main/resources/icons/Uniman.png"))});
if (!System.getProperty("os.name").toLowerCase().contains("mac")) { }
settings.setIcons(new Image[]{ImageIO.read(new File("src/main/resources/icons/Uniman.png"))}); catch (IOException e) {
} else {
LOGGER.log(Level.INFO, "Icon setting skipped on macOS due to system restrictions.");
}
} catch (IOException e) {
LOGGER.log(Level.ERROR, e.getMessage()); LOGGER.log(Level.ERROR, e.getMessage());
} }
settings.setResolution(config.getResolutionWidth(), config.getResolutionHeight()); settings.setResolution(config.getResolutionWidth(), config.getResolutionHeight());
@@ -293,8 +289,6 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
stateManager.attach(stats); stateManager.attach(stats);
} }
flyCam.setEnabled(false); flyCam.setEnabled(false);
flyCam.setMoveSpeed(4f); // Setzt die Bewegungsgeschwindigkeit der Kamera (Standardwert ist 1f)
stateManager.detach(stateManager.getState(StatsAppState.class)); stateManager.detach(stateManager.getState(StatsAppState.class));
stateManager.detach(stateManager.getState(DebugKeysAppState.class)); stateManager.detach(stateManager.getState(DebugKeysAppState.class));

View File

@@ -106,26 +106,6 @@ public class MonopolyAppConfig extends MonopolyClientConfig {
@Property("overlay.top.color") //NON-NLS @Property("overlay.top.color") //NON-NLS
private ColorRGBA topColor = ColorRGBA.White; private ColorRGBA topColor = ColorRGBA.White;
private ColorRGBA applyGammaCorrection(ColorRGBA color) {
return new ColorRGBA(
correctGamma(color.r),
correctGamma(color.g),
correctGamma(color.b),
color.a // Alpha bleibt unverändert
);
}
private float correctGamma(float channel) {
// Formel: ((RGB / 255)^2.2) * 255
float normalized = channel / 255.0f; // RGB normalisieren (0-1)
float gammaCorrected = (float) Math.pow(normalized, 2.2); // ^2.2
return gammaCorrected * 255.0f; // Zurückskalieren auf 0-255
}
private float correctGamma(float channel, float gamma) {
return (float) Math.pow(channel, gamma);
}
/** /**
* Creates a default {@code MonopolyAppConfig} with predefined values. * Creates a default {@code MonopolyAppConfig} with predefined values.
*/ */

View File

@@ -56,7 +56,7 @@ public class PopUpManager implements GameEventListener {
} }
}); });
} }
}, 8000); }, 2500);
} else if (event.msg().equals("Winner")) { } else if (event.msg().equals("Winner")) {
new WinnerPopUp(app).open(); new WinnerPopUp(app).open();
} else if (event.msg().equals("Looser")) { } else if (event.msg().equals("Looser")) {

View File

@@ -3,9 +3,6 @@ package pp.monopoly.client.gui;
import com.jme3.material.Material; import com.jme3.material.Material;
import com.jme3.material.RenderState.BlendMode; import com.jme3.material.RenderState.BlendMode;
import com.jme3.math.ColorRGBA; import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue.ShadowMode; import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.scene.Geometry; import com.jme3.scene.Geometry;
import com.jme3.scene.Node; import com.jme3.scene.Node;
@@ -45,10 +42,8 @@ public class BobTheBuilder extends GameBoardSynchronizer {
// Setze die Position basierend auf der Feld-ID // Setze die Position basierend auf der Feld-ID
node.setLocalTranslation(figure.getPos()); node.setLocalTranslation(figure.getPos());
// Setze die Anfangsrotation auf 90 Grad nach links // Setze die Rotation basierend auf der Feld-ID
Quaternion initialRotation = new Quaternion().fromAngleAxis(FastMath.HALF_PI, Vector3f.UNIT_Y); node.setLocalRotation(figure.getRot().toQuaternion());
node.setLocalRotation(initialRotation);
node.addControl(new FigureControl(node, figure, app)); node.addControl(new FigureControl(node, figure, app));
return node; return node;
} }
@@ -86,7 +81,7 @@ public class BobTheBuilder extends GameBoardSynchronizer {
private Spatial createFigure(Figure figure) { private Spatial createFigure(Figure figure) {
// Lade das Modell // Lade das Modell
Spatial model = app.getAssetManager().loadModel("models/" + "Spielfiguren/" + figure.getType() + "/" + figure.getType() + ".j3o"); Spatial model = app.getAssetManager().loadModel("models/" + "Spielfiguren/" + figure.getType() + "/" + figure.getType() + ".j3o");
// Skaliere und positioniere das Modell // Skaliere und positioniere das Modell
model.scale(0.5f); model.scale(0.5f);

View File

@@ -3,106 +3,64 @@ package pp.monopoly.client.gui;
import com.jme3.math.Vector3f; import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera; import com.jme3.renderer.Camera;
import pp.monopoly.client.MonopolyApp; // Import MonopolyApp /**
import pp.monopoly.game.server.PlayerHandler; * Controls the movement of the camera within the scene.
import pp.monopoly.notification.GameEventListener; */
import pp.monopoly.notification.UpdatePlayerView; public class CameraController {
public class CameraController implements GameEventListener{
public enum CameraMode {
FOCUS_CURRENT_PLAYER,
FOCUS_SELF,
FREECAM
}
private final Camera camera; private final Camera camera;
private CameraMode currentMode; private final float height = 25; // Height of the camera above the game board
private PlayerHandler playerHandler; // Reference to PlayerHandler for player data /**
private final MonopolyApp app; // Reference to MonopolyApp for self ID * Constructor for the CameraController.
*
public CameraController(Camera camera, MonopolyApp app) { * @param camera The camera to be controlled
*/
public CameraController(Camera camera) {
this.camera = camera; this.camera = camera;
this.playerHandler = app.getGameLogic().getPlayerHandler(); setPosition(0);
this.app = app; camera.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);
app.getGameLogic().addListener(this);
setMode(CameraMode.FOCUS_SELF); // Initialize the camera mode
}
public void setMode(CameraMode mode) {
this.currentMode = mode;
} }
/**
* Updates the camera's position and orientation.
*
* @param tpf Time per frame
*/
public void update(float tpf) { public void update(float tpf) {
camera.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);
switch (currentMode) {
case FOCUS_CURRENT_PLAYER:
updatePosition();
break;
case FOCUS_SELF:
updatePosition();
break;
case FREECAM:
break;
default:
break;
}
} }
public void updatePosition() { /**
Vector3f newPosition = getPos(); * Sets the camera's position based on the field ID.
camera.setLocation(newPosition); *
* @param fieldID The ID of the field to which the camera should move
camera.lookAt(app.getGameLogic().getBoard().getFigure(app.getId()).getPos(), Vector3f.UNIT_Y); */
camera.update(); public void setPosition(int fieldID) {
camera.setLocation(fieldIdToVector(fieldID));
} }
private Vector3f getPos() { /**
Vector3f pos = new Vector3f(); * Sets the camera's position using specific coordinates.
switch (currentMode) { *
case FOCUS_CURRENT_PLAYER: * @param x The X-coordinate of the new camera position
pos = app.getGameLogic().getBoard().getFigure(playerHandler.getPlayerById(0).getId()).getPos(); * @param y The Y-coordinate of the new camera position
*/
case FOCUS_SELF: public void setPosition(float x, float y) {
pos = app.getGameLogic().getBoard().getFigure(app.getId()).getPos(); camera.setLocation(new Vector3f(x, height, y));
case FREECAM:
break;
default:
break;
}
Vector3f offset = getOffset();
pos = new Vector3f(pos.getX() + offset.getX(), pos.getY() + offset.getY(), pos.getZ() + offset.getZ());
return pos;
} }
private Vector3f getOffset() { /**
Vector3f offset = new Vector3f(); * Maps a field ID to its corresponding position in the game world.
*
int fieldId = playerHandler.getPlayerById( (currentMode == CameraMode.FOCUS_SELF ? app.getId() : playerHandler.getPlayerAtIndex(0).getId()) ).getFieldID(); * @param fieldID The ID of the field
// System.out.println(); * @return The position of the field as a {@link Vector3f}
if(fieldId < 10) { * @throws IllegalArgumentException If the field ID is invalid
offset = new Vector3f(0, 10, -15); */
} else if(fieldId < 20) { private Vector3f fieldIdToVector(int fieldID) {
offset = new Vector3f(15 , 10, 0); if (fieldID <= 10) return new Vector3f(30, height, 0);
} else if(fieldId < 30) { if (fieldID <= 20) return new Vector3f(0, height, 30);
offset = new Vector3f(0, 10, 15 ); if (fieldID <= 30) return new Vector3f(-30, height, 0);
} else { if (fieldID <= 40) return new Vector3f(0, height, -30);
offset = new Vector3f(-15, 10, 0); else throw new IllegalArgumentException();
}
return offset;
} }
}
@Override
public void receivedEvent(UpdatePlayerView event) {
playerHandler = app.getGameLogic().getPlayerHandler();
}
}

View File

@@ -1,31 +1,60 @@
package pp.monopoly.client.gui; //package pp.monopoly.client.gui;
//
import com.jme3.input.InputManager; //import com.jme3.input.InputManager;
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;
//
public class CameraInputHandler { ///**
private CameraController cameraController; // * Handhabt die Eingaben für die Kamera.
// */
public CameraInputHandler(CameraController cameraController, InputManager inputManager) { //public class CameraInputHandler {
this.cameraController = cameraController; //
// private CameraController cameraController; // Kamera-Controller
// Tasten für die verschiedenen Kameramodi registrieren //
inputManager.addMapping("FocusCurrentPlayer", new KeyTrigger(KeyInput.KEY_1)); // /**
inputManager.addMapping("FocusSelf", new KeyTrigger(KeyInput.KEY_2)); // * Konstruktor für den CameraInputHandler.
inputManager.addMapping("FreeCam", new KeyTrigger(KeyInput.KEY_3)); // *
// * @param cameraController Der Kamera-Controller, der gesteuert werden soll.
inputManager.addListener(actionListener, "FocusCurrentPlayer", "FocusSelf", "FreeCam"); // * @param inputManager Der InputManager, um Eingaben zu registrieren.
} // */
// public CameraInputHandler(CameraController cameraController, InputManager inputManager) {
private final ActionListener actionListener = (name, isPressed, tpf) -> { // if (cameraController == null || inputManager == null) {
if (!isPressed) return; // throw new IllegalArgumentException("CameraController und InputManager dürfen nicht null sein");
// }
switch (name) { // this.cameraController = cameraController;
case "FocusCurrentPlayer" -> cameraController.setMode(CameraController.CameraMode.FOCUS_CURRENT_PLAYER); //
case "FocusSelf" -> cameraController.setMode(CameraController.CameraMode.FOCUS_SELF); // // Mappings für Kamerasteuerung
case "FreeCam" -> cameraController.setMode(CameraController.CameraMode.FREECAM); // inputManager.addMapping("FocusCurrentPlayer", new KeyTrigger(KeyInput.KEY_1)); // Modus 1
} // inputManager.addMapping("FocusSelf", new KeyTrigger(KeyInput.KEY_2)); // Modus 2
}; // inputManager.addMapping("FreeCam", new KeyTrigger(KeyInput.KEY_3)); // Modus 3
} //
// // Listener für die Kameramodi
// inputManager.addListener(actionListener, "FocusCurrentPlayer", "FocusSelf", "FreeCam");
// }
//
// /**
// * ActionListener für die Kamerasteuerung.
// */
// private final ActionListener actionListener = (name, isPressed, tpf) -> {
// if (!isPressed) return;
//
// // Umschalten der Kamera-Modi basierend auf der Eingabe
// switch (name) {
// case "FocusCurrentPlayer" -> {
// cameraController.setMode(CameraController.CameraMode.FOCUS_CURRENT_PLAYER);
// System.out.println("Kameramodus: Fokus auf aktuellen Spieler");
// }
// case "FocusSelf" -> {
// cameraController.setMode(CameraController.CameraMode.FOCUS_SELF);
// System.out.println("Kameramodus: Fokus auf eigene Figur");
// }
// case "FreeCam" -> {
// cameraController.setMode(CameraController.CameraMode.FREECAM);
// System.out.println("Kameramodus: Freie Kamera");
// }
// default -> System.err.println("Unbekannter Kameramodus: " + name);
// }
// };
//}
//

View File

@@ -1,7 +1,6 @@
package pp.monopoly.client.gui; package pp.monopoly.client.gui;
import com.jme3.math.FastMath; import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f; import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager; import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort; import com.jme3.renderer.ViewPort;
@@ -14,15 +13,15 @@ import pp.monopoly.model.Figure;
import pp.monopoly.notification.GameEventListener; import pp.monopoly.notification.GameEventListener;
import pp.monopoly.notification.UpdatePlayerView; import pp.monopoly.notification.UpdatePlayerView;
// import java.lang.System.Logger; import java.lang.System.Logger;
// import java.lang.System.Logger.Level; import java.lang.System.Logger.Level;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.Queue; import java.util.Queue;
public class FigureControl extends AbstractControl implements GameEventListener { public class FigureControl extends AbstractControl implements GameEventListener {
// // // private static final Logger LOGGER = System.getLogger(FigureControl.class.getName()); private static final Logger LOGGER = System.getLogger(FigureControl.class.getName());
private final Figure figure; private final Figure figure;
private final Node spatial; private final Node spatial;
private final MonopolyApp app; private final MonopolyApp app;
@@ -51,30 +50,14 @@ public class FigureControl extends AbstractControl implements GameEventListener
return; // Warte, bis die Verzögerung abgeschlossen ist return; // Warte, bis die Verzögerung abgeschlossen ist
} }
delayTime = 0; // Verzögerung abgeschlossen delayTime = 0; // Verzögerung abgeschlossen
LOGGER.log(Level.DEBUG, "Delay completed. Starting animation...");
} }
if (currentTarget == null && !path.isEmpty()) { if (currentTarget == null && !path.isEmpty()) {
// Hole das nächste Ziel aus dem Pfad // Hole das nächste Ziel aus dem Pfad
currentTarget = path.poll(); currentTarget = path.poll();
animationTime = 0f; animationTime = 0f;
LOGGER.log(Level.DEBUG, "Next target: {0}", currentTarget);
// Prüfe, ob eine Drehung erforderlich ist (Felder 0, 10, 20, 30)
int currentField = figure.getCurrentFieldID();
int nextField = nextField(currentField);
if ((nextField(currentField) == 10) ||
(nextField(currentField) == 20) ||
(nextField(currentField) == 30) ||
(nextField(currentField) == 0)) {
Quaternion rotation = spatial.getLocalRotation();
Quaternion turnRight = new Quaternion().fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_Y);
spatial.setLocalRotation(rotation.mult(turnRight));
}
} }
if (currentTarget != null) { if (currentTarget != null) {
@@ -88,7 +71,7 @@ public class FigureControl extends AbstractControl implements GameEventListener
// Hüpfeffekt hinzufügen // Hüpfeffekt hinzufügen
float hopHeight = 0.5f * FastMath.sin(FastMath.PI * (animationTime / durationPerField)); float hopHeight = 0.5f * FastMath.sin(FastMath.PI * (animationTime / durationPerField));
interpolatedPosition.setY(hopHeight ); interpolatedPosition.setY(hopHeight + 1);
spatial.setLocalTranslation(interpolatedPosition); spatial.setLocalTranslation(interpolatedPosition);
// Ziel erreicht // Ziel erreicht
@@ -96,14 +79,18 @@ public class FigureControl extends AbstractControl implements GameEventListener
spatial.setLocalTranslation(currentTarget); spatial.setLocalTranslation(currentTarget);
figure.moveTo(currentTarget); // Synchronisiere die interne Position figure.moveTo(currentTarget); // Synchronisiere die interne Position
currentTarget = null; // Setze Ziel zurück currentTarget = null; // Setze Ziel zurück
LOGGER.log(Level.DEBUG, "Target reached. Remaining path: {0}", path.size());
} }
} }
} }
private int nextField(int currentField) { // Beispiel: Berechnung des nächsten Feldes
return (currentField + 1) % 40; private int nextField() {
int currentField = figure.getCurrentFieldID();
return (currentField + 1) % 40; // Weiter zum nächsten Feld
} }
@@ -114,34 +101,34 @@ public class FigureControl extends AbstractControl implements GameEventListener
} }
public void setPath(int startField, int endField) { public void setPath(int startField, int endField) {
// LOGGER.log(Level.TRACE, "setPath called with startField: {0} to endField {1}", startField, endField); LOGGER.log(Level.TRACE, "setPath called with startField: {0} to endField {1}", startField, endField);
path.clear(); path.clear();
for (int fieldId = startField; fieldId != endField; fieldId = (fieldId + 1) % 40) { for (int fieldId = startField; fieldId != endField; fieldId = (fieldId + 1) % 40) {
Vector3f position = figure.calculateFieldPosition(fieldId); Vector3f position = figure.calculateFieldPosition(fieldId);
// LOGGER.log(Level.DEBUG, "Adding postition to path: {0}", position); LOGGER.log(Level.DEBUG, "Adding postition to path: {0}", position);
path.add(position); path.add(position);
} }
Vector3f finalPosition = figure.calculateFieldPosition(endField); Vector3f finalPosition = figure.calculateFieldPosition(endField);
path.add(finalPosition); path.add(finalPosition);
// LOGGER.log(Level.DEBUG, "Final position added to path: {0}", finalPosition); LOGGER.log(Level.DEBUG, "Final position added to path: {0}", finalPosition);
// LOGGER.log(Level.TRACE, "Path size: {0}", path.size()); LOGGER.log(Level.TRACE, "Path size: {0}", path.size());
} }
@Override @Override
public void receivedEvent(UpdatePlayerView event) { public void receivedEvent(UpdatePlayerView event) {
// LOGGER.log(Level.TRACE, "receivedEvent called with event: {0}", event); LOGGER.log(Level.TRACE, "receivedEvent called with event: {0}", event);
int newPos = app.getGameLogic().getPlayerHandler().getPlayerById(figure.getId()).getFieldID(); int newPos = app.getGameLogic().getPlayerHandler().getPlayerById(figure.getId()).getFieldID();
int currentField = figure.getCurrentFieldID(); int currentField = figure.getCurrentFieldID();
if (currentField == newPos) { if (currentField == newPos) {
// LOGGER.log(Level.DEBUG, "No movement required. Current field: {0}, New field: {1}", currentField, newPos); LOGGER.log(Level.DEBUG, "No movement required. Current field: {0}, New field: {1}", currentField, newPos);
return; return;
} }
// LOGGER.log(Level.DEBUG, "Movement required. Current field: {0}, New field: {1}", currentField, newPos); LOGGER.log(Level.DEBUG, "Movement required. Current field: {0}, New field: {1}", currentField, newPos);
setPath(currentField, newPos); setPath(currentField, newPos);

View File

@@ -154,7 +154,6 @@ public class LobbyMenu extends Dialog {
figures.add("Katze"); figures.add("Katze");
figures.add("OOP"); figures.add("OOP");
figures.add("Handyholster"); figures.add("Handyholster");
figures.add("Panzer");
figureDropdown = new Selector<>(figures, "glass"); figureDropdown = new Selector<>(figures, "glass");
@@ -326,6 +325,7 @@ public class LobbyMenu extends Dialog {
figure = selector.getSelectedItem(); figure = selector.getSelectedItem();
break; break;
} }
System.out.println("FIGUR:::::"+figure);
} }
/** /**

View File

@@ -65,7 +65,7 @@ public class StartMenu extends Dialog {
app.getGuiNode().attachChild(centerMenu); app.getGuiNode().attachChild(centerMenu);
// Load the Monopoly logo as a texture // Load the Monopoly logo as a texture
Texture logoTexture = app.getAssetManager().loadTexture("Pictures/logo-monopolyw.png"); Texture logoTexture = app.getAssetManager().loadTexture("Pictures/logo-monopoly.png");
// Create a container for the logo // Create a container for the logo
Container logoContainer = new Container(); Container logoContainer = new Container();
@@ -91,8 +91,8 @@ public class StartMenu extends Dialog {
QuadBackgroundComponent unibwBackground = new QuadBackgroundComponent(unibwTexture); QuadBackgroundComponent unibwBackground = new QuadBackgroundComponent(unibwTexture);
unibwContainer.setBackground(unibwBackground); unibwContainer.setBackground(unibwBackground);
float unibwWidth = 662; float unibwWidth = 512;
float unibwHeight = 180; float unibwHeight = 128;
unibwContainer.setPreferredSize(new Vector3f(unibwWidth, unibwHeight, 0)); unibwContainer.setPreferredSize(new Vector3f(unibwWidth, unibwHeight, 0));
unibwContainer.setLocalTranslation(new Vector3f( unibwContainer.setLocalTranslation(new Vector3f(

View File

@@ -99,9 +99,7 @@ public class Toolbar extends Dialog implements GameEventListener {
container.setBackground(background); container.setBackground(background);
setupBorders(container); setupBorders(container);
setupSpacer(container);
setupPlayerInfoSection(container); setupPlayerInfoSection(container);
setupSpacer(container);
setupDiceSection(container); setupDiceSection(container);
setupActionMenu(container); setupActionMenu(container);
@@ -137,17 +135,6 @@ public class Toolbar extends Dialog implements GameEventListener {
app.getGuiNode().attachChild(border); app.getGuiNode().attachChild(border);
} }
/**
* Adds a spacer to the specified container.
*
* @param container the container to which the spacer is added
*/
private void setupSpacer(Container container) {
Container spacer = container.addChild(new Container());
spacer.setPreferredSize(new Vector3f(20, 10, 0));
spacer.setBackground(null);
}
/** /**
* Sets up the player information section of the toolbar interface. * Sets up the player information section of the toolbar interface.
* *
@@ -196,6 +183,16 @@ public class Toolbar extends Dialog implements GameEventListener {
menuContainer.setBackground(null); menuContainer.setBackground(null);
} }
/**
* Returns the color of the current player.
*
* @return The color of the current player.
*/
private ColorRGBA getCurrentPlayerColor() {
Player currentPlayer = playerHandler.getPlayerById(app.getId());
return Player.getColor(currentPlayer.getId()).getColor();
}
/** /**
* Creates the dice display section of the toolbar interface. * Creates the dice display section of the toolbar interface.
* *
@@ -273,15 +270,15 @@ public class Toolbar extends Dialog implements GameEventListener {
* Handles the dice roll event. * Handles the dice roll event.
*/ */
private void handleDiceRoll() { private void handleDiceRoll() {
ifTopDialog(() -> { ifTopDialog(() -> {
if (!canRollDice) return; if (!canRollDice) return;
canRollDice = false; canRollDice = false;
if (endTurnButton != null) endTurnButton.setEnabled(true); if (endTurnButton != null) endTurnButton.setEnabled(true);
startDiceAnimation(); startDiceAnimation();
app.getGameLogic().send(new RollDice()); app.getGameLogic().send(new RollDice());
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
}); });
} }
private Button createTradeButton() { private Button createTradeButton() {
@@ -298,7 +295,6 @@ public class Toolbar extends Dialog implements GameEventListener {
tradeButton.addClickCommands(s -> ifTopDialog(() -> { tradeButton.addClickCommands(s -> ifTopDialog(() -> {
new ChoosePartner(app).open(); new ChoosePartner(app).open();
})); }));
return tradeButton; return tradeButton;
@@ -338,12 +334,25 @@ public class Toolbar extends Dialog implements GameEventListener {
endTurnButton.setIcon(icon); endTurnButton.setIcon(icon);
endTurnButton.addClickCommands(s -> ifTopDialog(() -> { endTurnButton.addClickCommands(s -> ifTopDialog(() -> {
handleEndTurn(); app.getGameLogic().send(new EndTurn());
receivedEvent(new ButtonStatusEvent(false));
})); }));
return endTurnButton; return endTurnButton;
} }
/**
* Creates a background with the specified color.
*
* @param color The color of the background.
* @return The background component.
*/
private QuadBackgroundComponent createButtonBackground(ColorRGBA color) {
QuadBackgroundComponent background = new QuadBackgroundComponent(color);
Texture gradient = app.getAssetManager().loadTexture("Textures/gradient.png");
if (gradient != null) background.setTexture(gradient);
return background;
}
/** /**
* Handles the end turn event. * Handles the end turn event.

View File

@@ -12,31 +12,33 @@ import com.simsilica.lemur.Label;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId; import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog; import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.MonopolyApp;
import pp.monopoly.client.gui.SettingsMenu;
import pp.monopoly.message.server.TradeReply; import pp.monopoly.message.server.TradeReply;
import pp.monopoly.notification.Sound; import pp.monopoly.notification.Sound;
/** /**
* Represents a confirmation dialog that appears when a trade is accepted. * Represents a confirmation dialog that appears when a trade is accepted .
* Displays a message to the user informing them that the trade was accepted. * <p>
* Displays a message to the user informing them that the trade they proposed has been accepted,
* along with a confirmation button to close the dialog.
* </p>
*/ */
public class AcceptTrade extends Dialog implements PopupDialog { public class AcceptTrade extends Dialog {
/** Reference to the Monopoly application instance. */ /** Reference to the Monopoly application instance. */
private final MonopolyApp app; private final MonopolyApp app;
/** Semi-transparent overlay background for the dialog. */ /** Semi-transparent overlay background for the dialog. */
private Geometry overlayBackground; private final Geometry overlayBackground;
/** Container for the warning message content. */ /** Container for the warning message content. */
private Container noMoneyWarningContainer; private final Container noMoneyWarningContainer;
/** Background container providing a border for the dialog. */ /** Background container providing a border for the dialog. */
private Container backgroundContainer; private final Container backgroundContainer;
/** /**
* Constructs the AcceptTrade dialog. * Constructs the accept trade dialog.
* *
* @param app the Monopoly application instance * @param app the Monopoly application instance
* @param msg the trade reply message containing details about the trade * @param msg the trade reply message containing details about the trade
@@ -45,99 +47,80 @@ public class AcceptTrade extends Dialog implements PopupDialog {
super(app.getDialogManager()); super(app.getDialogManager());
this.app = app; this.app = app;
// Initialize GUI elements
createOverlayBackground(); // Halbtransparentes Overlay hinzufügen
createBackgroundContainer(); overlayBackground = createOverlayBackground();
createWarningContainer(msg); app.getGuiNode().attachChild(overlayBackground);
// Create the background container
backgroundContainer = new Container();
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Darker background
app.getGuiNode().attachChild(backgroundContainer);
// Hauptcontainer für die Warnung
noMoneyWarningContainer = new Container();
noMoneyWarningContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f)));
noMoneyWarningContainer.setPreferredSize(new Vector3f(550,250,10));
float padding = 10; // Passt den backgroundContainer an die Größe des bankruptContainers an
backgroundContainer.setPreferredSize(noMoneyWarningContainer.getPreferredSize().addLocal(padding, padding, 0));
// Titel
Label gateFieldTitle = noMoneyWarningContainer.addChild(new Label("Handel angenommen!", new ElementId("warning-title")));
gateFieldTitle.setFontSize(48);
gateFieldTitle.setColor(ColorRGBA.Black);
// Text, der im Popup steht
Container textContainer = noMoneyWarningContainer.addChild(new Container());
textContainer.addChild(new Label("Du hast Spieler"+ " " + msg.getTradeHandler().getReceiver().getName() + " " + "einen Handel vorgeschlagen", new ElementId("label-Text")));
textContainer.addChild(new Label("", new ElementId("label-Text")));
textContainer.addChild(new Label("Der Handel wurde angenommen", new ElementId("label-Text")));
textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
// Passt den textContainer an die Größe des bankruptContainers an
textContainer.setPreferredSize(noMoneyWarningContainer.getPreferredSize().addLocal(-250,-200,0));
// Beenden-Button
Button quitButton = noMoneyWarningContainer.addChild(new Button("Bestätigen", new ElementId("button")));
quitButton.setFontSize(32);
quitButton.addClickCommands(source -> ifTopDialog(() -> {
app.getGameLogic().playSound(Sound.BUTTON);
close();
}));
// Zentriere das Popup
noMoneyWarningContainer.setLocalTranslation(
(app.getCamera().getWidth() - noMoneyWarningContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + noMoneyWarningContainer.getPreferredSize().y) / 2,
8
);
// Zentriere das Popup
backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - noMoneyWarningContainer.getPreferredSize().x - padding) / 2,
(app.getCamera().getHeight() + noMoneyWarningContainer.getPreferredSize().y+ padding) / 2,
7
);
app.getGuiNode().attachChild(noMoneyWarningContainer);
} }
/** /**
* Creates a semi-transparent background overlay for the dialog. * Creates a semi-transparent background overlay for the dialog.
*/
private void createOverlayBackground() {
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
overlayBackground = new Geometry("Overlay", quad);
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Semi-transparent
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
overlayBackground.setMaterial(material);
overlayBackground.setLocalTranslation(0, 0, 0);
}
/**
* Creates the background container for the dialog.
*/
private void createBackgroundContainer() {
backgroundContainer = new Container();
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray background
}
/**
* Creates the main warning container for the dialog.
* *
* @param msg the trade reply message * @return the geometry of the overlay
*/ */
private void createWarningContainer(TradeReply msg) { private Geometry createOverlayBackground() {
noMoneyWarningContainer = new Container(); Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
noMoneyWarningContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); Geometry overlay = new Geometry("Overlay", quad);
noMoneyWarningContainer.setPreferredSize(new Vector3f(550, 250, 10)); Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Halbtransparent
float padding = 10; material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
backgroundContainer.setPreferredSize(noMoneyWarningContainer.getPreferredSize().addLocal(padding, padding, 0)); overlay.setMaterial(material);
overlay.setLocalTranslation(0, 0, 0);
// Title return overlay;
Label title = noMoneyWarningContainer.addChild(new Label("Handel angenommen!", new ElementId("warning-title")));
title.setFontSize(48);
title.setColor(ColorRGBA.Black);
// Message
Container textContainer = noMoneyWarningContainer.addChild(new Container());
textContainer.addChild(new Label("Du hast " + msg.getTradeHandler().getReceiver().getName() + " einen Handel vorgeschlagen.", new ElementId("label-Text")));
textContainer.addChild(new Label("", new ElementId("label-Text")));
textContainer.addChild(new Label("Der Handel wurde angenommen.", new ElementId("label-Text")));
textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
textContainer.setPreferredSize(noMoneyWarningContainer.getPreferredSize().addLocal(-250, -200, 0));
// Confirmation button
Button confirmButton = noMoneyWarningContainer.addChild(new Button("Bestätigen", new ElementId("button")));
confirmButton.setFontSize(32);
confirmButton.addClickCommands(source -> ifTopDialog(() -> {
app.getGameLogic().playSound(Sound.BUTTON);
close();
}));
}
/**
* Centers the warning and background containers on the screen.
*/
private void centerContainers() {
float padding = 10;
// Center main container
noMoneyWarningContainer.setLocalTranslation(
(app.getCamera().getWidth() - noMoneyWarningContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + noMoneyWarningContainer.getPreferredSize().y) / 2,
8
);
// Center background container with padding
backgroundContainer.setPreferredSize(noMoneyWarningContainer.getPreferredSize().addLocal(padding, padding, 0));
backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - backgroundContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + backgroundContainer.getPreferredSize().y) / 2,
7
);
}
/**
* Displays the dialog by attaching it to the GUI through the DialogManager.
*/
@Override
public void show() {
app.getGuiNode().attachChild(overlayBackground);
app.getGuiNode().attachChild(backgroundContainer);
app.getGuiNode().attachChild(noMoneyWarningContainer);
centerContainers();
} }
/** /**
@@ -145,9 +128,9 @@ public class AcceptTrade extends Dialog implements PopupDialog {
*/ */
@Override @Override
public void close() { public void close() {
app.getGuiNode().detachChild(overlayBackground); app.getGuiNode().detachChild(noMoneyWarningContainer); // Entferne das Menü
app.getGuiNode().detachChild(backgroundContainer); app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
app.getGuiNode().detachChild(noMoneyWarningContainer); app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
super.close(); super.close();
} }
@@ -156,6 +139,6 @@ public class AcceptTrade extends Dialog implements PopupDialog {
*/ */
@Override @Override
public void escape() { public void escape() {
new SettingsMenu(app).open(); close();
} }
} }

View File

@@ -12,24 +12,24 @@ import com.simsilica.lemur.Label;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId; import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog; import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.MonopolyApp;
/** /**
* Bankrupt is a Warning-Popup which appears when the balance is negative at the end of a player´s turn. * Bankrupt is a Warning-Popup which appears when the balance is negative at the end of a player´s turn
*/ */
public class Bankrupt extends Dialog implements PopupDialog { public class Bankrupt extends Dialog {
/** Reference to the Monopoly application instance. */ /** Reference to the Monopoly application instance. */
private final MonopolyApp app; private final MonopolyApp app;
/** Semi-transparent overlay background for the popup. */ /** Semi-transparent overlay background for the popup. */
private Geometry overlayBackground; private final Geometry overlayBackground;
/** Main container for the bankruptcy warning content. */ /** Main container for the bankruptcy warning content. */
private Container bankruptContainer; private final Container bankruptContainer;
/** Background container providing a border for the popup. */ /** Background container providing a border for the popup. */
private Container backgroundContainer; private final Container backgroundContainer;
/** /**
* Constructs the bankruptcy warning popup. * Constructs the bankruptcy warning popup.
@@ -40,102 +40,86 @@ public class Bankrupt extends Dialog implements PopupDialog {
super(app.getDialogManager()); super(app.getDialogManager());
this.app = app; this.app = app;
// Initialize the components
createOverlayBackground(); // Halbtransparentes Overlay hinzufügen
createBackgroundContainer(); overlayBackground = createOverlayBackground();
createBankruptContainer(); app.getGuiNode().attachChild(overlayBackground);
// Create the background container
backgroundContainer = new Container();
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Darker background
app.getGuiNode().attachChild(backgroundContainer);
// Hauptcontainer für die Warnung
bankruptContainer = new Container();
bankruptContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f)));
bankruptContainer.setPreferredSize(new Vector3f(550,250,10));
float padding = 10; // Passt den backgroundContainer an die Größe des bankruptContainers an
backgroundContainer.setPreferredSize(bankruptContainer.getPreferredSize().addLocal(padding, padding, 0));
// Titel
Label gateFieldTitle = bankruptContainer.addChild(new Label("Vorsicht !", new ElementId("warning-title")));
gateFieldTitle.setFontSize(48);
gateFieldTitle.setColor(ColorRGBA.Black);
// Text, der im Popup steht
Container textContainer = bankruptContainer.addChild(new Container());
textContainer.addChild(new Label("Du hast noch einen negativen Kontostand. Wenn du jetzt deinen Zug beendest, gehst du Bankrott und verlierst das Spiel!\n"+
"Dieses PopUp wird nicht erneut angezeigt!", new ElementId("label-Text")));
textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
// Passt den textContainer an die Größe des bankruptContainers an
textContainer.setPreferredSize(bankruptContainer.getPreferredSize().addLocal(-250,-200,0));
// Beenden-Button
Button quitButton = bankruptContainer.addChild(new Button("Bestätigen", new ElementId("button")));
quitButton.setFontSize(32);
quitButton.addClickCommands(source -> ifTopDialog(this::close));
// Zentriere das Popup
bankruptContainer.setLocalTranslation(
(app.getCamera().getWidth() - bankruptContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + bankruptContainer.getPreferredSize().y) / 2,
8
);
// Zentriere das Popup
backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - bankruptContainer.getPreferredSize().x - padding) / 2,
(app.getCamera().getHeight() + bankruptContainer.getPreferredSize().y+ padding) / 2,
7
);
app.getGuiNode().attachChild(bankruptContainer);
} }
/** /**
* Creates a semi-transparent background overlay for the popup. * Creates a semi-transparent background overlay for the popup.
*
* @return the geometry of the overlay
*/ */
private void createOverlayBackground() { private Geometry createOverlayBackground() {
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight()); Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
overlayBackground = new Geometry("Overlay", quad); Geometry overlay = new Geometry("Overlay", quad);
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Semi-transparent material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Halbtransparent
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha); material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
overlayBackground.setMaterial(material); overlay.setMaterial(material);
overlayBackground.setLocalTranslation(0, 0, 0); overlay.setLocalTranslation(0, 0, 0);
return overlay;
} }
/** /**
* Creates the background container for the popup. * Closes the menu and removes the GUI elements.
*/
private void createBackgroundContainer() {
backgroundContainer = new Container();
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray background
}
/**
* Creates the main container for the bankruptcy warning content.
*/
private void createBankruptContainer() {
bankruptContainer = new Container();
bankruptContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f)));
bankruptContainer.setPreferredSize(new Vector3f(550, 350, 10));
// Title
Label title = bankruptContainer.addChild(new Label("Vorsicht!", new ElementId("warning-title")));
title.setFontSize(48);
title.setColor(ColorRGBA.Black);
// Text content
Container textContainer = bankruptContainer.addChild(new Container());
textContainer.addChild(new Label(
"Du hast einen negativen Kontostand. Wenn du jetzt deinen Zug beendest, gehst du bankrott und verlierst das Spiel!\n"
+ "Dieses Pop-Up wird nicht erneut angezeigt!",
new ElementId("label-Text")));
textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
textContainer.setPreferredSize(bankruptContainer.getPreferredSize().addLocal(-250, -200, 0));
// Confirmation button
Button confirmButton = bankruptContainer.addChild(new Button("Bestätigen", new ElementId("button")));
confirmButton.setFontSize(32);
confirmButton.addClickCommands(source -> ifTopDialog(this::close));
}
/**
* Centers the popup containers on the screen.
*/
private void centerContainers() {
float padding = 10;
// Center bankrupt container
bankruptContainer.setLocalTranslation(
(app.getCamera().getWidth() - bankruptContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + bankruptContainer.getPreferredSize().y) / 2,
8
);
// Center background container with padding
backgroundContainer.setPreferredSize(bankruptContainer.getPreferredSize().addLocal(padding, padding, 0));
backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - backgroundContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + backgroundContainer.getPreferredSize().y) / 2,
7
);
}
/**
* Displays the popup by attaching it to the GUI.
*/
@Override
public void show() {
app.getGuiNode().attachChild(overlayBackground);
app.getGuiNode().attachChild(backgroundContainer);
app.getGuiNode().attachChild(bankruptContainer);
centerContainers();
}
/**
* Closes the popup and removes the associated GUI elements.
*/ */
@Override @Override
public void close() { public void close() {
app.getGuiNode().detachChild(overlayBackground); app.getGuiNode().detachChild(bankruptContainer); // Entferne das Menü
app.getGuiNode().detachChild(backgroundContainer); app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
app.getGuiNode().detachChild(bankruptContainer); app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
super.close(); super.close();
} }
@@ -146,4 +130,4 @@ public class Bankrupt extends Dialog implements PopupDialog {
public void escape() { public void escape() {
close(); close();
} }
} }

View File

@@ -1,7 +1,6 @@
package pp.monopoly.client.gui.popups; package pp.monopoly.client.gui.popups;
import com.jme3.math.ColorRGBA; import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.simsilica.lemur.Button; import com.simsilica.lemur.Button;
import com.simsilica.lemur.Container; import com.simsilica.lemur.Container;
import com.simsilica.lemur.Label; import com.simsilica.lemur.Label;
@@ -9,7 +8,6 @@ import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId; import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog; import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.MonopolyApp;
import pp.monopoly.client.gui.SettingsMenu; import pp.monopoly.client.gui.SettingsMenu;
import pp.monopoly.message.client.BuyPropertyResponse; import pp.monopoly.message.client.BuyPropertyResponse;
@@ -18,12 +16,16 @@ import pp.monopoly.model.fields.BuildingProperty;
import pp.monopoly.notification.Sound; import pp.monopoly.notification.Sound;
/** /**
* BuildingPropertyCard creates a popup for displaying field information. * BuildingPropertyCard creates the popup for field information
*/ */
public class BuildingPropertyCard extends Dialog implements PopupDialog { public class BuildingPropertyCard extends Dialog {
/** Reference to the Monopoly application instance. */
private final MonopolyApp app; private final MonopolyApp app;
/** Main container for the building property information. */
private final Container buildingPropertyContainer; private final Container buildingPropertyContainer;
/** Background container providing a border for the property card. */
private final Container backgroundContainer; private final Container backgroundContainer;
/** /**
@@ -35,123 +37,83 @@ public class BuildingPropertyCard extends Dialog implements PopupDialog {
super(app.getDialogManager()); super(app.getDialogManager());
this.app = app; this.app = app;
//Generate the corresponding field
int index = app.getGameLogic().getPlayerHandler().getPlayerById(app.getId()).getFieldID(); int index = app.getGameLogic().getPlayerHandler().getPlayerById(app.getId()).getFieldID();
BuildingProperty field = (BuildingProperty) new BoardManager().getFieldAtIndex(index); BuildingProperty field = (BuildingProperty) new BoardManager().getFieldAtIndex(index);
// Create the main container for the popup
buildingPropertyContainer = new Container();
buildingPropertyContainer.setBackground(new QuadBackgroundComponent(field.getColor().getColor()));
addContentToContainer(buildingPropertyContainer, field);
buildingPropertyContainer.setPreferredSize(new Vector3f(360,460,1));
System.out.println(buildingPropertyContainer.getPreferredSize());
// Create the background container // Create the background container
backgroundContainer = new Container(); backgroundContainer = new Container();
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Darker background
attachChild(backgroundContainer);
// Add padding to the background // Hauptcontainer für die Gebäudekarte
float padding = 10f; buildingPropertyContainer = new Container();
buildingPropertyContainer.setBackground(new QuadBackgroundComponent(field.getColor().getColor()));
float padding = 10; // Passt den backgroundContainer an die Größe des buildingPropertyContainer an
backgroundContainer.setPreferredSize(buildingPropertyContainer.getPreferredSize().addLocal(padding, padding, 0)); backgroundContainer.setPreferredSize(buildingPropertyContainer.getPreferredSize().addLocal(padding, padding, 0));
//Titel
Label settingsTitle = buildingPropertyContainer.addChild(new Label( field.getName(), new ElementId("label-Bold")));
settingsTitle.setBackground(new QuadBackgroundComponent(field.getColor().getColor()));
settingsTitle.setFontSize(48);
System.out.println(backgroundContainer.getPreferredSize()); // Text, der auf der Karte steht
// Die Preise werden dynamisch dem BoardManager entnommen
// Position the containers Container propertyValuesContainer = buildingPropertyContainer.addChild(new Container());
centerContainers(padding); propertyValuesContainer.addChild(new Label("„Grundstückswert: " + field.getPrice() + " EUR", new ElementId("label-Text")));
} propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));// Leerzeile
propertyValuesContainer.addChild(new Label("„Miete allein: " + field.getAllRent().get(0)+ " EUR", new ElementId("label-Text")));
/** propertyValuesContainer.addChild(new Label("„-mit 1 Haus: " + field.getAllRent().get(1) + " EUR", new ElementId("label-Text")));
* Adds the property details and buttons to the container. propertyValuesContainer.addChild(new Label("„-mit 2 Häuser: " + field.getAllRent().get(2) + " EUR", new ElementId("label-Text")));
* propertyValuesContainer.addChild(new Label("„-mit 3 Häuser: " + field.getAllRent().get(3) + " EUR", new ElementId("label-Text")));
* @param container the main container for the property card propertyValuesContainer.addChild(new Label("„-mit 4 Häuser: " + field.getAllRent().get(4) + " EUR", new ElementId("label-Text")));
* @param field the building property to display propertyValuesContainer.addChild(new Label("„-mit 1 Hotel: " + field.getAllRent().get(5) + " EUR", new ElementId("label-Text")));
*/ propertyValuesContainer.addChild(new Label("„-1 Haus kostet: " + field.getHousePrice()+ " EUR", new ElementId("label-Text")));
private void addContentToContainer(Container container, BuildingProperty field) { propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));// Leerzeile
// Title propertyValuesContainer.addChild(new Label("„Hypothek: " + field.getHypo() + " EUR", new ElementId("label-Text")));
Label title = container.addChild(new Label(field.getName(), new ElementId("label-Bold")));
title.setBackground(new QuadBackgroundComponent(field.getColor().getColor()));
title.setFontSize(38);
// Property details
Container propertyValuesContainer = container.addChild(new Container());
propertyValuesContainer.addChild(new Label("Grundstückswert: " + field.getPrice() + " EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("Miete allein: " + field.getAllRent().get(0) + " EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("- mit 1 Haus: " + field.getAllRent().get(1) + " EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("- mit 2 Häusern: " + field.getAllRent().get(2) + " EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("- mit 3 Häusern: " + field.getAllRent().get(3) + " EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("- mit 4 Häusern: " + field.getAllRent().get(4) + " EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("- mit 1 Hotel: " + field.getAllRent().get(5) + " EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("1 Haus kostet: " + field.getHousePrice() + " EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("Hypothek: " + field.getHypo() + " EUR", new ElementId("label-Text")));
propertyValuesContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f))); propertyValuesContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
// Add buttons // Beenden-Button
addButtons(container); Button quitButton = buildingPropertyContainer.addChild(new Button("Beenden", new ElementId("button")));
}
/**
* Adds the buttons for closing or buying the property.
*
* @param container the main container
*/
private void addButtons(Container container) {
// Quit button
Button quitButton = container.addChild(new Button("Beenden", new ElementId("button")));
quitButton.setFontSize(32); quitButton.setFontSize(32);
quitButton.addClickCommands(s -> ifTopDialog(() -> { quitButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
close(); close();
})); }));
// Kaufen-Button
// Buy button Button buyButton = buildingPropertyContainer.addChild(new Button("Kaufen", new ElementId("button")));
Button buyButton = container.addChild(new Button("Kaufen", new ElementId("button")));
buyButton.setFontSize(32); buyButton.setFontSize(32);
buyButton.addClickCommands(s -> ifTopDialog(() -> { buyButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
close(); close();
app.getGameLogic().send(new BuyPropertyResponse()); app.getGameLogic().send(new BuyPropertyResponse());
})); }));
}
/** // Zentriere das Popup
* Centers the containers on the screen.
*
* @param padding the padding size
*/
private void centerContainers(float padding) {
// Center main container
buildingPropertyContainer.setLocalTranslation( buildingPropertyContainer.setLocalTranslation(
(app.getCamera().getWidth() - buildingPropertyContainer.getPreferredSize().x) / 2, (app.getCamera().getWidth() - buildingPropertyContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + buildingPropertyContainer.getPreferredSize().y) / 2, (app.getCamera().getHeight() + buildingPropertyContainer.getPreferredSize().y) / 2,
8 10
); );
// Center background container with padding // Zentriere das Popup
backgroundContainer.setLocalTranslation( backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - buildingPropertyContainer.getPreferredSize().x - padding) / 2, (app.getCamera().getWidth() - buildingPropertyContainer.getPreferredSize().x - padding) / 2,
(app.getCamera().getHeight() + buildingPropertyContainer.getPreferredSize().y + padding) / 2, (app.getCamera().getHeight() + buildingPropertyContainer.getPreferredSize().y+ padding) / 2,
7 9
); );
}
/**
* Attaches the popup to the GUI through the DialogManager.
*/
@Override
public void show() {
app.getGuiNode().attachChild(backgroundContainer);
app.getGuiNode().attachChild(buildingPropertyContainer); app.getGuiNode().attachChild(buildingPropertyContainer);
} }
/** /**
* Closes the popup and removes associated GUI elements. * Closes the popup and removes the associated GUI elements.
*/ */
@Override @Override
public void close() { public void close() {
app.getGuiNode().detachChild(buildingPropertyContainer); app.getGuiNode().detachChild(buildingPropertyContainer); // Entferne das Menü
app.getGuiNode().detachChild(backgroundContainer); app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
super.close(); super.close();
} }
@@ -162,4 +124,4 @@ public class BuildingPropertyCard extends Dialog implements PopupDialog {
public void escape() { public void escape() {
new SettingsMenu(app).open(); new SettingsMenu(app).open();
} }
} }

View File

@@ -7,6 +7,7 @@ import com.simsilica.lemur.Button;
import com.simsilica.lemur.Container; import com.simsilica.lemur.Container;
import com.simsilica.lemur.Label; import com.simsilica.lemur.Label;
import com.simsilica.lemur.Selector; import com.simsilica.lemur.Selector;
import com.simsilica.lemur.TextField;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.component.SpringGridLayout; import com.simsilica.lemur.component.SpringGridLayout;
import com.simsilica.lemur.core.VersionedList; import com.simsilica.lemur.core.VersionedList;

View File

@@ -7,7 +7,6 @@ import com.simsilica.lemur.Label;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId; import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog; import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.MonopolyApp;
import pp.monopoly.client.gui.SettingsMenu; import pp.monopoly.client.gui.SettingsMenu;
import pp.monopoly.client.gui.TradeMenu; import pp.monopoly.client.gui.TradeMenu;
@@ -19,18 +18,18 @@ import pp.monopoly.notification.Sound;
/** /**
* ConfirmTrade is a popup which appears when a trade is proposed to this certain player. * ConfirmTrade is a popup which appears when a trade is proposed to this certain player.
*/ */
public class ConfirmTrade extends Dialog implements PopupDialog { public class ConfirmTrade extends Dialog {
/** Reference to the Monopoly application instance. */ /** Reference to the Monopoly application instance. */
private final MonopolyApp app; private final MonopolyApp app;
/** Main container for the "Confirm Trade" popup UI. */ /** Main container for the "Confirm Trade" popup UI. */
private Container confirmTradeContainer; private final Container confirmTradeContainer;
/** Background container providing a border for the popup. */ /** Background container providing a border for the popup. */
private Container backgroundContainer; private final Container backgroundContainer;
/** The trade handler managing the details of the trade proposal. */ /** The trade handler managing the details of the trade proposal. */
private final TradeHandler tradeHandler; private TradeHandler tradeHandler;
/** /**
* Constructs the "Confirm Trade" popup. * Constructs the "Confirm Trade" popup.
@@ -40,61 +39,53 @@ public class ConfirmTrade extends Dialog implements PopupDialog {
public ConfirmTrade(MonopolyApp app) { public ConfirmTrade(MonopolyApp app) {
super(app.getDialogManager()); super(app.getDialogManager());
this.app = app; this.app = app;
this.tradeHandler = app.getGameLogic().getTradeHandler(); tradeHandler = app.getGameLogic().getTradeHandler();
// Initialize components // Create the background container
createBackgroundContainer();
createConfirmTradeContainer();
}
/**
* Initializes the background container.
*/
private void createBackgroundContainer() {
backgroundContainer = new Container(); backgroundContainer = new Container();
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f)));
} attachChild(backgroundContainer);
/**
* Initializes the main confirm trade container and its UI components.
*/
private void createConfirmTradeContainer() {
confirmTradeContainer = new Container(); confirmTradeContainer = new Container();
// Title float padding = 10;
Label title = confirmTradeContainer.addChild(new Label("Handel", new ElementId("warning-title"))); backgroundContainer.setPreferredSize(confirmTradeContainer.getPreferredSize().addLocal(padding, padding, 0));
// Titel
Label title = confirmTradeContainer.addChild(new Label( "Handel", new ElementId("warning-title")));
title.setFontSize(48); title.setFontSize(48);
title.setColor(ColorRGBA.Black); title.setColor(ColorRGBA.Black);
// Build trade information strings
StringBuilder offeredProperties = new StringBuilder(); StringBuilder offeredProperties = new StringBuilder();
for (PropertyField field : tradeHandler.getOfferedProperties()) { for (PropertyField field : tradeHandler.getOfferedProperties()) {
offeredProperties.append(field.getName()).append(", "); offeredProperties.append(field.getName());
offeredProperties.append(", ");
} }
StringBuilder requestedProperties = new StringBuilder(); StringBuilder requestedProperties = new StringBuilder();
for (PropertyField field : tradeHandler.getRequestedProperties()) { for (PropertyField field : tradeHandler.getRequestedProperties()) {
requestedProperties.append(field.getName()).append(", "); requestedProperties.append(field.getName());
requestedProperties.append(", ");
} }
// Trade details // Text, der auf der Karte steht
Container propertyValuesContainer = confirmTradeContainer.addChild(new Container()); Container propertyValuesContainer = confirmTradeContainer.addChild(new Container());
propertyValuesContainer.addChild(new Label( tradeHandler.getSender().getName() + " möchte:", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("„Spieler " + " " + tradeHandler.getSender().getName() + " " +" möchte:", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));// Leerzeile
propertyValuesContainer.addChild(new Label("- " + offeredProperties, new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("- " + offeredProperties, new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("- " + tradeHandler.getOfferedAmount() + " EUR", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("- " + tradeHandler.getOfferedAmount() + " EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("- " + tradeHandler.getOfferedJailCards() + " Sonderkarten", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("- " + tradeHandler.getOfferedJailCards() +" Sonderkarten", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));// Leerzeile
propertyValuesContainer.addChild(new Label("gegen:", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("gegen:", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));// Leerzeile
propertyValuesContainer.addChild(new Label("- " + requestedProperties, new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("- "+ requestedProperties, new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("- " + tradeHandler.getRequestedAmount() + " EUR", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("- "+ tradeHandler.getRequestedAmount() +" EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("- " + tradeHandler.getRequestedJailCards() + " Sonderkarten", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("- "+ tradeHandler.getRequestedJailCards() +" Sonderkarten", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));// Leerzeile
propertyValuesContainer.addChild(new Label("tauschen, willst du das Angebot annehmen?", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("tauschen, willst du das Angebot annehmen?", new ElementId("label-Text")));
propertyValuesContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f))); propertyValuesContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
// Decline button // Ablehnen-Button
Button declineButton = confirmTradeContainer.addChild(new Button("Ablehnen", new ElementId("button"))); Button declineButton = confirmTradeContainer.addChild(new Button("Ablehnen", new ElementId("button")));
declineButton.setFontSize(32); declineButton.setFontSize(32);
declineButton.addClickCommands(s -> ifTopDialog(() -> { declineButton.addClickCommands(s -> ifTopDialog(() -> {
@@ -102,50 +93,39 @@ public class ConfirmTrade extends Dialog implements PopupDialog {
app.getGameLogic().send(new TradeResponse(false, tradeHandler)); app.getGameLogic().send(new TradeResponse(false, tradeHandler));
close(); close();
})); }));
// Verhandeln-Button
// Negotiate button
Button negotiateButton = confirmTradeContainer.addChild(new Button("Verhandeln", new ElementId("button"))); Button negotiateButton = confirmTradeContainer.addChild(new Button("Verhandeln", new ElementId("button")));
negotiateButton.setFontSize(32); negotiateButton.setFontSize(32);
negotiateButton.addClickCommands(s -> ifTopDialog(() -> { negotiateButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
close(); close();
TradeHandler t = new TradeHandler(app.getGameLogic().getPlayerHandler().getPlayerById(tradeHandler.getSender().getId())); TradeHandler t = new TradeHandler(app.getGameLogic().getPlayerHandler().getPlayerById(tradeHandler.getSender().getId()));
t.setReceiver(app.getGameLogic().getPlayerHandler().getPlayerById(tradeHandler.getReceiver().getId())); t.setReceiver(app.getGameLogic().getPlayerHandler().getPlayerById(tradeHandler.getReceiver().getId()));
new TradeMenu(app, t).open(); new TradeMenu(app, t).open();
})); }));
// Confirm-Button
// Confirm button
Button confirmButton = confirmTradeContainer.addChild(new Button("Bestätigen", new ElementId("button"))); Button confirmButton = confirmTradeContainer.addChild(new Button("Bestätigen", new ElementId("button")));
confirmButton.setFontSize(32); confirmButton.setFontSize(32);
confirmButton.addClickCommands(s -> ifTopDialog(() -> { confirmButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
app.getGameLogic().send(new TradeResponse(true, tradeHandler)); app.getGameLogic().send(new TradeResponse(true, tradeHandler));
close(); close();
})); }));
}
/** // Zentriere das Menü
* Displays the popup by attaching it to the GUI.
*/
@Override
public void show() {
float padding = 10;
// Center and adjust sizes
backgroundContainer.setPreferredSize(confirmTradeContainer.getPreferredSize().addLocal(padding, padding, 0));
confirmTradeContainer.setLocalTranslation( confirmTradeContainer.setLocalTranslation(
(app.getCamera().getWidth() - confirmTradeContainer.getPreferredSize().x) / 2, (app.getCamera().getWidth() - confirmTradeContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + confirmTradeContainer.getPreferredSize().y) / 2, (app.getCamera().getHeight() + confirmTradeContainer.getPreferredSize().y) / 2,
8 8
); );
// Zentriere das Menü
backgroundContainer.setLocalTranslation( backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - confirmTradeContainer.getPreferredSize().x - padding) / 2, (app.getCamera().getWidth() - confirmTradeContainer.getPreferredSize().x - padding) / 2,
(app.getCamera().getHeight() + confirmTradeContainer.getPreferredSize().y + padding) / 2, (app.getCamera().getHeight() + confirmTradeContainer.getPreferredSize().y+ padding) / 2,
7 7
); );
// Attach to GUI node
app.getGuiNode().attachChild(backgroundContainer);
app.getGuiNode().attachChild(confirmTradeContainer); app.getGuiNode().attachChild(confirmTradeContainer);
} }

View File

@@ -12,25 +12,25 @@ import com.simsilica.lemur.Label;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId; import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog; import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.MonopolyApp;
import pp.monopoly.notification.Sound; import pp.monopoly.notification.Sound;
/** /**
* EventCardPopup is a popup which appears when a certain EventCard is triggered by entering an EventCardField. * EventCardPopup is a popup which appears when a certain EventCard is triggered by entering a EventCardField
*/ */
public class EventCardPopup extends Dialog implements PopupDialog { public class EventCardPopup extends Dialog {
/** Reference to the Monopoly application instance. */ /** Reference to the Monopoly application instance. */
private final MonopolyApp app; private final MonopolyApp app;
/** Semi-transparent overlay background for the popup. */ /** Semi-transparent overlay background for the popup. */
private Geometry overlayBackground; private final Geometry overlayBackground;
/** Main container for the event card information. */ /** Main container for the event card information. */
private Container eventCardContainer; private final Container eventCardContainer;
/** Background container providing a border for the popup. */ /** Background container providing a border for the popup. */
private Container backgroundContainer; private final Container backgroundContainer;
/** /**
* Constructs the EventCardPopup to display the details of a triggered event card. * Constructs the EventCardPopup to display the details of a triggered event card.
@@ -42,87 +42,74 @@ public class EventCardPopup extends Dialog implements PopupDialog {
super(app.getDialogManager()); super(app.getDialogManager());
this.app = app; this.app = app;
// Initialize the UI components // Halbtransparentes Overlay hinzufügen
createOverlayBackground(); overlayBackground = createOverlayBackground();
createBackgroundContainer(); app.getGuiNode().attachChild(overlayBackground);
createEventCardContainer(description);
}
/** // Create the background container
* Initializes the semi-transparent background overlay.
*/
private void createOverlayBackground() {
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
overlayBackground = new Geometry("Overlay", quad);
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Semi-transparent black
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
overlayBackground.setMaterial(material);
overlayBackground.setLocalTranslation(0, 0, 0);
}
/**
* Initializes the background container.
*/
private void createBackgroundContainer() {
backgroundContainer = new Container(); backgroundContainer = new Container();
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray background backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Darker background
} app.getGuiNode().attachChild(backgroundContainer);
/**
* Initializes the main event card container and its UI components.
*
* @param description the description of the triggered event card
*/
private void createEventCardContainer(String description) {
eventCardContainer = new Container(); eventCardContainer = new Container();
eventCardContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); eventCardContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f)));
eventCardContainer.setPreferredSize(new Vector3f(550, 400, 10)); eventCardContainer.setPreferredSize(new Vector3f(550,400,10));
// Title float padding = 10;
Label title = eventCardContainer.addChild(new Label("Ereigniskarte", new ElementId("settings-title"))); backgroundContainer.setPreferredSize(eventCardContainer.getPreferredSize().addLocal(padding, padding, 0));
title.setFontSize(48);
title.setColor(ColorRGBA.Black);
// Event description // Titel
Container textContainer = eventCardContainer.addChild(new Container()); Label gateFieldTitle = eventCardContainer.addChild(new Label("Ereigniskarte", new ElementId("settings-title")));
textContainer.addChild(new Label(description, new ElementId("label-Text"))); gateFieldTitle.setFontSize(48);
textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f))); gateFieldTitle.setColor(ColorRGBA.Black);
textContainer.setPreferredSize(new Vector3f(300, 200, 0));
// Confirm button // Text, der auf der Karte steht
Button confirmButton = eventCardContainer.addChild(new Button("Jawohl", new ElementId("button"))); // Die Erklärungsfelder werden automatisch den descriptions der Message entnommen
confirmButton.setFontSize(32); Container propertyValuesContainer = eventCardContainer.addChild(new Container());
confirmButton.addClickCommands(source -> ifTopDialog(() -> { propertyValuesContainer.addChild(new Label(description, new ElementId("label-Text")));
propertyValuesContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
propertyValuesContainer.setPreferredSize(new Vector3f(300,200,0));
// Beenden-Button
Button quitButton = eventCardContainer.addChild(new Button("Jawohl", new ElementId("button")));
quitButton.setFontSize(32);
quitButton.addClickCommands(source -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
close(); close();
})); }));
// Zentriere das Popup
eventCardContainer.setLocalTranslation(
(app.getCamera().getWidth() - eventCardContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + eventCardContainer.getPreferredSize().y) / 2,
10
);
// Zentriere das Popup
backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - eventCardContainer.getPreferredSize().x - padding) / 2,
(app.getCamera().getHeight() + eventCardContainer.getPreferredSize().y+ padding) / 2,
9
);
app.getGuiNode().attachChild(eventCardContainer);
} }
/** /**
* Displays the popup by attaching it to the GUI. * Creates a semi-transparent background overlay for the popup.
*
* @return the geometry of the overlay
*/ */
@Override private Geometry createOverlayBackground() {
public void show() { Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
float padding = 10; Geometry overlay = new Geometry("Overlay", quad);
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
// Adjust sizes and center elements material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f));
backgroundContainer.setPreferredSize(eventCardContainer.getPreferredSize().addLocal(padding, padding, 0)); material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
eventCardContainer.setLocalTranslation( overlay.setMaterial(material);
(app.getCamera().getWidth() - eventCardContainer.getPreferredSize().x) / 2, overlay.setLocalTranslation(0, 0, 0);
(app.getCamera().getHeight() + eventCardContainer.getPreferredSize().y) / 2, return overlay;
8
);
backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - eventCardContainer.getPreferredSize().x - padding) / 2,
(app.getCamera().getHeight() + eventCardContainer.getPreferredSize().y + padding) / 2,
7
);
// Attach components to the GUI
app.getGuiNode().attachChild(overlayBackground);
app.getGuiNode().attachChild(backgroundContainer);
app.getGuiNode().attachChild(eventCardContainer);
} }
/** /**
@@ -130,9 +117,9 @@ public class EventCardPopup extends Dialog implements PopupDialog {
*/ */
@Override @Override
public void close() { public void close() {
app.getGuiNode().detachChild(overlayBackground);
app.getGuiNode().detachChild(eventCardContainer); app.getGuiNode().detachChild(eventCardContainer);
app.getGuiNode().detachChild(backgroundContainer); app.getGuiNode().detachChild(backgroundContainer);
app.getGuiNode().detachChild(overlayBackground);
super.close(); super.close();
} }
@@ -143,4 +130,4 @@ public class EventCardPopup extends Dialog implements PopupDialog {
public void escape() { public void escape() {
close(); close();
} }
} }

View File

@@ -3,7 +3,6 @@ package pp.monopoly.client.gui.popups;
import com.jme3.material.Material; import com.jme3.material.Material;
import com.jme3.material.RenderState.BlendMode; import com.jme3.material.RenderState.BlendMode;
import com.jme3.math.ColorRGBA; import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry; import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Quad; import com.jme3.scene.shape.Quad;
import com.simsilica.lemur.Button; import com.simsilica.lemur.Button;
@@ -13,27 +12,27 @@ import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId; import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog; import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.MonopolyApp;
import pp.monopoly.client.gui.SettingsMenu;
import pp.monopoly.message.client.BuyPropertyResponse; import pp.monopoly.message.client.BuyPropertyResponse;
import pp.monopoly.model.fields.FoodField; import pp.monopoly.model.fields.FoodField;
import pp.monopoly.notification.Sound; import pp.monopoly.notification.Sound;
/** /**
* FoodFieldCard creates the popup for field information. * FoodFieldCard creates the popup for field information
*/ */
public class FoodFieldCard extends Dialog implements PopupDialog { public class FoodFieldCard extends Dialog {
/** Reference to the Monopoly application instance. */ /** Reference to the Monopoly application instance. */
private final MonopolyApp app; private final MonopolyApp app;
/** Semi-transparent overlay background for the popup. */ /** Semi-transparent overlay background for the popup. */
private Geometry overlayBackground; private final Geometry overlayBackground;
/** Main container for the food field information. */ /** Main container for the food field information. */
private Container foodFieldContainer; private final Container foodFieldContainer;
/** Background container providing a border for the popup. */ /** Background container providing a border for the popup. */
private Container backgroundContainer; private final Container backgroundContainer;
/** /**
* Constructs a FoodFieldCard popup displaying details about a food field. * Constructs a FoodFieldCard popup displaying details about a food field.
@@ -44,127 +43,108 @@ public class FoodFieldCard extends Dialog implements PopupDialog {
super(app.getDialogManager()); super(app.getDialogManager());
this.app = app; this.app = app;
// Retrieve field information
int index = app.getGameLogic().getPlayerHandler().getPlayerById(app.getId()).getFieldID(); int index = app.getGameLogic().getPlayerHandler().getPlayerById(app.getId()).getFieldID();
FoodField field = (FoodField) app.getGameLogic().getBoardManager().getFieldAtIndex(index); FoodField field = (FoodField) app.getGameLogic().getBoardManager().getFieldAtIndex(index);
// Create UI elements overlayBackground = createOverlayBackground();
createOverlayBackground(); app.getGuiNode().attachChild(overlayBackground);
createBackgroundContainer();
createFoodFieldContainer(field);
}
/**
* Initializes the semi-transparent background overlay.
*/
private void createOverlayBackground() {
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
overlayBackground = new Geometry("Overlay", quad);
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Semi-transparent
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
overlayBackground.setMaterial(material);
overlayBackground.setLocalTranslation(0, 0, 0);
}
/**
* Initializes the background container.
*/
private void createBackgroundContainer() {
backgroundContainer = new Container(); backgroundContainer = new Container();
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray background backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Darker background
attachChild(backgroundContainer);
}
/**
* Initializes the main food field container and its UI components.
*
* @param field the food field information to display
*/
private void createFoodFieldContainer(FoodField field) {
foodFieldContainer = new Container(); foodFieldContainer = new Container();
foodFieldContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.1f, 0.1f, 0.1f, 0.9f))); foodFieldContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.1f, 0.1f, 0.1f, 0.9f)));
foodFieldContainer.setPreferredSize(new Vector3f(360,445,1));
// Title float padding = 10;
Label title = foodFieldContainer.addChild(new Label(field.getName(), new ElementId("label-Bold"))); backgroundContainer.setPreferredSize(foodFieldContainer.getPreferredSize().addLocal(padding, padding, 0));
title.setFontSize(48);
title.setColor(ColorRGBA.White); Label settingsTitle = foodFieldContainer.addChild(new Label(field.getName(), new ElementId("label-Bold")));
settingsTitle.setFontSize(48);
settingsTitle.setColor(ColorRGBA.White);
// Field details
Container propertyValuesContainer = foodFieldContainer.addChild(new Container()); Container propertyValuesContainer = foodFieldContainer.addChild(new Container());
propertyValuesContainer.addChild(new Label("„Preis: " + field.getPrice() + " EUR", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("„Preis: " + field.getPrice() + " EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); // Empty line propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); // Leerzeile
propertyValuesContainer.addChild(new Label("Miete: 40x Würfel-Augen,", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("Wenn man Besitzer des", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("„wenn Besitzer eines ", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label(field.getName()+" ist, so ist die", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("„Restaurants.", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("Miete 40-mal so hoch, wie", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("„Miete: 100x Würfel-Augen, ", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("Augen auf den zwei Würfeln sind.", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("„wenn Besitzer eines ", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); // Leerzeile
propertyValuesContainer.addChild(new Label("Restaurants.", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("Wenn man Besitzer beider", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); // Empty line propertyValuesContainer.addChild(new Label("Restaurants ist, so ist die", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("Miete 100-mal so hoch, wie", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("Augen auf den zwei Würfeln sind.", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); // Leerzeile
propertyValuesContainer.addChild(new Label("„Hypothek: " + field.getHypo() + " EUR", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("„Hypothek: " + field.getHypo() + " EUR", new ElementId("label-Text")));
propertyValuesContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f))); propertyValuesContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
// Quit button // Beenden-Button
Button quitButton = foodFieldContainer.addChild(new Button("Beenden", new ElementId("button"))); Button quitButton = foodFieldContainer.addChild(new Button("Beenden", new ElementId("button")));
quitButton.setFontSize(32); quitButton.setFontSize(32);
quitButton.addClickCommands(s -> ifTopDialog(() -> { quitButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
close(); close();
})); }));
// Kaufen-Button
// Buy button
Button buyButton = foodFieldContainer.addChild(new Button("Kaufen", new ElementId("button"))); Button buyButton = foodFieldContainer.addChild(new Button("Kaufen", new ElementId("button")));
buyButton.setFontSize(32); buyButton.setFontSize(32);
buyButton.addClickCommands(s -> ifTopDialog(() -> { buyButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
app.getGameLogic().send(new BuyPropertyResponse()); app.getGameLogic().send(new BuyPropertyResponse());
close(); close();
})); }));
}
/** // Zentriere das Popup
* Displays the popup by attaching its elements to the GUI.
*/
@Override
public void show() {
float padding = 10;
// Adjust sizes and center elements
backgroundContainer.setPreferredSize(foodFieldContainer.getPreferredSize().addLocal(padding, padding, 0));
foodFieldContainer.setLocalTranslation( foodFieldContainer.setLocalTranslation(
(app.getCamera().getWidth() - foodFieldContainer.getPreferredSize().x) / 2, (app.getCamera().getWidth() - foodFieldContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + foodFieldContainer.getPreferredSize().y) / 2, (app.getCamera().getHeight() + foodFieldContainer.getPreferredSize().y) / 2,
8 8
); );
// Zentriere das Popup
backgroundContainer.setLocalTranslation( backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - foodFieldContainer.getPreferredSize().x - padding) / 2, (app.getCamera().getWidth() - foodFieldContainer.getPreferredSize().x - padding) / 2,
(app.getCamera().getHeight() + foodFieldContainer.getPreferredSize().y + padding) / 2, (app.getCamera().getHeight() + foodFieldContainer.getPreferredSize().y+ padding) / 2,
7 7
); );
// Attach components to the GUI
app.getGuiNode().attachChild(overlayBackground);
app.getGuiNode().attachChild(backgroundContainer);
app.getGuiNode().attachChild(foodFieldContainer); app.getGuiNode().attachChild(foodFieldContainer);
} }
/**
* Creates a semi-transparent background overlay for the popup.
*
* @return the geometry of the overlay
*/
private Geometry createOverlayBackground() {
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
Geometry overlay = new Geometry("Overlay", quad);
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Halbtransparent
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
overlay.setMaterial(material);
overlay.setLocalTranslation(0, 0, 0);
return overlay;
}
/** /**
* Closes the popup and removes its associated GUI elements. * Closes the popup and removes its associated GUI elements.
*/ */
@Override @Override
public void close() { public void close() {
app.getGuiNode().detachChild(overlayBackground); app.getGuiNode().detachChild(foodFieldContainer); // Entferne das Menü
app.getGuiNode().detachChild(foodFieldContainer); app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
app.getGuiNode().detachChild(backgroundContainer); app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
super.close(); super.close();
} }
/** /**
* Handles the escape key action by closing the popup. * Opens the settings menu when the escape key is pressed.
*/ */
@Override @Override
public void escape() { public void escape() {
close(); new SettingsMenu(app).open();
} }
} }

View File

@@ -1,15 +1,12 @@
package pp.monopoly.client.gui.popups; package pp.monopoly.client.gui.popups;
import com.jme3.math.ColorRGBA; import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.simsilica.lemur.Button; import com.simsilica.lemur.Button;
import com.simsilica.lemur.Container; import com.simsilica.lemur.Container;
import com.simsilica.lemur.Label; import com.simsilica.lemur.Label;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId; import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog; import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.MonopolyApp;
import pp.monopoly.client.gui.SettingsMenu; import pp.monopoly.client.gui.SettingsMenu;
import pp.monopoly.message.client.BuyPropertyResponse; import pp.monopoly.message.client.BuyPropertyResponse;
@@ -17,17 +14,17 @@ import pp.monopoly.model.fields.GateField;
import pp.monopoly.notification.Sound; import pp.monopoly.notification.Sound;
/** /**
* GateFieldCard creates the popup for field information. * GateFieldCard creates the popup for field information
*/ */
public class GateFieldCard extends Dialog implements PopupDialog { public class GateFieldCard extends Dialog {
/** Reference to the Monopoly application instance. */ /** Reference to the Monopoly application instance. */
private final MonopolyApp app; private final MonopolyApp app;
/** Main container for the gate field information. */ /** Main container for the gate field information. */
private Container gateFieldContainer; private final Container gateFieldContainer;
/** Background container providing a border for the popup. */ /** Background container providing a border for the popup. */
private Container backgroundContainer; private final Container backgroundContainer;
/** /**
* Constructs a GateFieldCard popup displaying details about a gate field. * Constructs a GateFieldCard popup displaying details about a gate field.
@@ -38,94 +35,73 @@ public class GateFieldCard extends Dialog implements PopupDialog {
super(app.getDialogManager()); super(app.getDialogManager());
this.app = app; this.app = app;
// Generate the corresponding field //Generate the corresponfing field
int index = app.getGameLogic().getPlayerHandler().getPlayerById(app.getId()).getFieldID(); int index = app.getGameLogic().getPlayerHandler().getPlayerById(app.getId()).getFieldID();
GateField field = (GateField) app.getGameLogic().getBoardManager().getFieldAtIndex(index); GateField field = (GateField) app.getGameLogic().getBoardManager().getFieldAtIndex(index);
// Initialize UI elements // Create the background container
createBackgroundContainer();
createGateFieldContainer(field);
}
/**
* Initializes the background container.
*/
private void createBackgroundContainer() {
backgroundContainer = new Container(); backgroundContainer = new Container();
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray background backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Darker background
} attachChild(backgroundContainer);
/** // Hauptcontainer für die Gebäudekarte
* Initializes the main gate field container and its UI components.
*
* @param field the gate field information to display
*/
private void createGateFieldContainer(GateField field) {
gateFieldContainer = new Container(); gateFieldContainer = new Container();
//TODO: Set the size of the container to the size of the screen @Simon
gateFieldContainer.setPreferredSize(new Vector3f(360,460,1));
gateFieldContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); gateFieldContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f)));
// Title float padding = 10; // Passt den backgroundContainer an die Größe des gateFieldContainers an
backgroundContainer.setPreferredSize(gateFieldContainer.getPreferredSize().addLocal(padding, padding, 0));
// Titel, bestehend aus dynamischen Namen anhand der ID und der Schriftfarbe/größe
Label gateFieldTitle = gateFieldContainer.addChild(new Label(field.getName(), new ElementId("label-Bold"))); Label gateFieldTitle = gateFieldContainer.addChild(new Label(field.getName(), new ElementId("label-Bold")));
gateFieldTitle.setFontSize(48); gateFieldTitle.setFontSize(48);
gateFieldTitle.setColor(ColorRGBA.Black); gateFieldTitle.setColor(ColorRGBA.Black);
// Field details // Text, der auf der Karte steht
// Die Preise werden dynamisch dem BoardManager entnommen
Container propertyValuesContainer = gateFieldContainer.addChild(new Container()); Container propertyValuesContainer = gateFieldContainer.addChild(new Container());
propertyValuesContainer.addChild(new Label("„Preis: " + field.getPrice() + " EUR", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("„Preis: " + field.getPrice() + " EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); // Empty line propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("Miete: 250 EUR", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("Miete: 250 EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("Wenn man 2 Tore", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("Wenn man", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("besitzt: 500 EUR", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("2 Bahnhof besitzt: 500 EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("Wenn man 3 Tore", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("Wenn man", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("besitzt: 1000 EUR", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("3 Bahnhof besitzt: 1000 EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("Wenn man 4 Tore", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("Wenn man", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("besitzt: 2000 EUR", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("4 Bahnhof besitzt: 2000 EUR", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); // Empty line propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));
propertyValuesContainer.addChild(new Label("„Hypothek: " + field.getHypo() + " EUR", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("„Hypothek: " + field.getHypo() + " EUR", new ElementId("label-Text")));
propertyValuesContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f))); propertyValuesContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
// Quit button // Beenden-Button
Button quitButton = gateFieldContainer.addChild(new Button("Beenden", new ElementId("button"))); Button quitButton = gateFieldContainer.addChild(new Button("Beenden", new ElementId("button")));
quitButton.setFontSize(32); quitButton.setFontSize(32);
quitButton.addClickCommands(s -> ifTopDialog(() -> { quitButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
close(); close();
})); }));
// Kaufen-Button
// Buy button
Button buyButton = gateFieldContainer.addChild(new Button("Kaufen", new ElementId("button"))); Button buyButton = gateFieldContainer.addChild(new Button("Kaufen", new ElementId("button")));
buyButton.setFontSize(32); buyButton.setFontSize(32);
buyButton.addClickCommands(s -> ifTopDialog(() -> { buyButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
app.getGameLogic().send(new BuyPropertyResponse()); app.getGameLogic().send(new BuyPropertyResponse());
close(); close();
})); }));
}
/** // Zentriere das Popup
* Displays the popup by attaching its elements to the GUI.
*/
@Override
public void show() {
float padding = 10;
// Adjust sizes and center elements
backgroundContainer.setPreferredSize(gateFieldContainer.getPreferredSize().addLocal(padding, padding, 0));
gateFieldContainer.setLocalTranslation( gateFieldContainer.setLocalTranslation(
(app.getCamera().getWidth() - gateFieldContainer.getPreferredSize().x) / 2, (app.getCamera().getWidth() - gateFieldContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + gateFieldContainer.getPreferredSize().y) / 2, (app.getCamera().getHeight() + gateFieldContainer.getPreferredSize().y) / 2,
8 8
); );
// Zentriere das Popup
backgroundContainer.setLocalTranslation( backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - gateFieldContainer.getPreferredSize().x - padding) / 2, (app.getCamera().getWidth() - gateFieldContainer.getPreferredSize().x - padding) / 2,
(app.getCamera().getHeight() + gateFieldContainer.getPreferredSize().y + padding) / 2, (app.getCamera().getHeight() + gateFieldContainer.getPreferredSize().y+ padding) / 2,
7 7
); );
// Attach components to the GUI
app.getGuiNode().attachChild(backgroundContainer);
app.getGuiNode().attachChild(gateFieldContainer); app.getGuiNode().attachChild(gateFieldContainer);
} }
@@ -134,8 +110,8 @@ public class GateFieldCard extends Dialog implements PopupDialog {
*/ */
@Override @Override
public void close() { public void close() {
app.getGuiNode().detachChild(gateFieldContainer); // Remove main container app.getGuiNode().detachChild(gateFieldContainer); // Entferne das Menü
app.getGuiNode().detachChild(backgroundContainer); // Remove background container app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
super.close(); super.close();
} }

View File

@@ -11,9 +11,7 @@ import com.simsilica.lemur.Container;
import com.simsilica.lemur.Label; import com.simsilica.lemur.Label;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId; import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog; import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.MonopolyApp;
import pp.monopoly.notification.Sound; import pp.monopoly.notification.Sound;
@@ -23,21 +21,21 @@ import pp.monopoly.notification.Sound;
* This popup informs the player that they are being sent to the Gulag and includes a confirmation button. * This popup informs the player that they are being sent to the Gulag and includes a confirmation button.
* </p> * </p>
*/ */
public class Gulag extends Dialog implements PopupDialog { public class Gulag extends Dialog {
/** Reference to the Monopoly application instance. */ /** Reference to the Monopoly application instance. */
private final MonopolyApp app; private final MonopolyApp app;
/** Semi-transparent overlay background for the popup. */ /** Semi-transparent overlay background for the popup. */
private Geometry overlayBackground; private final Geometry overlayBackground;
/** Main container for the Gulag warning message. */ /** Main container for the Gulag warning message. */
private Container gulagContainer; private final Container gulagContainer;
/** Background container providing a border for the popup. */ /** Background container providing a border for the popup. */
private Container backgroundContainer; private final Container backgroundContainer;
/** /**
* Constructs the Gulag popup. * Constructs the Gulag popup, displaying a warning when a player lands on the "Wache" field.
* *
* @param app the Monopoly application instance * @param app the Monopoly application instance
*/ */
@@ -45,97 +43,90 @@ public class Gulag extends Dialog implements PopupDialog {
super(app.getDialogManager()); super(app.getDialogManager());
this.app = app; this.app = app;
// Initialize UI elements
createOverlayBackground();
createBackgroundContainer();
createGulagContainer();
}
/** // Halbtransparentes Overlay hinzufügen
* Creates the semi-transparent overlay background for the popup. overlayBackground = createOverlayBackground();
*/ app.getGuiNode().attachChild(overlayBackground);
private void createOverlayBackground() {
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
overlayBackground = new Geometry("Overlay", quad);
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Semi-transparent black
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
overlayBackground.setMaterial(material);
overlayBackground.setLocalTranslation(0, 0, 0);
}
/** // Create the background container
* Creates the background container providing a border for the popup.
*/
private void createBackgroundContainer() {
backgroundContainer = new Container(); backgroundContainer = new Container();
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray background backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Darker background
} app.getGuiNode().attachChild(backgroundContainer);
/**
* Creates the main container for the Gulag warning message.
*/ // Hauptcontainer für die Warnung
private void createGulagContainer() {
gulagContainer = new Container(); gulagContainer = new Container();
gulagContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); gulagContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f)));
gulagContainer.setPreferredSize(new Vector3f(550, 250, 10)); gulagContainer.setPreferredSize(new Vector3f(550,250,10));
// Title float padding = 10; // Passt den backgroundContainer an die Größe des bankruptContainers an
Label title = gulagContainer.addChild(new Label("Du kommst ins Gulag!", new ElementId("warning-title"))); backgroundContainer.setPreferredSize(gulagContainer.getPreferredSize().addLocal(padding, padding, 0));
title.setFontSize(48);
title.setColor(ColorRGBA.Black);
// Confirmation Button // Titel
Button confirmButton = gulagContainer.addChild(new Button("Jawohl Gulag", new ElementId("button"))); Label gateFieldTitle = gulagContainer.addChild(new Label("Du kommst ins Gulag!", new ElementId("warning-title")));
confirmButton.setFontSize(32); gateFieldTitle.setFontSize(48);
confirmButton.addClickCommands(source -> ifTopDialog(() -> { gateFieldTitle.setColor(ColorRGBA.Black);
// Beenden-Button
Button quitButton = gulagContainer.addChild(new Button("Jawohl Gulag", new ElementId("button")));
quitButton.setFontSize(32);
quitButton.addClickCommands(source -> ifTopDialog(() -> {
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
close(); close();
})); }));
}
/**
* Displays the popup by attaching its elements to the GUI.
*/
@Override
public void show() {
float padding = 10;
// Adjust and position the containers // Zentriere das Popup
backgroundContainer.setPreferredSize(gulagContainer.getPreferredSize().addLocal(padding, padding, 0));
gulagContainer.setLocalTranslation( gulagContainer.setLocalTranslation(
(app.getCamera().getWidth() - gulagContainer.getPreferredSize().x) / 2, (app.getCamera().getWidth() - gulagContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + gulagContainer.getPreferredSize().y) / 2, (app.getCamera().getHeight() + gulagContainer.getPreferredSize().y) / 2,
8 8
); );
// Zentriere das Popup
backgroundContainer.setLocalTranslation( backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - gulagContainer.getPreferredSize().x - padding) / 2, (app.getCamera().getWidth() - gulagContainer.getPreferredSize().x - padding) / 2,
(app.getCamera().getHeight() + gulagContainer.getPreferredSize().y + padding) / 2, (app.getCamera().getHeight() + gulagContainer.getPreferredSize().y+ padding) / 2,
7 7
); );
// Attach components to the GUI
app.getGuiNode().attachChild(overlayBackground);
app.getGuiNode().attachChild(backgroundContainer);
app.getGuiNode().attachChild(gulagContainer); app.getGuiNode().attachChild(gulagContainer);
} }
/**
* Creates a semi-transparent overlay background for the popup.
*
* @return the geometry of the overlay
*/
private Geometry createOverlayBackground() {
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
Geometry overlay = new Geometry("Overlay", quad);
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Halbtransparent
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
overlay.setMaterial(material);
overlay.setLocalTranslation(0, 0, 0);
return overlay;
}
/** /**
* Closes the popup and removes its associated GUI elements. * Closes the popup and removes its associated GUI elements.
*/ */
@Override @Override
public void close() { public void close() {
app.getGuiNode().detachChild(overlayBackground); app.getGuiNode().detachChild(gulagContainer); // Entferne das Menü
app.getGuiNode().detachChild(gulagContainer); app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
app.getGuiNode().detachChild(backgroundContainer); app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
super.close(); super.close();
} }
/** /**
* Handles the escape action by closing the popup. * Handles the escape action to close the popup.
*/ */
@Override @Override
public void escape() { public void escape() {
close(); close();
} }
} }

View File

@@ -7,138 +7,112 @@ import com.simsilica.lemur.Label;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId; import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog; import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.MonopolyApp;
import pp.monopoly.client.gui.SettingsMenu;
import pp.monopoly.message.client.NotificationAnswer; import pp.monopoly.message.client.NotificationAnswer;
import pp.monopoly.notification.Sound; import pp.monopoly.notification.Sound;
/** /**
* GulagInfo is a popup that provides options for a player who is stuck in the "Gulag" (jail) field. * GulagInfo is a popup that provides options for a player who is stuck in the "Gulag" (jail) field.
* <p>
* This dialog offers multiple actions, including paying a bribe, using a "Get Out of Jail" card, or waiting. * This dialog offers multiple actions, including paying a bribe, using a "Get Out of Jail" card, or waiting.
* </p>
*/ */
public class GulagInfo extends Dialog implements PopupDialog { public class GulagInfo extends Dialog {
/** Reference to the Monopoly application instance. */ /** Reference to the Monopoly application instance. */
private final MonopolyApp app; private final MonopolyApp app;
/** Main container for the Gulag information dialog. */ /** Main container for the Gulag information dialog. */
private Container gulagInfoContainer; private final Container gulagInfoContainer;
/** Background container providing a styled border around the dialog. */ /** Background container providing a styled border around the dialog. */
private Container backgroundContainer; private final Container backgroundContainer;
/** /**
* Constructs a GulagInfo popup that provides the player with options for getting out of the "Gulag" field. * Constructs a GulagInfo popup that provides the player with options for getting out of the "Gulag" field.
* *
* @param app the Monopoly application instance * @param app the Monopoly application instance
* @param trys the number of failed attempts to roll doubles for release * @param trys the number of failed attempts to roll doubles for release
*/ */
public GulagInfo(MonopolyApp app, int trys) { public GulagInfo(MonopolyApp app, int trys) {
super(app.getDialogManager()); super(app.getDialogManager());
this.app = app; this.app = app;
// Initialize UI components // Create the background container
createBackgroundContainer();
createGulagInfoContainer(trys);
}
/**
* Creates the background container providing a border for the dialog.
*/
private void createBackgroundContainer() {
backgroundContainer = new Container(); backgroundContainer = new Container();
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray background backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Darker background
} attachChild(backgroundContainer);
/** // Hauptcontainer für das Bestätigungspopup
* Creates the main container for the Gulag information dialog.
*
* @param trys the number of failed attempts to roll doubles for release
*/
private void createGulagInfoContainer(int trys) {
gulagInfoContainer = new Container(); gulagInfoContainer = new Container();
gulagInfoContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f)));
// Title float padding = 10; // Passt den backgroundContainer an die Größe des confirmTradeContainer an
Label title = gulagInfoContainer.addChild(new Label("Gulag", new ElementId("warning-title"))); backgroundContainer.setPreferredSize(gulagInfoContainer.getPreferredSize().addLocal(padding, padding, 0));
// Titel
Label title = gulagInfoContainer.addChild(new Label( "Gulag", new ElementId("warning-title")));
title.setFontSize(48); title.setFontSize(48);
title.setColor(ColorRGBA.Black); title.setColor(ColorRGBA.Black);
// Text Description // Text, der auf der Karte steht
Container textContainer = gulagInfoContainer.addChild(new Container()); // Die Werte werden dem Handel entnommen (Iwas auch immer da dann ist)
textContainer.addChild(new Label("„Du sitzt im Gefängnis und kommst nicht raus ...", new ElementId("label-Text"))); Container propertyValuesContainer = gulagInfoContainer.addChild(new Container());
textContainer.addChild(new Label("Es sei denn, du ...", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("„Du sitzt im Gefänginis und kommst nicht raus ...", new ElementId("label-Text")));
textContainer.addChild(new Label("- bestichst die Wache mit 500 EUR", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("Es sei denn, du ...", new ElementId("label-Text")));// Leerzeile
textContainer.addChild(new Label("- löst eine Gulag-Frei-Karte ein", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));
textContainer.addChild(new Label("- wartest 3 Runden und bezahlst dann", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("- bestichst die Wache mit 500 EUR", new ElementId("label-Text")));
textContainer.addChild(new Label("- oder du würfelst einen Pasch", new ElementId("label-Text"))); propertyValuesContainer.addChild(new Label("- löst eine Gulag-Frei-Karte ein", new ElementId("label-Text")));
textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f))); propertyValuesContainer.addChild(new Label("- wartest 3 Runden und bezahlst dann", new ElementId("label-Text")));// Leerzeile
propertyValuesContainer.addChild(new Label("- oder du würfelst einen Pasch", new ElementId("label-Text")));
propertyValuesContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
// Action Buttons
addActionButtons(trys);
}
/** // Bezahlen-Button
* Adds action buttons to the dialog.
*
* @param trys the number of failed attempts to roll doubles for release
*/
private void addActionButtons(int trys) {
// Bribe Button
Button payButton = gulagInfoContainer.addChild(new Button("Bestechungsgeld bezahlen", new ElementId("button"))); Button payButton = gulagInfoContainer.addChild(new Button("Bestechungsgeld bezahlen", new ElementId("button")));
payButton.setFontSize(32); payButton.setFontSize(32);
payButton.addClickCommands(s -> ifTopDialog(() -> { payButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
app.getGameLogic().send(new NotificationAnswer("PayJail")); app.getGameLogic().send(new NotificationAnswer("PayJail"));
close(); close();
})); }));
// Ereigniskarte-Button
// Use Jail-Free Card Button Button eventCardButton = gulagInfoContainer.addChild(new Button("Ereigniskarte nutzen", new ElementId("button")));
Button eventCardButton = gulagInfoContainer.addChild(new Button("Ereigniskarte nutzen", new ElementId("button-toolbar2")));
eventCardButton.setFontSize(32); eventCardButton.setFontSize(32);
eventCardButton.addClickCommands(s -> ifTopDialog(() -> { eventCardButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
app.getGameLogic().send(new NotificationAnswer("UseJailCard")); app.getGameLogic().send(new NotificationAnswer("UseJailCard"));
close(); close();
})); }));
// Schließen-Button
// Close Button
Button closeButton = gulagInfoContainer.addChild(new Button("Schließen", new ElementId("button"))); Button closeButton = gulagInfoContainer.addChild(new Button("Schließen", new ElementId("button")));
closeButton.setFontSize(32); closeButton.setFontSize(32);
closeButton.addClickCommands(s -> ifTopDialog(this::close)); closeButton.addClickCommands(s -> ifTopDialog(() -> {
app.getGameLogic().playSound(Sound.BUTTON);
close();
}));
// Disable options based on conditions // Zentriere das Menü
if (app.getGameLogic().getPlayerHandler().getPlayerById(app.getId()).getNumJailCard() == 0) {
eventCardButton.setEnabled(false);
}
if (trys == 3) {
closeButton.setEnabled(false);
}
}
/**
* Displays the popup by attaching its elements to the GUI.
*/
@Override
public void show() {
float padding = 10;
// Adjust the background size
backgroundContainer.setPreferredSize(gulagInfoContainer.getPreferredSize().addLocal(padding, padding, 0));
// Center the dialog and background
gulagInfoContainer.setLocalTranslation( gulagInfoContainer.setLocalTranslation(
(app.getCamera().getWidth() - gulagInfoContainer.getPreferredSize().x) / 2, (app.getCamera().getWidth() - gulagInfoContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + gulagInfoContainer.getPreferredSize().y) / 2, (app.getCamera().getHeight() + gulagInfoContainer.getPreferredSize().y) / 2,
8 8
); );
// Zentriere das Menü
backgroundContainer.setLocalTranslation( backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - gulagInfoContainer.getPreferredSize().x - padding) / 2, (app.getCamera().getWidth() - gulagInfoContainer.getPreferredSize().x - padding) / 2,
(app.getCamera().getHeight() + gulagInfoContainer.getPreferredSize().y + padding) / 2, (app.getCamera().getHeight() + gulagInfoContainer.getPreferredSize().y+ padding) / 2,
7 7
); );
// Attach containers to the GUI if(app.getGameLogic().getPlayerHandler().getPlayerById(app.getId()).getNumJailCard() == 0) {
app.getGuiNode().attachChild(backgroundContainer); eventCardButton.setEnabled(false);
}
if(trys == 3) {
closeButton.setEnabled(false);
}
app.getGuiNode().attachChild(gulagInfoContainer); app.getGuiNode().attachChild(gulagInfoContainer);
} }
@@ -147,8 +121,16 @@ public class GulagInfo extends Dialog implements PopupDialog {
*/ */
@Override @Override
public void close() { public void close() {
app.getGuiNode().detachChild(gulagInfoContainer); // Remove dialog app.getGuiNode().detachChild(gulagInfoContainer); // Entferne das Menü
app.getGuiNode().detachChild(backgroundContainer); // Remove background app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
super.close(); super.close();
} }
/**
* Handles the escape action to close the GulagInfo dialog.
*/
@Override
public void escape() {
new SettingsMenu(app).open();
}
} }

View File

@@ -12,14 +12,19 @@ import com.simsilica.lemur.Label;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId; import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog; import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.MonopolyApp;
import pp.monopoly.notification.Sound; import pp.monopoly.notification.Sound;
/** /**
* NoMoneyWarning is a warning popup that informs the player they lack sufficient funds to proceed with an action. * NoMoneyWarning is a warning popup that appears when a player tries to perform
* an action they cannot afford due to insufficient funds, such as attempting
* to purchase a property or building.
* <p>
* This dialog notifies the player of their lack of funds and provides a single
* confirmation button to close the dialog.
* </p>
*/ */
public class NoMoneyWarning extends Dialog implements PopupDialog { public class NoMoneyWarning extends Dialog {
/** Reference to the Monopoly application instance. */ /** Reference to the Monopoly application instance. */
private final MonopolyApp app; private final MonopolyApp app;
@@ -41,15 +46,66 @@ public class NoMoneyWarning extends Dialog implements PopupDialog {
super(app.getDialogManager()); super(app.getDialogManager());
this.app = app; this.app = app;
overlayBackground = createOverlayBackground();
backgroundContainer = createBackgroundContainer();
noMoneyWarningContainer = createNoMoneyWarningContainer();
adjustPaddingAndCenter(); // Halbtransparentes Overlay hinzufügen
overlayBackground = createOverlayBackground();
app.getGuiNode().attachChild(overlayBackground);
// Create the background container
backgroundContainer = new Container();
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Darker background
app.getGuiNode().attachChild(backgroundContainer);
// Hauptcontainer für die Warnung
noMoneyWarningContainer = new Container();
noMoneyWarningContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f)));
noMoneyWarningContainer.setPreferredSize(new Vector3f(550,250,10));
float padding = 10; // Passt den backgroundContainer an die Größe des bankruptContainers an
backgroundContainer.setPreferredSize(noMoneyWarningContainer.getPreferredSize().addLocal(padding, padding, 0));
// Titel
Label gateFieldTitle = noMoneyWarningContainer.addChild(new Label("Na, schon wieder Pleite?", new ElementId("warning-title")));
gateFieldTitle.setFontSize(38);
gateFieldTitle.setColor(ColorRGBA.Black);
// Text, der im Popup steht
Container textContainer = noMoneyWarningContainer.addChild(new Container());
textContainer.addChild(new Label("Du hast nicht genug Geld, um dieses Gebäude zu kaufen", new ElementId("label-Text")));
textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
// Passt den textContainer an die Größe des bankruptContainers an
textContainer.setPreferredSize(noMoneyWarningContainer.getPreferredSize().addLocal(-250,-200,0));
// Bestätigen-Button
Button quitButton = noMoneyWarningContainer.addChild(new Button("Bestätigen", new ElementId("button")));
quitButton.setFontSize(32);
quitButton.addClickCommands(source -> ifTopDialog(() -> {
app.getGameLogic().playSound(Sound.BUTTON);
close();
}));
// Zentriere das Popup
noMoneyWarningContainer.setLocalTranslation(
(app.getCamera().getWidth() - noMoneyWarningContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + noMoneyWarningContainer.getPreferredSize().y) / 2,
8
);
// Zentriere das Popup
backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - noMoneyWarningContainer.getPreferredSize().x - padding) / 2,
(app.getCamera().getHeight() + noMoneyWarningContainer.getPreferredSize().y+ padding) / 2,
7
);
app.getGuiNode().attachChild(noMoneyWarningContainer);
} }
/** /**
* Creates the semi-transparent overlay background. * Creates a semi-transparent overlay background for the dialog.
* *
* @return The geometry representing the overlay background. * @return The geometry representing the overlay background.
*/ */
@@ -57,7 +113,7 @@ public class NoMoneyWarning extends Dialog implements PopupDialog {
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight()); Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
Geometry overlay = new Geometry("Overlay", quad); Geometry overlay = new Geometry("Overlay", quad);
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Semi-transparent black material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Halbtransparent
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha); material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
overlay.setMaterial(material); overlay.setMaterial(material);
overlay.setLocalTranslation(0, 0, 0); overlay.setLocalTranslation(0, 0, 0);
@@ -65,86 +121,13 @@ public class NoMoneyWarning extends Dialog implements PopupDialog {
} }
/** /**
* Creates the background container for the dialog. * Closes the menu and removes the GUI elements.
*
* @return A styled container for the dialog background.
*/
private Container createBackgroundContainer() {
Container container = new Container();
container.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray
return container;
}
/**
* Creates the main container for the NoMoneyWarning dialog UI.
*
* @return The container for the dialog content.
*/
private Container createNoMoneyWarningContainer() {
Container container = new Container();
container.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f)));
container.setPreferredSize(new Vector3f(550, 250, 10));
// Title
Label title = container.addChild(new Label("Na, schon wieder Pleite?", new ElementId("warning-title")));
title.setFontSize(38);
title.setColor(ColorRGBA.Black);
// Warning message
Container textContainer = container.addChild(new Container());
textContainer.addChild(new Label("Du hast nicht genug Geld, um dieses Gebäude zu kaufen", new ElementId("label-Text")));
textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
textContainer.setPreferredSize(container.getPreferredSize().addLocal(-250, -200, 0));
// Confirmation button
Button confirmButton = container.addChild(new Button("Bestätigen", new ElementId("button")));
confirmButton.setFontSize(32);
confirmButton.addClickCommands(source -> ifTopDialog(() -> {
app.getGameLogic().playSound(Sound.BUTTON);
close();
}));
return container;
}
/**
* Adjusts the padding and centers the dialog on the screen.
*/
private void adjustPaddingAndCenter() {
float padding = 10;
backgroundContainer.setPreferredSize(noMoneyWarningContainer.getPreferredSize().addLocal(padding, padding, 0));
noMoneyWarningContainer.setLocalTranslation(
(app.getCamera().getWidth() - noMoneyWarningContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + noMoneyWarningContainer.getPreferredSize().y) / 2,
8
);
backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - backgroundContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + backgroundContainer.getPreferredSize().y) / 2,
7
);
}
/**
* Displays the dialog by attaching its components to the GUI node.
*/
@Override
public void show() {
app.getGuiNode().attachChild(overlayBackground);
app.getGuiNode().attachChild(backgroundContainer);
app.getGuiNode().attachChild(noMoneyWarningContainer);
}
/**
* Closes the dialog and removes its components from the GUI node.
*/ */
@Override @Override
public void close() { public void close() {
app.getGuiNode().detachChild(overlayBackground); app.getGuiNode().detachChild(noMoneyWarningContainer); // Entferne das Menü
app.getGuiNode().detachChild(backgroundContainer); app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
app.getGuiNode().detachChild(noMoneyWarningContainer); app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
super.close(); super.close();
} }
@@ -155,4 +138,4 @@ public class NoMoneyWarning extends Dialog implements PopupDialog {
public void escape() { public void escape() {
close(); close();
} }
} }

View File

@@ -12,95 +12,115 @@ import com.simsilica.lemur.Label;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId; import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog; import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.MonopolyApp;
import pp.monopoly.notification.Sound; import pp.monopoly.notification.Sound;
/** /**
* ReceivedRent is a popup that informs a player about rent they have received. * Rent is a popup that is triggered when a player lands on a property owned by another player
* and needs to pay rent in the Monopoly application.
* <p>
* Displays the rent amount and the recipient player's name, with an option to confirm the payment.
* </p>
*/ */
public class ReceivedRent extends Dialog implements PopupDialog { public class ReceivedRent extends Dialog {
/** Reference to the Monopoly application instance. */ /** Reference to the Monopoly application instance. */
private final MonopolyApp app; private final MonopolyApp app;
/** Semi-transparent overlay background for the popup. */ /** Semi-transparent overlay background for the popup. */
private Geometry overlayBackground; private final Geometry overlayBackground;
/** Main container for the rent information and action. */ /** Main container for the rent information and action. */
private Container rentContainer; private final Container rentContainer;
/** Background container providing a border for the rent popup. */ /** Background container providing a border for the rent popup. */
private Container backgroundContainer; private final Container backgroundContainer;
/** /**
* Constructs the ReceivedRent popup displaying the rent amount and payer. * Constructs the Rent popup displaying the rent amount and recipient player.
* *
* @param app the Monopoly application instance * @param app the Monopoly application instance
* @param playerName the name of the player who paid the rent * @param playerName the name of the player to whom the rent is owed
* @param amount the amount of rent received * @param amount the amount of rent to be paid
*/ */
public ReceivedRent(MonopolyApp app, String playerName, int amount) { public ReceivedRent(MonopolyApp app, String playerName, int amount) {
super(app.getDialogManager()); super(app.getDialogManager());
this.app = app; this.app = app;
// Initialize GUI elements // Create the overlay
createOverlayBackground(); overlayBackground = createOverlayBackground();
createBackgroundContainer(); app.getGuiNode().attachChild(overlayBackground);
createRentContainer(playerName, amount);
// Create and position the background container
backgroundContainer = createBackgroundContainer();
app.getGuiNode().attachChild(backgroundContainer);
// Create and position the rent container
rentContainer = createRentContainer(playerName, amount);
app.getGuiNode().attachChild(rentContainer);
centerContainers();
} }
/** /**
* Creates a semi-transparent overlay background. * Creates a semi-transparent overlay background.
*
* @return the overlay geometry
*/ */
private void createOverlayBackground() { private Geometry createOverlayBackground() {
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight()); Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
overlayBackground = new Geometry("Overlay", quad); Geometry overlay = new Geometry("Overlay", quad);
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Semi-transparent black material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Semi-transparent black
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha); material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
overlayBackground.setMaterial(material); overlay.setMaterial(material);
overlayBackground.setLocalTranslation(0, 0, 0); overlay.setLocalTranslation(0, 0, 0);
return overlay;
} }
/** /**
* Creates the background container with styling. * Creates the background container with styling.
*
* @return the styled background container
*/ */
private void createBackgroundContainer() { private Container createBackgroundContainer() {
backgroundContainer = new Container(); Container container = new Container();
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray background container.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray background
return container;
} }
/** /**
* Creates the main rent container with title, text, and button. * Creates the main rent container with title, text, and button.
* *
* @param playerName the name of the player who paid the rent * @param playerName the name of the player to whom the rent is owed
* @param amount the rent amount * @param amount the rent amount
* @return the rent container
*/ */
private void createRentContainer(String playerName, int amount) { private Container createRentContainer(String playerName, int amount) {
rentContainer = new Container(); Container container = new Container();
rentContainer.setBackground(new QuadBackgroundComponent(ColorRGBA.Gray)); container.setBackground(new QuadBackgroundComponent(ColorRGBA.Gray));
rentContainer.setPreferredSize(new Vector3f(550, 250, 10)); container.setPreferredSize(new Vector3f(550, 250, 10));
// Title // Title
Label title = rentContainer.addChild(new Label("Miete!", new ElementId("warning-title"))); Label title = container.addChild(new Label("Miete!", new ElementId("warning-title")));
title.setFontSize(48); title.setFontSize(48);
title.setColor(ColorRGBA.Black); title.setColor(ColorRGBA.Black);
// Rent message // Rent message
Container textContainer = rentContainer.addChild(new Container()); Container textContainer = container.addChild(new Container());
textContainer.addChild(new Label(playerName + " zahlt dir " + amount + " EUR Miete", textContainer.addChild(new Label(playerName+ " zahlt dir " + amount + " EUR Miete",
new ElementId("label-Text"))); new ElementId("label-Text")));
textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f))); textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
textContainer.setPreferredSize(rentContainer.getPreferredSize().addLocal(-250, -200, 0)); textContainer.setPreferredSize(container.getPreferredSize().addLocal(-250, -200, 0));
// Confirmation button // Payment button
Button confirmButton = rentContainer.addChild(new Button("Bestätigen", new ElementId("button"))); Button payButton = container.addChild(new Button("Bestätigen", new ElementId("button")));
confirmButton.setFontSize(32); payButton.setFontSize(32);
confirmButton.addClickCommands(s -> ifTopDialog(() -> { payButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
close(); close();
})); }));
return container;
} }
/** /**
@@ -125,25 +145,14 @@ public class ReceivedRent extends Dialog implements PopupDialog {
); );
} }
/**
* Displays the popup by attaching it to the GUI through the DialogManager.
*/
@Override
public void show() {
app.getGuiNode().attachChild(overlayBackground);
app.getGuiNode().attachChild(backgroundContainer);
app.getGuiNode().attachChild(rentContainer);
centerContainers();
}
/** /**
* Closes the popup and removes GUI elements. * Closes the popup and removes GUI elements.
*/ */
@Override @Override
public void close() { public void close() {
app.getGuiNode().detachChild(overlayBackground);
app.getGuiNode().detachChild(backgroundContainer);
app.getGuiNode().detachChild(rentContainer); app.getGuiNode().detachChild(rentContainer);
app.getGuiNode().detachChild(backgroundContainer);
app.getGuiNode().detachChild(overlayBackground);
super.close(); super.close();
} }

View File

@@ -12,16 +12,19 @@ import com.simsilica.lemur.Label;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId; import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog; import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.MonopolyApp;
import pp.monopoly.message.server.TradeReply; import pp.monopoly.message.server.TradeReply;
import pp.monopoly.notification.Sound; import pp.monopoly.notification.Sound;
/** /**
* RejectTrade is a popup that appears when a trade proposal is rejected by another player. * RejectTrade is a popup that appears when a trade proposal is rejected by another player
* Displays a message indicating the rejection and provides an option to close the popup. * in the Monopoly application.
* <p>
* Displays a message indicating that the proposed trade has been declined, along with
* details of the involved players and provides an option to close the popup.
* </p>
*/ */
public class RejectTrade extends Dialog implements PopupDialog { public class RejectTrade extends Dialog {
/** Reference to the Monopoly application instance. */ /** Reference to the Monopoly application instance. */
private final MonopolyApp app; private final MonopolyApp app;
@@ -29,11 +32,12 @@ public class RejectTrade extends Dialog implements PopupDialog {
private final Geometry overlayBackground; private final Geometry overlayBackground;
/** Main container for the rejection message content. */ /** Main container for the rejection message content. */
private final Container rejectTradeContainer; private final Container noMoneyWarningContainer;
/** Background container providing a border for the popup. */ /** Background container providing a border for the popup. */
private final Container backgroundContainer; private final Container backgroundContainer;
/** /**
* Constructs the RejectTrade popup displaying the rejection of a trade proposal. * Constructs the RejectTrade popup displaying the rejection of a trade proposal.
* *
@@ -44,15 +48,68 @@ public class RejectTrade extends Dialog implements PopupDialog {
super(app.getDialogManager()); super(app.getDialogManager());
this.app = app; this.app = app;
overlayBackground = createOverlayBackground();
backgroundContainer = createBackgroundContainer();
rejectTradeContainer = createRejectTradeContainer(msg);
adjustPaddingAndCenter(); // Halbtransparentes Overlay hinzufügen
overlayBackground = createOverlayBackground();
app.getGuiNode().attachChild(overlayBackground);
// Create the background container
backgroundContainer = new Container();
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Darker background
app.getGuiNode().attachChild(backgroundContainer);
// Hauptcontainer für die Warnung
noMoneyWarningContainer = new Container();
noMoneyWarningContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f)));
noMoneyWarningContainer.setPreferredSize(new Vector3f(550,250,10));
float padding = 10; // Passt den backgroundContainer an die Größe des bankruptContainers an
backgroundContainer.setPreferredSize(noMoneyWarningContainer.getPreferredSize().addLocal(padding, padding, 0));
// Titel
Label gateFieldTitle = noMoneyWarningContainer.addChild(new Label("Handel abgelehnt!", new ElementId("warning-title")));
gateFieldTitle.setFontSize(48);
gateFieldTitle.setColor(ColorRGBA.Black);
// Text, der im Popup steht
Container textContainer = noMoneyWarningContainer.addChild(new Container());
textContainer.addChild(new Label("Du hast Spieler"+ " " + msg.getTradeHandler().getReceiver().getName() + " " + "einen Handel vorgeschlagen", new ElementId("label-Text")));
textContainer.addChild(new Label("", new ElementId("label-Text")));
textContainer.addChild(new Label("Der Handel wurde abgelehnt", new ElementId("label-Text")));
textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
// Passt den textContainer an die Größe des bankruptContainers an
textContainer.setPreferredSize(noMoneyWarningContainer.getPreferredSize().addLocal(-250,-200,0));
// Beenden-Button
Button quitButton = noMoneyWarningContainer.addChild(new Button("Bestätigen", new ElementId("button")));
quitButton.setFontSize(32);
quitButton.addClickCommands(source -> ifTopDialog(() -> {
app.getGameLogic().playSound(Sound.BUTTON);
close();
}));
// Zentriere das Popup
noMoneyWarningContainer.setLocalTranslation(
(app.getCamera().getWidth() - noMoneyWarningContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + noMoneyWarningContainer.getPreferredSize().y) / 2,
8
);
// Zentriere das Popup
backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - noMoneyWarningContainer.getPreferredSize().x - padding) / 2,
(app.getCamera().getHeight() + noMoneyWarningContainer.getPreferredSize().y+ padding) / 2,
7
);
app.getGuiNode().attachChild(noMoneyWarningContainer);
} }
/** /**
* Creates the semi-transparent background overlay for the popup. * Creates a semi-transparent background overlay for the popup.
* *
* @return the geometry of the overlay * @return the geometry of the overlay
*/ */
@@ -60,98 +117,21 @@ public class RejectTrade extends Dialog implements PopupDialog {
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight()); Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
Geometry overlay = new Geometry("Overlay", quad); Geometry overlay = new Geometry("Overlay", quad);
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Semi-transparent black material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Halbtransparent
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha); material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
overlay.setMaterial(material); overlay.setMaterial(material);
overlay.setLocalTranslation(0, 0, 0); overlay.setLocalTranslation(0, 0, 0);
return overlay; return overlay;
} }
/**
* Creates the background container for the dialog.
*
* @return A styled container for the dialog background.
*/
private Container createBackgroundContainer() {
Container container = new Container();
container.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray background
return container;
}
/**
* Creates the main container for the RejectTrade dialog UI.
*
* @param msg the trade reply message containing details about the rejected trade
* @return The container for the rejection message and action button
*/
private Container createRejectTradeContainer(TradeReply msg) {
Container container = new Container();
container.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f)));
container.setPreferredSize(new Vector3f(550, 250, 10));
// Title
Label title = container.addChild(new Label("Handel abgelehnt!", new ElementId("warning-title")));
title.setFontSize(48);
title.setColor(ColorRGBA.Black);
// Rejection message
Container textContainer = container.addChild(new Container());
textContainer.addChild(new Label("Du hast " + msg.getTradeHandler().getReceiver().getName()
+ " einen Handel vorgeschlagen.", new ElementId("label-Text")));
textContainer.addChild(new Label("", new ElementId("label-Text")));
textContainer.addChild(new Label("Der Handel wurde abgelehnt.", new ElementId("label-Text")));
textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
textContainer.setPreferredSize(container.getPreferredSize().addLocal(-250, -200, 0));
// Confirmation button
Button confirmButton = container.addChild(new Button("Bestätigen", new ElementId("button")));
confirmButton.setFontSize(32);
confirmButton.addClickCommands(source -> ifTopDialog(() -> {
app.getGameLogic().playSound(Sound.BUTTON);
close();
}));
return container;
}
/**
* Adjusts the padding and centers the dialog on the screen.
*/
private void adjustPaddingAndCenter() {
float padding = 10;
backgroundContainer.setPreferredSize(rejectTradeContainer.getPreferredSize().addLocal(padding, padding, 0));
rejectTradeContainer.setLocalTranslation(
(app.getCamera().getWidth() - rejectTradeContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + rejectTradeContainer.getPreferredSize().y) / 2,
8
);
backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - backgroundContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + backgroundContainer.getPreferredSize().y) / 2,
7
);
}
/**
* Displays the popup by attaching its elements to the GUI node.
*/
@Override
public void show() {
app.getGuiNode().attachChild(overlayBackground);
app.getGuiNode().attachChild(backgroundContainer);
app.getGuiNode().attachChild(rejectTradeContainer);
}
/** /**
* Closes the menu and removes the GUI elements. * Closes the menu and removes the GUI elements.
*/ */
@Override @Override
public void close() { public void close() {
app.getGuiNode().detachChild(overlayBackground); app.getGuiNode().detachChild(noMoneyWarningContainer); // Entferne das Menü
app.getGuiNode().detachChild(backgroundContainer); app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
app.getGuiNode().detachChild(rejectTradeContainer); app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
super.close(); super.close();
} }
@@ -162,4 +142,4 @@ public class RejectTrade extends Dialog implements PopupDialog {
public void escape() { public void escape() {
close(); close();
} }
} }

View File

@@ -12,7 +12,6 @@ import com.simsilica.lemur.Label;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.style.ElementId; import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog; import pp.dialog.Dialog;
import pp.dialog.PopupDialog;
import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.MonopolyApp;
import pp.monopoly.notification.Sound; import pp.monopoly.notification.Sound;
@@ -23,77 +22,122 @@ import pp.monopoly.notification.Sound;
* Displays the rent amount and the recipient player's name, with an option to confirm the payment. * Displays the rent amount and the recipient player's name, with an option to confirm the payment.
* </p> * </p>
*/ */
public class Rent extends Dialog implements PopupDialog { public class Rent extends Dialog {
/** Reference to the Monopoly application instance. */
private final MonopolyApp app; private final MonopolyApp app;
/** Semi-transparent overlay background for the popup. */
private final Geometry overlayBackground; private final Geometry overlayBackground;
/** Main container for the rent information and action. */
private final Container rentContainer; private final Container rentContainer;
/** Background container providing a border for the rent popup. */
private final Container backgroundContainer; private final Container backgroundContainer;
/**
* Constructs the Rent popup displaying the rent amount and recipient player.
*
* @param app the Monopoly application instance
* @param playerName the name of the player to whom the rent is owed
* @param amount the amount of rent to be paid
*/
public Rent(MonopolyApp app, String playerName, int amount) { public Rent(MonopolyApp app, String playerName, int amount) {
super(app.getDialogManager()); super(app.getDialogManager());
this.app = app; this.app = app;
// Create the overlay and containers // Create the overlay
overlayBackground = createOverlayBackground(); overlayBackground = createOverlayBackground();
backgroundContainer = createBackgroundContainer(); app.getGuiNode().attachChild(overlayBackground);
rentContainer = createRentContainer(playerName, amount);
// Create and position the background container
backgroundContainer = createBackgroundContainer();
app.getGuiNode().attachChild(backgroundContainer);
// Create and position the rent container
rentContainer = createRentContainer(playerName, amount);
app.getGuiNode().attachChild(rentContainer);
// Center containers (positioning logic only, no GUI attachment)
centerContainers(); centerContainers();
} }
/**
* Creates a semi-transparent overlay background.
*
* @return the overlay geometry
*/
private Geometry createOverlayBackground() { private Geometry createOverlayBackground() {
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight()); Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
Geometry overlay = new Geometry("Overlay", quad); Geometry overlay = new Geometry("Overlay", quad);
Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Semi-transparent black
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha); material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
overlay.setMaterial(material); overlay.setMaterial(material);
overlay.setLocalTranslation(0, 0, 0); overlay.setLocalTranslation(0, 0, 0);
return overlay; return overlay;
} }
/**
* Creates the background container with styling.
*
* @return the styled background container
*/
private Container createBackgroundContainer() { private Container createBackgroundContainer() {
Container container = new Container(); Container container = new Container();
container.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); container.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray background
return container; return container;
} }
/**
* Creates the main rent container with title, text, and button.
*
* @param playerName the name of the player to whom the rent is owed
* @param amount the rent amount
* @return the rent container
*/
private Container createRentContainer(String playerName, int amount) { private Container createRentContainer(String playerName, int amount) {
Container container = new Container(); Container container = new Container();
container.setBackground(new QuadBackgroundComponent(ColorRGBA.Gray)); container.setBackground(new QuadBackgroundComponent(ColorRGBA.Gray));
container.setPreferredSize(new Vector3f(550, 250, 10)); container.setPreferredSize(new Vector3f(550, 250, 10));
// Title
Label title = container.addChild(new Label("Miete!", new ElementId("warning-title"))); Label title = container.addChild(new Label("Miete!", new ElementId("warning-title")));
title.setFontSize(48); title.setFontSize(48);
title.setColor(ColorRGBA.Black); title.setColor(ColorRGBA.Black);
// Rent message
Container textContainer = container.addChild(new Container()); Container textContainer = container.addChild(new Container());
textContainer.addChild(new Label("Du musst " + amount + " EUR Miete an " + playerName + " zahlen", textContainer.addChild(new Label("Du musst " + amount + " EUR Miete an " + playerName + " zahlen",
new ElementId("label-Text"))); new ElementId("label-Text")));
textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f))); textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
textContainer.setPreferredSize(container.getPreferredSize().addLocal(-250, -200, 0)); textContainer.setPreferredSize(container.getPreferredSize().addLocal(-250, -200, 0));
// Payment button
Button payButton = container.addChild(new Button("Überweisen", new ElementId("button"))); Button payButton = container.addChild(new Button("Überweisen", new ElementId("button")));
payButton.setFontSize(32); payButton.setFontSize(32);
payButton.addClickCommands(s -> ifTopDialog(() -> { payButton.addClickCommands(s -> ifTopDialog( () -> {
app.getGameLogic().playSound(Sound.BUTTON); app.getGameLogic().playSound(Sound.BUTTON);
close(); close();
})); }));
return container; return container;
} }
/**
* Centers the rent and background containers on the screen.
*/
private void centerContainers() { private void centerContainers() {
float padding = 10; float padding = 10;
// Center rent container
rentContainer.setLocalTranslation( rentContainer.setLocalTranslation(
(app.getCamera().getWidth() - rentContainer.getPreferredSize().x) / 2, (app.getCamera().getWidth() - rentContainer.getPreferredSize().x) / 2,
(app.getCamera().getHeight() + rentContainer.getPreferredSize().y) / 2, (app.getCamera().getHeight() + rentContainer.getPreferredSize().y) / 2,
8 8
); );
// Center background container with padding
backgroundContainer.setPreferredSize(rentContainer.getPreferredSize().addLocal(padding, padding, 0)); backgroundContainer.setPreferredSize(rentContainer.getPreferredSize().addLocal(padding, padding, 0));
backgroundContainer.setLocalTranslation( backgroundContainer.setLocalTranslation(
(app.getCamera().getWidth() - backgroundContainer.getPreferredSize().x) / 2, (app.getCamera().getWidth() - backgroundContainer.getPreferredSize().x) / 2,
@@ -102,25 +146,22 @@ public class Rent extends Dialog implements PopupDialog {
); );
} }
@Override /**
public void show() { * Closes the popup and removes GUI elements.
// Attach components to GUI only when the dialog is displayed via DialogManager */
app.getGuiNode().attachChild(overlayBackground);
app.getGuiNode().attachChild(backgroundContainer);
app.getGuiNode().attachChild(rentContainer);
}
@Override @Override
public void close() { public void close() {
app.getGuiNode().detachChild(overlayBackground);
app.getGuiNode().detachChild(backgroundContainer);
app.getGuiNode().detachChild(rentContainer); app.getGuiNode().detachChild(rentContainer);
app.getGuiNode().detachChild(backgroundContainer);
app.getGuiNode().detachChild(overlayBackground);
super.close(); super.close();
} }
/**
* Handles the escape action to close the dialog.
*/
@Override @Override
public void escape() { public void escape() {
close(); close();
} }
} }

View File

@@ -7,6 +7,7 @@ import com.simsilica.lemur.Button;
import com.simsilica.lemur.Container; import com.simsilica.lemur.Container;
import com.simsilica.lemur.Label; import com.simsilica.lemur.Label;
import com.simsilica.lemur.Selector; import com.simsilica.lemur.Selector;
import com.simsilica.lemur.TextField;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.component.SpringGridLayout; import com.simsilica.lemur.component.SpringGridLayout;
import com.simsilica.lemur.core.VersionedList; import com.simsilica.lemur.core.VersionedList;

View File

@@ -7,6 +7,7 @@ import com.simsilica.lemur.Button;
import com.simsilica.lemur.Container; import com.simsilica.lemur.Container;
import com.simsilica.lemur.Label; import com.simsilica.lemur.Label;
import com.simsilica.lemur.Selector; import com.simsilica.lemur.Selector;
import com.simsilica.lemur.TextField;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.component.SpringGridLayout; import com.simsilica.lemur.component.SpringGridLayout;
import com.simsilica.lemur.core.VersionedList; import com.simsilica.lemur.core.VersionedList;

View File

@@ -7,6 +7,7 @@ import com.simsilica.lemur.Button;
import com.simsilica.lemur.Container; import com.simsilica.lemur.Container;
import com.simsilica.lemur.Label; import com.simsilica.lemur.Label;
import com.simsilica.lemur.Selector; import com.simsilica.lemur.Selector;
import com.simsilica.lemur.TextField;
import com.simsilica.lemur.component.QuadBackgroundComponent; import com.simsilica.lemur.component.QuadBackgroundComponent;
import com.simsilica.lemur.component.SpringGridLayout; import com.simsilica.lemur.component.SpringGridLayout;
import com.simsilica.lemur.core.VersionedList; import com.simsilica.lemur.core.VersionedList;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 304 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 473 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 KiB

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 588 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 707 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 215 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 478 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 518 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 552 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 215 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

View File

@@ -327,11 +327,6 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker {
board.add(new Hotel(property.getId())); board.add(new Hotel(property.getId()));
} else { } else {
for(int i = 0; i < 4; i++) {
board.remove(board.getHouse(msg.getId(), i+1));
}
board.add(new House( property.getHouses(), property.getId())); board.add(new House( property.getHouses(), property.getId()));
} }
} else { } else {

View File

@@ -492,8 +492,7 @@ public class Player implements FieldVisitor<Void>{
} }
return total; return total;
} }
private static int c = 0; // private static int c = 0;
private static int[] rolls = {4,4, 1,2, 2,3};
/** /**
* Inner class for dice functionality in the game. * Inner class for dice functionality in the game.
@@ -508,20 +507,8 @@ public class Player implements FieldVisitor<Void>{
* @return the result of a dice roll (1 to 6) * @return the result of a dice roll (1 to 6)
*/ */
private static int rollDice() { private static int rollDice() {
// return random.nextInt(6) + 1; return random.nextInt(6) + 1;
// c++; // c++;
if(c >= rolls.length) return random.nextInt(6) + 1;
System.out.println();
System.out.println();
System.out.println();
System.out.println();
System.out.println("DICEEEEEEEEEEEEEEEEEEEEE");
System.out.println();
System.out.println();
System.out.println();
System.out.println();
System.out.println();
return rolls[c++];
// return (c%2 == 0)? 3: 2; // return (c%2 == 0)? 3: 2;
// if(c < 7) { // if(c < 7) {
// return 3; // return 3;

View File

@@ -120,7 +120,7 @@ public class PlayerHandler {
* @param index the index of the queue * @param index the index of the queue
* @return the Player at the required index * @return the Player at the required index
*/ */
public Player getPlayerAtIndex(int index) { Player getPlayerAtIndex(int index) {
return players.get(index); return players.get(index);
} }
@@ -165,11 +165,10 @@ public class PlayerHandler {
* Shuffles the players and sets their state to WaitForNextTurn, the first one will be active * Shuffles the players and sets their state to WaitForNextTurn, the first one will be active
*/ */
void randomOrder() { void randomOrder() {
// Collections.shuffle(players); Collections.shuffle(players);
// for (Player player : players) { for (Player player : players) {
// player.finishTurn(); player.finishTurn();
// } }
nextPlayer();
players.get(0).setActive(); players.get(0).setActive();
} }

View File

@@ -229,8 +229,6 @@ public class ServerGameLogic implements ClientInterpreter {
for (Player p : playerHandler.getPlayers()) { for (Player p : playerHandler.getPlayers()) {
send(p, new GameStart(playerHandler)); send(p, new GameStart(playerHandler));
} }
playerHandler.randomOrder(); playerHandler.randomOrder();
send(playerHandler.getPlayerAtIndex(0), new NextPlayerTurn()); send(playerHandler.getPlayerAtIndex(0), new NextPlayerTurn());
} }
@@ -474,7 +472,7 @@ public class ServerGameLogic implements ClientInterpreter {
// Define properties to assign // Define properties to assign
Set<Integer> p1Properties = Set.of(1, 3, 6, 8); // Gym, Sportplatz, Studium+, PhysikHörsaal Set<Integer> p1Properties = Set.of(1, 3, 6, 8); // Gym, Sportplatz, Studium+, PhysikHörsaal
Set<Integer> p2Properties = Set.of(21, 23, 24, 9, 11); // Red set + Audimax + Spießtor Set<Integer> p2Properties = Set.of(21, 23, 24, 9); // Red set + Audimax
// Assign properties via AlterProperty // Assign properties via AlterProperty
assignProperties(p1, p1Properties); assignProperties(p1, p1Properties);
@@ -485,15 +483,13 @@ public class ServerGameLogic implements ClientInterpreter {
// Player 2 builds houses on the Red set // Player 2 builds houses on the Red set
// buildHouses(p2, Set.of(21, 23, 24)); // buildHouses(p2, Set.of(21, 23, 24));
// buildHouses(p2, Set.of(23, 24));
// // buildHouses(p2, Set.of( 24));
// Set player balances // Set player balances
p1.setAccountBalance(12325); p1.setAccountBalance(12325);
p2.setAccountBalance(26750); p2.setAccountBalance(26750);
// Add Get Out of Jail cards // Add Get Out of Jail cards
p2.addJailCard(); p1.addJailCard();
// Set player positions // Set player positions
p1.setPosition(6); // Near Studium+ p1.setPosition(6); // Near Studium+
@@ -518,8 +514,6 @@ public class ServerGameLogic implements ClientInterpreter {
field.setOwner(player); field.setOwner(player);
player.addProperty(propertyId); player.addProperty(propertyId);
} }
updateAllPlayers();
LOGGER.log(Level.DEBUG, "Properties assigned to player {0}: {1}", player.getName(), properties); LOGGER.log(Level.DEBUG, "Properties assigned to player {0}: {1}", player.getName(), properties);
} }
@@ -538,8 +532,6 @@ public class ServerGameLogic implements ClientInterpreter {
if (boardManager.canBuild(field) && player.getAccountBalance() >= field.getHousePrice()) { if (boardManager.canBuild(field) && player.getAccountBalance() >= field.getHousePrice()) {
field.build(); field.build();
player.pay(field.getHousePrice()); player.pay(field.getHousePrice());
updateAllPlayers();
sendAll( new BuildInfo(field.getId(), true));
LOGGER.log(Level.DEBUG, "House built on property {0} for player {1}.", field.getName(), player.getName()); LOGGER.log(Level.DEBUG, "House built on property {0} for player {1}.", field.getName(), player.getName());
} }
} }

View File

@@ -147,10 +147,6 @@ public class Board {
return getHotels().filter(hotel -> hotel.getFieldID() == fieldId).findFirst().orElse(null); return getHotels().filter(hotel -> hotel.getFieldID() == fieldId).findFirst().orElse(null);
} }
public Figure getFigure(int playerId) {
return getFigures().filter(figure -> figure.getId() == playerId).findFirst().orElse(null);
}
/** /**
* Returns a stream of all hotels currently on the map. * Returns a stream of all hotels currently on the map.
* *

View File

@@ -17,26 +17,25 @@ public class DeckHelper{
public DeckHelper() { public DeckHelper() {
cards = new LinkedList<Card>(); cards = new LinkedList<Card>();
cards.add(new Card("Dein Jodel eines Schneepenis mit Unterhodenbeleuchtung geht viral. Ziehe 1000 EUR ein", "jodel-eispenis"));
cards.add(new Card("Auf deiner Stube wurde Schimmel gefunden. Gehe ins Gulak. Begib dich direkt dorthin. Gehe nicht über Monatsgehalt. Ziehe nicht 2000 EUR ein.", "schimmel-gulak"));
cards.add(new Card("Malkmus läd zum Pubquiz ein. Rücke vor bis zum 20er.", "pubquiz"));
cards.add(new Card("Du wurdest mit einem Dienst KFZ geblitzt. Zahle 800 EUR", "dienst-kfz-blitzer")); cards.add(new Card("Du wurdest mit einem Dienst KFZ geblitzt. Zahle 800 EUR", "dienst-kfz-blitzer"));
cards.add(new Card("Die erste Spoparty steht bevor. Ziehe vor zum 23er.", "spoparty")); cards.add(new Card("Die erste Spoparty steht bevor. Ziehe vor zum 23er.", "spoparty"));
cards.add(new Card("Deine IGF-Daten sind verschwunden. Statte Padubrin einen Besuch ab und gib ihm einen Jägermeister aus. Zahle 250 EUR", "IGF-Padubrin"));
cards.add(new Card("Du kommst aus dem Gulak frei!", "gulak-frei-1")); cards.add(new Card("Du kommst aus dem Gulak frei!", "gulak-frei-1"));
cards.add(new Card("Du kommst aus dem Gulak frei!", "gulak-frei-2")); cards.add(new Card("Du kommst aus dem Gulak frei!", "gulak-frei-2"));
cards.add(new Card("Du hast den Dienstführerschein bestanden. Ziehe vor bis Teststrecke.", "dienstfuehrerschein")); cards.add(new Card("Du hast den Dienstführerschein bestanden. Ziehe vor bis Teststrecke.", "dienstfuehrerschein"));
cards.add(new Card("Malkmus läd zum Pubquiz ein. Rücke vor bis zum 20er.", "pubquiz"));
cards.add(new Card("Deine IGF-Daten sind verschwunden. Statte Padubrin einen Besuch ab und gib ihm einen Jägermeister aus. Zahle 250 EUR", "IGF-Padubrin"));
cards.add(new Card("Du hast heute die Spendierhosen an und gibst eine Runde in der Unibar. Zahle jedem Spieler 400 EUR", "spendierhosen-unibar")); cards.add(new Card("Du hast heute die Spendierhosen an und gibst eine Runde in der Unibar. Zahle jedem Spieler 400 EUR", "spendierhosen-unibar"));
cards.add(new Card("Du musstest einen Rückstuferantrag stellen. Setze eine Runde aus.", "rueckstuferantrag"));
cards.add(new Card("Du warst in der Prüfungsphase krank. Gehe 3 Felder zurück.", "pruefungsphase-krank")); cards.add(new Card("Du warst in der Prüfungsphase krank. Gehe 3 Felder zurück.", "pruefungsphase-krank"));
cards.add(new Card("Ziehe vor bis zum nächsten Monatsgehalt.", "naechstes-monatsgehalt")); cards.add(new Card("Ziehe vor bis zum nächsten Monatsgehalt.", "naechstes-monatsgehalt"));
cards.add(new Card("Du hast ein Antreten verschlafen. Zahle 500 EUR", "antreten-verschlafen-1")); cards.add(new Card("Du hast ein Antreten verschlafen. Zahle 500 EUR", "antreten-verschlafen-1"));
cards.add(new Card("Du hast den Maibock organisiert. Du erhältst 3000 EUR", "maibock-organisiert")); cards.add(new Card("Du hast den Maibock organisiert. Du erhältst 3000 EUR", "maibock-organisiert"));
cards.add(new Card("Der Spieß macht eine unangekündigte Inventur. Zahle für jedes Haus 400 EUR und für jedes Hotel 2800 EUR", "inventur-haeuser-hotels")); cards.add(new Card("Der Spieß macht eine unangekündigte Inventur. Zahle für jedes Haus 400 EUR und für jedes Hotel 2800 EUR", "inventur-haeuser-hotels"));
cards.add(new Card("Es gab keine Mozzarella-Bällchen mehr für Thoma. Rücke vor bis aufs Gym.", "dienstsport-gym")); cards.add(new Card("Es gab keine Mozzarella-Bällchen mehr für Thoma. Rücke vor bis aufs Gym.", "dienstsport-gym"));
cards.add(new Card("Auf deiner Stube wurde Schimmel gefunden. Gehe ins Gulak. Begib dich direkt dorthin. Gehe nicht über Monatsgehalt. Ziehe nicht 2000 EUR ein.", "schimmel-gulak"));
cards.add(new Card("Deine Stube ist nach einer Partynacht nicht mehr bewohnbar. Du ziehst ins Gulak. Begib dich direkt dorthin. Gehe nicht über Monatsgehalt. Ziehe nicht 2000 EUR ein.", "partynacht-gulak")); cards.add(new Card("Deine Stube ist nach einer Partynacht nicht mehr bewohnbar. Du ziehst ins Gulak. Begib dich direkt dorthin. Gehe nicht über Monatsgehalt. Ziehe nicht 2000 EUR ein.", "partynacht-gulak"));
cards.add(new Card("Das Jahresabschlussantreten steht an. Ziehe vor bis Schwimmhalle.", "jahresabschlussantreten")); cards.add(new Card("Das Jahresabschlussantreten steht an. Ziehe vor bis Schwimmhalle.", "jahresabschlussantreten"));
cards.add(new Card("Du wurdest beim Verkaufen von Versicherungen erwischt. Zahle 4000 EUR", "verkaufen-versicherungen")); cards.add(new Card("Du wurdest beim Verkaufen von Versicherungen erwischt. Zahle 4000 EUR", "verkaufen-versicherungen"));
cards.add(new Card("Du musstest einen Rückstuferantrag stellen. Setze eine Runde aus.", "rueckstuferantrag"));
cards.add(new Card("Auf einer Hausfeier bist du betrunken auf der Treppe gestürzt und dabei auf einen Kameraden gefallen. Zahle 800 EUR und gehe zurück zum SanZ.", "hausfeier-sturz")); cards.add(new Card("Auf einer Hausfeier bist du betrunken auf der Treppe gestürzt und dabei auf einen Kameraden gefallen. Zahle 800 EUR und gehe zurück zum SanZ.", "hausfeier-sturz"));
cards.add(new Card("Beförderung. Beim nächsten Monatsgehalt ziehst du 3000 EUR ein", "befoerderung")); cards.add(new Card("Beförderung. Beim nächsten Monatsgehalt ziehst du 3000 EUR ein", "befoerderung"));
cards.add(new Card("Du entscheidest dich für eine Dienstreise nach Lourd. Zahle 1000 EUR und setze eine Runde aus.", "dienstreise-lourd")); cards.add(new Card("Du entscheidest dich für eine Dienstreise nach Lourd. Zahle 1000 EUR und setze eine Runde aus.", "dienstreise-lourd"));
@@ -49,8 +48,9 @@ public class DeckHelper{
cards.add(new Card("Du wurdest zur VP gewählt und schmeißt eine Einstandsparty. Zahle 800 EUR", "vp-einstandsparty")); cards.add(new Card("Du wurdest zur VP gewählt und schmeißt eine Einstandsparty. Zahle 800 EUR", "vp-einstandsparty"));
cards.add(new Card("Du hast eine Party veranstaltet und dick Gewinn gemacht. Ziehe 1500 EUR ein", "party-gewinn")); cards.add(new Card("Du hast eine Party veranstaltet und dick Gewinn gemacht. Ziehe 1500 EUR ein", "party-gewinn"));
cards.add(new Card("Zur falschen Zeit am falschen Ort. Du musst einen Bergmarsch planen und setzt eine Runde aus.", "bergmarsch")); cards.add(new Card("Zur falschen Zeit am falschen Ort. Du musst einen Bergmarsch planen und setzt eine Runde aus.", "bergmarsch"));
cards.add(new Card("Dein Jodel eines Schneepenis mit Unterhodenbeleuchtung geht viral. Ziehe 1000 EUR ein", "jodel-eispenis"));
// shuffle(); shuffle();
} }
public void visit(Card card, Player player) { public void visit(Card card, Player player) {

View File

@@ -54,7 +54,7 @@ public class BoardManager {
fields.add(new EventField("Üvas", 22)); fields.add(new EventField("Üvas", 22));
fields.add(new BuildingProperty("StudFBer B", 23, 2200, 180, 1500, FieldColor.RED)); fields.add(new BuildingProperty("StudFBer B", 23, 2200, 180, 1500, FieldColor.RED));
fields.add(new BuildingProperty("StudFBer A", 24, 2400, 200, 1500, FieldColor.RED)); fields.add(new BuildingProperty("StudFBer A", 24, 2400, 200, 1500, FieldColor.RED));
fields.add(new GateField("Spießtor", 25)); fields.add(new GateField("Nordtor", 25));
fields.add(new BuildingProperty("Cascada", 26, 2600, 220, 1500, FieldColor.YELLOW)); fields.add(new BuildingProperty("Cascada", 26, 2600, 220, 1500, FieldColor.YELLOW));
fields.add(new BuildingProperty("Fakultätsgebäude", 27, 2600, 220, 1500, FieldColor.YELLOW)); fields.add(new BuildingProperty("Fakultätsgebäude", 27, 2600, 220, 1500, FieldColor.YELLOW));
fields.add(new FoodField("Truppenküche", 28)); fields.add(new FoodField("Truppenküche", 28));