diff --git a/Battle.j3o b/Battle.j3o
new file mode 100644
index 0000000..9e1ef4d
Binary files /dev/null and b/Battle.j3o differ
diff --git a/BoatSmall.j3o b/BoatSmall.j3o
new file mode 100644
index 0000000..c13785d
Binary files /dev/null and b/BoatSmall.j3o differ
diff --git a/CV.j3o b/CV.j3o
new file mode 100644
index 0000000..c49ddb2
Binary files /dev/null and b/CV.j3o differ
diff --git a/KingGeorgeV.j3o b/KingGeorgeV.j3o
new file mode 100644
index 0000000..b030d91
Binary files /dev/null and b/KingGeorgeV.j3o differ
diff --git a/Projekte/battleship/converter/src/main/java/pp/battleship/exporter/ModelExporter.java b/Projekte/battleship/converter/src/main/java/pp/battleship/exporter/ModelExporter.java
index ae9350b..5a95a98 100644
--- a/Projekte/battleship/converter/src/main/java/pp/battleship/exporter/ModelExporter.java
+++ b/Projekte/battleship/converter/src/main/java/pp/battleship/exporter/ModelExporter.java
@@ -45,7 +45,12 @@ public class ModelExporter extends SimpleApplication {
         export("Models/BoatSmall/12219_boat_v2_L2.obj", "BoatSmall.j3o"); //NON-NLS
         export("Models/Battle/14084_WWII_Ship_German_Type_II_U-boat_v2_L1.obj", "Battle.j3o"); //NON-NLS
         export("Models/CV/essex_scb-125_generic.obj", "CV.j3o"); //NON-NLS
-
+        export("Models/Figures/Würfel_blau.obj", "Würfel_blau.j30");
+        export("Models/Figures/Würfel_gelb.obj", "Würfel_gelb.j30");
+        export("Models/Figures/Würfel_grün.obj", "Würfel_grün.j30");
+        export("Models/Figures/Würfel_rosa.obj", "Würfel_rosa.j30");
+        export("Models/Figures/Würfel_rot.obj", "Würfel_rot.j30");
+        export("Models/Figures/Würfel_schwarz.obj", "Würfel_schwarz.j30");
         stop();
     }
 
diff --git a/Projekte/jme-common/src/main/resources/Interface/Lemur/pp-styles.groovy b/Projekte/jme-common/src/main/resources/Interface/Lemur/pp-styles.groovy
index 957bc68..36ee17e 100644
--- a/Projekte/jme-common/src/main/resources/Interface/Lemur/pp-styles.groovy
+++ b/Projekte/jme-common/src/main/resources/Interface/Lemur/pp-styles.groovy
@@ -1,76 +1,69 @@
 // Styling of Lemur components
 // For documentation, see:
 // https://github.com/jMonkeyEngine-Contributions/Lemur/wiki/Styling
-
 import com.simsilica.lemur.*
 import com.simsilica.lemur.component.QuadBackgroundComponent
+import com.simsilica.lemur.Button
+import com.simsilica.lemur.Button.ButtonAction
+import com.simsilica.lemur.Command
+import com.simsilica.lemur.HAlignment
+import com.simsilica.lemur.Insets3f
+import com.simsilica.lemur.component.QuadBackgroundComponent
+import com.simsilica.lemur.component.TbtQuadBackgroundComponent
 
 def bgColor = color(1, 1, 1, 1)
-def buttonEnabledColor = color(0.8, 0.9, 1, 1)
+def buttonEnabledColor = color(0, 0, 0, 1)
 def buttonDisabledColor = color(0.8, 0.9, 1, 0.2)
-//def buttonBgColor = color(0, 0.75, 0.75, 1)
+def buttonBgColor = color(1, 1, 1, 1)
 def sliderColor = color(0.6, 0.8, 0.8, 1)
 def sliderBgColor = color(0.5, 0.75, 0.75, 1)
-def gradientColor = color(1, 1, 1, 1)
+def gradientColor = color(0.5, 0.75, 0.85, 0.5)
 def tabbuttonEnabledColor = color(0.4, 0.45, 0.5, 1)
-def playButtonBorderColor = color(1, 0.6, 0, 1) // For "Spielen" button
-def blackColor = color(0, 0, 0, 1) // Define black color for border
+def solidWhiteBackground = new QuadBackgroundComponent(color(1, 1, 1, 1)) // Solid white
 
-def playButtonBorderColor = color(1, 0.6, 0, 1) // Orange border for "Spielen" button
-def playButtonTextColor = color(0, 0, 0, 1) // Black text color for "Spielen" button
-def buttonBgColor = color(1, 1, 1, 1) // White background for "Spiel beenden" and "Einstellungen" buttons
-def buttonTextColor = color(0, 0, 0, 1) // Black text color for "Spiel beenden" and "Einstellungen" buttons
-def borderColor = color(0, 0, 0, 1) // Black border for "Spiel beenden" and "Einstellungen"
 
 
 def gradient = TbtQuadBackgroundComponent.create(
-        texture(name: "/com/simsilica/lemur/icons/bordered-gradient.png", generateMips: false),
-       1, 1, 1, 126, 126, 1f, false)
+        texture(name: "/com/simsilica/lemur/icons/bordered-gradient.png",
+                generateMips: false),
+        1, 1, 1, 126, 126,
+        1f, false)
 
 def doubleGradient = new QuadBackgroundComponent(gradientColor)
-doubleGradient.texture = texture(name: "/com/simsilica/lemur/icons/double-gradient-128.png", generateMips: false)
+doubleGradient.texture = texture(name: "/com/simsilica/lemur/icons/double-gradient-128.png",
+        generateMips: false)
+
+def orangeBorder = TbtQuadBackgroundComponent.create(
+        texture(name: "/com/simsilica/lemur/icons/bordered-gradient.png", // Replace with an appropriate texture if needed
+                generateMips: false),
+        1, 1, 1, 126, 126,
+        1f, false)
+orangeBorder.color = color(1, 0.5, 0, 1) // Orange color
 
-// Hauptstil für die Schriftart
 selector("pp") {
     font = font("Interface/Fonts/Metropolis/Metropolis-Regular-32.fnt")
 }
 
-// Titel für "Einstellungen"
-selector("settings-title", "pp") {
-    color = color(1, 1, 1, 1)
-    fontSize = 48
-    textHAlignment = HAlignment.Center
-    insets = new Insets3f(5, 5, 5, 5)
+selector("label", "pp") {
+    insets = new Insets3f(2, 2, 2, 2)
+    color = buttonEnabledColor
+}
+
+selector("header", "pp") {
+    font = font("Interface/Fonts/Metropolis/Metropolis-Bold-42.fnt")
+    insets = new Insets3f(2, 2, 2, 2)
+    color = color(1, 0.5, 0, 1)
+    textHAlignment = HAlignment.Center
 }
 
-// Container Stil
 selector("container", "pp") {
-    background = gradient.clone()
+    background = solidWhiteBackground.clone()
     background.setColor(bgColor)
 }
 
-// Slider Stil
 selector("slider", "pp") {
-    insets = new Insets3f(5, 10, 5, 10) // Abstand
-    background = new QuadBackgroundComponent(sliderBgColor)
-}
-
-selector("play-button", "pp") {
-    color = playButtonTextColor // Black text color
-    background = new QuadBackgroundComponent(playButtonBorderColor) // Orange border background
-    insets = new Insets3f(15, 25, 15, 25) // Padding for larger button size
-    background.setMargin(5, 5) // Thin border effect around the background color
-    fontSize = 36 // Larger font size for prominence
-}
-
-selector("menu-button", "pp") {
-    color = buttonTextColor // Black text color
-    background = new QuadBackgroundComponent(buttonBgColor) // White background
-    insets = new Insets3f(10, 20, 10, 20) // Padding
-    background.setMargin(1, 1) // Thin black border
-    background.setColor(borderColor) // Set black border color
-
-    fontSize = 24 // Standard font size
+    background = gradient.clone()
+    background.setColor(bgColor)
 }
 
 def pressedCommand = new Command<Button>() {
@@ -91,6 +84,30 @@ def enabledCommand = new Command<Button>() {
     }
 }
 
+def repeatCommand = new Command<Button>() {
+    private long startTime
+    private long lastClick
+
+    void execute(Button source) {
+        // Only do the repeating click while the mouse is
+        // over the button (and pressed of course)
+        if (source.isPressed() && source.isHighlightOn()) {
+            long elapsedTime = System.currentTimeMillis() - startTime
+            // After half a second pause, click 8 times a second
+            if (elapsedTime > 500 && elapsedTime > lastClick + 125) {
+                source.click()
+
+                // Try to quantize the last click time to prevent drift
+                lastClick = ((elapsedTime - 500) / 125) * 125 + 500
+            }
+        }
+        else {
+            startTime = System.currentTimeMillis()
+            lastClick = 0
+        }
+    }
+}
+
 def stdButtonCommands = [
         (ButtonAction.Down)    : [pressedCommand],
         (ButtonAction.Up)      : [pressedCommand],
@@ -98,9 +115,101 @@ def stdButtonCommands = [
         (ButtonAction.Disabled): [enabledCommand]
 ]
 
-selector("button", "pp") {
-    background = gradient.clone()
-    color = buttonEnabledColor
+def sliderButtonCommands = [
+        (ButtonAction.Hover): [repeatCommand]
+]
+
+selector("title", "pp") {
+    color = color(0.8, 0.9, 1, 0.85f)
+    highlightColor = color(1, 0.8, 1, 0.85f)
+    shadowColor = color(0, 0, 0, 0.75f)
+    shadowOffset = vec3(2, -2, -1)
+    background = new QuadBackgroundComponent(color(0.5, 0.75, 0.85, 1))
+    background.texture = texture(name: "/com/simsilica/lemur/icons/double-gradient-128.png",
+            generateMips: false)
     insets = new Insets3f(2, 2, 2, 2)
+
+    buttonCommands = stdButtonCommands
+}
+
+
+selector("button", "pp") {
+    def outerBackground = new QuadBackgroundComponent(color(1, 0.5, 0, 1)) // Orange border
+    def innerBackground = new QuadBackgroundComponent(buttonBgColor) // Inner button background
+
+    // Apply the outer border as the main background
+    background = outerBackground
+
+    // Use insets to create a margin/padding effect for the inner background
+    insets = new Insets3f(3, 3, 3, 3) // Adjust the border thickness
+    buttonCommands = stdButtonCommands
+}
+
+selector("slider", "pp") {
+    insets = new Insets3f(1, 3, 1, 2)
+}
+
+selector("slider", "button", "pp") {
+    background = doubleGradient.clone()
+    //background.setColor(sliderBgColor)
+    insets = new Insets3f(0, 0, 0, 0)
+}
+
+selector("slider.thumb.button", "pp") {
+    text = "[]"
+    color = sliderColor
+}
+
+selector("slider.left.button", "pp") {
+    text = "-"
+    background = doubleGradient.clone()
+    //background.setColor(sliderBgColor)
+    background.setMargin(5, 0)
+    color = sliderColor
+
+    buttonCommands = sliderButtonCommands
+}
+
+selector("slider.right.button", "pp") {
+    text = "+"
+    background = doubleGradient.clone()
+    //background.setColor(sliderBgColor)
+    background.setMargin(4, 0)
+    color = sliderColor
+
+    buttonCommands = sliderButtonCommands
+}
+
+selector("slider.up.button", "pp") {
+    buttonCommands = sliderButtonCommands
+}
+
+selector("slider.down.button", "pp") {
+    buttonCommands = sliderButtonCommands
+}
+
+selector("checkbox", "pp") {
+    color = buttonEnabledColor
+}
+
+selector("rollup", "pp") {
+    background = gradient.clone()
+    background.setColor(bgColor)
+}
+
+selector("tabbedPanel", "pp") {
+    activationColor = buttonEnabledColor
+}
+
+selector("tabbedPanel.container", "pp") {
+    background = null
+}
+
+selector("tab.button", "pp") {
+    background = solidWhiteBackground.clone()
+    background.setColor(bgColor)
+    color = tabbuttonEnabledColor
+    insets = new Insets3f(4, 2, 0, 2)
+
     buttonCommands = stdButtonCommands
 }
diff --git a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/GameSound.java b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/GameSound.java
index df498f5..bf5d649 100644
--- a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/GameSound.java
+++ b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/GameSound.java
@@ -1,3 +1,10 @@
+////////////////////////////////////////
+// Programming project code
+// UniBw M, 2022, 2023, 2024
+// www.unibw.de/inf2
+// (c) Mark Minas (mark.minas@unibw.de)
+////////////////////////////////////////
+
 package pp.monopoly.client;
 
 import java.lang.System.Logger;
@@ -7,6 +14,8 @@ import java.util.prefs.Preferences;
 import com.jme3.app.Application;
 import com.jme3.app.state.AbstractAppState;
 import com.jme3.app.state.AppStateManager;
+import com.jme3.asset.AssetLoadException;
+import com.jme3.asset.AssetNotFoundException;
 import com.jme3.audio.AudioData;
 import com.jme3.audio.AudioNode;
 
@@ -15,14 +24,16 @@ import pp.monopoly.notification.SoundEvent;
 import static pp.util.PreferencesUtils.getPreferences;
 
 /**
- * An application state that plays sounds based on game events.
+ * An application state that plays sounds.
  */
 public class GameSound extends AbstractAppState implements GameEventListener {
     private static final Logger LOGGER = System.getLogger(GameSound.class.getName());
     private static final Preferences PREFERENCES = getPreferences(GameSound.class);
-    private static final String ENABLED_PREF = "enabled";
+    private static final String ENABLED_PREF = "enabled"; //NON-NLS
 
-    private Application app; // Feld zum Speichern der Application-Instanz
+    private AudioNode splashSound;
+    private AudioNode shipDestroyedSound;
+    private AudioNode explosionSound;
 
     /**
      * Checks if sound is enabled in the preferences.
@@ -42,6 +53,7 @@ public class GameSound extends AbstractAppState implements GameEventListener {
 
     /**
      * Sets the enabled state of this AppState.
+     * Overrides {@link com.jme3.app.state.AbstractAppState#setEnabled(boolean)}
      *
      * @param enabled {@code true} to enable the AppState, {@code false} to disable it.
      */
@@ -49,52 +61,69 @@ public class GameSound extends AbstractAppState implements GameEventListener {
     public void setEnabled(boolean enabled) {
         if (isEnabled() == enabled) return;
         super.setEnabled(enabled);
-        LOGGER.log(Level.INFO, "Sound enabled: {0}", enabled);
+        LOGGER.log(Level.INFO, "Sound enabled: {0}", enabled); //NON-NLS
         PREFERENCES.putBoolean(ENABLED_PREF, enabled);
     }
 
     /**
-     * Initializes the sound effects for the game and stores the application reference.
+     * Initializes the sound effects for the game.
+     * Overrides {@link AbstractAppState#initialize(AppStateManager, Application)}
      *
      * @param stateManager The state manager
-     * @param app          The application instance
+     * @param app          The application
      */
     @Override
     public void initialize(AppStateManager stateManager, Application app) {
         super.initialize(stateManager, app);
-        this.app = app; // Speichert die Application-Instanz
     }
 
     /**
      * Loads a sound from the specified file.
      *
+     * @param app  The application
      * @param name The name of the sound file.
      * @return The loaded AudioNode.
      */
-    private AudioNode loadSound(String name) {
+    private AudioNode loadSound(Application app, String name) {
         try {
-            AudioNode sound = new AudioNode(app.getAssetManager(), name, AudioData.DataType.Buffer);
+            final AudioNode sound = new AudioNode(app.getAssetManager(), name, AudioData.DataType.Buffer);
             sound.setLooping(false);
             sound.setPositional(false);
             return sound;
-        } catch (Exception ex) {
+        }
+        catch (AssetLoadException | AssetNotFoundException ex) {
             LOGGER.log(Level.ERROR, ex.getMessage(), ex);
         }
         return null;
     }
 
     /**
-     * Handles sound-related game events to play specific sounds.
-     *
-     * @param event The sound event received.
+     * Plays the splash sound effect.
      */
+    public void splash() {
+        if (isEnabled() && splashSound != null)
+            splashSound.playInstance();
+    }
+
+    /**
+     * Plays the explosion sound effect.
+     */
+    public void explosion() {
+        if (isEnabled() && explosionSound != null)
+            explosionSound.playInstance();
+    }
+
+    /**
+     * Plays sound effect when a ship has been destroyed.
+     */
+    public void shipDestroyed() {
+        if (isEnabled() && shipDestroyedSound != null)
+            shipDestroyedSound.playInstance();
+    }
+
     @Override
     public void receivedEvent(SoundEvent event) {
-        if (isEnabled()) {
-            AudioNode sound = loadSound(event.getSoundFileName());
-            if (sound != null) {
-                sound.play();
-            }
+        switch (event.sound()) {
         }
     }
-}//heloo
+}
diff --git a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/MonopolyApp.java b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/MonopolyApp.java
index 68c73d9..baac5f7 100644
--- a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/MonopolyApp.java
+++ b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/MonopolyApp.java
@@ -9,12 +9,7 @@ import com.jme3.font.BitmapText;
 import com.jme3.input.KeyInput;
 import com.jme3.input.controls.ActionListener;
 import com.jme3.input.controls.KeyTrigger;
-import com.jme3.material.Material;
-import com.jme3.math.Vector3f;
-import com.jme3.scene.Geometry;
-import com.jme3.scene.shape.Box;
 import com.jme3.system.AppSettings;
-import com.jme3.texture.Texture;
 import com.simsilica.lemur.GuiGlobals;
 import com.simsilica.lemur.style.BaseStyles;
 
@@ -22,6 +17,7 @@ import pp.dialog.DialogBuilder;
 import pp.dialog.DialogManager;
 import pp.graphics.Draw;
 import pp.monopoly.client.gui.SettingsMenu;
+import pp.monopoly.client.gui.TestWorld;
 import pp.monopoly.game.client.ClientGameLogic;
 import pp.monopoly.game.client.MonopolyClient;
 import pp.monopoly.game.client.ServerConnection;
@@ -36,10 +32,20 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
     private final ActionListener escapeListener = (name, isPressed, tpf) -> handleEscape(isPressed);
     private final DialogManager dialogManager = new DialogManager(this);
     private final ExecutorService executor = Executors.newCachedThreadPool();
-    private SettingsMenu settingsMenu;
     private final Draw draw;
-
+    private SettingsMenu settingsMenu;
+    private TestWorld testWorld;
     private boolean isSettingsMenuOpen = false;
+    private boolean inputBlocked = false;
+    /**
+     * Path to the styles script for GUI elements.
+     */
+    private static final String STYLES_SCRIPT = "Interface/Lemur/pp-styles.groovy"; //NON-NLS
+    /**
+     * Path to the font resource used in the GUI.
+     */
+    private static final String FONT = "Interface/Fonts/Default.fnt"; //NON-NLS
+
 
     public static void main(String[] args) {
         new MonopolyApp().start();
@@ -55,55 +61,6 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
         setSettings(makeSettings());
     }
 
-    /**
-     * Creates and configures application settings from the client configuration.
-     *
-     * @return A configured {@link AppSettings} object.
-     */
-    private AppSettings makeSettings() {
-        final AppSettings settings = new AppSettings(true);
-        settings.setTitle(lookup("monopoly.name"));
-        settings.setResolution(config.getResolutionWidth(), config.getResolutionHeight());
-        settings.setFullscreen(config.fullScreen());
-        settings.setUseRetinaFrameBuffer(config.useRetinaFrameBuffer());
-        settings.setGammaCorrection(config.useGammaCorrection());
-        return settings;
-    }
-
-    /**
-     * Factory method for creating a server connection based on the current
-     * client configuration.
-     *
-     * @return A {@link ServerConnection} instance, which could be a real or mock server.
-     */
-    private ServerConnection makeServerConnection() {
-        return new NetworkSupport(this);
-    }
-
-    /**
-     * Returns the dialog manager responsible for managing in-game dialogs.
-     *
-     * @return The {@link DialogManager} instance.
-     */
-    public DialogManager getDialogManager() {
-        return dialogManager;
-    }
-
-    /**
-     * Returns the game logic handler for the client.
-     *
-     * @return The {@link ClientGameLogic} instance.
-     */
-    @Override
-    public ClientGameLogic getGameLogic() {
-        return logic;
-    }
-
-    /**
-     * Returns the current configuration settings for the Monopoly client.
-     *
-     * @return The {@link MonopolyClientConfig} instance.
-     */
     @Override
     public MonopolyAppConfig getConfig() {
         return config;
@@ -122,24 +79,17 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
         return settings;
     }
 
-    public boolean isSettingsMenuOpen() {
-        return isSettingsMenuOpen;
-    }
-
-    public void setSettingsMenuOpen(boolean isOpen) {
-        this.isSettingsMenuOpen = isOpen;
-    }
-
     @Override
     public void simpleInitApp() {
-        GuiGlobals.initialize(this); 
-        BaseStyles.loadGlassStyle();
-        GuiGlobals.getInstance().getStyles().setDefaultStyle("glass");
+        GuiGlobals.initialize(this);
+        BaseStyles.loadStyleResources(STYLES_SCRIPT);
+        GuiGlobals.getInstance().getStyles().setDefaultStyle("pp"); //NON-NLS
+        final BitmapFont normalFont = assetManager.loadFont(FONT); //NON-NLS
 
         setupInput();
         setupGui();
 
-        // Initialisiere das Startmenü
+        // Zeige das Startmenü
         StartMenu.createStartMenu(this);
     }
 
@@ -156,23 +106,45 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
         inputManager.addMapping("ESC", new KeyTrigger(KeyInput.KEY_ESCAPE));
         inputManager.addListener(escapeListener, "ESC");
     }
-    
 
     private void handleEscape(boolean isPressed) {
         if (isPressed) {
-            if (isSettingsMenuOpen && settingsMenu != null) {
+            if (settingsMenu != null && isSettingsMenuOpen) {
+                // Schließe das SettingsMenu
+                System.out.println("Schließe SettingsMenu...");
                 settingsMenu.close();
+                settingsMenu = null;
                 setSettingsMenuOpen(false);
             } else {
+                // Öffne das SettingsMenu
+                System.out.println("Öffne SettingsMenu...");
                 settingsMenu = new SettingsMenu(this);
                 settingsMenu.open();
                 setSettingsMenuOpen(true);
             }
         }
     }
+    
+    
 
+    private void blockInputs() {
+        if (!inputBlocked) {
+            System.out.println("Blockiere Eingaben...");
+            inputManager.setCursorVisible(true); // Cursor sichtbar machen
+            inputManager.clearMappings();       // Alle Mappings entfernen
+            inputBlocked = true;
+        }
+    }
+    
+    public void unblockInputs() {
+        if (inputBlocked) {
+            System.out.println("Aktiviere Eingaben...");
+            setupInput(); // Standard-Eingaben neu registrieren
+            inputBlocked = false;
+        }
+    }
 
-    void setInfoText(String text) {
+    public void setInfoText(String text) {
         topText.setText(text);
     }
 
@@ -212,35 +184,26 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga
                 .build()
                 .open();
     }
-    //altes Fenster beim Start von TestWorld schließen
-    public void startTestWorld() {
-     // Entferne die aktuelle GUI
-     guiNode.detachAllChildren();
-    
-     // Erstelle ein Quadrat mit Textur
-     Box box = new Box(1, 0.01f, 1);  // Dünnes Quadrat
-     Geometry geom = new Geometry("Box", box);
-    
-     // Setze das Material mit Textur
-     Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
-     Texture texture = assetManager.loadTexture("Pictures/board.png");
-     mat.setTexture("ColorMap", texture);
-     geom.setMaterial(mat);
-    
-     // Füge das Quadrat zur Szene hinzu
-     rootNode.attachChild(geom);
-    
-     // Setze die Kameraposition
-     cam.setLocation(new Vector3f(0, 0, 3));
-     cam.lookAt(geom.getLocalTranslation(), Vector3f.UNIT_Y);
-    }
-    public void returnToMenu() {
-        // Entferne die Testszene
-        rootNode.detachAllChildren();
-    
-        // Zeige das Startmenü erneut
-        StartMenu.createStartMenu(this);
-    }
-    
 
+    public void setSettingsMenuOpen(boolean isOpen) {
+        this.isSettingsMenuOpen = isOpen;
+    }
+
+    @Override
+    public void simpleUpdate(float tpf) {
+        if (testWorld != null) {
+            testWorld.update(tpf); // Aktualisiere die Kamera in der TestWorld
+        }
+    }
+
+    public void startTestWorld() {
+        guiNode.detachAllChildren(); // Entferne GUI
+        testWorld = new TestWorld(this); // Erstelle eine Instanz von TestWorld
+        testWorld.initializeScene();     // Initialisiere die Szene
+    }
+
+    public void returnToMenu() {
+        guiNode.detachAllChildren(); // Entferne die GUI
+        StartMenu.createStartMenu(this); // Zeige das Startmenü erneut
+    }
 }
diff --git a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/MonopolyAppConfig.java b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/MonopolyAppConfig.java
index e126f75..15a69f1 100644
--- a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/MonopolyAppConfig.java
+++ b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/MonopolyAppConfig.java
@@ -1,10 +1,3 @@
-////////////////////////////////////////
-// Programming project code
-// UniBw M, 2022, 2023, 2024
-// www.unibw.de/inf2
-// (c) Mark Minas (mark.minas@unibw.de)
-////////////////////////////////////////
-
 package pp.monopoly.client;
 
 import com.jme3.math.ColorRGBA;
@@ -194,4 +187,4 @@ public class MonopolyAppConfig extends MonopolyClientConfig {
     public ColorRGBA getTopColor() {
         return topColor;
     }
-}
+}
\ No newline at end of file
diff --git a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/MonopolyAppState.java b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/MonopolyAppState.java
index 76b002e..ec11aa4 100644
--- a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/MonopolyAppState.java
+++ b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/MonopolyAppState.java
@@ -81,4 +81,4 @@ public abstract class MonopolyAppState extends AbstractAppState {
      * Called when the state is disabled. Override to define specific behavior.
      */
     protected abstract void disableState();
-}
+}
\ No newline at end of file
diff --git a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/NetworkDialog.java b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/NetworkDialog.java
index 6671b7b..d399636 100644
--- a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/NetworkDialog.java
+++ b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/NetworkDialog.java
@@ -142,4 +142,5 @@ class NetworkDialog extends SimpleDialog {
         network.getApp().errorDialog("Verbindung zum Server fehlgeschlagen.");
         network.getApp().setInfoText(e.getLocalizedMessage());
     }
-}
+    
+}
\ No newline at end of file
diff --git a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/NetworkSupport.java b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/NetworkSupport.java
index 065bcf6..3ea11b0 100644
--- a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/NetworkSupport.java
+++ b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/NetworkSupport.java
@@ -141,4 +141,4 @@ class NetworkSupport implements MessageListener<Client>, ClientStateListener, Se
             client.send(message);
         }
     }
-}
+}
\ No newline at end of file
diff --git a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/StartMenu.java b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/StartMenu.java
index 75c37a2..e1796cc 100644
--- a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/StartMenu.java
+++ b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/StartMenu.java
@@ -1,117 +1,182 @@
 package pp.monopoly.client;
 
-import com.jme3.asset.TextureKey;
 import com.jme3.material.Material;
+import com.jme3.math.ColorRGBA;
 import com.jme3.math.Vector3f;
 import com.jme3.scene.Geometry;
 import com.jme3.scene.shape.Quad;
 import com.jme3.texture.Texture;
+import com.simsilica.lemur.Axis;
 import com.simsilica.lemur.Button;
-import com.simsilica.lemur.Insets3f;
-import com.simsilica.lemur.Label;
-import com.simsilica.lemur.Panel;
-import com.simsilica.lemur.style.ElementId;
+import com.simsilica.lemur.Container;
+import com.simsilica.lemur.HAlignment;
 import com.simsilica.lemur.component.QuadBackgroundComponent;
-import com.jme3.math.ColorRGBA;
+import com.simsilica.lemur.component.SpringGridLayout;
+
 import pp.dialog.Dialog;
+import pp.monopoly.client.gui.CreateGameMenu;
+import pp.monopoly.client.gui.SettingsMenu;
+
+/**
+ * Constructs the startup menu dialog for the Monopoly application.
 import pp.monopoly.client.gui.GameMenu;
-import pp.dialog.DialogManager;
-
-import java.util.prefs.Preferences;
-
-import static pp.monopoly.Resources.lookup;
-import static pp.util.PreferencesUtils.getPreferences;
-
+ */
 public class StartMenu extends Dialog {
-    private static final Preferences PREFERENCES = getPreferences(StartMenu.class);
     private final MonopolyApp app;
-
-    // Buttons for the menu
-    private final Button playButton = new Button(lookup("button.play"));
-    private final Button quitButton = new Button(lookup("menu.quit"));
-    private final Button settingsButton = new Button("Einstellungen", new ElementId("menu-button"));
+    private Container logoContainer;
+    private Container unibwLogoContainer;
 
     /**
-     * Constructs the StartMenu dialog for the Monopoly application.
+     * Constructs the Startup Menu dialog for the Monopoly application.
      *
      * @param app the MonopolyApp instance
      */
     public StartMenu(MonopolyApp app) {
         super(app.getDialogManager());
         this.app = app;
+    }
 
-        // Load and display the background image
-        TextureKey backgroundKey = new TextureKey("unibw-bib", false);
-        Texture backgroundTexture = app.getAssetManager().loadTexture(backgroundKey);
+    /**
+     * Creates and displays the Start Menu with buttons for starting the game,
+     * opening settings, and quitting the application.
+     */
+    public static void createStartMenu(MonopolyApp app) {
+        int screenWidth = app.getContext().getSettings().getWidth();
+        int screenHeight = app.getContext().getSettings().getHeight();
+
+        // Set up the background image
+        Texture backgroundImage = app.getAssetManager().loadTexture("Pictures/unibw-Bib2.png");
+        Quad quad = new Quad(screenWidth, screenHeight);
+        Geometry background = new Geometry("Background", quad);
         Material backgroundMaterial = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
-        backgroundMaterial.setTexture("ColorMap", backgroundTexture);
-
-        // Create a large Quad for the background
-        Quad backgroundQuad = new Quad(16, 9); // Adjust size as necessary to fill the screen
-        Geometry background = new Geometry("Background", backgroundQuad);
+        backgroundMaterial.setTexture("ColorMap", backgroundImage);
         background.setMaterial(backgroundMaterial);
-        background.setLocalTranslation(new Vector3f(-8, -4.5f, -1)); // Position it behind the UI components
-
-        // Attach the background as the first element
+        background.setLocalTranslation(0, 0, -1); // Ensure it is behind other GUI elements
         app.getGuiNode().attachChild(background);
 
-        // Load and display the Monopoly logo
-        TextureKey monopolyLogoKey = new TextureKey("log-Monopoly", false);
-        Texture monopolyLogoTexture = app.getAssetManager().loadTexture(monopolyLogoKey);
-        Material monopolyLogoMaterial = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
-        monopolyLogoMaterial.setTexture("ColorMap", monopolyLogoTexture);
+        createMonopolyLogo(app);
+        createUnibwLogo(app);
 
-        Quad monopolyQuad = new Quad(5, 1.5f); // Adjust dimensions as necessary
-        Geometry monopolyLogo = new Geometry("MonopolyLogo", monopolyQuad);
-        monopolyLogo.setMaterial(monopolyLogoMaterial);
-        monopolyLogo.setLocalTranslation(new Vector3f(0, 5, 0)); // Position Monopoly logo at the top
+        // Center container for title and play button
+        Container centerMenu = new Container(new SpringGridLayout(Axis.Y, Axis.X));
 
-        Panel monopolyLogoPanel = new Panel();
-        addChild(monopolyLogoPanel);
+        Button startButton = new Button("Spielen");
+        startButton.setPreferredSize(new Vector3f(190, 60, 0)); // Increase button size (width, height)
+        startButton.setFontSize(40); // Set the font size for the button text
+        startButton.setTextHAlignment(HAlignment.Center); // Center the text horizontally
 
-        // Load and display the university logo
-        TextureKey universityLogoKey = new TextureKey("unibw-logo.png", false);
-        Texture universityLogoTexture = app.getAssetManager().loadTexture(universityLogoKey);
-        Material universityLogoMaterial = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
-        universityLogoMaterial.setTexture("ColorMap", universityLogoTexture);
+        startButton.addClickCommands(source -> startGame(app));
+        centerMenu.addChild(startButton);
 
-        Quad universityQuad = new Quad(4, 1); // Adjust dimensions to fit below Monopoly logo
-        Geometry universityLogo = new Geometry("UniversityLogo", universityQuad);
-        universityLogo.setMaterial(universityLogoMaterial);
-        universityLogo.setLocalTranslation(new Vector3f(0, 3, 0)); // Position below the Monopoly logo
+        // Position the center container in the middle of the screen
+        centerMenu.setLocalTranslation(new Vector3f(screenWidth / 2f - centerMenu.getPreferredSize().x / 2f,
+                                                    screenHeight / 2f - 280 + centerMenu.getPreferredSize().y / 2f,
+                                                    0));
+        app.getGuiNode().attachChild(centerMenu);
 
-        Panel universityLogoPanel = new Panel();
-        addChild(universityLogoPanel);
+        // Lower-left container for "Spiel beenden" button
+        Container lowerLeftMenu = new Container();
+        lowerLeftMenu.setLocalTranslation(new Vector3f(100, 90, 0));
+        Button quitButton = new Button("Spiel beenden");
+        quitButton.setPreferredSize(new Vector3f(130, 40, 0)); // Increase button size slightly (width, height)
+        quitButton.setFontSize(18);
+        quitButton.addClickCommands(source -> quitGame());
+        lowerLeftMenu.addChild(quitButton);
+        app.getGuiNode().attachChild(lowerLeftMenu);
 
-
-
-        // Button actions
-        playButton.addClickCommands(source -> startGame());
-        quitButton.addClickCommands(source -> app.closeApp());
-        settingsButton.addClickCommands(source -> openSettings());
-
-        addChild(monopolyLogoPanel);
-        addChild(universityLogoPanel);
-        addChild(playButton);
-        addChild(quitButton);
-        addChild(settingsButton);
+        // Lower-right container for "Einstellungen" button
+        Container lowerRightMenu = new Container();
+        lowerRightMenu.setLocalTranslation(new Vector3f(screenWidth - 200, 90, 0));
+        Button settingsButton = new Button("Einstellungen");
+        settingsButton.setPreferredSize(new Vector3f(130, 40, 0)); // Increase button size slightly (width, height)
+        settingsButton.setFontSize(18); // Increase the font size for the text
+        settingsButton.addClickCommands(source -> openSettings(app));
+        lowerRightMenu.addChild(settingsButton);
+        app.getGuiNode().attachChild(lowerRightMenu);
     }
 
-    private void startGame() {
-        System.out.println("Starting game...");
+    /**
+     * Creates and positions the Monopoly logo container in the center of the screen.
+     */
+    private static void createMonopolyLogo(MonopolyApp app) {
+        int screenWidth = app.getContext().getSettings().getWidth();
+        int screenHeight = app.getContext().getSettings().getHeight();
+
+        // Load the Monopoly logo as a texture
+        Texture logoTexture = app.getAssetManager().loadTexture("Pictures/logo-monopoly.png");
+
+        // Create a container for the logo
+        Container logoContainer = new Container();
+        QuadBackgroundComponent logoBackground = new QuadBackgroundComponent(logoTexture);
+        logoContainer.setBackground(logoBackground);
+
+        // Set the size of the container to fit the logo
+        float logoWidth = 512;  // Adjust these values based on the logo dimensions
+        float logoHeight = 128; // Adjust these values based on the logo dimensions
+        logoContainer.setPreferredSize(new Vector3f(logoWidth, logoHeight, 0));
+
+        // Position the container at the center of the screen
+        logoContainer.setLocalTranslation(new Vector3f(
+                screenWidth / 2f - logoWidth / 2f,
+                screenHeight / 2f + 200, // Adjust this value for vertical position
+                0
+        ));
+
+        // Attach the container to the GUI node
+        app.getGuiNode().attachChild(logoContainer);
     }
 
-    private void openSettings() {
-        app.getDialogManager().close(this);
-        app.getDialogManager().open(new GameMenu(app));
+    /**
+     * Creates and positions the Unibw logo container in the center of the screen.
+     */
+    private static void createUnibwLogo(MonopolyApp app) {
+        int screenWidth = app.getContext().getSettings().getWidth();
+        int screenHeight = app.getContext().getSettings().getHeight();
+
+        // Load the Unibw logo as a texture
+        Texture unibwTexture = app.getAssetManager().loadTexture("Pictures/logo-unibw.png");
+
+        // Create a container for the Unibw logo
+        Container unibwContainer = new Container();
+        QuadBackgroundComponent unibwBackground = new QuadBackgroundComponent(unibwTexture);
+        unibwContainer.setBackground(unibwBackground);
+
+        // Set the size of the container to fit the Unibw logo
+        float unibwWidth = 512;  // Adjust these values based on the logo dimensions
+        float unibwHeight = 128; // Adjust these values based on the logo dimensions
+        unibwContainer.setPreferredSize(new Vector3f(unibwWidth, unibwHeight, 0));
+
+        // Position the container slightly below the Monopoly logo
+        unibwContainer.setLocalTranslation(new Vector3f(
+                screenWidth / 2f - unibwWidth / 2f,
+                screenHeight / 2f + 100, // Adjust this value for vertical position
+                0
+        ));
+
+        // Attach the container to the GUI node
+        app.getGuiNode().attachChild(unibwContainer);
     }
 
-    @Override
-    public void update() {
+    /**
+     * Starts the game by transitioning to the CreateGameMenu.
+     */
+    private static void startGame(MonopolyApp app) {
+        app.getGuiNode().detachAllChildren();
+        new CreateGameMenu(app);
     }
 
-    @Override
-    public void escape() {
-        close();
+    /**
+     * Opens the settings menu.
+     */
+    private static void openSettings(MonopolyApp app) {
+        app.getGuiNode().detachAllChildren();
+        new SettingsMenu(app);
     }
-}
+
+    /**
+     * Quits the game application.
+     */
+    private static void quitGame() {
+        System.exit(0);
+    }
+}
\ No newline at end of file
diff --git a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/BoardSynchronizer.java b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/BoardSynchronizer.java
index f1819e4..007389d 100644
--- a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/BoardSynchronizer.java
+++ b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/BoardSynchronizer.java
@@ -17,7 +17,7 @@ import pp.view.ModelViewSynchronizer;
  * are accurately reflected in the view.
  */
 abstract class BoardSynchronizer extends ModelViewSynchronizer<Item> implements Visitor<Spatial>, GameEventListener {
-    private final Board board;
+    protected final Board board;
 
     /**
      * Constructs a new BoardSynchronizer.
diff --git a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/CameraController.java b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/CameraController.java
new file mode 100644
index 0000000..314ebb6
--- /dev/null
+++ b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/CameraController.java
@@ -0,0 +1,59 @@
+package pp.monopoly.client.gui;
+
+import com.jme3.math.FastMath;
+import com.jme3.math.Vector3f;
+import com.jme3.renderer.Camera;
+
+/**
+ * Steuert die Kamerabewegung in der Szene.
+ */
+public class CameraController {
+    private final Camera camera;
+    private final Vector3f center; // Fokuspunkt der Kamera
+    private final float radius;    // Radius der Kreisbewegung
+    private final float height;    // Höhe der Kamera über dem Spielfeld
+    private final float speed;     // Geschwindigkeit der Kamerabewegung
+    private float angle;           // Aktueller Winkel in der Kreisbewegung
+
+    /**
+     * Konstruktor für den CameraController.
+     *
+     * @param camera Die Kamera, die gesteuert werden soll
+     * @param center Der Mittelpunkt der Kreisbewegung (Fokuspunkt)
+     * @param radius Der Radius der Kreisbewegung
+     * @param height Die Höhe der Kamera über dem Fokuspunkt
+     * @param speed  Die Geschwindigkeit der Kamerabewegung
+     */
+    public CameraController(Camera camera, Vector3f center, float radius, float height, float speed) {
+        this.camera = camera;
+        this.center = center;
+        this.radius = radius;
+        this.height = height;
+        this.speed = speed;
+        this.angle = 0; // Starte bei Winkel 0
+    }
+
+    /**
+     * Aktualisiert die Kameraposition und -ausrichtung.
+     *
+     * @param tpf Zeit pro Frame
+     */
+    public void update(float tpf) {
+        // Aktualisiere den Winkel basierend auf der Geschwindigkeit
+        angle += speed * tpf;
+        if (angle >= FastMath.TWO_PI) {
+            angle -= FastMath.TWO_PI; // Winkel zurücksetzen, um Überläufe zu vermeiden
+        }
+
+        // Berechne die neue Position der Kamera
+        float x = center.x + radius * FastMath.cos(angle);
+        float z = center.z + radius * FastMath.sin(angle);
+        float y = center.y + height;
+
+        // Setze die Kameraposition
+        camera.setLocation(new Vector3f(x, y, z));
+
+        // Lasse die Kamera auf den Fokuspunkt blicken
+        camera.lookAt(center, Vector3f.UNIT_Y);
+    }
+}
diff --git a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/CreateGameMenu.java b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/CreateGameMenu.java
index 6b88b62..5472da4 100644
--- a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/CreateGameMenu.java
+++ b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/CreateGameMenu.java
@@ -23,6 +23,11 @@ public class CreateGameMenu {
     private final Container menuContainer;
     private Geometry background;
 
+    /**
+     * Konstruktor für das CreateGameMenu.
+     *
+     * @param app Die Hauptanwendung (MonopolyApp)
+     */
     public CreateGameMenu(MonopolyApp app) {
         this.app = app;
 
@@ -43,12 +48,12 @@ public class CreateGameMenu {
         inputContainer.setLocalTranslation(20, 0, 0); // Abstand vom Rand
 
         inputContainer.addChild(new Label("Server-Adresse:"));
-        TextField playerNameField = inputContainer.addChild(new TextField("localhost"));
-        playerNameField.setPreferredWidth(400); // Breite des Textfelds
+        TextField serverAddressField = inputContainer.addChild(new TextField("localhost"));
+        serverAddressField.setPreferredWidth(400); // Breite des Textfelds
 
         inputContainer.addChild(new Label("Port:"));
-        TextField serverAddressField = inputContainer.addChild(new TextField("42069"));
-        serverAddressField.setPreferredWidth(400); // Breite des Textfelds
+        TextField portField = inputContainer.addChild(new TextField("42069"));
+        portField.setPreferredWidth(400); // Breite des Textfelds
 
         // Button-Container
         Container buttonContainer = menuContainer.addChild(new Container(new SpringGridLayout(Axis.X, Axis.Y)));
@@ -64,15 +69,14 @@ public class CreateGameMenu {
         Button hostButton = buttonContainer.addChild(new Button("Spiel hosten"));
         hostButton.setPreferredSize(new Vector3f(120, 40, 0));
         hostButton.addClickCommands(source -> {
-        closeCreateGameMenu(); // Schließt das Menü
-        app.startTestWorld(); // Startet die Testwelt in der Hauptanwendung
-});
-
+            closeCreateGameMenu();      // Schließt das Menü
+            app.startTestWorld();       // Starte die TestWorld im selben Fenster
+        });
 
         // "Beitreten"-Button
         Button joinButton = buttonContainer.addChild(new Button("Beitreten"));
         joinButton.setPreferredSize(new Vector3f(120, 40, 0));
-        // joinButton.addClickCommands(source -> joinGame()); // Placeholder for joining logic
+        // Placeholder für die Beitrittslogik
 
         // Zentrierung des Containers
         menuContainer.setLocalTranslation(
@@ -103,27 +107,15 @@ public class CreateGameMenu {
      * Geht zum Startmenü zurück, wenn "Abbrechen" angeklickt wird.
      */
     private void goBackToStartMenu() {
-        app.getGuiNode().detachChild(menuContainer);
-        app.getGuiNode().detachChild(background); // Entfernt das Hintergrundbild
-        StartMenu.createStartMenu(app);
-    }
-    /*
-     * Link zwischen createGame und TestWorld
-     */
-    
-    private void startTestWorld() {
-        // Entfernt das Menü
-        app.getGuiNode().detachChild(menuContainer);
-        app.getGuiNode().detachChild(background);
-        
-        // Startet die Testszene
-        TestWorld.startTestWorld();
+        closeCreateGameMenu();          // Schließt das Menü
+        StartMenu.createStartMenu(app); // Zeige das Startmenü
     }
 
+    /**
+     * Entfernt das CreateGameMenu und dessen Hintergrund.
+     */
     private void closeCreateGameMenu() {
         app.getGuiNode().detachChild(menuContainer); // Entfernt den Menü-Container
-        app.getGuiNode().detachChild(background); // Entfernt das Hintergrundbild
+        app.getGuiNode().detachChild(background);    // Entfernt das Hintergrundbild
     }
-    
-
 }
diff --git a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/GameBoardSynchronizer.java b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/GameBoardSynchronizer.java
new file mode 100644
index 0000000..637f7ab
--- /dev/null
+++ b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/GameBoardSynchronizer.java
@@ -0,0 +1,124 @@
+////////////////////////////////////////
+// Programming project code
+// UniBw M, 2022, 2023, 2024
+// www.unibw.de/inf2
+// (c) Mark Minas (mark.minas@unibw.de)
+////////////////////////////////////////
+
+package pp.monopoly.client.gui;
+
+import com.jme3.material.Material;
+import com.jme3.material.RenderState.BlendMode;
+import com.jme3.math.ColorRGBA;
+import com.jme3.renderer.queue.RenderQueue.ShadowMode;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.Node;
+import com.jme3.scene.Spatial;
+import com.jme3.scene.shape.Box;
+
+import pp.monopoly.client.MonopolyApp;
+import pp.monopoly.game.server.PlayerColor;
+import pp.monopoly.model.Board;
+import pp.monopoly.model.Figure;
+import pp.monopoly.model.Rotation;
+import static pp.util.FloatMath.HALF_PI;
+import static pp.util.FloatMath.PI;
+
+/**
+ * The {@code GameBoardSynchronizer} class is responsible for synchronizing the graphical
+ * representation of the ships and shots on the sea map with the underlying data model.
+ * It extends the {@link BoardSynchronizer} to provide specific synchronization
+ * logic for the sea map.
+ */
+class GameBoardSynchronizer extends BoardSynchronizer {
+    private static final String UNSHADED = "Common/MatDefs/Misc/Unshaded.j3md"; //NON-NLS
+    private static final String LIGHTING = "Common/MatDefs/Light/Lighting.j3md";
+    private static final String COLOR = "Color"; //NON-NLS
+    private static final String FIGURE = "figure"; //NON-NLS
+
+    private final MonopolyApp app;
+    private final ParticleEffectFactory particleFactory;
+
+    /**
+     * Constructs a {@code GameBoardSynchronizer} object with the specified application, root node, and ship map.
+     *
+     * @param app  the Battleship application
+     * @param root the root node to which graphical elements will be attached
+     * @param map  the ship map containing the ships and shots
+     */
+    public GameBoardSynchronizer(MonopolyApp app, Node root, Board board) {
+        super(board, root);
+        this.app = app;
+        this.particleFactory = new ParticleEffectFactory(app);
+        addExisting();
+    }
+
+    /**
+     * Visits a {@link Battleship} and creates a graphical representation of it.
+     * The representation is either a 3D model or a simple box depending on the
+     * type of battleship.
+     *
+     * @param ship the battleship to be represented
+     * @return the node containing the graphical representation of the battleship
+     */
+    public Spatial visit(Figure figure) {
+        final Node node = new Node(FIGURE);
+        node.attachChild(createBox(figure));
+        // compute the center of the ship in world coordinates
+        final float x = 1;
+        final float z = 1;
+        node.setLocalTranslation(x, 0f, z);
+        return node;
+    }
+
+    /**
+     * Creates a simple box to represent a battleship that is not of the "King George V" type.
+     *
+     * @param ship the battleship to be represented
+     * @return the geometry representing the battleship as a box
+     */
+    private Spatial createBox(Figure figure) {
+        final Box box = new Box(0.5f * (figure.getMaxY() - figure.getMinY()) + 0.3f,
+                                0.3f,
+                                0.5f * (figure.getMaxX() - figure.getMinX()) + 0.3f);
+        final Geometry geometry = new Geometry(FIGURE, box);
+        geometry.setMaterial(createColoredMaterial(PlayerColor.PINK.getColor()));
+        geometry.setShadowMode(ShadowMode.CastAndReceive);
+
+        return geometry;
+    }
+
+    /**
+     * Creates a new {@link Material} with the specified color.
+     * If the color includes transparency (i.e., alpha value less than 1),
+     * the material's render state is set to use alpha blending, allowing for
+     * semi-transparent rendering.
+     *
+     * @param color the {@link ColorRGBA} to be applied to the material. If the alpha value
+     *              of the color is less than 1, the material will support transparency.
+     * @return a {@link Material} instance configured with the specified color and,
+     * if necessary, alpha blending enabled.
+     */
+    private Material createColoredMaterial(ColorRGBA color) {
+        final Material material = new Material(app.getAssetManager(), UNSHADED);
+        if (color.getAlpha() < 1f)
+            material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
+        material.setColor(COLOR, color);
+        return material;
+    }
+
+    /**
+     * Calculates the rotation angle for the specified rotation.
+     *
+     * @param rot the rotation of the battleship
+     * @return the rotation angle in radians
+     */
+    private static float calculateRotationAngle(Rotation rot) {
+        return switch (rot) {
+            case RIGHT -> HALF_PI;
+            case DOWN -> 0f;
+            case LEFT -> -HALF_PI;
+            case UP -> PI;
+        };
+    }
+}
diff --git a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/GameMenu.java b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/GameMenu.java
index ef5dd78..da390c8 100644
--- a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/GameMenu.java
+++ b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/GameMenu.java
@@ -5,6 +5,7 @@ import com.jme3.math.ColorRGBA;
 import com.simsilica.lemur.Button;
 import com.simsilica.lemur.Label;
 import com.simsilica.lemur.style.ElementId;
+
 import pp.dialog.Dialog;
 import pp.monopoly.client.MonopolyApp;
 
diff --git a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/MapView.java b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/MapView.java
index 638e402..f93c1d5 100644
--- a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/MapView.java
+++ b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/MapView.java
@@ -55,7 +55,7 @@ class MapView {
         mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
         Geometry background = new Geometry("MapBackground", new Quad(board.getWidth() * FIELD_SIZE, board.getHeight() * FIELD_SIZE));
         background.setMaterial(mat);
-        background.setLocalTranslation(0f, 0f, BACKGROUND_DEPTH);
+        background.setLocalTranslation(0f, 1f, BACKGROUND_DEPTH);
         background.setCullHint(CullHint.Never);
         mapNode.attachChild(background);
     }
diff --git a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/MapViewSynchronizer.java b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/MapViewSynchronizer.java
index c239394..4853356 100644
--- a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/MapViewSynchronizer.java
+++ b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/MapViewSynchronizer.java
@@ -1,5 +1,9 @@
 package pp.monopoly.client.gui;
 
+import com.jme3.scene.Spatial;
+
+import pp.monopoly.model.Figure;
+
 /**
  * Synchronizes the visual representation of the board with the game model.
  * Handles updates for items on the board.
@@ -33,4 +37,9 @@ class MapViewSynchronizer extends BoardSynchronizer {
     protected void disableState() {
         view.getNode().detachAllChildren(); // Entfernt alle visuellen Elemente vom Knoten
     }
+
+    
+    public Spatial visit(Figure figure) {
+        return figure.accept(this);
+    }
 }
diff --git a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/ParticleEffectFactory.java b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/ParticleEffectFactory.java
new file mode 100644
index 0000000..790400c
--- /dev/null
+++ b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/ParticleEffectFactory.java
@@ -0,0 +1,22 @@
+package pp.monopoly.client.gui;
+
+import com.jme3.effect.ParticleMesh.Type;
+
+import pp.monopoly.client.MonopolyApp;
+
+/**
+ * Factory class responsible for creating particle effects used in the game.
+ * This centralizes the creation of various types of particle emitters.
+ */
+public class ParticleEffectFactory {
+    private static final int COUNT_FACTOR = 1;
+    private static final float COUNT_FACTOR_F = 1f;
+    private static final boolean POINT_SPRITE = true;
+    private static final Type EMITTER_TYPE = POINT_SPRITE ? Type.Point : Type.Triangle;
+    
+    private final MonopolyApp app;
+
+    ParticleEffectFactory(MonopolyApp app) {
+        this.app = app;
+    }
+}
\ No newline at end of file
diff --git a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/SettingsMenu.java b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/SettingsMenu.java
index eb882da..6997c45 100644
--- a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/SettingsMenu.java
+++ b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/SettingsMenu.java
@@ -1,10 +1,10 @@
 package pp.monopoly.client.gui;
 
+import com.jme3.material.Material;
+import com.jme3.material.RenderState.BlendMode;
 import com.jme3.math.ColorRGBA;
 import com.jme3.scene.Geometry;
-import com.jme3.scene.Node;
 import com.jme3.scene.shape.Quad;
-import com.jme3.texture.Texture;
 import com.simsilica.lemur.Button;
 import com.simsilica.lemur.Checkbox;
 import com.simsilica.lemur.Container;
@@ -16,122 +16,85 @@ import com.simsilica.lemur.style.ElementId;
 import pp.dialog.Dialog;
 import pp.monopoly.client.MonopolyApp;
 
+/**
+ * SettingsMenu ist ein Overlay-Menü, das durch ESC aufgerufen werden kann.
+ */
 public class SettingsMenu extends Dialog {
     private final MonopolyApp app;
+    private final Geometry overlayBackground;
     private final Container settingsContainer;
-    private Geometry blockLayer;
-    private final Node savedGuiNodeContent = new Node("SavedGuiNodeContent");
 
     public SettingsMenu(MonopolyApp app) {
         super(app.getDialogManager());
         this.app = app;
 
-        // Blockierungsebene hinzufügen
-        addBlockLayer();
-
-        // Hintergrundbild
-        addBackgroundImage();
+        // Halbtransparentes Overlay hinzufügen
+        overlayBackground = createOverlayBackground();
+        app.getGuiNode().attachChild(overlayBackground);
 
+        // Hauptcontainer für das Menü
         settingsContainer = new Container();
+        settingsContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.1f, 0.1f, 0.1f, 0.9f)));
 
-        // Hintergrundfarbe für das Container-Element setzen, um es undurchsichtig zu machen
-        settingsContainer.setBackground(new QuadBackgroundComponent(new ColorRGBA(0.1f, 0.1f, 0.1f, 0.8f))); // Teiltransparent, falls gewünscht
-
-        // Titel "Einstellungen"
+        // Titel
         Label settingsTitle = settingsContainer.addChild(new Label("Einstellungen", new ElementId("settings-title")));
         settingsTitle.setFontSize(48);
-        settingsTitle.setColor(ColorRGBA.White);
 
-        // Effekt Sound mit Slider und Checkbox
+        // Effekt-Sound: Slider und Checkbox
         Container effectSoundContainer = settingsContainer.addChild(new Container());
-        Label effectSoundLabel = effectSoundContainer.addChild(new Label("Effekt Sound", new ElementId("label")));
-        effectSoundLabel.setFontSize(24);
-        effectSoundLabel.setColor(ColorRGBA.White);
+        effectSoundContainer.addChild(new Label("Effekt Sound", new ElementId("label")));
+        effectSoundContainer.addChild(new Slider());
+        effectSoundContainer.addChild(new Checkbox("Aktivieren")).setChecked(true);
 
-        Slider effectSoundSlider = effectSoundContainer.addChild(new Slider());
-        effectSoundSlider.setPreferredSize(new com.jme3.math.Vector3f(300, 30, 0));
-
-        Checkbox effectSoundCheckbox = effectSoundContainer.addChild(new Checkbox(""));
-        effectSoundCheckbox.setChecked(true);
-
-        // Hintergrund Musik mit Slider und Checkbox
+        // Hintergrundmusik: Slider und Checkbox
         Container backgroundMusicContainer = settingsContainer.addChild(new Container());
-        Label backgroundMusicLabel = backgroundMusicContainer.addChild(new Label("Hintergrund Musik", new ElementId("label")));
-        backgroundMusicLabel.setFontSize(24);
-        backgroundMusicLabel.setColor(ColorRGBA.White);
+        backgroundMusicContainer.addChild(new Label("Hintergrund Musik", new ElementId("label")));
+        backgroundMusicContainer.addChild(new Slider());
+        backgroundMusicContainer.addChild(new Checkbox("Aktivieren")).setChecked(true);
 
-        Slider backgroundMusicSlider = backgroundMusicContainer.addChild(new Slider());
-        backgroundMusicSlider.setPreferredSize(new com.jme3.math.Vector3f(300, 30, 0));
-
-        Checkbox backgroundMusicCheckbox = backgroundMusicContainer.addChild(new Checkbox(""));
-        backgroundMusicCheckbox.setChecked(true);
-
-        // Beenden Button
+        // Beenden-Button
         Button quitButton = settingsContainer.addChild(new Button("Beenden", new ElementId("menu-button")));
         quitButton.setFontSize(32);
-        quitButton.setColor(ColorRGBA.White);
         quitButton.addClickCommands(source -> app.stop());
 
-        // Zentrieren des Containers
+        // Zentriere das Menü
         settingsContainer.setLocalTranslation(
             (app.getCamera().getWidth() - settingsContainer.getPreferredSize().x) / 2,
             (app.getCamera().getHeight() + settingsContainer.getPreferredSize().y) / 2,
-            1  // Höhere Z-Ebene für den Vordergrund
+            1
         );
 
         app.getGuiNode().attachChild(settingsContainer);
     }
 
-    private void addBlockLayer() {
-        // Sichern des aktuellen GUI-Inhalts
-        for (var child : app.getGuiNode().getChildren()) {
-            savedGuiNodeContent.attachChild(child);
-        }
-        app.getGuiNode().detachAllChildren();
-
-        // Blockierungsebene erstellen und hinzufügen
-        blockLayer = new Geometry("BlockLayer", new Quad(app.getCamera().getWidth(), app.getCamera().getHeight()));
-        blockLayer.setMaterial(createTransparentMaterial());
-        blockLayer.setLocalTranslation(0, 0, 0); // Platzierung unterhalb des SettingsMenu
-        app.getGuiNode().attachChild(blockLayer);
-    }
-
-    private com.jme3.material.Material createTransparentMaterial() {
-        com.jme3.material.Material material = new com.jme3.material.Material(
-            app.getAssetManager(),
-            "Common/MatDefs/Misc/Unshaded.j3md"
-        );
-        material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Halbtransparent
-        material.getAdditionalRenderState().setBlendMode(com.jme3.material.RenderState.BlendMode.Alpha);
-        return material;
-    }
-
-    private void addBackgroundImage() {
-        Texture backgroundImage = app.getAssetManager().loadTexture("Pictures/unibw-Bib2.png");
+    /**
+     * Erstellt einen halbtransparenten Hintergrund für das Menü.
+     *
+     * @return Geometrie des Overlays
+     */
+    private Geometry createOverlayBackground() {
         Quad quad = new Quad(app.getCamera().getWidth(), app.getCamera().getHeight());
-        Geometry background = new Geometry("Background", quad);
-        com.jme3.material.Material backgroundMaterial = new com.jme3.material.Material(
-            app.getAssetManager(),
-            "Common/MatDefs/Misc/Unshaded.j3md"
-        );
-        backgroundMaterial.setTexture("ColorMap", backgroundImage);
-        background.setMaterial(backgroundMaterial);
-        background.setLocalTranslation(0, 0, -1); // Platzierung hinter dem SettingsMenu
-        app.getGuiNode().attachChild(background);
+        Geometry overlay = new Geometry("Overlay", quad);
+        Material material = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
+        material.setColor("Color", new ColorRGBA(0, 0, 0, 0.5f)); // Halbtransparent
+        material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
+        overlay.setMaterial(material);
+        overlay.setLocalTranslation(0, 0, 0);
+        return overlay;
     }
 
+    /**
+     * Schließt das Menü und entfernt die GUI-Elemente.
+     */
     @Override
     public void close() {
-        // Entfernt das SettingsMenu und die Blockierungsebene
-        app.getGuiNode().detachChild(settingsContainer);
-        app.getGuiNode().detachChild(blockLayer);
-
-        // Stellt die ursprüngliche GUI wieder her
-        for (var child : savedGuiNodeContent.getChildren()) {
-            app.getGuiNode().attachChild(child);
-        }
-        savedGuiNodeContent.detachAllChildren();
-
-        app.setSettingsMenuOpen(false);
+        System.out.println("Schließe SettingsMenu..."); // Debugging-Ausgabe
+        app.getGuiNode().detachChild(settingsContainer);  // Entferne das Menü
+        app.getGuiNode().detachChild(overlayBackground);  // Entferne das Overlay
+        app.setSettingsMenuOpen(false);                  // Menü als geschlossen markieren
+        app.unblockInputs();                             // Eingaben wieder aktivieren
+        System.out.println("SettingsMenu geschlossen."); // Debugging-Ausgabe
     }
+
+
 }
diff --git a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/TestWorld.java b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/TestWorld.java
index b0a82fc..50a2a23 100644
--- a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/TestWorld.java
+++ b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/TestWorld.java
@@ -1,39 +1,107 @@
 package pp.monopoly.client.gui;
 
-import com.jme3.app.SimpleApplication;
 import com.jme3.material.Material;
+import com.jme3.math.ColorRGBA;
 import com.jme3.math.Vector3f;
 import com.jme3.scene.Geometry;
 import com.jme3.scene.shape.Box;
 import com.jme3.texture.Texture;
 
+import pp.monopoly.client.MonopolyApp;
+
 /**
  * TestWorld zeigt eine einfache Szene mit einem texturierten Quadrat.
+ * Die Kamera wird durch den CameraController gesteuert.
  */
-public class TestWorld extends SimpleApplication {
+public class TestWorld {
 
-    @Override
-    public void simpleInitApp() {
+    private final MonopolyApp app;
+    private CameraController cameraController; // Steuert die Kamera
+    private Geometry cube; // Spielfigur
+
+    /**
+     * Konstruktor für TestWorld.
+     *
+     * @param app Die Hauptanwendung (MonopolyApp)
+     */
+    public TestWorld(MonopolyApp app) {
+        this.app = app;
+    }
+
+    /**
+     * Initialisiert die Szene und startet die Kamerabewegung.
+     */
+    public void initializeScene() {
+        app.getGuiNode().detachAllChildren(); // Entferne GUI
+        app.getRootNode().detachAllChildren(); // Entferne andere Szenenobjekte
+
+        setSkyColor(); // Setze den Himmel auf hellblau
+        createBoard(); // Erstelle das Spielfeld
+        createCube();  // Füge den Würfel hinzu
+
+        // Erstelle den CameraController
+        cameraController = new CameraController(
+                app.getCamera(),           // Die Kamera der App
+                Vector3f.ZERO,            // Fokus auf die Mitte des Spielfelds
+                5,                        // Radius des Kreises
+                3,                        // Höhe der Kamera
+                0.5f                      // Geschwindigkeit der Bewegung
+        );
+
+        // Füge die Toolbar hinzu
+        new Toolbar(app, cube);
+    }
+
+    /**
+     * Aktualisiert die Kameraposition.
+     *
+     * @param tpf Zeit pro Frame
+     */
+    public void update(float tpf) {
+        if (cameraController != null) {
+            cameraController.update(tpf);
+        }
+    }
+
+    /**
+     * Setzt die Hintergrundfarbe der Szene auf hellblau.
+     */
+    private void setSkyColor() {
+        app.getViewPort().setBackgroundColor(new ColorRGBA(0.5f, 0.7f, 1.0f, 1.0f)); // Hellblauer Himmel
+    }
+
+    /**
+     * Erstelle das Spielfeld.
+     */
+    private void createBoard() {
         // Erstelle ein Quadrat
         Box box = new Box(1, 0.01f, 1);  // Dünnes Quadrat für die Textur
-        Geometry geom = new Geometry("Box", box);
+        Geometry geom = new Geometry("Board", box);
 
         // Setze das Material mit Textur
-        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
-        Texture texture = assetManager.loadTexture("Pictures/board.png"); // Ersetze durch den Pfad zum gewünschten Bild
+        Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
+        Texture texture = app.getAssetManager().loadTexture("Pictures/board.png");
         mat.setTexture("ColorMap", texture);
         geom.setMaterial(mat);
 
-        // Füge das Quadrat zur Szene hinzu
-        rootNode.attachChild(geom);
-
-        // Setze die Kameraposition, um das Quadrat zu fokussieren
-        cam.setLocation(new Vector3f(0, 0, 3));  // Kamera auf der Z-Achse, nah am Quadrat
-        cam.lookAt(geom.getLocalTranslation(), Vector3f.UNIT_Y);
+        app.getRootNode().attachChild(geom);
     }
 
-    public static void startTestWorld() {
-        TestWorld testWorldApp = new TestWorld();
-        testWorldApp.start();
+    /**
+     * Erstellt den Würfel (Spielfigur) in der Szene.
+     */
+    private void createCube() {
+        Box box = new Box(0.05f, 0.05f, 0.05f); // Kleinere Größe für Spielfigur
+        cube = new Geometry("Cube", box);
+
+        // Setze das Material für den Würfel
+        Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
+        mat.setColor("Color", ColorRGBA.Blue); // Blau gefärbter Würfel
+        cube.setMaterial(mat);
+
+        // Setze den Startpunkt des Würfels
+        cube.setLocalTranslation(0.8999999f, 0.1f, -0.9f);
+
+        app.getRootNode().attachChild(cube);
     }
 }
diff --git a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/TestWorldWithMenu.java b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/TestWorldWithMenu.java
deleted file mode 100644
index 8240049..0000000
--- a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/TestWorldWithMenu.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package pp.monopoly.client.gui;
-
-import com.jme3.app.SimpleApplication;
-import com.jme3.material.Material;
-import com.jme3.math.Vector3f;
-import com.jme3.scene.Geometry;
-import com.jme3.scene.shape.Box;
-import com.jme3.texture.Texture;
-import com.jme3.system.JmeCanvasContext;
-import com.jme3.system.AppSettings;
-
-import javax.swing.*;
-import java.awt.*;
-import java.awt.event.ActionEvent;
-
-public class TestWorldWithMenu extends SimpleApplication {
-
-    public static void createAndShowGUI() {
-        // Create JFrame
-        JFrame frame = new JFrame("Test World with Menu");
-        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-        frame.setLayout(new BorderLayout());
-        frame.setSize(800, 600);
-
-        // Create Menu Bar
-        JMenuBar menuBar = new JMenuBar();
-        JMenu fileMenu = new JMenu("File");
-        JMenuItem exitItem = new JMenuItem(new AbstractAction("Exit") {
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                System.exit(0);
-            }
-        });
-        fileMenu.add(exitItem);
-        menuBar.add(fileMenu);
-        frame.setJMenuBar(menuBar);
-
-        // Create Canvas for jMonkey
-        AppSettings settings = new AppSettings(true);
-        settings.setWidth(800);
-        settings.setHeight(600);
-
-        TestWorldWithMenu app = new TestWorldWithMenu();
-        app.setSettings(settings);
-        app.createCanvas(); // Create a canvas for embedding
-        JmeCanvasContext ctx = (JmeCanvasContext) app.getContext();
-        ctx.setSystemListener(app);
-        Canvas canvas = ctx.getCanvas();
-        canvas.setSize(800, 600);
-
-        // Add the canvas to JFrame
-        frame.add(canvas, BorderLayout.CENTER);
-
-        // Show the frame
-        frame.setVisible(true);
-
-        // Start the jMonkeyEngine application
-        app.startCanvas();
-    }
-
-    @Override
-    public void simpleInitApp() {
-        // Erstelle ein Quadrat
-        Box box = new Box(1, 0.01f, 1);  // Dünnes Quadrat für die Textur
-        Geometry geom = new Geometry("Box", box);
-
-        // Setze das Material mit Textur
-        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
-        Texture texture = assetManager.loadTexture("Pictures/board.png"); // Replace with the path to your image
-        mat.setTexture("ColorMap", texture);
-        geom.setMaterial(mat);
-
-        // Füge das Quadrat zur Szene hinzu
-        rootNode.attachChild(geom);
-
-        // Setze die Kameraposition, um das Quadrat zu fokussieren
-        cam.setLocation(new Vector3f(0, 0, 3));  // Kamera auf der Z-Achse, nah am Quadrat
-        cam.lookAt(geom.getLocalTranslation(), Vector3f.UNIT_Y);
-    }
-}
diff --git a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/Toolbar.java b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/Toolbar.java
new file mode 100644
index 0000000..5a9a3f0
--- /dev/null
+++ b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/gui/Toolbar.java
@@ -0,0 +1,168 @@
+package pp.monopoly.client.gui;
+
+import java.util.Random;
+
+import com.jme3.font.BitmapText;
+import com.jme3.math.Vector3f;
+import com.jme3.scene.Geometry;
+import com.simsilica.lemur.Axis;
+import com.simsilica.lemur.Button;
+import com.simsilica.lemur.Container;
+import com.simsilica.lemur.component.SpringGridLayout;
+
+import pp.monopoly.client.MonopolyApp;
+
+/**
+ * Toolbar Klasse, die am unteren Rand der Szene angezeigt wird.
+ * Die Buttons bewegen den Würfel auf dem Spielfeld.
+ */
+public class Toolbar {
+
+    private final MonopolyApp app;
+    private final Container toolbarContainer;
+    private final Geometry cube; // Referenz auf den Würfel
+    private final BitmapText positionText; // Anzeige für die aktuelle Position
+    private final float boardLimit = 0.95f; // Grenzen des Bretts
+    private final float stepSize = 0.18f; // Schrittgröße pro Bewegung
+    private int currentPosition = 0; // Aktuelle Position auf dem Spielfeld
+    private final int positionsPerSide = 10; // Anzahl der Positionen pro Seite
+    private final Random random = new Random(); // Zufallsgenerator für den Würfelwurf
+
+    /**
+     * Konstruktor für die Toolbar.
+     *
+     * @param app  Die Hauptanwendung (MonopolyApp)
+     * @param cube Der Würfel, der bewegt werden soll
+     */
+    public Toolbar(MonopolyApp app, Geometry cube) {
+        this.app = app;
+        this.cube = cube;
+
+        // Erstelle die Toolbar
+        toolbarContainer = new Container(new SpringGridLayout(Axis.X, Axis.Y));
+
+        // Setze die Position am unteren Rand und die Breite
+        toolbarContainer.setLocalTranslation(
+                0,                                 // Links bündig
+                100,                               // Höhe über dem unteren Rand
+                0                                  // Z-Ebene
+        );
+        toolbarContainer.setPreferredSize(new Vector3f(app.getCamera().getWidth(), 100, 0)); // Volle Breite
+
+        // Füge Buttons zur Toolbar hinzu
+        initializeButtons();
+
+        // Füge die Toolbar zur GUI hinzu
+        app.getGuiNode().attachChild(toolbarContainer);
+
+        // Erstelle die Position-Anzeige
+        positionText = createPositionDisplay();
+        updatePositionDisplay(); // Initialisiere die Anzeige mit der Startposition
+    }
+
+    /**
+     * Initialisiert die Buttons in der Toolbar.
+     */
+    private void initializeButtons() {
+        addButton("Vorwärts", 1);  // Bewegung nach vorne
+        addButton("Rückwärts", -1); // Bewegung nach hinten
+        addDiceRollButton();       // Würfel-Button
+    }
+
+    /**
+     * Fügt einen Button mit einer Bewegung hinzu.
+     *
+     * @param label   Der Text des Buttons
+     * @param step    Schrittweite (+1 für vorwärts, -1 für rückwärts)
+     */
+    private void addButton(String label, int step) {
+        Button button = new Button(label);
+        button.setPreferredSize(new Vector3f(150, 50, 0)); // Größe der Buttons
+        button.addClickCommands(source -> moveCube(step));
+        toolbarContainer.addChild(button);
+    }
+
+    /**
+     * Fügt den Würfel-Button hinzu, der die Figur entsprechend der gewürfelten Zahl bewegt.
+     */
+    private void addDiceRollButton() {
+        Button diceButton = new Button("Würfeln");
+        diceButton.setPreferredSize(new Vector3f(150, 50, 0)); // Größe des Buttons
+        diceButton.addClickCommands(source -> rollDice());
+        toolbarContainer.addChild(diceButton);
+    }
+
+    /**
+     * Simuliert einen Würfelwurf und bewegt die Figur entsprechend.
+     */
+    private void rollDice() {
+        int diceRoll = random.nextInt(6) + 1; // Zahl zwischen 1 und 6
+        System.out.println("Gewürfelt: " + diceRoll);
+        moveCube(diceRoll); // Bewege die Figur um die gewürfelte Zahl
+    }
+
+    /**
+     * Bewegt den Würfel basierend auf der aktuellen Position auf dem Brett.
+     *
+     * @param step Schrittweite (+1 für vorwärts, -1 für rückwärts oder andere Werte)
+     */
+    private void moveCube(int step) {
+        currentPosition = (currentPosition + step + 4 * positionsPerSide) % (4 * positionsPerSide);
+        Vector3f newPosition = calculatePosition(currentPosition);
+        cube.setLocalTranslation(newPosition);
+        updatePositionDisplay(); // Aktualisiere die Positionsanzeige
+        System.out.println("Würfelposition: " + newPosition + " (Feld-ID: " + currentPosition + ")");
+    }
+
+    /**
+     * Berechnet die neue Position des Würfels basierend auf der aktuellen Brettseite und Position.
+     *
+     * @param position Aktuelle Position auf dem Spielfeld
+     * @return Die berechnete Position als Vector3f
+     */
+    private Vector3f calculatePosition(int position) {
+        int side = position / positionsPerSide; // Seite des Bretts (0 = unten, 1 = rechts, 2 = oben, 3 = links)
+        int offset = position % positionsPerSide; // Position auf der aktuellen Seite
+
+        switch (side) {
+            case 0: // Unten (positive x-Achse)
+                return new Vector3f(-boardLimit + offset * stepSize, 0.1f, -boardLimit + 0.05f);
+            case 1: // Rechts (positive z-Achse)
+                return new Vector3f(boardLimit - 0.05f, 0.1f, -boardLimit + offset * stepSize);
+            case 2: // Oben (negative x-Achse)
+                return new Vector3f(boardLimit - offset * stepSize, 0.1f, boardLimit - 0.05f);
+            case 3: // Links (negative z-Achse)
+                return new Vector3f(-boardLimit + 0.05f, 0.1f, boardLimit - offset * stepSize);
+            default:
+                throw new IllegalArgumentException("Ungültige Position: " + position);
+        }
+    }
+
+    /**
+     * Erstellt die Anzeige für die aktuelle Position.
+     *
+     * @return Das BitmapText-Objekt für die Anzeige
+     */
+    private BitmapText createPositionDisplay() {
+        BitmapText text = new BitmapText(app.getAssetManager().loadFont("Interface/Fonts/Default.fnt"), false);
+        text.setSize(20); // Schriftgröße
+        text.setLocalTranslation(10, app.getCamera().getHeight() - 10, 0); // Oben links
+        app.getGuiNode().attachChild(text);
+        return text;
+    }
+
+    /**
+     * Aktualisiert die Anzeige für die aktuelle Position.
+     */
+    private void updatePositionDisplay() {
+        positionText.setText("Feld-ID: " + currentPosition);
+    }
+
+    /**
+     * Entfernt die Toolbar.
+     */
+    public void remove() {
+        app.getGuiNode().detachChild(toolbarContainer);
+        app.getGuiNode().detachChild(positionText);
+    }
+}
diff --git a/Projekte/monopoly/client/src/main/resources/Models/Würfel_blau.j30 b/Projekte/monopoly/client/src/main/resources/Models/Würfel_blau.j30
new file mode 100644
index 0000000..eb3b559
Binary files /dev/null and b/Projekte/monopoly/client/src/main/resources/Models/Würfel_blau.j30 differ
diff --git a/Projekte/monopoly/client/src/main/resources/Models/Würfel_gelb.j30 b/Projekte/monopoly/client/src/main/resources/Models/Würfel_gelb.j30
new file mode 100644
index 0000000..e0156e1
Binary files /dev/null and b/Projekte/monopoly/client/src/main/resources/Models/Würfel_gelb.j30 differ
diff --git a/Projekte/monopoly/client/src/main/resources/Models/Würfel_grün.j30 b/Projekte/monopoly/client/src/main/resources/Models/Würfel_grün.j30
new file mode 100644
index 0000000..e442c42
Binary files /dev/null and b/Projekte/monopoly/client/src/main/resources/Models/Würfel_grün.j30 differ
diff --git a/Projekte/monopoly/client/src/main/resources/Models/Würfel_rosa.j30 b/Projekte/monopoly/client/src/main/resources/Models/Würfel_rosa.j30
new file mode 100644
index 0000000..cb0c503
Binary files /dev/null and b/Projekte/monopoly/client/src/main/resources/Models/Würfel_rosa.j30 differ
diff --git a/Projekte/monopoly/client/src/main/resources/Models/Würfel_rot.j30 b/Projekte/monopoly/client/src/main/resources/Models/Würfel_rot.j30
new file mode 100644
index 0000000..ec70137
Binary files /dev/null and b/Projekte/monopoly/client/src/main/resources/Models/Würfel_rot.j30 differ
diff --git a/Projekte/monopoly/client/src/main/resources/Models/Würfel_schwarz.j30 b/Projekte/monopoly/client/src/main/resources/Models/Würfel_schwarz.j30
new file mode 100644
index 0000000..d61fbdf
Binary files /dev/null and b/Projekte/monopoly/client/src/main/resources/Models/Würfel_schwarz.j30 differ
diff --git a/Projekte/monopoly/client/src/main/resources/Pictures/logo-unibw.png b/Projekte/monopoly/client/src/main/resources/Pictures/logo-unibw.png
index 5d1b76f..bf1c878 100644
Binary files a/Projekte/monopoly/client/src/main/resources/Pictures/logo-unibw.png and b/Projekte/monopoly/client/src/main/resources/Pictures/logo-unibw.png differ
diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/game/client/ClientGameLogic.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/game/client/ClientGameLogic.java
index e05af47..f972be6 100644
--- a/Projekte/monopoly/model/src/main/java/pp/monopoly/game/client/ClientGameLogic.java
+++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/game/client/ClientGameLogic.java
@@ -7,6 +7,13 @@
 
 package pp.monopoly.game.client;
 
+import java.io.File;
+import java.io.IOException;
+import java.lang.System.Logger;
+import java.lang.System.Logger.Level;
+import java.util.ArrayList;
+import java.util.List;
+
 import pp.monopoly.message.client.ClientMessage;
 import pp.monopoly.message.server.BuyPropertyResponse;
 import pp.monopoly.message.server.DiceResult;
@@ -19,10 +26,9 @@ import pp.monopoly.message.server.ServerInterpreter;
 import pp.monopoly.message.server.TimeOutWarning;
 import pp.monopoly.message.server.TradeReply;
 import pp.monopoly.message.server.TradeRequest;
-import pp.monopoly.message.server.UpdatePlayerAssets;
 import pp.monopoly.message.server.ViewAssetsResponse;
-import pp.monopoly.model.IntPoint;
 import pp.monopoly.model.Board;
+import pp.monopoly.model.IntPoint;
 import pp.monopoly.notification.ClientStateEvent;
 import pp.monopoly.notification.GameEvent;
 import pp.monopoly.notification.GameEventBroker;
@@ -38,18 +44,6 @@ import java.lang.System.Logger.Level;
 import java.util.ArrayList;
 import java.util.List;
 
-import pp.monopoly.message.client.ClientMessage;
-import pp.monopoly.message.server.ServerInterpreter;
-import pp.monopoly.model.Board;
-import pp.monopoly.model.IntPoint;
-import pp.monopoly.notification.ClientStateEvent;
-import pp.monopoly.notification.GameEvent;
-import pp.monopoly.notification.GameEventBroker;
-import pp.monopoly.notification.GameEventListener;
-import pp.monopoly.notification.InfoTextEvent;
-import pp.monopoly.notification.Sound;
-import pp.monopoly.notification.SoundEvent;
-
 /**
  * Controls the client-side game logic for Monopoly.
  * Manages the player's placement, interactions with the map, and response to server messages.
@@ -58,9 +52,8 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker {
     static final Logger LOGGER = System.getLogger(ClientGameLogic.class.getName());
     private final ClientSender clientSender;
     private final List<GameEventListener> listeners = new ArrayList<>();
-    private Board ownMap;
-    private Board harbor;
-    private Board opponentMap;
+    private Board board;
+
     private ClientState state = new ClientState(this) {
         
     };
@@ -98,8 +91,8 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker {
      *
      * @return the player's own map
      */
-    public Board getMap() {
-        return ownMap;
+    public Board getBoard() {
+        return board;
     }
 
     /**
@@ -195,73 +188,73 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker {
 
     @Override
     public void received(BuyPropertyResponse msg) {
-        // TODO Auto-generated method stub
-        throw new UnsupportedOperationException("Unimplemented method 'received'");
+        if (msg.isSuccessful()) {
+            setInfoText("You successfully bought " + msg.getPropertyName() + "!");
+            playSound(Sound.MONEY_LOST);
+        } else {
+            setInfoText("Unable to buy " + msg.getPropertyName() + ". Reason: " + msg.getReason());
+        }
     }
-
+    
     @Override
     public void received(DiceResult msg) {
-        // TODO Auto-generated method stub
-        throw new UnsupportedOperationException("Unimplemented method 'received'");
+        setInfoText("You rolled a " + msg.calcTotal() + "!");
+        playSound(Sound.DICE_ROLL);
     }
-
+    
     @Override
     public void received(EventDrawCard msg) {
-        // TODO Auto-generated method stub
-        throw new UnsupportedOperationException("Unimplemented method 'received'");
+        setInfoText("Event card drawn: " + msg.getCardDescription());
+        playSound(Sound.EVENT_CARD);
     }
-
+    
     @Override
     public void received(GameOver msg) {
-        // TODO Auto-generated method stub
-        throw new UnsupportedOperationException("Unimplemented method 'received'");
+        if (msg.isWinner()) {
+            setInfoText("Congratulations! You have won the game!");
+            playSound(Sound.WINNER);
+        } else {
+            setInfoText("Game over. Better luck next time!");
+            playSound(Sound.LOSER);
+        }
     }
-
+    
     @Override
     public void received(GameStart msg) {
-        // TODO Auto-generated method stub
-        throw new UnsupportedOperationException("Unimplemented method 'received'");
+        setInfoText("The game has started! Good luck!");
     }
-
+    
     @Override
     public void received(JailEvent msg) {
-        // TODO Auto-generated method stub
-        throw new UnsupportedOperationException("Unimplemented method 'received'");
+        if (msg.isGoingToJail()) {
+            setInfoText("You are sent to jail!");
+            playSound(Sound.GULAG);
+        } else {
+            setInfoText("You are out of jail!");
+        }
     }
-
+    
     @Override
     public void received(PlayerStatusUpdate msg) {
-        // TODO Auto-generated method stub
-        throw new UnsupportedOperationException("Unimplemented method 'received'");
+        setInfoText("Player " + msg.getPlayerName() + " status updated: " + msg.getStatus());
     }
-
+    
     @Override
     public void received(TimeOutWarning msg) {
-        // TODO Auto-generated method stub
-        throw new UnsupportedOperationException("Unimplemented method 'received'");
+        setInfoText("Warning! Time is running out. You have " + msg.getRemainingTime() + " seconds left.");
     }
-
-    @Override
-    public void received(UpdatePlayerAssets msg) {
-        // TODO Auto-generated method stub
-        throw new UnsupportedOperationException("Unimplemented method 'received'");
-    }
-
+    
     @Override
     public void received(ViewAssetsResponse msg) {
-        // TODO Auto-generated method stub
-        throw new UnsupportedOperationException("Unimplemented method 'received'");
+        setInfoText("Your current assets are being displayed.");
     }
-
+    
     @Override
     public void received(TradeReply msg) {
-        // TODO Auto-generated method stub
-        throw new UnsupportedOperationException("Unimplemented method 'received'");
     }
-
+    
     @Override
     public void received(TradeRequest msg) {
-        // TODO Auto-generated method stub
-        throw new UnsupportedOperationException("Unimplemented method 'received'");
     }
+    
 }
diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/PlayerHandler.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/PlayerHandler.java
index a5cc850..d7bbe10 100644
--- a/Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/PlayerHandler.java
+++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/PlayerHandler.java
@@ -109,8 +109,10 @@ public class PlayerHandler {
      * @return the next players who is active
      */
     Player nextPlayer() {
-        players.addLast(players.removeFirst());
-        return players.getFirst();
+        Player tmp = players.get(0);
+        players.remove(0);
+        players.add(tmp);
+        return players.get(0);
     }
 
     /**
diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/BuyPropertyResponse.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/BuyPropertyResponse.java
index cd2b906..e926317 100644
--- a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/BuyPropertyResponse.java
+++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/BuyPropertyResponse.java
@@ -1,11 +1,34 @@
 package pp.monopoly.message.server;
 
+/**
+ * Represents the server's response to a player's request to buy a property.
+ */
 public class BuyPropertyResponse extends ServerMessage{
+    private final boolean successful;
+    private final String propertyName;
+    private final String reason; // Reason for failure, if any
+
+    public BuyPropertyResponse(boolean successful, String propertyName, String reason) {
+        this.successful = successful;
+        this.propertyName = propertyName;
+        this.reason = reason;
+    }
+
+    public boolean isSuccessful() {
+        return successful;
+    }
+
+    public String getPropertyName() {
+        return propertyName;
+    }
+
+    public String getReason() {
+        return reason;
+    }
 
     @Override
     public void accept(ServerInterpreter interpreter) {
-        // TODO Auto-generated method stub
-        throw new UnsupportedOperationException("Unimplemented method 'accept'");
+        interpreter.received(this);
     }
 
     @Override
@@ -13,5 +36,4 @@ public class BuyPropertyResponse extends ServerMessage{
         // TODO Auto-generated method stub
         throw new UnsupportedOperationException("Unimplemented method 'getInfoTextKey'");
     }
-
 }
diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/EventDrawCard.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/EventDrawCard.java
index 7ed4938..968f2bb 100644
--- a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/EventDrawCard.java
+++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/EventDrawCard.java
@@ -1,6 +1,11 @@
 package pp.monopoly.message.server;
 
 public class EventDrawCard extends ServerMessage{
+    private final String cardDescription;
+
+    public EventDrawCard(String cardDescription) {
+        this.cardDescription = cardDescription;
+    }
 
     @Override
     public void accept(ServerInterpreter interpreter) {
@@ -13,4 +18,8 @@ public class EventDrawCard extends ServerMessage{
         throw new UnsupportedOperationException("Unimplemented method 'getInfoTextKey'");
     }
 
+    public String getCardDescription() {
+        return cardDescription;
+    }
+
 }
diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/GameOver.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/GameOver.java
index 9b2cff3..e91041e 100644
--- a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/GameOver.java
+++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/GameOver.java
@@ -1,6 +1,15 @@
 package pp.monopoly.message.server;
 
 public class GameOver extends ServerMessage{
+    private final boolean isWinner;
+
+    public GameOver(boolean isWinner) {
+        this.isWinner = isWinner;
+    }
+
+    public boolean isWinner() {
+        return isWinner;
+    }
 
     @Override
     public void accept(ServerInterpreter interpreter) {
diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/JailEvent.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/JailEvent.java
index a802398..485a7fd 100644
--- a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/JailEvent.java
+++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/JailEvent.java
@@ -2,6 +2,16 @@ package pp.monopoly.message.server;
 
 public class JailEvent extends ServerMessage{
 
+    private final boolean goingToJail;
+
+    public JailEvent(boolean goingToJail) {
+        this.goingToJail = goingToJail;
+    }
+
+    public boolean isGoingToJail() {
+        return goingToJail;
+    }
+
     @Override
     public void accept(ServerInterpreter interpreter) {
         interpreter.received(this);
diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/PlayerStatusUpdate.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/PlayerStatusUpdate.java
index 8b51066..c876108 100644
--- a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/PlayerStatusUpdate.java
+++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/PlayerStatusUpdate.java
@@ -1,7 +1,31 @@
 package pp.monopoly.message.server;
 
+import pp.monopoly.game.server.PlayerColor;
+
 public class PlayerStatusUpdate extends ServerMessage{
 
+    private final String playerName;
+    private final String status;
+    private final PlayerColor color;
+
+    public PlayerStatusUpdate(String playerName, String status, PlayerColor color) {
+        this.playerName = playerName;
+        this.status = status;
+        this.color = color;
+    }
+
+    public String getPlayerName() {
+        return playerName;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public PlayerColor getColor() {
+        return color;
+    }
+
     @Override
     public void accept(ServerInterpreter interpreter) {
         interpreter.received(this);
diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/ServerInterpreter.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/ServerInterpreter.java
index 3480d20..1f78ba7 100644
--- a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/ServerInterpreter.java
+++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/ServerInterpreter.java
@@ -69,13 +69,6 @@ public interface ServerInterpreter {
      */
     void received(TimeOutWarning msg);
 
-    /**
-     * Handles a UpdatePlayerAssets message received from the server.
-     *
-     * @param msg the UpdatePlayerAssets message received
-     */
-    void received(UpdatePlayerAssets msg);
-
     /**
      * Handles a ViewAssetsResponse message received from the server.
      *
diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/TimeOutWarning.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/TimeOutWarning.java
index f9510a7..b862170 100644
--- a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/TimeOutWarning.java
+++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/TimeOutWarning.java
@@ -2,6 +2,16 @@ package pp.monopoly.message.server;
 
 public class TimeOutWarning extends ServerMessage{
 
+    private final int remainingTime;
+
+    public TimeOutWarning(int remainingTime) {
+        this.remainingTime = remainingTime;
+    }
+
+    public int getRemainingTime() {
+        return remainingTime;
+    }
+
     @Override
     public void accept(ServerInterpreter interpreter) {
         interpreter.received(this);
diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/UpdatePlayerAssets.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/UpdatePlayerAssets.java
deleted file mode 100644
index e37c78c..0000000
--- a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/UpdatePlayerAssets.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package pp.monopoly.message.server;
-
-public class UpdatePlayerAssets extends ServerMessage{
-
-    @Override
-    public void accept(ServerInterpreter interpreter) {
-        interpreter.received(this);
-    }
-
-    @Override
-    public String getInfoTextKey() {
-        // TODO Auto-generated method stub
-        throw new UnsupportedOperationException("Unimplemented method 'getInfoTextKey'");
-    }
-
-}
diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/ViewAssetsResponse.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/ViewAssetsResponse.java
index 116366e..9a00833 100644
--- a/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/ViewAssetsResponse.java
+++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/message/server/ViewAssetsResponse.java
@@ -8,9 +8,9 @@ import pp.monopoly.model.fields.PropertyField;
  */
 public class ViewAssetsResponse extends ServerMessage{
 
-    private List<PropertyField> properties;
-    private int accountBalance;
-    private int jailCards;
+    private final List<PropertyField> properties;
+    private final int accountBalance;
+    private final int jailCards;
 
     /**
      * Constructs a ViewAssetsResponse with the specified properties and account balance.
diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/Board.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/Board.java
index e46308f..31ee634 100644
--- a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/Board.java
+++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/Board.java
@@ -57,6 +57,7 @@ public class Board {
         this.width = width;
         this.height = height;
         this.eventBroker = eventBroker;
+        addItem(new Figure(5, 5, 5, Rotation.LEFT));
     }
 
     /**
diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/Figure.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/Figure.java
index b27f06f..d076acd 100644
--- a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/Figure.java
+++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/Figure.java
@@ -1,17 +1,309 @@
 package pp.monopoly.model;
 
-public class Figure implements Item{
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
 
-    @Override
-    public <T> T accept(Visitor<T> visitor) {
-        // TODO Auto-generated method stub
-        throw new UnsupportedOperationException("Unimplemented method 'accept'");
+import static java.lang.Math.max;
+import static java.lang.Math.min;
+
+public class Figure implements Item{
+    /**
+     * Enumeration representing the different statuses a Figure can have during the game.
+     */
+    public enum Status {
+        /**
+         * The ship is in its normal state, not being previewed for placement.
+         */
+        NORMAL,
+
+        /**
+         * The ship is being previewed in a valid position for placement.
+         */
+        VALID_PREVIEW,
+
+        /**
+         * The ship is being previewed in an invalid position for placement.
+         */
+        INVALID_PREVIEW
     }
 
+    private final int length; // The length of the Figure
+    private int x;            // The x-coordinate of the Figure's position
+    private int y;            // The y-coordinate of the Figure's position
+    private Rotation rot;     // The rotation of the Figure
+    private Status status;    // The current status of the Figure
+    private final Set<IntPoint> damaged = new HashSet<>(); // The set of positions that have been hit on this ship
+
+    /**
+     * Default constructor for serialization. Initializes a Figure with length 0,
+     * at position (0, 0), with a default rotation of RIGHT.
+     */
+    private Figure() {
+        this(0, 0, 0, Rotation.RIGHT);
+    }
+
+    /**
+     * Constructs a new Figure with the specified length, position, and rotation.
+     *
+     * @param length the length of the Figure
+     * @param x      the x-coordinate of the Figure's initial position
+     * @param y      the y-coordinate of the Figure's initial position
+     * @param rot    the rotation of the Figure
+     */
+    public Figure(int length, int x, int y, Rotation rot) {
+        this.x = x;
+        this.y = y;
+        this.rot = rot;
+        this.length = length;
+        this.status = Status.NORMAL;
+    }
+
+    /**
+     * Returns the current x-coordinate of the Figure's position.
+     *
+     * @return the x-coordinate of the Figure
+     */
+    public int getX() {
+        return x;
+    }
+
+    /**
+     * Returns the current y-coordinate of the Figure's position.
+     *
+     * @return the y-coordinate of the Figure
+     */
+    public int getY() {
+        return y;
+    }
+
+    /**
+     * Moves the Figure to the specified coordinates.
+     *
+     * @param x the new x-coordinate of the Figure's position
+     * @param y the new y-coordinate of the Figure's position
+     */
+    public void moveTo(int x, int y) {
+        this.x = x;
+        this.y = y;
+    }
+
+    /**
+     * Moves the Figure to the specified position.
+     *
+     * @param pos the new position of the Figure
+     */
+    public void moveTo(IntPosition pos) {
+        moveTo(pos.getX(), pos.getY());
+    }
+
+    /**
+     * Returns the current status of the Figure.
+     *
+     * @return the status of the Figure
+     */
+    public Status getStatus() {
+        return status;
+    }
+
+    /**
+     * Sets the status of the Figure.
+     *
+     * @param status the new status to be set for the Figure
+     */
+    public void setStatus(Status status) {
+        this.status = status;
+    }
+
+    /**
+     * Returns the length of the Figure.
+     *
+     * @return the length of the Figure
+     */
+    public int getLength() {
+        return length;
+    }
+
+    /**
+     * Returns the minimum x-coordinate that the Figure occupies based on its current position and rotation.
+     *
+     * @return the minimum x-coordinate of the Figure
+     */
+    public int getMinX() {
+        return x + min(0, (length - 1) * rot.dx());
+    }
+
+    /**
+     * Returns the maximum x-coordinate that the Figure occupies based on its current position and rotation.
+     *
+     * @return the maximum x-coordinate of the Figure
+     */
+    public int getMaxX() {
+        return x + max(0, (length - 1) * rot.dx());
+    }
+
+    /**
+     * Returns the minimum y-coordinate that the Figure occupies based on its current position and rotation.
+     *
+     * @return the minimum y-coordinate of the Figure
+     */
+    public int getMinY() {
+        return y + min(0, (length - 1) * rot.dy());
+    }
+
+    /**
+     * Returns the maximum y-coordinate that the Figure occupies based on its current position and rotation.
+     *
+     * @return the maximum y-coordinate of the Figure
+     */
+    public int getMaxY() {
+        return y + max(0, (length - 1) * rot.dy());
+    }
+
+    /**
+     * Returns the current rotation of the Figure.
+     *
+     * @return the rotation of the Figure
+     */
+    public Rotation getRot() {
+        return rot;
+    }
+
+    /**
+     * Sets the rotation of the Figure.
+     *
+     * @param rot the new rotation to be set for the Figure
+     */
+    public void setRotation(Rotation rot) {
+        this.rot = rot;
+    }
+
+    /**
+     * Rotates the Figure by 90 degrees clockwise.
+     */
+    public void rotated() {
+        setRotation(rot.rotate());
+    }
+
+    /**
+     * Attempts to hit the Figure at the specified position.
+     * If the position is part of the Figure, the hit is recorded.
+     *
+     * @param x the x-coordinate of the position to hit
+     * @param y the y-coordinate of the position to hit
+     * @return true if the position is part of the Figure, false otherwise
+     * @see #contains(int, int)
+     */
+    public boolean hit(int x, int y) {
+        if (!contains(x, y))
+            return false;
+        damaged.add(new IntPoint(x, y));
+        return true;
+    }
+
+    /**
+     * Attempts to hit the Figure at the specified position.
+     * If the position is part of the Figure, the hit is recorded.
+     * This is a convenience method for {@linkplain #hit(int, int)}.
+     *
+     * @param position the position to hit
+     * @return true if the position is part of the Figure, false otherwise
+     */
+    public boolean hit(IntPosition position) {
+        return hit(position.getX(), position.getY());
+    }
+
+    /**
+     * Returns the positions of this Figure that have been hit.
+     *
+     * @return a set of positions that have been hit
+     * @see #hit(int, int)
+     */
+    public Set<IntPoint> getDamaged() {
+        return Collections.unmodifiableSet(damaged);
+    }
+
+    /**
+     * Checks whether the specified position is covered by the Figure. This method does
+     * not record a hit, only checks coverage.
+     * This is a convenience method for {@linkplain #contains(int, int)}.
+     *
+     * @param pos the position to check
+     * @return true if the position is covered by the Figure, false otherwise
+     */
+    public boolean contains(IntPosition pos) {
+        return contains(pos.getX(), pos.getY());
+    }
+
+    /**
+     * Checks whether the specified position is covered by the Figure. This method does
+     * not record a hit, only checks coverage.
+     *
+     * @param x the x-coordinate of the position to check
+     * @param y the y-coordinate of the position to check
+     * @return true if the position is covered by the Figure, false otherwise
+     */
+    public boolean contains(int x, int y) {
+        return getMinX() <= x && x <= getMaxX() &&
+               getMinY() <= y && y <= getMaxY();
+    }
+
+    /**
+     * Determines if the Figure has been completely destroyed. A Figure is considered
+     * destroyed if all of its positions have been hit.
+     *
+     * @return true if the Figure is destroyed, false otherwise
+     * @see #hit(int, int)
+     */
+    public boolean isDestroyed() {
+        return damaged.size() == length;
+    }
+
+    /**
+     * Checks whether this Figure collides with another Figure. Two Figures collide
+     * if any of their occupied positions overlap.
+     *
+     * @param other the other Figure to check collision with
+     * @return true if the Figures collide, false otherwise
+     */
+    public boolean collidesWith(Figure other) {
+        return other.getMaxX() >= getMinX() && getMaxX() >= other.getMinX() &&
+               other.getMaxY() >= getMinY() && getMaxY() >= other.getMinY();
+    }
+
+    /**
+     * Returns a string representation of the Figure, including its length, position,
+     * and rotation.
+     *
+     * @return a string representation of the Figure
+     */
+    @Override
+    public String toString() {
+        return "Ship{length=" + length + ", x=" + x + ", y=" + y + ", rot=" + rot + '}';  //NON-NLS
+    }
+
+    /**
+     * Accepts a visitor that returns a value of type {@code T}. This method is part of the
+     * Visitor design pattern.
+     *
+     * @param visitor the visitor to accept
+     * @param <T>     the type of the value returned by the visitor
+     * @return the value returned by the visitor
+     */
+    @Override
+    public <T> T accept(Visitor<T> visitor) {
+        return visitor.visit(this);
+    }
+
+    /**
+     * Accepts a visitor that does not return a value. This method is part of the
+     * Visitor design pattern.
+     *
+     * @param visitor the visitor to accept
+     */
     @Override
     public void accept(VoidVisitor visitor) {
-        // TODO Auto-generated method stub
-        throw new UnsupportedOperationException("Unimplemented method 'accept'");
+        visitor.visit(this);
     }
 
 }
diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/Visitor.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/Visitor.java
index ed5deec..bba2ace 100644
--- a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/Visitor.java
+++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/Visitor.java
@@ -14,4 +14,12 @@ package pp.monopoly.model;
  */
 public interface Visitor<T> {
 
+    /**
+     * Visits a Figure element.
+     *
+     * @param figure the figure element to visit
+     * @return the result of visiting the figure element
+     */
+    T visit(Figure figure);
+
 }
diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/VoidVisitor.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/VoidVisitor.java
index 471421d..0654feb 100644
--- a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/VoidVisitor.java
+++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/VoidVisitor.java
@@ -12,5 +12,11 @@ package pp.monopoly.model;
  * without returning any result.
  */
 public interface VoidVisitor {
+    /**
+     * Visits a Figure element.
+     *
+     * @param figure the Figure element to visit
+     */
+    void visit(Figure figure);
 
 }
diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/BoardManager.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/BoardManager.java
index cf0b74d..0cb7c0c 100644
--- a/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/BoardManager.java
+++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/model/fields/BoardManager.java
@@ -25,46 +25,46 @@ public class BoardManager {
     private static List<Field> createBoard() {
         ArrayList<Field> fields = new ArrayList<>();
 
-        fields.addLast(new GoField());
-        fields.addLast(new BuildingProperty("Gym", 1, 600, 20));
-        fields.addLast(new EventField("Hausfeier", 2));
-        fields.addLast(new BuildingProperty("Sportplatz", 3, 600, 40));
-        fields.addLast(new FineField("Diszi", 4, 2000));
-        fields.addLast(new GateField("Südtor", 5));
-        fields.addLast(new BuildingProperty("Studium+", 6, 1000, 60));
-        fields.addLast(new EventField("Üvas", 7));
-        fields.addLast(new BuildingProperty("PhysikHörsaal", 8, 1000, 60));
-        fields.addLast(new BuildingProperty("Audimax", 9, 1200, 80));
-        fields.addLast(new GulagField());
-        fields.addLast(new BuildingProperty("99er", 11, 1400, 100));
-        fields.addLast(new FoodField("Brandl", 12));
-        fields.addLast(new BuildingProperty("12er", 13, 1400, 100));
-        fields.addLast(new BuildingProperty("23er", 14, 1600, 120));
-        fields.addLast(new GateField("HauptWache", 15));
-        fields.addLast(new BuildingProperty("Schwimmhalle", 16, 1800, 140));
-        fields.addLast(new BuildingProperty("CISM-Bahn", 17, 1800, 140));
-        fields.addLast(new EventField("Marine-Welcome-Party", 18));
-        fields.addLast(new BuildingProperty("Kletterturm", 19, 2000, 160));
-        fields.addLast(new TestStreckeField());
-        fields.addLast(new BuildingProperty("StudFBer C", 21, 2200, 180));
-        fields.addLast(new EventField("Üvas", 22));
-        fields.addLast(new BuildingProperty("StudFBer B", 23, 2200, 180));
-        fields.addLast(new BuildingProperty("StudFBer A", 24, 2400, 200));
-        fields.addLast(new GateField("Nordtor", 25));
-        fields.addLast(new BuildingProperty("Cascada", 26, 2600, 220));
-        fields.addLast(new BuildingProperty("Fakultätsgebäude", 27, 2600, 220));
-        fields.addLast(new FoodField("Truppenküche", 28));
-        fields.addLast(new BuildingProperty("Prüfungsamt", 29, 2800, 240));
-        fields.addLast(new WacheField());
-        fields.addLast(new BuildingProperty("Feuerwehr", 31, 3000, 260));
-        fields.addLast(new BuildingProperty("SanZ", 32, 300, 260));
-        fields.addLast(new EventField("Maibock", 33));
-        fields.addLast(new BuildingProperty("Rechenzentrum", 34, 3200, 280));
-        fields.addLast(new GateField("Osttor", 35));
-        fields.addLast(new EventField("Üvas", 36));
-        fields.addLast(new BuildingProperty("2er", 37, 3500, 350));
-        fields.addLast(new FineField("EZM", 38, 1000));
-        fields.addLast(new BuildingProperty("20er", 39, 4000, 500));
+        fields.add(new GoField());
+        fields.add(new BuildingProperty("Gym", 1, 600, 20));
+        fields.add(new EventField("Hausfeier", 2));
+        fields.add(new BuildingProperty("Sportplatz", 3, 600, 40));
+        fields.add(new FineField("Diszi", 4, 2000));
+        fields.add(new GateField("Südtor", 5));
+        fields.add(new BuildingProperty("Studium+", 6, 1000, 60));
+        fields.add(new EventField("Üvas", 7));
+        fields.add(new BuildingProperty("PhysikHörsaal", 8, 1000, 60));
+        fields.add(new BuildingProperty("Audimax", 9, 1200, 80));
+        fields.add(new GulagField());
+        fields.add(new BuildingProperty("99er", 11, 1400, 100));
+        fields.add(new FoodField("Brandl", 12));
+        fields.add(new BuildingProperty("12er", 13, 1400, 100));
+        fields.add(new BuildingProperty("23er", 14, 1600, 120));
+        fields.add(new GateField("HauptWache", 15));
+        fields.add(new BuildingProperty("Schwimmhalle", 16, 1800, 140));
+        fields.add(new BuildingProperty("CISM-Bahn", 17, 1800, 140));
+        fields.add(new EventField("Marine-Welcome-Party", 18));
+        fields.add(new BuildingProperty("Kletterturm", 19, 2000, 160));
+        fields.add(new TestStreckeField());
+        fields.add(new BuildingProperty("StudFBer C", 21, 2200, 180));
+        fields.add(new EventField("Üvas", 22));
+        fields.add(new BuildingProperty("StudFBer B", 23, 2200, 180));
+        fields.add(new BuildingProperty("StudFBer A", 24, 2400, 200));
+        fields.add(new GateField("Nordtor", 25));
+        fields.add(new BuildingProperty("Cascada", 26, 2600, 220));
+        fields.add(new BuildingProperty("Fakultätsgebäude", 27, 2600, 220));
+        fields.add(new FoodField("Truppenküche", 28));
+        fields.add(new BuildingProperty("Prüfungsamt", 29, 2800, 240));
+        fields.add(new WacheField());
+        fields.add(new BuildingProperty("Feuerwehr", 31, 3000, 260));
+        fields.add(new BuildingProperty("SanZ", 32, 300, 260));
+        fields.add(new EventField("Maibock", 33));
+        fields.add(new BuildingProperty("Rechenzentrum", 34, 3200, 280));
+        fields.add(new GateField("Osttor", 35));
+        fields.add(new EventField("Üvas", 36));
+        fields.add(new BuildingProperty("2er", 37, 3500, 350));
+        fields.add(new FineField("EZM", 38, 1000));
+        fields.add(new BuildingProperty("20er", 39, 4000, 500));
 
         return fields;
     }
diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/notification/Sound.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/notification/Sound.java
index 6bbe2cb..9e0e3df 100644
--- a/Projekte/monopoly/model/src/main/java/pp/monopoly/notification/Sound.java
+++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/notification/Sound.java
@@ -1,20 +1,61 @@
 package pp.monopoly.notification;
 
 /**
- * Enumeration representing different types of sounds used in the game.
+ * Enum representing various sound effects in the game.
  */
 public enum Sound {
-    CLICK("click_sound.wav"),
-    WIN("win_sound.wav"),
-    LOSE("lose_sound.wav");
+    /**
+     * UC-sound-01: Sound effect for passing the start/Los field.
+     */
+    PASS_START,
 
-    private final String fileName;
+    /**
+     * UC-sound-02: Sound effect for drawing an event card.
+     */
+    EVENT_CARD,
 
-    Sound(String fileName) {
-        this.fileName = fileName;
-    }
+    /**
+     * UC-sound-03: Sound effect for entering the Gulag.
+     */
+    GULAG,
 
-    public String getFileName() {
-        return fileName;
-    }
+    /**
+     * UC-sound-04: Sound effect for rolling the dice.
+     */
+    DICE_ROLL,
+
+    /**
+     * UC-sound-05: Sound effect for collecting money.
+     */
+    MONEY_COLLECTED,
+
+    /**
+     * UC-sound-06: Sound effect for losing money.
+     */
+    MONEY_LOST,
+
+    /**
+     * UC-sound-07: Sound effect for accepting a trade offer.
+     */
+    TRADE_ACCEPTED,
+
+    /**
+     * UC-sound-08: Sound effect for rejecting a trade offer.
+     */
+    TRADE_REJECTED,
+
+    /**
+     * UC-sound-09: Sound effect for winning the game.
+     */
+    WINNER,
+
+    /**
+     * UC-sound-10: Sound effect for losing the game.
+     */
+    LOSER,
+
+    /**
+     * UC-sound-11: Sound effect for button click.
+     */
+    BUTTON;
 }
\ No newline at end of file
diff --git a/Projekte/monopoly/model/src/main/java/pp/monopoly/notification/SoundEvent.java b/Projekte/monopoly/model/src/main/java/pp/monopoly/notification/SoundEvent.java
index b42ed7d..2eaaefe 100644
--- a/Projekte/monopoly/model/src/main/java/pp/monopoly/notification/SoundEvent.java
+++ b/Projekte/monopoly/model/src/main/java/pp/monopoly/notification/SoundEvent.java
@@ -1,25 +1,26 @@
+////////////////////////////////////////
+// Programming project code
+// UniBw M, 2022, 2023, 2024
+// www.unibw.de/inf2
+// (c) Mark Minas (mark.minas@unibw.de)
+////////////////////////////////////////
+
 package pp.monopoly.notification;
 
 /**
- * Event when a sound needs to be played.
+ * Event when an item is added to a map.
  *
- * @param soundFileName the sound file to be played
+ * @param sound the sound to be played
  */
-public class SoundEvent implements GameEvent {
-    private final String soundFileName;
-
-    public SoundEvent(Sound sound) {
-        this.soundFileName = sound.getFileName(); // Angenommen, Sound hat eine Methode getFileName()
-    }
-
-    public String getSoundFileName() {
-        return soundFileName;
-    }
+public record SoundEvent(Sound sound) implements GameEvent {
 
+    /**
+     * Notifies the game event listener of this event.
+     *
+     * @param listener the game event listener
+     */
     @Override
     public void notifyListener(GameEventListener listener) {
         listener.receivedEvent(this);
     }
 }
-
-