mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 14:28:43 +00:00
Controllers and Fxml nicely refactored, tests still broken #story[463]
This commit is contained in:
@@ -1,33 +1,19 @@
|
||||
package seng302.controllers;
|
||||
|
||||
import javafx.animation.*;
|
||||
import javafx.beans.property.DoubleProperty;
|
||||
import javafx.beans.property.SimpleDoubleProperty;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.geometry.NodeOrientation;
|
||||
import javafx.scene.canvas.Canvas;
|
||||
import javafx.scene.canvas.GraphicsContext;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.text.Font;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.util.Duration;
|
||||
import seng302.models.Boat;
|
||||
import seng302.models.Event;
|
||||
import seng302.models.Race;
|
||||
import seng302.models.TimelineInfo;
|
||||
import seng302.models.mark.GateMark;
|
||||
import seng302.models.mark.Mark;
|
||||
import seng302.models.mark.MarkType;
|
||||
import seng302.models.mark.SingleMark;
|
||||
import seng302.models.parsers.ConfigParser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
@@ -39,28 +25,26 @@ public class CanvasController {
|
||||
@FXML
|
||||
private AnchorPane canvasPane;
|
||||
|
||||
private RaceViewController raceViewController;
|
||||
private ResizableCanvas canvas;
|
||||
private Race race;
|
||||
private GraphicsContext gc;
|
||||
private HashMap<Boat, TimelineInfo> timelineInfos;
|
||||
private Animation.Status raceStatus = Animation.Status.PAUSED;
|
||||
|
||||
///test
|
||||
private HashSet<Integer> headingTest = new HashSet<>();
|
||||
private final double ORIGIN_LAT = 32.321504;
|
||||
private final double ORIGIN_LON = -64.857063;
|
||||
private final int SCALE = 16000;
|
||||
|
||||
public void setup(RaceViewController raceViewController){
|
||||
this.raceViewController = raceViewController;
|
||||
}
|
||||
|
||||
public void initialize() {
|
||||
canvas = new ResizableCanvas();
|
||||
|
||||
canvasPane.getChildren().add(canvas);
|
||||
|
||||
// Bind canvas size to stack pane size.
|
||||
canvas.widthProperty().bind(
|
||||
canvasPane.widthProperty());
|
||||
canvas.heightProperty().bind(
|
||||
canvasPane.heightProperty());
|
||||
canvas.widthProperty().bind(canvasPane.widthProperty());
|
||||
canvas.heightProperty().bind(canvasPane.heightProperty());
|
||||
gc = canvas.getGraphicsContext2D();
|
||||
//
|
||||
// timelineInfos = new HashMap<>();
|
||||
|
||||
|
||||
// overriding the handle so that it can clean canvas and redraw boats and course marks
|
||||
AnimationTimer timer = new AnimationTimer() {
|
||||
@@ -80,13 +64,12 @@ public class CanvasController {
|
||||
drawFps(lastFpsCount);
|
||||
|
||||
// If race has started, draw the boats and play the timeline
|
||||
if (race.getRaceTime() > 1){
|
||||
playTimelines();
|
||||
|
||||
if (raceViewController.getRace().getRaceTime() > 1){
|
||||
raceViewController.playTimelines();
|
||||
}
|
||||
// Race has not started, pause the timelines
|
||||
else if (race.getRaceTime() < 1 || raceStatus == Animation.Status.RUNNING){
|
||||
pauseTimelines();
|
||||
else {
|
||||
raceViewController.pauseTimelines();
|
||||
}
|
||||
lastUpdate = now;
|
||||
fpsCount ++;
|
||||
@@ -98,44 +81,7 @@ public class CanvasController {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
try{
|
||||
generateTimelines();
|
||||
}
|
||||
catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
timer.start();
|
||||
loadTimerView();
|
||||
|
||||
Double maxDuration = 0.0;
|
||||
Timeline maxTimeline = null;
|
||||
|
||||
for (TimelineInfo timelineInfo : timelineInfos.values()) {
|
||||
|
||||
Timeline timeline = timelineInfo.getTimeline();
|
||||
if (timeline.getTotalDuration().toMillis() >= maxDuration) {
|
||||
maxDuration = timeline.getTotalDuration().toMillis();
|
||||
maxTimeline = timeline;
|
||||
}
|
||||
|
||||
// Timelines are paused by default
|
||||
timeline.play();
|
||||
timeline.pause();
|
||||
raceStatus = Animation.Status.RUNNING;
|
||||
}
|
||||
|
||||
maxTimeline.setOnFinished(event -> {
|
||||
race.setRaceFinished();
|
||||
loadRaceResultView();
|
||||
});
|
||||
|
||||
|
||||
|
||||
//set wind direction!!!!!!! can't find another place to put my code --haoming
|
||||
double windDirection = new ConfigParser("/config.xml").getWindDirection();
|
||||
windDirectionText.setText(String.format("%.1f°", windDirection));
|
||||
windArrowText.setRotate(windDirection);
|
||||
}
|
||||
|
||||
class ResizableCanvas extends Canvas {
|
||||
@@ -170,98 +116,8 @@ public class CanvasController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the list of boats in the order they finished the race
|
||||
*/
|
||||
private void loadRaceResultView() {
|
||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("/FinishView.fxml"));
|
||||
loader.setController(new RaceResultController(race));
|
||||
|
||||
try {
|
||||
contentAnchorPane.getChildren().removeAll();
|
||||
contentAnchorPane.getChildren().clear();
|
||||
contentAnchorPane.getChildren().addAll((Pane) loader.load());
|
||||
|
||||
} catch (javafx.fxml.LoadException e) {
|
||||
System.err.println(e.getCause());
|
||||
} catch (IOException e) {
|
||||
System.err.println(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Play each boats timeline
|
||||
*/
|
||||
private void playTimelines(){
|
||||
for (TimelineInfo timelineInfo : timelineInfos.values()){
|
||||
Timeline timeline = timelineInfo.getTimeline();
|
||||
|
||||
if (timeline.getStatus() == Animation.Status.PAUSED){
|
||||
timeline.play();
|
||||
}
|
||||
}
|
||||
raceStatus = Animation.Status.RUNNING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pause each boats timeline
|
||||
*/
|
||||
private void pauseTimelines(){
|
||||
for (TimelineInfo timelineInfo : timelineInfos.values()){
|
||||
Timeline timeline = timelineInfo.getTimeline();
|
||||
|
||||
if (timeline.getStatus() == Animation.Status.RUNNING){
|
||||
timeline.pause();
|
||||
}
|
||||
}
|
||||
raceStatus = Animation.Status.PAUSED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates time line for each boat, and stores time time into timelineInfos hash map
|
||||
*/
|
||||
private void generateTimelines() {
|
||||
HashMap<Boat, List> boat_events = race.getEvents();
|
||||
|
||||
for (Boat boat : boat_events.keySet()) {
|
||||
// x, y are the real time coordinates
|
||||
DoubleProperty x = new SimpleDoubleProperty();
|
||||
DoubleProperty y = new SimpleDoubleProperty();
|
||||
|
||||
List<KeyFrame> keyFrames = new ArrayList<>();
|
||||
List<Event> events = boat_events.get(boat);
|
||||
|
||||
// iterates all events and convert each event to keyFrame, then add them into a list
|
||||
for (Event event : events) {
|
||||
if (event.getIsFinishingEvent()) {
|
||||
keyFrames.add(
|
||||
new KeyFrame(Duration.seconds(event.getTime() / 60 / 60 / 5),
|
||||
onFinished -> {race.setBoatFinished(boat); teamPositionsController.handleEvent(event);},
|
||||
new KeyValue(x, event.getThisMark().getLatitude()),
|
||||
new KeyValue(y, event.getThisMark().getLongitude())
|
||||
)
|
||||
);
|
||||
} else {
|
||||
keyFrames.add(
|
||||
new KeyFrame(Duration.seconds(event.getTime() / 60 / 60 / 5),
|
||||
onFinished ->{
|
||||
teamPositionsController.handleEvent(event);
|
||||
boat.setHeading(event.getBoatHeading());
|
||||
},
|
||||
new KeyValue(x, event.getThisMark().getLatitude()),
|
||||
new KeyValue(y, event.getThisMark().getLongitude())
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// uses the lists generated above to create a Timeline for the boat.
|
||||
timelineInfos.put(boat, new TimelineInfo(new Timeline(keyFrames.toArray(new KeyFrame[keyFrames.size()])), x, y));
|
||||
}
|
||||
}
|
||||
|
||||
private void drawFps(int fps){
|
||||
if (displayFps){
|
||||
if (raceViewController.isDisplayFps()){
|
||||
gc.setFill(Color.BLACK);
|
||||
gc.setFont(new Font(14));
|
||||
gc.setLineWidth(3);
|
||||
@@ -273,6 +129,7 @@ public class CanvasController {
|
||||
* Draws all the boats.
|
||||
*/
|
||||
private void drawBoats() {
|
||||
Map<Boat, TimelineInfo> timelineInfos = raceViewController.getTimelineInfos();
|
||||
for (Boat boat : timelineInfos.keySet()) {
|
||||
TimelineInfo timelineInfo = timelineInfos.get(boat);
|
||||
|
||||
@@ -318,7 +175,7 @@ public class CanvasController {
|
||||
|
||||
gc.setFill(color);
|
||||
|
||||
if (annotationCheck) {
|
||||
if (raceViewController.isDisplayAnnotations()) {
|
||||
// Set boat text
|
||||
gc.setFont(new Font(14));
|
||||
gc.setLineWidth(3);
|
||||
@@ -338,7 +195,7 @@ public class CanvasController {
|
||||
double[] yy = new double[] {p1.y + y, p2.y + y, y, p3.y + y};
|
||||
gc.fillPolygon(xx, yy, 4);
|
||||
|
||||
if (annotationCheck){
|
||||
if (raceViewController.isDisplayAnnotations()){
|
||||
drawWake(gc, x, y, speed, color, heading);
|
||||
}
|
||||
}
|
||||
@@ -368,7 +225,7 @@ public class CanvasController {
|
||||
* Draws the course.
|
||||
*/
|
||||
private void drawCourse() {
|
||||
for (Mark mark : race.getCourse()) {
|
||||
for (Mark mark : raceViewController.getRace().getCourse()) {
|
||||
if (mark.getMarkType() == MarkType.SINGLE_MARK) {
|
||||
drawSingleMark((SingleMark) mark, Color.BLACK);
|
||||
} else if (mark.getMarkType() == MarkType.GATE_MARK) {
|
||||
@@ -423,8 +280,4 @@ public class CanvasController {
|
||||
gc.setLineWidth(1);
|
||||
gc.strokeLine(x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
public Race getRace(){
|
||||
return this.race;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user