diff --git a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/BoardAppState.java b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/BoardAppState.java index dfa1460..8fd4701 100644 --- a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/BoardAppState.java +++ b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/BoardAppState.java @@ -25,6 +25,7 @@ import com.jme3.util.TangentBinormalGenerator; import pp.monopoly.client.gui.BobTheBuilder; import pp.monopoly.client.gui.Toolbar; import pp.monopoly.model.Board; +import pp.monopoly.client.gui.FigureControl; import static pp.util.FloatMath.TWO_PI; import static pp.util.FloatMath.cos; import static pp.util.FloatMath.sin; @@ -66,6 +67,8 @@ public class BoardAppState extends MonopolyAppState { */ private PopUpManager popUpManager;; + private Vector3f currentTarget = new Vector3f(-10f,0,-10f); + /** * Initializes the state by setting up the sky, lights, and other visual components. * This method is called when the state is first attached to the state manager. @@ -120,12 +123,14 @@ public class BoardAppState extends MonopolyAppState { final float x = mx - cos; final float y = my - sin; final Camera camera = getApp().getCamera(); - camera.setLocation(new Vector3f(-30,25,-30)); - camera.lookAt(new Vector3f(0,0, 0), + camera.setLocation(new Vector3f(0,30,0)); + camera.lookAt(new Vector3f(getCurrentTarget()), Vector3f.UNIT_Y); camera.update(); } + + /** * Disables the sea and sky state, removing visual elements from the scene and unregistering listeners. * This method is called when the state is set to inactive. @@ -230,4 +235,8 @@ public class BoardAppState extends MonopolyAppState { cardDeck.attachChild(card2); return cardDeck; } + + public Vector3f getCurrentTarget(){ + return currentTarget; +} } \ No newline at end of file diff --git a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/FigureControl.java b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/FigureControl.java index 668494c..0c22485 100644 --- a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/FigureControl.java +++ b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/FigureControl.java @@ -1,5 +1,8 @@ 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.Spatial; @@ -10,38 +13,126 @@ import pp.monopoly.model.Figure; import pp.monopoly.notification.GameEventListener; import pp.monopoly.notification.UpdatePlayerView; -public class FigureControl extends AbstractControl implements GameEventListener{ +import java.util.LinkedList; +import java.util.Queue; + +public class FigureControl extends AbstractControl implements GameEventListener { private final Figure figure; private final Spatial spatial; private final MonopolyApp app; + private Queue 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(Spatial spatial, Figure figure, MonopolyApp app) { super(); this.figure = figure; - this.app = app; 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 + System.out.println("Delay completed. Starting animation..."); + } + + if (currentTarget == null && !path.isEmpty()) { + // Hole das nächste Ziel aus dem Pfad + currentTarget = path.poll(); + animationTime = 0f; + System.out.println("Next target: " + currentTarget); + } + + 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 + 1); + spatial.setLocalTranslation(interpolatedPosition); + + // Ziel erreicht + if (animationTime >= durationPerField) { + spatial.setLocalTranslation(currentTarget); + figure.moveTo(currentTarget); // Synchronisiere die interne Position + currentTarget = null; // Setze Ziel zurück + System.out.println("Target reached."); + } + } } + + +// Beispiel: Berechnung des nächsten Feldes +private int nextField() { + int currentField = figure.getCurrentFieldID(); + return (currentField + 1) % 40; // Weiter zum nächsten Feld +} + + + @Override protected void controlRender(RenderManager rm, ViewPort vp) { - // No rendering required + // No rendering logic required } + + public void setPath(int startField, int endField) { + System.out.println("setPath called with startField: " + startField + ", endField: " + endField); + path.clear(); + for (int fieldId = startField; fieldId != endField; fieldId = (fieldId + 1) % 40) { + Vector3f position = figure.calculateFieldPosition(fieldId); + System.out.println("Adding position to path: " + position); + path.add(position); + } + Vector3f finalPosition = figure.calculateFieldPosition(endField); + path.add(finalPosition); + System.out.println("Final position added to path: " + finalPosition); + System.out.println("Path size: " + path.size()); + } + @Override public void receivedEvent(UpdatePlayerView event) { + System.out.println("Event received: " + event); + int newPos = app.getGameLogic().getPlayerHandler().getPlayerById(figure.getId()).getFieldID(); + int currentField = figure.getCurrentFieldID(); - figure.moveTo(newPos); + if (currentField == newPos) { + System.out.println("Figure is already at the correct position. No path set."); + return; + } - //TODO hier einzelne Punkte der Animation ablkaufen mit figure.setLocalTransLation und jeweils Rotation anpassen + System.out.println("Movement required. Current field: " + currentField + ", New field: " + newPos); - spatial.setLocalTranslation(figure.getPos()); + setPath(currentField, newPos); + delayTime = 3f; // Verzögerung zurücksetzen + delayElapsed = 0f; // Timer zurücksetzen + } + + + + + + } diff --git a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/Toolbar.java b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/Toolbar.java index 9225ef2..51aec7d 100644 --- a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/Toolbar.java +++ b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/Toolbar.java @@ -247,7 +247,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; } diff --git a/Projekte/monopoly/client/src/main/resources/Pictures/dice/5.png b/Projekte/monopoly/client/src/main/resources/Pictures/dice/5.png index 92a4500..9db30de 100644 Binary files a/Projekte/monopoly/client/src/main/resources/Pictures/dice/5.png and b/Projekte/monopoly/client/src/main/resources/Pictures/dice/5.png differ diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/Figure.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/Figure.java index ea2e570..74e4dc4 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/Figure.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/Figure.java @@ -98,49 +98,51 @@ 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; switch (fieldID) { - case 0: baseX = -5.0f; baseZ = -5.0f; break; - case 1: baseX = -3.5f; baseZ = -5.0f; break; - case 2: baseX = -2.5f; baseZ = -5.0f; break; - case 3: baseX = -1.5f; baseZ = -5.0f; break; - case 4: baseX = -0.5f; baseZ = -5.0f; break; - case 5: baseX = 0.5f; baseZ = -5.0f; break; - case 6: baseX = 1.5f; baseZ = -5.0f; break; - case 7: baseX = 2.5f; baseZ = -5.0f; break; - case 8: baseX = 3.5f; baseZ = -5.0f; break; - case 9: baseX = 5.0f; baseZ = -5.0f; break; - case 10: baseX = 5.0f; baseZ = -3.5f; break; - case 11: baseX = 5.0f; baseZ = -2.5f; break; - case 12: baseX = 5.0f; baseZ = -1.5f; break; - case 13: baseX = 5.0f; baseZ = -0.5f; break; - case 14: baseX = 5.0f; baseZ = 0.5f; break; - case 15: baseX = 5.0f; baseZ = 1.5f; break; - case 16: baseX = 5.0f; baseZ = 2.5f; break; - case 17: baseX = 5.0f; baseZ = 3.5f; break; - case 18: baseX = 5.0f; baseZ = 5.0f; break; - case 19: baseX = 3.5f; baseZ = 5.0f; break; - case 20: baseX = 2.5f; baseZ = 5.0f; break; - case 21: baseX = 1.5f; baseZ = 5.0f; break; - case 22: baseX = 0.5f; baseZ = 5.0f; break; - case 23: baseX = -0.5f; baseZ = 5.0f; break; - case 24: baseX = -1.5f; baseZ = 5.0f; break; - case 25: baseX = -2.5f; baseZ = 5.0f; break; - case 26: baseX = -3.5f; baseZ = 5.0f; break; - case 27: baseX = -5.0f; baseZ = 5.0f; break; - case 28: baseX = -5.0f; baseZ = 3.5f; break; - case 29: baseX = -5.0f; baseZ = 2.5f; break; - case 30: baseX = -5.0f; baseZ = 1.5f; break; - case 31: baseX = -5.0f; baseZ = 0.5f; break; - case 32: baseX = -5.0f; baseZ = -0.5f; break; - case 33: baseX = -5.0f; baseZ = -1.5f; break; - case 34: baseX = -5.0f; baseZ = -2.5f; break; - case 35: baseX = -5.0f; baseZ = -3.5f; break; - case 36: baseX = -5.0f; baseZ = -4.5f; break; - case 37: baseX = -5.0f; baseZ = -5.0f; break; + case 0: baseX = -9.1f; baseZ = -9.1f; break; + case 1: baseX = -6.5f; baseZ = -9.1f; break; + case 2: baseX = -4.9f; baseZ = -9.1f; break; + case 3: baseX = -3.3f; baseZ = -9.1f; break; + case 4: baseX = -1.6f; baseZ = -9.1f; break; + case 5: baseX = 0.0f; baseZ = -9.1f; break; + case 6: baseX = 1.6f; baseZ = -9.1f; break; + case 7: baseX = 3.3f; baseZ = -9.1f; break; + case 8: baseX = 4.9f; baseZ = -9.1f; break; + case 9: baseX = 6.5f; baseZ = -9.1f; break; + case 10: baseX = 9.1f; baseZ = -9.1f; break; + case 11: baseX = 9.1f; baseZ = -6.5f; break; + case 12: baseX = 9.1f; baseZ = -4.9f; break; + case 13: baseX = 9.1f; baseZ = -3.3f; break; + case 14: baseX = 9.1f; baseZ = -1.6f; break; + case 15: baseX = 9.1f; baseZ = 0.0f; break; + case 16: baseX = 9.1f; baseZ = 1.6f; break; + case 17: baseX = 9.1f; baseZ = 3.3f; break; + case 18: baseX = 9.1f; baseZ = 4.9f; break; + case 19: baseX = 9.1f; baseZ = 6.5f; break; + case 20: baseX = 9.1f; baseZ = 9.1f; break; + case 21: baseX = 6.5f; baseZ = 9.1f; break; + case 22: baseX = 4.9f; baseZ = 9.1f; break; + case 23: baseX = 3.3f; baseZ = 9.1f; break; + case 24: baseX = 1.6f; baseZ = 9.1f; break; + case 25: baseX = 0.0f; baseZ = 9.1f; break; + case 26: baseX = -1.6f; baseZ = 9.1f; break; + case 27: baseX = -3.3f; baseZ = 9.1f; break; + case 28: baseX = -4.9f; baseZ = 9.1f; break; + case 29: baseX = -6.5f; baseZ = 9.1f; break; + case 30: baseX = -9.1f; baseZ = 9.1f; break; + case 31: baseX = -9.1f; baseZ = 6.5f; break; + case 32: baseX = -9.1f; baseZ = 4.9f; break; + case 33: baseX = -9.1f; baseZ = 3.3f; break; + case 34: baseX = -9.1f; baseZ = 1.6f; break; + case 35: baseX = -9.1f; baseZ = 0.0f; break; + case 36: baseX = -9.1f; baseZ = -1.6f; break; + case 37: baseX = -9.1f; baseZ = -3.3f; break; + case 38: baseX = -9.1f; baseZ = -4.9f; break; + case 39: baseX = -9.1f; baseZ = -6.5f; break; default: throw new IllegalArgumentException("Ungültige Feld-ID: " + fieldID); } @@ -148,7 +150,19 @@ 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 , 1, 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 + System.out.println("Current field ID: " + fieldID); + return fieldID; + } + } + throw new IllegalStateException("Current field ID could not be determined from position: " + pos); } /**