Merge branch 'master' into MapWindRotation
# Conflicts: # racevisionGame/src/main/java/mock/app/Event.java # racevisionGame/src/main/java/mock/model/MockRace.java # racevisionGame/src/main/java/visualiser/app/VisualiserInput.java # racevisionGame/src/main/java/visualiser/model/VisualiserRace.java
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
package visualiser.Controllers;
|
||||
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.shape.Circle;
|
||||
import shared.model.Bearing;
|
||||
import shared.model.Wind;
|
||||
import visualiser.model.VisualiserRace;
|
||||
|
||||
/**
|
||||
* Controller for the arrow.fxml view.
|
||||
*/
|
||||
public class ArrowController {
|
||||
|
||||
|
||||
@FXML
|
||||
private Pane compass;
|
||||
|
||||
@FXML
|
||||
private StackPane arrowStackPane;
|
||||
|
||||
@FXML
|
||||
private ImageView arrowImage;
|
||||
|
||||
@FXML
|
||||
private Circle circle;
|
||||
|
||||
@FXML
|
||||
private Label northLabel;
|
||||
|
||||
@FXML
|
||||
private Label windLabel;
|
||||
|
||||
@FXML
|
||||
private Label speedLabel;
|
||||
|
||||
|
||||
/**
|
||||
* This is the property our arrow control binds to.
|
||||
*/
|
||||
private Property<Wind> wind;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public ArrowController() {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets which wind property the arrow control should bind to.
|
||||
* @param wind The wind property to bind to.
|
||||
*/
|
||||
public void setWindProperty(Property<Wind> wind) {
|
||||
this.wind = wind;
|
||||
|
||||
wind.addListener((observable, oldValue, newValue) -> {
|
||||
if (newValue != null) {
|
||||
Platform.runLater(() -> updateWind(newValue));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates the control to use the new wind value.
|
||||
* This updates the arrow direction (due to bearing), arrow length (due to speed), and label (due to speed).
|
||||
* @param wind The wind value to use.
|
||||
*/
|
||||
private void updateWind(Wind wind) {
|
||||
updateWindBearing(wind.getWindDirection());
|
||||
updateWindSpeed(wind.getWindSpeed());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates the control to account for the new wind speed.
|
||||
* This changes the length (height) of the wind arrow, and updates the speed label.
|
||||
* @param speedKnots The new wind speed, in knots.
|
||||
*/
|
||||
private void updateWindSpeed(double speedKnots) {
|
||||
updateWindArrowLength(speedKnots);
|
||||
updateWindSpeedLabel(speedKnots);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the length of the wind arrow according to the specified wind speed.
|
||||
* @param speedKnots Wind speed, in knots.
|
||||
*/
|
||||
private void updateWindArrowLength(double speedKnots) {
|
||||
|
||||
//At 2 knots, the arrow reaches its minimum height, and at 30 knots it reaches its maximum height.
|
||||
double minKnots = 2;
|
||||
double maxKnots = 30;
|
||||
double deltaKnots = maxKnots - minKnots;
|
||||
|
||||
double minHeight = 25;
|
||||
double maxHeight = 75;
|
||||
double deltaHeight = maxHeight - minHeight;
|
||||
|
||||
//Clamp speed.
|
||||
if (speedKnots > maxKnots) {
|
||||
speedKnots = maxKnots;
|
||||
} else if (speedKnots < minKnots) {
|
||||
speedKnots = minKnots;
|
||||
}
|
||||
|
||||
//How far between the knots bounds is the current speed?
|
||||
double currentDeltaKnots = speedKnots - minKnots;
|
||||
double currentKnotsScalar = currentDeltaKnots / deltaKnots;
|
||||
|
||||
//Thus, how far between the pixel height bounds should the arrow height be?
|
||||
double newHeight = minHeight + (currentKnotsScalar * deltaHeight);
|
||||
|
||||
arrowImage.setFitHeight(newHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the wind speed label according to the specified wind speed.
|
||||
* @param speedKnots Wind speed, in knots.
|
||||
*/
|
||||
private void updateWindSpeedLabel(double speedKnots) {
|
||||
speedLabel.setText(String.format("%.1fkn", speedKnots));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates the control to account for a new wind bearing.
|
||||
* This rotates the arrow according to the bearing.
|
||||
* @param bearing The bearing to use to rotate arrow.
|
||||
*/
|
||||
private void updateWindBearing(Bearing bearing) {
|
||||
|
||||
//We need to display wind-from, so add 180 degrees.
|
||||
Bearing fromBearing = Bearing.fromDegrees(bearing.degrees() + 180d);
|
||||
|
||||
//Rotate the wind arrow.
|
||||
arrowStackPane.setRotate(fromBearing.degrees());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -5,7 +5,6 @@ import javafx.animation.AnimationTimer;
|
||||
import javafx.application.Platform;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.chart.LineChart;
|
||||
import javafx.scene.control.*;
|
||||
@@ -24,10 +23,8 @@ import visualiser.gameController.Keys.ControlKey;
|
||||
import visualiser.gameController.Keys.KeyFactory;
|
||||
import visualiser.model.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
@@ -60,6 +57,11 @@ public class RaceController extends Controller {
|
||||
*/
|
||||
private Sparkline sparkline;
|
||||
|
||||
/**
|
||||
* The arrow controller.
|
||||
*/
|
||||
@FXML private ArrowController arrowController;
|
||||
|
||||
/**
|
||||
* Service for sending keystrokes to server
|
||||
*/
|
||||
@@ -67,8 +69,18 @@ public class RaceController extends Controller {
|
||||
|
||||
|
||||
@FXML private GridPane canvasBase;
|
||||
@FXML private Pane arrow;
|
||||
|
||||
|
||||
@FXML private SplitPane race;
|
||||
|
||||
/**
|
||||
* This is the root node of the arrow control.
|
||||
*/
|
||||
@FXML private Pane arrow;
|
||||
|
||||
/**
|
||||
* This is the pane we place the actual arrow control inside of.
|
||||
*/
|
||||
@FXML private StackPane arrowPane;
|
||||
@FXML private Label timer;
|
||||
@FXML private Label FPS;
|
||||
@@ -118,15 +130,15 @@ public class RaceController extends Controller {
|
||||
//Fps display.
|
||||
initialiseFps(this.visualiserRace);
|
||||
|
||||
//Need to add the included arrow pane to the arrowPane container.
|
||||
initialiseArrow();
|
||||
|
||||
//Information table.
|
||||
initialiseInfoTable(this.visualiserRace);
|
||||
|
||||
//Sparkline.
|
||||
initialiseSparkline(this.visualiserRace);
|
||||
|
||||
//Arrow.
|
||||
initialiseArrow(this.visualiserRace);
|
||||
|
||||
//Race canvas.
|
||||
initialiseRaceCanvas(this.visualiserRace);
|
||||
|
||||
@@ -294,7 +306,7 @@ public class RaceController extends Controller {
|
||||
private void initialiseRaceCanvas(VisualiserRace race) {
|
||||
|
||||
//Create canvas.
|
||||
raceCanvas = new ResizableRaceCanvas(race, arrow.getChildren().get(0));
|
||||
raceCanvas = new ResizableRaceCanvas(race);
|
||||
|
||||
//Set properties.
|
||||
raceCanvas.setMouseTransparent(true);
|
||||
@@ -367,10 +379,11 @@ public class RaceController extends Controller {
|
||||
|
||||
|
||||
/**
|
||||
* Adds the included arrow pane (see arrow.fxml) to the arrowPane (see race.fxml).
|
||||
* Initialises the arrow controller with data from the race to observe.
|
||||
* @param race The race to observe.
|
||||
*/
|
||||
private void initialiseArrow() {
|
||||
arrowPane.getChildren().add(arrow);
|
||||
private void initialiseArrow(VisualiserRace race) {
|
||||
arrowController.setWindProperty(race.windProperty());
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user