Bounding-box bug?

Started by
8 comments, last by Zkd 16 years, 5 months ago
I recently have been making a breakout clone. I finished most of its systems except, in my collision detection code there seems to be a bug. The ball, if it hits the exact corners of a block or the paddle, it will go inside them and bounce off in a wierd direction. If anyone has had this problem and knows how to fix it any help would be greatly appreciated!
Advertisement
Your bound tests must be ignoring a special case. Post your bound-test code please.
Without seeing code my immediate thought is your collision function detects a collision twice and you are changing the ball direction twice.

Note: This is in &#106avascript.

function BallCollision(a, b) { //a is the ball, b is the other object	if(b.isAlive==true) {		if((a.x>=b.x) && (a.x<=(b.x+b.w))) {			if(((a.x+a.w)>=b.x) && ((a.x+a.w)<=(b.x+b.w))) {				if((a.y>=b.y && a.y<=(b.y+b.h)) || ((a.y+a.h)>=b.y && (a.y+a.h)<=(b.y+b.h))) {					//Ball has hit top or bottom face of object	  					bounce.play([0]);   					ball.vy =  -ball.vy;  					if(b.id=="block") { 						b.isAlive = false; 						score += [50];					} 				}        			}		}        			if((a.y>=b.y) && (a.y<=(b.y+b.h))) { 			if(((a.y+a.h)>=b.y) && ((a.y+a.h)<=(b.y+b.h))) {				if((a.x>=b.x && a.x<=(b.x+b.w))) {	         	     	         					//ball has hit right face of object	 					bounce.play([0]);        					a.vx = -a.vx;					if(b.id=="block") { 						b.isAlive = false; 						score += [50];					} 	     				}	                	   				if (((a.x+a.w)>=b.x && (a.x+a.w)<=(b.x+b.w))) {					//ball has hit left face of object					bounce.play([0]);	     	     	         		 					a.vx = -a.vx;					if(b.id=="block") { 						b.isAlive = false; 						score += [50];					} 	  				}	   			}           		}	}}
You're making a few small mistakes here. First, you check if a's left side lies between b's left and right sides. But what id a's left side lies to the left, but it's right side lies between b's left and right sides? A collision can happen in that case too, but you're ignoring it. For your information: if(a.x >= b.x) -> if(a.x + a.w >= b.x). There might be more cases where you make the same or a similar mistake.

As for hitting the top or left side or any other specific side of an object, you can't tell that by using positions alone - for example, a ball may move at high speed, and end up on the other side of the object after just a single frame. Taking it's velocity into account here should help you determine which side it should've hit first. Unless you can be sure that the ball won't move that fast, this is a suspicious area.


Also, I find a and b somewhat undescriptive names, and while w and h might indicate width and height, it all reads like a complex serie of equations. Consider using more descriptive names, like ball, object, width, height... I'm sure it'll help you find problems easier because you can focus on what the code actually does, rather than having to decipher it first. :)
Create-ivity - a game development blog Mouseover for more information.
Ok, I updated my collision script but I still don't think that its right. If the ball gets going to fast it will just go through blocks and I can't figure this out.

function BallCollision(a, b) {	if(b.isAlive==true) {		if((a.x>=b.x) && (a.x<=(b.x+b.w))) {			if(((a.x+a.w)>=b.x) && ((a.x+a.w)<=(b.x+b.w))) {				if((a.y+a.h)+a.vy>=b.y && a.y<=b.y) {					//Ball has hit top face of object	  					bounce.play([0]);   					if(b.id=="paddle") {											if(isMovingRight==true) {							if(a.vx>[0] || a.vx ==[0] || a.vx<[0] ) { 								a.vx += pspeed/[5]; 								ball_speed += pspeed/[45];							}						}											if(isMovingLeft==true) {							if(a.vx>[1] || a.vx==[0] || a.vx<[1]) { 								a.vx -= pspeed/[5]; 								ball_speed -= pspeed/[45];							}						}											a.y   = b.y - a.h; 					}					if(a.vy>[2]) { a.vy -= ball_speed*[2]; }					a.vy  =  -a.vy;  					if(b.id=="block") { 						b.isAlive = false; 						score += [50];					} 				}  				if(a.y-a.vy<=(b.y+b.h) && (a.y+a.h)>=(b.y+b.h)) {					//Ball has hit bottom face of object	  					bounce.play([0]);   					if(b.id=="paddle") { a.y   = b.y + b.h; }					a.vy  =  -a.vy;  					if(b.id=="block") { 						b.isAlive = false; 						score += [50];					} 				}			}		}        			if((a.y>=b.y) && (a.y<=(b.y+b.h))) { 			if(((a.y+a.h)>=b.y) && ((a.y+a.h)<=(b.y+b.h))) {				if((a.x<=(b.x+b.w) && (a.x+a.w)>=(b.x+b.w))) {	         	     	         					//ball has hit right face of object	 					bounce.play([0]);  					if(b.id=="paddle") { a.x   = b.x + b.w;  }      					a.vx  = -a.vx;					if(b.id=="block") { 						b.isAlive = false; 						score += [50];					} 	     				}	                	   				if ((a.x+a.w)>=b.x && a.x<=b.x) {					//ball has hit left face of object					bounce.play([0]);	   	 					if(b.id=="paddle") { a.x   = b.x - a.w; } 	          		 					a.vx  = -a.vx;					if(b.id=="block") { 						b.isAlive = false; 						score += [50];					} 	  				}	   			}           		}	}}
Quote:Original post by Zkd
Ok, I updated my collision script but I still don't think that its right. If the ball gets going to fast it will just go through blocks and I can't figure this out.

*** Source Snippet Removed ***


When the ball hits a block , try to set the position equal to its position - its width.
What i mean:
if( ball.x+ball.width >=block.x) ball.x=block.x-ball.width

I have tried this before and it produces some unwanted results. It makes the ball appear to jump. Is there a fix?
Quote:Original post by Zkd
I have tried this before and it produces some unwanted results. It makes the ball appear to jump. Is there a fix?


Do you update the velocity?
For example:
if( ball.x+ball.width >=block.x){ ball.x=block.x-ball.width  update velocity based on side.}
I have the lines (a.vy = -a.vy) and (a.vx = -a.vx) for the appropriate sides.


What I meant earlier is the ball will start to go through a block and then jump back to the side that it hit and change velocity. So it makes the ball jump every time it hits a block and it looks goofy.
Like:\         / \       /  \     /   \   .(Point B)  - - \ - - - - - -    Then it jumps from point a to point b and it looks very     \                 unatural.      .(Point A)

This topic is closed to new replies.

Advertisement