mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 14:28:43 +00:00
Fix for some movement on racestart issues
#bug
This commit is contained in:
@@ -5,6 +5,7 @@ import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.stage.Stage;
|
||||
import seng302.controllers.Controller;
|
||||
import seng302.models.parsers.StreamParser;
|
||||
import seng302.models.parsers.StreamReceiver;
|
||||
import seng302.server.ServerThread;
|
||||
@@ -13,10 +14,11 @@ public class App extends Application
|
||||
{
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
Parent root = FXMLLoader.load(getClass().getResource("/views/MainView.fxml"));
|
||||
// Parent root = FXMLLoader.load(getClass().getResource("/views/MainView.fxml"));
|
||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("/views/MainView.fxml"));
|
||||
primaryStage.setTitle("RaceVision");
|
||||
primaryStage.setScene(new Scene(root));
|
||||
|
||||
primaryStage.setScene(new Scene(loader.load()));
|
||||
((Controller) loader.getController()).setStage(primaryStage);
|
||||
primaryStage.show();
|
||||
}
|
||||
|
||||
@@ -34,8 +36,8 @@ public class App extends Application
|
||||
sr = new StreamReceiver("localhost", 8085, "RaceStream");
|
||||
}
|
||||
else{
|
||||
// sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4941,"RaceStream");
|
||||
sr = new StreamReceiver("livedata.americascup.com", 4941, "RaceStream");
|
||||
sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4941,"RaceStream");
|
||||
// sr = new StreamReceiver("livedata.americascup.com", 4941, "RaceStream");
|
||||
// sr = new StreamReceiver("localhost", 8085, "RaceStream");
|
||||
}
|
||||
|
||||
|
||||
@@ -5,11 +5,14 @@ import javafx.beans.property.SimpleDoubleProperty;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.geometry.Point2D;
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.canvas.Canvas;
|
||||
import javafx.scene.canvas.GraphicsContext;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.text.Font;
|
||||
import javafx.stage.Stage;
|
||||
import seng302.models.Boat;
|
||||
import seng302.models.BoatGroup;
|
||||
import seng302.models.Colors;
|
||||
@@ -326,7 +329,7 @@ public class CanvasController {
|
||||
for (Boat boat : boats) {
|
||||
BoatGroup boatGroup = new BoatGroup(boat, Colors.getColor());
|
||||
boatGroup.moveTo(startingX, startingY, 0d);
|
||||
boatGroup.forceRotation();
|
||||
boatGroup.setStage(raceViewController.getStage());
|
||||
raceObjects.add(boatGroup);
|
||||
boatAnnotations.getChildren().add(boatGroup.getLowPriorityAnnotations());
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import javafx.concurrent.Task;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TableColumn;
|
||||
@@ -15,6 +16,7 @@ import javafx.scene.control.cell.PropertyValueFactory;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.stage.Stage;
|
||||
import seng302.models.parsers.StreamParser;
|
||||
import seng302.models.parsers.XMLParser;
|
||||
|
||||
@@ -48,12 +50,17 @@ public class Controller implements Initializable {
|
||||
private TableColumn countryCol;
|
||||
@FXML
|
||||
private Label realTime;
|
||||
private Stage stage;
|
||||
|
||||
private void setContentPane(String jfxUrl){
|
||||
try{
|
||||
contentPane.getChildren().removeAll();
|
||||
contentPane.getChildren().clear();
|
||||
contentPane.getChildren().addAll((Pane) FXMLLoader.load(getClass().getResource(jfxUrl)));
|
||||
// contentPane.getChildren().addAll((Pane) FXMLLoader.load(getClass().getResource(jfxUrl)));
|
||||
FXMLLoader loader = new FXMLLoader(getClass().getResource(jfxUrl));
|
||||
contentPane.getChildren().addAll((Node) loader.load());
|
||||
RaceViewController r = (RaceViewController) loader.getController();
|
||||
//((RaceViewController) loader.getController()).setStage(stage);
|
||||
}
|
||||
catch(javafx.fxml.LoadException e){
|
||||
System.err.println(e.getCause());
|
||||
@@ -145,4 +152,7 @@ public class Controller implements Initializable {
|
||||
data.add(boat);
|
||||
}
|
||||
}
|
||||
public void setStage (Stage stage) {
|
||||
this.stage = stage;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import javafx.scene.layout.Pane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.util.Duration;
|
||||
import javafx.util.StringConverter;
|
||||
import seng302.models.*;
|
||||
@@ -49,6 +50,7 @@ public class RaceViewController extends Thread{
|
||||
private Map<Boat, TimelineInfo> timelineInfos = new HashMap<>();
|
||||
private ArrayList<Boat> boatOrder = new ArrayList<>();
|
||||
private Race race;
|
||||
private Stage stage;
|
||||
|
||||
public void initialize() {
|
||||
|
||||
@@ -397,4 +399,11 @@ public class RaceViewController extends Thread{
|
||||
}
|
||||
}
|
||||
|
||||
void setStage (Stage stage) {
|
||||
this.stage = stage;
|
||||
}
|
||||
|
||||
Stage getStage () {
|
||||
return stage;
|
||||
}
|
||||
}
|
||||
@@ -7,33 +7,46 @@ import javafx.scene.shape.Line;
|
||||
import javafx.scene.shape.Polygon;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.scene.transform.Rotate;
|
||||
import seng302.models.parsers.StreamParser;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* BoatGroup is a javafx group that by default contains a graphical objects for representing a 2 dimensional boat.
|
||||
* It contains a single polygon for the boat, a group of lines to show it's path, a wake object and two text labels to
|
||||
* annotate the boat teams name and the boats velocity.
|
||||
* annotate the boat teams name and the boats velocity. The boat will update it's position onscreen everytime
|
||||
* UpdatePosition is called unless the window is minimized in which case it attempts to store animations and apply them
|
||||
* when the window is maximised.
|
||||
*/
|
||||
public class BoatGroup extends RaceObject{
|
||||
|
||||
//Constants for drawing
|
||||
private static final double TEAMNAME_X_OFFSET = 10d;
|
||||
private static final double TEAMNAME_Y_OFFSET = -15d;
|
||||
private static final double VELOCITY_X_OFFSET = 10d;
|
||||
private static final double VELOCITY_Y_OFFSET = -5d;
|
||||
private static final double BOAT_HEIGHT = 15d;
|
||||
private static final double BOAT_WIDTH = 10d;
|
||||
private static double expectedUpdateInterval = 200;
|
||||
private boolean destinationSet;
|
||||
//Variables for boat logic.
|
||||
private Point2D lastPoint;
|
||||
private int wakeGenerationDelay = 10;
|
||||
private double distanceTravelled;
|
||||
|
||||
//Graphical objects
|
||||
private Boat boat;
|
||||
private Group lineGroup = new Group();
|
||||
private Polygon boatPoly;
|
||||
private Text teamNameObject;
|
||||
private Text velocityObject;
|
||||
private Wake wake;
|
||||
//Handles boat moving when connecting to a stream
|
||||
private boolean setToInitialLocation = false;
|
||||
private boolean destinationSet;
|
||||
//Variables for handling minimization
|
||||
private Stage stage;
|
||||
private boolean isMaximized= true;
|
||||
private List<Line> lineStorage = new ArrayList<>();
|
||||
private int setCallCount = 5;
|
||||
|
||||
/**
|
||||
* Creates a BoatGroup with the default triangular boat polygon.
|
||||
@@ -146,6 +159,7 @@ public class BoatGroup extends RaceObject{
|
||||
*/
|
||||
public void updatePosition (long timeInterval) {
|
||||
//Calculate the movement of the boat.
|
||||
if (isMaximized) {
|
||||
double dx = pixelVelocityX * timeInterval;
|
||||
double dy = pixelVelocityY * timeInterval;
|
||||
double rotation = rotationalVelocity * timeInterval;
|
||||
@@ -165,32 +179,34 @@ public class BoatGroup extends RaceObject{
|
||||
l.setStroke(boatPoly.getFill());
|
||||
lineGroup.getChildren().add(l);
|
||||
}
|
||||
if (destinationSet){ //Only begin drawing after the first destination is set
|
||||
if (destinationSet) { //Only begin drawing after the first destination is set
|
||||
lastPoint = new Point2D(boatPoly.getLayoutX(), boatPoly.getLayoutY());
|
||||
}
|
||||
}
|
||||
wake.updatePosition(timeInterval);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the destination of the boat and the headng it should have once it reaches
|
||||
* @param newXValue
|
||||
* @param newYValue
|
||||
* @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 raceIds RaceID of the object to move.
|
||||
*/
|
||||
public void setDestination (double newXValue, double newYValue, double rotation, double groundSpeed, int... raceIds) {
|
||||
if (hasRaceId(raceIds)) {
|
||||
if (setToInitialLocation) {
|
||||
destinationSet = true;
|
||||
boat.setVelocity(groundSpeed);
|
||||
if (currentRotation < 0)
|
||||
currentRotation = 360 - currentRotation;
|
||||
double dx = newXValue - boatPoly.getLayoutX();
|
||||
if ((dx > 0 && pixelVelocityX < 0) || (dx < 0 && pixelVelocityX > 0)) {
|
||||
pixelVelocityX = 0;
|
||||
} else {
|
||||
// if ((dx > 0 && pixelVelocityX < 0) || (dx < 0 && pixelVelocityX > 0)) {
|
||||
// pixelVelocityX = 0;
|
||||
// } else {
|
||||
pixelVelocityX = dx / expectedUpdateInterval;
|
||||
}
|
||||
// }
|
||||
double dy = newYValue - boatPoly.getLayoutY();
|
||||
//Check movement is reasonable. Assumes a 1000 * 1000 canvas
|
||||
if (Math.abs(dx) > 50 || Math.abs(dy) > 50) {
|
||||
@@ -218,11 +234,40 @@ public class BoatGroup extends RaceObject{
|
||||
calculateRotationalVelocity();
|
||||
if (wakeGenerationDelay > 0) {
|
||||
wake.rotate(rotationalGoal);
|
||||
rotateTo(rotationalGoal);
|
||||
rotationalVelocity = 0;
|
||||
wakeGenerationDelay--;
|
||||
} else {
|
||||
wake.setRotationalVelocity(rotationalVelocity, currentRotation, boat.getVelocity());
|
||||
}
|
||||
velocityObject.setText(String.format("%.2f m/s", boat.getVelocity()));
|
||||
} else {
|
||||
setToInitialLocation = true;
|
||||
rotationalGoal = rotation;
|
||||
moveTo(newXValue, newYValue, rotation);
|
||||
}
|
||||
}
|
||||
//If minimized generate lines every 5 calls to set destination.
|
||||
if (!isMaximized) {
|
||||
setToInitialLocation = false;
|
||||
wakeGenerationDelay = 2;
|
||||
if(setCallCount-- == 0) {
|
||||
setCallCount = 5;
|
||||
if (lastPoint != null) {
|
||||
Line l = new Line(
|
||||
lastPoint.getX(),
|
||||
lastPoint.getY(),
|
||||
newXValue,
|
||||
newYValue
|
||||
);
|
||||
l.getStrokeDashArray().setAll(3d, 7d);
|
||||
l.setStroke(boatPoly.getFill());
|
||||
lineStorage.add(l);
|
||||
}
|
||||
if (destinationSet) { //Only begin drawing after the first destination is set
|
||||
lastPoint = new Point2D(newXValue, newYValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -307,4 +352,22 @@ public class BoatGroup extends RaceObject{
|
||||
group.getChildren().addAll(wake, lineGroup);
|
||||
return group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this function to let the BoatGroup know about the stage it is in. If it knows about it's stage then it will
|
||||
* listen to the iconified property of that stage and change it's behaviour upon minimization. Without setting the
|
||||
* Stage there is guarantee that the BoatGroup will draw properly when the stage is minimized.
|
||||
*
|
||||
* @param stage The stage that the BoatGroup is added to.
|
||||
*/
|
||||
public void setStage (Stage stage) {
|
||||
this.stage = stage;
|
||||
this.stage.iconifiedProperty().addListener(e -> {
|
||||
isMaximized = !stage.isIconified();
|
||||
if (!lineStorage.isEmpty()) {
|
||||
lineGroup.getChildren().addAll(lineStorage);
|
||||
lineStorage.clear();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ class Wake extends Group {
|
||||
//Default triangle is -110 deg out of phase with a default wake and has angle of 40 deg.
|
||||
arc = new Arc(0,0,0,0,-110,40);
|
||||
//Opacity increases from 0.5 -> 0 evenly over the 5 wake arcs.
|
||||
arc.setFill(new Color(0.18, 0.7, 1.0, 0.50 + -0.1 * i));
|
||||
arc.setFill(new Color(0.18, 0.7, 1.0, 1.0 + -0.175 * i));
|
||||
arc.setType(ArcType.ROUND);
|
||||
arcs[i] = arc;
|
||||
}
|
||||
@@ -52,17 +52,17 @@ class Wake extends Group {
|
||||
* @param velocity The real world velocity of the boat in m/s.
|
||||
*/
|
||||
void setRotationalVelocity (double rotationalVelocity, double rotationGoal, double velocity) {
|
||||
// if (Math.abs(rotationalVelocity) > 0.5) {
|
||||
// rotationalVelocity = 0;
|
||||
// }
|
||||
sum -= Math.abs(velocities[(velocityIndices[0] + 10) % 13]);
|
||||
sum += Math.abs(rotationalVelocity);
|
||||
// System.out.println("sum = " + sum);
|
||||
max = Math.max(max, rotationalVelocity);
|
||||
if (sum < max)
|
||||
// System.out.println("max = " + max);
|
||||
if (sum < (max / 3))
|
||||
rotate (rotationGoal); //In relatively straight segments the wake snaps to match the boats current position.
|
||||
//This stops the wake from eventually becoming out of sync with the boat.
|
||||
|
||||
// if (Math.abs(rotationalVelocity) > 0.5) {
|
||||
// rotationalVelocity = 0;
|
||||
// }
|
||||
//Update the index of the array of recent velocities that each wake uses. Each wake is 3 velocities behind the
|
||||
//next smallest wake.
|
||||
velocityIndices[0] = (13 + (velocityIndices[0] - 1) % 13) % 13;
|
||||
|
||||
Reference in New Issue
Block a user