diff --git a/src/main/java/seng302/visualiser/controllers/LobbyController.java b/src/main/java/seng302/visualiser/controllers/LobbyController.java index 610ce041..84be615c 100644 --- a/src/main/java/seng302/visualiser/controllers/LobbyController.java +++ b/src/main/java/seng302/visualiser/controllers/LobbyController.java @@ -2,17 +2,33 @@ package seng302.visualiser.controllers; import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXDialog; +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.ResourceBundle; import javafx.application.Platform; import javafx.collections.ListChangeListener; +import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.fxml.Initializable; +import javafx.geometry.Point3D; +import javafx.scene.Group; import javafx.scene.control.Label; import javafx.scene.control.ScrollPane; +import javafx.scene.input.MouseEvent; import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.Pane; import javafx.scene.layout.StackPane; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; +import javafx.scene.transform.Rotate; +import javafx.scene.transform.Scale; +import javafx.scene.transform.Translate; import seng302.discoveryServer.DiscoveryServerClient; import seng302.gameServer.GameStages; import seng302.gameServer.GameState; @@ -27,13 +43,10 @@ import seng302.utilities.Sounds; import seng302.visualiser.MapPreview; import seng302.visualiser.controllers.cells.PlayerCell; import seng302.visualiser.controllers.dialogs.BoatCustomizeController; - -import java.io.IOException; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.ResourceBundle; +import seng302.visualiser.controllers.dialogs.PopupDialogController; +import seng302.visualiser.controllers.dialogs.TokenInfoDialogController; +import seng302.visualiser.fxObjects.assets_3D.ModelFactory; +import seng302.visualiser.fxObjects.assets_3D.ModelType; public class LobbyController implements Initializable { @@ -57,10 +70,13 @@ public class LobbyController implements Initializable { private AnchorPane serverMap; @FXML private Label roomLabel; + @FXML + private Pane speedTokenPane, handlingTokenPane, windWalkerTokenPane, bumperTokenPane, randomTokenPane; //---------FXML END---------// private RaceState raceState; private JFXDialog customizationDialog; + private JFXDialog tokenInfoDialog; public Color playersColor; private Map playerBoats; private Double mapWidth = INITIAL_MAP_WIDTH, mapHeight = INITIAL_MAP_HEIGHT; @@ -128,6 +144,107 @@ public class LobbyController implements Initializable { beginRaceButton.setOnMouseEntered(e -> Sounds.playHoverSound()); initMapPreview(); + initTokenPreviews(); + } + + + /** + * Initialises the tokens in the side panel + */ + private void initTokenPreviews() { + Group speedToken = ModelFactory.importModel(ModelType.VELOCITY_PICKUP).getAssets(); + Group handlingToken = ModelFactory.importModel(ModelType.HANDLING_PICKUP).getAssets(); + Group windWalkerToken = ModelFactory.importModel(ModelType.WIND_WALKER_PICKUP).getAssets(); + Group bumperToken = ModelFactory.importModel(ModelType.BUMPER_PICKUP).getAssets(); + Group randomToken = ModelFactory.importModel(ModelType.RANDOM_PICKUP).getAssets(); + + HashMap tokenPanes = new HashMap<>(); + tokenPanes.put(speedTokenPane, speedToken); + tokenPanes.put(handlingTokenPane, handlingToken); + tokenPanes.put(windWalkerTokenPane, windWalkerToken); + tokenPanes.put(bumperTokenPane, bumperToken); + tokenPanes.put(randomTokenPane, randomToken); + + Scale hoverScale = new Scale(1.2, 1.2, 1.2); + + tokenPanes.entrySet().forEach((entry) -> { + Pane thisPane = entry.getKey(); + Group thisToken = entry.getValue(); + + thisToken.getTransforms().addAll( + new Translate(40, 50, 0), + new Scale(13, 13, 13)); + + thisPane.setOnMouseEntered(event -> { + thisToken.getTransforms().add(hoverScale); + }); + thisPane.setOnMouseExited(event -> { + thisToken.getTransforms().remove(hoverScale); + }); + thisPane.setOnMouseReleased(event -> { + tokenInfoDialog = makeTokenDialog(thisPane); + tokenInfoDialog.show(); + }); + + thisPane.getChildren().add(thisToken); + }); + + //Hacky rotations for wind and random to level it in the plane + windWalkerToken.getTransforms().addAll( + new Rotate(-70, new Point3D(1, 0, 0)), + new Translate(0, 2,0) + ); + randomToken.getTransforms().addAll( + new Rotate(-90, new Point3D(1, 0, 0)), + new Translate(0, 0,1) + ); + } + + private JFXDialog makeTokenDialog(Pane inducingPane) { + String header = "..."; + String body = "Nothing to see here"; + ModelType modelType = ModelType.RANDOM_PICKUP; + + if (inducingPane == speedTokenPane) { + header = "Speed Boost"; + body = "Increases your max velocity"; + modelType = ModelType.VELOCITY_PICKUP; + } else if (inducingPane == handlingTokenPane) { + header = "Handling Boost"; + body = "Increases your turing rate"; + modelType = ModelType.HANDLING_PICKUP; + } else if (inducingPane == windWalkerTokenPane) { + header = "Wind Walker"; + body = "The wind now rotates with you, giving you your optimal speed in all directions"; + modelType = ModelType.WIND_WALKER_PICKUP; + } else if (inducingPane == bumperTokenPane) { + header = "Bumper"; + body = "While this is active, upon hitting another boat, you will power it down for a short time"; + modelType = ModelType.BUMPER_PICKUP; + } else if (inducingPane == randomTokenPane) { + header = "Random"; + body = "A 50% chance of becoming any other token and a 50% chance of slowing your boat for a time"; + modelType = ModelType.RANDOM_PICKUP; + } + + FXMLLoader dialog = new FXMLLoader( + getClass().getResource("/views/dialogs/TokenInfoDialog.fxml")); + + JFXDialog tokenInfoDialog = null; + + try { + tokenInfoDialog = new JFXDialog(serverListMainStackPane, dialog.load(), + JFXDialog.DialogTransition.CENTER); + } catch (IOException e) { + e.printStackTrace(); + } + + TokenInfoDialogController controller = dialog.getController(); + controller.setParentController(this); + controller.setHeader(header); + controller.setContent(body); + controller.setToken(modelType); + return tokenInfoDialog; } private JFXDialog createCustomizeDialog() { @@ -252,6 +369,10 @@ public class LobbyController implements Initializable { customizationDialog.close(); } + public void closeTokenInfoDialog() { + tokenInfoDialog.close(); + } + public void setRoomCode(String roomCode) { roomLabel.setText("Room: " + roomCode); } diff --git a/src/main/java/seng302/visualiser/controllers/ViewManager.java b/src/main/java/seng302/visualiser/controllers/ViewManager.java index c63b1a9f..1e3ab4ce 100644 --- a/src/main/java/seng302/visualiser/controllers/ViewManager.java +++ b/src/main/java/seng302/visualiser/controllers/ViewManager.java @@ -302,7 +302,7 @@ public class ViewManager { Stage stage = new Stage(); initialStartView(stage); } catch (Exception e) { - e.printStackTrace(); + logger.warn("Could not go to start view"); } } diff --git a/src/main/java/seng302/visualiser/controllers/dialogs/TokenInfoDialogController.java b/src/main/java/seng302/visualiser/controllers/dialogs/TokenInfoDialogController.java new file mode 100644 index 00000000..214456b7 --- /dev/null +++ b/src/main/java/seng302/visualiser/controllers/dialogs/TokenInfoDialogController.java @@ -0,0 +1,90 @@ +package seng302.visualiser.controllers.dialogs; + +import com.jfoenix.controls.JFXButton; +import com.jfoenix.controls.JFXTextArea; +import java.net.URL; +import java.util.ResourceBundle; +import javafx.event.EventHandler; +import javafx.fxml.FXML; +import javafx.fxml.Initializable; +import javafx.geometry.Point3D; +import javafx.scene.Group; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.TextArea; +import javafx.scene.input.MouseEvent; +import javafx.scene.layout.Pane; +import javafx.scene.transform.Rotate; +import javafx.scene.transform.Scale; +import javafx.scene.transform.Translate; +import seng302.utilities.Sounds; +import seng302.visualiser.controllers.LobbyController; +import seng302.visualiser.fxObjects.assets_3D.ModelFactory; +import seng302.visualiser.fxObjects.assets_3D.ModelType; + +/** + * Created by wmu16 on 28/09/17. + */ +public class TokenInfoDialogController implements Initializable { + + @FXML + private Label headerLabel; + @FXML + private TextArea contentText; + @FXML + private Pane tokenPane; + @FXML + private Button optionButton; + + private LobbyController lobbyController; + + @Override + public void initialize(URL location, ResourceBundle resources) { + optionButton.setOnMouseReleased(event -> { + Sounds.playButtonClick(); + lobbyController.closeTokenInfoDialog(); + }); + + contentText.setEditable(false); + + } + + + public void setContent(String content) { + contentText.setText(content); + } + + public void setHeader(String header) { + this.headerLabel.setText(header); + } + + public void setToken(ModelType token) { + tokenPane.getChildren().clear(); + + Group tokenObject = ModelFactory.importModel(token).getAssets(); + + tokenObject.getTransforms().addAll( + new Translate(138 / 2, 138 / 2, 0), + new Scale(20, 20, 20)); + + if (token == ModelType.WIND_WALKER_PICKUP) { + tokenObject.getTransforms().addAll( + new Rotate(-70, new Point3D(1, 0, 0)), + new Translate(0, 2, 0) + ); + } else if (token == ModelType.RANDOM_PICKUP) { + tokenObject.getTransforms().addAll( + new Rotate(-90, new Point3D(1, 0, 0)), + new Translate(0, 0, 1) + ); + } + + tokenPane.getChildren().add(tokenObject); + } + + public void setParentController(LobbyController lobbyController) { + this.lobbyController = lobbyController; + } + + +} diff --git a/src/main/java/seng302/visualiser/fxObjects/assets_3D/BoatMeshType.java b/src/main/java/seng302/visualiser/fxObjects/assets_3D/BoatMeshType.java index 5c659c9c..4be41d90 100644 --- a/src/main/java/seng302/visualiser/fxObjects/assets_3D/BoatMeshType.java +++ b/src/main/java/seng302/visualiser/fxObjects/assets_3D/BoatMeshType.java @@ -13,7 +13,8 @@ public enum BoatMeshType { PIRATE_SHIP("pirateship_hull.stl", "pirateship_mast.stl", -0.5415, "pirateship_mainsail.stl", -0.5415, "pirateship_frontsail.stl", true, 1.2, 1.6, 1.2), DUCKY("ducky_hull.stl", "ducky_mast.stl", -2.18539, "ducky_sail.stl", -2.18539, "ducky_eyes.stl", false, 1.2, 1.1, 1.4), - PARROT("parrot_hull.stl", null, 0, "parrot_sail.stl", 0, "parrot_features.stl", true, 1, 1, 1); + PARROT("parrot_hull.stl", null, 0, "parrot_sail.stl", 0, "parrot_features.stl", true, 1, 1, 1), + WAKA("waka_hull.stl", "waka_mast.stl", 0, "waka_sail.stl", 0, null, true, 1.7, 0.5, 1.5); final String hullFile, mastFile, sailFile, jibFile; final double mastOffset, sailOffset; @@ -21,7 +22,7 @@ public enum BoatMeshType { public final double accelerationMultiplier; public final double turnStep; final boolean fixedSail; - final static BoatMeshType[] boatTypes = new BoatMeshType[]{DINGHY, CATAMARAN, PIRATE_SHIP, DUCKY, PARROT}; + final static BoatMeshType[] boatTypes = new BoatMeshType[]{DINGHY, CATAMARAN, PIRATE_SHIP, DUCKY, PARROT, WAKA}; BoatMeshType(String hullFile, String mastFile, double mastOffset, String sailFile, double sailOffset, String jibFile, boolean fixedSail, double maxSpeedMultiplier, double accelerationMultiplier, double turnStep) { diff --git a/src/main/java/seng302/visualiser/fxObjects/assets_3D/ModelFactory.java b/src/main/java/seng302/visualiser/fxObjects/assets_3D/ModelFactory.java index bc0ce008..93d16c13 100644 --- a/src/main/java/seng302/visualiser/fxObjects/assets_3D/ModelFactory.java +++ b/src/main/java/seng302/visualiser/fxObjects/assets_3D/ModelFactory.java @@ -80,30 +80,6 @@ public class ModelFactory { return bo; } - public static BoatModel boatRotatingView(BoatMeshType boatType, Color primaryColour) { - Group boatAssets = getUnmodifiedBoatModel(boatType, primaryColour); - boatAssets.getTransforms().addAll( - new Scale(40, 40, 40), - new Rotate(90, new Point3D(0,0,1)), - new Rotate(90, new Point3D(0, 1, 0)) - ); - - final Rotate animationRotate = new Rotate(0, new Point3D(1,1,1)); - boatAssets.getTransforms().add(animationRotate); - - return new BoatModel(boatAssets, new AnimationTimer() { - - private double rotation = 0; - private Rotate rotate = animationRotate; - - @Override - public void handle(long now) { - rotation += 0.5; - rotate.setAngle(rotation); - } - }, boatType); - } - public static BoatModel boatGameView(BoatMeshType boatType, Color primaryColour) { Group boatAssets = getUnmodifiedBoatModel(boatType, primaryColour); boatAssets.getTransforms().setAll( diff --git a/src/main/resources/css/LobbyView.css b/src/main/resources/css/LobbyView.css index 22871381..398f8eea 100644 --- a/src/main/resources/css/LobbyView.css +++ b/src/main/resources/css/LobbyView.css @@ -65,4 +65,8 @@ /*-fx-background-repeat: no-repeat;*/ /*-fx-background-size: cover;*/ -fx-background-color: dodgerblue; +} + +.tokenView { + -fx-cursor: hand; } \ No newline at end of file diff --git a/src/main/resources/css/TokenInfoDialog.css b/src/main/resources/css/TokenInfoDialog.css new file mode 100644 index 00000000..32e6723e --- /dev/null +++ b/src/main/resources/css/TokenInfoDialog.css @@ -0,0 +1,22 @@ +.text-area { + -fx-background-insets: 0; + -fx-background-color: transparent, white, transparent, white; +} + +.text-area .content { + -fx-background-color: transparent, white, transparent, white; +} + +.text-area:focused .content { + -fx-background-color: transparent, white, transparent, white; +} + +.text-area:focused { + -fx-highlight-fill: #7ecfff; +} + +.text-area .content { + -fx-padding: 10px; + -fx-text-fill: gray; + -fx-highlight-fill: #7ecfff; +} \ No newline at end of file diff --git a/src/main/resources/meshes/boatSTLs/waka_hull.stl b/src/main/resources/meshes/boatSTLs/waka_hull.stl new file mode 100644 index 00000000..91b09389 Binary files /dev/null and b/src/main/resources/meshes/boatSTLs/waka_hull.stl differ diff --git a/src/main/resources/meshes/boatSTLs/waka_mast.stl b/src/main/resources/meshes/boatSTLs/waka_mast.stl new file mode 100644 index 00000000..3911bad6 Binary files /dev/null and b/src/main/resources/meshes/boatSTLs/waka_mast.stl differ diff --git a/src/main/resources/meshes/boatSTLs/waka_sail.stl b/src/main/resources/meshes/boatSTLs/waka_sail.stl new file mode 100644 index 00000000..34f8d7de Binary files /dev/null and b/src/main/resources/meshes/boatSTLs/waka_sail.stl differ diff --git a/src/main/resources/views/LobbyView.fxml b/src/main/resources/views/LobbyView.fxml index 4356306c..6ca95c58 100644 --- a/src/main/resources/views/LobbyView.fxml +++ b/src/main/resources/views/LobbyView.fxml @@ -1,5 +1,13 @@ + + + + + + + + @@ -13,7 +21,7 @@ - + @@ -72,29 +80,152 @@ - - + + + - + - + + + + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -106,10 +237,10 @@ - - - - + + + + diff --git a/src/main/resources/views/cells/PlayerCell.fxml b/src/main/resources/views/cells/PlayerCell.fxml index 96d4c735..cfc26a09 100644 --- a/src/main/resources/views/cells/PlayerCell.fxml +++ b/src/main/resources/views/cells/PlayerCell.fxml @@ -1,5 +1,9 @@ + + + + @@ -8,33 +12,30 @@ - + + - - + + - + - - + + - + - + - + diff --git a/src/main/resources/views/dialogs/PopupDialog.fxml b/src/main/resources/views/dialogs/PopupDialog.fxml index 00574bc4..657a9c95 100644 --- a/src/main/resources/views/dialogs/PopupDialog.fxml +++ b/src/main/resources/views/dialogs/PopupDialog.fxml @@ -1,6 +1,11 @@ - + + + + + + @@ -9,6 +14,7 @@ +