From d9f5f7a137541b7d8f2cb977166047be2e4174c8 Mon Sep 17 00:00:00 2001 From: Calum Date: Tue, 18 Jul 2017 14:00:24 +1200 Subject: [PATCH] Refactoring view for game development #story[987] --- ...ontroller.java => GameViewController.java} | 155 ++++++------------ .../controllers/RaceViewController.java | 26 +-- .../java/seng302/fxObjects/BoatGroup.java | 4 +- src/main/resources/views/CanvasView.fxml | 7 - src/main/resources/views/GameView.fxml | 7 + src/main/resources/views/MainView.fxml | 5 - src/main/resources/views/RaceView.fxml | 6 +- 7 files changed, 78 insertions(+), 132 deletions(-) rename src/main/java/seng302/controllers/{CanvasController.java => GameViewController.java} (80%) delete mode 100644 src/main/resources/views/CanvasView.fxml create mode 100644 src/main/resources/views/GameView.fxml diff --git a/src/main/java/seng302/controllers/CanvasController.java b/src/main/java/seng302/controllers/GameViewController.java similarity index 80% rename from src/main/java/seng302/controllers/CanvasController.java rename to src/main/java/seng302/controllers/GameViewController.java index 7f40b243..390255c9 100644 --- a/src/main/java/seng302/controllers/CanvasController.java +++ b/src/main/java/seng302/controllers/GameViewController.java @@ -7,13 +7,12 @@ import java.util.List; import java.util.Map; import java.util.concurrent.PriorityBlockingQueue; import javafx.animation.AnimationTimer; -import javafx.beans.property.SimpleDoubleProperty; +import javafx.collections.ObservableList; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.geometry.Point2D; import javafx.scene.Group; -import javafx.scene.canvas.Canvas; -import javafx.scene.canvas.GraphicsContext; +import javafx.scene.Node; import javafx.scene.image.ImageView; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.GridPane; @@ -43,22 +42,20 @@ import seng302.utilities.GeoUtility; * Created by ptg19 on 15/03/17. * Modified by Haoming Yin (hyi25) on 20/3/2017. */ -public class CanvasController { +public class GameViewController { @FXML - private AnchorPane canvasPane; + private AnchorPane mainPane; private RaceViewController raceViewController; - private ResizableCanvas canvas; - private Group group; - private GraphicsContext gc; + private ObservableList gameObjects; private ImageView mapImage; - private final int BUFFER_SIZE = 50; - private final int PANEL_WIDTH = 1260; // it should be 1280 but, minors 40 to cancel the bias. - private final int PANEL_HEIGHT = 960; - private final int CANVAS_WIDTH = 720; - private final int CANVAS_HEIGHT = 720; + private int BUFFER_SIZE = 50; + private int panelWidth = 1260; // it should be 1280 but, minors 40 to cancel the bias. + private int panelHeight = 960; + private double canvasWidth = 720; + private double canvasHeight = 720; private boolean horizontalInversion = false; private double distanceScaleFactor; @@ -83,48 +80,43 @@ public class CanvasController { private int frameTimeIndex = 0; private boolean arrayFilled = false; - public AnimationTimer timer; + AnimationTimer timer; private enum ScaleDirection { HORIZONTAL, VERTICAL } - public void setup(RaceViewController raceViewController) { + void setup(RaceViewController raceViewController) { this.raceViewController = raceViewController; } public void initialize() { raceViewController = new RaceViewController(); - canvas = new ResizableCanvas(); - group = new Group(); - + gameObjects = mainPane.getChildren(); // create image view for map, bind panel size to image mapImage = new ImageView(); - canvasPane.getChildren().add(mapImage); - mapImage.fitWidthProperty().bind(canvasPane.widthProperty()); - mapImage.fitHeightProperty().bind(canvasPane.heightProperty()); - - canvasPane.getChildren().add(canvas); - canvasPane.getChildren().add(group); - // Bind canvas size to stack pane size. - canvas.widthProperty().bind(new SimpleDoubleProperty(CANVAS_WIDTH)); - canvas.heightProperty().bind(new SimpleDoubleProperty(CANVAS_HEIGHT)); + mainPane.getChildren().add(mapImage); + mapImage.fitWidthProperty().bind(mainPane.widthProperty()); + mapImage.fitHeightProperty().bind(mainPane.heightProperty()); } - public void initializeCanvas() { + void initializeCanvas() { - gc = canvas.getGraphicsContext2D(); - gc.setGlobalAlpha(0.5); fitMarksToCanvas(); drawGoogleMap(); FPSdisplay.setLayoutX(5); FPSdisplay.setLayoutY(20); FPSdisplay.setStrokeWidth(2); - group.getChildren().add(FPSdisplay); - group.getChildren().add(raceBorder); + gameObjects.add(FPSdisplay); + gameObjects.add(raceBorder); initializeMarks(); initializeBoats(); + mainPane.widthProperty().addListener(resize -> { + canvasWidth = mainPane.getWidth(); + canvasHeight = mainPane.getHeight(); + fitMarksToCanvas(); + }); timer = new AnimationTimer() { private long lastTime = 0; @@ -171,15 +163,13 @@ public class CanvasController { private void switchToFinishScreen() { try { // canvas view -> anchor pane -> grid pane -> main view - GridPane gridPane = (GridPane) canvasPane.getParent().getParent(); + GridPane gridPane = (GridPane) mainPane.getParent().getParent(); AnchorPane contentPane = (AnchorPane) gridPane.getParent(); contentPane.getChildren().removeAll(); contentPane.getChildren().clear(); contentPane.getStylesheets().add(getClass().getResource("/css/master.css").toString()); contentPane.getChildren().addAll( (Pane) FXMLLoader.load(getClass().getResource("/views/FinishScreenView.fxml"))); - } catch (javafx.fxml.LoadException e) { - e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } @@ -206,10 +196,10 @@ public class CanvasController { // distance from origin corner to bottom right corner of the panel double distanceFromOriginToBottomRight = Math.sqrt( - Math.pow(PANEL_HEIGHT * metersPerPixelY, 2) + Math - .pow(PANEL_WIDTH * metersPerPixelX, 2)); + Math.pow(panelHeight * metersPerPixelY, 2) + Math + .pow(panelWidth * metersPerPixelX, 2)); double bearingFromOriginToBottomRight = Math - .toDegrees(Math.atan2(PANEL_WIDTH, -PANEL_HEIGHT)); + .toDegrees(Math.atan2(panelWidth, -panelHeight)); GeoPoint bottomRightPos = GeoUtility .getGeoCoordinate(originPos, bearingFromOriginToBottomRight, distanceFromOriginToBottomRight); @@ -288,7 +278,7 @@ public class CanvasController { } } - void updateMarkGroup (long raceId, MarkGroup markGroup) { + private void updateMarkGroup (long raceId, MarkGroup markGroup) { PriorityBlockingQueue movementQueue = StreamParser.markLocations.get(raceId); if (movementQueue.size() > 0){ try { @@ -327,10 +317,10 @@ public class CanvasController { annotations.getChildren().add(boatGroup.getAnnotations()); } } - group.getChildren().addAll(trails); - group.getChildren().addAll(wakes); - group.getChildren().addAll(annotations); - group.getChildren().addAll(boatGroups); + gameObjects.addAll(trails); + gameObjects.addAll(wakes); + gameObjects.addAll(annotations); + gameObjects.addAll(boatGroups); } private void initializeMarks() { @@ -349,40 +339,7 @@ public class CanvasController { markGroups.add(markGroup); } } - group.getChildren().addAll(markGroups); - } - - class ResizableCanvas extends Canvas { - - ResizableCanvas() { - // Redraw canvas when size changes. - widthProperty().addListener(evt -> draw()); - heightProperty().addListener(evt -> draw()); - } - - private void draw() { - double width = getWidth(); - double height = getHeight(); - - GraphicsContext gc = getGraphicsContext2D(); - gc.clearRect(0, 0, width, height); - } - - @Override - public boolean isResizable() { - return true; - } - - @Override - public double prefWidth(double height) { - return getWidth(); - } - - @Override - public double prefHeight(double width) { - return getHeight(); - } - + gameObjects.addAll(markGroups); } private void drawFps(int fps){ @@ -452,21 +409,21 @@ public class CanvasController { referencePointX = BUFFER_SIZE + distanceScaleFactor * Math.sin(referenceAngle) * Mark.calculateDistance(referencePoint, minLonPoint); referenceAngle = Math.abs(Mark.calculateHeadingRad(referencePoint, maxLatPoint)); - referencePointY = CANVAS_HEIGHT - (BUFFER_SIZE + BUFFER_SIZE); + referencePointY = canvasHeight - (BUFFER_SIZE + BUFFER_SIZE); referencePointY -= distanceScaleFactor * Math.cos(referenceAngle) * Mark.calculateDistance(referencePoint, maxLatPoint); referencePointY = referencePointY / 2; referencePointY += BUFFER_SIZE; referencePointY += distanceScaleFactor * Math.cos(referenceAngle) * Mark.calculateDistance(referencePoint, maxLatPoint); } else { - referencePointY = CANVAS_HEIGHT - BUFFER_SIZE; + referencePointY = canvasHeight - BUFFER_SIZE; referenceAngle = Math.abs(Mark.calculateHeadingRad(referencePoint, minLonPoint)); referencePointX = BUFFER_SIZE; referencePointX += distanceScaleFactor * Math.sin(referenceAngle) * Mark.calculateDistance(referencePoint, minLonPoint); - referencePointX += ((CANVAS_WIDTH - (BUFFER_SIZE + BUFFER_SIZE)) - (minLonToMaxLon * distanceScaleFactor)) / 2; + referencePointX += ((canvasWidth - (BUFFER_SIZE + BUFFER_SIZE)) - (minLonToMaxLon * distanceScaleFactor)) / 2; } if(horizontalInversion) { - referencePointX = CANVAS_WIDTH - BUFFER_SIZE - (referencePointX - BUFFER_SIZE); + referencePointX = canvasWidth - BUFFER_SIZE - (referencePointX - BUFFER_SIZE); } } @@ -490,10 +447,10 @@ public class CanvasController { double horiDistance = Math.cos(horiAngle) * Mark.calculateDistance(minLonPoint, maxLonPoint); - double vertScale = (CANVAS_HEIGHT - (BUFFER_SIZE + BUFFER_SIZE)) / vertDistance; + double vertScale = (canvasHeight - (BUFFER_SIZE + BUFFER_SIZE)) / vertDistance; - if ((horiDistance * vertScale) > (CANVAS_WIDTH - (BUFFER_SIZE + BUFFER_SIZE))) { - distanceScaleFactor = (CANVAS_WIDTH - (BUFFER_SIZE + BUFFER_SIZE)) / horiDistance; + if ((horiDistance * vertScale) > (canvasWidth - (BUFFER_SIZE + BUFFER_SIZE))) { + distanceScaleFactor = (canvasWidth - (BUFFER_SIZE + BUFFER_SIZE)) / horiDistance; scaleDirection = ScaleDirection.HORIZONTAL; } else { distanceScaleFactor = vertScale; @@ -509,8 +466,8 @@ public class CanvasController { public Point2D findScaledXY (double unscaledLat, double unscaledLon) { double distanceFromReference; double angleFromReference; - int xAxisLocation = (int) referencePointX; - int yAxisLocation = (int) referencePointY; + double xAxisLocation = referencePointX; + double yAxisLocation = referencePointY; angleFromReference = Mark .calculateHeadingRad(minLatPoint.getLatitude(), minLatPoint.getLongitude(), unscaledLat, @@ -519,31 +476,23 @@ public class CanvasController { .calculateDistance(minLatPoint.getLatitude(), minLatPoint.getLongitude(), unscaledLat, unscaledLon); if (angleFromReference >= 0 && angleFromReference <= Math.PI / 2) { - xAxisLocation += (int) Math - .round(distanceScaleFactor * Math.sin(angleFromReference) * distanceFromReference); - yAxisLocation -= (int) Math - .round(distanceScaleFactor * Math.cos(angleFromReference) * distanceFromReference); + xAxisLocation += Math.round(distanceScaleFactor * Math.sin(angleFromReference) * distanceFromReference); + yAxisLocation -= Math.round(distanceScaleFactor * Math.cos(angleFromReference) * distanceFromReference); } else if (angleFromReference >= 0) { angleFromReference = angleFromReference - Math.PI / 2; - xAxisLocation += (int) Math - .round(distanceScaleFactor * Math.cos(angleFromReference) * distanceFromReference); - yAxisLocation += (int) Math - .round(distanceScaleFactor * Math.sin(angleFromReference) * distanceFromReference); + xAxisLocation += Math.round(distanceScaleFactor * Math.cos(angleFromReference) * distanceFromReference); + yAxisLocation += Math.round(distanceScaleFactor * Math.sin(angleFromReference) * distanceFromReference); } else if (angleFromReference < 0 && angleFromReference >= -Math.PI / 2) { angleFromReference = Math.abs(angleFromReference); - xAxisLocation -= (int) Math - .round(distanceScaleFactor * Math.sin(angleFromReference) * distanceFromReference); - yAxisLocation -= (int) Math - .round(distanceScaleFactor * Math.cos(angleFromReference) * distanceFromReference); + xAxisLocation -= Math.round(distanceScaleFactor * Math.sin(angleFromReference) * distanceFromReference); + yAxisLocation -= Math.round(distanceScaleFactor * Math.cos(angleFromReference) * distanceFromReference); } else { angleFromReference = Math.abs(angleFromReference) - Math.PI / 2; - xAxisLocation -= (int) Math - .round(distanceScaleFactor * Math.cos(angleFromReference) * distanceFromReference); - yAxisLocation += (int) Math - .round(distanceScaleFactor * Math.sin(angleFromReference) * distanceFromReference); + xAxisLocation -= Math.round(distanceScaleFactor * Math.cos(angleFromReference) * distanceFromReference); + yAxisLocation += Math.round(distanceScaleFactor * Math.sin(angleFromReference) * distanceFromReference); } if(horizontalInversion) { - xAxisLocation = CANVAS_WIDTH - BUFFER_SIZE - (xAxisLocation - BUFFER_SIZE); + xAxisLocation = canvasWidth - BUFFER_SIZE - (xAxisLocation - BUFFER_SIZE); } return new Point2D(xAxisLocation, yAxisLocation); } diff --git a/src/main/java/seng302/controllers/RaceViewController.java b/src/main/java/seng302/controllers/RaceViewController.java index 8b30113c..f9d2f360 100644 --- a/src/main/java/seng302/controllers/RaceViewController.java +++ b/src/main/java/seng302/controllers/RaceViewController.java @@ -72,7 +72,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel @FXML private ComboBox boatSelectionComboBox; @FXML - private CanvasController includedCanvasController; + private GameViewController gameViewController; private static ArrayList startingBoats = new ArrayList<>(); private boolean displayFps; @@ -95,13 +95,13 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel sparklineYAxis.setTickMarkVisible(false); startingBoats = new ArrayList<>(StreamParser.getBoats().values()); - includedCanvasController.setup(this); - includedCanvasController.initializeCanvas(); + gameViewController.setup(this); + gameViewController.initializeCanvas(); initializeUpdateTimer(); initialiseFPSCheckBox(); initialiseAnnotationSlider(); initialiseBoatSelectionComboBox(); - includedCanvasController.timer.start(); + gameViewController.timer.start(); selectAnnotationBtn.setOnAction(event -> loadSelectAnnotationView()); } @@ -416,13 +416,13 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel // Can only calc leg direction if there is a next mark and it is a gate mark if (nextMark != null) { if (nextMark instanceof GateMark) { - if (bg.isUpwindLeg(includedCanvasController, nextMark)) { + if (bg.isUpwindLeg(gameViewController, nextMark)) { isUpwind = true; } else { isUpwind = false; } - for(MarkGroup mg : includedCanvasController.getMarkGroups()) { + for(MarkGroup mg : gameViewController.getMarkGroups()) { mg.removeLaylines(); @@ -430,8 +430,10 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel SingleMark singleMark1 = ((GateMark) nextMark).getSingleMark1(); SingleMark singleMark2 = ((GateMark) nextMark).getSingleMark2(); - Point2D markPoint1 = includedCanvasController.findScaledXY(singleMark1.getLatitude(), singleMark1.getLongitude()); - Point2D markPoint2 = includedCanvasController.findScaledXY(singleMark2.getLatitude(), singleMark2.getLongitude()); + Point2D markPoint1 = gameViewController + .findScaledXY(singleMark1.getLatitude(), singleMark1.getLongitude()); + Point2D markPoint2 = gameViewController + .findScaledXY(singleMark2.getLatitude(), singleMark2.getLongitude()); HashMap angleAndSpeed; if (isUpwind) { angleAndSpeed = PolarTable.getOptimalUpwindVMG(StreamParser.getWindSpeed()); @@ -575,13 +577,13 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel switch (annotationLevel) { // No Annotations case 0: - for (BoatGroup bg : includedCanvasController.getBoatGroups()) { + for (BoatGroup bg : gameViewController.getBoatGroups()) { bg.setVisibility(false, false, false, false, false, false); } break; // Important Annotations case 1: - for (BoatGroup bg : includedCanvasController.getBoatGroups()) { + for (BoatGroup bg : gameViewController.getBoatGroups()) { bg.setVisibility( importantAnnotations.getAnnotationState(Annotation.NAME), importantAnnotations.getAnnotationState(Annotation.SPEED), @@ -594,7 +596,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel break; // All Annotations case 2: - for (BoatGroup bg : includedCanvasController.getBoatGroups()) { + for (BoatGroup bg : gameViewController.getBoatGroups()) { bg.setVisibility(true, true, true, true, true, true); } break; @@ -608,7 +610,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel * @param yacht The yacht for which we want to view all annotations */ private void setSelectedBoat(Yacht yacht) { - for (BoatGroup bg : includedCanvasController.getBoatGroups()) { + for (BoatGroup bg : gameViewController.getBoatGroups()) { //We need to iterate over all race groups to get the matching boat group belonging to this boat if we //are to toggle its annotations, there is no other backwards knowledge of a yacht to its boatgroup. if (bg.getBoat().getHullID().equals(yacht.getHullID())) { diff --git a/src/main/java/seng302/fxObjects/BoatGroup.java b/src/main/java/seng302/fxObjects/BoatGroup.java index 0848db30..a63b482a 100644 --- a/src/main/java/seng302/fxObjects/BoatGroup.java +++ b/src/main/java/seng302/fxObjects/BoatGroup.java @@ -11,7 +11,7 @@ import javafx.scene.shape.Polygon; import javafx.scene.transform.Rotate; import seng302.models.Yacht; import seng302.utilities.GeometryUtils; -import seng302.controllers.CanvasController; +import seng302.controllers.GameViewController; import seng302.models.mark.GateMark; import seng302.models.mark.Mark; import seng302.models.mark.SingleMark; @@ -236,7 +236,7 @@ public class BoatGroup extends Group { * going up wind, if they are on different sides of the gate, then the boat is going downwind * @param canvasController */ - public Boolean isUpwindLeg(CanvasController canvasController, Mark nextMark) { + public Boolean isUpwindLeg(GameViewController canvasController, Mark nextMark) { Double windAngle = StreamParser.getWindDirection(); GateMark thisGateMark = (GateMark) nextMark; diff --git a/src/main/resources/views/CanvasView.fxml b/src/main/resources/views/CanvasView.fxml deleted file mode 100644 index 94c08695..00000000 --- a/src/main/resources/views/CanvasView.fxml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/main/resources/views/GameView.fxml b/src/main/resources/views/GameView.fxml new file mode 100644 index 00000000..eada7edc --- /dev/null +++ b/src/main/resources/views/GameView.fxml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/main/resources/views/MainView.fxml b/src/main/resources/views/MainView.fxml index dab6e135..76af833e 100644 --- a/src/main/resources/views/MainView.fxml +++ b/src/main/resources/views/MainView.fxml @@ -1,10 +1,5 @@ - - - - - diff --git a/src/main/resources/views/RaceView.fxml b/src/main/resources/views/RaceView.fxml index d777cece..9fb1f20a 100644 --- a/src/main/resources/views/RaceView.fxml +++ b/src/main/resources/views/RaceView.fxml @@ -7,7 +7,7 @@ - + @@ -61,9 +61,9 @@ - + - +