diff --git a/racevisionGame/src/main/java/mock/app/Event.java b/racevisionGame/src/main/java/mock/app/Event.java index 11553a07..3814fa80 100644 --- a/racevisionGame/src/main/java/mock/app/Event.java +++ b/racevisionGame/src/main/java/mock/app/Event.java @@ -77,7 +77,7 @@ public class Event { String boatsXMLFile = "mock/mockXML/boatTest.xml"; String regattaXMLFile = "mock/mockXML/regattaTest.xml"; switch (mapIndex){ - case 0:raceXMLFile = "mock/mockXML/raceSixPlayers.xml"; + case 0:raceXMLFile = "mock/mockXML/ac35MapLayout.xml"; break; case 1:raceXMLFile = "mock/mockXML/oMapLayout.xml"; break; @@ -90,13 +90,12 @@ public class Event { boatsXMLFile = "mock/mockXML/boatTutorial.xml"; regattaXMLFile = "mock/mockXML/regattaTutorial.xml"; break; - default: raceXMLFile = "mock/mockXML/raceSixPlayers.xml"; + default: raceXMLFile = "mock/mockXML/ac35MapLayout.xml"; } if (singlePlayer) { - raceXMLFile = "mock/mockXML/raceSinglePlayer.xml"; boatsXMLFile = "mock/mockXML/boatsSinglePlayer.xml"; } diff --git a/racevisionGame/src/main/java/mock/model/MockRace.java b/racevisionGame/src/main/java/mock/model/MockRace.java index a0140189..969d9d94 100644 --- a/racevisionGame/src/main/java/mock/model/MockRace.java +++ b/racevisionGame/src/main/java/mock/model/MockRace.java @@ -109,8 +109,6 @@ public class MockRace extends RaceState { colliderRegistry.addCollider(mark.getMark1()); if(mark.getMark2() != null) colliderRegistry.addCollider(mark.getMark2()); } - - this.colliderRegistry.addAllColliders(boats); } @@ -133,9 +131,9 @@ public class MockRace extends RaceState { this.boats.add(mockBoat); this.activeObserverCommands.put(boat.getSourceID(), new ActiveObserverCommand()); + this.colliderRegistry.addCollider(mockBoat); getRaceDataSource().incrementSequenceNumber(); - } /** diff --git a/racevisionGame/src/main/java/shared/model/Boat.java b/racevisionGame/src/main/java/shared/model/Boat.java index 99871678..a094bcc9 100644 --- a/racevisionGame/src/main/java/shared/model/Boat.java +++ b/racevisionGame/src/main/java/shared/model/Boat.java @@ -418,7 +418,7 @@ public class Boat extends Collider { @Override public boolean rayCast(Boat boat) { if(boat != this) { - return rayCast(boat, 15); + return rayCast(boat, 50); } else return false; } diff --git a/racevisionGame/src/main/java/shared/model/Constants.java b/racevisionGame/src/main/java/shared/model/Constants.java index 6d1c35a8..e62a2e04 100644 --- a/racevisionGame/src/main/java/shared/model/Constants.java +++ b/racevisionGame/src/main/java/shared/model/Constants.java @@ -28,7 +28,7 @@ public class Constants { * Frame periods are multiplied by this to get the amount of time a single frame represents. * E.g., frame period = 20ms, scale = 5, frame represents 20 * 5 = 100ms, and so boats are simulated for 100ms, even though only 20ms actually occurred. */ - public static final int RaceTimeScale = 2; + public static final int RaceTimeScale = 1; /** * The race pre-start time, in milliseconds. 30 seconds. diff --git a/racevisionGame/src/main/java/shared/model/MarkRoundingSequence.java b/racevisionGame/src/main/java/shared/model/MarkRoundingSequence.java index de11c170..2b8fd823 100644 --- a/racevisionGame/src/main/java/shared/model/MarkRoundingSequence.java +++ b/racevisionGame/src/main/java/shared/model/MarkRoundingSequence.java @@ -17,8 +17,9 @@ public class MarkRoundingSequence { /** * For each leg, mark rounding information. + * Maps between leg number and rounding data. */ - private Map roundingPoints; + private Map roundingPoints; @@ -34,7 +35,7 @@ public class MarkRoundingSequence { * @return Rounding points for leg. */ public MarkRoundingData getRoundingData(Leg leg) { - return roundingPoints.get(leg); + return roundingPoints.get(leg.getLegNumber()); } @@ -139,7 +140,7 @@ public class MarkRoundingSequence { roundingData.setRoundCheck2Halfway(roundCheck2Halfway); - this.roundingPoints.put(currentLeg, roundingData); + this.roundingPoints.put(currentLeg.getLegNumber(), roundingData); //Rounding points: diff --git a/racevisionGame/src/main/java/visualiser/Controllers/RaceViewController.java b/racevisionGame/src/main/java/visualiser/Controllers/RaceViewController.java index 54328137..d170ed4c 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/RaceViewController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/RaceViewController.java @@ -433,7 +433,7 @@ public class RaceViewController extends Controller { // Track player boat with camera viewSubjects.add(boatModel); Platform.runLater(() -> { - view3D.trackSubject(boatModel); + view3D.trackSubject(boatModel, 0); view3D.setThirdPerson(); }); @@ -574,7 +574,12 @@ public class RaceViewController extends Controller { // Bind zooming to scrolling view3D.setOnScroll(e -> { - view3D.updateDistance(e.getDeltaY()); + //view3D.updateDistance(e.getDeltaY()); + if (e.getDeltaY() > 0) { + view3D.zoomIn(); + } else { + view3D.zoomOut(); + } }); // Bind zooming to keypress (Z/X default) diff --git a/racevisionGame/src/main/java/visualiser/Controllers/TitleController.java b/racevisionGame/src/main/java/visualiser/Controllers/TitleController.java index 4f39ea65..ec27d068 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/TitleController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/TitleController.java @@ -1,17 +1,33 @@ package visualiser.Controllers; +import com.interactivemesh.jfx.importer.stl.StlMeshImporter; +import javafx.animation.AnimationTimer; +import javafx.application.Platform; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; import javafx.fxml.FXML; -import javafx.scene.control.Label; +import javafx.scene.AmbientLight; +import javafx.scene.PointLight; +import javafx.scene.control.Button; import javafx.scene.control.RadioButton; +import javafx.scene.control.ToggleGroup; import javafx.scene.image.Image; import javafx.scene.image.ImageView; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.GridPane; import javafx.scene.layout.Pane; import javafx.scene.media.AudioClip; import javafx.scene.media.Media; import javafx.scene.media.MediaPlayer; +import javafx.scene.paint.Color; +import javafx.scene.shape.MeshView; import javafx.stage.Modality; import mock.exceptions.EventConstructionException; import visualiser.app.App; +import visualiser.layout.SeaSurface; +import visualiser.layout.SkyBox; +import visualiser.layout.Subject3D; +import visualiser.layout.View3D; import java.io.File; import java.io.IOException; @@ -28,11 +44,74 @@ import java.util.logging.Logger; * the game. */ public class TitleController extends Controller { + private @FXML AnchorPane titleWrapper; private @FXML RadioButton dayModeRD; private @FXML RadioButton nightModeRD; - private @FXML Label tutorialLabel; - private @FXML Pane menuPane; + private @FXML Button tutorialButton; private @FXML ImageView imgSun; + private @FXML GridPane view3DContainer; + private ToggleGroup toggleGroup = new ToggleGroup(); + + public void initialize() { + dayModeRD.setToggleGroup(toggleGroup); + nightModeRD.setToggleGroup(toggleGroup); + + AmbientLight ambientLight = new AmbientLight(Color.web("#CCCCFF")); + ambientLight.setTranslateX(250); + ambientLight.setTranslateZ(210); + ambientLight.setLightOn(true); + + PointLight pointLight = new PointLight(Color.web("#AAAAFF")); + pointLight.setTranslateX(250); + pointLight.setTranslateZ(210); + pointLight.setLightOn(true); + + ObservableList subjects = FXCollections.observableArrayList(); + View3D view3D = new View3D(); + view3D.addAmbientLight(ambientLight); + view3D.addPointLight(pointLight); + view3D.setDistance(10); + view3D.setPitch(5); + view3D.setItems(subjects); + + SkyBox skyBox = new SkyBox(750,200,250,0,250); + subjects.addAll(skyBox.getSkyBoxPlanes()); + + SeaSurface seaSurface = new SeaSurface(750, 200); + seaSurface.setX(250); + seaSurface.setZ(250); + subjects.add(seaSurface); + + URL asset = RaceViewController.class.getClassLoader().getResource("assets/V1.2 Complete Boat.stl"); + StlMeshImporter importer = new StlMeshImporter(); + importer.read(asset); + Subject3D boat = new Subject3D(new MeshView(importer.getImport()), 0); + + double radius = 100; + boat.setX(0); + boat.setZ(radius); + boat.setScale(0.1); + + subjects.add(boat); + view3D.trackSubject(boat, -45); + + view3DContainer.add(view3D, 0, 0); + + AnimationTimer loop = new AnimationTimer() { + double angle = -90; + double offset = 0.05; + @Override + public void handle(long now) { + boat.setX(radius * Math.cos(angle * Math.PI/180)); + boat.setZ(radius * Math.sin(angle * Math.PI/180)); + boat.setHeading(-angle); + angle += offset; + } + }; + loop.start(); + + titleWrapper.getStylesheets().add("/css/dayMode.css"); + } /** * Method called when the 'host a game' button is pressed. @@ -58,10 +137,7 @@ public class TitleController extends Controller { */ public void setDayMode(){ dayModeRD.getScene().getStylesheets().clear(); - menuPane.getStylesheets().clear(); - imgSun.setImage(new Image(getClass().getResource("/visualiser/images/sun.png").toExternalForm())); dayModeRD.getScene().getStylesheets().add("/css/dayMode.css"); - menuPane.setStyle("-fx-background-color: #6be6ff;"); nightModeRD.setSelected(false); App.dayMode = true; } @@ -71,10 +147,7 @@ public class TitleController extends Controller { */ public void setNightMode(){ nightModeRD.getScene().getStylesheets().clear(); - menuPane.getStylesheets().clear(); - imgSun.setImage(new Image(getClass().getResource("/visualiser/images/sunsleep.png").toExternalForm())); nightModeRD.getScene().getStylesheets().add("/css/nightMode.css"); - menuPane.setStyle("-fx-background-color: #1f2c60;"); dayModeRD.setSelected(false); App.dayMode = false; } diff --git a/racevisionGame/src/main/java/visualiser/app/App.java b/racevisionGame/src/main/java/visualiser/app/App.java index c704ff49..49c1712d 100644 --- a/racevisionGame/src/main/java/visualiser/app/App.java +++ b/racevisionGame/src/main/java/visualiser/app/App.java @@ -134,7 +134,6 @@ public class App extends Application { FXMLLoader loader = new FXMLLoader(getClass().getResource ("/visualiser/scenes/title.fxml")); Parent root = loader.load(); - stage.setResizable(false); Scene scene = new Scene(root); stage.setTitle("The Boat Game - Burgers & Boats"); stage.getIcons().add(new Image(getClass().getClassLoader().getResourceAsStream("images/SailIcon.png"))); diff --git a/racevisionGame/src/main/java/visualiser/layout/View3D.java b/racevisionGame/src/main/java/visualiser/layout/View3D.java index 8501cdaa..8bc92b2b 100644 --- a/racevisionGame/src/main/java/visualiser/layout/View3D.java +++ b/racevisionGame/src/main/java/visualiser/layout/View3D.java @@ -174,7 +174,7 @@ public class View3D extends Pane { PickResult result = e.getPickResult(); if(result != null && result.getIntersectedNode() != null && result.getIntersectedNode() instanceof Shape3D) { untrackSubject(); - trackSubject(shapeMap.get(result.getIntersectedNode())); + trackSubject(shapeMap.get(result.getIntersectedNode()), 0); setThirdPerson(); } }); @@ -215,15 +215,16 @@ public class View3D extends Pane { /** * Set camera to follow the selected subject * @param subject to track + * @param yaw to add to boat heading */ - public void trackSubject(Subject3D subject) { + public void trackSubject(Subject3D subject, double yaw) { target.set(subject); this.trackBoat = new AnimationTimer() { @Override public void handle(long now) { updatePivot(target.get().getPosition()); - setYaw(target.get().getHeading().getAngle()); + setYaw(target.get().getHeading().getAngle() + yaw); } }; trackBoat.start(); @@ -268,8 +269,10 @@ public class View3D extends Pane { public void updateDistance(double delta) { double newDistance = -this.distance.getZ() + delta; if (target.get() == null){ - if (newDistance > MAX_ZOOM_LIMIT){ + if (newDistance > MAX_ZOOM_LIMIT) { setDistance(MAX_ZOOM_LIMIT); + } else if (newDistance <= ZOOM_IN_LIMIT) { + setDistance(ZOOM_IN_LIMIT); } else { setDistance(newDistance); } @@ -372,4 +375,4 @@ public class View3D extends Pane { public void addPointLight(PointLight pointLight) { this.world.getChildren().add(pointLight); } -} \ No newline at end of file +} diff --git a/racevisionGame/src/main/java/visualiser/model/ResizableRaceCanvas.java b/racevisionGame/src/main/java/visualiser/model/ResizableRaceCanvas.java index b6f41a07..c46651e3 100644 --- a/racevisionGame/src/main/java/visualiser/model/ResizableRaceCanvas.java +++ b/racevisionGame/src/main/java/visualiser/model/ResizableRaceCanvas.java @@ -605,7 +605,7 @@ public class ResizableRaceCanvas extends ResizableCanvas { //Prepare to draw. gc.setLineWidth(1); - gc.setFill(Color.DEEPSKYBLUE); + gc.setFill(Color.web("#f1f1d4")); //Calculate the screen coordinates of the boundary. diff --git a/racevisionGame/src/main/resources/css/nightMode.css b/racevisionGame/src/main/resources/css/nightMode.css index 514893aa..098c2931 100644 --- a/racevisionGame/src/main/resources/css/nightMode.css +++ b/racevisionGame/src/main/resources/css/nightMode.css @@ -102,3 +102,236 @@ -fx-border-color: #012256; -fx-border-width: 3; } + +/* Title menu buttons */ +#hostAGameBtn { + -fx-background-image: url("/visualiser/images/hostAGameBtn.png"); + -fx-background-size: 150px; + -fx-background-repeat: no-repeat; + -fx-background-position: center center; + -fx-focus-color: transparent; + -fx-background-color: transparent; +} + +#hostAGameBtn:pressed { + -fx-background-image: url("/visualiser/images/hostAGameBtnPressed.png"); + -fx-background-size: 150px; + -fx-background-repeat: no-repeat; + -fx-background-position: center center; + -fx-focus-color: transparent; + -fx-background-color: transparent; +} + +#btnJoin { + -fx-background-image: url("/visualiser/images/JoinAGameBtn.png"); + -fx-background-size: 150px; + -fx-background-repeat: no-repeat; + -fx-background-position: center center; + -fx-focus-color: transparent; + -fx-background-color: transparent; +} + +#btnJoin:pressed { + -fx-background-image: url("/visualiser/images/JoinAGameBtnPressed.png"); + -fx-background-size: 150px; + -fx-background-repeat: no-repeat; + -fx-background-position: center center; + -fx-focus-color: transparent; + -fx-background-color: transparent; +} + +#tutorialButton { + -fx-background-image: url("/visualiser/images/howToPlayBtn.png"); + -fx-background-size: 150px; + -fx-background-repeat: no-repeat; + -fx-background-position: center center; + -fx-focus-color: transparent; + -fx-background-color: transparent; +} + +#tutorialButton:pressed { + -fx-background-image: url("/visualiser/images/howToPlayBtnPressed.png"); + -fx-background-size: 150px; + -fx-background-repeat: no-repeat; + -fx-background-position: center center; + -fx-focus-color: transparent; + -fx-background-color: transparent; +} + +#controlsBtn { + -fx-background-image: url("/visualiser/images/controlsBtn.png"); + -fx-background-size: 150px; + -fx-background-repeat: no-repeat; + -fx-background-position: center center; + -fx-focus-color: transparent; + -fx-background-color: transparent; +} + +#controlsBtn:pressed { + -fx-background-image: url("/visualiser/images/controlsBtnPressed.png"); + -fx-background-size: 150px; + -fx-background-repeat: no-repeat; + -fx-background-position: center center; + -fx-focus-color: transparent; + -fx-background-color: transparent; +} + +/* host game lobby buttons */ + +#hostGameBtn { + -fx-background-image: url("/visualiser/images/startGameBtn.png"); + -fx-background-size: 150px; + -fx-background-repeat: no-repeat; + -fx-background-position: center center; + -fx-focus-color: transparent; + -fx-background-color: transparent; +} + +#hostGameBtn:pressed { + -fx-background-image: url("/visualiser/images/startGameBtnPressed.png"); + -fx-background-size: 150px; + -fx-background-repeat: no-repeat; + -fx-background-position: center center; + -fx-focus-color: transparent; + -fx-background-color: transparent; +} + +#mainMenuBtn { + -fx-background-image: url("/visualiser/images/mainMenuBtn.png"); + -fx-background-size: 115px; + -fx-background-repeat: no-repeat; + -fx-background-position: center center; + -fx-focus-color: transparent; + -fx-background-color: transparent; +} + + +#mainMenuBtn:pressed { + -fx-background-image: url("/visualiser/images/mainMenuBtnPressed.png"); + -fx-background-size: 115px; + -fx-background-repeat: no-repeat; + -fx-background-position: center center; + -fx-focus-color: transparent; + -fx-background-color: transparent; +} + +/* match browsing lobby buttons */ + +#addBtn { + -fx-background-image: url("/visualiser/images/addBtn.png"); + -fx-background-size: 115px; + -fx-background-repeat: no-repeat; + -fx-background-position: center center; + -fx-focus-color: transparent; + -fx-background-color: transparent; +} + +#addBtn:pressed { + -fx-background-image: url("/visualiser/images/addBtnPressed.png"); + -fx-background-size: 115px; + -fx-background-repeat: no-repeat; + -fx-background-position: center center; + -fx-focus-color: transparent; + -fx-background-color: transparent; +} + +#refreshBtn { + -fx-background-image: url("/visualiser/images/refreshBtn.png"); + -fx-background-size: 115px; + -fx-background-repeat: no-repeat; + -fx-background-position: center center; + -fx-focus-color: transparent; + -fx-background-color: transparent; +} + +#refreshBtn:pressed { + -fx-background-image: url("/visualiser/images/refreshBtnPressed.png"); + -fx-background-size: 115px; + -fx-background-repeat: no-repeat; + -fx-background-position: center center; + -fx-focus-color: transparent; + -fx-background-color: transparent; +} + +#refreshBtn { + -fx-background-image: url("/visualiser/images/refreshBtn.png"); + -fx-background-size: 115px; + -fx-background-repeat: no-repeat; + -fx-background-position: center center; + -fx-focus-color: transparent; + -fx-background-color: transparent; +} + +#joinGameBtn { + -fx-background-image: url("/visualiser/images/participateBtn.png"); + -fx-background-size: 115px; + -fx-background-repeat: no-repeat; + -fx-background-position: center center; + -fx-focus-color: transparent; + -fx-background-color: transparent; +} + +#joinGameBtn:pressed { + -fx-background-image: url("/visualiser/images/participateBtnPressed.png"); + -fx-background-size: 115px; + -fx-background-repeat: no-repeat; + -fx-background-position: center center; + -fx-focus-color: transparent; + -fx-background-color: transparent; +} + +#spectateButton { + -fx-background-image: url("/visualiser/images/spectateBtn.png"); + -fx-background-size: 115px; + -fx-background-repeat: no-repeat; + -fx-background-position: center center; + -fx-focus-color: transparent; + -fx-background-color: transparent; +} + +#spectateButton:pressed { + -fx-background-image: url("/visualiser/images/spectateBtnPressed.png"); + -fx-background-size: 115px; + -fx-background-repeat: no-repeat; + -fx-background-position: center center; + -fx-focus-color: transparent; + -fx-background-color: transparent; +} + +/* in-game lobby buttons */ + +#quitBtn { + -fx-background-image: url("/visualiser/images/quitBtn.png"); + -fx-background-size: 115px; + -fx-background-repeat: no-repeat; + -fx-background-position: center center; + -fx-focus-color: transparent; + -fx-background-color: transparent; +} + +#quitBtn:pressed { + -fx-background-image: url("/visualiser/images/quitBtnPressed.png"); + -fx-background-size: 115px; + -fx-background-repeat: no-repeat; + -fx-background-position: center center; + -fx-focus-color: transparent; + -fx-background-color: transparent; +} + +#startButton { + -fx-background-image: url("/visualiser/images/startBtn.png"); + -fx-background-size: 115px; + -fx-background-repeat: no-repeat; + -fx-background-position: center center; + -fx-focus-color: transparent; + -fx-background-color: transparent; +} + +#startButton:pressed { + -fx-background-image: url("/visualiser/images/startBtnPressed.png"); + -fx-background-size: 115px; + -fx-background-repeat: no-repeat; + -fx-background-position: center center; + -fx-focus-color: transparent; + -fx-background-color: transparent; +} diff --git a/racevisionGame/src/main/resources/mock/mockXML/raceSixPlayers.xml b/racevisionGame/src/main/resources/mock/mockXML/ac35MapLayout.xml similarity index 76% rename from racevisionGame/src/main/resources/mock/mockXML/raceSixPlayers.xml rename to racevisionGame/src/main/resources/mock/mockXML/ac35MapLayout.xml index 6ae04ef8..6931f080 100644 --- a/racevisionGame/src/main/resources/mock/mockXML/raceSixPlayers.xml +++ b/racevisionGame/src/main/resources/mock/mockXML/ac35MapLayout.xml @@ -37,16 +37,16 @@ - - - - - - - - - - - + + + + + + + + + + + diff --git a/racevisionGame/src/main/resources/mock/mockXML/raceSinglePlayer.xml b/racevisionGame/src/main/resources/mock/mockXML/raceSinglePlayer.xml deleted file mode 100644 index c4efcd17..00000000 --- a/racevisionGame/src/main/resources/mock/mockXML/raceSinglePlayer.xml +++ /dev/null @@ -1,51 +0,0 @@ - - - 5326 - FLEET - RACE_CREATION_TIME - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/racevisionGame/src/main/resources/mock/mockXML/raceThreePlayers.xml b/racevisionGame/src/main/resources/mock/mockXML/raceThreePlayers.xml deleted file mode 100644 index c4efcd17..00000000 --- a/racevisionGame/src/main/resources/mock/mockXML/raceThreePlayers.xml +++ /dev/null @@ -1,51 +0,0 @@ - - - 5326 - FLEET - RACE_CREATION_TIME - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/racevisionGame/src/main/resources/visualiser/scenes/gameLobby.fxml b/racevisionGame/src/main/resources/visualiser/scenes/gameLobby.fxml index b0c5dc2e..964b23c4 100644 --- a/racevisionGame/src/main/resources/visualiser/scenes/gameLobby.fxml +++ b/racevisionGame/src/main/resources/visualiser/scenes/gameLobby.fxml @@ -1,5 +1,10 @@ + + + + + @@ -9,11 +14,11 @@ - + - + - - - - - - + +