From 350c157493dc74655dd4499b1f47a76adcd18dca Mon Sep 17 00:00:00 2001 From: Luca Puderbach Date: Sun, 1 Dec 2024 05:38:27 +0100 Subject: [PATCH] Figuren Animationen --- .../pp/monopoly/client/gui/TestWorld.java | 76 +++++++++++++++++-- 1 file changed, 70 insertions(+), 6 deletions(-) diff --git a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/TestWorld.java b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/TestWorld.java index c94f4f8..86d3b6f 100644 --- a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/TestWorld.java +++ b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/TestWorld.java @@ -3,7 +3,11 @@ package pp.monopoly.client.gui; import java.util.Timer; import java.util.TimerTask; +import com.jme3.math.FastMath; import com.jme3.math.Vector3f; +import com.jme3.renderer.RenderManager; +import com.jme3.renderer.ViewPort; +import com.jme3.scene.control.AbstractControl; import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.gui.popups.BuyCard; @@ -41,9 +45,9 @@ public class TestWorld implements GameEventListener { */ public TestWorld(MonopolyApp app) { this.app = app; - this.playerHandler = app.getGameLogic().getPlayerHandler(); + this.playerHandler = app.getGameLogic().getPlayerHandler(); // Hole den PlayerHandler app.getGameLogic().addListener(this); - cameraController = new CameraController(app.getCamera()); + cameraController = new CameraController(app.getCamera(), playerHandler); // Übergebe PlayerHandler } /** @@ -180,27 +184,87 @@ public class TestWorld implements GameEventListener { private void movePlayerFigure(Player player) { int fieldID = player.getFieldID(); - int playerIndex = playerHandler.getPlayers().indexOf(player); // Hole den Index des Spielers + int playerIndex = playerHandler.getPlayers().indexOf(player); // Spielerindex holen Vector3f targetPosition = calculateFieldPosition(fieldID, playerIndex); String figureName = "PlayerFigure_" + player.getId(); com.jme3.scene.Spatial figure = app.getRootNode().getChild(figureName); if (figure != null) { + Vector3f startPosition = figure.getLocalTranslation(); + Vector3f cornerPosition = calculateCornerPosition(startPosition, targetPosition); // Berechne Eckpunkt + float animationDuration = 3.0f; // Gesamtdauer der Animation + float[] elapsedTime = {0.0f}; // Verstrichene Zeit + Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { app.enqueue(() -> { - figure.setLocalTranslation(targetPosition); - System.out.println("Spieler " + player.getId() + " bewegt zu Feld " + fieldID + " (" + targetPosition + ")"); + app.getRootNode().addControl(new AbstractControl() { + @Override + protected void controlUpdate(float tpf) { + elapsedTime[0] += tpf; + float progress = Math.min(elapsedTime[0] / animationDuration, 1.0f); + + Vector3f interpolatedPosition; + if (progress < 0.5f) { + // Erste Hälfte der Animation: Bewegung zur Ecke + float localProgress = progress / 0.5f; // Normiere auf [0, 1] + interpolatedPosition = new Vector3f( + FastMath.interpolateLinear(localProgress, startPosition.x, cornerPosition.x), + FastMath.interpolateLinear(localProgress, startPosition.y, cornerPosition.y), + FastMath.interpolateLinear(localProgress, startPosition.z, cornerPosition.z) + ); + } else { + // Zweite Hälfte der Animation: Bewegung vom Eckpunkt zum Ziel + float localProgress = (progress - 0.5f) / 0.5f; // Normiere auf [0, 1] + interpolatedPosition = new Vector3f( + FastMath.interpolateLinear(localProgress, cornerPosition.x, targetPosition.x), + FastMath.interpolateLinear(localProgress, cornerPosition.y, targetPosition.y), + FastMath.interpolateLinear(localProgress, cornerPosition.z, targetPosition.z) + ); + } + + figure.setLocalTranslation(interpolatedPosition); + + // Animation beenden, wenn sie fertig ist + if (progress >= 1.0f) { + this.setEnabled(false); + app.getRootNode().removeControl(this); + System.out.println("Spieler " + player.getId() + " hat das Ziel erreicht: " + targetPosition); + } + } + + @Override + protected void controlRender(RenderManager rm, ViewPort vp) { + // Keine spezielle Renderlogik notwendig + } + }); }); } - }, 3000); // 3 Sekunden Verzögerung für die Bewegung + }, (long) 2000); // Verzögerung in Millisekunden } else { System.err.println("Figur für Spieler " + player.getId() + " nicht gefunden."); } } + + /** + * Berechnet den Eckpunkt basierend auf Start- und Zielposition. + * + * @param startPosition Die Startposition der Figur. + * @param targetPosition Die Zielposition der Figur. + * @return Die Position der Ecke, die passiert werden muss. + */ + private Vector3f calculateCornerPosition(Vector3f startPosition, Vector3f targetPosition) { + if (Math.abs(startPosition.x - targetPosition.x) > Math.abs(startPosition.z - targetPosition.z)) { + // Bewegung entlang der X-Achse zuerst, dann Z-Achse + return new Vector3f(targetPosition.x, 0, startPosition.z); + } else { + // Bewegung entlang der Z-Achse zuerst, dann X-Achse + return new Vector3f(startPosition.x, 0, targetPosition.z); + } + } @Override public void receivedEvent(PopUpEvent event) {