diff --git a/src/main/java/seng302/gameServer/GameState.java b/src/main/java/seng302/gameServer/GameState.java index c5317fa6..be7039fa 100644 --- a/src/main/java/seng302/gameServer/GameState.java +++ b/src/main/java/seng302/gameServer/GameState.java @@ -47,6 +47,7 @@ public class GameState implements Runnable { private static final Double BOUNCE_DISTANCE_MARK = 20.0; public static final Double BOUNCE_DISTANCE_YACHT = 30.0; private static final Double COLLISION_VELOCITY_PENALTY = 0.3; + private static final Integer VELOCITY_BOOST_MULTIPLIER = 2; private static Long previousUpdateTime; public static Double windDirection; @@ -453,8 +454,7 @@ public class GameState implements Runnable { Double maxBoatSpeed = GeoUtility.knotsToMMS(boatSpeedInKnots) * speedMultiplier; if (yacht.getPowerUp() != null) { if (yacht.getPowerUp().equals(TokenType.BOOST)) { - // TODO: 11/09/17 wmu16 CHANGE THIS TO MAGIC NUMBER - maxBoatSpeed *= 2; + maxBoatSpeed *= VELOCITY_BOOST_MULTIPLIER; } } diff --git a/src/main/java/seng302/model/ClientYacht.java b/src/main/java/seng302/model/ClientYacht.java index 89715852..b1996333 100644 --- a/src/main/java/seng302/model/ClientYacht.java +++ b/src/main/java/seng302/model/ClientYacht.java @@ -12,9 +12,13 @@ import javafx.beans.property.ReadOnlyIntegerProperty; import javafx.beans.property.ReadOnlyIntegerWrapper; import javafx.beans.property.ReadOnlyLongProperty; import javafx.beans.property.ReadOnlyLongWrapper; +import javafx.beans.value.ObservableObjectValue; +import javafx.collections.FXCollections; import javafx.scene.paint.Color; +import jdk.nashorn.internal.objects.annotations.Function; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import seng302.model.token.TokenType; /** * Yacht class for the racing boat.

Class created to store more variables (eg. boat statuses) @@ -34,6 +38,12 @@ public class ClientYacht extends Observable { void notifyRounding(ClientYacht yacht, int legNumber); } + @FunctionalInterface + public interface PowerUpListener { + + void notifyPowerUp(ClientYacht yacht, TokenType tokenType); + } + private Logger logger = LoggerFactory.getLogger(ClientYacht.class); @@ -44,6 +54,7 @@ public class ClientYacht extends Observable { private String boatName; private String country; private Integer position; + private TokenType powerUp; private Long estimateTimeAtFinish; private Boolean sailIn = false; @@ -58,6 +69,7 @@ public class ClientYacht extends Observable { private List locationListeners = new ArrayList<>(); private List markRoundingListeners = new ArrayList<>(); + private List powerUpListeners = new ArrayList<>(); private ReadOnlyDoubleWrapper velocityProperty = new ReadOnlyDoubleWrapper(); private ReadOnlyLongWrapper timeTillNextProperty = new ReadOnlyLongWrapper(); private ReadOnlyLongWrapper timeSinceLastMarkProperty = new ReadOnlyLongWrapper(); @@ -199,6 +211,17 @@ public class ClientYacht extends Observable { this.position = position; } + public void setPowerUp(TokenType tokenType) { + this.powerUp = tokenType; + for (PowerUpListener listener : powerUpListeners) { + listener.notifyPowerUp(this, tokenType); + } + } + + public TokenType getPowerUp() { + return powerUp; + } + public void toggleSail() { sailIn = !sailIn; } @@ -268,6 +291,10 @@ public class ClientYacht extends Observable { markRoundingListeners.add(listener); } + public void addPowerUpListener(PowerUpListener listener) { + powerUpListeners.add(listener); + } + public void removeMarkRoundingListener(MarkRoundingListener listener) { markRoundingListeners.remove(listener); } diff --git a/src/main/java/seng302/visualiser/GameClient.java b/src/main/java/seng302/visualiser/GameClient.java index 5cab5040..10a682fa 100644 --- a/src/main/java/seng302/visualiser/GameClient.java +++ b/src/main/java/seng302/visualiser/GameClient.java @@ -37,6 +37,7 @@ import seng302.model.stream.parser.RaceStatusData; import seng302.model.stream.parser.YachtEventData; import seng302.model.stream.xml.parser.RaceXMLData; import seng302.model.stream.xml.parser.RegattaXMLData; +import seng302.model.token.TokenType; import seng302.utilities.Sounds; import seng302.utilities.StreamParser; import seng302.utilities.XMLGenerator; @@ -245,7 +246,7 @@ public class GameClient { break; case YACHT_EVENT_CODE: - displayYachtEvent(StreamParser.extractYachtEventCode(packet)); + processYachtEvent(StreamParser.extractYachtEventCode(packet)); break; case CHATTER_TEXT: @@ -408,19 +409,25 @@ public class GameClient { * * @param yachtEventData The YachtEvent data packet */ - private void displayYachtEvent(YachtEventData yachtEventData) { + private void processYachtEvent(YachtEventData yachtEventData) { if (yachtEventData.getEventId() == YachtEventType.COLLISION.getCode()) { showCollisionAlert(yachtEventData); - } else if (yachtEventData.getEventId() == YachtEventType.TOKEN_VELOCITY.getCode()) { - showPickUp(yachtEventData); - } else if (yachtEventData.getEventId() == YachtEventType.TOKEN_BUMPER.getCode()) { - showPickUp(yachtEventData); - } else if (yachtEventData.getEventId() == YachtEventType.TOKEN_HANDLING.getCode()) { - showPickUp(yachtEventData); - } else if (yachtEventData.getEventId() == YachtEventType.TOKEN_RANDOM.getCode()) { - showPickUp(yachtEventData); - } else if (yachtEventData.getEventId() == YachtEventType.TOKEN_WIND_WALKER.getCode()) { - showPickUp(yachtEventData); + } else { + TokenType tokenType = null; + if (yachtEventData.getEventId() == YachtEventType.TOKEN_VELOCITY.getCode()) { + tokenType = TokenType.BOOST; + } else if (yachtEventData.getEventId() == YachtEventType.TOKEN_BUMPER.getCode()) { + tokenType = TokenType.BUMPER; + } else if (yachtEventData.getEventId() == YachtEventType.TOKEN_HANDLING.getCode()) { + tokenType = TokenType.HANDLING; + } else if (yachtEventData.getEventId() == YachtEventType.TOKEN_RANDOM.getCode()) { + tokenType = TokenType.RANDOM; + } else if (yachtEventData.getEventId() == YachtEventType.TOKEN_WIND_WALKER.getCode()) { + tokenType = TokenType.WIND_WALKER; + } + + showTokenPickUp(tokenType); + allBoatsMap.get(yachtEventData.getSubjectId().intValue()).setPowerUp(tokenType); } } @@ -437,7 +444,7 @@ public class GameClient { } // TODO: 11/09/17 wmu16 - Add in functionality to viually indicate a pickup to a user - private void showPickUp(YachtEventData yachtEventData) { + private void showTokenPickUp(TokenType tokenType) { Sounds.playTokenPickupSound(); } diff --git a/src/main/java/seng302/visualiser/controllers/RaceViewController.java b/src/main/java/seng302/visualiser/controllers/RaceViewController.java index 2ac06dfb..15c3d8ec 100644 --- a/src/main/java/seng302/visualiser/controllers/RaceViewController.java +++ b/src/main/java/seng302/visualiser/controllers/RaceViewController.java @@ -20,6 +20,8 @@ import javafx.collections.ObservableList; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.geometry.Point2D; +import javafx.scene.Group; +import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.SubScene; import javafx.scene.chart.LineChart; @@ -47,10 +49,12 @@ import javafx.scene.text.Text; import javafx.stage.Stage; import javafx.stage.StageStyle; import seng302.model.ClientYacht; +import seng302.model.ClientYacht.PowerUpListener; import seng302.model.RaceState; import seng302.model.mark.CompoundMark; import seng302.model.mark.Mark; import seng302.model.stream.xml.parser.RaceXMLData; +import seng302.model.token.TokenType; import seng302.utilities.Sounds; import seng302.visualiser.GameView3D; import seng302.visualiser.controllers.annotations.ImportantAnnotationController; @@ -60,6 +64,8 @@ import seng302.visualiser.controllers.dialogs.FinishDialogController; import seng302.visualiser.fxObjects.ChatHistory; import seng302.visualiser.fxObjects.assets_2D.WindArrow; import seng302.visualiser.fxObjects.assets_3D.BoatObject; +import seng302.visualiser.fxObjects.assets_3D.ModelFactory; +import seng302.visualiser.fxObjects.assets_3D.ModelType; /** * Controller class that manages the display of a race @@ -110,6 +116,8 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel private Label windSpeedLabel; @FXML private Label positionLabel, boatSpeedLabel, boatHeadingLabel; + @FXML + private ImageView velocityIcon, handlingIcon, windWalkerIcon, bumperIcon; //Race Data private Map participants; @@ -222,6 +230,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel return finishScreenDialog; } + public void loadRace ( Map participants, RaceXMLData raceData, RaceState raceState, ClientYacht player) { @@ -241,6 +250,25 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel } }); + player.addPowerUpListener((yacht, tokenType) -> { + if (yacht == player) { + switch (tokenType) { + case BOOST: + velocityIcon.setVisible(true); + break; + case HANDLING: + handlingIcon.setVisible(true); + break; + case WIND_WALKER: + windWalkerIcon.setVisible(true); + break; + case BUMPER: + bumperIcon.setVisible(true); + break; + } + } + }); + updateOrder(raceState.getPlayerPositions()); gameView = new GameView3D(); // gameView.setFrameRateFXText(fpsDisplay); @@ -279,6 +307,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel }); } + /** * The important annotations have been changed, update this view * diff --git a/src/main/resources/views/RaceView.fxml b/src/main/resources/views/RaceView.fxml index a2c22e09..03728bde 100644 --- a/src/main/resources/views/RaceView.fxml +++ b/src/main/resources/views/RaceView.fxml @@ -1,5 +1,14 @@ + + + + + + + + + @@ -14,6 +23,7 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +