Reputation: 305
This is a grade 12 OPP assignment.
Currently I have a problem that the ball occasionally would go into the blocks instead of reflecting.
Here's my code:
how the main checks if the ball is hitting a block:
public void theBall(){
//System.out.println(blocks.size());
if(!started){
balls.get(0).withPaddle(paddle.returnX());
}
if(started){
for(int i=0;i<balls.size();i++){
if(balls.get(i).returnX()>=0 && balls.get(i).returnX()<=800 && balls.get(i).returnY()>=0){
balls.get(i).move();
}
if(balls.get(i).returnX()+balls.get(i).returnDx()<= 0){
balls.get(i).collide(1);//collide with left wall
}
if(balls.get(i).returnX()+10+balls.get(i).returnDx() >= 800){
balls.get(i).collide(2);//collide with right wall
}
if(balls.get(i).returnY()-balls.get(i).returnDy() <= 0){
balls.get(i).collide(3);//collide with up wall
}
if(paddle.returnX() < balls.get(i).returnX() && balls.get(i).returnX()< paddle.returnX()+paddle.returnSize() && balls.get(i).returnY()-balls.get(i).returnDy() >= 545){//fix this && balls.get(i).returnY()-balls.get(i).returnDy() <= 560
balls.get(i).collidePaddle(balls.get(i).returnX()-paddle.returnX());//collide with paddle
//System.out.println(ball.returnDy());
}
for(int j=0;j<blocks.size();j++){
//blocks.get(j).getHit(balls.get(i));
if(balls.get(i).returnX()+10+balls.get(i).returnDx() >= blocks.get(j).returnX() && balls.get(i).returnX()+10+balls.get(i).returnDx() <= blocks.get(j).returnX()+5 && balls.get(i).returnY() >= blocks.get(j).returnY() && balls.get(i).returnY() < blocks.get(j).returnY()+50){
if(!blocks.get(j).returnHit()){
balls.get(i).collide(2);//collide with right wall (block's left)
blocks.get(j).getHit(balls.get(i));
System.out.println("boiboiboiboibo1");
}
}
if(balls.get(i).returnX()+balls.get(i).returnDx() <= blocks.get(j).returnX()+50 && balls.get(i).returnX()+balls.get(i).returnDx() >= blocks.get(j).returnX()+45 && balls.get(i).returnY() >= blocks.get(j).returnY() && balls.get(i).returnY() < blocks.get(j).returnY()+50){
if(!blocks.get(j).returnHit()){
balls.get(i).collide(1);//collide with left wall (block's right)
blocks.get(j).getHit(balls.get(i));
System.out.println("boiboiboiboibo2");
}
}
if(balls.get(i).returnX() >= blocks.get(j).returnX() && balls.get(i).returnX() < blocks.get(j).returnX()+50 && balls.get(i).returnY()-balls.get(i).returnDy() <= blocks.get(j).returnY()+50 && balls.get(i).returnY()-balls.get(i).returnDy() >= blocks.get(j).returnY()+45){
if(!blocks.get(j).returnHit()){
balls.get(i).collide(3);//collide with up wall (block's bottom)
blocks.get(j).getHit(balls.get(i));
System.out.println("boiboiboiboibo3");
}
}
if(balls.get(i).returnX() >= blocks.get(j).returnX() && balls.get(i).returnX() < blocks.get(j).returnX()+50 && balls.get(i).returnY()+10-balls.get(i).returnDy() >= blocks.get(j).returnY() && balls.get(i).returnY()+10-balls.get(i).returnDy() <= blocks.get(j).returnY()+5){
if(!blocks.get(j).returnHit()){
balls.get(i).collide(4);//collide with down wall (block's top)
blocks.get(j).getHit(balls.get(i));
System.out.println("boiboiboiboibo4");
}
}
}
for(int j=0;j<specialBlocks.size();j++){
if(balls.get(i).returnX()>=specialBlocks.get(j).returnX() && balls.get(i).returnX()<=specialBlocks.get(j).returnX()+100 && balls.get(i).returnY()>=specialBlocks.get(j).returnY() && balls.get(i).returnY()<=specialBlocks.get(j).returnY()+100){
oneAndThreeBalls(i, j);
balls.get(i).changeType(j);
}
}
}
}
}
How the ball reflects:
public void collide(int collideWith){
if(collideWith==1){//collide with left wall
if(90<direction && direction<180){
direction = 180-direction;
}
if(180<direction && direction<270){
direction = 540-direction;
}
}
if(collideWith==2){//collide with right wall
if(0<direction && direction<90){
direction = 180-direction;
}
if(270<direction && direction<360){
direction = 540-direction;
}
}
if(collideWith==3){//collide with up wall
direction = 360-direction;
}
if(collideWith==4){//collide with down wall
direction = 360-direction;
}
}
It is very clear to me that the bug is because of the double checking of the boundaries. When the ball is at the corner of a block, it happens. But that's the only way I can think of to check for the ball's position to reflect. Any ideas of how I can fix this bug? Thank you.
Upvotes: 0
Views: 564
Reputation: 21773
Why not make it so:
1) After doing a bounce, you stop checking collision for that ball until the next tick of the game. That way a ball can only bounce once per tick.
2) After colliding with and bouncing off of a block, you ignore collision between that specific block and the ball until such time as the ball does not overlap the block. That way a ball can't spuriously bounce off of a block twice on the same impact.
Btw, you have a lot of copied and pasted code with only slight changes in numbers and so on. If you found a way to restate it in terms of a method you keep calling with slightly different parameters, your code will become a lot neater and the underlying symmetry of the problem will also be more obvious.
Upvotes: 1