Compare commits
77 Commits
43d0549e9e
...
demo
Author | SHA1 | Date | |
---|---|---|---|
|
eb54fb1d14 | ||
|
40c550cc4d | ||
|
18300987a4 | ||
|
df4a81cbf2 | ||
|
c635df9369 | ||
|
c6ad605021 | ||
|
1e20a2ac6e | ||
|
36a9a7addf | ||
|
e1190cd4a2 | ||
|
34ecd2277b | ||
|
5959f36a21 | ||
|
1db2d9ebac | ||
|
54bac50a7e | ||
|
274ed2b25d | ||
|
371fa83319 | ||
|
c1faf91188 | ||
|
617d707df8 | ||
|
d18cea435c | ||
|
1543f0dcea | ||
|
ae181e4eff | ||
|
fa96324c15 | ||
|
9f559fe0d7 | ||
|
cf6ee535b8 | ||
|
be89bf1a27 | ||
|
6f2027c2fb | ||
|
6e99f17787 | ||
|
b7e2e3213a | ||
|
3ea6452d6d | ||
|
fd3c141967 | ||
|
b3d2dfed08 | ||
|
5306208107 | ||
|
2a7cbeed89 | ||
|
0a34751825 | ||
|
996bc0118a | ||
|
bbcb12c131 | ||
|
1969afc58f | ||
|
ad0c432102 | ||
|
315739646c | ||
|
330e788498 | ||
|
fc5a2809c8 | ||
|
0acb63adb6 | ||
|
b4c664927b | ||
|
ed27e0aaf1 | ||
|
98f453d7f8 | ||
|
8de7499c21 | ||
|
b680d7bc58 | ||
|
30559bf443 | ||
|
8774c4246d | ||
|
7b82b20736 | ||
|
698937e77c | ||
|
7cbf000c44 | ||
|
e98e17f6d7 | ||
|
e337303408 | ||
|
97619fe662 | ||
|
246566a211 | ||
|
96a78ee61b | ||
|
c9e99ee9ff | ||
|
111f2b1283 | ||
|
93386fa77a | ||
|
6cdf0eee53 | ||
|
b6803c562c | ||
|
38699ac07a | ||
|
f396ef52f2 | ||
|
73bf147817 | ||
|
80f9054add | ||
|
b819e1ca9b | ||
|
c4955e0b57 | ||
|
008cb1ebe4 | ||
|
723c934d73 | ||
|
4eac2e3312 | ||
|
fef881f42c | ||
|
eeaf29a646 | ||
|
2eae0fce2a | ||
|
aa9e8ed3f0 | ||
|
3e14a2674f | ||
|
815899fa8d | ||
|
793e93ef24 |
@@ -19,6 +19,8 @@ import java.util.Deque;
|
||||
|
||||
import static java.lang.Math.max;
|
||||
|
||||
import java.lang.System.Logger;
|
||||
|
||||
/**
|
||||
* Manages dialog boxes within the application, handling their display, positioning, and focus.
|
||||
*/
|
||||
@@ -28,11 +30,15 @@ public class DialogManager {
|
||||
*/
|
||||
private final SimpleApplication app;
|
||||
|
||||
|
||||
private final static Logger LOGGER = System.getLogger(DialogManager.class.getName());
|
||||
/**
|
||||
* A stack to keep track of the dialogs.
|
||||
*/
|
||||
private final Deque<Dialog> dialogStack = new ArrayDeque<>();
|
||||
|
||||
private final Deque<PopupDialog> popUpStack = new ArrayDeque<>();
|
||||
|
||||
/**
|
||||
* Constructs a DialogManager for the specified application.
|
||||
*
|
||||
@@ -112,11 +118,45 @@ public class DialogManager {
|
||||
* @param dialog the dialog to open
|
||||
*/
|
||||
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);
|
||||
if(dialog instanceof PopupDialog) {
|
||||
((PopupDialog)dialog).show();
|
||||
}
|
||||
dialog.update();
|
||||
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.
|
||||
*
|
||||
@@ -140,6 +180,8 @@ public class DialogManager {
|
||||
if (!dialogStack.isEmpty())
|
||||
dialogStack.peek().update();
|
||||
app.getGuiNode().detachChild(dialog);
|
||||
|
||||
processPopUps();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -0,0 +1,5 @@
|
||||
package pp.dialog;
|
||||
|
||||
public interface PopupDialog {
|
||||
void show();
|
||||
}
|
@@ -101,6 +101,13 @@ selector("label-Text", "pp") {
|
||||
color = buttonEnabledColor
|
||||
}
|
||||
|
||||
selector("label-player", "pp") {
|
||||
insets = new Insets3f(2, 2, 2, 2)
|
||||
font = font("Interface/Fonts/Metropolis/Metropolis-Bold-32.fnt")
|
||||
fontSize = 20
|
||||
color = buttonEnabledColor
|
||||
}
|
||||
|
||||
selector("label-account", "pp") {
|
||||
insets = new Insets3f(2, 2, 2, 2)
|
||||
fontSize = 25
|
||||
@@ -398,3 +405,44 @@ selector("button-clear", "pp") { playerColor ->
|
||||
textHAlignment = HAlignment.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
|
||||
}
|
||||
|
||||
|
@@ -3,32 +3,35 @@ package pp.monopoly.client;
|
||||
import com.jme3.app.Application;
|
||||
import com.jme3.app.state.AppStateManager;
|
||||
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.DirectionalLight;
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.material.RenderState.FaceCullMode;
|
||||
import com.jme3.math.ColorRGBA;
|
||||
import com.jme3.math.FastMath;
|
||||
import com.jme3.math.Quaternion;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.renderer.Camera;
|
||||
import com.jme3.renderer.queue.RenderQueue;
|
||||
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
|
||||
import com.jme3.scene.Geometry;
|
||||
import com.jme3.scene.Node;
|
||||
import com.jme3.scene.Spatial;
|
||||
import com.jme3.scene.shape.Box;
|
||||
import com.jme3.scene.shape.Cylinder;
|
||||
import com.jme3.shadow.DirectionalLightShadowRenderer;
|
||||
import com.jme3.shadow.EdgeFilteringMode;
|
||||
import com.jme3.texture.Texture;
|
||||
import com.jme3.util.SkyFactory;
|
||||
import com.jme3.util.TangentBinormalGenerator;
|
||||
|
||||
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.model.Board;
|
||||
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.
|
||||
@@ -40,6 +43,7 @@ public class BoardAppState extends MonopolyAppState {
|
||||
* The path to the unshaded texture material.
|
||||
*/
|
||||
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.
|
||||
@@ -64,7 +68,12 @@ public class BoardAppState extends MonopolyAppState {
|
||||
/**
|
||||
* The pop-up manager for displaying messages and notifications.
|
||||
*/
|
||||
private PopUpManager popUpManager;;
|
||||
private PopUpManager popUpManager;
|
||||
|
||||
private CameraController cameraController;
|
||||
|
||||
private CameraInputHandler cameraInputHandler;
|
||||
|
||||
|
||||
/**
|
||||
* Initializes the state by setting up the sky, lights, and other visual components.
|
||||
@@ -76,10 +85,19 @@ public class BoardAppState extends MonopolyAppState {
|
||||
@Override
|
||||
public void initialize(AppStateManager stateManager, Application 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());
|
||||
viewNode.attachChild(sceneNode);
|
||||
|
||||
setupLights();
|
||||
setupSky();
|
||||
// setupSky();
|
||||
getApp().getViewPort().setBackgroundColor(new com.jme3.math.ColorRGBA(0.5f, 0.7f, 1.0f, 1.0f));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -91,40 +109,19 @@ public class BoardAppState extends MonopolyAppState {
|
||||
getApp().getRootNode().detachAllChildren();
|
||||
getApp().getGuiNode().detachAllChildren();
|
||||
|
||||
getApp().getDialogManager().close(getApp().getDialogManager().getDialogStack().peek());
|
||||
|
||||
new Toolbar(getApp()).open();
|
||||
sceneNode.detachAllChildren();
|
||||
setupScene();
|
||||
if (bobTheBuilder == null) {
|
||||
bobTheBuilder = new BobTheBuilder(getApp(), getApp().getRootNode());
|
||||
System.out.println("LISTENER IS REGISTEDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD");
|
||||
bobTheBuilder = new BobTheBuilder(getApp(), sceneNode);
|
||||
getGameLogic().addListener(bobTheBuilder);
|
||||
}
|
||||
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(x, ABOVE_SEA_LEVEL, y));
|
||||
camera.lookAt(new Vector3f(0,0, 0),
|
||||
Vector3f.UNIT_Y);
|
||||
camera.update();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Disables the sea and sky state, removing visual elements from the scene and unregistering listeners.
|
||||
@@ -139,18 +136,7 @@ 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.
|
||||
@@ -169,7 +155,8 @@ public class BoardAppState extends MonopolyAppState {
|
||||
viewNode.addLight(sun);
|
||||
shRend.setLight(sun);
|
||||
|
||||
final AmbientLight ambientLight = new AmbientLight(new ColorRGBA(1f, 1f, 1f, 1f));
|
||||
final AmbientLight ambientLight = new AmbientLight();
|
||||
// ambientLight.setColor(ColorRGBA.White.mult(0.f)); // brightness
|
||||
viewNode.addLight(ambientLight);
|
||||
}
|
||||
|
||||
@@ -179,17 +166,79 @@ public class BoardAppState extends MonopolyAppState {
|
||||
*/
|
||||
private void setupSky() {
|
||||
final AssetManager assetManager = getApp().getAssetManager();
|
||||
final Texture west = assetManager.loadTexture("Pictures/Backdrop/west.jpg"); //NON-NLS
|
||||
final Texture east = assetManager.loadTexture("Pictures/Backdrop/ost.jpg"); //NON-NLS
|
||||
final Texture north = assetManager.loadTexture("Pictures/Backdrop/nord.jpg"); //NON-NLS
|
||||
final Texture south = assetManager.loadTexture("Pictures/Backdrop/sued.jpg"); //NON-NLS
|
||||
final Texture up = assetManager.loadTexture("Pictures/Backdrop/sued.jpg"); //NON-NLS
|
||||
final Texture down = assetManager.loadTexture("Pictures/Backdrop/sued.jpg"); //NON-NLS
|
||||
final Spatial sky = SkyFactory.createSky(assetManager, west, east, north, south, up, down);
|
||||
// sky.rotate(0, PI, 0);
|
||||
viewNode.attachChild(sky);
|
||||
|
||||
// Create a cylinder for the sky
|
||||
float radius = 500f; // Adjust radius as needed
|
||||
float height = 200f; // Height of the cylinder
|
||||
int radialSamples = 64; // Number of radial segments for smoothness
|
||||
int axisSamples = 2; // No vertical divisions (flat vertical surface)
|
||||
|
||||
Cylinder skyCylinder = new Cylinder(axisSamples, radialSamples, radius, height, true);
|
||||
|
||||
// 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,
|
||||
* applying textures, and enabling shadows.
|
||||
@@ -199,17 +248,107 @@ public class BoardAppState extends MonopolyAppState {
|
||||
final float x = board.getWidth();
|
||||
final float y = board.getHeight();
|
||||
final Box seaMesh = new Box(y, 0.1f, x);
|
||||
final Geometry seaGeo = new Geometry("sea", seaMesh); //NONs-NLS
|
||||
final Geometry seaGeo = new Geometry("sea", seaMesh); //NON-NLS
|
||||
seaGeo.setLocalTranslation(new Vector3f(0, -0.1f, 0));
|
||||
Quaternion rotation = new com.jme3.math.Quaternion();
|
||||
rotation.fromAngleAxis(FastMath.HALF_PI, com.jme3.math.Vector3f.UNIT_Y);
|
||||
Quaternion rotation = new Quaternion();
|
||||
rotation.fromAngleAxis(FastMath.HALF_PI, Vector3f.UNIT_Y);
|
||||
seaGeo.setLocalRotation(rotation);
|
||||
final Material seaMat = new Material(getApp().getAssetManager(), "Common/MatDefs/Light/Lighting.j3md");
|
||||
Texture texture = getApp().getAssetManager().loadTexture("Pictures/board2.png");
|
||||
texture.setMagFilter(Texture.MagFilter.Bilinear);
|
||||
texture.setMinFilter(Texture.MinFilter.Trilinear);
|
||||
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.setShadowMode(ShadowMode.CastAndReceive);
|
||||
TangentBinormalGenerator.generate(seaGeo);
|
||||
|
||||
sceneNode.attachChild(createCardDeck());
|
||||
sceneNode.attachChild(seaGeo);
|
||||
|
||||
// Schneefall hinzufügen
|
||||
// addSnowEffect(sceneNode);
|
||||
}
|
||||
|
||||
private Node createCardDeck() {
|
||||
Node cardDeck = new Node("cardDeck");
|
||||
|
||||
// Ereigniskarten
|
||||
Vector3f basePosition1 = new Vector3f(3.1f, 0.4f, 3.8f); // Basisposition für Ereigniskarten
|
||||
float baseRotation1 = -60; // Basisrotation in Grad
|
||||
for (int i = 0; i < 6; i++) {
|
||||
Box box = new Box(1.2f, 0.05f, 1.8f); // Sehr flaches Rechteck
|
||||
Geometry flatCard = new Geometry("Ereigniskarten_" + i, box);
|
||||
Material mat = new Material(getApp().getAssetManager(), UNSHADED);
|
||||
mat.setTexture("ColorMap", getApp().getAssetManager().loadTexture("Textures/Ereigniskarten.png"));
|
||||
flatCard.setMaterial(mat);
|
||||
|
||||
// Position und Rotation für die Karte
|
||||
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;
|
||||
}
|
||||
|
||||
private void addSnowEffect(Node parentNode) {
|
||||
// ParticleEmitter für Schnee
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
@@ -120,6 +120,7 @@ public class GameSound extends AbstractAppState implements GameEventListener {
|
||||
winnerSound = loadSound(app, "Sound/Effects/winner.ogg");
|
||||
looserSound = loadSound(app, "Sound/Effects/loser.ogg");
|
||||
buttonSound = loadSound(app, "Sound/Effects/button.ogg");
|
||||
setVolume(volumeInPreferences());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -15,6 +15,9 @@ import java.lang.System.Logger.Level;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.logging.LogManager;
|
||||
import java.awt.Image;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import com.jme3.app.DebugKeysAppState;
|
||||
import com.jme3.app.SimpleApplication;
|
||||
@@ -169,6 +172,16 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
|
||||
private AppSettings makeSettings() {
|
||||
final AppSettings settings = new AppSettings(true);
|
||||
settings.setTitle(lookup("monopoly.name"));
|
||||
try {
|
||||
// Prüfen, ob das Betriebssystem ein Mac-System ist
|
||||
if (!System.getProperty("os.name").toLowerCase().contains("mac")) {
|
||||
settings.setIcons(new Image[]{ImageIO.read(new File("src/main/resources/icons/Uniman.png"))});
|
||||
} else {
|
||||
LOGGER.log(Level.INFO, "Icon setting skipped on macOS due to system restrictions.");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOGGER.log(Level.ERROR, e.getMessage());
|
||||
}
|
||||
settings.setResolution(config.getResolutionWidth(), config.getResolutionHeight());
|
||||
settings.setFullscreen(config.fullScreen());
|
||||
settings.setUseRetinaFrameBuffer(config.useRetinaFrameBuffer());
|
||||
@@ -280,6 +293,8 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
|
||||
stateManager.attach(stats);
|
||||
}
|
||||
flyCam.setEnabled(false);
|
||||
flyCam.setMoveSpeed(4f); // Setzt die Bewegungsgeschwindigkeit der Kamera (Standardwert ist 1f)
|
||||
|
||||
stateManager.detach(stateManager.getState(StatsAppState.class));
|
||||
stateManager.detach(stateManager.getState(DebugKeysAppState.class));
|
||||
|
||||
|
@@ -106,6 +106,26 @@ public class MonopolyAppConfig extends MonopolyClientConfig {
|
||||
@Property("overlay.top.color") //NON-NLS
|
||||
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.
|
||||
*/
|
||||
|
@@ -56,7 +56,7 @@ public class PopUpManager implements GameEventListener {
|
||||
}
|
||||
});
|
||||
}
|
||||
}, 2500);
|
||||
}, 8000);
|
||||
} else if (event.msg().equals("Winner")) {
|
||||
new WinnerPopUp(app).open();
|
||||
} else if (event.msg().equals("Looser")) {
|
||||
|
@@ -3,6 +3,9 @@ package pp.monopoly.client.gui;
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.material.RenderState.BlendMode;
|
||||
import com.jme3.math.ColorRGBA;
|
||||
import com.jme3.math.FastMath;
|
||||
import com.jme3.math.Quaternion;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
|
||||
import com.jme3.scene.Geometry;
|
||||
import com.jme3.scene.Node;
|
||||
@@ -36,14 +39,17 @@ public class BobTheBuilder extends GameBoardSynchronizer {
|
||||
@Override
|
||||
public Spatial visit(Figure figure) {
|
||||
final Node node = new Node(FIGURE);
|
||||
node.attachChild(createFigure(figure));
|
||||
Spatial spatial = createFigure(figure);
|
||||
node.attachChild(spatial);
|
||||
|
||||
// Setze die Position basierend auf der Feld-ID
|
||||
node.setLocalTranslation(figure.getPos());
|
||||
|
||||
// Setze die Rotation basierend auf der Feld-ID
|
||||
node.setLocalRotation(figure.getRot().toQuaternion());
|
||||
node.addControl(new FigureControl(figure));
|
||||
// Setze die Anfangsrotation auf 90 Grad nach links
|
||||
Quaternion initialRotation = new Quaternion().fromAngleAxis(FastMath.HALF_PI, Vector3f.UNIT_Y);
|
||||
node.setLocalRotation(initialRotation);
|
||||
|
||||
node.addControl(new FigureControl(node, figure, app));
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -80,7 +86,7 @@ public class BobTheBuilder extends GameBoardSynchronizer {
|
||||
private Spatial createFigure(Figure figure) {
|
||||
// Lade das Modell
|
||||
Spatial model = app.getAssetManager().loadModel("models/" + "Spielfiguren/" + figure.getType() + "/" + figure.getType() + ".j3o");
|
||||
|
||||
|
||||
// Skaliere und positioniere das Modell
|
||||
model.scale(0.5f);
|
||||
|
||||
@@ -138,9 +144,4 @@ public class BobTheBuilder extends GameBoardSynchronizer {
|
||||
material.setColor(COLOR, color);
|
||||
return material;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receivedEvent(UpdatePlayerView event) {
|
||||
//TODO player move animation
|
||||
}
|
||||
}
|
||||
|
@@ -3,64 +3,106 @@ package pp.monopoly.client.gui;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.renderer.Camera;
|
||||
|
||||
/**
|
||||
* Controls the movement of the camera within the scene.
|
||||
*/
|
||||
public class CameraController {
|
||||
import pp.monopoly.client.MonopolyApp; // Import MonopolyApp
|
||||
import pp.monopoly.game.server.PlayerHandler;
|
||||
import pp.monopoly.notification.GameEventListener;
|
||||
import pp.monopoly.notification.UpdatePlayerView;
|
||||
|
||||
public class CameraController implements GameEventListener{
|
||||
|
||||
public enum CameraMode {
|
||||
FOCUS_CURRENT_PLAYER,
|
||||
FOCUS_SELF,
|
||||
FREECAM
|
||||
}
|
||||
|
||||
private final Camera camera;
|
||||
private final float height = 25; // Height of the camera above the game board
|
||||
private CameraMode currentMode;
|
||||
|
||||
/**
|
||||
* Constructor for the CameraController.
|
||||
*
|
||||
* @param camera The camera to be controlled
|
||||
*/
|
||||
public CameraController(Camera camera) {
|
||||
private PlayerHandler playerHandler; // Reference to PlayerHandler for player data
|
||||
private final MonopolyApp app; // Reference to MonopolyApp for self ID
|
||||
|
||||
public CameraController(Camera camera, MonopolyApp app) {
|
||||
this.camera = camera;
|
||||
setPosition(0);
|
||||
camera.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);
|
||||
this.playerHandler = app.getGameLogic().getPlayerHandler();
|
||||
this.app = app;
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the camera's position based on the field ID.
|
||||
*
|
||||
* @param fieldID The ID of the field to which the camera should move
|
||||
*/
|
||||
public void setPosition(int fieldID) {
|
||||
camera.setLocation(fieldIdToVector(fieldID));
|
||||
public void updatePosition() {
|
||||
Vector3f newPosition = getPos();
|
||||
camera.setLocation(newPosition);
|
||||
|
||||
camera.lookAt(app.getGameLogic().getBoard().getFigure(app.getId()).getPos(), Vector3f.UNIT_Y);
|
||||
camera.update();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the camera's position using specific coordinates.
|
||||
*
|
||||
* @param x The X-coordinate of the new camera position
|
||||
* @param y The Y-coordinate of the new camera position
|
||||
*/
|
||||
public void setPosition(float x, float y) {
|
||||
camera.setLocation(new Vector3f(x, height, y));
|
||||
private Vector3f getPos() {
|
||||
Vector3f pos = new Vector3f();
|
||||
switch (currentMode) {
|
||||
case FOCUS_CURRENT_PLAYER:
|
||||
pos = app.getGameLogic().getBoard().getFigure(playerHandler.getPlayerById(0).getId()).getPos();
|
||||
|
||||
case FOCUS_SELF:
|
||||
pos = app.getGameLogic().getBoard().getFigure(app.getId()).getPos();
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps a field ID to its corresponding position in the game world.
|
||||
*
|
||||
* @param fieldID The ID of the field
|
||||
* @return The position of the field as a {@link Vector3f}
|
||||
* @throws IllegalArgumentException If the field ID is invalid
|
||||
*/
|
||||
private Vector3f fieldIdToVector(int fieldID) {
|
||||
if (fieldID <= 10) return new Vector3f(30, height, 0);
|
||||
if (fieldID <= 20) return new Vector3f(0, height, 30);
|
||||
if (fieldID <= 30) return new Vector3f(-30, height, 0);
|
||||
if (fieldID <= 40) return new Vector3f(0, height, -30);
|
||||
else throw new IllegalArgumentException();
|
||||
private Vector3f getOffset() {
|
||||
Vector3f offset = new Vector3f();
|
||||
|
||||
int fieldId = playerHandler.getPlayerById( (currentMode == CameraMode.FOCUS_SELF ? app.getId() : playerHandler.getPlayerAtIndex(0).getId()) ).getFieldID();
|
||||
// System.out.println();
|
||||
if(fieldId < 10) {
|
||||
offset = new Vector3f(0, 10, -15);
|
||||
} else if(fieldId < 20) {
|
||||
offset = new Vector3f(15 , 10, 0);
|
||||
} else if(fieldId < 30) {
|
||||
offset = new Vector3f(0, 10, 15 );
|
||||
} else {
|
||||
offset = new Vector3f(-15, 10, 0);
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receivedEvent(UpdatePlayerView event) {
|
||||
playerHandler = app.getGameLogic().getPlayerHandler();
|
||||
}
|
||||
}
|
||||
|
@@ -1,60 +1,31 @@
|
||||
//package pp.monopoly.client.gui;
|
||||
//
|
||||
//import com.jme3.input.InputManager;
|
||||
//import com.jme3.input.KeyInput;
|
||||
//import com.jme3.input.controls.ActionListener;
|
||||
//import com.jme3.input.controls.KeyTrigger;
|
||||
//
|
||||
///**
|
||||
// * Handhabt die Eingaben für die Kamera.
|
||||
// */
|
||||
//public class CameraInputHandler {
|
||||
//
|
||||
// private CameraController cameraController; // Kamera-Controller
|
||||
//
|
||||
// /**
|
||||
// * Konstruktor für den CameraInputHandler.
|
||||
// *
|
||||
// * @param cameraController Der Kamera-Controller, der gesteuert werden soll.
|
||||
// * @param inputManager Der InputManager, um Eingaben zu registrieren.
|
||||
// */
|
||||
// public CameraInputHandler(CameraController cameraController, InputManager inputManager) {
|
||||
// if (cameraController == null || inputManager == null) {
|
||||
// throw new IllegalArgumentException("CameraController und InputManager dürfen nicht null sein");
|
||||
// }
|
||||
// this.cameraController = cameraController;
|
||||
//
|
||||
// // Mappings für Kamerasteuerung
|
||||
// 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);
|
||||
// }
|
||||
// };
|
||||
//}
|
||||
//
|
||||
package pp.monopoly.client.gui;
|
||||
|
||||
import com.jme3.input.InputManager;
|
||||
import com.jme3.input.KeyInput;
|
||||
import com.jme3.input.controls.ActionListener;
|
||||
import com.jme3.input.controls.KeyTrigger;
|
||||
|
||||
public class CameraInputHandler {
|
||||
private CameraController cameraController;
|
||||
|
||||
public CameraInputHandler(CameraController cameraController, InputManager inputManager) {
|
||||
this.cameraController = cameraController;
|
||||
|
||||
// Tasten für die verschiedenen Kameramodi registrieren
|
||||
inputManager.addMapping("FocusCurrentPlayer", new KeyTrigger(KeyInput.KEY_1));
|
||||
inputManager.addMapping("FocusSelf", new KeyTrigger(KeyInput.KEY_2));
|
||||
inputManager.addMapping("FreeCam", new KeyTrigger(KeyInput.KEY_3));
|
||||
|
||||
inputManager.addListener(actionListener, "FocusCurrentPlayer", "FocusSelf", "FreeCam");
|
||||
}
|
||||
|
||||
private final ActionListener actionListener = (name, isPressed, tpf) -> {
|
||||
if (!isPressed) return;
|
||||
|
||||
switch (name) {
|
||||
case "FocusCurrentPlayer" -> cameraController.setMode(CameraController.CameraMode.FOCUS_CURRENT_PLAYER);
|
||||
case "FocusSelf" -> cameraController.setMode(CameraController.CameraMode.FOCUS_SELF);
|
||||
case "FreeCam" -> cameraController.setMode(CameraController.CameraMode.FREECAM);
|
||||
}
|
||||
};
|
||||
}
|
@@ -1,28 +1,158 @@
|
||||
package pp.monopoly.client.gui;
|
||||
|
||||
import com.jme3.math.FastMath;
|
||||
import com.jme3.math.Quaternion;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.renderer.RenderManager;
|
||||
import com.jme3.renderer.ViewPort;
|
||||
import com.jme3.scene.Node;
|
||||
import com.jme3.scene.control.AbstractControl;
|
||||
|
||||
import pp.monopoly.client.MonopolyApp;
|
||||
import pp.monopoly.game.client.ClientGameLogic;
|
||||
import pp.monopoly.model.Figure;
|
||||
import pp.monopoly.notification.GameEventListener;
|
||||
import pp.monopoly.notification.UpdatePlayerView;
|
||||
|
||||
public class FigureControl extends AbstractControl {
|
||||
// import java.lang.System.Logger;
|
||||
// import java.lang.System.Logger.Level;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
|
||||
public class FigureControl extends AbstractControl implements GameEventListener {
|
||||
|
||||
// // // private static final Logger LOGGER = System.getLogger(FigureControl.class.getName());
|
||||
private final Figure figure;
|
||||
private final Node spatial;
|
||||
private final MonopolyApp app;
|
||||
private Queue<Vector3f> path; // Path to follow
|
||||
private Vector3f currentTarget;
|
||||
private float animationTime = 0f; // Time elapsed for the current movement
|
||||
private final float durationPerField = 0.5f; // Time to move between fields
|
||||
private float delayTime = 3f; // Verzögerung in Sekunden
|
||||
private float delayElapsed = 0f; // Zeit, die seit dem Start der Verzögerung vergangen ist
|
||||
|
||||
public FigureControl(Figure figure) {
|
||||
|
||||
public FigureControl(Node spatial, Figure figure, MonopolyApp app) {
|
||||
super();
|
||||
this.figure = figure;
|
||||
this.spatial = spatial;
|
||||
this.app = app;
|
||||
this.path = new LinkedList<>();
|
||||
app.getGameLogic().addListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void controlUpdate(float tpf) {
|
||||
//TODO: animation
|
||||
if (delayTime > 0) {
|
||||
delayElapsed += tpf;
|
||||
if (delayElapsed < delayTime) {
|
||||
return; // Warte, bis die Verzögerung abgeschlossen ist
|
||||
}
|
||||
delayTime = 0; // Verzögerung abgeschlossen
|
||||
|
||||
}
|
||||
|
||||
if (currentTarget == null && !path.isEmpty()) {
|
||||
// Hole das nächste Ziel aus dem Pfad
|
||||
currentTarget = path.poll();
|
||||
animationTime = 0f;
|
||||
|
||||
// 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) {
|
||||
animationTime += tpf;
|
||||
|
||||
Vector3f startPosition = spatial.getLocalTranslation();
|
||||
Vector3f interpolatedPosition = startPosition.interpolateLocal(
|
||||
currentTarget,
|
||||
animationTime / durationPerField
|
||||
);
|
||||
|
||||
// Hüpfeffekt hinzufügen
|
||||
float hopHeight = 0.5f * FastMath.sin(FastMath.PI * (animationTime / durationPerField));
|
||||
interpolatedPosition.setY(hopHeight );
|
||||
spatial.setLocalTranslation(interpolatedPosition);
|
||||
|
||||
// Ziel erreicht
|
||||
if (animationTime >= durationPerField) {
|
||||
spatial.setLocalTranslation(currentTarget);
|
||||
figure.moveTo(currentTarget); // Synchronisiere die interne Position
|
||||
currentTarget = null; // Setze Ziel zurück
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private int nextField(int currentField) {
|
||||
return (currentField + 1) % 40;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected void controlRender(RenderManager rm, ViewPort vp) {
|
||||
// No rendering required
|
||||
// No rendering logic required
|
||||
}
|
||||
|
||||
public void setPath(int startField, int endField) {
|
||||
// LOGGER.log(Level.TRACE, "setPath called with startField: {0} to endField {1}", startField, endField);
|
||||
path.clear();
|
||||
for (int fieldId = startField; fieldId != endField; fieldId = (fieldId + 1) % 40) {
|
||||
Vector3f position = figure.calculateFieldPosition(fieldId);
|
||||
// LOGGER.log(Level.DEBUG, "Adding postition to path: {0}", position);
|
||||
path.add(position);
|
||||
}
|
||||
Vector3f finalPosition = figure.calculateFieldPosition(endField);
|
||||
path.add(finalPosition);
|
||||
// LOGGER.log(Level.DEBUG, "Final position added to path: {0}", finalPosition);
|
||||
|
||||
|
||||
// LOGGER.log(Level.TRACE, "Path size: {0}", path.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receivedEvent(UpdatePlayerView event) {
|
||||
// LOGGER.log(Level.TRACE, "receivedEvent called with event: {0}", event);
|
||||
|
||||
int newPos = app.getGameLogic().getPlayerHandler().getPlayerById(figure.getId()).getFieldID();
|
||||
int currentField = figure.getCurrentFieldID();
|
||||
|
||||
if (currentField == newPos) {
|
||||
// LOGGER.log(Level.DEBUG, "No movement required. Current field: {0}, New field: {1}", currentField, newPos);
|
||||
return;
|
||||
}
|
||||
|
||||
// LOGGER.log(Level.DEBUG, "Movement required. Current field: {0}, New field: {1}", currentField, newPos);
|
||||
|
||||
|
||||
setPath(currentField, newPos);
|
||||
delayTime = 3f; // Verzögerung zurücksetzen
|
||||
delayElapsed = 0f; // Timer zurücksetzen
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@@ -154,6 +154,7 @@ public class LobbyMenu extends Dialog {
|
||||
figures.add("Katze");
|
||||
figures.add("OOP");
|
||||
figures.add("Handyholster");
|
||||
figures.add("Panzer");
|
||||
|
||||
|
||||
figureDropdown = new Selector<>(figures, "glass");
|
||||
@@ -325,7 +326,6 @@ public class LobbyMenu extends Dialog {
|
||||
figure = selector.getSelectedItem();
|
||||
break;
|
||||
}
|
||||
System.out.println("FIGUR:::::"+figure);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -65,7 +65,7 @@ public class StartMenu extends Dialog {
|
||||
app.getGuiNode().attachChild(centerMenu);
|
||||
|
||||
// Load the Monopoly logo as a texture
|
||||
Texture logoTexture = app.getAssetManager().loadTexture("Pictures/logo-monopoly.png");
|
||||
Texture logoTexture = app.getAssetManager().loadTexture("Pictures/logo-monopolyw.png");
|
||||
|
||||
// Create a container for the logo
|
||||
Container logoContainer = new Container();
|
||||
@@ -91,8 +91,8 @@ public class StartMenu extends Dialog {
|
||||
QuadBackgroundComponent unibwBackground = new QuadBackgroundComponent(unibwTexture);
|
||||
unibwContainer.setBackground(unibwBackground);
|
||||
|
||||
float unibwWidth = 512;
|
||||
float unibwHeight = 128;
|
||||
float unibwWidth = 662;
|
||||
float unibwHeight = 180;
|
||||
unibwContainer.setPreferredSize(new Vector3f(unibwWidth, unibwHeight, 0));
|
||||
|
||||
unibwContainer.setLocalTranslation(new Vector3f(
|
||||
|
@@ -99,7 +99,9 @@ public class Toolbar extends Dialog implements GameEventListener {
|
||||
container.setBackground(background);
|
||||
|
||||
setupBorders(container);
|
||||
setupSpacer(container);
|
||||
setupPlayerInfoSection(container);
|
||||
setupSpacer(container);
|
||||
setupDiceSection(container);
|
||||
setupActionMenu(container);
|
||||
|
||||
@@ -135,6 +137,17 @@ public class Toolbar extends Dialog implements GameEventListener {
|
||||
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.
|
||||
*
|
||||
@@ -183,16 +196,6 @@ public class Toolbar extends Dialog implements GameEventListener {
|
||||
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.
|
||||
*
|
||||
@@ -247,7 +250,7 @@ public class Toolbar extends Dialog implements GameEventListener {
|
||||
private Label createDiceLabel(String iconPath) {
|
||||
Label label = new Label("");
|
||||
IconComponent icon = new IconComponent(iconPath);
|
||||
icon.setIconSize(new Vector2f(100, 100));
|
||||
icon.setIconSize(new Vector2f(80, 80));
|
||||
label.setIcon(icon);
|
||||
return label;
|
||||
}
|
||||
@@ -270,15 +273,15 @@ public class Toolbar extends Dialog implements GameEventListener {
|
||||
* Handles the dice roll event.
|
||||
*/
|
||||
private void handleDiceRoll() {
|
||||
ifTopDialog(() -> {
|
||||
if (!canRollDice) return;
|
||||
canRollDice = false;
|
||||
if (endTurnButton != null) endTurnButton.setEnabled(true);
|
||||
startDiceAnimation();
|
||||
app.getGameLogic().send(new RollDice());
|
||||
app.getGameLogic().playSound(Sound.BUTTON);
|
||||
});
|
||||
}
|
||||
ifTopDialog(() -> {
|
||||
if (!canRollDice) return;
|
||||
canRollDice = false;
|
||||
if (endTurnButton != null) endTurnButton.setEnabled(true);
|
||||
startDiceAnimation();
|
||||
app.getGameLogic().send(new RollDice());
|
||||
app.getGameLogic().playSound(Sound.BUTTON);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private Button createTradeButton() {
|
||||
@@ -295,6 +298,7 @@ public class Toolbar extends Dialog implements GameEventListener {
|
||||
|
||||
tradeButton.addClickCommands(s -> ifTopDialog(() -> {
|
||||
new ChoosePartner(app).open();
|
||||
|
||||
}));
|
||||
|
||||
return tradeButton;
|
||||
@@ -334,25 +338,12 @@ public class Toolbar extends Dialog implements GameEventListener {
|
||||
endTurnButton.setIcon(icon);
|
||||
|
||||
endTurnButton.addClickCommands(s -> ifTopDialog(() -> {
|
||||
app.getGameLogic().send(new EndTurn());
|
||||
receivedEvent(new ButtonStatusEvent(false));
|
||||
handleEndTurn();
|
||||
}));
|
||||
|
||||
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.
|
||||
@@ -381,7 +372,7 @@ public class Toolbar extends Dialog implements GameEventListener {
|
||||
showFinalDiceResult(latestDiceRollEvent);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
System.err.println("Dice animation interrupted: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
@@ -510,7 +501,8 @@ public class Toolbar extends Dialog implements GameEventListener {
|
||||
if (player.getId() != app.getId()) {
|
||||
Label playerLabel = new Label(
|
||||
player.getName() + ": " + player.getAccountBalance() + " EUR",
|
||||
new ElementId("label-Text")
|
||||
new ElementId("label-player")
|
||||
|
||||
);
|
||||
playerLabel.setColor(Player.getColor(player.getId()).getColor());
|
||||
overviewContainer.addChild(playerLabel);
|
||||
@@ -526,7 +518,6 @@ public class Toolbar extends Dialog implements GameEventListener {
|
||||
*/
|
||||
@Override
|
||||
public void receivedEvent(ButtonStatusEvent event) {
|
||||
System.out.println("Button status event received: " + event.buttonsEnabled()+ "GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG");
|
||||
boolean enabled = event.buttonsEnabled();
|
||||
canRollDice = enabled;
|
||||
tradeButton.setEnabled(enabled);
|
||||
|
@@ -910,7 +910,6 @@
|
||||
}
|
||||
sliderhorsetup();
|
||||
adjustothercolumnmodel();
|
||||
// System.out.println("Columns available: " +availableColumns);
|
||||
}
|
||||
|
||||
@StyleAttribute(value="visibleColumns")
|
||||
@@ -923,7 +922,6 @@
|
||||
sliderhorsetup();
|
||||
grid.refreshGrid();
|
||||
refreshSelector();
|
||||
// System.out.println("Columns visble: " +grid.getVisibleColumns());
|
||||
}
|
||||
|
||||
// Column Operations
|
||||
|
@@ -12,33 +12,31 @@ import com.simsilica.lemur.Label;
|
||||
import com.simsilica.lemur.component.QuadBackgroundComponent;
|
||||
import com.simsilica.lemur.style.ElementId;
|
||||
import pp.dialog.Dialog;
|
||||
import pp.dialog.PopupDialog;
|
||||
import pp.monopoly.client.MonopolyApp;
|
||||
import pp.monopoly.client.gui.SettingsMenu;
|
||||
import pp.monopoly.message.server.TradeReply;
|
||||
import pp.monopoly.notification.Sound;
|
||||
|
||||
/**
|
||||
* Represents a confirmation dialog that appears when a trade is 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>
|
||||
* Represents a confirmation dialog that appears when a trade is accepted.
|
||||
* Displays a message to the user informing them that the trade was accepted.
|
||||
*/
|
||||
public class AcceptTrade extends Dialog {
|
||||
public class AcceptTrade extends Dialog implements PopupDialog {
|
||||
/** Reference to the Monopoly application instance. */
|
||||
private final MonopolyApp app;
|
||||
|
||||
/** Semi-transparent overlay background for the dialog. */
|
||||
private final Geometry overlayBackground;
|
||||
private Geometry overlayBackground;
|
||||
|
||||
/** Container for the warning message content. */
|
||||
private final Container noMoneyWarningContainer;
|
||||
private Container noMoneyWarningContainer;
|
||||
|
||||
/** Background container providing a border for the dialog. */
|
||||
private final Container backgroundContainer;
|
||||
|
||||
private Container backgroundContainer;
|
||||
|
||||
/**
|
||||
* Constructs the accept trade dialog.
|
||||
* Constructs the AcceptTrade dialog.
|
||||
*
|
||||
* @param app the Monopoly application instance
|
||||
* @param msg the trade reply message containing details about the trade
|
||||
@@ -47,80 +45,99 @@ public class AcceptTrade extends Dialog {
|
||||
super(app.getDialogManager());
|
||||
this.app = app;
|
||||
|
||||
|
||||
// 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 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);
|
||||
// Initialize GUI elements
|
||||
createOverlayBackground();
|
||||
createBackgroundContainer();
|
||||
createWarningContainer(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a semi-transparent background overlay for the dialog.
|
||||
*
|
||||
* @return the geometry of the overlay
|
||||
*/
|
||||
private Geometry createOverlayBackground() {
|
||||
private void createOverlayBackground() {
|
||||
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
|
||||
Geometry overlay = new Geometry("Overlay", quad);
|
||||
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)); // Halbtransparent
|
||||
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Semi-transparent
|
||||
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
|
||||
overlay.setMaterial(material);
|
||||
overlay.setLocalTranslation(0, 0, 0);
|
||||
return overlay;
|
||||
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
|
||||
*/
|
||||
private void createWarningContainer(TradeReply msg) {
|
||||
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;
|
||||
backgroundContainer.setPreferredSize(noMoneyWarningContainer.getPreferredSize().addLocal(padding, padding, 0));
|
||||
|
||||
// Title
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -128,9 +145,9 @@ public class AcceptTrade extends Dialog {
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
app.getGuiNode().detachChild(noMoneyWarningContainer); // Entferne das Menü
|
||||
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
|
||||
app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
|
||||
app.getGuiNode().detachChild(overlayBackground);
|
||||
app.getGuiNode().detachChild(backgroundContainer);
|
||||
app.getGuiNode().detachChild(noMoneyWarningContainer);
|
||||
super.close();
|
||||
}
|
||||
|
||||
@@ -139,6 +156,6 @@ public class AcceptTrade extends Dialog {
|
||||
*/
|
||||
@Override
|
||||
public void escape() {
|
||||
close();
|
||||
new SettingsMenu(app).open();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -12,24 +12,24 @@ import com.simsilica.lemur.Label;
|
||||
import com.simsilica.lemur.component.QuadBackgroundComponent;
|
||||
import com.simsilica.lemur.style.ElementId;
|
||||
import pp.dialog.Dialog;
|
||||
import pp.dialog.PopupDialog;
|
||||
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 {
|
||||
public class Bankrupt extends Dialog implements PopupDialog {
|
||||
/** Reference to the Monopoly application instance. */
|
||||
private final MonopolyApp app;
|
||||
|
||||
/** Semi-transparent overlay background for the popup. */
|
||||
private final Geometry overlayBackground;
|
||||
private Geometry overlayBackground;
|
||||
|
||||
/** Main container for the bankruptcy warning content. */
|
||||
private final Container bankruptContainer;
|
||||
private Container bankruptContainer;
|
||||
|
||||
/** Background container providing a border for the popup. */
|
||||
private final Container backgroundContainer;
|
||||
|
||||
private Container backgroundContainer;
|
||||
|
||||
/**
|
||||
* Constructs the bankruptcy warning popup.
|
||||
@@ -40,86 +40,102 @@ public class Bankrupt extends Dialog {
|
||||
super(app.getDialogManager());
|
||||
this.app = app;
|
||||
|
||||
|
||||
// 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
|
||||
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);
|
||||
// Initialize the components
|
||||
createOverlayBackground();
|
||||
createBackgroundContainer();
|
||||
createBankruptContainer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a semi-transparent background overlay for the popup.
|
||||
*
|
||||
* @return the geometry of the overlay
|
||||
*/
|
||||
private Geometry createOverlayBackground() {
|
||||
private void createOverlayBackground() {
|
||||
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
|
||||
Geometry overlay = new Geometry("Overlay", quad);
|
||||
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)); // Halbtransparent
|
||||
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Semi-transparent
|
||||
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
|
||||
overlay.setMaterial(material);
|
||||
overlay.setLocalTranslation(0, 0, 0);
|
||||
return overlay;
|
||||
overlayBackground.setMaterial(material);
|
||||
overlayBackground.setLocalTranslation(0, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the menu and removes the GUI elements.
|
||||
* Creates the background container for the popup.
|
||||
*/
|
||||
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
|
||||
public void close() {
|
||||
app.getGuiNode().detachChild(bankruptContainer); // Entferne das Menü
|
||||
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
|
||||
app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
|
||||
app.getGuiNode().detachChild(overlayBackground);
|
||||
app.getGuiNode().detachChild(backgroundContainer);
|
||||
app.getGuiNode().detachChild(bankruptContainer);
|
||||
super.close();
|
||||
}
|
||||
|
||||
@@ -130,4 +146,4 @@ public class Bankrupt extends Dialog {
|
||||
public void escape() {
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
package pp.monopoly.client.gui.popups;
|
||||
|
||||
import com.jme3.math.ColorRGBA;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.simsilica.lemur.Button;
|
||||
import com.simsilica.lemur.Container;
|
||||
import com.simsilica.lemur.Label;
|
||||
@@ -8,6 +9,7 @@ import com.simsilica.lemur.component.QuadBackgroundComponent;
|
||||
import com.simsilica.lemur.style.ElementId;
|
||||
|
||||
import pp.dialog.Dialog;
|
||||
import pp.dialog.PopupDialog;
|
||||
import pp.monopoly.client.MonopolyApp;
|
||||
import pp.monopoly.client.gui.SettingsMenu;
|
||||
import pp.monopoly.message.client.BuyPropertyResponse;
|
||||
@@ -16,16 +18,12 @@ import pp.monopoly.model.fields.BuildingProperty;
|
||||
import pp.monopoly.notification.Sound;
|
||||
|
||||
/**
|
||||
* BuildingPropertyCard creates the popup for field information
|
||||
* BuildingPropertyCard creates a popup for displaying field information.
|
||||
*/
|
||||
public class BuildingPropertyCard extends Dialog {
|
||||
/** Reference to the Monopoly application instance. */
|
||||
public class BuildingPropertyCard extends Dialog implements PopupDialog {
|
||||
|
||||
private final MonopolyApp app;
|
||||
|
||||
/** Main container for the building property information. */
|
||||
private final Container buildingPropertyContainer;
|
||||
|
||||
/** Background container providing a border for the property card. */
|
||||
private final Container backgroundContainer;
|
||||
|
||||
/**
|
||||
@@ -37,84 +35,123 @@ public class BuildingPropertyCard extends Dialog {
|
||||
super(app.getDialogManager());
|
||||
this.app = app;
|
||||
|
||||
//Generate the corresponding field
|
||||
int index = app.getGameLogic().getPlayerHandler().getPlayerById(app.getId()).getFieldID();
|
||||
BuildingProperty field = (BuildingProperty) new BoardManager().getFieldAtIndex(index);
|
||||
|
||||
// Create the background container
|
||||
backgroundContainer = new Container();
|
||||
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Darker background
|
||||
attachChild(backgroundContainer);
|
||||
|
||||
// Hauptcontainer für die Gebäudekarte
|
||||
// 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());
|
||||
|
||||
float padding = 10; // Passt den backgroundContainer an die Größe des buildingPropertyContainer an
|
||||
// Create the background container
|
||||
backgroundContainer = new Container();
|
||||
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray
|
||||
|
||||
// Add padding to the background
|
||||
float padding = 10f;
|
||||
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);
|
||||
|
||||
// Text, der auf der Karte steht
|
||||
// Die Preise werden dynamisch dem BoardManager entnommen
|
||||
Container propertyValuesContainer = buildingPropertyContainer.addChild(new Container());
|
||||
propertyValuesContainer.addChild(new Label("„Grundstückswert: " + field.getPrice() + " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));// Leerzeile
|
||||
propertyValuesContainer.addChild(new Label("„Miete allein: " + field.getAllRent().get(0)+ " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("„-mit 1 Haus: " + field.getAllRent().get(1) + " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("„-mit 2 Häuser: " + field.getAllRent().get(2) + " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("„-mit 3 Häuser: " + field.getAllRent().get(3) + " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("„-mit 4 Häuser: " + field.getAllRent().get(4) + " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("„-mit 1 Hotel: " + field.getAllRent().get(5) + " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("„-1 Haus kostet: " + field.getHousePrice()+ " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));// Leerzeile
|
||||
propertyValuesContainer.addChild(new Label("„Hypothek: " + field.getHypo() + " EUR", new ElementId("label-Text")));
|
||||
System.out.println(backgroundContainer.getPreferredSize());
|
||||
|
||||
// Position the containers
|
||||
centerContainers(padding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the property details and buttons to the container.
|
||||
*
|
||||
* @param container the main container for the property card
|
||||
* @param field the building property to display
|
||||
*/
|
||||
private void addContentToContainer(Container container, BuildingProperty field) {
|
||||
// Title
|
||||
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)));
|
||||
|
||||
// Beenden-Button
|
||||
Button quitButton = buildingPropertyContainer.addChild(new Button("Beenden", new ElementId("button")));
|
||||
// Add buttons
|
||||
addButtons(container);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.addClickCommands(s -> ifTopDialog( () -> {
|
||||
System.err.println("Button does something?");
|
||||
quitButton.addClickCommands(s -> ifTopDialog(() -> {
|
||||
app.getGameLogic().playSound(Sound.BUTTON);
|
||||
close();
|
||||
}));
|
||||
// Kaufen-Button
|
||||
Button buyButton = buildingPropertyContainer.addChild(new Button("Kaufen", new ElementId("button")));
|
||||
|
||||
// Buy button
|
||||
Button buyButton = container.addChild(new Button("Kaufen", new ElementId("button")));
|
||||
buyButton.setFontSize(32);
|
||||
buyButton.addClickCommands(s -> ifTopDialog( () -> {
|
||||
buyButton.addClickCommands(s -> ifTopDialog(() -> {
|
||||
app.getGameLogic().playSound(Sound.BUTTON);
|
||||
close();
|
||||
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(
|
||||
(app.getCamera().getWidth() - buildingPropertyContainer.getPreferredSize().x) / 2,
|
||||
(app.getCamera().getHeight() + buildingPropertyContainer.getPreferredSize().y) / 2,
|
||||
8
|
||||
);
|
||||
|
||||
// Zentriere das Popup
|
||||
// Center background container with padding
|
||||
backgroundContainer.setLocalTranslation(
|
||||
(app.getCamera().getWidth() - buildingPropertyContainer.getPreferredSize().x - padding) / 2,
|
||||
(app.getCamera().getHeight() + buildingPropertyContainer.getPreferredSize().y+ padding) / 2,
|
||||
7
|
||||
(app.getCamera().getWidth() - buildingPropertyContainer.getPreferredSize().x - padding) / 2,
|
||||
(app.getCamera().getHeight() + buildingPropertyContainer.getPreferredSize().y + padding) / 2,
|
||||
7
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches the popup to the GUI through the DialogManager.
|
||||
*/
|
||||
@Override
|
||||
public void show() {
|
||||
app.getGuiNode().attachChild(backgroundContainer);
|
||||
app.getGuiNode().attachChild(buildingPropertyContainer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the popup and removes the associated GUI elements.
|
||||
* Closes the popup and removes associated GUI elements.
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
app.getGuiNode().detachChild(buildingPropertyContainer); // Entferne das Menü
|
||||
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
|
||||
app.getGuiNode().detachChild(buildingPropertyContainer);
|
||||
app.getGuiNode().detachChild(backgroundContainer);
|
||||
super.close();
|
||||
}
|
||||
|
||||
@@ -125,4 +162,4 @@ public class BuildingPropertyCard extends Dialog {
|
||||
public void escape() {
|
||||
new SettingsMenu(app).open();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -7,7 +7,6 @@ import com.simsilica.lemur.Button;
|
||||
import com.simsilica.lemur.Container;
|
||||
import com.simsilica.lemur.Label;
|
||||
import com.simsilica.lemur.Selector;
|
||||
import com.simsilica.lemur.TextField;
|
||||
import com.simsilica.lemur.component.QuadBackgroundComponent;
|
||||
import com.simsilica.lemur.component.SpringGridLayout;
|
||||
import com.simsilica.lemur.core.VersionedList;
|
||||
@@ -77,7 +76,7 @@ public class BuyHouse extends Dialog {
|
||||
backgroundContainer.setPreferredSize(buyHouseContainer.getPreferredSize().addLocal(padding, padding, 0));
|
||||
|
||||
// Title
|
||||
Label title = buyHouseContainer.addChild(new Label("Gebäude Kaufen", new ElementId("warning-Bold")));
|
||||
Label title = buyHouseContainer.addChild(new Label("Gebäude Kaufen", new ElementId("label-Bold")));
|
||||
title.setFontSize(48);
|
||||
title.setColor(ColorRGBA.Black);
|
||||
|
||||
@@ -125,13 +124,13 @@ public class BuyHouse extends Dialog {
|
||||
buyHouseContainer.setLocalTranslation(
|
||||
(app.getCamera().getWidth() - buyHouseContainer.getPreferredSize().x) / 2,
|
||||
(app.getCamera().getHeight() + buyHouseContainer.getPreferredSize().y) / 2,
|
||||
11
|
||||
9
|
||||
);
|
||||
|
||||
backgroundContainer.setLocalTranslation(
|
||||
(app.getCamera().getWidth() - buyHouseContainer.getPreferredSize().x - padding) / 2,
|
||||
(app.getCamera().getHeight() + buyHouseContainer.getPreferredSize().y + padding) / 2,
|
||||
10
|
||||
8
|
||||
);
|
||||
|
||||
app.getGuiNode().attachChild(buyHouseContainer);
|
||||
@@ -145,7 +144,7 @@ public class BuyHouse extends Dialog {
|
||||
private Container createPropertyDropdown() {
|
||||
Container dropdownContainer = new Container(new SpringGridLayout(Axis.Y, Axis.X));
|
||||
dropdownContainer.setPreferredSize(new Vector3f(300, 200, 0));
|
||||
dropdownContainer.setBackground(new QuadBackgroundComponent(ColorRGBA.Orange));
|
||||
dropdownContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.0f, 0.0f, 0.0f, 1.0f)));
|
||||
|
||||
VersionedList<String> propertyOptions = new VersionedList<>();
|
||||
List<BuildingProperty> playerProperties = getPlayerProperties();
|
||||
@@ -164,6 +163,7 @@ public class BuyHouse extends Dialog {
|
||||
// Initialize the selection display here
|
||||
selectionDisplay = new Label("");
|
||||
selectionDisplay.setPreferredSize(new Vector3f(300, 30, 0));
|
||||
selectionDisplay.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
|
||||
dropdownContainer.addChild(selectionDisplay); // Add it to the dropdown container
|
||||
|
||||
// Set initial selection
|
||||
|
@@ -7,6 +7,7 @@ import com.simsilica.lemur.Label;
|
||||
import com.simsilica.lemur.component.QuadBackgroundComponent;
|
||||
import com.simsilica.lemur.style.ElementId;
|
||||
import pp.dialog.Dialog;
|
||||
import pp.dialog.PopupDialog;
|
||||
import pp.monopoly.client.MonopolyApp;
|
||||
import pp.monopoly.client.gui.SettingsMenu;
|
||||
import pp.monopoly.client.gui.TradeMenu;
|
||||
@@ -18,18 +19,18 @@ import pp.monopoly.notification.Sound;
|
||||
/**
|
||||
* ConfirmTrade is a popup which appears when a trade is proposed to this certain player.
|
||||
*/
|
||||
public class ConfirmTrade extends Dialog {
|
||||
public class ConfirmTrade extends Dialog implements PopupDialog {
|
||||
/** Reference to the Monopoly application instance. */
|
||||
private final MonopolyApp app;
|
||||
|
||||
/** Main container for the "Confirm Trade" popup UI. */
|
||||
private final Container confirmTradeContainer;
|
||||
private Container confirmTradeContainer;
|
||||
|
||||
/** Background container providing a border for the popup. */
|
||||
private final Container backgroundContainer;
|
||||
private Container backgroundContainer;
|
||||
|
||||
/** The trade handler managing the details of the trade proposal. */
|
||||
private TradeHandler tradeHandler;
|
||||
private final TradeHandler tradeHandler;
|
||||
|
||||
/**
|
||||
* Constructs the "Confirm Trade" popup.
|
||||
@@ -39,53 +40,61 @@ public class ConfirmTrade extends Dialog {
|
||||
public ConfirmTrade(MonopolyApp app) {
|
||||
super(app.getDialogManager());
|
||||
this.app = app;
|
||||
tradeHandler = app.getGameLogic().getTradeHandler();
|
||||
this.tradeHandler = app.getGameLogic().getTradeHandler();
|
||||
|
||||
// Create the background container
|
||||
// Initialize components
|
||||
createBackgroundContainer();
|
||||
createConfirmTradeContainer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the background container.
|
||||
*/
|
||||
private void createBackgroundContainer() {
|
||||
backgroundContainer = new Container();
|
||||
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();
|
||||
|
||||
float padding = 10;
|
||||
backgroundContainer.setPreferredSize(confirmTradeContainer.getPreferredSize().addLocal(padding, padding, 0));
|
||||
|
||||
// Titel
|
||||
Label title = confirmTradeContainer.addChild(new Label( "Handel", new ElementId("warning-title")));
|
||||
// Title
|
||||
Label title = confirmTradeContainer.addChild(new Label("Handel", new ElementId("warning-title")));
|
||||
title.setFontSize(48);
|
||||
title.setColor(ColorRGBA.Black);
|
||||
|
||||
// Build trade information strings
|
||||
StringBuilder offeredProperties = new StringBuilder();
|
||||
for (PropertyField field : tradeHandler.getOfferedProperties()) {
|
||||
offeredProperties.append(field.getName());
|
||||
offeredProperties.append(", ");
|
||||
offeredProperties.append(field.getName()).append(", ");
|
||||
}
|
||||
|
||||
StringBuilder requestedProperties = new StringBuilder();
|
||||
for (PropertyField field : tradeHandler.getRequestedProperties()) {
|
||||
requestedProperties.append(field.getName());
|
||||
requestedProperties.append(", ");
|
||||
requestedProperties.append(field.getName()).append(", ");
|
||||
}
|
||||
|
||||
// Text, der auf der Karte steht
|
||||
// Trade details
|
||||
Container propertyValuesContainer = confirmTradeContainer.addChild(new Container());
|
||||
propertyValuesContainer.addChild(new Label("„Spieler " + " " + tradeHandler.getSender().getName() + " " +" möchte:", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));// Leerzeile
|
||||
propertyValuesContainer.addChild(new Label( tradeHandler.getSender().getName() + " möchte:", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("", 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.getOfferedJailCards() +" Sonderkarten", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));// Leerzeile
|
||||
propertyValuesContainer.addChild(new Label("- " + tradeHandler.getOfferedJailCards() + " Sonderkarten", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("gegen:", 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("- "+ tradeHandler.getRequestedAmount() +" EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("- "+ tradeHandler.getRequestedJailCards() +" Sonderkarten", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));// Leerzeile
|
||||
propertyValuesContainer.addChild(new Label("", 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.getRequestedJailCards() + " Sonderkarten", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("", 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)));
|
||||
|
||||
// Ablehnen-Button
|
||||
// Decline button
|
||||
Button declineButton = confirmTradeContainer.addChild(new Button("Ablehnen", new ElementId("button")));
|
||||
declineButton.setFontSize(32);
|
||||
declineButton.addClickCommands(s -> ifTopDialog(() -> {
|
||||
@@ -93,39 +102,50 @@ public class ConfirmTrade extends Dialog {
|
||||
app.getGameLogic().send(new TradeResponse(false, tradeHandler));
|
||||
close();
|
||||
}));
|
||||
// Verhandeln-Button
|
||||
|
||||
// Negotiate button
|
||||
Button negotiateButton = confirmTradeContainer.addChild(new Button("Verhandeln", new ElementId("button")));
|
||||
negotiateButton.setFontSize(32);
|
||||
negotiateButton.addClickCommands(s -> ifTopDialog( () -> {
|
||||
negotiateButton.addClickCommands(s -> ifTopDialog(() -> {
|
||||
app.getGameLogic().playSound(Sound.BUTTON);
|
||||
close();
|
||||
TradeHandler t = new TradeHandler(app.getGameLogic().getPlayerHandler().getPlayerById(tradeHandler.getSender().getId()));
|
||||
t.setReceiver(app.getGameLogic().getPlayerHandler().getPlayerById(tradeHandler.getReceiver().getId()));
|
||||
new TradeMenu(app, t).open();
|
||||
}));
|
||||
// Confirm-Button
|
||||
|
||||
// Confirm button
|
||||
Button confirmButton = confirmTradeContainer.addChild(new Button("Bestätigen", new ElementId("button")));
|
||||
confirmButton.setFontSize(32);
|
||||
confirmButton.addClickCommands(s -> ifTopDialog( () -> {
|
||||
confirmButton.addClickCommands(s -> ifTopDialog(() -> {
|
||||
app.getGameLogic().playSound(Sound.BUTTON);
|
||||
app.getGameLogic().send(new TradeResponse(true, tradeHandler));
|
||||
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(
|
||||
(app.getCamera().getWidth() - confirmTradeContainer.getPreferredSize().x) / 2,
|
||||
(app.getCamera().getHeight() + confirmTradeContainer.getPreferredSize().y) / 2,
|
||||
8
|
||||
(app.getCamera().getWidth() - confirmTradeContainer.getPreferredSize().x) / 2,
|
||||
(app.getCamera().getHeight() + confirmTradeContainer.getPreferredSize().y) / 2,
|
||||
8
|
||||
);
|
||||
|
||||
// Zentriere das Menü
|
||||
backgroundContainer.setLocalTranslation(
|
||||
(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
|
||||
);
|
||||
|
||||
// Attach to GUI node
|
||||
app.getGuiNode().attachChild(backgroundContainer);
|
||||
app.getGuiNode().attachChild(confirmTradeContainer);
|
||||
}
|
||||
|
||||
|
@@ -12,25 +12,25 @@ import com.simsilica.lemur.Label;
|
||||
import com.simsilica.lemur.component.QuadBackgroundComponent;
|
||||
import com.simsilica.lemur.style.ElementId;
|
||||
import pp.dialog.Dialog;
|
||||
import pp.dialog.PopupDialog;
|
||||
import pp.monopoly.client.MonopolyApp;
|
||||
import pp.monopoly.notification.Sound;
|
||||
|
||||
/**
|
||||
* EventCardPopup is a popup which appears when a certain EventCard is triggered by entering a EventCardField
|
||||
* EventCardPopup is a popup which appears when a certain EventCard is triggered by entering an EventCardField.
|
||||
*/
|
||||
public class EventCardPopup extends Dialog {
|
||||
public class EventCardPopup extends Dialog implements PopupDialog {
|
||||
/** Reference to the Monopoly application instance. */
|
||||
private final MonopolyApp app;
|
||||
|
||||
/** Semi-transparent overlay background for the popup. */
|
||||
private final Geometry overlayBackground;
|
||||
private Geometry overlayBackground;
|
||||
|
||||
/** Main container for the event card information. */
|
||||
private final Container eventCardContainer;
|
||||
private Container eventCardContainer;
|
||||
|
||||
/** Background container providing a border for the popup. */
|
||||
private final Container backgroundContainer;
|
||||
|
||||
private Container backgroundContainer;
|
||||
|
||||
/**
|
||||
* Constructs the EventCardPopup to display the details of a triggered event card.
|
||||
@@ -42,74 +42,87 @@ public class EventCardPopup extends Dialog {
|
||||
super(app.getDialogManager());
|
||||
this.app = app;
|
||||
|
||||
// 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);
|
||||
|
||||
|
||||
eventCardContainer = new Container();
|
||||
eventCardContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f)));
|
||||
eventCardContainer.setPreferredSize(new Vector3f(550,400,10));
|
||||
|
||||
float padding = 10;
|
||||
backgroundContainer.setPreferredSize(eventCardContainer.getPreferredSize().addLocal(padding, padding, 0));
|
||||
|
||||
// Titel
|
||||
Label gateFieldTitle = eventCardContainer.addChild(new Label("Ereigniskarte", new ElementId("settings-title")));
|
||||
gateFieldTitle.setFontSize(48);
|
||||
gateFieldTitle.setColor(ColorRGBA.Black);
|
||||
|
||||
// Text, der auf der Karte steht
|
||||
// Die Erklärungsfelder werden automatisch den descriptions der Message entnommen
|
||||
Container propertyValuesContainer = eventCardContainer.addChild(new Container());
|
||||
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,10));
|
||||
|
||||
// Beenden-Button
|
||||
Button quitButton = eventCardContainer.addChild(new Button("Jawohl", new ElementId("button")));
|
||||
quitButton.setFontSize(32);
|
||||
quitButton.addClickCommands(source -> ifTopDialog( () -> {
|
||||
app.getGameLogic().playSound(Sound.BUTTON);
|
||||
close();
|
||||
}));
|
||||
|
||||
// Zentriere das Popup
|
||||
eventCardContainer.setLocalTranslation(
|
||||
(app.getCamera().getWidth() - eventCardContainer.getPreferredSize().x) / 2,
|
||||
(app.getCamera().getHeight() + eventCardContainer.getPreferredSize().y) / 2,
|
||||
9
|
||||
);
|
||||
|
||||
// Zentriere das Popup
|
||||
backgroundContainer.setLocalTranslation(
|
||||
(app.getCamera().getWidth() - eventCardContainer.getPreferredSize().x - padding) / 2,
|
||||
(app.getCamera().getHeight() + eventCardContainer.getPreferredSize().y+ padding) / 2,
|
||||
8
|
||||
);
|
||||
|
||||
app.getGuiNode().attachChild(eventCardContainer);
|
||||
// Initialize the UI components
|
||||
createOverlayBackground();
|
||||
createBackgroundContainer();
|
||||
createEventCardContainer(description);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a semi-transparent background overlay for the popup.
|
||||
*
|
||||
* @return the geometry of the overlay
|
||||
* Initializes the semi-transparent background overlay.
|
||||
*/
|
||||
private Geometry createOverlayBackground() {
|
||||
private void createOverlayBackground() {
|
||||
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
|
||||
Geometry overlay = new Geometry("Overlay", quad);
|
||||
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));
|
||||
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Semi-transparent black
|
||||
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
|
||||
overlay.setMaterial(material);
|
||||
overlay.setLocalTranslation(0, 0, 0);
|
||||
return overlay;
|
||||
overlayBackground.setMaterial(material);
|
||||
overlayBackground.setLocalTranslation(0, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the background container.
|
||||
*/
|
||||
private void createBackgroundContainer() {
|
||||
backgroundContainer = new Container();
|
||||
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray background
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f)));
|
||||
eventCardContainer.setPreferredSize(new Vector3f(550, 400, 10));
|
||||
|
||||
// Title
|
||||
Label title = eventCardContainer.addChild(new Label("Ereigniskarte", new ElementId("settings-title")));
|
||||
title.setFontSize(48);
|
||||
title.setColor(ColorRGBA.Black);
|
||||
|
||||
// Event description
|
||||
Container textContainer = eventCardContainer.addChild(new Container());
|
||||
textContainer.addChild(new Label(description, new ElementId("label-Text")));
|
||||
textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
|
||||
textContainer.setPreferredSize(new Vector3f(300, 200, 0));
|
||||
|
||||
// Confirm button
|
||||
Button confirmButton = eventCardContainer.addChild(new Button("Jawohl", new ElementId("button")));
|
||||
confirmButton.setFontSize(32);
|
||||
confirmButton.addClickCommands(source -> ifTopDialog(() -> {
|
||||
app.getGameLogic().playSound(Sound.BUTTON);
|
||||
close();
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the popup by attaching it to the GUI.
|
||||
*/
|
||||
@Override
|
||||
public void show() {
|
||||
float padding = 10;
|
||||
|
||||
// Adjust sizes and center elements
|
||||
backgroundContainer.setPreferredSize(eventCardContainer.getPreferredSize().addLocal(padding, padding, 0));
|
||||
eventCardContainer.setLocalTranslation(
|
||||
(app.getCamera().getWidth() - eventCardContainer.getPreferredSize().x) / 2,
|
||||
(app.getCamera().getHeight() + eventCardContainer.getPreferredSize().y) / 2,
|
||||
8
|
||||
);
|
||||
backgroundContainer.setLocalTranslation(
|
||||
(app.getCamera().getWidth() - eventCardContainer.getPreferredSize().x - padding) / 2,
|
||||
(app.getCamera().getHeight() + eventCardContainer.getPreferredSize().y + padding) / 2,
|
||||
7
|
||||
);
|
||||
|
||||
// Attach components to the GUI
|
||||
app.getGuiNode().attachChild(overlayBackground);
|
||||
app.getGuiNode().attachChild(backgroundContainer);
|
||||
app.getGuiNode().attachChild(eventCardContainer);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -117,9 +130,9 @@ public class EventCardPopup extends Dialog {
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
app.getGuiNode().detachChild(overlayBackground);
|
||||
app.getGuiNode().detachChild(eventCardContainer);
|
||||
app.getGuiNode().detachChild(backgroundContainer);
|
||||
app.getGuiNode().detachChild(overlayBackground);
|
||||
super.close();
|
||||
}
|
||||
|
||||
@@ -130,4 +143,4 @@ public class EventCardPopup extends Dialog {
|
||||
public void escape() {
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -3,6 +3,7 @@ package pp.monopoly.client.gui.popups;
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.material.RenderState.BlendMode;
|
||||
import com.jme3.math.ColorRGBA;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.scene.Geometry;
|
||||
import com.jme3.scene.shape.Quad;
|
||||
import com.simsilica.lemur.Button;
|
||||
@@ -12,27 +13,27 @@ import com.simsilica.lemur.component.QuadBackgroundComponent;
|
||||
import com.simsilica.lemur.style.ElementId;
|
||||
|
||||
import pp.dialog.Dialog;
|
||||
import pp.dialog.PopupDialog;
|
||||
import pp.monopoly.client.MonopolyApp;
|
||||
import pp.monopoly.client.gui.SettingsMenu;
|
||||
import pp.monopoly.message.client.BuyPropertyResponse;
|
||||
import pp.monopoly.model.fields.FoodField;
|
||||
import pp.monopoly.notification.Sound;
|
||||
|
||||
/**
|
||||
* FoodFieldCard creates the popup for field information
|
||||
* FoodFieldCard creates the popup for field information.
|
||||
*/
|
||||
public class FoodFieldCard extends Dialog {
|
||||
public class FoodFieldCard extends Dialog implements PopupDialog {
|
||||
/** Reference to the Monopoly application instance. */
|
||||
private final MonopolyApp app;
|
||||
|
||||
/** Semi-transparent overlay background for the popup. */
|
||||
private final Geometry overlayBackground;
|
||||
private Geometry overlayBackground;
|
||||
|
||||
/** Main container for the food field information. */
|
||||
private final Container foodFieldContainer;
|
||||
private Container foodFieldContainer;
|
||||
|
||||
/** Background container providing a border for the popup. */
|
||||
private final Container backgroundContainer;
|
||||
private Container backgroundContainer;
|
||||
|
||||
/**
|
||||
* Constructs a FoodFieldCard popup displaying details about a food field.
|
||||
@@ -43,89 +44,109 @@ public class FoodFieldCard extends Dialog {
|
||||
super(app.getDialogManager());
|
||||
this.app = app;
|
||||
|
||||
// Retrieve field information
|
||||
int index = app.getGameLogic().getPlayerHandler().getPlayerById(app.getId()).getFieldID();
|
||||
FoodField field = (FoodField) app.getGameLogic().getBoardManager().getFieldAtIndex(index);
|
||||
|
||||
overlayBackground = createOverlayBackground();
|
||||
app.getGuiNode().attachChild(overlayBackground);
|
||||
// Create UI elements
|
||||
createOverlayBackground();
|
||||
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.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Darker background
|
||||
attachChild(backgroundContainer);
|
||||
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray background
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.1f, 0.1f, 0.1f, 0.9f)));
|
||||
foodFieldContainer.setPreferredSize(new Vector3f(360,445,1));
|
||||
|
||||
float padding = 10;
|
||||
backgroundContainer.setPreferredSize(foodFieldContainer.getPreferredSize().addLocal(padding, padding, 0));
|
||||
|
||||
Label settingsTitle = foodFieldContainer.addChild(new Label(field.getName(), new ElementId("label-Bold")));
|
||||
settingsTitle.setFontSize(48);
|
||||
settingsTitle.setColor(ColorRGBA.White);
|
||||
// Title
|
||||
Label title = foodFieldContainer.addChild(new Label(field.getName(), new ElementId("label-Bold")));
|
||||
title.setFontSize(48);
|
||||
title.setColor(ColorRGBA.White);
|
||||
|
||||
// Field details
|
||||
Container propertyValuesContainer = foodFieldContainer.addChild(new Container());
|
||||
propertyValuesContainer.addChild(new Label("„Preis: " + field.getPrice() + " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); // Leerzeile
|
||||
propertyValuesContainer.addChild(new Label("„Wenn man Besitzer des", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label(field.getName()+" ist, so ist die", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("Miete 40-mal so hoch, wie", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("Augen auf den zwei Würfeln sind.", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); // Leerzeile
|
||||
propertyValuesContainer.addChild(new Label("„Wenn man Besitzer beider", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("Restaurants ist, so ist die", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("Miete 100-mal so hoch, wie", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("Augen auf den zwei Würfeln sind.", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); // Leerzeile
|
||||
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); // Empty line
|
||||
propertyValuesContainer.addChild(new Label("„Miete: 40x Würfel-Augen,", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("„wenn Besitzer eines ", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("„Restaurants.", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("„Miete: 100x Würfel-Augen, ", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("„wenn Besitzer eines ", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("„Restaurants.", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); // Empty line
|
||||
propertyValuesContainer.addChild(new Label("„Hypothek: " + field.getHypo() + " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
|
||||
|
||||
// Beenden-Button
|
||||
// Quit button
|
||||
Button quitButton = foodFieldContainer.addChild(new Button("Beenden", new ElementId("button")));
|
||||
quitButton.setFontSize(32);
|
||||
quitButton.addClickCommands(s -> ifTopDialog( () -> {
|
||||
quitButton.addClickCommands(s -> ifTopDialog(() -> {
|
||||
app.getGameLogic().playSound(Sound.BUTTON);
|
||||
close();
|
||||
}));
|
||||
// Kaufen-Button
|
||||
|
||||
// Buy button
|
||||
Button buyButton = foodFieldContainer.addChild(new Button("Kaufen", new ElementId("button")));
|
||||
buyButton.setFontSize(32);
|
||||
buyButton.addClickCommands(s -> ifTopDialog( () -> {
|
||||
buyButton.addClickCommands(s -> ifTopDialog(() -> {
|
||||
app.getGameLogic().playSound(Sound.BUTTON);
|
||||
app.getGameLogic().send(new BuyPropertyResponse());
|
||||
close();
|
||||
}));
|
||||
|
||||
// Zentriere das Popup
|
||||
foodFieldContainer.setLocalTranslation(
|
||||
(app.getCamera().getWidth() - foodFieldContainer.getPreferredSize().x) / 2,
|
||||
(app.getCamera().getHeight() + foodFieldContainer.getPreferredSize().y) / 2,
|
||||
8
|
||||
);
|
||||
|
||||
// Zentriere das Popup
|
||||
backgroundContainer.setLocalTranslation(
|
||||
(app.getCamera().getWidth() - foodFieldContainer.getPreferredSize().x - padding) / 2,
|
||||
(app.getCamera().getHeight() + foodFieldContainer.getPreferredSize().y+ padding) / 2,
|
||||
7
|
||||
);
|
||||
|
||||
app.getGuiNode().attachChild(foodFieldContainer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a semi-transparent background overlay for the popup.
|
||||
*
|
||||
* @return the geometry of the overlay
|
||||
* Displays the popup by attaching its elements to the GUI.
|
||||
*/
|
||||
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;
|
||||
@Override
|
||||
public void show() {
|
||||
float padding = 10;
|
||||
|
||||
// Adjust sizes and center elements
|
||||
backgroundContainer.setPreferredSize(foodFieldContainer.getPreferredSize().addLocal(padding, padding, 0));
|
||||
foodFieldContainer.setLocalTranslation(
|
||||
(app.getCamera().getWidth() - foodFieldContainer.getPreferredSize().x) / 2,
|
||||
(app.getCamera().getHeight() + foodFieldContainer.getPreferredSize().y) / 2,
|
||||
8
|
||||
);
|
||||
backgroundContainer.setLocalTranslation(
|
||||
(app.getCamera().getWidth() - foodFieldContainer.getPreferredSize().x - padding) / 2,
|
||||
(app.getCamera().getHeight() + foodFieldContainer.getPreferredSize().y + padding) / 2,
|
||||
7
|
||||
);
|
||||
|
||||
// Attach components to the GUI
|
||||
app.getGuiNode().attachChild(overlayBackground);
|
||||
app.getGuiNode().attachChild(backgroundContainer);
|
||||
app.getGuiNode().attachChild(foodFieldContainer);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,18 +154,17 @@ public class FoodFieldCard extends Dialog {
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
app.getGuiNode().detachChild(foodFieldContainer); // Entferne das Menü
|
||||
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
|
||||
app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
|
||||
app.getGuiNode().detachChild(overlayBackground);
|
||||
app.getGuiNode().detachChild(foodFieldContainer);
|
||||
app.getGuiNode().detachChild(backgroundContainer);
|
||||
super.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the settings menu when the escape key is pressed.
|
||||
* Handles the escape key action by closing the popup.
|
||||
*/
|
||||
@Override
|
||||
public void escape() {
|
||||
new SettingsMenu(app).open();
|
||||
close();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,12 +1,15 @@
|
||||
package pp.monopoly.client.gui.popups;
|
||||
|
||||
import com.jme3.math.ColorRGBA;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.simsilica.lemur.Button;
|
||||
import com.simsilica.lemur.Container;
|
||||
import com.simsilica.lemur.Label;
|
||||
import com.simsilica.lemur.component.QuadBackgroundComponent;
|
||||
import com.simsilica.lemur.style.ElementId;
|
||||
|
||||
import pp.dialog.Dialog;
|
||||
import pp.dialog.PopupDialog;
|
||||
import pp.monopoly.client.MonopolyApp;
|
||||
import pp.monopoly.client.gui.SettingsMenu;
|
||||
import pp.monopoly.message.client.BuyPropertyResponse;
|
||||
@@ -14,17 +17,17 @@ import pp.monopoly.model.fields.GateField;
|
||||
import pp.monopoly.notification.Sound;
|
||||
|
||||
/**
|
||||
* GateFieldCard creates the popup for field information
|
||||
* GateFieldCard creates the popup for field information.
|
||||
*/
|
||||
public class GateFieldCard extends Dialog {
|
||||
public class GateFieldCard extends Dialog implements PopupDialog {
|
||||
/** Reference to the Monopoly application instance. */
|
||||
private final MonopolyApp app;
|
||||
|
||||
/** Main container for the gate field information. */
|
||||
private final Container gateFieldContainer;
|
||||
private Container gateFieldContainer;
|
||||
|
||||
/** Background container providing a border for the popup. */
|
||||
private final Container backgroundContainer;
|
||||
private Container backgroundContainer;
|
||||
|
||||
/**
|
||||
* Constructs a GateFieldCard popup displaying details about a gate field.
|
||||
@@ -35,73 +38,94 @@ public class GateFieldCard extends Dialog {
|
||||
super(app.getDialogManager());
|
||||
this.app = app;
|
||||
|
||||
//Generate the corresponfing field
|
||||
// Generate the corresponding field
|
||||
int index = app.getGameLogic().getPlayerHandler().getPlayerById(app.getId()).getFieldID();
|
||||
GateField field = (GateField) app.getGameLogic().getBoardManager().getFieldAtIndex(index);
|
||||
|
||||
// Create the background container
|
||||
backgroundContainer = new Container();
|
||||
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Darker background
|
||||
attachChild(backgroundContainer);
|
||||
// Initialize UI elements
|
||||
createBackgroundContainer();
|
||||
createGateFieldContainer(field);
|
||||
}
|
||||
|
||||
// Hauptcontainer für die Gebäudekarte
|
||||
/**
|
||||
* Initializes the background container.
|
||||
*/
|
||||
private void createBackgroundContainer() {
|
||||
backgroundContainer = new Container();
|
||||
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray background
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
//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)));
|
||||
|
||||
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
|
||||
// Title
|
||||
Label gateFieldTitle = gateFieldContainer.addChild(new Label(field.getName(), new ElementId("label-Bold")));
|
||||
gateFieldTitle.setFontSize(48);
|
||||
gateFieldTitle.setColor(ColorRGBA.Black);
|
||||
|
||||
// Text, der auf der Karte steht
|
||||
// Die Preise werden dynamisch dem BoardManager entnommen
|
||||
// Field details
|
||||
Container propertyValuesContainer = gateFieldContainer.addChild(new Container());
|
||||
propertyValuesContainer.addChild(new Label("„Preis: " + field.getPrice() + " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); // Empty line
|
||||
propertyValuesContainer.addChild(new Label("Miete: 250 EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("Wenn man", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("2 Bahnhof besitzt: 500 EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("Wenn man", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("3 Bahnhof besitzt: 1000 EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("Wenn man", 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")));
|
||||
propertyValuesContainer.addChild(new Label("Wenn man 2 Tore", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("besitzt: 500 EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("Wenn man 3 Tore", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("besitzt: 1000 EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("Wenn man 4 Tore", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("besitzt: 2000 EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); // Empty line
|
||||
propertyValuesContainer.addChild(new Label("„Hypothek: " + field.getHypo() + " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
|
||||
|
||||
// Beenden-Button
|
||||
// Quit button
|
||||
Button quitButton = gateFieldContainer.addChild(new Button("Beenden", new ElementId("button")));
|
||||
quitButton.setFontSize(32);
|
||||
quitButton.addClickCommands(s -> ifTopDialog( () -> {
|
||||
quitButton.addClickCommands(s -> ifTopDialog(() -> {
|
||||
app.getGameLogic().playSound(Sound.BUTTON);
|
||||
close();
|
||||
}));
|
||||
// Kaufen-Button
|
||||
|
||||
// Buy button
|
||||
Button buyButton = gateFieldContainer.addChild(new Button("Kaufen", new ElementId("button")));
|
||||
buyButton.setFontSize(32);
|
||||
buyButton.addClickCommands(s -> ifTopDialog( () -> {
|
||||
buyButton.addClickCommands(s -> ifTopDialog(() -> {
|
||||
app.getGameLogic().playSound(Sound.BUTTON);
|
||||
app.getGameLogic().send(new BuyPropertyResponse());
|
||||
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(
|
||||
(app.getCamera().getWidth() - gateFieldContainer.getPreferredSize().x) / 2,
|
||||
(app.getCamera().getHeight() + gateFieldContainer.getPreferredSize().y) / 2,
|
||||
8
|
||||
);
|
||||
|
||||
// Zentriere das Popup
|
||||
backgroundContainer.setLocalTranslation(
|
||||
(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
|
||||
);
|
||||
|
||||
// Attach components to the GUI
|
||||
app.getGuiNode().attachChild(backgroundContainer);
|
||||
app.getGuiNode().attachChild(gateFieldContainer);
|
||||
}
|
||||
|
||||
@@ -110,8 +134,8 @@ public class GateFieldCard extends Dialog {
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
app.getGuiNode().detachChild(gateFieldContainer); // Entferne das Menü
|
||||
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
|
||||
app.getGuiNode().detachChild(gateFieldContainer); // Remove main container
|
||||
app.getGuiNode().detachChild(backgroundContainer); // Remove background container
|
||||
super.close();
|
||||
}
|
||||
|
||||
|
@@ -11,7 +11,9 @@ import com.simsilica.lemur.Container;
|
||||
import com.simsilica.lemur.Label;
|
||||
import com.simsilica.lemur.component.QuadBackgroundComponent;
|
||||
import com.simsilica.lemur.style.ElementId;
|
||||
|
||||
import pp.dialog.Dialog;
|
||||
import pp.dialog.PopupDialog;
|
||||
import pp.monopoly.client.MonopolyApp;
|
||||
import pp.monopoly.notification.Sound;
|
||||
|
||||
@@ -21,21 +23,21 @@ import pp.monopoly.notification.Sound;
|
||||
* This popup informs the player that they are being sent to the Gulag and includes a confirmation button.
|
||||
* </p>
|
||||
*/
|
||||
public class Gulag extends Dialog {
|
||||
public class Gulag extends Dialog implements PopupDialog {
|
||||
/** Reference to the Monopoly application instance. */
|
||||
private final MonopolyApp app;
|
||||
|
||||
/** Semi-transparent overlay background for the popup. */
|
||||
private final Geometry overlayBackground;
|
||||
private Geometry overlayBackground;
|
||||
|
||||
/** Main container for the Gulag warning message. */
|
||||
private final Container gulagContainer;
|
||||
private Container gulagContainer;
|
||||
|
||||
/** Background container providing a border for the popup. */
|
||||
private final Container backgroundContainer;
|
||||
private Container backgroundContainer;
|
||||
|
||||
/**
|
||||
* Constructs the Gulag popup, displaying a warning when a player lands on the "Wache" field.
|
||||
* Constructs the Gulag popup.
|
||||
*
|
||||
* @param app the Monopoly application instance
|
||||
*/
|
||||
@@ -43,90 +45,97 @@ public class Gulag extends Dialog {
|
||||
super(app.getDialogManager());
|
||||
this.app = app;
|
||||
|
||||
// Initialize UI elements
|
||||
createOverlayBackground();
|
||||
createBackgroundContainer();
|
||||
createGulagContainer();
|
||||
}
|
||||
|
||||
// Halbtransparentes Overlay hinzufügen
|
||||
overlayBackground = createOverlayBackground();
|
||||
app.getGuiNode().attachChild(overlayBackground);
|
||||
/**
|
||||
* Creates the semi-transparent overlay background for the popup.
|
||||
*/
|
||||
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.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Darker background
|
||||
app.getGuiNode().attachChild(backgroundContainer);
|
||||
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray background
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Hauptcontainer für die Warnung
|
||||
/**
|
||||
* Creates the main container for the Gulag warning message.
|
||||
*/
|
||||
private void createGulagContainer() {
|
||||
gulagContainer = new Container();
|
||||
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));
|
||||
|
||||
float padding = 10; // Passt den backgroundContainer an die Größe des bankruptContainers an
|
||||
backgroundContainer.setPreferredSize(gulagContainer.getPreferredSize().addLocal(padding, padding, 0));
|
||||
// Title
|
||||
Label title = gulagContainer.addChild(new Label("Du kommst ins Gulag!", new ElementId("warning-title")));
|
||||
title.setFontSize(48);
|
||||
title.setColor(ColorRGBA.Black);
|
||||
|
||||
// Titel
|
||||
Label gateFieldTitle = gulagContainer.addChild(new Label("Du kommst ins Gulag!", new ElementId("warning-title")));
|
||||
gateFieldTitle.setFontSize(48);
|
||||
gateFieldTitle.setColor(ColorRGBA.Black);
|
||||
|
||||
// Beenden-Button
|
||||
Button quitButton = gulagContainer.addChild(new Button("Jawohl Gulag", new ElementId("button")));
|
||||
quitButton.setFontSize(32);
|
||||
quitButton.addClickCommands(source -> ifTopDialog(() -> {
|
||||
// Confirmation Button
|
||||
Button confirmButton = gulagContainer.addChild(new Button("Jawohl Gulag", new ElementId("button")));
|
||||
confirmButton.setFontSize(32);
|
||||
confirmButton.addClickCommands(source -> ifTopDialog(() -> {
|
||||
app.getGameLogic().playSound(Sound.BUTTON);
|
||||
close();
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the popup by attaching its elements to the GUI.
|
||||
*/
|
||||
@Override
|
||||
public void show() {
|
||||
float padding = 10;
|
||||
|
||||
// Zentriere das Popup
|
||||
// Adjust and position the containers
|
||||
backgroundContainer.setPreferredSize(gulagContainer.getPreferredSize().addLocal(padding, padding, 0));
|
||||
gulagContainer.setLocalTranslation(
|
||||
(app.getCamera().getWidth() - gulagContainer.getPreferredSize().x) / 2,
|
||||
(app.getCamera().getHeight() + gulagContainer.getPreferredSize().y) / 2,
|
||||
8
|
||||
);
|
||||
|
||||
// Zentriere das Popup
|
||||
backgroundContainer.setLocalTranslation(
|
||||
(app.getCamera().getWidth() - gulagContainer.getPreferredSize().x - padding) / 2,
|
||||
(app.getCamera().getHeight() + gulagContainer.getPreferredSize().y+ padding) / 2,
|
||||
7
|
||||
(app.getCamera().getWidth() - gulagContainer.getPreferredSize().x - padding) / 2,
|
||||
(app.getCamera().getHeight() + gulagContainer.getPreferredSize().y + padding) / 2,
|
||||
7
|
||||
);
|
||||
|
||||
// Attach components to the GUI
|
||||
app.getGuiNode().attachChild(overlayBackground);
|
||||
app.getGuiNode().attachChild(backgroundContainer);
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
app.getGuiNode().detachChild(gulagContainer); // Entferne das Menü
|
||||
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
|
||||
app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
|
||||
app.getGuiNode().detachChild(overlayBackground);
|
||||
app.getGuiNode().detachChild(gulagContainer);
|
||||
app.getGuiNode().detachChild(backgroundContainer);
|
||||
super.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the escape action to close the popup.
|
||||
* Handles the escape action by closing the popup.
|
||||
*/
|
||||
@Override
|
||||
public void escape() {
|
||||
close();
|
||||
}
|
||||
|
||||
}
|
@@ -7,112 +7,138 @@ import com.simsilica.lemur.Label;
|
||||
import com.simsilica.lemur.component.QuadBackgroundComponent;
|
||||
import com.simsilica.lemur.style.ElementId;
|
||||
import pp.dialog.Dialog;
|
||||
import pp.dialog.PopupDialog;
|
||||
import pp.monopoly.client.MonopolyApp;
|
||||
import pp.monopoly.client.gui.SettingsMenu;
|
||||
import pp.monopoly.message.client.NotificationAnswer;
|
||||
import pp.monopoly.notification.Sound;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* </p>
|
||||
*/
|
||||
public class GulagInfo extends Dialog {
|
||||
public class GulagInfo extends Dialog implements PopupDialog {
|
||||
/** Reference to the Monopoly application instance. */
|
||||
private final MonopolyApp app;
|
||||
|
||||
/** Main container for the Gulag information dialog. */
|
||||
private final Container gulagInfoContainer;
|
||||
private Container gulagInfoContainer;
|
||||
|
||||
/** Background container providing a styled border around the dialog. */
|
||||
private final Container backgroundContainer;
|
||||
private Container backgroundContainer;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public GulagInfo(MonopolyApp app, int trys) {
|
||||
super(app.getDialogManager());
|
||||
this.app = app;
|
||||
|
||||
// Create the background container
|
||||
// Initialize UI components
|
||||
createBackgroundContainer();
|
||||
createGulagInfoContainer(trys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the background container providing a border for the dialog.
|
||||
*/
|
||||
private void createBackgroundContainer() {
|
||||
backgroundContainer = new Container();
|
||||
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Darker background
|
||||
attachChild(backgroundContainer);
|
||||
backgroundContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f))); // Light gray background
|
||||
}
|
||||
|
||||
// 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.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.8657f, 0.8735f, 0.8892f, 1.0f)));
|
||||
|
||||
float padding = 10; // Passt den backgroundContainer an die Größe des confirmTradeContainer an
|
||||
backgroundContainer.setPreferredSize(gulagInfoContainer.getPreferredSize().addLocal(padding, padding, 0));
|
||||
|
||||
// Titel
|
||||
Label title = gulagInfoContainer.addChild(new Label( "Gulag", new ElementId("warning-title")));
|
||||
// Title
|
||||
Label title = gulagInfoContainer.addChild(new Label("Gulag", new ElementId("warning-title")));
|
||||
title.setFontSize(48);
|
||||
title.setColor(ColorRGBA.Black);
|
||||
|
||||
// Text, der auf der Karte steht
|
||||
// Die Werte werden dem Handel entnommen (Iwas auch immer da dann ist)
|
||||
Container propertyValuesContainer = gulagInfoContainer.addChild(new Container());
|
||||
propertyValuesContainer.addChild(new Label("„Du sitzt im Gefänginis und kommst nicht raus ...", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("Es sei denn, du ...", new ElementId("label-Text")));// Leerzeile
|
||||
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("- bestichst die Wache mit 500 EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("- löst eine Gulag-Frei-Karte ein", new ElementId("label-Text")));
|
||||
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)));
|
||||
// Text Description
|
||||
Container textContainer = gulagInfoContainer.addChild(new Container());
|
||||
textContainer.addChild(new Label("„Du sitzt im Gefängnis und kommst nicht raus ...", new ElementId("label-Text")));
|
||||
textContainer.addChild(new Label("Es sei denn, du ...", new ElementId("label-Text")));
|
||||
textContainer.addChild(new Label("- bestichst die Wache mit 500 EUR", new ElementId("label-Text")));
|
||||
textContainer.addChild(new Label("- löst eine Gulag-Frei-Karte ein", new ElementId("label-Text")));
|
||||
textContainer.addChild(new Label("- wartest 3 Runden und bezahlst dann", new ElementId("label-Text")));
|
||||
textContainer.addChild(new Label("- oder du würfelst einen Pasch", new ElementId("label-Text")));
|
||||
textContainer.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")));
|
||||
payButton.setFontSize(32);
|
||||
payButton.addClickCommands(s -> ifTopDialog( () -> {
|
||||
payButton.addClickCommands(s -> ifTopDialog(() -> {
|
||||
app.getGameLogic().playSound(Sound.BUTTON);
|
||||
app.getGameLogic().send(new NotificationAnswer("PayJail"));
|
||||
close();
|
||||
}));
|
||||
// Ereigniskarte-Button
|
||||
Button eventCardButton = gulagInfoContainer.addChild(new Button("Ereigniskarte nutzen", new ElementId("button")));
|
||||
|
||||
// Use Jail-Free Card Button
|
||||
Button eventCardButton = gulagInfoContainer.addChild(new Button("Ereigniskarte nutzen", new ElementId("button-toolbar2")));
|
||||
eventCardButton.setFontSize(32);
|
||||
eventCardButton.addClickCommands(s -> ifTopDialog( () -> {
|
||||
eventCardButton.addClickCommands(s -> ifTopDialog(() -> {
|
||||
app.getGameLogic().playSound(Sound.BUTTON);
|
||||
app.getGameLogic().send(new NotificationAnswer("UseJailCard"));
|
||||
close();
|
||||
}));
|
||||
// Schließen-Button
|
||||
|
||||
// Close Button
|
||||
Button closeButton = gulagInfoContainer.addChild(new Button("Schließen", new ElementId("button")));
|
||||
closeButton.setFontSize(32);
|
||||
closeButton.addClickCommands(s -> ifTopDialog(() -> {
|
||||
app.getGameLogic().playSound(Sound.BUTTON);
|
||||
close();
|
||||
}));
|
||||
closeButton.addClickCommands(s -> ifTopDialog(this::close));
|
||||
|
||||
// Zentriere das Menü
|
||||
// Disable options based on conditions
|
||||
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(
|
||||
(app.getCamera().getWidth() - gulagInfoContainer.getPreferredSize().x) / 2,
|
||||
(app.getCamera().getHeight() + gulagInfoContainer.getPreferredSize().y) / 2,
|
||||
8
|
||||
);
|
||||
|
||||
// Zentriere das Menü
|
||||
backgroundContainer.setLocalTranslation(
|
||||
(app.getCamera().getWidth() - gulagInfoContainer.getPreferredSize().x - padding) / 2,
|
||||
(app.getCamera().getHeight() + gulagInfoContainer.getPreferredSize().y+ padding) / 2,
|
||||
7
|
||||
(app.getCamera().getWidth() - gulagInfoContainer.getPreferredSize().x - padding) / 2,
|
||||
(app.getCamera().getHeight() + gulagInfoContainer.getPreferredSize().y + padding) / 2,
|
||||
7
|
||||
);
|
||||
|
||||
if(app.getGameLogic().getPlayerHandler().getPlayerById(app.getId()).getNumJailCard() == 0) {
|
||||
eventCardButton.setEnabled(false);
|
||||
}
|
||||
|
||||
if(trys == 3) {
|
||||
closeButton.setEnabled(false);
|
||||
}
|
||||
|
||||
// Attach containers to the GUI
|
||||
app.getGuiNode().attachChild(backgroundContainer);
|
||||
app.getGuiNode().attachChild(gulagInfoContainer);
|
||||
}
|
||||
|
||||
@@ -121,16 +147,8 @@ public class GulagInfo extends Dialog {
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
app.getGuiNode().detachChild(gulagInfoContainer); // Entferne das Menü
|
||||
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
|
||||
app.getGuiNode().detachChild(gulagInfoContainer); // Remove dialog
|
||||
app.getGuiNode().detachChild(backgroundContainer); // Remove background
|
||||
super.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the escape action to close the GulagInfo dialog.
|
||||
*/
|
||||
@Override
|
||||
public void escape() {
|
||||
new SettingsMenu(app).open();
|
||||
}
|
||||
}
|
||||
|
@@ -12,19 +12,14 @@ import com.simsilica.lemur.Label;
|
||||
import com.simsilica.lemur.component.QuadBackgroundComponent;
|
||||
import com.simsilica.lemur.style.ElementId;
|
||||
import pp.dialog.Dialog;
|
||||
import pp.dialog.PopupDialog;
|
||||
import pp.monopoly.client.MonopolyApp;
|
||||
import pp.monopoly.notification.Sound;
|
||||
|
||||
/**
|
||||
* 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>
|
||||
* NoMoneyWarning is a warning popup that informs the player they lack sufficient funds to proceed with an action.
|
||||
*/
|
||||
public class NoMoneyWarning extends Dialog {
|
||||
public class NoMoneyWarning extends Dialog implements PopupDialog {
|
||||
/** Reference to the Monopoly application instance. */
|
||||
private final MonopolyApp app;
|
||||
|
||||
@@ -46,66 +41,15 @@ public class NoMoneyWarning extends Dialog {
|
||||
super(app.getDialogManager());
|
||||
this.app = app;
|
||||
|
||||
|
||||
// Halbtransparentes Overlay hinzufügen
|
||||
overlayBackground = createOverlayBackground();
|
||||
app.getGuiNode().attachChild(overlayBackground);
|
||||
backgroundContainer = createBackgroundContainer();
|
||||
noMoneyWarningContainer = createNoMoneyWarningContainer();
|
||||
|
||||
// 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);
|
||||
adjustPaddingAndCenter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a semi-transparent overlay background for the dialog.
|
||||
* Creates the semi-transparent overlay background.
|
||||
*
|
||||
* @return The geometry representing the overlay background.
|
||||
*/
|
||||
@@ -113,7 +57,7 @@ public class NoMoneyWarning extends Dialog {
|
||||
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.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Semi-transparent black
|
||||
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
|
||||
overlay.setMaterial(material);
|
||||
overlay.setLocalTranslation(0, 0, 0);
|
||||
@@ -121,13 +65,86 @@ public class NoMoneyWarning extends Dialog {
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the menu and removes the GUI elements.
|
||||
* 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
|
||||
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
|
||||
public void close() {
|
||||
app.getGuiNode().detachChild(noMoneyWarningContainer); // Entferne das Menü
|
||||
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
|
||||
app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
|
||||
app.getGuiNode().detachChild(overlayBackground);
|
||||
app.getGuiNode().detachChild(backgroundContainer);
|
||||
app.getGuiNode().detachChild(noMoneyWarningContainer);
|
||||
super.close();
|
||||
}
|
||||
|
||||
@@ -138,4 +155,4 @@ public class NoMoneyWarning extends Dialog {
|
||||
public void escape() {
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -12,115 +12,95 @@ import com.simsilica.lemur.Label;
|
||||
import com.simsilica.lemur.component.QuadBackgroundComponent;
|
||||
import com.simsilica.lemur.style.ElementId;
|
||||
import pp.dialog.Dialog;
|
||||
import pp.dialog.PopupDialog;
|
||||
import pp.monopoly.client.MonopolyApp;
|
||||
import pp.monopoly.notification.Sound;
|
||||
|
||||
/**
|
||||
* 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>
|
||||
* ReceivedRent is a popup that informs a player about rent they have received.
|
||||
*/
|
||||
public class ReceivedRent extends Dialog {
|
||||
public class ReceivedRent extends Dialog implements PopupDialog {
|
||||
|
||||
/** Reference to the Monopoly application instance. */
|
||||
private final MonopolyApp app;
|
||||
|
||||
/** Semi-transparent overlay background for the popup. */
|
||||
private final Geometry overlayBackground;
|
||||
private Geometry overlayBackground;
|
||||
|
||||
/** Main container for the rent information and action. */
|
||||
private final Container rentContainer;
|
||||
private Container rentContainer;
|
||||
|
||||
/** Background container providing a border for the rent popup. */
|
||||
private final Container backgroundContainer;
|
||||
private Container backgroundContainer;
|
||||
|
||||
/**
|
||||
* Constructs the Rent popup displaying the rent amount and recipient player.
|
||||
* Constructs the ReceivedRent popup displaying the rent amount and payer.
|
||||
*
|
||||
* @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
|
||||
* @param playerName the name of the player who paid the rent
|
||||
* @param amount the amount of rent received
|
||||
*/
|
||||
public ReceivedRent(MonopolyApp app, String playerName, int amount) {
|
||||
super(app.getDialogManager());
|
||||
this.app = app;
|
||||
|
||||
// Create the overlay
|
||||
overlayBackground = createOverlayBackground();
|
||||
app.getGuiNode().attachChild(overlayBackground);
|
||||
|
||||
// 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();
|
||||
// Initialize GUI elements
|
||||
createOverlayBackground();
|
||||
createBackgroundContainer();
|
||||
createRentContainer(playerName, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a semi-transparent overlay background.
|
||||
*
|
||||
* @return the overlay geometry
|
||||
*/
|
||||
private Geometry createOverlayBackground() {
|
||||
private void createOverlayBackground() {
|
||||
Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
|
||||
Geometry overlay = new Geometry("Overlay", quad);
|
||||
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);
|
||||
overlay.setMaterial(material);
|
||||
overlay.setLocalTranslation(0, 0, 0);
|
||||
return overlay;
|
||||
overlayBackground.setMaterial(material);
|
||||
overlayBackground.setLocalTranslation(0, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the background container with styling.
|
||||
*
|
||||
* @return the styled background container
|
||||
*/
|
||||
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;
|
||||
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 rent container with title, text, and button.
|
||||
*
|
||||
* @param playerName the name of the player to whom the rent is owed
|
||||
* @param playerName the name of the player who paid the rent
|
||||
* @param amount the rent amount
|
||||
* @return the rent container
|
||||
*/
|
||||
private Container createRentContainer(String playerName, int amount) {
|
||||
Container container = new Container();
|
||||
container.setBackground(new QuadBackgroundComponent(ColorRGBA.Gray));
|
||||
container.setPreferredSize(new Vector3f(550, 250, 10));
|
||||
private void createRentContainer(String playerName, int amount) {
|
||||
rentContainer = new Container();
|
||||
rentContainer.setBackground(new QuadBackgroundComponent(ColorRGBA.Gray));
|
||||
rentContainer.setPreferredSize(new Vector3f(550, 250, 10));
|
||||
|
||||
// Title
|
||||
Label title = container.addChild(new Label("Miete!", new ElementId("warning-title")));
|
||||
Label title = rentContainer.addChild(new Label("Miete!", new ElementId("warning-title")));
|
||||
title.setFontSize(48);
|
||||
title.setColor(ColorRGBA.Black);
|
||||
|
||||
// Rent message
|
||||
Container textContainer = container.addChild(new Container());
|
||||
textContainer.addChild(new Label(playerName+ " zahlt dir " + amount + " EUR Miete",
|
||||
Container textContainer = rentContainer.addChild(new Container());
|
||||
textContainer.addChild(new Label(playerName + " zahlt dir " + amount + " EUR Miete",
|
||||
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));
|
||||
textContainer.setPreferredSize(rentContainer.getPreferredSize().addLocal(-250, -200, 0));
|
||||
|
||||
// Payment button
|
||||
Button payButton = container.addChild(new Button("Bestätigen", new ElementId("button")));
|
||||
payButton.setFontSize(32);
|
||||
payButton.addClickCommands(s -> ifTopDialog( () -> {
|
||||
app.getGameLogic().playSound(Sound.BUTTON);
|
||||
close();
|
||||
// Confirmation button
|
||||
Button confirmButton = rentContainer.addChild(new Button("Bestätigen", new ElementId("button")));
|
||||
confirmButton.setFontSize(32);
|
||||
confirmButton.addClickCommands(s -> ifTopDialog(() -> {
|
||||
app.getGameLogic().playSound(Sound.BUTTON);
|
||||
close();
|
||||
}));
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -145,14 +125,25 @@ public class ReceivedRent extends Dialog {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
app.getGuiNode().detachChild(rentContainer);
|
||||
app.getGuiNode().detachChild(backgroundContainer);
|
||||
app.getGuiNode().detachChild(overlayBackground);
|
||||
app.getGuiNode().detachChild(backgroundContainer);
|
||||
app.getGuiNode().detachChild(rentContainer);
|
||||
super.close();
|
||||
}
|
||||
|
||||
|
@@ -12,19 +12,16 @@ import com.simsilica.lemur.Label;
|
||||
import com.simsilica.lemur.component.QuadBackgroundComponent;
|
||||
import com.simsilica.lemur.style.ElementId;
|
||||
import pp.dialog.Dialog;
|
||||
import pp.dialog.PopupDialog;
|
||||
import pp.monopoly.client.MonopolyApp;
|
||||
import pp.monopoly.message.server.TradeReply;
|
||||
import pp.monopoly.notification.Sound;
|
||||
|
||||
/**
|
||||
* RejectTrade is a popup that appears when a trade proposal is rejected by another player
|
||||
* 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>
|
||||
* 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.
|
||||
*/
|
||||
public class RejectTrade extends Dialog {
|
||||
public class RejectTrade extends Dialog implements PopupDialog {
|
||||
/** Reference to the Monopoly application instance. */
|
||||
private final MonopolyApp app;
|
||||
|
||||
@@ -32,12 +29,11 @@ public class RejectTrade extends Dialog {
|
||||
private final Geometry overlayBackground;
|
||||
|
||||
/** Main container for the rejection message content. */
|
||||
private final Container noMoneyWarningContainer;
|
||||
private final Container rejectTradeContainer;
|
||||
|
||||
/** Background container providing a border for the popup. */
|
||||
private final Container backgroundContainer;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs the RejectTrade popup displaying the rejection of a trade proposal.
|
||||
*
|
||||
@@ -48,68 +44,15 @@ public class RejectTrade extends Dialog {
|
||||
super(app.getDialogManager());
|
||||
this.app = app;
|
||||
|
||||
|
||||
// Halbtransparentes Overlay hinzufügen
|
||||
overlayBackground = createOverlayBackground();
|
||||
app.getGuiNode().attachChild(overlayBackground);
|
||||
backgroundContainer = createBackgroundContainer();
|
||||
rejectTradeContainer = createRejectTradeContainer(msg);
|
||||
|
||||
// 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);
|
||||
adjustPaddingAndCenter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a semi-transparent background overlay for the popup.
|
||||
* Creates the semi-transparent background overlay for the popup.
|
||||
*
|
||||
* @return the geometry of the overlay
|
||||
*/
|
||||
@@ -117,21 +60,98 @@ public class RejectTrade extends Dialog {
|
||||
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.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Semi-transparent black
|
||||
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
|
||||
overlay.setMaterial(material);
|
||||
overlay.setLocalTranslation(0, 0, 0);
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
app.getGuiNode().detachChild(noMoneyWarningContainer); // Entferne das Menü
|
||||
app.getGuiNode().detachChild(backgroundContainer); //Entfernt Rand
|
||||
app.getGuiNode().detachChild(overlayBackground); // Entferne das Overlay
|
||||
app.getGuiNode().detachChild(overlayBackground);
|
||||
app.getGuiNode().detachChild(backgroundContainer);
|
||||
app.getGuiNode().detachChild(rejectTradeContainer);
|
||||
super.close();
|
||||
}
|
||||
|
||||
@@ -142,4 +162,4 @@ public class RejectTrade extends Dialog {
|
||||
public void escape() {
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@ import com.simsilica.lemur.Label;
|
||||
import com.simsilica.lemur.component.QuadBackgroundComponent;
|
||||
import com.simsilica.lemur.style.ElementId;
|
||||
import pp.dialog.Dialog;
|
||||
import pp.dialog.PopupDialog;
|
||||
import pp.monopoly.client.MonopolyApp;
|
||||
import pp.monopoly.notification.Sound;
|
||||
|
||||
@@ -22,122 +23,77 @@ import pp.monopoly.notification.Sound;
|
||||
* Displays the rent amount and the recipient player's name, with an option to confirm the payment.
|
||||
* </p>
|
||||
*/
|
||||
public class Rent extends Dialog {
|
||||
/** Reference to the Monopoly application instance. */
|
||||
public class Rent extends Dialog implements PopupDialog {
|
||||
private final MonopolyApp app;
|
||||
|
||||
/** Semi-transparent overlay background for the popup. */
|
||||
private final Geometry overlayBackground;
|
||||
|
||||
/** Main container for the rent information and action. */
|
||||
private final Container rentContainer;
|
||||
|
||||
/** Background container providing a border for the rent popup. */
|
||||
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) {
|
||||
super(app.getDialogManager());
|
||||
this.app = app;
|
||||
|
||||
// Create the overlay
|
||||
// Create the overlay and containers
|
||||
overlayBackground = createOverlayBackground();
|
||||
app.getGuiNode().attachChild(overlayBackground);
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a semi-transparent overlay background.
|
||||
*
|
||||
* @return the overlay geometry
|
||||
*/
|
||||
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)); // Semi-transparent black
|
||||
material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f));
|
||||
material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
|
||||
overlay.setMaterial(material);
|
||||
overlay.setLocalTranslation(0, 0, 0);
|
||||
return overlay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the background container with styling.
|
||||
*
|
||||
* @return the styled background container
|
||||
*/
|
||||
private Container createBackgroundContainer() {
|
||||
Container container = new Container();
|
||||
container.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)));
|
||||
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) {
|
||||
Container container = new Container();
|
||||
container.setBackground(new QuadBackgroundComponent(ColorRGBA.Gray));
|
||||
container.setPreferredSize(new Vector3f(550, 250, 10));
|
||||
|
||||
// Title
|
||||
Label title = container.addChild(new Label("Miete!", new ElementId("warning-title")));
|
||||
title.setFontSize(48);
|
||||
title.setColor(ColorRGBA.Black);
|
||||
|
||||
// Rent message
|
||||
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")));
|
||||
textContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
|
||||
textContainer.setPreferredSize(container.getPreferredSize().addLocal(-250, -200, 0));
|
||||
|
||||
// Payment button
|
||||
Button payButton = container.addChild(new Button("Überweisen", new ElementId("button")));
|
||||
payButton.setFontSize(32);
|
||||
payButton.addClickCommands(s -> ifTopDialog( () -> {
|
||||
app.getGameLogic().playSound(Sound.BUTTON);
|
||||
close();
|
||||
|
||||
payButton.addClickCommands(s -> ifTopDialog(() -> {
|
||||
app.getGameLogic().playSound(Sound.BUTTON);
|
||||
close();
|
||||
}));
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Centers the rent and background containers on the screen.
|
||||
*/
|
||||
private void centerContainers() {
|
||||
float padding = 10;
|
||||
|
||||
// Center rent container
|
||||
rentContainer.setLocalTranslation(
|
||||
(app.getCamera().getWidth() - rentContainer.getPreferredSize().x) / 2,
|
||||
(app.getCamera().getHeight() + rentContainer.getPreferredSize().y) / 2,
|
||||
8
|
||||
);
|
||||
|
||||
// Center background container with padding
|
||||
backgroundContainer.setPreferredSize(rentContainer.getPreferredSize().addLocal(padding, padding, 0));
|
||||
backgroundContainer.setLocalTranslation(
|
||||
(app.getCamera().getWidth() - backgroundContainer.getPreferredSize().x) / 2,
|
||||
@@ -146,22 +102,25 @@ public class Rent extends Dialog {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the popup and removes GUI elements.
|
||||
*/
|
||||
@Override
|
||||
public void show() {
|
||||
// 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
|
||||
public void close() {
|
||||
app.getGuiNode().detachChild(rentContainer);
|
||||
app.getGuiNode().detachChild(backgroundContainer);
|
||||
app.getGuiNode().detachChild(overlayBackground);
|
||||
app.getGuiNode().detachChild(backgroundContainer);
|
||||
app.getGuiNode().detachChild(rentContainer);
|
||||
super.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the escape action to close the dialog.
|
||||
*/
|
||||
@Override
|
||||
public void escape() {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -7,7 +7,6 @@ import com.simsilica.lemur.Button;
|
||||
import com.simsilica.lemur.Container;
|
||||
import com.simsilica.lemur.Label;
|
||||
import com.simsilica.lemur.Selector;
|
||||
import com.simsilica.lemur.TextField;
|
||||
import com.simsilica.lemur.component.QuadBackgroundComponent;
|
||||
import com.simsilica.lemur.component.SpringGridLayout;
|
||||
import com.simsilica.lemur.core.VersionedList;
|
||||
@@ -82,7 +81,7 @@ public class RepayMortage extends Dialog {
|
||||
backgroundContainer.setPreferredSize(repayMortageContainer.getPreferredSize().addLocal(padding, padding, 0));
|
||||
|
||||
// Titel
|
||||
Label title = repayMortageContainer.addChild(new Label( "Hypothek Abbezahlen", new ElementId("warining-Bold")));
|
||||
Label title = repayMortageContainer.addChild(new Label( "Hypothek Abbezahlen", new ElementId("label-Bold")));
|
||||
title.setFontSize(48);
|
||||
title.setColor(ColorRGBA.Black);
|
||||
|
||||
@@ -97,7 +96,7 @@ public class RepayMortage extends Dialog {
|
||||
upContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
|
||||
|
||||
middleContainer.setPreferredSize(new Vector3f(100, 150, 0));
|
||||
middleContainer.setBackground(new QuadBackgroundComponent(ColorRGBA.Orange));
|
||||
middleContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.0f, 0.0f, 0.0f, 1.0f)));
|
||||
|
||||
middleContainer.addChild(createPropertyDropdown());
|
||||
|
||||
@@ -149,7 +148,7 @@ public class RepayMortage extends Dialog {
|
||||
private Container createPropertyDropdown() {
|
||||
Container dropdownContainer = new Container(new SpringGridLayout(Axis.Y, Axis.X));
|
||||
dropdownContainer.setPreferredSize(new Vector3f(300, 200, 0));
|
||||
dropdownContainer.setBackground(new QuadBackgroundComponent(ColorRGBA.Orange));
|
||||
dropdownContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.0f, 0.0f, 0.0f, 1.0f)));
|
||||
|
||||
VersionedList<String> propertyOptions = new VersionedList<>();
|
||||
List<PropertyField> playerProperties = getPlayerProperties();
|
||||
@@ -168,6 +167,7 @@ public class RepayMortage extends Dialog {
|
||||
// Initialize the selection display here
|
||||
selectionDisplay = new Label(""); // Create TextField for displaying selections
|
||||
selectionDisplay.setPreferredSize(new Vector3f(300, 30, 0));
|
||||
selectionDisplay.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
|
||||
dropdownContainer.addChild(selectionDisplay); // Add it to the dropdown container
|
||||
|
||||
// Set initial selection
|
||||
|
@@ -7,7 +7,6 @@ import com.simsilica.lemur.Button;
|
||||
import com.simsilica.lemur.Container;
|
||||
import com.simsilica.lemur.Label;
|
||||
import com.simsilica.lemur.Selector;
|
||||
import com.simsilica.lemur.TextField;
|
||||
import com.simsilica.lemur.component.QuadBackgroundComponent;
|
||||
import com.simsilica.lemur.component.SpringGridLayout;
|
||||
import com.simsilica.lemur.core.VersionedList;
|
||||
@@ -82,7 +81,7 @@ public class SellHouse extends Dialog {
|
||||
backgroundContainer.setPreferredSize(sellhouseContainer.getPreferredSize().addLocal(padding, padding, 0));
|
||||
|
||||
// Titel
|
||||
Label title = sellhouseContainer.addChild(new Label( "Gebäude Abreißen", new ElementId("warining-Bold")));
|
||||
Label title = sellhouseContainer.addChild(new Label( "Gebäude Abreißen", new ElementId("label-Bold")));
|
||||
title.setFontSize(48);
|
||||
title.setColor(ColorRGBA.Black);
|
||||
|
||||
@@ -119,13 +118,7 @@ public class SellHouse extends Dialog {
|
||||
confirmButton.addClickCommands(s -> ifTopDialog( () -> {
|
||||
app.getGameLogic().playSound(Sound.BUTTON);
|
||||
AlterProperty msg = new AlterProperty("SellHouse");
|
||||
for (String string : selectedProperties) {
|
||||
System.out.println(string);
|
||||
}
|
||||
msg.setProperties(selectedProperties.stream().map(p -> app.getGameLogic().getBoardManager().getFieldByName(p).getId()).map(p -> (Integer) p).collect(Collectors.toSet()));
|
||||
for (Integer integer : msg.getProperties()) {
|
||||
System.out.println("ID des verkaufs: "+integer);
|
||||
}
|
||||
app.getGameLogic().send(msg);
|
||||
close();
|
||||
}));
|
||||
@@ -155,7 +148,7 @@ public class SellHouse extends Dialog {
|
||||
private Container createPropertyDropdown() {
|
||||
Container dropdownContainer = new Container(new SpringGridLayout(Axis.Y, Axis.X));
|
||||
dropdownContainer.setPreferredSize(new Vector3f(300, 200, 0));
|
||||
dropdownContainer.setBackground(new QuadBackgroundComponent(ColorRGBA.Orange));
|
||||
dropdownContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.0f, 0.0f, 0.0f, 1.0f)));
|
||||
|
||||
VersionedList<String> propertyOptions = new VersionedList<>();
|
||||
List<BuildingProperty> playerProperties = getPlayerProperties();
|
||||
@@ -174,6 +167,7 @@ public class SellHouse extends Dialog {
|
||||
// Initialize the selection display here
|
||||
selectionDisplay = new Label("");
|
||||
selectionDisplay.setPreferredSize(new Vector3f(300, 30, 0));
|
||||
selectionDisplay.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
|
||||
dropdownContainer.addChild(selectionDisplay); // Add it to the dropdown container
|
||||
|
||||
// Set initial selection
|
||||
|
@@ -7,7 +7,6 @@ import com.simsilica.lemur.Button;
|
||||
import com.simsilica.lemur.Container;
|
||||
import com.simsilica.lemur.Label;
|
||||
import com.simsilica.lemur.Selector;
|
||||
import com.simsilica.lemur.TextField;
|
||||
import com.simsilica.lemur.component.QuadBackgroundComponent;
|
||||
import com.simsilica.lemur.component.SpringGridLayout;
|
||||
import com.simsilica.lemur.core.VersionedList;
|
||||
@@ -83,7 +82,7 @@ public class TakeMortage extends Dialog {
|
||||
backgroundContainer.setPreferredSize(takeMortageContainer.getPreferredSize().addLocal(padding, padding, 0));
|
||||
|
||||
// Titel
|
||||
Label title = takeMortageContainer.addChild(new Label( "Hypothek aufnehmen", new ElementId("warining-Bold")));
|
||||
Label title = takeMortageContainer.addChild(new Label( "Hypothek aufnehmen", new ElementId("label-Bold")));
|
||||
title.setFontSize(48);
|
||||
title.setColor(ColorRGBA.Black);
|
||||
|
||||
@@ -150,7 +149,7 @@ public class TakeMortage extends Dialog {
|
||||
private Container createPropertyDropdown() {
|
||||
Container dropdownContainer = new Container(new SpringGridLayout(Axis.Y, Axis.X));
|
||||
dropdownContainer.setPreferredSize(new Vector3f(300, 200, 0));
|
||||
dropdownContainer.setBackground(new QuadBackgroundComponent(ColorRGBA.Orange));
|
||||
dropdownContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.0f, 0.0f, 0.0f, 1.0f)));
|
||||
|
||||
VersionedList<String> propertyOptions = new VersionedList<>();
|
||||
List<PropertyField> playerProperties = getPlayerProperties();
|
||||
@@ -174,6 +173,7 @@ public class TakeMortage extends Dialog {
|
||||
// Initialize the selection display here
|
||||
selectionDisplay = new Label(""); // Create TextField for displaying selections
|
||||
selectionDisplay.setPreferredSize(new Vector3f(300, 30, 0));
|
||||
selectionDisplay.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.4657f, 0.4735f, 0.4892f, 1.0f)));
|
||||
dropdownContainer.addChild(selectionDisplay); // Add it to the dropdown container
|
||||
|
||||
// Set initial selection
|
||||
|
After Width: | Height: | Size: 121 KiB |
After Width: | Height: | Size: 114 KiB |
After Width: | Height: | Size: 304 KiB |
After Width: | Height: | Size: 473 KiB |
After Width: | Height: | Size: 94 KiB |
After Width: | Height: | Size: 136 KiB |
After Width: | Height: | Size: 136 KiB |
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 1.9 MiB |
Before Width: | Height: | Size: 105 KiB After Width: | Height: | Size: 132 KiB |
After Width: | Height: | Size: 588 KiB |
BIN
Projekte/monopoly/client/src/main/resources/Textures/Bot.jpg
Normal file
After Width: | Height: | Size: 707 KiB |
Before Width: | Height: | Size: 18 MiB After Width: | Height: | Size: 14 MiB |
After Width: | Height: | Size: 215 KiB |
After Width: | Height: | Size: 60 KiB |
BIN
Projekte/monopoly/client/src/main/resources/Textures/Top.png
Normal file
After Width: | Height: | Size: 478 KiB |
BIN
Projekte/monopoly/client/src/main/resources/Textures/grass.jpg
Normal file
After Width: | Height: | Size: 3.2 MiB |
After Width: | Height: | Size: 3.5 KiB |
BIN
Projekte/monopoly/client/src/main/resources/icons/Uniman.png
Normal file
After Width: | Height: | Size: 364 KiB |
Before Width: | Height: | Size: 518 KiB |
Before Width: | Height: | Size: 55 KiB |
Before Width: | Height: | Size: 552 KiB |
Before Width: | Height: | Size: 100 KiB |
Before Width: | Height: | Size: 24 MiB |
After Width: | Height: | Size: 215 KiB |
After Width: | Height: | Size: 60 KiB |
Before Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 200 KiB |
Before Width: | Height: | Size: 6.7 MiB |
Before Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 31 MiB After Width: | Height: | Size: 57 MiB |
@@ -4,6 +4,7 @@ import java.lang.System.Logger;
|
||||
import java.lang.System.Logger.Level;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.jme3.math.Vector3f;
|
||||
|
||||
@@ -235,7 +236,7 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker {
|
||||
playerHandler = msg.getPlayerHandler();
|
||||
setState(new WaitForTurnState(this));
|
||||
for (Player player : playerHandler.getPlayers()) {
|
||||
board.add(new Figure(Vector3f.ZERO, Rotation.NORTH, player.getFigure()));
|
||||
board.add(new Figure(Vector3f.ZERO, Rotation.NORTH, player.getFigure(), player.getId()));
|
||||
}
|
||||
notifyListeners(new ButtonStatusEvent(false));
|
||||
notifyListeners(new UpdatePlayerView());
|
||||
@@ -252,7 +253,7 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker {
|
||||
@Override
|
||||
public void received(PlayerStatusUpdate msg) {
|
||||
playerHandler = msg.getPlayerHandler();
|
||||
System.out.println("Update Player");
|
||||
LOGGER.log(Level.TRACE, "Update Player View triggerd with message: {0}", msg);
|
||||
notifyListeners(new UpdatePlayerView());
|
||||
}
|
||||
|
||||
@@ -309,19 +310,36 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker {
|
||||
} else if(msg.getKeyWord().equals("ReceivedRent")) {
|
||||
playSound(Sound.MONEY_COLLECTED);
|
||||
notifyListeners(new PopUpEvent("ReceivedRent", msg));
|
||||
} else if (msg.getKeyWord().equals("aussetzen")) {
|
||||
notifyListeners(new ButtonStatusEvent(false));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void received(BuildInfo msg) {
|
||||
System.out.println("TRIGGER BUILD INFO");
|
||||
if (msg.isAdded()) {
|
||||
BuildingProperty property = ((BuildingProperty)boardManager.getFieldAtIndex(msg.getId()));
|
||||
if (property.getHotel() == 1 ) {
|
||||
|
||||
for(int i = 0; i < 4; i++) {
|
||||
board.remove(board.getHouse(msg.getId(), i+1));
|
||||
}
|
||||
|
||||
board.add(new Hotel(property.getId()));
|
||||
} else {
|
||||
|
||||
for(int i = 0; i < 4; i++) {
|
||||
board.remove(board.getHouse(msg.getId(), i+1));
|
||||
}
|
||||
|
||||
board.add(new House( property.getHouses(), property.getId()));
|
||||
}
|
||||
} else {
|
||||
if( ((BuildingProperty)boardManager.getFieldAtIndex(msg.getId())).getHouses() == 4 ) {
|
||||
board.remove(board.getHotel(msg.getId()));
|
||||
} else {
|
||||
board.remove(board.getHouse(msg.getId(), ((BuildingProperty)boardManager.getFieldAtIndex(msg.getId())).getHouses()+1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -492,7 +492,8 @@ public class Player implements FieldVisitor<Void>{
|
||||
}
|
||||
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.
|
||||
@@ -507,8 +508,20 @@ public class Player implements FieldVisitor<Void>{
|
||||
* @return the result of a dice roll (1 to 6)
|
||||
*/
|
||||
private static int rollDice() {
|
||||
return random.nextInt(6) + 1;
|
||||
// return random.nextInt(6) + 1;
|
||||
// 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;
|
||||
// if(c < 7) {
|
||||
// return 3;
|
||||
|
@@ -120,7 +120,7 @@ public class PlayerHandler {
|
||||
* @param index the index of the queue
|
||||
* @return the Player at the required index
|
||||
*/
|
||||
Player getPlayerAtIndex(int index) {
|
||||
public Player getPlayerAtIndex(int index) {
|
||||
return players.get(index);
|
||||
}
|
||||
|
||||
@@ -165,10 +165,11 @@ public class PlayerHandler {
|
||||
* Shuffles the players and sets their state to WaitForNextTurn, the first one will be active
|
||||
*/
|
||||
void randomOrder() {
|
||||
Collections.shuffle(players);
|
||||
for (Player player : players) {
|
||||
player.finishTurn();
|
||||
}
|
||||
// Collections.shuffle(players);
|
||||
// for (Player player : players) {
|
||||
// player.finishTurn();
|
||||
// }
|
||||
nextPlayer();
|
||||
players.get(0).setActive();
|
||||
}
|
||||
|
||||
|
@@ -85,7 +85,7 @@ public class ServerGameLogic implements ClientInterpreter {
|
||||
* @param player the Player to whom the message is sent
|
||||
* @param msg the ServerMessage to send
|
||||
*/
|
||||
void send(Player player, ServerMessage msg) {
|
||||
public void send(Player player, ServerMessage msg) {
|
||||
if (player != null && msg != null) {
|
||||
serverSender.send(player.getId(), msg);
|
||||
LOGGER.log(Level.DEBUG, "Message sent to player {0}: {1}", player.getName(), msg.getClass().getSimpleName());
|
||||
@@ -168,7 +168,6 @@ public class ServerGameLogic implements ClientInterpreter {
|
||||
PropertyField property = (PropertyField) boardManager.getFieldAtIndex(player.getFieldID()); // Assuming player position for property
|
||||
|
||||
player.buyProperty(property);
|
||||
System.out.println("Properties:" +player.getProperties().toString());
|
||||
LOGGER.log(Level.INFO, "Player {0} bought property {1}", player.getName(), property.getName());
|
||||
}
|
||||
updateAllPlayers();
|
||||
@@ -230,6 +229,8 @@ public class ServerGameLogic implements ClientInterpreter {
|
||||
for (Player p : playerHandler.getPlayers()) {
|
||||
send(p, new GameStart(playerHandler));
|
||||
}
|
||||
|
||||
|
||||
playerHandler.randomOrder();
|
||||
send(playerHandler.getPlayerAtIndex(0), new NextPlayerTurn());
|
||||
}
|
||||
@@ -454,13 +455,9 @@ public class ServerGameLogic implements ClientInterpreter {
|
||||
}
|
||||
|
||||
private void generatePredefinedGameState() {
|
||||
// Ensure at least two players exist
|
||||
if (playerHandler.getPlayers().size() < 2) {
|
||||
Player player1 = new Player(0, "Player1", playerHandler);
|
||||
Player player2 = new Player(1, "Player2", playerHandler);
|
||||
|
||||
playerHandler.addPlayer(player1);
|
||||
playerHandler.addPlayer(player2);
|
||||
|
||||
if(playerHandler.getPlayerCount() < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player p1 = playerHandler.getPlayerById(0);
|
||||
@@ -477,24 +474,26 @@ public class ServerGameLogic implements ClientInterpreter {
|
||||
|
||||
// Define properties to assign
|
||||
Set<Integer> p1Properties = Set.of(1, 3, 6, 8); // Gym, Sportplatz, Studium+, PhysikHörsaal
|
||||
Set<Integer> p2Properties = Set.of(21, 23, 24, 9); // Red set + Audimax
|
||||
Set<Integer> p2Properties = Set.of(21, 23, 24, 9, 11); // Red set + Audimax + Spießtor
|
||||
|
||||
// Assign properties via AlterProperty
|
||||
assignProperties(p1, p1Properties);
|
||||
assignProperties(p2, p2Properties);
|
||||
|
||||
// Player 1 builds houses on Gym and Sportplatz
|
||||
buildHouses(p1, Set.of(1, 3));
|
||||
// buildHouses(p1, Set.of(1, 3));
|
||||
|
||||
// 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
|
||||
p1.setAccountBalance(12325);
|
||||
p2.setAccountBalance(26750);
|
||||
|
||||
// Add Get Out of Jail cards
|
||||
p1.addJailCard();
|
||||
p2.addJailCard();
|
||||
|
||||
// Set player positions
|
||||
p1.setPosition(6); // Near Studium+
|
||||
@@ -519,6 +518,8 @@ public class ServerGameLogic implements ClientInterpreter {
|
||||
field.setOwner(player);
|
||||
player.addProperty(propertyId);
|
||||
}
|
||||
|
||||
updateAllPlayers();
|
||||
LOGGER.log(Level.DEBUG, "Properties assigned to player {0}: {1}", player.getName(), properties);
|
||||
}
|
||||
|
||||
@@ -537,6 +538,8 @@ public class ServerGameLogic implements ClientInterpreter {
|
||||
if (boardManager.canBuild(field) && player.getAccountBalance() >= field.getHousePrice()) {
|
||||
field.build();
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
@@ -139,6 +139,18 @@ public class Board {
|
||||
return getItems(House.class);
|
||||
}
|
||||
|
||||
public House getHouse(int fieldId, int stage) {
|
||||
return getHouses().filter(house -> house.getFieldID() == fieldId && house.getStage() == stage).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
public Hotel getHotel(int fieldId) {
|
||||
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.
|
||||
*
|
||||
|
@@ -7,6 +7,8 @@ import com.jme3.network.serializing.Serializable;
|
||||
|
||||
@Serializable
|
||||
public class Figure implements Item{
|
||||
|
||||
private final int id;
|
||||
private final String type;
|
||||
private Vector3f position;
|
||||
private Rotation rot; // The rotation of the Figure
|
||||
@@ -16,7 +18,7 @@ public class Figure implements Item{
|
||||
* at position (0, 0), with a default rotation of NORTH.
|
||||
*/
|
||||
private Figure() {
|
||||
this(null, Rotation.NORTH, "");
|
||||
this(null, Rotation.NORTH, "", 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -27,10 +29,19 @@ public class Figure implements Item{
|
||||
* @param z the z-coordinate of the Figure's initial position
|
||||
* @param rot the rotation of the Figure
|
||||
*/
|
||||
public Figure(Vector3f position, Rotation rot, String type) {
|
||||
public Figure(Vector3f position, Rotation rot, String type, int id) {
|
||||
this.position = calculateFieldPosition(0);
|
||||
this.rot = rot;
|
||||
this.type = type;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the id corresponding to the players id
|
||||
* @return the id of the figure
|
||||
*/
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,7 +98,7 @@ public class Figure implements Item{
|
||||
moveTo(calculateFieldPosition(fieldId));
|
||||
}
|
||||
|
||||
private Vector3f calculateFieldPosition(int fieldID) {
|
||||
public Vector3f calculateFieldPosition(int fieldID) {
|
||||
float baseX = 0.0f;
|
||||
float baseZ = 0.0f;
|
||||
|
||||
@@ -139,7 +150,18 @@ public class Figure implements Item{
|
||||
float zOffset = new Random().nextFloat();
|
||||
|
||||
//TODO adjust y pos
|
||||
return new Vector3f(baseX + xOffset, 1, baseZ + zOffset);
|
||||
return new Vector3f(baseX , 0, baseZ );
|
||||
}
|
||||
|
||||
public int getCurrentFieldID() {
|
||||
Vector3f pos = getPos();
|
||||
for (int fieldID = 0; fieldID < 40; fieldID++) {
|
||||
Vector3f fieldPosition = calculateFieldPosition(fieldID);
|
||||
if (pos.distance(fieldPosition) < 0.1f) { // Toleranz für Positionsvergleich
|
||||
return fieldID;
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("Current field ID could not be determined from position: " + pos);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -96,4 +96,13 @@ public class Hotel implements Item{
|
||||
// TODO
|
||||
return Rotation.NORTH;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID of the field the hotel is on.
|
||||
*
|
||||
* @return the ID of the field the hotel is on
|
||||
*/
|
||||
public int getFieldID() {
|
||||
return fieldID;
|
||||
}
|
||||
}
|
||||
|
@@ -24,6 +24,15 @@ public class House implements Item{
|
||||
this.fieldID = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field ID of the house.
|
||||
*
|
||||
* @return the field ID of the house
|
||||
*/
|
||||
public int getFieldID() {
|
||||
return fieldID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new house with the given stage.
|
||||
*
|
||||
|
@@ -8,6 +8,7 @@ import java.util.Queue;
|
||||
|
||||
import pp.monopoly.game.server.Player;
|
||||
import pp.monopoly.message.client.EndTurn;
|
||||
import pp.monopoly.message.server.NotificationMessage;
|
||||
|
||||
public class DeckHelper{
|
||||
|
||||
@@ -16,25 +17,26 @@ public class DeckHelper{
|
||||
|
||||
public DeckHelper() {
|
||||
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("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-2"));
|
||||
cards.add(new Card("Du hast den Dienstführerschein bestanden. Ziehe vor bis Teststrecke.", "dienstfuehrerschein"));
|
||||
cards.add(new Card("Malkmus läd zum Pubquiz ein. Rücke vor bis zum 20er.", "pubquiz"));
|
||||
cards.add(new Card("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 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("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 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("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("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 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("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"));
|
||||
@@ -47,9 +49,8 @@ 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 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("Dein Jodel eines Schneepenis mit Unterhodenbeleuchtung geht viral. Ziehe 1000 EUR ein", "jodel-eispenis"));
|
||||
|
||||
shuffle();
|
||||
// shuffle();
|
||||
}
|
||||
|
||||
public void visit(Card card, Player player) {
|
||||
@@ -258,6 +259,7 @@ public class DeckHelper{
|
||||
|
||||
private void rueckstuferantrag(Player player) {
|
||||
player.getHandler().getLogic().received(new EndTurn(), player.getId());
|
||||
player.getHandler().getLogic().send(player, new NotificationMessage("aussetzen"));
|
||||
}
|
||||
|
||||
private void hausfeierSturz(Player player) {
|
||||
@@ -272,6 +274,7 @@ public class DeckHelper{
|
||||
private void dienstreiseLourd(Player player) {
|
||||
player.pay(1000);
|
||||
player.getHandler().getLogic().received(new EndTurn(), player.getId());
|
||||
player.getHandler().getLogic().send(player, new NotificationMessage("aussetzen"));
|
||||
}
|
||||
|
||||
private void blutspendenSonderurlaub(Player player) {
|
||||
@@ -296,6 +299,7 @@ public class DeckHelper{
|
||||
|
||||
private void partyEskaliert(Player player) {
|
||||
player.getHandler().getLogic().received(new EndTurn(), player.getId());
|
||||
player.getHandler().getLogic().send(player, new NotificationMessage("aussetzen"));
|
||||
}
|
||||
|
||||
private void vpEinstandsparty(Player player) {
|
||||
@@ -308,6 +312,7 @@ public class DeckHelper{
|
||||
|
||||
private void bergmarsch(Player player) {
|
||||
player.getHandler().getLogic().received(new EndTurn(), player.getId());
|
||||
player.getHandler().getLogic().send(player, new NotificationMessage("aussetzen"));
|
||||
}
|
||||
|
||||
private void jodelEispenis(Player player) {
|
||||
|
@@ -54,7 +54,7 @@ public class BoardManager {
|
||||
fields.add(new EventField("Üvas", 22));
|
||||
fields.add(new BuildingProperty("StudFBer B", 23, 2200, 180, 1500, FieldColor.RED));
|
||||
fields.add(new BuildingProperty("StudFBer A", 24, 2400, 200, 1500, FieldColor.RED));
|
||||
fields.add(new GateField("Nordtor", 25));
|
||||
fields.add(new GateField("Spießtor", 25));
|
||||
fields.add(new BuildingProperty("Cascada", 26, 2600, 220, 1500, FieldColor.YELLOW));
|
||||
fields.add(new BuildingProperty("Fakultätsgebäude", 27, 2600, 220, 1500, FieldColor.YELLOW));
|
||||
fields.add(new FoodField("Truppenküche", 28));
|
||||
@@ -146,45 +146,47 @@ public class BoardManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a House can be sold on the given Property
|
||||
* Checks if a House or Hotel can be sold on the given Property.
|
||||
*
|
||||
* @param field the Property to check
|
||||
* @return true if a house can be sold on the property, false otherwise
|
||||
* @return true if a house or hotel can be sold on the property, false otherwise
|
||||
*/
|
||||
public boolean canSell(BuildingProperty field) {
|
||||
if (field == null) {
|
||||
return false; // Null check for safety
|
||||
}
|
||||
|
||||
|
||||
// Get the color group of the property
|
||||
FieldColor groupColor = field.getColor();
|
||||
|
||||
|
||||
// Get all properties of the same color group
|
||||
List<BuildingProperty> groupProperties = board.stream()
|
||||
.filter(f -> f instanceof BuildingProperty)
|
||||
.map(f -> (BuildingProperty) f)
|
||||
.filter(bp -> bp.getColor() == groupColor)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
|
||||
// Check if the property has houses or a hotel to sell
|
||||
if (field.getHouses() == 0 && field.getHotel() == 0) {
|
||||
return false; // No houses or hotels to sell
|
||||
}
|
||||
|
||||
|
||||
// Ensure balanced selling: You cannot sell houses unevenly in the group
|
||||
int currentHouses = field.getHouses();
|
||||
int currentHotel = field.getHotel();
|
||||
|
||||
// If there is a hotel, selling is allowed only if all other properties have max houses
|
||||
|
||||
// If there is a hotel, ensure all other properties have max houses (4) before selling it
|
||||
if (currentHotel > 0) {
|
||||
return groupProperties.stream()
|
||||
.allMatch(bp -> bp.getHouses() == 4 || bp.equals(field));
|
||||
}
|
||||
|
||||
|
||||
// If there are houses, check that selling does not unbalance the group
|
||||
return groupProperties.stream()
|
||||
.allMatch(bp -> bp.getHouses() <= currentHouses);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gibt eine Liste von BuildingProperty-Feldern zurück, auf denen Häuser oder Hotels stehen.
|
||||
* @return Liste von BuildingProperty-Feldern mit Gebäuden
|
||||
@@ -198,3 +200,10 @@ public class BoardManager {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* TODO:
|
||||
- Häuser beim bau eines Hotels entfernen
|
||||
- Alle texturen schwarz
|
||||
|
||||
*
|
||||
*/
|
||||
|
@@ -801,8 +801,6 @@ public class ServerGameLogicTest {
|
||||
|
||||
player.buyProperty(property);
|
||||
|
||||
System.out.println("Player Balance: " + player.getAccountBalance());
|
||||
System.out.println("Player Properties: " + player.getProperties());
|
||||
assertEquals(14000, player.getAccountBalance());
|
||||
assertTrue(player.getProperties().contains(property.getId()));
|
||||
}
|
||||
|