From b8c4582d2ac51f103ec65e4782f36da43b7510f4 Mon Sep 17 00:00:00 2001 From: Connor Taylor-Brown Date: Thu, 14 Sep 2017 12:06:47 +1200 Subject: [PATCH 1/6] Replaced mark arrow listener with animation timer. #story[1195] --- .../Controllers/RaceController.java | 32 ++++++++----------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java b/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java index deaba17e..8b75be1d 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java @@ -82,7 +82,7 @@ public class RaceController extends Controller { private ObservableList viewSubjects; private Subject3D nextMarkArrow; - private ChangeListener pointToMark; + private AnimationTimer pointToMark; /** * The arrow controller. @@ -367,17 +367,19 @@ public class RaceController extends Controller { try { VisualiserBoat boat = visualiserRace.getVisualiserRaceState().getBoat(subject3D.getSourceID()); - this.pointToMark = (o, prev, curr) -> { - 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()); - }; + this.pointToMark = new AnimationTimer() { + @Override + public void handle(long now) { + CompoundMark target = boat.getCurrentLeg().getEndCompoundMark(); + Bearing headingToMark = GPSCoordinate.calculateBearing(boat.getPosition(), target.getAverageGPSCoordinate()); - boat.positionProperty().addListener(pointToMark); + 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(); } @@ -385,13 +387,7 @@ public class RaceController extends Controller { private void removeThirdPersonAnnotations(Subject3D subject3D) { viewSubjects.remove(nextMarkArrow); - - try { - VisualiserBoat boat = visualiserRace.getVisualiserRaceState().getBoat(subject3D.getSourceID()); - boat.positionProperty().removeListener(pointToMark); - } catch (BoatNotFoundException e) { - e.printStackTrace(); - } + pointToMark.stop(); } /** From e354320d74c1af724eea5164b2036521e40a1932 Mon Sep 17 00:00:00 2001 From: Connor Taylor-Brown Date: Thu, 14 Sep 2017 12:20:55 +1200 Subject: [PATCH 2/6] Replaced camera tracking listeners with animation timer - Documented animation timers and mark arrow #story[1195] --- .../Controllers/RaceController.java | 6 +++ .../main/java/visualiser/layout/View3D.java | 37 ++++++------------- 2 files changed, 18 insertions(+), 25 deletions(-) diff --git a/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java b/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java index 8b75be1d..51d9c451 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java @@ -81,7 +81,13 @@ public class RaceController extends Controller { private View3D view3D; private ObservableList viewSubjects; + /** + * Arrow pointing to next mark in third person + */ private Subject3D nextMarkArrow; + /** + * Animation loop for rotating mark arrow + */ private AnimationTimer pointToMark; /** diff --git a/racevisionGame/src/main/java/visualiser/layout/View3D.java b/racevisionGame/src/main/java/visualiser/layout/View3D.java index c62fe22e..f51eecff 100644 --- a/racevisionGame/src/main/java/visualiser/layout/View3D.java +++ b/racevisionGame/src/main/java/visualiser/layout/View3D.java @@ -1,5 +1,6 @@ package visualiser.layout; +import javafx.animation.AnimationTimer; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ChangeListener; @@ -71,21 +72,9 @@ public class View3D extends Pane { */ private Rotate pitch; /** - * Single listener for subject heading changes + * Animation loop for camera tracking */ - private ChangeListener pivotHeading = (o, prev, curr) -> yaw.setAngle((double)curr); - /** - * Single listener for subject position (x) changes - */ - private ChangeListener pivotX = (o, prev, curr) -> pivot.setX((double)curr); - /** - * Single listener for subject position (y) changes - */ - private ChangeListener pivotY = (o, prev, curr) -> pivot.setY((double)curr); - /** - * Single listener for subject position (z) changes - */ - private ChangeListener pivotZ = (o, prev, curr) -> pivot.setZ((double)curr); + private AnimationTimer trackBoat; /** * Distance to switch from third person to bird's eye */ @@ -219,10 +208,7 @@ public class View3D extends Pane { */ private void untrackSubject() { if(target.get() != null) { - target.get().getPosition().xProperty().removeListener(pivotX); - target.get().getPosition().yProperty().removeListener(pivotY); - target.get().getPosition().zProperty().removeListener(pivotZ); - target.get().getHeading().angleProperty().removeListener(pivotHeading); + trackBoat.stop(); target.setValue(null); } } @@ -234,13 +220,14 @@ public class View3D extends Pane { private void trackSubject(Subject3D subject) { target.set(subject); - updatePivot(target.get().getPosition()); - setYaw(target.get().getHeading().getAngle()); - - target.get().getPosition().xProperty().addListener(pivotX); - target.get().getPosition().yProperty().addListener(pivotY); - target.get().getPosition().zProperty().addListener(pivotZ); - target.get().getHeading().angleProperty().addListener(pivotHeading); + this.trackBoat = new AnimationTimer() { + @Override + public void handle(long now) { + updatePivot(target.get().getPosition()); + setYaw(target.get().getHeading().getAngle()); + } + }; + trackBoat.start(); } public void setNearClip(double nearClip) { From f2370485a0b127fc5178b4510c0f38145ebb3cb1 Mon Sep 17 00:00:00 2001 From: Connor Taylor-Brown Date: Thu, 14 Sep 2017 12:48:02 +1200 Subject: [PATCH 3/6] RaceController can now set up collision listeners on each boat. #story[1195] --- .../BoatCollisionCommand.java | 9 ++++++++- .../Controllers/RaceController.java | 5 +++++ .../java/visualiser/model/VisualiserBoat.java | 20 +++++++++++++------ 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/racevisionGame/src/main/java/visualiser/Commands/VisualiserRaceCommands/BoatCollisionCommand.java b/racevisionGame/src/main/java/visualiser/Commands/VisualiserRaceCommands/BoatCollisionCommand.java index c3046d18..48d19d09 100644 --- a/racevisionGame/src/main/java/visualiser/Commands/VisualiserRaceCommands/BoatCollisionCommand.java +++ b/racevisionGame/src/main/java/visualiser/Commands/VisualiserRaceCommands/BoatCollisionCommand.java @@ -3,6 +3,8 @@ package visualiser.Commands.VisualiserRaceCommands; import javafx.scene.media.AudioClip; import mock.model.commandFactory.Command; import network.Messages.YachtEvent; +import shared.exceptions.BoatNotFoundException; +import visualiser.model.VisualiserBoat; import visualiser.model.VisualiserRaceState; /** @@ -34,6 +36,11 @@ public class BoatCollisionCommand implements Command { sound.play(); } - //System.out.println("Collision command executed!"); + try { + VisualiserBoat boat = visualiserRace.getBoat(yachtEvent.getSourceID()); + boat.setHasCollided(true); + } catch (BoatNotFoundException e) { + e.printStackTrace(); + } } } diff --git a/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java b/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java index 51d9c451..ba641ad4 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java @@ -311,6 +311,7 @@ public class RaceController extends Controller { } boat.legProperty().addListener((o, prev, curr) -> swapColours(curr)); + boat.hasCollidedProperty().addListener((o, prev, curr) -> showCollision(boat)); } // Fix initial bird's-eye position view3D.updatePivot(new Translate(250, 0, 210)); @@ -368,6 +369,10 @@ public class RaceController extends Controller { }); } + private void showCollision(VisualiserBoat boat) { + System.out.println(boat.getSourceID() + " has collided"); + } + private void addThirdPersonAnnotations(Subject3D subject3D) { viewSubjects.add(nextMarkArrow); diff --git a/racevisionGame/src/main/java/visualiser/model/VisualiserBoat.java b/racevisionGame/src/main/java/visualiser/model/VisualiserBoat.java index 555def15..5e66c02a 100644 --- a/racevisionGame/src/main/java/visualiser/model/VisualiserBoat.java +++ b/racevisionGame/src/main/java/visualiser/model/VisualiserBoat.java @@ -1,6 +1,8 @@ package visualiser.model; +import javafx.beans.property.BooleanProperty; import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.scene.paint.Color; import network.Messages.Enums.BoatStatusEnum; @@ -62,6 +64,7 @@ public class VisualiserBoat extends Boat { private ObjectProperty positionProperty; private ObjectProperty bearingProperty; + private BooleanProperty hasCollided; /** @@ -74,6 +77,7 @@ public class VisualiserBoat extends Boat { super(boat.getSourceID(), boat.getName(), boat.getCountry()); this.color = color; + this.hasCollided = new SimpleBooleanProperty(false); } @@ -253,10 +257,6 @@ public class VisualiserBoat extends Boat { this.positionProperty.set(position); } - public ObjectProperty positionProperty() { - return positionProperty; - } - @Override public Bearing getBearing() { return bearingProperty.get(); @@ -270,7 +270,15 @@ public class VisualiserBoat extends Boat { this.bearingProperty.set(bearing); } - public ObjectProperty bearingProperty() { - return bearingProperty; + public boolean hasCollided() { + return hasCollided.get(); + } + + public BooleanProperty hasCollidedProperty() { + return hasCollided; + } + + public void setHasCollided(boolean hasCollided) { + this.hasCollided.set(hasCollided); } } From cdc7b642db54974d4d9ddfafd9cabe986f9aa4d8 Mon Sep 17 00:00:00 2001 From: cbt24 Date: Thu, 14 Sep 2017 16:22:04 +1200 Subject: [PATCH 4/6] Boat now shows a fading collision effect #story[1195] --- .../Controllers/RaceController.java | 30 ++++++++++++++----- .../java/visualiser/layout/Shockwave.java | 17 +++++++++++ 2 files changed, 40 insertions(+), 7 deletions(-) create mode 100644 racevisionGame/src/main/java/visualiser/layout/Shockwave.java diff --git a/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java b/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java index ba641ad4..edb28df4 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java @@ -21,10 +21,7 @@ import javafx.scene.layout.StackPane; import javafx.scene.paint.Color; import javafx.scene.paint.Material; import javafx.scene.paint.PhongMaterial; -import javafx.scene.shape.Box; -import javafx.scene.shape.MeshView; -import javafx.scene.shape.Shape3D; -import javafx.scene.shape.Sphere; +import javafx.scene.shape.*; import javafx.scene.transform.Translate; import javafx.util.Callback; import network.Messages.Enums.RaceStatusEnum; @@ -309,9 +306,12 @@ public class RaceController extends Controller { if(nextMark.getMark2() != null) { view3D.getShape(nextMark.getMark2().getSourceID()).setMaterial(markColor); } + Subject3D shockwave = new Shockwave(); + + viewSubjects.add(shockwave); boat.legProperty().addListener((o, prev, curr) -> swapColours(curr)); - boat.hasCollidedProperty().addListener((o, prev, curr) -> showCollision(boat)); + boat.hasCollidedProperty().addListener((o, prev, curr) -> showCollision(boatModel, shockwave)); } // Fix initial bird's-eye position view3D.updatePivot(new Translate(250, 0, 210)); @@ -369,8 +369,24 @@ public class RaceController extends Controller { }); } - private void showCollision(VisualiserBoat boat) { - System.out.println(boat.getSourceID() + " has collided"); + private void showCollision(Subject3D boat, Subject3D shockwave) { + 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()); + + if(opacity <= 0) this.stop(); + else { + shockwave.getMesh().setMaterial(new PhongMaterial(new Color(1,0,0,opacity))); + opacity -= 0.1; + } + } + }; + shockFront.start(); } private void addThirdPersonAnnotations(Subject3D subject3D) { diff --git a/racevisionGame/src/main/java/visualiser/layout/Shockwave.java b/racevisionGame/src/main/java/visualiser/layout/Shockwave.java new file mode 100644 index 00000000..9143f92e --- /dev/null +++ b/racevisionGame/src/main/java/visualiser/layout/Shockwave.java @@ -0,0 +1,17 @@ +package visualiser.layout; + +import javafx.scene.paint.Color; +import javafx.scene.paint.PhongMaterial; +import javafx.scene.shape.Cylinder; +import javafx.scene.transform.Rotate; + +/** + * Created by cbt24 on 14/09/17. + */ +public class Shockwave extends Subject3D { + public Shockwave() { + super(new Cylinder(5,0),0); + getMesh().getTransforms().add(new Rotate(-90, Rotate.X_AXIS)); + getMesh().setMaterial(new PhongMaterial(new Color(0,0,0,0))); + } +} From 7d58b05e38bd4bccd07d292a330af51f5de73e48 Mon Sep 17 00:00:00 2001 From: cbt24 Date: Thu, 14 Sep 2017 16:23:21 +1200 Subject: [PATCH 5/6] Fixed collision not fading to zero #story[1195] --- .../src/main/java/visualiser/Controllers/RaceController.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java b/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java index edb28df4..264d69f7 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java @@ -379,7 +379,10 @@ public class RaceController extends Controller { shockwave.setY(boat.getPosition().getY()); shockwave.setZ(boat.getPosition().getZ()); - if(opacity <= 0) this.stop(); + if(opacity <= 0) { + shockwave.getMesh().setMaterial(new PhongMaterial(new Color(1,0,0,0))); + this.stop(); + } else { shockwave.getMesh().setMaterial(new PhongMaterial(new Color(1,0,0,opacity))); opacity -= 0.1; From 02b4146fa3b78230ea1e0560eaa86a28647aa405 Mon Sep 17 00:00:00 2001 From: cbt24 Date: Thu, 14 Sep 2017 16:24:14 +1200 Subject: [PATCH 6/6] Amended collision effect radius #story[1195] --- .../src/main/java/visualiser/Controllers/RaceController.java | 2 +- racevisionGame/src/main/java/visualiser/layout/Shockwave.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java b/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java index 264d69f7..d86b05a9 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java @@ -306,7 +306,7 @@ public class RaceController extends Controller { if(nextMark.getMark2() != null) { view3D.getShape(nextMark.getMark2().getSourceID()).setMaterial(markColor); } - Subject3D shockwave = new Shockwave(); + Subject3D shockwave = new Shockwave(10); viewSubjects.add(shockwave); diff --git a/racevisionGame/src/main/java/visualiser/layout/Shockwave.java b/racevisionGame/src/main/java/visualiser/layout/Shockwave.java index 9143f92e..efdb0c5d 100644 --- a/racevisionGame/src/main/java/visualiser/layout/Shockwave.java +++ b/racevisionGame/src/main/java/visualiser/layout/Shockwave.java @@ -9,8 +9,8 @@ import javafx.scene.transform.Rotate; * Created by cbt24 on 14/09/17. */ public class Shockwave extends Subject3D { - public Shockwave() { - super(new Cylinder(5,0),0); + public Shockwave(double radius) { + super(new Cylinder(radius,0),0); getMesh().getTransforms().add(new Rotate(-90, Rotate.X_AXIS)); getMesh().setMaterial(new PhongMaterial(new Color(0,0,0,0))); }