796 lines
28 KiB
Java
796 lines
28 KiB
Java
package worms.model;
|
|
|
|
import be.kuleuven.cs.som.annotate.*;
|
|
import worms.util.Coordinate;
|
|
import worms.util.IllegalNameException;
|
|
|
|
import static java.lang.Math.*;
|
|
|
|
import java.util.Random;
|
|
|
|
/**
|
|
* A class with the specifications of the worm
|
|
*
|
|
* @invar The location of the worm must be a valid location.
|
|
* |isValidLocation(getLocation())
|
|
* @invar The orientation of the worm must be a valid location.
|
|
* |isValidOrientation(getOrientation())
|
|
* @invar The radius of the worm mus be a valid radius.
|
|
* |isValidMinRadius(getRadius())
|
|
* @invar The mass of the worm must bef a valid mass.
|
|
* |isValidMass(getMass())
|
|
* @invar The value of the action points of the worm must be a valid value for action points.
|
|
* |isValidValueActionPoints(getActionPoints())
|
|
* @invar The name of the worm must be a valid name.
|
|
* |isValidName(getName())
|
|
*
|
|
* @version 1.0
|
|
* @author Arthur Bols and Leen Dereu
|
|
*
|
|
* Arthur Bols 1e bachelor Informatica
|
|
* Leen Dereu 1e bachelor Informatica
|
|
*
|
|
* URL: https://github.com/KUL-ogp/ogp1718-project-bols-dereu
|
|
*/
|
|
public class Worm {
|
|
|
|
// region constructor
|
|
//===================================================================================
|
|
|
|
/**
|
|
*initialize the new worm with given location, orientation, name and radius
|
|
*
|
|
* @param location
|
|
* the location for the new worm
|
|
* @param orientation
|
|
* the orientation for the new worm
|
|
* @param name
|
|
* the name for the new worm
|
|
* @param radius
|
|
* the radius for the new worm
|
|
* @post the new location of the worm is equal to the given location
|
|
* |new.getLocation() == location
|
|
* @post the new orientation of the worm is equal to the given orientation
|
|
* |new.getOrientation() == orientation
|
|
* @post the new name of the worm is equal to the given name
|
|
* |new.getName() == name
|
|
* @post the new radius of the worm is equal to the given radius
|
|
* |new.getRadius() == radius
|
|
*/
|
|
@Raw
|
|
public Worm(Coordinate location, double orientation, String name, double radius) {
|
|
|
|
this(location, orientation, name, radius, 0.25);
|
|
}
|
|
|
|
/**
|
|
*initialize the new worm with given location, orientation, name, radius and minimum radius
|
|
*
|
|
* @param location
|
|
* the location for the new worm
|
|
* @param orientation
|
|
* the orientation for the new worm
|
|
* @param name
|
|
* the name for the new worm
|
|
* @param radius
|
|
* the radius for the new worm
|
|
* @param minRadius
|
|
* the minimum radius the new worm can have
|
|
* @post the new location of the worm is equal to the given location
|
|
* |new.getLocation() == location
|
|
* @post the new orientation of the worm is equal to the given orientation
|
|
* |new.getOrientation() == orientation
|
|
* @post the new name of the worm is equal to the given name
|
|
* |new.getName() == name
|
|
* @post the new radius of the worm is equal to the given radius
|
|
* |new.getRadius() == radius
|
|
* @post the new minimum radius of the worm is equal to the given minimum radius
|
|
* |new.getMinRadius() == minRadius
|
|
* @throws IllegalArgumentException
|
|
* the given location is not a valid location for a worm
|
|
* |!isValidLocation(location)
|
|
* @throws IllegalArgumentException
|
|
* the given minimum radius is not a valid minimum radius for a worm
|
|
* |!isValidMinRadius(minRadius)
|
|
* @throws IllegalArgumentException
|
|
* the given radius can not be a minimum radius for a worm
|
|
* |!canHaveAsMinRadius(radius)
|
|
* @throws IllegalNameException
|
|
* the given name is not a valid name for a worm
|
|
* |isValidName(name)
|
|
*/
|
|
@Raw
|
|
public Worm(Coordinate location, double orientation, String name, double radius, double minRadius)
|
|
throws IllegalArgumentException {
|
|
|
|
if (!isValidLocation(location))
|
|
throw new IllegalArgumentException("Illegal value for location");
|
|
setLocation(location);
|
|
|
|
setOrientation(orientation);
|
|
|
|
if (!isValidMinRadius(minRadius))
|
|
throw new IllegalArgumentException("Invalid min radius");
|
|
this.minRadius = minRadius;
|
|
|
|
if (!canHaveAsRadius(radius))
|
|
throw new IllegalArgumentException("Invalid radius");
|
|
|
|
setRadius(radius);
|
|
|
|
setActionPoints(getMaxActionPoints());
|
|
|
|
int validName = isValidName(name);
|
|
if (validName != -1)
|
|
throw new IllegalNameException(validName, name);
|
|
this.name = name;
|
|
|
|
long startHitPoints = 1000 + (new Random().nextLong() * (2000 - 1000));
|
|
setHitPoints(startHitPoints);
|
|
}
|
|
|
|
//===================================================================================
|
|
// endregion
|
|
|
|
// region location
|
|
//===================================================================================
|
|
|
|
/**
|
|
* Return the location of the worm
|
|
* the location of the worm expresses the place of the worm
|
|
* in the play area
|
|
*/
|
|
@Basic @Immutable @Raw
|
|
public Coordinate getLocation() {
|
|
return this.location;
|
|
}
|
|
|
|
/**
|
|
* check whether the given location is a valid location for the worm
|
|
*
|
|
* @param location
|
|
* the location to check
|
|
* @return True if and only if the location is not equal to null and the coordinates of
|
|
* the worm are numbers
|
|
* |result == ( (location != null) && (location.getCoordinateX() != null) && (location.getCoordinateY() != null)
|
|
* |&& (!Double.isNaN(location.getCoordinateX())) && (!Double.isNaN(location.getCoordinateY())) )
|
|
*/
|
|
public static boolean isValidLocation(Coordinate location) {
|
|
return location != null && !Double.isNaN(location.getCoordinateX()) && !Double.isNaN(location.getCoordinateY());
|
|
}
|
|
|
|
/**
|
|
* this variable contains the location of the worm (a Coordinate)
|
|
*/
|
|
private Coordinate location;
|
|
|
|
/**
|
|
* set the location of the worm to the given location
|
|
*
|
|
* @param location
|
|
* the new location for the worm
|
|
* @post the new location of the worm is equal to the given location
|
|
* |new.getLocation() == location
|
|
* @throws IllegalArgumentException
|
|
* the given location is not a valid location for a worm
|
|
* |! isValidLocation(location)
|
|
*/
|
|
@Raw
|
|
private void setLocation(Coordinate location) throws IllegalArgumentException {
|
|
|
|
if (!isValidLocation(location))
|
|
throw new IllegalArgumentException("Illegal value for location");
|
|
this.location = location;
|
|
}
|
|
|
|
|
|
//===================================================================================
|
|
// endregion
|
|
|
|
|
|
// region Orientation
|
|
//===================================================================================
|
|
|
|
/**
|
|
* Return the orientation of the worm
|
|
* the orientation of a worm expresses the direction in which
|
|
* the worm is looking
|
|
*/
|
|
@Basic @Raw
|
|
public double getOrientation() {
|
|
return orientation;
|
|
}
|
|
|
|
/**
|
|
* this variable contains the orientation of the worm
|
|
*/
|
|
private double orientation;
|
|
|
|
/**
|
|
* set the orientation of the worm to the given orientation
|
|
*
|
|
* @param orientation
|
|
* the new orientation of the worm
|
|
* @pre the given orientation must be a valid orientation for any worm
|
|
* |isValidOrientation(orientation)
|
|
* @post the new orientation of the worm must be equal to the given orientation
|
|
* |new.getOrientation() == orientation
|
|
*/
|
|
@Raw
|
|
private void setOrientation(double orientation) {
|
|
assert isValidOrientation(orientation);
|
|
this.orientation = orientation;
|
|
}
|
|
|
|
/**
|
|
*check whether the given orientation is a valid orientation for the worm
|
|
*
|
|
* @param newOrientation
|
|
* the orientation to check
|
|
* @return True if and only if the orientation is bigger then and smaller then 2pi
|
|
* |result == ( newOrientation >= 0 && newOrientation < 2 * PI )
|
|
*/
|
|
public static boolean isValidOrientation(double newOrientation) {
|
|
return newOrientation >= 0 && newOrientation < 2 * PI;
|
|
}
|
|
|
|
//===================================================================================
|
|
// endregion
|
|
|
|
|
|
|
|
|
|
// region Shape mass/radius
|
|
//===================================================================================
|
|
|
|
/**
|
|
* Return the radius of the worm
|
|
* the radius of the worm expresses half of the
|
|
* width of the worm
|
|
*/
|
|
@Basic @Raw
|
|
public double getRadius() {
|
|
return this.radius;
|
|
}
|
|
|
|
/**
|
|
* check whether the given radius is a valid minimum radius for the worm
|
|
*
|
|
* @param minRadius
|
|
* the radius to check
|
|
* @return True if and only if the radius is a number and the radius is bigger then 0
|
|
* |result == ((!Double.isNaN(radius)) && (radius > 0))
|
|
*/
|
|
public static boolean isValidMinRadius(double minRadius) {
|
|
return !Double.isNaN(minRadius) && minRadius > 0;
|
|
}
|
|
|
|
/**
|
|
* set the radius of the worm to the given radius
|
|
*
|
|
* @param radius
|
|
* the new radius for the worm
|
|
* @post the new radius of the worm is equal to the given radius
|
|
* |new.getRadius() == radius
|
|
* @throws IllegalArgumentException
|
|
* the given radius is not a valid radius for any worm
|
|
* |! canHaveAsMinRadius(radius)
|
|
*/
|
|
@Raw
|
|
public void setRadius(double radius) throws IllegalArgumentException {
|
|
if (!canHaveAsRadius(radius))
|
|
throw new IllegalArgumentException("Invalid radius");
|
|
|
|
this.radius = radius;
|
|
setMass(radius);
|
|
}
|
|
|
|
/**
|
|
* Return the minimum radius the worm can have
|
|
* the minimum radius of the worm expresses the minimum length
|
|
* of half of the width of the worm
|
|
*/
|
|
@Basic @Raw
|
|
public double getMinRadius() {
|
|
return this.minRadius;
|
|
}
|
|
|
|
|
|
/**
|
|
* This variable contains the radius of the worm
|
|
*/
|
|
private double radius;
|
|
|
|
/**
|
|
* This variable contains the minimum value of the radius
|
|
*/
|
|
private final double minRadius;
|
|
|
|
/**
|
|
* Check whether the given radius is a valid radius for the worm
|
|
*
|
|
* @param radius
|
|
* the radius to check
|
|
* @return True if and only if the radius is bigger then the minimum radius
|
|
* (or equal) and the radius is a number
|
|
* |result == (radius >= getMinRadius() && !Double.isNaN(radius))
|
|
*/
|
|
@Raw
|
|
private boolean canHaveAsRadius(double radius) {
|
|
return !Double.isNaN(radius) && radius >= getMinRadius();
|
|
}
|
|
|
|
/**
|
|
* Return the mass of the worm
|
|
* the mass of the worm expresses the weight of the worm
|
|
*/
|
|
@Basic @Raw
|
|
public double getMass() {
|
|
return this.mass;
|
|
}
|
|
|
|
/**
|
|
* this variable contains the mass of the worm
|
|
*/
|
|
private double mass;
|
|
|
|
/**
|
|
* set the mass of the worm to the given mass (dependent on the radius)
|
|
*
|
|
* @param radius
|
|
* part of the formula to calculate the mass
|
|
* @post the new mass of the worm is equal to
|
|
* rho * (4 / 3 * Math.PI * Math.pow(radius, 3))
|
|
* |new.getMass() == rho * (4 / 3 * Math.PI * Math.pow(radius, 3))
|
|
*/
|
|
@Raw
|
|
private void setMass(double radius) {
|
|
|
|
final double rho = 1062.0;
|
|
double mass = round(rho * (4.0 / 3.0 * PI * pow(radius, 3)));
|
|
this.mass = mass;
|
|
setMaxActionPoints(mass);
|
|
}
|
|
|
|
//===================================================================================
|
|
// endregion
|
|
|
|
|
|
|
|
// region ActionPoints
|
|
//===================================================================================
|
|
|
|
/**
|
|
* Return the current action points of the worm
|
|
* the action points identifies the energy of the worm
|
|
*/
|
|
@Basic @Raw
|
|
public long getActionPoints() {
|
|
return this.actionPoints;
|
|
}
|
|
|
|
/**
|
|
* Return the maximum of action points of the worm
|
|
* the maximum action points identifies the maximum energy of the worm
|
|
*/
|
|
@Basic @Raw
|
|
public long getMaxActionPoints() {
|
|
return this.maxActionPoints;
|
|
}
|
|
|
|
/**
|
|
* set the current points of the worm to the given points
|
|
*
|
|
* @param actionPoints
|
|
* the new points for the worm
|
|
* @post if the given points are bigger then the maximum points, the current points
|
|
* are equal to the maximum points. If the given points are lower then 0
|
|
* the current points are equal to 0. If the given points is between the
|
|
* maximum points and 0, the current points is equal to the given points
|
|
* |if (actionPoints > getMaxActionPoints())
|
|
* | actionPoints = getMaxActionPoints();
|
|
* |else if (actionPoints < 0)
|
|
* | actionPoints = 0;
|
|
* |this.actionPoints = actionPoints;
|
|
*/
|
|
@Raw
|
|
private void setActionPoints(long actionPoints) {
|
|
if (actionPoints > getMaxActionPoints())
|
|
actionPoints = getMaxActionPoints();
|
|
else if (actionPoints < 0)
|
|
actionPoints = 0;
|
|
|
|
this.actionPoints = actionPoints;
|
|
}
|
|
|
|
/**
|
|
*substract the current points of the worm
|
|
*
|
|
* @param delta
|
|
* the value which should be decreased
|
|
* @post the current points are set to the old current points minus the given value
|
|
* |setActionPoints(getActionPoints() - delta)
|
|
*/
|
|
public void decreaseActionPoints (long delta) {
|
|
|
|
setActionPoints(getActionPoints() - delta);
|
|
}
|
|
|
|
/**
|
|
* this variable contains the current action points of the worm
|
|
*/
|
|
private long actionPoints;
|
|
|
|
/**
|
|
* this variable contains the maximum action points a worm can have
|
|
*/
|
|
private long maxActionPoints;
|
|
|
|
/**
|
|
* set the maximum of points to the given maximum of points
|
|
*
|
|
* @param maxActionPoints
|
|
* the new maximum of points for the worm
|
|
* @post the new maximum points is set to the given maximum points (as an integer)
|
|
* |this.maxPoints = round(maxActionPoints)
|
|
* @post when the maximum points change, the current points should change too
|
|
* |setActionPoints(getActionPoints)
|
|
*/
|
|
@Raw
|
|
private void setMaxActionPoints(double maxActionPoints) {
|
|
this.maxActionPoints = round(maxActionPoints);
|
|
setActionPoints(getActionPoints());
|
|
}
|
|
|
|
/**
|
|
* substract the current points of the worm
|
|
*
|
|
* @param value
|
|
* the value which should be subtracted
|
|
* @post the current points are set to the old current points minus the given value
|
|
* |setActionPoints(getActionPoints() - value)
|
|
*/
|
|
private void subtractActionPoints (long value) {
|
|
|
|
setActionPoints(getActionPoints() - value);
|
|
}
|
|
|
|
/**
|
|
* substract the current points of the worm
|
|
*
|
|
* @param angle
|
|
* the angle needed to calculate the new current points
|
|
* @post the current points are set to the old current points minus
|
|
* the angle (in degrees) divided by 6
|
|
* |setActionPoints(getActionPoints() - (long) ceil(toDegrees(angle) / 6))
|
|
*/
|
|
private void subtractActionPoints (double angle) {
|
|
|
|
setActionPoints(getActionPoints() - (long) ceil(toDegrees(angle) / 6));
|
|
}
|
|
|
|
//===================================================================================
|
|
// endregion
|
|
|
|
|
|
|
|
// region name
|
|
//===================================================================================
|
|
|
|
/**
|
|
* Return the name of the worm
|
|
* the name of the worm expresses the identity of the worm
|
|
*/
|
|
@Basic @Immutable @Raw
|
|
public String getName() {
|
|
return this.name;
|
|
}
|
|
|
|
/**
|
|
* check whether the given name is a valid name for all worms
|
|
*
|
|
* @param name
|
|
* the name to check
|
|
* @return -1 if and only if the given name is longer then 2,
|
|
* the first letter is uppercase and the name only exists
|
|
* of letters, " ", " ' " and " "" "
|
|
* |for (i = 0; i < name.length(); i++)
|
|
* |result == (name.length() > 2 && Character.isUpperCase(name.charAt(0)
|
|
* |&& Character.isLetter(name.charAt(i)) &&
|
|
* |allowedCharacters.indexOf(name.charAt(i)))
|
|
*/
|
|
public static int isValidName (String name) {
|
|
|
|
if (name.length() < 2 || !Character.isUpperCase(name.charAt(0))) {
|
|
return 0;
|
|
}
|
|
String allowedCharacters = "'\" ";
|
|
|
|
for (int i = 0; i < name.length(); i++) {
|
|
if (!Character.isLetter(name.charAt(i))) {
|
|
if (allowedCharacters.indexOf(name.charAt(i)) == -1) {
|
|
return i;
|
|
}
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* set the name of the worm tot the given name
|
|
*
|
|
* @param name
|
|
* the new name for the worm
|
|
* @post the new name of the worm is equal to the given name
|
|
* |new.GetName() == name
|
|
* @throws IllegalNameException
|
|
* the given name is not a valid name for any worm
|
|
* |! isValidName(name)
|
|
*/
|
|
@Raw
|
|
public void setName(String name) throws IllegalNameException {
|
|
|
|
int validName = isValidName(name);
|
|
if (validName != -1)
|
|
throw new IllegalNameException(validName, name);
|
|
|
|
this.name = name;
|
|
}
|
|
|
|
/**
|
|
* this variable contains the name of the worm
|
|
*/
|
|
private String name;
|
|
|
|
//===================================================================================
|
|
// endregion
|
|
|
|
|
|
|
|
// region move
|
|
//===================================================================================
|
|
|
|
/**
|
|
* move the worm for the given number of steps
|
|
*
|
|
* @param numberSteps
|
|
* the number of steps the worm should take
|
|
*
|
|
* @post the x-coordinate of the new location of the worm should be the location of
|
|
* the old x-coordinate plus the number of steps multiplied with the distance
|
|
* that the x-coordinate should move (distance is equal to the radius multiplied
|
|
* with the cosinus of the orientation)
|
|
* |distanceX = this.radius * cos(getOrientation())
|
|
* |new.xCoordinate = getLocation().getCoordinateX() + numberSteps * distanceX
|
|
* @post the y-coordinate of the new location of the worm should be the location of
|
|
* the old y-coordinate plus the number of steps multiplied with the distance
|
|
* that the y-coordinate should move (distance is equal to the radius multiplied
|
|
* with the sinus of the orientation)
|
|
* |distanceY = this.radius * sin(getOrientation())
|
|
* |new.yCoordinate = getLocation().getCoordinateY() + numberSteps * distanceY
|
|
* @post the current value of action actionPoints has changed. The current value of action actionPoints
|
|
* minus the cost of moving (abs(cos(theta)) + abs(4 sin(theta)))
|
|
* |cost = (long) ceil(abs(cos(getOrientation())) + abs(4 * sin(getOrientation()))) * numberSteps
|
|
* |subtractActionPoints(cost)
|
|
* @throws IllegalArgumentException
|
|
* when the total of steps is lower then 0 or when the cost of action point is more
|
|
* then the current value of action point
|
|
* |NumberSteps < 0 || cost > this.actionPoints
|
|
*/
|
|
public void move(int numberSteps) throws IllegalArgumentException {
|
|
if (numberSteps < 0)
|
|
throw new IllegalArgumentException();
|
|
|
|
long cost = (long) ceil(abs(cos(getOrientation())) + abs(4 * sin(getOrientation()))) * numberSteps;
|
|
|
|
if (cost > getActionPoints())
|
|
throw new IllegalArgumentException();
|
|
|
|
double distanceX = getRadius() * cos(getOrientation());
|
|
double distanceY = getRadius() * sin(getOrientation());
|
|
setLocation(Coordinate.create(getLocation().getCoordinateX() + numberSteps * distanceX,
|
|
getLocation().getCoordinateY() + numberSteps * distanceY));
|
|
subtractActionPoints(cost);
|
|
}
|
|
|
|
public void collision(Worm smallestWorm, Worm largestWorm) {
|
|
long total = 1 + (new Random().nextLong() * (10 - 1));
|
|
long loseSmallest = (long) (total / (largestWorm.getOrientation() / (smallestWorm.getOrientation() + largestWorm.getOrientation())));
|
|
long loseLargest = total - loseSmallest;
|
|
smallestWorm.incrementHitPoints(loseSmallest);
|
|
largestWorm.incrementHitPoints(loseLargest);
|
|
}
|
|
|
|
//===================================================================================
|
|
// endregion
|
|
|
|
|
|
// region turn
|
|
//===================================================================================
|
|
|
|
/**
|
|
* turns the worm with the given angle
|
|
*
|
|
* @param angle
|
|
* the angle that must be added to the orientation
|
|
* @pre the angle to add must be between 0 and 2pi (including 0)
|
|
* |0 <= angle < 2pi
|
|
* @post the new orientation is the old orientation plus the given angle
|
|
* |new.getOrientation() = this.getOrientation() + angle
|
|
* @post the resulting angle (= the new orientation) must be between 0 and 2pi (including 0)
|
|
* |0 <= new.getOrientation() < 2pi
|
|
* @post current actionPoints of action actionPoints should be reduced, for this there is another
|
|
* method with as parameter the given angle
|
|
* |substractActionPoints(angle)
|
|
*/
|
|
public void turn(double angle) {
|
|
assert canTurn(angle);
|
|
setOrientation(getOrientation() + angle);
|
|
subtractActionPoints(abs(angle));
|
|
}
|
|
|
|
/**
|
|
*return a boolean reflecting whether the worm can accept the given angle to turn
|
|
*
|
|
* @param angle
|
|
* the angle to be checked
|
|
* @return true if and only if the given angle is between 0 (including) and 2pi,
|
|
* the angle is a number and the current number of action points is high enough to turn
|
|
* |result == ( (0 <= angle) && (angle < (2 * PI)) &&
|
|
| (!Double.isNaN(angle)) &&
|
|
| (getActionPoints() - (long) ceil(toDegrees(angle) / 6) >= 0) )
|
|
*/
|
|
private boolean canTurn(double angle) {
|
|
double currentAngle = getOrientation();
|
|
return 0 <= angle + currentAngle && angle + currentAngle < (2 * PI) &&
|
|
!Double.isNaN(angle) &&
|
|
getActionPoints() - (long) ceil(toDegrees(angle) / 6) >= 0;
|
|
}
|
|
|
|
//===================================================================================
|
|
// endregion
|
|
|
|
|
|
// region Jump
|
|
//===================================================================================
|
|
|
|
/**
|
|
* this constant contains the gravity
|
|
* */
|
|
public static final double G = 5.0;
|
|
|
|
/**
|
|
* this constant contains the duration of the force
|
|
*/
|
|
public static final double FORCE_TIME = 0.5;
|
|
|
|
/**
|
|
* let the worm jump
|
|
*
|
|
* @post the worm jumps to his new place. The new place is the x-coordinate plus the jump distance
|
|
* with the jump velocity
|
|
* |setLocation(Coordinate.create(getLocation().getCoordinateX() + jumpDistance(this.jumpVelocity()), getLocation().getCoordinateY()))
|
|
* @post the current action actionPoints should be 0 after a jump
|
|
* |setActionPoints(0)
|
|
* @throws IllegalStateException
|
|
* if the current action actionPoints is equal to 0 or the orientation is more then
|
|
* pi the worm can not jump
|
|
* |!canJump()
|
|
*/
|
|
public void jump() throws IllegalStateException {
|
|
|
|
if (!canJump())
|
|
throw new IllegalStateException();
|
|
|
|
setLocation(Coordinate.create( getLocation().getCoordinateX() + jumpDistance(this.jumpVelocity()), getLocation().getCoordinateY()));
|
|
setActionPoints(0);
|
|
}
|
|
|
|
/**
|
|
* Return the time the worm will jump
|
|
*
|
|
* @return the time the worm will jump. The distance divided by the velocity multiplied
|
|
* with the cosinus of the orientation
|
|
* |jumpDistance(this.jumpVelocity) / (this.jumpVelocity * Math.cos(this.orientation))
|
|
* @throws IllegalStateException
|
|
* Orientation is bigger then pi or action points is equal to 0
|
|
* |getOrientation() >= PI || getActionPoints() == 0
|
|
*/
|
|
public double jumpTime() {
|
|
|
|
if (getOrientation() >= PI || getActionPoints() == 0)
|
|
throw new IllegalStateException();
|
|
|
|
return (jumpDistance(jumpVelocity()) / (jumpVelocity() * cos(getOrientation())));
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param deltaTime
|
|
* the total time the worm should jump
|
|
* @return Coordinate with the new location of the worm. The new x-coordinate is the old x-coordinate plus the jump velocity
|
|
* multiplied with the cosinus of the orientation multiplied with delta time. The new y-coordinate is the old y-coordinate plus
|
|
* the jump velocity multiplied with the sinus of the orientation multiplied with delta time minus 0,5 times the gravity multiplied
|
|
* with the second power of delta time
|
|
* |Coordinate.create(getLocation().getCoordinateX() + this.jumpVelocity() * cos(getOrientation()) * deltaTime,
|
|
|getLocation().getCoordinateY() + this.jumpVelocity() * sin(getOrientation()) * deltaTime - 0.5 * G * pow(deltaTime, 2))
|
|
* @throws IllegalArgumentException()
|
|
* if the deltaTime is not a number or bigger then jumpTime or smaller then 0
|
|
* |if (Double.isNaN(deltaTime) || deltaTime > this.jumpTime() || deltaTime < 0)
|
|
*/
|
|
public Coordinate jumpStep(double deltaTime) {
|
|
if (Double.isNaN(deltaTime) || deltaTime > this.jumpTime() || deltaTime < 0)
|
|
throw new IllegalArgumentException();
|
|
|
|
return Coordinate.create(getLocation().getCoordinateX() + this.jumpVelocity() * cos(getOrientation()) * deltaTime,
|
|
getLocation().getCoordinateY() + this.jumpVelocity() * sin(getOrientation()) * deltaTime - 0.5 * G * pow(deltaTime, 2));
|
|
}
|
|
|
|
/**
|
|
* Return a boolean whether the worm can jump or not
|
|
*
|
|
* @return True if and only if the action actionPoints is bigger then 0 and the orientation
|
|
* is lower then pi
|
|
* |result == getActionPoints() > 0 && getOrientation() < PI
|
|
*/
|
|
private boolean canJump() {
|
|
return getActionPoints() > 0 && getOrientation() < PI;
|
|
}
|
|
|
|
/**
|
|
* Return the distance the worm will jump
|
|
*
|
|
* @param v
|
|
* The velocity of the jump
|
|
* @return The distance the worm will jump. The distance is equal to the velocity powered by 2 multiplied
|
|
* with the sinus of 2 times the orientation en this divided with the gravity
|
|
* |(pow(v, 2) * sin(2 * getOrientation())) / G
|
|
*/
|
|
private double jumpDistance(double v) {
|
|
return (pow(v, 2) * sin(2 * getOrientation())) / G;
|
|
}
|
|
|
|
/**
|
|
* Return the velocity of the jump
|
|
*
|
|
* @return the velocity of the jump. The force of the jump is equal to 5 multiplied with the
|
|
* current action actionPoints plus the mass multiplied with the gravity. Therefrom the velocity
|
|
* is equal to the force divided with the mass, multiplied with the time te force takes
|
|
* |force = 5 * getActionPoints() + getMass() * G
|
|
* |velocity = (force / getMass()) * FORCE_TIME
|
|
*/
|
|
private double jumpVelocity() {
|
|
|
|
double force = 5 * getActionPoints() + getMass() * G;
|
|
return force / getMass() * FORCE_TIME;
|
|
}
|
|
|
|
|
|
//===================================================================================
|
|
// endregion
|
|
|
|
// region hitPoints
|
|
//===================================================================================
|
|
|
|
@Basic @Raw
|
|
public long getHitPoints() {
|
|
return this.hitPoints;
|
|
}
|
|
|
|
@Raw
|
|
private void setHitPoints(long hitPoints) {
|
|
if (hitPoints <= 0)
|
|
// TODO worm sterft + weghalen van gamewereld
|
|
this.hitPoints = hitPoints;
|
|
}
|
|
|
|
private long hitPoints;
|
|
|
|
public void incrementHitPoints(long value) {
|
|
setHitPoints(getHitPoints() - value);
|
|
}
|
|
|
|
//===================================================================================
|
|
// endregion
|
|
}
|