Refactored 2d game view distance calculations to better size and sale the map,

#implement #refactor #story[1275]
This commit is contained in:
Calum
2017-09-25 21:06:18 +13:00
parent 9b00ba654a
commit 35b50d1436
4 changed files with 147 additions and 98 deletions
@@ -195,8 +195,10 @@ public class ClientToServerThread implements Runnable {
* @param packet The registration requests packet * @param packet The registration requests packet
*/ */
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, 4));
int statusCode = (int) Message.bytesToLong(Arrays.copyOfRange(packet.getPayload(), 4,5)); int statusCode = (int) Message.bytesToLong(Arrays.copyOfRange(packet.getPayload(), 4,5));
System.out.println("sourceId = " + sourceId);
System.out.println("statusCode = " + statusCode);
RegistrationResponseStatus status = RegistrationResponseStatus.getResponseStatus(statusCode); RegistrationResponseStatus status = RegistrationResponseStatus.getResponseStatus(statusCode);
+116 -75
View File
@@ -8,7 +8,9 @@ import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane; import javafx.scene.layout.Pane;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
import javafx.scene.paint.Paint; import javafx.scene.paint.Paint;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Polygon; import javafx.scene.shape.Polygon;
import javafx.scene.shape.Rectangle;
import seng302.gameServer.messages.RoundingSide; import seng302.gameServer.messages.RoundingSide;
import seng302.model.GeoPoint; import seng302.model.GeoPoint;
import seng302.model.Limit; import seng302.model.Limit;
@@ -26,7 +28,7 @@ import java.util.*;
*/ */
public class GameView extends Pane { public class GameView extends Pane {
private double bufferSize = 50; private double bufferSize = 0;
private double horizontalBuffer = 0; private double horizontalBuffer = 0;
private double canvasWidth = 1100; private double canvasWidth = 1100;
@@ -69,9 +71,21 @@ public class GameView extends Pane {
gameObjects.addAll(mapImage, raceBorder, markers, tokens); gameObjects.addAll(mapImage, raceBorder, markers, tokens);
this.parentProperty().addListener((obs, old, parent) -> { this.parentProperty().addListener((obs, old, parent) -> {
if (parent != null) { if (parent != null) {
canvasWidth = parent.prefWidth(0) * 2; canvasWidth = parent.prefWidth(1) * 1.5;
canvasHeight = parent.prefHeight(0) * 2; canvasHeight = parent.prefHeight(1) * 1.5;
// rescaleRace(borderPoints); // rescaleRace(borderPoints);
System.out.println("parent = " + parent.maxWidth(100));
System.out.println("parent.minWidth(1) = " + parent.minWidth(100));
System.out.println(canvasWidth);
System.out.println(canvasHeight);
this.getChildren().add(new Circle(canvasWidth / 2, canvasHeight / 2, 7, Color.GREENYELLOW));
this.getChildren().add(new Circle(canvasWidth, canvasHeight, 7, Color.GREENYELLOW));
this.getChildren().add(new Circle(0,0, 7, Color.GREENYELLOW));
this.getChildren().add(new Circle(canvasWidth, 0, 7, Color.GREENYELLOW));
this.getChildren().add(new Circle(0,canvasHeight, 7, Color.GREENYELLOW));
Rectangle r = new Rectangle(canvasWidth, canvasHeight, Color.TRANSPARENT);
r.setStroke(Color.BLACK);
this.getChildren().add(r);
updateBorder(borderPoints); updateBorder(borderPoints);
updateCourse(compoundMarks, courseOrder); updateCourse(compoundMarks, courseOrder);
} }
@@ -285,7 +299,7 @@ public class GameView extends Pane {
return; return;
} }
borderPoints = border; borderPoints = border;
rescaleRace(new ArrayList<>(borderPoints)); rescaleRace(borderPoints);
List<Double> boundaryPoints = new ArrayList<>(); List<Double> boundaryPoints = new ArrayList<>();
for (Limit limit : border) { for (Limit limit : border) {
@@ -305,7 +319,7 @@ public class GameView extends Pane {
//Check is called once to avoid unnecessarily change the orderedMarks limits once the race is running //Check is called once to avoid unnecessarily change the orderedMarks limits once the race is running
findMinMaxPoint(limitingCoordinates); findMinMaxPoint(limitingCoordinates);
double minLonToMaxLon = scaleRaceExtremities(); double minLonToMaxLon = scaleRaceExtremities();
calculateReferencePointLocation(minLonToMaxLon); calculateReferencePointLocation();
} }
/** /**
@@ -324,55 +338,81 @@ public class GameView extends Pane {
minLonPoint = new GeoPoint(sortedPoints.get(0).getLat(), sortedPoints.get(0).getLng()); minLonPoint = new GeoPoint(sortedPoints.get(0).getLat(), sortedPoints.get(0).getLng());
GeoPoint maxLon = sortedPoints.get(sortedPoints.size() - 1); GeoPoint maxLon = sortedPoints.get(sortedPoints.size() - 1);
maxLonPoint = new GeoPoint(maxLon.getLat(), maxLon.getLng()); maxLonPoint = new GeoPoint(maxLon.getLat(), maxLon.getLng());
if (maxLonPoint.getLng() - minLonPoint.getLng() > 180) { // if (maxLonPoint.getLng() - minLonPoint.getLng() > 180) {
horizontalInversion = true; // horizontalInversion = true;
} // }
} }
/** private void calculateReferencePointLocation() {
* Calculates the location of a reference point, this is always the point with minimum latitude,
* in relation to the canvas.
*
* @param minLonToMaxLon The horizontal distance between the point of minimum longitude to
* maximum longitude.
*/
private void calculateReferencePointLocation(double minLonToMaxLon) {
GeoPoint referencePoint = minLatPoint;
double referenceAngle;
if (scaleDirection == ScaleDirection.HORIZONTAL) { referencePointX = canvasWidth / 2;
referenceAngle = Math.abs( referencePointY = canvasHeight / 2;
GeoUtility.getBearingRad(referencePoint, minLonPoint) GeoPoint ref = new GeoPoint(
(maxLatPoint.getLat() - minLatPoint.getLat()) / 2 + minLatPoint.getLat(),
(maxLonPoint.getLng() - minLonPoint.getLng()) / 2 + minLonPoint.getLng()
); );
referencePointX =
bufferSize + distanceScaleFactor * Math.sin(referenceAngle) * GeoUtility
.getDistance(referencePoint, minLonPoint); // double vertAngle = Math.abs(
referenceAngle = Math.abs(GeoUtility.getDistance(referencePoint, maxLatPoint)); // GeoUtility.getBearingRad(minLatPoint, maxLatPoint)
referencePointY = canvasHeight - (bufferSize + bufferSize); // );
referencePointY -= distanceScaleFactor * Math.cos(referenceAngle) * GeoUtility
.getDistance(referencePoint, maxLatPoint); double vertDistance = GeoUtility.getDistance(
referencePointY = referencePointY / 2; ref, new GeoPoint(ref.getLat(), maxLonPoint.getLng())
referencePointY += bufferSize; ) * 2.1; //2.1 allows for empty space around the map.
referencePointY += distanceScaleFactor * Math.cos(referenceAngle) * GeoUtility
.getDistance(referencePoint, maxLatPoint); double horiDistance = GeoUtility.getDistance(
ref, new GeoPoint(maxLatPoint.getLat(), ref.getLng())
) * 2.1;
double vertScale = canvasHeight / vertDistance;
if (horiDistance * vertScale > canvasWidth) {
distanceScaleFactor = canvasWidth / horiDistance;
scaleDirection = ScaleDirection.HORIZONTAL;
} else { } else {
referencePointY = canvasHeight - bufferSize; distanceScaleFactor = vertScale;
referenceAngle = Math.abs( scaleDirection = ScaleDirection.VERTICAL;
Math.toRadians(
GeoUtility.getDistance(referencePoint, minLonPoint)
)
);
referencePointX = bufferSize;
referencePointX += distanceScaleFactor * Math.sin(referenceAngle) * GeoUtility
.getDistance(referencePoint, minLonPoint);
referencePointX +=
((canvasWidth - (bufferSize + bufferSize)) - (minLonToMaxLon * distanceScaleFactor))
/ 2;
referencePointX += horizontalBuffer;
}
if (horizontalInversion) {
referencePointX = canvasWidth - bufferSize - (referencePointX - bufferSize);
} }
minLatPoint = ref;
// Point2D center = new Point2D(canvasWidth / 2, canvasHeight / 2);
//
// if (scaleDirection == ScaleDirection.HORIZONTAL) {
// referenceAngle = Math.abs(
// GeoUtility.getBearingRad(referencePoint, minLonPoint)
// );
// referencePointX =
// bufferSize + distanceScaleFactor * Math.sin(referenceAngle) * GeoUtility
// .getDistance(referencePoint, minLonPoint);
// referenceAngle = Math.abs(GeoUtility.getDistance(referencePoint, maxLatPoint));
// referencePointY = canvasHeight - (bufferSize + bufferSize);
// referencePointY -= distanceScaleFactor * Math.cos(referenceAngle) * GeoUtility
// .getDistance(referencePoint, maxLatPoint);
// referencePointY = referencePointY / 2;
// referencePointY += bufferSize;
// referencePointY += distanceScaleFactor * Math.cos(referenceAngle) * GeoUtility
// .getDistance(referencePoint, maxLatPoint);
// } else {
// referencePointY = canvasHeight - bufferSize;
// referenceAngle = Math.abs(
// Math.toRadians(
// GeoUtility.getDistance(referencePoint, minLonPoint)
// )
// );
// referencePointX = bufferSize;
// referencePointX += distanceScaleFactor * Math.sin(referenceAngle) * GeoUtility
// .getDistance(referencePoint, minLonPoint);
// referencePointX +=
// ((canvasWidth - (bufferSize + bufferSize)) - (minLonToMaxLon * distanceScaleFactor))
// / 2;
// }
// if (horizontalInversion) {
// referencePointX = canvasWidth - bufferSize - (referencePointX - bufferSize);
// }
} }
@@ -381,33 +421,34 @@ public class GameView extends Pane {
* 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)
); // );
double vertDistance = // double vertDistance =
Math.cos(vertAngle) * GeoUtility.getDistance(minLatPoint, maxLatPoint); // Math.cos(vertAngle) * GeoUtility.getDistance(minLatPoint, maxLatPoint);
double horiAngle = Math.abs( // double horiAngle = Math.abs(
GeoUtility.getBearingRad(minLonPoint, maxLonPoint) // GeoUtility.getBearingRad(minLonPoint, maxLonPoint)
); // );
if (horiAngle <= (Math.PI / 2)) { // if (horiAngle <= (Math.PI / 2)) {
horiAngle = (Math.PI / 2) - horiAngle; // horiAngle = (Math.PI / 2) - horiAngle;
} else { // } else {
horiAngle = horiAngle - (Math.PI / 2); // horiAngle = horiAngle - (Math.PI / 2);
} // }
double horiDistance = // double horiDistance =
Math.cos(horiAngle) * GeoUtility.getDistance(minLonPoint, maxLonPoint); // Math.cos(horiAngle) * GeoUtility.getDistance(minLonPoint, maxLonPoint);
//
double vertScale = (canvasHeight - (bufferSize + bufferSize)) / vertDistance; // double vertScale = canvasHeight / vertDistance;
//
if ((horiDistance * vertScale) > (canvasWidth - (bufferSize + bufferSize))) { // if (horiDistance * vertScale > canvasWidth) {
distanceScaleFactor = (canvasWidth - (bufferSize + bufferSize)) / horiDistance; // distanceScaleFactor = canvasWidth / horiDistance;
scaleDirection = ScaleDirection.HORIZONTAL; // scaleDirection = ScaleDirection.HORIZONTAL;
} else { // } else {
distanceScaleFactor = vertScale; // distanceScaleFactor = vertScale;
scaleDirection = ScaleDirection.VERTICAL; // scaleDirection = ScaleDirection.VERTICAL;
} // }
return horiDistance; // return horiDistance;
return 0;
} }
private Point2D findScaledXY(double unscaledLat, double unscaledLon) { private Point2D findScaledXY(double unscaledLat, double unscaledLon) {
@@ -153,25 +153,32 @@ public class LobbyController implements Initializable {
* Initializes a top down preview of the race course map. * Initializes a top down preview of the race course map.
*/ */
private void initMapPreview() { private void initMapPreview() {
gameView = new GameView(new ArrayList<>(), new ArrayList<>(), new ArrayList<>()); // gameView = new GameView(marks, corners, border);
gameView.setHorizontalBuffer(330d); // gameView.setHorizontalBuffer(330d);
mapWidth = 770d; // mapWidth = 770d;
mapHeight = 574d; // mapHeight = 574d;
// Add game view // Add game view
RaceXMLData raceData = ViewManager.getInstance().getGameClient().getCourseData();
List<Limit> border = raceData.getCourseLimit();
List<CompoundMark> marks = new ArrayList<CompoundMark>(raceData.getCompoundMarks().values());
List<Corner> corners = raceData.getMarkSequence();
// gameView.updateBorder(border);
// gameView.updateCourse(marks, corners);
gameView = new GameView(marks, corners, border);
serverMap.getChildren().clear(); serverMap.getChildren().clear();
serverMap.getChildren().add(gameView); serverMap.getChildren().add(gameView);
serverMap.widthProperty().addListener((observable, oldValue, newValue) -> { // serverMap.widthProperty().addListener((observable, oldValue, newValue) -> {
mapWidth = newValue.doubleValue(); // mapWidth = newValue.doubleValue();
refreshMapView(); // refreshMapView();
}); // });
//
serverMap.heightProperty().addListener((observable, oldValue, newValue) -> { // serverMap.heightProperty().addListener((observable, oldValue, newValue) -> {
mapHeight = newValue.doubleValue(); // mapHeight = newValue.doubleValue();
refreshMapView(); // refreshMapView();
}); // });
} }
/** /**
+7 -8
View File
@@ -12,7 +12,8 @@
<?import javafx.scene.layout.StackPane?> <?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?> <?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?> <?import javafx.scene.text.Font?>
<StackPane fx:id="serverListMainStackPane" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.visualiser.controllers.LobbyController">
<StackPane fx:id="serverListMainStackPane" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.visualiser.controllers.LobbyController">
<children> <children>
<GridPane fx:id="serverListMainGridPane" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"> <GridPane fx:id="serverListMainGridPane" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308">
<children> <children>
@@ -37,8 +38,7 @@
</GridPane> </GridPane>
<GridPane> <GridPane>
<children> <children>
<Label fx:id="serverName" text="Party Parrots In Space" <Label fx:id="serverName" text="Party Parrots In Space" GridPane.valignment="CENTER">
GridPane.valignment="CENTER">
<font> <font>
<Font size="31.0" /> <Font size="31.0" />
</font> </font>
@@ -46,8 +46,7 @@
<Insets left="35.0" top="10.0" /> <Insets left="35.0" top="10.0" />
</padding> </padding>
</Label> </Label>
<Label fx:id="mapName" text="This is a map, it's called Haoming" <Label fx:id="mapName" text="This is a map, it's called Haoming" GridPane.rowIndex="1">
GridPane.rowIndex="1">
<padding> <padding>
<Insets left="35.0" top="-15.0" /> <Insets left="35.0" top="-15.0" />
</padding> </padding>
@@ -73,13 +72,13 @@
<children> <children>
<ScrollPane fx:id="playerListScrollPane" hbarPolicy="NEVER" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.valignment="CENTER"> <ScrollPane fx:id="playerListScrollPane" hbarPolicy="NEVER" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.valignment="CENTER">
<content> <content>
<VBox fx:id="playerListVBox" prefHeight="200.0" prefWidth="100.0"/> <VBox fx:id="playerListVBox" prefHeight="200.0" prefWidth="100.0" />
</content> </content>
<GridPane.margin> <GridPane.margin>
<Insets bottom="15.0" left="7.0" right="15.0" top="15.0" /> <Insets bottom="15.0" left="7.0" right="15.0" top="15.0" />
</GridPane.margin> </GridPane.margin>
</ScrollPane> </ScrollPane>
<Pane fx:id="serverMap" style="-fx-background-color: skyblue;"> <Pane fx:id="serverMap" prefHeight="370.0" prefWidth="0.0" style="-fx-background-color: skyblue;">
<GridPane.margin> <GridPane.margin>
<Insets bottom="15.0" left="15.0" right="7.0" top="15.0" /> <Insets bottom="15.0" left="15.0" right="7.0" top="15.0" />
</GridPane.margin> </GridPane.margin>
@@ -96,7 +95,7 @@
<RowConstraints maxHeight="80.0" minHeight="80.0" prefHeight="80.0" vgrow="SOMETIMES" /> <RowConstraints maxHeight="80.0" minHeight="80.0" prefHeight="80.0" vgrow="SOMETIMES" />
</rowConstraints> </rowConstraints>
<stylesheets> <stylesheets>
<String fx:value="/css/Master.css"/> <String fx:value="/css/Master.css" />
<String fx:value="/css/LobbyView.css" /> <String fx:value="/css/LobbyView.css" />
</stylesheets> </stylesheets>
</GridPane> </GridPane>