Reformatted and refactored the canvas controller

#fix #refactor #story[377]
This commit is contained in:
Haoming Yin
2017-03-20 17:23:33 +13:00
parent 3b8dd11758
commit ee34e5028f
3 changed files with 109 additions and 203 deletions
@@ -11,10 +11,14 @@ import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;
import javafx.util.Duration;
import seng302.models.*;
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 java.util.ArrayList;
import java.util.HashMap;
@@ -24,103 +28,129 @@ import static java.lang.Math.abs;
/**
* Created by ptg19 on 15/03/17.
* Modified by Haoming Yin (hyi25) on 20/3/2017.
*/
public class CanvasController {
@FXML private Canvas canvas;
Race race;
GraphicsContext gc;
HashMap<Boat, TimelineInfo> timelineInfos;
private Race race;
private GraphicsContext gc;
private HashMap<Boat, TimelineInfo> timelineInfos;
@FXML
private Canvas canvas;
public void initialize() {
gc = canvas.getGraphicsContext2D();
gc.scale(5,5);
gc.scale(5, 5);
RaceController raceController = new RaceController();
raceController.initializeRace();
race = raceController.getRace();
timelineInfos = new HashMap<>();
HashMap<Boat, List> boat_events = race.getEvents();
// System.out.println(boat_events);
// generating timelines
for (Boat boat : boat_events.keySet()) {
DoubleProperty x = new SimpleDoubleProperty();
DoubleProperty y = new SimpleDoubleProperty();
List<KeyFrame> keyFrames = new ArrayList<>();
List<Event> events = boat_events.get(boat);
for (Event event: events){
keyFrames.add(
// new KeyFrame(Duration.seconds(event.getDistanceBetweenMarks()/event.getBoat().getVelocity()),
new KeyFrame(Duration.seconds(event.getTime()/60/60/5),
new KeyValue(x, event.getMark().getLatitude()),
new KeyValue(y, event.getMark().getLongitude())
)
);
// drawBoat(gc, event.getMark().getLatitude(), event.getMark().getLongitude(), Colors.getColor());
System.out.println(event.getMark().getName());
}
timelineInfos.put(boat, new TimelineInfo(new Timeline(keyFrames.toArray(new KeyFrame[keyFrames.size()])), x, y));
}
// overriding the handle so that it can clean canvas and redraw boats and course marks
AnimationTimer timer = new AnimationTimer() {
@Override
public void handle(long now) {
gc.clearRect(0,0,760,360);
gc.clearRect(0, 0, 760, 360);
drawCourse();
drawBoats();
}
};
generateTimeline();
// starts the timer and reads events from each boat's time line
timer.start();
for (TimelineInfo timelineInfo: timelineInfos.values()){
for (TimelineInfo timelineInfo : timelineInfos.values()) {
Timeline timeline = timelineInfo.getTimeline();
timeline.play();
}
}
private void drawBoats(){
for (Boat boat: timelineInfos.keySet()){
/**
* Generates time line for each boat, and stores time time into timelineInfos hash map
*/
private void generateTimeline() {
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) {
keyFrames.add(
new KeyFrame(Duration.seconds(event.getTime() / 60 / 60 / 5),
new KeyValue(x, event.getMark().getLatitude()),
new KeyValue(y, event.getMark().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));
}
}
/**
* Draws all the boats.
*/
private void drawBoats() {
for (Boat boat : timelineInfos.keySet()) {
TimelineInfo timelineInfo = timelineInfos.get(boat);
drawBoat(timelineInfo.getX().doubleValue(), timelineInfo.getY().doubleValue(), boat.getColor());
}
}
/**
* Draws a boat with given (x, y) position in the given color
*
* @param x
* @param y
* @param color
*/
private void drawBoat(double x, double y, Color color) {
x = abs(x - 32.313291) * 1000; // to prevent negative longtitude
x = abs(x - 32.313291) * 1000; // to prevent negative longitude
y = abs(y + 64.887057) * 1000; // to prevent negative latitude
// y = abs(y);
int diameter = 2;
gc.setFill(color);
gc.fillOval(x, y, diameter, diameter);
}
private void drawCourse(){
for (Mark mark: race.getCourse()){
gc.setFill(Color.BLACK);
if (mark.getMarkType() == MarkType.SINGLE_MARK){
double x = abs(mark.getLatitude() - 32.313291) * 1000; // to prevent negative longtitude
double y = abs(mark.getLongitude() + 64.887057) * 1000; // to prevent negative latitude
gc.fillOval(x, y, 2, 2);
}
else if (mark.getMarkType() == MarkType.GATE_MARK){
double x;
double y;
GateMark gateMark = (GateMark) mark;
Mark mark1 = gateMark.getSingleMark1();
Mark mark2 = gateMark.getSingleMark1();
x = abs(mark1.getLatitude() - 32.313291) * 1000; // to prevent negative longtitude
y = abs(mark1.getLongitude() + 64.887057) * 1000; // to prevent negative latitude
gc.fillOval(x, y, 2, 2);
x = abs(mark2.getLatitude() - 32.313291) * 1000; // to prevent negative longtitude
y = abs(mark2.getLongitude() + 64.887057) * 1000; // to prevent negative latitude
gc.fillOval(x, y, 2, 2);
/**
* Draws the course.
*/
private void drawCourse() {
for (Mark mark : race.getCourse()) {
if (mark.getMarkType() == MarkType.SINGLE_MARK) {
drawSingleMark((SingleMark) mark);
} else if (mark.getMarkType() == MarkType.GATE_MARK) {
drawGateMark((GateMark) mark);
}
}
}
/**
* Draw a given mark on canvas
*
* @param singleMark
*/
private void drawSingleMark(SingleMark singleMark) {
double x = abs(singleMark.getLatitude() - 32.313291) * 1000; // to prevent negative longitude
double y = abs(singleMark.getLongitude() + 64.887057) * 1000; // to prevent negative latitude
gc.setFill(Color.BLACK);
gc.fillOval(x, y, 2, 2);
}
/**
* Draw a gate mark which contains two single marks
*
* @param gateMark
*/
private void drawGateMark(GateMark gateMark) {
drawSingleMark(gateMark.getSingleMark1());
drawSingleMark(gateMark.getSingleMark2());
}
}