/*
* Copyright (c) 2009, Hamish Morgan. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the University of Sussex nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package locusts.common.entities;
import java.awt.geom.AffineTransform;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import locusts.common.AbstractUniqueObject;
import locusts.common.UniqueObject;
import locusts.lib.MathUtil;
import org.slf4j.LoggerFactory;
/**
*
* @author Hamish Morgan
*/
public class Entity extends AbstractUniqueObject implements Serializable,
Cloneable, UniqueObject {
private static final transient double DEFAULT_X = 0;
private static final transient double DEFAULT_Y = 0;
private static final transient double DEFAULT_ORIENTATION = 0;
private static final transient boolean DEFAULT_ALIVE = true;
private static final transient double DEFAULT_ENERGY = 100;
//
private transient final long creationTime;
private transient boolean modified;
//
private int typeId;
private boolean alive;
private double x;
private double y;
private double orientation;
private double energy;
private int zOrder;
//
public Entity(int typeId, double x, double y, double orientation,
double energy) {
super(Entity.class);
this.typeId = typeId;
setPosition(x, y);
setOrientation(orientation);
setAlive(DEFAULT_ALIVE);
setEnergy(energy);
modified = true;
zOrder = 0;
creationTime = System.currentTimeMillis();
}
public Entity(int typeId, double x, double y, double orientation) {
this(typeId, x, y, orientation, DEFAULT_ENERGY);
}
public Entity(int typeId, double x, double y) {
this(typeId, x, y, DEFAULT_ORIENTATION);
}
public Entity(int typeId) {
this(typeId, DEFAULT_X, DEFAULT_Y);
}
protected Entity(Entity other) {
super(other);
this.typeId = other.typeId;
this.alive = other.alive;
this.x = other.x;
this.y = other.y;
this.orientation = other.orientation;
this.modified = other.modified;
this.energy = other.energy;
this.zOrder = other.zOrder;
this.creationTime = other.creationTime;
}
public long getCreationTime() {
return creationTime;
}
private void writeObject(ObjectOutputStream out) throws IOException {
// if(x < -Float.MAX_VALUE) x = -Float.MAX_VALUE;
// else if(x > Float.MAX_VALUE) x = Float.MAX_VALUE;
// if(y < -Float.MAX_VALUE) y = -Float.MAX_VALUE;
// else if(y > Float.MAX_VALUE) y = Float.MAX_VALUE;
// if(orientation < -Float.MAX_VALUE) orientation = -Float.MAX_VALUE;
// else if(orientation > Float.MAX_VALUE) orientation = Float.MAX_VALUE;
// if(energy < -Float.MAX_VALUE) energy = -Float.MAX_VALUE;
// else if(energy > Float.MAX_VALUE) energy = Float.MAX_VALUE;
if (x < -Float.MAX_VALUE) x = 0;
else if (x > Float.MAX_VALUE) x = 0;
if (y < -Float.MAX_VALUE) y = 0;
else if (y > Float.MAX_VALUE) y = 0;
if (orientation < -Float.MAX_VALUE) orientation = 0;
else if (orientation > Float.MAX_VALUE) orientation = 0;
if (energy < -Float.MAX_VALUE) energy = 0;
else if (energy > Float.MAX_VALUE) energy = 0;
out.writeFloat((float) x);
out.writeFloat((float) y);
out.writeFloat((float) orientation);
out.writeFloat((float) energy);
out.writeBoolean(alive);
out.writeInt(typeId);
out.writeInt(zOrder);
}
private void readObject(ObjectInputStream in) throws IOException {
try {
setX(in.readFloat());
setY(in.readFloat());
setOrientation(in.readFloat());
setEnergy(in.readFloat());
setAlive(in.readBoolean());
setTypeId(in.readInt());
setzOrder(in.readInt());
} catch (IllegalArgumentException e) {
LoggerFactory.getLogger(Entity.class).error(
"Failed to unserialize Entity.", e);
throw e;
}
}
public int getzOrder() {
return zOrder;
}
public void setzOrder(int zOrder) {
this.zOrder = zOrder;
}
public int getTypeId() {
return typeId;
}
public void setTypeId(int typeId) {
if (typeId < 0)
throw new IllegalArgumentException(
"Type ID should be a possitive integer.");
this.typeId = typeId;
}
public boolean isAlive() {
return alive;
}
public void setAlive(boolean alive) {
this.alive = alive;
}
public void setPosition(double x, double y) {
setX(x);
setY(y);
}
public double getOrientation() {
return orientation;
}
public void setOrientation(double orientation) {
if (Double.isNaN(orientation) || Double.isInfinite(orientation))
throw new IllegalArgumentException(
"Orientation is not a real number.");
this.orientation = MathUtil.normaliseAngle(orientation);
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public void setX(double x) {
if (Double.isNaN(x) || Double.isInfinite(x))
throw new IllegalArgumentException(
"X-Position is not a real number.");
this.x = x;
}
public void setY(double y) {
if (Double.isNaN(y) || Double.isInfinite(y))
throw new IllegalArgumentException(
"Y-Position is not a real number.");
this.y = y;
}
public double getEnergy() {
return energy;
}
public void setEnergy(double energy) {
if (Double.isNaN(energy) || Double.isInfinite(energy))
throw new IllegalArgumentException(
"X-Velocity is not a real number.");
this.energy = energy;
}
public final double distance(final double x, final double y) {
final double dx = x - this.x;
final double dy = y - this.y;
return Math.sqrt(dx * dx + dy * dy);
}
public final double distanceSquared(final double x, final double y) {
final double dx = x - this.x;
final double dy = y - this.y;
return dx * dx + dy * dy;
}
public final double distance(final Entity other) {
return distance(other.getX(), other.getY());
}
public final double distanceSquare(final Entity other) {
return distanceSquared(other.getX(), other.getY());
}
public AffineTransform getAffineTransform() {
final AffineTransform at = new AffineTransform();
at.translate(getX(), getY());
at.rotate(getOrientation());
return at;
}
public void setModified() {
modified = true;
}
public void clearModified() {
modified = false;
}
public boolean isModified() {
return modified;
}
@Override
public Object clone() {
return new Entity(this);
}
@Override
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("Entity ");
buf.append("Position: (");
buf.append(x).append(", ").append(y).append(')');
buf.append("Orientation: ").append(orientation);
buf.append("Alive: ").append(alive);
return buf.toString();
}
}
|