diff --git a/src/main/java/seng302/models/BoatGroup.java b/src/main/java/seng302/models/BoatGroup.java index 70b979ff..cc6b3e22 100644 --- a/src/main/java/seng302/models/BoatGroup.java +++ b/src/main/java/seng302/models/BoatGroup.java @@ -1,6 +1,7 @@ package seng302.models; import javafx.geometry.Point2D; +import javafx.scene.CacheHint; import javafx.scene.Group; import javafx.scene.paint.Color; import javafx.scene.shape.Line; @@ -47,6 +48,10 @@ public class BoatGroup extends RaceObject{ private boolean isMaximized= true; private List lineStorage = new ArrayList<>(); private int setCallCount = 5; + private int frameCount = 90; + + private double lastX; + private double lastY; /** * Creates a BoatGroup with the default triangular boat polygon. @@ -80,9 +85,16 @@ public class BoatGroup extends RaceObject{ private void initChildren (Color color, double... points) { boatPoly = new Polygon(points); boatPoly.setFill(color); + boatPoly.setCache(true); + boatPoly.setCacheHint(CacheHint.SPEED); + teamNameObject = new Text(boat.getShortName()); + teamNameObject.setCache(true); + teamNameObject.setCacheHint(CacheHint.SPEED); velocityObject = new Text(String.valueOf(boat.getVelocity())); + velocityObject.setCache(true); + velocityObject.setCacheHint(CacheHint.SPEED); teamNameObject.setX(TEAMNAME_X_OFFSET); teamNameObject.setY(TEAMNAME_Y_OFFSET); @@ -114,8 +126,8 @@ public class BoatGroup extends RaceObject{ * @param dy The amount to move the Y coordinate by */ public void moveGroupBy(double dx, double dy, double rotation) { - boatPoly.setLayoutX(boatPoly.getLayoutX() + dx); - boatPoly.setLayoutY(boatPoly.getLayoutY() + dy); + boatPoly.setLayoutX(lastX + dx); + boatPoly.setLayoutY(lastY + dy); teamNameObject.setLayoutX(teamNameObject.getLayoutX() + dx); teamNameObject.setLayoutY(teamNameObject.getLayoutY() + dy); velocityObject.setLayoutX(velocityObject.getLayoutX() + dx); @@ -166,21 +178,21 @@ public class BoatGroup extends RaceObject{ distanceTravelled += Math.abs(dx) + Math.abs(dy); moveGroupBy(dx, dy, rotation); //Draw a new section of the trail every 20 pixels of movement. - if (distanceTravelled > 20) { - distanceTravelled = 0; + if (frameCount-- == 0) { + frameCount = (int) (300 - boat.getVelocity() * 10); if (lastPoint != null) { Line l = new Line( lastPoint.getX(), lastPoint.getY(), - boatPoly.getLayoutX(), - boatPoly.getLayoutY() + lastX, + lastY ); l.getStrokeDashArray().setAll(3d, 7d); l.setStroke(boatPoly.getFill()); lineGroup.getChildren().add(l); } if (destinationSet) { //Only begin drawing after the first destination is set - lastPoint = new Point2D(boatPoly.getLayoutX(), boatPoly.getLayoutY()); + lastPoint = new Point2D(lastX, lastY); } } wake.updatePosition(timeInterval); @@ -201,8 +213,8 @@ public class BoatGroup extends RaceObject{ boat.setVelocity(groundSpeed); if (currentRotation < 0) currentRotation = 360 - currentRotation; - double dx = newXValue - boatPoly.getLayoutX(); - double dy = newYValue - boatPoly.getLayoutY(); + double dx = newXValue - lastX; + double dy = newYValue - lastY; //Check movement is reasonable. Assumes a 1000 * 1000 canvas // if (Math.abs(dx) > 50 || Math.abs(dy) > 50) { // dx = 0; @@ -212,6 +224,8 @@ public class BoatGroup extends RaceObject{ pixelVelocityX = dx / expectedUpdateInterval; pixelVelocityY = dy / expectedUpdateInterval; + lastX = newXValue; + lastY = newYValue; rotationalGoal = rotation; calculateRotationalVelocity(); if (Math.abs(rotationalVelocity) > 0.075) { @@ -259,7 +273,7 @@ public class BoatGroup extends RaceObject{ double rotation = Math.abs( Math.toDegrees( Math.atan( - (newYValue - boatPoly.getLayoutY()) / (newXValue - boatPoly.getLayoutX()) + (newYValue - lastY) / (newXValue - lastX) ) ) ); diff --git a/src/main/java/seng302/models/Wake.java b/src/main/java/seng302/models/Wake.java index 94312780..664e7501 100644 --- a/src/main/java/seng302/models/Wake.java +++ b/src/main/java/seng302/models/Wake.java @@ -1,5 +1,6 @@ package seng302.models; +import javafx.scene.CacheHint; import javafx.scene.Group; import javafx.scene.paint.Color; import javafx.scene.shape.Arc; @@ -12,20 +13,13 @@ import javafx.scene.transform.Rotate; */ class Wake extends Group { - //Wake Settings. - //Changes the relationship between separation of wakes and velocity. Only logarithmic is guaranteed to work always since it's my favourite :/. - private enum functionType {LINEAR, LOGARITHMIC, POWER, ROOT, POWOUT_LOGIN} - private functionType wakeFunction = functionType.LOGARITHMIC; - //Change the wake style. Currently can be ArcType.OPEN or ArcType.ROUND - private ArcType arcType = ArcType.OPEN; //The number of wakes - private int numWakes = 10; + private int numWakes = 8; //The total possible difference between the first wake and the last. Increasing/Decreasing this will make wakes fan out more/less. private final double MAX_DIFF = 75; //Increasing/decreasing this will alter the speed that wakes converge when the heading stop changing. Anything over about 1500 may cause oscillation. private final int UNIFICATION_SPEED = 500; - //The power used for the power function. Changing this will probably break stuff in a cool way. - private final int POWER = 2; + private Arc[] arcs = new Arc[numWakes]; private double[] rotationalVelocities = new double[numWakes]; @@ -34,6 +28,7 @@ class Wake extends Group { /** * Create a wake at the given location. + * * @param startingX x location where the tip of wake arcs will be. * @param startingY y location where the tip of wake arcs will be. */ @@ -44,21 +39,15 @@ class Wake extends Group { for (int i = 0; i < numWakes; i++) { //Default triangle is -110 deg out of phase with a default wake and has angle of 40 deg. arc = new Arc(0, 0, 0, 0, -110, 40); - - if (arcType == ArcType.ROUND) { - arc.setFill(new Color(0.18, 0.7, 1.0, 0.4 + (-0.35 / numWakes * i))); - arc.setType(ArcType.ROUND); - baseRad = 10; - - } else if (arcType == ArcType.OPEN) { - arc.setType(ArcType.OPEN); - arc.setStroke(new Color(0.18, 0.7, 1.0, 1.0 + (-0.99 / numWakes * i))); - arc.setStrokeWidth(3.0); - arc.setStrokeLineCap(StrokeLineCap.ROUND); - arc.setFill(new Color(0.0, 0.0, 0.0, 0.0)); - baseRad = (20 / numWakes); - arcs[i] = arc; - } + arc.setCache(true); + arc.setCacheHint(CacheHint.SPEED); + arc.setType(ArcType.OPEN); + arc.setStroke(new Color(0.18, 0.7, 1.0, 1.0 + (-0.99 / numWakes * i))); + arc.setStrokeWidth(3.0); + arc.setStrokeLineCap(StrokeLineCap.ROUND); + arc.setFill(new Color(0.0, 0.0, 0.0, 0.0)); + baseRad = (20 / numWakes); + arcs[i] = arc; } super.getChildren().addAll(arcs); } @@ -86,67 +75,17 @@ class Wake extends Group { ); difference = Math.toDegrees(difference); - if (wakeFunction == functionType.LOGARITHMIC) { - if (rotationalVelocities[i-1] < 0.01 && rotationalVelocities[i-1] > -0.01) { - rotationalVelocities[i] = difference / UNIFICATION_SPEED * Math.log(Math.abs(difference) + 1) / Math.log(MAX_DIFF / numWakes) * 1.5; -// if (difference < 0) -// { -// rotationalVelocities[i] = -rotationalVelocities[i]; -// } - } else { - rotationalVelocities[i] = rotationalVelocities[i-1] * Math.log(Math.abs(difference) + 1) / Math.log(MAX_DIFF / numWakes); - } + if (rotationalVelocities[i-1] < 0.01 && rotationalVelocities[i-1] > -0.01) { + rotationalVelocities[i] = difference / UNIFICATION_SPEED * Math.log(Math.abs(difference) + 1) / Math.log(MAX_DIFF / numWakes) * 1.5; - } else if (wakeFunction == functionType.LINEAR) { - if (rotationalVelocities[i - 1] < 0.01 && rotationalVelocities[i - 1] > -0.01) { - rotationalVelocities[i] = difference / UNIFICATION_SPEED * 2; - } else { - if (difference < (MAX_DIFF / numWakes)) - rotationalVelocities[i] = rotationalVelocities[i - 1] * difference / (MAX_DIFF / numWakes); - else - rotationalVelocities[i] = rotationalVelocities[i - 1]; - } - } else if (wakeFunction == functionType.POWER) { - if (rotationalVelocities[i - 1] < 0.01 && rotationalVelocities[i - 1] > -0.01) { - rotationalVelocities[i] = difference / UNIFICATION_SPEED * Math.pow(difference, POWER) / Math.pow((MAX_DIFF / numWakes), POWER); - } else { - if (difference < (MAX_DIFF / numWakes)) - rotationalVelocities[i] = rotationalVelocities[i - 1] * Math.pow(difference, POWER) / Math.pow((MAX_DIFF / numWakes), POWER); - else - rotationalVelocities[i] = rotationalVelocities[i - 1]; - } - } else if (wakeFunction == functionType.ROOT) { - if (rotationalVelocities[i - 1] < 0.01 && rotationalVelocities[i - 1] > -0.01) { - rotationalVelocities[i] = (MAX_DIFF / numWakes) / UNIFICATION_SPEED * Math.sqrt(Math.abs(difference)) / Math.sqrt(MAX_DIFF / numWakes); - } else { - if (difference < (MAX_DIFF / numWakes)) - rotationalVelocities[i] = rotationalVelocities[i - 1] * Math.sqrt(Math.abs(difference)) / Math.sqrt(MAX_DIFF / numWakes); - else - rotationalVelocities[i] = rotationalVelocities[i - 1]; - } - if (difference < 0) - rotationalVelocities[i] = -rotationalVelocities[i]; - } else if (wakeFunction == functionType.POWOUT_LOGIN) { - if (rotationalVelocities[i - 1] < 0.01 && rotationalVelocities[i - 1] > -0.01) { - rotationalVelocities[i] = difference / UNIFICATION_SPEED * Math.log(Math.abs(difference) + 1) / Math.log(MAX_DIFF / numWakes); - } else { - if (difference < (MAX_DIFF / numWakes)) - rotationalVelocities[i] = rotationalVelocities[i - 1] * Math.pow(difference, POWER) / Math.pow((MAX_DIFF / numWakes), POWER); - else - rotationalVelocities[i] = rotationalVelocities[i - 1]; - } + } else { + if (difference < (MAX_DIFF / numWakes)) + rotationalVelocities[i] = rotationalVelocities[i-1] * Math.log(Math.abs(difference) + 1) / Math.log(MAX_DIFF / numWakes); + else + rotationalVelocities[i] = rotationalVelocities[i - 1]; } - } - //Scale wakes based on velocity. -// if (count-- == 0) -// { -// count = 10; -// offSet = 0; -// } else { -// offSet += baseRad / 5; -// } double rad = baseRad + velocity; for (Arc arc :arcs) { arc.setRadiusX(rad); @@ -177,5 +116,4 @@ class Wake extends Group { arcs[i].getTransforms().setAll(new Rotate(rotation)); } } - }