mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 14:28:43 +00:00
Boats and map are now updated using the observer pattern.
#implement
This commit is contained in:
@@ -107,19 +107,8 @@ public class ClientToServerThread implements Runnable {
|
||||
int sync1;
|
||||
int sync2;
|
||||
// TODO: 14/07/17 wmu16 - Work out how to fix this while loop
|
||||
while(socketOpen) { /**REMOVED SOMETHING HERE ClientState.isConnectedToHost() */
|
||||
System.out.println("socket.isConnected() = " + socket.isConnected());
|
||||
while(socketOpen) {
|
||||
try {
|
||||
//Perform a write if it is time to as delegated by the MainServerThread
|
||||
// if (updateClient) {
|
||||
// // TODO: 13/07/17 wmu16 - Write out game state - some function that would write all appropriate messages to this output stream
|
||||
//// try {
|
||||
//// GameState.outputState(os);
|
||||
//// } catch (IOException e) {
|
||||
//// System.out.println("IO error in server thread upon writing to output stream");
|
||||
//// }
|
||||
// updateClient = false;
|
||||
// }
|
||||
crcBuffer = new ByteArrayOutputStream();
|
||||
sync1 = readByte();
|
||||
sync2 = readByte();
|
||||
@@ -136,9 +125,6 @@ public class ClientToServerThread implements Runnable {
|
||||
long computedCrc = checksum.getValue();
|
||||
long packetCrc = Message.bytesToLong(getBytes(4));
|
||||
if (computedCrc == packetCrc) {
|
||||
// streamPackets.add(new StreamPacket(type, payloadLength, timeStamp, payload));
|
||||
// for (ClientSocketListener csl : listeners)
|
||||
// csl.newPacket(new StreamPacket(type, payloadLength, timeStamp, payload));
|
||||
if (streamPackets.size() > 0) {
|
||||
streamPackets.add(new StreamPacket(type, payloadLength, timeStamp, payload));
|
||||
} else {
|
||||
|
||||
@@ -10,20 +10,22 @@ import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.layout.Pane;
|
||||
import seng302.gameServer.GameState;
|
||||
import seng302.gameServer.MainServerThread;
|
||||
import seng302.model.RaceState;
|
||||
import seng302.model.Yacht;
|
||||
import seng302.model.mark.Mark;
|
||||
import seng302.model.stream.packets.StreamPacket;
|
||||
import seng302.model.stream.parser.MarkRoundingData;
|
||||
import seng302.model.stream.parser.PositionUpdateData;
|
||||
import seng302.model.stream.parser.PositionUpdateData.DeviceType;
|
||||
import seng302.model.stream.parser.RaceStatusData;
|
||||
import seng302.utilities.StreamParser;
|
||||
import seng302.model.stream.xml.parser.RaceXMLData;
|
||||
import seng302.model.stream.xml.parser.RegattaXMLData;
|
||||
import seng302.server.messages.BoatActionMessage;
|
||||
import seng302.server.messages.BoatActionType;
|
||||
import seng302.utilities.StreamParser;
|
||||
import seng302.utilities.XMLParser;
|
||||
import seng302.visualiser.controllers.LobbyController;
|
||||
import seng302.visualiser.controllers.LobbyController.CloseStatus;
|
||||
@@ -47,11 +49,14 @@ public class GameClient {
|
||||
|
||||
private ObservableList<String> lobbyList = FXCollections.observableArrayList();
|
||||
|
||||
private long lastSendingTime;
|
||||
private int KEY_STROKE_SENDING_FREQUENCY = 50;
|
||||
|
||||
public GameClient(Pane holder) {
|
||||
this.holderPane = holder;
|
||||
}
|
||||
|
||||
public void runAsClient (String ipAddress, Integer portNumber) {
|
||||
public void runAsClient(String ipAddress, Integer portNumber) {
|
||||
try {
|
||||
socketThread = new ClientToServerThread(ipAddress, portNumber);
|
||||
} catch (IOException ioe) {
|
||||
@@ -66,7 +71,7 @@ public class GameClient {
|
||||
socketThread.addStreamObserver(this::parsePackets);
|
||||
}
|
||||
|
||||
public void runAsHost (String ipAddress, Integer portNumber) {
|
||||
public void runAsHost(String ipAddress, Integer portNumber) {
|
||||
server = new MainServerThread();
|
||||
try {
|
||||
socketThread = new ClientToServerThread(ipAddress, portNumber);
|
||||
@@ -87,7 +92,7 @@ public class GameClient {
|
||||
});
|
||||
}
|
||||
|
||||
private void loadStartScreen () {
|
||||
private void loadStartScreen() {
|
||||
socketThread.setSocketToClose();
|
||||
socketThread = null;
|
||||
if (server != null) {
|
||||
@@ -95,7 +100,8 @@ public class GameClient {
|
||||
// server.shutDown();
|
||||
server = null;
|
||||
}
|
||||
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/views/StartScreenView.fxml"));
|
||||
FXMLLoader fxmlLoader = new FXMLLoader(
|
||||
getClass().getResource("/views/StartScreenView.fxml"));
|
||||
try {
|
||||
holderPane.getChildren().clear();
|
||||
holderPane.getChildren().add(fxmlLoader.load());
|
||||
@@ -106,10 +112,11 @@ public class GameClient {
|
||||
|
||||
/**
|
||||
* Loads a view of the lobby into the clients pane
|
||||
*
|
||||
* @param lobbyView fxml file for the desired lobby
|
||||
* @return the lobby controller.
|
||||
*/
|
||||
private LobbyController loadLobby (String lobbyView) {
|
||||
private LobbyController loadLobby(String lobbyView) {
|
||||
FXMLLoader fxmlLoader = new FXMLLoader(GameClient.class.getResource(lobbyView));
|
||||
try {
|
||||
holderPane.getChildren().clear();
|
||||
@@ -120,22 +127,25 @@ public class GameClient {
|
||||
return fxmlLoader.getController();
|
||||
}
|
||||
|
||||
private void loadRaceView () {
|
||||
private void loadRaceView() {
|
||||
// allBoatsMap.forEach((id, boat) -> {
|
||||
// if (courseData.getParticipants().contains(id))
|
||||
// racingBoats.put(id, boat);
|
||||
// });
|
||||
FXMLLoader fxmlLoader = new FXMLLoader(RaceViewController.class.getResource("/views/RaceView.fxml"));
|
||||
FXMLLoader fxmlLoader = new FXMLLoader(
|
||||
RaceViewController.class.getResource("/views/RaceView.fxml"));
|
||||
// raceView = fxmlLoader.getController();
|
||||
try {
|
||||
Node node = fxmlLoader.load();
|
||||
Platform.runLater(() -> {
|
||||
holderPane.getChildren().clear();
|
||||
holderPane.getChildren().add(node);
|
||||
holderPane.getChildren().clear();
|
||||
holderPane.getChildren().add(node);
|
||||
});
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
holderPane.getScene().setOnKeyPressed(this::keyPressed);
|
||||
holderPane.getScene().setOnKeyReleased(this::keyReleased);
|
||||
raceView = fxmlLoader.getController();
|
||||
raceView.loadRace(allBoatsMap, courseData, raceState);
|
||||
}
|
||||
@@ -201,33 +211,34 @@ public class GameClient {
|
||||
}
|
||||
|
||||
private void startRaceIfAllDataReceived() {
|
||||
if (allXMLReceived())
|
||||
if (allXMLReceived() && raceView == null)
|
||||
loadRaceView();
|
||||
}
|
||||
|
||||
private boolean allXMLReceived () {
|
||||
private boolean allXMLReceived() {
|
||||
return courseData != null && allBoatsMap != null && regattaData != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the position of a boat. Boat and position are given in the provided data.
|
||||
* @param positionData
|
||||
*/
|
||||
private void updatePosition(PositionUpdateData positionData) {
|
||||
if (positionData.getType() == DeviceType.YACHT_TYPE) {
|
||||
if (allXMLReceived() && allBoatsMap.containsKey(positionData.getDeviceId())) {
|
||||
Yacht yacht = allBoatsMap.get(positionData.getDeviceId());
|
||||
yacht.updateLocation(positionData.getLat(),
|
||||
positionData.getLon(), positionData.getHeading(), positionData.getGroundSpeed());
|
||||
positionData.getLon(), positionData.getHeading(),
|
||||
positionData.getGroundSpeed());
|
||||
}
|
||||
} else if (positionData.getType() == DeviceType.MARK_TYPE) {
|
||||
Mark mark = courseData.getCompoundMarks().get(positionData.getDeviceId());
|
||||
//CompoundMark mark = courseData.getCompoundMarks().get(positionData.getDeviceId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the boat as having passed the mark. Boat and mark are given by the ids in the
|
||||
* provided data.
|
||||
*
|
||||
* @param roundingData Contains data for the rounding of a mark.
|
||||
*/
|
||||
private void updateMarkRounding(MarkRoundingData roundingData) {
|
||||
@@ -244,7 +255,7 @@ public class GameClient {
|
||||
}
|
||||
}
|
||||
|
||||
private void processRaceStatusUpdate (RaceStatusData data) {
|
||||
private void processRaceStatusUpdate(RaceStatusData data) {
|
||||
if (allXMLReceived()) {
|
||||
raceState.updateState(data);
|
||||
for (long[] boatData : data.getBoatData()) {
|
||||
@@ -267,49 +278,55 @@ public class GameClient {
|
||||
}
|
||||
}
|
||||
|
||||
private void close () {
|
||||
private void close() {
|
||||
socketThread.setSocketToClose();
|
||||
}
|
||||
|
||||
// /** Handle the key-pressed event from the text field. */
|
||||
// public void keyPressed(KeyEvent e) {
|
||||
// BoatActionMessage boatActionMessage;
|
||||
// switch (e.getCode()){
|
||||
// case SPACE: // align with vmg
|
||||
// boatActionMessage = new BoatActionMessage(BoatActionType.VMG);
|
||||
// clientToServerThread.sendBoatActionMessage(boatActionMessage);
|
||||
// break;
|
||||
// case PAGE_UP: // upwind
|
||||
// boatActionMessage = new BoatActionMessage(BoatActionType.UPWIND);
|
||||
// clientToServerThread.sendBoatActionMessage(boatActionMessage);
|
||||
// break;
|
||||
// case PAGE_DOWN: // downwind
|
||||
// boatActionMessage = new BoatActionMessage(BoatActionType.DOWNWIND);
|
||||
// clientToServerThread.sendBoatActionMessage(boatActionMessage);
|
||||
// break;
|
||||
// case ENTER: // tack/gybe
|
||||
// boatActionMessage = new BoatActionMessage(BoatActionType.TACK_GYBE);
|
||||
// clientToServerThread.sendBoatActionMessage(boatActionMessage);
|
||||
// break;
|
||||
// //TODO Allow a zoom in and zoom out methods
|
||||
// case Z: // zoom in
|
||||
// System.out.println("Zoom in");
|
||||
// break;
|
||||
// case X: // zoom out
|
||||
// System.out.println("Zoom out");
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// public void keyReleased(KeyEvent e) {
|
||||
// switch (e.getCode()) {
|
||||
// //TODO 12/07/17 Determine the sail state and send the appropriate packet (eg. if sails are in, send a sail out packet)
|
||||
// case SHIFT: // sails in/sails out
|
||||
// BoatActionMessage boatActionMessage = new BoatActionMessage(BoatActionType.SAILS_IN);
|
||||
// clientToServerThread.sendBoatActionMessage(boatActionMessage);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// onKeyPressed="#keyPressed" onKeyReleased="#keyReleased"
|
||||
/**
|
||||
* Handle the key-pressed event from the text field.
|
||||
*/
|
||||
public void keyPressed(KeyEvent e) {
|
||||
BoatActionMessage boatActionMessage;
|
||||
long currentTime = System.currentTimeMillis();
|
||||
if (currentTime - lastSendingTime > KEY_STROKE_SENDING_FREQUENCY) {
|
||||
lastSendingTime = currentTime;
|
||||
switch (e.getCode()) {
|
||||
case SPACE: // align with vmg
|
||||
boatActionMessage = new BoatActionMessage(BoatActionType.VMG);
|
||||
socketThread.sendBoatActionMessage(boatActionMessage);
|
||||
break;
|
||||
case PAGE_UP: // upwind
|
||||
boatActionMessage = new BoatActionMessage(BoatActionType.UPWIND);
|
||||
socketThread.sendBoatActionMessage(boatActionMessage);
|
||||
break;
|
||||
case PAGE_DOWN: // downwind
|
||||
boatActionMessage = new BoatActionMessage(BoatActionType.DOWNWIND);
|
||||
socketThread.sendBoatActionMessage(boatActionMessage);
|
||||
break;
|
||||
case ENTER: // tack/gybe
|
||||
boatActionMessage = new BoatActionMessage(BoatActionType.TACK_GYBE);
|
||||
socketThread.sendBoatActionMessage(boatActionMessage);
|
||||
break;
|
||||
//TODO Allow a zoom in and zoom out methods
|
||||
case Z: // zoom in
|
||||
System.out.println("Zoom in");
|
||||
break;
|
||||
case X: // zoom out
|
||||
System.out.println("Zoom out");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void keyReleased(KeyEvent e) {
|
||||
switch (e.getCode()) {
|
||||
//TODO 12/07/17 Determine the sail state and send the appropriate packet (eg. if sails are in, send a sail out packet)
|
||||
case SHIFT: // sails in/sails out
|
||||
BoatActionMessage boatActionMessage = new BoatActionMessage(
|
||||
BoatActionType.SAILS_IN);
|
||||
socketThread.sendBoatActionMessage(boatActionMessage);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,10 +24,12 @@ import seng302.model.GeoPoint;
|
||||
import seng302.model.Limit;
|
||||
import seng302.model.Yacht;
|
||||
import seng302.model.mark.CompoundMark;
|
||||
import seng302.model.mark.Corner;
|
||||
import seng302.model.mark.Mark;
|
||||
import seng302.utilities.GeoUtility;
|
||||
import seng302.visualiser.fxObjects.AnnotationBox;
|
||||
import seng302.visualiser.fxObjects.BoatObject;
|
||||
import seng302.visualiser.fxObjects.CourseBoundary;
|
||||
import seng302.visualiser.fxObjects.Gate;
|
||||
import seng302.visualiser.fxObjects.Marker;
|
||||
import seng302.visualiser.map.Boundary;
|
||||
@@ -52,7 +54,7 @@ public class GameView extends Pane {
|
||||
private double metersPerPixelX, metersPerPixelY;
|
||||
|
||||
private Text fpsDisplay = new Text();
|
||||
private Polygon raceBorder = new Polygon();
|
||||
private Polygon raceBorder = new CourseBoundary();
|
||||
|
||||
/* Note that if either of these is null then values for it have not been added and the other
|
||||
should be used as the limits of the map. */
|
||||
@@ -61,8 +63,8 @@ public class GameView extends Pane {
|
||||
private Map<Mark, Marker> markerObjects;
|
||||
|
||||
private Map<Yacht, BoatObject> boatObjects = new HashMap<>();
|
||||
private List<AnnotationBox> annotations = new ArrayList<>();
|
||||
private List<Integer> markSequence;
|
||||
private Map<Yacht, AnnotationBox> annotations = new HashMap<>();
|
||||
private List<Corner> markSequence;
|
||||
private ObservableList<Node> gameObjects;
|
||||
|
||||
private ImageView mapImage = new ImageView();
|
||||
@@ -83,8 +85,8 @@ public class GameView extends Pane {
|
||||
public GameView () {
|
||||
gameObjects = this.getChildren();
|
||||
// create image view for map, bind panel size to image
|
||||
mapImage.fitWidthProperty().bind(this.widthProperty());
|
||||
mapImage.fitHeightProperty().bind(this.heightProperty());
|
||||
// mapImage.fitWidthProperty().bind(this.widthProperty());
|
||||
// mapImage.fitHeightProperty().bind(this.heightProperty());
|
||||
gameObjects.add(mapImage);
|
||||
fpsDisplay.setLayoutX(5);
|
||||
fpsDisplay.setLayoutY(20);
|
||||
@@ -92,15 +94,15 @@ public class GameView extends Pane {
|
||||
gameObjects.add(fpsDisplay);
|
||||
gameObjects.add(raceBorder);
|
||||
initializeTimer();
|
||||
this.widthProperty().addListener(resize -> {
|
||||
canvasWidth = this.getWidth();
|
||||
canvasHeight = this.getHeight();
|
||||
if (borderPoints != null) {
|
||||
updateBorder(borderPoints);
|
||||
} else if (course != null) {
|
||||
updateCourse(course, markSequence);
|
||||
}
|
||||
});
|
||||
// this.widthProperty().addListener(resize -> {
|
||||
// canvasWidth = this.getWidth();
|
||||
// canvasHeight = this.getHeight();
|
||||
// if (borderPoints != null) {
|
||||
// updateBorder(borderPoints);
|
||||
// } else if (course != null) {
|
||||
// updateCourse(course, markSequence);
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
private void initializeTimer () {
|
||||
@@ -130,7 +132,7 @@ public class GameView extends Pane {
|
||||
drawFps(frameRate.intValue());
|
||||
}
|
||||
}
|
||||
boatObjects.forEach((boat, boatObject) -> {});
|
||||
boatObjects.forEach((boat, boatObject) -> boatObject.updateLocation());
|
||||
lastTime = now;
|
||||
}
|
||||
}
|
||||
@@ -179,7 +181,7 @@ public class GameView extends Pane {
|
||||
*
|
||||
* @param newCourse the mark objects that make up the course.
|
||||
*/
|
||||
public void updateCourse(List<CompoundMark> newCourse, List<Integer> sequence) {
|
||||
public void updateCourse(List<CompoundMark> newCourse, List<Corner> sequence) {
|
||||
course = newCourse;
|
||||
this.markSequence = sequence;
|
||||
markerObjects = new HashMap<>();
|
||||
@@ -187,9 +189,9 @@ public class GameView extends Pane {
|
||||
//Creates new markers
|
||||
for (CompoundMark cMark : course) {
|
||||
//Set start and end colour
|
||||
if (cMark.getId() == sequence.get(0)) {
|
||||
if (cMark.getId() == sequence.get(0).getCompoundMarkID()) {
|
||||
colour = Color.GREEN;
|
||||
} else if (cMark.getId() == sequence.get(sequence.size() - 1)) {
|
||||
} else if (cMark.getId() == sequence.get(sequence.size() - 1).getCompoundMarkID()) {
|
||||
colour = Color.RED;
|
||||
}
|
||||
//Create mark dots
|
||||
@@ -198,7 +200,7 @@ public class GameView extends Pane {
|
||||
}
|
||||
//Create gate line
|
||||
if (cMark.isGate()) {
|
||||
for (int i = 0; i < cMark.getMarks().size()-1; i++) {
|
||||
for (int i = 1; i < cMark.getMarks().size(); i++) {
|
||||
makeAndBindGate(
|
||||
markerObjects.get(cMark.getSubMark(i)),
|
||||
markerObjects.get(cMark.getSubMark(i+1)),
|
||||
@@ -301,34 +303,35 @@ public class GameView extends Pane {
|
||||
Group annotationsGroup = new Group();
|
||||
Group wakesGroup = new Group();
|
||||
Group boatObjectGroup = new Group();
|
||||
Group trails = new Group();
|
||||
|
||||
BoatObject newObject;
|
||||
BoatObject newBoat;
|
||||
for (Yacht yacht : yachts) {
|
||||
newObject = new BoatObject();
|
||||
newObject.setFill(Colors.getColor());
|
||||
boatObjects.put(yacht, newObject);
|
||||
newBoat = new BoatObject();
|
||||
newBoat.setFill(Colors.getColor());
|
||||
boatObjects.put(yacht, newBoat);
|
||||
yacht.addLocationListener((boat, lat, lon, heading, velocity) ->{
|
||||
BoatObject bo = boatObjects.get(boat);
|
||||
Point2D p2d = findScaledXY(lat, lon);
|
||||
bo.setLayoutX(p2d.getX());
|
||||
bo.setLayoutY(p2d.getY());
|
||||
// bo.setTrajectory(heading, velocity * (metersPerPixelX + metersPerPixelY) / 2);
|
||||
bo.moveTo(p2d.getX(), p2d.getY(), heading);
|
||||
bo.setTrajectory(
|
||||
heading,
|
||||
velocity,
|
||||
metersPerPixelX,
|
||||
metersPerPixelY);
|
||||
});
|
||||
createAnnotationBox(yacht);
|
||||
|
||||
createAndBindAnnotationBox(yacht);
|
||||
wakesGroup.getChildren().add(newBoat.getWake());
|
||||
boatObjectGroup.getChildren().add(newBoat);
|
||||
trails.getChildren().add(newBoat.getTrail());
|
||||
}
|
||||
// Group wakes = new Group();
|
||||
// Group trails = new Group();
|
||||
// Group annotationsGroup = new Group();
|
||||
//
|
||||
// gameObjects.addAll(trails);
|
||||
// gameObjects.addAll(wakes);
|
||||
annotationsGroup.getChildren().addAll(annotations);
|
||||
annotationsGroup.getChildren().addAll(annotations.values());
|
||||
gameObjects.addAll(trails);
|
||||
gameObjects.addAll(annotationsGroup);
|
||||
gameObjects.addAll(boatObjects.values());
|
||||
gameObjects.addAll(boatObjectGroup);
|
||||
}
|
||||
|
||||
private AnnotationBox createAnnotationBox (Yacht yacht) {
|
||||
private void createAndBindAnnotationBox (Yacht yacht) {
|
||||
AnnotationBox newAnnotation;
|
||||
newAnnotation = new AnnotationBox();
|
||||
newAnnotation.addAnnotation("name", yacht.getShortName());
|
||||
@@ -354,8 +357,7 @@ public class GameView extends Pane {
|
||||
return format.format(time);
|
||||
}
|
||||
);
|
||||
annotations.add(newAnnotation);
|
||||
return newAnnotation;
|
||||
annotations.put(yacht, newAnnotation);
|
||||
}
|
||||
|
||||
private void drawFps(int fps){
|
||||
@@ -370,6 +372,9 @@ public class GameView extends Pane {
|
||||
private void findMinMaxPoint(List<GeoPoint> points) {
|
||||
List<GeoPoint> sortedPoints = new ArrayList<>(points);
|
||||
sortedPoints.sort(Comparator.comparingDouble(GeoPoint::getLat));
|
||||
for (GeoPoint gp : sortedPoints) {
|
||||
System.out.println(gp.getLat());
|
||||
}
|
||||
minLatPoint = new GeoPoint(sortedPoints.get(0).getLat(), sortedPoints.get(0).getLng());
|
||||
GeoPoint maxLat = sortedPoints.get(sortedPoints.size()-1);
|
||||
maxLatPoint = new GeoPoint(maxLat.getLat(), maxLat.getLng());
|
||||
@@ -472,6 +477,7 @@ public class GameView extends Pane {
|
||||
distanceFromReference = GeoUtility.getDistance(
|
||||
minLatPoint, new GeoPoint(unscaledLat, unscaledLon)
|
||||
);
|
||||
System.out.println("distanceFromReference = " + distanceFromReference);
|
||||
if (angleFromReference >= 0 && angleFromReference <= Math.PI / 2) {
|
||||
xAxisLocation += Math.round(distanceScaleFactor * Math.sin(angleFromReference) * distanceFromReference);
|
||||
yAxisLocation -= Math.round(distanceScaleFactor * Math.cos(angleFromReference) * distanceFromReference);
|
||||
@@ -491,6 +497,8 @@ public class GameView extends Pane {
|
||||
if(horizontalInversion) {
|
||||
xAxisLocation = canvasWidth - bufferSize - (xAxisLocation - bufferSize);
|
||||
}
|
||||
System.out.println("yAxisLocation = " + yAxisLocation + " " + unscaledLat);
|
||||
System.out.println("xAxisLocation = " + xAxisLocation + " " + unscaledLon);
|
||||
return new Point2D(xAxisLocation, yAxisLocation);
|
||||
}
|
||||
|
||||
@@ -520,7 +528,7 @@ public class GameView extends Pane {
|
||||
for (BoatObject boatObject : boatObjects.values()) {
|
||||
boatObject.setVisibility(teamName, velocity, estTime, legTime, trail, wake);
|
||||
}
|
||||
for (AnnotationBox ag : annotations) {
|
||||
for (AnnotationBox ag : annotations.values()) {
|
||||
ag.setAnnotationVisibility("name", teamName);
|
||||
ag.setAnnotationVisibility("velocity", velocity);
|
||||
ag.setAnnotationVisibility("nextMark", estTime);
|
||||
@@ -549,4 +557,9 @@ public class GameView extends Pane {
|
||||
public void startRace () {
|
||||
timer.start();
|
||||
}
|
||||
|
||||
public void setBoatAsPlayer (Yacht playerYacht) {
|
||||
boatObjects.get(playerYacht).setAsPlayer();
|
||||
// annotations.get(playerYacht).setAsPlayer();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javafx.animation.KeyFrame;
|
||||
import javafx.animation.Timeline;
|
||||
import javafx.application.Platform;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXML;
|
||||
@@ -37,6 +38,7 @@ import javafx.util.Duration;
|
||||
import javafx.util.StringConverter;
|
||||
import seng302.model.RaceState;
|
||||
import seng302.model.Yacht;
|
||||
import seng302.model.mark.CompoundMark;
|
||||
import seng302.model.mark.Mark;
|
||||
import seng302.model.stream.xml.parser.RaceXMLData;
|
||||
import seng302.visualiser.GameView;
|
||||
@@ -74,7 +76,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
||||
|
||||
//Race Data
|
||||
private Map<Integer, Yacht> participants;
|
||||
private Map<Integer, Mark> markers;
|
||||
private Map<Integer, CompoundMark> markers;
|
||||
private RaceXMLData courseData;
|
||||
private GameView gameView;
|
||||
private RaceState raceState;
|
||||
@@ -111,11 +113,19 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
||||
initialiseBoatSelectionComboBox();
|
||||
|
||||
gameView = new GameView();
|
||||
gameView.setBoats(new ArrayList<>(participants.values()));
|
||||
gameView.updateBorder(raceData.getCourseLimit());
|
||||
gameView.updateCourse(new ArrayList<>(raceData.getCompoundMarks().values()));
|
||||
gameView.startRace();
|
||||
System.out.println("haha");
|
||||
Platform.runLater(() -> {
|
||||
contentAnchorPane.getChildren().add(gameView);
|
||||
|
||||
// contentAnchorPane.getChildren().add(gameView);
|
||||
System.out.println("hehe");
|
||||
gameView.setBoats(new ArrayList<>(participants.values()));
|
||||
gameView.updateBorder(raceData.getCourseLimit());
|
||||
gameView.updateCourse(
|
||||
new ArrayList<>(raceData.getCompoundMarks().values()), raceData.getMarkSequence()
|
||||
);
|
||||
gameView.startRace();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,13 +23,10 @@ public class BoatObject extends Group {
|
||||
//Constants for drawing
|
||||
private static final double BOAT_HEIGHT = 15d;
|
||||
private static final double BOAT_WIDTH = 10d;
|
||||
//Variables for boat logic.
|
||||
private boolean isStopped = true;
|
||||
private double xIncrement;
|
||||
private double yIncrement;
|
||||
private long lastTimeValid = 0;
|
||||
private Double lastRotation = 0.0;
|
||||
private long framesToMove;
|
||||
|
||||
private double xVelocity;
|
||||
private double yVelocity;
|
||||
private double lastHeading;
|
||||
//Graphical objects
|
||||
private Group lineGroup = new Group();
|
||||
private Polygon boatPoly;
|
||||
@@ -38,11 +35,7 @@ public class BoatObject extends Group {
|
||||
private Line rightLayline;
|
||||
private Double distanceTravelled = 0.0;
|
||||
private Point2D lastPoint;
|
||||
private boolean destinationSet;
|
||||
private AnnotationBox annotationBox;
|
||||
|
||||
private Paint colour = Color.BLACK;
|
||||
|
||||
private Boolean isSelected = true; //All boats are initialised as selected
|
||||
|
||||
/**
|
||||
@@ -63,7 +56,6 @@ public class BoatObject extends Group {
|
||||
*/
|
||||
public BoatObject(double... points) {
|
||||
this.colour = colour;
|
||||
destinationSet = false;
|
||||
initChildren(points);
|
||||
}
|
||||
|
||||
@@ -104,7 +96,6 @@ public class BoatObject extends Group {
|
||||
public void setFill (Paint value) {
|
||||
this.colour = value;
|
||||
boatPoly.setFill(colour);
|
||||
// annotationBox.setFill(colour);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -117,8 +108,6 @@ public class BoatObject extends Group {
|
||||
private void moveGroupBy(double dx, double dy) {
|
||||
boatPoly.setLayoutX(boatPoly.getLayoutX() + dx);
|
||||
boatPoly.setLayoutY(boatPoly.getLayoutY() + dy);
|
||||
annotationBox.setLayoutX(annotationBox.getLayoutX() + dx);
|
||||
annotationBox.setLayoutY(annotationBox.getLayoutY() + dy);
|
||||
wake.setLayoutX(wake.getLayoutX() + dx);
|
||||
wake.setLayoutY(wake.getLayoutY() + dy);
|
||||
}
|
||||
@@ -130,12 +119,10 @@ public class BoatObject extends Group {
|
||||
* @param x The X coordinate to move the boat to
|
||||
* @param y The Y coordinate to move the boat to
|
||||
*/
|
||||
private void moveTo(double x, double y, double rotation) {
|
||||
public void moveTo(double x, double y, double rotation) {
|
||||
rotateTo(rotation);
|
||||
boatPoly.setLayoutX(x);
|
||||
boatPoly.setLayoutY(y);
|
||||
annotationBox.setLayoutX(x);
|
||||
annotationBox.setLayoutY(y);
|
||||
wake.setLayoutX(x);
|
||||
wake.setLayoutY(y);
|
||||
wake.rotate(rotation);
|
||||
@@ -145,17 +132,12 @@ public class BoatObject extends Group {
|
||||
boatPoly.getTransforms().setAll(new Rotate(rotation));
|
||||
}
|
||||
|
||||
public void move() {
|
||||
double dx = xIncrement * framesToMove;
|
||||
double dy = yIncrement * framesToMove;
|
||||
public void updateLocation() {
|
||||
double dx = xVelocity / 60;
|
||||
double dy = yVelocity / 60;
|
||||
|
||||
distanceTravelled += Math.abs(dx) + Math.abs(dy);
|
||||
moveGroupBy(xIncrement, yIncrement);
|
||||
framesToMove = framesToMove - 1;
|
||||
|
||||
if (framesToMove <= 0) {
|
||||
isStopped = true;
|
||||
}
|
||||
moveGroupBy(dx, dy);
|
||||
|
||||
if (distanceTravelled > 70) {
|
||||
distanceTravelled = 0d;
|
||||
@@ -173,65 +155,11 @@ public class BoatObject extends Group {
|
||||
l.setCacheHint(CacheHint.SPEED);
|
||||
lineGroup.getChildren().add(l);
|
||||
}
|
||||
|
||||
if (destinationSet) {
|
||||
lastPoint = new Point2D(boatPoly.getLayoutX(), boatPoly.getLayoutY());
|
||||
}
|
||||
lastPoint = new Point2D(boatPoly.getLayoutX(), boatPoly.getLayoutY());
|
||||
}
|
||||
wake.updatePosition();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the destination of the boat and the headng it should have once it reaches
|
||||
*
|
||||
* @param newXValue The X co-ordinate the boat needs to move to.
|
||||
* @param newYValue The Y co-ordinate the boat needs to move to.
|
||||
* @param rotation Rotation to move graphics to.
|
||||
* @param timeValid the time the position values are valid for
|
||||
*/
|
||||
public void setDestination(double newXValue, double newYValue, double rotation,
|
||||
double groundSpeed, long timeValid, double frameRate) {
|
||||
|
||||
destinationSet = true;
|
||||
Double dx = Math.abs(boatPoly.getLayoutX() - newXValue);
|
||||
Double dy = Math.abs(boatPoly.getLayoutY() - newYValue);
|
||||
moveTo(newXValue, newYValue, rotation);
|
||||
|
||||
|
||||
rotateTo(rotation);
|
||||
wake.setRotation(rotation, groundSpeed);
|
||||
// yacht.setVelocity(groundSpeed);
|
||||
lastTimeValid = timeValid;
|
||||
// boat.setVelocity(groundSpeed);
|
||||
isStopped = false;
|
||||
lastRotation = rotation;
|
||||
// boatAnnotations.update();
|
||||
|
||||
distanceTravelled += Math.sqrt((dx * dx) + (dy * dy));
|
||||
|
||||
if (distanceTravelled > 10){// && isPlayer) {
|
||||
distanceTravelled = 0d;
|
||||
|
||||
if (lastPoint != null) {
|
||||
Line l = new Line(
|
||||
lastPoint.getX(),
|
||||
lastPoint.getY(),
|
||||
boatPoly.getLayoutX(),
|
||||
boatPoly.getLayoutY()
|
||||
);
|
||||
l.getStrokeDashArray().setAll(3d, 7d);
|
||||
l.setStroke(this.colour);
|
||||
l.setCache(true);
|
||||
l.setCacheHint(CacheHint.SPEED);
|
||||
lineGroup.getChildren().add(l);
|
||||
}
|
||||
if (destinationSet) {
|
||||
lastPoint = new Point2D(boatPoly.getLayoutX(), boatPoly.getLayoutY());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// /**
|
||||
// * This function works out if a boat is going upwind or down wind. It looks at the boats current position, the next
|
||||
// * gates position and the current wind
|
||||
@@ -269,7 +197,6 @@ public class BoatObject extends Group {
|
||||
this.isSelected = isSelected;
|
||||
setLineGroupVisible(isSelected);
|
||||
setWakeVisible(isSelected);
|
||||
annotationBox.setVisible(isSelected);
|
||||
setLayLinesVisible(isSelected);
|
||||
}
|
||||
|
||||
@@ -313,10 +240,6 @@ public class BoatObject extends Group {
|
||||
return lineGroup;
|
||||
}
|
||||
|
||||
public Group getAnnotations() {
|
||||
return annotationBox;
|
||||
}
|
||||
|
||||
public Double getBoatLayoutX() {
|
||||
return boatPoly.getLayoutX();
|
||||
}
|
||||
@@ -326,24 +249,34 @@ public class BoatObject extends Group {
|
||||
return boatPoly.getLayoutY();
|
||||
}
|
||||
|
||||
public boolean isStopped() {
|
||||
return isStopped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this boat to appear highlighted
|
||||
*/
|
||||
public void setAsPlayer() {
|
||||
// boatPoly.getPoints().setAll(
|
||||
// -BOAT_WIDTH / 1.75, BOAT_HEIGHT / 1.75,
|
||||
// 0.0, -BOAT_HEIGHT / 1.75,
|
||||
// BOAT_WIDTH / 1.75, BOAT_HEIGHT / 1.75
|
||||
// );
|
||||
// boatPoly.setStroke(Color.BLACK);
|
||||
// boatPoly.setStrokeWidth(3);
|
||||
boatPoly.getPoints().setAll(
|
||||
-BOAT_WIDTH / 1.75, BOAT_HEIGHT / 1.75,
|
||||
0.0, -BOAT_HEIGHT / 1.75,
|
||||
BOAT_WIDTH / 1.75, BOAT_HEIGHT / 1.75
|
||||
);
|
||||
boatPoly.setStroke(Color.BLACK);
|
||||
boatPoly.setStrokeWidth(3);
|
||||
// boatAnnotations.setAsPlayer();
|
||||
// isPlayer = true;
|
||||
}
|
||||
|
||||
public void updateTrajectory(heading, velocity, scaleFactor)
|
||||
public void setTrajectory(double heading, double velocity) {
|
||||
wake.setRotation(lastHeading - heading, velocity);
|
||||
rotateTo(heading);
|
||||
xVelocity = Math.cos(Math.toRadians(heading)) * velocity;
|
||||
yVelocity = Math.sin(Math.toRadians(heading)) * velocity;
|
||||
lastHeading = heading;
|
||||
}
|
||||
|
||||
public void setTrajectory(double heading, double velocity, double scaleFactorX, double scaleFactorY) {
|
||||
// wake.setRotation(lastHeading - heading, velocity);
|
||||
// rotateTo(heading);
|
||||
// xVelocity = Math.cos(Math.toRadians(heading)) * velocity * scaleFactorX;
|
||||
// yVelocity = Math.sin(Math.toRadians(heading)) * velocity * scaleFactorY;
|
||||
lastHeading = heading;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -6,8 +6,8 @@ import javafx.scene.shape.Polygon;
|
||||
/**
|
||||
* Polygon with default course border settings.
|
||||
*/
|
||||
public class CourseBorder extends Polygon {
|
||||
public CourseBorder() {
|
||||
public class CourseBoundary extends Polygon {
|
||||
public CourseBoundary() {
|
||||
this.setStroke(new Color(0.0f, 0.0f, 0.74509807f, 1));
|
||||
this.setStrokeWidth(3);
|
||||
this.setFill(new Color(0,0,0,0));
|
||||
Reference in New Issue
Block a user