diff --git a/racevisionGame/src/main/java/mock/model/MockRace.java b/racevisionGame/src/main/java/mock/model/MockRace.java index 41fbe4d8..9ede32d1 100644 --- a/racevisionGame/src/main/java/mock/model/MockRace.java +++ b/racevisionGame/src/main/java/mock/model/MockRace.java @@ -366,10 +366,8 @@ public class MockRace extends RaceState { //Checks if the current boat has finished the race or not. boolean finish = this.isLastLeg(boat.getCurrentLeg()); - if (!finish && totalElapsedMilliseconds >= updatePeriodMilliseconds) { - + if (!finish && totalElapsedMilliseconds >= updatePeriodMilliseconds && !boat.isColliding()) { if(boat.isVelocityDefault()) setBoatSpeed(boat); - //Calculates the distance travelled, in meters, in the current timeslice. double distanceTravelledMeters = boat.calculateMetersTravelled(updatePeriodMilliseconds) * this.scaleFactor; diff --git a/racevisionGame/src/main/java/mock/model/collider/Collider.java b/racevisionGame/src/main/java/mock/model/collider/Collider.java index 28c01f9f..3bce3bc3 100644 --- a/racevisionGame/src/main/java/mock/model/collider/Collider.java +++ b/racevisionGame/src/main/java/mock/model/collider/Collider.java @@ -24,7 +24,8 @@ public abstract class Collider extends Observable implements Locatable { // Direction of collider from heading Bearing relative = Bearing.fromDegrees(absolute.degrees() - boat.getBearing().degrees()); - if(actualDistance <= distance) { + if(!boat.isColliding() && actualDistance <= distance) { + boat.setColliding(true); Collision collision = new Collision(boat, relative, distance); // Notify object of collision onCollisionEnter(collision); diff --git a/racevisionGame/src/main/java/mock/model/commandFactory/CollisionCommand.java b/racevisionGame/src/main/java/mock/model/commandFactory/CollisionCommand.java index bb86433d..52ec2b34 100644 --- a/racevisionGame/src/main/java/mock/model/commandFactory/CollisionCommand.java +++ b/racevisionGame/src/main/java/mock/model/commandFactory/CollisionCommand.java @@ -29,17 +29,18 @@ public class CollisionCommand extends ObserverCommand { public void execute() { this.azimuth = Azimuth.fromDegrees(boat.getBearing().degrees() - 180d); this.startingPosition = boat.getPosition(); - this.distance = 30; + this.distance = 60; boat.setVelocityDefault(false); } @Override public void update(Observable o, Object arg) { if(GPSCoordinate.calculateDistanceMeters(boat.getPosition(), startingPosition) < distance) { - boat.setPosition(GPSCoordinate.calculateNewPosition(boat.getPosition(), 2, azimuth)); + boat.setPosition(GPSCoordinate.calculateNewPosition(boat.getPosition(), 3, azimuth)); } else { race.deleteObserver(this); boat.setVelocityDefault(true); + boat.setColliding(false); } } } diff --git a/racevisionGame/src/main/java/shared/model/Boat.java b/racevisionGame/src/main/java/shared/model/Boat.java index bd3eea5e..edbba025 100644 --- a/racevisionGame/src/main/java/shared/model/Boat.java +++ b/racevisionGame/src/main/java/shared/model/Boat.java @@ -98,6 +98,11 @@ public class Boat extends Collider { */ private boolean sailsOut = true; + /** + * Indicates whether boat is currently involved in a collision + */ + private boolean isColliding = false; + /** * Constructs a boat object with a given sourceID, name, country/team abbreviation, and polars table. * @@ -407,7 +412,7 @@ public class Boat extends Collider { @Override public boolean rayCast(Boat boat) { if(boat != this) { - return rayCast(boat, 100); + return rayCast(boat, 15); } else return false; } @@ -419,4 +424,12 @@ public class Boat extends Collider { notifyObservers(e); } } + + public boolean isColliding() { + return isColliding; + } + + public void setColliding(boolean colliding) { + isColliding = colliding; + } } diff --git a/racevisionGame/src/main/java/shared/model/Mark.java b/racevisionGame/src/main/java/shared/model/Mark.java index 23778cff..fd46112f 100644 --- a/racevisionGame/src/main/java/shared/model/Mark.java +++ b/racevisionGame/src/main/java/shared/model/Mark.java @@ -29,11 +29,6 @@ public class Mark extends Collider{ */ private GPSCoordinate position; - /** - * Repulsion radius of the mark - */ - private double repulsionRadius = 50; - /** * Constructs a mark with a given source ID, name, and position. * @param sourceID The source ID of the mark. @@ -97,7 +92,7 @@ public class Mark extends Collider{ @Override public boolean rayCast(Boat boat) { - return rayCast(boat, repulsionRadius); + return rayCast(boat, 15); } @Override diff --git a/racevisionGame/src/main/java/visualiser/Controllers/HostController.java b/racevisionGame/src/main/java/visualiser/Controllers/HostController.java deleted file mode 100644 index e69de29b..00000000 diff --git a/racevisionGame/src/main/java/visualiser/Controllers/RaceViewController.java b/racevisionGame/src/main/java/visualiser/Controllers/RaceViewController.java index e37f1ff2..6a92c75c 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/RaceViewController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/RaceViewController.java @@ -323,16 +323,16 @@ public class RaceViewController extends Controller { Material markColor = new PhongMaterial(new Color(0.15,0.9,0.2,1)); CompoundMark nextMark = boat.getCurrentLeg().getEndCompoundMark(); - view3D.getShape(nextMark.getMark1().getSourceID()).setMaterial(markColor); + view3D.getShape(nextMark.getMark1().getSourceID()).getMesh().setMaterial(markColor); if(nextMark.getMark2() != null) { - view3D.getShape(nextMark.getMark2().getSourceID()).setMaterial(markColor); + view3D.getShape(nextMark.getMark2().getSourceID()).getMesh().setMaterial(markColor); } Subject3D shockwave = new Shockwave(10); viewSubjects.add(shockwave); - boat.legProperty().addListener((o, prev, curr) -> swapColours(curr)); - boat.hasCollidedProperty().addListener((o, prev, curr) -> showCollision(boatModel, shockwave)); + boat.legProperty().addListener((o, prev, curr) -> Platform.runLater(() -> swapColours(curr))); + boat.hasCollidedProperty().addListener((o, prev, curr) -> Platform.runLater(() -> showCollision(boat, shockwave))); } // Fix initial bird's-eye position view3D.updatePivot(new Translate(250, 0, 210)); @@ -341,7 +341,7 @@ public class RaceViewController extends Controller { if(curr != null && visualiserRace.getVisualiserRaceState().isVisualiserBoat(curr.getSourceID())) { addThirdPersonAnnotations(curr); } else { - removeThirdPersonAnnotations(prev); + removeThirdPersonAnnotations(); } }); @@ -390,18 +390,20 @@ public class RaceViewController extends Controller { }); } - private void showCollision(Subject3D boat, Subject3D shockwave) { + private void showCollision(VisualiserBoat boat, Subject3D shockwave) { + Subject3D boatModel = view3D.getShape(boat.getSourceID()); AnimationTimer shockFront = new AnimationTimer() { double opacity = 1; @Override public void handle(long now) { - shockwave.setX(boat.getPosition().getX()); - shockwave.setY(boat.getPosition().getY()); - shockwave.setZ(boat.getPosition().getZ()); + shockwave.setX(boatModel.getPosition().getX()); + shockwave.setY(boatModel.getPosition().getY()); + shockwave.setZ(boatModel.getPosition().getZ()); if(opacity <= 0) { - shockwave.getMesh().setMaterial(new PhongMaterial(new Color(1,0,0,0))); + shockwave.getMesh().setMaterial(new PhongMaterial(Color.TRANSPARENT)); + boat.setHasCollided(false); this.stop(); } else { @@ -435,38 +437,14 @@ public class RaceViewController extends Controller { } }; arrowToNextMark.start(); - /* - try { - VisualiserBoat boat = visualiserRace.getVisualiserRaceState().getBoat(subject3D.getSourceID()); - this.pointToMark = new AnimationTimer() { - @Override - public void handle(long now) { - CompoundMark target = boat.getCurrentLeg().getEndCompoundMark(); - Bearing headingToMark = GPSCoordinate.calculateBearing(boat.getPosition(), target.getAverageGPSCoordinate()); - - nextMarkArrow.setX(view3D.getPivot().getX()); - nextMarkArrow.setY(view3D.getPivot().getY()); - nextMarkArrow.setZ(view3D.getPivot().getZ() + 10); - nextMarkArrow.setHeading(headingToMark.degrees()); - } - }; - pointToMark.start(); - } catch (BoatNotFoundException e) { - e.printStackTrace(); - }*/ } - private void removeThirdPersonAnnotations(Subject3D subject3D) { + private void removeThirdPersonAnnotations() { viewSubjects.remove(nextMarkArrow); - arrowToNextMark.stop(); -/* - try { - VisualiserBoat boat = visualiserRace.getVisualiserRaceState().getBoat(subject3D.getSourceID()); - boat.positionProperty().removeListener(pointToMark); - } catch (BoatNotFoundException e) { - e.printStackTrace(); - }*/ - //pointToMark.stop(); + if (arrowToNextMark != null) { + arrowToNextMark.stop(); + } + } /** @@ -477,21 +455,26 @@ public class RaceViewController extends Controller { CompoundMark start = leg.getStartCompoundMark(); CompoundMark end = leg.getEndCompoundMark(); - Shape3D start1 = view3D.getShape(start.getMark1().getSourceID()); - Shape3D end1 = view3D.getShape(end.getMark1().getSourceID()); + //The last leg "finish" doesn't have compound marks. + if (start == null || end == null ) { + return; + } + + Shape3D start1 = view3D.getShape(start.getMark1().getSourceID()).getMesh(); + Shape3D end1 = view3D.getShape(end.getMark1().getSourceID()).getMesh(); Material nextMark = start1.getMaterial(); Material lastMark = end1.getMaterial(); start1.setMaterial(lastMark); if(start.getMark2() != null) { - Shape3D start2 = view3D.getShape(start.getMark2().getSourceID()); + Shape3D start2 = view3D.getShape(start.getMark2().getSourceID()).getMesh(); start2.setMaterial(lastMark); } end1.setMaterial(nextMark); if(end.getMark2() != null) { - Shape3D end2 = view3D.getShape(end.getMark2().getSourceID()); + Shape3D end2 = view3D.getShape(end.getMark2().getSourceID()).getMesh(); end2.setMaterial(nextMark); } } @@ -600,6 +583,7 @@ public class RaceViewController extends Controller { /** * Transition from the race view to the finish view. + * @throws IOException Thrown if the finish scene cannot be loaded. */ private void finishRace() throws IOException { RaceFinishController fc = @@ -766,4 +750,4 @@ public class RaceViewController extends Controller { } } -} \ No newline at end of file +} diff --git a/racevisionGame/src/main/java/visualiser/gameController/ControllerServer.java b/racevisionGame/src/main/java/visualiser/gameController/ControllerServer.java index b9dde4af..602f1e33 100644 --- a/racevisionGame/src/main/java/visualiser/gameController/ControllerServer.java +++ b/racevisionGame/src/main/java/visualiser/gameController/ControllerServer.java @@ -80,8 +80,9 @@ public class ControllerServer implements RunnableWithFramePeriod { try { Command command = CommandFactory.createCommand(raceState, boatAction); - compositeCommand.addCommand(command); - + if(command != null) { + compositeCommand.addCommand(command); + } } catch (CommandConstructionException e) { Logger.getGlobal().log(Level.WARNING, "ControllerServer could not create a Command for BoatAction: " + boatAction + ".", e); diff --git a/racevisionGame/src/main/java/visualiser/layout/Boundary3D.java b/racevisionGame/src/main/java/visualiser/layout/Boundary3D.java index bfbf7dcf..35d531c2 100644 --- a/racevisionGame/src/main/java/visualiser/layout/Boundary3D.java +++ b/racevisionGame/src/main/java/visualiser/layout/Boundary3D.java @@ -35,7 +35,7 @@ public class Boundary3D { if (points.size() < 2){ return; } - System.out.println(points.size()); + for (int i = 0; i < points.size(); i++){ if (i + 1 != points.size()){ addBound(points.get(i), points.get(i + 1)); diff --git a/racevisionGame/src/main/java/visualiser/layout/SeaSurface.java b/racevisionGame/src/main/java/visualiser/layout/SeaSurface.java index f9827e5c..af3374fb 100644 --- a/racevisionGame/src/main/java/visualiser/layout/SeaSurface.java +++ b/racevisionGame/src/main/java/visualiser/layout/SeaSurface.java @@ -32,6 +32,9 @@ public class SeaSurface extends Subject3D { /** * Creates the sea surface + * @param size size of sea noise array. + * @param freq frequency of sea noise array. + * @return The sea surface. */ private static Shape3D createSurface(int size, double freq) { float[][] noiseArray = PerlinNoiseGenerator.createNoise(size, freq); diff --git a/racevisionGame/src/main/java/visualiser/layout/Subject3D.java b/racevisionGame/src/main/java/visualiser/layout/Subject3D.java index 7a2aed21..e6a6f047 100644 --- a/racevisionGame/src/main/java/visualiser/layout/Subject3D.java +++ b/racevisionGame/src/main/java/visualiser/layout/Subject3D.java @@ -33,6 +33,7 @@ public class Subject3D { /** * Constructor for view subject wrapper * @param mesh to be rendered + * @param sourceID Source ID of the subject. */ public Subject3D(Shape3D mesh, int sourceID) { this.mesh = mesh; diff --git a/racevisionGame/src/main/java/visualiser/layout/View3D.java b/racevisionGame/src/main/java/visualiser/layout/View3D.java index 5709505c..e9069c5d 100644 --- a/racevisionGame/src/main/java/visualiser/layout/View3D.java +++ b/racevisionGame/src/main/java/visualiser/layout/View3D.java @@ -36,9 +36,9 @@ public class View3D extends Pane { */ private Map shapeMap; /** - * Map for selecting Shape3D from source ID + * Map for selecting Subject3D from source ID */ - private Map sourceMap; + private Map sourceMap; /** * Subject tracked by camera */ @@ -150,14 +150,14 @@ public class View3D extends Pane { for (Subject3D shape : c.getAddedSubList()) { world.getChildren().add(shape.getMesh()); shapeMap.put(shape.getMesh(), shape); - sourceMap.put(shape.getSourceID(), shape.getMesh()); + sourceMap.put(shape.getSourceID(), shape); } } } }); } - public Shape3D getShape(int sourceID) { + public Subject3D getShape(int sourceID) { return sourceMap.get(sourceID); }