diff --git a/racevisionGame/src/main/java/mock/model/MockBoat.java b/racevisionGame/src/main/java/mock/model/MockBoat.java index 104fa264..24c94531 100644 --- a/racevisionGame/src/main/java/mock/model/MockBoat.java +++ b/racevisionGame/src/main/java/mock/model/MockBoat.java @@ -1,6 +1,8 @@ package mock.model; +import mock.model.collider.Collider; +import mock.model.collider.Collision; import shared.model.*; @@ -8,7 +10,7 @@ import shared.model.*; * Represents a Boat on the mock side of a race. * This adds mock specific functionality to a boat. */ -public class MockBoat extends Boat { +public class MockBoat extends Boat implements Collider { /** @@ -203,4 +205,19 @@ public class MockBoat extends Boat { public void setAutoVMG(boolean autoVMG) { this.autoVMG = autoVMG; } + + @Override + public boolean rayCast(MockBoat boat) { + double distance = GPSCoordinate.calculateDistanceMeters(boat.getCurrentPosition(), this.getCurrentPosition()); + Bearing bearing = Bearing.fromAzimuth(GPSCoordinate.calculateAzimuth(boat.getCurrentPosition(), this.getCurrentPosition())); + if(distance < 100 && boat != this) { + onCollisionEnter(new Collision(bearing, distance)); + return true; + } else return false; + } + + @Override + public void onCollisionEnter(Collision e) { + System.out.println(e.getBearing().degrees()); + } } diff --git a/racevisionGame/src/main/java/mock/model/MockRace.java b/racevisionGame/src/main/java/mock/model/MockRace.java index 0ae5cfcc..9d03ff14 100644 --- a/racevisionGame/src/main/java/mock/model/MockRace.java +++ b/racevisionGame/src/main/java/mock/model/MockRace.java @@ -1,5 +1,6 @@ package mock.model; +import mock.model.collider.ColliderRegistry; import network.Messages.Enums.BoatStatusEnum; import network.Messages.LatestMessages; import org.opengis.geometry.primitive.*; @@ -30,8 +31,6 @@ public class MockRace extends Race { */ private List boats; - - /** * A copy of the boundary list, except "shrunk" inwards by 50m. */ @@ -79,6 +78,8 @@ public class MockRace extends Race { //Wind. this.setWind(windGenerator.generateBaselineWind()); + + this.colliderRegistry.addAllColliders(boats); } /** diff --git a/racevisionGame/src/main/java/mock/model/RaceLogic.java b/racevisionGame/src/main/java/mock/model/RaceLogic.java index adc0fe37..42265646 100644 --- a/racevisionGame/src/main/java/mock/model/RaceLogic.java +++ b/racevisionGame/src/main/java/mock/model/RaceLogic.java @@ -1,7 +1,6 @@ package mock.model; import javafx.animation.AnimationTimer; -import mock.model.commandFactory.Command; import mock.model.commandFactory.CommandFactory; import mock.model.commandFactory.CompositeCommand; import network.Messages.Enums.BoatActionEnum; @@ -12,7 +11,6 @@ import visualiser.gameController.ControllerServer; import java.util.Observable; import java.util.Observer; -import java.util.Stack; public class RaceLogic implements Observer, Runnable { /** @@ -136,7 +134,7 @@ public class RaceLogic implements Observer, Runnable { if (boat.getStatus() == BoatStatusEnum.RACING) { commands.execute(); race.updatePosition(boat, framePeriod, race.getRaceClock().getDurationMilli()); - + race.getColliderRegistry().rayCast(boat); } } diff --git a/racevisionGame/src/main/java/mock/model/collider/Collider.java b/racevisionGame/src/main/java/mock/model/collider/Collider.java index ae11d063..a443d3f9 100644 --- a/racevisionGame/src/main/java/mock/model/collider/Collider.java +++ b/racevisionGame/src/main/java/mock/model/collider/Collider.java @@ -9,10 +9,9 @@ public interface Collider { /** * Indicates whether a ray cast from a boat to a target collider triggers a collision. * @param boat potentially colliding with target - * @param collision details of potential collision * @return whether or not a collision has occurred */ - boolean rayCast(MockBoat boat, Collision collision); + boolean rayCast(MockBoat boat); /** * Handle a collision event diff --git a/racevisionGame/src/main/java/mock/model/collider/ColliderRegistry.java b/racevisionGame/src/main/java/mock/model/collider/ColliderRegistry.java index e44ef5e1..e58a28f1 100644 --- a/racevisionGame/src/main/java/mock/model/collider/ColliderRegistry.java +++ b/racevisionGame/src/main/java/mock/model/collider/ColliderRegistry.java @@ -3,6 +3,7 @@ package mock.model.collider; import mock.model.MockBoat; import java.util.ArrayList; +import java.util.Collection; import java.util.List; /** @@ -29,10 +30,14 @@ public class ColliderRegistry implements Collider { colliders.remove(collider); } + public void addAllColliders(Collection colliders) { + for(Collider collider: colliders) addCollider(collider); + } + @Override - public boolean rayCast(MockBoat boat, Collision collision) { + public boolean rayCast(MockBoat boat) { for(Collider collider: colliders) { - if(collider.rayCast(boat, collision)) return true; + if(collider.rayCast(boat)) return true; } return false; } diff --git a/racevisionGame/src/main/java/shared/model/CompoundMark.java b/racevisionGame/src/main/java/shared/model/CompoundMark.java index b9f45753..f8080c8d 100644 --- a/racevisionGame/src/main/java/shared/model/CompoundMark.java +++ b/racevisionGame/src/main/java/shared/model/CompoundMark.java @@ -1,10 +1,19 @@ package shared.model; +import mock.model.MockBoat; +import mock.model.collider.Collider; +import mock.model.collider.Collision; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + /** * Represents a compound mark - that is, either one or two individual marks which form a single compound mark. */ -public class CompoundMark { +public class CompoundMark implements Collider { /** * The ID of the compound mark. @@ -110,7 +119,7 @@ public class CompoundMark { * @return The position of the second mark in the compound mark. */ public GPSCoordinate getMark2Position() { - return mark2.getPosition(); + return mark2 == null? mark1.getPosition() : mark2.getPosition(); } @@ -128,17 +137,32 @@ public class CompoundMark { * @return The average coordinate of the compound mark. */ private GPSCoordinate calculateAverage() { - - //If the compound mark only contains one mark, the average is simply the first mark's position. - if (this.mark2 == null) { - return this.getMark1Position(); - } - - //Otherwise, calculate the average of both marks. GPSCoordinate averageCoordinate = GPSCoordinate.calculateAverageCoordinate(this.getMark1Position(), this.getMark2Position()); return averageCoordinate; } + + private Mark closestMark(GPSCoordinate coordinate) { + double mark1distance = GPSCoordinate.calculateDistanceMeters(getMark1Position(), coordinate); + double mark2distance = GPSCoordinate.calculateDistanceMeters(getMark2Position(), coordinate); + return mark1distance <= mark2distance? mark1 : mark2; + } + + @Override + public boolean rayCast(MockBoat boat) { + GPSCoordinate position = boat.getCurrentPosition(); + double distance = GPSCoordinate.calculateDistanceMeters(position, closestMark(position).getPosition()); + Bearing bearing = Bearing.fromAzimuth(GPSCoordinate.calculateAzimuth(position, closestMark(position).getPosition())); + if(distance < 100) { + onCollisionEnter(new Collision(bearing, distance)); + return true; + } else return false; + } + + @Override + public void onCollisionEnter(Collision e) { + System.out.println(e.getBearing().degrees()); + } } diff --git a/racevisionGame/src/main/java/shared/model/Race.java b/racevisionGame/src/main/java/shared/model/Race.java index f9fc984e..00b6eaf0 100644 --- a/racevisionGame/src/main/java/shared/model/Race.java +++ b/racevisionGame/src/main/java/shared/model/Race.java @@ -4,6 +4,7 @@ import javafx.beans.property.IntegerProperty; import javafx.beans.property.Property; import javafx.beans.property.SimpleIntegerProperty; import javafx.beans.property.SimpleObjectProperty; +import mock.model.collider.ColliderRegistry; import network.Messages.Enums.RaceStatusEnum; import network.Messages.Enums.RaceTypeEnum; import network.Messages.LatestMessages; @@ -20,90 +21,72 @@ import java.util.List; * Has a course, state, wind, boundaries, etc.... Boats are added by inheriting classes (see {@link Boat}, {@link mock.model.MockBoat}, {@link visualiser.model.VisualiserBoat}. */ public abstract class Race { - - /** * The source of race related data. */ protected RaceDataSource raceDataSource; - /** * The source of boat related data. */ protected BoatDataSource boatDataSource; - /** * The source of regatta related data. */ protected RegattaDataSource regattaDataSource; - /** * The collection of latest race messages. * Can be either read from or written to. */ protected LatestMessages latestMessages; - /** * A list of compound marks in the race. */ protected List compoundMarks; - /** * A list of legs in the race. */ protected List legs; - /** * A list of coordinates describing the boundary of the course. */ protected List boundary; - - - /** * The clock which tracks the race's start time, current time, and elapsed duration. */ protected RaceClock raceClock; - - /** * The race ID of the course. */ protected int raceId; - /** * The name of the regatta. */ protected String regattaName; - /** * The current status of the race. */ protected RaceStatusEnum raceStatusEnum; - /** * The type of race this is. */ protected RaceTypeEnum raceType; - - /** * The race's wind. */ protected Property raceWind = new SimpleObjectProperty<>(); - - + /** + * Registry for all collider object in this race + */ + protected ColliderRegistry colliderRegistry; /** * The number of frames per second. * We essentially track the number of frames generated per second, over a one second period. When {@link #lastFpsResetTime} reaches 1 second, {@link #currentFps} is reset. */ private int currentFps = 0; - /** * The number of frames per second we generated over the last 1 second period. */ private IntegerProperty lastFps = new SimpleIntegerProperty(0); - /** * The time, in milliseconds, since we last reset our {@link #currentFps} counter. */ @@ -156,9 +139,13 @@ public abstract class Race { //Wind. this.setWind(Bearing.fromDegrees(0), 0); + this.colliderRegistry = new ColliderRegistry(); + this.colliderRegistry.addAllColliders(compoundMarks); } - + public ColliderRegistry getColliderRegistry() { + return colliderRegistry; + } /** * Initialise the boats in the race. @@ -272,14 +259,6 @@ public abstract class Race { return raceWind.getValue().getWindSpeed(); } - /** - * Returns the race's wind. - * @return The race's wind. - */ - public Property windProperty() { - return raceWind; - } - /** * Returns the RaceClock for this race. * This is used to track the start time, current time, and elapsed duration of the race.