diff --git a/src/main/java/seng302/models/BoatGroup.java b/src/main/java/seng302/models/BoatGroup.java index 961cc012..ec3e8262 100644 --- a/src/main/java/seng302/models/BoatGroup.java +++ b/src/main/java/seng302/models/BoatGroup.java @@ -22,7 +22,7 @@ public class BoatGroup extends RaceObject{ private static final double VELOCITY_Y_OFFSET = -5d; private static final double BOAT_HEIGHT = 15d; private static final double BOAT_WIDTH = 10d; - private static final int LINE_INTERVAL = 180; + private static final int LINE_INTERVAL = 30; private static double expectedUpdateInterval = 200; private double framesForNewLine = 0; private boolean destinationSet; @@ -150,7 +150,6 @@ public class BoatGroup extends RaceObject{ double dx = pixelVelocityX * timeInterval; double dy = pixelVelocityY * timeInterval; double rotation = rotationalVelocity * timeInterval; - moveGroupBy(dx, dy, rotation); if (framesForNewLine-- == 0) { @@ -176,9 +175,11 @@ public class BoatGroup extends RaceObject{ } public void setDestination (double newXValue, double newYValue, double rotation, int... raceIds) { - destinationSet = true; - boat.setVelocity(StreamParser.boatSpeeds.get((long)boat.getId())); if (hasRaceId(raceIds)) { + destinationSet = true; + boat.setVelocity(StreamParser.boatSpeeds.get((long)boat.getId())); + if (currentRotation < 0) + currentRotation = 360 - currentRotation; double dx = newXValue - boatPoly.getLayoutX(); if ((dx > 0 && pixelVelocityX < 0) || (dx < 0 && pixelVelocityX > 0)) { pixelVelocityX = 0; @@ -191,24 +192,13 @@ public class BoatGroup extends RaceObject{ } else { pixelVelocityY = dy / expectedUpdateInterval; } -// this.pixelVelocityX = (newXValue - boatPoly.getLayoutX()) / expectedUpdateInterval; -// this.pixelVelocityY = (newYValue - boatPoly.getLayoutY()) / expectedUpdateInterval; rotationalGoal = rotation; calculateRotationalVelocity(); - //Sometimes rotations are way too big. - //if (Math.abs(rotationalVelocity) > 0.00003) - // rotationalVelocity = 0; -// if (wakeGenerationDelay > 0) { wake.rotate(rotationalGoal); wakeGenerationDelay--; } else { - if (Math.abs(rotationalVelocity) > 0.1) -// rotationalVelocity = 0; -// - wake.setRotationalVelocity(0, rotationalGoal, pixelVelocityX, pixelVelocityY); - else - wake.setRotationalVelocity(rotationalVelocity, rotationalGoal, pixelVelocityX, pixelVelocityY); + wake.setRotationalVelocity(rotationalVelocity, currentRotation, pixelVelocityX, pixelVelocityY); } } } diff --git a/src/main/java/seng302/models/RaceObject.java b/src/main/java/seng302/models/RaceObject.java index 30ca28f3..5e1d5ab0 100644 --- a/src/main/java/seng302/models/RaceObject.java +++ b/src/main/java/seng302/models/RaceObject.java @@ -18,6 +18,8 @@ public abstract class RaceObject extends Group { protected double pixelVelocityX; protected double pixelVelocityY; + static double max = 0; + public Point2D getPosition () { return new Point2D(super.getLayoutX(), getLayoutY()); } @@ -40,6 +42,13 @@ public abstract class RaceObject extends Group { } else { this.rotationalVelocity = (rotationalGoal - currentRotation) / expectedUpdateInterval; } + //Sometimes the rotation is too large to be realistic. In that case just do it instantly. + if (Math.abs(rotationalVelocity) > 1) { + rotationalVelocity = 0; + rotateTo(rotationalGoal); + } +// max = Math.max(max, Math.abs(rotationalVelocity)); +// System.out.println("max = " + max); } /** diff --git a/src/main/java/seng302/models/Wake.java b/src/main/java/seng302/models/Wake.java index 897f5919..417ef958 100644 --- a/src/main/java/seng302/models/Wake.java +++ b/src/main/java/seng302/models/Wake.java @@ -21,6 +21,8 @@ class Wake extends Group { private double[] rotations = new double[numWakes]; private int[] velocityIndices = new int[numWakes]; private double sum = 0; + static double max = 0; + static double min = Double.MAX_VALUE; /** * Create a wake at the given location. @@ -48,12 +50,21 @@ class Wake extends Group { * @param rotationalVelocity The rotationalVelocity the wake should move at. */ void setRotationalVelocity (double rotationalVelocity, double rotationGoal, double velocityX, double velocityY) { - sum -= Math.abs(velocities[velocityIndices[0]]); + if (Math.abs(rotationalVelocity) > 0.5) { + rotationalVelocity = 0; + } + sum -= Math.abs(velocities[(velocityIndices[0] + 10) % 13]); +// sum -= Math.abs(velocities[velocityIndices[0]]); sum += Math.abs(rotationalVelocity); - if (sum < 0.00002) + System.out.println("sum = " + sum); + if (sum < 0.9) rotate (rotationGoal); //In relatively straight segments the wake snaps to match the boats current position. //This stops the wake from eventually becoming out of sync with the boat. + max = Math.max(max, sum); + min = Math.min(max, sum); + System.out.println("max = " + max); + System.out.println("min = " + min); //Update the index of the array of recent velocities that each wake uses. Each wake is 3 velocities behind the //next smallest wake. velocityIndices[0] = (13 + (velocityIndices[0] - 1) % 13) % 13; diff --git a/src/main/java/seng302/models/mark/MarkGroup.java b/src/main/java/seng302/models/mark/MarkGroup.java index 6c36cb43..239e0577 100644 --- a/src/main/java/seng302/models/mark/MarkGroup.java +++ b/src/main/java/seng302/models/mark/MarkGroup.java @@ -28,6 +28,9 @@ public class MarkGroup extends RaceObject { private Point2D[] nodeDestinations; public MarkGroup (Mark mark, Point2D... points) { + nodePixelVelocitiesX = new double[points.length]; + nodePixelVelocitiesY = new double[points.length]; + nodeDestinations = new Point2D[points.length]; marks.add(mark); mainMark = mark; Color color = Color.BLACK; @@ -36,36 +39,58 @@ public class MarkGroup extends RaceObject { } else if (mark.getName().equals("Finish")){ color = Color.RED; } - System.out.println("HERE ARE THE CHILDREN LOL"); + Circle markCircle; if (mark.getMarkType() == MarkType.SINGLE_MARK) { - super.getChildren().add(new Circle(0, 0, MARK_RADIUS, color)); - nodeDestinations = new Point2D[]{ - new Point2D(super.getChildren().get(0).getLayoutX() - , super.getChildren().get(0).getLayoutY())}; + markCircle = new Circle( + points[0].getX(), + points[0].getY(), + MARK_RADIUS, + color + ); + nodeDestinations = new Point2D[]{ + new Point2D(markCircle.getCenterX(), markCircle.getCenterY() + ) + }; + super.getChildren().add(markCircle); } else { marks.add(((GateMark) mark).getSingleMark1()); marks.add(((GateMark) mark).getSingleMark2()); - super.getChildren().add( - new Circle( - (points[1].getX() - points[0].getX()) / 2d, - (points[1].getY() - points[0].getY()) / 2d, - MARK_RADIUS, - color - ) + nodePixelVelocitiesX = new double[]{0d,0d}; + nodePixelVelocitiesY = new double[]{0d,0d}; + nodeDestinations = new Point2D[2]; +// markCircle = new Circle( +// (points[1].getX() - points[0].getX()) / 2d, +// (points[1].getY() - points[0].getY()) / 2d, +// MARK_RADIUS, +// color +// + markCircle = new Circle( + points[0].getX(), + points[0].getY(), + MARK_RADIUS, + color ); - super.getChildren().add( - new Circle( - -(points[1].getX() - points[0].getX()) / 2d, - -(points[1].getY() - points[0].getY()) / 2d, - MARK_RADIUS, - color - ) + nodeDestinations[0] = new Point2D(markCircle.getCenterX(), markCircle.getCenterY()); + super.getChildren().add(markCircle); +// markCircle = new Circle( +// -(points[1].getX() - points[0].getX()) / 2d, +// -(points[1].getY() - points[0].getY()) / 2d, +// MARK_RADIUS, +// color +// ); + markCircle = new Circle( + points[1].getX(), + points[1].getY(), + MARK_RADIUS, + color ); + nodeDestinations[1] = new Point2D(markCircle.getCenterX(), markCircle.getCenterY()); + super.getChildren().add(markCircle); Line line = new Line( - (points[1].getX() - points[0].getX()) / 2d, - (points[1].getY() - points[0].getY()) / 2d, - -(points[1].getX() - points[0].getX()) / 2d, - -(points[1].getY() - points[0].getY()) / 2d + points[0].getX(), + points[0].getY(), + points[1].getX(), + points[1].getY() ); line.setStrokeWidth(LINE_THICKNESS); line.setStroke(color); @@ -73,14 +98,8 @@ public class MarkGroup extends RaceObject { line.getStrokeDashArray().addAll(DASHED_GAP_LEN, DASHED_LINE_LEN); } super.getChildren().add(line); - nodePixelVelocitiesX = new double[]{0d,0d}; - nodePixelVelocitiesY = new double[]{0d,0d}; - nodeDestinations = new Point2D[]{ - new Point2D(super.getChildren().get(0).getLayoutX(), super.getChildren().get(0).getLayoutY()), - new Point2D(super.getChildren().get(1).getLayoutX(), super.getChildren().get(1).getLayoutY()) - }; } - moveTo(points[0].getX(), points[0].getY()); + //moveTo(points[0].getX(), points[0].getY()); } public void setDestination (double x, double y, double rotation, int... raceIds) { @@ -90,110 +109,90 @@ public class MarkGroup extends RaceObject { } public void setDestination (double x, double y, int... raceIds) { - int childrenIndex = -1; - for (Mark mark : marks) { + for (int i = 0; i < marks.size(); i++) for (int id : raceIds) - if (id == mark.getId() && childrenIndex != -1) - setDestinationChild(x, y, childrenIndex); - else if (id == mark.getId()) - setDestinationGroup(x, y); - childrenIndex++; - } - updateChildren(); + if (id == marks.get(i).getId()) + setDestinationChild(x, y, Math.max(0, i-1)); } private void setDestinationChild (double x, double y, int childIndex) { - double relativeX = x - super.getLayoutX(); - double relativeY = y - super.getLayoutY(); - this.nodeDestinations[childIndex] = new Point2D(relativeX, relativeY); - this.nodePixelVelocitiesX[childIndex] = (relativeX - super.getChildren().get(childIndex).getLayoutX()) / expectedUpdateInterval; - this.nodePixelVelocitiesY[childIndex] = (relativeY - super.getChildren().get(childIndex).getLayoutY()) / expectedUpdateInterval; - + //double relativeX = x - super.getLayoutX(); + //double relativeY = y - super.getLayoutY(); + Circle markCircle = (Circle) super.getChildren().get(childIndex); + this.nodeDestinations[childIndex] = new Point2D(x, y); + //if (Math.abs(relativeX - markCircle.getCenterX()) > 30 && Math.abs(relativeY - markCircle.getCenterY()) > 30) { + this.nodePixelVelocitiesX[childIndex] = (x - markCircle.getCenterX()) / expectedUpdateInterval; + this.nodePixelVelocitiesY[childIndex] = (y - markCircle.getCenterY()) / expectedUpdateInterval; + //} } - private void setDestinationGroup (double x, double y) { - double relativeX = x - super.getLayoutX(); - double relativeY = y - super.getLayoutY(); - this.nodeDestinations[0] = new Point2D(relativeX, relativeY); - pixelVelocityX = (x - super.getLayoutX()) / expectedUpdateInterval; - pixelVelocityY = (y - super.getLayoutY()) / expectedUpdateInterval; - } - - public void rotateTo (double rotation) { - super.getTransforms().clear(); - super.getTransforms().add(new Rotate(rotation)); + if (mainMark.getMarkType() != MarkType.SINGLE_MARK) { + Line line = (Line) super.getChildren().get(2); + double xCenter = Math.abs(line.getEndX() - line.getStartX()); + double yCenter = Math.abs(line.getEndY() - line.getStartY()); + super.getTransforms().setAll(new Rotate(rotation, xCenter, yCenter)); + } } public void updatePosition (long timeInterval) { -// double x = pixelVelocityX * timeInterval; -// double y = pixelVelocityY * timeInterval; -// double rotation = rotationalVelocity * timeInterval; -// moveGroupBy(x, y, rotation); -// updateChildren(timeInterval); + Circle markCircle = (Circle) super.getChildren().get(0); + + if (nodePixelVelocitiesX[0] > 0 && markCircle.getCenterX() > nodeDestinations[0].getX() || + nodePixelVelocitiesX[0] < 0 && markCircle.getCenterX() < nodeDestinations[0].getY()) + nodePixelVelocitiesX[0] = 0; + else + markCircle.setCenterX(markCircle.getCenterX() + nodePixelVelocitiesX[0] * timeInterval); + + if (nodePixelVelocitiesY[0] > 0 && markCircle.getCenterY() > nodeDestinations[0].getY() || + nodePixelVelocitiesY[0] < 0 && markCircle.getCenterY() < nodeDestinations[0].getY()) + nodePixelVelocitiesY[0] = 0; + else + markCircle.setCenterY(markCircle.getCenterY() + nodePixelVelocitiesY[0] * timeInterval); + + if (mainMark.getMarkType() != MarkType.SINGLE_MARK) { + + Line line = (Line) super.getChildren().get(2); + line.setStartX(markCircle.getCenterX()); + line.setStartY(markCircle.getCenterY()); + + markCircle = (Circle) super.getChildren().get(1); + + if (nodePixelVelocitiesX[1] > 0 && markCircle.getCenterX() >= nodeDestinations[1].getX() || + nodePixelVelocitiesX[1] < 0 && markCircle.getCenterX() <= nodeDestinations[1].getX()) + nodePixelVelocitiesX[1] = 0; + else + markCircle.setCenterX(markCircle.getCenterX() + nodePixelVelocitiesX[1] * timeInterval); + + if (nodePixelVelocitiesY[1] > 0 && markCircle.getCenterY() > nodeDestinations[1].getY() || + nodePixelVelocitiesY[1] < 0 && markCircle.getCenterY() < nodeDestinations[1].getY()) + nodePixelVelocitiesY[1] = 0; + else + markCircle.setCenterY(markCircle.getCenterY() + nodePixelVelocitiesY[1] * timeInterval); + line.setEndX(markCircle.getCenterX()); + line.setEndY(markCircle.getCenterY()); + } } public void moveGroupBy (double x, double y, double rotation) { - super.setLayoutX(super.getLayoutX() + x); - super.setLayoutY(super.getLayoutY() + y); - rotateTo(rotation); - } - - private void updateChildren () { - if (mainMark.getMarkType() != MarkType.SINGLE_MARK) { Line line = (Line) super.getChildren().get(2); for (int childIndex = 0; childIndex < 2; childIndex++){ Circle mark = (Circle) super.getChildren().get(childIndex); - Point2D dest = nodeDestinations[childIndex]; - mark.setCenterY(dest.getY()); - mark.setCenterX(dest.getX()); + mark.setCenterY(mark.getCenterY() + y); + mark.setCenterX(mark.getCenterX() + x); } - line.setStartX(nodeDestinations[0].getX()); - line.setStartY(nodeDestinations[0].getY()); - line.setEndX(nodeDestinations[1].getX()); - line.setEndY(nodeDestinations[1].getY()); -// Circle mark = (Circle) super.getChildren().get(0); -// if (nodePixelVelocitiesX[0] > 0 && mark.getLayoutX() >= nodeDestinations[0].getX()) { -// nodePixelVelocitiesX[0] = 0; -// } else if (nodePixelVelocitiesX[0] < 0 && mark.getLayoutX() <= nodeDestinations[0].getX()) { -// nodePixelVelocitiesX[0] = 0; -// } else { -// mark.setLayoutX(mark.getLayoutX() + nodePixelVelocitiesX[0] * timeInterval); -// mark.setLayoutY(mark.getLayoutY() + nodePixelVelocitiesY[0] * timeInterval); -// } -// if (nodePixelVelocitiesY[0] >= 0 && mark.getLayoutY() > nodeDestinations[0].getY()) { -// nodePixelVelocitiesY[0] = 0; -// } else if (nodePixelVelocitiesY[0] < 0 && mark.getLayoutY() <= nodeDestinations[0].getY()) { -// nodePixelVelocitiesY[0] = 0; -// } else { -// mark.setLayoutX(mark.getLayoutX() + nodePixelVelocitiesX[0] * timeInterval); -// mark.setLayoutY(mark.getLayoutY() + nodePixelVelocitiesY[0] * timeInterval); -// } -// mark = (Circle) super.getChildren().get(1); -// if (nodePixelVelocitiesX[1] > 0 && mark.getLayoutX() >= nodeDestinations[1].getX()) { -// nodePixelVelocitiesX[1] = 0; -// } else if (nodePixelVelocitiesX[1] < 0 && mark.getLayoutX() <= nodeDestinations[1].getX()) { -// nodePixelVelocitiesX[1] = 0; -// } else { -// mark.setLayoutX(mark.getLayoutX() + nodePixelVelocitiesX[1] * timeInterval); -// mark.setLayoutY(mark.getLayoutY() + nodePixelVelocitiesY[1] * timeInterval); -// } -// if (nodePixelVelocitiesY[1] >= 0 && mark.getLayoutY() > nodeDestinations[1].getY()) { -// nodePixelVelocitiesY[1] = 0; -// } else if (nodePixelVelocitiesY[1] < 0 && mark.getLayoutY() <= nodeDestinations[1].getY()) { -// nodePixelVelocitiesY[1] = 0; -// } else { -// mark.setLayoutX(mark.getLayoutX() + nodePixelVelocitiesX[1] * timeInterval); -// mark.setLayoutY(mark.getLayoutY() + nodePixelVelocitiesY[1] * timeInterval); -// } + line.setStartX(line.getStartX() + x); + line.setStartY(line.getStartY() + y); + line.setEndX(line.getEndX() + x); + line.setEndY(line.getEndY() + y); } else { Circle mark = (Circle) super.getChildren().get(0); - Point2D dest = nodeDestinations[0]; - mark.setCenterY(dest.getY()); - mark.setCenterX(dest.getX()); + mark.setCenterY(mark.getCenterY() + y); + mark.setCenterX(mark.getCenterX() + x); } + rotateTo(currentRotation + rotation); } public void moveTo (double x, double y, double rotation) { @@ -202,8 +201,19 @@ public class MarkGroup extends RaceObject { } public void moveTo (double x, double y) { - super.setLayoutX(x); - super.setLayoutY(y); + Circle markCircle = (Circle) super.getChildren().get(0); + markCircle.setCenterX(x); + markCircle.setCenterY(y); + if (mainMark.getMarkType() != MarkType.SINGLE_MARK) { + markCircle = (Circle) super.getChildren().get(1); + markCircle.setCenterX(x); + markCircle.setCenterY(y); + Line line = (Line) super.getChildren().get(2); + line.setStartX(x); + line.setStartY(y); + line.setEndX(x); + line.setEndY(y); + } } public boolean hasRaceId (int... raceIds) { @@ -232,5 +242,4 @@ public class MarkGroup extends RaceObject { idArray[i++] = mark.getId(); return idArray; } - } diff --git a/src/main/java/seng302/models/parsers/StreamPacket.java b/src/main/java/seng302/models/parsers/StreamPacket.java index 1b0d7f94..5c2c0706 100644 --- a/src/main/java/seng302/models/parsers/StreamPacket.java +++ b/src/main/java/seng302/models/parsers/StreamPacket.java @@ -22,7 +22,7 @@ public class StreamPacket { // if (this.type == PacketType.XML_MESSAGE){ // //System.out.println("--------"); // System.out.println(new String(payload)); -// StreamParser.parsePacket(this); +// //StreamParser.parsePacket(this); // } }