mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 14:28:43 +00:00
Added a minimap to the race view.
#implement #story[1273]
This commit is contained in:
@@ -2,7 +2,6 @@ package seng302.visualiser;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -24,7 +23,11 @@ import javafx.scene.transform.Scale;
|
|||||||
import javafx.scene.transform.Translate;
|
import javafx.scene.transform.Translate;
|
||||||
import org.fxyz3d.scene.Skybox;
|
import org.fxyz3d.scene.Skybox;
|
||||||
import seng302.gameServer.messages.RoundingSide;
|
import seng302.gameServer.messages.RoundingSide;
|
||||||
import seng302.model.*;
|
import seng302.model.ClientYacht;
|
||||||
|
import seng302.model.GameKeyBind;
|
||||||
|
import seng302.model.KeyAction;
|
||||||
|
import seng302.model.Limit;
|
||||||
|
import seng302.model.ScaledPoint;
|
||||||
import seng302.model.mark.CompoundMark;
|
import seng302.model.mark.CompoundMark;
|
||||||
import seng302.model.mark.Corner;
|
import seng302.model.mark.Corner;
|
||||||
import seng302.model.mark.Mark;
|
import seng302.model.mark.Mark;
|
||||||
@@ -47,7 +50,7 @@ import seng302.visualiser.fxObjects.assets_3D.ModelType;
|
|||||||
* Collection of animated3D assets that displays a race.
|
* Collection of animated3D assets that displays a race.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class GameView3D extends GameView{
|
public class GameView3D extends GameView {
|
||||||
|
|
||||||
private final double FOV = 60;
|
private final double FOV = 60;
|
||||||
private final double DEFAULT_CAMERA_X = 0;
|
private final double DEFAULT_CAMERA_X = 0;
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ import seng302.visualiser.fxObjects.assets_2D.Marker2D;
|
|||||||
public class MapPreview extends GameView {
|
public class MapPreview extends GameView {
|
||||||
|
|
||||||
private Polygon raceBorder = new CourseBoundary();
|
private Polygon raceBorder = new CourseBoundary();
|
||||||
private Map<Mark, Marker2D> markerObjects;
|
protected Map<Mark, Marker2D> markerObjects;
|
||||||
|
|
||||||
public MapPreview(List<CompoundMark> marks, List<Corner> course, List<Limit> border) {
|
public MapPreview(List<CompoundMark> marks, List<Corner> course, List<Limit> border) {
|
||||||
this.compoundMarks = marks;
|
this.compoundMarks = marks;
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
package seng302.visualiser;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import javafx.application.Platform;
|
||||||
|
import javafx.geometry.Point2D;
|
||||||
|
import javafx.scene.paint.Color;
|
||||||
|
import javafx.scene.shape.Circle;
|
||||||
|
import javafx.scene.shape.Polygon;
|
||||||
|
import seng302.model.ClientYacht;
|
||||||
|
import seng302.model.Limit;
|
||||||
|
import seng302.model.mark.CompoundMark;
|
||||||
|
import seng302.model.mark.Corner;
|
||||||
|
import seng302.model.mark.Mark;
|
||||||
|
import seng302.utilities.Sounds;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by cir27 on 28/09/17.
|
||||||
|
*/
|
||||||
|
public class MiniMap extends MapPreview {
|
||||||
|
|
||||||
|
private HashMap<ClientYacht, Circle> boatIcons = new HashMap<>();
|
||||||
|
private Polygon playerBoat;
|
||||||
|
private double playerRotation;
|
||||||
|
private List<ClientYacht> boats;
|
||||||
|
private ClientYacht player;
|
||||||
|
|
||||||
|
public MiniMap (List<CompoundMark> marks, List<Corner> course, List<Limit> border, List<ClientYacht> boats, ClientYacht player) {
|
||||||
|
super(marks, course, border);
|
||||||
|
this.boats = boats;
|
||||||
|
this.player = player;
|
||||||
|
setBoats(boats);
|
||||||
|
// player.addMarkRoundingListener(this::updateMarkArrows);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBoats(List<ClientYacht> yachts) {
|
||||||
|
for (ClientYacht yacht : yachts) {
|
||||||
|
Circle boatIcon = new Circle(0, 0, 4);
|
||||||
|
boatIcon.setStroke(Color.BLACK);
|
||||||
|
boatIcon.setFill(Color.GRAY);
|
||||||
|
boatIcon.setFill(yacht.getColour());
|
||||||
|
boatIcon.setFill(yacht.getColour());
|
||||||
|
boatIcons.put(yacht, boatIcon);
|
||||||
|
yacht.addLocationListener((boat, lat, lon, heading, sailIn, velocity) -> {
|
||||||
|
Circle bi = boatIcons.get(boat);
|
||||||
|
Point2D p2d = scaledPoint.findScaledXY(lat, lon);
|
||||||
|
bi.setCenterX(p2d.getX());
|
||||||
|
bi.setCenterY(p2d.getY());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
gameObjects.getChildren().addAll(boatIcons.values());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateMarkArrows (ClientYacht yacht, int legNumber) {
|
||||||
|
CompoundMark compoundMark;
|
||||||
|
if (legNumber - 1 >= 0) {
|
||||||
|
Sounds.playMarkRoundingSound();
|
||||||
|
compoundMark = course.get(legNumber-1);
|
||||||
|
for (Mark mark : compoundMark.getMarks()) {
|
||||||
|
markerObjects.get(mark).showNextExitArrow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CompoundMark nextMark = null;
|
||||||
|
if (legNumber < course.size() - 1) {
|
||||||
|
Sounds.playMarkRoundingSound();
|
||||||
|
nextMark = course.get(legNumber);
|
||||||
|
for (Mark mark : nextMark.getMarks()) {
|
||||||
|
markerObjects.get(mark).showNextEnterArrow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (legNumber - 2 >= 0) {
|
||||||
|
CompoundMark lastMark = course.get(Math.max(0, legNumber - 2));
|
||||||
|
if (lastMark != nextMark) {
|
||||||
|
for (Mark mark : lastMark.getMarks()) {
|
||||||
|
markerObjects.get(mark).hideAllArrows();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,67 +4,38 @@ import com.jfoenix.controls.JFXButton;
|
|||||||
import com.jfoenix.controls.JFXDialog;
|
import com.jfoenix.controls.JFXDialog;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import javafx.animation.RotateTransition;
|
import javafx.animation.RotateTransition;
|
||||||
import javafx.animation.Timeline;
|
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.property.ReadOnlyBooleanProperty;
|
import javafx.beans.property.ReadOnlyBooleanProperty;
|
||||||
import javafx.collections.FXCollections;
|
|
||||||
import javafx.collections.ListChangeListener;
|
|
||||||
import javafx.collections.ObservableList;
|
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
import javafx.geometry.Point2D;
|
|
||||||
import javafx.scene.Scene;
|
|
||||||
import javafx.scene.SubScene;
|
import javafx.scene.SubScene;
|
||||||
import javafx.scene.chart.LineChart;
|
|
||||||
import javafx.scene.chart.NumberAxis;
|
|
||||||
import javafx.scene.chart.XYChart.Series;
|
|
||||||
import javafx.scene.control.Button;
|
|
||||||
import javafx.scene.control.CheckBox;
|
|
||||||
import javafx.scene.control.ComboBox;
|
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.control.Slider;
|
|
||||||
import javafx.scene.control.TextField;
|
import javafx.scene.control.TextField;
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
import javafx.scene.image.ImageView;
|
import javafx.scene.image.ImageView;
|
||||||
import javafx.scene.layout.AnchorPane;
|
import javafx.scene.layout.AnchorPane;
|
||||||
import javafx.scene.layout.GridPane;
|
|
||||||
import javafx.scene.layout.Pane;
|
import javafx.scene.layout.Pane;
|
||||||
import javafx.scene.layout.StackPane;
|
import javafx.scene.layout.StackPane;
|
||||||
import javafx.scene.layout.VBox;
|
|
||||||
import javafx.scene.paint.Color;
|
|
||||||
import javafx.scene.paint.Paint;
|
import javafx.scene.paint.Paint;
|
||||||
import javafx.scene.shape.Line;
|
|
||||||
import javafx.scene.shape.Polyline;
|
|
||||||
import javafx.scene.text.Text;
|
|
||||||
import javafx.stage.Stage;
|
|
||||||
import javafx.stage.StageStyle;
|
|
||||||
import javafx.util.Duration;
|
import javafx.util.Duration;
|
||||||
import seng302.model.ClientYacht;
|
import seng302.model.ClientYacht;
|
||||||
import seng302.model.RaceState;
|
import seng302.model.RaceState;
|
||||||
import seng302.model.mark.CompoundMark;
|
|
||||||
import seng302.model.mark.Mark;
|
|
||||||
import seng302.model.stream.xml.parser.RaceXMLData;
|
import seng302.model.stream.xml.parser.RaceXMLData;
|
||||||
import seng302.model.token.TokenType;
|
import seng302.model.token.TokenType;
|
||||||
import seng302.utilities.Sounds;
|
import seng302.utilities.Sounds;
|
||||||
import seng302.visualiser.GameView3D;
|
import seng302.visualiser.GameView3D;
|
||||||
import seng302.visualiser.controllers.annotations.ImportantAnnotationController;
|
import seng302.visualiser.MiniMap;
|
||||||
import seng302.visualiser.controllers.annotations.ImportantAnnotationDelegate;
|
|
||||||
import seng302.visualiser.controllers.annotations.ImportantAnnotationsState;
|
|
||||||
import seng302.visualiser.controllers.dialogs.FinishDialogController;
|
import seng302.visualiser.controllers.dialogs.FinishDialogController;
|
||||||
import seng302.visualiser.fxObjects.ChatHistory;
|
import seng302.visualiser.fxObjects.ChatHistory;
|
||||||
import seng302.visualiser.fxObjects.assets_2D.WindArrow;
|
|
||||||
import seng302.visualiser.fxObjects.assets_3D.BoatObject;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controller class that manages the display of a race
|
* Controller class that manages the display of a race
|
||||||
*/
|
*/
|
||||||
public class RaceViewController extends Thread implements ImportantAnnotationDelegate {
|
public class RaceViewController extends Thread {
|
||||||
|
|
||||||
private final int CHAT_LIMIT = 128;
|
private final int CHAT_LIMIT = 128;
|
||||||
private static final Double ICON_BLINK_TIMEOUT_RATIO = 0.6;
|
private static final Double ICON_BLINK_TIMEOUT_RATIO = 0.6;
|
||||||
@@ -75,39 +46,17 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
@FXML
|
@FXML
|
||||||
private ImageView loadingScreen;
|
private ImageView loadingScreen;
|
||||||
@FXML
|
@FXML
|
||||||
private Pane basePane;
|
|
||||||
@FXML
|
|
||||||
private JFXButton chatSend;
|
private JFXButton chatSend;
|
||||||
@FXML
|
@FXML
|
||||||
private Pane chatHistoryHolder;
|
private Pane chatHistoryHolder;
|
||||||
@FXML
|
@FXML
|
||||||
private TextField chatInput;
|
private TextField chatInput;
|
||||||
@FXML
|
@FXML
|
||||||
private LineChart<String, Double> raceSparkLine;
|
|
||||||
@FXML
|
|
||||||
private NumberAxis sparklineYAxis;
|
|
||||||
@FXML
|
|
||||||
private VBox positionVbox;
|
|
||||||
@FXML
|
|
||||||
private CheckBox toggleFps;
|
|
||||||
@FXML
|
|
||||||
private Label timerLabel;
|
private Label timerLabel;
|
||||||
@FXML
|
@FXML
|
||||||
private StackPane contentStackPane;
|
private StackPane contentStackPane;
|
||||||
|
|
||||||
private GridPane contentGridPane;
|
|
||||||
@FXML
|
@FXML
|
||||||
private AnchorPane rvAnchorPane;
|
private Pane miniMapPane;
|
||||||
@FXML
|
|
||||||
private AnchorPane windArrowHolder;
|
|
||||||
@FXML
|
|
||||||
private Slider annotationSlider;
|
|
||||||
@FXML
|
|
||||||
private Button selectAnnotationBtn;
|
|
||||||
@FXML
|
|
||||||
private ComboBox<ClientYacht> yachtSelectionComboBox;
|
|
||||||
@FXML
|
|
||||||
private Text fpsDisplay;
|
|
||||||
@FXML
|
@FXML
|
||||||
private ImageView windImageView;
|
private ImageView windImageView;
|
||||||
@FXML
|
@FXML
|
||||||
@@ -118,33 +67,24 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
private Label positionLabel, boatSpeedLabel, boatHeadingLabel;
|
private Label positionLabel, boatSpeedLabel, boatHeadingLabel;
|
||||||
@FXML
|
@FXML
|
||||||
private ImageView velocityIcon, handlingIcon, windWalkerIcon, bumperIcon, badRandomIcon;
|
private ImageView velocityIcon, handlingIcon, windWalkerIcon, bumperIcon, badRandomIcon;
|
||||||
|
@FXML
|
||||||
|
private JFXButton miniMapButton;
|
||||||
|
|
||||||
//Race Data
|
|
||||||
private Map<Integer, ClientYacht> participants;
|
|
||||||
private Map<Integer, CompoundMark> markers;
|
|
||||||
private RaceXMLData courseData;
|
|
||||||
private GameView3D gameView;
|
private GameView3D gameView;
|
||||||
private RaceState raceState;
|
private RaceState raceState;
|
||||||
|
|
||||||
private ChatHistory chatHistory;
|
private ChatHistory chatHistory;
|
||||||
|
|
||||||
private Timeline timerTimeline;
|
|
||||||
private Timer timer = new Timer();
|
private Timer timer = new Timer();
|
||||||
private List<Series<String, Double>> sparkLineData = new ArrayList<>();
|
|
||||||
private ImportantAnnotationsState importantAnnotations;
|
|
||||||
private Polyline windArrow = new WindArrow(Color.LIGHTGRAY);
|
|
||||||
private ObservableList<ClientYacht> selectionComboBoxList = FXCollections.observableArrayList();
|
|
||||||
private ClientYacht player;
|
private ClientYacht player;
|
||||||
private JFXDialog finishScreenDialog;
|
private JFXDialog finishScreenDialog;
|
||||||
private FinishDialogController finishDialogController;
|
private FinishDialogController finishDialogController;
|
||||||
|
|
||||||
//Icon stuff
|
|
||||||
private Timer blinkingTimer = new Timer();
|
private Timer blinkingTimer = new Timer();
|
||||||
private ImageView iconToDisplay;
|
private ImageView iconToDisplay;
|
||||||
|
|
||||||
private Double lastWindDirection;
|
private Double lastWindDirection;
|
||||||
|
private MiniMap miniMap;
|
||||||
|
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
|
miniMapPane.setVisible(false);
|
||||||
|
miniMapButton.setVisible(false);
|
||||||
contentStackPane.setVisible(false);
|
contentStackPane.setVisible(false);
|
||||||
Image loadingImage = new Image("PP.png");
|
Image loadingImage = new Image("PP.png");
|
||||||
loadingScreen.setImage(loadingImage);
|
loadingScreen.setImage(loadingImage);
|
||||||
@@ -204,7 +144,8 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
public void showView(){
|
public void showView(){
|
||||||
loadingScreenPane.setVisible(false);
|
loadingScreenPane.setVisible(false);
|
||||||
contentStackPane.setVisible(true);
|
contentStackPane.setVisible(true);
|
||||||
|
miniMapPane.setVisible(true);
|
||||||
|
miniMapButton.setVisible(true);
|
||||||
Platform.runLater(new Runnable() {
|
Platform.runLater(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@@ -238,31 +179,35 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
Map<Integer, ClientYacht> participants, RaceXMLData raceData, RaceState raceState,
|
Map<Integer, ClientYacht> participants, RaceXMLData raceData, RaceState raceState,
|
||||||
ClientYacht player) {
|
ClientYacht player) {
|
||||||
|
|
||||||
this.participants = participants;
|
|
||||||
this.courseData = raceData;
|
|
||||||
this.markers = raceData.getCompoundMarks();
|
|
||||||
this.raceState = raceState;
|
this.raceState = raceState;
|
||||||
this.player = player;
|
this.player = player;
|
||||||
|
|
||||||
raceState.getPlayerPositions().addListener((ListChangeListener<ClientYacht>) c -> {
|
|
||||||
while (c.next()) {
|
|
||||||
if (c.wasPermutated()) {
|
|
||||||
updateOrder(raceState.getPlayerPositions());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
player.addPowerUpListener(this::displayPowerUpIcon);
|
player.addPowerUpListener(this::displayPowerUpIcon);
|
||||||
player.addPowerDownListener(this::removeIcon);
|
player.addPowerDownListener(this::removeIcon);
|
||||||
|
|
||||||
updateOrder(raceState.getPlayerPositions());
|
|
||||||
gameView = new GameView3D();
|
gameView = new GameView3D();
|
||||||
|
miniMap = new MiniMap(
|
||||||
|
new ArrayList<>(raceData.getCompoundMarks().values()),
|
||||||
|
raceData.getMarkSequence(), raceData.getCourseLimit(),
|
||||||
|
new ArrayList<>(participants.values()), player
|
||||||
|
);
|
||||||
|
miniMapButton.setOnMouseClicked((event) -> {
|
||||||
|
if (miniMapPane.visibleProperty().get()) {
|
||||||
|
miniMapPane.setVisible(false);
|
||||||
|
miniMapButton.setText("✕");
|
||||||
|
} else {
|
||||||
|
miniMapPane.setVisible(true);
|
||||||
|
miniMapButton.setText("✓");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
contentStackPane.getChildren().add(0, gameView.getAssets());
|
contentStackPane.getChildren().add(0, gameView.getAssets());
|
||||||
((SubScene) gameView.getAssets()).widthProperty()
|
((SubScene) gameView.getAssets()).widthProperty()
|
||||||
.bind(ViewManager.getInstance().getStage().widthProperty());
|
.bind(ViewManager.getInstance().getStage().widthProperty());
|
||||||
((SubScene) gameView.getAssets()).heightProperty()
|
((SubScene) gameView.getAssets()).heightProperty()
|
||||||
.bind(ViewManager.getInstance().getStage().heightProperty());
|
.bind(ViewManager.getInstance().getStage().heightProperty());
|
||||||
|
miniMapPane.getChildren().add(miniMap.getAssets());
|
||||||
});
|
});
|
||||||
gameView.setBoats(new ArrayList<>(participants.values()));
|
gameView.setBoats(new ArrayList<>(participants.values()));
|
||||||
gameView.updateBorder(raceData.getCourseLimit());
|
gameView.updateBorder(raceData.getCourseLimit());
|
||||||
@@ -350,45 +295,6 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The important annotations have been changed, update this view
|
|
||||||
*
|
|
||||||
* @param importantAnnotationsState The current state of the selected annotations
|
|
||||||
*/
|
|
||||||
public void importantAnnotationsChanged(ImportantAnnotationsState importantAnnotationsState) {
|
|
||||||
this.importantAnnotations = importantAnnotationsState;
|
|
||||||
setAnnotations((int) annotationSlider.getValue()); // Refresh the displayed annotations
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads the "select annotations" view in a new window
|
|
||||||
*/
|
|
||||||
private void loadSelectAnnotationView() {
|
|
||||||
try {
|
|
||||||
FXMLLoader fxmlLoader = new FXMLLoader();
|
|
||||||
Stage stage = new Stage();
|
|
||||||
// Set controller
|
|
||||||
ImportantAnnotationController controller = new ImportantAnnotationController(
|
|
||||||
this, stage
|
|
||||||
);
|
|
||||||
fxmlLoader.setController(controller);
|
|
||||||
// Load FXML and set CSS
|
|
||||||
fxmlLoader.setLocation(
|
|
||||||
getClass().getResource("/views/importantAnnotationSelectView.fxml")
|
|
||||||
);
|
|
||||||
Scene scene = new Scene(fxmlLoader.load(), 469, 298);
|
|
||||||
scene.getStylesheets().add(getClass().getResource("/css/master.css").toString());
|
|
||||||
stage.initStyle(StageStyle.UNDECORATED);
|
|
||||||
stage.setScene(scene);
|
|
||||||
stage.show();
|
|
||||||
controller.loadState(importantAnnotations);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialises a timer which updates elements of the RaceView such as wind direction, yacht
|
* Initialises a timer which updates elements of the RaceView such as wind direction, yacht
|
||||||
* orderings etc.. which are dependent on the info from the stream parser constantly.
|
* orderings etc.. which are dependent on the info from the stream parser constantly.
|
||||||
@@ -406,35 +312,6 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
}, 0, 1000);
|
}, 0, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Iterates over all corners until ones SeqID matches with the yachts current leg number.
|
|
||||||
* Then it gets the compoundMarkID of that corner and uses it to fetch the appropriate mark
|
|
||||||
* Returns null if no next mark found.
|
|
||||||
* @param bg The BoatGroup to find the next mark of
|
|
||||||
* @return The next Mark or null if none found
|
|
||||||
*/
|
|
||||||
private Mark getNextMark(BoatObject bg) {
|
|
||||||
// TODO: 1/08/17 Move to GameView
|
|
||||||
//
|
|
||||||
// Integer legNumber = bg.getClientYacht().getLegNumber();
|
|
||||||
// List<Corner> markSequence = courseData.getMarkSequence();
|
|
||||||
//
|
|
||||||
// if (legNumber == 0) {
|
|
||||||
// return null;
|
|
||||||
// } else if (legNumber == markSequence.size() - 1) {
|
|
||||||
// return null;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// for (Corner corner : markSequence) {
|
|
||||||
// if (legNumber + 2 == corner.getSeqID()) {
|
|
||||||
// return courseData.getCompoundMarks().get(corner.getCompoundMarkID());
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return null;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the wind direction arrow and text as from info from the StreamParser
|
* Updates the wind direction arrow and text as from info from the StreamParser
|
||||||
* @param direction the from north angle of the wind.
|
* @param direction the from north angle of the wind.
|
||||||
@@ -516,226 +393,6 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
boatHeadingLabel.setText(String.format("Boat Heading:\n%.1f°", player.getHeading()));
|
boatHeadingLabel.setText(String.format("Boat Heading:\n%.1f°", player.getHeading()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the order of the yachts as from the StreamParser and sets them in the yacht order
|
|
||||||
* section
|
|
||||||
*/
|
|
||||||
private void updateOrder(ObservableList<ClientYacht> yachts) {
|
|
||||||
// List<Text> vboxEntries = new ArrayList<>();
|
|
||||||
//
|
|
||||||
// for (int i = 0; i < yachts.size(); i++) {
|
|
||||||
//// System.out.println("yacht == null " + String.valueOf(yacht == null));
|
|
||||||
// if (yachts.get(i).getBoatStatus() == BoatStatus.FINISHED
|
|
||||||
// .getCode()) { // 3 is finish status
|
|
||||||
// Text textToAdd = new Text(i + 1 + ". " +
|
|
||||||
// yachts.get(i).getShortName() + " (Finished)");
|
|
||||||
// textToAdd.setFill(Paint.valueOf("#d3d3d3"));
|
|
||||||
// vboxEntries.add(textToAdd);
|
|
||||||
//
|
|
||||||
// } else {
|
|
||||||
// Text textToAdd = new Text(i + 1 + ". " +
|
|
||||||
// yachts.get(i).getShortName() + " ");
|
|
||||||
// textToAdd.setFill(Paint.valueOf("#d3d3d3"));
|
|
||||||
// textToAdd.setStyle("");
|
|
||||||
// vboxEntries.add(textToAdd);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// Platform.runLater(() ->
|
|
||||||
// positionVbox.getChildren().setAll(vboxEntries)
|
|
||||||
// );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void updateLaylines(BoatObject bg) {
|
|
||||||
// TODO: 1/08/17 move to GameView
|
|
||||||
//
|
|
||||||
// Mark nextMark = getNextMark(bg);
|
|
||||||
// Boolean isUpwind = null;
|
|
||||||
// // Can only calc leg direction if there is a next mark and it is a gate mark
|
|
||||||
// if (nextMark != null) {
|
|
||||||
// if (nextMark instanceof GateMark) {
|
|
||||||
// if (bg.isUpwindLeg(gameViewController, nextMark)) {
|
|
||||||
// isUpwind = true;
|
|
||||||
// } else {
|
|
||||||
// isUpwind = false;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// for(MarkObject mg : gameViewController.getMarkGroups()) {
|
|
||||||
//
|
|
||||||
// mg.removeLaylines();
|
|
||||||
//
|
|
||||||
// if (mg.getMainMark().getId() == nextMark.getId()) {
|
|
||||||
//
|
|
||||||
// SingleMark singleMark1 = ((GateMark) nextMark).getSingleMark1();
|
|
||||||
// SingleMark singleMark2 = ((GateMark) nextMark).getSingleMark2();
|
|
||||||
// Point2D markPoint1 = gameViewController
|
|
||||||
// .findScaledXY(singleMark1.getLatitude(), singleMark1.getLongitude());
|
|
||||||
// Point2D markPoint2 = gameViewController
|
|
||||||
// .findScaledXY(singleMark2.getLatitude(), singleMark2.getLongitude());
|
|
||||||
// HashMap<Double, Double> angleAndSpeed;
|
|
||||||
// if (isUpwind) {
|
|
||||||
// angleAndSpeed = PolarTable.getOptimalUpwindVMG(StreamParser.getWindSpeed());
|
|
||||||
// } else {
|
|
||||||
// angleAndSpeed = PolarTable.getOptimalDownwindVMG(StreamParser.getWindSpeed());
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Double resultingAngle = angleAndSpeed.keySet().iterator().next();
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Point2D yachtCurrentPos = new Point2D(bg.getBoatLayoutX(), bg.getBoatLayoutY());
|
|
||||||
// Point2D gateMidPoint = markPoint1.midpoint(markPoint2);
|
|
||||||
// Integer lineFuncResult = GeoUtility.lineFunction(yachtCurrentPos, gateMidPoint, markPoint2);
|
|
||||||
// Line rightLayline = new Line();
|
|
||||||
// Line leftLayline = new Line();
|
|
||||||
// if (lineFuncResult == 1) {
|
|
||||||
// rightLayline = makeRightLayline(markPoint2, 180 - resultingAngle, StreamParser.getWindDirection());
|
|
||||||
// leftLayline = makeLeftLayline(markPoint1, 180 - resultingAngle, StreamParser.getWindDirection());
|
|
||||||
// } else if (lineFuncResult == -1) {
|
|
||||||
// rightLayline = makeRightLayline(markPoint1, 180 - resultingAngle, StreamParser.getWindDirection());
|
|
||||||
// leftLayline = makeLeftLayline(markPoint2, 180 - resultingAngle, StreamParser.getWindDirection());
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// leftLayline.setStrokeWidth(0.5);
|
|
||||||
// leftLayline.setStroke(bg.getBoat().getColour());
|
|
||||||
//
|
|
||||||
// rightLayline.setStrokeWidth(0.5);
|
|
||||||
// rightLayline.setStroke(bg.getBoat().getColour());
|
|
||||||
//
|
|
||||||
// bg.setLaylines(leftLayline, rightLayline);
|
|
||||||
// mg.addLaylines(leftLayline, rightLayline);
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private Point2D getPointRotation(Point2D ref, Double distance, Double angle) {
|
|
||||||
Double newX = ref.getX() + (ref.getX() + distance - ref.getX()) * Math.cos(angle)
|
|
||||||
- (ref.getY() + distance - ref.getY()) * Math.sin(angle);
|
|
||||||
Double newY = ref.getY() + (ref.getX() + distance - ref.getX()) * Math.sin(angle)
|
|
||||||
+ (ref.getY() + distance - ref.getY()) * Math.cos(angle);
|
|
||||||
|
|
||||||
return new Point2D(newX, newY);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Line makeLeftLayline(Point2D startPoint, Double layLineAngle, Double baseAngle) {
|
|
||||||
Point2D ep = getPointRotation(startPoint, 50.0, baseAngle + layLineAngle);
|
|
||||||
Line line = new Line(startPoint.getX(), startPoint.getY(), ep.getX(), ep.getY());
|
|
||||||
return line;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Line makeRightLayline(Point2D startPoint, Double layLineAngle, Double baseAngle) {
|
|
||||||
|
|
||||||
Point2D ep = getPointRotation(startPoint, 50.0, baseAngle - layLineAngle);
|
|
||||||
Line line = new Line(startPoint.getX(), startPoint.getY(), ep.getX(), ep.getY());
|
|
||||||
return line;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialised the combo box with any yachts currently in the race and adds the required listener
|
|
||||||
* for the combobox to take action upon selection
|
|
||||||
*/
|
|
||||||
private void initialiseBoatSelectionComboBox() {
|
|
||||||
// yachtSelectionComboBox.setItems(
|
|
||||||
// FXCollections.observableArrayList(participants.values())
|
|
||||||
// );
|
|
||||||
// //Null check is if the listener is fired but nothing selected
|
|
||||||
// yachtSelectionComboBox.valueProperty().addListener((obs, lastSelection, selectedBoat) -> {
|
|
||||||
// if (selectedBoat != null) {
|
|
||||||
// gameView.selectBoat(selectedBoat);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
//TODO uncomment out
|
|
||||||
// selectionComboBoxList.setAll(participants.values());
|
|
||||||
// yachtSelectionComboBox.setItems(selectionComboBoxList);
|
|
||||||
// yachtSelectionComboBox.valueProperty().addListener((obs, lastSelection, selectedBoat) -> {
|
|
||||||
// if (selectedBoat != null) {
|
|
||||||
// gameView.selectBoat(selectedBoat);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Display the list of yachts in the order they finished the race
|
|
||||||
*/
|
|
||||||
private void loadRaceResultView() {
|
|
||||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("/views/FinishView.fxml"));
|
|
||||||
|
|
||||||
try {
|
|
||||||
contentGridPane.getChildren().removeAll();
|
|
||||||
contentGridPane.getChildren().clear();
|
|
||||||
contentGridPane.getChildren().addAll((Pane) loader.load());
|
|
||||||
|
|
||||||
} catch (javafx.fxml.LoadException e) {
|
|
||||||
System.err.println(e.getCause().toString());
|
|
||||||
} catch (IOException e) {
|
|
||||||
System.err.println(e.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getMillisToFormattedTime(long milliseconds) {
|
|
||||||
return String.format("%02d:%02d:%02d",
|
|
||||||
TimeUnit.MILLISECONDS.toHours(milliseconds),
|
|
||||||
TimeUnit.MILLISECONDS.toMinutes(milliseconds) % 60, //Modulus 60 minutes per hour
|
|
||||||
TimeUnit.MILLISECONDS.toSeconds(milliseconds) % 60 //Modulus 60 seconds per minute
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setAnnotations(Integer annotationLevel) {
|
|
||||||
// switch (annotationLevel) {
|
|
||||||
// // No Annotations
|
|
||||||
// case 0:
|
|
||||||
// gameView.setAnnotationVisibilities(
|
|
||||||
// false, false, false, false, false, false
|
|
||||||
// );
|
|
||||||
// break;
|
|
||||||
// // Important Annotations
|
|
||||||
// case 1:
|
|
||||||
// gameView.setAnnotationVisibilities(
|
|
||||||
// importantAnnotations.getAnnotationState(Annotation.NAME),
|
|
||||||
// importantAnnotations.getAnnotationState(Annotation.SPEED),
|
|
||||||
// importantAnnotations.getAnnotationState(Annotation.ESTTIMETONEXTMARK),
|
|
||||||
// importantAnnotations.getAnnotationState(Annotation.LEGTIME),
|
|
||||||
// importantAnnotations.getAnnotationState(Annotation.TRACK),
|
|
||||||
// importantAnnotations.getAnnotationState(Annotation.WAKE)
|
|
||||||
// );
|
|
||||||
// break;
|
|
||||||
// // All Annotations
|
|
||||||
// case 2:
|
|
||||||
// gameView.setAnnotationVisibilities(
|
|
||||||
// true, true, true, true, true, true
|
|
||||||
// );
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets all the annotations of the selected yacht to be visible and all others to be hidden
|
|
||||||
*
|
|
||||||
* @param yacht The yacht for which we want to view all annotations
|
|
||||||
*/
|
|
||||||
private void setSelectedBoat(ClientYacht yacht) {
|
|
||||||
// for (BoatObject bg : gameViewController.getBoatGroups()) {
|
|
||||||
// //We need to iterate over all race groups to get the matching yacht group belonging to this yacht if we
|
|
||||||
// //are to toggle its annotations, there is no other backwards knowledge of a yacht to its yachtgroup.
|
|
||||||
// if (bg.getBoat().getHullID().equals(yacht.getHullID())) {
|
|
||||||
//// updateLaylines(bg);
|
|
||||||
// bg.setIsSelected(true);
|
|
||||||
//// selectedBoat = yacht;
|
|
||||||
// } else {
|
|
||||||
// bg.setIsSelected(false);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateTokens(RaceXMLData raceData) {
|
public void updateTokens(RaceXMLData raceData) {
|
||||||
gameView.updateTokens(raceData.getTokens());
|
gameView.updateTokens(raceData.getTokens());
|
||||||
|
|||||||
@@ -29,11 +29,11 @@ public class MarkArrowFactory {
|
|||||||
STARBOARD,
|
STARBOARD,
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final double MARK_ARROW_SEPARATION = 15;
|
public static final double MARK_ARROW_SEPARATION = 8;
|
||||||
public static final double ARROW_LENGTH = 75;
|
public static final double ARROW_LENGTH = 20;
|
||||||
public static final double ARROW_HEAD_DEPTH = 10;
|
public static final double ARROW_HEAD_DEPTH = 5;
|
||||||
public static final double ARROW_HEAD_WIDTH = 6;
|
public static final double ARROW_HEAD_WIDTH = 3;
|
||||||
public static final double STROKE_WIDTH = 3;
|
public static final double STROKE_WIDTH = 1;
|
||||||
|
|
||||||
public static Model constructEntryArrow3D (
|
public static Model constructEntryArrow3D (
|
||||||
RoundingSide roundingSide, double angle, ModelType type) {
|
RoundingSide roundingSide, double angle, ModelType type) {
|
||||||
|
|||||||
@@ -60,8 +60,10 @@ public class BoatModel extends Model {
|
|||||||
*/
|
*/
|
||||||
public void changeColour(Color newColour) {
|
public void changeColour(Color newColour) {
|
||||||
changeColourChild(HULL_INDEX, newColour);
|
changeColourChild(HULL_INDEX, newColour);
|
||||||
|
if (meshType != BoatMeshType.PARROT) {
|
||||||
changeColourChild(MAST_INDEX, newColour);
|
changeColourChild(MAST_INDEX, newColour);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void changeColourChild(int index, Color newColour) {
|
private void changeColourChild(int index, Color newColour) {
|
||||||
MeshView meshView = getMeshViewChild(index);
|
MeshView meshView = getMeshViewChild(index);
|
||||||
|
|||||||
@@ -117,12 +117,7 @@ public class ModelFactory {
|
|||||||
Group boatAssets = new Group();
|
Group boatAssets = new Group();
|
||||||
MeshView hull = importSTL(boatType.hullFile);
|
MeshView hull = importSTL(boatType.hullFile);
|
||||||
hull.setMaterial(new PhongMaterial(primaryColour));
|
hull.setMaterial(new PhongMaterial(primaryColour));
|
||||||
MeshView sail = importSTL(boatType.sailFile);
|
boatAssets.getChildren().addAll(hull);
|
||||||
sail.setMaterial(
|
|
||||||
new PhongMaterial(boatType == BoatMeshType.PARROT ? Color.BLACK : Color.WHITE)
|
|
||||||
);
|
|
||||||
|
|
||||||
boatAssets.getChildren().addAll(hull, sail);
|
|
||||||
|
|
||||||
if (boatType.mastFile != null) {
|
if (boatType.mastFile != null) {
|
||||||
MeshView mast = importSTL(boatType.mastFile);
|
MeshView mast = importSTL(boatType.mastFile);
|
||||||
@@ -130,11 +125,17 @@ public class ModelFactory {
|
|||||||
boatAssets.getChildren().add(mast);
|
boatAssets.getChildren().add(mast);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (boatType.jibFile != null) {
|
MeshView sail = importSTL(boatType.sailFile);
|
||||||
MeshView jib = importSTL(boatType.jibFile);
|
|
||||||
sail.setMaterial(
|
sail.setMaterial(
|
||||||
new PhongMaterial(boatType == BoatMeshType.PARROT ? Color.DARKGRAY : Color.WHITE)
|
new PhongMaterial(boatType == BoatMeshType.PARROT ? Color.DARKGRAY : Color.WHITE)
|
||||||
);
|
);
|
||||||
|
boatAssets.getChildren().addAll(sail);
|
||||||
|
|
||||||
|
if (boatType.jibFile != null) {
|
||||||
|
MeshView jib = importSTL(boatType.jibFile);
|
||||||
|
jib.setMaterial(
|
||||||
|
new PhongMaterial(boatType == BoatMeshType.PARROT ? Color.BLACK : Color.WHITE)
|
||||||
|
);
|
||||||
boatAssets.getChildren().add(jib);
|
boatAssets.getChildren().add(jib);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
<?import javafx.scene.*?>
|
|
||||||
<?import javafx.scene.shape.*?>
|
|
||||||
<?import com.jfoenix.controls.*?>
|
<?import com.jfoenix.controls.*?>
|
||||||
<?import java.lang.*?>
|
<?import java.lang.*?>
|
||||||
<?import javafx.geometry.*?>
|
<?import javafx.geometry.*?>
|
||||||
@@ -25,267 +23,206 @@
|
|||||||
|
|
||||||
<StackPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="800.0" prefWidth="1200.0" style="-fx-background-color: skyblue;" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.visualiser.controllers.RaceViewController">
|
<StackPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="800.0" prefWidth="1200.0" style="-fx-background-color: skyblue;" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.visualiser.controllers.RaceViewController">
|
||||||
<children>
|
<children>
|
||||||
<StackPane fx:id="contentStackPane" maxHeight="1.7976931348623157E308"
|
<StackPane fx:id="contentStackPane" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="800.0" prefWidth="1200.0" style="-fx-background-color: skyblue;" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1">
|
||||||
maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="800.0"
|
|
||||||
prefWidth="1200.0" style="-fx-background-color: skyblue;" xmlns="http://javafx.com/javafx/8.0.111"
|
|
||||||
xmlns:fx="http://javafx.com/fxml/1">
|
|
||||||
<children>
|
<children>
|
||||||
<GridPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
|
<GridPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="800.0" prefWidth="1200.0">
|
||||||
prefHeight="800.0" prefWidth="1200.0">
|
|
||||||
<columnConstraints>
|
<columnConstraints>
|
||||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="250.0" minWidth="250.0"
|
<ColumnConstraints hgrow="SOMETIMES" maxWidth="250.0" minWidth="250.0" prefWidth="250.0" />
|
||||||
prefWidth="250.0"/>
|
<ColumnConstraints hgrow="SOMETIMES" maxWidth="1.7976931348623157E308" />
|
||||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="1.7976931348623157E308"/>
|
<ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity" minWidth="400.0" prefWidth="400.0" />
|
||||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity" minWidth="400.0"
|
<ColumnConstraints />
|
||||||
prefWidth="400.0"/>
|
|
||||||
</columnConstraints>
|
</columnConstraints>
|
||||||
<rowConstraints>
|
<rowConstraints>
|
||||||
<RowConstraints maxHeight="70.0" minHeight="70.0" prefHeight="70.0"
|
<RowConstraints maxHeight="70.0" minHeight="70.0" prefHeight="70.0" vgrow="SOMETIMES" />
|
||||||
vgrow="SOMETIMES"/>
|
<RowConstraints maxHeight="1.7976931348623157E308" vgrow="SOMETIMES" />
|
||||||
<RowConstraints maxHeight="1.7976931348623157E308" vgrow="SOMETIMES"/>
|
<RowConstraints maxHeight="250.0" minHeight="250.0" prefHeight="250.0" valignment="BOTTOM" vgrow="SOMETIMES" />
|
||||||
<RowConstraints maxHeight="250.0" minHeight="250.0" prefHeight="250.0"
|
|
||||||
valignment="BOTTOM" vgrow="SOMETIMES"/>
|
|
||||||
</rowConstraints>
|
</rowConstraints>
|
||||||
<children>
|
<children>
|
||||||
<GridPane id="timerGrid" fx:id="timerGrid" prefWidth="192.0" styleClass="timer">
|
<GridPane id="timerGrid" fx:id="timerGrid" prefWidth="192.0" styleClass="timer">
|
||||||
<columnConstraints>
|
<columnConstraints>
|
||||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="50.0" minWidth="50.0"
|
<ColumnConstraints hgrow="SOMETIMES" maxWidth="50.0" minWidth="50.0" prefWidth="50.0" />
|
||||||
prefWidth="50.0"/>
|
<ColumnConstraints hgrow="SOMETIMES" maxWidth="135.0" minWidth="135.0" prefWidth="135.0" />
|
||||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="135.0" minWidth="135.0"
|
|
||||||
prefWidth="135.0"/>
|
|
||||||
</columnConstraints>
|
</columnConstraints>
|
||||||
<rowConstraints>
|
<rowConstraints>
|
||||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
|
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||||
</rowConstraints>
|
</rowConstraints>
|
||||||
<opaqueInsets>
|
<opaqueInsets>
|
||||||
<Insets/>
|
<Insets />
|
||||||
</opaqueInsets>
|
</opaqueInsets>
|
||||||
<GridPane.margin>
|
<GridPane.margin>
|
||||||
<Insets left="10.0" right="200.0" top="10.0"/>
|
<Insets left="10.0" right="200.0" top="10.0" />
|
||||||
</GridPane.margin>
|
</GridPane.margin>
|
||||||
<children>
|
<children>
|
||||||
<ImageView fitHeight="40.0" fitWidth="40.0" pickOnBounds="true"
|
<ImageView fitHeight="40.0" fitWidth="40.0" pickOnBounds="true" preserveRatio="true" GridPane.halignment="CENTER" GridPane.valignment="CENTER">
|
||||||
preserveRatio="true" GridPane.halignment="CENTER"
|
|
||||||
GridPane.valignment="CENTER">
|
|
||||||
<image>
|
<image>
|
||||||
<Image url="@../images/timer.png"/>
|
<Image url="@../images/timer.png" />
|
||||||
</image>
|
</image>
|
||||||
<GridPane.margin>
|
<GridPane.margin>
|
||||||
<Insets/>
|
<Insets />
|
||||||
</GridPane.margin>
|
</GridPane.margin>
|
||||||
</ImageView>
|
</ImageView>
|
||||||
<Label fx:id="timerLabel" text="00:03:34" GridPane.columnIndex="1"
|
<Label fx:id="timerLabel" text="00:03:34" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.valignment="CENTER">
|
||||||
GridPane.halignment="CENTER" GridPane.valignment="CENTER">
|
|
||||||
<font>
|
<font>
|
||||||
<Font size="21.0"/>
|
<Font size="21.0" />
|
||||||
</font>
|
</font>
|
||||||
<GridPane.margin>
|
<GridPane.margin>
|
||||||
<Insets/>
|
<Insets />
|
||||||
</GridPane.margin>
|
</GridPane.margin>
|
||||||
</Label>
|
</Label>
|
||||||
</children>
|
</children>
|
||||||
</GridPane>
|
</GridPane>
|
||||||
<GridPane GridPane.columnIndex="2">
|
<GridPane GridPane.columnIndex="2">
|
||||||
<columnConstraints>
|
<columnConstraints>
|
||||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
|
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
|
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||||
</columnConstraints>
|
</columnConstraints>
|
||||||
<rowConstraints>
|
<rowConstraints>
|
||||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
|
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||||
</rowConstraints>
|
</rowConstraints>
|
||||||
</GridPane>
|
</GridPane>
|
||||||
<GridPane fx:id="chatGridPane" GridPane.columnIndex="2" GridPane.rowIndex="2">
|
<GridPane fx:id="chatGridPane" GridPane.columnIndex="2" GridPane.rowIndex="2">
|
||||||
<columnConstraints>
|
<columnConstraints>
|
||||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="390.0" minWidth="390.0"
|
<ColumnConstraints hgrow="SOMETIMES" maxWidth="390.0" minWidth="390.0" prefWidth="390.0" />
|
||||||
prefWidth="390.0"/>
|
|
||||||
</columnConstraints>
|
</columnConstraints>
|
||||||
<rowConstraints>
|
<rowConstraints>
|
||||||
<RowConstraints maxHeight="1.7976931348623157E308" vgrow="SOMETIMES"/>
|
<RowConstraints maxHeight="1.7976931348623157E308" vgrow="SOMETIMES" />
|
||||||
<RowConstraints maxHeight="60.0" minHeight="60.0" prefHeight="60.0"
|
<RowConstraints maxHeight="60.0" minHeight="60.0" prefHeight="60.0" vgrow="SOMETIMES" />
|
||||||
vgrow="SOMETIMES"/>
|
|
||||||
</rowConstraints>
|
</rowConstraints>
|
||||||
<children>
|
<children>
|
||||||
<Pane fx:id="chatHistoryHolder" prefHeight="200.0" prefWidth="200.0"
|
<Pane fx:id="chatHistoryHolder" prefHeight="200.0" prefWidth="200.0" GridPane.hgrow="ALWAYS" GridPane.valignment="BOTTOM" GridPane.vgrow="ALWAYS">
|
||||||
GridPane.hgrow="ALWAYS" GridPane.valignment="BOTTOM"
|
|
||||||
GridPane.vgrow="ALWAYS">
|
|
||||||
<GridPane.margin>
|
<GridPane.margin>
|
||||||
<Insets/>
|
<Insets />
|
||||||
</GridPane.margin>
|
</GridPane.margin>
|
||||||
<padding>
|
<padding>
|
||||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
|
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||||
</padding>
|
</padding>
|
||||||
</Pane>
|
</Pane>
|
||||||
<GridPane fx:id="chatInputHolder" GridPane.rowIndex="1">
|
<GridPane fx:id="chatInputHolder" GridPane.rowIndex="1">
|
||||||
<columnConstraints>
|
<columnConstraints>
|
||||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0"
|
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||||
prefWidth="100.0"/>
|
<ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity" minWidth="90.0" prefWidth="90.0" />
|
||||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity"
|
|
||||||
minWidth="90.0" prefWidth="90.0"/>
|
|
||||||
</columnConstraints>
|
</columnConstraints>
|
||||||
<rowConstraints>
|
<rowConstraints>
|
||||||
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0"
|
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" valignment="CENTER" vgrow="SOMETIMES" />
|
||||||
valignment="CENTER" vgrow="SOMETIMES"/>
|
|
||||||
</rowConstraints>
|
</rowConstraints>
|
||||||
<children>
|
<children>
|
||||||
<JFXButton fx:id="chatSend" alignment="CENTER" buttonType="RAISED"
|
<JFXButton fx:id="chatSend" alignment="CENTER" buttonType="RAISED" focusTraversable="false" maxHeight="-Infinity" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="35.0" text="SEND" GridPane.columnIndex="1">
|
||||||
focusTraversable="false" maxHeight="-Infinity"
|
|
||||||
maxWidth="1.7976931348623157E308" minHeight="-Infinity"
|
|
||||||
minWidth="-Infinity" prefHeight="35.0" text="SEND"
|
|
||||||
GridPane.columnIndex="1">
|
|
||||||
<GridPane.margin>
|
<GridPane.margin>
|
||||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
|
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||||
</GridPane.margin>
|
</GridPane.margin>
|
||||||
</JFXButton>
|
</JFXButton>
|
||||||
<JFXTextField fx:id="chatInput" focusTraversable="false"
|
<JFXTextField fx:id="chatInput" focusTraversable="false" maxHeight="35.0" minHeight="-Infinity" prefHeight="35.0">
|
||||||
maxHeight="35.0" minHeight="-Infinity" prefHeight="35.0">
|
|
||||||
<GridPane.margin>
|
<GridPane.margin>
|
||||||
<Insets bottom="10.0" left="20.0" right="10.0"/>
|
<Insets bottom="10.0" left="20.0" right="10.0" />
|
||||||
</GridPane.margin>
|
</GridPane.margin>
|
||||||
<padding>
|
<padding>
|
||||||
<Insets right="15.0"/>
|
<Insets right="15.0" />
|
||||||
</padding>
|
</padding>
|
||||||
</JFXTextField>
|
</JFXTextField>
|
||||||
</children>
|
</children>
|
||||||
<GridPane.margin>
|
<GridPane.margin>
|
||||||
<Insets top="10.0"/>
|
<Insets top="10.0" />
|
||||||
</GridPane.margin>
|
</GridPane.margin>
|
||||||
</GridPane>
|
</GridPane>
|
||||||
</children>
|
</children>
|
||||||
<GridPane.margin>
|
<GridPane.margin>
|
||||||
<Insets bottom="10.0" right="10.0"/>
|
<Insets bottom="10.0" right="10.0" />
|
||||||
</GridPane.margin>
|
</GridPane.margin>
|
||||||
</GridPane>
|
</GridPane>
|
||||||
<GridPane fx:id="windGridPane" maxHeight="-Infinity" maxWidth="-Infinity"
|
<GridPane fx:id="windGridPane" maxHeight="-Infinity" maxWidth="-Infinity" prefHeight="150.0" prefWidth="240.0" GridPane.halignment="CENTER" GridPane.rowIndex="2" GridPane.valignment="BOTTOM">
|
||||||
prefHeight="150.0" prefWidth="240.0" GridPane.halignment="CENTER"
|
|
||||||
GridPane.rowIndex="2" GridPane.valignment="BOTTOM">
|
|
||||||
<columnConstraints>
|
<columnConstraints>
|
||||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="110.0" minWidth="110.0"
|
<ColumnConstraints hgrow="SOMETIMES" maxWidth="110.0" minWidth="110.0" prefWidth="110.0" />
|
||||||
prefWidth="110.0"/>
|
<ColumnConstraints hgrow="SOMETIMES" maxWidth="132.0" minWidth="10.0" prefWidth="132.0" />
|
||||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="132.0" minWidth="10.0"
|
|
||||||
prefWidth="132.0"/>
|
|
||||||
</columnConstraints>
|
</columnConstraints>
|
||||||
<rowConstraints>
|
<rowConstraints>
|
||||||
<RowConstraints maxHeight="120.0" minHeight="120.0" prefHeight="120.0"
|
<RowConstraints maxHeight="120.0" minHeight="120.0" prefHeight="120.0" vgrow="SOMETIMES" />
|
||||||
vgrow="SOMETIMES"/>
|
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||||
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0"
|
|
||||||
vgrow="SOMETIMES"/>
|
|
||||||
</rowConstraints>
|
</rowConstraints>
|
||||||
<children>
|
<children>
|
||||||
<Label fx:id="positionLabel" text="Position:" GridPane.columnIndex="1"
|
<Label fx:id="positionLabel" text="Position:" GridPane.columnIndex="1" GridPane.halignment="LEFT" GridPane.rowSpan="2" GridPane.valignment="TOP">
|
||||||
GridPane.halignment="LEFT" GridPane.rowSpan="2" GridPane.valignment="TOP">
|
|
||||||
<padding>
|
<padding>
|
||||||
<Insets bottom="5.0" left="10.0" right="5.0" top="5.0"/>
|
<Insets bottom="5.0" left="10.0" right="5.0" top="5.0" />
|
||||||
</padding>
|
</padding>
|
||||||
</Label>
|
</Label>
|
||||||
<Label fx:id="boatSpeedLabel" text="Boat Speed:" GridPane.columnIndex="1"
|
<Label fx:id="boatSpeedLabel" text="Boat Speed:" GridPane.columnIndex="1" GridPane.halignment="LEFT" GridPane.rowSpan="2" GridPane.valignment="CENTER">
|
||||||
GridPane.halignment="LEFT" GridPane.rowSpan="2"
|
|
||||||
GridPane.valignment="CENTER">
|
|
||||||
<opaqueInsets>
|
<opaqueInsets>
|
||||||
<Insets/>
|
<Insets />
|
||||||
</opaqueInsets>
|
</opaqueInsets>
|
||||||
<padding>
|
<padding>
|
||||||
<Insets bottom="5.0" left="10.0" right="5.0" top="5.0"/>
|
<Insets bottom="5.0" left="10.0" right="5.0" top="5.0" />
|
||||||
</padding>
|
</padding>
|
||||||
</Label>
|
</Label>
|
||||||
<Label fx:id="boatHeadingLabel" text="Boat Heading:"
|
<Label fx:id="boatHeadingLabel" text="Boat Heading:" GridPane.columnIndex="1" GridPane.halignment="LEFT" GridPane.rowSpan="2" GridPane.valignment="BOTTOM">
|
||||||
GridPane.columnIndex="1" GridPane.halignment="LEFT" GridPane.rowSpan="2"
|
|
||||||
GridPane.valignment="BOTTOM">
|
|
||||||
<padding>
|
<padding>
|
||||||
<Insets bottom="5.0" left="10.0" right="5.0" top="5.0"/>
|
<Insets bottom="5.0" left="10.0" right="5.0" top="5.0" />
|
||||||
</padding>
|
</padding>
|
||||||
</Label>
|
</Label>
|
||||||
<GridPane fx:id="windHolder" GridPane.rowSpan="2">
|
<GridPane fx:id="windHolder" GridPane.rowSpan="2">
|
||||||
<columnConstraints>
|
<columnConstraints>
|
||||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0"
|
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||||
prefWidth="100.0"/>
|
|
||||||
</columnConstraints>
|
</columnConstraints>
|
||||||
<rowConstraints>
|
<rowConstraints>
|
||||||
<RowConstraints maxHeight="120.0" minHeight="120.0"
|
<RowConstraints maxHeight="120.0" minHeight="120.0" prefHeight="120.0" vgrow="SOMETIMES" />
|
||||||
prefHeight="120.0" vgrow="SOMETIMES"/>
|
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||||
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0"
|
|
||||||
vgrow="SOMETIMES"/>
|
|
||||||
</rowConstraints>
|
</rowConstraints>
|
||||||
<children>
|
<children>
|
||||||
<ImageView fx:id="windImageView" fitHeight="92.0" fitWidth="109.0"
|
<ImageView fx:id="windImageView" fitHeight="92.0" fitWidth="109.0" pickOnBounds="true" preserveRatio="true" GridPane.halignment="CENTER" GridPane.rowSpan="2" GridPane.valignment="CENTER" />
|
||||||
pickOnBounds="true" preserveRatio="true"
|
<Label fx:id="windSpeedLabel" text="0.0 Knots" GridPane.halignment="RIGHT" GridPane.rowIndex="1" GridPane.valignment="CENTER">
|
||||||
GridPane.halignment="CENTER" GridPane.rowSpan="2"
|
|
||||||
GridPane.valignment="CENTER"/>
|
|
||||||
<Label fx:id="windSpeedLabel" text="0.0 Knots"
|
|
||||||
GridPane.halignment="RIGHT" GridPane.rowIndex="1"
|
|
||||||
GridPane.valignment="CENTER">
|
|
||||||
<GridPane.margin>
|
<GridPane.margin>
|
||||||
<Insets right="5.0"/>
|
<Insets right="5.0" />
|
||||||
</GridPane.margin>
|
</GridPane.margin>
|
||||||
</Label>
|
</Label>
|
||||||
<Label fx:id="windDirectionLabel" text="180.0°"
|
<Label fx:id="windDirectionLabel" text="180.0°" GridPane.halignment="LEFT" GridPane.rowIndex="1" GridPane.valignment="CENTER">
|
||||||
GridPane.halignment="LEFT" GridPane.rowIndex="1"
|
|
||||||
GridPane.valignment="CENTER">
|
|
||||||
<GridPane.margin>
|
<GridPane.margin>
|
||||||
<Insets left="5.0"/>
|
<Insets left="5.0" />
|
||||||
</GridPane.margin>
|
</GridPane.margin>
|
||||||
</Label>
|
</Label>
|
||||||
</children>
|
</children>
|
||||||
</GridPane>
|
</GridPane>
|
||||||
</children>
|
</children>
|
||||||
<opaqueInsets>
|
<opaqueInsets>
|
||||||
<Insets/>
|
<Insets />
|
||||||
</opaqueInsets>
|
</opaqueInsets>
|
||||||
<GridPane.margin>
|
<GridPane.margin>
|
||||||
<Insets bottom="10.0" left="10.0" top="40.0"/>
|
<Insets bottom="10.0" left="10.0" top="40.0" />
|
||||||
</GridPane.margin>
|
</GridPane.margin>
|
||||||
</GridPane>
|
</GridPane>
|
||||||
<GridPane GridPane.columnIndex="1" GridPane.rowIndex="2">
|
<GridPane GridPane.columnIndex="1" GridPane.rowIndex="2">
|
||||||
<columnConstraints>
|
<columnConstraints>
|
||||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
|
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
|
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
|
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
|
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
|
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||||
</columnConstraints>
|
</columnConstraints>
|
||||||
<rowConstraints>
|
<rowConstraints>
|
||||||
<RowConstraints maxHeight="152.0" minHeight="10.0" prefHeight="152.0"
|
<RowConstraints maxHeight="152.0" minHeight="10.0" prefHeight="152.0" vgrow="SOMETIMES" />
|
||||||
vgrow="SOMETIMES"/>
|
<RowConstraints maxHeight="118.0" minHeight="10.0" prefHeight="98.0" vgrow="SOMETIMES" />
|
||||||
<RowConstraints maxHeight="118.0" minHeight="10.0" prefHeight="98.0"
|
|
||||||
vgrow="SOMETIMES"/>
|
|
||||||
</rowConstraints>
|
</rowConstraints>
|
||||||
<children>
|
<children>
|
||||||
<ImageView fx:id="velocityIcon" fitHeight="88.0" fitWidth="106.0"
|
<ImageView fx:id="velocityIcon" fitHeight="88.0" fitWidth="106.0" pickOnBounds="true" preserveRatio="true" visible="false" GridPane.halignment="CENTER" GridPane.rowIndex="1">
|
||||||
pickOnBounds="true" preserveRatio="true" visible="false"
|
|
||||||
GridPane.halignment="CENTER" GridPane.rowIndex="1">
|
|
||||||
<image>
|
<image>
|
||||||
<Image url="@../icons/velocity.png"/>
|
<Image url="@../icons/velocity.png" />
|
||||||
</image>
|
</image>
|
||||||
</ImageView>
|
</ImageView>
|
||||||
<ImageView fx:id="handlingIcon" fitHeight="87.0" fitWidth="98.0"
|
<ImageView fx:id="handlingIcon" fitHeight="87.0" fitWidth="98.0" pickOnBounds="true" preserveRatio="true" visible="false" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="1">
|
||||||
pickOnBounds="true" preserveRatio="true" visible="false"
|
|
||||||
GridPane.columnIndex="1" GridPane.halignment="CENTER"
|
|
||||||
GridPane.rowIndex="1">
|
|
||||||
<image>
|
<image>
|
||||||
<Image url="@../icons/handlingIcon.png"/>
|
<Image url="@../icons/handlingIcon.png" />
|
||||||
</image>
|
</image>
|
||||||
</ImageView>
|
</ImageView>
|
||||||
<ImageView fx:id="windWalkerIcon" fitHeight="83.0" fitWidth="100.0"
|
<ImageView fx:id="windWalkerIcon" fitHeight="83.0" fitWidth="100.0" pickOnBounds="true" preserveRatio="true" visible="false" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="1">
|
||||||
pickOnBounds="true" preserveRatio="true" visible="false"
|
|
||||||
GridPane.columnIndex="2" GridPane.halignment="CENTER"
|
|
||||||
GridPane.rowIndex="1">
|
|
||||||
<image>
|
<image>
|
||||||
<Image url="@../icons/windWalkerIcon.png"/>
|
<Image url="@../icons/windWalkerIcon.png" />
|
||||||
</image>
|
</image>
|
||||||
</ImageView>
|
</ImageView>
|
||||||
<ImageView fx:id="bumperIcon" fitHeight="83.0" fitWidth="88.0"
|
<ImageView fx:id="bumperIcon" fitHeight="83.0" fitWidth="88.0" pickOnBounds="true" preserveRatio="true" visible="false" GridPane.columnIndex="3" GridPane.halignment="CENTER" GridPane.rowIndex="1">
|
||||||
pickOnBounds="true" preserveRatio="true" visible="false"
|
|
||||||
GridPane.columnIndex="3" GridPane.halignment="CENTER"
|
|
||||||
GridPane.rowIndex="1">
|
|
||||||
<image>
|
<image>
|
||||||
<Image url="@../icons/bumperIcon.png"/>
|
<Image url="@../icons/bumperIcon.png" />
|
||||||
</image>
|
</image>
|
||||||
</ImageView>
|
</ImageView>
|
||||||
<ImageView fx:id="badRandomIcon" fitHeight="69.0" fitWidth="103.0"
|
<ImageView fx:id="badRandomIcon" fitHeight="69.0" fitWidth="103.0" pickOnBounds="true" preserveRatio="true" visible="false" GridPane.columnIndex="4" GridPane.halignment="CENTER" GridPane.rowIndex="1" GridPane.valignment="CENTER">
|
||||||
pickOnBounds="true" preserveRatio="true" visible="false"
|
|
||||||
GridPane.columnIndex="4" GridPane.halignment="CENTER"
|
|
||||||
GridPane.rowIndex="1" GridPane.valignment="CENTER">
|
|
||||||
<image>
|
<image>
|
||||||
<Image url="@../icons/slowedIcon.png"/>
|
<Image url="@../icons/slowedIcon.png" />
|
||||||
</image>
|
</image>
|
||||||
</ImageView>
|
</ImageView>
|
||||||
</children>
|
</children>
|
||||||
@@ -294,15 +231,30 @@
|
|||||||
</GridPane>
|
</GridPane>
|
||||||
</children>
|
</children>
|
||||||
</StackPane>
|
</StackPane>
|
||||||
|
<Pane fx:id="miniMapPane" maxHeight="200.0" maxWidth="200.0" minHeight="200.0" minWidth="200.0" prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: white; -fx-opacity: 0.45; -fx-background-radius: 10;" StackPane.alignment="TOP_RIGHT">
|
||||||
|
<StackPane.margin>
|
||||||
|
<Insets right="15.0" top="15.0" />
|
||||||
|
</StackPane.margin>
|
||||||
|
</Pane>
|
||||||
|
<JFXButton fx:id="miniMapButton" style="-fx-background-color: white; -fx-opacity: 0.45; -fx-background-radius: 10;" text="✓" StackPane.alignment="TOP_RIGHT">
|
||||||
|
<font>
|
||||||
|
<Font size="15.0" />
|
||||||
|
</font>
|
||||||
|
<StackPane.margin>
|
||||||
|
<Insets right="15.0" top="15.0" />
|
||||||
|
</StackPane.margin>
|
||||||
|
</JFXButton>
|
||||||
</children>
|
</children>
|
||||||
|
<children>
|
||||||
<AnchorPane fx:id="loadingScreenPane">
|
<AnchorPane fx:id="loadingScreenPane">
|
||||||
<children>
|
<children>
|
||||||
<ImageView fx:id="loadingScreen" fitHeight="672.0" fitWidth="1200.0" pickOnBounds="true" preserveRatio="true" />
|
<ImageView fx:id="loadingScreen" fitHeight="672.0" fitWidth="1200.0" pickOnBounds="true" preserveRatio="true" />
|
||||||
<JFXSpinner layoutX="566.0" layoutY="692.0" radius="30.0" />
|
<JFXSpinner layoutX="566.0" layoutY="692.0" radius="30.0" />
|
||||||
</children>
|
</children>
|
||||||
</AnchorPane>
|
</AnchorPane>
|
||||||
|
</children>
|
||||||
<stylesheets>
|
<stylesheets>
|
||||||
<String fx:value="/css/Master.css"/>
|
<String fx:value="/css/Master.css" />
|
||||||
<String fx:value="/css/RaceView.css"/>
|
<String fx:value="/css/RaceView.css" />
|
||||||
</stylesheets>
|
</stylesheets>
|
||||||
</StackPane>
|
</StackPane>
|
||||||
|
|||||||
Reference in New Issue
Block a user