meer refactoring

This commit is contained in:
2018-05-23 21:03:10 +02:00
parent ffcc27104c
commit f3d6d971b9
5 changed files with 295 additions and 204 deletions

View File

@@ -8,8 +8,8 @@ import static java.lang.Math.cos;
import static java.lang.Math.sin; import static java.lang.Math.sin;
public class Bazooka extends Projectile { public class Bazooka extends Projectile {
protected Bazooka(World world, Coordinate wormLocation, double wormOrientation, double wormRadius, double force) { protected Bazooka(Worm worm) {
super(world, wormLocation, wormOrientation, wormRadius, 300, force); super(worm, 300, calcForce(worm.getActionPoints()));
} }
@Override @Override
@@ -35,7 +35,8 @@ public class Bazooka extends Projectile {
} }
public static double calcForce(double actionPoints) { public static double calcForce(double actionPoints) {
double hp = 2.5 + (actionPoints - 25) % 8.0; double hp = 2.5 +
actionPoints % 8.0;
if (hp > 9.5) return 9.5; if (hp > 9.5) return 9.5;
return hp; return hp;
} }

View File

@@ -7,22 +7,8 @@ import static java.lang.Math.*;
public abstract class GameObject { public abstract class GameObject {
/** // region Constructor
* //===================================================================================
*/
protected double mass;
/**
*
*/
protected World world;
/**
*
*/
protected boolean terminated = false;
/**
* this variable contains the location of the worm (a Coordinate)
*/
protected Coordinate location;
/** /**
* @param world * @param world
@@ -60,16 +46,15 @@ public abstract class GameObject {
setLocation(location); setLocation(location);
setRadius(radius); setRadius(radius);
if (isValidWorld(world)) world.add(this); if (isValidWorld(world)) world.add(this);
setWorld(world); this.world = world;
} }
/** // ===================================================================================
* @param world // endregion
* @return ... |result == !world.hasActiveGame() && !world.isTerminated()
*/
public static boolean isValidWorld(World world) { // region world
return world != null && !world.hasActiveGame() && !world.isTerminated(); //===================================================================================
}
/** /**
* @return ... * @return ...
@@ -79,6 +64,16 @@ public abstract class GameObject {
return this.world; return this.world;
} }
/**
* @param world
* @return ... |result == !world.hasActiveGame() && !world.isTerminated()
*/
public static boolean isValidWorld(World world) {
return world != null && !world.hasActiveGame() && !world.isTerminated();
}
/** /**
* @param world * @param world
* @post ... * @post ...
@@ -87,7 +82,7 @@ public abstract class GameObject {
* |else: * |else:
* | this.world = world * | this.world = world
*/ */
public void setWorld(World world) { public void setWorld(World world) throws IllegalArgumentException {
if (world == null) { if (world == null) {
this.world = null; this.world = null;
return; return;
@@ -97,24 +92,16 @@ public abstract class GameObject {
} }
/** /**
* @return ... *
* |result == this.terminated
*/ */
public boolean isTerminated() { protected World world;
return this.terminated;
}
/** // ===================================================================================
* @post ... // endregion
* |this.terminated = true
* |getWorld().remove(this)
*/ // region location
public void terminate() { //===================================================================================
this.terminated = true;
if (this.world != null) {
this.world.remove(this);
}
}
/** /**
* Return the location of the game object * Return the location of the game object
@@ -125,6 +112,13 @@ public abstract class GameObject {
return this.location; return this.location;
} }
/**
* @return ... |result == this.location.toArray()
*/
public double[] getLocationArray() {
return this.location.toArray();
}
/** /**
* @param location * @param location
* @throws IllegalArgumentException ... * @throws IllegalArgumentException ...
@@ -145,13 +139,6 @@ public abstract class GameObject {
this.location = location; this.location = location;
} }
/**
* @return ... |result == this.location.toArray()
*/
public double[] getLocationArray() {
return this.location.toArray();
}
/** /**
* set the location of the worm to the given location * set the location of the worm to the given location
* *
@@ -163,12 +150,49 @@ public abstract class GameObject {
*/ */
protected void setLocation(double[] location) throws IllegalArgumentException { protected void setLocation(double[] location) throws IllegalArgumentException {
Coordinate locationCoordinate = Coordinate.create(location); setLocation(Coordinate.create(location));
if (!isValidLocation(locationCoordinate)) throw new IllegalArgumentException();
this.location = locationCoordinate;
} }
/**
* @param location
* @return ... |if (world == null)
* | result == !Double.isNaN(location.getX()) && !Double.isNaN(location.getY())
* |result == !Double.isNaN(location.getX()) &&
* | !Double.isNaN(location.getY()) &&
* | !(location.getX() - radius < 0) &&
* | !(location.getX() + radius > getWorld().getWidth()) &&
* | !(location.getY() + radius > getWorld().getHeight()) &&
* | !(location.getY() - radius < 0 &&
* | !getWorld().isPassable(location))
*/
protected boolean isValidLocation(Coordinate location) {
double radius = getRadius();
if (world == null) {
return !Double.isNaN(location.getX()) &&
!Double.isNaN(location.getY());
}
return !Double.isNaN(location.getX()) &&
!Double.isNaN(location.getY()) &&
!(location.getX() - radius < 0) &&
!(location.getX() + radius > getWorld().getWidth()) &&
!(location.getY() + radius > getWorld().getHeight()) &&
!(location.getY() - radius < 0) && getWorld().isPassable(location);
}
/**
* this variable contains the location of the GameObject (a Coordinate)
*/
protected Coordinate location;
// ===================================================================================
// endregion
// region radius
//===================================================================================
/** /**
* Return the radius of the game object * Return the radius of the game object
* the radius of the game object expresses half of the * the radius of the game object expresses half of the
@@ -206,32 +230,12 @@ public abstract class GameObject {
return !Double.isNaN(radius) && radius > 0; return !Double.isNaN(radius) && radius > 0;
} }
/** // ===================================================================================
* @param location // endregion
* @return ... |if (world == null)
* | result == !Double.isNaN(location.getX()) && !Double.isNaN(location.getY())
* |result == !Double.isNaN(location.getX()) &&
* | !Double.isNaN(location.getY()) &&
* | !(location.getX() - radius < 0) &&
* | !(location.getX() + radius > getWorld().getWidth()) &&
* | !(location.getY() + radius > getWorld().getHeight()) &&
* | !(location.getY() - radius < 0 &&
* | !getWorld().isPassable(location))
*/
protected boolean isValidLocation(Coordinate location) {
double radius = getRadius();
if (world == null) {
return !Double.isNaN(location.getX()) && // region mass
!Double.isNaN(location.getY()); //===================================================================================
}
return !Double.isNaN(location.getX()) &&
!Double.isNaN(location.getY()) &&
!(location.getX() - radius < 0) &&
!(location.getX() + radius > getWorld().getWidth()) &&
!(location.getY() + radius > getWorld().getHeight()) &&
!(location.getY() - radius < 0) && getWorld().isPassable(location);
}
/** /**
* @return ... |result == this.mass * @return ... |result == this.mass
@@ -241,7 +245,7 @@ public abstract class GameObject {
} }
/** /**
* set the mass of the worm to the given mass (dependent on the radius) * set the mass of the GameObject to the given mass (dependent on the radius)
* *
* @param radius part of the formula to calculate the mass * @param radius part of the formula to calculate the mass
* @post the new mass of the worm is equal to * @post the new mass of the worm is equal to
@@ -253,28 +257,28 @@ public abstract class GameObject {
this.mass = rho * (4.0 / 3.0 * PI * pow(radius, 3.0)); this.mass = rho * (4.0 / 3.0 * PI * pow(radius, 3.0));
} }
/**
*
*/
protected double mass;
// ===================================================================================
// endregion
// region distance calc
//===================================================================================
public double getDistance(GameObject o) { public double getDistance(GameObject o) {
Coordinate otherLocation = o.getLocation(); return getDistance(o.getLocation(), this.radius);
return Math.round((Math.sqrt(Math.pow((otherLocation.getX() - location.getX()), 2) + Math.pow((otherLocation.getY() - location.getY()), 2)) - o.getRadius() - getRadius()) * 100000000.0) / 100000000.0;
} }
public double getDistance(Coordinate otherLocation, double radius) { public double getDistance(Coordinate otherLocation, double radius) {
return Math.round((Math.sqrt(Math.pow((otherLocation.getX() - location.getX()), 2) + Math.pow((otherLocation.getY() - location.getY()), 2)) - radius - getRadius()) * 100000000.0) / 100000000.0; return Math.round((Math.sqrt(Math.pow((otherLocation.getX() - this.location.getX()), 2) +
} Math.pow((otherLocation.getY() - this.location.getY()), 2)) - radius - this.radius) * 10000.0) / 10000.0;
public double getAngle(GameObject o) {
if (o.equals(this)) return Double.NaN;
double x1 = getLocation().getX();
double y1 = getLocation().getY();
double x2 = o.getLocation().getX();
double y2 = o.getLocation().getY();
return Math.abs(Math.atan(Math.abs(x1 - x2) / Math.abs(y1 - y2)) - Math.PI / 2.0);
} }
/** /**
@@ -291,4 +295,57 @@ public abstract class GameObject {
return Math.sqrt(Math.pow(Math.abs(start.getX() - end.getX()), 2) + return Math.sqrt(Math.pow(Math.abs(start.getX() - end.getX()), 2) +
Math.pow(Math.abs(start.getY() - end.getY()), 2)); Math.pow(Math.abs(start.getY() - end.getY()), 2));
} }
/**
* Returns the angle between (dit?) this and the specified GameObject
*
* @param o
* @return
*/
public double getAngle(GameObject o) {
if (o.equals(this)) return Double.NaN;
Coordinate otherLoc = o.getLocation();
return Math.abs(Math.atan(Math.abs(this.location.getX() - otherLoc.getX()) /
Math.abs(this.location.getY() - otherLoc.getY())) - Math.PI / 2.0);
}
// ===================================================================================
// endregion
// region destructor
//===================================================================================
/**
* @return ...
* |result == this.terminated
*/
public boolean isTerminated() {
return this.terminated;
}
/**
* @post ...
* |this.terminated = true
* |getWorld().remove(this)
*/
public void terminate() {
this.terminated = true;
if (this.world != null) {
this.world.remove(this);
}
}
/**
*
*/
private boolean terminated = false;
// ===================================================================================
// endregion
} }

View File

@@ -1,23 +1,37 @@
package worms.model; package worms.model;
import static java.lang.Math.*; import static java.lang.Math.*;
import worms.util.Coordinate; import worms.util.Coordinate;
import java.util.List; import java.util.List;
public abstract class Projectile extends GameObject implements IJumpable { public abstract class Projectile extends GameObject implements IJumpable {
private static final int rho = 7800; private static final int rho = 7800;
protected Projectile (World world, Coordinate wormLocation, double wormOrientation, double wormRadius, double mass, double force) { // region constructor
super(world, calcLocation(wormLocation, wormOrientation, wormRadius, mass), calcRadius(mass)); //===================================================================================
public static final double G = 5.0;
public static final double FORCE_TIME = 0.5;
protected Projectile (Worm worm, double mass, double force) {
super(worm.getWorld(), calcLocation(worm.getLocation(), worm.getOrientation(), worm.getRadius(), mass), calcRadius(mass));
super.mass = mass; super.mass = mass;
this.force = force; this.force = force;
this.orientation = wormOrientation; this.orientation = worm.getOrientation();
this.hitPoints = getRandomHitPoints(); this.hitPoints = getRandomHitPoints();
} }
// ===================================================================================
// endregion
// region radius / orientation / force
//===================================================================================
public double getOrientation() {
return orientation;
}
public static double calcRadius(double mass) { public static double calcRadius(double mass) {
return pow(((mass / 1000.0 / rho) * (3.0 / (4.0 * PI))), 1.0 / 3.0); return pow(((mass / 1000.0 / rho) * (3.0 / (4.0 * PI))), 1.0 / 3.0);
@@ -26,64 +40,76 @@ public abstract class Projectile extends GameObject implements IJumpable {
public double getForce() { public double getForce() {
return this.force; return this.force;
} }
protected final double force; protected final double force;
private final double orientation;
protected int hitPoints; // ===================================================================================
// endregion
protected abstract int getRandomHitPoints();
// region hitpoints
//===================================================================================
public int getHitPoints() { public int getHitPoints() {
return this.hitPoints; return this.hitPoints;
} }
protected abstract int getImpactHitPoints();
protected abstract void setHitPoints(int value) throws IllegalArgumentException;
public void incrementHitPoints(int value) { public void incrementHitPoints(int value) {
setHitPoints(this.hitPoints + value); setHitPoints(this.hitPoints + value);
} }
private final double orientation; public void hit(Worm worm){
public double getOrientation() { worm.decreaseHitPoints(getImpactHitPoints());
return orientation; terminate();
} }
@Override protected abstract void setHitPoints(int value) throws IllegalArgumentException;
protected boolean isValidLocation(Coordinate location) {
double radius = getRadius();
if (getWorld() == null) { protected abstract int getImpactHitPoints();
return !Double.isNaN(location.getX()) &&
!Double.isNaN(location.getY()); protected abstract int getRandomHitPoints();
protected int hitPoints;
// ===================================================================================
// endregion
// region jump
//===================================================================================
public void jump(double jumpTimeStep) throws IllegalStateException {
if (!canJump())
throw new IllegalStateException();
double v = jumpVelocity();
double t = jumpTime(jumpTimeStep);
double a = getOrientation();
Coordinate newLocation = this.location;
List<Worm> worms = getWorld().getGameObjectsByClass(Worm.class);
if (!getWorld().isAdjacent(getLocation(),getRadius())) {
newLocation = Coordinate.create(getLocation().getX() + v * t * cos(a),
getLocation().getY() + v * t * sin(a) - (G * t * t) / 2.0);
}
if (!isValidLocation(newLocation)) {
terminate();
return;
}
setLocation(newLocation);
for (Worm worm: worms) {
if (this.getDistance(worm) < 0) {
setLocation(newLocation);
hit(worm);
}
} }
return !Double.isNaN(location.getX()) &&
!Double.isNaN(location.getY()) &&
!(location.getX() - radius < 0) &&
!(location.getX() + radius > getWorld().getWidth()) &&
!(location.getY() + radius > getWorld().getHeight()) &&
!(location.getY() - radius < 0);
} }
public static final double G = 5.0;
public static final double FORCE_TIME = 0.5;
public Coordinate jumpStep(double elapsedTime) {
if (Double.isNaN(elapsedTime) || elapsedTime < 0)
throw new IllegalArgumentException();
double velocity = this.jumpVelocity();
return Coordinate.create(getLocation().getX() + velocity * cos(getOrientation()) * elapsedTime,
getLocation().getY() + velocity * sin(getOrientation()) * elapsedTime - 0.5 * G * pow(elapsedTime, 2));
}
private double jumpVelocity() {
return (getForce() / (getMass() / 1000)) * FORCE_TIME;
}
public double jumpTime(double timeStep) { public double jumpTime(double timeStep) {
World world = getWorld(); World world = getWorld();
@@ -116,50 +142,58 @@ public abstract class Projectile extends GameObject implements IJumpable {
} }
public Coordinate jumpStep(double elapsedTime) {
if (Double.isNaN(elapsedTime) || elapsedTime < 0)
throw new IllegalArgumentException();
double velocity = this.jumpVelocity();
return Coordinate.create(getLocation().getX() + velocity * cos(getOrientation()) * elapsedTime,
getLocation().getY() + velocity * sin(getOrientation()) * elapsedTime - 0.5 * G * pow(elapsedTime, 2));
}
private boolean canJump() { private boolean canJump() {
return getOrientation() < PI; return getOrientation() < PI;
} }
public void jump(double jumpTimeStep) throws IllegalStateException {
if (!canJump())
throw new IllegalStateException();
double v = jumpVelocity(); private double jumpVelocity() {
double t = jumpTime(jumpTimeStep); return (getForce() / (getMass() / 1000)) * FORCE_TIME;
double a = getOrientation();
Coordinate newLocation = this.location;
List<Worm> worms = getWorld().getGameObjectsByClass(Worm.class);
if (!getWorld().isAdjacent(getLocation(),getRadius())) {
newLocation = Coordinate.create(getLocation().getX() + v * t * cos(a),
getLocation().getY() + v * t * sin(a) - (G * t * t) / 2.0);
}
if (!isValidLocation(newLocation)) {
terminate();
return;
}
setLocation(newLocation);
for (Worm worm: worms) {
if (this.getDistance(worm) < 0) {
setLocation(newLocation);
hit(worm);
}
}
} }
private static Coordinate calcLocation(Coordinate wormLocation, double wormOrientation, double wormRadius, double mass) { // ===================================================================================
// endregion
// region location
//===================================================================================
@Override
protected boolean isValidLocation(Coordinate location) {
double radius = getRadius();
if (getWorld() == null) {
return !Double.isNaN(location.getX()) &&
!Double.isNaN(location.getY());
}
return !Double.isNaN(location.getX()) &&
!Double.isNaN(location.getY()) &&
!(location.getX() - radius < 0) &&
!(location.getX() + radius > getWorld().getWidth()) &&
!(location.getY() + radius > getWorld().getHeight()) &&
!(location.getY() - radius < 0);
}
public static Coordinate calcLocation(Coordinate wormLocation, double wormOrientation, double wormRadius, double mass) {
double radius = calcRadius(mass); double radius = calcRadius(mass);
return Coordinate.create(wormLocation.getX() + cos(wormOrientation) * (wormRadius + radius), return Coordinate.create(wormLocation.getX() + cos(wormOrientation) * (wormRadius + radius),
wormLocation.getY() + sin(wormOrientation) * (wormRadius + radius)); wormLocation.getY() + sin(wormOrientation) * (wormRadius + radius));
} }
public void hit(Worm worm){
worm.decreaseHitPoints(getImpactHitPoints()); // ===================================================================================
terminate(); // endregion
}
} }

View File

@@ -10,8 +10,8 @@ import static java.lang.Math.sin;
public class Rifle extends Projectile { public class Rifle extends Projectile {
public Rifle(World world, Coordinate wormLocation, double wormOrientation, double wormRadius) { public Rifle(Worm worm) {
super(world, wormLocation, wormOrientation, wormRadius, 10, 1.5); super(worm, 10, 1.5);
} }
@Override @Override

View File

@@ -1114,12 +1114,11 @@ public class Worm extends GameObject implements IJumpable{
if (random == 0) { if (random == 0) {
decrementActionPoints(10); decrementActionPoints(10);
return new Rifle(this.world, this.location, this.orientation, this.radius); return new Rifle(this);
} else { } else {
double force = Bazooka.calcForce(this.actionPoints); double force = Bazooka.calcForce(this.actionPoints);
decrementActionPoints(25); decrementActionPoints(25);
return new Bazooka(this);
return new Bazooka(this.world, this.location, this.orientation, this.radius, force);
} }
} }