Created ray casting methods for MockBoat and CompoundMark

- Added ColliderRegistry to Race
- Added collision triggering to RaceLogic
- Created basic collision handlers for MockBoat and CompoundMark
main
cbt24 9 years ago
parent 7474de9816
commit 2fbb96afd7

@ -1,6 +1,8 @@
package mock.model; package mock.model;
import mock.model.collider.Collider;
import mock.model.collider.Collision;
import shared.model.*; import shared.model.*;
@ -8,7 +10,7 @@ import shared.model.*;
* Represents a Boat on the mock side of a race. * Represents a Boat on the mock side of a race.
* This adds mock specific functionality to a boat. * 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) { public void setAutoVMG(boolean autoVMG) {
this.autoVMG = 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());
}
} }

@ -1,5 +1,6 @@
package mock.model; package mock.model;
import mock.model.collider.ColliderRegistry;
import network.Messages.Enums.BoatStatusEnum; import network.Messages.Enums.BoatStatusEnum;
import network.Messages.LatestMessages; import network.Messages.LatestMessages;
import org.opengis.geometry.primitive.*; import org.opengis.geometry.primitive.*;
@ -30,8 +31,6 @@ public class MockRace extends Race {
*/ */
private List<MockBoat> boats; private List<MockBoat> boats;
/** /**
* A copy of the boundary list, except "shrunk" inwards by 50m. * A copy of the boundary list, except "shrunk" inwards by 50m.
*/ */
@ -79,6 +78,8 @@ public class MockRace extends Race {
//Wind. //Wind.
this.setWind(windGenerator.generateBaselineWind()); this.setWind(windGenerator.generateBaselineWind());
this.colliderRegistry.addAllColliders(boats);
} }
/** /**

@ -1,7 +1,6 @@
package mock.model; package mock.model;
import javafx.animation.AnimationTimer; import javafx.animation.AnimationTimer;
import mock.model.commandFactory.Command;
import mock.model.commandFactory.CommandFactory; import mock.model.commandFactory.CommandFactory;
import mock.model.commandFactory.CompositeCommand; import mock.model.commandFactory.CompositeCommand;
import network.Messages.Enums.BoatActionEnum; import network.Messages.Enums.BoatActionEnum;
@ -12,7 +11,6 @@ import visualiser.gameController.ControllerServer;
import java.util.Observable; import java.util.Observable;
import java.util.Observer; import java.util.Observer;
import java.util.Stack;
public class RaceLogic implements Observer, Runnable { public class RaceLogic implements Observer, Runnable {
/** /**
@ -136,7 +134,7 @@ public class RaceLogic implements Observer, Runnable {
if (boat.getStatus() == BoatStatusEnum.RACING) { if (boat.getStatus() == BoatStatusEnum.RACING) {
commands.execute(); commands.execute();
race.updatePosition(boat, framePeriod, race.getRaceClock().getDurationMilli()); race.updatePosition(boat, framePeriod, race.getRaceClock().getDurationMilli());
race.getColliderRegistry().rayCast(boat);
} }
} }

@ -9,10 +9,9 @@ public interface Collider {
/** /**
* Indicates whether a ray cast from a boat to a target collider triggers a collision. * Indicates whether a ray cast from a boat to a target collider triggers a collision.
* @param boat potentially colliding with target * @param boat potentially colliding with target
* @param collision details of potential collision
* @return whether or not a collision has occurred * @return whether or not a collision has occurred
*/ */
boolean rayCast(MockBoat boat, Collision collision); boolean rayCast(MockBoat boat);
/** /**
* Handle a collision event * Handle a collision event

@ -3,6 +3,7 @@ package mock.model.collider;
import mock.model.MockBoat; import mock.model.MockBoat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
/** /**
@ -29,10 +30,14 @@ public class ColliderRegistry implements Collider {
colliders.remove(collider); colliders.remove(collider);
} }
public void addAllColliders(Collection<? extends Collider> colliders) {
for(Collider collider: colliders) addCollider(collider);
}
@Override @Override
public boolean rayCast(MockBoat boat, Collision collision) { public boolean rayCast(MockBoat boat) {
for(Collider collider: colliders) { for(Collider collider: colliders) {
if(collider.rayCast(boat, collision)) return true; if(collider.rayCast(boat)) return true;
} }
return false; return false;
} }

@ -1,10 +1,19 @@
package shared.model; 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. * 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. * The ID of the compound mark.
@ -110,7 +119,7 @@ public class CompoundMark {
* @return The position of the second mark in the compound mark. * @return The position of the second mark in the compound mark.
*/ */
public GPSCoordinate getMark2Position() { 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. * @return The average coordinate of the compound mark.
*/ */
private GPSCoordinate calculateAverage() { 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. //Otherwise, calculate the average of both marks.
GPSCoordinate averageCoordinate = GPSCoordinate.calculateAverageCoordinate(this.getMark1Position(), this.getMark2Position()); GPSCoordinate averageCoordinate = GPSCoordinate.calculateAverageCoordinate(this.getMark1Position(), this.getMark2Position());
return averageCoordinate; 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());
}
} }

@ -4,6 +4,7 @@ import javafx.beans.property.IntegerProperty;
import javafx.beans.property.Property; import javafx.beans.property.Property;
import javafx.beans.property.SimpleIntegerProperty; import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
import mock.model.collider.ColliderRegistry;
import network.Messages.Enums.RaceStatusEnum; import network.Messages.Enums.RaceStatusEnum;
import network.Messages.Enums.RaceTypeEnum; import network.Messages.Enums.RaceTypeEnum;
import network.Messages.LatestMessages; 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}. * 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 { public abstract class Race {
/** /**
* The source of race related data. * The source of race related data.
*/ */
protected RaceDataSource raceDataSource; protected RaceDataSource raceDataSource;
/** /**
* The source of boat related data. * The source of boat related data.
*/ */
protected BoatDataSource boatDataSource; protected BoatDataSource boatDataSource;
/** /**
* The source of regatta related data. * The source of regatta related data.
*/ */
protected RegattaDataSource regattaDataSource; protected RegattaDataSource regattaDataSource;
/** /**
* The collection of latest race messages. * The collection of latest race messages.
* Can be either read from or written to. * Can be either read from or written to.
*/ */
protected LatestMessages latestMessages; protected LatestMessages latestMessages;
/** /**
* A list of compound marks in the race. * A list of compound marks in the race.
*/ */
protected List<CompoundMark> compoundMarks; protected List<CompoundMark> compoundMarks;
/** /**
* A list of legs in the race. * A list of legs in the race.
*/ */
protected List<Leg> legs; protected List<Leg> legs;
/** /**
* A list of coordinates describing the boundary of the course. * A list of coordinates describing the boundary of the course.
*/ */
protected List<GPSCoordinate> boundary; protected List<GPSCoordinate> boundary;
/** /**
* The clock which tracks the race's start time, current time, and elapsed duration. * The clock which tracks the race's start time, current time, and elapsed duration.
*/ */
protected RaceClock raceClock; protected RaceClock raceClock;
/** /**
* The race ID of the course. * The race ID of the course.
*/ */
protected int raceId; protected int raceId;
/** /**
* The name of the regatta. * The name of the regatta.
*/ */
protected String regattaName; protected String regattaName;
/** /**
* The current status of the race. * The current status of the race.
*/ */
protected RaceStatusEnum raceStatusEnum; protected RaceStatusEnum raceStatusEnum;
/** /**
* The type of race this is. * The type of race this is.
*/ */
protected RaceTypeEnum raceType; protected RaceTypeEnum raceType;
/** /**
* The race's wind. * The race's wind.
*/ */
protected Property<Wind> raceWind = new SimpleObjectProperty<>(); protected Property<Wind> raceWind = new SimpleObjectProperty<>();
/**
* Registry for all collider object in this race
*/
protected ColliderRegistry colliderRegistry;
/** /**
* The number of frames per second. * 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. * 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; private int currentFps = 0;
/** /**
* The number of frames per second we generated over the last 1 second period. * The number of frames per second we generated over the last 1 second period.
*/ */
private IntegerProperty lastFps = new SimpleIntegerProperty(0); private IntegerProperty lastFps = new SimpleIntegerProperty(0);
/** /**
* The time, in milliseconds, since we last reset our {@link #currentFps} counter. * The time, in milliseconds, since we last reset our {@link #currentFps} counter.
*/ */
@ -156,9 +139,13 @@ public abstract class Race {
//Wind. //Wind.
this.setWind(Bearing.fromDegrees(0), 0); 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. * Initialise the boats in the race.
@ -272,14 +259,6 @@ public abstract class Race {
return raceWind.getValue().getWindSpeed(); return raceWind.getValue().getWindSpeed();
} }
/**
* Returns the race's wind.
* @return The race's wind.
*/
public Property<Wind> windProperty() {
return raceWind;
}
/** /**
* Returns the RaceClock for this race. * Returns the RaceClock for this race.
* This is used to track the start time, current time, and elapsed duration of the race. * This is used to track the start time, current time, and elapsed duration of the race.

Loading…
Cancel
Save