Compare commits
11 Commits
1db2d9ebac
...
demo
Author | SHA1 | Date | |
---|---|---|---|
|
eb54fb1d14 | ||
|
40c550cc4d | ||
|
18300987a4 | ||
|
df4a81cbf2 | ||
|
c635df9369 | ||
|
c6ad605021 | ||
|
1e20a2ac6e | ||
|
36a9a7addf | ||
|
e1190cd4a2 | ||
|
34ecd2277b | ||
|
5959f36a21 |
@@ -8,24 +8,22 @@ import com.jme3.effect.ParticleMesh;
|
||||
import com.jme3.effect.shapes.EmitterSphereShape;
|
||||
import com.jme3.light.AmbientLight;
|
||||
import com.jme3.light.DirectionalLight;
|
||||
import com.jme3.light.PointLight;
|
||||
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.scene.shape.Sphere;
|
||||
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;
|
||||
@@ -33,13 +31,7 @@ import pp.monopoly.client.gui.CameraController;
|
||||
import pp.monopoly.client.gui.CameraInputHandler;
|
||||
import pp.monopoly.client.gui.Toolbar;
|
||||
import pp.monopoly.model.Board;
|
||||
import pp.monopoly.client.gui.FigureControl;
|
||||
|
||||
import static java.lang.Math.divideExact;
|
||||
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.
|
||||
@@ -51,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.
|
||||
@@ -75,16 +68,10 @@ public class BoardAppState extends MonopolyAppState {
|
||||
/**
|
||||
* The pop-up manager for displaying messages and notifications.
|
||||
*/
|
||||
private PopUpManager popUpManager;;
|
||||
private PopUpManager popUpManager;
|
||||
|
||||
private Vector3f currentTarget = new Vector3f(-10f,0,-10f);
|
||||
|
||||
private float modelHeight = -5f;
|
||||
private final float targetHeight = 0f;
|
||||
private final float animationSpeed = 0.01389f;
|
||||
private Node modelNode;
|
||||
private boolean startAnimation = false;
|
||||
private CameraController cameraController;
|
||||
|
||||
private CameraInputHandler cameraInputHandler;
|
||||
|
||||
|
||||
@@ -100,7 +87,7 @@ public class BoardAppState extends MonopolyAppState {
|
||||
super.initialize(stateManager, application);
|
||||
|
||||
// Initialisiere den CameraController zuerst
|
||||
cameraController = new CameraController(getApp().getCamera(), 25, 40);
|
||||
cameraController = new CameraController(getApp().getCamera(), getApp());
|
||||
|
||||
// Danach den CameraInputHandler mit dem initialisierten CameraController
|
||||
cameraInputHandler = new CameraInputHandler(cameraController, getApp().getInputManager());
|
||||
@@ -109,7 +96,8 @@ public class BoardAppState extends MonopolyAppState {
|
||||
viewNode.attachChild(sceneNode);
|
||||
|
||||
setupLights();
|
||||
setupSky();
|
||||
// setupSky();
|
||||
getApp().getViewPort().setBackgroundColor(new com.jme3.math.ColorRGBA(0.5f, 0.7f, 1.0f, 1.0f));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -167,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);
|
||||
}
|
||||
|
||||
@@ -177,17 +166,79 @@ public class BoardAppState extends MonopolyAppState {
|
||||
*/
|
||||
private void setupSky() {
|
||||
final AssetManager assetManager = getApp().getAssetManager();
|
||||
final Texture west = assetManager.loadTexture("Pictures/Backdrop/wall.jpg"); //NON-NLS
|
||||
final Texture east = assetManager.loadTexture("Pictures/Backdrop/door.jpg"); //NON-NLS
|
||||
final Texture north = assetManager.loadTexture("Pictures/Backdrop/board.jpg"); //NON-NLS
|
||||
final Texture south = assetManager.loadTexture("Pictures/Backdrop/wall.jpg"); //NON-NLS
|
||||
final Texture up = assetManager.loadTexture("Pictures/Backdrop/wall.jpg"); //NON-NLS
|
||||
final Texture down = assetManager.loadTexture("Pictures/Backdrop/floor1.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.
|
||||
@@ -204,42 +255,67 @@ public class BoardAppState extends MonopolyAppState {
|
||||
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);
|
||||
|
||||
addModelToCenter(sceneNode);
|
||||
|
||||
// Schneefall hinzufügen
|
||||
addSnowEffect(sceneNode);
|
||||
// addSnowEffect(sceneNode);
|
||||
}
|
||||
|
||||
private Node createCardDeck() {
|
||||
Node cardDeck = new Node("cardDeck");
|
||||
Spatial card = getApp().getAssetManager().loadModel("models/Kartendecks/Ereigniskarten.j3o");
|
||||
card.setLocalTranslation(5.5f, 0, 2.7f);
|
||||
card.setLocalScale(4.1f);
|
||||
card.setLocalRotation(new Quaternion().fromAngleAxis(FastMath.QUARTER_PI, Vector3f.UNIT_Y));
|
||||
|
||||
Spatial card2 = getApp().getAssetManager().loadModel("models/Kartendecks/Gemeinschaftskarten.j3o");
|
||||
card2.setLocalTranslation(-1.4f, 0, -3.8f);
|
||||
card2.setLocalScale(4.1f);
|
||||
card2.setLocalRotation(new Quaternion().fromAngleAxis(FastMath.QUARTER_PI , Vector3f.UNIT_Y));
|
||||
|
||||
//TODO insert card deck
|
||||
// cardDeck.attachChild(card);
|
||||
// cardDeck.attachChild(card2);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
public Vector3f getCurrentTarget(){
|
||||
return currentTarget;
|
||||
}
|
||||
|
||||
private void addSnowEffect(Node parentNode) {
|
||||
// ParticleEmitter für Schnee
|
||||
ParticleEmitter snowEmitter = new ParticleEmitter("Snow", ParticleMesh.Type.Triangle, 5000);
|
||||
@@ -269,86 +345,10 @@ public class BoardAppState extends MonopolyAppState {
|
||||
parentNode.attachChild(snowEmitter);
|
||||
}
|
||||
|
||||
private void addModelToCenter(Node parentNode) {
|
||||
AssetManager assetManager = getApp().getAssetManager();
|
||||
|
||||
Material material = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
|
||||
material.setColor("Diffuse", ColorRGBA.White);
|
||||
material.setBoolean("UseMaterialColors", true);
|
||||
|
||||
Sphere lowerSphereLeft = new Sphere(32, 32, 0.5f);
|
||||
Geometry lowerSphereLeftGeom = new Geometry("LowerSphereLeft", lowerSphereLeft);
|
||||
lowerSphereLeftGeom.setMaterial(material);
|
||||
lowerSphereLeftGeom.setLocalTranslation(-0.6f - 4f, 0.5f, 0.3f - 5f);
|
||||
|
||||
Sphere lowerSphereRight = new Sphere(32, 32, 0.5f);
|
||||
Geometry lowerSphereRightGeom = new Geometry("LowerSphereRight", lowerSphereRight);
|
||||
lowerSphereRightGeom.setMaterial(material);
|
||||
lowerSphereRightGeom.setLocalTranslation(0.6f - 4f, 0.5f, 0.3f - 5f);
|
||||
|
||||
Cylinder cylinder = new Cylinder(16, 16, 0.4f, 2f, true);
|
||||
Geometry cylinderGeom = new Geometry("Cylinder", cylinder);
|
||||
cylinderGeom.setMaterial(material);
|
||||
cylinderGeom.setLocalTranslation(0f - 4f, 1.5f, 0f - 5f);
|
||||
cylinderGeom.rotate(FastMath.HALF_PI, 0, 0);
|
||||
|
||||
Sphere upperSphere = new Sphere(32, 32, 0.4f);
|
||||
Geometry upperSphereGeom = new Geometry("UpperSphere", upperSphere);
|
||||
upperSphereGeom.setMaterial(material);
|
||||
upperSphereGeom.setLocalTranslation(0f - 4f, 2.5f, 0f - 5f);
|
||||
|
||||
this.modelNode = new Node("3DModel");
|
||||
this.modelNode.attachChild(lowerSphereLeftGeom);
|
||||
this.modelNode.attachChild(lowerSphereRightGeom);
|
||||
this.modelNode.attachChild(cylinderGeom);
|
||||
this.modelNode.attachChild(upperSphereGeom);
|
||||
|
||||
this.modelNode.setLocalTranslation(0, modelHeight, 0);
|
||||
parentNode.attachChild(this.modelNode);
|
||||
|
||||
PointLight lightLeft = new PointLight();
|
||||
lightLeft.setColor(ColorRGBA.Blue);
|
||||
lightLeft.setPosition(new Vector3f(-0.6f - 4f, 0f, 0.3f - 5f));
|
||||
lightLeft.setRadius(2f);
|
||||
parentNode.addLight(lightLeft);
|
||||
|
||||
PointLight lightRight = new PointLight();
|
||||
lightRight.setColor(ColorRGBA.Blue);
|
||||
lightRight.setPosition(new Vector3f(0.6f - 4f, 0f, 0.3f - 5f));
|
||||
lightRight.setRadius(2f);
|
||||
parentNode.addLight(lightRight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(float tpf) {
|
||||
super.update(tpf);
|
||||
if (startAnimation && modelHeight < targetHeight) {
|
||||
modelHeight += animationSpeed * tpf; // Geschwindigkeit basierend auf Zeit pro Frame
|
||||
if (modelHeight > targetHeight) {
|
||||
modelHeight = targetHeight; // Zielhöhe nicht überschreiten
|
||||
startAnimation = false; // Animation beenden
|
||||
}
|
||||
updateModelHeight(); // Aktualisiere die Position des Modells
|
||||
}
|
||||
}
|
||||
|
||||
private void updateModelHeight() {
|
||||
if (modelNode == null) {
|
||||
modelNode = (Node) sceneNode.getChild("3DModel");
|
||||
}
|
||||
if (modelNode != null) {
|
||||
modelNode.setLocalTranslation(0, modelHeight, 0); // Aktualisiere die Y-Position
|
||||
}
|
||||
}
|
||||
|
||||
public void onRollDicePressed() {
|
||||
System.out.println("onRollDicePressed called");
|
||||
if (!startAnimation) {
|
||||
startAnimation = true;
|
||||
modelHeight = -5f; // Reset der Höhe
|
||||
updateModelHeight(); // Stelle sicher, dass das Modell an der Startposition ist
|
||||
System.out.println("Animation started, startAnimation set to: " + startAnimation);
|
||||
}
|
||||
cameraController.update(tpf);
|
||||
}
|
||||
|
||||
}
|
@@ -292,7 +292,9 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
|
||||
final StatsAppState stats = new StatsAppState(guiNode, normalFont);
|
||||
stateManager.attach(stats);
|
||||
}
|
||||
flyCam.setEnabled(true);
|
||||
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));
|
||||
|
||||
|
@@ -56,7 +56,7 @@ public class PopUpManager implements GameEventListener {
|
||||
}
|
||||
});
|
||||
}
|
||||
}, 6000);
|
||||
}, 8000);
|
||||
} else if (event.msg().equals("Winner")) {
|
||||
new WinnerPopUp(app).open();
|
||||
} else if (event.msg().equals("Looser")) {
|
||||
|
@@ -3,7 +3,13 @@ package pp.monopoly.client.gui;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.renderer.Camera;
|
||||
|
||||
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,
|
||||
@@ -11,49 +17,92 @@ public class CameraController {
|
||||
}
|
||||
|
||||
private final Camera camera;
|
||||
private CameraMode currentMode = CameraMode.FOCUS_CURRENT_PLAYER;
|
||||
private CameraMode currentMode;
|
||||
|
||||
private final float height; // Höhe der Kamera
|
||||
private final float offset; // Versatz zur Spielfeldseite
|
||||
private PlayerHandler playerHandler; // Reference to PlayerHandler for player data
|
||||
private final MonopolyApp app; // Reference to MonopolyApp for self ID
|
||||
|
||||
public CameraController(Camera camera, float height, float offset) {
|
||||
public CameraController(Camera camera, MonopolyApp app) {
|
||||
this.camera = camera;
|
||||
this.height = height;
|
||||
this.offset = offset;
|
||||
setMode(currentMode);
|
||||
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;
|
||||
updatePosition(0); // Standardmäßig das Startfeld fokussieren
|
||||
}
|
||||
|
||||
public void update(float tpf) {
|
||||
if (currentMode != CameraMode.FREECAM) {
|
||||
camera.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);
|
||||
}
|
||||
}
|
||||
|
||||
public void updatePosition(int fieldID) {
|
||||
Vector3f newPosition = fieldIdToVector(fieldID);
|
||||
camera.setLocation(newPosition);
|
||||
if (currentMode != CameraMode.FREECAM) {
|
||||
camera.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);
|
||||
}
|
||||
}
|
||||
|
||||
private Vector3f fieldIdToVector(int fieldID) {
|
||||
switch (currentMode) {
|
||||
case FOCUS_CURRENT_PLAYER:
|
||||
if (fieldID <= 10) return new Vector3f(offset, height, 0);
|
||||
if (fieldID <= 20) return new Vector3f(0, height, offset);
|
||||
if (fieldID <= 30) return new Vector3f(-offset, height, 0);
|
||||
return new Vector3f(0, height, -offset);
|
||||
updatePosition();
|
||||
break;
|
||||
case FOCUS_SELF:
|
||||
return new Vector3f(0, height, fieldID <= 20 ? offset : -offset);
|
||||
updatePosition();
|
||||
break;
|
||||
|
||||
case FREECAM:
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return new Vector3f(0, height, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void updatePosition() {
|
||||
Vector3f newPosition = getPos();
|
||||
camera.setLocation(newPosition);
|
||||
|
||||
camera.lookAt(app.getGameLogic().getBoard().getFigure(app.getId()).getPos(), Vector3f.UNIT_Y);
|
||||
camera.update();
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
@@ -20,7 +20,6 @@ import com.simsilica.lemur.event.MouseEventControl;
|
||||
import com.simsilica.lemur.event.MouseListener;
|
||||
import com.simsilica.lemur.style.ElementId;
|
||||
import pp.dialog.Dialog;
|
||||
import pp.monopoly.client.BoardAppState;
|
||||
import pp.monopoly.client.MonopolyApp;
|
||||
import pp.monopoly.client.gui.popups.Bankrupt;
|
||||
import pp.monopoly.game.server.Player;
|
||||
@@ -197,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.
|
||||
*
|
||||
@@ -291,12 +280,6 @@ public class Toolbar extends Dialog implements GameEventListener {
|
||||
startDiceAnimation();
|
||||
app.getGameLogic().send(new RollDice());
|
||||
app.getGameLogic().playSound(Sound.BUTTON);
|
||||
|
||||
// Animation in BoardAppState starten
|
||||
BoardAppState boardAppState = app.getStateManager().getState(BoardAppState.class);
|
||||
if (boardAppState != null) {
|
||||
boardAppState.onRollDicePressed(); // Animation starten
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -361,18 +344,6 @@ public class Toolbar extends Dialog implements GameEventListener {
|
||||
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.
|
||||
|
@@ -76,11 +76,11 @@ public class GateFieldCard extends Dialog implements PopupDialog {
|
||||
propertyValuesContainer.addChild(new Label("„Preis: " + field.getPrice() + " EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("", new ElementId("label-Text"))); // Empty line
|
||||
propertyValuesContainer.addChild(new Label("Miete: 250 EUR", new ElementId("label-Text")));
|
||||
propertyValuesContainer.addChild(new Label("Wenn man 2 Bahnhöfe", 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 Bahnhöfe", 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 Bahnhöfe", 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")));
|
||||
|
BIN
Projekte/monopoly/client/src/main/resources/Textures/Bot.jpg
Normal file
After Width: | Height: | Size: 707 KiB |
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: 215 KiB |
After Width: | Height: | Size: 60 KiB |
@@ -327,6 +327,11 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker {
|
||||
|
||||
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 {
|
||||
|
@@ -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();
|
||||
}
|
||||
|
||||
|
@@ -229,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());
|
||||
}
|
||||
@@ -472,7 +474,7 @@ 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);
|
||||
@@ -483,13 +485,15 @@ public class ServerGameLogic implements ClientInterpreter {
|
||||
|
||||
// Player 2 builds houses on the Red set
|
||||
// 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+
|
||||
@@ -514,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);
|
||||
}
|
||||
|
||||
@@ -532,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());
|
||||
}
|
||||
}
|
||||
|
@@ -147,6 +147,10 @@ public class Board {
|
||||
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.
|
||||
*
|
||||
|
@@ -17,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"));
|
||||
@@ -48,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) {
|
||||
|