mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 14:28:43 +00:00
Mostly got boats going to marks on the canvas (code currently broken) #story[377] #pair[zyt10, ptg19]
This commit is contained in:
@@ -10,13 +10,12 @@ public class App extends Application
|
|||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void start(Stage primaryStage) throws Exception {
|
public void start(Stage primaryStage) throws Exception {
|
||||||
System.out.println(getClass().getResource("/RaceView.fxml"));
|
|
||||||
|
|
||||||
Parent root = FXMLLoader.load(getClass().getResource("/RaceView.fxml"));
|
Parent root = FXMLLoader.load(getClass().getResource("/RaceView.fxml"));
|
||||||
primaryStage.setTitle("RaceVision");
|
primaryStage.setTitle("RaceVision");
|
||||||
primaryStage.setScene(new Scene(root));
|
primaryStage.setScene(new Scene(root));
|
||||||
|
|
||||||
seng302.models.OldApp.main(); // Run this to show how positions are updated
|
// seng302.models.OldApp.main(); // Run this to show how positions are updated
|
||||||
|
// seng302.controllers.RaceController.initializeRace();
|
||||||
|
|
||||||
primaryStage.show();
|
primaryStage.show();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,13 @@ import javafx.scene.canvas.Canvas;
|
|||||||
import javafx.scene.canvas.GraphicsContext;
|
import javafx.scene.canvas.GraphicsContext;
|
||||||
import javafx.scene.paint.Color;
|
import javafx.scene.paint.Color;
|
||||||
import javafx.util.Duration;
|
import javafx.util.Duration;
|
||||||
|
import seng302.models.*;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static java.lang.Math.abs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by ptg19 on 15/03/17.
|
* Created by ptg19 on 15/03/17.
|
||||||
@@ -18,19 +25,73 @@ import javafx.util.Duration;
|
|||||||
public class CanvasController {
|
public class CanvasController {
|
||||||
@FXML private Canvas canvas;
|
@FXML private Canvas canvas;
|
||||||
|
|
||||||
|
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
GraphicsContext gc = canvas.getGraphicsContext2D();
|
GraphicsContext gc = canvas.getGraphicsContext2D();
|
||||||
|
gc.scale(5,5);
|
||||||
|
RaceController raceController = new RaceController();
|
||||||
|
raceController.initializeRace();
|
||||||
|
Race race = raceController.getRace();
|
||||||
|
HashMap<Boat, TimelineInfo> timelineInfos = new HashMap<>();
|
||||||
|
|
||||||
|
HashMap<Boat, List> boat_events = race.getEvents();
|
||||||
|
// System.out.println(boat_events);
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
AnimationTimer timer = new AnimationTimer() {
|
||||||
|
@Override
|
||||||
|
public void handle(long now) {
|
||||||
|
GraphicsContext gc = canvas.getGraphicsContext2D();
|
||||||
|
gc.clearRect(0,0,760,360);
|
||||||
|
gc.setFill(Color.FORESTGREEN);
|
||||||
|
for (Boat boat: timelineInfos.keySet()){
|
||||||
|
TimelineInfo timelineInfo = timelineInfos.get(boat);
|
||||||
|
// System.out.println(timelineInfo.getX().doubleValue());
|
||||||
|
// System.out.println(timelineInfo.getY().doubleValue());
|
||||||
|
drawBoat(gc, timelineInfo.getX().doubleValue(), timelineInfo.getY().doubleValue(), boat.getColor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
timer.start();
|
||||||
|
for (TimelineInfo timelineInfo: timelineInfos.values()){
|
||||||
|
Timeline timeline = timelineInfo.getTimeline();
|
||||||
|
timeline.play();
|
||||||
|
}
|
||||||
|
|
||||||
|
// drawBoat(gc, 0, 0, Color.GREEN);
|
||||||
|
// drawBoat(gc, 100, 100, Color.BLUE);
|
||||||
|
// drawBoat(gc, 32.296577, -64.854304, Color.RED);
|
||||||
|
// drawBoat(gc, 32.293771, -64.855242, Color.RED);
|
||||||
|
// drawBoat(gc, 32.317379, -64.839291, Color.GREEN);
|
||||||
|
// drawBoat(gc, 32.317257, -64.836260, Color.GREEN);
|
||||||
|
// drawBoat(gc, 32.313291, -64.887057, Color.YELLOW);
|
||||||
|
|
||||||
|
|
||||||
drawBoat(gc, 0, 0, Color.GREEN);
|
|
||||||
drawBoat(gc, 100, 100, Color.BLUE);
|
|
||||||
drawBoat(gc, 32.296577, -64.854304, Color.RED);
|
|
||||||
drawBoat(gc, 32.293771 , -64.855242, Color.RED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void drawBoat(GraphicsContext gc, double x, double y, Color color) {
|
private void drawBoat(GraphicsContext gc, double x, double y, Color color) {
|
||||||
x += 180; // to prevent negative longtitude
|
x = abs(x - 32.313291) * 1000; // to prevent negative longtitude
|
||||||
y += 90; // to prevent negative latitude
|
y = abs(y + 64.887057) * 1000; // to prevent negative latitude
|
||||||
int diameter = 10;
|
|
||||||
|
// y = abs(y);
|
||||||
|
int diameter = 2;
|
||||||
gc.setFill(color);
|
gc.setFill(color);
|
||||||
gc.fillOval(x, y, diameter, diameter);
|
gc.fillOval(x, y, diameter, diameter);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,92 @@
|
|||||||
|
package seng302.controllers;
|
||||||
|
|
||||||
|
import seng302.models.Boat;
|
||||||
|
import seng302.models.FileParser;
|
||||||
|
import seng302.models.Mark;
|
||||||
|
import seng302.models.Race;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.lang.reflect.Array;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by zyt10 on 17/03/17.
|
||||||
|
* run before CanvasController to initialize race events
|
||||||
|
* the CanvasController then uses the event data to make the animations
|
||||||
|
*/
|
||||||
|
public class RaceController {
|
||||||
|
Race race = null;
|
||||||
|
public void initializeRace() {
|
||||||
|
String raceConfigFile;
|
||||||
|
raceConfigFile = "doc/examples/config.json";
|
||||||
|
|
||||||
|
try {
|
||||||
|
race = createRace(raceConfigFile);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("There was an error creating the race.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (race != null) {
|
||||||
|
race.startRace();
|
||||||
|
} else {
|
||||||
|
System.out.println("There was an error creating the race. Exiting.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Race createRace(String configFile) throws Exception {
|
||||||
|
Race race = new Race();
|
||||||
|
FileParser fp;
|
||||||
|
|
||||||
|
// Read team names from file
|
||||||
|
try{
|
||||||
|
fp = new FileParser(configFile);
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException e){
|
||||||
|
System.out.println("Config file does not exist");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayList<String> boatNames = new ArrayList<>();
|
||||||
|
ArrayList<Map<String, Object>> teams = fp.getTeams();
|
||||||
|
|
||||||
|
//get race size
|
||||||
|
int numberOfBoats = (int) fp.getRaceSize();
|
||||||
|
|
||||||
|
//get time scale
|
||||||
|
double timeScale = fp.getTimeScale();
|
||||||
|
race.setTimeScale(timeScale);
|
||||||
|
|
||||||
|
for (Map<String, Object> team : teams) {
|
||||||
|
boatNames.add((String) team.get("team-name"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shuffle team names
|
||||||
|
long seed = System.nanoTime();
|
||||||
|
Collections.shuffle(boatNames, new Random(seed));
|
||||||
|
|
||||||
|
if (numberOfBoats > Array.getLength(boatNames.toArray())) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add boats to the race
|
||||||
|
for (int i = 0; i < numberOfBoats; i++) {
|
||||||
|
race.addBoat(new Boat(boatNames.get(i), (Double) (teams.get(i).get("velocity"))));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add marks to race in order
|
||||||
|
race.addMark(new Mark("Start", 32.296038,-64.854401 ));
|
||||||
|
race.addMark(new Mark("Mid Mark", 32.292881,-64.843231 ));
|
||||||
|
race.addMark(new Mark("Leeward Gate", 32.283808,-64.850012 ));
|
||||||
|
race.addMark(new Mark("Windward Gate", 32.309908,-64.833665 ));
|
||||||
|
race.addMark(new Mark("Finish", 32.318439,-64.837367 ));
|
||||||
|
|
||||||
|
return race;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Race getRace() {
|
||||||
|
return race;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package seng302.models;
|
package seng302.models;
|
||||||
|
|
||||||
|
import seng302.models.mark.Mark;
|
||||||
import seng302.models.mark.SingleMark;
|
import seng302.models.mark.SingleMark;
|
||||||
|
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
@@ -11,8 +12,8 @@ import java.util.*;
|
|||||||
public class Race {
|
public class Race {
|
||||||
private ArrayList<Boat> boats; // The boats in the race
|
private ArrayList<Boat> boats; // The boats in the race
|
||||||
private ArrayList<Boat> finishingOrder; // The order in which the boats finish the race
|
private ArrayList<Boat> finishingOrder; // The order in which the boats finish the race
|
||||||
private PriorityQueue<Event> events; // The events that occur in the race
|
private HashMap<Boat, List> events = new HashMap<>(); // The events that occur in the race
|
||||||
private ArrayList<SingleMark> singleMarks; // Marks in the race
|
private ArrayList<Mark> marks; // Marks in the race
|
||||||
private int numberOfBoats = 0;
|
private int numberOfBoats = 0;
|
||||||
private long startTime = 0;
|
private long startTime = 0;
|
||||||
private double timeScale = 1;
|
private double timeScale = 1;
|
||||||
@@ -23,24 +24,24 @@ public class Race {
|
|||||||
public Race() {
|
public Race() {
|
||||||
this.boats = new ArrayList<Boat>();
|
this.boats = new ArrayList<Boat>();
|
||||||
this.finishingOrder = new ArrayList<Boat>();
|
this.finishingOrder = new ArrayList<Boat>();
|
||||||
this.singleMarks = new ArrayList<SingleMark>();
|
this.marks = new ArrayList<Mark>();
|
||||||
|
|
||||||
// create a priority queue with a custom Comparator to order events
|
// create a priority queue with a custom Comparator to order events
|
||||||
this.events = new PriorityQueue<Event>(new Comparator<Event>() {
|
// this.events = new PriorityQueue<Event>(new Comparator<Event>() {
|
||||||
@Override
|
// @Override
|
||||||
public int compare(Event o1, Event o2) {
|
// public int compare(Event o1, Event o2) {
|
||||||
Double time1 = o1.getTime();
|
// Double time1 = o1.getTime();
|
||||||
Double time2 = o2.getTime();
|
// Double time2 = o2.getTime();
|
||||||
|
//
|
||||||
// order event asc. by time. if tie appears, then order team
|
// // order event asc. by time. if tie appears, then order team
|
||||||
// name alphabetically.
|
// // name alphabetically.
|
||||||
if (time1 != time2) {
|
// if (time1 != time2) {
|
||||||
return time1.compareTo(time2);
|
// return time1.compareTo(time2);
|
||||||
} else {
|
// } else {
|
||||||
return o1.getBoat().getTeamName().compareTo(o2.getBoat().getTeamName());
|
// return o1.getBoat().getTeamName().compareTo(o2.getBoat().getTeamName());
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -142,23 +143,28 @@ public class Race {
|
|||||||
|
|
||||||
for (Boat boat : this.boats) {
|
for (Boat boat : this.boats) {
|
||||||
double totalDistance = 0;
|
double totalDistance = 0;
|
||||||
int numberOfMarks = this.singleMarks.size();
|
int numberOfMarks = this.marks.size();
|
||||||
|
|
||||||
for(int i = 0; i < numberOfMarks; i++){
|
for(int i = 0; i < numberOfMarks; i++){
|
||||||
Double time = (Double) (1000 * totalDistance / boat.getVelocity());
|
Double time = (Double) (1000 * totalDistance / boat.getVelocity());
|
||||||
|
|
||||||
// If there are singleMarks after this event
|
// If there are singleMarks after this event
|
||||||
if (i < numberOfMarks-1) {
|
if (i < numberOfMarks-1) {
|
||||||
Event event = new Event(time, boat, singleMarks.get(i), singleMarks.get(i + 1));
|
Event event = new Event(time, boat, marks.get(i), marks.get(i + 1));
|
||||||
events.add(event);
|
|
||||||
totalDistance += event.getDistanceBetweenMarks();
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
events.get(boat).add(event);
|
||||||
|
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
events.put(boat, new ArrayList<Event>(Arrays.asList(event)));
|
||||||
}
|
}
|
||||||
// There are no more singleMarks after this event
|
totalDistance += event.getDistanceBetweenMarks();
|
||||||
else{
|
|
||||||
Event event = new Event(time, boat, singleMarks.get(i));
|
|
||||||
events.add(event);
|
|
||||||
}
|
}
|
||||||
|
// There are no more marks after this event
|
||||||
|
// else{
|
||||||
|
// Event event = new Event(time, boat, marks.get(i));
|
||||||
|
// events.put(boat, new ArrayList<Event>(Arrays.asList(event)));
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -179,40 +185,40 @@ public class Race {
|
|||||||
* Iterate over events in the race and print the
|
* Iterate over events in the race and print the
|
||||||
* event string for each event
|
* event string for each event
|
||||||
*/
|
*/
|
||||||
public void iterateEvents() {
|
// public void iterateEvents() {
|
||||||
// iterates all events. ends when no event in events.
|
// // iterates all events. ends when no event in events.
|
||||||
|
//
|
||||||
while (!events.isEmpty()) {
|
// while (!events.isEmpty()) {
|
||||||
Event peekEvent = events.peek();
|
// Event peekEvent = events.peek();
|
||||||
long currentTime = (long) ((System.currentTimeMillis() - this.startTime) * this.timeScale);
|
// long currentTime = (long) ((System.currentTimeMillis() - this.startTime) * this.timeScale);
|
||||||
|
//
|
||||||
if (currentTime > peekEvent.getTime()) {
|
// if (currentTime > peekEvent.getTime()) {
|
||||||
Event nextEvent = events.poll();
|
// Event nextEvent = events.poll();
|
||||||
|
//
|
||||||
// Display a summary of the event
|
// // Display a summary of the event
|
||||||
System.out.println(nextEvent.getEventString());
|
// System.out.println(nextEvent.getEventString());
|
||||||
|
//
|
||||||
// Display latitude and longitude
|
// // Display latitude and longitude
|
||||||
if (!nextEvent.getIsFinishingEvent()){
|
// if (!nextEvent.getIsFinishingEvent()){
|
||||||
System.out.println(nextEvent.getMark().getLatitude() + ", " + nextEvent.getNextMark().getLongitude());
|
// System.out.println(nextEvent.getMark().getLatitude() + ", " + nextEvent.getNextMark().getLongitude());
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
System.out.println();
|
// System.out.println();
|
||||||
|
//
|
||||||
// If event is a boat finishing the race
|
// // If event is a boat finishing the race
|
||||||
if (nextEvent.getIsFinishingEvent()) {
|
// if (nextEvent.getIsFinishingEvent()) {
|
||||||
this.finishingOrder.add(nextEvent.getBoat());
|
// this.finishingOrder.add(nextEvent.getBoat());
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// Wait for 100ms to throttle the while loop
|
// // Wait for 100ms to throttle the while loop
|
||||||
try {
|
// try {
|
||||||
Thread.sleep(100);
|
// Thread.sleep(100);
|
||||||
} catch (java.lang.InterruptedException e) {
|
// } catch (java.lang.InterruptedException e) {
|
||||||
continue;
|
// continue;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start the race and print each marker with the order
|
* Start the race and print each marker with the order
|
||||||
@@ -221,8 +227,8 @@ public class Race {
|
|||||||
public void startRace() {
|
public void startRace() {
|
||||||
// record start time.
|
// record start time.
|
||||||
generateEvents();
|
generateEvents();
|
||||||
this.startTime = System.currentTimeMillis();
|
// this.startTime = System.currentTimeMillis();
|
||||||
iterateEvents();
|
// iterateEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -230,6 +236,10 @@ public class Race {
|
|||||||
* @param singleMark, the singleMark to add
|
* @param singleMark, the singleMark to add
|
||||||
*/
|
*/
|
||||||
public void addMark(SingleMark singleMark){
|
public void addMark(SingleMark singleMark){
|
||||||
this.singleMarks.add(singleMark);
|
this.marks.add(singleMark);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HashMap<Boat, List> getEvents() {
|
||||||
|
return events;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package seng302.models;
|
||||||
|
|
||||||
|
import javafx.animation.Timeline;
|
||||||
|
import javafx.beans.property.DoubleProperty;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by zyt10 on 17/03/17.
|
||||||
|
* this class is literally just to associate a timeline with a DoubleProperty x and y
|
||||||
|
*/
|
||||||
|
public class TimelineInfo {
|
||||||
|
private Timeline timeline;
|
||||||
|
private DoubleProperty x;
|
||||||
|
private DoubleProperty y;
|
||||||
|
|
||||||
|
public TimelineInfo(Timeline timeline, DoubleProperty x, DoubleProperty y) {
|
||||||
|
this.timeline = timeline;
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Timeline getTimeline() {
|
||||||
|
return timeline;
|
||||||
|
}
|
||||||
|
public DoubleProperty getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
public DoubleProperty getY() {
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user