mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 14:28:43 +00:00
Fixed and enables the old wakes. Enabled the fps counter by implementing the team-27s fps counter from their code, fixed trails from starting at the start of the startline no matter at what point in the race the stream is connected to (this is means the map starts a lot cleaner). Added live tracked speeds which are taken from the boat location packet. Linked the speeds coming in to their specified boats and allowed the onscreen speed tracker to keep up with the speeds. Linked the current speeds to the wakes so the wakes are redrawn for each change in speed and size to match the speed. Also added the toggle functionality back to the fps counter so they can be toggled on an off.
#story[818]
This commit is contained in:
@@ -22,6 +22,7 @@ import seng302.models.parsers.StreamParser;
|
||||
import seng302.models.parsers.StreamReceiver;
|
||||
|
||||
import java.sql.Time;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
@@ -59,6 +60,13 @@ public class CanvasController {
|
||||
private double metersToPixels;
|
||||
private List<RaceObject> raceObjects = new ArrayList<>();
|
||||
|
||||
//FRAME RATE
|
||||
private static final double UPDATE_TIME = 0.016666; // 1 / 60 ie 60fps
|
||||
private final long[] frameTimes = new long[30];
|
||||
private int frameTimeIndex = 0;
|
||||
private boolean arrayFilled = false;
|
||||
private DecimalFormat decimalFormat2dp = new DecimalFormat("0.00");
|
||||
|
||||
public AnimationTimer timer;
|
||||
|
||||
private enum ScaleDirection {
|
||||
@@ -138,6 +146,8 @@ public class CanvasController {
|
||||
|
||||
|
||||
timer = new AnimationTimer() {
|
||||
|
||||
|
||||
private int countdown = 60;
|
||||
private int[] currentRaceMarker = {1, 1, 1, 1, 1, 1};
|
||||
List<Mark> marks = raceViewController.getRace().getCourse();
|
||||
@@ -150,6 +160,20 @@ public class CanvasController {
|
||||
int boatIndex = 0;
|
||||
|
||||
Mark nextMark;
|
||||
|
||||
long oldFrameTime = frameTimes[frameTimeIndex] ;
|
||||
frameTimes[frameTimeIndex] = now ;
|
||||
frameTimeIndex = (frameTimeIndex + 1) % frameTimes.length ;
|
||||
if (frameTimeIndex == 0) {
|
||||
arrayFilled = true ;
|
||||
}
|
||||
if (arrayFilled) {
|
||||
long elapsedNanos = now - oldFrameTime ;
|
||||
long elapsedNanosPerFrame = elapsedNanos / frameTimes.length ;
|
||||
Double frameRate = 1_000_000_000.0 / elapsedNanosPerFrame ;
|
||||
drawFps(frameRate.intValue());
|
||||
}
|
||||
|
||||
//if (countdown == 0) {
|
||||
//System.out.println("called the at");
|
||||
for (RaceObject raceObject : raceObjects) {
|
||||
@@ -163,8 +187,6 @@ public class CanvasController {
|
||||
|
||||
//descending = nextMark.getY() > boatGroup.getLayoutY();
|
||||
//leftToRight = nextMark.getX() < boatGroup.getLayoutX();
|
||||
|
||||
|
||||
raceObject.updatePosition(1000 / 60);
|
||||
for (int id : raceObject.getRaceIds()) {
|
||||
//System.out.println("id = " + id);
|
||||
@@ -285,10 +307,15 @@ public class CanvasController {
|
||||
|
||||
private void drawFps(int fps){
|
||||
if (raceViewController.isDisplayFps()){
|
||||
gc.clearRect(5,5,50,20);
|
||||
gc.setFill(Color.BLACK);
|
||||
gc.setFont(new Font(14));
|
||||
gc.setLineWidth(3);
|
||||
gc.fillText(fps + " FPS", 5, 20);
|
||||
} else {
|
||||
gc.clearRect(5,5,50,20);
|
||||
gc.setFill(Color.SKYBLUE);
|
||||
gc.fillRect(4,4,51,21);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -307,7 +334,7 @@ public class CanvasController {
|
||||
for (Boat boat : boats) {
|
||||
BoatGroup boatGroup = new BoatGroup(boat, Colors.getColor());
|
||||
boatGroup.moveTo(startingX, startingY, 0d);
|
||||
boatGroup.setDestination(firstMarkX, firstMarkY);
|
||||
// boatGroup.setDestination(firstMarkX, firstMarkY);
|
||||
boatGroup.forceRotation();
|
||||
group.getChildren().add(boatGroup);
|
||||
raceObjects.add(boatGroup);
|
||||
|
||||
@@ -5,6 +5,7 @@ import javafx.animation.KeyFrame;
|
||||
import javafx.animation.Timeline;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.control.CheckBox;
|
||||
|
||||
@@ -140,4 +140,5 @@ public class Boat {
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import javafx.scene.shape.Polygon;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.scene.transform.Rotate;
|
||||
import javafx.scene.transform.Translate;
|
||||
import seng302.models.parsers.StreamParser;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -28,6 +29,7 @@ public class BoatGroup extends RaceObject{
|
||||
private static double expectedUpdateInterval = 200;
|
||||
private static int WAKE_FRAME_INTERVAL = 30;
|
||||
private double framesForNewLine = 0;
|
||||
private boolean destinationSet;
|
||||
private Point2D lastPoint;
|
||||
|
||||
private Boat boat;
|
||||
@@ -35,7 +37,7 @@ public class BoatGroup extends RaceObject{
|
||||
private List<Wake> wakes = new ArrayList<>();
|
||||
private List<Line> lines = new ArrayList<>();
|
||||
private Polygon boatPoly;
|
||||
// private Polygon wakePoly;
|
||||
private Polygon wakePoly;
|
||||
private Text teamNameObject;
|
||||
private Text velocityObject;
|
||||
|
||||
@@ -56,12 +58,12 @@ public class BoatGroup extends RaceObject{
|
||||
// boatPoly.setLayoutY(0);
|
||||
// boatPoly.relocate(boatPoly.getLayoutX(), boatPoly.getLayoutY());
|
||||
//
|
||||
// wakePoly = new Polygon(
|
||||
// 5.0,0.0,
|
||||
// 10.0, boat.getVelocity() * VELOCITY_WAKE_RATIO,
|
||||
// 0.0, boat.getVelocity() * VELOCITY_WAKE_RATIO
|
||||
// );
|
||||
// wakePoly.setFill(Color.DARKBLUE);
|
||||
wakePoly = new Polygon(
|
||||
5.0,0.0,
|
||||
10.0, boat.getVelocity() * VELOCITY_WAKE_RATIO,
|
||||
0.0, boat.getVelocity() * VELOCITY_WAKE_RATIO
|
||||
);
|
||||
wakePoly.setFill(Color.DARKBLUE);
|
||||
|
||||
teamNameObject = new Text(boat.getShortName());
|
||||
velocityObject = new Text(String.valueOf(boat.getVelocity()));
|
||||
@@ -73,9 +75,8 @@ public class BoatGroup extends RaceObject{
|
||||
velocityObject.setX(VELOCITY_X_OFFSET);
|
||||
velocityObject.setY(VELOCITY_Y_OFFSET);
|
||||
velocityObject.relocate(velocityObject.getX(), velocityObject.getY());
|
||||
|
||||
// super.getChildren().addAll(wakePoly, boatPoly, teamNameObject, velocityObject);
|
||||
super.getChildren().addAll(teamNameObject, velocityObject, boatPoly);
|
||||
destinationSet = false;
|
||||
super.getChildren().addAll(wakePoly, boatPoly, teamNameObject, velocityObject);
|
||||
}
|
||||
|
||||
private void initChildren (Color color) {
|
||||
@@ -97,8 +98,8 @@ public class BoatGroup extends RaceObject{
|
||||
teamNameObject.setLayoutY(teamNameObject.getLayoutY() + dy);
|
||||
velocityObject.setLayoutX(velocityObject.getLayoutX() + dx);
|
||||
velocityObject.setLayoutY(velocityObject.getLayoutY() + dy);
|
||||
// wakePoly.setLayoutX(wakePoly.getLayoutX() + dx);
|
||||
// wakePoly.setLayoutY(wakePoly.getLayoutY() + dy);
|
||||
wakePoly.setLayoutX(wakePoly.getLayoutX() + dx);
|
||||
wakePoly.setLayoutY(wakePoly.getLayoutY() + dy);
|
||||
rotateTo(currentRotation);
|
||||
}
|
||||
|
||||
@@ -119,8 +120,8 @@ public class BoatGroup extends RaceObject{
|
||||
teamNameObject.setLayoutY(y);
|
||||
velocityObject.setLayoutX(x);
|
||||
velocityObject.setLayoutY(y);
|
||||
// wakePoly.setLayoutX(x);
|
||||
// wakePoly.setLayoutY(y);
|
||||
wakePoly.setLayoutX(x);
|
||||
wakePoly.setLayoutY(y);
|
||||
}
|
||||
|
||||
public void updatePosition (double timeInterval) {
|
||||
@@ -158,9 +159,8 @@ public class BoatGroup extends RaceObject{
|
||||
boatPoly.getLayoutX(),
|
||||
boatPoly.getLayoutY(),
|
||||
pixelVelocityX,
|
||||
pixelVelocityY, rotation);
|
||||
// wake.getTransforms().clear();
|
||||
// wake.getTransforms().add(new Rotate(rotation, 0, 0));
|
||||
pixelVelocityY,
|
||||
rotation);
|
||||
super.getChildren().add(wake);
|
||||
wakes.add(wake);
|
||||
}
|
||||
@@ -174,13 +174,18 @@ public class BoatGroup extends RaceObject{
|
||||
lines.add(l);
|
||||
super.getChildren().add(l);
|
||||
}
|
||||
lastPoint = new Point2D(boatPoly.getLayoutX(), boatPoly.getLayoutY());
|
||||
if (destinationSet){
|
||||
lastPoint = new Point2D(boatPoly.getLayoutX(), boatPoly.getLayoutY());
|
||||
}
|
||||
}
|
||||
framesForNewLine -= 1;
|
||||
}
|
||||
|
||||
public void setDestination (double newXValue, double newYValue, double rotation, int... raceIds) {
|
||||
//System.out.println("MADE IT");
|
||||
destinationSet = true;
|
||||
boat.setVelocity(StreamParser.boatSpeeds.get((long)boat.getId()));
|
||||
resizeWake();
|
||||
if (hasRaceId(raceIds)) {
|
||||
this.pixelVelocityX = (newXValue - boatPoly.getLayoutX()) / expectedUpdateInterval;
|
||||
this.pixelVelocityY = (newYValue - boatPoly.getLayoutY()) / expectedUpdateInterval;
|
||||
@@ -191,6 +196,8 @@ public class BoatGroup extends RaceObject{
|
||||
}
|
||||
|
||||
public void setDestination (double newXValue, double newYValue, int... raceIDs) {
|
||||
destinationSet = true;
|
||||
|
||||
if (hasRaceId(raceIDs)) {
|
||||
double rotation = Math.abs(
|
||||
Math.toDegrees(
|
||||
@@ -212,16 +219,34 @@ public class BoatGroup extends RaceObject{
|
||||
}
|
||||
}
|
||||
|
||||
void resizeWake(){
|
||||
velocityObject.setText(String.valueOf(boat.getVelocity()));
|
||||
super.getChildren().remove(wakePoly);
|
||||
wakePoly = new Polygon(
|
||||
5.0,0.0,
|
||||
10.0, boat.getVelocity() * VELOCITY_WAKE_RATIO,
|
||||
0.0, boat.getVelocity() * VELOCITY_WAKE_RATIO
|
||||
);
|
||||
wakePoly.setLayoutX(boatPoly.getLayoutX());
|
||||
wakePoly.setLayoutY(boatPoly.getLayoutY());
|
||||
wakePoly.setFill(Color.DARKBLUE);
|
||||
super.getChildren().add(wakePoly);
|
||||
|
||||
}
|
||||
|
||||
public void rotateTo (double rotation) {
|
||||
if(rotation != 0) {
|
||||
rotationalGoal = rotation;
|
||||
boatPoly.getTransforms().clear();
|
||||
boatPoly.getTransforms().add(new Rotate(rotation, BOAT_WIDTH / 2, 0));
|
||||
wakePoly.getTransforms().clear();
|
||||
wakePoly.getTransforms().add(new Translate(0, BOAT_HEIGHT));
|
||||
wakePoly.getTransforms().add(new Rotate(rotation, BOAT_WIDTH/2, -BOAT_HEIGHT));
|
||||
}
|
||||
// wakePoly.getTransforms().clear();
|
||||
// wakePoly.getTransforms().add(new Rotate(rotation, 0, 0));
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void forceRotation () {
|
||||
rotateTo (rotationalGoal);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ class Wake extends Arc {
|
||||
super.setType(ArcType.OPEN);
|
||||
super.setFill(new Color(0, 0, 0 ,0));
|
||||
super.setStrokeWidth(2.0);
|
||||
super.getTransforms().add(new Rotate(rotation, 5, -15));
|
||||
super.getTransforms().add(new Rotate(rotation - 270, startingX + 20, startingY + 20));
|
||||
// this.velocityX = -velocityX;
|
||||
// this.velocityY = -velocityY;
|
||||
this.velocityX = 0;
|
||||
|
||||
@@ -14,6 +14,8 @@ import javax.xml.parsers.ParserConfigurationException;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
@@ -25,6 +27,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
public class StreamParser extends Thread{
|
||||
|
||||
public static ConcurrentHashMap<Long,Point3D> boatPositions = new ConcurrentHashMap<>();
|
||||
public static ConcurrentHashMap<Long,Double> boatSpeeds = new ConcurrentHashMap<>();
|
||||
private static ArrayList<Long> boat_IDS = new ArrayList<>();
|
||||
private String threadName;
|
||||
private Thread t;
|
||||
@@ -253,6 +256,8 @@ public class StreamParser extends Thread{
|
||||
byte[] lonBytes = Arrays.copyOfRange(payload,20,24);
|
||||
byte[] boatIdBytes = Arrays.copyOfRange(payload,7,11);
|
||||
byte[] headingBytes = Arrays.copyOfRange(payload,28,30);
|
||||
byte[] speedBytes = Arrays.copyOfRange(payload,38,40);
|
||||
|
||||
long timeStamp = extractTimeStamp(Arrays.copyOfRange(payload,1,7), 6);
|
||||
// int boatSeq = ByteBuffer.wrap(seqBytes).getInt();
|
||||
long seq = bytesToLong(seqBytes);
|
||||
@@ -260,7 +265,13 @@ public class StreamParser extends Thread{
|
||||
long lat = bytesToLong(latBytes);
|
||||
long lon = bytesToLong(lonBytes);
|
||||
long heading = bytesToLong(headingBytes);
|
||||
|
||||
// long speed = extractTimeStamp(speedBytes, 2);
|
||||
ByteBuffer bb = ByteBuffer.allocate(2);
|
||||
bb.order(ByteOrder.LITTLE_ENDIAN);
|
||||
bb.put(speedBytes[0]);
|
||||
bb.put(speedBytes[1]);
|
||||
double speed = bb.getShort(0)/1000.0;
|
||||
short s = (short) ((speedBytes[1] & 0xFF) << 8 | (speedBytes[0] & 0xFF));
|
||||
if ((int)deviceType == 1 || (int)deviceType == 4){
|
||||
// System.out.println("boatId = " + boatId);
|
||||
// System.out.println("deviceType = " + (long)deviceType);
|
||||
@@ -268,13 +279,16 @@ public class StreamParser extends Thread{
|
||||
//needs to be validated
|
||||
Point3D point = new Point3D(((180d * (double)lat)/Math.pow(2,31)),((180d *(double)lon)/Math.pow(2,31)),(double)heading);
|
||||
boatPositions.putIfAbsent(boatId, point);
|
||||
boatSpeeds.putIfAbsent(boatId, speed);
|
||||
boatPositions.replace(boatId, point);
|
||||
boatSpeeds.replace(boatId, speed);
|
||||
// System.out.println("lon = " + ((180d * (double)lon)/Math.pow(2,31)));
|
||||
// System.out.println("lat = " + ((180d *(double)lat)/Math.pow(2,31)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static void extractMarkRounding(StreamPacket packet){
|
||||
byte[] payload = packet.getPayload();
|
||||
int messageVersionNo = payload[0];
|
||||
|
||||
@@ -4,37 +4,37 @@
|
||||
<team>
|
||||
<name>Oracle Team USA</name>
|
||||
<alias>USA</alias>
|
||||
<velocity>12.9</velocity>
|
||||
<velocity>0.0</velocity>
|
||||
<id>102</id>
|
||||
</team>
|
||||
<team>
|
||||
<name>Artemis Racing</name>
|
||||
<alias>ART</alias>
|
||||
<velocity>13.1</velocity>
|
||||
<velocity>0.0</velocity>
|
||||
<id>101</id>
|
||||
</team>
|
||||
<team>
|
||||
<name>Emirates Team New Zealand</name>
|
||||
<alias>NZL</alias>
|
||||
<velocity>15.6</velocity>
|
||||
<velocity>0.0</velocity>
|
||||
<id>103</id>
|
||||
</team>
|
||||
<team>
|
||||
<name>Land Rover BAR</name>
|
||||
<alias>BAR</alias>
|
||||
<velocity>13.3</velocity>
|
||||
<velocity>0.0</velocity>
|
||||
<id>104</id>
|
||||
</team>
|
||||
<team>
|
||||
<name>SoftBank Team Japan</name>
|
||||
<alias>JAP</alias>
|
||||
<velocity>14.7</velocity>
|
||||
<velocity>0.0</velocity>
|
||||
<id>105</id>
|
||||
</team>
|
||||
<team>
|
||||
<name>Groupama Team France</name>
|
||||
<alias>FRC</alias>
|
||||
<velocity>11.4</velocity>
|
||||
<velocity>0.0</velocity>
|
||||
<id>106</id>
|
||||
</team>
|
||||
</teams>
|
||||
@@ -1,15 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.text.*?>
|
||||
<?import javafx.scene.shape.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import java.lang.*?>
|
||||
<?import javafx.scene.canvas.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.canvas.Canvas?>
|
||||
<?import javafx.scene.control.CheckBox?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.layout.ColumnConstraints?>
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.scene.layout.Pane?>
|
||||
<?import javafx.scene.layout.RowConstraints?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.shape.Circle?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
<?import javafx.scene.text.Text?>
|
||||
|
||||
<GridPane prefHeight="1080.0" prefWidth="1920.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.controllers.RaceViewController">
|
||||
<GridPane prefHeight="1080.0" prefWidth="1920.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.controllers.RaceViewController">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints maxWidth="246.0" minWidth="246.0" prefWidth="246.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="1034.0" />
|
||||
|
||||
Reference in New Issue
Block a user