From c47e5b145019010b5a29629aaaa61a4fa34bc89c Mon Sep 17 00:00:00 2001 From: William Muir Date: Sat, 23 Sep 2017 16:31:18 +1200 Subject: [PATCH] Boat now changes color when it is bumped for a time ClientYacht: Added ColorChangeListener from GameView3D to re paint the boat when the color attribute is changed #story[1293] --- .../java/seng302/gameServer/GameState.java | 11 +++--- src/main/java/seng302/model/ClientYacht.java | 24 +++++++++++-- .../java/seng302/visualiser/GameClient.java | 34 ++++++++++++++----- .../java/seng302/visualiser/GameView3D.java | 24 ++++++++++--- 4 files changed, 72 insertions(+), 21 deletions(-) diff --git a/src/main/java/seng302/gameServer/GameState.java b/src/main/java/seng302/gameServer/GameState.java index 496c7cb9..150fd652 100644 --- a/src/main/java/seng302/gameServer/GameState.java +++ b/src/main/java/seng302/gameServer/GameState.java @@ -60,7 +60,7 @@ public class GameState implements Runnable { //Powerup Constants private static final Integer VELOCITY_BOOST_MULTIPLIER = 2; private static final Integer HANDLING_BOOST_MULTIPLIER = 2; - private static final Long BUMPER_DISABLE_TIME = 5_000L; + public static final Long BUMPER_DISABLE_TIME = 5_000L; private static Long previousUpdateTime; public static Double windDirection; @@ -359,8 +359,8 @@ public class GameState implements Runnable { //Get a random token location with random type Token token = allTokens.get(random.nextInt(allTokens.size())); -// token.assignRandomType(); - token.assignType(TokenType.BUMPER); + token.assignRandomType(); +// token.assignType(TokenType.BUMPER); logger.debug("Spawned token of type " + token.getTokenType()); @@ -386,8 +386,7 @@ public class GameState implements Runnable { updateVelocity(yacht); yacht.runAutoPilot(); yacht.updateLocation(timeInterval); - preformTokenUpdates( - yacht); //This update must be done before collision. Sorry sorta hacky rn. + preformTokenUpdates(yacht); //This update must be done before collision. Sorta hacky checkCollision(yacht); if (yacht.getBoatStatus() != BoatStatus.FINISHED) { checkForLegProgression(yacht); @@ -424,7 +423,7 @@ public class GameState implements Runnable { boatTempShutDown(collidedYacht); notifyMessageListeners(MessageFactory.makePowerDownMessage(yacht)); notifyMessageListeners( - MessageFactory.makeStatusEffectMessage(yacht, powerUp)); + MessageFactory.makeStatusEffectMessage(collidedYacht, powerUp)); } break; } diff --git a/src/main/java/seng302/model/ClientYacht.java b/src/main/java/seng302/model/ClientYacht.java index f626db30..0b5449ae 100644 --- a/src/main/java/seng302/model/ClientYacht.java +++ b/src/main/java/seng302/model/ClientYacht.java @@ -39,17 +39,21 @@ public class ClientYacht extends Observable { void notifyRounding(ClientYacht yacht, int legNumber); } + @FunctionalInterface + public interface ColorChangeListener { + + void notifyColorChange(ClientYacht yacht); + } + //This notifies RaceViewController so it can display icon - wmu16 @FunctionalInterface public interface PowerUpListener { - void notifyPowerUp(ClientYacht yacht, TokenType tokenType); } //This notifies RaceViewController so it can remove token icon - wmu16 @FunctionalInterface public interface PowerDownListener { - void notifyPowerDown(ClientYacht yacht); } @@ -82,6 +86,7 @@ public class ClientYacht extends Observable { private List markRoundingListeners = new ArrayList<>(); private List powerUpListeners = new ArrayList<>(); private List powerDownListeners = new ArrayList<>(); + private List colorChangeListeners = new ArrayList<>(); private ReadOnlyDoubleWrapper velocityProperty = new ReadOnlyDoubleWrapper(); private ReadOnlyLongWrapper timeTillNextProperty = new ReadOnlyLongWrapper(); @@ -224,6 +229,9 @@ public class ClientYacht extends Observable { this.position = position; } + /** + * Powers down the boat and notifies the raceViewController to display + */ public void powerDown() { this.powerUp = null; for (PowerDownListener listener : powerDownListeners) { @@ -231,6 +239,11 @@ public class ClientYacht extends Observable { } } + /** + * powers up the boat and notifies the raceViewController to display + * + * @param tokenType The type of token that this boat is being powered up with + */ public void setPowerUp(TokenType tokenType) { this.powerUp = tokenType; for (PowerUpListener listener : powerUpListeners) { @@ -290,6 +303,9 @@ public class ClientYacht extends Observable { public void setColour(Color colour) { this.colour = colour; + for (ColorChangeListener listener : colorChangeListeners) { + listener.notifyColorChange(this); + } } @@ -319,6 +335,10 @@ public class ClientYacht extends Observable { powerDownListeners.add(listener); } + public void addColorChangeListener(ColorChangeListener listener) { + colorChangeListeners.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 9947719e..0e4b4a7a 100644 --- a/src/main/java/seng302/visualiser/GameClient.java +++ b/src/main/java/seng302/visualiser/GameClient.java @@ -10,6 +10,8 @@ import java.util.Date; import java.util.List; import java.util.Map; import java.util.TimeZone; +import java.util.Timer; +import java.util.TimerTask; import javafx.application.Platform; import javafx.collections.FXCollections; import javafx.collections.ObservableList; @@ -19,6 +21,7 @@ import javafx.scene.control.Alert.AlertType; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; import javafx.scene.layout.Pane; +import javafx.scene.paint.Color; import javafx.util.Pair; import seng302.gameServer.GameStages; import seng302.gameServer.GameState; @@ -413,12 +416,12 @@ public class GameClient { ClientYacht thisYacht = allBoatsMap.get(yachtEventData.getSubjectId().intValue()); if (yachtEventData.getEventId() == YachtEventType.COLLISION.getCode()) { - showCollisionAlert(yachtEventData); + showCollisionAlert(thisYacht); } else if (yachtEventData.getEventId() == YachtEventType.POWER_DOWN.getCode()) { thisYacht.powerDown(); Sounds.playTokenPickupSound(); // TODO: 23/09/17 This should be power down sound } else if (yachtEventData.getEventId() == YachtEventType.BUMPER_CRASH.getCode()) { - // TODO: 23/09/17 notify the client that the yacht has been disabled + showDisableAlert(thisYacht); } else { TokenType tokenType = null; if (yachtEventData.getEventId() == YachtEventType.TOKEN_VELOCITY.getCode()) { @@ -438,16 +441,31 @@ public class GameClient { } } + + /** + * Turns a disabled boat black until the bumper affect wears off + * + * @param yacht The yacht to show as disabled + */ + private void showDisableAlert(ClientYacht yacht) { + Color originalColor = yacht.getColour(); + yacht.setColour(Color.BLACK); + + Timer disableTimer = new Timer("Disable Timer"); + disableTimer.schedule(new TimerTask() { + @Override + public void run() { + yacht.setColour(originalColor); + } + }, GameState.BUMPER_DISABLE_TIME); + } + /** * Tells race view to show a collision animation. */ - private void showCollisionAlert(YachtEventData yachtEventData) { + private void showCollisionAlert(ClientYacht yacht) { Sounds.playCrashSound(); - raceState.storeCollision( - allBoatsMap.get( - yachtEventData.getSubjectId().intValue() - ) - ); + raceState.storeCollision(yacht); } // TODO: 11/09/17 wmu16 - Add in functionality to viually indicate a pickup to a user diff --git a/src/main/java/seng302/visualiser/GameView3D.java b/src/main/java/seng302/visualiser/GameView3D.java index 486f0717..3c662dfb 100644 --- a/src/main/java/seng302/visualiser/GameView3D.java +++ b/src/main/java/seng302/visualiser/GameView3D.java @@ -467,11 +467,8 @@ public class GameView3D { wakesGroup.getChildren().add(newBoat.getWake()); wakes.add(newBoat.getWake()); boatObjectGroup.getChildren().add(newBoat); - clientYacht.addLocationListener((boat, lat, lon, heading, sailIn, velocity) -> { - BoatObject bo = boatObjects.get(boat); - Point2D p2d = findScaledXY(lat, lon); - bo.moveTo(p2d.getX(), p2d.getY(), heading, velocity, sailIn, windDir); - }); + clientYacht.addLocationListener(this::updateBoatLocation); + clientYacht.addColorChangeListener(this::updateBoatColor); } Platform.runLater(() -> { gameObjects.getChildren().addAll(wakes); @@ -483,6 +480,23 @@ public class GameView3D { return view; } + /** + * Updates the boatObjects color with that of the clientYachts object. Used in notification from + * a listener on this attribute in clientYacht to re paint the boat mesh + * + * @param clientYacht The yacht to update the colour for + */ + private void updateBoatColor(ClientYacht clientYacht) { + boatObjects.get(clientYacht).setFill(clientYacht.getColour()); + } + + private void updateBoatLocation(ClientYacht boat, Double lat, Double lon, Double heading, + Boolean sailIn, Double velocity) { + BoatObject bo = boatObjects.get(boat); + Point2D p2d = findScaledXY(lat, lon); + bo.moveTo(p2d.getX(), p2d.getY(), heading, velocity, sailIn, windDir); + } + /** * Adds a border to the GameView and rescales to the size of the border, does not rescale if a * border already exists. Assumes the border is larger than the course.