Metroids/Game/src/MovingObject.java

252 lines
7.2 KiB
Java

/**
* An Object that moves following physical rules
* @author vanitas
*
*/
public class MovingObject
{
//Attributes
protected float velocity, //whats the velocity of the object? 0 or 1
x, //x position of the object
y, //y position of the object
speedX, //x component of the speedvector
speedY, //y component (eg. x=2,y=2 => object is flying to the right corner with a speed of 2.7
maxSpeed, //Maximal speed of the object
rotation, //totation of the object (0° <=> object points towards the top of the screen)
thrust; //Power of acceleration
protected int team; //Which team is the object in? 0 = nature
protected Shape shape; //Contains the vertices for the shape
//Constructors (Lol there are none)
/**
* moves the Object one frame
* @param delta
* @param keepOnScreen
*/
public void move(float delta, boolean keepOnScreen)
{
//Set new x and y locations calculated from old location and
//Speedvector
this.setX(this.getX()+this.getSpeedX()*delta*0.2f);
this.setY(this.getY()+this.getSpeedY()*delta*0.2f);
//Eventually keep the object on the screen if it leaves at the borders
if(keepOnScreen) this.keepOnScreen();
}
/**
* Rotates the Object to the right
* @param delta
*/
public void turnRight(int delta)
{
this.setRotation(this.getRotation() + 0.35f * delta);
}
/**
* Rotates the Object to the left
* @param delta
*/
public void turnLeft(int delta)
{
this.setRotation(this.getRotation() - 0.35f * delta);
}
/**
* Let this Object follow another Object
* @param x
*/
public void follow(MovingObject x) //TODO Test this
{
float xOther = x.getX();
float yOther = x.getY();
float hypot = (float) Math.hypot(Math.abs(this.x-xOther), Math.abs(this.y-yOther));
//Set Rotation
float rot;
if(this.x<xOther) rot = (float) -(Math.toDegrees((Math.PI/2)-Math.asin((yOther-this.getY())/hypot)));
else rot = (float) (Math.toDegrees((Math.PI/2)-Math.asin((yOther-this.getY())/hypot)));
//Catch NaN (if rot is Infinity)
if(!Float.isNaN(rot)) this.setRotation(rot);
else this.setRotation(0);
this.setVelocity(1);
}
/**
* Calculate the SpeedVector for the Object.
*/
public void accelerate()
{
this.speedX = (float) (Math.sin(Math.toRadians(this.getRotation()))*this.getThrust()*this.getVelocity()+this.getSpeedX());
this.speedY = (float) (Math.cos(Math.toRadians(this.getRotation()))*this.getThrust()*this.getVelocity()+this.getSpeedY());
double actualSpeed = Math.sqrt(Math.pow(this.getSpeedX(),2)+Math.pow(this.getSpeedY(),2));
if(actualSpeed>this.getMaxSpeed())
{
double fac = actualSpeed/this.getMaxSpeed();
this.speedX = (float) (this.speedX/fac);
this.speedY = (float) (this.speedY/fac);
}
}
/**
* Keep the Object on the screen if it leaves to the borders
*/
public void keepOnScreen()
{
this.x = this.x%SpaceSpiel.frameSizeX;
this.y = this.y%SpaceSpiel.frameSizeY;
if(this.x<0) this.x = SpaceSpiel.frameSizeX+this.x;
if(this.y<0) this.y = SpaceSpiel.frameSizeY+this.y;
}
/**
* This Method fires (In this class its only there, to be overwritten)
* @param delta
*/
public void fire(float delta)
{
//Let me empty
}
/**
* Checks, if this Object collides with another TODO: This is not accurate, maybe there's a fix for this
* @param otherObject The Object, this Object should check for collision with
* @return the Object if collided, else null
* @author lil, Oooh, vanitas
*/
public MovingObject intersect(MovingObject otherObject)
{
//Extract the shapes of the objects
Shape one = this.getShape();
Shape other = otherObject.getShape();
//Go through all the edges of the shape of THIS object
for(int i = 0; i<one.getLength(); i++)
{
int iinc = (i+1)%one.getLength();
//Go through all the edges of otherObject's shape
for(int j = 0; j< other.getLength(); j++)
{
int jinc = (j+1)%other.getLength();
//Calculate all the start and end-points of the edges
//(1-2=>current edge of THIS shape, 3-4 => current edge of otherObject's shape)
double x1 = this.getX()+MathShit.rotateX(Math.toRadians(this.getRotation()), one.getX(i), one.getY(i))*one.getSize();
double x2 = this.getX()+MathShit.rotateX(Math.toRadians(this.getRotation()), one.getX(iinc), one.getY(iinc))*one.getSize();
double x3 = otherObject.getX()+MathShit.rotateX(Math.toRadians(otherObject.getRotation()), other.getX(j), other.getY(j))*other.getSize();
double x4 = otherObject.getX()+MathShit.rotateX(Math.toRadians(otherObject.getRotation()), other.getX(jinc), other.getY(jinc))*other.getSize();
double y1 = this.getY()+MathShit.rotateY(Math.toRadians(this.getRotation()), one.getX(i), one.getY(i))*one.getSize();
double y2 = this.getY()+MathShit.rotateY(Math.toRadians(this.getRotation()), one.getX(iinc), one.getY(iinc))*one.getSize();
double y3 = otherObject.getY()+MathShit.rotateY(Math.toRadians(otherObject.getRotation()), other.getX(j), other.getY(j))*other.getSize();
double y4 = otherObject.getY()+MathShit.rotateY(Math.toRadians(otherObject.getRotation()), other.getX(jinc), other.getY(jinc))*other.getSize();
// Zaehler
double zx = (x1 * y2 - y1 * x2)*(x3-x4) - (x1 - x2) * (x3 * y4 - y3 * x4);
double zy = (x1 * y2 - y1 * x2)*(y3-y4) - (y1 - y2) * (x3 * y4 - y3 * x4);
// Nenner
double n = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
// Koordinaten des Schnittpunktes
double x = zx/n;
double y = zy/n;
// Vielleicht ist bei der Division durch n etwas schief gelaufen
if (Double.isNaN(x)& Double.isNaN(y))
{
System.out.println("NaN");
}
// Test ob der Schnittpunkt auf den angebenen Strecken liegt oder außerhalb.
if (Math.abs((x - x1) / (x2 - x1)) > 1 || Math.abs((x - x3) / (x4 - x3)) > 1 || Math.abs((y - y1) / (y2 - y1)) > 1 || Math.abs((y - y3) / (y4 - y3)) > 1 )
{
//System.out.println("Alles ok");
}
else return otherObject;
}
}
return null;
}
/**
* Placeholder for children. Children should overwrite this method to handle the case of a collision
* @param o The Object THIS collided with
*/
public void processCollision(MovingObject o)
{
}
//Getters and setters
public float getVelocity()
{
return this.velocity;
}
public void setVelocity(float v)
{
this.velocity = v;
}
public float getX()
{
return this.x;
}
public void setX(float x)
{
this.x = x;
}
public float getY()
{
return y;
}
public void setY(float y)
{
this.y = y;
}
public float getSpeedX()
{
return speedX;
}
public void setSpeedX(float speedX)
{
this.speedX = speedX;
}
public float getSpeedY()
{
return speedY;
}
public void setSpeedY(float speedY)
{
this.speedY = speedY;
}
public float getMaxSpeed()
{
return maxSpeed;
}
public void setMaxSpeed(float maxSpeed)
{
this.maxSpeed = maxSpeed;
}
public float getRotation()
{
return rotation;
}
public void setRotation(float rotation)
{
this.rotation = rotation%360;
}
public float getThrust()
{
return thrust;
}
public void setThrust(float thrust)
{
this.thrust = thrust;
}
public int getTeam()
{
return team;
}
public void setTeam(int team)
{
this.team = team;
}
public Shape getShape()
{
return shape;
}
public void setShape(Shape shape)
{
this.shape = shape;
}
}