From c6ad60502132fcd352bb48b28f7a3e03ea1a30ce Mon Sep 17 00:00:00 2001 From: Johannes Schmelz Date: Tue, 10 Dec 2024 11:22:21 +0100 Subject: [PATCH] basic camera movement --- .../pp/monopoly/client/BoardAppState.java | 83 +++++++------- .../java/pp/monopoly/client/MonopolyApp.java | 2 +- .../monopoly/client/gui/CameraController.java | 105 +++++++++++++----- .../monopoly/game/server/PlayerHandler.java | 2 +- .../main/java/pp/monopoly/model/Board.java | 4 + 5 files changed, 125 insertions(+), 71 deletions(-) diff --git a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/BoardAppState.java b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/BoardAppState.java index 8fc94db..ec8b303 100644 --- a/Projekte/monopoly/client/src/main/java/pp/monopoly/client/BoardAppState.java +++ b/Projekte/monopoly/client/src/main/java/pp/monopoly/client/BoardAppState.java @@ -69,9 +69,8 @@ public class BoardAppState extends MonopolyAppState { */ private PopUpManager popUpManager; - private Vector3f currentTarget = new Vector3f(-10f,0,-10f); - private CameraController cameraController; + private CameraInputHandler cameraInputHandler; @@ -87,7 +86,7 @@ public class BoardAppState extends MonopolyAppState { super.initialize(stateManager, application); // Initialisiere den CameraController zuerst - cameraController = new CameraController(getApp().getCamera(), 25, 40); + cameraController = new CameraController(getApp().getCamera(), getApp()); // Danach den CameraInputHandler mit dem initialisierten CameraController cameraInputHandler = new CameraInputHandler(cameraController, getApp().getInputManager()); @@ -197,44 +196,44 @@ public class BoardAppState extends MonopolyAppState { addCylinderCaps(); } -/** - * Adds top and bottom caps to the cylinder sky. - */ -private void addCylinderCaps() { - final AssetManager assetManager = getApp().getAssetManager(); + /** + * Adds top and bottom caps to the cylinder sky. + */ + private void addCylinderCaps() { + final AssetManager assetManager = getApp().getAssetManager(); - float radius = 500f; // Match the cylinder's radius - float height = 225f; // Match the cylinder's height - int radialSamples = 64; // Match the cylinder's radial samples + float radius = 500f; // Match the cylinder's radius + float height = 225f; // Match the cylinder's height + int radialSamples = 64; // Match the cylinder's radial samples - // Bottom Cap - Cylinder bottomCap = new Cylinder(2, radialSamples, radius, 0.01f, true, false); // Thin bottom cap - Geometry bottomGeometry = new Geometry("BottomCap", bottomCap); - bottomGeometry.setLocalTranslation(0, -height / 2, 0); // Position at the bottom - bottomGeometry.rotate(FastMath.HALF_PI, 0, 0); // Rotate to make it horizontal - Material bottomMaterial = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - bottomMaterial.setTexture("ColorMap", assetManager.loadTexture("Textures/grass.jpg")); // Bottom texture - bottomMaterial.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off); // Render both sides - bottomGeometry.setMaterial(bottomMaterial); - bottomGeometry.setQueueBucket(RenderQueue.Bucket.Sky); - bottomGeometry.setCullHint(Spatial.CullHint.Never); + // Bottom Cap + Cylinder bottomCap = new Cylinder(2, radialSamples, radius, 0.01f, true, false); // Thin bottom cap + Geometry bottomGeometry = new Geometry("BottomCap", bottomCap); + bottomGeometry.setLocalTranslation(0, -height / 2, 0); // Position at the bottom + bottomGeometry.rotate(FastMath.HALF_PI, 0, 0); // Rotate to make it horizontal + Material bottomMaterial = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + bottomMaterial.setTexture("ColorMap", assetManager.loadTexture("Textures/grass.jpg")); // Bottom texture + bottomMaterial.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off); // Render both sides + bottomGeometry.setMaterial(bottomMaterial); + bottomGeometry.setQueueBucket(RenderQueue.Bucket.Sky); + bottomGeometry.setCullHint(Spatial.CullHint.Never); - // Top Cap - Cylinder topCap = new Cylinder(2, radialSamples, radius, 0.01f, true, false); // Thin top cap - Geometry topGeometry = new Geometry("TopCap", topCap); - topGeometry.setLocalTranslation(0, height / 2, 0); // Position at the top - topGeometry.rotate(FastMath.HALF_PI, 0, 0); // Rotate to make it horizontal - Material topMaterial = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); - topMaterial.setTexture("ColorMap", assetManager.loadTexture("Textures/Top.png")); // Top texture - topMaterial.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off); // Render both sides - topGeometry.setMaterial(topMaterial); - topGeometry.setQueueBucket(RenderQueue.Bucket.Sky); - topGeometry.setCullHint(Spatial.CullHint.Never); + // Top Cap + Cylinder topCap = new Cylinder(2, radialSamples, radius, 0.01f, true, false); // Thin top cap + Geometry topGeometry = new Geometry("TopCap", topCap); + topGeometry.setLocalTranslation(0, height / 2, 0); // Position at the top + topGeometry.rotate(FastMath.HALF_PI, 0, 0); // Rotate to make it horizontal + Material topMaterial = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + topMaterial.setTexture("ColorMap", assetManager.loadTexture("Textures/Top.png")); // Top texture + topMaterial.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off); // Render both sides + topGeometry.setMaterial(topMaterial); + topGeometry.setQueueBucket(RenderQueue.Bucket.Sky); + topGeometry.setCullHint(Spatial.CullHint.Never); - // Attach caps to the view node - viewNode.attachChild(bottomGeometry); - viewNode.attachChild(topGeometry); -} + // Attach caps to the view node + viewNode.attachChild(bottomGeometry); + viewNode.attachChild(topGeometry); + } /** @@ -283,10 +282,6 @@ private void addCylinderCaps() { return cardDeck; } - public Vector3f getCurrentTarget(){ - return currentTarget; - } - private void addSnowEffect(Node parentNode) { // ParticleEmitter für Schnee ParticleEmitter snowEmitter = new ParticleEmitter("Snow", ParticleMesh.Type.Triangle, 5000); @@ -316,4 +311,10 @@ private void addCylinderCaps() { parentNode.attachChild(snowEmitter); } + @Override + public void update(float tpf) { + super.update(tpf); + cameraController.update(tpf); + } + } \ No newline at end of file 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 d4a085e..960b0ea 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 @@ -292,7 +292,7 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga final StatsAppState stats = new StatsAppState(guiNode, normalFont); stateManager.attach(stats); } - flyCam.setEnabled(true); + flyCam.setEnabled(false); stateManager.detach(stateManager.getState(StatsAppState.class)); stateManager.detach(stateManager.getState(DebugKeysAppState.class)); 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 index c42cebe..c4154c8 100644 --- 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 @@ -3,7 +3,13 @@ package pp.monopoly.client.gui; import com.jme3.math.Vector3f; import com.jme3.renderer.Camera; -public class CameraController { +import pp.monopoly.client.MonopolyApp; // Import MonopolyApp +import pp.monopoly.game.server.PlayerHandler; +import pp.monopoly.notification.GameEventListener; +import pp.monopoly.notification.UpdatePlayerView; + +public class CameraController implements GameEventListener{ + public enum CameraMode { FOCUS_CURRENT_PLAYER, FOCUS_SELF, @@ -11,49 +17,92 @@ public class CameraController { } private final Camera camera; - private CameraMode currentMode = CameraMode.FOCUS_CURRENT_PLAYER; + private CameraMode currentMode; - private final float height; // Höhe der Kamera - private final float offset; // Versatz zur Spielfeldseite + private PlayerHandler playerHandler; // Reference to PlayerHandler for player data + private final MonopolyApp app; // Reference to MonopolyApp for self ID - public CameraController(Camera camera, float height, float offset) { + public CameraController(Camera camera, MonopolyApp app) { this.camera = camera; - this.height = height; - this.offset = offset; - setMode(currentMode); + this.playerHandler = app.getGameLogic().getPlayerHandler(); + this.app = app; + app.getGameLogic().addListener(this); + setMode(CameraMode.FOCUS_SELF); // Initialize the camera mode } public void setMode(CameraMode mode) { this.currentMode = mode; - updatePosition(0); // Standardmäßig das Startfeld fokussieren } public void update(float tpf) { - if (currentMode != CameraMode.FREECAM) { - camera.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y); - } - } - public void updatePosition(int fieldID) { - Vector3f newPosition = fieldIdToVector(fieldID); - camera.setLocation(newPosition); - if (currentMode != CameraMode.FREECAM) { - camera.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y); - } - } - - private Vector3f fieldIdToVector(int fieldID) { switch (currentMode) { case FOCUS_CURRENT_PLAYER: - if (fieldID <= 10) return new Vector3f(offset, height, 0); - if (fieldID <= 20) return new Vector3f(0, height, offset); - if (fieldID <= 30) return new Vector3f(-offset, height, 0); - return new Vector3f(0, height, -offset); + updatePosition(); + break; case FOCUS_SELF: - return new Vector3f(0, height, fieldID <= 20 ? offset : -offset); + updatePosition(); + break; + case FREECAM: + + break; + default: - return new Vector3f(0, height, 0); + break; } } + + public void updatePosition() { + Vector3f newPosition = getPos(); + camera.setLocation(newPosition); + + camera.lookAt(app.getGameLogic().getBoard().getFigure(app.getId()).getPos(), Vector3f.UNIT_Y); + camera.update(); + } + + private Vector3f getPos() { + Vector3f pos = new Vector3f(); + switch (currentMode) { + case FOCUS_CURRENT_PLAYER: + pos = app.getGameLogic().getBoard().getFigure(playerHandler.getPlayerById(0).getId()).getPos(); + + case FOCUS_SELF: + pos = app.getGameLogic().getBoard().getFigure(app.getId()).getPos(); + + case FREECAM: + + break; + default: + break; + } + Vector3f offset = getOffset(); + pos = new Vector3f(pos.getX() + offset.getX(), pos.getY() + offset.getY(), pos.getZ() + offset.getZ()); + + return pos; + + } + + private Vector3f getOffset() { + Vector3f offset = new Vector3f(); + + int fieldId = playerHandler.getPlayerById( (currentMode == CameraMode.FOCUS_SELF ? app.getId() : playerHandler.getPlayerAtIndex(0).getId()) ).getFieldID(); + // System.out.println(); + if(fieldId < 10) { + offset = new Vector3f(0, 15, -20); + } else if(fieldId < 20) { + offset = new Vector3f(20 , 15, 0); + } else if(fieldId < 30) { + offset = new Vector3f(0, 15, 20 ); + } else { + offset = new Vector3f(-20, 15, 0); + } + + return offset; + } + + @Override + public void receivedEvent(UpdatePlayerView event) { + playerHandler = app.getGameLogic().getPlayerHandler(); + } } 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 b1d4a56..4590e98 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 @@ -120,7 +120,7 @@ public class PlayerHandler { * @param index the index of the queue * @return the Player at the required index */ - Player getPlayerAtIndex(int index) { + public Player getPlayerAtIndex(int index) { return players.get(index); } 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 4650ad5..eecc7f5 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 @@ -147,6 +147,10 @@ public class Board { return getHotels().filter(hotel -> hotel.getFieldID() == fieldId).findFirst().orElse(null); } + public Figure getFigure(int playerId) { + return getFigures().filter(figure -> figure.getId() == playerId).findFirst().orElse(null); + } + /** * Returns a stream of all hotels currently on the map. *