diff --git a/src/main/java/seng302/Controllers/RaceController.java b/src/main/java/seng302/Controllers/RaceController.java index bc2d8a1d..768bef51 100644 --- a/src/main/java/seng302/Controllers/RaceController.java +++ b/src/main/java/seng302/Controllers/RaceController.java @@ -1,14 +1,15 @@ package seng302.Controllers; +import javafx.beans.property.ReadOnlyObjectWrapper; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; +import javafx.collections.FXCollections; import javafx.collections.ObservableList; -import javafx.event.ActionEvent; -import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.scene.control.*; import javafx.scene.layout.GridPane; +import javafx.util.Callback; import org.xml.sax.SAXException; import seng302.Model.*; import seng302.RaceXMLReader; @@ -26,11 +27,12 @@ public class RaceController extends Controller { @FXML GridPane canvasBase; - //user saved data for annotation display - private ArrayList presetAnno; - ResizableRaceCanvas raceMap; - @FXML SplitPane race; + + @FXML + GridPane startScreen; + @FXML + SplitPane ongoingRacePane; @FXML CheckBox showFPS; @FXML @@ -39,16 +41,6 @@ public class RaceController extends Controller { Label timer; @FXML Label FPS; - @FXML - CheckBox showName; - @FXML - CheckBox showAbbrev; - @FXML - CheckBox showSpeed; - @FXML - Button saveAnno; - @FXML - Button showSetAnno; @FXML TableView boatInfoTable; @@ -88,6 +80,26 @@ public class RaceController extends Controller { boatPlacingColumn.setCellValueFactory(cellData -> cellData.getValue().positionProperty()); } + /** + * Begins the race with a scale factor of 15 + */ + public void startRace1Min() { + startRace(15); + } + + /** + * Begins the race with a scale factor of 3 + */ + public void startRace5Min() { + startRace(3); + } + + /** + * Begins the race with a scale factor of 1 + */ + public void startRaceNoScaling() { + startRace(1); + } @Override public void initialize(URL location, ResourceBundle resources) { @@ -110,8 +122,7 @@ public class RaceController extends Controller { * * @param scaleFactor scale value of race */ - public void startRace(int scaleFactor) { - + private void startRace(int scaleFactor) { RaceXMLReader raceXMLReader = null; try { raceXMLReader = new RaceXMLReader("raceXML/bermuda_AC35.xml"); @@ -132,12 +143,12 @@ public class RaceController extends Controller { ArrayList legs = raceXMLReader.getLegs(); - ConstantVelocityRace newRace = new ConstantVelocityRace(boats, legs, this, scaleFactor); - newRace.initialiseBoats(); + ConstantVelocityRace race = new ConstantVelocityRace(boats, legs, this, scaleFactor); + race.initialiseBoats(); - BoatInRace[] startingBoats = new BoatInRace[newRace.getStartingBoats().size()]; + BoatInRace[] startingBoats = new BoatInRace[race.getStartingBoats().size()]; int i = 0; - for (BoatInRace boat : newRace.getStartingBoats()) { + for (BoatInRace boat : race.getStartingBoats()) { startingBoats[i] = boat; i++; } @@ -152,13 +163,13 @@ public class RaceController extends Controller { raceMap.setVisible(true); canvasBase.getChildren().add(raceMap); - race.setVisible(true); + startScreen.setVisible(false); + ongoingRacePane.setVisible(true); - //Initialize save annotation array, fps listener, and annotation listeners initializeFPS(); initializeAnnotations(); - new Thread((newRace)).start(); + new Thread((race)).start(); } @@ -201,7 +212,6 @@ public class RaceController extends Controller { * Set up boat annotations */ private void initializeAnnotations() { - presetAnno = new ArrayList<>(); //listener for annotation showAnnotations.selectedProperty().addListener(new ChangeListener() { public void changed(ObservableValue ov, @@ -210,51 +220,6 @@ public class RaceController extends Controller { raceMap.update(); } }); - //listener for show name in annotation - showName.selectedProperty().addListener(new ChangeListener() { - public void changed(ObservableValue ov, - Boolean old_val, Boolean new_val) { - raceMap.toggleAnnoName(); - raceMap.update(); - } - }); - //listener for show abbreviation for annotation - showAbbrev.selectedProperty().addListener(new ChangeListener() { - public void changed(ObservableValue ov, - Boolean old_val, Boolean new_val) { - raceMap.toggleAnnoAbbrev(); - raceMap.update(); - } - }); - //listener to show speed for annotation - showSpeed.selectedProperty().addListener(new ChangeListener() { - public void changed(ObservableValue ov, - Boolean old_val, Boolean new_val) { - raceMap.toggleAnnoSpeed(); - raceMap.update(); - } - }); - //listener to save currently selected annotation - saveAnno.setOnAction(new EventHandler() { - @Override - public void handle(ActionEvent event) { - presetAnno.clear(); - presetAnno.add(showName.isSelected()); - presetAnno.add(showAbbrev.isSelected()); - presetAnno.add(showSpeed.isSelected()); - } - }); - //listener to show saved annotation - showSetAnno.setOnAction(new EventHandler() { - @Override - public void handle(ActionEvent event) { - if (presetAnno.size() > 0) { - showName.setSelected(presetAnno.get(0)); - showAbbrev.setSelected(presetAnno.get(1)); - showSpeed.setSelected(presetAnno.get(2)); - raceMap.update(); - } - } - }); } + } diff --git a/src/main/java/seng302/Model/BoatInRace.java b/src/main/java/seng302/Model/BoatInRace.java index d306eb4c..cf2cc7aa 100644 --- a/src/main/java/seng302/Model/BoatInRace.java +++ b/src/main/java/seng302/Model/BoatInRace.java @@ -1,6 +1,5 @@ package seng302.Model; -import javafx.beans.property.IntegerProperty; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; import javafx.scene.paint.Color; @@ -9,6 +8,8 @@ import seng302.Constants; import seng302.GPSCoordinate; import java.awt.geom.Point2D; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; /** * Boat in the Race extends Boat. @@ -27,6 +28,12 @@ public class BoatInRace extends Boat { private boolean started = false; private StringProperty position; + private Queue track = new ConcurrentLinkedQueue<>(); + private long nextValidTime = 0; + private final int TRACK_POINT_TIME_INTERVAL = 1000; // every 1 seconds + private final int TRACK_POINT_LIMIT = 10; + private boolean trackVisible = true; + /** * Constructor method. * @@ -251,4 +258,26 @@ public class BoatInRace extends Boat { public void setPosition(String position) { this.position.set(position); } + + public boolean addTrackPoint(GPSCoordinate coordinate) { + Boolean added = System.currentTimeMillis() >= nextValidTime; + long currentTime = System.currentTimeMillis(); + if (added && this.started) { + nextValidTime = currentTime + TRACK_POINT_TIME_INTERVAL; + track.add(new TrackPoint(coordinate, currentTime, TRACK_POINT_LIMIT * TRACK_POINT_TIME_INTERVAL)); + } + return added; + } + + public Queue getTrack() { + return track; + } + + public boolean isTrackVisible() { + return trackVisible; + } + + public void setTrackVisible(boolean trackVisible) { + this.trackVisible = trackVisible; + } } diff --git a/src/main/java/seng302/Model/Race.java b/src/main/java/seng302/Model/Race.java index 825b7145..b57e1f32 100644 --- a/src/main/java/seng302/Model/Race.java +++ b/src/main/java/seng302/Model/Race.java @@ -214,20 +214,23 @@ public abstract class Race implements Runnable { for (BoatInRace boat : startingBoats) { if (boat != null && !boat.isFinished()) { + boat.addTrackPoint(boat.getCurrentPosition()); updatePosition(boat, Math.round(1000 / lastFPS) > 20 ? 15 : Math.round(1000 / lastFPS)); checkPosition(boat, totalTimeElapsed); } } - if (controller != null) controller.updateMap(startingBoats); +// if (controller != null) controller.updateMap(startingBoats); if (timerEnabled) updateTime(calcTimer()); - } else { - //Exit animation timer - updateTime(calcTimer()); - updateFPS(0); //race ended so fps = 0 - stop(); //exit animation timer } + controller.updateMap(startingBoats); +// } else { +// //Exit animation timer +// updateTime(calcTimer()); +// updateFPS(0); //race ended so fps = 0 +// stop(); //exit animation timer +// } fps++; if ((System.currentTimeMillis() - timeCurrent) > 1000) { updateFPS(fps); diff --git a/src/main/java/seng302/Model/ResizableRaceCanvas.java b/src/main/java/seng302/Model/ResizableRaceCanvas.java index befa173c..cab71f1f 100644 --- a/src/main/java/seng302/Model/ResizableRaceCanvas.java +++ b/src/main/java/seng302/Model/ResizableRaceCanvas.java @@ -338,10 +338,21 @@ public class ResizableRaceCanvas extends Canvas { if (raceAnno) displayText(boat.toString(), boat.getAbbrev(), boat.getVelocity(), this.map.convertGPS(boat.getCurrentPosition())); + + if(boat.isTrackVisible()) drawTrackPoint(boat); } } } + private void drawTrackPoint(BoatInRace boat) { + for (TrackPoint point : boat.getTrack()) { + GraphCoordinate scaledCoordinate = this.map.convertGPS(point.getCoordinate()); + Color boatColour = boat.getColour(); + gc.setFill(new Color(boatColour.getRed(), boatColour.getGreen(), boatColour.getBlue(), point.getAlpha())); + gc.fillOval(scaledCoordinate.getX(), scaledCoordinate.getY(), 5, 5); + } + } + public void setRaceBoundaries(ArrayList boundaries) { this.raceBoundaries = new ArrayList<>(); for (GPSCoordinate bound : boundaries) { diff --git a/src/main/java/seng302/Model/TrackPoint.java b/src/main/java/seng302/Model/TrackPoint.java new file mode 100644 index 00000000..6a28bd22 --- /dev/null +++ b/src/main/java/seng302/Model/TrackPoint.java @@ -0,0 +1,32 @@ +package seng302.Model; + +import seng302.GPSCoordinate; + +/** + * Created by cbt24 on 7/04/17. + */ +public class TrackPoint { + private GPSCoordinate coordinate; + private long timeAdded; + private long expiry; + private double minAlpha; + + public TrackPoint(GPSCoordinate coordinate, long timeAdded, long expiry) { + this.coordinate = coordinate; + this.timeAdded = timeAdded; + this.expiry = expiry; + this.minAlpha = 0.1; + } + + public GPSCoordinate getCoordinate() { + return coordinate; + } + + public double getAlpha() { + return Double.max(minAlpha,1.0 - (double)(System.currentTimeMillis() - timeAdded) / expiry); + } + + public long getTimeAdded() { + return timeAdded; + } +} diff --git a/src/main/resources/scenes/racepane.fxml b/src/main/resources/scenes/racepane.fxml new file mode 100644 index 00000000..8b65d5d7 --- /dev/null +++ b/src/main/resources/scenes/racepane.fxml @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +