From 3717e7b79465af646aa93c4aafac97c31ea194fb Mon Sep 17 00:00:00 2001 From: Cedric Beck Date: Mon, 2 Dec 2024 03:48:11 +0100 Subject: [PATCH] added javadocs to board --- .../client/{animation => }/InitControl.java | 2 +- .../src/main/java/pp/mdga/client/MdgaApp.java | 2 +- .../mdga/client/NotificationSynchronizer.java | 14 +- .../pp/mdga/client/animation/MoveControl.java | 3 +- .../mdga/client/animation/SymbolControl.java | 4 +- .../pp/mdga/client/animation/ZoomControl.java | 5 +- .../java/pp/mdga/client/board/AssetOnMap.java | 3 + .../pp/mdga/client/board/BoardHandler.java | 264 +++++++++++++++--- .../pp/mdga/client/board/CameraHandler.java | 39 +++ .../java/pp/mdga/client/board/MapLoader.java | 23 ++ .../pp/mdga/client/board/NodeControl.java | 21 ++ .../pp/mdga/client/board/OutlineControl.java | 54 ++-- .../pp/mdga/client/board/PieceControl.java | 98 ++++++- .../pp/mdga/client/board/PileControl.java | 5 - .../java/pp/mdga/client/board/Rotation.java | 12 - .../java/pp/mdga/client/view/GameView.java | 3 + 16 files changed, 443 insertions(+), 109 deletions(-) rename Projekte/mdga/client/src/main/java/pp/mdga/client/{animation => }/InitControl.java (97%) delete mode 100644 Projekte/mdga/client/src/main/java/pp/mdga/client/board/PileControl.java delete mode 100644 Projekte/mdga/client/src/main/java/pp/mdga/client/board/Rotation.java diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/InitControl.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/InitControl.java similarity index 97% rename from Projekte/mdga/client/src/main/java/pp/mdga/client/animation/InitControl.java rename to Projekte/mdga/client/src/main/java/pp/mdga/client/InitControl.java index f618e32e..73f259ff 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/InitControl.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/InitControl.java @@ -1,4 +1,4 @@ -package pp.mdga.client.animation; +package pp.mdga.client; import com.jme3.renderer.RenderManager; import com.jme3.renderer.ViewPort; diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java index cb0371c0..5aa92fc0 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java @@ -106,7 +106,7 @@ public void simpleInitApp() { gameView = new GameView(this); ceremonyView = new CeremonyView(this); - enter(MdgaState.MAIN); + enter(MdgaState.GAME); } /** diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/NotificationSynchronizer.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/NotificationSynchronizer.java index b45c1867..b943e955 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/NotificationSynchronizer.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/NotificationSynchronizer.java @@ -67,8 +67,9 @@ private void handleLobby(Notification notification) { lobbyView.setTaken(n.getColor(), false, false, null); } else if(notification instanceof LobbyReadyNotification lobbyReadyNotification) { lobbyView.setReady(lobbyReadyNotification.getColor(), lobbyReadyNotification.isReady()); - } else if (notification instanceof GameNotification) { + } else if (notification instanceof GameNotification n) { app.enter(MdgaState.GAME); + ((GameView) app.getView()).setOwnColor(n.getOwnColor()); } else { throw new RuntimeException("notification not expected: " + notification.toString()); } @@ -84,6 +85,7 @@ private void handleGame(Notification notification) { guiHandler.addCard(n.getBonusCard()); } else if (notification instanceof ActivePlayerNotification n) { gameView.getGuiHandler().setActivePlayer(n.getColor()); + boardHandler.showDice(n.getColor()); } else if (notification instanceof CeremonyNotification ceremonyNotification) { app.enter(MdgaState.CEREMONY); CeremonyView ceremonyView = (CeremonyView) app.getView(); @@ -116,23 +118,22 @@ private void handleGame(Notification notification) { } else if (notification instanceof DrawCardNotification n) { guiHandler.drawCard(n.getColor()); } else if (notification instanceof HomeMoveNotification home) { - boardHandler.moveHomePiece(home.getPieceId(), home.getHomeIndex()); + boardHandler.movePieceHomeAnim(home.getPieceId(), home.getHomeIndex()); guiHandler.hideText(); } else if (notification instanceof InterruptNotification) { app.enter(MdgaState.LOBBY); } else if (notification instanceof MovePieceNotification n) { if(n.isMoveStart()) { //StartMove - boardHandler.movePieceStart(n.getPiece(), n.getMoveIndex()); + boardHandler.movePieceStartAnim(n.getPiece(), n.getMoveIndex()); } else { //InfieldMove - boardHandler.movePiece(n.getPiece(), n.getStartIndex(), n.getMoveIndex()); -// boardHandler.test(n.getPiece(), n.getStartIndex(), n.getMoveIndex()); + boardHandler.movePieceAnim(n.getPiece(), n.getStartIndex(), n.getMoveIndex()); } guiHandler.hideText(); } else if (notification instanceof ThrowPieceNotification n) { - boardHandler.throwPiece(n.getPieceId()); + boardHandler.throwPieceAnim(n.getPieceId()); } else if (notification instanceof NoShieldNotification n) { boardHandler.unshieldPiece(n.getPieceId()); } else if (notification instanceof PlayCardNotification n) { @@ -152,6 +153,7 @@ private void handleGame(Notification notification) { guiHandler.rollDice(n.getEyes(), n.isTurbo() ? n.getMultiplier() : -1); } else { + boardHandler.hideDice(); if (n.isTurbo()) guiHandler.showRolledDiceMult(n.getEyes(), n.getMultiplier(), n.getColor()); else guiHandler.showRolledDice(n.getEyes(), n.getColor()); } diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/MoveControl.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/MoveControl.java index 621eb118..8aea4efc 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/MoveControl.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/MoveControl.java @@ -1,8 +1,7 @@ package pp.mdga.client.animation; import com.jme3.math.Vector3f; -import com.jme3.renderer.RenderManager; -import com.jme3.renderer.ViewPort; +import pp.mdga.client.InitControl; /** * A control that smoothly moves a spatial from an initial position to an end position diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/SymbolControl.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/SymbolControl.java index 3bc3e10a..1abf533c 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/SymbolControl.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/SymbolControl.java @@ -2,9 +2,7 @@ import com.jme3.math.Quaternion; import com.jme3.math.Vector3f; -import com.jme3.renderer.RenderManager; -import com.jme3.renderer.ViewPort; -import com.jme3.scene.control.AbstractControl; +import pp.mdga.client.InitControl; import pp.mdga.game.BonusCard; /** diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/ZoomControl.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/ZoomControl.java index 8cf83daf..eb4319cd 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/ZoomControl.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/animation/ZoomControl.java @@ -1,9 +1,6 @@ package pp.mdga.client.animation; -import com.jme3.renderer.RenderManager; -import com.jme3.renderer.ViewPort; -import com.jme3.scene.Spatial; -import com.jme3.scene.control.AbstractControl; +import pp.mdga.client.InitControl; /** * A control that applies a zoom effect to a spatial, smoothly scaling it in and out. diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/AssetOnMap.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/AssetOnMap.java index d78d48fd..ac6bdf53 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/AssetOnMap.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/AssetOnMap.java @@ -2,4 +2,7 @@ import pp.mdga.client.Asset; +/** + * Record for holding Asset information + */ record AssetOnMap(Asset asset, int x, int y, float rot) {} diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/BoardHandler.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/BoardHandler.java index 6f3f6237..a00508e8 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/BoardHandler.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/BoardHandler.java @@ -16,16 +16,24 @@ import java.util.*; +/** + * BoardHandler is responsible for managing the game board in the MDGA client, including handling + * the initialization, movement, and management of game pieces and assets. + * It works closely with the MdgaApp to create and manipulate 3D models of assets, track player pieces, + * and manage movement across the game board. + */ public class BoardHandler { + // Constants defining the grid size and elevation of the board private static final float GRID_SIZE = 1.72f; private static final float GRID_ELEVATION = 0.0f; private static final String MAP_NAME = "Maps/map.mdga"; + // The main application instance for accessing game assets and logic private final MdgaApp app; + // Collection of in-game assets and board elements private ArrayList infield; private Map pieces; - private Map> colorAssetsMap; private Map> homeNodesMap; private Map> waitingNodesMap; @@ -35,11 +43,11 @@ public class BoardHandler { private final Node rootNodeBoard; private final Node rootNode; - private final FilterPostProcessor fpp; private boolean isInitialised; + // Flags and lists for handling piece selection and movement private List selectableOwnPieces; private List selectableEnemyPieces; private List outlineNodes; @@ -47,6 +55,14 @@ public class BoardHandler { private PieceControl selectedEnemyPiece; private DiceControl diceControl; + /** + * Creates a new BoardHandler. + * + * @param app The main application instance + * @param rootNode The root node where the board will be attached + * @param fpp The post-processor for effects like shadows or filters + * @throws RuntimeException if the app is null + */ public BoardHandler(MdgaApp app, Node rootNode, FilterPostProcessor fpp) { if(app == null) throw new RuntimeException("app is null"); @@ -57,6 +73,9 @@ public BoardHandler(MdgaApp app, Node rootNode, FilterPostProcessor fpp) { isInitialised = false; } + /** + * Initializes the game board by setting up the pieces and nodes. + */ public void init() { isInitialised = true; selectableOwnPieces = new ArrayList<>(); @@ -68,17 +87,30 @@ public void init() { rootNode.attachChild(rootNodeBoard); } + /** + * Shuts down the board handler by detaching all board-related nodes and clearing selected pieces. + */ public void shutdown(){ clearSelectable(); isInitialised = false; rootNode.detachChild(rootNodeBoard); } + /** + * Adds an asset to the map of player assets, ensuring that the player does not have too many assets. + * + * @param col The color of the player + * @param assetOnMap The asset to be added + * @throws RuntimeException if there are too many assets for the player + */ private void addFigureToPlayerMap(Color col, AssetOnMap assetOnMap) { List inMap = addItemToMapList(colorAssetsMap, col, assetOnMap); if (inMap.size() > 4) throw new RuntimeException("to many assets for " + col); } + /** + * Initializes the map with the assets loaded from the map file and corresponding nodes. + */ private void initMap() { pieces = new HashMap<>(); colorAssetsMap = new HashMap<>(); @@ -120,6 +152,13 @@ private void initMap() { } } + /** + * Converts an asset to its corresponding color. + * + * @param asset The asset to be converted + * @return The color associated with the asset + * @throws RuntimeException if the asset is invalid + */ private Color assetToColor(Asset asset) { return switch (asset) { case lw -> Color.AIRFORCE; @@ -130,6 +169,14 @@ private Color assetToColor(Asset asset) { }; } + /** + * Creates a 3D model of an asset and adds it to the board. + * + * @param asset The asset to be displayed + * @param pos The position of the asset on the board + * @param rot The rotation of the asset + * @return The Spatial representation of the asset + */ private Spatial createModel(Asset asset, Vector3f pos, float rot) { String modelName = asset.getModelPath(); String texName = asset.getDiffPath(); @@ -146,10 +193,23 @@ private Spatial createModel(Asset asset, Vector3f pos, float rot) { return model; } + /** + * Converts grid coordinates to world space. + * + * @param x The x-coordinate on the grid + * @param y The y-coordinate on the grid + * @return The corresponding world position + */ private static Vector3f gridToWorld(int x, int y) { return new Vector3f(GRID_SIZE * x, GRID_SIZE * y, GRID_ELEVATION); } + /** + * Displays an asset on the map at the given position with the specified rotation. + * + * @param assetOnMap The asset to be displayed. + * @return A spatial representation of the asset at the specified location and rotation. + */ private Spatial displayAsset(AssetOnMap assetOnMap) { int x = assetOnMap.x(); int y = assetOnMap.y(); @@ -171,6 +231,13 @@ private void addHomeNode(Map> map, Color color, AssetOn if (homeNodes.size() > 4) throw new RuntimeException("too many homeNodes for " + color); } + /** + * Calculates the rotation angle required to move a piece from one position to another. + * + * @param prev The previous position. + * @param next The target position. + * @return The rotation angle in degrees. + */ private float getRotationMove(Vector3f prev, Vector3f next) { Vector3f direction = next.subtract(prev).normalizeLocal(); //I had to reverse dir.y, because then it worked. @@ -179,6 +246,14 @@ private float getRotationMove(Vector3f prev, Vector3f next) { return newRot; } + /** + * Recursively moves a piece from its current index to the destination index, + * to keep track of the piece rotation. + * + * @param uuid The UUID of the piece to move. + * @param curIndex The current index of the piece. + * @param moveIndex The target index to move the piece to. + */ private void movePieceRek(UUID uuid, int curIndex, int moveIndex){ if (curIndex == moveIndex) return; @@ -211,6 +286,12 @@ private Vector3f getWaitingPos(Color color){ return getMeanPosition(waitingNodesMap.get(color).stream().map(NodeControl::getLocation).toList()); } + /** + * Gets the mean position of a list of vectors. + * + * @param vectors The list of vectors. + * @return The mean position as a Vector3f. + */ public static Vector3f getMeanPosition(List vectors) { if (vectors.isEmpty()) return new Vector3f(0, 0, 0); @@ -221,7 +302,13 @@ public static Vector3f getMeanPosition(List vectors) { return sum.divide(vectors.size()); } - //public methods**************************************************************************************************** + /** + * Adds a player to the game by associating a color and a list of UUIDs to corresponding assets and waiting nodes. + * + * @param color the color of the player + * @param uuid the list of UUIDs representing the player's assets + * @throws RuntimeException if the number of assets or waiting nodes does not match the provided UUIDs + */ public void addPlayer(Color color, List uuid) { List playerAssets = colorAssetsMap.get(color); @@ -254,7 +341,14 @@ public void addPlayer(Color color, List uuid) { } } - public void moveHomePiece(UUID uuid, int index){ + /** + * Moves a piece to its corresponding home node based on the given index. + * + * @param uuid the UUID of the piece to move + * @param index the index of the home node to move the piece to + * @throws RuntimeException if the UUID is not mapped to a color or if the home nodes are not properly defined + */ + private void moveHomePiece(UUID uuid, int index){ Color color = pieceColor.get(uuid); if(color == null) throw new RuntimeException("uuid is not mapped to a color"); @@ -275,7 +369,15 @@ public void moveHomePiece(UUID uuid, int index){ app.getModelSynchronize().animationEnd(); } - public void movePieceStart(UUID uuid, int nodeIndex){ + /** + * Starts the movement of a piece to a target node based on the given index. + * + * @param uuid the UUID of the piece to move + * @param nodeIndex the index of the target node to move the piece to + * @throws RuntimeException if the UUID is not mapped to a color or the piece control is not found + * @throws IllegalArgumentException if the node index is invalid + */ + private void movePieceStart(UUID uuid, int nodeIndex){ // Farbe des Pieces abrufen Color color = pieceColor.get(uuid); @@ -298,13 +400,26 @@ public void movePieceStart(UUID uuid, int nodeIndex){ app.getModelSynchronize().animationEnd(); } - public void movePiece(UUID uuid, int curIndex, int moveIndex){ + /** + * Moves a piece from its current position to the target position based on the given indexes. + * + * @param uuid the UUID of the piece to move + * @param curIndex the current index of the piece + * @param moveIndex the target index of the move + */ + private void movePiece(UUID uuid, int curIndex, int moveIndex){ movePieceRek(uuid, curIndex, moveIndex); app.getModelSynchronize().animationEnd(); } - public void throwPiece(UUID uuid){ + /** + * Throws a piece to the next available waiting node and updates the waiting node mapping. + * + * @param uuid the UUID of the piece to throw + * @throws RuntimeException if the UUID is not mapped to a color or if no available waiting nodes are found + */ + private void throwPiece(UUID uuid){ // Farbe des Pieces abrufen Color color = pieceColor.get(uuid); @@ -331,59 +446,65 @@ public void throwPiece(UUID uuid){ app.getModelSynchronize().animationEnd(); } + + /** + * Activates the shield for the specified piece. + * + * @param uuid the UUID of the piece to shield + */ public void shieldPiece(UUID uuid){ pieces.get(uuid).activateShield(); } + /** + * Deactivates the shield for the specified piece. + * + * @param uuid the UUID of the piece to unshield + */ public void unshieldPiece(UUID uuid){ pieces.get(uuid).deactivateShield(); } + /** + * Suppresses the shield for the specified piece. + * + * @param uuid the UUID of the piece to suppress the shield + */ public void suppressShield(UUID uuid){ pieces.get(uuid).suppressShield(); } - public void swapPieces(PieceControl p1, PieceControl p2, Vector3f loc1, float rot1, Vector3f loc2, float rot2){ - -// PieceControl piece1Control = pieces.get(piece1); -// PieceControl piece2Control = pieces.get(piece2); - -// if(piece1Control == null) throw new RuntimeException("piece1 UUID is not valid"); -// if(piece2Control == null) throw new RuntimeException("piece2 UUID is not valid"); - -// float rot1 = piece1Control.getRotation(); -// float rot2 = piece2Control.getRotation(); - -// piece1Control.setRotation(rot2); -// piece2Control.setRotation(rot1); - -// Vector3f pos1 = piece1Control.getLocation().clone(); -// Vector3f pos2 = piece2Control.getLocation().clone(); - -// piece1Control.setLocation(pos2); -// piece2Control.setLocation(pos1); - + /** + * Swaps the positions and rotations of two pieces. + * + * @param p1 the first piece to swap + * @param p2 the second piece to swap + * @param loc1 the original location of the first piece + * @param rot1 the original rotation of the first piece + * @param loc2 the original location of the second piece + * @param rot2 the original rotation of the second piece + */ + private void swapPieces(PieceControl p1, PieceControl p2, Vector3f loc1, float rot1, Vector3f loc2, float rot2){ p1.setLocation(loc2); p2.setLocation(loc1); p1.setRotation(rot2); p2.setRotation(rot1); - app.getModelSynchronize().animationEnd(); } - public void highlight(UUID uuid, boolean bool){ - - pieces.get(uuid).highlight(bool); - pieces.get(uuid).setSelectable(bool); - - } - - //called when (dice) moveNum is received from server to display the movable pieces and corresponding moveNodes + /** + * Outlines the possible move nodes for a list of pieces based on the move indices and whether it's a home move. + * + * @param pieces the list of UUIDs representing the pieces to outline + * @param moveIndexe the list of indices for the target move nodes + * @param homeMoves the list indicating whether the move is a home move + * @throws RuntimeException if the sizes of the input lists do not match + */ public void outlineMove(List pieces, List moveIndexe, List homeMoves) { if(pieces.size() != moveIndexe.size() || pieces.size() != homeMoves.size()) throw new RuntimeException("arrays are not the same size"); @@ -413,7 +534,12 @@ public void outlineMove(List pieces, List moveIndexe, List ownPieces, List enemyPieces){ selectableEnemyPieces.clear(); @@ -437,6 +563,11 @@ public void outlineSwap(List ownPieces, List enemyPieces){ } } + /** + * Outlines the pieces that can be shielded based on the provided list of pieces. + * + * @param pieces the list of UUIDs representing the pieces to be shielded + */ public void outlineShield(List pieces){ selectableOwnPieces.clear(); selectableEnemyPieces.clear(); @@ -452,7 +583,11 @@ public void outlineShield(List pieces){ } } - //called from inputSynchronizer when a piece is selectable + /** + * Selects a piece from either the own or enemy pieces based on the input and deselects others if needed. + * + * @param pieceSelected the PieceControl instance representing the piece selected by the user + */ public void pieceSelect(PieceControl pieceSelected) { boolean isSelected = pieceSelected.isSelected(); if(selectableOwnPieces.contains(pieceSelected)){ @@ -486,7 +621,9 @@ else if(selectableEnemyPieces.contains(pieceSelected)) { app.getModelSynchronize().select(getKeyByValue(pieces, selectedOwnPiece), getKeyByValue(pieces, selectedEnemyPiece)); } - //called when view is no longer needed to select pieces + /** + * Clears all highlighted, selectable, and selected pieces and nodes. + */ public void clearSelectable(){ for(PieceControl p : selectableEnemyPieces) { p.unSelect(); @@ -508,16 +645,20 @@ public void clearSelectable(){ selectedOwnPiece = null; } - public void enableHover(UUID uuid){ - pieces.get(uuid).setHoverable(true); - } - + /** + * Displays the dice for the specified color at the appropriate position. + * + * @param color the color of the player whose dice should be displayed + */ public void showDice(Color color){ rootNodeBoard.attachChild(diceControl.getSpatial()); diceControl.setPos(getWaitingPos(color).add(new Vector3f(0,0,4))); diceControl.spin(); } + /** + * Hides the dice from the view. + */ public void hideDice(){ diceControl.hide(); } @@ -531,6 +672,13 @@ private K getKeyByValue(Map map, V value) { return null; } + /** + * Animates the movement of a piece from its current index to a target index. + * + * @param uuid the UUID of the piece to animate + * @param curIndex the current index of the piece + * @param moveIndex the target index to animate the piece to + */ public void movePieceAnim(UUID uuid, int curIndex, int moveIndex){ pieces.get(uuid).getSpatial().addControl(new MoveControl( infield.get(curIndex).getLocation(), @@ -538,6 +686,12 @@ public void movePieceAnim(UUID uuid, int curIndex, int moveIndex){ ()->movePiece(uuid,curIndex,moveIndex))); } + /** + * Animates the movement of a piece to its home position based on the given home index. + * + * @param uuid the UUID of the piece to animate + * @param homeIndex the index of the home node to move the piece to + */ public void movePieceHomeAnim(UUID uuid, int homeIndex){ pieces.get(uuid).getSpatial().addControl(new MoveControl( pieces.get(uuid).getLocation(), @@ -545,6 +699,12 @@ public void movePieceHomeAnim(UUID uuid, int homeIndex){ ()->moveHomePiece(uuid,homeIndex))); } + /** + * Animates the start of the movement of a piece to a target index. + * + * @param uuid the UUID of the piece to animate + * @param moveIndex the target index to animate the piece to + */ public void movePieceStartAnim(UUID uuid, int moveIndex){ pieces.get(uuid).getSpatial().addControl(new MoveControl( pieces.get(uuid).getLocation(), @@ -553,6 +713,11 @@ public void movePieceStartAnim(UUID uuid, int moveIndex){ )); } + /** + * Animates the throwing of a piece to the next available waiting node. + * + * @param uuid the UUID of the piece to animate + */ public void throwPieceAnim(UUID uuid){ pieces.get(uuid).getSpatial().addControl(new MoveControl( pieces.get(uuid).getLocation(), @@ -561,6 +726,12 @@ public void throwPieceAnim(UUID uuid){ )); } + /** + * Animates the swapping of two pieces by swapping their positions and rotations. + * + * @param piece1 the UUID of the first piece + * @param piece2 the UUID of the second piece + */ public void swapPieceAnim(UUID piece1, UUID piece2){ PieceControl piece1Control = pieces.get(piece1); PieceControl piece2Control = pieces.get(piece2); @@ -582,6 +753,13 @@ public void swapPieceAnim(UUID piece1, UUID piece2){ )); } + /** + * Retrieves the next available waiting node for the specified color. + * + * @param color the color of the player to get the next waiting node for + * @return the next available NodeControl for the specified color + * @throws IllegalStateException if no available waiting nodes are found for the color + */ private NodeControl getNextWaitingNode(Color color) { List nodes = waitingNodesMap.get(color); diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/CameraHandler.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/CameraHandler.java index c0469eef..57da8393 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/CameraHandler.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/CameraHandler.java @@ -15,6 +15,10 @@ import pp.mdga.client.MdgaApp; import pp.mdga.game.Color; +/** + * Handles the camera position, rotation, and lighting effects for the game. + * Provides methods for camera initialization, updates based on user input, and shutdown operations. + */ public class CameraHandler { MdgaApp app; @@ -34,6 +38,12 @@ public class CameraHandler { private boolean init; private boolean initRot; + /** + * Constructor for the CameraHandler. Initializes the camera settings and lighting. + * + * @param app The main application instance that provides the camera and root node. + * @param fpp The FilterPostProcessor used for post-processing effects. + */ public CameraHandler(MdgaApp app, FilterPostProcessor fpp) { init = false; initRot = false; @@ -61,6 +71,12 @@ public CameraHandler(MdgaApp app, FilterPostProcessor fpp) { } + /** + * Initializes the camera with a specific color orientation. + * Adds lights, sky, and shadow filters to the scene. + * + * @param ownColor The color that defines the initial camera view angle. + */ public void init(Color ownColor) { app.getRootNode().addLight(sun); app.getRootNode().addLight(ambient); @@ -72,6 +88,10 @@ public void init(Color ownColor) { app.getInputSynchronize().setRotation(getInitAngleByColor(ownColor)*2); } + /** + * Shuts down the camera handler by removing all lights, sky, and filters, + * and resets the camera position and rotation to its default state. + */ public void shutdown() { app.getRootNode().removeLight(sun); app.getRootNode().removeLight(ambient); @@ -84,6 +104,13 @@ public void shutdown() { fpp.removeFilter(dlsf); } + /** + * Updates the camera position and rotation based on user input (scroll and rotation). + * Adjusts the vertical angle and radius based on zoom and rotation values. + * + * @param scroll The scroll input, determining zoom level. + * @param rotation The rotation input, determining camera orientation. + */ public void update(float scroll, float rotation) { if(!init) return; float scrollValue = Math.max(0, Math.min(scroll, 100)); @@ -117,6 +144,12 @@ public void update(float scroll, float rotation) { app.getCamera().lookAt(Vector3f.ZERO, Vector3f.UNIT_Z); } + /** + * Returns the camera angle based on the specified color. + * + * @param color The color used to determine the camera angle. + * @return The camera angle in degrees. + */ private float getAngleByColor(Color color){ return switch (color){ case ARMY -> 0; @@ -127,6 +160,12 @@ private float getAngleByColor(Color color){ }; } + /** + * Returns the initial camera angle based on the specified color. + * + * @param color The color used to determine the camera angle. + * @return The initial camera angle in degrees. + */ private float getInitAngleByColor(Color color){ return (getAngleByColor(color) + 180) % 360; } diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/MapLoader.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/MapLoader.java index c85a7dcc..9d283f8f 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/MapLoader.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/MapLoader.java @@ -10,11 +10,27 @@ import java.util.ArrayList; import java.util.List; +/** + * A utility class for loading and parsing map data from a file. + * The map contains asset names and coordinates for objects placed on the map. + */ class MapLoader { + /** + * Private constructor to prevent instantiation. + */ private MapLoader() { } + /** + * Loads a map file and parses its contents into a list of assets and their positions. + * Each line in the map file defines an asset, its coordinates, and its rotation. + * + * @param mapName The name of the map file to load. The file is expected to be located in the resources directory. + * @return A list of {@link AssetOnMap} objects representing the assets placed on the map. + * @throws IOException If an error occurs while reading the map file. + * @throws IllegalArgumentException If the map file contains invalid data. + */ public static List loadMap(String mapName) { List assetsOnMap = new ArrayList<>(); @@ -60,6 +76,13 @@ public static List loadMap(String mapName) { return assetsOnMap; } + /** + * Returns the corresponding {@link Asset} for a given asset name. + * + * @param assetName The name of the asset to load. + * @return The {@link Asset} associated with the given name. + * @throws IllegalStateException If the asset name is unrecognized. + */ private static Asset getLoadedAsset(String assetName) { return switch (assetName) { case "lw" -> Asset.lw; diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/NodeControl.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/NodeControl.java index 5288b537..d3f1d80e 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/NodeControl.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/NodeControl.java @@ -8,19 +8,40 @@ import com.jme3.scene.control.AbstractControl; import pp.mdga.client.MdgaApp; +/** + * A control that adds highlighting functionality to a node in the game. + * This class extends {@link OutlineControl} to add an outline effect when the node is highlighted. + */ public class NodeControl extends OutlineControl { private static final ColorRGBA OUTLINE_HIGHLIGHT_COLOR = ColorRGBA.White; private static final int OUTLINE_HIGHLIGHT_WIDTH = 6; + /** + * Constructs a {@link NodeControl} with the specified application and post processor. + * This constructor sets up the necessary elements for highlighting functionality. + * + * @param app The {@link MdgaApp} instance to use for the application context. + * @param fpp The {@link FilterPostProcessor} to apply post-processing effects. + */ public NodeControl(MdgaApp app, FilterPostProcessor fpp) { super(app, fpp); } + /** + * Returns the location of the node in 3D space. + * This is the node's local translation in the scene. + * + * @return The {@link Vector3f} representing the node's location. + */ public Vector3f getLocation(){ return this.getSpatial().getLocalTranslation(); } + /** + * Highlights the node by applying an outline effect. + * The outline color and width are predefined as white and 6, respectively. + */ public void highlight() { super.outline(OUTLINE_HIGHLIGHT_COLOR, OUTLINE_HIGHLIGHT_WIDTH); } diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/OutlineControl.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/OutlineControl.java index 9444e841..f0dfba51 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/OutlineControl.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/OutlineControl.java @@ -3,16 +3,19 @@ import com.jme3.math.ColorRGBA; import com.jme3.post.FilterPostProcessor; import com.jme3.renderer.Camera; -import com.jme3.renderer.RenderManager; -import com.jme3.renderer.ViewPort; -import com.jme3.scene.Spatial; -import com.jme3.scene.control.AbstractControl; import pp.mdga.client.MdgaApp; +import pp.mdga.client.InitControl; import pp.mdga.client.outline.SelectObjectOutliner; -public class OutlineControl extends AbstractControl { - private static final int THICKNESS_DEFAULT = 6; +/** + * A control that provides outline functionality to a spatial object. + * This class is responsible for adding an outline effect to a spatial + * object, allowing it to be highlighted or deselected. + */ +public class OutlineControl extends InitControl { + /** The {@link SelectObjectOutliner} responsible for managing the outline effect. */ private final SelectObjectOutliner outlineOwn; + private static final int THICKNESS_DEFAULT = 6; private MdgaApp app; @@ -31,44 +34,33 @@ public OutlineControl(MdgaApp app, FilterPostProcessor fpp, Camera cam, int thic outlineOwn = new SelectObjectOutliner(thickness, fpp, app.getRenderManager(), app.getAssetManager(), cam, app); } + /** + * Applies an outline to the spatial object with the given color. + * + * @param color The {@link ColorRGBA} representing the color of the outline. + */ public void outline(ColorRGBA color){ outlineOwn.select(spatial, color); } + /** + * Applies an outline to the spatial object with the given color and width. + * + * @param color The {@link ColorRGBA} representing the color of the outline. + * @param width The width of the outline. + */ public void outline(ColorRGBA color, int width){ deOutline(); outlineOwn.select(spatial, color, width); } + /** + * Removes the outline effect from the spatial object. + */ public void deOutline(){ outlineOwn.deselect(spatial); } - @Override - protected void controlUpdate(float tpf) { - - } - - @Override - protected void controlRender(RenderManager rm, ViewPort vp) { - - } - - public void initSpatial(){ - - } - - @Override - public void setSpatial(Spatial spatial){ - if(this.spatial == null && spatial != null){ - super.setSpatial(spatial); - initSpatial(); - } - else{ - super.setSpatial(spatial); - } - } - public MdgaApp getApp() { return app; } diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/PieceControl.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/PieceControl.java index d9b22030..4a75533d 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/PieceControl.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/PieceControl.java @@ -14,6 +14,12 @@ import pp.mdga.client.Asset; import pp.mdga.client.MdgaApp; +/** + * A control that manages the behavior and properties of a game piece, such as its rotation, + * position, shield activation, and highlighting. This class extends {@link OutlineControl} + * to provide outline functionality and includes additional features like shield effects, + * hover states, and selection states. + */ public class PieceControl extends OutlineControl { private final float initRotation; private final AssetManager assetManager; @@ -43,7 +49,15 @@ public class PieceControl extends OutlineControl { private boolean selectable; private boolean select; - + /** + * Constructs a {@link PieceControl} with the specified initial rotation, asset manager, + * application, and post-processor. + * + * @param initRotation The initial rotation of the piece in degrees. + * @param assetManager The {@link AssetManager} used for loading models and materials. + * @param app The {@link MdgaApp} instance to use for the application context. + * @param fpp The {@link FilterPostProcessor} to apply post-processing effects. + */ public PieceControl(float initRotation, AssetManager assetManager, MdgaApp app, FilterPostProcessor fpp){ super(app, fpp); this.parentNode = new Node(); @@ -59,10 +73,20 @@ public PieceControl(float initRotation, AssetManager assetManager, MdgaApp app, select = false; } + /** + * Gets the current rotation of the piece in degrees. + * + * @return The rotation of the piece in degrees. + */ public float getRotation() { return (float) Math.toDegrees(spatial.getLocalRotation().toAngleAxis(new Vector3f(0,0,1))); } + /** + * Sets the rotation of the piece to the specified value in degrees. + * + * @param rot The rotation in degrees to set. + */ public void setRotation(float rot){ if(rot < 0) rot =- 360; @@ -71,10 +95,20 @@ public void setRotation(float rot){ spatial.setLocalRotation(quaternion); } + /** + * Gets the current location (position) of the piece. + * + * @return The location of the piece as a {@link Vector3f}. + */ public Vector3f getLocation(){ return spatial.getLocalTranslation(); } + /** + * Updates the piece control every frame. If the shield is active, it will rotate. + * + * @param delta The time difference between frames (time per frame). + */ @Override protected void controlUpdate(float delta) { if(shieldRing != null){ @@ -82,10 +116,19 @@ protected void controlUpdate(float delta) { } } + /** + * Sets the location (position) of the piece. + * + * @param loc The location to set as a {@link Vector3f}. + */ public void setLocation(Vector3f loc){ this.spatial.setLocalTranslation(loc); } + /** + * Initializes the spatial object and sets its rotation. + * This also moves the spatial to a new parent node for organizational purposes. + */ @Override public void initSpatial(){ setRotation(this.initRotation); @@ -101,6 +144,10 @@ public void rotateInit() { // rotate(rotation - initRotation); } + /** + * Activates the shield around the piece. + * This adds a visual shield effect in the form of a rotating ring. + */ public void activateShield(){ shieldRing = assetManager.loadModel(Asset.shieldRing.getModelPath()); shieldRing.scale(1f); @@ -115,11 +162,18 @@ public void activateShield(){ parentNode.attachChild(shieldRing); } + /** + * Deactivates the shield by removing the shield ring from the scene. + */ + public void deactivateShield(){ parentNode.detachChild(shieldRing); shieldRing = null; } + /** + * Suppresses the shield, changing its color to a suppressed state. + */ public void suppressShield(){ assert(shieldRing != null) : "PieceControl: shieldRing is not set"; shieldMat.setColor("Color", SHIELD_SUPPRESSED_COLOR); @@ -133,22 +187,36 @@ public Material getMaterial(){ return ((Geometry) getSpatial()).getMaterial(); } + /** + * Highlights the piece with the appropriate outline color based on whether it is an enemy or not. + * + * @param enemy True if the piece is an enemy, false if it is owned by the player. + */ public void highlight(boolean enemy) { this.enemy = enemy; highlight = true; super.outline(enemy ? OUTLINE_ENEMY_COLOR : OUTLINE_OWN_COLOR, OUTLINE_HIGHLIGHT_WIDTH); } + /** + * Removes the highlight effect from the piece. + */ public void unHighlight(){ highlight = false; deOutline(); } + /** + * Applies a hover effect on the piece if it is hoverable. + */ public void hover(){ if(!hoverable) return; super.outline(enemy ? OUTLINE_ENEMY_HOVER_COLOR : OUTLINE_OWN_HOVER_COLOR, OUTLINE_HOVER_WIDTH); } + /** + * Removes the hover effect from the piece. + */ public void hoverOff(){ if(!hoverable) return; @@ -157,28 +225,56 @@ public void hoverOff(){ else deOutline(); } + /** + * Deselects the piece and removes the selection outline. If the piece was highlighted, + * it will be re-highlighted. Otherwise, the outline is removed. + */ public void unSelect(){ select = false; if(highlight) highlight(enemy); else deOutline(); } + /** + * Selects the piece and applies the selection outline. If the piece is an enemy, it will + * be outlined with the enemy selection color; otherwise, the own selection color will be used. + */ public void select(){ if(!selectable) return; select = true; super.outline(enemy ? OUTLINE_ENEMY_SELECT_COLOR : OUTLINE_OWN_SELECT_COLOR, OUTLINE_SELECT_WIDTH); } + /** + * Sets whether the piece is selectable. + * + * @param selectable True if the piece can be selected, false otherwise. + */ public void setSelectable(boolean selectable){ this.selectable = selectable; } + /** + * Checks if the piece is selected. + * + * @return True if the piece is selected, false otherwise. + */ public boolean isSelected() { return select; } + /** + * Checks if the piece is selectable. + * + * @return True if the piece is selectable, false otherwise. + */ public boolean isSelectable() { return selectable; } + /** + * Sets whether the piece is hoverable. + * + * @param hoverable True if the piece can be hovered over, false otherwise. + */ public void setHoverable(boolean hoverable) { this.hoverable = hoverable; } diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/PileControl.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/PileControl.java deleted file mode 100644 index f4e604c6..00000000 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/PileControl.java +++ /dev/null @@ -1,5 +0,0 @@ -package pp.mdga.client.board; - -class PileControl { - -} diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/Rotation.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/Rotation.java deleted file mode 100644 index 5db07057..00000000 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/Rotation.java +++ /dev/null @@ -1,12 +0,0 @@ -package pp.mdga.client.board; - -public enum Rotation { - UP, - RIGHT, - DOWN, - LEFT, - UP_LEFT, - UP_RIGHT, - DOWN_RIGHT, - DOWN_LEFT -} diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/view/GameView.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/view/GameView.java index 41a2b412..9d1a7fe5 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/view/GameView.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/view/GameView.java @@ -64,6 +64,9 @@ public void onEnter() { app.getViewPort().addProcessor(fpp); app.getAcousticHandler().playSound(MdgaSound.START); + + app.getNotificationSynchronizer().addTestNotification(new AcquireCardNotification(BonusCard.SHIELD)); + app.getNotificationSynchronizer().addTestNotification(new SelectableCardsNotification(List.of(BonusCard.SHIELD))); } @Override