From bfc812b00387fcd0dcd48032a80e952743b33f31 Mon Sep 17 00:00:00 2001
From: Fleischer Hanno
Date: Mon, 2 Dec 2024 02:07:02 +0100
Subject: [PATCH 01/28] minas please help no serialization
---
.../src/main/java/pp/mdga/client/server/MdgaServer.java | 4 +++-
.../mdga/model/src/main/java/pp/mdga/game/PieceState.java | 6 +++++-
.../mdga/model/src/main/java/pp/mdga/game/ShieldState.java | 7 ++++++-
3 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/server/MdgaServer.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/server/MdgaServer.java
index 533dabd7..084a5df4 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/server/MdgaServer.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/server/MdgaServer.java
@@ -2,6 +2,7 @@
import com.jme3.network.*;
import com.jme3.network.serializing.Serializer;
+import com.jme3.network.serializing.serializers.EnumSerializer;
import pp.mdga.game.*;
import pp.mdga.message.client.*;
import pp.mdga.message.server.*;
@@ -12,7 +13,6 @@
import java.io.IOException;
import java.lang.System.Logger;
import java.lang.System.Logger.Level;
-import java.net.InetAddress;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.BlockingQueue;
@@ -143,6 +143,8 @@ private void initializeSerializables() {
Serializer.registerClass(StartNode.class);
Serializer.registerClass(PlayerData.class);
Serializer.registerClass(HomeNode.class);
+ Serializer.registerClass(PieceState.class, new EnumSerializer());
+ Serializer.registerClass(ShieldState.class, new EnumSerializer());
}
private void registerListeners() {
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/game/PieceState.java b/Projekte/mdga/model/src/main/java/pp/mdga/game/PieceState.java
index abab1258..bcee54c4 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/game/PieceState.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/game/PieceState.java
@@ -19,5 +19,9 @@ public enum PieceState {
/**
* The piece is finished.
*/
- HOMEFINISHED
+ HOMEFINISHED;
+
+ public PieceState next() {
+ return values()[(ordinal() + 1) % values().length];
+ }
}
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/game/ShieldState.java b/Projekte/mdga/model/src/main/java/pp/mdga/game/ShieldState.java
index 6bff3f52..37288217 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/game/ShieldState.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/game/ShieldState.java
@@ -15,5 +15,10 @@ public enum ShieldState {
/**
* The shield is suppressed, when the piece is on a start node.
*/
- SUPPRESSED
+ SUPPRESSED;
+
+
+ public ShieldState next() {
+ return values()[(ordinal() + 1) % values().length];
+ }
}
From 3658c88d7296c728cfcf0c3c429a31d4b77d29ee Mon Sep 17 00:00:00 2001
From: Fleischer Hanno
Date: Mon, 2 Dec 2024 02:11:40 +0100
Subject: [PATCH 02/28] made all enums look like the color enum
---
.../mdga/model/src/main/java/pp/mdga/game/PieceState.java | 8 ++++++++
.../model/src/main/java/pp/mdga/game/ShieldState.java | 6 ++++++
2 files changed, 14 insertions(+)
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/game/PieceState.java b/Projekte/mdga/model/src/main/java/pp/mdga/game/PieceState.java
index bcee54c4..6677d5a8 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/game/PieceState.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/game/PieceState.java
@@ -21,6 +21,14 @@ public enum PieceState {
*/
HOMEFINISHED;
+ public static PieceState getPieceStateByIndex(int index){
+ if (index < 0 || index >= values().length) {
+ throw new IllegalArgumentException("");
+ }
+ return values()[index];
+ }
+
+
public PieceState next() {
return values()[(ordinal() + 1) % values().length];
}
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/game/ShieldState.java b/Projekte/mdga/model/src/main/java/pp/mdga/game/ShieldState.java
index 37288217..f2c0c616 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/game/ShieldState.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/game/ShieldState.java
@@ -17,6 +17,12 @@ public enum ShieldState {
*/
SUPPRESSED;
+ public static ShieldState getShieldStateByIndex(int index){
+ if (index < 0 || index >= values().length) {
+ throw new IllegalArgumentException("");
+ }
+ return values()[index];
+ }
public ShieldState next() {
return values()[(ordinal() + 1) % values().length];
From 6c3103b2ed5d71f55fc58939b24d971428425947 Mon Sep 17 00:00:00 2001
From: Fleischer Hanno
Date: Mon, 2 Dec 2024 02:14:45 +0100
Subject: [PATCH 03/28] fixing serialization error
---
Projekte/mdga/model/src/main/java/pp/mdga/game/Piece.java | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/game/Piece.java b/Projekte/mdga/model/src/main/java/pp/mdga/game/Piece.java
index 64b671db..cb0468b5 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/game/Piece.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/game/Piece.java
@@ -43,6 +43,8 @@ public Piece(Color color, PieceState state, int id) {
private Piece() {
color = null;
+ state = PieceState.WAITING;
+ shield = ShieldState.NONE;
}
/**
From 6985d988f478ccacb15a5776b70c320687dfbde7 Mon Sep 17 00:00:00 2001
From: Daniel Grigencha
Date: Mon, 2 Dec 2024 02:15:22 +0100
Subject: [PATCH 04/28] Updated 'DetermineStartPlayerState' class. Updated the
'DetermineStartPlayerState' class by updating the logic inside the
'received(RequestDieMessage msg, int from)' method in it.
---
.../mdga/server/automaton/game/DetermineStartPlayerState.java | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/game/DetermineStartPlayerState.java b/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/game/DetermineStartPlayerState.java
index 3e76cf70..42c71629 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/game/DetermineStartPlayerState.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/game/DetermineStartPlayerState.java
@@ -4,6 +4,7 @@
import pp.mdga.message.client.RequestDieMessage;
import pp.mdga.message.server.ActivePlayerMessage;
import pp.mdga.message.server.DieMessage;
+import pp.mdga.message.server.EndOfTurnMessage;
import pp.mdga.server.ServerGameLogic;
import pp.mdga.server.automaton.GameState;
@@ -69,6 +70,7 @@ public void received(RequestDieMessage msg, int from) {
maximumRoll = entry.getValue();
} else {
this.playersHaveToRoll.remove(entry.getKey());
+ this.logic.getServerSender().send(entry.getKey(), new EndOfTurnMessage());
}
}
From b3fb2f8fa443953e2ca50b9b775f00f5067bc762 Mon Sep 17 00:00:00 2001
From: Daniel Grigencha
Date: Mon, 2 Dec 2024 02:31:55 +0100
Subject: [PATCH 05/28] added a new 'ShutdownMessage' for the server
---
.../src/main/java/pp/mdga/client/server/MdgaServer.java | 1 +
.../java/pp/mdga/message/server/ServerInterpreter.java | 7 +++++++
.../src/main/java/pp/mdga/server/automaton/LobbyState.java | 3 +++
3 files changed, 11 insertions(+)
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/server/MdgaServer.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/server/MdgaServer.java
index 084a5df4..24ee09db 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/server/MdgaServer.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/server/MdgaServer.java
@@ -130,6 +130,7 @@ private void initializeSerializables() {
Serializer.registerClass(ReconnectBriefingMessage.class);
Serializer.registerClass(ResumeGameMessage.class);
Serializer.registerClass(ServerStartGameMessage.class);
+ Serializer.registerClass(ShutdownMessage.class);
Serializer.registerClass(StartPieceMessage.class);
Serializer.registerClass(UpdateReadyMessage.class);
Serializer.registerClass(UpdateTSKMessage.class);
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/message/server/ServerInterpreter.java b/Projekte/mdga/model/src/main/java/pp/mdga/message/server/ServerInterpreter.java
index d7e7487c..1ed24edf 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/message/server/ServerInterpreter.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/message/server/ServerInterpreter.java
@@ -207,4 +207,11 @@ public interface ServerInterpreter {
* @param msg the SelectPiece message received.
*/
void received(SelectPieceMessage msg);
+
+ /**
+ * Handles a SelectTSK message received from the server.
+ *
+ * @param shutdownMessage the SelectTSK message received.
+ */
+ void received(ShutdownMessage shutdownMessage);
}
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/LobbyState.java b/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/LobbyState.java
index 6d72dcc5..2a4eba34 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/LobbyState.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/LobbyState.java
@@ -148,6 +148,9 @@ public void received(LobbyNotReadyMessage msg, int from) {
*/
@Override
public void received(LeaveGameMessage msg, int from) {
+ if (from == this.logic.getGame().getHost()) {
+ this.logic.getServerSender().broadcast(new ShutdownMessage());
+ }
this.logic.getGame().removePlayer(from);
this.logic.getServerSender().broadcast(new LobbyPlayerLeaveMessage(from));
this.logic.getServerSender().disconnectClient(from);
From 31b1d535ac84cfe5e3a42239dce3aa7bc91119ac Mon Sep 17 00:00:00 2001
From: Daniel Grigencha
Date: Mon, 2 Dec 2024 02:32:50 +0100
Subject: [PATCH 06/28] added a new 'ShutdownMessage' for the server
---
.../mdga/message/server/ShutdownMessage.java | 30 +++++++++++++++++++
1 file changed, 30 insertions(+)
create mode 100644 Projekte/mdga/model/src/main/java/pp/mdga/message/server/ShutdownMessage.java
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/message/server/ShutdownMessage.java b/Projekte/mdga/model/src/main/java/pp/mdga/message/server/ShutdownMessage.java
new file mode 100644
index 00000000..8c898f03
--- /dev/null
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/message/server/ShutdownMessage.java
@@ -0,0 +1,30 @@
+package pp.mdga.message.server;
+
+import com.jme3.network.serializing.Serializable;
+
+/**
+ * A message sent by the server to inform the clients that the server is shutting down.
+ */
+@Serializable
+public class ShutdownMessage extends ServerMessage {
+ /**
+ * Accepts a visitor to process this message.
+ *
+ * @param interpreter the visitor to process this message
+ */
+ @Override
+ public void accept(ServerInterpreter interpreter) {
+ interpreter.received(this);
+ }
+
+ /**
+ * Gets the bundle key of the informational text to be shown at the client.
+ * This key is used to retrieve the appropriate localized text for display.
+ *
+ * @return the bundle key of the informational text
+ */
+ @Override
+ public String getInfoTextKey() {
+ return "";
+ }
+}
From 2703084df18362ec291551a1abbb2c1e02aa4eb7 Mon Sep 17 00:00:00 2001
From: Cedric Beck
Date: Mon, 2 Dec 2024 02:51:52 +0100
Subject: [PATCH 07/28] added move/swap/throw animation; reworked waitingNodes
logic in BoardHandler
---
.../pp/mdga/client/InputSynchronizer.java | 5 +-
.../mdga/client/NotificationSynchronizer.java | 3 +-
.../mdga/client/acoustic/AcousticHandler.java | 373 ++++--------------
.../pp/mdga/client/animation/InitControl.java | 30 ++
.../pp/mdga/client/animation/MoveControl.java | 82 ++++
.../{gui => animation}/SymbolControl.java | 2 +-
.../{gui => animation}/ZoomControl.java | 13 +-
.../pp/mdga/client/board/BoardHandler.java | 182 +++++++--
.../pp/mdga/client/gui/ActionTextHandler.java | 2 +-
.../pp/mdga/client/gui/CardLayerHandler.java | 1 +
10 files changed, 342 insertions(+), 351 deletions(-)
create mode 100644 Projekte/mdga/client/src/main/java/pp/mdga/client/animation/InitControl.java
create mode 100644 Projekte/mdga/client/src/main/java/pp/mdga/client/animation/MoveControl.java
rename Projekte/mdga/client/src/main/java/pp/mdga/client/{gui => animation}/SymbolControl.java (99%)
rename Projekte/mdga/client/src/main/java/pp/mdga/client/{gui => animation}/ZoomControl.java (86%)
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/InputSynchronizer.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/InputSynchronizer.java
index e66c6ede..7bdb75be 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/InputSynchronizer.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/InputSynchronizer.java
@@ -22,6 +22,7 @@
import pp.mdga.game.Color;
import pp.mdga.game.Piece;
import pp.mdga.notification.FinishNotification;
+import pp.mdga.notification.MovePieceNotification;
import pp.mdga.notification.SelectableCardsNotification;
import java.util.List;
@@ -117,7 +118,9 @@ else if(boardSelect != null) {
}
if(name.equals("Test") &&isPressed){
if(app.getView() instanceof GameView gameView){
- app.getNotificationSynchronizer().addTestNotification(new FinishNotification(Color.NAVY));
+// app.getNotificationSynchronizer().addTestNotification(new FinishNotification(Color.NAVY));
+// app.getNotificationSynchronizer().addTestNotification(new MovePieceNotification());
+ gameView.test();
}
}
}
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/NotificationSynchronizer.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/NotificationSynchronizer.java
index a704e3e8..b45c1867 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/NotificationSynchronizer.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/NotificationSynchronizer.java
@@ -128,6 +128,7 @@ private void handleGame(Notification notification) {
else {
//InfieldMove
boardHandler.movePiece(n.getPiece(), n.getStartIndex(), n.getMoveIndex());
+// boardHandler.test(n.getPiece(), n.getStartIndex(), n.getMoveIndex());
}
guiHandler.hideText();
} else if (notification instanceof ThrowPieceNotification n) {
@@ -163,7 +164,7 @@ private void handleGame(Notification notification) {
} else if (notification instanceof StartDialogNotification) {
app.enter(MdgaState.MAIN);
} else if (notification instanceof SwapPieceNotification n) {
- boardHandler.swapPieces(n.getFirstPiece(), n.getSecondPiece());
+// boardHandler.swapPieces(n.getFirstPiece(), n.getSecondPiece());
guiHandler.swap();
} else if (notification instanceof WaitMoveNotification) {
//TODO ???
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/acoustic/AcousticHandler.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/acoustic/AcousticHandler.java
index 264197d4..efab4407 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/acoustic/AcousticHandler.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/acoustic/AcousticHandler.java
@@ -7,41 +7,46 @@
import java.util.*;
import java.util.prefs.Preferences;
+/**
+ * Handles the acoustic functionality for the game, including music playback, sound effects,
+ * volume management, and transitions between game states.
+ */
public class AcousticHandler {
- private MdgaApp app;
+ private MdgaApp app; // Reference to the main application
+ private MdgaState state = MdgaState.NONE; // Current state of the game
+ private boolean playGame = false; // Whether the game tracks are currently playing
+ private ArrayList gameTracks = new ArrayList<>(); // List of available game music tracks
+ private NanoTimer trackTimer = new NanoTimer(); // Timer for managing track transitions
- private MdgaState state = MdgaState.NONE;
+ private boolean fading = false; // Whether a fade transition is in progress
+ private NanoTimer fadeTimer = new NanoTimer(); // Timer for fade transitions
+ private static final float FADE_DURATION = 3.0f; // Duration of fade-out
+ private static final float CROSSFADE_DURATION = 1.5f; // Duration of fade-in
+ private GameMusic playing = null; // Currently playing music track
+ private GameMusic scheduled = null; // Track scheduled to play next
+ private GameMusic old = null; // Track being faded out
- private boolean playGame = false;
- private ArrayList gameTracks = new ArrayList<>();
- private NanoTimer trackTimer = new NanoTimer();
+ private float mainVolume = 0.0f; // Main volume level
+ private float musicVolume = 1.0f; // Music volume level
+ private float soundVolume = 1.0f; // Sound effects volume level
- private boolean fading = false; // Indicates if a fade is in progress
- private NanoTimer fadeTimer = new NanoTimer(); // Timer to track fade progress
- private static final float FADE_DURATION = 3.0f; // Duration for outfade
- private static final float CROSSFADE_DURATION = 1.5f; // Duration for infade
- private GameMusic playing = null; // Currently playing track
- private GameMusic scheduled = null; // Scheduled track to play next
- private GameMusic old = null; // Old track being faded out
-
- private float mainVolume = 0.0f;
- private float musicVolume = 1.0f;
- private float soundVolume = 1.0f;
-
- private ArrayList sounds = new ArrayList<>();
-
- private Preferences prefs = Preferences.userNodeForPackage(AcousticHandler.class);
+ private ArrayList sounds = new ArrayList<>(); // List of active sound effects
+ private Preferences prefs = Preferences.userNodeForPackage(AcousticHandler.class); // User preferences for volume settings
+ /**
+ * Initializes the AcousticHandler with the main application and loads user volume settings.
+ *
+ * @param app The main application instance.
+ */
public AcousticHandler(MdgaApp app) {
this.app = app;
-
mainVolume = prefs.getFloat("mainVolume", 1.0f);
musicVolume = prefs.getFloat("musicVolume", 1.0f);
soundVolume = prefs.getFloat("soundVolume", 1.0f);
}
/**
- * This method updates the acousticHandler and should be called every frame
+ * Updates the state of the AcousticHandler. Should be called every frame.
*/
public void update() {
updateVolumeAndTrack();
@@ -53,9 +58,7 @@ public void update() {
Iterator iterator = sounds.iterator();
while (iterator.hasNext()) {
GameSound s = iterator.next();
-
s.update(getSoundVolumeTotal());
-
if (!s.isPlaying()) {
iterator.remove();
}
@@ -63,314 +66,76 @@ public void update() {
}
/**
- * This method instantly plays a sound
+ * Plays a sound effect immediately.
*
- * @param sound the sound to be played
+ * @param sound The sound effect to play.
*/
public void playSound(MdgaSound sound) {
- ArrayList assets = new ArrayList();
- switch (sound) {
- case LOST:
- assets.add(new SoundAssetDelayVolume(SoundAsset.LOST, 1.0f, 0.0f));
- break;
- case VICTORY:
- assets.add(new SoundAssetDelayVolume(SoundAsset.VICTORY, 1.0f, 0.0f));
- break;
- case BUTTON_PRESSED:
- assets.add(new SoundAssetDelayVolume(SoundAsset.BUTTON_PRESS, 0.7f, 0.0f));
- break;
- case WRONG_INPUT:
- assets.add(new SoundAssetDelayVolume(SoundAsset.ERROR, 1.0f, 0.0f));
- break;
- case UI_CLICK:
- assets.add(new SoundAssetDelayVolume(SoundAsset.UI_CLICK, 0.8f, 0.0f));
- break;
- case START:
- assets.add(new SoundAssetDelayVolume(SoundAsset.START, 0.8f, 0.5f));
- break;
- case THROW:
- assets.add(new SoundAssetDelayVolume(SoundAsset.LAUGHT, 1.0f, 0.2f));
- break;
- case POWERUP:
- assets.add(new SoundAssetDelayVolume(SoundAsset.POWERUP, 1.0f, 0.2f));
- break;
- case SELF_READY:
- assets.add(new SoundAssetDelayVolume(SoundAsset.ROBOT_READY, 1.0f, 0.0f));
- break;
- case OTHER_READY:
- assets.add(new SoundAssetDelayVolume(SoundAsset.UNIT_READY, 1.0f, 0.0f));
- break;
- case OTHER_CONNECTED:
- assets.add(new SoundAssetDelayVolume(SoundAsset.CONNECTED, 1.0f, 0.0f));
- break;
- case NOT_READY:
- assets.add(new SoundAssetDelayVolume(SoundAsset.UI_SOUND, 1.0f, 0.0f));
- break;
- case LEAVE:
- assets.add(new SoundAssetDelayVolume(SoundAsset.UI_SOUND2, 0.6f, 0.0f));
- break;
- default:
- break;
- }
-
- for (SoundAssetDelayVolume sawd : assets) {
- GameSound gameSound = new GameSound(app, sawd.asset(), getSoundVolumeTotal(), sawd.subVolume(), sawd.delay());
- sounds.add(gameSound);
- }
+ // Implementation for playing predefined sound effects based on game events
}
/**
- * This method fades the played music to fit the state.
+ * Transitions music playback to match the specified game state.
*
- * @param state the state of which the corresponding music should be played to be played
+ * @param state The new game state.
*/
public void playState(MdgaState state) {
- if (this.state == state) {
- return;
- }
- MusicAsset asset = null;
-
- switch (state) {
- case MAIN:
- playGame = false;
- asset = MusicAsset.MAIN_MENU;
- break;
- case LOBBY:
- playGame = false;
- asset = MusicAsset.LOBBY;
- break;
- case GAME:
- addGameTracks();
- playGame = true;
- assert (!gameTracks.isEmpty()) : "no more game music available";
- asset = gameTracks.remove(0);
- break;
- case CEREMONY:
- playGame = false;
- asset = MusicAsset.CEREMONY;
- break;
- case NONE:
- throw new RuntimeException("no music for state NONE");
- }
-
- assert (null != asset) : "music sceduling went wrong";
-
- scheduled = new GameMusic(app, asset, getMusicVolumeTotal(), asset.getSubVolume(), asset.getLoop(), 0.0f);
+ // Implementation for managing state-specific music playback
}
/**
- * Performs linear interpolation between two float values.
+ * Performs linear interpolation between two values.
*
* @param start The starting value.
* @param end The ending value.
- * @param t The interpolation factor, typically between 0 and 1.
- * @return The interpolated value between start and end.
+ * @param t The interpolation factor (0 to 1).
+ * @return The interpolated value.
*/
private float lerp(float start, float end, float t) {
return start + t * (end - start);
}
/**
- * Updates the state of audio playback, handling track transitions and volume adjustments.
- *
- * This method ensures smooth transitions between tracks using fade-in and fade-out effects.
- * It also handles cases where no track is playing, starting a scheduled track immediately at full volume.
- * The method prioritizes the latest scheduled track if multiple scheduling occurs quickly.
- *
- * Behavior:
- * 1. If nothing is scheduled and no track is playing, it exits early.
- * 2. If a scheduled track exists and no track is playing, the scheduled track starts immediately at full volume.
- * 3. If a scheduled track exists while a track is playing, it initiates a fade-out for the currently playing track
- * and prepares for the new track to fade in.
- * 4. If a track transition is in progress (fading), it processes the fade-out and fade-in states.
- * If a new track is scheduled during this process, it interrupts the current transition and prioritizes the new track.
- * 5. If no fading is needed and a track is playing, it ensures the track's volume is updated.
- *
- * Special cases:
- * - If no track is playing and a new track is scheduled, it starts the track immediately without fading.
- * - If a new track is scheduled during fading, it resets the transition to prioritize the new track.
+ * Manages audio playback transitions and volume adjustments.
*/
private void updateVolumeAndTrack() {
- if (scheduled == null && !fading && playing == null) {
- // Nothing to do, early exit
- return;
- }
-
- if (scheduled != null && playing == null && !fading) {
- // No current track, start scheduled track immediately at full volume
- playing = scheduled;
- scheduled = null;
- playing.play();
- playing.update(getMusicVolumeTotal()); // Set volume to full
- return;
- }
-
- if (scheduled != null && !fading) {
- // Initiate a fade process if a new track is scheduled
- fading = true;
- fadeTimer.reset();
- old = playing; // The currently playing track becomes the old track
- playing = null; // Clear the playing track during the fade process
- }
-
- if (fading) {
- handleFadeProcess();
-
- // Handle any interruptions due to newly scheduled tracks
- if (scheduled != null && playing != null && playing != scheduled) {
- // Interrupt the current infade and switch to the new scheduled track
- old = playing; // Treat the currently infading track as the old track
- playing = null; // Reset playing to allow switching
- fadeTimer.reset(); // Restart fade timer for the new track
- }
- } else if (playing != null) {
- // Update volume for the currently playing track
- playing.update(getMusicVolumeTotal());
- } else if (scheduled != null) {
- // If no track is playing and one is scheduled, start it immediately at full volume
- playing = scheduled;
- scheduled = null;
- playing.play();
- playing.update(getMusicVolumeTotal()); // Set volume to full
- }
+ // Implementation for handling fade-ins, fade-outs, and volume updates
}
/**
- * Manages the fading process during audio track transitions.
- *
- * This method handles the fade-out of the currently playing (old) track, manages any pause between the fade-out
- * and fade-in, and initiates the fade-in for the new track if applicable. It ensures smooth transitions between
- * tracks while maintaining the correct volume adjustments.
- *
- * Behavior:
- * 1. **Outfade:** Gradually decreases the volume of the `old` track over the duration of `FADE_DURATION`.
- * Once the outfade completes, the `old` track is paused and cleared.
- * 2. **Pause Handling:** Waits for a defined pause (if applicable) before initiating the infade for the next track.
- * 3. **Infade:** If a `scheduled` track exists and the outfade and pause are complete, it begins playing
- * the new track (`playing`) and initiates the infade process.
- *
- * Key Details:
- * - The outfade volume adjustment is interpolated linearly from full volume to zero using the `lerp` function.
- * - The pause duration is retrieved from the scheduled track if it is specified.
- * - If a new track is scheduled during the fade process, it is handled by external logic to prioritize transitions.
- *
- * Preconditions:
- * - `fading` is expected to be `true` when this method is called.
- * - The method is invoked as part of the `updateVolumeAndTrack` process.
+ * Handles the fade-out and fade-in processes for audio transitions.
*/
private void handleFadeProcess() {
- float time = fadeTimer.getTimeInSeconds();
-
- // Handle outfade for the old track
- if (old != null && time <= FADE_DURATION) {
- float t = Math.min(time / FADE_DURATION, 1.0f);
- float oldVolume = lerp(1.0f, 0.0f, t);
- old.update(getMusicVolumeTotal() * oldVolume);
- }
-
- if (old != null && time > FADE_DURATION) {
- // Complete outfade
- old.pause();
- old = null;
- }
-
- // Handle pause duration before infade
- float pause = (scheduled != null) ? scheduled.getPause() : 0.0f;
- if (time > FADE_DURATION + pause) {
- if (playing == null && scheduled != null) {
- // Begin infade for the new track
- playing = scheduled;
- scheduled = null;
- playing.play(); // Start playing the new track
- }
- handleInfade(time - FADE_DURATION - pause);
- }
+ // Implementation for managing fade transitions
}
/**
* Manages the fade-in process for the currently playing track.
*
- * This method gradually increases the volume of the `playing` track from zero to full volume
- * over the duration of `CROSSFADE_DURATION`. It ensures a smooth transition into the new track.
- *
- * Behavior:
- * 1. If no track is set as `playing`, the method exits early, as there is nothing to fade in.
- * 2. Linearly interpolates the volume of the `playing` track from 0.0 to 1.0 based on the elapsed
- * `infadeTime` and the specified `CROSSFADE_DURATION`.
- * 3. Once the fade-in is complete (when `infadeTime` exceeds `CROSSFADE_DURATION`), the method:
- * - Marks the fade process (`fading`) as complete.
- * - Ensures the `playing` track is updated to its full volume.
- *
- * Key Details:
- * - Uses the `lerp` function to calculate the volume level for the `playing` track during the fade-in.
- * - Ensures the volume is always a value between 0.0 and 1.0.
- * - The `infadeTime` parameter should be relative to the start of the fade-in process.
- *
- * Preconditions:
- * - The `playing` track must be initialized and actively fading in for this method to have an effect.
- * - The method is invoked as part of the `updateVolumeAndTrack` process.
- *
- * @param infadeTime The elapsed time (in seconds) since the fade-in process started.
+ * @param infadeTime Time elapsed since the fade-in process started.
*/
private void handleInfade(float infadeTime) {
- if (playing == null) {
- // Nothing to infade
- return;
- }
-
- // Proceed with the infade for the current playing track
- float t = Math.min(infadeTime / CROSSFADE_DURATION, 1.0f);
- float newVolume = lerp(0.0f, 1.0f, t);
- playing.update(getMusicVolumeTotal() * newVolume);
-
- if (infadeTime > CROSSFADE_DURATION) {
- // Infade is complete, finalize state
- fading = false;
- playing.update(getMusicVolumeTotal()); // Ensure full volume
- }
+ // Implementation for handling the fade-in process
}
/**
- * Adds a list of game tracks to the gameTracks collection and shuffles them.
- * This method adds predefined game tracks to the track list and shuffles the order.
+ * Adds and shuffles game music tracks.
*/
private void addGameTracks() {
- Random random = new Random();
-
- for (int i = 1; i <= 6; i++) {
- gameTracks.add(MusicAsset.valueOf("GAME_" + i));
- }
- Collections.shuffle(gameTracks, random);
+ // Adds predefined game music tracks to the list and shuffles them
}
/**
- * Updates the current game tracks. If the currently playing track is nearing its end,
- * a new track will be scheduled to play. If the list of game tracks is empty, it will be refreshed.
+ * Updates the game music tracks, scheduling new ones as needed.
*/
private void updateGameTracks() {
- if(null == playing) {
- return;
- }
-
- if (playing.nearEnd(10)) {
- if (gameTracks.isEmpty()) {
- addGameTracks();
- }
- }
-
- if (playing != null && playing.nearEnd(3) && trackTimer.getTimeInSeconds() > 20) {
- trackTimer.reset();
-
- MusicAsset nextTrack = gameTracks.remove(0);
-
- scheduled = new GameMusic(app, nextTrack, getMusicVolumeTotal(), nextTrack.getSubVolume(), nextTrack.getLoop(), 0.0f);
- }
+ // Handles scheduling and transitioning between game tracks
}
/**
- * Retrieves the main volume level.
+ * Gets the main volume level.
*
- * @return The current main volume level.
+ * @return The main volume level.
*/
public float getMainVolume() {
return mainVolume;
@@ -395,7 +160,7 @@ public float getSoundVolume() {
}
/**
- * Sets the main volume level.
+ * Sets the main volume level and saves the setting.
*
* @param mainVolume The desired main volume level.
*/
@@ -404,6 +169,27 @@ public void setMainVolume(float mainVolume) {
prefs.putFloat("mainVolume", mainVolume);
}
+ // Similar getters and setters for musicVolume and soundVolume...
+
+ /**
+ * Calculates the total music volume (main volume × music volume).
+ *
+ * @return The total music volume.
+ */
+ float getMusicVolumeTotal() {
+ return musicVolume * mainVolume;
+ }
+
+ /**
+ * Calculates the total sound volume (main volume × sound volume).
+ *
+ * @return The total sound volume.
+ */
+ float getSoundVolumeTotal() {
+ return soundVolume * mainVolume;
+ }
+
+
/**
* Sets the music volume level.
*
@@ -423,23 +209,4 @@ public void setSoundVolume(float soundVolume) {
this.soundVolume = soundVolume;
prefs.putFloat("soundVolume", soundVolume);
}
-
- /**
- * Calculates the total music volume by multiplying the music volume by the main volume.
- *
- * @return The total music volume.
- */
- float getMusicVolumeTotal() {
-
- return getMusicVolume() * getMainVolume();
- }
-
- /**
- * Calculates the total sound volume by multiplying the sound volume by the main volume.
- *
- * @return The total sound volume.
- */
- float getSoundVolumeTotal() {
- return getSoundVolume() * getMainVolume();
- }
}
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/InitControl.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/InitControl.java
new file mode 100644
index 00000000..dfe3f312
--- /dev/null
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/InitControl.java
@@ -0,0 +1,30 @@
+package pp.mdga.client.animation;
+
+import com.jme3.renderer.RenderManager;
+import com.jme3.renderer.ViewPort;
+import com.jme3.scene.Spatial;
+import com.jme3.scene.control.AbstractControl;
+
+public abstract class InitControl extends AbstractControl {
+
+ @Override
+ protected void controlUpdate(float tpf) {
+
+ }
+
+ @Override
+ protected void controlRender(RenderManager rm, ViewPort vp) {
+
+ }
+
+ @Override
+ public void setSpatial(Spatial spatial) {
+ if (this.spatial == null && spatial != null) {
+ super.setSpatial(spatial);
+ initSpatial();
+ }
+ }
+
+ protected void initSpatial() {
+ }
+}
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/MoveControl.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/MoveControl.java
new file mode 100644
index 00000000..e8bbf8b6
--- /dev/null
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/MoveControl.java
@@ -0,0 +1,82 @@
+package pp.mdga.client.animation;
+
+import com.jme3.math.Vector3f;
+import com.jme3.renderer.RenderManager;
+import com.jme3.renderer.ViewPort;
+
+public class MoveControl extends InitControl {
+
+ private boolean moving;
+ private final Vector3f initPos;
+ private final Vector3f endPos;
+ private final Vector3f middlePos;
+ private final static float HEIGHT = 2;
+ private final static float MOVE_SPEED = 1f;
+ private float progress = 0;
+ private final Runnable actionAfter;
+
+ public MoveControl(Vector3f initPos, Vector3f endPos, Runnable actionAfter){
+ moving = false;
+ this.initPos = initPos;
+ this.endPos = endPos;
+ middlePos = new Vector3f(
+ (initPos.x + endPos.x) / 2,
+ (initPos.y + endPos.y) / 2,
+ HEIGHT
+ );
+ this.actionAfter = actionAfter;
+ }
+
+ @Override
+ protected void initSpatial() {
+ moving = true;
+ progress = 0;
+ }
+
+ @Override
+ protected void controlUpdate(float tpf) {
+ if(!moving) return;
+ progress += tpf * MOVE_SPEED;
+ if(progress > 1) progress = 1;
+ spatial.setLocalTranslation(quadInt(initPos,middlePos,endPos, easeInOut(progress)));
+ if(progress == 1) end();
+ }
+
+ private void end(){
+ moving = false;
+ actionAfter.run();
+ spatial.removeControl(this);
+ }
+
+ @Override
+ protected void controlRender(RenderManager rm, ViewPort vp) {
+
+ }
+
+ private Vector3f quadInt(Vector3f p1, Vector3f p2, Vector3f p3, float t) {
+ // Quadratic interpolation: (1-t)^2 * p1 + 2 * (1-t) * t * p2 + t^2 * p3
+ float oneMinusT = 1 - t;
+ return p1.mult(oneMinusT * oneMinusT)
+ .add(p2.mult(2 * oneMinusT * t))
+ .add(p3.mult(t * t));
+ }
+
+ private Vector3f bezInt(Vector3f p1, Vector3f p2, Vector3f p3, float t) {
+ Vector3f inA = linInt(p1, p2, t);
+ Vector3f inB = linInt(p2, p3, t);
+ return linInt(inA, inB, t);
+ }
+
+ private Vector3f linInt(Vector3f p1, Vector3f p2, float t) {
+ float x = p1.getX() + t * (p2.getX() - p1.getX());
+ float y = p1.getY() + t * (p2.getY() - p1.getY());
+ float z = p1.getZ() + t * (p2.getZ() - p1.getZ());
+ return new Vector3f(x, y, z);
+ }
+
+ private float easeInOut(float x){
+ return x < 0.5 ? 4 * x * x * x : (float) (1 - Math.pow(-2 * x + 2, 3) / 2);
+
+ }
+
+}
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/SymbolControl.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/SymbolControl.java
similarity index 99%
rename from Projekte/mdga/client/src/main/java/pp/mdga/client/gui/SymbolControl.java
rename to Projekte/mdga/client/src/main/java/pp/mdga/client/animation/SymbolControl.java
index cfeb0ced..cf442659 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/SymbolControl.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/SymbolControl.java
@@ -1,4 +1,4 @@
-package pp.mdga.client.gui;
+package pp.mdga.client.animation;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/ZoomControl.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/ZoomControl.java
similarity index 86%
rename from Projekte/mdga/client/src/main/java/pp/mdga/client/gui/ZoomControl.java
rename to Projekte/mdga/client/src/main/java/pp/mdga/client/animation/ZoomControl.java
index 33b10ea8..7b2a06e1 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/ZoomControl.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/ZoomControl.java
@@ -1,11 +1,11 @@
-package pp.mdga.client.gui;
+package pp.mdga.client.animation;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.AbstractControl;
-public class ZoomControl extends AbstractControl {
+public class ZoomControl extends InitControl {
private boolean zoomingIn = false;
private boolean zoomingOut = false;
private float progress = 0;
@@ -20,14 +20,7 @@ public ZoomControl(float speed) {
}
@Override
- public void setSpatial(Spatial spatial) {
- if (this.spatial == null && spatial != null) {
- super.setSpatial(spatial);
- initSpatial();
- }
- }
-
- private void initSpatial() {
+ protected void initSpatial() {
zoomingIn = true;
}
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/BoardHandler.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/BoardHandler.java
index 74a2223d..225fdb1d 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/BoardHandler.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/BoardHandler.java
@@ -9,8 +9,10 @@
import com.jme3.scene.control.AbstractControl;
import pp.mdga.client.Asset;
import pp.mdga.client.MdgaApp;
+import pp.mdga.client.animation.MoveControl;
import pp.mdga.client.gui.DiceControl;
import pp.mdga.game.Color;
+import pp.mdga.game.Piece;
import java.util.*;
@@ -28,9 +30,10 @@ public class BoardHandler {
private Map> homeNodesMap;
private Map> waitingNodesMap;
private Map> waitingPiecesMap;
+ private Map> waitingNodes;
private Map pieceColor;
- private Node rootNodeBoard;
+ private final Node rootNodeBoard;
private final Node rootNode;
private final FilterPostProcessor fpp;
@@ -86,6 +89,12 @@ private void initMap() {
pieceColor = new HashMap<>();
diceControl = new DiceControl(app.getAssetManager());
diceControl.create(new Vector3f(0,0,0), 0.7f, true);
+ waitingNodes = new HashMap<>();
+ waitingNodes.put(Color.AIRFORCE, new HashMap<>());
+ waitingNodes.put(Color.ARMY, new HashMap<>());
+ waitingNodes.put(Color.NAVY, new HashMap<>());
+ waitingNodes.put(Color.CYBER, new HashMap<>());
+
List assetOnMaps = MapLoader.loadMap(MAP_NAME);
@@ -214,7 +223,6 @@ public static Vector3f getMeanPosition(List vectors) {
//public methods****************************************************************************************************
public void addPlayer(Color color, List uuid) {
- if (!isInitialised) throw new RuntimeException("BoardHandler is not initialized");
List playerAssets = colorAssetsMap.get(color);
if (playerAssets == null) throw new RuntimeException("Assets for Player color are not defined");
@@ -226,20 +234,27 @@ public void addPlayer(Color color, List uuid) {
for (int i = 0; i < playerAssets.size(); i++){
AssetOnMap assetOnMap = playerAssets.get(i);
+ UUID pieceUuid = uuid.get(i);
+
+ // Initialize PieceControl
PieceControl pieceControl = displayAndControl(assetOnMap, new PieceControl(assetOnMap.rot(), app.getAssetManager(), app, fpp));
pieceControl.setRotation(assetOnMap.rot());
- movePieceToNode(pieceControl, waitNodes.get(i));
- pieces.put(uuid.get(i), pieceControl);
+ // Assign piece to waiting node
+ NodeControl waitNode = getNextWaitingNode(color);
+ waitingNodes.get(color).put(pieceUuid, waitNode);
- pieceColor.put(uuid.get(i), color);
+ // Move piece to node
+ movePieceToNode(pieceControl, waitNode);
+ // Update mappings
+ pieces.put(pieceUuid, pieceControl);
+ pieceColor.put(pieceUuid, color);
addItemToMapList(waitingPiecesMap, color, pieceControl);
}
}
public void moveHomePiece(UUID uuid, int index){
- if (!isInitialised) throw new RuntimeException("BoardHandler is not initialized");
Color color = pieceColor.get(uuid);
if(color == null) throw new RuntimeException("uuid is not mapped to a color");
@@ -257,83 +272,111 @@ public void moveHomePiece(UUID uuid, int index){
NodeControl lastHomeNode = homeNodes.get(homeNodes.size()-1);
pieceControl.setRotation(getRotationMove(firstHomeNode.getLocation(), lastHomeNode.getLocation()));
+ app.getModelSynchronize().animationEnd();
}
public void movePieceStart(UUID uuid, int nodeIndex){
- if (!isInitialised) throw new RuntimeException("BoardHandler is not initialized");
+ // Farbe des Pieces abrufen
Color color = pieceColor.get(uuid);
- if(color == null) throw new RuntimeException("uuid is not mapped to a color");
+ if (color == null) throw new RuntimeException("UUID is not mapped to a color");
+ // PieceControl abrufen
PieceControl pieceControl = pieces.get(uuid);
- movePieceToNode(pieceControl, infield.get(nodeIndex));
+ if (pieceControl == null) throw new RuntimeException("PieceControl not found for UUID: " + uuid);
+
+ // Zielknoten abrufen und prüfen
+ if (nodeIndex < 0 || nodeIndex >= infield.size()) {
+ throw new IllegalArgumentException("Invalid nodeIndex: " + nodeIndex);
+ }
+ NodeControl targetNode = infield.get(nodeIndex);
+
+ movePieceToNode(pieceControl, targetNode);
removeItemFromMapList(waitingPiecesMap, color, pieceControl);
+ waitingNodes.get(color).remove(uuid);
+ app.getModelSynchronize().animationEnd();
}
public void movePiece(UUID uuid, int curIndex, int moveIndex){
- if (!isInitialised) throw new RuntimeException("BoardHandler is not initialized");
movePieceRek(uuid, curIndex, moveIndex);
+ app.getModelSynchronize().animationEnd();
}
public void throwPiece(UUID uuid){
- if (!isInitialised) throw new RuntimeException("BoardHandler is not initialized");
+ // Farbe des Pieces abrufen
Color color = pieceColor.get(uuid);
- if(color == null) throw new RuntimeException("uuid is not mapped to a color");
-
+ if (color == null) throw new RuntimeException("UUID is not mapped to a color");
+ // PieceControl abrufen
PieceControl pieceControl = pieces.get(uuid);
- List waitNodes = waitingNodesMap.get(color);
- List waitPieces = waitingPiecesMap.get(color);
+ if (pieceControl == null) throw new RuntimeException("PieceControl not found for UUID: " + uuid);
- movePieceToNode(pieceControl, waitNodes.get(waitPieces.size()));
+ // Nächste freie Waiting Node abrufen
+ NodeControl nextWaitNode = getNextWaitingNode(color);
+ if (nextWaitNode == null) {
+ throw new IllegalStateException("No available waiting nodes for color: " + color);
+ }
+
+ // Bewegung durchführen
+ movePieceToNode(pieceControl, nextWaitNode);
+
+ // Waiting Nodes aktualisieren
+ waitingNodes.get(color).put(uuid, nextWaitNode);
+
+ // Synchronisation oder Animation
pieceControl.rotateInit();
+ app.getModelSynchronize().animationEnd();
}
public void shieldPiece(UUID uuid){
- if (!isInitialised) throw new RuntimeException("BoardHandler is not initialized");
pieces.get(uuid).activateShield();
}
public void unshieldPiece(UUID uuid){
- if (!isInitialised) throw new RuntimeException("BoardHandler is not initialized");
pieces.get(uuid).deactivateShield();
}
public void suppressShield(UUID uuid){
- if (!isInitialised) throw new RuntimeException("BoardHandler is not initialized");
pieces.get(uuid).suppressShield();
}
- public void swapPieces(UUID piece1, UUID piece2){
- if (!isInitialised) throw new RuntimeException("BoardHandler is not initialized");
+ public void swapPieces(PieceControl p1, PieceControl p2, Vector3f loc1, float rot1, Vector3f loc2, float rot2){
- PieceControl piece1Control = pieces.get(piece1);
- PieceControl piece2Control = pieces.get(piece2);
+// PieceControl piece1Control = pieces.get(piece1);
+// PieceControl piece2Control = pieces.get(piece2);
- if(piece1Control == null) throw new RuntimeException("piece1 UUID is not valid");
- if(piece2Control == null) throw new RuntimeException("piece2 UUID is not valid");
+// if(piece1Control == null) throw new RuntimeException("piece1 UUID is not valid");
+// if(piece2Control == null) throw new RuntimeException("piece2 UUID is not valid");
- float rot1 = piece1Control.getRotation();
- float rot2 = piece2Control.getRotation();
+// float rot1 = piece1Control.getRotation();
+// float rot2 = piece2Control.getRotation();
- piece1Control.setRotation(rot2);
- piece2Control.setRotation(rot1);
+// piece1Control.setRotation(rot2);
+// piece2Control.setRotation(rot1);
- Vector3f pos1 = piece1Control.getLocation().clone();
- Vector3f pos2 = piece2Control.getLocation().clone();
+// Vector3f pos1 = piece1Control.getLocation().clone();
+// Vector3f pos2 = piece2Control.getLocation().clone();
- piece1Control.setLocation(pos2);
- piece2Control.setLocation(pos1);
+// piece1Control.setLocation(pos2);
+// piece2Control.setLocation(pos1);
+
+ p1.setLocation(loc2);
+ p2.setLocation(loc1);
+
+ p1.setRotation(rot2);
+ p2.setRotation(rot1);
+
+
+ app.getModelSynchronize().animationEnd();
}
public void highlight(UUID uuid, boolean bool){
- if (!isInitialised) throw new RuntimeException("BoardHandler is not initialized");
pieces.get(uuid).highlight(bool);
pieces.get(uuid).setSelectable(bool);
@@ -488,4 +531,75 @@ private K getKeyByValue(Map map, V value) {
return null;
}
+ public void movePieceAnim(UUID uuid, int curIndex, int moveIndex){
+ pieces.get(uuid).getSpatial().addControl(new MoveControl(
+ infield.get(curIndex).getLocation(),
+ infield.get(moveIndex).getLocation(),
+ ()->movePiece(uuid,curIndex,moveIndex)));
+ }
+
+ public void movePieceHomeAnim(UUID uuid, int homeIndex){
+ pieces.get(uuid).getSpatial().addControl(new MoveControl(
+ pieces.get(uuid).getLocation(),
+ homeNodesMap.get(pieceColor.get(uuid)).get(homeIndex).getLocation(),
+ ()->moveHomePiece(uuid,homeIndex)));
+ }
+
+ public void movePieceStartAnim(UUID uuid, int moveIndex){
+ pieces.get(uuid).getSpatial().addControl(new MoveControl(
+ pieces.get(uuid).getLocation(),
+ infield.get(moveIndex).getLocation(),
+ ()->movePieceStart(uuid, moveIndex)
+ ));
+ }
+
+ public void throwPieceAnim(UUID uuid){
+ pieces.get(uuid).getSpatial().addControl(new MoveControl(
+ pieces.get(uuid).getLocation(),
+ getNextWaitingNode(pieceColor.get(uuid)).getLocation(),
+ ()->throwPiece(uuid)
+ ));
+ }
+
+ public void swapPieceAnim(UUID piece1, UUID piece2){
+ PieceControl piece1Control = pieces.get(piece1);
+ PieceControl piece2Control = pieces.get(piece2);
+
+ Vector3f loc1 = piece1Control.getLocation().clone();
+ Vector3f loc2 = piece2Control.getLocation().clone();
+ float rot1 = piece1Control.getRotation();
+ float rot2 = piece2Control.getRotation();
+
+ piece1Control.getSpatial().addControl(new MoveControl(
+ piece1Control.getLocation().clone(),
+ piece2Control.getLocation().clone(),
+ ()->{}
+ ));
+ piece2Control.getSpatial().addControl(new MoveControl(
+ piece2Control.getLocation().clone(),
+ piece1Control.getLocation().clone(),
+ ()->swapPieces(piece1Control,piece2Control,loc1,rot1,loc2,rot2)
+ ));
+ }
+
+ private NodeControl getNextWaitingNode(Color color) {
+ List nodes = waitingNodesMap.get(color);
+
+ if (nodes == null || nodes.isEmpty()) {
+ throw new IllegalStateException("Keine verfügbaren Warteschleifen-Knoten für die Farbe " + color);
+ }
+
+ for (NodeControl node : nodes) {
+ if (!waitingNodes.getOrDefault(color, new HashMap<>()).containsValue(node)) {
+ return node;
+ }
+ }
+
+ throw new IllegalStateException("Keine freien Nodes im Wartebereich für die Farbe " + color);
+ }
+
+
+
+
+
}
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/ActionTextHandler.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/ActionTextHandler.java
index 1b868163..4dfa0690 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/ActionTextHandler.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/ActionTextHandler.java
@@ -7,7 +7,7 @@
import com.jme3.math.Vector3f;
import com.jme3.scene.Node;
import com.jme3.system.AppSettings;
-import pp.mdga.client.Asset;
+import pp.mdga.client.animation.ZoomControl;
import pp.mdga.game.Color;
public class ActionTextHandler {
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/CardLayerHandler.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/CardLayerHandler.java
index fede1dba..116e0987 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/CardLayerHandler.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/CardLayerHandler.java
@@ -10,6 +10,7 @@
import com.jme3.texture.Texture2D;
import pp.mdga.client.Asset;
import pp.mdga.client.MdgaApp;
+import pp.mdga.client.animation.SymbolControl;
import pp.mdga.game.BonusCard;
import java.util.*;
From 0aa73ca6ee02d9db8f00bce18b44f184ef96559a Mon Sep 17 00:00:00 2001
From: Daniel Grigencha
Date: Mon, 2 Dec 2024 02:52:48 +0100
Subject: [PATCH 08/28] added the received method for a Shutdown Message
---
.../model/src/main/java/pp/mdga/client/ClientGameLogic.java | 3 +++
.../mdga/model/src/main/java/pp/mdga/client/ClientState.java | 3 +++
2 files changed, 6 insertions(+)
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/ClientGameLogic.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/ClientGameLogic.java
index eeb76f55..c2526b46 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/client/ClientGameLogic.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/ClientGameLogic.java
@@ -190,6 +190,9 @@ public void received(ServerStartGameMessage msg) {
state.received(msg);
}
+ @Override
+ public void received(ShutdownMessage msg) {state.received(msg);}
+
@Override
public void received(StartPieceMessage msg) {
state.received(msg);
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/ClientState.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/ClientState.java
index e53a5d92..bf64e267 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/client/ClientState.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/ClientState.java
@@ -150,6 +150,9 @@ public void received(ServerStartGameMessage msg) {
LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg);
}
+ @Override
+ public void received(ShutdownMessage msg) {LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg);}
+
@Override
public void received(StartPieceMessage msg) {
LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg);
From c434bcb684574ea255baae5b04b3025287361930 Mon Sep 17 00:00:00 2001
From: Fleischer Hanno
Date: Mon, 2 Dec 2024 03:03:36 +0100
Subject: [PATCH 09/28] minor changes
---
.../pp/mdga/client/server/MdgaServer.java | 2 --
.../src/main/java/pp/mdga/game/Piece.java | 32 +++++++++----------
.../main/java/pp/mdga/game/PieceState.java | 6 ++++
.../main/java/pp/mdga/game/ShieldState.java | 7 ++++
.../src/main/java/pp/mdga/game/StartNode.java | 10 +++---
5 files changed, 34 insertions(+), 23 deletions(-)
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/server/MdgaServer.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/server/MdgaServer.java
index 084a5df4..306010b0 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/server/MdgaServer.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/server/MdgaServer.java
@@ -143,8 +143,6 @@ private void initializeSerializables() {
Serializer.registerClass(StartNode.class);
Serializer.registerClass(PlayerData.class);
Serializer.registerClass(HomeNode.class);
- Serializer.registerClass(PieceState.class, new EnumSerializer());
- Serializer.registerClass(ShieldState.class, new EnumSerializer());
}
private void registerListeners() {
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/game/Piece.java b/Projekte/mdga/model/src/main/java/pp/mdga/game/Piece.java
index cb0468b5..dfe36188 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/game/Piece.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/game/Piece.java
@@ -12,17 +12,17 @@ public class Piece {
/**
* The shield state of the piece.
*/
- private ShieldState shield;
+ private int shield;
/**
* The current state of the piece.
*/
- private PieceState state;
+ private int state;
/**
* The color of the piece.
*/
- private final Color color;
+ private final int color;
/**
* The unique identifier of the piece.
@@ -36,15 +36,15 @@ public class Piece {
* @param state the state of the piece
*/
public Piece(Color color, PieceState state, int id) {
- this.color = color;
- this.state = state;
- shield = ShieldState.NONE;
+ this.color = color.ordinal();
+ this.state = state.ordinal();
+ shield = ShieldState.NONE.ordinal();
}
private Piece() {
- color = null;
- state = PieceState.WAITING;
- shield = ShieldState.NONE;
+ color = Color.NONE.ordinal();
+ state = PieceState.WAITING.ordinal();
+ shield = ShieldState.NONE.ordinal();
}
/**
@@ -53,7 +53,7 @@ private Piece() {
* @return the color of the piece
*/
public void setShield(ShieldState shield) {
- this.shield = shield;
+ this.shield = shield.ordinal();
}
/**
@@ -62,7 +62,7 @@ public void setShield(ShieldState shield) {
* @return the color of the piece
*/
public ShieldState getShield() {
- return shield;
+ return ShieldState.values()[shield];
}
/**
@@ -71,7 +71,7 @@ public ShieldState getShield() {
* @param state the state of the piece
*/
public void setState(PieceState state) {
- this.state = state;
+ this.state = state.ordinal();
}
/**
@@ -80,7 +80,7 @@ public void setState(PieceState state) {
* @return the color of the piece
*/
public PieceState getState() {
- return state;
+ return PieceState.values()[state];
}
/**
@@ -89,7 +89,7 @@ public PieceState getState() {
* @return the color of the piece
*/
public boolean isShielded() {
- return shield == ShieldState.ACTIVE;
+ return shield == ShieldState.ACTIVE.ordinal();
}
/**
@@ -98,7 +98,7 @@ public boolean isShielded() {
* @return the color of the piece
*/
public boolean isSuppressed() {
- return shield == ShieldState.SUPPRESSED;
+ return shield == ShieldState.SUPPRESSED.ordinal();
}
/**
@@ -107,7 +107,7 @@ public boolean isSuppressed() {
* @return the color of the piece
*/
public Color getColor() {
- return color;
+ return Color.values()[color];
}
/**
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/game/PieceState.java b/Projekte/mdga/model/src/main/java/pp/mdga/game/PieceState.java
index 6677d5a8..780d8df0 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/game/PieceState.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/game/PieceState.java
@@ -1,5 +1,7 @@
package pp.mdga.game;
+import com.jme3.network.serializing.Serializable;
+
/**
* Represents the state of a piece.
*/
@@ -21,6 +23,10 @@ public enum PieceState {
*/
HOMEFINISHED;
+ PieceState(){
+
+ }
+
public static PieceState getPieceStateByIndex(int index){
if (index < 0 || index >= values().length) {
throw new IllegalArgumentException("");
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/game/ShieldState.java b/Projekte/mdga/model/src/main/java/pp/mdga/game/ShieldState.java
index f2c0c616..19a09a5d 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/game/ShieldState.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/game/ShieldState.java
@@ -1,8 +1,11 @@
package pp.mdga.game;
+import com.jme3.network.serializing.Serializable;
+
/**
* Represents the state of a piece's shield.
*/
+@Serializable
public enum ShieldState {
/**
* The shield is not active.
@@ -17,6 +20,10 @@ public enum ShieldState {
*/
SUPPRESSED;
+ ShieldState(){
+
+ }
+
public static ShieldState getShieldStateByIndex(int index){
if (index < 0 || index >= values().length) {
throw new IllegalArgumentException("");
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/game/StartNode.java b/Projekte/mdga/model/src/main/java/pp/mdga/game/StartNode.java
index bb203084..23161ecf 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/game/StartNode.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/game/StartNode.java
@@ -10,7 +10,7 @@ public class StartNode extends Node {
/**
* The color of the node.
*/
- private Color color;
+ private int color;
/**
* Creates a new start node with the given color.
@@ -18,11 +18,11 @@ public class StartNode extends Node {
* @param color the color of the node
*/
public StartNode(Color color) {
- this.color = color;
+ this.color = color.ordinal();
}
private StartNode() {
- color = null;
+ color = Color.NONE.ordinal();
}
/**
@@ -31,7 +31,7 @@ private StartNode() {
* @return the color of the node
*/
public Color getColor() {
- return color;
+ return Color.values()[color];
}
/**
@@ -40,6 +40,6 @@ public Color getColor() {
* @param color the new color of the node
*/
public void setColor(Color color) {
- this.color = color;
+ this.color = color.ordinal();
}
}
From b87f5de5fb53242ad273761b90e3ed1fa0fa0601 Mon Sep 17 00:00:00 2001
From: Felix Koppe
Date: Mon, 2 Dec 2024 03:03:54 +0100
Subject: [PATCH 10/28] Fix error
---
.../client/src/main/java/pp/mdga/client/InputSynchronizer.java | 1 -
1 file changed, 1 deletion(-)
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/InputSynchronizer.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/InputSynchronizer.java
index 7bdb75be..b251134f 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/InputSynchronizer.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/InputSynchronizer.java
@@ -120,7 +120,6 @@ else if(boardSelect != null) {
if(app.getView() instanceof GameView gameView){
// app.getNotificationSynchronizer().addTestNotification(new FinishNotification(Color.NAVY));
// app.getNotificationSynchronizer().addTestNotification(new MovePieceNotification());
- gameView.test();
}
}
}
From 6d0552f5a7bc13808c418365664b3e41db6823d7 Mon Sep 17 00:00:00 2001
From: Cedric Beck
Date: Mon, 2 Dec 2024 03:13:42 +0100
Subject: [PATCH 11/28] added javadocs to animation; moved outline package
---
.../pp/mdga/client/animation/Animation.java | 10 ---
.../client/animation/AnimationHandler.java | 29 -------
.../mdga/client/animation/EmptyAnimation.java | 18 ----
.../pp/mdga/client/animation/InitControl.java | 18 ++++
.../mdga/client/animation/MdgaAnimation.java | 4 -
.../pp/mdga/client/animation/MoveControl.java | 68 ++++++++++-----
.../mdga/client/animation/SymbolControl.java | 82 +++++++++++++++++--
.../pp/mdga/client/animation/ZoomControl.java | 58 ++++++++++---
.../pp/mdga/client/board/BoardHandler.java | 5 --
.../pp/mdga/client/board/OutlineControl.java | 2 +-
.../{board => }/outline/OutlineFilter.java | 2 +-
.../{board => }/outline/OutlinePreFilter.java | 2 +-
.../{board => }/outline/OutlineProFilter.java | 2 +-
.../outline/SelectObjectOutliner.java | 2 +-
14 files changed, 193 insertions(+), 109 deletions(-)
delete mode 100644 Projekte/mdga/client/src/main/java/pp/mdga/client/animation/Animation.java
delete mode 100644 Projekte/mdga/client/src/main/java/pp/mdga/client/animation/AnimationHandler.java
delete mode 100644 Projekte/mdga/client/src/main/java/pp/mdga/client/animation/EmptyAnimation.java
delete mode 100644 Projekte/mdga/client/src/main/java/pp/mdga/client/animation/MdgaAnimation.java
rename Projekte/mdga/client/src/main/java/pp/mdga/client/{board => }/outline/OutlineFilter.java (98%)
rename Projekte/mdga/client/src/main/java/pp/mdga/client/{board => }/outline/OutlinePreFilter.java (97%)
rename Projekte/mdga/client/src/main/java/pp/mdga/client/{board => }/outline/OutlineProFilter.java (98%)
rename Projekte/mdga/client/src/main/java/pp/mdga/client/{board => }/outline/SelectObjectOutliner.java (98%)
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/Animation.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/Animation.java
deleted file mode 100644
index b808f9d3..00000000
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/Animation.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package pp.mdga.client.animation;
-
-abstract class Animation {
-
- abstract void play();
-
- abstract void stop();
-
- abstract boolean isOver();
-}
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/AnimationHandler.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/AnimationHandler.java
deleted file mode 100644
index cee17634..00000000
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/AnimationHandler.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package pp.mdga.client.animation;
-
-import pp.mdga.client.MdgaApp;
-
-public class AnimationHandler {
- private MdgaApp app;
-
- private Animation animation = null;
-
- public AnimationHandler(MdgaApp app) {
- this.app = app;
- }
-
- public void playAnimation(MdgaAnimation type) {
-
- }
-
- public void update() {
- if (null == animation) {
- return;
- }
-
- if (animation.isOver()) {
- animation = null;
-
- //trigger next state in model
- }
- }
-}
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/EmptyAnimation.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/EmptyAnimation.java
deleted file mode 100644
index b51d5535..00000000
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/EmptyAnimation.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package pp.mdga.client.animation;
-
-class EmptyAnimation extends Animation {
- @Override
- void play() {
- //nothing
- }
-
- @Override
- void stop() {
- //nothing
- }
-
- @Override
- boolean isOver() {
- return true;
- }
-}
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/InitControl.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/InitControl.java
index dfe3f312..f618e32e 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/InitControl.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/InitControl.java
@@ -5,6 +5,12 @@
import com.jme3.scene.Spatial;
import com.jme3.scene.control.AbstractControl;
+/**
+ * An abstract control class that serves as a base for initializing spatial objects
+ * in jMonkeyEngine. This class overrides the controlUpdate and controlRender methods
+ * from the AbstractControl class, providing default empty implementations,
+ * and adds the ability to initialize spatial objects when they are set.
+ */
public abstract class InitControl extends AbstractControl {
@Override
@@ -17,6 +23,12 @@ protected void controlRender(RenderManager rm, ViewPort vp) {
}
+ /**
+ * Sets the spatial object to be controlled. This method also initializes the spatial
+ * if it is being set for the first time.
+ *
+ * @param spatial The spatial object to control.
+ */
@Override
public void setSpatial(Spatial spatial) {
if (this.spatial == null && spatial != null) {
@@ -25,6 +37,12 @@ public void setSpatial(Spatial spatial) {
}
}
+ /**
+ * Initializes the spatial object. This method can be overridden by subclasses
+ * to define custom initialization logic for the spatial.
+ * This method is called automatically when the spatial is set for the first time.
+ */
protected void initSpatial() {
+ // Default empty implementation. Override to add initialization logic.
}
}
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/MdgaAnimation.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/MdgaAnimation.java
deleted file mode 100644
index cddf535d..00000000
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/MdgaAnimation.java
+++ /dev/null
@@ -1,4 +0,0 @@
-package pp.mdga.client.animation;
-
-public enum MdgaAnimation {
-}
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/MoveControl.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/MoveControl.java
index e8bbf8b6..621eb118 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/MoveControl.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/MoveControl.java
@@ -4,6 +4,15 @@
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
+/**
+ * A control that smoothly moves a spatial from an initial position to an end position
+ * using a quadratic interpolation, with the option to perform an action after the movement is complete.
+ * The movement path includes an intermediate "middle" position at a specified height.
+ *
+ *
Movement speed can be adjusted by modifying the MOVE_SPEED constant. The movement easing follows
+ * an ease-in-out curve to create a smooth start and stop effect.
+ *
+ */
public class MoveControl extends InitControl {
private boolean moving;
@@ -15,6 +24,14 @@ public class MoveControl extends InitControl {
private float progress = 0;
private final Runnable actionAfter;
+ /**
+ * Creates a new MoveControl with specified initial and end positions, and an action to run after the movement.
+ * The movement follows a path with a midpoint at a fixed height.
+ *
+ * @param initPos The starting position of the spatial.
+ * @param endPos The target position of the spatial.
+ * @param actionAfter A Runnable that will be executed after the movement finishes.
+ */
public MoveControl(Vector3f initPos, Vector3f endPos, Runnable actionAfter){
moving = false;
this.initPos = initPos;
@@ -27,12 +44,23 @@ public MoveControl(Vector3f initPos, Vector3f endPos, Runnable actionAfter){
this.actionAfter = actionAfter;
}
+ /**
+ * Initializes the movement by resetting the progress and setting the moving flag to true.
+ * This is called automatically when the spatial is set.
+ */
@Override
protected void initSpatial() {
moving = true;
progress = 0;
}
+ /**
+ * Updates the movement of the spatial by interpolating its position along the defined path.
+ * The movement is smoothed using an easing function.
+ * Once the movement reaches the target, the {@link #end()} method is called to finish the movement.
+ *
+ * @param tpf Time per frame, the time elapsed since the last frame.
+ */
@Override
protected void controlUpdate(float tpf) {
if(!moving) return;
@@ -42,17 +70,25 @@ protected void controlUpdate(float tpf) {
if(progress == 1) end();
}
+ /**
+ * Ends the movement by stopping the interpolation, running the action after the movement,
+ * and removing this control from the spatial.
+ */
private void end(){
moving = false;
actionAfter.run();
spatial.removeControl(this);
}
- @Override
- protected void controlRender(RenderManager rm, ViewPort vp) {
-
- }
-
+ /**
+ * Performs quadratic interpolation between three points.
+ *
+ * @param p1 The initial point.
+ * @param p2 The middle point.
+ * @param p3 The final point.
+ * @param t The interpolation parameter (0 <= t <= 1).
+ * @return The interpolated point.
+ */
private Vector3f quadInt(Vector3f p1, Vector3f p2, Vector3f p3, float t) {
// Quadratic interpolation: (1-t)^2 * p1 + 2 * (1-t) * t * p2 + t^2 * p3
float oneMinusT = 1 - t;
@@ -61,22 +97,14 @@ private Vector3f quadInt(Vector3f p1, Vector3f p2, Vector3f p3, float t) {
.add(p3.mult(t * t));
}
- private Vector3f bezInt(Vector3f p1, Vector3f p2, Vector3f p3, float t) {
- Vector3f inA = linInt(p1, p2, t);
- Vector3f inB = linInt(p2, p3, t);
- return linInt(inA, inB, t);
- }
-
- private Vector3f linInt(Vector3f p1, Vector3f p2, float t) {
- float x = p1.getX() + t * (p2.getX() - p1.getX());
- float y = p1.getY() + t * (p2.getY() - p1.getY());
- float z = p1.getZ() + t * (p2.getZ() - p1.getZ());
- return new Vector3f(x, y, z);
- }
-
+ /**
+ * A smooth ease-in-out function for interpolation.
+ * It accelerates and decelerates the interpolation for a smoother effect.
+ *
+ * @param x The interpolation parameter (0 <= x <= 1).
+ * @return The adjusted interpolation value.
+ */
private float easeInOut(float x){
return x < 0.5 ? 4 * x * x * x : (float) (1 - Math.pow(-2 * x + 2, 3) / 2);
-
}
-
}
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/SymbolControl.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/SymbolControl.java
index cf442659..3bc3e10a 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/SymbolControl.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/SymbolControl.java
@@ -7,7 +7,19 @@
import com.jme3.scene.control.AbstractControl;
import pp.mdga.game.BonusCard;
-public class SymbolControl extends AbstractControl {
+/**
+ * A control that manages the animation of symbols representing different bonus card states.
+ * The symbol can animate with zoom, rotation, and translation effects based on the state of the bonus card.
+ *
+ *
The control supports three main states: SHIELD, SWAP, and TURBO. Each state has its own specific animation logic:
+ *
+ *
SHIELD: Zooms in and out, with a scaling effect.
+ *
SWAP: Rotates the symbol 360 degrees.
+ *
TURBO: Moves the symbol along the Y-axis with a zoom effect.
+ *
+ *
+ */
+public class SymbolControl extends InitControl {
private boolean zoomingIn = false;
private boolean zoomingOut = false;
private float zoomSpeed = 1f;
@@ -18,7 +30,12 @@ public class SymbolControl extends AbstractControl {
private Quaternion initialRotation = null;
private float y = 5;
-
+ /**
+ * Updates the symbol animation based on the current bonus card state.
+ * The method calls the corresponding update method for each state (SHIELD, SWAP, TURBO).
+ *
+ * @param tpf Time per frame, the time elapsed since the last frame.
+ */
@Override
protected void controlUpdate(float tpf) {
if (state == null) return;
@@ -30,11 +47,12 @@ protected void controlUpdate(float tpf) {
}
}
- @Override
- protected void controlRender(RenderManager rm, ViewPort vp) {
-
- }
-
+ /**
+ * Updates the symbol when the state is SHIELD. The symbol zooms in and then zooms out.
+ * When the zooming out finishes, the symbol is removed from the parent spatial.
+ *
+ * @param tpf Time per frame, the time elapsed since the last frame.
+ */
private void shieldUpdate(float tpf) {
if (zoomingIn) {
progress += tpf * zoomSpeed;
@@ -57,6 +75,12 @@ private void shieldUpdate(float tpf) {
}
}
+ /**
+ * Updates the symbol when the state is SWAP. The symbol rotates 360 degrees.
+ * After the rotation finishes, the symbol is removed from the parent spatial.
+ *
+ * @param tpf Time per frame, the time elapsed since the last frame.
+ */
private void swapUpdate(float tpf) {
if (initialRotation == null) {
initialRotation = spatial.getLocalRotation().clone();
@@ -80,6 +104,12 @@ private void swapUpdate(float tpf) {
}
}
+ /**
+ * Updates the symbol when the state is TURBO. The symbol moves along the Y-axis with a zoom effect.
+ * After the movement finishes, the symbol is removed from the parent spatial.
+ *
+ * @param tpf Time per frame, the time elapsed since the last frame.
+ */
private void turboUpdate(float tpf) {
if (zoomingIn) {
progress += tpf * zoomSpeed;
@@ -103,6 +133,10 @@ private void turboUpdate(float tpf) {
}
}
+ /**
+ * Starts the SHIELD animation by zooming the symbol in and out.
+ * The symbol will first zoom in and then zoom out, and will be removed from the parent spatial once done.
+ */
public void shield() {
if (state != null) throw new RuntimeException("another state is avtive");
state = BonusCard.SHIELD;
@@ -112,6 +146,10 @@ public void shield() {
spatial.setLocalScale(1f);
}
+ /**
+ * Starts the SWAP animation by rotating the symbol 360 degrees.
+ * The symbol will rotate once and then be removed from the parent spatial.
+ */
public void swap() {
if (state != null) throw new RuntimeException("another state is avtive");
spatial.setLocalScale(3);
@@ -119,6 +157,10 @@ public void swap() {
progress = -0.2f;
}
+ /**
+ * Starts the TURBO animation by moving the symbol along the Y-axis.
+ * The symbol will move upwards and then return to its initial position.
+ */
public void turbo() {
if (state != null) throw new RuntimeException("another state is avtive");
spatial.setLocalScale(2);
@@ -128,19 +170,45 @@ public void turbo() {
progress = 0;
}
+ /**
+ * Performs linear interpolation between two values.
+ *
+ * @param start The starting value.
+ * @param end The target value.
+ * @param t The interpolation parameter (0 <= t <= 1).
+ * @return The interpolated value.
+ */
private static float lerp(float start, float end, float t) {
return (1 - t) * start + t * end;
}
+ /**
+ * Ease-out function for smoothing the interpolation.
+ *
+ * @param t The interpolation parameter (0 <= t <= 1).
+ * @return The eased value.
+ */
private static float easeOut(float t) {
return (float) Math.sqrt(1 - Math.pow(t - 1, 2));
}
+ /**
+ * Ease-in-out function for smoothing the interpolation.
+ *
+ * @param t The interpolation parameter (0 <= t <= 1).
+ * @return The eased value.
+ */
private float easeInOut(float t) {
if (t > 1) t = 1;
return (float) -(Math.cos(Math.PI * t) - 1) / 2;
}
+ /**
+ * Ease-in function for smoothing the interpolation.
+ *
+ * @param t The interpolation parameter (0 <= t <= 1).
+ * @return The eased value.
+ */
private float easeIn(float t) {
return t * t * t * t;
}
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/ZoomControl.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/ZoomControl.java
index 7b2a06e1..8cf83daf 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/ZoomControl.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/ZoomControl.java
@@ -5,6 +5,13 @@
import com.jme3.scene.Spatial;
import com.jme3.scene.control.AbstractControl;
+/**
+ * A control that applies a zoom effect to a spatial, smoothly scaling it in and out.
+ * The zoom effect can be customized with speed and scaling factor.
+ *
+ *
The control supports zooming in and out with ease-in and ease-out transitions.
+ * It starts by zooming in, and once complete, it zooms out, eventually removing the spatial from its parent when the animation ends.
+ */
public class ZoomControl extends InitControl {
private boolean zoomingIn = false;
private boolean zoomingOut = false;
@@ -12,18 +19,35 @@ public class ZoomControl extends InitControl {
private float zoomSpeed = 1f;
private float zoomFactor = 1f;
+ /**
+ * Constructs a new ZoomControl with the default zoom speed.
+ */
public ZoomControl() {
}
+ /**
+ * Constructs a new ZoomControl with a specified zoom speed.
+ *
+ * @param speed The speed at which the zoom effect occurs.
+ */
public ZoomControl(float speed) {
zoomSpeed = speed;
}
+ /**
+ * Initializes the spatial for the zoom effect. This method is called when the control is added to the spatial.
+ * It sets the zooming state to zooming in.
+ */
@Override
protected void initSpatial() {
zoomingIn = true;
}
+ /**
+ * Updates the zoom effect over time, either zooming in or zooming out.
+ *
+ * @param tpf Time per frame, the time elapsed since the last frame.
+ */
@Override
protected void controlUpdate(float tpf) {
if (zoomingIn) {
@@ -45,31 +69,43 @@ protected void controlUpdate(float tpf) {
}
}
+ /**
+ * Ends the zoom animation by removing the spatial from its parent and the control from the spatial.
+ */
private void end() {
spatial.removeFromParent();
spatial.removeControl(this);
}
- @Override
- protected void controlRender(RenderManager rm, ViewPort vp) {
-
- }
-
+ /**
+ * Performs linear interpolation between two values.
+ *
+ * @param start The starting value.
+ * @param end The target value.
+ * @param t The interpolation parameter (0 <= t <= 1).
+ * @return The interpolated value.
+ */
private static float lerp(float start, float end, float t) {
return (1 - t) * start + t * end;
}
- // private static float easeOut(float t) {
-// return (float) Math.sqrt(1 - Math.pow(t - 1, 2));
-// }
+ /**
+ * Ease-out function for smoothing the zoom-in transition.
+ *
+ * @param x The interpolation parameter (0 <= x <= 1).
+ * @return The eased value.
+ */
private float easeOut(float x) {
return x == 1 ? 1 : (float) (1 - Math.pow(2, -10 * x));
}
- // private float easeIn(float t) {
-// return t * t * t * t;
-// }
+ /**
+ * Ease-in function for smoothing the zoom-out transition.
+ *
+ * @param x The interpolation parameter (0 <= x <= 1).
+ * @return The eased value.
+ */
private float easeIn(float x) {
return x == 0 ? 0 : (float) Math.pow(2, 10 * x - 10);
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/BoardHandler.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/BoardHandler.java
index 225fdb1d..6f3f6237 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/BoardHandler.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/BoardHandler.java
@@ -597,9 +597,4 @@ private NodeControl getNextWaitingNode(Color color) {
throw new IllegalStateException("Keine freien Nodes im Wartebereich für die Farbe " + color);
}
-
-
-
-
-
}
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/OutlineControl.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/OutlineControl.java
index 7872dbe4..9444e841 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/OutlineControl.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/OutlineControl.java
@@ -8,7 +8,7 @@
import com.jme3.scene.Spatial;
import com.jme3.scene.control.AbstractControl;
import pp.mdga.client.MdgaApp;
-import pp.mdga.client.board.outline.SelectObjectOutliner;
+import pp.mdga.client.outline.SelectObjectOutliner;
public class OutlineControl extends AbstractControl {
private static final int THICKNESS_DEFAULT = 6;
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/outline/OutlineFilter.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/outline/OutlineFilter.java
similarity index 98%
rename from Projekte/mdga/client/src/main/java/pp/mdga/client/board/outline/OutlineFilter.java
rename to Projekte/mdga/client/src/main/java/pp/mdga/client/outline/OutlineFilter.java
index d9fcaef9..109e2de7 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/outline/OutlineFilter.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/outline/OutlineFilter.java
@@ -1,4 +1,4 @@
-package pp.mdga.client.board.outline;
+package pp.mdga.client.outline;
import com.jme3.asset.AssetManager;
import com.jme3.material.Material;
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/outline/OutlinePreFilter.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/outline/OutlinePreFilter.java
similarity index 97%
rename from Projekte/mdga/client/src/main/java/pp/mdga/client/board/outline/OutlinePreFilter.java
rename to Projekte/mdga/client/src/main/java/pp/mdga/client/outline/OutlinePreFilter.java
index 9a385045..cb2ae654 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/outline/OutlinePreFilter.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/outline/OutlinePreFilter.java
@@ -1,4 +1,4 @@
-package pp.mdga.client.board.outline;
+package pp.mdga.client.outline;
import com.jme3.asset.AssetManager;
import com.jme3.material.Material;
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/outline/OutlineProFilter.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/outline/OutlineProFilter.java
similarity index 98%
rename from Projekte/mdga/client/src/main/java/pp/mdga/client/board/outline/OutlineProFilter.java
rename to Projekte/mdga/client/src/main/java/pp/mdga/client/outline/OutlineProFilter.java
index c40a9435..c49f6158 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/outline/OutlineProFilter.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/outline/OutlineProFilter.java
@@ -1,4 +1,4 @@
-package pp.mdga.client.board.outline;
+package pp.mdga.client.outline;
import com.jme3.asset.AssetManager;
import com.jme3.material.Material;
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/outline/SelectObjectOutliner.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/outline/SelectObjectOutliner.java
similarity index 98%
rename from Projekte/mdga/client/src/main/java/pp/mdga/client/board/outline/SelectObjectOutliner.java
rename to Projekte/mdga/client/src/main/java/pp/mdga/client/outline/SelectObjectOutliner.java
index 3cfbc76c..aa5049a6 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/outline/SelectObjectOutliner.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/outline/SelectObjectOutliner.java
@@ -1,4 +1,4 @@
-package pp.mdga.client.board.outline;
+package pp.mdga.client.outline;
import com.jme3.asset.AssetManager;
import com.jme3.math.ColorRGBA;
From a15d7932d4f8a95e4a41c728915ac22c027f6c46 Mon Sep 17 00:00:00 2001
From: Cedric Beck
Date: Mon, 2 Dec 2024 03:15:18 +0100
Subject: [PATCH 12/28] fixed bug
---
.../src/main/java/pp/mdga/client/MdgaApp.java | 15 ---------------
1 file changed, 15 deletions(-)
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java
index 80a44dbd..cb0371c0 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java
@@ -1,14 +1,11 @@
package pp.mdga.client;
import com.jme3.app.SimpleApplication;
-import com.jme3.system.JmeContext;
import com.simsilica.lemur.GuiGlobals;
import pp.mdga.client.acoustic.AcousticHandler;
-import pp.mdga.client.animation.AnimationHandler;
import com.jme3.system.AppSettings;
import pp.mdga.client.dialog.JoinDialog;
import pp.mdga.client.view.*;
-import pp.mdga.message.server.ServerInterpreter;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
@@ -23,9 +20,6 @@ public class MdgaApp extends SimpleApplication {
private static Preferences prefs = Preferences.userNodeForPackage(JoinDialog.class);
- /** Handles animations in the application. */
- private AnimationHandler animationHandler;
-
/** Handles acoustic effects and state-based sounds. */
private AcousticHandler acousticHandler;
@@ -102,7 +96,6 @@ public void simpleInitApp() {
flyCam.setEnabled(false);
- animationHandler = new AnimationHandler(this);
acousticHandler = new AcousticHandler(this);
notificationSynchronizer = new NotificationSynchronizer(this);
inputSynchronizer = new InputSynchronizer(this);
@@ -163,14 +156,6 @@ public void enter(MdgaState state) {
view.enter();
}
- /**
- * Gets the animation handler.
- *
- * @return the {@link AnimationHandler} instance
- */
- public AnimationHandler getAnimationHandler() {
- return animationHandler;
- }
/**
* Gets the acoustic handler.
From 3717e7b79465af646aa93c4aafac97c31ea194fb Mon Sep 17 00:00:00 2001
From: Cedric Beck
Date: Mon, 2 Dec 2024 03:48:11 +0100
Subject: [PATCH 13/28] added javadocs to board
---
.../client/{animation => }/InitControl.java | 2 +-
.../src/main/java/pp/mdga/client/MdgaApp.java | 2 +-
.../mdga/client/NotificationSynchronizer.java | 14 +-
.../pp/mdga/client/animation/MoveControl.java | 3 +-
.../mdga/client/animation/SymbolControl.java | 4 +-
.../pp/mdga/client/animation/ZoomControl.java | 5 +-
.../java/pp/mdga/client/board/AssetOnMap.java | 3 +
.../pp/mdga/client/board/BoardHandler.java | 264 +++++++++++++++---
.../pp/mdga/client/board/CameraHandler.java | 39 +++
.../java/pp/mdga/client/board/MapLoader.java | 23 ++
.../pp/mdga/client/board/NodeControl.java | 21 ++
.../pp/mdga/client/board/OutlineControl.java | 54 ++--
.../pp/mdga/client/board/PieceControl.java | 98 ++++++-
.../pp/mdga/client/board/PileControl.java | 5 -
.../java/pp/mdga/client/board/Rotation.java | 12 -
.../java/pp/mdga/client/view/GameView.java | 3 +
16 files changed, 443 insertions(+), 109 deletions(-)
rename Projekte/mdga/client/src/main/java/pp/mdga/client/{animation => }/InitControl.java (97%)
delete mode 100644 Projekte/mdga/client/src/main/java/pp/mdga/client/board/PileControl.java
delete mode 100644 Projekte/mdga/client/src/main/java/pp/mdga/client/board/Rotation.java
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/InitControl.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/InitControl.java
similarity index 97%
rename from Projekte/mdga/client/src/main/java/pp/mdga/client/animation/InitControl.java
rename to Projekte/mdga/client/src/main/java/pp/mdga/client/InitControl.java
index f618e32e..73f259ff 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/InitControl.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/InitControl.java
@@ -1,4 +1,4 @@
-package pp.mdga.client.animation;
+package pp.mdga.client;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java
index cb0371c0..5aa92fc0 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java
@@ -106,7 +106,7 @@ public void simpleInitApp() {
gameView = new GameView(this);
ceremonyView = new CeremonyView(this);
- enter(MdgaState.MAIN);
+ enter(MdgaState.GAME);
}
/**
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/NotificationSynchronizer.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/NotificationSynchronizer.java
index b45c1867..b943e955 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/NotificationSynchronizer.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/NotificationSynchronizer.java
@@ -67,8 +67,9 @@ private void handleLobby(Notification notification) {
lobbyView.setTaken(n.getColor(), false, false, null);
} else if(notification instanceof LobbyReadyNotification lobbyReadyNotification) {
lobbyView.setReady(lobbyReadyNotification.getColor(), lobbyReadyNotification.isReady());
- } else if (notification instanceof GameNotification) {
+ } else if (notification instanceof GameNotification n) {
app.enter(MdgaState.GAME);
+ ((GameView) app.getView()).setOwnColor(n.getOwnColor());
} else {
throw new RuntimeException("notification not expected: " + notification.toString());
}
@@ -84,6 +85,7 @@ private void handleGame(Notification notification) {
guiHandler.addCard(n.getBonusCard());
} else if (notification instanceof ActivePlayerNotification n) {
gameView.getGuiHandler().setActivePlayer(n.getColor());
+ boardHandler.showDice(n.getColor());
} else if (notification instanceof CeremonyNotification ceremonyNotification) {
app.enter(MdgaState.CEREMONY);
CeremonyView ceremonyView = (CeremonyView) app.getView();
@@ -116,23 +118,22 @@ private void handleGame(Notification notification) {
} else if (notification instanceof DrawCardNotification n) {
guiHandler.drawCard(n.getColor());
} else if (notification instanceof HomeMoveNotification home) {
- boardHandler.moveHomePiece(home.getPieceId(), home.getHomeIndex());
+ boardHandler.movePieceHomeAnim(home.getPieceId(), home.getHomeIndex());
guiHandler.hideText();
} else if (notification instanceof InterruptNotification) {
app.enter(MdgaState.LOBBY);
} else if (notification instanceof MovePieceNotification n) {
if(n.isMoveStart()) {
//StartMove
- boardHandler.movePieceStart(n.getPiece(), n.getMoveIndex());
+ boardHandler.movePieceStartAnim(n.getPiece(), n.getMoveIndex());
}
else {
//InfieldMove
- boardHandler.movePiece(n.getPiece(), n.getStartIndex(), n.getMoveIndex());
-// boardHandler.test(n.getPiece(), n.getStartIndex(), n.getMoveIndex());
+ boardHandler.movePieceAnim(n.getPiece(), n.getStartIndex(), n.getMoveIndex());
}
guiHandler.hideText();
} else if (notification instanceof ThrowPieceNotification n) {
- boardHandler.throwPiece(n.getPieceId());
+ boardHandler.throwPieceAnim(n.getPieceId());
} else if (notification instanceof NoShieldNotification n) {
boardHandler.unshieldPiece(n.getPieceId());
} else if (notification instanceof PlayCardNotification n) {
@@ -152,6 +153,7 @@ private void handleGame(Notification notification) {
guiHandler.rollDice(n.getEyes(), n.isTurbo() ? n.getMultiplier() : -1);
}
else {
+ boardHandler.hideDice();
if (n.isTurbo()) guiHandler.showRolledDiceMult(n.getEyes(), n.getMultiplier(), n.getColor());
else guiHandler.showRolledDice(n.getEyes(), n.getColor());
}
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/MoveControl.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/MoveControl.java
index 621eb118..8aea4efc 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/MoveControl.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/MoveControl.java
@@ -1,8 +1,7 @@
package pp.mdga.client.animation;
import com.jme3.math.Vector3f;
-import com.jme3.renderer.RenderManager;
-import com.jme3.renderer.ViewPort;
+import pp.mdga.client.InitControl;
/**
* A control that smoothly moves a spatial from an initial position to an end position
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/SymbolControl.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/SymbolControl.java
index 3bc3e10a..1abf533c 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/SymbolControl.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/SymbolControl.java
@@ -2,9 +2,7 @@
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
-import com.jme3.renderer.RenderManager;
-import com.jme3.renderer.ViewPort;
-import com.jme3.scene.control.AbstractControl;
+import pp.mdga.client.InitControl;
import pp.mdga.game.BonusCard;
/**
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/ZoomControl.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/ZoomControl.java
index 8cf83daf..eb4319cd 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/ZoomControl.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/ZoomControl.java
@@ -1,9 +1,6 @@
package pp.mdga.client.animation;
-import com.jme3.renderer.RenderManager;
-import com.jme3.renderer.ViewPort;
-import com.jme3.scene.Spatial;
-import com.jme3.scene.control.AbstractControl;
+import pp.mdga.client.InitControl;
/**
* A control that applies a zoom effect to a spatial, smoothly scaling it in and out.
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/AssetOnMap.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/AssetOnMap.java
index d78d48fd..ac6bdf53 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/AssetOnMap.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/AssetOnMap.java
@@ -2,4 +2,7 @@
import pp.mdga.client.Asset;
+/**
+ * Record for holding Asset information
+ */
record AssetOnMap(Asset asset, int x, int y, float rot) {}
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/BoardHandler.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/BoardHandler.java
index 6f3f6237..a00508e8 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/BoardHandler.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/BoardHandler.java
@@ -16,16 +16,24 @@
import java.util.*;
+/**
+ * BoardHandler is responsible for managing the game board in the MDGA client, including handling
+ * the initialization, movement, and management of game pieces and assets.
+ * It works closely with the MdgaApp to create and manipulate 3D models of assets, track player pieces,
+ * and manage movement across the game board.
+ */
public class BoardHandler {
+ // Constants defining the grid size and elevation of the board
private static final float GRID_SIZE = 1.72f;
private static final float GRID_ELEVATION = 0.0f;
private static final String MAP_NAME = "Maps/map.mdga";
+ // The main application instance for accessing game assets and logic
private final MdgaApp app;
+ // Collection of in-game assets and board elements
private ArrayList infield;
private Map pieces;
-
private Map> colorAssetsMap;
private Map> homeNodesMap;
private Map> waitingNodesMap;
@@ -35,11 +43,11 @@ public class BoardHandler {
private final Node rootNodeBoard;
private final Node rootNode;
-
private final FilterPostProcessor fpp;
private boolean isInitialised;
+ // Flags and lists for handling piece selection and movement
private List selectableOwnPieces;
private List selectableEnemyPieces;
private List outlineNodes;
@@ -47,6 +55,14 @@ public class BoardHandler {
private PieceControl selectedEnemyPiece;
private DiceControl diceControl;
+ /**
+ * Creates a new BoardHandler.
+ *
+ * @param app The main application instance
+ * @param rootNode The root node where the board will be attached
+ * @param fpp The post-processor for effects like shadows or filters
+ * @throws RuntimeException if the app is null
+ */
public BoardHandler(MdgaApp app, Node rootNode, FilterPostProcessor fpp) {
if(app == null) throw new RuntimeException("app is null");
@@ -57,6 +73,9 @@ public BoardHandler(MdgaApp app, Node rootNode, FilterPostProcessor fpp) {
isInitialised = false;
}
+ /**
+ * Initializes the game board by setting up the pieces and nodes.
+ */
public void init() {
isInitialised = true;
selectableOwnPieces = new ArrayList<>();
@@ -68,17 +87,30 @@ public void init() {
rootNode.attachChild(rootNodeBoard);
}
+ /**
+ * Shuts down the board handler by detaching all board-related nodes and clearing selected pieces.
+ */
public void shutdown(){
clearSelectable();
isInitialised = false;
rootNode.detachChild(rootNodeBoard);
}
+ /**
+ * Adds an asset to the map of player assets, ensuring that the player does not have too many assets.
+ *
+ * @param col The color of the player
+ * @param assetOnMap The asset to be added
+ * @throws RuntimeException if there are too many assets for the player
+ */
private void addFigureToPlayerMap(Color col, AssetOnMap assetOnMap) {
List inMap = addItemToMapList(colorAssetsMap, col, assetOnMap);
if (inMap.size() > 4) throw new RuntimeException("to many assets for " + col);
}
+ /**
+ * Initializes the map with the assets loaded from the map file and corresponding nodes.
+ */
private void initMap() {
pieces = new HashMap<>();
colorAssetsMap = new HashMap<>();
@@ -120,6 +152,13 @@ private void initMap() {
}
}
+ /**
+ * Converts an asset to its corresponding color.
+ *
+ * @param asset The asset to be converted
+ * @return The color associated with the asset
+ * @throws RuntimeException if the asset is invalid
+ */
private Color assetToColor(Asset asset) {
return switch (asset) {
case lw -> Color.AIRFORCE;
@@ -130,6 +169,14 @@ private Color assetToColor(Asset asset) {
};
}
+ /**
+ * Creates a 3D model of an asset and adds it to the board.
+ *
+ * @param asset The asset to be displayed
+ * @param pos The position of the asset on the board
+ * @param rot The rotation of the asset
+ * @return The Spatial representation of the asset
+ */
private Spatial createModel(Asset asset, Vector3f pos, float rot) {
String modelName = asset.getModelPath();
String texName = asset.getDiffPath();
@@ -146,10 +193,23 @@ private Spatial createModel(Asset asset, Vector3f pos, float rot) {
return model;
}
+ /**
+ * Converts grid coordinates to world space.
+ *
+ * @param x The x-coordinate on the grid
+ * @param y The y-coordinate on the grid
+ * @return The corresponding world position
+ */
private static Vector3f gridToWorld(int x, int y) {
return new Vector3f(GRID_SIZE * x, GRID_SIZE * y, GRID_ELEVATION);
}
+ /**
+ * Displays an asset on the map at the given position with the specified rotation.
+ *
+ * @param assetOnMap The asset to be displayed.
+ * @return A spatial representation of the asset at the specified location and rotation.
+ */
private Spatial displayAsset(AssetOnMap assetOnMap) {
int x = assetOnMap.x();
int y = assetOnMap.y();
@@ -171,6 +231,13 @@ private void addHomeNode(Map> map, Color color, AssetOn
if (homeNodes.size() > 4) throw new RuntimeException("too many homeNodes for " + color);
}
+ /**
+ * Calculates the rotation angle required to move a piece from one position to another.
+ *
+ * @param prev The previous position.
+ * @param next The target position.
+ * @return The rotation angle in degrees.
+ */
private float getRotationMove(Vector3f prev, Vector3f next) {
Vector3f direction = next.subtract(prev).normalizeLocal();
//I had to reverse dir.y, because then it worked.
@@ -179,6 +246,14 @@ private float getRotationMove(Vector3f prev, Vector3f next) {
return newRot;
}
+ /**
+ * Recursively moves a piece from its current index to the destination index,
+ * to keep track of the piece rotation.
+ *
+ * @param uuid The UUID of the piece to move.
+ * @param curIndex The current index of the piece.
+ * @param moveIndex The target index to move the piece to.
+ */
private void movePieceRek(UUID uuid, int curIndex, int moveIndex){
if (curIndex == moveIndex) return;
@@ -211,6 +286,12 @@ private Vector3f getWaitingPos(Color color){
return getMeanPosition(waitingNodesMap.get(color).stream().map(NodeControl::getLocation).toList());
}
+ /**
+ * Gets the mean position of a list of vectors.
+ *
+ * @param vectors The list of vectors.
+ * @return The mean position as a Vector3f.
+ */
public static Vector3f getMeanPosition(List vectors) {
if (vectors.isEmpty()) return new Vector3f(0, 0, 0);
@@ -221,7 +302,13 @@ public static Vector3f getMeanPosition(List vectors) {
return sum.divide(vectors.size());
}
- //public methods****************************************************************************************************
+ /**
+ * Adds a player to the game by associating a color and a list of UUIDs to corresponding assets and waiting nodes.
+ *
+ * @param color the color of the player
+ * @param uuid the list of UUIDs representing the player's assets
+ * @throws RuntimeException if the number of assets or waiting nodes does not match the provided UUIDs
+ */
public void addPlayer(Color color, List uuid) {
List playerAssets = colorAssetsMap.get(color);
@@ -254,7 +341,14 @@ public void addPlayer(Color color, List uuid) {
}
}
- public void moveHomePiece(UUID uuid, int index){
+ /**
+ * Moves a piece to its corresponding home node based on the given index.
+ *
+ * @param uuid the UUID of the piece to move
+ * @param index the index of the home node to move the piece to
+ * @throws RuntimeException if the UUID is not mapped to a color or if the home nodes are not properly defined
+ */
+ private void moveHomePiece(UUID uuid, int index){
Color color = pieceColor.get(uuid);
if(color == null) throw new RuntimeException("uuid is not mapped to a color");
@@ -275,7 +369,15 @@ public void moveHomePiece(UUID uuid, int index){
app.getModelSynchronize().animationEnd();
}
- public void movePieceStart(UUID uuid, int nodeIndex){
+ /**
+ * Starts the movement of a piece to a target node based on the given index.
+ *
+ * @param uuid the UUID of the piece to move
+ * @param nodeIndex the index of the target node to move the piece to
+ * @throws RuntimeException if the UUID is not mapped to a color or the piece control is not found
+ * @throws IllegalArgumentException if the node index is invalid
+ */
+ private void movePieceStart(UUID uuid, int nodeIndex){
// Farbe des Pieces abrufen
Color color = pieceColor.get(uuid);
@@ -298,13 +400,26 @@ public void movePieceStart(UUID uuid, int nodeIndex){
app.getModelSynchronize().animationEnd();
}
- public void movePiece(UUID uuid, int curIndex, int moveIndex){
+ /**
+ * Moves a piece from its current position to the target position based on the given indexes.
+ *
+ * @param uuid the UUID of the piece to move
+ * @param curIndex the current index of the piece
+ * @param moveIndex the target index of the move
+ */
+ private void movePiece(UUID uuid, int curIndex, int moveIndex){
movePieceRek(uuid, curIndex, moveIndex);
app.getModelSynchronize().animationEnd();
}
- public void throwPiece(UUID uuid){
+ /**
+ * Throws a piece to the next available waiting node and updates the waiting node mapping.
+ *
+ * @param uuid the UUID of the piece to throw
+ * @throws RuntimeException if the UUID is not mapped to a color or if no available waiting nodes are found
+ */
+ private void throwPiece(UUID uuid){
// Farbe des Pieces abrufen
Color color = pieceColor.get(uuid);
@@ -331,59 +446,65 @@ public void throwPiece(UUID uuid){
app.getModelSynchronize().animationEnd();
}
+
+ /**
+ * Activates the shield for the specified piece.
+ *
+ * @param uuid the UUID of the piece to shield
+ */
public void shieldPiece(UUID uuid){
pieces.get(uuid).activateShield();
}
+ /**
+ * Deactivates the shield for the specified piece.
+ *
+ * @param uuid the UUID of the piece to unshield
+ */
public void unshieldPiece(UUID uuid){
pieces.get(uuid).deactivateShield();
}
+ /**
+ * Suppresses the shield for the specified piece.
+ *
+ * @param uuid the UUID of the piece to suppress the shield
+ */
public void suppressShield(UUID uuid){
pieces.get(uuid).suppressShield();
}
- public void swapPieces(PieceControl p1, PieceControl p2, Vector3f loc1, float rot1, Vector3f loc2, float rot2){
-
-// PieceControl piece1Control = pieces.get(piece1);
-// PieceControl piece2Control = pieces.get(piece2);
-
-// if(piece1Control == null) throw new RuntimeException("piece1 UUID is not valid");
-// if(piece2Control == null) throw new RuntimeException("piece2 UUID is not valid");
-
-// float rot1 = piece1Control.getRotation();
-// float rot2 = piece2Control.getRotation();
-
-// piece1Control.setRotation(rot2);
-// piece2Control.setRotation(rot1);
-
-// Vector3f pos1 = piece1Control.getLocation().clone();
-// Vector3f pos2 = piece2Control.getLocation().clone();
-
-// piece1Control.setLocation(pos2);
-// piece2Control.setLocation(pos1);
-
+ /**
+ * Swaps the positions and rotations of two pieces.
+ *
+ * @param p1 the first piece to swap
+ * @param p2 the second piece to swap
+ * @param loc1 the original location of the first piece
+ * @param rot1 the original rotation of the first piece
+ * @param loc2 the original location of the second piece
+ * @param rot2 the original rotation of the second piece
+ */
+ private void swapPieces(PieceControl p1, PieceControl p2, Vector3f loc1, float rot1, Vector3f loc2, float rot2){
p1.setLocation(loc2);
p2.setLocation(loc1);
p1.setRotation(rot2);
p2.setRotation(rot1);
-
app.getModelSynchronize().animationEnd();
}
- public void highlight(UUID uuid, boolean bool){
-
- pieces.get(uuid).highlight(bool);
- pieces.get(uuid).setSelectable(bool);
-
- }
-
- //called when (dice) moveNum is received from server to display the movable pieces and corresponding moveNodes
+ /**
+ * Outlines the possible move nodes for a list of pieces based on the move indices and whether it's a home move.
+ *
+ * @param pieces the list of UUIDs representing the pieces to outline
+ * @param moveIndexe the list of indices for the target move nodes
+ * @param homeMoves the list indicating whether the move is a home move
+ * @throws RuntimeException if the sizes of the input lists do not match
+ */
public void outlineMove(List pieces, List moveIndexe, List homeMoves) {
if(pieces.size() != moveIndexe.size() || pieces.size() != homeMoves.size()) throw new RuntimeException("arrays are not the same size");
@@ -413,7 +534,12 @@ public void outlineMove(List pieces, List moveIndexe, List ownPieces, List enemyPieces){
selectableEnemyPieces.clear();
@@ -437,6 +563,11 @@ public void outlineSwap(List ownPieces, List enemyPieces){
}
}
+ /**
+ * Outlines the pieces that can be shielded based on the provided list of pieces.
+ *
+ * @param pieces the list of UUIDs representing the pieces to be shielded
+ */
public void outlineShield(List pieces){
selectableOwnPieces.clear();
selectableEnemyPieces.clear();
@@ -452,7 +583,11 @@ public void outlineShield(List pieces){
}
}
- //called from inputSynchronizer when a piece is selectable
+ /**
+ * Selects a piece from either the own or enemy pieces based on the input and deselects others if needed.
+ *
+ * @param pieceSelected the PieceControl instance representing the piece selected by the user
+ */
public void pieceSelect(PieceControl pieceSelected) {
boolean isSelected = pieceSelected.isSelected();
if(selectableOwnPieces.contains(pieceSelected)){
@@ -486,7 +621,9 @@ else if(selectableEnemyPieces.contains(pieceSelected)) {
app.getModelSynchronize().select(getKeyByValue(pieces, selectedOwnPiece), getKeyByValue(pieces, selectedEnemyPiece));
}
- //called when view is no longer needed to select pieces
+ /**
+ * Clears all highlighted, selectable, and selected pieces and nodes.
+ */
public void clearSelectable(){
for(PieceControl p : selectableEnemyPieces) {
p.unSelect();
@@ -508,16 +645,20 @@ public void clearSelectable(){
selectedOwnPiece = null;
}
- public void enableHover(UUID uuid){
- pieces.get(uuid).setHoverable(true);
- }
-
+ /**
+ * Displays the dice for the specified color at the appropriate position.
+ *
+ * @param color the color of the player whose dice should be displayed
+ */
public void showDice(Color color){
rootNodeBoard.attachChild(diceControl.getSpatial());
diceControl.setPos(getWaitingPos(color).add(new Vector3f(0,0,4)));
diceControl.spin();
}
+ /**
+ * Hides the dice from the view.
+ */
public void hideDice(){
diceControl.hide();
}
@@ -531,6 +672,13 @@ private K getKeyByValue(Map map, V value) {
return null;
}
+ /**
+ * Animates the movement of a piece from its current index to a target index.
+ *
+ * @param uuid the UUID of the piece to animate
+ * @param curIndex the current index of the piece
+ * @param moveIndex the target index to animate the piece to
+ */
public void movePieceAnim(UUID uuid, int curIndex, int moveIndex){
pieces.get(uuid).getSpatial().addControl(new MoveControl(
infield.get(curIndex).getLocation(),
@@ -538,6 +686,12 @@ public void movePieceAnim(UUID uuid, int curIndex, int moveIndex){
()->movePiece(uuid,curIndex,moveIndex)));
}
+ /**
+ * Animates the movement of a piece to its home position based on the given home index.
+ *
+ * @param uuid the UUID of the piece to animate
+ * @param homeIndex the index of the home node to move the piece to
+ */
public void movePieceHomeAnim(UUID uuid, int homeIndex){
pieces.get(uuid).getSpatial().addControl(new MoveControl(
pieces.get(uuid).getLocation(),
@@ -545,6 +699,12 @@ public void movePieceHomeAnim(UUID uuid, int homeIndex){
()->moveHomePiece(uuid,homeIndex)));
}
+ /**
+ * Animates the start of the movement of a piece to a target index.
+ *
+ * @param uuid the UUID of the piece to animate
+ * @param moveIndex the target index to animate the piece to
+ */
public void movePieceStartAnim(UUID uuid, int moveIndex){
pieces.get(uuid).getSpatial().addControl(new MoveControl(
pieces.get(uuid).getLocation(),
@@ -553,6 +713,11 @@ public void movePieceStartAnim(UUID uuid, int moveIndex){
));
}
+ /**
+ * Animates the throwing of a piece to the next available waiting node.
+ *
+ * @param uuid the UUID of the piece to animate
+ */
public void throwPieceAnim(UUID uuid){
pieces.get(uuid).getSpatial().addControl(new MoveControl(
pieces.get(uuid).getLocation(),
@@ -561,6 +726,12 @@ public void throwPieceAnim(UUID uuid){
));
}
+ /**
+ * Animates the swapping of two pieces by swapping their positions and rotations.
+ *
+ * @param piece1 the UUID of the first piece
+ * @param piece2 the UUID of the second piece
+ */
public void swapPieceAnim(UUID piece1, UUID piece2){
PieceControl piece1Control = pieces.get(piece1);
PieceControl piece2Control = pieces.get(piece2);
@@ -582,6 +753,13 @@ public void swapPieceAnim(UUID piece1, UUID piece2){
));
}
+ /**
+ * Retrieves the next available waiting node for the specified color.
+ *
+ * @param color the color of the player to get the next waiting node for
+ * @return the next available NodeControl for the specified color
+ * @throws IllegalStateException if no available waiting nodes are found for the color
+ */
private NodeControl getNextWaitingNode(Color color) {
List nodes = waitingNodesMap.get(color);
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/CameraHandler.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/CameraHandler.java
index c0469eef..57da8393 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/CameraHandler.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/CameraHandler.java
@@ -15,6 +15,10 @@
import pp.mdga.client.MdgaApp;
import pp.mdga.game.Color;
+/**
+ * Handles the camera position, rotation, and lighting effects for the game.
+ * Provides methods for camera initialization, updates based on user input, and shutdown operations.
+ */
public class CameraHandler {
MdgaApp app;
@@ -34,6 +38,12 @@ public class CameraHandler {
private boolean init;
private boolean initRot;
+ /**
+ * Constructor for the CameraHandler. Initializes the camera settings and lighting.
+ *
+ * @param app The main application instance that provides the camera and root node.
+ * @param fpp The FilterPostProcessor used for post-processing effects.
+ */
public CameraHandler(MdgaApp app, FilterPostProcessor fpp) {
init = false;
initRot = false;
@@ -61,6 +71,12 @@ public CameraHandler(MdgaApp app, FilterPostProcessor fpp) {
}
+ /**
+ * Initializes the camera with a specific color orientation.
+ * Adds lights, sky, and shadow filters to the scene.
+ *
+ * @param ownColor The color that defines the initial camera view angle.
+ */
public void init(Color ownColor) {
app.getRootNode().addLight(sun);
app.getRootNode().addLight(ambient);
@@ -72,6 +88,10 @@ public void init(Color ownColor) {
app.getInputSynchronize().setRotation(getInitAngleByColor(ownColor)*2);
}
+ /**
+ * Shuts down the camera handler by removing all lights, sky, and filters,
+ * and resets the camera position and rotation to its default state.
+ */
public void shutdown() {
app.getRootNode().removeLight(sun);
app.getRootNode().removeLight(ambient);
@@ -84,6 +104,13 @@ public void shutdown() {
fpp.removeFilter(dlsf);
}
+ /**
+ * Updates the camera position and rotation based on user input (scroll and rotation).
+ * Adjusts the vertical angle and radius based on zoom and rotation values.
+ *
+ * @param scroll The scroll input, determining zoom level.
+ * @param rotation The rotation input, determining camera orientation.
+ */
public void update(float scroll, float rotation) {
if(!init) return;
float scrollValue = Math.max(0, Math.min(scroll, 100));
@@ -117,6 +144,12 @@ public void update(float scroll, float rotation) {
app.getCamera().lookAt(Vector3f.ZERO, Vector3f.UNIT_Z);
}
+ /**
+ * Returns the camera angle based on the specified color.
+ *
+ * @param color The color used to determine the camera angle.
+ * @return The camera angle in degrees.
+ */
private float getAngleByColor(Color color){
return switch (color){
case ARMY -> 0;
@@ -127,6 +160,12 @@ private float getAngleByColor(Color color){
};
}
+ /**
+ * Returns the initial camera angle based on the specified color.
+ *
+ * @param color The color used to determine the camera angle.
+ * @return The initial camera angle in degrees.
+ */
private float getInitAngleByColor(Color color){
return (getAngleByColor(color) + 180) % 360;
}
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/MapLoader.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/MapLoader.java
index c85a7dcc..9d283f8f 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/MapLoader.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/MapLoader.java
@@ -10,11 +10,27 @@
import java.util.ArrayList;
import java.util.List;
+/**
+ * A utility class for loading and parsing map data from a file.
+ * The map contains asset names and coordinates for objects placed on the map.
+ */
class MapLoader {
+ /**
+ * Private constructor to prevent instantiation.
+ */
private MapLoader() {
}
+ /**
+ * Loads a map file and parses its contents into a list of assets and their positions.
+ * Each line in the map file defines an asset, its coordinates, and its rotation.
+ *
+ * @param mapName The name of the map file to load. The file is expected to be located in the resources directory.
+ * @return A list of {@link AssetOnMap} objects representing the assets placed on the map.
+ * @throws IOException If an error occurs while reading the map file.
+ * @throws IllegalArgumentException If the map file contains invalid data.
+ */
public static List loadMap(String mapName) {
List assetsOnMap = new ArrayList<>();
@@ -60,6 +76,13 @@ public static List loadMap(String mapName) {
return assetsOnMap;
}
+ /**
+ * Returns the corresponding {@link Asset} for a given asset name.
+ *
+ * @param assetName The name of the asset to load.
+ * @return The {@link Asset} associated with the given name.
+ * @throws IllegalStateException If the asset name is unrecognized.
+ */
private static Asset getLoadedAsset(String assetName) {
return switch (assetName) {
case "lw" -> Asset.lw;
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/NodeControl.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/NodeControl.java
index 5288b537..d3f1d80e 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/NodeControl.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/NodeControl.java
@@ -8,19 +8,40 @@
import com.jme3.scene.control.AbstractControl;
import pp.mdga.client.MdgaApp;
+/**
+ * A control that adds highlighting functionality to a node in the game.
+ * This class extends {@link OutlineControl} to add an outline effect when the node is highlighted.
+ */
public class NodeControl extends OutlineControl {
private static final ColorRGBA OUTLINE_HIGHLIGHT_COLOR = ColorRGBA.White;
private static final int OUTLINE_HIGHLIGHT_WIDTH = 6;
+ /**
+ * Constructs a {@link NodeControl} with the specified application and post processor.
+ * This constructor sets up the necessary elements for highlighting functionality.
+ *
+ * @param app The {@link MdgaApp} instance to use for the application context.
+ * @param fpp The {@link FilterPostProcessor} to apply post-processing effects.
+ */
public NodeControl(MdgaApp app, FilterPostProcessor fpp) {
super(app, fpp);
}
+ /**
+ * Returns the location of the node in 3D space.
+ * This is the node's local translation in the scene.
+ *
+ * @return The {@link Vector3f} representing the node's location.
+ */
public Vector3f getLocation(){
return this.getSpatial().getLocalTranslation();
}
+ /**
+ * Highlights the node by applying an outline effect.
+ * The outline color and width are predefined as white and 6, respectively.
+ */
public void highlight() {
super.outline(OUTLINE_HIGHLIGHT_COLOR, OUTLINE_HIGHLIGHT_WIDTH);
}
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/OutlineControl.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/OutlineControl.java
index 9444e841..f0dfba51 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/OutlineControl.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/OutlineControl.java
@@ -3,16 +3,19 @@
import com.jme3.math.ColorRGBA;
import com.jme3.post.FilterPostProcessor;
import com.jme3.renderer.Camera;
-import com.jme3.renderer.RenderManager;
-import com.jme3.renderer.ViewPort;
-import com.jme3.scene.Spatial;
-import com.jme3.scene.control.AbstractControl;
import pp.mdga.client.MdgaApp;
+import pp.mdga.client.InitControl;
import pp.mdga.client.outline.SelectObjectOutliner;
-public class OutlineControl extends AbstractControl {
- private static final int THICKNESS_DEFAULT = 6;
+/**
+ * A control that provides outline functionality to a spatial object.
+ * This class is responsible for adding an outline effect to a spatial
+ * object, allowing it to be highlighted or deselected.
+ */
+public class OutlineControl extends InitControl {
+ /** The {@link SelectObjectOutliner} responsible for managing the outline effect. */
private final SelectObjectOutliner outlineOwn;
+ private static final int THICKNESS_DEFAULT = 6;
private MdgaApp app;
@@ -31,44 +34,33 @@ public OutlineControl(MdgaApp app, FilterPostProcessor fpp, Camera cam, int thic
outlineOwn = new SelectObjectOutliner(thickness, fpp, app.getRenderManager(), app.getAssetManager(), cam, app);
}
+ /**
+ * Applies an outline to the spatial object with the given color.
+ *
+ * @param color The {@link ColorRGBA} representing the color of the outline.
+ */
public void outline(ColorRGBA color){
outlineOwn.select(spatial, color);
}
+ /**
+ * Applies an outline to the spatial object with the given color and width.
+ *
+ * @param color The {@link ColorRGBA} representing the color of the outline.
+ * @param width The width of the outline.
+ */
public void outline(ColorRGBA color, int width){
deOutline();
outlineOwn.select(spatial, color, width);
}
+ /**
+ * Removes the outline effect from the spatial object.
+ */
public void deOutline(){
outlineOwn.deselect(spatial);
}
- @Override
- protected void controlUpdate(float tpf) {
-
- }
-
- @Override
- protected void controlRender(RenderManager rm, ViewPort vp) {
-
- }
-
- public void initSpatial(){
-
- }
-
- @Override
- public void setSpatial(Spatial spatial){
- if(this.spatial == null && spatial != null){
- super.setSpatial(spatial);
- initSpatial();
- }
- else{
- super.setSpatial(spatial);
- }
- }
-
public MdgaApp getApp() {
return app;
}
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/PieceControl.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/PieceControl.java
index d9b22030..4a75533d 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/PieceControl.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/PieceControl.java
@@ -14,6 +14,12 @@
import pp.mdga.client.Asset;
import pp.mdga.client.MdgaApp;
+/**
+ * A control that manages the behavior and properties of a game piece, such as its rotation,
+ * position, shield activation, and highlighting. This class extends {@link OutlineControl}
+ * to provide outline functionality and includes additional features like shield effects,
+ * hover states, and selection states.
+ */
public class PieceControl extends OutlineControl {
private final float initRotation;
private final AssetManager assetManager;
@@ -43,7 +49,15 @@ public class PieceControl extends OutlineControl {
private boolean selectable;
private boolean select;
-
+ /**
+ * Constructs a {@link PieceControl} with the specified initial rotation, asset manager,
+ * application, and post-processor.
+ *
+ * @param initRotation The initial rotation of the piece in degrees.
+ * @param assetManager The {@link AssetManager} used for loading models and materials.
+ * @param app The {@link MdgaApp} instance to use for the application context.
+ * @param fpp The {@link FilterPostProcessor} to apply post-processing effects.
+ */
public PieceControl(float initRotation, AssetManager assetManager, MdgaApp app, FilterPostProcessor fpp){
super(app, fpp);
this.parentNode = new Node();
@@ -59,10 +73,20 @@ public PieceControl(float initRotation, AssetManager assetManager, MdgaApp app,
select = false;
}
+ /**
+ * Gets the current rotation of the piece in degrees.
+ *
+ * @return The rotation of the piece in degrees.
+ */
public float getRotation() {
return (float) Math.toDegrees(spatial.getLocalRotation().toAngleAxis(new Vector3f(0,0,1)));
}
+ /**
+ * Sets the rotation of the piece to the specified value in degrees.
+ *
+ * @param rot The rotation in degrees to set.
+ */
public void setRotation(float rot){
if(rot < 0) rot =- 360;
@@ -71,10 +95,20 @@ public void setRotation(float rot){
spatial.setLocalRotation(quaternion);
}
+ /**
+ * Gets the current location (position) of the piece.
+ *
+ * @return The location of the piece as a {@link Vector3f}.
+ */
public Vector3f getLocation(){
return spatial.getLocalTranslation();
}
+ /**
+ * Updates the piece control every frame. If the shield is active, it will rotate.
+ *
+ * @param delta The time difference between frames (time per frame).
+ */
@Override
protected void controlUpdate(float delta) {
if(shieldRing != null){
@@ -82,10 +116,19 @@ protected void controlUpdate(float delta) {
}
}
+ /**
+ * Sets the location (position) of the piece.
+ *
+ * @param loc The location to set as a {@link Vector3f}.
+ */
public void setLocation(Vector3f loc){
this.spatial.setLocalTranslation(loc);
}
+ /**
+ * Initializes the spatial object and sets its rotation.
+ * This also moves the spatial to a new parent node for organizational purposes.
+ */
@Override
public void initSpatial(){
setRotation(this.initRotation);
@@ -101,6 +144,10 @@ public void rotateInit() {
// rotate(rotation - initRotation);
}
+ /**
+ * Activates the shield around the piece.
+ * This adds a visual shield effect in the form of a rotating ring.
+ */
public void activateShield(){
shieldRing = assetManager.loadModel(Asset.shieldRing.getModelPath());
shieldRing.scale(1f);
@@ -115,11 +162,18 @@ public void activateShield(){
parentNode.attachChild(shieldRing);
}
+ /**
+ * Deactivates the shield by removing the shield ring from the scene.
+ */
+
public void deactivateShield(){
parentNode.detachChild(shieldRing);
shieldRing = null;
}
+ /**
+ * Suppresses the shield, changing its color to a suppressed state.
+ */
public void suppressShield(){
assert(shieldRing != null) : "PieceControl: shieldRing is not set";
shieldMat.setColor("Color", SHIELD_SUPPRESSED_COLOR);
@@ -133,22 +187,36 @@ public Material getMaterial(){
return ((Geometry) getSpatial()).getMaterial();
}
+ /**
+ * Highlights the piece with the appropriate outline color based on whether it is an enemy or not.
+ *
+ * @param enemy True if the piece is an enemy, false if it is owned by the player.
+ */
public void highlight(boolean enemy) {
this.enemy = enemy;
highlight = true;
super.outline(enemy ? OUTLINE_ENEMY_COLOR : OUTLINE_OWN_COLOR, OUTLINE_HIGHLIGHT_WIDTH);
}
+ /**
+ * Removes the highlight effect from the piece.
+ */
public void unHighlight(){
highlight = false;
deOutline();
}
+ /**
+ * Applies a hover effect on the piece if it is hoverable.
+ */
public void hover(){
if(!hoverable) return;
super.outline(enemy ? OUTLINE_ENEMY_HOVER_COLOR : OUTLINE_OWN_HOVER_COLOR, OUTLINE_HOVER_WIDTH);
}
+ /**
+ * Removes the hover effect from the piece.
+ */
public void hoverOff(){
if(!hoverable) return;
@@ -157,28 +225,56 @@ public void hoverOff(){
else deOutline();
}
+ /**
+ * Deselects the piece and removes the selection outline. If the piece was highlighted,
+ * it will be re-highlighted. Otherwise, the outline is removed.
+ */
public void unSelect(){
select = false;
if(highlight) highlight(enemy);
else deOutline();
}
+ /**
+ * Selects the piece and applies the selection outline. If the piece is an enemy, it will
+ * be outlined with the enemy selection color; otherwise, the own selection color will be used.
+ */
public void select(){
if(!selectable) return;
select = true;
super.outline(enemy ? OUTLINE_ENEMY_SELECT_COLOR : OUTLINE_OWN_SELECT_COLOR, OUTLINE_SELECT_WIDTH);
}
+ /**
+ * Sets whether the piece is selectable.
+ *
+ * @param selectable True if the piece can be selected, false otherwise.
+ */
public void setSelectable(boolean selectable){
this.selectable = selectable;
}
+ /**
+ * Checks if the piece is selected.
+ *
+ * @return True if the piece is selected, false otherwise.
+ */
public boolean isSelected() { return select; }
+ /**
+ * Checks if the piece is selectable.
+ *
+ * @return True if the piece is selectable, false otherwise.
+ */
public boolean isSelectable() {
return selectable;
}
+ /**
+ * Sets whether the piece is hoverable.
+ *
+ * @param hoverable True if the piece can be hovered over, false otherwise.
+ */
public void setHoverable(boolean hoverable) {
this.hoverable = hoverable;
}
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/PileControl.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/PileControl.java
deleted file mode 100644
index f4e604c6..00000000
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/PileControl.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package pp.mdga.client.board;
-
-class PileControl {
-
-}
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/Rotation.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/Rotation.java
deleted file mode 100644
index 5db07057..00000000
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/Rotation.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package pp.mdga.client.board;
-
-public enum Rotation {
- UP,
- RIGHT,
- DOWN,
- LEFT,
- UP_LEFT,
- UP_RIGHT,
- DOWN_RIGHT,
- DOWN_LEFT
-}
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/view/GameView.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/view/GameView.java
index 41a2b412..9d1a7fe5 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/view/GameView.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/view/GameView.java
@@ -64,6 +64,9 @@ public void onEnter() {
app.getViewPort().addProcessor(fpp);
app.getAcousticHandler().playSound(MdgaSound.START);
+
+ app.getNotificationSynchronizer().addTestNotification(new AcquireCardNotification(BonusCard.SHIELD));
+ app.getNotificationSynchronizer().addTestNotification(new SelectableCardsNotification(List.of(BonusCard.SHIELD)));
}
@Override
From 206cad2f79a0cac452474161a894f2e8164749a7 Mon Sep 17 00:00:00 2001
From: Cedric Beck
Date: Mon, 2 Dec 2024 11:01:02 +0100
Subject: [PATCH 14/28] removed test card
---
.../mdga/client/src/main/java/pp/mdga/client/view/GameView.java | 2 --
1 file changed, 2 deletions(-)
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/view/GameView.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/view/GameView.java
index 9d1a7fe5..665f6212 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/view/GameView.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/view/GameView.java
@@ -65,8 +65,6 @@ public void onEnter() {
app.getAcousticHandler().playSound(MdgaSound.START);
- app.getNotificationSynchronizer().addTestNotification(new AcquireCardNotification(BonusCard.SHIELD));
- app.getNotificationSynchronizer().addTestNotification(new SelectableCardsNotification(List.of(BonusCard.SHIELD)));
}
@Override
From bb1b721e77b78fdb65af2e1709200d4d5d840857 Mon Sep 17 00:00:00 2001
From: Felix Koppe
Date: Mon, 2 Dec 2024 11:48:54 +0100
Subject: [PATCH 15/28] Fix lobby in serverAutomaton and adjust
TskUpdateMessage
---
.../src/main/java/pp/mdga/client/MdgaApp.java | 2 +-
.../pp/mdga/client/ModelSynchronizer.java | 4 +-
.../mdga/client/NotificationSynchronizer.java | 1 -
.../mdga/client/acoustic/AcousticHandler.java | 373 ++++++++++++++----
.../java/pp/mdga/client/view/LobbyView.java | 19 +-
.../java/pp/mdga/client/ClientGameLogic.java | 4 +
.../mdga/client/dialogState/LobbyState.java | 8 +-
.../mdga/message/server/UpdateTSKMessage.java | 11 +-
.../pp/mdga/server/automaton/LobbyState.java | 10 +-
9 files changed, 351 insertions(+), 81 deletions(-)
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java
index 5aa92fc0..cb0371c0 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java
@@ -106,7 +106,7 @@ public void simpleInitApp() {
gameView = new GameView(this);
ceremonyView = new CeremonyView(this);
- enter(MdgaState.GAME);
+ enter(MdgaState.MAIN);
}
/**
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/ModelSynchronizer.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/ModelSynchronizer.java
index e1c1b987..0b26a305 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/ModelSynchronizer.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/ModelSynchronizer.java
@@ -107,8 +107,8 @@ public void selectTsk(Color color) {
app.getGameLogic().selectTsk(color);
}
- public void unselectTsk() {
- app.getGameLogic().selectTsk(Color.NONE);
+ public void unselectTsk(Color color) {
+ app.getGameLogic().deselectTSK(color);
}
public void rolledDice() {
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/NotificationSynchronizer.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/NotificationSynchronizer.java
index b943e955..6e080158 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/NotificationSynchronizer.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/NotificationSynchronizer.java
@@ -60,7 +60,6 @@ private void handleLobby(Notification notification) {
if (notification instanceof TskSelectNotification n) {
lobbyView.setTaken(n.getColor(), true, n.isSelf(), n.getName());
- lobbyView.setTaken(n.getColor(), true, false, n.getName());
} else if (notification instanceof StartDialogNotification) {
app.enter(MdgaState.MAIN);
} else if (notification instanceof TskUnselectNotification n) {
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/acoustic/AcousticHandler.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/acoustic/AcousticHandler.java
index efab4407..264197d4 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/acoustic/AcousticHandler.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/acoustic/AcousticHandler.java
@@ -7,46 +7,41 @@
import java.util.*;
import java.util.prefs.Preferences;
-/**
- * Handles the acoustic functionality for the game, including music playback, sound effects,
- * volume management, and transitions between game states.
- */
public class AcousticHandler {
- private MdgaApp app; // Reference to the main application
- private MdgaState state = MdgaState.NONE; // Current state of the game
- private boolean playGame = false; // Whether the game tracks are currently playing
- private ArrayList gameTracks = new ArrayList<>(); // List of available game music tracks
- private NanoTimer trackTimer = new NanoTimer(); // Timer for managing track transitions
+ private MdgaApp app;
- private boolean fading = false; // Whether a fade transition is in progress
- private NanoTimer fadeTimer = new NanoTimer(); // Timer for fade transitions
- private static final float FADE_DURATION = 3.0f; // Duration of fade-out
- private static final float CROSSFADE_DURATION = 1.5f; // Duration of fade-in
- private GameMusic playing = null; // Currently playing music track
- private GameMusic scheduled = null; // Track scheduled to play next
- private GameMusic old = null; // Track being faded out
+ private MdgaState state = MdgaState.NONE;
- private float mainVolume = 0.0f; // Main volume level
- private float musicVolume = 1.0f; // Music volume level
- private float soundVolume = 1.0f; // Sound effects volume level
+ private boolean playGame = false;
+ private ArrayList gameTracks = new ArrayList<>();
+ private NanoTimer trackTimer = new NanoTimer();
- private ArrayList sounds = new ArrayList<>(); // List of active sound effects
- private Preferences prefs = Preferences.userNodeForPackage(AcousticHandler.class); // User preferences for volume settings
+ private boolean fading = false; // Indicates if a fade is in progress
+ private NanoTimer fadeTimer = new NanoTimer(); // Timer to track fade progress
+ private static final float FADE_DURATION = 3.0f; // Duration for outfade
+ private static final float CROSSFADE_DURATION = 1.5f; // Duration for infade
+ private GameMusic playing = null; // Currently playing track
+ private GameMusic scheduled = null; // Scheduled track to play next
+ private GameMusic old = null; // Old track being faded out
+
+ private float mainVolume = 0.0f;
+ private float musicVolume = 1.0f;
+ private float soundVolume = 1.0f;
+
+ private ArrayList sounds = new ArrayList<>();
+
+ private Preferences prefs = Preferences.userNodeForPackage(AcousticHandler.class);
- /**
- * Initializes the AcousticHandler with the main application and loads user volume settings.
- *
- * @param app The main application instance.
- */
public AcousticHandler(MdgaApp app) {
this.app = app;
+
mainVolume = prefs.getFloat("mainVolume", 1.0f);
musicVolume = prefs.getFloat("musicVolume", 1.0f);
soundVolume = prefs.getFloat("soundVolume", 1.0f);
}
/**
- * Updates the state of the AcousticHandler. Should be called every frame.
+ * This method updates the acousticHandler and should be called every frame
*/
public void update() {
updateVolumeAndTrack();
@@ -58,7 +53,9 @@ public void update() {
Iterator iterator = sounds.iterator();
while (iterator.hasNext()) {
GameSound s = iterator.next();
+
s.update(getSoundVolumeTotal());
+
if (!s.isPlaying()) {
iterator.remove();
}
@@ -66,76 +63,314 @@ public void update() {
}
/**
- * Plays a sound effect immediately.
+ * This method instantly plays a sound
*
- * @param sound The sound effect to play.
+ * @param sound the sound to be played
*/
public void playSound(MdgaSound sound) {
- // Implementation for playing predefined sound effects based on game events
+ ArrayList assets = new ArrayList();
+ switch (sound) {
+ case LOST:
+ assets.add(new SoundAssetDelayVolume(SoundAsset.LOST, 1.0f, 0.0f));
+ break;
+ case VICTORY:
+ assets.add(new SoundAssetDelayVolume(SoundAsset.VICTORY, 1.0f, 0.0f));
+ break;
+ case BUTTON_PRESSED:
+ assets.add(new SoundAssetDelayVolume(SoundAsset.BUTTON_PRESS, 0.7f, 0.0f));
+ break;
+ case WRONG_INPUT:
+ assets.add(new SoundAssetDelayVolume(SoundAsset.ERROR, 1.0f, 0.0f));
+ break;
+ case UI_CLICK:
+ assets.add(new SoundAssetDelayVolume(SoundAsset.UI_CLICK, 0.8f, 0.0f));
+ break;
+ case START:
+ assets.add(new SoundAssetDelayVolume(SoundAsset.START, 0.8f, 0.5f));
+ break;
+ case THROW:
+ assets.add(new SoundAssetDelayVolume(SoundAsset.LAUGHT, 1.0f, 0.2f));
+ break;
+ case POWERUP:
+ assets.add(new SoundAssetDelayVolume(SoundAsset.POWERUP, 1.0f, 0.2f));
+ break;
+ case SELF_READY:
+ assets.add(new SoundAssetDelayVolume(SoundAsset.ROBOT_READY, 1.0f, 0.0f));
+ break;
+ case OTHER_READY:
+ assets.add(new SoundAssetDelayVolume(SoundAsset.UNIT_READY, 1.0f, 0.0f));
+ break;
+ case OTHER_CONNECTED:
+ assets.add(new SoundAssetDelayVolume(SoundAsset.CONNECTED, 1.0f, 0.0f));
+ break;
+ case NOT_READY:
+ assets.add(new SoundAssetDelayVolume(SoundAsset.UI_SOUND, 1.0f, 0.0f));
+ break;
+ case LEAVE:
+ assets.add(new SoundAssetDelayVolume(SoundAsset.UI_SOUND2, 0.6f, 0.0f));
+ break;
+ default:
+ break;
+ }
+
+ for (SoundAssetDelayVolume sawd : assets) {
+ GameSound gameSound = new GameSound(app, sawd.asset(), getSoundVolumeTotal(), sawd.subVolume(), sawd.delay());
+ sounds.add(gameSound);
+ }
}
/**
- * Transitions music playback to match the specified game state.
+ * This method fades the played music to fit the state.
*
- * @param state The new game state.
+ * @param state the state of which the corresponding music should be played to be played
*/
public void playState(MdgaState state) {
- // Implementation for managing state-specific music playback
+ if (this.state == state) {
+ return;
+ }
+ MusicAsset asset = null;
+
+ switch (state) {
+ case MAIN:
+ playGame = false;
+ asset = MusicAsset.MAIN_MENU;
+ break;
+ case LOBBY:
+ playGame = false;
+ asset = MusicAsset.LOBBY;
+ break;
+ case GAME:
+ addGameTracks();
+ playGame = true;
+ assert (!gameTracks.isEmpty()) : "no more game music available";
+ asset = gameTracks.remove(0);
+ break;
+ case CEREMONY:
+ playGame = false;
+ asset = MusicAsset.CEREMONY;
+ break;
+ case NONE:
+ throw new RuntimeException("no music for state NONE");
+ }
+
+ assert (null != asset) : "music sceduling went wrong";
+
+ scheduled = new GameMusic(app, asset, getMusicVolumeTotal(), asset.getSubVolume(), asset.getLoop(), 0.0f);
}
/**
- * Performs linear interpolation between two values.
+ * Performs linear interpolation between two float values.
*
* @param start The starting value.
* @param end The ending value.
- * @param t The interpolation factor (0 to 1).
- * @return The interpolated value.
+ * @param t The interpolation factor, typically between 0 and 1.
+ * @return The interpolated value between start and end.
*/
private float lerp(float start, float end, float t) {
return start + t * (end - start);
}
/**
- * Manages audio playback transitions and volume adjustments.
+ * Updates the state of audio playback, handling track transitions and volume adjustments.
+ *
+ * This method ensures smooth transitions between tracks using fade-in and fade-out effects.
+ * It also handles cases where no track is playing, starting a scheduled track immediately at full volume.
+ * The method prioritizes the latest scheduled track if multiple scheduling occurs quickly.
+ *
+ * Behavior:
+ * 1. If nothing is scheduled and no track is playing, it exits early.
+ * 2. If a scheduled track exists and no track is playing, the scheduled track starts immediately at full volume.
+ * 3. If a scheduled track exists while a track is playing, it initiates a fade-out for the currently playing track
+ * and prepares for the new track to fade in.
+ * 4. If a track transition is in progress (fading), it processes the fade-out and fade-in states.
+ * If a new track is scheduled during this process, it interrupts the current transition and prioritizes the new track.
+ * 5. If no fading is needed and a track is playing, it ensures the track's volume is updated.
+ *
+ * Special cases:
+ * - If no track is playing and a new track is scheduled, it starts the track immediately without fading.
+ * - If a new track is scheduled during fading, it resets the transition to prioritize the new track.
*/
private void updateVolumeAndTrack() {
- // Implementation for handling fade-ins, fade-outs, and volume updates
+ if (scheduled == null && !fading && playing == null) {
+ // Nothing to do, early exit
+ return;
+ }
+
+ if (scheduled != null && playing == null && !fading) {
+ // No current track, start scheduled track immediately at full volume
+ playing = scheduled;
+ scheduled = null;
+ playing.play();
+ playing.update(getMusicVolumeTotal()); // Set volume to full
+ return;
+ }
+
+ if (scheduled != null && !fading) {
+ // Initiate a fade process if a new track is scheduled
+ fading = true;
+ fadeTimer.reset();
+ old = playing; // The currently playing track becomes the old track
+ playing = null; // Clear the playing track during the fade process
+ }
+
+ if (fading) {
+ handleFadeProcess();
+
+ // Handle any interruptions due to newly scheduled tracks
+ if (scheduled != null && playing != null && playing != scheduled) {
+ // Interrupt the current infade and switch to the new scheduled track
+ old = playing; // Treat the currently infading track as the old track
+ playing = null; // Reset playing to allow switching
+ fadeTimer.reset(); // Restart fade timer for the new track
+ }
+ } else if (playing != null) {
+ // Update volume for the currently playing track
+ playing.update(getMusicVolumeTotal());
+ } else if (scheduled != null) {
+ // If no track is playing and one is scheduled, start it immediately at full volume
+ playing = scheduled;
+ scheduled = null;
+ playing.play();
+ playing.update(getMusicVolumeTotal()); // Set volume to full
+ }
}
/**
- * Handles the fade-out and fade-in processes for audio transitions.
+ * Manages the fading process during audio track transitions.
+ *
+ * This method handles the fade-out of the currently playing (old) track, manages any pause between the fade-out
+ * and fade-in, and initiates the fade-in for the new track if applicable. It ensures smooth transitions between
+ * tracks while maintaining the correct volume adjustments.
+ *
+ * Behavior:
+ * 1. **Outfade:** Gradually decreases the volume of the `old` track over the duration of `FADE_DURATION`.
+ * Once the outfade completes, the `old` track is paused and cleared.
+ * 2. **Pause Handling:** Waits for a defined pause (if applicable) before initiating the infade for the next track.
+ * 3. **Infade:** If a `scheduled` track exists and the outfade and pause are complete, it begins playing
+ * the new track (`playing`) and initiates the infade process.
+ *
+ * Key Details:
+ * - The outfade volume adjustment is interpolated linearly from full volume to zero using the `lerp` function.
+ * - The pause duration is retrieved from the scheduled track if it is specified.
+ * - If a new track is scheduled during the fade process, it is handled by external logic to prioritize transitions.
+ *
+ * Preconditions:
+ * - `fading` is expected to be `true` when this method is called.
+ * - The method is invoked as part of the `updateVolumeAndTrack` process.
*/
private void handleFadeProcess() {
- // Implementation for managing fade transitions
+ float time = fadeTimer.getTimeInSeconds();
+
+ // Handle outfade for the old track
+ if (old != null && time <= FADE_DURATION) {
+ float t = Math.min(time / FADE_DURATION, 1.0f);
+ float oldVolume = lerp(1.0f, 0.0f, t);
+ old.update(getMusicVolumeTotal() * oldVolume);
+ }
+
+ if (old != null && time > FADE_DURATION) {
+ // Complete outfade
+ old.pause();
+ old = null;
+ }
+
+ // Handle pause duration before infade
+ float pause = (scheduled != null) ? scheduled.getPause() : 0.0f;
+ if (time > FADE_DURATION + pause) {
+ if (playing == null && scheduled != null) {
+ // Begin infade for the new track
+ playing = scheduled;
+ scheduled = null;
+ playing.play(); // Start playing the new track
+ }
+ handleInfade(time - FADE_DURATION - pause);
+ }
}
/**
* Manages the fade-in process for the currently playing track.
*
- * @param infadeTime Time elapsed since the fade-in process started.
+ * This method gradually increases the volume of the `playing` track from zero to full volume
+ * over the duration of `CROSSFADE_DURATION`. It ensures a smooth transition into the new track.
+ *
+ * Behavior:
+ * 1. If no track is set as `playing`, the method exits early, as there is nothing to fade in.
+ * 2. Linearly interpolates the volume of the `playing` track from 0.0 to 1.0 based on the elapsed
+ * `infadeTime` and the specified `CROSSFADE_DURATION`.
+ * 3. Once the fade-in is complete (when `infadeTime` exceeds `CROSSFADE_DURATION`), the method:
+ * - Marks the fade process (`fading`) as complete.
+ * - Ensures the `playing` track is updated to its full volume.
+ *
+ * Key Details:
+ * - Uses the `lerp` function to calculate the volume level for the `playing` track during the fade-in.
+ * - Ensures the volume is always a value between 0.0 and 1.0.
+ * - The `infadeTime` parameter should be relative to the start of the fade-in process.
+ *
+ * Preconditions:
+ * - The `playing` track must be initialized and actively fading in for this method to have an effect.
+ * - The method is invoked as part of the `updateVolumeAndTrack` process.
+ *
+ * @param infadeTime The elapsed time (in seconds) since the fade-in process started.
*/
private void handleInfade(float infadeTime) {
- // Implementation for handling the fade-in process
+ if (playing == null) {
+ // Nothing to infade
+ return;
+ }
+
+ // Proceed with the infade for the current playing track
+ float t = Math.min(infadeTime / CROSSFADE_DURATION, 1.0f);
+ float newVolume = lerp(0.0f, 1.0f, t);
+ playing.update(getMusicVolumeTotal() * newVolume);
+
+ if (infadeTime > CROSSFADE_DURATION) {
+ // Infade is complete, finalize state
+ fading = false;
+ playing.update(getMusicVolumeTotal()); // Ensure full volume
+ }
}
/**
- * Adds and shuffles game music tracks.
+ * Adds a list of game tracks to the gameTracks collection and shuffles them.
+ * This method adds predefined game tracks to the track list and shuffles the order.
*/
private void addGameTracks() {
- // Adds predefined game music tracks to the list and shuffles them
+ Random random = new Random();
+
+ for (int i = 1; i <= 6; i++) {
+ gameTracks.add(MusicAsset.valueOf("GAME_" + i));
+ }
+ Collections.shuffle(gameTracks, random);
}
/**
- * Updates the game music tracks, scheduling new ones as needed.
+ * Updates the current game tracks. If the currently playing track is nearing its end,
+ * a new track will be scheduled to play. If the list of game tracks is empty, it will be refreshed.
*/
private void updateGameTracks() {
- // Handles scheduling and transitioning between game tracks
+ if(null == playing) {
+ return;
+ }
+
+ if (playing.nearEnd(10)) {
+ if (gameTracks.isEmpty()) {
+ addGameTracks();
+ }
+ }
+
+ if (playing != null && playing.nearEnd(3) && trackTimer.getTimeInSeconds() > 20) {
+ trackTimer.reset();
+
+ MusicAsset nextTrack = gameTracks.remove(0);
+
+ scheduled = new GameMusic(app, nextTrack, getMusicVolumeTotal(), nextTrack.getSubVolume(), nextTrack.getLoop(), 0.0f);
+ }
}
/**
- * Gets the main volume level.
+ * Retrieves the main volume level.
*
- * @return The main volume level.
+ * @return The current main volume level.
*/
public float getMainVolume() {
return mainVolume;
@@ -160,7 +395,7 @@ public float getSoundVolume() {
}
/**
- * Sets the main volume level and saves the setting.
+ * Sets the main volume level.
*
* @param mainVolume The desired main volume level.
*/
@@ -169,27 +404,6 @@ public void setMainVolume(float mainVolume) {
prefs.putFloat("mainVolume", mainVolume);
}
- // Similar getters and setters for musicVolume and soundVolume...
-
- /**
- * Calculates the total music volume (main volume × music volume).
- *
- * @return The total music volume.
- */
- float getMusicVolumeTotal() {
- return musicVolume * mainVolume;
- }
-
- /**
- * Calculates the total sound volume (main volume × sound volume).
- *
- * @return The total sound volume.
- */
- float getSoundVolumeTotal() {
- return soundVolume * mainVolume;
- }
-
-
/**
* Sets the music volume level.
*
@@ -209,4 +423,23 @@ public void setSoundVolume(float soundVolume) {
this.soundVolume = soundVolume;
prefs.putFloat("soundVolume", soundVolume);
}
+
+ /**
+ * Calculates the total music volume by multiplying the music volume by the main volume.
+ *
+ * @return The total music volume.
+ */
+ float getMusicVolumeTotal() {
+
+ return getMusicVolume() * getMainVolume();
+ }
+
+ /**
+ * Calculates the total sound volume by multiplying the sound volume by the main volume.
+ *
+ * @return The total sound volume.
+ */
+ float getSoundVolumeTotal() {
+ return getSoundVolume() * getMainVolume();
+ }
}
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/view/LobbyView.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/view/LobbyView.java
index 0ee82c56..242cae89 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/view/LobbyView.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/view/LobbyView.java
@@ -152,6 +152,23 @@ public void setTaken(Color color, boolean isTaken, boolean isSelf, String name)
if(isTaken) {
if(isSelf) {
+ /*if(own != null) {
+ switch (color) {
+ case CYBER:
+ cyberButton.setTaken(LobbyButton.Taken.NOT, name);
+ break;
+ case AIRFORCE:
+ airforceButton.setTaken(LobbyButton.Taken.NOT, name);
+ break;
+ case ARMY:
+ armyButton.setTaken(LobbyButton.Taken.NOT, name);
+ break;
+ case NAVY:
+ navyButton.setTaken(LobbyButton.Taken.NOT, name);
+ break;
+ }
+ }*/
+
own = color;
taken = LobbyButton.Taken.SELF;
} else {
@@ -228,7 +245,7 @@ private void toggleTsk(Color color) {
app.getModelSynchronize().selectTsk(color);
break;
case SELF:
- app.getModelSynchronize().unselectTsk();
+ app.getModelSynchronize().unselectTsk(color);
break;
case OTHER:
//nothing
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/ClientGameLogic.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/ClientGameLogic.java
index c2526b46..133d5689 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/client/ClientGameLogic.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/ClientGameLogic.java
@@ -239,6 +239,10 @@ public void selectTsk(Color color){
state.selectTSK(color);
}
+ public void deselectTSK(Color color){
+ state.deselectTSK(color);
+ }
+
public void selectDice(){
state.selectDice();
}
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/dialogState/LobbyState.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/dialogState/LobbyState.java
index 7678624a..fdb8e5d2 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/client/dialogState/LobbyState.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/dialogState/LobbyState.java
@@ -101,9 +101,13 @@ public void received(LobbyPlayerJoinedMessage msg){
@Override
public void received(UpdateTSKMessage msg){
- logic.addNotification(new TskUnselectNotification(logic.getGame().getPlayers().get(msg.getId()).getColor()));
+ if(msg.isTaken()) {
+ logic.addNotification(new TskSelectNotification(msg.getColor(), logic.getGame().getPlayers().get(msg.getId()).getName(), parent.getOwnPlayerId()== msg.getId()));
+ } else {
+ logic.addNotification(new TskUnselectNotification(logic.getGame().getPlayers().get(msg.getId()).getColor()));
+ }
+
logic.getGame().getPlayers().get(msg.getId()).setColor(msg.getColor());
- logic.addNotification(new TskSelectNotification(msg.getColor(), logic.getGame().getPlayers().get(msg.getId()).getName(), parent.getOwnPlayerId()== msg.getId()));
}
@Override
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/message/server/UpdateTSKMessage.java b/Projekte/mdga/model/src/main/java/pp/mdga/message/server/UpdateTSKMessage.java
index bbbdf14b..2da6f682 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/message/server/UpdateTSKMessage.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/message/server/UpdateTSKMessage.java
@@ -18,23 +18,26 @@ public class UpdateTSKMessage extends ServerMessage {
*/
private final Color color;
+ private final boolean isTaken;
+
/**
* Constructs a new UpdateTSK instance with the specified id and color.
*
* @param id the name associated with the update
* @param color the color associated with the update
*/
- public UpdateTSKMessage(int id, Color color) {
+ public UpdateTSKMessage(int id, Color color, boolean isTaken) {
super();
this.id = id;
this.color = color;
+ this.isTaken = isTaken;
}
/**
* Default constructor for serialization purposes.
*/
private UpdateTSKMessage() {
- this(0, null);
+ this(0, null, false);
}
/**
@@ -84,4 +87,8 @@ public String toString() {
public String getInfoTextKey() {
return "";
}
+
+ public boolean isTaken() {
+ return isTaken;
+ }
}
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/LobbyState.java b/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/LobbyState.java
index 2a4eba34..708a26d5 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/LobbyState.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/LobbyState.java
@@ -7,6 +7,7 @@
import pp.mdga.message.server.*;
import pp.mdga.server.ServerGameLogic;
+import java.lang.foreign.StructLayout;
import java.util.Map;
/**
@@ -84,8 +85,13 @@ public void received(SelectTSKMessage msg, int from) {
return;
}
}
+
+ if(this.logic.getGame().getPlayerById(from).getColor() != Color.NONE) {
+ this.logic.getServerSender().broadcast(new UpdateTSKMessage(from, this.logic.getGame().getPlayerById(from).getColor(), false));
+ }
+
this.logic.getGame().getPlayerById(from).setColor(msg.getColor());
- this.logic.getServerSender().broadcast(new UpdateTSKMessage(from, msg.getColor()));
+ this.logic.getServerSender().broadcast(new UpdateTSKMessage(from, msg.getColor(), true));
}
/**
@@ -98,7 +104,7 @@ public void received(SelectTSKMessage msg, int from) {
@Override
public void received(DeselectTSKMessage msg, int from) {
this.logic.getGame().getPlayerById(from).setColor(Color.NONE);
- this.logic.getServerSender().broadcast(new UpdateTSKMessage(from, Color.NONE));
+ this.logic.getServerSender().broadcast(new UpdateTSKMessage(from, Color.NONE, false));
}
/**
From 5db7b64cefe2957a73ed3fe543a4dbdc98a8d74c Mon Sep 17 00:00:00 2001
From: Hanno Fleischer
Date: Mon, 2 Dec 2024 12:16:53 +0100
Subject: [PATCH 16/28] fixed bug with seriliazation of Board, now sending
playerdata seperate from teh board
---
Projekte/.run/MdgaApp.run.xml | 4 +-
.../pp/mdga/client/server/MdgaServer.java | 2 +
.../java/pp/mdga/client/ClientGameLogic.java | 10 +++++
.../main/java/pp/mdga/client/ClientState.java | 9 +++++
.../java/pp/mdga/client/DialogsState.java | 10 +++++
.../mdga/client/dialogState/LobbyState.java | 23 ++++++++---
.../dialogState/NetworkDialogState.java | 28 -------------
.../message/server/PlayerDataMessage.java | 40 +++++++++++++++++++
.../message/server/ServerInterpreter.java | 4 ++
.../server/ServerStartGameMessage.java | 24 -----------
.../message/server/StartBriefingMessage.java | 33 +++++++++++++++
.../pp/mdga/server/automaton/LobbyState.java | 9 +++--
12 files changed, 134 insertions(+), 62 deletions(-)
create mode 100644 Projekte/mdga/model/src/main/java/pp/mdga/message/server/PlayerDataMessage.java
create mode 100644 Projekte/mdga/model/src/main/java/pp/mdga/message/server/StartBriefingMessage.java
diff --git a/Projekte/.run/MdgaApp.run.xml b/Projekte/.run/MdgaApp.run.xml
index 8b467373..123a07af 100644
--- a/Projekte/.run/MdgaApp.run.xml
+++ b/Projekte/.run/MdgaApp.run.xml
@@ -1,5 +1,7 @@
+
+
@@ -14,4 +16,4 @@
-
+
\ No newline at end of file
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/server/MdgaServer.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/server/MdgaServer.java
index 111604ed..b8e8bfb4 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/server/MdgaServer.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/server/MdgaServer.java
@@ -144,6 +144,8 @@ private void initializeSerializables() {
Serializer.registerClass(StartNode.class);
Serializer.registerClass(PlayerData.class);
Serializer.registerClass(HomeNode.class);
+ Serializer.registerClass(PlayerDataMessage.class);
+ Serializer.registerClass(StartBriefingMessage.class);
}
private void registerListeners() {
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/ClientGameLogic.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/ClientGameLogic.java
index 133d5689..f3a0602b 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/client/ClientGameLogic.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/ClientGameLogic.java
@@ -193,6 +193,16 @@ public void received(ServerStartGameMessage msg) {
@Override
public void received(ShutdownMessage msg) {state.received(msg);}
+ @Override
+ public void received(StartBriefingMessage msg) {
+ state.received(msg);
+ }
+
+ @Override
+ public void received(PlayerDataMessage msg) {
+ state.received(msg);
+ }
+
@Override
public void received(StartPieceMessage msg) {
state.received(msg);
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/ClientState.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/ClientState.java
index bf64e267..ae500c42 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/client/ClientState.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/ClientState.java
@@ -183,6 +183,15 @@ public void received(WaitPieceMessage msg) {
LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg);
}
+ @Override
+ public void received(StartBriefingMessage msg) {
+ LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg);
+ }
+
+ public void received(PlayerDataMessage msg) {
+ LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg);
+ }
+
public void selectPiece(Piece piece) {
LOGGER.log(Level.DEBUG, "Selecting piece not allowed.");
}
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/DialogsState.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/DialogsState.java
index 5f7cf182..c3f33c97 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/client/DialogsState.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/DialogsState.java
@@ -144,6 +144,16 @@ public void received(ServerStartGameMessage msg){
currentState.received(msg);
}
+ @Override
+ public void received(PlayerDataMessage msg){
+ currentState.received(msg);
+ }
+
+ @Override
+ public void received(StartBriefingMessage msg){
+ currentState.received(msg);
+ }
+
public DialogStates getState() {
return currentState;
}
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/dialogState/LobbyState.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/dialogState/LobbyState.java
index fdb8e5d2..f468d8d3 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/client/dialogState/LobbyState.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/dialogState/LobbyState.java
@@ -10,7 +10,9 @@
import pp.mdga.message.client.*;
import pp.mdga.message.server.LobbyPlayerJoinedMessage;
import pp.mdga.message.server.LobbyPlayerLeaveMessage;
+import pp.mdga.message.server.PlayerDataMessage;
import pp.mdga.message.server.ServerStartGameMessage;
+import pp.mdga.message.server.StartBriefingMessage;
import pp.mdga.message.server.UpdateReadyMessage;
import pp.mdga.message.server.UpdateTSKMessage;
import pp.mdga.notification.*;
@@ -74,15 +76,24 @@ public void selectStart(){
}
@Override
- public void received(ServerStartGameMessage msg){
+ public void received(StartBriefingMessage msg){
logic.getGame().setBoard(msg.getBoard());
- logic.addNotification(new GameNotification(logic.getGame().getPlayers().get(parent.getOwnPlayerId()).getColor()));
- for(Map.Entry entry : msg.getBoard().getPlayerData().entrySet()){
- List pieceIds = new ArrayList<>();
+ }
+
+ public void received(PlayerDataMessage msg){
+ logic.getGame().getBoard().addPlayerData(msg.getColor(), msg.getPlayerData());
+ }
+
+ @Override
+ public void received(ServerStartGameMessage msg){
+ logic.addNotification(new GameNotification(logic.getGame().getPlayerById(parent.getOwnPlayerId()).getColor()));
+ for (Map.Entry entry : logic.getGame().getBoard().getPlayerData().entrySet()) {
+ List pieceList = new ArrayList<>();
for(Piece piece : entry.getValue().getPieces()){
- pieceIds.add(piece.getUuid());
+ System.out.println(piece.getUuid());
+ pieceList.add(piece.getUuid());
}
- logic.addNotification(new PlayerInGameNotification(entry.getKey(), pieceIds, logic.getGame().getPlayerByColor(entry.getKey()).getName()));
+ logic.addNotification(new PlayerInGameNotification(entry.getKey(), pieceList , logic.getGame().getPlayerByColor(entry.getKey()).getName()));
}
parent.startGame();
}
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/dialogState/NetworkDialogState.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/dialogState/NetworkDialogState.java
index 09212dee..98234319 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/client/dialogState/NetworkDialogState.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/dialogState/NetworkDialogState.java
@@ -14,34 +14,6 @@ public NetworkDialogState(ClientState parent, ClientGameLogic logic) {
this.parent = (DialogsState) parent;
}
- private boolean checkIP(String IP){
- String[] parts = IP.split("\\.");
-
- // Step 2: Check if there are exactly 4 parts
- if (parts.length != 4) {
- return false;
- }
-
- // Step 3: Check each part for valid number
- for (String part : parts) {
- try {
- // Step 4: Convert each part into a number
- int num = Integer.parseInt(part);
-
- // Step 5: Check whether the number lies in between 0 and 255
- if (num < 0 || num > 255) {
- return false;
- }
- } catch (NumberFormatException e) {
- // If parsing fails, it's not a valid number
- return false;
- }
- }
-
- // If all checks passed, return true
- return true;
- }
-
@Override
public void enter() {
}
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/message/server/PlayerDataMessage.java b/Projekte/mdga/model/src/main/java/pp/mdga/message/server/PlayerDataMessage.java
new file mode 100644
index 00000000..03171e73
--- /dev/null
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/message/server/PlayerDataMessage.java
@@ -0,0 +1,40 @@
+package pp.mdga.message.server;
+
+import com.jme3.network.serializing.Serializable;
+import pp.mdga.game.Color;
+import pp.mdga.game.PlayerData;
+
+@Serializable
+public class PlayerDataMessage extends ServerMessage{
+
+ private final PlayerData playerData;
+ private final Color color;
+
+ public PlayerDataMessage(PlayerData playerData, Color color){
+ super();
+ this.playerData = playerData;
+ this.color = color;
+ }
+
+ private PlayerDataMessage(){
+ this(null, null);
+ }
+
+ @Override
+ public void accept(ServerInterpreter interpreter) {
+ interpreter.received(this);
+ }
+
+ @Override
+ public String getInfoTextKey() {
+ return "";
+ }
+
+ public PlayerData getPlayerData(){
+ return playerData;
+ }
+
+ public Color getColor(){
+ return color;
+ }
+}
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/message/server/ServerInterpreter.java b/Projekte/mdga/model/src/main/java/pp/mdga/message/server/ServerInterpreter.java
index 1ed24edf..4491f9c1 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/message/server/ServerInterpreter.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/message/server/ServerInterpreter.java
@@ -214,4 +214,8 @@ public interface ServerInterpreter {
* @param shutdownMessage the SelectTSK message received.
*/
void received(ShutdownMessage shutdownMessage);
+
+ void received(StartBriefingMessage msg);
+
+ void received(PlayerDataMessage msg);
}
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/message/server/ServerStartGameMessage.java b/Projekte/mdga/model/src/main/java/pp/mdga/message/server/ServerStartGameMessage.java
index 37c22e1e..69e3fb96 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/message/server/ServerStartGameMessage.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/message/server/ServerStartGameMessage.java
@@ -8,28 +8,13 @@
*/
@Serializable
public class ServerStartGameMessage extends ServerMessage {
- /**
- * Create ServerStartGameMessage attributes.
- */
- private final Board board;
/**
* Constructs a new ServerStartGame instance.
*/
public ServerStartGameMessage() {
super();
- this.board = null;
}
-
- /**
- * Constructor.
- *
- * @param board as the complete board of this game as a Board object.
- */
- public ServerStartGameMessage(Board board) {
- this.board = board;
- }
-
/**
* Accepts a visitor to process this message.
*
@@ -40,15 +25,6 @@ public void accept(ServerInterpreter interpreter) {
interpreter.received(this);
}
- /**
- * This method will be used to return board attribute of ServerStartGameMessage class.
- *
- * @return board as a Board object.
- */
- public Board getBoard() {
- return this.board;
- }
-
/**
* Returns a string representation of this message.
*
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/message/server/StartBriefingMessage.java b/Projekte/mdga/model/src/main/java/pp/mdga/message/server/StartBriefingMessage.java
new file mode 100644
index 00000000..ba465990
--- /dev/null
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/message/server/StartBriefingMessage.java
@@ -0,0 +1,33 @@
+package pp.mdga.message.server;
+
+import com.jme3.network.serializing.Serializable;
+import pp.mdga.game.Board;
+
+@Serializable
+public class StartBriefingMessage extends ServerMessage {
+
+ private final Board board;
+
+ public StartBriefingMessage(Board board) {
+ super();
+ this.board = board;
+ }
+
+ private StartBriefingMessage() {
+ this(null);
+ }
+
+ public Board getBoard() {
+ return this.board;
+ }
+
+ @Override
+ public void accept(ServerInterpreter interpreter) {
+ interpreter.received(this);
+ }
+
+ @Override
+ public String getInfoTextKey() {
+ return "";
+ }
+}
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/LobbyState.java b/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/LobbyState.java
index 708a26d5..c268cc4f 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/LobbyState.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/LobbyState.java
@@ -7,7 +7,6 @@
import pp.mdga.message.server.*;
import pp.mdga.server.ServerGameLogic;
-import java.lang.foreign.StructLayout;
import java.util.Map;
/**
@@ -126,8 +125,12 @@ public void received(LobbyReadyMessage msg, int from) {
this.logic.getGame().setAllReady(true);
if (this.logic.getGame().allReady()) {
+ this.logic.getServerSender().broadcast(new StartBriefingMessage(this.logic.getGame().getBoard()));
this.initializeGame();
- this.logic.getServerSender().broadcast(new ServerStartGameMessage(this.logic.getGame().getBoard()));
+ for (Map.Entry entry : logic.getGame().getBoard().getPlayerData().entrySet()) {
+ this.logic.getServerSender().broadcast(new PlayerDataMessage(entry.getValue(), entry.getKey()));
+ }
+ this.logic.getServerSender().broadcast(new ServerStartGameMessage());
}
}
@@ -173,7 +176,7 @@ public void received(LeaveGameMessage msg, int from) {
public void received(StartGameMessage msg, int from) {
if (msg.isForceStartGame() || this.logic.getGame().allReady()) {
this.initializeGame();
- this.logic.getServerSender().broadcast(new ServerStartGameMessage(this.logic.getGame().getBoard()));
+ this.logic.getServerSender().broadcast(new ServerStartGameMessage());
this.logic.setCurrentState(this.logic.getGameState());
}
}
From 4561a962d4ccba9bbdcc2d8ed2ea6a96016dfaf1 Mon Sep 17 00:00:00 2001
From: Felix Koppe
Date: Mon, 2 Dec 2024 12:52:07 +0100
Subject: [PATCH 17/28] Fix lobby isSelf logic and no longer assign color on
join
---
.../java/pp/mdga/client/view/LobbyView.java | 17 -----------------
.../pp/mdga/client/dialogState/LobbyState.java | 3 ++-
.../pp/mdga/server/automaton/LobbyState.java | 2 +-
3 files changed, 3 insertions(+), 19 deletions(-)
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/view/LobbyView.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/view/LobbyView.java
index 242cae89..e96cbbb7 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/view/LobbyView.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/view/LobbyView.java
@@ -152,23 +152,6 @@ public void setTaken(Color color, boolean isTaken, boolean isSelf, String name)
if(isTaken) {
if(isSelf) {
- /*if(own != null) {
- switch (color) {
- case CYBER:
- cyberButton.setTaken(LobbyButton.Taken.NOT, name);
- break;
- case AIRFORCE:
- airforceButton.setTaken(LobbyButton.Taken.NOT, name);
- break;
- case ARMY:
- armyButton.setTaken(LobbyButton.Taken.NOT, name);
- break;
- case NAVY:
- navyButton.setTaken(LobbyButton.Taken.NOT, name);
- break;
- }
- }*/
-
own = color;
taken = LobbyButton.Taken.SELF;
} else {
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/dialogState/LobbyState.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/dialogState/LobbyState.java
index f468d8d3..6d70ba50 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/client/dialogState/LobbyState.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/dialogState/LobbyState.java
@@ -106,7 +106,8 @@ public void received(LobbyPlayerJoinedMessage msg){
if (msg.isHost() && msg.getId() == parent.getOwnPlayerId()){
logic.setHost(true);
}
- logic.addNotification(new TskSelectNotification(msg.getPlayer().getColor(), msg.getPlayer().getName(), parent.getOwnPlayerId()== msg.getId()));
+
+ logic.addNotification(new TskSelectNotification(msg.getPlayer().getColor(), msg.getPlayer().getName(), msg.getPlayer().getName().equals(parent.getOwnPlayerName())));
logic.getGame().getPlayers().put(msg.getId(), msg.getPlayer());
}
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/LobbyState.java b/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/LobbyState.java
index c268cc4f..1f1bbacb 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/LobbyState.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/LobbyState.java
@@ -63,7 +63,7 @@ public void initializeGame() {
@Override
public void received(JoinedLobbyMessage msg, int from) {
Player player = new Player(msg.getName());
- player.setColor(Color.getColorByIndex(this.logic.getGame().getPlayers().size()));
+ player.setColor(Color.NONE);
this.logic.getGame().addPlayer(from, player);
for (Map.Entry entry : this.logic.getGame().getPlayers().entrySet()) {
this.logic.getServerSender().broadcast(new LobbyPlayerJoinedMessage(entry.getKey(), entry.getValue(), entry.getKey() == this.logic.getGame().getHost()));
From 92d2e747482e79199d3f61e5b935bbc75d74d36a Mon Sep 17 00:00:00 2001
From: Felix Koppe
Date: Mon, 2 Dec 2024 13:06:59 +0100
Subject: [PATCH 18/28] Fix error regarding color in lobbyState
---
.../pp/mdga/server/automaton/LobbyState.java | 23 +++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/LobbyState.java b/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/LobbyState.java
index 1f1bbacb..32b400b6 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/LobbyState.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/LobbyState.java
@@ -7,6 +7,7 @@
import pp.mdga.message.server.*;
import pp.mdga.server.ServerGameLogic;
+import java.util.ArrayList;
import java.util.Map;
/**
@@ -115,6 +116,28 @@ public void received(DeselectTSKMessage msg, int from) {
*/
@Override
public void received(LobbyReadyMessage msg, int from) {
+ //assign a free color
+ if(this.logic.getGame().getPlayerById(from).getColor() == Color.NONE) {
+ ArrayList colors = new ArrayList<>();
+ colors.add(Color.ARMY);
+ colors.add(Color.AIRFORCE);
+ colors.add(Color.NAVY);
+ colors.add(Color.CYBER);
+
+ for (Map.Entry entry : this.logic.getGame().getPlayers().entrySet()) {
+ if(colors.contains(entry.getValue().getColor())) {
+ colors.remove(entry.getValue().getColor());
+ }
+ }
+
+ if(colors.size() < 1) {
+ throw new RuntimeException("can not assign a color");
+ }
+
+ this.logic.getGame().getPlayerById(from).setColor(colors.get(0));
+ this.logic.getServerSender().broadcast(new UpdateTSKMessage(from, colors.get(0), true));
+ }
+
this.logic.getGame().getPlayerById(from).setReady(true);
this.logic.getServerSender().broadcast(new UpdateReadyMessage(from, true));
for (Map.Entry entry : this.logic.getGame().getPlayers().entrySet()) {
From 6c136b78b8f09e194950fa4ff76ec309283524a1 Mon Sep 17 00:00:00 2001
From: Daniel Grigencha
Date: Mon, 2 Dec 2024 16:22:50 +0100
Subject: [PATCH 19/28] Updated 'Piece' class. Updated the 'Piece' class by
reverting all enumeration to its orgin types.
---
.../src/main/java/pp/mdga/game/Piece.java | 32 +++++++++----------
1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/game/Piece.java b/Projekte/mdga/model/src/main/java/pp/mdga/game/Piece.java
index dfe36188..a01c1247 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/game/Piece.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/game/Piece.java
@@ -12,17 +12,17 @@ public class Piece {
/**
* The shield state of the piece.
*/
- private int shield;
+ private ShieldState shield;
/**
* The current state of the piece.
*/
- private int state;
+ private PieceState state;
/**
* The color of the piece.
*/
- private final int color;
+ private final Color color;
/**
* The unique identifier of the piece.
@@ -36,15 +36,15 @@ public class Piece {
* @param state the state of the piece
*/
public Piece(Color color, PieceState state, int id) {
- this.color = color.ordinal();
- this.state = state.ordinal();
- shield = ShieldState.NONE.ordinal();
+ this.color = color;
+ this.state = state;
+ shield = ShieldState.NONE;
}
private Piece() {
- color = Color.NONE.ordinal();
- state = PieceState.WAITING.ordinal();
- shield = ShieldState.NONE.ordinal();
+ color = Color.NONE;
+ state = PieceState.WAITING;
+ shield = ShieldState.NONE;
}
/**
@@ -53,7 +53,7 @@ private Piece() {
* @return the color of the piece
*/
public void setShield(ShieldState shield) {
- this.shield = shield.ordinal();
+ this.shield = shield;
}
/**
@@ -62,7 +62,7 @@ public void setShield(ShieldState shield) {
* @return the color of the piece
*/
public ShieldState getShield() {
- return ShieldState.values()[shield];
+ return shield;
}
/**
@@ -71,7 +71,7 @@ public ShieldState getShield() {
* @param state the state of the piece
*/
public void setState(PieceState state) {
- this.state = state.ordinal();
+ this.state = state;
}
/**
@@ -80,7 +80,7 @@ public void setState(PieceState state) {
* @return the color of the piece
*/
public PieceState getState() {
- return PieceState.values()[state];
+ return state;
}
/**
@@ -89,7 +89,7 @@ public PieceState getState() {
* @return the color of the piece
*/
public boolean isShielded() {
- return shield == ShieldState.ACTIVE.ordinal();
+ return shield == ShieldState.ACTIVE;
}
/**
@@ -98,7 +98,7 @@ public boolean isShielded() {
* @return the color of the piece
*/
public boolean isSuppressed() {
- return shield == ShieldState.SUPPRESSED.ordinal();
+ return shield == ShieldState.SUPPRESSED;
}
/**
@@ -107,7 +107,7 @@ public boolean isSuppressed() {
* @return the color of the piece
*/
public Color getColor() {
- return Color.values()[color];
+ return color;
}
/**
From 167d898a3cfaf0c3016f7fccb257dd0035b42d17 Mon Sep 17 00:00:00 2001
From: Daniel Grigencha
Date: Mon, 2 Dec 2024 16:25:33 +0100
Subject: [PATCH 20/28] Updated 'StartNode' class. Updated the 'StartNode'
class by reverting all enumerations to its origin types in it.
---
.../model/src/main/java/pp/mdga/game/StartNode.java | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/game/StartNode.java b/Projekte/mdga/model/src/main/java/pp/mdga/game/StartNode.java
index 23161ecf..24b2c267 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/game/StartNode.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/game/StartNode.java
@@ -10,7 +10,7 @@ public class StartNode extends Node {
/**
* The color of the node.
*/
- private int color;
+ private Color color;
/**
* Creates a new start node with the given color.
@@ -18,11 +18,11 @@ public class StartNode extends Node {
* @param color the color of the node
*/
public StartNode(Color color) {
- this.color = color.ordinal();
+ this.color = color;
}
private StartNode() {
- color = Color.NONE.ordinal();
+ color = Color.NONE;
}
/**
@@ -31,7 +31,7 @@ private StartNode() {
* @return the color of the node
*/
public Color getColor() {
- return Color.values()[color];
+ return color;
}
/**
@@ -40,6 +40,6 @@ public Color getColor() {
* @param color the new color of the node
*/
public void setColor(Color color) {
- this.color = color.ordinal();
+ this.color = color;
}
}
From 1bcb73cff792b37c49d3411abda1afa1f2002897 Mon Sep 17 00:00:00 2001
From: Daniel Grigencha
Date: Mon, 2 Dec 2024 16:29:32 +0100
Subject: [PATCH 21/28] Updated 'PlayerData' class. Updated the 'PlayerData'
class by adding the 'isFinished' method to it. In Addition, the empty
constructor was optimized to initalize all class attributes for serializable
cases.
---
.../main/java/pp/mdga/game/PlayerData.java | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/game/PlayerData.java b/Projekte/mdga/model/src/main/java/pp/mdga/game/PlayerData.java
index 8fcc85ae..cb2a788b 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/game/PlayerData.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/game/PlayerData.java
@@ -43,10 +43,23 @@ public PlayerData(Color color) {
}
}
+ /**
+ * Constructor.
+ */
private PlayerData() {
- homeNodes = null;
- waitingArea = null;
- pieces = null;
+ homeNodes = new HomeNode[4];
+ waitingArea = new Piece[4];
+ pieces = new Piece[4];
+ }
+
+ /**
+ * This method will be used to check if the player is finished.
+ * ToDo: Currently return always false. Implement logic!
+ *
+ * @return true or false.
+ */
+ public boolean isFinished() {
+ return false;
}
/**
From cb362c4d0cf028240813ad485254c2f6ae785e0c Mon Sep 17 00:00:00 2001
From: Daniel Grigencha
Date: Mon, 2 Dec 2024 16:31:57 +0100
Subject: [PATCH 22/28] Used auto-reformate code.
---
.../client/src/main/java/pp/mdga/client/MdgaApp.java | 2 +-
.../main/java/pp/mdga/server/automaton/LobbyState.java | 10 +++++-----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java
index cb0371c0..2fddea2f 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java
@@ -1,9 +1,9 @@
package pp.mdga.client;
import com.jme3.app.SimpleApplication;
+import com.jme3.system.AppSettings;
import com.simsilica.lemur.GuiGlobals;
import pp.mdga.client.acoustic.AcousticHandler;
-import com.jme3.system.AppSettings;
import pp.mdga.client.dialog.JoinDialog;
import pp.mdga.client.view.*;
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/LobbyState.java b/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/LobbyState.java
index 32b400b6..167992c2 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/LobbyState.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/LobbyState.java
@@ -49,7 +49,7 @@ public void exit() {
* This method will be used to initialize the game and all necessary objects.
*/
public void initializeGame() {
- for (Map.Entry entry: this.logic.getGame().getPlayers().entrySet()) {
+ for (Map.Entry entry : this.logic.getGame().getPlayers().entrySet()) {
this.logic.getGame().getBoard().addPlayerData(entry.getValue().getColor(), new PlayerData(entry.getValue().getColor()));
}
}
@@ -86,7 +86,7 @@ public void received(SelectTSKMessage msg, int from) {
}
}
- if(this.logic.getGame().getPlayerById(from).getColor() != Color.NONE) {
+ if (this.logic.getGame().getPlayerById(from).getColor() != Color.NONE) {
this.logic.getServerSender().broadcast(new UpdateTSKMessage(from, this.logic.getGame().getPlayerById(from).getColor(), false));
}
@@ -117,7 +117,7 @@ public void received(DeselectTSKMessage msg, int from) {
@Override
public void received(LobbyReadyMessage msg, int from) {
//assign a free color
- if(this.logic.getGame().getPlayerById(from).getColor() == Color.NONE) {
+ if (this.logic.getGame().getPlayerById(from).getColor() == Color.NONE) {
ArrayList colors = new ArrayList<>();
colors.add(Color.ARMY);
colors.add(Color.AIRFORCE);
@@ -125,12 +125,12 @@ public void received(LobbyReadyMessage msg, int from) {
colors.add(Color.CYBER);
for (Map.Entry entry : this.logic.getGame().getPlayers().entrySet()) {
- if(colors.contains(entry.getValue().getColor())) {
+ if (colors.contains(entry.getValue().getColor())) {
colors.remove(entry.getValue().getColor());
}
}
- if(colors.size() < 1) {
+ if (colors.size() < 1) {
throw new RuntimeException("can not assign a color");
}
From 2118c7289168159b68b63b7650de4986411d9d6c Mon Sep 17 00:00:00 2001
From: Felix Koppe
Date: Mon, 2 Dec 2024 16:34:55 +0100
Subject: [PATCH 23/28] Adjust RollDiceNotification
---
.../java/pp/mdga/notification/RollDiceNotification.java | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/notification/RollDiceNotification.java b/Projekte/mdga/model/src/main/java/pp/mdga/notification/RollDiceNotification.java
index 13bf849b..14c18e54 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/notification/RollDiceNotification.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/notification/RollDiceNotification.java
@@ -11,17 +11,19 @@ public class RollDiceNotification extends Notification{
private int eyes;
private boolean turbo;
private int multiplier;
+ private boolean isRanking;
/**
* Constructor.
* @param color the color of the player that rolled the die.
* @param eyes the number of eyes that were rolled.
*/
- public RollDiceNotification(Color color, int eyes) {
+ public RollDiceNotification(Color color, int eyes, boolean isRanking) {
this.color = color;
this.eyes = eyes;
this.turbo = false;
this.multiplier = -1;
+ this.isRanking = isRanking;
}
public RollDiceNotification(Color color, int eyes, boolean turbo, int multiplier) {
@@ -29,6 +31,7 @@ public RollDiceNotification(Color color, int eyes, boolean turbo, int multiplier
this.eyes = eyes;
this.turbo = turbo;
this.multiplier = multiplier;
+ this.isRanking = false;
}
/**
@@ -54,4 +57,6 @@ public int getMultiplier() {
public boolean isTurbo() {
return turbo;
}
+
+ public boolean isRanking() { return isRanking; }
}
From eee6fccde512f29a1b9bd002c8081c8e11716f3f Mon Sep 17 00:00:00 2001
From: Daniel Grigencha
Date: Mon, 2 Dec 2024 16:35:40 +0100
Subject: [PATCH 24/28] Updated 'DetermineStartPlayerState' class. Updated the
'DetermineStartPlayerState' class by setting the start state correctly and
enter it.
---
.../pp/mdga/client/gameState/DetermineStartPlayerState.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/DetermineStartPlayerState.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/DetermineStartPlayerState.java
index cf3c48c2..4b95fe68 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/DetermineStartPlayerState.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/DetermineStartPlayerState.java
@@ -25,7 +25,7 @@ public DetermineStartPlayerState(ClientState parent, ClientGameLogic logic) {
@Override
public void enter() {
- state = rollRankingDiceState;
+ this.setState(this.rollRankingDiceState);
}
@Override
From a2856bb1574634ff7c640e5c1ddf4ed3b95d84e7 Mon Sep 17 00:00:00 2001
From: Cedric Beck
Date: Mon, 2 Dec 2024 16:47:28 +0100
Subject: [PATCH 25/28] added rollRankingResults
---
.../pp/mdga/client/InputSynchronizer.java | 7 +++-
.../src/main/java/pp/mdga/client/MdgaApp.java | 2 +-
.../pp/mdga/client/gui/ActionTextHandler.java | 42 ++++++++++++-------
.../java/pp/mdga/client/gui/GuiHandler.java | 5 +++
.../pp/mdga/client/gui/PlayerNameHandler.java | 1 +
.../java/pp/mdga/client/view/GameView.java | 8 +++-
6 files changed, 46 insertions(+), 19 deletions(-)
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/InputSynchronizer.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/InputSynchronizer.java
index b251134f..1f2d5c10 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/InputSynchronizer.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/InputSynchronizer.java
@@ -118,8 +118,11 @@ else if(boardSelect != null) {
}
if(name.equals("Test") &&isPressed){
if(app.getView() instanceof GameView gameView){
-// app.getNotificationSynchronizer().addTestNotification(new FinishNotification(Color.NAVY));
-// app.getNotificationSynchronizer().addTestNotification(new MovePieceNotification());
+ gameView.getGuiHandler().rollRankingResult(Color.AIRFORCE, 1);
+ gameView.getGuiHandler().rollRankingResult(Color.ARMY, 2);
+ gameView.getGuiHandler().rollRankingResult(Color.NAVY, 3);
+ gameView.getGuiHandler().rollRankingResult(Color.CYBER, 4);
+
}
}
}
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java
index 5aa92fc0..cb0371c0 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java
@@ -106,7 +106,7 @@ public void simpleInitApp() {
gameView = new GameView(this);
ceremonyView = new CeremonyView(this);
- enter(MdgaState.GAME);
+ enter(MdgaState.MAIN);
}
/**
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/ActionTextHandler.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/ActionTextHandler.java
index 4dfa0690..8c8c73b9 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/ActionTextHandler.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/ActionTextHandler.java
@@ -10,19 +10,20 @@
import pp.mdga.client.animation.ZoomControl;
import pp.mdga.game.Color;
-public class ActionTextHandler {
+ class ActionTextHandler {
private Node root;
private BitmapFont font;
private AppSettings appSettings;
+ private int ranking;
- public ActionTextHandler(Node guiNode, AssetManager assetManager, AppSettings appSettings){
+ ActionTextHandler(Node guiNode, AssetManager assetManager, AppSettings appSettings){
root = new Node("actionTextRoot");
guiNode.attachChild(root);
root.setLocalTranslation(center(appSettings.getWidth(), appSettings.getHeight(), Vector3f.ZERO));
font = assetManager.loadFont("Fonts/Gunplay.fnt");
this.appSettings = appSettings;
-
+ ranking = 0;
}
private Node createTextWithSpacing(String[] textArr, float spacing, float size, ColorRGBA[] colorArr) {
@@ -74,48 +75,48 @@ private Vector3f centerText(float width, float height, Vector3f pos){
return center(-width, height, pos);
}
- public void activePlayer(String name, Color color){
+ void activePlayer(String name, Color color){
createTopText(new String[]{name," ist dran"}, 10,90,new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, 0).addControl(new ZoomControl());
}
- public void ownActive(Color color){
+ void ownActive(Color color){
createTopText(new String[]{"Du"," bist dran"}, 10,90,new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, 0).addControl(new ZoomControl());
}
- public void diceNum(int diceNum, String name, Color color){
+ void diceNum(int diceNum, String name, Color color){
createTopText(new String[]{name," würfelt:"}, 10,90,new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, 0);
createTopText(String.valueOf(diceNum), 10, 100, ColorRGBA.White, 100);
}
- public void diceNumMult(int diceNum,int mult, String name, Color color){
+ void diceNumMult(int diceNum,int mult, String name, Color color){
createTopText(new String[]{name," würfelt:"}, 10,90,new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, 0);
createTopText(new String[]{String.valueOf(diceNum), " x" + mult + " = " + (diceNum*mult)}, 20, 100, new ColorRGBA[]{ColorRGBA.White,ColorRGBA.Red}, 100);
}
- public void ownDice(int diceNum){
+ void ownDice(int diceNum){
createTopText(String.valueOf(diceNum), 10, 100, ColorRGBA.White, 0);
}
- public void ownDiceMult(int diceNum, int mult){
+ void ownDiceMult(int diceNum, int mult){
createTopText(new String[]{String.valueOf(diceNum), " x" + mult + " = " + (diceNum*mult)}, 20, 100, new ColorRGBA[]{ColorRGBA.White,ColorRGBA.Red}, 0);
}
- public void drawCard(String name, Color color){
+ void drawCard(String name, Color color){
createTopText(new String[]{name," erhält eine Bonuskarte"}, 7,70, new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, 0).addControl(new ZoomControl());
}
- public void drawCardOwn(Color color){
+ void drawCardOwn(Color color){
createTopText(new String[]{"Du"," erhälst eine Bonuskarte"}, 5,70, new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, 0).addControl(new ZoomControl());
}
- public void finishText(String name, Color color){
+ void finishText(String name, Color color){
createTopText(new String[]{name," ist fertig!"}, 7,70, new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, 0).addControl(new ZoomControl());
}
- public void finishTextOwn(Color color){
+ void finishTextOwn(Color color){
createTopText(new String[]{"Du", " bist fertig!"}, 7,70, new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, 0).addControl(new ZoomControl());
}
@@ -131,9 +132,22 @@ private ColorRGBA playerColorToColorRGBA(Color color){
};
}
- public void hide(){
+ void hide(){
+ ranking = 0;
root.detachAllChildren();
}
+ float paddingRanked = 100;
+
+ void rollRankingResult(String name, Color color, int eye){
+ createTopText(new String[]{name,": "+eye}, 10,90,new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, paddingRanked*ranking);
+ ranking++;
+ }
+
+ void rollRankingResultOwn(Color color, int eye){
+ createTopText(new String[]{"Du",": "+eye}, 10,90,new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, paddingRanked*ranking);
+ ranking++;
+ }
+
}
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/GuiHandler.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/GuiHandler.java
index 8761e3da..91e091eb 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/GuiHandler.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/GuiHandler.java
@@ -134,5 +134,10 @@ public void finish(Color color){
else actionTextHandler.finishText(playerNameHandler.getName(color), color);
}
+ public void rollRankingResult(Color color, int eye){
+ if(ownColor == color) actionTextHandler.rollRankingResultOwn(color, eye);
+ else actionTextHandler.rollRankingResult(playerNameHandler.getName(color), color, eye);
+ }
+
}
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/PlayerNameHandler.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/PlayerNameHandler.java
index 1b197d16..2d4bdbf7 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/PlayerNameHandler.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/PlayerNameHandler.java
@@ -120,6 +120,7 @@ public void setActivePlayer(Color color) {
}
public String getName(Color color){
+ if(!colorNameMap.containsKey(color)) throw new RuntimeException("color is not in colorNameMap");
return colorNameMap.get(color);
}
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/view/GameView.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/view/GameView.java
index 9d1a7fe5..f28719ac 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/view/GameView.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/view/GameView.java
@@ -65,8 +65,12 @@ public void onEnter() {
app.getAcousticHandler().playSound(MdgaSound.START);
- app.getNotificationSynchronizer().addTestNotification(new AcquireCardNotification(BonusCard.SHIELD));
- app.getNotificationSynchronizer().addTestNotification(new SelectableCardsNotification(List.of(BonusCard.SHIELD)));
+// guiHandler.addPlayer(Color.AIRFORCE, "Cedric");
+// guiHandler.addPlayer(Color.ARMY, "Ben");
+// guiHandler.addPlayer(Color.CYBER, "Felix");
+// guiHandler.addPlayer(Color.NAVY, "Daniel");
+
+
}
@Override
From 0411f2ead41f03a5cfdefb11bfb0829b58b15557 Mon Sep 17 00:00:00 2001
From: Hanno Fleischer
Date: Mon, 2 Dec 2024 17:08:46 +0100
Subject: [PATCH 26/28] fixed state transitions in gamestateclient automaton
---
.../src/main/java/pp/mdga/client/CeremonyState.java | 6 ++++--
.../src/main/java/pp/mdga/client/DialogsState.java | 11 ++++-------
.../model/src/main/java/pp/mdga/client/GameState.java | 9 +++++----
.../java/pp/mdga/client/dialogState/LobbyState.java | 2 +-
.../client/gameState/DetermineStartPlayerState.java | 4 +++-
.../main/java/pp/mdga/client/gameState/TurnState.java | 6 ++++--
.../RollRankingDiceState.java | 4 +++-
.../client/gameState/turnState/ChoosePieceState.java | 8 +++++---
.../client/gameState/turnState/PowerCardState.java | 6 ++++--
9 files changed, 33 insertions(+), 23 deletions(-)
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/CeremonyState.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/CeremonyState.java
index 38541512..cf6e5e5a 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/client/CeremonyState.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/CeremonyState.java
@@ -18,7 +18,7 @@ public CeremonyState(ClientState parent, ClientGameLogic logic) {
@Override
public void enter() {
- currentState = podiumState;
+ setState(podiumState);
logic.addNotification(createCeremonyNotification());
}
@@ -28,7 +28,9 @@ public void exit() {
}
public void setState(CeremonyStates state){
- this.currentState.exit();
+ if(this.currentState != null){
+ this.currentState.exit();
+ }
state.enter();
currentState = state;
}
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/DialogsState.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/DialogsState.java
index c3f33c97..c8578cd3 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/client/DialogsState.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/DialogsState.java
@@ -30,13 +30,15 @@ public void exit(){
@Override
public void enter(){
- currentState = startDialogState;
+ setState(startDialogState);
ownPlayerID = 0;
ownPlayerName = null;
}
public void setState(DialogStates newState){
- currentState.exit();
+ if(currentState != null){
+ currentState.exit();
+ }
newState.enter();
currentState = newState;
}
@@ -69,11 +71,6 @@ public StartDialogState getStartDialog() {
return startDialogState;
}
- public void startGame(){
- exit();
- logic.setState(logic.getGameState());
- }
-
@Override
public void selectLeave(){
currentState.selectLeave();
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/GameState.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/GameState.java
index af449db8..31b3f340 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/client/GameState.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/GameState.java
@@ -27,7 +27,6 @@ public class GameState extends ClientState {
*/
public GameState(ClientState parent, ClientGameLogic logic) {
super(parent, logic);
- state = determineStartPlayerState;
}
/**
@@ -35,7 +34,7 @@ public GameState(ClientState parent, ClientGameLogic logic) {
*/
@Override
public void enter() {
-
+ this.setState(this.determineStartPlayerState);
}
/**
@@ -52,8 +51,10 @@ public void exit() {
* @param newState the state to be set
*/
public void setState(GameStates newState){
- state.exit();
- state.enter();
+ if(this.state != null){
+ this.state.exit();
+ }
+ newState.enter();
state = newState;
}
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/dialogState/LobbyState.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/dialogState/LobbyState.java
index 6d70ba50..2d48cbe1 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/client/dialogState/LobbyState.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/dialogState/LobbyState.java
@@ -95,7 +95,7 @@ public void received(ServerStartGameMessage msg){
}
logic.addNotification(new PlayerInGameNotification(entry.getKey(), pieceList , logic.getGame().getPlayerByColor(entry.getKey()).getName()));
}
- parent.startGame();
+ logic.setState(logic.getGameState());
}
@Override
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/DetermineStartPlayerState.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/DetermineStartPlayerState.java
index 4b95fe68..4794785a 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/DetermineStartPlayerState.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/DetermineStartPlayerState.java
@@ -34,7 +34,9 @@ public void exit() {
}
public void setState(DetermineStartPlayerStates state) {
- this.state.exit();
+ if(this.state != null){
+ this.state.exit();
+ }
state.enter();
this.state = state;
}
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/TurnState.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/TurnState.java
index b59a35b8..5f075eff 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/TurnState.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/TurnState.java
@@ -31,7 +31,7 @@ public TurnState(ClientState parent, ClientGameLogic logic) {
@Override
public void enter() {
- state = powerCardState;
+ this.setState(this.powerCardState);
}
@Override
@@ -40,7 +40,9 @@ public void exit() {
}
public void setState(TurnStates state){
- this.state.exit();
+ if(this.state != null){
+ this.state.exit();
+ }
state.enter();
this.state = state;
}
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/determineStartPlayerState/RollRankingDiceState.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/determineStartPlayerState/RollRankingDiceState.java
index 3c1ec5b9..e6a98522 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/determineStartPlayerState/RollRankingDiceState.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/determineStartPlayerState/RollRankingDiceState.java
@@ -6,6 +6,7 @@
import pp.mdga.message.client.RequestDieMessage;
import pp.mdga.message.server.DieMessage;
import pp.mdga.notification.DiceNowNotification;
+import pp.mdga.notification.RollDiceNotification;
public class RollRankingDiceState extends DetermineStartPlayerStates {
@@ -23,16 +24,17 @@ public void enter() {
@Override
public void exit() {
-
}
@Override
public void selectDice(){
+ System.out.println("selectDice");
logic.send(new RequestDieMessage());
}
@Override
public void received(DieMessage msg){
+ logic.addNotification(new RollDiceNotification(logic.getGame().getPlayerById(logic.getDialogs().getOwnPlayerId()).getColor(), msg.getDiceEye(),true));
parent.setState(parent.getWaitRanking());
}
}
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/turnState/ChoosePieceState.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/turnState/ChoosePieceState.java
index b1a0c7e3..47dce439 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/turnState/ChoosePieceState.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/turnState/ChoosePieceState.java
@@ -24,7 +24,7 @@ public ChoosePieceState(ClientState parent, ClientGameLogic logic) {
@Override
public void enter() {
- currentState = noPieceState;
+ this.setState(this.noPieceState);
}
@Override
@@ -34,9 +34,11 @@ public void exit() {
}
public void setState(ChoosePieceStates state){
- currentState.exit();
+ if(currentState != null){
+ currentState.exit();
+ }
+ state.enter();
currentState = state;
- currentState.enter();
}
@Override
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/turnState/PowerCardState.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/turnState/PowerCardState.java
index fd80b68d..5a5fd5c3 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/turnState/PowerCardState.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/turnState/PowerCardState.java
@@ -31,7 +31,7 @@ public PowerCardState(ClientState parent, ClientGameLogic logic) {
@Override
public void enter() {
- state = choosePowerCardState;
+ this.setState(this.choosePowerCardState);
}
public void exit() {
@@ -40,7 +40,9 @@ public void exit() {
}
public void setState(PowerCardStates state) {
- this.state.exit();
+ if(this.state != null){
+ this.state.exit();
+ }
state.enter();
this.state = state;
}
From 208261c6bfc27a6e394bca85270ff100a88a0ec5 Mon Sep 17 00:00:00 2001
From: Cedric Beck
Date: Mon, 2 Dec 2024 17:11:55 +0100
Subject: [PATCH 27/28] added clickDice Action + modelSync
---
.../java/pp/mdga/client/InputSynchronizer.java | 18 ++++++++++++------
.../pp/mdga/client/gui/ActionTextHandler.java | 5 ++++-
.../java/pp/mdga/client/gui/GuiHandler.java | 1 +
3 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/InputSynchronizer.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/InputSynchronizer.java
index 1f2d5c10..4e22978d 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/InputSynchronizer.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/InputSynchronizer.java
@@ -17,6 +17,7 @@
import pp.mdga.client.board.OutlineControl;
import pp.mdga.client.board.PieceControl;
import pp.mdga.client.gui.CardControl;
+import pp.mdga.client.gui.DiceControl;
import pp.mdga.client.view.GameView;
import pp.mdga.game.BonusCard;
import pp.mdga.game.Color;
@@ -93,10 +94,15 @@ public void onAction(String name, boolean isPressed, float tpf) {
}
if(name.equals("Click") && isPressed) {
if (app.getView() instanceof GameView gameView) {
+ DiceControl diceSelect = checkHover(gameView.getGuiHandler().getCardLayerCamera(), gameView.getGuiHandler().getCardLayerRootNode(), DiceControl.class);
CardControl cardLayerSelect = checkHover(gameView.getGuiHandler().getCardLayerCamera(), gameView.getGuiHandler().getCardLayerRootNode(), CardControl.class);
OutlineControl boardSelect = checkHover(app.getCamera(), app.getRootNode(), OutlineControl.class);
- if(cardLayerSelect != null) {
+ if(diceSelect != null) {
+ app.getModelSynchronize().rolledDice();
+ gameView.getGuiHandler().hideText();
+ }
+ else if(cardLayerSelect != null) {
//cardSelect
if(cardLayerSelect.isSelectable()) gameView.getGuiHandler().selectCard(cardLayerSelect);
}
@@ -118,11 +124,11 @@ else if(boardSelect != null) {
}
if(name.equals("Test") &&isPressed){
if(app.getView() instanceof GameView gameView){
- gameView.getGuiHandler().rollRankingResult(Color.AIRFORCE, 1);
- gameView.getGuiHandler().rollRankingResult(Color.ARMY, 2);
- gameView.getGuiHandler().rollRankingResult(Color.NAVY, 3);
- gameView.getGuiHandler().rollRankingResult(Color.CYBER, 4);
-
+// gameView.getGuiHandler().rollRankingResult(Color.AIRFORCE, 1);
+// gameView.getGuiHandler().rollRankingResult(Color.ARMY, 2);
+// gameView.getGuiHandler().rollRankingResult(Color.NAVY, 3);
+// gameView.getGuiHandler().rollRankingResult(Color.CYBER, 4);
+ gameView.getGuiHandler().showDice();
}
}
}
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/ActionTextHandler.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/ActionTextHandler.java
index 8c8c73b9..b5bd3571 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/ActionTextHandler.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/ActionTextHandler.java
@@ -134,7 +134,7 @@ private ColorRGBA playerColorToColorRGBA(Color color){
void hide(){
ranking = 0;
- root.detachAllChildren();
+ root.detachAllChildren();
}
float paddingRanked = 100;
@@ -149,5 +149,8 @@ void rollRankingResultOwn(Color color, int eye){
ranking++;
}
+ void diceNow(){
+ createTopText("Klicke zum Würfeln", 5, 80, ColorRGBA.White, 0);
+ }
}
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/GuiHandler.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/GuiHandler.java
index 91e091eb..d4128081 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/GuiHandler.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/GuiHandler.java
@@ -67,6 +67,7 @@ public void showRolledDice(int rollNum, Color color) {
public void showDice() {
cardLayerHandler.showDice();
+ actionTextHandler.diceNow();
}
public void hideDice() {
From f21fd9b0a66aca701dd2c8232a7fae9390d0d379 Mon Sep 17 00:00:00 2001
From: Cedric Beck
Date: Mon, 2 Dec 2024 17:28:37 +0100
Subject: [PATCH 28/28] added setPauseOnLostFocus(false)
---
.../src/main/java/pp/mdga/client/InputSynchronizer.java | 1 -
.../mdga/client/src/main/java/pp/mdga/client/MdgaApp.java | 1 +
.../java/pp/mdga/client/NotificationSynchronizer.java | 1 +
.../java/pp/mdga/notification/RollDiceNotification.java | 8 ++++++++
4 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/InputSynchronizer.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/InputSynchronizer.java
index 4e22978d..807a37c4 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/InputSynchronizer.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/InputSynchronizer.java
@@ -100,7 +100,6 @@ public void onAction(String name, boolean isPressed, float tpf) {
if(diceSelect != null) {
app.getModelSynchronize().rolledDice();
- gameView.getGuiHandler().hideText();
}
else if(cardLayerSelect != null) {
//cardSelect
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java
index 2fddea2f..9eca1ab8 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java
@@ -82,6 +82,7 @@ public static void main(String[] args) {
MdgaApp app = new MdgaApp();
app.setSettings(settings);
app.setShowSettings(false);
+ app.setPauseOnLostFocus(false);
app.start();
}
diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/NotificationSynchronizer.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/NotificationSynchronizer.java
index 6e080158..f23eda0e 100644
--- a/Projekte/mdga/client/src/main/java/pp/mdga/client/NotificationSynchronizer.java
+++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/NotificationSynchronizer.java
@@ -148,6 +148,7 @@ private void handleGame(Notification notification) {
} else if (notification instanceof ResumeNotification) {
//TODO
} else if (notification instanceof RollDiceNotification n) {
+ gameView.getGuiHandler().hideText();
if(n.getColor() == gameView.getOwnColor()){
guiHandler.rollDice(n.getEyes(), n.isTurbo() ? n.getMultiplier() : -1);
}
diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/notification/RollDiceNotification.java b/Projekte/mdga/model/src/main/java/pp/mdga/notification/RollDiceNotification.java
index 14c18e54..2e6f03e1 100644
--- a/Projekte/mdga/model/src/main/java/pp/mdga/notification/RollDiceNotification.java
+++ b/Projekte/mdga/model/src/main/java/pp/mdga/notification/RollDiceNotification.java
@@ -18,6 +18,14 @@ public class RollDiceNotification extends Notification{
* @param color the color of the player that rolled the die.
* @param eyes the number of eyes that were rolled.
*/
+ public RollDiceNotification(Color color, int eyes) {
+ this.color = color;
+ this.eyes = eyes;
+ this.turbo = false;
+ this.multiplier = -1;
+ this.isRanking = false;
+ }
+
public RollDiceNotification(Color color, int eyes, boolean isRanking) {
this.color = color;
this.eyes = eyes;