Collision detection generally works find but I have trouble when the ball is hitting corners of the box. That is particularly annoying to check especially when levels are very different of each other.
This is the function where I check collision with boxes.
Expand|Select|Wrap|Line Numbers
- public void checkCollideWithBox(int x, int y, int r, Ball ball, boolean second){
- boolean collidedwithbox = false;
- for(int j = 0; j<insidebox.length;j++){
- if(insidebox[j]){
- if((((x+r>=boxes[j].getPositionX()&&(x<=boxes[j].getPositionX()+20)
- &&ball.getDirectionX()>0))||((x<=boxes[j].getPositionX()+20
- &&(x+r>=boxes[j].getPositionX())
- &&ball.getDirectionX()<=0)))
- &&(y+r>=boxes[j].getPositionY()
- &&y<=boxes[j].getPositionY()+40)
- &&!boxes[j].getDestroyed())collidedwithbox = true;
- else insidebox[j] = false;
- }
- }
- boolean yhit = false, xhit = false;
- for(int i = 0; i<boxes.length && !collidedwithbox&&!(yhit||xhit); i++){
- if(!boxes[i].getDestroyed()){ //if box is not destroyed already
- if((((x+r>=boxes[i].getPositionX()&&(x<=boxes[i].getPositionX()+20)
- &&ball.getDirectionX()>0))||((x<=boxes[i].getPositionX()+20
- &&(x+r>=boxes[i].getPositionX())&&ball.getDirectionX()<=0)))
- &&(y+r>=boxes[i].getPositionY()
- &&y<=boxes[i].getPositionY()+40)){ //if ball is touching or inside the box
- if((y==boxes[i].getPositionY()+40&&!(ball.getDirectionY()>=0))
- ||(y+r==boxes[i].getPositionY()
- &&!(ball.getDirectionY()<=0))){ //if ball is on upper or lower side of the box
- //trying to solve corner cases, this is not enough:
- if(!((x+r==boxes[i].getPositionX()&&ball.getDirectionX()<0)||(x==boxes[i].getPositionX()
- &&ball.getDirectionX()>0))){
- yhit = true;
- xhit = false;
- }else{
- yhit = false;
- xhit = true;
- }
- } else xhit = true;
- if(boxes[i].getHits()<=1){
- boxes[i].getEffect(ball, b1, b2, ballthread);
- boxes[i].setDestroyed();
- if(!boxes[i].isIndestructible()){
- g.playSound(2);
- boxesleft--;
- if(lasthitplayer1ball1)scoreplayer1 +=10;
- else scoreplayer2 +=10;
- da.updateScoreBox(scoreplayer1, scoreplayer2);
- }else g.playSound(3); //indestructible sound
- if(boxesleft <= 0){
- collidedwithbox = true;
- this.changeLevel();
- }
- }else{
- g.playSound(2);
- boxes[i].setHits(boxes[i].getHits()-1);
- boxes[i].setColor(boxes[i].getColor()-1);
- if(!twoballs){
- if(lasthitplayer1ball1)scoreplayer1 +=10;
- else scoreplayer2 +=10;
- }else{
- if(!second){
- if(lasthitplayer1ball1)scoreplayer1 +=10;
- else scoreplayer2 +=10;
- }else{
- if(lasthitplayer1ball2)scoreplayer1 +=10;
- else scoreplayer2 +=10;
- }
- }
- da.updateScoreBox(scoreplayer1, scoreplayer2);
- }
- insidebox[i] = true;
- }
- }
- }
- if(!collidedwithbox){
- if(xhit) ball.setDirectionX(-ball.getDirectionX());
- else if(yhit)ball.setDirectionY(-ball.getDirectionY());
- }
- }
Insidebox is boolean array for checking if ball is out of box's area.
Any help to solve this problem?