I'm experimenting with a simple Break Out clone to get an understanding of Game States, Game Loops etc.
One of the things I'm having difficulty with is the collision detection.
I have a GameItem
class that is extended by Ball, Brick and Paddle. In this class I have a getBounds()
method to return the bounding Rectangle of the object, a collision(GameItem
item) method to determine whether 2 GameItem
objects have collided as well as methods for hitTop()
, hitBottom()
, hitLeft()
and hitRight()
to determine which side the object collided with the other.
These methods are as follows:
public Rectangle getBounds()
{
return new Rectangle(x, y, width, height);
}
public boolean collision(GameItem item)
{
return getBounds().intersects(item.getBounds());
}
public boolean hitTop(GameItem item)
{
return getY()+getHeight()>=item.getY();
}
public boolean hitLeft(GameItem item)
{
return getX()+getWidth()>=item.getX();
}
public boolean hitBottom(GameItem item)
{
return getY()<=item.getY()+item.getHeight();
}
public boolean hitRight(GameItem item)
{
return getX()<=item.getX()+item.getWidth();
}
The ball class has a method called checkBallCollissions(GameItem item)
to determine when the ball has hit another object. This is as follows:
public boolean checkBallCollisions(GameItem item)
{
if(this.collision(item))
{
if(this.hitTop(item))
{
this.setVY(-1*this.getVY());
return true;
}
else if(this.hitBottom(item))
{
this.setVY(-1*this.getVY());
return true;
}
else if(this.hitLeft(item))
{
this.setVX(-1*this.getVX());
return true;
}
else if(this.hitRight(item))
{
this.setVX(-1*this.getVX());
return true;
}
return false;
}
return false;
}
Which would be called as follows:
ball.checkBallCollisions(paddle);
As you can see, if it hits one of the 4 edges, the x/y direction is reversed accordingly.
However, this doesn't work. Analysing the code it seems there's an obvious issue that I can't fathom a solution to.
The 3 images below show a collision of the ball with an object from above, below and the right.
With the code as it is, it first detects a collision based on the bounding Rectangles and the intersects() method. It then determines which side it hit. If it hits from above it works. However, when it hits form the bottom or right then hitTop()
will return true since getY()+getHeight()>=item.getY()
is true for both these cases (i.e the bottom edge of the ball has a greater y value than the top edge of the object it's colliding with).
What conditions am I missing to resolve this and have perfect collision detection?