From 358beacc650da68fc110b73d6f010c657ba24ddd Mon Sep 17 00:00:00 2001 From: Luca Puderbach Date: Sun, 1 Dec 2024 02:47:30 +0100 Subject: [PATCH 1/5] Mozzarella Update --- .../src/main/java/pp/monopoly/model/card/DeckHelper.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/card/DeckHelper.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/card/DeckHelper.java index 4a09f88..9f89f43 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/card/DeckHelper.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/card/DeckHelper.java @@ -236,9 +236,7 @@ public class DeckHelper{ } private void dienstsportGym(Player player) { - for (Player p : player.getHandler().getPlayers()) { - p.setPosition(1); - } + player.setPosition(1); } private void schimmelGulak(Player player) { From 73bfafa7f7808603cefbebcff04aa210e9952edd Mon Sep 17 00:00:00 2001 From: Luca Puderbach Date: Sun, 1 Dec 2024 03:00:30 +0100 Subject: [PATCH 2/5] Anpassungen Ereigniskarten --- .../src/main/java/pp/monopoly/model/card/DeckHelper.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/card/DeckHelper.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/card/DeckHelper.java index 9f89f43..b9fa193 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/card/DeckHelper.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/card/DeckHelper.java @@ -22,7 +22,7 @@ public class DeckHelper{ 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("Du warst ohne Namensschild in der Truppenküche. Rücke vor zum 10er. Gehe nicht über Monatsgehalt. Ziehe keine 2000 EUR ein.", "namensschild-truppenkueche")); + cards.add(new Card("Deine IGF-Daten sind verschwunden, statte Padubrin einen Besuch ab.", "namensschild-truppenkueche")); 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 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")); @@ -205,7 +205,7 @@ public class DeckHelper{ } private void namensschildTruppenkueche(Player player) { - //TODO 10 existiert nicht mehr + player.setPosition(24); } private void spendierhosenUnibar(Player player) { @@ -292,7 +292,7 @@ public class DeckHelper{ } private void kranzExmatrikulation(Player player) { - player.setPosition(5); + player.setPosition(29); } private void partyEskaliert(Player player) { From 528126aa292a7494caf0eba6a7be95c1f08e0793 Mon Sep 17 00:00:00 2001 From: Luca Puderbach Date: Sun, 1 Dec 2024 05:04:27 +0100 Subject: [PATCH 3/5] Kleines Ereigniskarten update --- .../model/src/main/java/pp/monopoly/model/card/DeckHelper.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/card/DeckHelper.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/card/DeckHelper.java index b9fa193..9185bb9 100644 --- a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/card/DeckHelper.java +++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/card/DeckHelper.java @@ -22,7 +22,7 @@ public class DeckHelper{ 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.", "namensschild-truppenkueche")); + cards.add(new Card("Deine IGF-Daten sind verschwunden, statte Padubrin einen Besuch ab und gib ihm einen Jägermeister aus.", "namensschild-truppenkueche")); 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 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")); @@ -206,6 +206,7 @@ public class DeckHelper{ private void namensschildTruppenkueche(Player player) { player.setPosition(24); + player.pay(25); } private void spendierhosenUnibar(Player player) { From 51b879a7c843dadbc85b0d61a6207aa0ffbe1b59 Mon Sep 17 00:00:00 2001 From: Luca Puderbach Date: Sun, 1 Dec 2024 05:05:11 +0100 Subject: [PATCH 4/5] =?UTF-8?q?Figuren=20Bewegung=20eingef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/pp/monopoly/client/MonopolyApp.java | 21 +- .../pp/monopoly/client/gui/TestWorld.java | 192 +++++++++++++----- 2 files changed, 154 insertions(+), 59 deletions(-) diff --git a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/MonopolyApp.java b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/MonopolyApp.java index 386ca28..87e082e 100644 --- a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/MonopolyApp.java +++ b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/MonopolyApp.java @@ -38,7 +38,18 @@ import static pp.monopoly.Resources.lookup; import pp.monopoly.client.gui.SettingsMenu; import pp.monopoly.client.gui.StartMenu; import pp.monopoly.client.gui.TestWorld; -import pp.monopoly.client.gui.popups.*; +import pp.monopoly.client.gui.popups.Bankrupt; +import pp.monopoly.client.gui.popups.BuildingPropertyCard; +import pp.monopoly.client.gui.popups.BuyCard; +import pp.monopoly.client.gui.popups.BuyHouse; +import pp.monopoly.client.gui.popups.EventCardPopup; +import pp.monopoly.client.gui.popups.FoodFieldCard; +import pp.monopoly.client.gui.popups.GateFieldCard; +import pp.monopoly.client.gui.popups.LooserPopUp; +import pp.monopoly.client.gui.popups.RepayMortage; +import pp.monopoly.client.gui.popups.SellHouse; +import pp.monopoly.client.gui.popups.TakeMortage; +import pp.monopoly.client.gui.popups.TimeOut; import pp.monopoly.game.client.ClientGameLogic; import pp.monopoly.game.client.MonopolyClient; import pp.monopoly.game.client.ServerConnection; @@ -335,10 +346,10 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga logic.update(tpf); stateManager.update(tpf); - //TODO testing replace later - if (testWorld != null) { - testWorld.update(tpf); - } + // //TODO testing replace later + // if (testWorld != null) { + // testWorld.update(tpf); + // } } /** 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 580c95d..c94f4f8 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 @@ -1,22 +1,20 @@ package pp.monopoly.client.gui; -import java.util.List; +import java.util.Timer; +import java.util.TimerTask; import com.jme3.math.Vector3f; import pp.monopoly.client.MonopolyApp; import pp.monopoly.client.gui.popups.BuyCard; -import pp.monopoly.client.gui.popups.ConfirmTrade; import pp.monopoly.client.gui.popups.EventCardPopup; import pp.monopoly.client.gui.popups.FoodFieldCard; import pp.monopoly.client.gui.popups.GateFieldCard; import pp.monopoly.client.gui.popups.LooserPopUp; -import pp.monopoly.client.gui.popups.Rent; import pp.monopoly.client.gui.popups.TimeOut; import pp.monopoly.client.gui.popups.WinnerPopUp; import pp.monopoly.game.server.Player; import pp.monopoly.game.server.PlayerHandler; -import pp.monopoly.message.server.NotificationMessage; import pp.monopoly.model.fields.BuildingProperty; import pp.monopoly.model.fields.FoodField; import pp.monopoly.model.fields.GateField; @@ -28,10 +26,10 @@ import pp.monopoly.notification.UpdatePlayerView; /** * TestWorld zeigt eine einfache Szene mit Spielfeld und Spielfiguren. */ -public class TestWorld implements GameEventListener{ +public class TestWorld implements GameEventListener { private final MonopolyApp app; - private PlayerHandler playerHandler; // Liste der Spieler, bereits aus GameStart geladen + private PlayerHandler playerHandler; private CameraController cameraController; private Toolbar toolbar; @@ -58,10 +56,10 @@ public class TestWorld implements GameEventListener{ System.out.println("Szene initialisiert."); - // Initialisiere Szene + //Füge Inhalte ein setSkyColor(); createBoard(); - createPlayerFigures(); // Lädt Figuren aus der bereits vorhandenen Liste + createPlayerFigures(); toolbar = new Toolbar(app); toolbar.open(); } @@ -78,21 +76,23 @@ public class TestWorld implements GameEventListener{ */ private void createBoard() { try { - // Erstelle das Spielfeld als flaches Rechteck - com.jme3.scene.shape.Box box = new com.jme3.scene.shape.Box(10, 0.1f, 10); // Breite, Höhe, Tiefe + com.jme3.scene.shape.Box box = new com.jme3.scene.shape.Box(10, 0.1f, 10); com.jme3.scene.Geometry geom = new com.jme3.scene.Geometry("Board", box); - // Lade und setze das Material mit der Textur com.jme3.material.Material mat = new com.jme3.material.Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); com.jme3.texture.Texture texture = app.getAssetManager().loadTexture("Pictures/board2.png"); mat.setTexture("ColorMap", texture); geom.setMaterial(mat); - // Positioniere das Spielfeld in der Szene - geom.setLocalTranslation(0, -0.1f, 0); // Direkt auf der Grundebene + geom.setLocalTranslation(0, -0.1f, 0); + + com.jme3.math.Quaternion rotation = new com.jme3.math.Quaternion(); + rotation.fromAngleAxis(com.jme3.math.FastMath.HALF_PI, com.jme3.math.Vector3f.UNIT_Y); + geom.setLocalRotation(rotation); + app.getRootNode().attachChild(geom); - System.out.println("Spielbrett erfolgreich erstellt und hinzugefügt."); + System.out.println("Spielbrett erfolgreich erstellt, gedreht und hinzugefügt."); } catch (Exception e) { System.err.println("Fehler beim Erstellen des Spielfelds: " + e.getMessage()); } @@ -105,70 +105,154 @@ public class TestWorld implements GameEventListener{ for (int i = 0; i < playerHandler.getPlayers().size(); i++) { Player player = playerHandler.getPlayers().get(i); try { - // Lade das 3D-Modell der Spielfigur - com.jme3.scene.Spatial model = app.getAssetManager().loadModel("Models/" + player.getFigure().getType() + "/" + player.getFigure().getType() + ".j3o"); - model.setLocalScale(0.5f); // Skaliere das Modell - - // Positioniere die Figur unten rechts - float startX = 9.1f; // X-Koordinate für die Ecke unten rechts - float startZ = -9.1f; // Z-Koordinate für die Ecke unten rechts - float spacing = 0.4f; // Abstand zwischen den Figuren - model.setLocalTranslation(startX, 0, startZ - (i * spacing)); // Position anpassen - + com.jme3.scene.Spatial model = app.getAssetManager().loadModel( + "Models/" + player.getFigure().getType() + "/" + player.getFigure().getType() + ".j3o" + ); + model.setLocalScale(0.5f); + + Vector3f startPosition = calculateFieldPosition(player.getFieldID(), i); + model.setLocalTranslation(startPosition); + + model.setName("PlayerFigure_" + player.getId()); app.getRootNode().attachChild(model); - System.out.println("Figur für Spieler " + player.getId() + " positioniert bei (" + startX + ", 0, " + (startZ - (i * spacing)) + ")"); + + System.out.println("Figur für Spieler " + player.getId() + " erstellt bei " + startPosition); } catch (Exception e) { System.err.println("Fehler beim Laden des Modells für Spieler " + player.getId() + ": " + e.getMessage()); } } } - /** - * Wird bei jedem Frame aufgerufen, um die Szene zu aktualisieren. - * - * @param tpf Zeit seit dem letzten Frame in Sekunden - */ - public void update(float tpf) { - if (cameraController != null) { - cameraController.update(tpf); // Aktualisiere die Kameraposition + private Vector3f calculateFieldPosition(int fieldID, int playerIndex) { + float offset = 0.1f; + float baseX = 0.0f; + float baseZ = 0.0f; + + switch (fieldID) { + 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); + } + + float xOffset = (playerIndex % 2) * offset; + float zOffset = (playerIndex / 2) * offset; + + return new Vector3f(baseX + xOffset, 0, baseZ + zOffset); + } + + private void movePlayerFigure(Player player) { + int fieldID = player.getFieldID(); + int playerIndex = playerHandler.getPlayers().indexOf(player); // Hole den Index des Spielers + Vector3f targetPosition = calculateFieldPosition(fieldID, playerIndex); + + String figureName = "PlayerFigure_" + player.getId(); + com.jme3.scene.Spatial figure = app.getRootNode().getChild(figureName); + + if (figure != null) { + 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 + ")"); + }); + } + }, 3000); // 3 Sekunden Verzögerung für die Bewegung + } else { + System.err.println("Figur für Spieler " + player.getId() + " nicht gefunden."); } } @Override public void receivedEvent(PopUpEvent event) { - if(event.msg().equals("Buy")) { - int field = app.getGameLogic().getPlayerHandler().getPlayerById(app.getId()).getFieldID(); - Object fieldObject = app.getGameLogic().getBoardManager().getFieldAtIndex(field); - - if (fieldObject instanceof BuildingProperty) { - new BuyCard(app).open(); - } else if (fieldObject instanceof GateField){ - new GateFieldCard(app).open(); - } else if (fieldObject instanceof FoodField) { - new FoodFieldCard(app).open(); - } - } else if(event.msg().equals("Winner")) { + if (event.msg().equals("Buy")) { + // Erstelle einen Timer, um den Delay umzusetzen + Timer timer = new Timer(); + timer.schedule(new TimerTask() { + @Override + public void run() { + // GUI-Operationen im jMonkey-Thread ausführen + app.enqueue(() -> { + int field = app.getGameLogic().getPlayerHandler().getPlayerById(app.getId()).getFieldID(); + Object fieldObject = app.getGameLogic().getBoardManager().getFieldAtIndex(field); + + if (fieldObject instanceof BuildingProperty) { + new BuyCard(app).open(); + } else if (fieldObject instanceof GateField) { + new GateFieldCard(app).open(); + } else if (fieldObject instanceof FoodField) { + new FoodFieldCard(app).open(); + } + }); + } + }, 5000); // Verzögerung in Millisekunden + } else if (event.msg().equals("Winner")) { new WinnerPopUp(app).open(); - } else if(event.msg().equals("Looser")) { + } else if (event.msg().equals("Looser")) { new LooserPopUp(app).open(); - } else if(event.msg().equals("timeout")) { + } else if (event.msg().equals("timeout")) { new TimeOut(app).open(); - } else if (event.msg().equals("tradeRequest")) { - new ConfirmTrade(app).open(); - } else if(event.msg().equals("rent")) { - new Rent(app, ( (NotificationMessage) event.message()).getRentOwner(), ( (NotificationMessage) event.message()).getRentAmount() ).open(); } } @Override public void receivedEvent(EventCardEvent event) { - new EventCardPopup(app, event.description()).open(); + Timer timer = new Timer(); + timer.schedule(new TimerTask() { + @Override + public void run() { + app.enqueue(() -> new EventCardPopup(app, event.description()).open()); + } + }, 5000); // 5 Sekunden Verzögerung für Event-Popups } + @Override public void receivedEvent(UpdatePlayerView event) { this.playerHandler = app.getGameLogic().getPlayerHandler(); - cameraController.setPosition(playerHandler.getPlayerById(app.getId()).getFieldID()); - cameraController.update(0); + + // Aktualisiere die Position aller Spielerfiguren + for (Player player : playerHandler.getPlayers()) { + movePlayerFigure(player); + } } } From 350c157493dc74655dd4499b1f47a76adcd18dca Mon Sep 17 00:00:00 2001 From: Luca Puderbach Date: Sun, 1 Dec 2024 05:38:27 +0100 Subject: [PATCH 5/5] 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) {