mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 06:18:44 +00:00
Merge remote-tracking branch 'origin/develop' into 1293_PowerUps
# Conflicts: # src/main/java/seng302/visualiser/GameView3D.java
This commit is contained in:
@@ -5,19 +5,19 @@ package seng302.gameServer.messages;
|
|||||||
*/
|
*/
|
||||||
public class BoatActionMessage extends Message{
|
public class BoatActionMessage extends Message{
|
||||||
private final MessageType MESSAGE_TYPE = MessageType.BOAT_ACTION;
|
private final MessageType MESSAGE_TYPE = MessageType.BOAT_ACTION;
|
||||||
private final int MESSAGE_SIZE = 1;
|
private final int MESSAGE_SIZE = 5;
|
||||||
private BoatAction actionType;
|
private BoatAction actionType;
|
||||||
|
|
||||||
public BoatActionMessage(BoatAction actionType) {
|
public BoatActionMessage(BoatAction actionType, int sourceId) {
|
||||||
this.actionType = actionType;
|
this.actionType = actionType;
|
||||||
setHeader(new Header(MessageType.BOAT_ACTION, 0, (short) 1)); // the second variable is the source id
|
setHeader(new Header(MessageType.BOAT_ACTION, sourceId, (short) MESSAGE_SIZE)); // the second variable is the source id
|
||||||
allocateBuffer();
|
allocateBuffer();
|
||||||
writeHeaderToBuffer();
|
writeHeaderToBuffer();
|
||||||
// Write message fields
|
// Write message fields
|
||||||
putInt(actionType.getValue(), 1);
|
putInt(actionType.getValue(), 1);
|
||||||
|
putInt(sourceId, 4);
|
||||||
writeCRC();
|
writeCRC();
|
||||||
rewind();
|
rewind();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ package seng302.gameServer.messages;
|
|||||||
public class RegistrationRequestMessage extends Message {
|
public class RegistrationRequestMessage extends Message {
|
||||||
private static int MESSAGE_LENGTH = 2;
|
private static int MESSAGE_LENGTH = 2;
|
||||||
|
|
||||||
public RegistrationRequestMessage(ClientType type){
|
public RegistrationRequestMessage(ClientType type, int clientID){
|
||||||
setHeader(new Header(MessageType.REGISTRATION_REQUEST, 1, (short) getSize()));
|
setHeader(new Header(MessageType.REGISTRATION_REQUEST, clientID, (short) getSize()));
|
||||||
|
|
||||||
allocateBuffer();
|
allocateBuffer();
|
||||||
writeHeaderToBuffer();
|
writeHeaderToBuffer();
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Observable;
|
import java.util.Observable;
|
||||||
import java.util.Observer;
|
import java.util.Observer;
|
||||||
|
import java.util.Timer;
|
||||||
import javafx.beans.property.ReadOnlyDoubleProperty;
|
import javafx.beans.property.ReadOnlyDoubleProperty;
|
||||||
import javafx.beans.property.ReadOnlyDoubleWrapper;
|
import javafx.beans.property.ReadOnlyDoubleWrapper;
|
||||||
import javafx.beans.property.ReadOnlyIntegerProperty;
|
import javafx.beans.property.ReadOnlyIntegerProperty;
|
||||||
@@ -20,6 +21,7 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import seng302.model.token.TokenType;
|
import seng302.model.token.TokenType;
|
||||||
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
|
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
|
||||||
|
import seng302.visualiser.fxObjects.assets_3D.BoatObject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Yacht class for the racing boat. <p> Class created to store more variables (eg. boat statuses)
|
* Yacht class for the racing boat. <p> Class created to store more variables (eg. boat statuses)
|
||||||
@@ -82,6 +84,10 @@ public class ClientYacht extends Observable {
|
|||||||
private Integer boatStatus;
|
private Integer boatStatus;
|
||||||
private Double currentVelocity;
|
private Double currentVelocity;
|
||||||
|
|
||||||
|
Timer t;
|
||||||
|
|
||||||
|
private BoatObject boatObject;
|
||||||
|
|
||||||
private List<YachtLocationListener> locationListeners = new ArrayList<>();
|
private List<YachtLocationListener> locationListeners = new ArrayList<>();
|
||||||
private List<MarkRoundingListener> markRoundingListeners = new ArrayList<>();
|
private List<MarkRoundingListener> markRoundingListeners = new ArrayList<>();
|
||||||
private List<PowerUpListener> powerUpListeners = new ArrayList<>();
|
private List<PowerUpListener> powerUpListeners = new ArrayList<>();
|
||||||
@@ -92,6 +98,7 @@ public class ClientYacht extends Observable {
|
|||||||
private ReadOnlyLongWrapper timeTillNextProperty = new ReadOnlyLongWrapper();
|
private ReadOnlyLongWrapper timeTillNextProperty = new ReadOnlyLongWrapper();
|
||||||
private ReadOnlyLongWrapper timeSinceLastMarkProperty = new ReadOnlyLongWrapper();
|
private ReadOnlyLongWrapper timeSinceLastMarkProperty = new ReadOnlyLongWrapper();
|
||||||
private ReadOnlyIntegerWrapper placingProperty = new ReadOnlyIntegerWrapper();
|
private ReadOnlyIntegerWrapper placingProperty = new ReadOnlyIntegerWrapper();
|
||||||
|
private ReadOnlyDoubleWrapper headingProperty = new ReadOnlyDoubleWrapper();
|
||||||
private Color colour;
|
private Color colour;
|
||||||
|
|
||||||
public ClientYacht(BoatMeshType boatType, Integer sourceId, String hullID, String shortName,
|
public ClientYacht(BoatMeshType boatType, Integer sourceId, String hullID, String shortName,
|
||||||
@@ -104,6 +111,7 @@ public class ClientYacht extends Observable {
|
|||||||
this.country = country;
|
this.country = country;
|
||||||
this.location = new GeoPoint(57.670341, 11.826856);
|
this.location = new GeoPoint(57.670341, 11.826856);
|
||||||
this.heading = 120.0; //In degrees
|
this.heading = 120.0; //In degrees
|
||||||
|
this.headingProperty.set(this.heading);
|
||||||
this.currentVelocity = 0d;
|
this.currentVelocity = 0d;
|
||||||
this.boatStatus = 1;
|
this.boatStatus = 1;
|
||||||
this.colour = Color.rgb(0, 0, 0, 1.0);
|
this.colour = Color.rgb(0, 0, 0, 1.0);
|
||||||
@@ -277,6 +285,7 @@ public class ClientYacht extends Observable {
|
|||||||
|
|
||||||
public void setHeading(Double heading) {
|
public void setHeading(Double heading) {
|
||||||
this.heading = heading;
|
this.heading = heading;
|
||||||
|
setHeadingProperty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -308,10 +317,10 @@ public class ClientYacht extends Observable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void updateLocation(double lat, double lng, double heading, double velocity) {
|
public void updateLocation(double lat, double lng, double heading, double velocity) {
|
||||||
setLocation(lat, lng);
|
setLocation(lat, lng);
|
||||||
this.heading = heading;
|
this.heading = heading;
|
||||||
|
setHeadingProperty();
|
||||||
this.currentVelocity = velocity;
|
this.currentVelocity = velocity;
|
||||||
updateVelocityProperty(velocity);
|
updateVelocityProperty(velocity);
|
||||||
for (YachtLocationListener yll : locationListeners) {
|
for (YachtLocationListener yll : locationListeners) {
|
||||||
@@ -319,6 +328,10 @@ public class ClientYacht extends Observable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setHeadingProperty() {
|
||||||
|
headingProperty.set(heading);
|
||||||
|
}
|
||||||
|
|
||||||
public void addLocationListener(YachtLocationListener listener) {
|
public void addLocationListener(YachtLocationListener listener) {
|
||||||
locationListeners.add(listener);
|
locationListeners.add(listener);
|
||||||
}
|
}
|
||||||
@@ -359,4 +372,17 @@ public class ClientYacht extends Observable {
|
|||||||
public Double getCurrentVelocity() {
|
public Double getCurrentVelocity() {
|
||||||
return currentVelocity;
|
return currentVelocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setBoatObject(BoatObject newBoatObject) {
|
||||||
|
this.boatObject = newBoatObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BoatObject getBoatObject() {
|
||||||
|
return this.boatObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReadOnlyDoubleWrapper getHeadingProperty() {
|
||||||
|
return headingProperty;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,12 @@ public class GameKeyBind {
|
|||||||
keys.add(KeyCode.ENTER);
|
keys.add(KeyCode.ENTER);
|
||||||
keys.add(KeyCode.PAGE_UP);
|
keys.add(KeyCode.PAGE_UP);
|
||||||
keys.add(KeyCode.PAGE_DOWN);
|
keys.add(KeyCode.PAGE_DOWN);
|
||||||
for (int i = 0; i < 7; i++) {
|
keys.add(KeyCode.F1);
|
||||||
|
keys.add(KeyCode.D);
|
||||||
|
keys.add(KeyCode.A);
|
||||||
|
keys.add(KeyCode.W);
|
||||||
|
keys.add(KeyCode.S);
|
||||||
|
for (int i = 0; i < 12; i++) {
|
||||||
actionToKeyMap.put(KeyAction.getType(i + 1), keys.get(i));
|
actionToKeyMap.put(KeyAction.getType(i + 1), keys.get(i));
|
||||||
keyToActionMap.put(keys.get(i), KeyAction.getType(i + 1));
|
keyToActionMap.put(keys.get(i), KeyAction.getType(i + 1));
|
||||||
}
|
}
|
||||||
@@ -47,6 +52,10 @@ public class GameKeyBind {
|
|||||||
return instance.actionToKeyMap.get(keyAction);
|
return instance.actionToKeyMap.get(keyAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public KeyAction getKeyAction(KeyCode keyCode) {
|
||||||
|
return instance.keyToActionMap.get(keyCode);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Binds a key to a key action
|
* Binds a key to a key action
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -10,7 +10,12 @@ public enum KeyAction {
|
|||||||
SAILS_STATE(4),
|
SAILS_STATE(4),
|
||||||
TACK_GYBE(5),
|
TACK_GYBE(5),
|
||||||
UPWIND(6),
|
UPWIND(6),
|
||||||
DOWNWIND(7);
|
DOWNWIND(7),
|
||||||
|
VIEW(8),
|
||||||
|
RIGHT(9),
|
||||||
|
LEFT(10),
|
||||||
|
FORWARD(11),
|
||||||
|
BACKWARD(12);
|
||||||
|
|
||||||
private final int type;
|
private final int type;
|
||||||
private static final Map<Integer, KeyAction> intToTypeMap = new HashMap<>();
|
private static final Map<Integer, KeyAction> intToTypeMap = new HashMap<>();
|
||||||
|
|||||||
@@ -160,11 +160,11 @@ public class ServerYacht {
|
|||||||
/**
|
/**
|
||||||
* Enables the boats auto pilot feature, which will move the boat towards a given heading.
|
* Enables the boats auto pilot feature, which will move the boat towards a given heading.
|
||||||
*
|
*
|
||||||
* @param thisHeading The heading to move the boat towards.
|
* @param newHeading The heading to move the boat towards.
|
||||||
*/
|
*/
|
||||||
private void setAutoPilot(Double thisHeading) {
|
private void setAutoPilot(Double newHeading) {
|
||||||
isAuto = true;
|
isAuto = true;
|
||||||
autoHeading = thisHeading;
|
autoHeading = newHeading;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -182,8 +182,9 @@ public class ServerYacht {
|
|||||||
if (isAuto) {
|
if (isAuto) {
|
||||||
turnTowardsHeading(autoHeading);
|
turnTowardsHeading(autoHeading);
|
||||||
if (Math.abs(heading - autoHeading)
|
if (Math.abs(heading - autoHeading)
|
||||||
<= turnStep) { //Cancel when within 1 turn step of target.
|
<= turnStep*1.5) {
|
||||||
isAuto = false;
|
isAuto = false;
|
||||||
|
setHeading(autoHeading);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -269,7 +270,7 @@ public class ServerYacht {
|
|||||||
|
|
||||||
// Take optimal heading and turn into a boat heading rather than a wind heading.
|
// Take optimal heading and turn into a boat heading rather than a wind heading.
|
||||||
optimalHeading =
|
optimalHeading =
|
||||||
optimalHeading + GameState.getWindDirection();
|
(optimalHeading + GameState.getWindDirection()) % 360;
|
||||||
|
|
||||||
setAutoPilot(optimalHeading);
|
setAutoPilot(optimalHeading);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,12 +4,14 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Random;
|
||||||
import javafx.scene.paint.Color;
|
import javafx.scene.paint.Color;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
import org.w3c.dom.NodeList;
|
import org.w3c.dom.NodeList;
|
||||||
import seng302.model.ClientYacht;
|
import seng302.model.ClientYacht;
|
||||||
|
import seng302.model.Colors;
|
||||||
import seng302.model.Limit;
|
import seng302.model.Limit;
|
||||||
import seng302.model.mark.CompoundMark;
|
import seng302.model.mark.CompoundMark;
|
||||||
import seng302.model.mark.Corner;
|
import seng302.model.mark.Corner;
|
||||||
@@ -139,14 +141,26 @@ public class XMLParser {
|
|||||||
Node currentBoat = boatsList.item(i);
|
Node currentBoat = boatsList.item(i);
|
||||||
if (currentBoat.getNodeName().equals("Boat")) {
|
if (currentBoat.getNodeName().equals("Boat")) {
|
||||||
// Boat boat = new Boat(currentBoat);
|
// Boat boat = new Boat(currentBoat);
|
||||||
|
BoatMeshType boatMeshType;
|
||||||
|
try {
|
||||||
|
boatMeshType = BoatMeshType.valueOf(XMLParser.getNodeAttributeString(currentBoat, "Type"));
|
||||||
|
} catch (IllegalArgumentException e){
|
||||||
|
boatMeshType = BoatMeshType.DINGHY;
|
||||||
|
}
|
||||||
|
Color color;
|
||||||
|
try {
|
||||||
|
color = Color.web(getNodeAttributeString(currentBoat, "Color"));
|
||||||
|
} catch (NullPointerException npe) {
|
||||||
|
color = Colors.getColor(new Random().nextInt(8));
|
||||||
|
}
|
||||||
ClientYacht yacht = new ClientYacht(
|
ClientYacht yacht = new ClientYacht(
|
||||||
BoatMeshType.valueOf(XMLParser.getNodeAttributeString(currentBoat, "Type")),
|
boatMeshType,
|
||||||
XMLParser.getNodeAttributeInt(currentBoat, "SourceID"),
|
XMLParser.getNodeAttributeInt(currentBoat, "SourceID"),
|
||||||
XMLParser.getNodeAttributeString(currentBoat, "HullNum"),
|
XMLParser.getNodeAttributeString(currentBoat, "HullNum"),
|
||||||
XMLParser.getNodeAttributeString(currentBoat, "ShortName"),
|
XMLParser.getNodeAttributeString(currentBoat, "ShortName"),
|
||||||
XMLParser.getNodeAttributeString(currentBoat, "BoatName"),
|
XMLParser.getNodeAttributeString(currentBoat, "BoatName"),
|
||||||
XMLParser.getNodeAttributeString(currentBoat, "Country"));
|
XMLParser.getNodeAttributeString(currentBoat, "Country"));
|
||||||
yacht.setColour(Color.web(getNodeAttributeString(currentBoat, "Color")));
|
yacht.setColour(color);
|
||||||
competingBoats.put(yacht.getSourceId(), yacht);
|
competingBoats.put(yacht.getSourceId(), yacht);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -195,17 +209,20 @@ public class XMLParser {
|
|||||||
*/
|
*/
|
||||||
private static List<Token> extractTokens(Element docEle) {
|
private static List<Token> extractTokens(Element docEle) {
|
||||||
List<Token> tokens = new ArrayList<>();
|
List<Token> tokens = new ArrayList<>();
|
||||||
NodeList tokenList = docEle.getElementsByTagName("Tokens").item(0).getChildNodes();
|
try {
|
||||||
for (int i = 0; i < tokenList.getLength(); i++) {
|
NodeList tokenList = docEle.getElementsByTagName("Tokens").item(0).getChildNodes();
|
||||||
Node tokenNode = tokenList.item(i);
|
for (int i = 0; i < tokenList.getLength(); i++) {
|
||||||
if (tokenNode.getNodeName().equals("Token")) {
|
Node tokenNode = tokenList.item(i);
|
||||||
String tokenType = getNodeAttributeString(tokenNode, "TokenType");
|
if (tokenNode.getNodeName().equals("Token")) {
|
||||||
Double lat = getNodeAttributeDouble(tokenNode, "TargetLat");
|
String tokenType = getNodeAttributeString(tokenNode, "TokenType");
|
||||||
Double lng = getNodeAttributeDouble(tokenNode, "TargetLng");
|
Double lat = getNodeAttributeDouble(tokenNode, "TargetLat");
|
||||||
tokens.add(new Token(TokenType.valueOf(tokenType), lat, lng));
|
Double lng = getNodeAttributeDouble(tokenNode, "TargetLng");
|
||||||
|
tokens.add(new Token(TokenType.valueOf(tokenType), lat, lng));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (NullPointerException npe) {
|
||||||
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
return tokens;
|
return tokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ public class ClientToServerThread implements Runnable {
|
|||||||
* Sends a request to the server asking for a source ID
|
* Sends a request to the server asking for a source ID
|
||||||
*/
|
*/
|
||||||
private void sendRegistrationRequest() {
|
private void sendRegistrationRequest() {
|
||||||
RegistrationRequestMessage requestMessage = new RegistrationRequestMessage(ClientType.PLAYER);
|
RegistrationRequestMessage requestMessage = new RegistrationRequestMessage(ClientType.PLAYER, clientId);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
os.write(requestMessage.getBuffer());
|
os.write(requestMessage.getBuffer());
|
||||||
@@ -193,7 +193,6 @@ public class ClientToServerThread implements Runnable {
|
|||||||
private void processRegistrationResponse(StreamPacket packet){
|
private void processRegistrationResponse(StreamPacket packet){
|
||||||
int sourceId = (int) Message.bytesToLong(Arrays.copyOfRange(packet.getPayload(), 0, 3));
|
int sourceId = (int) Message.bytesToLong(Arrays.copyOfRange(packet.getPayload(), 0, 3));
|
||||||
int statusCode = (int) Message.bytesToLong(Arrays.copyOfRange(packet.getPayload(), 4,5));
|
int statusCode = (int) Message.bytesToLong(Arrays.copyOfRange(packet.getPayload(), 4,5));
|
||||||
|
|
||||||
RegistrationResponseStatus status = RegistrationResponseStatus.getResponseStatus(statusCode);
|
RegistrationResponseStatus status = RegistrationResponseStatus.getResponseStatus(statusCode);
|
||||||
|
|
||||||
if (status.equals(RegistrationResponseStatus.SUCCESS_PLAYING)){
|
if (status.equals(RegistrationResponseStatus.SUCCESS_PLAYING)){
|
||||||
@@ -243,7 +242,7 @@ public class ClientToServerThread implements Runnable {
|
|||||||
new TimerTask() {
|
new TimerTask() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
sendBoatActionMessage(new BoatActionMessage(BoatAction.DOWNWIND));
|
sendBoatActionMessage(new BoatActionMessage(BoatAction.DOWNWIND, clientId));
|
||||||
}
|
}
|
||||||
}, 0, PACKET_SENDING_INTERVAL_MS
|
}, 0, PACKET_SENDING_INTERVAL_MS
|
||||||
);
|
);
|
||||||
@@ -256,14 +255,14 @@ public class ClientToServerThread implements Runnable {
|
|||||||
new TimerTask() {
|
new TimerTask() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
sendBoatActionMessage(new BoatActionMessage(BoatAction.UPWIND));
|
sendBoatActionMessage(new BoatActionMessage(BoatAction.UPWIND, clientId));
|
||||||
}
|
}
|
||||||
}, 0, PACKET_SENDING_INTERVAL_MS
|
}, 0, PACKET_SENDING_INTERVAL_MS
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
sendBoatActionMessage(new BoatActionMessage(actionType));
|
sendBoatActionMessage(new BoatActionMessage(actionType, clientId));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,6 @@ import javafx.application.Platform;
|
|||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
import javafx.scene.control.Alert;
|
|
||||||
import javafx.scene.control.Alert.AlertType;
|
|
||||||
import javafx.scene.input.KeyCode;
|
import javafx.scene.input.KeyCode;
|
||||||
import javafx.scene.input.KeyEvent;
|
import javafx.scene.input.KeyEvent;
|
||||||
import javafx.scene.layout.Pane;
|
import javafx.scene.layout.Pane;
|
||||||
@@ -50,6 +48,7 @@ import seng302.utilities.XMLParser;
|
|||||||
import seng302.visualiser.controllers.LobbyController;
|
import seng302.visualiser.controllers.LobbyController;
|
||||||
import seng302.visualiser.controllers.RaceViewController;
|
import seng302.visualiser.controllers.RaceViewController;
|
||||||
import seng302.visualiser.controllers.ViewManager;
|
import seng302.visualiser.controllers.ViewManager;
|
||||||
|
import seng302.visualiser.controllers.dialogs.PopupDialogController;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is a client side instance of a yacht racing game in JavaFX. The game is instantiated
|
* This class is a client side instance of a yacht racing game in JavaFX. The game is instantiated
|
||||||
@@ -173,10 +172,12 @@ public class GameClient {
|
|||||||
|
|
||||||
private void showConnectionError (String message) {
|
private void showConnectionError (String message) {
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
Alert alert = new Alert(AlertType.ERROR);
|
PopupDialogController controller = ViewManager.getInstance().showPopupDialog();
|
||||||
alert.setHeaderText("Connection Error");
|
controller.setHeader("Oops");
|
||||||
alert.setContentText(message);
|
controller.setContent(message);
|
||||||
alert.showAndWait();
|
controller.setOptionButtonText("GO HOME");
|
||||||
|
controller
|
||||||
|
.setOptionButtonEventHandler(event -> ViewManager.getInstance().goToStartView());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -397,7 +398,11 @@ public class GameClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (gameKeyBind.getKeyCode(KeyAction.SAILS_STATE) == e.getCode()) { // sails in/sails out
|
if (gameKeyBind.getKeyCode(KeyAction.SAILS_STATE) == e.getCode()) { // sails in/sails out
|
||||||
socketThread.sendBoatAction(BoatAction.SAILS_IN);
|
if (allBoatsMap.get(socketThread.getClientId()).getSailIn()) {
|
||||||
|
socketThread.sendBoatAction(BoatAction.SAILS_OUT);
|
||||||
|
} else {
|
||||||
|
socketThread.sendBoatAction(BoatAction.SAILS_IN);
|
||||||
|
}
|
||||||
allBoatsMap.get(socketThread.getClientId()).toggleSail();
|
allBoatsMap.get(socketThread.getClientId()).toggleSail();
|
||||||
} else if (gameKeyBind.getKeyCode(KeyAction.UPWIND) == e.getCode()
|
} else if (gameKeyBind.getKeyCode(KeyAction.UPWIND) == e.getCode()
|
||||||
|| gameKeyBind.getKeyCode(KeyAction.DOWNWIND) == e.getCode()) {
|
|| gameKeyBind.getKeyCode(KeyAction.DOWNWIND) == e.getCode()) {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package seng302.visualiser;
|
package seng302.visualiser;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -9,6 +10,7 @@ import javafx.animation.AnimationTimer;
|
|||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.geometry.Point2D;
|
import javafx.geometry.Point2D;
|
||||||
import javafx.geometry.Point3D;
|
import javafx.geometry.Point3D;
|
||||||
|
import javafx.scene.Camera;
|
||||||
import javafx.scene.Group;
|
import javafx.scene.Group;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.PerspectiveCamera;
|
import javafx.scene.PerspectiveCamera;
|
||||||
@@ -21,7 +23,9 @@ import javafx.scene.transform.Scale;
|
|||||||
import javafx.scene.transform.Translate;
|
import javafx.scene.transform.Translate;
|
||||||
import seng302.gameServer.messages.RoundingSide;
|
import seng302.gameServer.messages.RoundingSide;
|
||||||
import seng302.model.ClientYacht;
|
import seng302.model.ClientYacht;
|
||||||
|
import seng302.model.GameKeyBind;
|
||||||
import seng302.model.GeoPoint;
|
import seng302.model.GeoPoint;
|
||||||
|
import seng302.model.KeyAction;
|
||||||
import seng302.model.Limit;
|
import seng302.model.Limit;
|
||||||
import seng302.model.mark.CompoundMark;
|
import seng302.model.mark.CompoundMark;
|
||||||
import seng302.model.mark.Corner;
|
import seng302.model.mark.Corner;
|
||||||
@@ -30,8 +34,12 @@ import seng302.model.token.Token;
|
|||||||
import seng302.model.token.TokenType;
|
import seng302.model.token.TokenType;
|
||||||
import seng302.utilities.GeoUtility;
|
import seng302.utilities.GeoUtility;
|
||||||
import seng302.utilities.Sounds;
|
import seng302.utilities.Sounds;
|
||||||
|
import seng302.visualiser.cameras.ChaseCamera;
|
||||||
|
import seng302.visualiser.cameras.IsometricCamera;
|
||||||
|
import seng302.visualiser.cameras.RaceCamera;
|
||||||
|
import seng302.visualiser.cameras.TopDownCamera;
|
||||||
|
import seng302.visualiser.controllers.ViewManager;
|
||||||
import seng302.visualiser.fxObjects.MarkArrowFactory;
|
import seng302.visualiser.fxObjects.MarkArrowFactory;
|
||||||
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
|
|
||||||
import seng302.visualiser.fxObjects.assets_3D.BoatObject;
|
import seng302.visualiser.fxObjects.assets_3D.BoatObject;
|
||||||
import seng302.visualiser.fxObjects.assets_3D.Marker3D;
|
import seng302.visualiser.fxObjects.assets_3D.Marker3D;
|
||||||
import seng302.visualiser.fxObjects.assets_3D.ModelFactory;
|
import seng302.visualiser.fxObjects.assets_3D.ModelFactory;
|
||||||
@@ -43,18 +51,19 @@ import seng302.visualiser.fxObjects.assets_3D.ModelType;
|
|||||||
|
|
||||||
public class GameView3D {
|
public class GameView3D {
|
||||||
|
|
||||||
|
|
||||||
private final double FOV = 60;
|
private final double FOV = 60;
|
||||||
private final double DEFAULT_CAMERA_DEPTH = -125;
|
|
||||||
private final double DEFAULT_CAMERA_X = 0;
|
private final double DEFAULT_CAMERA_X = 0;
|
||||||
private final double DEFAULT_CAMERA_Y = 155;
|
private final double DEFAULT_CAMERA_Y = 155;
|
||||||
|
|
||||||
private Group root3D;
|
private Group root3D;
|
||||||
private SubScene view;
|
private SubScene view;
|
||||||
// ParallelCamera camera;
|
|
||||||
private PerspectiveCamera camera;
|
|
||||||
private Group gameObjects;
|
private Group gameObjects;
|
||||||
|
|
||||||
|
// Cameras
|
||||||
|
private PerspectiveCamera isometricCam;
|
||||||
|
private PerspectiveCamera topDownCam;
|
||||||
|
private PerspectiveCamera chaseCam;
|
||||||
|
|
||||||
private double bufferSize = 0;
|
private double bufferSize = 0;
|
||||||
private double canvasWidth = 200;
|
private double canvasWidth = 200;
|
||||||
private double canvasHeight = 200;
|
private double canvasHeight = 200;
|
||||||
@@ -89,20 +98,22 @@ public class GameView3D {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public GameView3D () {
|
public GameView3D () {
|
||||||
camera = new PerspectiveCamera(true);
|
isometricCam = new IsometricCamera(DEFAULT_CAMERA_X, DEFAULT_CAMERA_Y);
|
||||||
camera.getTransforms().addAll(
|
topDownCam = new TopDownCamera();
|
||||||
new Translate(DEFAULT_CAMERA_X,DEFAULT_CAMERA_Y, DEFAULT_CAMERA_DEPTH)
|
chaseCam = new ChaseCamera();
|
||||||
);
|
|
||||||
camera.setFarClip(600);
|
for (PerspectiveCamera pc : Arrays.asList(isometricCam, topDownCam, chaseCam)) {
|
||||||
camera.setNearClip(0.1);
|
pc.setFarClip(600);
|
||||||
camera.setFieldOfView(FOV);
|
pc.setNearClip(0.1);
|
||||||
|
pc.setFieldOfView(FOV);
|
||||||
|
}
|
||||||
|
|
||||||
gameObjects = new Group();
|
gameObjects = new Group();
|
||||||
root3D = new Group(camera, gameObjects);
|
root3D = new Group(isometricCam, gameObjects);
|
||||||
view = new SubScene(
|
view = new SubScene(
|
||||||
root3D, 1000, 1000, true, SceneAntialiasing.BALANCED
|
root3D, 1000, 1000, true, SceneAntialiasing.BALANCED
|
||||||
);
|
);
|
||||||
view.setCamera(camera);
|
view.setCamera(isometricCam);
|
||||||
camera.getTransforms().add(new Rotate(30, new Point3D(1,0,0)));
|
|
||||||
|
|
||||||
gameObjects.getChildren().addAll(
|
gameObjects.getChildren().addAll(
|
||||||
ModelFactory.importModel(ModelType.OCEAN).getAssets(),
|
ModelFactory.importModel(ModelType.OCEAN).getAssets(),
|
||||||
@@ -337,7 +348,6 @@ public class GameView3D {
|
|||||||
* it to distanceScaleFactor Returns the max horizontal distance of the map.
|
* it to distanceScaleFactor Returns the max horizontal distance of the map.
|
||||||
*/
|
*/
|
||||||
private double scaleRaceExtremities() {
|
private double scaleRaceExtremities() {
|
||||||
|
|
||||||
double vertAngle = Math.abs(
|
double vertAngle = Math.abs(
|
||||||
GeoUtility.getBearingRad(minLatPoint, maxLatPoint)
|
GeoUtility.getBearingRad(minLatPoint, maxLatPoint)
|
||||||
);
|
);
|
||||||
@@ -405,40 +415,45 @@ public class GameView3D {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void cameraMovement(KeyEvent event) {
|
public void cameraMovement(KeyEvent event) {
|
||||||
switch (event.getCode()) {
|
GameKeyBind keyBinds = GameKeyBind.getInstance();
|
||||||
case NUMPAD8:
|
KeyAction keyPressed = keyBinds.getKeyAction(event.getCode());
|
||||||
camera.getTransforms().addAll(new Rotate(0.5, new Point3D(1,0,0)));
|
switch (keyPressed) {
|
||||||
|
case ZOOM_IN:
|
||||||
|
((RaceCamera) view.getCamera()).zoomIn();
|
||||||
break;
|
break;
|
||||||
case NUMPAD2:
|
case ZOOM_OUT:
|
||||||
camera.getTransforms().addAll(new Rotate(-0.5, new Point3D(1,0,0)));
|
((RaceCamera) view.getCamera()).zoomOut();
|
||||||
break;
|
break;
|
||||||
case NUMPAD4:
|
case FORWARD:
|
||||||
camera.getTransforms().addAll(new Rotate(-0.5, new Point3D(0,1,0)));
|
((RaceCamera) view.getCamera()).panUp();
|
||||||
break;
|
break;
|
||||||
case NUMPAD6:
|
case BACKWARD:
|
||||||
camera.getTransforms().addAll(new Rotate(0.5, new Point3D(0,1,0)));
|
((RaceCamera) view.getCamera()).panDown();
|
||||||
break;
|
break;
|
||||||
case Z:
|
case LEFT:
|
||||||
camera.getTransforms().addAll(new Translate(0, 0, 1.5));
|
((RaceCamera) view.getCamera()).panLeft();
|
||||||
break;
|
break;
|
||||||
case X:
|
case RIGHT:
|
||||||
camera.getTransforms().addAll(new Translate(0, 0, -1.5));
|
((RaceCamera) view.getCamera()).panRight();
|
||||||
break;
|
break;
|
||||||
case W:
|
case VIEW:
|
||||||
camera.getTransforms().addAll(new Translate(0, -1, 0));
|
toggleCamera();
|
||||||
break;
|
|
||||||
case S:
|
|
||||||
camera.getTransforms().addAll(new Translate(0, 1, 0));
|
|
||||||
break;
|
|
||||||
case A:
|
|
||||||
camera.getTransforms().addAll(new Translate(-1, 0, 0));
|
|
||||||
break;
|
|
||||||
case D:
|
|
||||||
camera.getTransforms().addAll(new Translate(1, 0, 0));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void toggleCamera() {
|
||||||
|
Camera currCamera = view.getCamera();
|
||||||
|
|
||||||
|
if (currCamera.equals(isometricCam)) {
|
||||||
|
view.setCamera(topDownCam);
|
||||||
|
} else if (currCamera.equals(topDownCam)) {
|
||||||
|
view.setCamera(chaseCam);
|
||||||
|
} else {
|
||||||
|
view.setCamera(isometricCam);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rescales the race to the size of the window.
|
* Rescales the race to the size of the window.
|
||||||
*
|
*
|
||||||
@@ -469,6 +484,12 @@ public class GameView3D {
|
|||||||
boatObjectGroup.getChildren().add(newBoat);
|
boatObjectGroup.getChildren().add(newBoat);
|
||||||
clientYacht.addLocationListener(this::updateBoatLocation);
|
clientYacht.addLocationListener(this::updateBoatLocation);
|
||||||
clientYacht.addColorChangeListener(this::updateBoatColor);
|
clientYacht.addColorChangeListener(this::updateBoatColor);
|
||||||
|
|
||||||
|
if (clientYacht.getSourceId().equals(
|
||||||
|
ViewManager.getInstance().getGameClient().getServerThread().getClientId())) {
|
||||||
|
((ChaseCamera) chaseCam).setPlayerBoat(newBoat);
|
||||||
|
((TopDownCamera) topDownCam).setPlayerBoat(newBoat);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
gameObjects.getChildren().addAll(wakes);
|
gameObjects.getChildren().addAll(wakes);
|
||||||
|
|||||||
@@ -0,0 +1,130 @@
|
|||||||
|
package seng302.visualiser.cameras;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import javafx.beans.property.DoubleProperty;
|
||||||
|
import javafx.collections.ObservableList;
|
||||||
|
import javafx.geometry.Point3D;
|
||||||
|
import javafx.scene.PerspectiveCamera;
|
||||||
|
import javafx.scene.transform.Rotate;
|
||||||
|
import javafx.scene.transform.Transform;
|
||||||
|
import javafx.scene.transform.Translate;
|
||||||
|
import seng302.visualiser.fxObjects.assets_3D.BoatObject;
|
||||||
|
|
||||||
|
|
||||||
|
public class ChaseCamera extends PerspectiveCamera implements RaceCamera {
|
||||||
|
|
||||||
|
private final Double VERTICAL_PAN_LIMIT = 20.0;
|
||||||
|
private final Double NEAR_ZOOM_LIMIT = -15.0;
|
||||||
|
private final Double FAR_ZOOM_LIMIT = -125.0;
|
||||||
|
|
||||||
|
private final Double ZOOM_STEP = 2.5;
|
||||||
|
private final Double PAN_STEP = 2.5;
|
||||||
|
|
||||||
|
private ObservableList<Transform> transforms;
|
||||||
|
private BoatObject playerBoat;
|
||||||
|
|
||||||
|
private Double zoomFactor;
|
||||||
|
private Double horizontalPan;
|
||||||
|
private Double verticalPan;
|
||||||
|
|
||||||
|
|
||||||
|
public ChaseCamera() {
|
||||||
|
super(true);
|
||||||
|
transforms = this.getTransforms();
|
||||||
|
|
||||||
|
zoomFactor = (FAR_ZOOM_LIMIT + NEAR_ZOOM_LIMIT) / 2.0;
|
||||||
|
this.horizontalPan = 0.0;
|
||||||
|
this.verticalPan = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a player boat object to observe and update the camera with.
|
||||||
|
*
|
||||||
|
* @param playerBoat The player boat to be observed.
|
||||||
|
*/
|
||||||
|
public void setPlayerBoat(BoatObject playerBoat) {
|
||||||
|
this.playerBoat = playerBoat;
|
||||||
|
|
||||||
|
for (DoubleProperty o : Arrays
|
||||||
|
.asList(playerBoat.getRotationProperty(), playerBoat.layoutYProperty(),
|
||||||
|
playerBoat.layoutXProperty())) {
|
||||||
|
o.addListener((obs, oldVal, newVal) -> repositionCamera());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves the camera to a new position after some change (Zooming or Panning)
|
||||||
|
*/
|
||||||
|
private void repositionCamera() {
|
||||||
|
transforms.clear();
|
||||||
|
transforms.addAll(
|
||||||
|
new Translate(playerBoat.getLayoutX(), playerBoat.getLayoutY(), 0),
|
||||||
|
new Rotate(playerBoat.getRotationProperty().getValue() + horizontalPan,
|
||||||
|
new Point3D(0, 0, 1)),
|
||||||
|
new Rotate(60 + verticalPan, new Point3D(1, 0, 0)),
|
||||||
|
new Translate(0, 0, zoomFactor)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjusts the zoom amount (camera depth) by some adjustment value
|
||||||
|
* @param adjustment the adjustment to be made to the camera
|
||||||
|
*/
|
||||||
|
private void adjustZoomFactor(Double adjustment) {
|
||||||
|
if (zoomFactor + adjustment < NEAR_ZOOM_LIMIT && zoomFactor + adjustment > FAR_ZOOM_LIMIT) {
|
||||||
|
zoomFactor = zoomFactor + adjustment;
|
||||||
|
repositionCamera();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjusts the Vertical Panning of the Camera
|
||||||
|
* @param adjustment the adjustment to be made to the camera
|
||||||
|
*/
|
||||||
|
private void adjustVerticalPan(Double adjustment) {
|
||||||
|
if (verticalPan + adjustment >= -VERTICAL_PAN_LIMIT
|
||||||
|
&& verticalPan + adjustment <= VERTICAL_PAN_LIMIT) {
|
||||||
|
verticalPan += adjustment;
|
||||||
|
repositionCamera();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjusts the Horizontal Panning of the Camera.
|
||||||
|
* @param adjustment the adjustment to be made to the camera
|
||||||
|
*/
|
||||||
|
private void adjustHorizontalPan(Double adjustment) {
|
||||||
|
this.horizontalPan += adjustment;
|
||||||
|
repositionCamera();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void zoomIn() {
|
||||||
|
adjustZoomFactor(ZOOM_STEP);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void zoomOut() {
|
||||||
|
adjustZoomFactor(-ZOOM_STEP);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void panLeft() {
|
||||||
|
adjustHorizontalPan(-PAN_STEP);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void panRight() {
|
||||||
|
adjustHorizontalPan(PAN_STEP);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void panUp() {
|
||||||
|
adjustVerticalPan(-PAN_STEP);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void panDown() {
|
||||||
|
adjustVerticalPan(PAN_STEP);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
package seng302.visualiser.cameras;
|
||||||
|
|
||||||
|
import javafx.collections.ObservableList;
|
||||||
|
import javafx.geometry.Point3D;
|
||||||
|
import javafx.scene.PerspectiveCamera;
|
||||||
|
import javafx.scene.transform.Rotate;
|
||||||
|
import javafx.scene.transform.Transform;
|
||||||
|
import javafx.scene.transform.Translate;
|
||||||
|
|
||||||
|
public class IsometricCamera extends PerspectiveCamera implements RaceCamera {
|
||||||
|
|
||||||
|
private final Double MIN_X = -120.0;
|
||||||
|
private final Double MAX_X = 125.0;
|
||||||
|
|
||||||
|
private final Double MIN_Y = 40.0;
|
||||||
|
private final Double MAX_Y = 170.0;
|
||||||
|
|
||||||
|
private final Double PAN_LIMIT = 160.0;
|
||||||
|
private final Double NEAR_ZOOM_LIMIT = -50.0;
|
||||||
|
private final Double FAR_ZOOM_LIMIT = -160.0;
|
||||||
|
|
||||||
|
private Double horizontalPan;
|
||||||
|
private Double verticalPan;
|
||||||
|
private Double zoomFactor;
|
||||||
|
|
||||||
|
private ObservableList<Transform> transforms;
|
||||||
|
|
||||||
|
public IsometricCamera(Double cameraStartX, Double cameraStartY) {
|
||||||
|
super(true);
|
||||||
|
transforms = this.getTransforms();
|
||||||
|
|
||||||
|
zoomFactor = (FAR_ZOOM_LIMIT + NEAR_ZOOM_LIMIT) / 2.0;
|
||||||
|
horizontalPan = cameraStartX;
|
||||||
|
verticalPan = cameraStartY;
|
||||||
|
|
||||||
|
updateCamera();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves the camera to a new position after some change (Zooming or Panning)
|
||||||
|
*/
|
||||||
|
private void updateCamera() {
|
||||||
|
transforms.clear();
|
||||||
|
transforms.addAll(
|
||||||
|
new Translate(horizontalPan, verticalPan, zoomFactor),
|
||||||
|
new Rotate(30, new Point3D(1, 0, 0))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjusts the zoom amount (camera depth) by some adjustment value
|
||||||
|
*
|
||||||
|
* @param adjustment the adjustment to be made to the camera
|
||||||
|
*/
|
||||||
|
private void adjustZoomFactor(Double adjustment) {
|
||||||
|
if (zoomFactor + adjustment < NEAR_ZOOM_LIMIT && zoomFactor + adjustment > FAR_ZOOM_LIMIT) {
|
||||||
|
zoomFactor = zoomFactor + adjustment;
|
||||||
|
updateCamera();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjusts the Vertical Panning of the Camera
|
||||||
|
* @param adjustment the adjustment to be made to the camera
|
||||||
|
*/
|
||||||
|
private void adjustVerticalPan(Double adjustment) {
|
||||||
|
if (verticalPan + adjustment >= MIN_Y && verticalPan + adjustment <= MAX_Y) {
|
||||||
|
verticalPan += adjustment;
|
||||||
|
updateCamera();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjusts the Horizontal Panning of the Camera.
|
||||||
|
* @param adjustment the adjustment to be made to the camera
|
||||||
|
*/
|
||||||
|
private void adjustHorizontalPan(Double adjustment) {
|
||||||
|
if (horizontalPan + adjustment >= MIN_X && horizontalPan + adjustment <= MIN_Y) {
|
||||||
|
this.horizontalPan += adjustment;
|
||||||
|
updateCamera();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void zoomIn() {
|
||||||
|
adjustZoomFactor(-2.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void zoomOut() {
|
||||||
|
adjustZoomFactor(2.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void panLeft() {
|
||||||
|
adjustHorizontalPan(-2.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void panRight() {
|
||||||
|
adjustHorizontalPan(2.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void panUp() {
|
||||||
|
adjustVerticalPan(-2.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void panDown() {
|
||||||
|
adjustVerticalPan(2.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package seng302.visualiser.cameras;
|
||||||
|
|
||||||
|
|
||||||
|
public interface RaceCamera {
|
||||||
|
|
||||||
|
void zoomIn();
|
||||||
|
|
||||||
|
void zoomOut();
|
||||||
|
|
||||||
|
void panLeft();
|
||||||
|
|
||||||
|
void panRight();
|
||||||
|
|
||||||
|
void panUp();
|
||||||
|
|
||||||
|
void panDown();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
package seng302.visualiser.cameras;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import javafx.beans.property.DoubleProperty;
|
||||||
|
import javafx.collections.ObservableList;
|
||||||
|
import javafx.scene.PerspectiveCamera;
|
||||||
|
import javafx.scene.transform.Transform;
|
||||||
|
import javafx.scene.transform.Translate;
|
||||||
|
import seng302.visualiser.fxObjects.assets_3D.BoatObject;
|
||||||
|
|
||||||
|
public class TopDownCamera extends PerspectiveCamera implements RaceCamera {
|
||||||
|
|
||||||
|
private final Double PAN_LIMIT = 30.0;
|
||||||
|
private final Double NEAR_ZOOM_LIMIT = -30.0;
|
||||||
|
private final Double FAR_ZOOM_LIMIT = -130.0;
|
||||||
|
private final Double ZOOM_STEP = 2.5;
|
||||||
|
|
||||||
|
private ObservableList<Transform> transforms;
|
||||||
|
private BoatObject playerBoat;
|
||||||
|
|
||||||
|
private Double zoomFactor;
|
||||||
|
private Double horizontalPan;
|
||||||
|
private Double verticalPan;
|
||||||
|
|
||||||
|
public TopDownCamera() {
|
||||||
|
super(true);
|
||||||
|
transforms = this.getTransforms();
|
||||||
|
|
||||||
|
zoomFactor = (FAR_ZOOM_LIMIT + NEAR_ZOOM_LIMIT) / 2.0;
|
||||||
|
horizontalPan = 0.0;
|
||||||
|
verticalPan = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a player boat object to observe and update the camera with.
|
||||||
|
*
|
||||||
|
* @param playerBoat The player boat to be observed.
|
||||||
|
*/
|
||||||
|
public void setPlayerBoat(BoatObject playerBoat) {
|
||||||
|
this.playerBoat = playerBoat;
|
||||||
|
|
||||||
|
for (DoubleProperty o : Arrays
|
||||||
|
.asList(playerBoat.layoutXProperty(), playerBoat.layoutYProperty())) {
|
||||||
|
o.addListener((obs, oldVal, newVal) -> updateCamera());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves the camera to a new position after some change (Zooming or Panning)
|
||||||
|
*/
|
||||||
|
private void updateCamera() {
|
||||||
|
transforms.clear();
|
||||||
|
transforms.addAll(
|
||||||
|
new Translate(playerBoat.getLayoutX() + horizontalPan,
|
||||||
|
playerBoat.getLayoutY() + verticalPan, zoomFactor)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjusts the zoom amount (camera depth) by some adjustment value
|
||||||
|
* @param adjustment the adjustment to be made to the camera
|
||||||
|
*/
|
||||||
|
private void adjustZoomFactor(Double adjustment) {
|
||||||
|
if (zoomFactor + adjustment < NEAR_ZOOM_LIMIT && zoomFactor + adjustment > FAR_ZOOM_LIMIT) {
|
||||||
|
zoomFactor = zoomFactor + adjustment;
|
||||||
|
updateCamera();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjusts the Vertical Panning of the Camera
|
||||||
|
* @param adjustment the adjustment to be made to the camera
|
||||||
|
*/
|
||||||
|
private void adjustVerticalPan(Double adjustment) {
|
||||||
|
if (verticalPan + adjustment >= -PAN_LIMIT && verticalPan + adjustment <= PAN_LIMIT) {
|
||||||
|
verticalPan += adjustment;
|
||||||
|
updateCamera();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjusts the Horizontal Panning of the Camera.
|
||||||
|
* @param adjustment the adjustment to be made to the camera
|
||||||
|
*/
|
||||||
|
private void adjustHorizontalPan(Double adjustment) {
|
||||||
|
if (horizontalPan + adjustment >= -PAN_LIMIT && horizontalPan + adjustment <= PAN_LIMIT) {
|
||||||
|
horizontalPan += adjustment;
|
||||||
|
updateCamera();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void zoomIn() {
|
||||||
|
adjustZoomFactor(ZOOM_STEP);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void zoomOut() {
|
||||||
|
adjustZoomFactor(-ZOOM_STEP);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void panLeft() {
|
||||||
|
adjustHorizontalPan(-1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void panRight() {
|
||||||
|
adjustHorizontalPan(1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void panUp() {
|
||||||
|
adjustVerticalPan(-1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void panDown() {
|
||||||
|
adjustVerticalPan(1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -88,7 +88,6 @@ public class FinishScreenViewController implements Initializable {
|
|||||||
|
|
||||||
public void switchToStartScreenView() {
|
public void switchToStartScreenView() {
|
||||||
Sounds.playButtonClick();
|
Sounds.playButtonClick();
|
||||||
//TODO merge fix
|
|
||||||
setContentPane("/views/StartScreenView.fxml");
|
setContentPane("/views/StartScreenView.fxml");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import seng302.utilities.BonjourInstallChecker;
|
|||||||
import seng302.utilities.Sounds;
|
import seng302.utilities.Sounds;
|
||||||
import seng302.visualiser.GameClient;
|
import seng302.visualiser.GameClient;
|
||||||
import seng302.visualiser.controllers.dialogs.KeyBindingDialogController;
|
import seng302.visualiser.controllers.dialogs.KeyBindingDialogController;
|
||||||
|
import seng302.visualiser.controllers.dialogs.PopupDialogController;
|
||||||
|
|
||||||
public class ViewManager {
|
public class ViewManager {
|
||||||
|
|
||||||
@@ -229,6 +230,26 @@ public class ViewManager {
|
|||||||
keyBindingDialog.close();
|
keyBindingDialog.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PopupDialogController showPopupDialog() {
|
||||||
|
FXMLLoader dialogContent = new FXMLLoader(
|
||||||
|
getClass().getResource("/views/dialogs/PopupDialog.fxml"));
|
||||||
|
for (Node node : decorator.getChildren()) {
|
||||||
|
if (node instanceof StackPane) {
|
||||||
|
try {
|
||||||
|
JFXDialog dialog = new JFXDialog((StackPane) node, dialogContent.load(),
|
||||||
|
DialogTransition.CENTER);
|
||||||
|
PopupDialogController popupDialogController = dialogContent.getController();
|
||||||
|
popupDialogController.setPopupDialog(dialog);
|
||||||
|
dialog.show();
|
||||||
|
return popupDialogController;
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.error("Cannot load Popup dialog");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show a snackbar at the bottom of the app for 1 second.
|
* Show a snackbar at the bottom of the app for 1 second.
|
||||||
*
|
*
|
||||||
|
|||||||
+14
-2
@@ -48,6 +48,16 @@ public class KeyBindingDialogController implements Initializable {
|
|||||||
private Label downwindLabel;
|
private Label downwindLabel;
|
||||||
@FXML
|
@FXML
|
||||||
private JFXToggleButton turningToggle;
|
private JFXToggleButton turningToggle;
|
||||||
|
@FXML
|
||||||
|
private JFXButton viewButton;
|
||||||
|
@FXML
|
||||||
|
private JFXButton rightButton;
|
||||||
|
@FXML
|
||||||
|
private JFXButton leftButton;
|
||||||
|
@FXML
|
||||||
|
private JFXButton forwardButton;
|
||||||
|
@FXML
|
||||||
|
private JFXButton backwardButton;
|
||||||
//---------FXML END---------//
|
//---------FXML END---------//
|
||||||
|
|
||||||
private GameKeyBind gameKeyBind;
|
private GameKeyBind gameKeyBind;
|
||||||
@@ -60,7 +70,9 @@ public class KeyBindingDialogController implements Initializable {
|
|||||||
gameKeyBind = GameKeyBind.getInstance();
|
gameKeyBind = GameKeyBind.getInstance();
|
||||||
buttons = new ArrayList<>();
|
buttons = new ArrayList<>();
|
||||||
Collections.addAll(buttons,
|
Collections.addAll(buttons,
|
||||||
zoomInbtn, zoomOutBtn, vmgBtn, sailInOutBtn, tackGybeBtn, upwindBtn, downwindBtn);
|
zoomInbtn, zoomOutBtn, vmgBtn, sailInOutBtn, tackGybeBtn, upwindBtn, downwindBtn,
|
||||||
|
viewButton,
|
||||||
|
rightButton, leftButton, forwardButton, backwardButton);
|
||||||
bindButtonWithAction();
|
bindButtonWithAction();
|
||||||
loadKeyBind();
|
loadKeyBind();
|
||||||
|
|
||||||
@@ -106,7 +118,7 @@ public class KeyBindingDialogController implements Initializable {
|
|||||||
*/
|
*/
|
||||||
private void bindButtonWithAction() {
|
private void bindButtonWithAction() {
|
||||||
buttonActionMap = new HashMap<>();
|
buttonActionMap = new HashMap<>();
|
||||||
for (int i = 0; i < 7; i++) {
|
for (int i = 0; i < 12; i++) {
|
||||||
buttonActionMap.put(buttons.get(i), KeyAction.getType(i + 1));
|
buttonActionMap.put(buttons.get(i), KeyAction.getType(i + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package seng302.visualiser.controllers.dialogs;
|
||||||
|
|
||||||
|
import com.jfoenix.controls.JFXButton;
|
||||||
|
import com.jfoenix.controls.JFXDialog;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
import javafx.event.EventHandler;
|
||||||
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.fxml.Initializable;
|
||||||
|
import javafx.scene.control.Label;
|
||||||
|
import javafx.scene.input.MouseEvent;
|
||||||
|
|
||||||
|
public class PopupDialogController implements Initializable {
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private Label headerLabel;
|
||||||
|
@FXML
|
||||||
|
private Label contentLabel;
|
||||||
|
@FXML
|
||||||
|
private Label closeLabel;
|
||||||
|
@FXML
|
||||||
|
private JFXButton optionButton;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private JFXDialog popupDialog;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize(URL location, ResourceBundle resources) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContent(String content) {
|
||||||
|
this.contentLabel.setText(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeader(String header) {
|
||||||
|
this.headerLabel.setText(header);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOptionButton(JFXButton jfxButton) {
|
||||||
|
this.optionButton = jfxButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOptionButtonText(String text) {
|
||||||
|
this.optionButton.setText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOptionButtonEventHandler(EventHandler<? super MouseEvent> eventHandler) {
|
||||||
|
this.optionButton.setOnMouseClicked(eventHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPopupDialog(JFXDialog popupDialog) {
|
||||||
|
this.popupDialog = popupDialog;
|
||||||
|
this.closeLabel.setOnMouseClicked(event -> this.popupDialog.close());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ package seng302.visualiser.fxObjects.assets_3D;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
|
import javafx.beans.property.ReadOnlyDoubleWrapper;
|
||||||
import javafx.geometry.Point3D;
|
import javafx.geometry.Point3D;
|
||||||
import javafx.scene.Group;
|
import javafx.scene.Group;
|
||||||
import javafx.scene.paint.Color;
|
import javafx.scene.paint.Color;
|
||||||
@@ -30,12 +31,15 @@ public class BoatObject extends Group {
|
|||||||
private Boolean isSelected = false;
|
private Boolean isSelected = false;
|
||||||
private Rotate rotation = new Rotate(0, new Point3D(0,0,1));
|
private Rotate rotation = new Rotate(0, new Point3D(0,0,1));
|
||||||
|
|
||||||
|
private ReadOnlyDoubleWrapper rotationProperty;
|
||||||
|
|
||||||
private List<SelectedBoatListener> selectedBoatListenerListeners = new ArrayList<>();
|
private List<SelectedBoatListener> selectedBoatListenerListeners = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a BoatGroup with the default triangular boat polygon.
|
* Creates a BoatGroup with the default triangular boat polygon.
|
||||||
*/
|
*/
|
||||||
public BoatObject(BoatMeshType boatMeshType) {
|
public BoatObject(BoatMeshType boatMeshType) {
|
||||||
|
rotationProperty = new ReadOnlyDoubleWrapper(0.0);
|
||||||
boatAssets = ModelFactory.boatGameView(boatMeshType, colour);
|
boatAssets = ModelFactory.boatGameView(boatMeshType, colour);
|
||||||
boatAssets.hideSail();
|
boatAssets.hideSail();
|
||||||
boatAssets.getAssets().getTransforms().addAll(
|
boatAssets.getAssets().getTransforms().addAll(
|
||||||
@@ -83,6 +87,7 @@ public class BoatObject extends Group {
|
|||||||
|
|
||||||
|
|
||||||
private void rotateTo(double heading, boolean sailsIn, double windDir) {
|
private void rotateTo(double heading, boolean sailsIn, double windDir) {
|
||||||
|
rotationProperty.set(heading);
|
||||||
rotation.setAngle(heading);
|
rotation.setAngle(heading);
|
||||||
wake.getTransforms().setAll(new Rotate(heading, new Point3D(0,0,1)));
|
wake.getTransforms().setAll(new Rotate(heading, new Point3D(0,0,1)));
|
||||||
if (sailsIn) {
|
if (sailsIn) {
|
||||||
@@ -130,4 +135,8 @@ public class BoatObject extends Group {
|
|||||||
public void addSelectedBoatListener(SelectedBoatListener sbl) {
|
public void addSelectedBoatListener(SelectedBoatListener sbl) {
|
||||||
selectedBoatListenerListeners.add(sbl);
|
selectedBoatListenerListeners.add(sbl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ReadOnlyDoubleWrapper getRotationProperty() {
|
||||||
|
return rotationProperty;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -51,6 +51,11 @@
|
|||||||
|
|
||||||
/********* customised scroll bar for scroll pane ***********/
|
/********* customised scroll bar for scroll pane ***********/
|
||||||
|
|
||||||
|
.scroll-pane {
|
||||||
|
-fx-focus-traversable: false;
|
||||||
|
-fx-border-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
/* The main scrollbar **track** CSS class */
|
/* The main scrollbar **track** CSS class */
|
||||||
.scroll-bar:horizontal .track,
|
.scroll-bar:horizontal .track,
|
||||||
.scroll-bar:vertical .track {
|
.scroll-bar:vertical .track {
|
||||||
|
|||||||
@@ -9,8 +9,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#closeLabel:hover {
|
#closeLabel:hover {
|
||||||
-fx-text-fill: -fx-pp-theme-color;
|
-fx-text-fill: red;
|
||||||
-fx-font-size: 33;
|
-fx-font-size: 33px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sectionLabel {
|
||||||
|
-fx-text-fill: -fx-pp-dark-text-color;
|
||||||
|
-fx-font-size: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
JFXButton {
|
JFXButton {
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
#headerLabel {
|
||||||
|
-fx-font-size: 20px;
|
||||||
|
-fx-text-fill: -fx-pp-dark-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
#closeLabel {
|
||||||
|
-fx-font-size: 22px;
|
||||||
|
-fx-text-fill: -fx-pp-dark-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
#closeLabel:hover {
|
||||||
|
-fx-font-size: 24px;
|
||||||
|
-fx-text-fill: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
#contentLabel {
|
||||||
|
-fx-font-size: 22px;
|
||||||
|
-fx-text-fill: -fx-pp-dark-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
#optionButton {
|
||||||
|
-fx-background-color: -fx-pp-theme-color;
|
||||||
|
-fx-text-fill: -fx-pp-light-text-color;
|
||||||
|
-fx-font-size: 18px;
|
||||||
|
-fx-effect: -fx-pp-dropshadow-light;
|
||||||
|
-fx-max-height: 55;
|
||||||
|
-fx-focus-traversable: false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#optionButton:hover {
|
||||||
|
-fx-font-size: 20px !important;
|
||||||
|
-fx-background-color: -fx-pp-light-theme-color;
|
||||||
|
}
|
||||||
@@ -6,117 +6,226 @@
|
|||||||
<?import java.net.URL?>
|
<?import java.net.URL?>
|
||||||
<?import javafx.geometry.Insets?>
|
<?import javafx.geometry.Insets?>
|
||||||
<?import javafx.scene.control.Label?>
|
<?import javafx.scene.control.Label?>
|
||||||
|
<?import javafx.scene.control.ScrollPane?>
|
||||||
<?import javafx.scene.layout.ColumnConstraints?>
|
<?import javafx.scene.layout.ColumnConstraints?>
|
||||||
<?import javafx.scene.layout.GridPane?>
|
<?import javafx.scene.layout.GridPane?>
|
||||||
<?import javafx.scene.layout.RowConstraints?>
|
<?import javafx.scene.layout.RowConstraints?>
|
||||||
|
<?import javafx.scene.layout.StackPane?>
|
||||||
<JFXDialogLayout fx:id="keyBindDialog" maxHeight="-Infinity" maxWidth="-Infinity"
|
<JFXDialogLayout fx:id="keyBindDialog" maxHeight="-Infinity" maxWidth="-Infinity"
|
||||||
minHeight="-Infinity" minWidth="-Infinity" prefHeight="580.0" prefWidth="500.0"
|
minHeight="-Infinity" minWidth="-Infinity" prefHeight="580.0" prefWidth="500.0"
|
||||||
xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
|
xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
|
||||||
fx:controller="seng302.visualiser.controllers.dialogs.KeyBindingDialogController">
|
fx:controller="seng302.visualiser.controllers.dialogs.KeyBindingDialogController">
|
||||||
|
<stylesheets>
|
||||||
|
<URL value="@../../css/dialogs/KeyBindingDialog.css"/>
|
||||||
|
<URL value="@../../css/Master.css"/>
|
||||||
|
</stylesheets>
|
||||||
<children>
|
<children>
|
||||||
<GridPane>
|
<GridPane>
|
||||||
<columnConstraints>
|
<columnConstraints>
|
||||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="100.0" prefWidth="100.0"/>
|
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
|
||||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="100.0" prefWidth="100.0"/>
|
|
||||||
</columnConstraints>
|
</columnConstraints>
|
||||||
<rowConstraints>
|
<rowConstraints>
|
||||||
<RowConstraints maxHeight="60.0" minHeight="60.0" prefHeight="60.0" vgrow="SOMETIMES" />
|
<RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="60.0"
|
||||||
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES"/>
|
vgrow="SOMETIMES"/>
|
||||||
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES"/>
|
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
|
||||||
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES"/>
|
<RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="60.0"
|
||||||
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES"/>
|
|
||||||
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES"/>
|
|
||||||
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES"/>
|
|
||||||
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES"/>
|
|
||||||
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES"/>
|
|
||||||
<RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="70.0"
|
|
||||||
vgrow="SOMETIMES"/>
|
vgrow="SOMETIMES"/>
|
||||||
</rowConstraints>
|
</rowConstraints>
|
||||||
<children>
|
<children>
|
||||||
<Label fx:id="keyBindingDialogHeader" text="CUSTOM KEYBIND" GridPane.columnSpan="2" GridPane.halignment="CENTER" GridPane.valignment="CENTER" />
|
<ScrollPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="1">
|
||||||
<Label text="ZOOM IN" GridPane.halignment="CENTER" GridPane.rowIndex="1"
|
<content>
|
||||||
GridPane.valignment="CENTER">
|
<StackPane prefHeight="150.0" prefWidth="200.0">
|
||||||
<GridPane.margin>
|
<children>
|
||||||
<Insets/>
|
<GridPane>
|
||||||
</GridPane.margin></Label>
|
<children>
|
||||||
<Label text="ZOOM OUT" GridPane.halignment="CENTER" GridPane.rowIndex="2"
|
<JFXButton fx:id="viewButton" buttonType="RAISED"
|
||||||
GridPane.valignment="CENTER">
|
minHeight="35.0" prefWidth="120.0" text="F1"
|
||||||
<GridPane.margin>
|
GridPane.columnIndex="1" GridPane.halignment="CENTER"
|
||||||
<Insets/>
|
GridPane.rowIndex="14" GridPane.valignment="CENTER"/>
|
||||||
</GridPane.margin></Label>
|
<Label text="VIEW ASPECT" GridPane.halignment="CENTER"
|
||||||
<Label text="VMG" GridPane.halignment="CENTER" GridPane.rowIndex="3"
|
GridPane.rowIndex="14" GridPane.valignment="CENTER"/>
|
||||||
GridPane.valignment="CENTER">
|
<JFXButton fx:id="rightButton" buttonType="RAISED"
|
||||||
<GridPane.margin>
|
minHeight="35.0" prefWidth="120.0" text="D"
|
||||||
<Insets/>
|
GridPane.columnIndex="1" GridPane.halignment="CENTER"
|
||||||
</GridPane.margin></Label>
|
GridPane.rowIndex="13" GridPane.valignment="CENTER"/>
|
||||||
<Label text="SAILS IN/OUT" GridPane.halignment="CENTER" GridPane.rowIndex="4"
|
<Label text="RIGHT" GridPane.halignment="CENTER"
|
||||||
GridPane.valignment="CENTER">
|
GridPane.rowIndex="13" GridPane.valignment="CENTER"/>
|
||||||
<GridPane.margin>
|
<JFXButton fx:id="leftButton" buttonType="RAISED"
|
||||||
<Insets/>
|
minHeight="35.0" prefWidth="120.0" text="A"
|
||||||
</GridPane.margin></Label>
|
GridPane.columnIndex="1" GridPane.halignment="CENTER"
|
||||||
<Label text="TACK/GYBE" GridPane.halignment="CENTER" GridPane.rowIndex="5"
|
GridPane.rowIndex="12" GridPane.valignment="CENTER"/>
|
||||||
GridPane.valignment="CENTER">
|
<Label text="LEFT" GridPane.halignment="CENTER"
|
||||||
<GridPane.margin>
|
GridPane.rowIndex="12" GridPane.valignment="CENTER"/>
|
||||||
<Insets/>
|
<JFXButton fx:id="forwardButton" buttonType="RAISED"
|
||||||
</GridPane.margin></Label>
|
minHeight="35.0" prefWidth="120.0" text="W"
|
||||||
<Label fx:id="upwindLabel" text="UPWIND" GridPane.halignment="CENTER"
|
GridPane.columnIndex="1" GridPane.halignment="CENTER"
|
||||||
GridPane.rowIndex="6" GridPane.valignment="CENTER">
|
GridPane.rowIndex="10" GridPane.valignment="CENTER"/>
|
||||||
<GridPane.margin>
|
<Label text="FORWARD" GridPane.halignment="CENTER"
|
||||||
<Insets/>
|
GridPane.rowIndex="10" GridPane.valignment="CENTER"/>
|
||||||
</GridPane.margin></Label>
|
<JFXButton fx:id="backwardButton" buttonType="RAISED"
|
||||||
<Label fx:id="downwindLabel" text="DOWNWIND" GridPane.halignment="CENTER"
|
minHeight="35.0" prefWidth="120.0" text="S"
|
||||||
GridPane.rowIndex="7" GridPane.valignment="CENTER">
|
GridPane.columnIndex="1" GridPane.halignment="CENTER"
|
||||||
<GridPane.margin>
|
GridPane.rowIndex="11" GridPane.valignment="CENTER"/>
|
||||||
<Insets/>
|
<Label text="BACKWARD" GridPane.halignment="CENTER"
|
||||||
</GridPane.margin></Label>
|
GridPane.rowIndex="11" GridPane.valignment="CENTER"/>
|
||||||
<JFXButton id="ZOOM IN" fx:id="zoomInbtn" buttonType="RAISED" maxHeight="-Infinity"
|
<Label text="ZOOM IN" GridPane.halignment="CENTER"
|
||||||
maxWidth="-Infinity" minHeight="35.0" minWidth="-Infinity" prefWidth="120.0" text="Z"
|
GridPane.rowIndex="1" GridPane.valignment="CENTER">
|
||||||
GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="1"
|
<GridPane.margin>
|
||||||
GridPane.valignment="CENTER"/>
|
<Insets/>
|
||||||
<JFXButton id="ZOOM OUT" fx:id="zoomOutBtn" buttonType="RAISED" maxHeight="-Infinity"
|
</GridPane.margin>
|
||||||
maxWidth="-Infinity" minHeight="35.0" minWidth="-Infinity" prefWidth="120.0" text="X"
|
</Label>
|
||||||
GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="2"
|
<Label text="ZOOM OUT" GridPane.halignment="CENTER"
|
||||||
GridPane.valignment="CENTER"/>
|
GridPane.rowIndex="2" GridPane.valignment="CENTER">
|
||||||
<JFXButton id="VMG" fx:id="vmgBtn" buttonType="RAISED" maxHeight="-Infinity"
|
<GridPane.margin>
|
||||||
maxWidth="-Infinity" minHeight="35.0" minWidth="-Infinity" prefWidth="120.0"
|
<Insets/>
|
||||||
text="SPACE" GridPane.columnIndex="1" GridPane.halignment="CENTER"
|
</GridPane.margin>
|
||||||
GridPane.rowIndex="3" GridPane.valignment="CENTER"/>
|
</Label>
|
||||||
<JFXButton id="SAILS IN/OUT" fx:id="sailInOutBtn" buttonType="RAISED"
|
<Label text="VMG" GridPane.halignment="CENTER"
|
||||||
maxHeight="-Infinity" maxWidth="-Infinity" minHeight="35.0" minWidth="-Infinity"
|
GridPane.rowIndex="3" GridPane.valignment="CENTER">
|
||||||
prefWidth="120.0" text="SHIFT" GridPane.columnIndex="1" GridPane.halignment="CENTER"
|
<GridPane.margin>
|
||||||
GridPane.rowIndex="4" GridPane.valignment="CENTER"/>
|
<Insets/>
|
||||||
<JFXButton id="TACK/GYBE" fx:id="tackGybeBtn" buttonType="RAISED" maxHeight="-Infinity"
|
</GridPane.margin>
|
||||||
maxWidth="-Infinity" minHeight="35.0" minWidth="-Infinity" prefWidth="120.0"
|
</Label>
|
||||||
text="ENTER" GridPane.columnIndex="1" GridPane.halignment="CENTER"
|
<Label text="SAILS IN/OUT" GridPane.halignment="CENTER"
|
||||||
GridPane.rowIndex="5" GridPane.valignment="CENTER"/>
|
GridPane.rowIndex="4" GridPane.valignment="CENTER">
|
||||||
<JFXButton id="UPWIND" fx:id="upwindBtn" buttonType="RAISED" maxHeight="-Infinity"
|
<GridPane.margin>
|
||||||
maxWidth="-Infinity" minHeight="35.0" minWidth="-Infinity" prefWidth="120.0"
|
<Insets/>
|
||||||
text="PAGE_UP" GridPane.columnIndex="1" GridPane.halignment="CENTER"
|
</GridPane.margin>
|
||||||
GridPane.rowIndex="6" GridPane.valignment="CENTER"/>
|
</Label>
|
||||||
<JFXButton id="DOWNWIND" fx:id="downwindBtn" buttonType="RAISED" maxHeight="-Infinity"
|
<Label text="TACK/GYBE" GridPane.halignment="CENTER"
|
||||||
maxWidth="-Infinity" minHeight="35.0" minWidth="-Infinity" prefWidth="120.0"
|
GridPane.rowIndex="5" GridPane.valignment="CENTER">
|
||||||
text="PAGE_DOWN" GridPane.columnIndex="1" GridPane.halignment="CENTER"
|
<GridPane.margin>
|
||||||
GridPane.rowIndex="7" GridPane.valignment="CENTER"/>
|
<Insets/>
|
||||||
<JFXToggleButton fx:id="turningToggle" minHeight="-Infinity" prefHeight="35.0"
|
</GridPane.margin>
|
||||||
text="OFF / ON" GridPane.columnIndex="1" GridPane.halignment="CENTER"
|
</Label>
|
||||||
GridPane.rowIndex="8"/>
|
<Label fx:id="upwindLabel" text="UPWIND"
|
||||||
<Label text="CONTINUOUSLY TURNING" GridPane.halignment="CENTER" GridPane.rowIndex="8"
|
GridPane.halignment="CENTER" GridPane.rowIndex="6"
|
||||||
GridPane.valignment="CENTER">
|
GridPane.valignment="CENTER">
|
||||||
<GridPane.margin>
|
<GridPane.margin>
|
||||||
<Insets/>
|
<Insets/>
|
||||||
</GridPane.margin>
|
</GridPane.margin>
|
||||||
</Label>
|
</Label>
|
||||||
|
<Label fx:id="downwindLabel" text="DOWNWIND"
|
||||||
|
GridPane.halignment="CENTER" GridPane.rowIndex="7"
|
||||||
|
GridPane.valignment="CENTER">
|
||||||
|
<GridPane.margin>
|
||||||
|
<Insets/>
|
||||||
|
</GridPane.margin>
|
||||||
|
</Label>
|
||||||
|
<JFXButton id="ZOOM IN" fx:id="zoomInbtn" buttonType="RAISED"
|
||||||
|
maxHeight="-Infinity" maxWidth="-Infinity" minHeight="35.0"
|
||||||
|
minWidth="-Infinity" prefWidth="120.0" text="Z"
|
||||||
|
GridPane.columnIndex="1" GridPane.halignment="CENTER"
|
||||||
|
GridPane.rowIndex="1" GridPane.valignment="CENTER"/>
|
||||||
|
<JFXButton id="ZOOM OUT" fx:id="zoomOutBtn" buttonType="RAISED"
|
||||||
|
maxHeight="-Infinity" maxWidth="-Infinity" minHeight="35.0"
|
||||||
|
minWidth="-Infinity" prefWidth="120.0" text="X"
|
||||||
|
GridPane.columnIndex="1" GridPane.halignment="CENTER"
|
||||||
|
GridPane.rowIndex="2" GridPane.valignment="CENTER"/>
|
||||||
|
<JFXButton id="VMG" fx:id="vmgBtn" buttonType="RAISED"
|
||||||
|
maxHeight="-Infinity" maxWidth="-Infinity" minHeight="35.0"
|
||||||
|
minWidth="-Infinity" prefWidth="120.0" text="SPACE"
|
||||||
|
GridPane.columnIndex="1" GridPane.halignment="CENTER"
|
||||||
|
GridPane.rowIndex="3" GridPane.valignment="CENTER"/>
|
||||||
|
<JFXButton id="SAILS IN/OUT" fx:id="sailInOutBtn"
|
||||||
|
buttonType="RAISED" maxHeight="-Infinity"
|
||||||
|
maxWidth="-Infinity" minHeight="35.0" minWidth="-Infinity"
|
||||||
|
prefWidth="120.0" text="SHIFT" GridPane.columnIndex="1"
|
||||||
|
GridPane.halignment="CENTER" GridPane.rowIndex="4"
|
||||||
|
GridPane.valignment="CENTER"/>
|
||||||
|
<JFXButton id="TACK/GYBE" fx:id="tackGybeBtn"
|
||||||
|
buttonType="RAISED" maxHeight="-Infinity"
|
||||||
|
maxWidth="-Infinity" minHeight="35.0" minWidth="-Infinity"
|
||||||
|
prefWidth="120.0" text="ENTER" GridPane.columnIndex="1"
|
||||||
|
GridPane.halignment="CENTER" GridPane.rowIndex="5"
|
||||||
|
GridPane.valignment="CENTER"/>
|
||||||
|
<JFXButton id="UPWIND" fx:id="upwindBtn" buttonType="RAISED"
|
||||||
|
maxHeight="-Infinity" maxWidth="-Infinity" minHeight="35.0"
|
||||||
|
minWidth="-Infinity" prefWidth="120.0" text="PAGE_UP"
|
||||||
|
GridPane.columnIndex="1" GridPane.halignment="CENTER"
|
||||||
|
GridPane.rowIndex="6" GridPane.valignment="CENTER"/>
|
||||||
|
<JFXButton id="DOWNWIND" fx:id="downwindBtn"
|
||||||
|
buttonType="RAISED" maxHeight="-Infinity"
|
||||||
|
maxWidth="-Infinity" minHeight="35.0" minWidth="-Infinity"
|
||||||
|
prefWidth="120.0" text="PAGE_DOWN" GridPane.columnIndex="1"
|
||||||
|
GridPane.halignment="CENTER" GridPane.rowIndex="7"
|
||||||
|
GridPane.valignment="CENTER"/>
|
||||||
|
<JFXToggleButton fx:id="turningToggle" minHeight="-Infinity"
|
||||||
|
prefHeight="35.0" text="OFF / ON" GridPane.columnIndex="1"
|
||||||
|
GridPane.halignment="CENTER" GridPane.rowIndex="8"/>
|
||||||
|
<Label text="CONTINUOUSLY TURNING" GridPane.halignment="CENTER"
|
||||||
|
GridPane.rowIndex="8" GridPane.valignment="CENTER">
|
||||||
|
<GridPane.margin>
|
||||||
|
<Insets/>
|
||||||
|
</GridPane.margin>
|
||||||
|
</Label>
|
||||||
|
<Label styleClass="sectionLabel" text="BOAT ACTIONS"
|
||||||
|
GridPane.columnSpan="2" GridPane.halignment="CENTER"
|
||||||
|
GridPane.valignment="CENTER">
|
||||||
|
<GridPane.margin>
|
||||||
|
<Insets left="50.0"/>
|
||||||
|
</GridPane.margin>
|
||||||
|
</Label>
|
||||||
|
<Label styleClass="sectionLabel" text="CAMERA SETTINGS"
|
||||||
|
GridPane.columnSpan="2" GridPane.halignment="CENTER"
|
||||||
|
GridPane.rowIndex="9" GridPane.valignment="CENTER">
|
||||||
|
<GridPane.margin>
|
||||||
|
<Insets left="50.0"/>
|
||||||
|
</GridPane.margin>
|
||||||
|
</Label>
|
||||||
|
</children>
|
||||||
|
<columnConstraints>
|
||||||
|
<ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity"
|
||||||
|
minWidth="-Infinity" prefWidth="250.0"/>
|
||||||
|
<ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity"
|
||||||
|
minWidth="-Infinity" prefWidth="150.0"/>
|
||||||
|
</columnConstraints>
|
||||||
|
<rowConstraints>
|
||||||
|
<RowConstraints maxHeight="50.0" minHeight="50.0"
|
||||||
|
prefHeight="50.0" vgrow="SOMETIMES"/>
|
||||||
|
<RowConstraints maxHeight="50.0" minHeight="50.0"
|
||||||
|
prefHeight="50.0" vgrow="SOMETIMES"/>
|
||||||
|
<RowConstraints maxHeight="50.0" minHeight="50.0"
|
||||||
|
prefHeight="50.0" vgrow="SOMETIMES"/>
|
||||||
|
<RowConstraints maxHeight="50.0" minHeight="50.0"
|
||||||
|
prefHeight="50.0" vgrow="SOMETIMES"/>
|
||||||
|
<RowConstraints maxHeight="50.0" minHeight="50.0"
|
||||||
|
prefHeight="50.0" vgrow="SOMETIMES"/>
|
||||||
|
<RowConstraints maxHeight="50.0" minHeight="50.0"
|
||||||
|
prefHeight="50.0" vgrow="SOMETIMES"/>
|
||||||
|
<RowConstraints maxHeight="50.0" minHeight="50.0"
|
||||||
|
prefHeight="50.0" vgrow="SOMETIMES"/>
|
||||||
|
<RowConstraints maxHeight="50.0" minHeight="50.0"
|
||||||
|
prefHeight="50.0" vgrow="SOMETIMES"/>
|
||||||
|
<RowConstraints maxHeight="50.0" minHeight="50.0"
|
||||||
|
prefHeight="50.0" vgrow="SOMETIMES"/>
|
||||||
|
<RowConstraints maxHeight="50.0" minHeight="50.0"
|
||||||
|
prefHeight="50.0" vgrow="SOMETIMES"/>
|
||||||
|
<RowConstraints maxHeight="50.0" minHeight="50.0"
|
||||||
|
prefHeight="50.0" vgrow="SOMETIMES"/>
|
||||||
|
<RowConstraints maxHeight="50.0" minHeight="50.0"
|
||||||
|
prefHeight="50.0" vgrow="SOMETIMES"/>
|
||||||
|
<RowConstraints maxHeight="50.0" minHeight="50.0"
|
||||||
|
prefHeight="50.0" vgrow="SOMETIMES"/>
|
||||||
|
<RowConstraints maxHeight="50.0" minHeight="50.0"
|
||||||
|
prefHeight="50.0" vgrow="SOMETIMES"/>
|
||||||
|
<RowConstraints maxHeight="50.0" minHeight="50.0"
|
||||||
|
prefHeight="50.0" vgrow="SOMETIMES"/>
|
||||||
|
</rowConstraints>
|
||||||
|
</GridPane>
|
||||||
|
</children>
|
||||||
|
</StackPane>
|
||||||
|
</content>
|
||||||
|
</ScrollPane>
|
||||||
|
<Label fx:id="keyBindingDialogHeader" text="CUSTOM KEYBINDING" GridPane.columnSpan="2"
|
||||||
|
GridPane.halignment="CENTER" GridPane.valignment="CENTER"/>
|
||||||
|
<Label fx:id="closeLabel" text="✖" GridPane.halignment="RIGHT"
|
||||||
|
GridPane.valignment="TOP"/>
|
||||||
<JFXButton fx:id="resetBtn" buttonType="RAISED" maxHeight="-Infinity"
|
<JFXButton fx:id="resetBtn" buttonType="RAISED" maxHeight="-Infinity"
|
||||||
maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="45.0"
|
maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="45.0"
|
||||||
prefWidth="150.0" text="RESET" GridPane.columnSpan="2" GridPane.halignment="CENTER"
|
prefWidth="150.0" text="RESET" GridPane.columnSpan="2" GridPane.halignment="CENTER"
|
||||||
GridPane.rowIndex="9" GridPane.valignment="CENTER"/>
|
GridPane.rowIndex="2" GridPane.valignment="CENTER"/>
|
||||||
<Label fx:id="closeLabel" text="✖" translateY="-5.0" GridPane.columnIndex="1"
|
|
||||||
GridPane.halignment="RIGHT" GridPane.valignment="TOP"/>
|
|
||||||
</children>
|
</children>
|
||||||
</GridPane>
|
</GridPane>
|
||||||
</children>
|
</children>
|
||||||
<stylesheets>
|
|
||||||
<URL value="@../../css/dialogs/KeyBindingDialog.css" />
|
|
||||||
<URL value="@../../css/Master.css" />
|
|
||||||
</stylesheets>
|
|
||||||
</JFXDialogLayout>
|
</JFXDialogLayout>
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
|
||||||
|
<?import com.jfoenix.controls.JFXButton?>
|
||||||
|
<?import com.jfoenix.controls.JFXDialogLayout?>
|
||||||
|
<?import java.net.URL?>
|
||||||
|
<?import javafx.geometry.Insets?>
|
||||||
|
<?import javafx.scene.control.Label?>
|
||||||
|
<?import javafx.scene.layout.ColumnConstraints?>
|
||||||
|
<?import javafx.scene.layout.GridPane?>
|
||||||
|
<?import javafx.scene.layout.RowConstraints?>
|
||||||
|
<JFXDialogLayout maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity"
|
||||||
|
minWidth="-Infinity" prefWidth="550.0" xmlns="http://javafx.com/javafx/8"
|
||||||
|
xmlns:fx="http://javafx.com/fxml/1"
|
||||||
|
fx:controller="seng302.visualiser.controllers.dialogs.PopupDialogController">
|
||||||
|
<children>
|
||||||
|
<GridPane>
|
||||||
|
<columnConstraints>
|
||||||
|
<ColumnConstraints hgrow="SOMETIMES" maxWidth="1.7976931348623157E308"/>
|
||||||
|
</columnConstraints>
|
||||||
|
<rowConstraints>
|
||||||
|
<RowConstraints maxHeight="-Infinity" minHeight="30.0" prefHeight="30.0"
|
||||||
|
vgrow="SOMETIMES"/>
|
||||||
|
<RowConstraints maxHeight="1.7976931348623157E308" minHeight="80.0"
|
||||||
|
prefHeight="80.0" vgrow="SOMETIMES"/>
|
||||||
|
<RowConstraints minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES"/>
|
||||||
|
</rowConstraints>
|
||||||
|
<children>
|
||||||
|
<JFXButton fx:id="optionButton" buttonType="RAISED" prefHeight="55.0"
|
||||||
|
prefWidth="150.0" GridPane.halignment="RIGHT" GridPane.rowIndex="2"
|
||||||
|
GridPane.valignment="CENTER">
|
||||||
|
<GridPane.margin>
|
||||||
|
<Insets/>
|
||||||
|
</GridPane.margin>
|
||||||
|
</JFXButton>
|
||||||
|
<Label fx:id="contentLabel" text="Popup content goes here ..."
|
||||||
|
GridPane.rowIndex="1"/>
|
||||||
|
<Label fx:id="headerLabel" text="Popup header"/>
|
||||||
|
<Label fx:id="closeLabel" text="✖" translateY="-10.0" GridPane.halignment="RIGHT"/>
|
||||||
|
</children>
|
||||||
|
</GridPane>
|
||||||
|
</children>
|
||||||
|
<stylesheets>
|
||||||
|
<URL value="@../../css/dialogs/Popup.css"/>
|
||||||
|
<URL value="@../../css/Master.css"/>
|
||||||
|
</stylesheets>
|
||||||
|
</JFXDialogLayout>
|
||||||
Reference in New Issue
Block a user