169 lines
5.4 KiB
Java
169 lines
5.4 KiB
Java
package break_out.model;
|
|
|
|
import break_out.Constants;
|
|
|
|
/**
|
|
* This class contains the information about the balls characteristics and behavior
|
|
*
|
|
* @author iSchumacher
|
|
* @author modified by Gruppe 175: Moritz Henseleit, Ruben Meyer
|
|
*/
|
|
public class Ball implements IBall {
|
|
|
|
/**
|
|
* The balls position on the playground
|
|
*/
|
|
private Position position;
|
|
|
|
/**
|
|
* The balls direction
|
|
*/
|
|
private Vector2D direction;
|
|
|
|
/**
|
|
* The constructor of a ball
|
|
* The balls position and direction are initialized here.
|
|
*/
|
|
public Ball() {
|
|
this.position = new Position(0, 0);
|
|
this.direction = new Vector2D(Constants.BALL_SPEED, Constants.BALL_SPEED);
|
|
this.direction.rescale();
|
|
|
|
// start at bottom-center
|
|
this.position.setX((Constants.SCREEN_WIDTH - Constants.BALL_DIAMETER) / 2.0);
|
|
this.position.setY(Constants.SCREEN_HEIGHT - Constants.BALL_DIAMETER - Constants.PADDLE_HEIGHT);
|
|
}
|
|
|
|
/**
|
|
* The getter for the balls position
|
|
*
|
|
* @return position The balls current position
|
|
*/
|
|
public Position getPosition() {
|
|
return this.position;
|
|
}
|
|
|
|
/**
|
|
* The getter for the balls direction
|
|
*
|
|
* @return direction The balls current direction
|
|
*/
|
|
public Vector2D getDirection() {
|
|
return this.direction;
|
|
}
|
|
|
|
/**
|
|
* updates ball position
|
|
*/
|
|
public void updatePosition() {
|
|
// sets X position
|
|
this.position.setX(this.position.getX() + this.direction.getDx());
|
|
|
|
// sets Y position
|
|
this.position.setY(this.position.getY() + this.direction.getDy());
|
|
}
|
|
|
|
/**
|
|
* Ball reacts to contact with the borders
|
|
*/
|
|
public void reactOnBorder() {
|
|
// reacts on left border
|
|
if (this.position.getX() <= 0) {
|
|
this.position.setX(0);
|
|
this.direction.setDx(-(this.direction.getDx()));
|
|
}
|
|
|
|
// reacts on right border (-Diameter because of hitbox)
|
|
if (this.position.getX() >= Constants.SCREEN_WIDTH - Constants.BALL_DIAMETER) {
|
|
this.position.setX(Constants.SCREEN_WIDTH - Constants.BALL_DIAMETER);
|
|
this.direction.setDx(-(this.direction.getDx()));
|
|
}
|
|
|
|
// reacts on top border
|
|
if (this.position.getY() <= 0) {
|
|
this.position.setY(0);
|
|
this.direction.setDy(-(this.direction.getDy()));
|
|
}
|
|
|
|
// reacts on bottom border (+Diameter because of hitbox)
|
|
if (this.position.getY() >= Constants.SCREEN_HEIGHT - Constants.BALL_DIAMETER) {
|
|
this.position.setY(Constants.SCREEN_HEIGHT - Constants.BALL_DIAMETER);
|
|
this.direction.setDy(-(this.direction.getDy()));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* tests whether the ball touches the paddle's hit box.
|
|
* @param paddle paddle which will be tested
|
|
* @return true when ball hits the paddle
|
|
*/
|
|
public boolean hitsPaddle(Paddle paddle) {
|
|
// paddles position
|
|
Position posPaddle = paddle.getPosition();
|
|
|
|
// balls position
|
|
Position posBall = this.getPosition();
|
|
|
|
// test balls y position against paddles y values
|
|
// paddles y values can be interpreted as a closed interval therefore if balls y position is in the interval, its true
|
|
boolean testPaddleY = (
|
|
posPaddle.getY() <= posBall.getY() && posBall.getY() <= posPaddle.getY()+paddle.getHeight() ||
|
|
posPaddle.getY() <= posBall.getY()+Constants.BALL_DIAMETER && posBall.getY()+Constants.BALL_DIAMETER <= posPaddle.getY()+paddle.getHeight()
|
|
);
|
|
|
|
// test balls x position against paddles x values
|
|
// paddles x values can be interpreted as a closed interval therefore if balls x position is in the interval, its true
|
|
boolean testPaddleX = (
|
|
posPaddle.getX() <= posBall.getX() && posBall.getX() <= posPaddle.getX()+paddle.getWidth() ||
|
|
posPaddle.getX() <= posBall.getX()+Constants.BALL_DIAMETER && posBall.getX()+Constants.BALL_DIAMETER <= posPaddle.getX()+paddle.getWidth()
|
|
);
|
|
|
|
// if balls y position is in paddles y values, verify x position
|
|
if(testPaddleY) {
|
|
// DEBUG OUTPUT
|
|
//System.out.println("ball is in y area of paddle: "+String.format("x, y, w, h: %s, %s, %s, %s", posPaddle.getX(), posPaddle.getY(), paddle.getWidth(), paddle.getHeight()));
|
|
|
|
// if ball is in paddles hit box
|
|
if(testPaddleX) {
|
|
// DEBUG OUTPUT
|
|
//System.out.println("ball hits paddle: "+String.format("x, y, w, h: %s, %s, %s, %s", posPaddle.getX(), posPaddle.getY(), paddle.getWidth(), paddle.getHeight()));
|
|
|
|
return true;
|
|
}
|
|
|
|
}
|
|
|
|
// default output, ball doesn't hit paddle
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Ball got hit by Paddle paddle
|
|
* @param paddle hitbox mechanism of paddle
|
|
* @todo implementation
|
|
*/
|
|
public void reflectOnPaddle(Paddle p) {
|
|
// get the Position of the middle of the paddle
|
|
Position newOffset = new Position(
|
|
p.getPosition().getX() + p.getWidth() / 2.0,//the middle of the x coordinates
|
|
p.getPosition().getY() + p.getHeight() / 2.0);//the middle of the y coordinates
|
|
//deciding if the paddle is at the top or bottom to adjust if its +or- y direction
|
|
if (p.getPosition().getY() == 0) {
|
|
newOffset.setY(newOffset.getY() - Constants.REFLECTION_OFFSET);// paddle at the top with negative direction
|
|
} else {
|
|
newOffset.setY(newOffset.getY() + Constants.REFLECTION_OFFSET); // the paddle at the bottom with positive direction
|
|
}
|
|
|
|
// calculating the center of the ball by dividing by zero
|
|
Position ballCenter = new Position(
|
|
position.getX() + Constants.BALL_DIAMETER/2.0, //the middle of the x coordinates
|
|
position.getY() + Constants.BALL_DIAMETER/2.0); //the middle of the y coordinates
|
|
|
|
// The direction is set to the middle of the offset point and the ball
|
|
direction = new Vector2D(newOffset, ballCenter);
|
|
// rescaling to adjust the balls speed
|
|
direction.rescale();
|
|
}
|
|
|
|
}
|